{"version":3,"sources":["../src/formatter.ts","../src/Structures/Channel.ts","../src/Structures/Thumbnail.ts","../src/Structures/Playlist.ts","../src/Structures/Video.ts","../src/Util.ts","../src/mod.ts"],"sourcesContent":["/*\n * MIT License\n *\n * Copyright (c) 2020 twlite\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport { Playlist, Video, Channel } from \"./Structures/exports\";\nimport Util from \"./Util\";\n\nexport class Formatter {\n    constructor() {\n        return Formatter;\n    }\n\n    public static formatSearchResult(\n        details: any[],\n        options: { limit?: number; type?: \"film\" | \"video\" | \"channel\" | \"playlist\" | \"all\" } = {\n            limit: 100,\n            type: \"all\"\n        }\n    ) {\n        const results: Array<Video | Channel | Playlist> = [];\n\n        for (let i = 0; i < details.length; i++) {\n            if (typeof options.limit === \"number\" && options.limit > 0 && results.length >= options.limit) break;\n            let data = details[i];\n            let res: Video | Channel | Playlist;\n            if (options.type === \"all\") {\n                if (!!data.videoRenderer) options.type = \"video\";\n                else if (!!data.channelRenderer) options.type = \"channel\";\n                else if (!!data.playlistRenderer) options.type = \"playlist\";\n                else continue;\n            }\n\n            if (options.type === \"video\" || options.type === \"film\") {\n                const parsed = Util.parseVideo(data);\n                if (!parsed) continue;\n                res = parsed;\n            } else if (options.type === \"channel\") {\n                const parsed = Util.parseChannel(data);\n                if (!parsed) continue;\n                res = parsed;\n            } else if (options.type === \"playlist\") {\n                const parsed = Util.parsePlaylist(data);\n                if (!parsed) continue;\n                res = parsed;\n            }\n\n            results.push(res);\n        }\n\n        return results;\n    }\n}\n","/*\n * MIT License\n *\n * Copyright (c) 2020 twlite\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nexport interface ChannelIconInterface {\n    url?: string;\n    width: number;\n    height: number;\n}\n\nexport class Channel {\n    name?: string;\n    verified: boolean;\n    id?: string;\n    url?: string;\n    icon: ChannelIconInterface;\n    subscribers?: string;\n\n    constructor(data: any) {\n        if (!data) throw new Error(`Cannot instantiate the ${this.constructor.name} class without data!`);\n\n        this._patch(data);\n    }\n\n    /**\n     * Patch raw data\n     * @private\n     * @ignore\n     */\n    private _patch(data: any): void {\n        if (!data) data = {};\n\n        this.name = data.name || null;\n        this.verified = !!data.verified || false;\n        this.id = data.id || null;\n        this.url = data.url || null;\n        this.icon = data.icon || { url: null, width: 0, height: 0 };\n        this.subscribers = data.subscribers || null;\n\n        if (this.icon.url?.startsWith(\"//\")) this.icon.url = `https:${this.icon.url}`;\n    }\n\n    /**\n     * Returns channel icon url\n     * @param {object} options Icon options\n     * @param {number} [options.size=0] Icon size. **Default is 0**\n     */\n    iconURL(options = { size: 0 }): string {\n        if (typeof options.size !== \"number\" || options.size < 0) throw new Error(\"invalid icon size\");\n        if (!this.icon.url) return null;\n        const def = this.icon.url.split(\"=s\")[1].split(\"-c\")[0];\n        return this.icon.url.replace(`=s${def}-c`, `=s${options.size}-c`);\n    }\n\n    get type(): \"channel\" {\n        return \"channel\";\n    }\n\n    toString(): string {\n        return this.name || \"\";\n    }\n\n    toJSON() {\n        return {\n            name: this.name,\n            verified: this.verified,\n            id: this.id,\n            url: this.url,\n            iconURL: this.iconURL(),\n            type: this.type,\n            subscribers: this.subscribers\n        };\n    }\n}\n","/*\n * MIT License\n *\n * Copyright (c) 2020 twlite\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\ntype ThumbnailType = \"default\" | \"hqdefault\" | \"mqdefault\" | \"sddefault\" | \"maxresdefault\" | \"ultrares\";\nexport class Thumbnail {\n    id?: string;\n    width: number;\n    height: number;\n    url?: string;\n\n    /**\n     * Thumbnail constructor\n     * @param data Thumbnail constructor params\n     */\n    constructor(data: any) {\n        if (!data) throw new Error(`Cannot instantiate the ${this.constructor.name} class without data!`);\n\n        this._patch(data);\n    }\n\n    /**\n     * Patch raw data\n     * @param data Raw Data\n     * @private\n     * @ignore\n     */\n    private _patch(data: any) {\n        if (!data) data = {};\n\n        this.id = data.id || null;\n        this.width = data.width || 0;\n        this.height = data.height || 0;\n        this.url = data.url || null;\n    }\n\n    /**\n     * Returns thumbnail url\n     * @param {\"default\"|\"hqdefault\"|\"mqdefault\"|\"sddefault\"|\"maxresdefault\"|\"ultrares\"} thumbnailType Thumbnail type\n     */\n    displayThumbnailURL(thumbnailType: ThumbnailType = \"ultrares\"): string {\n        if (![\"default\", \"hqdefault\", \"mqdefault\", \"sddefault\", \"maxresdefault\", \"ultrares\"].includes(thumbnailType)) throw new Error(`Invalid thumbnail type \"${thumbnailType}\"!`);\n        if (thumbnailType === \"ultrares\") return this.url;\n        return `https://i3.ytimg.com/vi/${this.id}/${thumbnailType}.jpg`;\n    }\n\n    /**\n     * Returns default thumbnail\n     * @param {\"0\"|\"1\"|\"2\"|\"3\"|\"4\"} id Thumbnail id. **4 returns thumbnail placeholder.**\n     */\n    defaultThumbnailURL(id: \"0\" | \"1\" | \"2\" | \"3\" | \"4\"): string {\n        if (!id) id = \"0\";\n        if (![\"0\", \"1\", \"2\", \"3\", \"4\"].includes(id)) throw new Error(`Invalid thumbnail id \"${id}\"!`);\n        return `https://i3.ytimg.com/vi/${this.id}/${id}.jpg`;\n    }\n\n    toString(): string {\n        return this.url ? `${this.url}` : \"\";\n    }\n\n    toJSON() {\n        return {\n            id: this.id,\n            width: this.width,\n            height: this.height,\n            url: this.url\n        };\n    }\n}\n","/*\n * MIT License\n *\n * Copyright (c) 2020 twlite\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport { Thumbnail } from \"./Thumbnail\";\nimport { Video } from \"./Video\";\nimport { Channel } from \"./Channel\";\nimport Util from \"../Util\";\nconst BASE_API = \"https://www.youtube.com/youtubei/v1/browse?key=\";\n\nexport class Playlist {\n    id?: string;\n    title?: string;\n    videoCount: number;\n    lastUpdate?: string;\n    views?: number;\n    url?: string;\n    link?: string;\n    channel?: Channel;\n    thumbnail?: Thumbnail;\n    videos: Video[];\n    mix?: boolean;\n    fake = false;\n    private _continuation: { api?: string; token?: string; clientVersion?: string } = {};\n\n    constructor(data = {}, searchResult = false) {\n        if (!data) throw new Error(`Cannot instantiate the ${this.constructor.name} class without data!`);\n        Object.defineProperty(this, \"_continuation\", { enumerable: false, configurable: true, writable: true });\n        if (!!searchResult) this._patchSearch(data);\n        else this._patch(data);\n    }\n\n    private _patch(data: any) {\n        this.id = data.id || null;\n        this.title = data.title || null;\n        this.videoCount = data.videoCount || 0;\n        this.lastUpdate = data.lastUpdate || null;\n        this.views = data.views || 0;\n        this.url = data.url || data.link || this.id ? `https://www.youtube.com/playlist?list=${this.id}` : null;\n        this.link = data.link || data.url || null;\n        this.channel = data.author || null;\n        this.thumbnail = new Thumbnail(data.thumbnail || {});\n        this.videos = data.videos || [];\n        this._continuation.api = data.continuation?.api ?? null;\n        this._continuation.token = data.continuation?.token ?? null;\n        this._continuation.clientVersion = data.continuation?.clientVersion ?? \"<important data>\";\n        this.mix = data.mix || false;\n        this.fake = Boolean(data.fake);\n    }\n\n    private _patchSearch(data: any) {\n        this.id = data.id || null;\n        this.title = data.title || null;\n        this.thumbnail = new Thumbnail(data.thumbnail || {});\n        this.channel = data.channel || null;\n        this.videos = data.videos || [];\n        this.videoCount = data.videos?.length || 0;\n        this.url = data.url || data.link || this.id ? `https://www.youtube.com/playlist?list=${this.id}` : null;\n        this.link = data.link || data.url || null;\n        this.lastUpdate = null;\n        this.views = 0;\n        this.mix = data.mix || false;\n        this.fake = Boolean(data.fake);\n    }\n\n    /**\n     * @param limit Max items to parse from current chunk\n     */\n    async next(limit: number = Infinity): Promise<Video[]> {\n        if (!this._continuation || !this._continuation.token) return [];\n\n        const nextPage = await Util.getHTML(`${BASE_API}${this._continuation.api}`, {\n            method: \"POST\",\n            body: JSON.stringify({\n                continuation: this._continuation.token,\n                context: {\n                    client: {\n                        utcOffsetMinutes: 0,\n                        gl: \"US\",\n                        hl: \"en\",\n                        clientName: \"WEB\",\n                        clientVersion: this._continuation.clientVersion\n                    },\n                    user: {},\n                    request: {}\n                }\n            })\n        });\n\n        const contents = Util.json(nextPage)?.onResponseReceivedActions[0]?.appendContinuationItemsAction?.continuationItems;\n        if (!contents) return [];\n        const partial = Util.getPlaylistVideos(contents, limit);\n        this._continuation.token = Util.getContinuationToken(contents);\n        this.videos = [...this.videos, ...partial];\n\n        return partial;\n    }\n\n    async fetch(max: number = Infinity) {\n        const ctn = this._continuation.token;\n        if (!ctn) return this;\n        if (max < 1) max = Infinity;\n\n        while (typeof this._continuation.token === \"string\" && this._continuation.token.length) {\n            if (this.videos.length >= max) break;\n            const res = await this.next();\n            if (!res.length) break;\n        }\n\n        return this;\n    }\n\n    get type(): \"playlist\" {\n        return \"playlist\";\n    }\n\n    *[Symbol.iterator](): IterableIterator<Video> {\n        yield* this.videos;\n    }\n\n    toJSON() {\n        return {\n            id: this.id,\n            title: this.title,\n            thumbnail: this.thumbnail?.toJSON() || null,\n            channel: {\n                name: this.channel.name,\n                id: this.channel.id,\n                icon: this.channel?.iconURL?.()\n            },\n            mix: this.mix,\n            url: this.url,\n            videos: this.videos\n        };\n    }\n}\n","/*\n * MIT License\n *\n * Copyright (c) 2020 twlite\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport { Channel } from \"./Channel\";\nimport { Thumbnail } from \"./Thumbnail\";\n\nexport interface VideoStreamingData {\n    expiresInSeconds: string;\n    formats: VideoStreamingFormat[];\n    adaptiveFormats: VideoStreamingFormatAdaptive[];\n}\n\nexport interface VideoStreamingFormat {\n    itag: number;\n    mimeType: string;\n    bitrate: number;\n    width: number;\n    height: number;\n    lastModified: string;\n    contentLength: string;\n    quality: string;\n    fps: number;\n    qualityLabel: string;\n    projectionType: string;\n    averageBitrate: number;\n    audioQuality: string;\n    approxDurationMs: string;\n    audioSampleRate: string;\n    audioChannels: number;\n    signatureCipher: string;\n}\n\nexport interface VideoStreamingFormatAdaptive extends VideoStreamingFormat {\n    initRange?: { start: string; end: string };\n    indexRange?: { start: string; end: string };\n    colorInfo?: {\n        primaries: string;\n        transferCharacteristics?: string;\n        matrixCoefficients?: string;\n    };\n    highReplication?: boolean;\n    loudnessDb?: number;\n}\n\nexport interface MusicInfo {\n    title: string;\n    cover: string;\n    artist: string;\n    album: string;\n}\n\nexport class Video {\n    id?: string;\n    title?: string;\n    description?: string;\n    durationFormatted: string;\n    duration: number;\n    uploadedAt?: string;\n    views: number;\n    thumbnail?: Thumbnail;\n    channel?: Channel;\n    videos?: Video[];\n    likes: number;\n    dislikes: number;\n    live: boolean;\n    private: boolean;\n    tags: string[];\n    nsfw = false;\n    shorts = false;\n    unlisted = false;\n    streamingData?: VideoStreamingData | null;\n    music: MusicInfo[];\n\n    constructor(data: any) {\n        if (!data) throw new Error(`Cannot instantiate the ${this.constructor.name} class without data!`);\n\n        this._patch(data);\n    }\n\n    /**\n     * Patch raw data\n     * @private\n     * @ignore\n     */\n    private _patch(data: any): void {\n        if (!data) data = {};\n\n        this.id = data.id || null;\n        this.title = data.title || null;\n        this.description = data.description || null;\n        this.durationFormatted = data.duration_raw || \"0:00\";\n        this.duration = (data.duration < 0 ? 0 : data.duration) || 0;\n        this.uploadedAt = data.uploadedAt || null;\n        this.views = parseInt(data.views) || 0;\n        this.thumbnail = new Thumbnail(data.thumbnail || {});\n        this.channel = new Channel(data.channel || {});\n        this.likes = data.ratings?.likes || 0;\n        this.dislikes = data.ratings?.dislikes || 0;\n        this.live = !!data.live;\n        this.private = !!data.private;\n        this.tags = data.tags || [];\n        this.nsfw = Boolean(data.nsfw);\n        this.unlisted = Boolean(data.unlisted);\n        this.shorts = Boolean(data.shorts);\n        this.music = data.music;\n        Object.defineProperty(this, \"streamingData\", {\n            enumerable: false,\n            configurable: true,\n            writable: true,\n            value: data.streamingData || null\n        });\n        Object.defineProperty(this, \"videos\", {\n            enumerable: false,\n            configurable: true,\n            writable: true,\n            value: data.videos || []\n        });\n    }\n\n    get formats() {\n        return this.streamingData?.formats || [];\n    }\n\n    get adaptiveFormats() {\n        return this.streamingData?.adaptiveFormats || [];\n    }\n\n    get url() {\n        if (!this.id) return null;\n        return `https://www.youtube.com/watch?v=${this.id}`;\n    }\n\n    get shortsURL() {\n        if (!this.shorts) return this.url;\n        return `https://www.youtube.com/shorts/${this.id}`;\n    }\n\n    /**\n     * YouTube video embed html\n     * @param {object} options Options\n     * @param {string} [options.id] DOM element id\n     * @param {number} [options.width] Iframe width\n     * @param {number} [options.height] Iframe height\n     */\n    embedHTML(options = { id: \"ytplayer\", width: 640, height: 360 }): string {\n        if (!this.id) return null;\n        return `<iframe title=\"__youtube_sr_frame__\" id=\"${options.id || \"ytplayer\"}\" type=\"text/html\" width=\"${options.width || 640}\" height=\"${options.height || 360}\" src=\"${this.embedURL}\" frameborder=\"0\"></iframe>`;\n    }\n\n    /**\n     * Creates mix playlist url from this video\n     */\n    createMixURL() {\n        return `${this.url}&list=RD${this.id}`;\n    }\n\n    /**\n     * YouTube video embed url\n     */\n    get embedURL(): string {\n        if (!this.id) return null;\n        return `https://www.youtube.com/embed/${this.id}`;\n    }\n\n    get type(): \"video\" {\n        return \"video\";\n    }\n\n    toString(): string {\n        return this.url || \"\";\n    }\n\n    toJSON() {\n        const res = {\n            id: this.id,\n            url: this.url,\n            shorts_url: this.shortsURL,\n            title: this.title,\n            description: this.description,\n            duration: this.duration,\n            duration_formatted: this.durationFormatted,\n            uploadedAt: this.uploadedAt,\n            unlisted: this.unlisted,\n            nsfw: this.nsfw,\n            thumbnail: this.thumbnail.toJSON(),\n            channel: {\n                name: this.channel.name,\n                id: this.channel.id,\n                icon: this.channel.iconURL()\n            },\n            views: this.views,\n            type: this.type,\n            tags: this.tags,\n            ratings: {\n                likes: this.likes,\n                dislikes: this.dislikes\n            },\n            shorts: this.shorts,\n            live: this.live,\n            private: this.private,\n            music: this.music\n        };\n\n        return res;\n    }\n}\n","/*\n * MIT License\n *\n * Copyright (c) 2020 twlite\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport { Formatter } from \"./formatter\";\nimport { Channel, Video, Playlist, MusicInfo } from \"./Structures/exports\";\n\nconst PLAYLIST_REGEX = /^https?:\\/\\/(www.)?youtube.com\\/playlist\\?list=((PL|FL|UU|LL|RD|OL)[a-zA-Z0-9-_]{16,41})$/;\nconst PLAYLIST_ID = /(PL|FL|UU|LL|RD|OL)[a-zA-Z0-9-_]{11,41}/;\nconst ALBUM_REGEX = /(RDC|O)LAK5uy_[a-zA-Z0-9-_]{33}/;\nconst VIDEO_URL = /^((?:https?:)?\\/\\/)?((?:www|m)\\.)?((?:youtube\\.com|youtu.be))(\\/(?:[\\w\\-]+\\?v=|embed\\/|v\\/)?)([\\w\\-]+)(\\S+)?$/;\nconst VIDEO_ID = /^[a-zA-Z0-9-_]{11}$/;\nconst DEFAULT_INNERTUBE_KEY = \"AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8\";\nlet innertubeCache: string = null;\nlet __fetch: typeof globalThis.fetch;\nconst isNode = typeof process !== \"undefined\" && \"node\" in (process.versions || {});\nconst FETCH_LIBS = [\"node-fetch\", \"cross-fetch\", \"undici\"];\n\nexport interface ParseSearchInterface {\n    type?: \"video\" | \"playlist\" | \"channel\" | \"all\" | \"film\";\n    limit?: number;\n    requestOptions?: RequestInit;\n}\n\nasync function getFetch(): Promise<typeof globalThis.fetch> {\n    // return if fetch is already resolved\n    if (typeof __fetch === \"function\") return __fetch;\n    // try to locate fetch in window\n    if (typeof window !== \"undefined\" && \"fetch\" in window) return window.fetch;\n    // try to locate fetch in globalThis\n    if (\"fetch\" in globalThis) return globalThis.fetch;\n\n    // try to resolve fetch by importing fetch libs\n    for (const fetchLib of FETCH_LIBS) {\n        try {\n            const pkg = await import(fetchLib);\n            const mod = pkg.fetch || pkg.default || pkg;\n            if (mod) return (__fetch = mod);\n        } catch {}\n    }\n\n    if (isNode) throw new Error(`Could not resolve fetch library. Install one of ${FETCH_LIBS.map((m) => `\"${m}\"`).join(\", \")} or define \"fetch\" in global scope!`);\n    throw new Error(\"Could not resolve fetch in global scope\");\n}\n\nclass Util {\n    constructor() {\n        return Util;\n    }\n\n    static async innertubeKey(): Promise<string> {\n        if (innertubeCache) return innertubeCache;\n        return await Util.fetchInnerTubeKey();\n    }\n\n    static get VideoRegex(): RegExp {\n        return VIDEO_URL;\n    }\n\n    static get VideoIDRegex(): RegExp {\n        return VIDEO_ID;\n    }\n\n    static get AlbumRegex(): RegExp {\n        return ALBUM_REGEX;\n    }\n\n    /**\n     * YouTube playlist URL Regex\n     * @type {RegExp}\n     */\n    static get PlaylistURLRegex(): RegExp {\n        return PLAYLIST_REGEX;\n    }\n\n    /**\n     * YouTube Playlist ID regex\n     * @type {RegExp}\n     */\n    static get PlaylistIDRegex(): RegExp {\n        return PLAYLIST_ID;\n    }\n\n    static async fetchInnerTubeKey() {\n        const html = await Util.getHTML(\"https://www.youtube.com?hl=en\");\n        const key = html.split('INNERTUBE_API_KEY\":\"')[1]?.split('\"')[0] ?? html.split('innertubeApiKey\":\"')[1]?.split('\"')[0];\n        if (key) innertubeCache = key;\n        return key ?? DEFAULT_INNERTUBE_KEY;\n    }\n\n    /**\n     * Parse HTML\n     * @param {string} url Website URL\n     * @param {RequestInit} [requestOptions] Request Options\n     * @returns {Promise<string>}\n     */\n    static getHTML(url: string, requestOptions: RequestInit = {}): Promise<string> {\n        requestOptions = Object.assign(\n            {},\n            {\n                headers: Object.assign(\n                    {},\n                    {\n                        \"User-Agent\": \"Mozilla/5.0 (Windows NT 10.0; rv:140.0) Gecko/20100101 Firefox/140.0\"\n                    },\n                    requestOptions?.headers || {}\n                )\n            } as RequestInit,\n            requestOptions || {}\n        );\n\n        return new Promise(async (resolve, reject) => {\n            // lazy load fetch\n            if (!__fetch) __fetch = await getFetch();\n            __fetch(url, requestOptions)\n                .then((res: Response) => {\n                    if (!res.ok) throw new Error(`Rejected with status code: ${res.status}`);\n                    return res.text();\n                })\n                .then((html: string) => resolve(html))\n                .catch((e: Error) => reject(e));\n        });\n    }\n\n    /**\n     * Returns duration in ms\n     * @param {string} duration Duration to parse\n     */\n    static parseDuration(duration: string): number {\n        duration ??= \"0:00\";\n        const args = duration.split(\":\");\n        let dur = 0;\n\n        switch (args.length) {\n            case 3:\n                dur = parseInt(args[0]) * 60 * 60 * 1000 + parseInt(args[1]) * 60 * 1000 + parseInt(args[2]) * 1000;\n                break;\n            case 2:\n                dur = parseInt(args[0]) * 60 * 1000 + parseInt(args[1]) * 1000;\n                break;\n            default:\n                dur = parseInt(args[0]) * 1000;\n        }\n\n        return dur;\n    }\n\n    /**\n     * Parse items from html\n     * @param {string} html HTML\n     * @param options Options\n     */\n    static parseSearchResult(html: string, options?: ParseSearchInterface): (Video | Channel | Playlist)[] {\n        if (!html) throw new Error(\"Invalid raw data\");\n        if (!options) options = { type: \"video\", limit: 0 };\n        if (!options.type) options.type = \"video\";\n\n        let details = [];\n        let fetched = false;\n\n        // try to parse html\n        try {\n            let data = html.split(\"ytInitialData = JSON.parse('\")[1].split(\"');</script>\")[0];\n            html = data.replace(/\\\\x([0-9A-F]{2})/gi, (...items) => {\n                return String.fromCharCode(parseInt(items[1], 16));\n            });\n        } catch {\n            /* do nothing */\n        }\n\n        try {\n            details = JSON.parse(html.split('{\"itemSectionRenderer\":{\"contents\":')[html.split('{\"itemSectionRenderer\":{\"contents\":').length - 1].split(',\"continuations\":[{')[0]);\n            fetched = true;\n        } catch {\n            /* do nothing */\n        }\n\n        if (!fetched) {\n            try {\n                details = JSON.parse(html.split('{\"itemSectionRenderer\":')[html.split('{\"itemSectionRenderer\":').length - 1].split('},{\"continuationItemRenderer\":{')[0]).contents;\n                fetched = true;\n            } catch {\n                /* do nothing */\n            }\n        }\n\n        if (!fetched) return [];\n\n        return Formatter.formatSearchResult(details, options);\n    }\n\n    /**\n     * Parse channel from raw data\n     * @param {object} data Raw data to parse video from\n     */\n    static parseChannel(data?: any): Channel {\n        if (!data || !data.channelRenderer) return;\n        const badges = data.channelRenderer.ownerBadges as any[];\n        let url = `https://www.youtube.com${data.channelRenderer.navigationEndpoint.browseEndpoint.canonicalBaseUrl || data.channelRenderer.navigationEndpoint.commandMetadata.webCommandMetadata.url}`;\n        let res = new Channel({\n            id: data.channelRenderer.channelId,\n            name: data.channelRenderer.title.simpleText,\n            icon: data.channelRenderer.thumbnail.thumbnails[data.channelRenderer.thumbnail.thumbnails.length - 1],\n            url: url,\n            verified: !badges?.length ? false : badges.some((badge) => badge[\"verifiedBadge\"] || badge?.metadataBadgeRenderer?.style?.toLowerCase().includes(\"verified\")),\n            subscribers: data.channelRenderer.subscriberCountText.simpleText\n        });\n\n        return res;\n    }\n\n    /**\n     * Parse video from raw data\n     * @param {object} data Raw data to parse video from\n     */\n    static parseVideo(data?: any): Video {\n        if (!data || !data.videoRenderer) return;\n\n        const badge = data.videoRenderer.ownerBadges && data.videoRenderer.ownerBadges[0];\n        let res = new Video({\n            id: data.videoRenderer.videoId,\n            url: `https://www.youtube.com/watch?v=${data.videoRenderer.videoId}`,\n            title: data.videoRenderer.title.runs[0].text,\n            description: data.videoRenderer.descriptionSnippet && data.videoRenderer.descriptionSnippet.runs[0] ? data.videoRenderer.descriptionSnippet.runs[0].text : \"\",\n            duration: data.videoRenderer.lengthText ? Util.parseDuration(data.videoRenderer.lengthText.simpleText) : 0,\n            duration_raw: data.videoRenderer.lengthText ? data.videoRenderer.lengthText.simpleText : null,\n            thumbnail: {\n                id: data.videoRenderer.videoId,\n                url: data.videoRenderer.thumbnail.thumbnails[data.videoRenderer.thumbnail.thumbnails.length - 1].url,\n                height: data.videoRenderer.thumbnail.thumbnails[data.videoRenderer.thumbnail.thumbnails.length - 1].height,\n                width: data.videoRenderer.thumbnail.thumbnails[data.videoRenderer.thumbnail.thumbnails.length - 1].width\n            },\n            channel: {\n                id: data.videoRenderer.ownerText.runs[0].navigationEndpoint.browseEndpoint.browseId || null,\n                name: data.videoRenderer.ownerText.runs[0].text || null,\n                url: `https://www.youtube.com${data.videoRenderer.ownerText.runs[0].navigationEndpoint.browseEndpoint.canonicalBaseUrl || data.videoRenderer.ownerText.runs[0].navigationEndpoint.commandMetadata.webCommandMetadata.url}`,\n                icon: {\n                    url: data.videoRenderer.channelThumbnail?.thumbnails?.[0]?.url || data.videoRenderer.channelThumbnailSupportedRenderers?.channelThumbnailWithLinkRenderer?.thumbnail?.thumbnails?.[0]?.url,\n                    width: data.videoRenderer.channelThumbnail?.thumbnails?.[0]?.width || data.videoRenderer.channelThumbnailSupportedRenderers?.channelThumbnailWithLinkRenderer?.thumbnail?.thumbnails?.[0]?.width,\n                    height: data.videoRenderer.channelThumbnail?.thumbnails?.[0]?.height || data.videoRenderer.channelThumbnailSupportedRenderers?.channelThumbnailWithLinkRenderer?.thumbnail?.thumbnails?.[0]?.height\n                },\n                verified: Boolean(badge?.metadataBadgeRenderer?.style?.toLowerCase().includes(\"verified\"))\n            },\n            uploadedAt: data.videoRenderer.publishedTimeText?.simpleText ?? null,\n            views: data.videoRenderer.viewCountText?.simpleText?.replace(/[^0-9]/g, \"\") ?? 0\n        });\n\n        return res;\n    }\n\n    static parsePlaylist(data?: any): Playlist {\n        if (!data.playlistRenderer) return;\n\n        const res = new Playlist(\n            {\n                id: data.playlistRenderer.playlistId,\n                title: data.playlistRenderer.title.simpleText,\n                thumbnail: {\n                    id: data.playlistRenderer.playlistId,\n                    url: data.playlistRenderer.thumbnails[0].thumbnails[data.playlistRenderer.thumbnails[0].thumbnails.length - 1].url,\n                    height: data.playlistRenderer.thumbnails[0].thumbnails[data.playlistRenderer.thumbnails[0].thumbnails.length - 1].height,\n                    width: data.playlistRenderer.thumbnails[0].thumbnails[data.playlistRenderer.thumbnails[0].thumbnails.length - 1].width\n                },\n                channel: {\n                    id: data.playlistRenderer.shortBylineText.runs[0].navigationEndpoint.browseEndpoint.browseId,\n                    name: data.playlistRenderer.shortBylineText.runs[0].text,\n                    url: `https://www.youtube.com${data.playlistRenderer.shortBylineText.runs[0].navigationEndpoint.browseEndpoint?.canonicalBaseUrl || data.playlistRenderer.shortBylineText.runs[0].navigationEndpoint.commandMetadata?.webCommandMetadata?.url}`\n                },\n                videos: parseInt(data.playlistRenderer.videoCount.replace(/[^0-9]/g, \"\"))\n            },\n            true\n        );\n\n        return res;\n    }\n\n    static getPlaylistVideos(data: any, limit: number = Infinity) {\n        const videos = [];\n\n        for (let i = 0; i < data.length; i++) {\n            if (limit === videos.length) break;\n            const info = data[i].playlistVideoRenderer;\n            if (!info || !info.shortBylineText) continue; // skip unknown videos\n\n            videos.push(\n                new Video({\n                    id: info.videoId,\n                    index: parseInt(info.index?.simpleText) || 0,\n                    duration: Util.parseDuration(info.lengthText?.simpleText) || 0,\n                    duration_raw: info.lengthText?.simpleText ?? \"0:00\",\n                    thumbnail: {\n                        id: info.videoId,\n                        url: info.thumbnail.thumbnails[info.thumbnail.thumbnails.length - 1].url,\n                        height: info.thumbnail.thumbnails[info.thumbnail.thumbnails.length - 1].height,\n                        width: info.thumbnail.thumbnails[info.thumbnail.thumbnails.length - 1].width\n                    },\n                    title: info.title.runs[0].text,\n                    channel: {\n                        id: info.shortBylineText.runs[0].navigationEndpoint.browseEndpoint.browseId || null,\n                        name: info.shortBylineText.runs[0].text || null,\n                        url: `https://www.youtube.com${info.shortBylineText.runs[0].navigationEndpoint.browseEndpoint.canonicalBaseUrl || info.shortBylineText.runs[0].navigationEndpoint.commandMetadata.webCommandMetadata.url}`,\n                        icon: null\n                    }\n                })\n            );\n        }\n\n        return videos;\n    }\n\n    static getPlaylist(html: string, limit?: number): Playlist {\n        if (!limit || typeof limit !== \"number\") limit = 100;\n        if (limit <= 0) limit = Infinity;\n        let parsed;\n        let playlistDetails;\n        try {\n            const rawJSON = `${html.split('{\"playlistVideoListRenderer\":{\"contents\":')[1].split('}],\"playlistId\"')[0]}}]`;\n            parsed = JSON.parse(rawJSON);\n            playlistDetails = JSON.parse(html.split('{\"playlistSidebarRenderer\":')[1].split(\"}};</script>\")[0]).items;\n        } catch {\n            return null;\n        }\n        const API_KEY = html.split('INNERTUBE_API_KEY\":\"')[1]?.split('\"')[0] ?? html.split('innertubeApiKey\":\"')[1]?.split('\"')[0] ?? DEFAULT_INNERTUBE_KEY;\n        const videos = Util.getPlaylistVideos(parsed, limit);\n\n        const data = playlistDetails[0].playlistSidebarPrimaryInfoRenderer;\n\n        if (!data.title.runs || !data.title.runs.length) return null;\n        const author = playlistDetails[1]?.playlistSidebarSecondaryInfoRenderer.videoOwner;\n        const views = data.stats.length === 3 ? data.stats[1].simpleText.replace(/[^0-9]/g, \"\") : 0;\n        const lastUpdate = data.stats.find((x: any) => \"runs\" in x && x[\"runs\"].find((y: any) => y.text.toLowerCase().includes(\"last update\")))?.runs.pop()?.text ?? null;\n        const videosCount = data.stats[0].runs[0].text.replace(/[^0-9]/g, \"\") || 0;\n\n        const res = new Playlist({\n            continuation: {\n                api: API_KEY,\n                token: Util.getContinuationToken(parsed),\n                clientVersion: html.split('\"INNERTUBE_CONTEXT_CLIENT_VERSION\":\"')[1]?.split('\"')[0] ?? html.split('\"innertube_context_client_version\":\"')[1]?.split('\"')[0] ?? \"<some version>\"\n            },\n            id: data.title.runs[0].navigationEndpoint.watchEndpoint.playlistId,\n            title: data.title.runs[0].text,\n            videoCount: parseInt(videosCount) || 0,\n            lastUpdate: lastUpdate,\n            views: parseInt(views) || 0,\n            videos: videos,\n            url: `https://www.youtube.com/playlist?list=${data.title.runs[0].navigationEndpoint.watchEndpoint.playlistId}`,\n            link: `https://www.youtube.com${data.title.runs[0].navigationEndpoint.commandMetadata.webCommandMetadata.url}`,\n            author: author\n                ? {\n                      name: author.videoOwnerRenderer.title.runs[0].text,\n                      id: author.videoOwnerRenderer.title.runs[0].navigationEndpoint.browseEndpoint.browseId,\n                      url: `https://www.youtube.com${author.videoOwnerRenderer.navigationEndpoint.commandMetadata.webCommandMetadata.url || author.videoOwnerRenderer.navigationEndpoint.browseEndpoint.canonicalBaseUrl}`,\n                      icon: author.videoOwnerRenderer.thumbnail.thumbnails.length ? author.videoOwnerRenderer.thumbnail.thumbnails.pop()?.url : null\n                  }\n                : {},\n            thumbnail: data.thumbnailRenderer.playlistVideoThumbnailRenderer?.thumbnail.thumbnails.length ? data.thumbnailRenderer.playlistVideoThumbnailRenderer.thumbnail.thumbnails.pop() : null\n        });\n\n        return res;\n    }\n\n    static getContinuationToken(ctx: any): string {\n        const continuationToken = ctx.find((x: any) => Object.keys(x)[0] === \"continuationItemRenderer\")?.continuationItemRenderer.continuationEndpoint?.continuationCommand?.token;\n        return continuationToken;\n    }\n\n    static getVideo(html: string) {\n        let data,\n            nextData = {};\n\n        try {\n            const parsed = JSON.parse(html.split(\"var ytInitialData = \")[1].split(\";</script>\")[0]);\n            data = parsed.contents.twoColumnWatchNextResults.results.results.contents;\n\n            try {\n                nextData = parsed.contents.twoColumnWatchNextResults.secondaryResults.secondaryResults.results;\n            } catch {}\n        } catch {\n            throw new Error(\"Could not parse video metadata!\");\n        }\n\n        const raw = {\n            primary: data?.find((section: any) => \"videoPrimaryInfoRenderer\" in section)?.videoPrimaryInfoRenderer || {},\n            secondary: data?.find((section: any) => \"videoSecondaryInfoRenderer\" in section)?.videoSecondaryInfoRenderer || {}\n        };\n\n        let info: any;\n\n        try {\n            info = JSON.parse(html.split(\"var ytInitialPlayerResponse = \")[1].split(\";</script>\")[0]);\n        } catch {\n            info = JSON.parse(html.split(\"var ytInitialPlayerResponse = \")[1].split(\";var\")[0]);\n        }\n\n        if (!info?.videoDetails) return null;\n\n        info = {\n            ...raw.primary,\n            ...raw.secondary,\n            info\n        };\n\n        // Get music info if there are any\n        let musicInfo: MusicInfo[] = [];\n\n        try {\n            const jsonData = html.split('{\"horizontalCardListRenderer\":')[1].split(',{\"reelShelfRenderer\"')[0];\n\n            musicInfo = JSON.parse('{\"horizontalCardListRenderer\":' + jsonData).horizontalCardListRenderer.cards.map((val: any) => {\n                return {\n                    title: val.videoAttributeViewModel.title,\n                    cover: val.videoAttributeViewModel.image.sources[0].url,\n                    artist: val.videoAttributeViewModel.subtitle,\n                    album: val.videoAttributeViewModel.secondarySubtitle.content\n                };\n            });\n        } catch {\n            musicInfo = [];\n        }\n\n        const payload = new Video({\n            id: info.info.videoDetails.videoId,\n            title: info.info.videoDetails.title,\n            views: parseInt(info.info.videoDetails.viewCount) || 0,\n            tags: info.info.videoDetails.keywords,\n            private: info.info.videoDetails.isPrivate,\n            unlisted: !!info.info.microformat?.playerMicroformatRenderer?.isUnlisted,\n            nsfw: info.info.microformat?.playerMicroformatRenderer?.isFamilySafe === false,\n            live: info.info.videoDetails.isLiveContent,\n            duration: parseInt(info.info.videoDetails.lengthSeconds) * 1000,\n            shorts: [`{\"webCommandMetadata\":{\"url\":\"/shorts/${info.info.videoDetails.videoId}\"`, `{window['ytPageType'] = \"shorts\";`, `\"/hashtag/shorts\"`].some((r) => html.includes(r)),\n            duration_raw: Util.durationString(Util.parseMS(parseInt(info.info.videoDetails.lengthSeconds) * 1000 || 0)),\n            channel: {\n                name: info.info.videoDetails.author,\n                id: info.info.videoDetails.channelId,\n                url: `https://www.youtube.com${info.owner.videoOwnerRenderer.title.runs[0].navigationEndpoint.browseEndpoint.canonicalBaseUrl}`,\n                icon: info.owner.videoOwnerRenderer.thumbnail.thumbnails[0],\n                subscribers: info.owner.videoOwnerRenderer.subscriberCountText?.simpleText?.replace(\" subscribers\", \"\")\n            },\n            description: info.info.videoDetails.shortDescription,\n            thumbnail: {\n                ...info.info.videoDetails.thumbnail.thumbnails[info.info.videoDetails.thumbnail.thumbnails.length - 1],\n                id: info.info.videoDetails.videoId\n            },\n            uploadedAt: info.dateText.simpleText,\n            ratings: {\n                likes: this.getInfoLikesCount(info) || 0,\n                dislikes: 0\n            },\n            videos: Util.getNext(nextData ?? {}) || [],\n            streamingData: info.info.streamingData || null,\n            music: musicInfo\n        });\n\n        return payload;\n    }\n\n    static getInfoLikesCount(info: Record<string, any>) {\n        const buttons = info.videoActions.menuRenderer.topLevelButtons as any[];\n        const button = buttons.find((button) => button.toggleButtonRenderer?.defaultIcon.iconType === \"LIKE\");\n        if (!button) return 0;\n\n        return parseInt(button.toggleButtonRenderer.defaultText.accessibility?.accessibilityData.label.split(\" \")[0].replace(/,/g, \"\"));\n    }\n\n    static getNext(body: any, home = false): Video[] {\n        const results: Video[] = [];\n        if (typeof body[Symbol.iterator] !== \"function\") return results;\n\n        for (const result of body) {\n            const details = home ? result : result.compactVideoRenderer;\n\n            if (details) {\n                try {\n                    let viewCount = details.viewCountText.simpleText;\n                    viewCount = (/^\\d/.test(viewCount) ? viewCount : \"0\").split(\" \")[0];\n\n                    results.push(\n                        new Video({\n                            id: details.videoId,\n                            title: details.title.simpleText ?? details.title.runs[0]?.text,\n                            views: parseInt(viewCount.replace(/,/g, \"\")) || 0,\n                            duration_raw: details.lengthText.simpleText ?? details.lengthText.accessibility.accessibilityData.label,\n                            duration: Util.parseDuration(details.lengthText.simpleText) / 1000,\n                            channel: {\n                                name: details.shortBylineText.runs[0].text,\n                                id: details.shortBylineText.runs[0].navigationEndpoint.browseEndpoint.browseId,\n                                url: `https://www.youtube.com${details.shortBylineText.runs[0].navigationEndpoint.browseEndpoint.canonicalBaseUrl}`,\n                                icon: home ? details.channelThumbnailSupportedRenderers.channelThumbnailWithLinkRenderer.thumbnail.thumbnails[0] : details.channelThumbnail.thumbnails[0],\n                                subscribers: \"0\",\n                                verified: Boolean(details.ownerBadges[0].metadataBadgeRenderer.tooltip === \"Verified\")\n                            },\n                            thumbnail: {\n                                ...details.thumbnail.thumbnails[details.thumbnail.thumbnails.length - 1],\n                                id: details.videoId\n                            },\n                            uploadedAt: details.publishedTimeText.simpleText,\n                            ratings: {\n                                likes: 0,\n                                dislikes: 0\n                            },\n                            description: details.descriptionSnippet?.runs[0]?.text\n                        })\n                    );\n                } catch {\n                    continue;\n                }\n            }\n        }\n\n        return results;\n    }\n\n    static getMix(html: string): Playlist {\n        let data = null;\n\n        try {\n            const parsed = JSON.parse(html.split(\"var ytInitialData = \")[1].split(\";</script>\")[0]);\n            data = parsed.contents.twoColumnWatchNextResults.playlist.playlist;\n        } catch {}\n\n        if (!data) return null;\n\n        const videos = data.contents.map((m: any) => {\n            const t = m.playlistPanelVideoRenderer;\n\n            return new Video({\n                id: t.videoId,\n                title: t.title.simpleText,\n                thumbnail: {\n                    id: t.videoId,\n                    url: t.thumbnail.thumbnails[t.thumbnail.thumbnails.length - 1].url,\n                    height: t.thumbnail.thumbnails[t.thumbnail.thumbnails.length - 1].height,\n                    width: t.thumbnail.thumbnails[t.thumbnail.thumbnails.length - 1].width\n                },\n                duration: Util.parseDuration(t.lengthText.simpleText),\n                duration_raw: t.lengthText.simpleText,\n                channel: {\n                    name: t.shortBylineText.runs[0].text,\n                    id: t.shortBylineText.runs[0].navigationEndpoint.browseEndpoint.browseId,\n                    url: `https://www.youtube.com${t.shortBylineText.runs[0].navigationEndpoint.browseEndpoint.canonicalBaseUrl}`,\n                    icon: null\n                }\n            });\n        });\n        const list = new Playlist(\n            {\n                id: data.playlistId,\n                title: data.title,\n                videoCount: data.contents.length,\n                videos,\n                link: data.playlistShareUrl,\n                url: data.playlistShareUrl,\n                thumbnail: videos[0]?.thumbnail?.toJSON() || null,\n                channel: {\n                    name: data.ownerName.simpleText\n                },\n                mix: true\n            },\n            true\n        );\n\n        return list;\n    }\n\n    static parseHomepage(html: string): Video[] {\n        let contents: any;\n\n        try {\n            contents = html.split(\"var ytInitialData = \")[1].split(\";</script>\")[0];\n            contents = JSON.parse(contents).contents.twoColumnBrowseResultsRenderer.tabs[0].tabRenderer.content.richGridRenderer.contents;\n        } catch {\n            return [];\n        }\n\n        if (!contents || !contents.length || !contents.find((x: any) => Object.keys(x)[0] === \"richItemRenderer\")) return [];\n        contents = contents.filter((a: any) => Object.keys(a)[0] === \"richItemRenderer\").map((m: any) => m.richItemRenderer.content.videoRenderer);\n\n        return Util.getNext(contents, true);\n    }\n\n    static getPlaylistURL(url: string): { url: string; mix: boolean } | null {\n        if (typeof url !== \"string\") return null;\n        const group = PLAYLIST_ID.exec(url) || ALBUM_REGEX.exec(url);\n        if (!group) return null;\n        // mix\n        if (group[0].startsWith(\"RD\") && !ALBUM_REGEX.exec(group[0])) return { url, mix: true };\n        const finalURL = `https://www.youtube.com/playlist?list=${group[0]}`;\n        return { url: finalURL, mix: false };\n    }\n\n    static validatePlaylist(url: string): void {\n        if (typeof url === \"string\" && (url.match(PLAYLIST_ID) !== null || url.match(ALBUM_REGEX) !== null)) return;\n        throw new Error(\"Invalid playlist url\");\n    }\n\n    static filter(ftype: string): string {\n        switch (ftype) {\n            case \"playlist\":\n                return \"EgIQAw%253D%253D\";\n            case \"video\":\n                return \"EgIQAQ%253D%253D\";\n            case \"channel\":\n                return \"EgIQAg%253D%253D\";\n            case \"film\":\n                return \"EgIQBA%253D%253D\";\n            default:\n                throw new TypeError(`Invalid filter type \"${ftype}\"!`);\n        }\n    }\n\n    static parseMS(milliseconds: number) {\n        return {\n            days: Math.trunc(milliseconds / 86400000),\n            hours: Math.trunc(milliseconds / 3600000) % 24,\n            minutes: Math.trunc(milliseconds / 60000) % 60,\n            seconds: Math.trunc(milliseconds / 1000) % 60\n        };\n    }\n\n    static durationString(data: any): string {\n        const items = Object.keys(data);\n        const required = [\"days\", \"hours\", \"minutes\", \"seconds\"];\n\n        const parsed = items.filter((x) => required.includes(x)).map((m) => (data[m] > 0 ? data[m] : \"\"));\n        const final = parsed\n            .slice(parsed.findIndex((x) => !!x))\n            .map((x, i) => (i == 0 ? x.toString() : x.toString().padStart(2, \"0\")))\n            .join(\":\");\n        return final.length <= 3 ? `0:${final.padStart(2, \"0\") || 0}` : final;\n    }\n\n    static json(data: string) {\n        try {\n            return JSON.parse(data);\n        } catch {\n            return null;\n        }\n    }\n\n    static async makeRequest(url = \"\", data: any = { data: {}, requestOptions: {} }) {\n        const key = await Util.innertubeKey();\n        const res = await Util.getHTML(`https://youtube.com/youtubei/v1${url}?key=${key}`, {\n            method: \"POST\",\n            headers: {\n                \"Content-Type\": \"application/json\",\n                Host: \"www.youtube.com\",\n                Referer: \"https://www.youtube.com\"\n            },\n            body: JSON.stringify({\n                context: {\n                    client: {\n                        utcOffsetMinutes: 0,\n                        gl: \"US\",\n                        hl: \"en\",\n                        clientName: \"WEB\",\n                        clientVersion: \"1.20220406.00.00\",\n                        originalUrl: \"https://www.youtube.com/\",\n                        ...(data.clientCtx || {})\n                    },\n                    ...(data.ctx || {})\n                },\n                ...(data.data || {})\n            }),\n            ...(data.requestOptions || {})\n        });\n        return Util.json(res);\n    }\n}\n\nexport default Util;\n","/*\n * MIT License\n *\n * Copyright (c) 2020 twlite\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport Util from \"./Util\";\nimport { Channel, Video, Playlist } from \"./Structures/exports\";\nimport { Formatter } from \"./formatter\";\n\nconst SAFE_SEARCH_COOKIE = \"PREF=f2=8000000\";\n\nexport interface SearchOptions {\n    limit?: number;\n    type?: \"video\" | \"channel\" | \"playlist\" | \"all\" | \"film\";\n    requestOptions?: RequestInit;\n    safeSearch?: boolean;\n}\n\nexport interface TrendingParseOptions {\n    type?: keyof typeof TrendingFilter | \"ALL\";\n}\n\nexport interface PlaylistOptions {\n    limit?: number;\n    requestOptions?: RequestInit;\n    fetchAll?: boolean;\n}\n\nexport const TrendingFilter = {\n    MUSIC: \"4gINGgt5dG1hX2NoYXJ0cw%3D%3D\",\n    GAMING: \"4gIcGhpnYW1pbmdfY29ycHVzX21vc3RfcG9wdWxhcg%3D%3D\",\n    MOVIES: \"4gIKGgh0cmFpbGVycw%3D%3D\"\n};\n\nclass YouTube {\n    constructor() {\n        return YouTube;\n    }\n\n    /**\n     * Search\n     * @param {string} query Search youtube\n     * @param {object} options Search options\n     * @param {number} [options.limit=20] Limit\n     * @param {\"video\"|\"channel\"|\"playlist\"|\"all\"|\"film\"} options.type Type\n     * @param {RequestInit} [options.requestOptions] Request options\n     * @param {boolean} [options.safeSearch] Safe search filter\n     */\n    static async search(query: string, options?: SearchOptions & { type: \"video\" }): Promise<Video[]>;\n    static async search(query: string, options?: SearchOptions & { type: \"film\" }): Promise<Video[]>;\n    static async search(query: string, options?: SearchOptions & { type: \"channel\" }): Promise<Channel[]>;\n    static async search(query: string, options?: SearchOptions & { type: \"playlist\" }): Promise<Playlist[]>;\n    static async search(query: string, options?: SearchOptions & { type: \"all\" }): Promise<(Video | Channel | Playlist)[]>;\n    static async search(query: string, options?: SearchOptions): Promise<(Video | Channel | Playlist)[]> {\n        if (!options) options = { limit: 100, type: \"video\", requestOptions: {} };\n        if (!query || typeof query !== \"string\") throw new Error(`Invalid search query \"${query}\"!`);\n        options.type = options.type || \"video\";\n\n        const requestOptions = options.safeSearch ? { ...options.requestOptions, headers: { cookie: SAFE_SEARCH_COOKIE } } : {};\n\n        try {\n            const filter = options.type === \"all\" ? null : Util.filter(options.type);\n            const res = await Util.makeRequest(\"/search\", {\n                data: {\n                    params: filter,\n                    query\n                },\n                clientCtx: {\n                    originalUrl: `https://youtube.com/results?search_query=${encodeURIComponent(query.trim()).replace(/%20/g, \"+\")}${filter}`\n                },\n                requestOptions\n            });\n            return Formatter.formatSearchResult(res.contents.twoColumnSearchResultsRenderer.primaryContents.sectionListRenderer.contents[0].itemSectionRenderer.contents, options);\n        } catch {\n            // fallback\n            const filter = options.type === \"all\" ? \"\" : `&sp=${Util.filter(options.type)}`;\n\n            const url = `https://youtube.com/results?search_query=${encodeURIComponent(query.trim()).replace(/%20/g, \"+\")}&hl=en${filter}`;\n\n            const html = await Util.getHTML(url, requestOptions);\n            return Util.parseSearchResult(html, options);\n        }\n    }\n\n    /**\n     * Search one\n     * @param {string} query Search query\n     * @param {\"video\"|\"channel\"|\"playlist\"|\"all\"|\"film\"} type Search type\n     * @param {boolean} safeSearch Safe search filter\n     * @param {RequestInit} requestOptions Request options\n     */\n    static searchOne(query: string, type?: \"video\", safeSearch?: boolean, requestOptions?: RequestInit): Promise<Video>;\n    static searchOne(query: string, type?: \"film\", safeSearch?: boolean, requestOptions?: RequestInit): Promise<Video>;\n    static searchOne(query: string, type?: \"channel\", safeSearch?: boolean, requestOptions?: RequestInit): Promise<Channel>;\n    static searchOne(query: string, type?: \"playlist\", safeSearch?: boolean, requestOptions?: RequestInit): Promise<Playlist>;\n    static searchOne(query: string, type?: \"video\" | \"channel\" | \"film\" | \"playlist\" | \"all\", safeSearch?: boolean, requestOptions?: RequestInit): Promise<Video | Channel | Playlist> {\n        if (!type) type = \"video\";\n        return new Promise((resolve) => {\n            // @ts-ignore\n            YouTube.search(query, { limit: 1, type: type, requestOptions: requestOptions, safeSearch: Boolean(safeSearch) })\n                .then((res) => {\n                    if (!res || !res.length) return resolve(null);\n                    resolve(res[0]);\n                })\n                .catch(() => {\n                    resolve(null);\n                });\n        });\n    }\n\n    /**\n     * Returns playlist details\n     * @param {string} url Playlist URL\n     * @param {object} [options] Options\n     * @param {number} [options.limit=100] Playlist video limit\n     * @param {RequestInit} [options.requestOptions] Request Options\n     */\n    static async getPlaylist(url: string, options?: PlaylistOptions): Promise<Playlist> {\n        if (!options) options = { limit: 100, requestOptions: {}, fetchAll: false };\n        if (!url || typeof url !== \"string\") throw new Error(`Expected playlist url, received ${typeof url}!`);\n        Util.validatePlaylist(url);\n        const resolved = Util.getPlaylistURL(url);\n        if (!resolved) return null;\n        url = resolved.url;\n        const html = await Util.getHTML(`${url}&hl=en`, options && options.requestOptions);\n        const res = resolved.mix ? Util.getMix(html) : Util.getPlaylist(html, options && options.limit);\n\n        // fallback\n        try {\n            if (!res && resolved.mix) {\n                const videoId = new URL(url).searchParams.get(\"v\");\n                if (videoId) {\n                    const vid: Video = await YouTube.getVideo(`https://www.youtube.com/watch?v=${videoId}`).catch((): any => null);\n                    if (vid) {\n                        // return fake playlist when mix could not be parsed\n                        return new Playlist(\n                            {\n                                id: vid.id,\n                                title: `Mix - ${vid.title}`,\n                                videoCount: 1,\n                                lastUpdate: null,\n                                views: vid.views,\n                                url: `https://www.youtube.com/watch?v=${vid.id}`,\n                                link: `https://www.youtube.com/watch?v=${vid.id}`,\n                                channel: {\n                                    name: \"youtube-sr\"\n                                },\n                                thumbnail: vid.thumbnail?.toJSON() || null,\n                                videos: [vid],\n                                mix: true,\n                                fake: true\n                            },\n                            true\n                        );\n                    }\n                }\n            }\n        } catch {\n            //\n        }\n\n        if (res && res instanceof Playlist && options.fetchAll) {\n            return await res.fetch(options && options.limit).catch(() => res);\n        }\n\n        return res;\n    }\n\n    /**\n     * Returns basic video info\n     * @param url Video url to parse\n     * @param requestOptions Request options\n     */\n    static async getVideo(url: string | Video, requestOptions?: RequestInit): Promise<Video> {\n        if (!url) throw new Error(\"Missing video url\");\n        if (url instanceof Video) url = url.url;\n        const isValid = YouTube.validate(url, \"VIDEO\");\n        if (!isValid) throw new Error(\"Invalid video url\");\n\n        const html = await Util.getHTML(`${url}&hl=en`, requestOptions);\n        return Util.getVideo(html);\n    }\n\n    /**\n     * Fetches homepage videos\n     */\n    static async homepage(): Promise<Video[]> {\n        const html = await Util.getHTML(\"https://www.youtube.com?hl=en\");\n        return Util.parseHomepage(html);\n    }\n\n    /**\n     * Attempts to parse `INNERTUBE_API_KEY`\n     */\n    static async fetchInnerTubeKey() {\n        return Util.fetchInnerTubeKey();\n    }\n\n    static async trending(options?: TrendingParseOptions): Promise<Video[]> {\n        const type = TrendingFilter[options?.type as keyof typeof TrendingFilter];\n\n        const html = await Util.getHTML(`https://www.youtube.com/feed/trending?${type ? \"bp=\" + type + \"&hl=en\" : \"hl=en\"}`);\n        let json;\n\n        try {\n            json = JSON.parse(html.split(\"var ytInitialData =\")[1].split(\";</script>\")[0]);\n        } catch {\n            return [];\n        }\n\n        const content = json.contents?.twoColumnBrowseResultsRenderer?.tabs[0].tabRenderer?.content?.sectionListRenderer?.contents[1]?.itemSectionRenderer?.contents[0]?.shelfRenderer?.content?.expandedShelfContentsRenderer?.items;\n        if (!content || !Array.isArray(content)) return [];\n\n        const res: Video[] = [];\n\n        for (const item of content.map((m) => m.videoRenderer)) {\n            res.push(\n                new Video({\n                    title: item.title.runs[0].text,\n                    id: item.videoId,\n                    url: `https://www.youtube.com/watch?v=${item.videoId}`,\n                    description: item.descriptionSnippet?.runs[0]?.text,\n                    duration: Util.parseDuration(item.lengthText.simpleText) / 1000 || 0,\n                    duration_raw: item.lengthText.simpleText,\n                    shorts: item.thumbnailOverlays?.some((res: any) => res.thumbnailOverlayTimeStatusRenderer?.style === \"SHORTS\"),\n                    thumbnail: {\n                        id: item.videoId,\n                        url: item.thumbnail.thumbnails[item.thumbnail.thumbnails.length - 1].url,\n                        height: item.thumbnail.thumbnails[item.thumbnail.thumbnails.length - 1].height,\n                        width: item.thumbnail.thumbnails[item.thumbnail.thumbnails.length - 1].width\n                    },\n                    channel: {\n                        id: item.ownerText.runs[0].navigationEndpoint.browseEndpoint.browseId,\n                        name: item.ownerText.runs[0].text,\n                        url: `https://www.youtube.com${item.ownerText.runs[0].navigationEndpoint.browseEndpoint.canonicalBaseUrl}`,\n                        icon: {\n                            url: null,\n                            width: 0,\n                            height: 0\n                        },\n                        verified: item.ownerBadges ? item.ownerBadges[0].metadataBadgeRenderer.tooltip === \"Verified\" : false\n                    },\n                    uploadedAt: item.publishedTimeText.simpleText,\n                    views: item.viewCountText.simpleText.replace(/[^0-9]/g, \"\") || 0\n                })\n            );\n        }\n\n        return res;\n    }\n\n    static async getSuggestions(query: string) {\n        if (!query) throw new Error(\"Search query was not provided!\");\n\n        try {\n            const res = await Util.getHTML(`https://suggestqueries-clients6.youtube.com/complete/search?client=youtube&gs_ri=youtube&ds=yt&q=${encodeURIComponent(query)}`);\n            const partition = res.split(\"window.google.ac.h(\")[1];\n            const data = Util.json(partition.slice(0, partition.length - 1)) as any[][];\n            return data[1].map((m) => m[0]);\n        } catch {\n            const res = await Util.getHTML(`https://clients1.google.com/complete/search?client=youtube&gs_ri=youtube&ds=yt&q=${encodeURIComponent(query)}`);\n            const searchSuggestions: string[] = [];\n            res.split(\"[\").forEach((ele, index) => {\n                if (!ele.split('\"')[1] || index === 1) return;\n                return searchSuggestions.push(ele.split('\"')[1]);\n            });\n\n            searchSuggestions.pop();\n            return searchSuggestions;\n        }\n    }\n\n    /**\n     * Validates playlist\n     * @param {string} url Playlist id or url/video id or url to validate\n     * @param {\"VIDEO\"|\"VIDEO_ID\"|\"PLAYLIST\"|\"PLAYLIST_ID\"} type URL validation type\n     * @returns {boolean}\n     */\n    static validate(url: string, type?: \"VIDEO\" | \"VIDEO_ID\" | \"PLAYLIST\" | \"PLAYLIST_ID\"): boolean {\n        if (typeof url !== \"string\") return false;\n        if (!type) type = \"PLAYLIST\";\n        switch (type) {\n            case \"PLAYLIST\":\n                return YouTube.Regex.PLAYLIST_URL.test(url);\n            case \"PLAYLIST_ID\":\n                return YouTube.Regex.PLAYLIST_ID.test(url) || YouTube.Regex.ALBUM.test(url);\n            case \"VIDEO\":\n                return YouTube.Regex.VIDEO_URL.test(url);\n            case \"VIDEO_ID\":\n                return YouTube.Regex.VIDEO_ID.test(url);\n            default:\n                return false;\n        }\n    }\n\n    static isPlaylist(src: string) {\n        try {\n            Util.validatePlaylist(src);\n            return true;\n        } catch {\n            return false;\n        }\n    }\n\n    static get Regex() {\n        return {\n            PLAYLIST_URL: Util.PlaylistURLRegex,\n            PLAYLIST_ID: Util.PlaylistIDRegex,\n            ALBUM: Util.AlbumRegex,\n            VIDEO_ID: Util.VideoIDRegex,\n            VIDEO_URL: Util.VideoRegex\n        };\n    }\n}\n\nexport { Util, YouTube, Formatter, SAFE_SEARCH_COOKIE };\n\nexport * from \"./Structures/exports\";\n\nexport default YouTube;\n"],"mappings":"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","names":["button","_a","res","_a"]}