{"version":3,"sources":["jsdelivr-header.js","/npm/discord-player@7.2.0/src/index.ts","/npm/discord-player@7.2.0/src/compat/createErisCompat.ts","/npm/discord-player@7.2.0/src/compat/common.ts","/npm/discord-player@7.2.0/src/utils/Util.ts","/npm/discord-player@7.2.0/src/fabric/Track.ts","/npm/discord-player@7.2.0/src/errors/index.ts","/npm/discord-player@7.2.0/src/utils/TypeUtil.ts","/npm/discord-player@7.2.0/src/utils/serde.ts","/npm/discord-player@7.2.0/src/fabric/Playlist.ts","/npm/discord-player@7.2.0/src/utils/QueryResolver.ts","/npm/discord-player@7.2.0/src/fabric/SearchResult.ts","/npm/discord-player@7.2.0/src/utils/AudioFilters.ts","/npm/discord-player@7.2.0/src/compat/createOceanicCompat.ts","/npm/discord-player@7.2.0/src/utils/PlayerEventsEmitter.ts","/npm/discord-player@7.2.0/src/extractors/BaseExtractor.ts","/npm/discord-player@7.2.0/src/extractors/ExtractorExecutionContext.ts","/npm/discord-player@7.2.0/src/hooks/context/async-context.ts","/npm/discord-player@7.2.0/src/utils/__internal__/_container.ts","/npm/discord-player@7.2.0/src/utils/__internal__/getGlobalRegistry.ts","/npm/discord-player@7.2.0/src/hooks/common.ts","/npm/discord-player@7.2.0/src/hooks/useHistory.ts","/npm/discord-player@7.2.0/src/hooks/usePlayer.ts","/npm/discord-player@7.2.0/src/hooks/useQueue.ts","/npm/discord-player@7.2.0/src/hooks/useMainPlayer.ts","/npm/discord-player@7.2.0/src/hooks/useMetadata.ts","/npm/discord-player@7.2.0/src/hooks/useTimeline.ts","/npm/discord-player@7.2.0/src/hooks/stream/onAfterCreateStream.ts","/npm/discord-player@7.2.0/src/hooks/stream/onBeforeCreateStream.ts","/npm/discord-player@7.2.0/src/hooks/stream/onStreamExtracted.ts","/npm/discord-player@7.2.0/src/hooks/useVolume.ts","/npm/discord-player@7.2.0/src/stream/InterceptedStream.ts","/npm/discord-player@7.2.0/src/queue/GuildNodeManager.ts","/npm/discord-player@7.2.0/src/queue/GuildQueue.ts","/npm/discord-player@7.2.0/src/stream/StreamDispatcher.ts","/npm/discord-player@7.2.0/src/queue/GuildQueueHistory.ts","/npm/discord-player@7.2.0/src/queue/GuildQueuePlayerNode.ts","/npm/discord-player@7.2.0/src/utils/AsyncQueue.ts","/npm/discord-player@7.2.0/src/queue/GuildQueueAudioFilters.ts","/npm/discord-player@7.2.0/src/utils/FFmpegStream.ts","/npm/discord-player@7.2.0/src/queue/GuildQueueStatistics.ts","/npm/discord-player@7.2.0/src/queue/SyncedLyricsProvider.ts","/npm/discord-player@7.2.0/src/utils/SequentialBucket.ts","/npm/discord-player@7.2.0/src/lrclib/LrcLib.ts","/npm/discord-player@7.2.0/src/stream/VoiceUtils.ts","/npm/discord-player@7.2.0/src/utils/QueryCache.ts","/npm/discord-player@7.2.0/src/Player.ts","/npm/discord-player@7.2.0/src/DefaultVoiceStateHandler.ts","/npm/discord-player@7.2.0/src/utils/DependencyReportGenerator.ts","/npm/discord-player@7.2.0/src/PlayerStreamInterceptor.ts","/npm/discord-player@7.2.0/src/version.ts"],"names":[],"mappings":"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","file":"/npm/discord-player@7.2.0/dist/index.js","sourceRoot":"","sourcesContent":["/**\n * Minified by jsDelivr using Terser v5.39.0.\n * Original file: /npm/discord-player@7.2.0/dist/index.js\n *\n * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files\n */\n","export { createErisCompat } from './compat/createErisCompat';\nexport { createOceanicCompat } from './compat/createOceanicCompat';\nexport { isErisProxy, isOceanicProxy } from './compat/common';\nexport * from './utils/PlayerEventsEmitter';\nexport * from './utils/AudioFilters';\nexport * from './extractors/BaseExtractor';\nexport * from './extractors/ExtractorExecutionContext';\nexport * from './fabric';\nexport * from './queue';\nexport * from './lrclib/LrcLib';\nexport * from './utils/SequentialBucket';\nexport * from './stream/VoiceUtils';\nexport * from './stream/StreamDispatcher';\nexport * from './utils/Util';\nexport * from './utils/TypeUtil';\nexport * from './utils/AsyncQueue';\nexport * from './utils/FFmpegStream';\nexport * from './utils/QueryCache';\nexport * from './utils/QueryResolver';\nexport * from '@discord-player/ffmpeg';\nexport * from './Player';\nexport * from './hooks';\nexport * from './utils/serde';\nexport * from './utils/DependencyReportGenerator';\nexport * from './stream/InterceptedStream';\nexport * from './PlayerStreamInterceptor';\nexport {\n  AudioFilters as PCMAudioFilters,\n  type BiquadFilters,\n  FilterType as BiquadFilterType,\n  type PCMFilters,\n  Q_BUTTERWORTH,\n  VolumeTransformer,\n  BASS_EQ_BANDS,\n  AF_NIGHTCORE_RATE,\n  AF_VAPORWAVE_RATE,\n  FiltersChain } from\n'@discord-player/equalizer';\nexport {\n  createAudioPlayer,\n  AudioPlayer,\n  getVoiceConnection,\n  getVoiceConnections,\n  joinVoiceChannel,\n  StreamType,\n  createAudioResource,\n  type JoinConfig,\n  type JoinVoiceChannelOptions,\n  type CreateAudioPlayerOptions } from\n'discord-voip';\n\nexport { version } from './version';","/* eslint-disable @typescript-eslint/no-explicit-any */\n// @ts-nocheck\n\nimport { ChannelType, GatewayDispatchEvents } from 'discord-api-types/v10';\nimport { createCompatClient } from './common';\nimport { Util } from '../utils/Util';\n\nimport type { DiscordGatewayAdapterCreator } from 'discord-voip';\nimport {\n  Client,\n  GatewayVoiceServerUpdateDispatchData,\n  GatewayVoiceStateUpdateDispatchData,\n  VoiceState } from\n'discord.js';\nimport type Eris from 'eris';\n\ntype ErisUserResolvable = Eris.User | string | Eris.Member;\ntype ErisGuildResolvable =\nEris.Guild |\nstring |\nEris.Member |\nEris.GuildChannel |\nEris.Role;\ntype ErisChannelResolvable = Eris.GuildChannel | string;\n\nconst DiscordPlayerClientSymbol = Symbol('DiscordPlayerClient');\n\nexport function isErisClient(client: any): client is Eris.Client {\n  const { module, error } = Util.require('eris');\n\n  if (error) return false;\n\n  const eris = module as typeof import('eris');\n\n  return client instanceof eris.Client;\n}\n\nfunction declareProperty(target: any, key: string, value: any) {\n  Reflect.set(target, key, value);\n}\n\nfunction getProperty<T>(target: any, key: string): T {\n  return Reflect.get(target, key);\n}\n\n/**\n * Allows Eris clients to be used with discord-player. When this method is called, discord-player creates a proxy object that intercepts certain methods and properties to make it compatible with discord-player.\n * @param client The Eris client to be used.\n * @returns The Eris client with discord-player compatibility.\n */\nexport function createErisCompat(client: Eris.Client): Client {\n  const { module, error } = Util.require('eris');\n\n  if (error) throw error;\n\n  const eris = module as typeof import('eris');\n\n  erisVoiceEventsHandler(client);\n\n  const erisProxy = new Proxy(client, {\n    get(target, p) {\n      switch (p) {\n        case 'users':\n          return erisUsersProxy(target, eris);\n        case 'guilds':\n          return erisGuildsProxy(target, eris);\n        case 'channels':\n          return erisChannelsProxy(target, eris);\n        case '__dp_voiceStateUpdate_proxy':\n          return (handler: (a, b) => void) =>\n          erisVoiceStateUpdateProxy(target, erisProxy, handler);\n        case 'incrementMaxListeners':\n          return () => {\n            // @ts-expect-error patching\n            client.setMaxListeners(client.getMaxListeners() + 1);\n          };\n        case 'decrementMaxListeners':\n          return () => {\n            // @ts-expect-error patching\n            const listeners = client.getMaxListeners() - 1;\n\n            // @ts-expect-error patching\n            client.setMaxListeners(listeners < 0 ? 1 : listeners);\n          };\n        default:\n          // @ts-expect-error patching\n          return target[p];\n      }\n    }\n  });\n\n  Reflect.set(erisProxy, DiscordPlayerClientSymbol, 'Eris');\n\n  return createCompatClient(erisProxy, 'Eris').client as unknown as Client;\n}\n\nfunction erisVoiceStateUpdateProxy(\nclient: Eris.Client,\nproxy: Eris.Client,\nhandler: (a, b) => void)\n{\n  client.on('voiceStateUpdate', (member, oldState) => {\n    try {\n      const proxiedOldState = {\n        channelId: oldState.channelID,\n        serverMute: oldState.mute,\n        suppress: oldState.suppress,\n        guild: {\n          id: oldState.guild.id\n        },\n        member: {\n          id: oldState.user.id\n        }\n      } as VoiceState;\n\n      const me = member.guild.members.get(client.user.id);\n      const resolvedChannel = member.guild.channels.get(\n        member.voiceState.channelID\n      );\n\n      const proxiedNewState = {\n        channelId: member.voiceState.channelID,\n        serverMute: member.voiceState.mute,\n        suppress: member.voiceState.suppress,\n        channel: erisResolvedChannelProxy(resolvedChannel, client),\n        member: {\n          id: member.id\n        },\n        guild: {\n          id: member.guild.id,\n          members: {\n            me: {\n              id: me?.id,\n              voice: {\n                async setRequestToSpeak(value: boolean) {\n                  void value;\n                  return me?.voiceState;\n                  // if (me) {\n                  //   return me.voice.setRequestToSpeak(value);\n                  // }\n                }\n              }\n            }\n          }\n        }\n      } as VoiceState;\n\n      return handler(proxiedNewState, proxiedOldState);\n    } catch {\n\n      /* noop */}\n  });\n}\n\nfunction erisVoiceEventsHandler(client: Eris.Client) {\n  let adapters = getProperty<Map<string, any>>(client, 'adapters');\n\n  if (!adapters) {\n    const collection = new Map<string, any>();\n    adapters = collection;\n    declareProperty(client, 'adapters', collection);\n  }\n\n  client.on('shardDisconnect', (_, shardId) => {\n    for (const [guildId, adapter] of adapters.entries()) {\n      if (client.guilds.get(guildId)?.shard.id === shardId) {\n        adapter.destroy();\n      }\n    }\n  });\n\n  client.on('rawWS', (packet) => {\n    switch (packet.t) {\n      case GatewayDispatchEvents.VoiceServerUpdate:{\n          const payload = packet.d as GatewayVoiceServerUpdateDispatchData;\n          adapters.get(payload.guild_id)?.onVoiceServerUpdate(payload);\n          return;\n        }\n      case GatewayDispatchEvents.VoiceStateUpdate:{\n          const payload = packet.d as GatewayVoiceStateUpdateDispatchData;\n\n          if (\n          payload.guild_id &&\n          payload.session_id &&\n          payload.user_id === client.user.id)\n          {\n            adapters.get(payload.guild_id)?.onVoiceStateUpdate(payload);\n          }\n\n          return;\n        }\n      default:\n        break;\n    }\n  });\n}\n\nfunction erisChannelsProxy(client: Eris.Client, eris: typeof import('eris')) {\n  const handler = {\n    client,\n    get cache() {\n      return {\n        get(id: string) {\n          return client.getChannel(id);\n        },\n        has(id: string) {\n          return id in client.channelGuildMap;\n        }\n      };\n    },\n    resolve(resolvable: string | ErisChannelResolvable) {\n      if (typeof resolvable === 'string') {\n        return erisResolvedChannelProxy(\n          this.client.getChannel(resolvable) as Eris.GuildChannel,\n          client\n        );\n      }\n\n      if (resolvable instanceof eris.GuildChannel) {\n        return erisResolvedChannelProxy(resolvable, client);\n      }\n    },\n    resolveId(resolvable: ErisChannelResolvable) {\n      const channel = this.resolve(resolvable);\n      return channel?.id;\n    }\n  };\n\n  return handler;\n}\n\nfunction erisResolvedChannelProxy(\nchannel: Eris.GuildChannel | undefined,\nclient: Eris.Client)\n: Eris.GuildChannel | undefined {\n  if (!channel) return;\n\n  return new Proxy(channel, {\n    get(target, p) {\n      switch (p) {\n        case 'guild':\n          return erisVoiceAdapterProxy(target.guild, client);\n        case 'members':\n          return (target as Eris.VoiceChannel).voiceMembers;\n        case 'isVoiceBased':\n          return () =>\n          target.type === ChannelType.GuildVoice ||\n          target.type === ChannelType.GuildStageVoice;\n        case 'isVoice':\n          return () => target.type === ChannelType.GuildVoice;\n        case 'isStage':\n          return () => target.type === ChannelType.GuildStageVoice;\n        default:\n          // @ts-expect-error patching\n          return target[p];\n      }\n    }\n  });\n}\n\nfunction erisVoiceAdapterProxy(\nguild: Eris.Guild | undefined,\nclient: Eris.Client)\n: Eris.Guild | undefined {\n  if (!guild) return;\n\n  return new Proxy(guild, {\n    get(target, p) {\n      if (p === 'voiceAdapterCreator') {\n        return erisVoiceAdapterCreator(target, client);\n      }\n\n      // @ts-expect-error patching\n      return target[p];\n    }\n  });\n}\n\nfunction erisVoiceAdapterCreator(\nguild: Eris.Guild,\nclient: Eris.Client)\n: DiscordGatewayAdapterCreator {\n  return (methods) => {\n    let adapters = getProperty<Map<string, typeof methods>>(client, 'adapters');\n\n    if (!adapters) {\n      const collection = new Map<string, typeof methods>();\n      adapters = collection;\n      declareProperty(client, 'adapters', collection);\n    }\n\n    adapters.set(guild.id, methods);\n\n    return {\n      sendPayload(payload) {\n        if (guild.shard.status !== 'ready') return false;\n        guild.shard.sendWS(payload.op, payload.d);\n        return true;\n      },\n      destroy() {\n        adapters.delete(guild.id);\n      }\n    };\n  };\n}\n\nfunction erisGuildsProxy(client: Eris.Client, eris: typeof import('eris')) {\n  return new Proxy(client.guilds, {\n    get(target, p) {\n      if (p === 'cache') {\n        return target;\n      }\n\n      if (p === 'resolve' || p === 'resolveId') {\n        const resolver = function (resolvable: ErisGuildResolvable) {\n          if (typeof resolvable === 'string') {\n            return target.get(resolvable);\n          }\n\n          if (resolvable instanceof eris.Guild) {\n            return resolvable;\n          }\n\n          if (\n          resolvable instanceof eris.Member ||\n          resolvable instanceof eris.Guild ||\n          resolvable instanceof eris.GuildChannel ||\n          resolvable instanceof eris.Role)\n          {\n            return resolvable.guild;\n          }\n        };\n\n        if (p === 'resolve') {\n          return resolver;\n        }\n\n        return (resolvable: ErisGuildResolvable) => {\n          const guild = resolver(resolvable);\n          return guild?.id;\n        };\n      }\n\n      // @ts-expect-error patching\n      return target[p];\n    }\n  });\n}\n\nfunction erisUsersProxy(client: Eris.Client, eris: typeof import('eris')) {\n  return new Proxy(client.users, {\n    get(target, p) {\n      if (p === 'cache') {\n        return target;\n      }\n\n      if (p === 'resolve' || p === 'resolveId') {\n        const resolver = function (resolvable: ErisUserResolvable) {\n          if (typeof resolvable === 'string') {\n            return target.get(resolvable);\n          }\n\n          if (resolvable instanceof eris.User) {\n            return resolvable;\n          }\n\n          if (resolvable instanceof eris.Member) {\n            return resolvable.user;\n          }\n        };\n\n        if (p === 'resolve') {\n          return resolver;\n        }\n\n        return (resolvable: ErisUserResolvable) => {\n          const user = resolver(resolvable);\n          return user?.id;\n        };\n      }\n\n      // @ts-expect-error patching\n      return target[p];\n    }\n  });\n}","/* eslint-disable @typescript-eslint/no-explicit-any */\n\nexport const DiscordPlayerClientSymbol = Symbol('DiscordPlayerClient');\n\nexport type CompatProvider = 'Eris' | 'Oceanic';\n\nexport interface CompatClient {\n  provider: CompatProvider;\n  client: any;\n}\n\nexport function createCompatClient(\nclient: any,\nprovider: CompatProvider)\n: CompatClient {\n  Reflect.set(client, DiscordPlayerClientSymbol, provider);\n  return {\n    provider,\n    client\n  };\n}\n\nexport function isClientProxy(client: any): boolean {\n  return Reflect.get(client, DiscordPlayerClientSymbol) != null;\n}\n\nexport function getCompatName(client: any): CompatProvider | null {\n  return Reflect.get(client, DiscordPlayerClientSymbol) ?? null;\n}\n\nexport function isErisProxy(client: any): boolean {\n  return getCompatName(client) === 'Eris';\n}\n\nexport function isOceanicProxy(client: any): boolean {\n  return getCompatName(client) === 'Oceanic';\n}","import { StageChannel, VoiceChannel } from 'discord.js';\nimport { setTimeout } from 'node:timers/promises';\nimport { GuildQueue } from '../queue';\nimport { Playlist, Track, TrackSource } from '../fabric';\nimport { OutOfSpaceError } from '../errors';\nimport { randomInt } from 'node:crypto';\nimport {\n  createFilter,\n  createSpotifyFilter,\n  fixTrackSuffix,\n  removeLive,\n  removeRemastered,\n  youtube,\n  removeZeroWidth,\n  replaceNbsp,\n  replaceSmartQuotes,\n  removeCleanExplicit } from\n'@web-scrobbler/metadata-filter';\n\nexport type RuntimeType = 'node' | 'deno' | 'bun' | 'unknown';\n\nexport interface TimeData {\n  /**\n   * Time in days\n   */\n  days: number;\n  /**\n   * Time in hours\n   */\n  hours: number;\n  /**\n   * Time in minutes\n   */\n  minutes: number;\n  /**\n   * Time in seconds\n   */\n  seconds: number;\n}\n\nexport interface Runtime {\n  name: RuntimeType;\n  version: string;\n}\n\nclass Util {\n  /**\n   * Utils\n   */\n  private constructor() {} // eslint-disable-line @typescript-eslint/no-empty-function\n\n  /**\n   * Gets the runtime information\n   */\n  static getRuntime(): Runtime {\n    const version =\n    typeof navigator !== 'undefined' ? navigator.userAgent : null;\n\n    // @ts-ignore\n    if (typeof Deno !== 'undefined' && Deno.version) {\n      // @ts-ignore\n      return { name: 'deno', version: Deno.version.deno };\n    }\n\n    // @ts-ignore\n    if (typeof Bun !== 'undefined' && Bun.version) {\n      // @ts-ignore\n      return { name: 'bun', version: Bun.version };\n    }\n\n    if (typeof process !== 'undefined' && process.version)\n    return { name: 'node', version: process.version };\n\n    return { name: 'unknown', version: version ?? 'unknown' };\n  }\n\n  /**\n   * Creates duration string\n   * @param {object} durObj The duration object\n   * @returns {string}\n   */\n  static durationString(durObj: Record<string, number>) {\n    return Object.values(durObj).\n    map((m) => isNaN(m) ? 0 : m).\n    join(':');\n  }\n\n  /**\n   * Parses milliseconds to consumable time object\n   * @param {number} milliseconds The time in ms\n   * @returns {TimeData}\n   */\n  static parseMS(milliseconds: number) {\n    if (isNaN(milliseconds)) milliseconds = 0;\n    const round = milliseconds > 0 ? Math.floor : Math.ceil;\n\n    return {\n      days: round(milliseconds / 86400000),\n      hours: round(milliseconds / 3600000) % 24,\n      minutes: round(milliseconds / 60000) % 60,\n      seconds: round(milliseconds / 1000) % 60\n    } as TimeData;\n  }\n\n  /**\n   * Builds time code\n   * @param {TimeData} duration The duration object\n   * @returns {string}\n   */\n  static buildTimeCode(duration: TimeData) {\n    const items = Object.keys(duration);\n    const required = ['days', 'hours', 'minutes', 'seconds'];\n\n    const parsed = items.\n    filter((x) => required.includes(x)).\n    map((m) => duration[m as keyof TimeData]);\n    const final = parsed.\n    slice(parsed.findIndex((x) => x !== 0)).\n    map((x) => x.toString().padStart(2, '0')).\n    join(':');\n\n    return final.length <= 3 ? `0:${final.padStart(2, '0') || 0}` : final;\n  }\n\n  /**\n   * Formats duration\n   * @param {number} duration The duration in ms\n   */\n  static formatDuration(duration: number) {\n    return this.buildTimeCode(this.parseMS(duration));\n  }\n\n  /**\n   * Picks last item of the given array\n   * @param {any[]} arr The array\n   * @returns {any}\n   */\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  static last<T = any>(arr: T[]): T {\n    if (!Array.isArray(arr)) return arr;\n    return arr[arr.length - 1];\n  }\n\n  /**\n   * Checks if the voice channel is empty\n   * @param {VoiceChannel|StageChannel} channel The voice channel\n   * @returns {boolean}\n   */\n  static isVoiceEmpty(channel: VoiceChannel | StageChannel) {\n    return (\n      channel && channel.members.filter((member) => !member.user.bot).size === 0);\n\n  }\n\n  /**\n   * Cleans the track title\n   * @param title The title\n   * @param source The source\n   * @returns Cleaned title\n   */\n  static cleanTitle(title: string, source: TrackSource) {\n    try {\n      const filterOpts = {\n        // prettier-ignore\n        track: [\n        removeRemastered,\n        removeLive,\n        fixTrackSuffix,\n        removeZeroWidth,\n        replaceNbsp,\n        replaceSmartQuotes,\n        removeCleanExplicit]\n\n      };\n      const spotifyFilter = createFilter(filterOpts);\n      spotifyFilter.extend(createSpotifyFilter());\n      const defaultFilter = createFilter(filterOpts);\n\n      switch (source) {\n        case 'youtube':\n          return youtube(title);\n        case 'spotify':\n          return spotifyFilter.filterField('track', title);\n        default:\n          return defaultFilter.filterField('track', title);\n      }\n    } catch {\n      return title;\n    }\n  }\n\n  /**\n   * Safer require\n   * @param {string} id Node require id\n   * @returns {any}\n   */\n  static require(id: string) {\n    try {\n      return { module: require(id), error: null };\n    } catch (error) {\n      return { module: null, error };\n    }\n  }\n\n  static async import(id: string) {\n    try {\n      const mod = await import(id);\n      return { module: mod, error: null };\n    } catch (error) {\n      return { module: null, error };\n    }\n  }\n\n  /**\n   * Asynchronous timeout\n   * @param {number} time The time in ms to wait\n   * @returns {Promise<unknown>}\n   */\n  static wait(time: number) {\n    return setTimeout(time, undefined, { ref: false });\n  }\n\n  static noop() {} // eslint-disable-line @typescript-eslint/no-empty-function\n\n  static async getFetch() {\n    if ('fetch' in globalThis) return globalThis.fetch;\n    for (const lib of ['node-fetch', 'undici']) {\n      try {\n        return await import(lib).then(\n          (res) => res.fetch || res.default?.fetch || res.default\n        );\n      } catch {\n        try {\n          // eslint-disable-next-line\n          const res = require(lib);\n          if (res) return res.fetch || res.default?.fetch || res.default;\n        } catch {\n\n          // no?\n        }}\n    }\n  }\n\n  static warn(message: string, code = 'DeprecationWarning', detail?: string) {\n    process.emitWarning(message, {\n      code,\n      detail\n    });\n  }\n\n  static randomChoice<T>(src: T[]): T {\n    return src[randomInt(src.length)];\n  }\n\n  static arrayCloneShuffle<T>(src: T[]): T[] {\n    const arr = src.slice();\n\n    let m = arr.length;\n\n    while (m) {\n      const i = Math.floor(Math.random() * m--);\n      [arr[m], arr[i]] = [arr[i], arr[m]];\n    }\n\n    return arr;\n  }\n}\n\nexport const VALIDATE_QUEUE_CAP = (\nqueue: GuildQueue,\nitems: Playlist | Track | Track[] | number) =>\n{\n  if (queue.maxSize < 1 || queue.maxSize === Infinity) return;\n\n  const tracks =\n  typeof items === 'number' ?\n  items :\n  (items instanceof Playlist ?\n  items.tracks :\n  Array.isArray(items) ?\n  items :\n  [items]).\n  length;\n\n  const maxCap = queue.getCapacity();\n\n  if (maxCap < tracks) {\n    throw new OutOfSpaceError('tracks queue', maxCap, tracks);\n  }\n};\n\nexport { Util };","import {\n  User,\n  escapeMarkdown,\n  SnowflakeUtil,\n  GuildVoiceChannelResolvable,\n  APIUser } from\n'discord.js';\nimport {\n  Player,\n  PlayerNodeInitializationResult,\n  PlayerNodeInitializerOptions } from\n'../Player';\nimport { Playlist, PlaylistJSON } from './Playlist';\nimport { GuildQueue } from '../queue/GuildQueue';\nimport { BaseExtractor } from '../extractors/BaseExtractor';\nimport { Collection } from '@discord-player/utils';\nimport { TypeUtil } from '../utils/TypeUtil';\nimport { SerializedType, tryIntoThumbnailString } from '../utils/serde';\nimport { InvalidArgTypeError } from '../errors';\nimport { Util } from '../utils/Util';\nimport { SearchQueryType } from '../utils/QueryResolver';\nimport { AudioResource } from 'discord-voip';\nimport { SeekEvent } from '@discord-player/equalizer';\n\nexport type TrackResolvable = Track | string | number;\n\nexport type WithMetadata<T extends object, M> = T & {\n  metadata: M;\n  requestMetadata(): Promise<M>;\n};\n\nexport type SerializedTrack = ReturnType<Track['serialize']>;\n\n/**\n * The track source:\n * - soundcloud\n * - youtube\n * - spotify\n * - apple_music\n * - arbitrary\n */\nexport type TrackSource =\n'soundcloud' |\n'youtube' |\n'spotify' |\n'apple_music' |\n'arbitrary';\n\nexport interface RawTrackData {\n  /**\n   * The title\n   */\n  title: string;\n  /**\n   * The description\n   */\n  description: string;\n  /**\n   * The author\n   */\n  author: string;\n  /**\n   * The url\n   */\n  url: string;\n  /**\n   * The thumbnail\n   */\n  thumbnail: string;\n  /**\n   * The duration\n   */\n  duration: string;\n  /**\n   * The duration in ms\n   */\n  views: number;\n  /**\n   * The user who requested this track\n   */\n  requestedBy?: User | null;\n  /**\n   * The playlist\n   */\n  playlist?: Playlist;\n  /**\n   * The source\n   */\n  source?: TrackSource;\n  /**\n   * The engine\n   */\n  engine?: any; // eslint-disable-line @typescript-eslint/no-explicit-any\n  /**\n   * If this track is live\n   */\n  live?: boolean;\n  /**\n   * The raw data\n   */\n  raw?: any; // eslint-disable-line @typescript-eslint/no-explicit-any\n  /**\n   * The query type\n   */\n  queryType?: SearchQueryType;\n  /**\n   * The serialized title\n   */\n  cleanTitle?: string;\n}\n\nexport interface TrackJSON {\n  /**\n   * The track id\n   */\n  id: string;\n  /**\n   * The track title\n   */\n  title: string;\n  /**\n   * The track description\n   */\n  description: string;\n  /**\n   * The track author\n   */\n  author: string;\n  /**\n   * The track url\n   */\n  url: string;\n  /**\n   * The track thumbnail\n   */\n  thumbnail: string;\n  /**\n   * The track duration\n   */\n  duration: string;\n  /**\n   * The track duration in ms\n   */\n  durationMS: number;\n  /**\n   * The track views\n   */\n  views: number;\n  /**\n   * The user id who requested this track\n   */\n  requestedBy: string;\n  /**\n   * The playlist info (if any)\n   */\n  playlist?: PlaylistJSON;\n}\n\nexport class Track<T = unknown> {\n  public title: string;\n  public description: string;\n  public author: string;\n  public url: string;\n  public thumbnail: string;\n  public duration: string;\n  public views: number;\n  public requestedBy: User | null = null;\n  public playlist?: Playlist;\n  public queryType: SearchQueryType | null | undefined = null;\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  public raw: any;\n  public extractor: BaseExtractor | null = null;\n  public readonly id = SnowflakeUtil.generate().toString();\n  private __metadata: T | null = null;\n  private __reqMetadataFn: () => Promise<T | null>;\n  public cleanTitle: string;\n  public live: boolean = false;\n  public bridgedExtractor: BaseExtractor | null = null;\n  public bridgedTrack: Track | null = null;\n\n  #onSeek: ((event: SeekEvent) => Awaited<void>) | null = null;\n  #resource: AudioResource<Track> | null = null;\n\n  /**\n   * Track constructor\n   * @param player The player that instantiated this Track\n   * @param data Track data\n   */\n  public constructor(\n  public readonly player: Player,\n  data: Partial<WithMetadata<RawTrackData, T>>)\n  {\n    this.title = escapeMarkdown(data.title ?? '');\n    this.author = data.author ?? '';\n    this.url = data.url ?? '';\n    this.thumbnail = data.thumbnail ?? '';\n    this.duration = data.duration ?? '';\n    this.views = data.views ?? 0;\n    this.queryType = data.queryType;\n    this.requestedBy = data.requestedBy || null;\n    this.playlist = data.playlist;\n    this.description = `${this.title} by ${this.author}`;\n    this.raw = Object.assign(\n      {},\n      { source: data.raw?.source ?? data.source },\n      data.raw ?? data\n    );\n    this.__metadata = data.metadata ?? null;\n    this.__reqMetadataFn =\n    data.requestMetadata || (() => Promise.resolve<T | null>(null));\n    this.cleanTitle =\n    data.cleanTitle ?? Util.cleanTitle(this.title, this.source);\n    this.live = data.live ?? false;\n  }\n\n  /**\n   * Whether this track can be seeked\n   */\n  public get seekable() {\n    return this.#onSeek !== null;\n  }\n\n  /**\n   * Set the onSeek event\n   * @param fn The onSeek event\n   */\n  public handleSeek(fn: (event: SeekEvent) => Awaited<void>) {\n    this.#onSeek = fn;\n  }\n\n  /**\n   * Request seek\n   * @param event The seek event\n   */\n  public async seek(event: SeekEvent) {\n    if (this.#onSeek) return this.#onSeek(event);\n  }\n\n  /**\n   * Sets audio resource for this track. This is not useful outside of the library.\n   * @param resource Audio resource\n   */\n  public setResource(resource: AudioResource<Track> | null) {\n    this.#resource = resource;\n  }\n\n  /**\n   * Gets audio resource for this track\n   */\n  public get resource() {\n    return this.#resource;\n  }\n\n  /**\n   * Whether this track has an audio resource\n   */\n  public get hasResource() {\n    return this.#resource != null;\n  }\n\n  /**\n   * Request metadata for this track\n   */\n  public async requestMetadata() {\n    const res = await this.__reqMetadataFn();\n\n    this.setMetadata(res);\n\n    return res;\n  }\n\n  /**\n   * Set metadata for this track\n   */\n  public setMetadata(m: T | null) {\n    this.__metadata = m;\n  }\n\n  /**\n   * Metadata of this track\n   */\n  public get metadata() {\n    return this.__metadata;\n  }\n\n  /**\n   * If this track has metadata\n   */\n  public get hasMetadata() {\n    return this.metadata != null;\n  }\n\n  /**\n   * The queue in which this track is located\n   */\n  public get queue(): GuildQueue {\n    return this.player.nodes.cache.find((q) =>\n    q.tracks.some((ab) => ab.id === this.id)\n    )!;\n  }\n\n  /**\n   * The track duration in millisecond\n   */\n  public get durationMS(): number {\n    const times = (n: number, t: number) => {\n      let tn = 1;\n      for (let i = 0; i < t; i++) tn *= n;\n      return t <= 0 ? 1000 : tn * 1000;\n    };\n\n    return this.duration.\n    split(':').\n    reverse().\n    map((m, i) => parseInt(m) * times(60, i)).\n    reduce((a, c) => a + c, 0);\n  }\n\n  /**\n   * Discord hyperlink representation of this track\n   */\n  public toHyperlink(): string /* not using `[${string}](${string})` yet */ {\n    return `[${this.title}](${this.url})`;\n  }\n\n  /**\n   * Returns source of this track\n   */\n  public get source() {\n    return this.raw?.source ?? 'arbitrary';\n  }\n\n  /**\n   * String representation of this track\n   */\n  public toString(): string {\n    return `${this.title} by ${this.author}`;\n  }\n\n  /**\n   * Raw JSON representation of this track\n   */\n  public toJSON(hidePlaylist?: boolean) {\n    return {\n      id: this.id,\n      title: this.title,\n      description: this.description,\n      author: this.author,\n      url: this.url,\n      thumbnail: this.thumbnail,\n      duration: this.duration,\n      durationMS: this.durationMS,\n      views: this.views,\n      requestedBy: this.requestedBy?.id || null,\n      playlist: hidePlaylist ? null : this.playlist?.toJSON() ?? null\n    } as TrackJSON;\n  }\n\n  /**\n   * Serialized track data that can be reconstructed\n   */\n  public serialize() {\n    return {\n      title: this.title,\n      description: this.description,\n      author: this.author,\n      url: this.url,\n      thumbnail: TypeUtil.isString(this.thumbnail) ?\n      this.thumbnail :\n      tryIntoThumbnailString(this.thumbnail),\n      duration: this.duration,\n      views: this.views ?? 0,\n      requested_by: this.requestedBy?.toJSON() ?? null,\n      source: this.source,\n      live: false,\n      query_type: this.queryType,\n      extractor: this.extractor?.identifier ?? null,\n      metadata: this.metadata,\n      $type: SerializedType.Track,\n      $encoder_version: this.player.version\n    };\n  }\n\n  /**\n   * Construct a track from serialized data\n   * @param player Player instance\n   * @param data Serialized data\n   */\n  public static fromSerialized(\n  player: Player,\n  data: ReturnType<Track['serialize']>)\n  {\n    if (data.$type !== SerializedType.Track)\n    throw new InvalidArgTypeError(\n      'data',\n      'SerializedTrack',\n      'malformed data'\n    );\n    const track = new Track(player, {\n      ...data,\n      requestedBy: data.requested_by ?\n      (() => {\n        const res = data.requested_by as APIUser;\n        try {\n          const resolved = player.client.users.resolve(res.id);\n          if (resolved) return resolved;\n          if (player.client.users.cache.has(res.id))\n          return player.client.users.cache.get(res.id)!;\n          // @ts-expect-error\n          const user = new User(player.client, res);\n          return user;\n        } catch {\n          return null;\n        }\n      })() :\n      null,\n      queryType: data.query_type ?? undefined\n    });\n\n    track.setMetadata(data.metadata);\n\n    return track;\n  }\n\n  /**\n   * Get belonging queues of this track\n   */\n  public getBelongingQueues() {\n    const nodes = this.player.nodes.cache.filter((node) =>\n    node.tracks.some((t) => t.id === this.id)\n    );\n\n    return nodes as Collection<string, GuildQueue<unknown>>;\n  }\n\n  /**\n   * Play this track to the given voice channel. If queue exists and another track is being played, this track will be added to the queue.\n   * @param channel Voice channel on which this track shall be played\n   * @param options Node initialization options\n   */\n  public async play<T = unknown>(\n  channel: GuildVoiceChannelResolvable,\n  options?: PlayerNodeInitializerOptions<T>)\n  : Promise<PlayerNodeInitializationResult<T>> {\n    const fn = this.player.play.bind(this.player);\n\n    return await fn(channel, this, options);\n  }\n}","export class DiscordPlayerError extends Error {\n  public readonly code: ErrorCodes;\n  public readonly timestamp: number = Date.now();\n\n  public constructor(code: ErrorCodes, message: string) {\n    super(message);\n    this.name = this.constructor.name;\n    this.code = code;\n\n    if (Error.captureStackTrace) {\n      Error.captureStackTrace(this, this.constructor);\n    }\n  }\n\n  public toJSON() {\n    return {\n      name: this.constructor.name,\n      code: this.code,\n      message: this.message,\n      timestamp: this.timestamp\n    };\n  }\n}\n\nexport class OutOfSpaceError extends DiscordPlayerError {\n  constructor(target: string, capacity: number, total: number) {\n    super(\n      ErrorCodes.ERR_OUT_OF_SPACE,\n      `Max capacity reached for ${target} (Capacity ${capacity}/Total ${total})`\n    );\n  }\n}\n\nexport class InvalidArgTypeError extends DiscordPlayerError {\n  constructor(target: string, expectation: string, found: string) {\n    super(\n      ErrorCodes.ERR_INVALID_ARG_TYPE,\n      `Expected ${target} to be \"${expectation}\", received \"${found}\"`\n    );\n  }\n}\n\nexport class NoResultError extends DiscordPlayerError {\n  constructor(message: string) {\n    super(ErrorCodes.ERR_NO_RESULT, message);\n  }\n}\n\nexport class NotImplementedError extends DiscordPlayerError {\n  constructor(target: string) {\n    super(ErrorCodes.ERR_NOT_IMPLEMENTED, `${target} is not yet implemented`);\n  }\n}\n\nexport class NotExistingError extends DiscordPlayerError {\n  constructor(target: string) {\n    super(ErrorCodes.ERR_NOT_EXISTING, `${target} does not exist`);\n  }\n}\n\nexport class OutOfRangeError extends DiscordPlayerError {\n  constructor(target: string, value: string, minimum: string, maximum: string) {\n    super(\n      ErrorCodes.ERR_OUT_OF_RANGE,\n      `${target} is out of range (Expected minimum ${minimum} and maximum ${maximum}, got ${value})`\n    );\n  }\n}\n\nexport class NoVoiceConnectionError extends DiscordPlayerError {\n  constructor(message?: string) {\n    super(\n      ErrorCodes.ERR_NO_VOICE_CONNECTION,\n      message ||\n      'No voice connection available, maybe connect to a voice channel first?'\n    );\n  }\n}\n\nexport class VoiceConnectionDestroyedError extends DiscordPlayerError {\n  constructor() {\n    super(\n      ErrorCodes.ERR_VOICE_CONNECTION_DESTROYED,\n      'Cannot use destroyed voice connection'\n    );\n  }\n}\n\nexport class NoVoiceChannelError extends DiscordPlayerError {\n  constructor() {\n    super(ErrorCodes.ERR_NO_VOICE_CHANNEL, 'Could not get the voice channel');\n  }\n}\n\nexport class InvalidVoiceChannelError extends DiscordPlayerError {\n  constructor() {\n    super(ErrorCodes.ERR_INVALID_VOICE_CHANNEL, 'Expected a voice channel');\n  }\n}\n\nexport class NoReceiverError extends DiscordPlayerError {\n  constructor(message?: string) {\n    super(\n      ErrorCodes.ERR_NO_RECEIVER,\n      message ||\n      'No voice receiver is available, maybe connect to a voice channel first?'\n    );\n  }\n}\n\nexport class FFmpegError extends DiscordPlayerError {\n  constructor(message: string) {\n    super(ErrorCodes.ERR_FFMPEG_LOCATOR, message);\n  }\n}\n\nexport class NoAudioResourceError extends DiscordPlayerError {\n  constructor(message?: string) {\n    super(\n      ErrorCodes.ERR_NO_AUDIO_RESOURCE,\n      message || 'Expected an audio resource'\n    );\n  }\n}\n\nexport class NoGuildQueueError extends DiscordPlayerError {\n  constructor(message?: string) {\n    super(ErrorCodes.ERR_NO_GUILD_QUEUE, message || 'Expected a guild queue');\n  }\n}\n\nexport class NoGuildError extends DiscordPlayerError {\n  constructor(message?: string) {\n    super(ErrorCodes.ERR_NO_GUILD, message || 'Expected a guild');\n  }\n}\n\nexport class InfoRequiredError extends DiscordPlayerError {\n  constructor(target: string, actual: string) {\n    super(\n      ErrorCodes.ERR_INFO_REQUIRED,\n      `Expected ${target}, found \"${actual}\"`\n    );\n  }\n}\n\nexport class SerializationError extends DiscordPlayerError {\n  constructor() {\n    super(\n      ErrorCodes.ERR_SERIALIZATION_FAILED,\n      \"Don't know how to serialize this data\"\n    );\n  }\n}\n\nexport class DeserializationError extends DiscordPlayerError {\n  constructor() {\n    super(\n      ErrorCodes.ERR_DESERIALIZATION_FAILED,\n      \"Don't know how to deserialize this data\"\n    );\n  }\n}\n\nexport class IllegalHookInvocationError extends DiscordPlayerError {\n  constructor(target: string, message?: string) {\n    super(\n      ErrorCodes.ERR_ILLEGAL_HOOK_INVOCATION,\n      `Illegal invocation of ${target} hook.${message ? ` ${message}` : ''}`\n    );\n  }\n}\n\nexport class ModuleNotFoundError extends DiscordPlayerError {\n  constructor(target: string, description = '') {\n    super(\n      ErrorCodes.ERR_NOT_EXISTING_MODULE,\n      `${target} module does not exist. Install it with \\`npm install ${target}\\`.${\n      description ? ' ' + description : ''}`\n\n    );\n  }\n}\n\nexport class BridgeFailedError extends DiscordPlayerError {\n  constructor(id: string | null, error: string) {\n    super(\n      ErrorCodes.ERR_BRIDGE_FAILED,\n      `${\n      id ? `(Extractor Execution Context ID is ${id})` : ''}Failed to bridge this query:\\n${\n      error}`\n    );\n  }\n}\n\n// For backwards compatibility\nexport const ErrorCodes = {\n  ERR_OUT_OF_SPACE: 'ERR_OUT_OF_SPACE',\n  ERR_INVALID_ARG_TYPE: 'ERR_INVALID_ARG_TYPE',\n  ERR_NO_RESULT: 'ERR_NO_RESULT',\n  ERR_NOT_IMPLEMENTED: 'ERR_NOT_IMPLEMENTED',\n  ERR_NOT_EXISTING: 'ERR_NOT_EXISTING',\n  ERR_OUT_OF_RANGE: 'ERR_OUT_OF_RANGE',\n  ERR_NO_VOICE_CONNECTION: 'ERR_NO_VOICE_CONNECTION',\n  ERR_VOICE_CONNECTION_DESTROYED: 'ERR_VOICE_CONNECTION_DESTROYED',\n  ERR_NO_VOICE_CHANNEL: 'ERR_NO_VOICE_CHANNEL',\n  ERR_INVALID_VOICE_CHANNEL: 'ERR_INVALID_VOICE_CHANNEL',\n  ERR_NO_RECEIVER: 'ERR_NO_RECEIVER',\n  ERR_FFMPEG_LOCATOR: 'ERR_FFMPEG_LOCATOR',\n  ERR_NO_AUDIO_RESOURCE: 'ERR_NO_AUDIO_RESOURCE',\n  ERR_NO_GUILD_QUEUE: 'ERR_NO_GUILD_QUEUE',\n  ERR_NO_GUILD: 'ERR_NO_GUILD',\n  ERR_INFO_REQUIRED: 'ERR_INFO_REQUIRED',\n  ERR_SERIALIZATION_FAILED: 'ERR_SERIALIZATION_FAILED',\n  ERR_DESERIALIZATION_FAILED: 'ERR_DESERIALIZATION_FAILED',\n  ERR_ILLEGAL_HOOK_INVOCATION: 'ERR_ILLEGAL_HOOK_INVOCATION',\n  ERR_NOT_EXISTING_MODULE: 'ERR_NOT_EXISTING_MODULE',\n  ERR_BRIDGE_FAILED: 'ERR_BRIDGE_FAILED'\n} as const;\n\nexport type ErrorCodes = (typeof ErrorCodes)[keyof typeof ErrorCodes];\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\nexport function isDiscordPlayerError(error: any): error is DiscordPlayerError {\n  return error != null && error instanceof DiscordPlayerError;\n}\n\n/**\n * Handle a `DiscordPlayerError` error.\n * @param error The error to handle\n * @param handler The handler function. This function will only be called if the error is a `DiscordPlayerError`.\n * @param args The arguments to pass to the handler\n * @returns The result of the handler\n * @example ```typescript\n * try {\n *   // ...\n * } catch (error) {\n *  handleDiscordPlayerError(error, (error) => {\n *    console.error(`An error occurred from discord-player: ${error.message}`);\n *  });\n * }\n * ```\n */\nexport function handleDiscordPlayerError<\n  T extends any[],\n  F extends (error: DiscordPlayerError, ...args: T) => any,\n  R extends ReturnType<F>>(\nerror: any, handler: F, args: T): R {\n  if (isDiscordPlayerError(error)) {\n    return handler(error, ...args) as R;\n  }\n\n  return undefined as R;\n}\n\n/* eslint-enable @typescript-eslint/no-explicit-any */","import { DiscordPlayerError, isDiscordPlayerError } from '../errors';\n\nexport class TypeUtil {\n  private constructor() {\n    return TypeUtil;\n  }\n\n  // eslint-disable-next-line @typescript-eslint/ban-types\n  public static isFunction(t: unknown): t is Function {\n    return typeof t === 'function';\n  }\n\n  public static isNumber(t: unknown): t is number {\n    return typeof t === 'number' && !isNaN(t);\n  }\n\n  public static isString(t: unknown): t is string {\n    return typeof t === 'string';\n  }\n\n  public static isBoolean(t: unknown): t is boolean {\n    return typeof t === 'boolean';\n  }\n\n  public static isNullish(t: unknown): t is null | undefined {\n    return t == null;\n  }\n\n  public static isArray(t: unknown): t is unknown[] {\n    return Array.isArray(t);\n  }\n\n  public static isError(t: unknown): t is Error {\n    return t instanceof Error;\n  }\n\n  public static isDiscordPlayerError(t: unknown): t is DiscordPlayerError {\n    return isDiscordPlayerError(t);\n  }\n}","/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport { DeserializationError, SerializationError } from '../errors';\nimport {\n  Playlist,\n  type SerializedTrack,\n  Track,\n  SerializedPlaylist } from\n'../fabric';\nimport { TypeUtil } from './TypeUtil';\nimport { Buffer } from 'buffer';\nimport { Player } from '../Player';\n\nexport enum SerializedType {\n  Track = 'track',\n  Playlist = 'playlist',\n}\n\nexport type Encodable = SerializedTrack | SerializedPlaylist;\n\nconst isTrack = (data: any): data is SerializedTrack =>\ndata.$type === SerializedType.Track;\nconst isPlaylist = (data: any): data is SerializedPlaylist =>\ndata.$type === SerializedType.Playlist;\n\nexport function serialize(data: Track | Playlist | any) {\n  if (data instanceof Track) return data.serialize();\n  if (data instanceof Playlist) return data.serialize();\n\n  try {\n    return data.toJSON();\n  } catch {\n    throw new SerializationError();\n  }\n}\n\nexport function deserialize(player: Player, data: Encodable) {\n  if (isTrack(data)) return Track.fromSerialized(player, data);\n  if (isPlaylist(data)) return Playlist.fromSerialized(player, data);\n\n  throw new DeserializationError();\n}\n\nexport function encode(data: Encodable) {\n  const str = JSON.stringify(data);\n\n  return Buffer.from(str).toString('base64');\n}\n\nexport function decode(data: string) {\n  const str = Buffer.from(data, 'base64').toString();\n\n  return JSON.parse(str);\n}\n\nexport function tryIntoThumbnailString(data: any) {\n  if (!data) return null;\n  try {\n    if (TypeUtil.isString(data)) return data;\n    return data?.url ?? data?.thumbnail?.url ?? null;\n  } catch {\n    return null;\n  }\n}","import {\n  Player,\n  PlayerNodeInitializationResult,\n  PlayerNodeInitializerOptions } from\n'../Player';\nimport { Track, TrackJSON, TrackSource } from './Track';\nimport { Util } from '../utils/Util';\nimport { GuildVoiceChannelResolvable } from 'discord.js';\nimport { SerializedType, tryIntoThumbnailString } from '../utils/serde';\nimport { TypeUtil } from '../utils/TypeUtil';\nimport { InvalidArgTypeError } from '../errors';\n\nexport type SerializedPlaylist = ReturnType<Playlist['serialize']>;\n\nexport interface PlaylistInitData {\n  /**\n   * The tracks of this playlist\n   */\n  tracks: Track[];\n  /**\n   * The playlist title\n   */\n  title: string;\n  /**\n   * The description\n   */\n  description: string;\n  /**\n   * The thumbnail\n   */\n  thumbnail: string;\n  /**\n   * The playlist type: `album` | `playlist`\n   */\n  type: 'album' | 'playlist';\n  /**\n   * The playlist source\n   */\n  source: TrackSource;\n  /**\n   * The playlist author\n   */\n  author: {\n    /**\n     * The author name\n     */\n    name: string;\n    /**\n     * The author url\n     */\n    url: string;\n  };\n  /**\n   * The playlist id\n   */\n  id: string;\n  /**\n   * The playlist url\n   */\n  url: string;\n  /**\n   * The raw playlist data\n   */\n  rawPlaylist?: any; // eslint-disable-line @typescript-eslint/no-explicit-any\n}\n\nexport interface PlaylistJSON {\n  /**\n   * The playlist id\n   */\n  id: string;\n  /**\n   * The playlist url\n   */\n  url: string;\n  /**\n   * The playlist title\n   */\n  title: string;\n  /**\n   * The playlist description\n   */\n  description: string;\n  /**\n   * The thumbnail\n   */\n  thumbnail: string;\n  /**\n   * The playlist type: `album` | `playlist`\n   */\n  type: 'album' | 'playlist';\n  /**\n   * The track source\n   */\n  source: TrackSource;\n  /**\n   * The playlist author\n   */\n  author: {\n    /**\n     * The author name\n     */\n    name: string;\n    /**\n     * The author url\n     */\n    url: string;\n  };\n  /**\n   * The tracks data (if any)\n   */\n  tracks: TrackJSON[];\n}\n\nexport class Playlist {\n  public readonly player: Player;\n  public tracks: Track[];\n  public title: string;\n  public description: string;\n  public thumbnail: string;\n  public type: 'album' | 'playlist';\n  public source: TrackSource;\n  public author: {\n    name: string;\n    url: string;\n  };\n  public id: string;\n  public url: string;\n  public readonly rawPlaylist?: any; // eslint-disable-line @typescript-eslint/no-explicit-any\n\n  /**\n   * Playlist constructor\n   * @param {Player} player The player\n   * @param {PlaylistInitData} data The data\n   */\n  constructor(player: Player, data: PlaylistInitData) {\n    /**\n     * The player\n     * @name Playlist#player\n     * @type {Player}\n     * @readonly\n     */\n    this.player = player;\n\n    /**\n     * The tracks in this playlist\n     * @name Playlist#tracks\n     * @type {Track[]}\n     */\n    this.tracks = data.tracks ?? [];\n\n    /**\n     * The author of this playlist\n     * @name Playlist#author\n     * @type {object}\n     */\n    this.author = data.author;\n\n    /**\n     * The description\n     * @name Playlist#description\n     * @type {string}\n     */\n    this.description = data.description;\n\n    /**\n     * The thumbnail of this playlist\n     * @name Playlist#thumbnail\n     * @type {string}\n     */\n    this.thumbnail = data.thumbnail;\n\n    /**\n     * The playlist type:\n     * - `album`\n     * - `playlist`\n     * @name Playlist#type\n     * @type {string}\n     */\n    this.type = data.type;\n\n    /**\n     * The source of this playlist:\n     * - `youtube`\n     * - `soundcloud`\n     * - `spotify`\n     * - `arbitrary`\n     * @name Playlist#source\n     * @type {string}\n     */\n    this.source = data.source;\n\n    /**\n     * The playlist id\n     * @name Playlist#id\n     * @type {string}\n     */\n    this.id = data.id;\n\n    /**\n     * The playlist url\n     * @name Playlist#url\n     * @type {string}\n     */\n    this.url = data.url;\n\n    /**\n     * The playlist title\n     * @type {string}\n     */\n    this.title = data.title;\n\n    /**\n     * @name Playlist#rawPlaylist\n     * @type {any}\n     * @readonly\n     */\n  }\n\n  *[Symbol.iterator]() {\n    yield* this.tracks;\n  }\n\n  /**\n   * Estimated duration of this playlist\n   */\n  public get estimatedDuration() {\n    return this.tracks.reduce((p, c) => p + c.durationMS, 0);\n  }\n\n  /**\n   * Formatted estimated duration of this playlist\n   */\n  public get durationFormatted() {\n    return Util.buildTimeCode(Util.parseMS(this.estimatedDuration));\n  }\n\n  /**\n   * JSON representation of this playlist\n   * @param {boolean} [withTracks=true] If it should build json with tracks\n   * @returns {PlaylistJSON}\n   */\n  toJSON(withTracks = true) {\n    const payload = {\n      id: this.id,\n      url: this.url,\n      title: this.title,\n      description: this.description,\n      thumbnail: this.thumbnail,\n      type: this.type,\n      source: this.source,\n      author: this.author,\n      tracks: [] as TrackJSON[]\n    };\n\n    if (withTracks) payload.tracks = this.tracks.map((m) => m.toJSON(true));\n\n    return payload as PlaylistJSON;\n  }\n\n  /**\n   * Serialize this playlist into reconstructable data\n   */\n  public serialize() {\n    return {\n      tracks: this.tracks.map((m) => m.serialize()),\n      title: this.title,\n      description: this.description,\n      thumbnail: TypeUtil.isString(this.thumbnail) ?\n      this.thumbnail :\n      tryIntoThumbnailString(this.thumbnail),\n      type: this.type,\n      source: this.source,\n      author: this.author,\n      id: this.id,\n      url: this.url,\n      $type: SerializedType.Playlist,\n      $encoder_version: this.player.version\n    };\n  }\n\n  /**\n   * Deserialize this playlist from serialized data\n   * @param player Player instance\n   * @param data Serialized data\n   */\n  public static fromSerialized(player: Player, data: SerializedPlaylist) {\n    if (data.$type !== SerializedType.Playlist)\n    throw new InvalidArgTypeError(\n      'data',\n      'SerializedPlaylist',\n      'malformed data'\n    );\n    return new Playlist(player, {\n      ...data,\n      tracks: data.tracks.map((m) => Track.fromSerialized(player, m))\n    });\n  }\n\n  /**\n   * Play this playlist to the given voice channel. If queue exists and another track is being played, this playlist will be added to the queue.\n   * @param channel Voice channel on which this playlist shall be played\n   * @param options Node initialization options\n   */\n  public async play<T = unknown>(\n  channel: GuildVoiceChannelResolvable,\n  options?: PlayerNodeInitializerOptions<T>)\n  : Promise<PlayerNodeInitializationResult<T>> {\n    const fn = this.player.play.bind(this.player);\n\n    return await fn(channel, this, options);\n  }\n}","import { TypeUtil } from './TypeUtil';\nimport { InfoRequiredError, InvalidArgTypeError } from '../errors';\nimport { fetch } from 'undici';\n\n// #region scary things below *sigh*\nconst spotifySongRegex =\n/^https?:\\/\\/(?:embed\\.|open\\.)(?:spotify\\.com\\/)(intl-([a-z]|[A-Z])+\\/)?(?:track\\/|\\?uri=spotify:track:)((\\w|-){22})(\\?si=.+)?$/;\nconst spotifyPlaylistRegex =\n/^https?:\\/\\/(?:embed\\.|open\\.)(?:spotify\\.com\\/)(intl-([a-z]|[A-Z])+\\/)?(?:playlist\\/|\\?uri=spotify:playlist:)((\\w|-){22})(\\?si=.+)?$/;\nconst spotifyAlbumRegex =\n/^https?:\\/\\/(?:embed\\.|open\\.)(?:spotify\\.com\\/)(intl-([a-z]|[A-Z])+\\/)?(?:album\\/|\\?uri=spotify:album:)((\\w|-){22})(\\?si=.+)?$/;\nconst vimeoRegex =\n/^(http|https)?:\\/\\/(www\\.|player\\.)?vimeo\\.com\\/(?:channels\\/(?:\\w+\\/)?|groups\\/([^/]*)\\/videos\\/|video\\/|)(\\d+)(?:|\\/\\?)$/;\nconst reverbnationRegex =\n/^https:\\/\\/(www.)?reverbnation.com\\/(.+)\\/song\\/(.+)$/;\nconst attachmentRegex = /^https?:\\/\\/.+$/;\nconst appleMusicSongRegex =\n/^https?:\\/\\/music\\.apple\\.com\\/.+?\\/(song|album)\\/.+?(\\/.+?\\?i=|\\/)([0-9]+)$/;\nconst appleMusicPlaylistRegex =\n/^https?:\\/\\/music\\.apple\\.com\\/.+?\\/playlist\\/.+\\/pl\\.(u-|pm-)?[a-zA-Z0-9]+$/;\nconst appleMusicAlbumRegex =\n/^https?:\\/\\/music\\.apple\\.com\\/.+?\\/album\\/.+\\/([0-9]+)$/;\nconst soundcloudTrackRegex =\n/^https?:\\/\\/(m.|www.)?soundcloud.com\\/(\\w|-)+\\/(\\w|-)+(.+)?$/;\nconst soundcloudPlaylistRegex =\n/^https?:\\/\\/(m.|www.)?soundcloud.com\\/(\\w|-)+\\/sets\\/(\\w|-)+(.+)?$/;\nconst youtubePlaylistRegex =\n/^https?:\\/\\/(www.)?youtube.com\\/playlist\\?list=((PL|FL|UU|LL|RD|OL)[a-zA-Z0-9-_]{16,41})$/;\nconst youtubeVideoURLRegex =\n/^((?:https?:)?\\/\\/)?((?:www|m)\\.)?((?:youtube\\.com|youtu.be))(\\/(?:[\\w-]+\\?v=|embed\\/|v\\/)?)([\\w-]+)(\\S+)?$/;\nconst youtubeVideoIdRegex = /^[a-zA-Z0-9-_]{11}$/;\n// discord-player://blob/uuid-v4\nconst discordPlayerBlobRegex = /^discord-player:\\/\\/blob\\/\\d+$/;\n// #endregion scary things above *sigh*\n\nconst DomainsMap = {\n  DiscordPlayer: ['discord-player'],\n  YouTube: [\n  'youtube.com',\n  'youtu.be',\n  'music.youtube.com',\n  'gaming.youtube.com',\n  'www.youtube.com',\n  'm.youtube.com'],\n\n  Spotify: ['open.spotify.com', 'embed.spotify.com'],\n  Vimeo: ['vimeo.com', 'player.vimeo.com'],\n  ReverbNation: ['reverbnation.com'],\n  SoundCloud: ['soundcloud.com'],\n  AppleMusic: ['music.apple.com']\n};\n\n// prettier-ignore\nconst redirectDomains = new Set([\n/^https?:\\/\\/spotify.link\\/[A-Za-z0-9]+$/,\n/^https:\\/\\/on\\.soundcloud\\.com\\/[a-zA-Z1-9]{0,17}$/]\n);\n\n/**\n * The search query type\n * This can be one of:\n * - AUTO\n * - YOUTUBE\n * - YOUTUBE_PLAYLIST\n * - SOUNDCLOUD_TRACK\n * - SOUNDCLOUD_PLAYLIST\n * - SOUNDCLOUD\n * - SPOTIFY_SONG\n * - SPOTIFY_ALBUM\n * - SPOTIFY_PLAYLIST\n * - SPOTIFY_SEARCH\n * - FACEBOOK\n * - VIMEO\n * - ARBITRARY\n * - REVERBNATION\n * - YOUTUBE_SEARCH\n * - YOUTUBE_VIDEO\n * - SOUNDCLOUD_SEARCH\n * - APPLE_MUSIC_SONG\n * - APPLE_MUSIC_ALBUM\n * - APPLE_MUSIC_PLAYLIST\n * - APPLE_MUSIC_SEARCH\n * - FILE\n * - AUTO_SEARCH\n * - DISCORD_PLAYER_BLOB\n * @typedef {string} QueryType\n */\nexport const QueryType = {\n  AUTO: 'auto',\n  YOUTUBE: 'youtube',\n  YOUTUBE_PLAYLIST: 'youtubePlaylist',\n  SOUNDCLOUD_TRACK: 'soundcloudTrack',\n  SOUNDCLOUD_PLAYLIST: 'soundcloudPlaylist',\n  SOUNDCLOUD: 'soundcloud',\n  SPOTIFY_SONG: 'spotifySong',\n  SPOTIFY_ALBUM: 'spotifyAlbum',\n  SPOTIFY_PLAYLIST: 'spotifyPlaylist',\n  SPOTIFY_SEARCH: 'spotifySearch',\n  FACEBOOK: 'facebook',\n  VIMEO: 'vimeo',\n  ARBITRARY: 'arbitrary',\n  REVERBNATION: 'reverbnation',\n  YOUTUBE_SEARCH: 'youtubeSearch',\n  YOUTUBE_VIDEO: 'youtubeVideo',\n  SOUNDCLOUD_SEARCH: 'soundcloudSearch',\n  APPLE_MUSIC_SONG: 'appleMusicSong',\n  APPLE_MUSIC_ALBUM: 'appleMusicAlbum',\n  APPLE_MUSIC_PLAYLIST: 'appleMusicPlaylist',\n  APPLE_MUSIC_SEARCH: 'appleMusicSearch',\n  FILE: 'file',\n  AUTO_SEARCH: 'autoSearch',\n  DISCORD_PLAYER_BLOB: 'discordPlayerBlob'\n} as const;\n\nexport type QueryType = (typeof QueryType)[keyof typeof QueryType];\n\nexport type SearchQueryType = keyof typeof QueryType | QueryType;\n\nexport interface ResolvedQuery {\n  type: (typeof QueryType)[keyof typeof QueryType];\n  query: string;\n}\n\nclass QueryResolver {\n  /**\n   * Query resolver\n   */\n  private constructor() {} // eslint-disable-line @typescript-eslint/no-empty-function\n\n  static get regex() {\n    return {\n      spotifyAlbumRegex,\n      spotifyPlaylistRegex,\n      spotifySongRegex,\n      vimeoRegex,\n      reverbnationRegex,\n      attachmentRegex,\n      appleMusicAlbumRegex,\n      appleMusicPlaylistRegex,\n      appleMusicSongRegex,\n      soundcloudTrackRegex,\n      soundcloudPlaylistRegex,\n      youtubePlaylistRegex,\n      discordPlayerBlobRegex\n    };\n  }\n\n  /**\n   * Pre-resolve redirect urls\n   */\n  static async preResolve(query: string, maxDepth = 5): Promise<string> {\n    if (!TypeUtil.isString(query))\n    throw new InvalidArgTypeError(query, 'string', typeof query);\n\n    for (const domain of redirectDomains) {\n      if (domain.test(query)) {\n        try {\n          const res = await fetch(query, {\n            method: 'GET',\n            redirect: 'follow'\n          });\n\n          if (!res.ok) break;\n\n          // spotify does not \"redirect\", it returns a page with js that redirects\n          if (/^https?:\\/\\/spotify.app.link\\/(.+)$/.test(res.url)) {\n            const body = await res.text();\n            const target = body.\n            split('https://open.spotify.com/track/')[1].\n            split('?si=')[0];\n\n            if (!target) break;\n\n            return `https://open.spotify.com/track/${target}`;\n          }\n          return maxDepth < 1 ?\n          res.url :\n          this.preResolve(res.url, maxDepth - 1);\n        } catch {\n          break;\n        }\n      }\n    }\n\n    return query;\n  }\n\n  /**\n   * Resolves the given search query\n   * @param {string} query The query\n   */\n  static resolve(\n  query: string,\n  fallbackSearchEngine: (typeof QueryType)[keyof typeof QueryType] = QueryType.AUTO_SEARCH)\n  : ResolvedQuery {\n    if (!TypeUtil.isString(query))\n    throw new InvalidArgTypeError(query, 'string', typeof query);\n    if (!query.length) throw new InfoRequiredError('query', String(query));\n\n    const resolver = (type: typeof fallbackSearchEngine, query: string) => ({\n      type,\n      query\n    });\n\n    if (discordPlayerBlobRegex.test(query))\n    return resolver(QueryType.DISCORD_PLAYER_BLOB, query);\n\n    try {\n      const url = new URL(query);\n\n      if (DomainsMap.YouTube.includes(url.host)) {\n        query = query.replace(/(m(usic)?|gaming)\\./, '').trim();\n        const playlistId = url.searchParams.get('list');\n        if (playlistId)\n        return resolver(\n          QueryType.YOUTUBE_PLAYLIST,\n          `https://www.youtube.com/${\n          url.searchParams.size === 1 ? 'playlist' : 'watch'}${\n          url.search}`\n        );\n        if (QueryResolver.validateId(query) || QueryResolver.validateURL(query))\n        return resolver(QueryType.YOUTUBE_VIDEO, query);\n        return resolver(fallbackSearchEngine, query);\n      } else if (DomainsMap.Spotify.includes(url.host)) {\n        query = query.replace(/intl-([a-zA-Z]+)\\//, '');\n        if (spotifyPlaylistRegex.test(query))\n        return resolver(QueryType.SPOTIFY_PLAYLIST, query);\n        if (spotifyAlbumRegex.test(query))\n        return resolver(QueryType.SPOTIFY_ALBUM, query);\n        if (spotifySongRegex.test(query))\n        return resolver(QueryType.SPOTIFY_SONG, query);\n        return resolver(fallbackSearchEngine, query);\n      } else if (DomainsMap.Vimeo.includes(url.host)) {\n        if (vimeoRegex.test(query)) return resolver(QueryType.VIMEO, query);\n        return resolver(fallbackSearchEngine, query);\n      } else if (DomainsMap.ReverbNation.includes(url.host)) {\n        if (reverbnationRegex.test(query))\n        return resolver(QueryType.REVERBNATION, query);\n        return resolver(fallbackSearchEngine, query);\n      } else if (DomainsMap.SoundCloud.includes(url.host)) {\n        if (soundcloudPlaylistRegex.test(query))\n        return resolver(QueryType.SOUNDCLOUD_PLAYLIST, query);\n        if (soundcloudTrackRegex.test(query))\n        return resolver(QueryType.SOUNDCLOUD_TRACK, query);\n        return resolver(fallbackSearchEngine, query);\n      } else if (DomainsMap.AppleMusic.includes(url.host)) {\n        if (appleMusicAlbumRegex.test(query))\n        return resolver(QueryType.APPLE_MUSIC_ALBUM, query);\n        if (appleMusicPlaylistRegex.test(query))\n        return resolver(QueryType.APPLE_MUSIC_PLAYLIST, query);\n        if (appleMusicSongRegex.test(query))\n        return resolver(QueryType.APPLE_MUSIC_SONG, query);\n        return resolver(fallbackSearchEngine, query);\n      } else {\n        return resolver(QueryType.ARBITRARY, query);\n      }\n    } catch {\n      return resolver(fallbackSearchEngine, query);\n    }\n  }\n\n  /**\n   * Parses vimeo id from url\n   * @param {string} query The query\n   * @returns {string}\n   */\n  static getVimeoID(query: string): string | null | undefined {\n    return QueryResolver.resolve(query).type === QueryType.VIMEO ?\n    query.split('/').filter(Boolean).pop() :\n    null;\n  }\n\n  static validateId(q: string) {\n    return youtubeVideoIdRegex.test(q);\n  }\n\n  static validateURL(q: string) {\n    return youtubeVideoURLRegex.test(q);\n  }\n}\n\nexport { QueryResolver };","import { User, UserResolvable } from 'discord.js';\nimport { BaseExtractor } from '../extractors/BaseExtractor';\nimport { Player } from '../Player';\nimport { Playlist } from './Playlist';\nimport { Track } from './Track';\nimport { QueryType, SearchQueryType } from '../utils/QueryResolver';\nimport type { RequestOptions } from 'http';\n\nexport interface SearchResultData {\n  query: string;\n  queryType?: SearchQueryType | QueryExtractorSearch | null;\n  extractor?: BaseExtractor | null;\n  playlist?: Playlist | null;\n  tracks?: Track[];\n  requestedBy?: User | null;\n}\n\nexport interface PlayOptions {\n  /**\n   * If this play was triggered for filters update\n   */\n  filtersUpdate?: boolean;\n  /**\n   * FFmpeg args passed to encoder\n   */\n  encoderArgs?: string[];\n  /**\n   * Time to seek to before playing\n   */\n  seek?: number;\n  /**\n   * If it should start playing the provided track immediately\n   */\n  immediate?: boolean;\n}\n\nexport type QueryExtractorSearch = `ext:${string}`;\n\nexport interface SearchOptions {\n  /**\n   * The user who requested this search\n   */\n  requestedBy?: UserResolvable;\n  /**\n   * The query search engine, can be extractor name to target specific one (custom)\n   */\n  searchEngine?: SearchQueryType | QueryExtractorSearch;\n  /**\n   * List of the extractors to block\n   */\n  blockExtractors?: string[];\n  /**\n   * If it should ignore query cache lookup\n   */\n  ignoreCache?: boolean;\n  /**\n   * Request options to be passed with the http request\n   */\n  requestOptions?: RequestOptions;\n  /**\n   * Fallback search engine to use\n   */\n  fallbackSearchEngine?: (typeof QueryType)[keyof typeof QueryType];\n}\n\nexport interface PlayerSearchResult {\n  playlist: Playlist | null;\n  tracks: Track[];\n}\n\nexport class SearchResult {\n  public constructor(public player: Player, private _data: SearchResultData) {\n    this._data.tracks?.forEach((track) => {\n      track.extractor ??= this._data.extractor || null;\n      track.requestedBy ??= _data.requestedBy || null;\n    });\n  }\n\n  public setQueryType(type: SearchQueryType | QueryExtractorSearch) {\n    this._data.queryType = type;\n    return this;\n  }\n\n  public setRequestedBy(user: User) {\n    this._data.requestedBy = user;\n    this._data.tracks?.forEach((track) => {\n      track.requestedBy = user;\n    });\n    return this;\n  }\n\n  public setExtractor(extractor: BaseExtractor) {\n    this._data.extractor = extractor;\n    this._data.tracks?.forEach((track) => {\n      track.extractor = extractor;\n    });\n    return this;\n  }\n\n  public setTracks(tracks: Track[]) {\n    this._data.tracks = tracks;\n    return this;\n  }\n\n  public setQuery(query: string) {\n    this._data.query = query;\n    return this;\n  }\n\n  public setPlaylist(playlist: Playlist) {\n    this._data.playlist = playlist;\n    return this;\n  }\n\n  /**\n   * The search query\n   */\n  public get query() {\n    return this._data.query;\n  }\n\n  /**\n   * The search query type\n   */\n  public get queryType() {\n    return this._data.queryType || QueryType.AUTO;\n  }\n\n  /**\n   * The extractor\n   */\n  public get extractor() {\n    return this._data.extractor || null;\n  }\n\n  /**\n   * Playlist result\n   */\n  public get playlist() {\n    return this._data.playlist;\n  }\n\n  /**\n   * Tracks result\n   */\n  public get tracks() {\n    return this._data.tracks || [];\n  }\n\n  /**\n   * Requested by\n   */\n  public get requestedBy() {\n    return this._data.requestedBy || null;\n  }\n\n  /**\n   * Re-execute this search\n   */\n  public async execute() {\n    return this.player.search(this.query, {\n      searchEngine: this.queryType,\n      requestedBy: this.requestedBy!\n    });\n  }\n\n  /**\n   * If this search result is empty\n   */\n  public isEmpty() {\n    return !this.tracks.length;\n  }\n\n  /**\n   * If this search result has playlist\n   */\n  public hasPlaylist() {\n    return this.playlist != null;\n  }\n\n  /**\n   * If this search result has tracks\n   */\n  public hasTracks() {\n    return this.tracks.length > 0;\n  }\n\n  /**\n   * JSON representation of this search\n   */\n  public toJSON() {\n    return {\n      query: this.query,\n      queryType: this.queryType,\n      playlist: this.playlist?.toJSON(false) || null,\n      tracks: this.tracks.map((m) => m.toJSON(true)),\n      extractor: this.extractor?.identifier || null,\n      requestedBy: this.requestedBy?.toJSON() || null\n    };\n  }\n}","export type FiltersName = keyof QueueFilters;\n\n/**\n * Represents FFmpeg filters\n */\nexport interface QueueFilters {\n  bassboost_low?: boolean;\n  bassboost?: boolean;\n  bassboost_high?: boolean;\n  '8D'?: boolean;\n  vaporwave?: boolean;\n  nightcore?: boolean;\n  phaser?: boolean;\n  tremolo?: boolean;\n  vibrato?: boolean;\n  reverse?: boolean;\n  treble?: boolean;\n  normalizer?: boolean;\n  normalizer2?: boolean;\n  surrounding?: boolean;\n  pulsator?: boolean;\n  subboost?: boolean;\n  karaoke?: boolean;\n  flanger?: boolean;\n  gate?: boolean;\n  haas?: boolean;\n  mcompand?: boolean;\n  mono?: boolean;\n  mstlr?: boolean;\n  mstrr?: boolean;\n  compressor?: boolean;\n  expander?: boolean;\n  softlimiter?: boolean;\n  chorus?: boolean;\n  chorus2d?: boolean;\n  chorus3d?: boolean;\n  fadein?: boolean;\n  dim?: boolean;\n  earrape?: boolean;\n  lofi?: boolean;\n  silenceremove?: boolean;\n}\n\nconst bass = (g: number) => `bass=g=${g}:f=110:w=0.3`;\n\nexport class AudioFilters {\n  public constructor() {\n    return AudioFilters;\n  }\n\n  public static filters: Record<FiltersName, string> = {\n    bassboost_low: bass(15),\n    bassboost: bass(20),\n    bassboost_high: bass(30),\n    '8D': 'apulsator=hz=0.09',\n    vaporwave: 'aresample=48000,asetrate=48000*0.8',\n    nightcore: 'aresample=48000,asetrate=48000*1.25',\n    lofi: 'aresample=48000,asetrate=48000*0.9,extrastereo=m=2.5:c=disabled',\n    phaser: 'aphaser=in_gain=0.4',\n    tremolo: 'tremolo',\n    vibrato: 'vibrato=f=6.5',\n    reverse: 'areverse',\n    treble: 'treble=g=5',\n    normalizer2: 'dynaudnorm=g=101',\n    normalizer: 'acompressor',\n    surrounding: 'surround',\n    pulsator: 'apulsator=hz=1',\n    subboost: 'asubboost',\n    karaoke: 'stereotools=mlev=0.03',\n    flanger: 'flanger',\n    gate: 'agate',\n    haas: 'haas',\n    mcompand: 'mcompand',\n    mono: 'pan=mono|c0=.5*c0+.5*c1',\n    mstlr: 'stereotools=mode=ms>lr',\n    mstrr: 'stereotools=mode=ms>rr',\n    compressor: 'compand=points=-80/-105|-62/-80|-15.4/-15.4|0/-12|20/-7.6',\n    expander:\n    'compand=attacks=0:points=-80/-169|-54/-80|-49.5/-64.6|-41.1/-41.1|-25.8/-15|-10.8/-4.5|0/0|20/8.3',\n    softlimiter:\n    'compand=attacks=0:points=-80/-80|-12.4/-12.4|-6/-8|0/-6.8|20/-2.8',\n    chorus: 'chorus=0.7:0.9:55:0.4:0.25:2',\n    chorus2d: 'chorus=0.6:0.9:50|60:0.4|0.32:0.25|0.4:2|1.3',\n    chorus3d: 'chorus=0.5:0.9:50|60|40:0.4|0.32|0.3:0.25|0.4|0.3:2|2.3|1.3',\n    fadein: 'afade=t=in:ss=0:d=10',\n    dim: `afftfilt=\"'real=re * (1-clip((b/nb)*b,0,1))':imag='im * (1-clip((b/nb)*b,0,1))'\"`,\n    earrape: 'channelsplit,sidechaingate=level_in=64',\n    silenceremove: 'silenceremove=1:0:-50dB'\n  };\n\n  public static get<K extends FiltersName>(name: K) {\n    return this.filters[name] ?? name;\n  }\n\n  public static has<K extends FiltersName>(name: K) {\n    return name in this.filters;\n  }\n\n  public static *[Symbol.iterator](): IterableIterator<{\n    name: FiltersName;\n    value: string;\n  }> {\n    for (const [k, v] of Object.entries(this.filters)) {\n      yield { name: k as FiltersName, value: v as string };\n    }\n  }\n\n  public static get names() {\n    return Object.keys(this.filters) as FiltersName[];\n  }\n\n  // @ts-ignore\n  public static get length() {\n    return this.names.length;\n  }\n\n  public static toString() {\n    return this.names.map((m) => (this as any)[m]).join(','); // eslint-disable-line @typescript-eslint/no-explicit-any\n  }\n\n  /**\n   * Create ffmpeg args from the specified filters name\n   * @param filter The filter name\n   * @returns\n   */\n  public static create<K extends FiltersName>(filters?: (K | string)[]) {\n    if (!filters || !Array.isArray(filters)) return this.toString();\n    return filters.\n    filter((predicate) => typeof predicate === 'string').\n    map((m) => this.get(m as K)).\n    join(',');\n  }\n\n  /**\n   * Defines audio filter\n   * @param filterName The name of the filter\n   * @param value The ffmpeg args\n   */\n  public static define(filterName: string, value: string) {\n    this.filters[filterName as FiltersName] = value;\n  }\n\n  /**\n   * Defines multiple audio filters\n   * @param filtersArray Array of filters containing the filter name and ffmpeg args\n   */\n  public static defineBulk(filtersArray: {name: string;value: string;}[]) {\n    filtersArray.forEach((arr) => this.define(arr.name, arr.value));\n  }\n}","/* eslint-disable @typescript-eslint/no-explicit-any */\n// @ts-nocheck\n\nimport { ChannelType, GatewayDispatchEvents } from 'discord-api-types/v10';\nimport { createCompatClient } from './common';\nimport { Util } from '../utils/Util';\n\nimport type { DiscordGatewayAdapterCreator } from 'discord-voip';\nimport {\n  Client,\n  GatewayVoiceServerUpdateDispatchData,\n  GatewayVoiceStateUpdateDispatchData,\n  VoiceState } from\n'discord.js';\nimport type Oceanic from 'oceanic.js';\n\ntype OceanicUserResolvable = Oceanic.User | string | Oceanic.Member;\ntype OceanicGuildResolvable =\nOceanic.Guild |\nstring |\nOceanic.Member |\nOceanic.GuildChannel |\nOceanic.Role;\ntype OceanicChannelResolvable = Oceanic.GuildChannel | string;\n\nconst DiscordPlayerClientSymbol = Symbol('DiscordPlayerClient');\n\nexport function isOceanicClient(client: any): client is Oceanic.Client {\n  const { module, error } = Util.require('oceanic.js');\n\n  if (error) return false;\n\n  const oceanic = module as typeof import('oceanic.js');\n\n  return client instanceof oceanic.Client;\n}\n\nfunction declareProperty(target: any, key: string, value: any): T {\n  Reflect.set(target, key, value);\n}\n\nfunction getProperty<T>(target: any, key: string): T {\n  return Reflect.get(target, key);\n}\n\n/**\n * Allows Oceanic.js clients to be used with discord-player. When this method is called, discord-player creates a proxy object that intercepts certain methods and properties to make it compatible with discord-player.\n * @param client The Oceanic.js client to be used.\n * @returns The Oceanic.js client with discord-player compatibility.\n */\nexport function createOceanicCompat(client: Oceanic.Client): Client {\n  const { module, error } = Util.require('oceanic.js');\n\n  if (error) throw error;\n\n  const oceanic = module as typeof import('oceanic.js');\n\n  oceanicVoiceEventsHandler(client);\n\n  const oceanicProxy = new Proxy(client, {\n    get(target, p) {\n      switch (p) {\n        case 'users':\n          return oceanicUsersProxy(target, oceanic);\n        case 'guilds':\n          return oceanicGuildsProxy(target, oceanic);\n        case 'channels':\n          return oceanicChannelsProxy(target, oceanic);\n        case '__dp_voiceStateUpdate_proxy':\n          return (handler: (a, b) => void) =>\n          oceanicVoiceStateUpdateProxy(target, oceanicProxy, handler);\n        case 'incrementMaxListeners':\n          return () => {\n            // @ts-expect-error patching\n            client.setMaxListeners(client.getMaxListeners() + 1);\n          };\n        case 'decrementMaxListeners':\n          return () => {\n            // @ts-expect-error patching\n            const listeners = client.getMaxListeners() - 1;\n\n            // @ts-expect-error patching\n            client.setMaxListeners(listeners < 0 ? 1 : listeners);\n          };\n        default:\n          // @ts-expect-error patching\n          return target[p];\n      }\n    }\n  });\n\n  Reflect.set(oceanicProxy, DiscordPlayerClientSymbol, 'Oceanic');\n\n  return createCompatClient(oceanicProxy, 'Oceanic').\n  client as unknown as Client;\n}\n\nfunction oceanicVoiceStateUpdateProxy(\nclient: Oceanic.Client,\nproxy: Oceanic.Client,\nhandler: (a, b) => void)\n{\n  client.on('voiceStateUpdate', (member, oldState) => {\n    try {\n      const proxiedOldState = {\n        channelId: oldState.channelID,\n        serverMute: oldState.mute,\n        suppress: oldState.suppress,\n        guild: {\n          id: oldState.guild.id\n        },\n        member: {\n          id: oldState.user.id\n        }\n      } as VoiceState;\n\n      const me = member.guild.members.get(client.user.id);\n      const resolvedChannel = member.guild.channels.get(\n        member.voiceState.channelID\n      );\n\n      const proxiedNewState = {\n        channelId: member.voiceState.channelID,\n        serverMute: member.voiceState.mute,\n        suppress: member.voiceState.suppress,\n        channel: oceanicResolvedChannelProxy(resolvedChannel, client),\n        member: {\n          id: member.id\n        },\n        guild: {\n          id: member.guild.id,\n          members: {\n            me: {\n              id: me?.id,\n              voice: {\n                async setRequestToSpeak(value: boolean) {\n                  void value;\n                  return me?.voiceState;\n                  // if (me) {\n                  //   return me.voice.setRequestToSpeak(value);\n                  // }\n                }\n              }\n            }\n          }\n        }\n      } as VoiceState;\n\n      return handler(proxiedNewState, proxiedOldState);\n    } catch {\n\n      /* noop */}\n  });\n}\n\nfunction oceanicVoiceEventsHandler(client: Oceanic.Client) {\n  let adapters = getProperty<Map<string, any>>(client, 'adapters');\n\n  if (!adapters) {\n    const collection = new Map<string, any>();\n    adapters = collection;\n    declareProperty(client, 'adapters', collection);\n  }\n\n  client.on('shardDisconnect', (_, shardId) => {\n    for (const [guildId, adapter] of adapters.entries()) {\n      if (client.guilds.get(guildId)?.shard.id === shardId) {\n        adapter.destroy();\n      }\n    }\n  });\n\n  client.on('packet', (packet) => {\n    switch (packet.t) {\n      case GatewayDispatchEvents.VoiceServerUpdate:{\n          const payload = packet.d as GatewayVoiceServerUpdateDispatchData;\n          adapters.get(payload.guild_id)?.onVoiceServerUpdate(payload);\n          return;\n        }\n      case GatewayDispatchEvents.VoiceStateUpdate:{\n          const payload = packet.d as GatewayVoiceStateUpdateDispatchData;\n\n          if (\n          payload.guild_id &&\n          payload.session_id &&\n          payload.user_id === client.user.id)\n          {\n            adapters.get(payload.guild_id)?.onVoiceStateUpdate(payload);\n          }\n\n          return;\n        }\n      default:\n        break;\n    }\n  });\n}\n\nfunction oceanicChannelsProxy(\nclient: Oceanic.Client,\noceanic: typeof import('oceanic.js'))\n{\n  const handler = {\n    client,\n    get cache() {\n      return {\n        get(id: string) {\n          return client.getChannel(id);\n        },\n        has(id: string) {\n          return id in client.channelGuildMap;\n        }\n      };\n    },\n    resolve(resolvable: string | OceanicChannelResolvable) {\n      if (typeof resolvable === 'string') {\n        return oceanicResolvedChannelProxy(\n          this.client.getChannel(resolvable) as Oceanic.GuildChannel,\n          client\n        );\n      }\n\n      if (resolvable instanceof oceanic.GuildChannel) {\n        return oceanicResolvedChannelProxy(resolvable, client);\n      }\n    },\n    resolveId(resolvable: OceanicChannelResolvable) {\n      const channel = this.resolve(resolvable);\n      return channel?.id;\n    }\n  };\n\n  return handler;\n}\n\nfunction oceanicResolvedChannelProxy(\nchannel: Oceanic.GuildChannel | undefined,\nclient: Oceanic.Client)\n: Oceanic.GuildChannel | undefined {\n  if (!channel) return;\n\n  return new Proxy(channel, {\n    get(target, p) {\n      switch (p) {\n        case 'guild':\n          return oceanicVoiceAdapterProxy(target.guild, client);\n        case 'members':\n          return (target as Oceanic.VoiceChannel).voiceMembers;\n        case 'isVoiceBased':\n          return () =>\n          target.type === ChannelType.GuildVoice ||\n          target.type === ChannelType.GuildStageVoice;\n        case 'isVoice':\n          return () => target.type === ChannelType.GuildVoice;\n        case 'isStage':\n          return () => target.type === ChannelType.GuildStageVoice;\n        default:\n          // @ts-expect-error patching\n          return target[p];\n      }\n    }\n  });\n}\n\nfunction oceanicVoiceAdapterProxy(\nguild: Oceanic.Guild | undefined,\nclient: Oceanic.Client)\n: Oceanic.Guild | undefined {\n  if (!guild) return;\n\n  return new Proxy(guild, {\n    get(target, p) {\n      if (p === 'voiceAdapterCreator') {\n        return oceanicVoiceAdapterCreator(target, client);\n      }\n\n      // @ts-expect-error patching\n      return target[p];\n    }\n  });\n}\n\nfunction oceanicVoiceAdapterCreator(\nguild: Oceanic.Guild,\nclient: Oceanic.Client)\n: DiscordGatewayAdapterCreator {\n  return (methods) => {\n    let adapters = getProperty<Map<string, typeof methods>>(client, 'adapters');\n\n    if (!adapters) {\n      const collection = new Map<string, typeof methods>();\n      adapters = collection;\n      declareProperty(client, 'adapters', collection);\n    }\n\n    adapters.set(guild.id, methods);\n\n    return {\n      sendPayload(payload) {\n        if (guild.shard.status !== 'ready') return false;\n        guild.shard.send(payload.op, payload.d);\n        return true;\n      },\n      destroy() {\n        adapters.delete(guild.id);\n      }\n    };\n  };\n}\n\nfunction oceanicGuildsProxy(\nclient: Oceanic.Client,\noceanic: typeof import('oceanic.js'))\n{\n  return new Proxy(client.guilds, {\n    get(target, p) {\n      if (p === 'cache') {\n        return target;\n      }\n\n      if (p === 'resolve' || p === 'resolveId') {\n        const resolver = function (resolvable: OceanicGuildResolvable) {\n          if (typeof resolvable === 'string') {\n            return target.get(resolvable);\n          }\n\n          if (resolvable instanceof oceanic.Guild) {\n            return resolvable;\n          }\n\n          if (\n          resolvable instanceof oceanic.Member ||\n          resolvable instanceof oceanic.Guild ||\n          resolvable instanceof oceanic.GuildChannel ||\n          resolvable instanceof oceanic.Role)\n          {\n            return resolvable.guild;\n          }\n        };\n\n        if (p === 'resolve') {\n          return resolver;\n        }\n\n        return (resolvable: OceanicGuildResolvable) => {\n          const guild = resolver(resolvable);\n          return guild?.id;\n        };\n      }\n\n      // @ts-expect-error patching\n      return target[p];\n    }\n  });\n}\n\nfunction oceanicUsersProxy(\nclient: Oceanic.Client,\noceanic: typeof import('oceanic.js'))\n{\n  return new Proxy(client.users, {\n    get(target, p) {\n      if (p === 'cache') {\n        return target;\n      }\n\n      if (p === 'resolve' || p === 'resolveId') {\n        const resolver = function (resolvable: OceanicUserResolvable) {\n          if (typeof resolvable === 'string') {\n            return target.get(resolvable);\n          }\n\n          if (resolvable instanceof oceanic.User) {\n            return resolvable;\n          }\n\n          if (resolvable instanceof oceanic.Member) {\n            return resolvable.user;\n          }\n        };\n\n        if (p === 'resolve') {\n          return resolver;\n        }\n\n        return (resolvable: OceanicUserResolvable) => {\n          const user = resolver(resolvable);\n          return user?.id;\n        };\n      }\n\n      // @ts-expect-error patching\n      return target[p];\n    }\n  });\n}","import { DefaultListener } from '@discord-player/utils';\nimport { ListenerSignature } from '@discord-player/utils';\nimport { EventEmitter } from '@discord-player/utils';\nimport { Util } from './Util';\n\nexport class PlayerEventsEmitter<\n  L extends ListenerSignature<L> = DefaultListener> extends\nEventEmitter<L> {\n  #hasDebugger = false;\n  public constructor(public requiredEvents: Array<keyof L> = []) {\n    super();\n  }\n\n  public on<K extends keyof L>(name: K, listener: L[K]) {\n    if (name === 'debug') {\n      this.#hasDebugger = true;\n    }\n\n    return super.on(name, listener);\n  }\n\n  public once<K extends keyof L>(name: K, listener: L[K]) {\n    if (name === 'debug') {\n      this.#hasDebugger = true;\n    }\n\n    return super.once(name, listener);\n  }\n\n  public addListener<K extends keyof L>(name: K, listener: L[K]) {\n    if (name === 'debug') {\n      this.#hasDebugger = true;\n    }\n\n    return super.addListener(name, listener);\n  }\n\n  public off<K extends keyof L>(name: K, listener: L[K]) {\n    this.#hasDebugger = this.listenerCount('debug' as K) > 0;\n\n    return super.off(name, listener);\n  }\n\n  public removeListener<K extends keyof L>(name: K, listener: L[K]) {\n    this.#hasDebugger = this.listenerCount('debug' as K) > 0;\n\n    return super.removeListener(name, listener);\n  }\n\n  public removeAllListeners<K extends keyof L>(name?: K) {\n    this.#hasDebugger = this.listenerCount('debug' as K) > 0;\n\n    return super.removeAllListeners(name);\n  }\n\n  public emit<K extends keyof L>(name: K, ...args: Parameters<L[K]>) {\n    if (\n    this.requiredEvents.includes(name) &&\n    !this.eventNames().includes(name))\n    {\n      // eslint-disable-next-line no-console\n      console.error(...args);\n      Util.warn(\n        `No event listener found for event \"${String(\n          name\n        )}\". Events ${this.requiredEvents.\n        map((m) => `\"${String(m)}\"`).\n        join(', ')} must have event listeners.`,\n        'UnhandledEventsWarning'\n      );\n      return false;\n    }\n\n    return super.emit(name, ...args);\n  }\n\n  public get hasDebugger() {\n    return this.#hasDebugger;\n  }\n}","import { User } from 'discord.js';\nimport { Readable } from 'stream';\nimport { Playlist } from '../fabric/Playlist';\nimport { Track } from '../fabric/Track';\nimport { ExtractorExecutionContext } from './ExtractorExecutionContext';\nimport type { RequestOptions } from 'http';\nimport { NotImplementedError } from '../errors';\nimport type { GuildQueueHistory } from '../queue';\nimport { SearchQueryType } from '../utils/QueryResolver';\nimport { PlayerEvents } from '../Player';\n\nexport type ExtractorStreamable =\nReadable |\nstring |\n{\n  $fmt: string;\n  stream: Readable;\n};\n\nexport class BaseExtractor<T extends object = object> {\n  /**\n   * Identifier for this extractor\n   */\n  public static identifier = 'com.discord-player.extractor';\n\n  /**\n   * Priority of this extractor. Higher value means higher priority (will be executed first).\n   */\n  public priority = 1;\n\n  /**\n   * A list of query protocols that this extractor supports.\n   */\n  public protocols: string[] = [];\n\n  /**\n   * Handle bridge query creation\n   * @param track The track to build query for\n   */\n  public createBridgeQuery = (track: Track) =>\n  `${track.title} by ${track.author} official audio`;\n\n  /**\n   * Extractor constructor\n   * @param context Context that instantiated this extractor\n   * @param options Initialization options for this extractor\n   */\n  public constructor(\n  public context: ExtractorExecutionContext,\n  public options: T = <T> {})\n  {}\n\n  /**\n   * Identifier of this extractor\n   */\n  public get identifier() {\n    return (this.constructor as typeof BaseExtractor).identifier;\n  }\n\n  /**\n   * Reconfigures this extractor\n   * @param options The new options to apply\n   */\n  public async reconfigure(options: T) {\n    this.options = options;\n    await this.deactivate();\n    await this.activate();\n  }\n\n  /**\n   * This method will be executed when this extractor is activated\n   */\n  public async activate() {\n    // executed when this extractor is activated\n    return;\n  }\n\n  /**\n   * This method will be executed when this extractor is deactivated\n   */\n  public async deactivate() {\n    // executed when this extractor is deactivated\n    return;\n  }\n\n  /**\n   * Validate incoming query\n   * @param query The query to validate\n   */\n  public async validate(\n  query: string,\n  type?: SearchQueryType | null)\n  : Promise<boolean> {\n    void type;\n    return false;\n  }\n\n  /**\n   * Stream the given track\n   * @param info The track to stream\n   */\n  public async stream(info: Track): Promise<ExtractorStreamable> {\n    void info;\n    throw new NotImplementedError(`${this.constructor.name}.stream()`);\n  }\n\n  /**\n   * Handle the given query\n   * @param query The query to handle\n   */\n  public async handle(\n  query: string,\n  context: ExtractorSearchContext)\n  : Promise<ExtractorInfo> {\n    void context;\n    throw new NotImplementedError(`${this.constructor.name}.handle()`);\n  }\n\n  /**\n   * Get related tracks for the given track\n   * @param track The track source\n   */\n  public async getRelatedTracks(\n  track: Track,\n  history: GuildQueueHistory)\n  : Promise<ExtractorInfo> {\n    void track;\n    void history;\n    throw new NotImplementedError(\n      `${this.constructor.name}.getRelatedTracks()`\n    );\n  }\n\n  /**\n   * A stream middleware to handle streams before passing it to the player\n   * @param stream The incoming stream\n   * @param next The next function\n   */\n  public handlePostStream(stream: Readable, next: NextFunction) {\n    return next(null, stream);\n  }\n\n  /**\n   * Dispatch an event to the player\n   * @param event The event to dispatch\n   * @param args The data to dispatch\n   */\n  public emit<K extends keyof PlayerEvents>(\n  event: K,\n  ...args: Parameters<PlayerEvents[K]>)\n  {\n    return this.context.player.emit(event, ...args);\n  }\n\n  /**\n   * Create extractor response\n   * @param playlist The playlist\n   * @param tracks The track array\n   */\n  public createResponse(\n  playlist?: Playlist | null,\n  tracks: Track[] = playlist?.tracks || [])\n  : ExtractorInfo {\n    return { playlist: playlist || null, tracks };\n  }\n\n  /**\n   * Write debug message\n   * @param message The debug message\n   */\n  public debug(message: string) {\n    return this.context.player.debug(message);\n  }\n\n  /**\n   * A flag to indicate `Demuxable` stream support for `opus`/`ogg/opus`/`webm/opus` formats.\n   */\n  public get supportsDemux() {\n    return !!this.context.player.options.skipFFmpeg;\n  }\n\n  /**\n   * Handle stream extraction for another extractor\n   * @param track The track to bridge\n   * @param sourceExtractor The source extractor\n   */\n  public async bridge(\n  track: Track,\n  sourceExtractor: BaseExtractor | null)\n  : Promise<ExtractorStreamable | null> {\n    void sourceExtractor;\n    return null;\n  }\n}\n\nexport type NextFunction = (error?: Error | null, stream?: Readable) => void;\n\nexport interface ExtractorInfo {\n  playlist: Playlist | null;\n  tracks: Track[];\n}\n\nexport interface ExtractorSearchContext {\n  type?: SearchQueryType | null;\n  requestedBy?: User | null;\n  requestOptions?: RequestOptions;\n  protocol?: string | null;\n}","import { Player } from '../Player';\nimport { Collection } from '@discord-player/utils';\nimport { BaseExtractor, ExtractorStreamable } from './BaseExtractor';\nimport { Util } from '../utils/Util';\nimport { PlayerEventsEmitter } from '../utils/PlayerEventsEmitter';\nimport { TypeUtil } from '../utils/TypeUtil';\nimport { Track } from '../fabric';\nimport { createContext } from '../hooks';\nimport { BridgeFailedError } from '../errors';\n\nexport interface ExtractorSession {\n  id: string;\n  attemptedExtractors: Set<string>;\n  bridgeAttemptedExtractors: Set<string>;\n}\n\nexport interface ExtractorExecutionEvents {\n  /**\n   * Emitted when a extractor is registered\n   * @param context The context where extractor was registered\n   * @param extractor The extractor that was registered\n   */\n  registered: (\n  context: ExtractorExecutionContext,\n  extractor: BaseExtractor)\n  => unknown;\n  /**\n   * Emitted when a extractor is unregistered\n   * @param context The context where extractor was unregistered\n   * @param extractor The extractor that was unregistered\n   */\n  unregistered: (\n  context: ExtractorExecutionContext,\n  extractor: BaseExtractor)\n  => unknown;\n  /**\n   * Emitted when a extractor is activated\n   * @param context The context where this event occurred\n   * @param extractor The extractor which was activated\n   */\n  activate: (\n  context: ExtractorExecutionContext,\n  extractor: BaseExtractor)\n  => unknown;\n  /**\n   * Emitted when a extractor is deactivated\n   * @param context The context where this event occurred\n   * @param extractor The extractor which was deactivated\n   */\n  deactivate: (\n  context: ExtractorExecutionContext,\n  extractor: BaseExtractor)\n  => unknown;\n  /**\n   * Emitted when a extractor fails to activate/deactivate\n   * @param context The context where this event occurred\n   * @param extractor The extractor which was deactivated\n   */\n  error: (\n  context: ExtractorExecutionContext,\n  extractor: BaseExtractor,\n  error: Error)\n  => unknown;\n}\n\nexport class ExtractorExecutionContext extends PlayerEventsEmitter<ExtractorExecutionEvents> {\n  /**\n   * The extractors store\n   */\n  public store = new Collection<string, BaseExtractor>();\n\n  public readonly context = createContext<ExtractorSession>();\n\n  public constructor(public player: Player) {\n    super(['error']);\n  }\n\n  /**\n   * Get the current execution id\n   */\n  public getExecutionId(): string | null {\n    return this.context.consume()?.id ?? null;\n  }\n\n  /**\n   * Get the current execution context\n   */\n  public getContext() {\n    return this.context.consume() ?? null;\n  }\n\n  public async loadDefault() {\n    const sample = `\\timport { DefaultExtractors } from '@discord-player/extractor';\\n\\tawait player.extractors.loadMulti(DefaultExtractors);`;\n\n    throw new Error(\n      `extractors.loadDefault() is no longer supported. Use extractors.loadMulti instead. Example:\\n${sample}\\n`\n    );\n  }\n\n  /**\n   * Load a bundle of extractors.\n   * @example import { DefaultExtractors } from '@discord-player/extractor';\n   *\n   * await player.extractors.loadMulti(DefaultExtractors);\n   */\n  public async loadMulti<\n    O extends object,\n    T extends (typeof BaseExtractor<O>)[],\n    R extends Record<\n      T[number]['identifier'],\n      ConstructorParameters<T[number]>[1]>>(\n\n  bundle: T, options: R = {} as R) {\n    bundle.forEach((ext) => {\n      // @ts-ignore\n      this.register(ext, options?.[ext.identifier] || {});\n    });\n\n    return { success: true, error: null };\n  }\n\n  /**\n   * Validate if the given extractor is registered\n   * @param identifier The extractor identifier\n   */\n  public isRegistered(identifier: string) {\n    return this.store.has(identifier);\n  }\n\n  /**\n   * The size of registered extractors\n   */\n  public get size() {\n    return this.store.size;\n  }\n\n  /**\n   * Get single extractor\n   * @param identifier The extractor to get\n   */\n  public get(identifier: string) {\n    return this.store.get(identifier);\n  }\n\n  /**\n   * Register single extractor\n   * @param _extractor The extractor to register\n   * @param options Options supplied to the extractor\n   */\n  public async register<O extends object, T extends typeof BaseExtractor<O>>(\n  _extractor: T,\n  options: ConstructorParameters<T>['1'])\n  : Promise<InstanceType<T> | null> {\n    if (\n    typeof _extractor.identifier !== 'string' ||\n    this.store.has(_extractor.identifier))\n\n    return null;\n    const extractor = new _extractor(this, options);\n\n    try {\n      this.store.set(_extractor.identifier, extractor);\n      if (this.player.hasDebugger)\n      this.player.debug(`${_extractor.identifier} extractor loaded!`);\n      this.emit('registered', this, extractor);\n      await extractor.activate();\n      if (this.player.hasDebugger)\n      this.player.debug(`${_extractor.identifier} extractor activated!`);\n      this.emit('activate', this, extractor);\n      return extractor as unknown as InstanceType<T>;\n    } catch (e) {\n      this.store.delete(_extractor.identifier);\n      if (this.player.hasDebugger)\n      this.player.debug(\n        `${_extractor.identifier} extractor failed to activate! Error: ${e}`\n      );\n      this.emit('error', this, extractor, e as Error);\n      return null;\n    }\n  }\n\n  /**\n   * Unregister single extractor\n   * @param _extractor The extractor to unregister\n   */\n  public async unregister<K extends string | BaseExtractor>(_extractor: K) {\n    const extractor =\n    typeof _extractor === 'string' ?\n    this.store.get(_extractor) :\n    this.store.find((r) => r === _extractor);\n    if (!extractor) return;\n\n    try {\n      const key =\n      extractor.identifier || this.store.findKey((e) => e === extractor)!;\n      this.store.delete(key);\n      if (this.player.hasDebugger)\n      this.player.debug(`${extractor.identifier} extractor disabled!`);\n      this.emit('unregistered', this, extractor);\n      await extractor.deactivate();\n      if (this.player.hasDebugger)\n      this.player.debug(`${extractor.identifier} extractor deactivated!`);\n      this.emit('deactivate', this, extractor);\n    } catch (e) {\n      if (this.player.hasDebugger)\n      this.player.debug(\n        `${extractor.identifier} extractor failed to deactivate!`\n      );\n      this.emit('error', this, extractor, e as Error);\n    }\n  }\n\n  /**\n   * Unregister all extractors\n   */\n  public async unregisterAll() {\n    try {\n      await Promise.all(this.store.map((e) => this.unregister(e)));\n    } catch {\n\n      // do nothing\n    }}\n\n  /**\n   * Run all the extractors\n   * @param fn The runner function\n   * @param filterBlocked Filter blocked extractors\n   */\n  public async run<T = unknown>(\n  fn: ExtractorExecutionFN<T>,\n  filterBlocked = true)\n  {\n    const blocked = this.player.options.blockExtractors ?? [];\n\n    if (!this.store.size) {\n      Util.warn(\n        'Skipping extractors execution since zero extractors were registered',\n        'NoExtractors'\n      );\n      return;\n    }\n\n    // sort by priority so that extractors with higher priority are executed first\n    const extractors = this.store.sort((a, b) => b.priority - a.priority);\n\n    let err: Error | null = null,\n      lastExt: BaseExtractor | null = null;\n\n    for (const ext of extractors.values()) {\n      if (filterBlocked && blocked.some((e) => e === ext.identifier)) continue;\n      if (this.player.hasDebugger)\n      this.player.debug(`Executing extractor ${ext.identifier}...`);\n      const result = await fn(ext).then(\n        (res) => {\n          return res;\n        },\n        (e) => {\n          if (this.player.hasDebugger)\n          this.player.debug(\n            `Extractor ${ext.identifier} failed with error: ${e}`\n          );\n\n          return TypeUtil.isError(e) ? e : new Error(`${e}`);\n        }\n      );\n\n      lastExt = ext;\n\n      if (result && !TypeUtil.isError(result)) {\n        if (this.player.hasDebugger)\n        this.player.debug(\n          `Extractor ${ext.identifier} executed successfully!`\n        );\n\n        return {\n          extractor: ext,\n          error: null,\n          result\n        } as ExtractorExecutionResult<T>;\n      } else if (TypeUtil.isError(result)) {\n        err = result;\n      }\n    }\n\n    if (err)\n    return {\n      extractor: lastExt!,\n      error: err,\n      result: false\n    } as ExtractorExecutionResult<false>;\n  }\n\n  /**\n   * Request bridge for a track\n   * @param track The track to request bridge for\n   * @param sourceExtractor The source extractor of the track\n   */\n  public async requestBridge(\n  track: Track,\n  sourceExtractor: BaseExtractor | null = track.extractor)\n  {\n    const previouslyAttempted =\n    this.getContext()?.bridgeAttemptedExtractors ?? new Set<string>();\n\n    const result = await this.run<ExtractorStreamable>(async (ext) => {\n      if (sourceExtractor && ext.identifier === sourceExtractor.identifier)\n      return false;\n      if (previouslyAttempted.has(ext.identifier)) return false;\n\n      previouslyAttempted.add(ext.identifier);\n\n      const result = await ext.bridge(track, sourceExtractor);\n\n      if (!result) return false;\n\n      return result;\n    });\n\n    if (!result?.result)\n    throw new BridgeFailedError(\n      this.getExecutionId(),\n      result?.error?.stack ||\n      result?.error?.message ||\n      'No extractors available to bridge'\n    );\n\n    track.bridgedExtractor = result.extractor;\n\n    return result;\n  }\n\n  /**\n   * Request bridge from the specified extractor\n   * @param track The track to request bridge for\n   * @param sourceExtractor The source extractor of the track\n   * @param targetExtractor The target extractor to bridge to\n   */\n  public async requestBridgeFrom(\n  track: Track,\n  sourceExtractor: BaseExtractor | null,\n  targetExtractor: ExtractorResolvable)\n  {\n    const target = this.resolve(targetExtractor);\n    if (!target) return null;\n    return target.bridge(track, sourceExtractor);\n  }\n\n  /**\n   * Check if extractor is disabled\n   */\n  public isDisabled(identifier: string) {\n    return this.player.options.blockExtractors?.includes(identifier) ?? false;\n  }\n\n  /**\n   * Check if extractor is enabled\n   */\n  public isEnabled(identifier: string) {\n    return !this.isDisabled(identifier);\n  }\n\n  /**\n   * Resolve extractor identifier\n   */\n  public resolveId(resolvable: ExtractorResolvable) {\n    return typeof resolvable === 'string' ? resolvable : resolvable.identifier;\n  }\n\n  /**\n   * Resolve extractor\n   */\n  public resolve(resolvable: ExtractorResolvable) {\n    return typeof resolvable === 'string' ? this.get(resolvable) : resolvable;\n  }\n}\n\nexport interface ExtractorExecutionResult<T = unknown> {\n  extractor: BaseExtractor;\n  error: Error | null;\n  result: T;\n}\n\nexport type ExtractorExecutionFN<T = unknown> = (\nextractor: BaseExtractor)\n=> Promise<T | boolean>;\n\nexport type ExtractorResolvable = string | BaseExtractor;","import { AsyncLocalStorage } from 'node:async_hooks';\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype unsafe = any;\n\n/**\n * The receiver function that will be called when the context is provided\n */\nexport type ContextReceiver<R> = () => R;\n\nexport class Context<T> {\n  private storage = new AsyncLocalStorage<T>();\n\n  public constructor(private defaultValue?: T) {}\n\n  /**\n   * Exit out of this context\n   */\n  public exit(scope: ContextReceiver<void>) {\n    this.storage.exit(scope);\n  }\n\n  /**\n   * Whether the context is lost\n   */\n  public get isLost() {\n    return this.storage.getStore() === undefined;\n  }\n\n  /**\n   * Get the current value of the context. If the context is lost and no default value is provided, undefined will be returned.\n   */\n  public consume(): T | undefined {\n    const data = this.storage.getStore();\n\n    if (data === undefined && this.defaultValue !== undefined)\n    return this.defaultValue;\n\n    return data;\n  }\n\n  /**\n   * Run a function within the context of this provider\n   */\n  public provide<R = unsafe>(value: T, receiver: ContextReceiver<R>): R {\n    if (value === undefined) {\n      throw new Error('Context value may not be undefined');\n    }\n\n    if (typeof receiver !== 'function') {\n      throw new Error('Context receiver must be a function');\n    }\n\n    return this.storage.run(value, receiver);\n  }\n}\n\n/**\n * Create a new context. The default value is optional.\n * @param defaultValue The default value of the context\n * @example const userContext = createContext();\n *\n *  // the value to provide\n *  const user = {\n *   id: 1,\n *   name: 'John Doe'\n *  };\n *\n *  // provide the context value to the receiver\n *  context.provide(user, handler);\n *\n *  function handler() {\n *    // get the context value\n *    const { id, name } = useContext(context);\n *\n *    console.log(id, name); // 1, John Doe\n *  }\n */\nexport function createContext<T = unsafe>(defaultValue?: T): Context<T> {\n  return new Context(defaultValue);\n}\n\n/**\n * Get the current value of the context. If the context is lost and no default value is provided, undefined will be returned.\n * @param context The context to get the value from\n * @example const value = useContext(context);\n */\nexport function useContext<T = unsafe>(context: Context<T>): T | undefined {\n  return context.consume();\n}","import { Collection } from '@discord-player/utils';\n\nexport const globalRegistry = new Collection<string, unknown>();","import { globalRegistry } from './_container';\n\nexport function getGlobalRegistry() {\n  return globalRegistry;\n}","import { Guild } from 'discord.js';\nimport { Player } from '../Player';\nimport { IllegalHookInvocationError } from '../errors';\nimport { createContext, useContext } from './context/async-context';\nimport { getGlobalRegistry } from '../utils/__internal__';\n\nexport interface HooksCtx {\n  guild: Guild;\n}\n\nexport const SUPER_CONTEXT = createContext<Player>();\n\nconst getFallbackContext = () => {\n  return getGlobalRegistry().get('@[player]') as Player | undefined;\n};\n\n/**\n * @private\n */\nexport function useHooksContext(hookName: string, mainOnly = false) {\n  let isFallback = false;\n\n  let player: Player | undefined;\n\n  if (!(player = SUPER_CONTEXT.consume())) {\n    player = getFallbackContext();\n    isFallback = true;\n  }\n\n  if (!player)\n  throw new IllegalHookInvocationError(\n    'discord-player',\n    `Player context is not available, ${\n    isFallback ?\n    'did you forget to initialize the player with `new Player(client)`?' :\n    'is it being called inside <Player>.context.provide()?'}`\n\n  );\n\n  if (mainOnly) return { player, context: {} as HooksCtx, isFallback };\n\n  let context: HooksCtx | undefined;\n\n  if (!isFallback) {\n    context = useContext(player.context);\n    if (!context)\n    throw new IllegalHookInvocationError(\n      hookName,\n      `${hookName} must be called inside a player context created by <Player>.context.provide()`\n    );\n  } else {\n    context = {\n      get guild() {\n        throw new IllegalHookInvocationError(\n          hookName,\n          `${hookName} must be called with an explicit guild argument when not inside a player context`\n        );\n      }\n    } as unknown as HooksCtx;\n  }\n\n  return { context, player, isFallback };\n}","import { GuildQueueHistory, NodeResolvable } from '../queue';\nimport { useHooksContext } from './common';\n\n/**\n * Fetch guild queue history\n * @param node guild queue node resolvable\n */\nexport function useHistory<Meta = unknown>(): GuildQueueHistory<Meta> | null;\nexport function useHistory<Meta = unknown>(\nnode: NodeResolvable)\n: GuildQueueHistory<Meta> | null;\nexport function useHistory<Meta = unknown>(\nnode?: NodeResolvable)\n: GuildQueueHistory<Meta> | null {\n  const { context, player } = useHooksContext('useHistory');\n\n  const queue = player.queues.get<Meta>(node ?? context.guild.id);\n  if (!queue) return null;\n\n  return queue.history;\n}","import { GuildQueuePlayerNode, NodeResolvable } from '../queue';\nimport { useHooksContext } from './common';\n\n/**\n * Fetch guild queue player node\n * @param node Guild queue node resolvable\n */\nexport function usePlayer<Meta = unknown>(): GuildQueuePlayerNode<Meta> | null;\nexport function usePlayer<Meta = unknown>(\nnode: NodeResolvable)\n: GuildQueuePlayerNode<Meta> | null;\nexport function usePlayer<Meta = unknown>(\nnode?: NodeResolvable)\n: GuildQueuePlayerNode<Meta> | null {\n  const { context, player } = useHooksContext('usePlayer');\n  const queue = player.queues.get<Meta>(node ?? context.guild.id);\n  if (!queue) return null;\n\n  return queue.node;\n}","import { GuildQueue, NodeResolvable } from '../queue';\nimport { useHooksContext } from './common';\n\n/**\n * Fetch guild queue.\n * @param node Guild queue node resolvable. Defaults to inferred guild from context.\n */\nexport function useQueue<Meta = unknown>(): GuildQueue<Meta> | null;\nexport function useQueue<Meta = unknown>(\nnode: NodeResolvable)\n: GuildQueue<Meta> | null;\nexport function useQueue<Meta = unknown>(\nnode?: NodeResolvable)\n: GuildQueue<Meta> | null {\n  const { context, player } = useHooksContext('useQueue');\n  const queue = player.queues.resolve<Meta>(node ?? context.guild.id);\n  if (!queue) return null;\n\n  return queue;\n}","import { useHooksContext } from './common';\n\n/**\n * Fetch main player instance\n */\nexport function useMainPlayer() {\n  const { player } = useHooksContext('useMainPlayer', true);\n\n  return player;\n}","import { NodeResolvable } from '../queue';\nimport { TypeUtil } from '../utils/TypeUtil';\nimport { useHooksContext } from './common';\n\nexport type SetterFN<T, P> = (previous: P) => T;\nexport type MetadataDispatch<T> = readonly [\n  () => T,\n  (metadata: T | SetterFN<T, T>) => void];\n\n\n/**\n * Fetch or manipulate guild queue metadata\n * @param node Guild queue node resolvable\n */\nexport function useMetadata<T = unknown>(): MetadataDispatch<T>;\nexport function useMetadata<T = unknown>(\nnode: NodeResolvable)\n: MetadataDispatch<T>;\nexport function useMetadata<T = unknown>(\nnode?: NodeResolvable)\n: MetadataDispatch<T> {\n  const { context, player } = useHooksContext('useMetadata');\n  const queue = player.queues.get<T>(node ?? context.guild.id);\n  const setter = (metadata: T | SetterFN<T, T>) => {\n    if (queue) {\n      if (TypeUtil.isFunction(metadata))\n      return queue.setMetadata(metadata(queue.metadata));\n      return queue.setMetadata(metadata);\n    }\n  };\n\n  const getter = () => {\n    return queue?.metadata as T;\n  };\n\n  return [getter, setter] as const;\n}","import { Track } from '../fabric';\nimport { NodeResolvable, PlayerTimestamp } from '../queue';\nimport { useHooksContext } from './common';\n\nexport interface TimelineDispatcherOptions {\n  ignoreFilters: boolean;\n  node: NodeResolvable;\n}\n\nexport interface GuildQueueTimeline {\n  readonly timestamp: PlayerTimestamp;\n  readonly volume: number;\n  readonly paused: boolean;\n  readonly track: Track<unknown> | null;\n  pause(): boolean;\n  resume(): boolean;\n  setVolume(vol: number): boolean;\n  setPosition(time: number): Promise<boolean>;\n}\n\n/**\n * Fetch or manipulate current track\n * @param options Options for timeline dispatcher\n */\nexport function useTimeline(): GuildQueueTimeline | null;\nexport function useTimeline(\noptions: Partial<TimelineDispatcherOptions>)\n: GuildQueueTimeline | null;\nexport function useTimeline(\noptions?: Partial<TimelineDispatcherOptions>)\n: GuildQueueTimeline | null {\n  const { context, player } = useHooksContext('useTimeline');\n  const queue = player.queues.get(options?.node ?? context.guild.id);\n  if (!queue) return null;\n\n  const timeline = Object.preventExtensions({\n    get timestamp() {\n      return queue.node.getTimestamp(options?.ignoreFilters)!;\n    },\n    get volume() {\n      return queue.node.volume;\n    },\n    get paused() {\n      return queue.node.isPaused();\n    },\n    get track() {\n      return queue.currentTrack;\n    },\n    pause() {\n      return queue.node.pause();\n    },\n    resume() {\n      return queue.node.resume();\n    },\n    setVolume(vol: number) {\n      return queue.node.setVolume(vol);\n    },\n    async setPosition(time: number) {\n      return queue.node.seek(time);\n    }\n  } satisfies GuildQueueTimeline);\n\n  return timeline;\n}","import { OnAfterCreateStreamHandler } from '../../queue';\nimport { getGlobalRegistry } from '../../utils/__internal__';\n\n/**\n * Global onAfterCreateStream handler\n * @param handler The handler callback\n */\nexport function onAfterCreateStream(handler: OnAfterCreateStreamHandler) {\n  getGlobalRegistry().set('@[onAfterCreateStream]', handler);\n}","import { OnBeforeCreateStreamHandler } from '../../queue';\nimport { getGlobalRegistry } from '../../utils/__internal__';\n\n/**\n * Global onBeforeCreateStream handler\n * @param handler The handler callback\n */\nexport function onBeforeCreateStream(handler: OnBeforeCreateStreamHandler) {\n  getGlobalRegistry().set('@[onBeforeCreateStream]', handler);\n}","import { OnStreamExtractedHandler } from '../../queue';\nimport { getGlobalRegistry } from '../../utils/__internal__';\n\n/**\n * Global onStreamExtracted handler\n * @param handler The handler callback\n */\nexport function onStreamExtracted(handler: OnStreamExtractedHandler) {\n  getGlobalRegistry().set('@[onStreamExtracted]', handler);\n}","import { NodeResolvable } from '../queue';\nimport { TypeUtil } from '../utils/TypeUtil';\nimport { useHooksContext } from './common';\n\ntype SetterFN = (previous: number) => number;\ntype VolumeDispatch = readonly [\n  () => number,\n  (volume: number | SetterFN) => boolean | undefined];\n\n\n/**\n * Fetch or manipulate player volume\n * @param node Guild queue node resolvable\n */\nexport function useVolume(): VolumeDispatch;\nexport function useVolume(node: NodeResolvable): VolumeDispatch;\nexport function useVolume(node?: NodeResolvable): VolumeDispatch {\n  const { context, player } = useHooksContext('useVolume');\n  const queue = player.queues.get(node ?? context.guild.id);\n  const setter = (volume: number | SetterFN) => {\n    if (queue) {\n      if (TypeUtil.isFunction(volume))\n      return queue.node.setVolume(volume(queue.node.volume));\n      return queue.node.setVolume(volume);\n    }\n  };\n\n  const getter = () => {\n    return queue?.node.volume as number;\n  };\n\n  return [getter, setter] as const;\n}","import { Transform, type TransformCallback, type Writable } from 'node:stream';\n\n/**\n * Represents a stream that can be intercepted and consumed without affecting the original consumer.\n * @example const stream = new InterceptedStream();\n *\n * // real consumer\n * stream.pipe(fs.createWriteStream('file.txt'));\n *\n * // man in the middle consumer\n * const manInTheMiddle = new Writable({\n *  write(chunk, encoding, callback) {\n *   console.log(chunk.toString());\n *   callback();\n *  }\n * });\n *\n * // stream.interceptors is a Set of Writable streams\n * stream.interceptors.add(manInTheMiddle);\n */\nexport class InterceptedStream extends Transform {\n  public readonly interceptors = new Set<Writable>();\n  #intercepting = true;\n\n  /**\n   * Start intercepting the stream. This is the default state of InterceptedStream.\n   */\n  public startIntercepting(): void {\n    this.#intercepting = true;\n  }\n\n  /**\n   * Stop intercepting the stream. This will prevent the stream from being consumed by the interceptors.\n   * This can be useful when you want to temporarily stop the interception. The stopped state can be resumed by calling startIntercepting again.\n   */\n  public stopIntercepting(): void {\n    this.#intercepting = false;\n  }\n\n  /**\n   * Whether the stream is being intercepted\n   */\n  public isIntercepting(): boolean {\n    return this.#intercepting;\n  }\n\n  public _transform(\n  chunk: Buffer,\n  encoding: BufferEncoding,\n  callback: TransformCallback)\n  : void {\n    this.push(chunk, encoding);\n\n    if (this.#intercepting && this.interceptors.size > 0) {\n      for (const consumer of this.interceptors) {\n        consumer.write(chunk, encoding);\n      }\n    }\n\n    callback();\n  }\n\n  _final(callback: TransformCallback): void {\n    for (const consumer of this.interceptors) {\n      consumer.end();\n    }\n\n    callback();\n  }\n\n  public _destroy(error: Error, callback: TransformCallback): void {\n    const ignoreError = String(error).includes('ERR_STREAM_PREMATURE_CLOSE');\n    const err = ignoreError ? undefined : error;\n\n    for (const consumer of this.interceptors) {\n      consumer.destroy(err);\n    }\n\n    this.interceptors.clear();\n\n    callback(err);\n  }\n}","import {\n  EqualizerBand,\n  PCMFilters,\n  BiquadFilters } from\n'@discord-player/equalizer';\nimport { Collection, QueueStrategy } from '@discord-player/utils';\nimport { GuildResolvable } from 'discord.js';\nimport { Player } from '../Player';\nimport {\n  GuildQueue,\n  OnAfterCreateStreamHandler,\n  OnBeforeCreateStreamHandler,\n  OnStreamExtractedHandler,\n  QueueRepeatMode } from\n'./GuildQueue';\nimport { getGlobalRegistry } from '../utils/__internal__';\nimport { NoGuildError, NoGuildQueueError } from '../errors';\nimport { FiltersName } from '../fabric';\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport interface GuildNodeCreateOptions<T = any> {\n  strategy?: QueueStrategy;\n  volume?: number;\n  equalizer?: EqualizerBand[];\n  a_filter?: PCMFilters[];\n  biquad?: BiquadFilters;\n  resampler?: number;\n  disableHistory?: boolean;\n  onBeforeCreateStream?: OnBeforeCreateStreamHandler;\n  onAfterCreateStream?: OnAfterCreateStreamHandler;\n  onStreamExtracted?: OnStreamExtractedHandler;\n  repeatMode?: QueueRepeatMode;\n  pauseOnEmpty?: boolean;\n  leaveOnEmpty?: boolean;\n  leaveOnEmptyCooldown?: number;\n  leaveOnEnd?: boolean;\n  leaveOnEndCooldown?: number;\n  leaveOnStop?: boolean;\n  leaveOnStopCooldown?: number;\n  metadata?: T | null;\n  selfDeaf?: boolean;\n  connectionTimeout?: number;\n  defaultFFmpegFilters?: FiltersName[];\n  bufferingTimeout?: number;\n  noEmitInsert?: boolean;\n  maxSize?: number;\n  maxHistorySize?: number;\n  preferBridgedMetadata?: boolean;\n  disableVolume?: boolean;\n  disableEqualizer?: boolean;\n  disableFilterer?: boolean;\n  disableBiquad?: boolean;\n  disableResampler?: boolean;\n  disableCompressor?: boolean;\n  disableSeeker?: boolean;\n  disableReverb?: boolean;\n  disableFallbackStream?: boolean;\n  enableStreamInterceptor?: boolean;\n  verifyFallbackStream?: boolean;\n}\n\nexport type NodeResolvable = GuildQueue | GuildResolvable;\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport class GuildNodeManager<Meta = any> {\n  public cache = new Collection<string, GuildQueue>();\n  public constructor(public player: Player) {}\n\n  /**\n   * Create guild queue if it does not exist\n   * @param guild The guild which will be the owner of the queue\n   * @param options Queue initializer options\n   */\n  public create<T = Meta>(\n  guild: GuildResolvable,\n  options: GuildNodeCreateOptions<T> = {})\n  : GuildQueue<T> {\n    const server = this.player.client.guilds.resolve(guild);\n    if (!server) {\n      throw new NoGuildError('Invalid or unknown guild');\n    }\n\n    if (this.cache.has(server.id)) {\n      return this.cache.get(server.id) as GuildQueue<T>;\n    }\n\n    options.strategy ??= 'FIFO';\n    options.volume ??= 100;\n    options.equalizer ??= [];\n    options.a_filter ??= [];\n    options.disableHistory ??= false;\n    options.leaveOnEmpty ??= true;\n    options.leaveOnEmptyCooldown ??= 0;\n    options.leaveOnEnd ??= true;\n    options.leaveOnEndCooldown ??= 0;\n    options.leaveOnStop ??= true;\n    options.leaveOnStopCooldown ??= 0;\n    options.resampler ??= 48000;\n    options.selfDeaf ??= true;\n    options.connectionTimeout ??= this.player.options.connectionTimeout;\n    options.bufferingTimeout ??= 1000;\n    options.maxSize ??= Infinity;\n    options.maxHistorySize ??= Infinity;\n    options.preferBridgedMetadata ??= true;\n    options.pauseOnEmpty ??= true;\n\n    // todo(twlite): maybe disable these by default?\n    options.disableBiquad ??= false;\n    options.disableEqualizer ??= false;\n    options.disableFilterer ??= false;\n    options.disableVolume ??= false;\n    options.disableResampler ??= false;\n    options.disableCompressor ??= true;\n    options.disableSeeker ??= true;\n    options.disableReverb ??= true;\n\n    options.disableFallbackStream ??= false;\n    options.enableStreamInterceptor ??= false;\n    options.verifyFallbackStream ??= false;\n\n    if (\n    getGlobalRegistry().has('@[onStreamExtracted]') &&\n    !options.onStreamExtracted)\n    {\n      options.onStreamExtracted = getGlobalRegistry().get(\n        '@[onStreamExtracted]'\n      ) as OnStreamExtractedHandler;\n    }\n\n    if (\n    getGlobalRegistry().has('@[onBeforeCreateStream]') &&\n    !options.onBeforeCreateStream)\n    {\n      options.onBeforeCreateStream = getGlobalRegistry().get(\n        '@[onBeforeCreateStream]'\n      ) as OnBeforeCreateStreamHandler;\n    }\n\n    if (\n    getGlobalRegistry().has('@[onAfterCreateStream]') &&\n    !options.onAfterCreateStream)\n    {\n      options.onAfterCreateStream = getGlobalRegistry().get(\n        '@[onAfterCreateStream]'\n      ) as OnAfterCreateStreamHandler;\n    }\n\n    const queue = new GuildQueue<T>(this.player, {\n      guild: server,\n      queueStrategy: options.strategy,\n      volume: options.volume,\n      equalizer: options.equalizer,\n      filterer: options.a_filter,\n      biquad: options.biquad,\n      resampler: options.resampler,\n      disableHistory: options.disableHistory,\n      onBeforeCreateStream: options.onBeforeCreateStream,\n      onAfterCreateStream: options.onAfterCreateStream,\n      onStreamExtracted: options.onStreamExtracted,\n      repeatMode: options.repeatMode,\n      leaveOnEmpty: options.leaveOnEmpty,\n      leaveOnEmptyCooldown: options.leaveOnEmptyCooldown,\n      leaveOnEnd: options.leaveOnEnd,\n      leaveOnEndCooldown: options.leaveOnEndCooldown,\n      leaveOnStop: options.leaveOnStop,\n      leaveOnStopCooldown: options.leaveOnStopCooldown,\n      metadata: options.metadata,\n      connectionTimeout: options.connectionTimeout ?? 120_000,\n      selfDeaf: options.selfDeaf,\n      ffmpegFilters: options.defaultFFmpegFilters ?? [],\n      bufferingTimeout: options.bufferingTimeout,\n      noEmitInsert: options.noEmitInsert ?? false,\n      preferBridgedMetadata: options.preferBridgedMetadata,\n      maxHistorySize: options.maxHistorySize,\n      maxSize: options.maxSize,\n      pauseOnEmpty: options.pauseOnEmpty,\n      disableBiquad: options.disableBiquad,\n      disableEqualizer: options.disableEqualizer,\n      disableFilterer: options.disableFilterer,\n      disableResampler: options.disableResampler,\n      disableVolume: options.disableVolume,\n      disableFallbackStream: options.disableFallbackStream,\n      enableStreamInterceptor: options.enableStreamInterceptor,\n      verifyFallbackStream: options.verifyFallbackStream,\n      disableCompressor: options.disableCompressor,\n      disableSeeker: options.disableSeeker,\n      disableReverb: options.disableReverb\n    });\n\n    this.cache.set(server.id, queue);\n\n    return queue;\n  }\n\n  /**\n   * Get existing queue\n   * @param node Queue resolvable\n   */\n  public get<T = Meta>(node: NodeResolvable) {\n    const queue = this.resolve(node);\n    if (!queue) return null;\n\n    return this.cache.get(queue.id) as GuildQueue<T> || null;\n  }\n\n  /**\n   * Check if a queue exists\n   * @param node Queue resolvable\n   */\n  public has(node: NodeResolvable) {\n    const id =\n    node instanceof GuildQueue ?\n    node.id :\n    this.player.client.guilds.resolveId(node)!;\n    return this.cache.has(id);\n  }\n\n  /**\n   * Delete queue\n   * @param node Queue resolvable\n   */\n  public delete(node: NodeResolvable) {\n    const queue = this.resolve(node);\n    if (!queue) {\n      throw new NoGuildQueueError('Cannot delete non-existing queue');\n    }\n\n    queue.setTransitioning(true);\n    queue.node.stop(true);\n    // @ts-ignore\n    queue.connection?.removeAllListeners();\n    queue.dispatcher?.removeAllListeners();\n    queue.dispatcher?.disconnect();\n    queue.timeouts.forEach((tm) => clearTimeout(tm));\n    queue.history.clear();\n    queue.tracks.clear();\n\n    return this.cache.delete(queue.id);\n  }\n\n  /**\n   * Resolve queue\n   * @param node Queue resolvable\n   */\n  public resolve<T = Meta>(node: NodeResolvable): GuildQueue<T> | undefined {\n    if (node instanceof GuildQueue) {\n      return node as GuildQueue<T>;\n    }\n\n    return this.cache.get(\n      this.player.client.guilds.resolveId(node)!\n    ) as GuildQueue<T>;\n  }\n\n  /**\n   * Resolve queue id\n   * @param node Queue resolvable\n   */\n  public resolveId(node: NodeResolvable) {\n    const q = this.resolve(node);\n    return q?.id || null;\n  }\n}","import { Player, PlayerNodeInitializerOptions, TrackLike } from '../Player';\nimport {\n  ChannelType,\n  Guild,\n  GuildVoiceChannelResolvable,\n  VoiceBasedChannel,\n  VoiceState } from\n'discord.js';\nimport { Collection, Queue, QueueStrategy } from '@discord-player/utils';\nimport {\n  BiquadFilters,\n  CommonResamplerFilterPreset,\n  CompressorParameters,\n  EqualizerBand,\n  PCMFilters,\n  ReverbParameters,\n  SeekerParameters } from\n'@discord-player/equalizer';\nimport { Track, TrackResolvable } from '../fabric/Track';\nimport { StreamDispatcher } from '../stream/StreamDispatcher';\nimport {\n  type AudioPlayer,\n  AudioResource,\n  StreamType,\n  VoiceConnection,\n  VoiceConnectionStatus } from\n'discord-voip';\nimport { Util, VALIDATE_QUEUE_CAP } from '../utils/Util';\nimport { Playlist } from '../fabric/Playlist';\nimport { GuildQueueHistory } from './GuildQueueHistory';\nimport { GuildQueuePlayerNode, StreamConfig } from './GuildQueuePlayerNode';\nimport { GuildQueueAudioFilters } from './GuildQueueAudioFilters';\nimport { Readable } from 'stream';\nimport { setTimeout } from 'timers';\nimport { GuildQueueStatistics } from './GuildQueueStatistics';\nimport { TypeUtil } from '../utils/TypeUtil';\nimport { AsyncQueue } from '../utils/AsyncQueue';\nimport {\n  InvalidArgTypeError,\n  NoVoiceChannelError,\n  NoVoiceConnectionError,\n  OutOfRangeError,\n  VoiceConnectionDestroyedError } from\n'../errors';\nimport { SyncedLyricsProvider } from './SyncedLyricsProvider';\nimport { LrcGetResult, LrcSearchResult } from '../lrclib/LrcLib';\nimport { FiltersName } from '../fabric';\nimport { SearchQueryType } from '../utils/QueryResolver';\nimport type { ExtractorStreamable } from '../extractors/BaseExtractor';\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport interface GuildNodeInit<Meta = any> {\n  guild: Guild;\n  queueStrategy: QueueStrategy;\n  equalizer: EqualizerBand[] | boolean;\n  volume: number | boolean;\n  biquad: BiquadFilters | boolean | undefined;\n  resampler: number | boolean;\n  filterer: PCMFilters[] | boolean;\n  ffmpegFilters: FiltersName[];\n  disableHistory: boolean;\n  onBeforeCreateStream?: OnBeforeCreateStreamHandler;\n  onAfterCreateStream?: OnAfterCreateStreamHandler;\n  onStreamExtracted?: OnStreamExtractedHandler;\n  repeatMode?: QueueRepeatMode;\n  leaveOnEmpty: boolean;\n  leaveOnEmptyCooldown: number;\n  leaveOnEnd: boolean;\n  leaveOnEndCooldown: number;\n  leaveOnStop: boolean;\n  leaveOnStopCooldown: number;\n  connectionTimeout: number;\n  selfDeaf?: boolean;\n  metadata?: Meta | null;\n  bufferingTimeout: number;\n  noEmitInsert: boolean;\n  maxSize?: number;\n  maxHistorySize?: number;\n  preferBridgedMetadata: boolean;\n  pauseOnEmpty?: boolean;\n  disableVolume: boolean;\n  disableEqualizer: boolean;\n  disableFilterer: boolean;\n  disableBiquad: boolean;\n  disableResampler: boolean;\n  disableCompressor: boolean;\n  disableReverb: boolean;\n  disableSeeker: boolean;\n  disableFallbackStream: boolean;\n  enableStreamInterceptor: boolean;\n  verifyFallbackStream: boolean;\n}\n\nexport interface VoiceConnectConfig {\n  deaf?: boolean;\n  timeout?: number;\n  group?: string;\n  audioPlayer?: AudioPlayer;\n  daveEncryption?: boolean;\n  decryptionFailureTolerance?: number;\n}\n\nexport interface PostProcessedResult {\n  stream: Readable;\n  type: StreamType;\n}\n\nexport type OnBeforeCreateStreamHandler = (\ntrack: Track,\nqueryType: SearchQueryType,\nqueue: GuildQueue)\n=> Promise<Readable | null>;\n\nexport type OnStreamExtractedHandler = (\nstream: Readable | ExtractorStreamable | string,\ntrack: Track,\nqueue: GuildQueue)\n=> Promise<Readable | ExtractorStreamable | string>;\n\nexport type OnAfterCreateStreamHandler<T = unknown> = (\nstream: Readable,\nqueue: GuildQueue,\ntrack: Track<T>)\n=> Promise<PostProcessedResult | null>;\n\nexport type PlayerTriggeredReason = 'filters' | 'normal';\n\nexport const GuildQueueEvent = {\n  /**\n   * Emitted when audio track is added to the queue\n   */\n  AudioTrackAdd: 'audioTrackAdd',\n  /**\n   * Emitted when audio tracks were added to the queue\n   */\n  AudioTracksAdd: 'audioTracksAdd',\n  /**\n   * Emitted when audio track is removed from the queue\n   */\n  AudioTrackRemove: 'audioTrackRemove',\n  /**\n   * Emitted when audio tracks are removed from the queue\n   */\n  AudioTracksRemove: 'audioTracksRemove',\n  /**\n   * Emitted when a connection is created\n   */\n  Connection: 'connection',\n  /**\n   * Emitted when a voice connection is destroyed\n   */\n  ConnectionDestroyed: 'connectionDestroyed',\n  /**\n   * Emitted when the bot is disconnected from the channel\n   */\n  Disconnect: 'disconnect',\n  /**\n   * Emitted when the queue sends a debug info\n   */\n  Debug: 'debug',\n  /**\n   * Emitted when the queue encounters error\n   */\n  Error: 'error',\n  /**\n   * Emitted when the voice channel is empty\n   */\n  EmptyChannel: 'emptyChannel',\n  /**\n   * Emitted when the queue is empty\n   */\n  EmptyQueue: 'emptyQueue',\n  /**\n   * Emitted when the audio player starts streaming audio track\n   */\n  PlayerStart: 'playerStart',\n  /**\n   * Emitted when the audio player errors while streaming audio track\n   */\n  PlayerError: 'playerError',\n  /**\n   * Emitted when the audio player finishes streaming audio track\n   */\n  PlayerFinish: 'playerFinish',\n  /**\n   * Emitted when the audio player skips current track\n   */\n  PlayerSkip: 'playerSkip',\n  /**\n   * Emitted when the audio player is triggered\n   */\n  PlayerTrigger: 'playerTrigger',\n  /**\n   * Emitted when the voice state is updated. Consuming this event may disable default voice state update handler if `Player.isVoiceStateHandlerLocked()` returns `false`.\n   */\n  VoiceStateUpdate: 'voiceStateUpdate',\n  /**\n   * Emitted when volume is updated\n   */\n  VolumeChange: 'volumeChange',\n  /**\n   * Emitted when player is paused\n   */\n  PlayerPause: 'playerPause',\n  /**\n   * Emitted when player is resumed\n   */\n  PlayerResume: 'playerResume',\n  /**\n   * Biquad Filters Update\n   */\n  BiquadFiltersUpdate: 'biquadFiltersUpdate',\n  /**\n   * Equalizer Update\n   */\n  EqualizerUpdate: 'equalizerUpdate',\n  /**\n   * DSP update\n   */\n  DSPUpdate: 'dspUpdate',\n  /**\n   * Audio Filters Update\n   */\n  AudioFiltersUpdate: 'audioFiltersUpdate',\n  /**\n   * Audio player will play next track\n   */\n  WillPlayTrack: 'willPlayTrack',\n  /**\n   * Emitted when a voice channel is repopulated\n   */\n  ChannelPopulate: 'channelPopulate',\n  /**\n   * Emitted when a queue is successfully created\n   */\n  QueueCreate: 'queueCreate',\n  /**\n   * Emitted when a queue is deleted\n   */\n  QueueDelete: 'queueDelete',\n  /**\n   * Emitted when a queue is trying to add similar track for autoplay\n   */\n  WillAutoPlay: 'willAutoPlay',\n  /**\n   * Emitted when sample rate is updated\n   */\n  SampleRateUpdate: 'sampleRateUpdate',\n  /**\n   * Emitted when a named sample rate filter is updated\n   */\n  SampleRateFilterUpdate: 'sampleRateFilterUpdate',\n  /**\n   * Emitted when reverb filter is updated\n   */\n  ReverbUpdate: 'reverbUpdate',\n  /**\n   * Emitted when compressor filter is updated\n   */\n  CompressorUpdate: 'compressorUpdate',\n  /**\n   * Emitted when seek is performed\n   */\n  PlayerSeek: 'playerSeek'\n} as const;\n\nexport type GuildQueueEvent =\n(typeof GuildQueueEvent)[keyof typeof GuildQueueEvent];\n\nexport enum TrackSkipReason {\n  NoStream = 'ERR_NO_STREAM',\n  Manual = 'MANUAL',\n  SEEK_OVER_THRESHOLD = 'SEEK_OVER_THRESHOLD',\n  Jump = 'JUMPED_TO_ANOTHER_TRACK',\n  SkipTo = 'SKIP_TO_ANOTHER_TRACK',\n  HistoryNext = 'HISTORY_NEXT_TRACK',\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport interface GuildQueueEvents<Meta = any> {\n  /**\n   * Emitted when audio track is added to the queue\n   * @param queue The queue where this event occurred\n   * @param track The track\n   */\n  [GuildQueueEvent.AudioTrackAdd]: (\n  queue: GuildQueue<Meta>,\n  track: Track)\n  => unknown;\n  /**\n   * Emitted when audio tracks were added to the queue\n   * @param queue The queue where this event occurred\n   * @param tracks The tracks array\n   */\n  [GuildQueueEvent.AudioTracksAdd]: (\n  queue: GuildQueue<Meta>,\n  track: Track[])\n  => unknown;\n  /**\n   * Emitted when audio track is removed from the queue\n   * @param queue The queue where this event occurred\n   * @param track The track\n   */\n  [GuildQueueEvent.AudioTrackRemove]: (\n  queue: GuildQueue<Meta>,\n  track: Track)\n  => unknown;\n  /**\n   * Emitted when audio tracks are removed from the queue\n   * @param queue The queue where this event occurred\n   * @param track The track\n   */\n  [GuildQueueEvent.AudioTracksRemove]: (\n  queue: GuildQueue<Meta>,\n  track: Track[])\n  => unknown;\n  /**\n   * Emitted when a connection is created\n   * @param queue The queue where this event occurred\n   */\n  [GuildQueueEvent.Connection]: (queue: GuildQueue<Meta>) => unknown;\n  /**\n   * Emitted when a connection is destroyed\n   * @param queue The queue where this event occurred\n   */\n  [GuildQueueEvent.ConnectionDestroyed]: (queue: GuildQueue<Meta>) => unknown;\n  /**\n   * Emitted when the bot is disconnected from the channel\n   * @param queue The queue where this event occurred\n   */\n  [GuildQueueEvent.Disconnect]: (queue: GuildQueue<Meta>) => unknown;\n  /**\n   * Emitted when the queue sends a debug info\n   * @param queue The queue where this event occurred\n   * @param message The debug message\n   */\n  [GuildQueueEvent.Debug]: (\n  queue: GuildQueue<Meta>,\n  message: string)\n  => unknown;\n  /**\n   * Emitted when the queue encounters error\n   * @param queue The queue where this event occurred\n   * @param error The error\n   */\n  [GuildQueueEvent.Error]: (queue: GuildQueue<Meta>, error: Error) => unknown;\n  /**\n   * Emitted when the voice channel is empty\n   * @param queue The queue where this event occurred\n   */\n  [GuildQueueEvent.EmptyChannel]: (queue: GuildQueue<Meta>) => unknown;\n  /**\n   * Emitted when the queue is empty\n   * @param queue The queue where this event occurred\n   */\n  [GuildQueueEvent.EmptyQueue]: (queue: GuildQueue<Meta>) => unknown;\n  /**\n   * Emitted when the audio player starts streaming audio track\n   * @param queue The queue where this event occurred\n   * @param track The track that is being streamed\n   */\n  [GuildQueueEvent.PlayerStart]: (\n  queue: GuildQueue<Meta>,\n  track: Track)\n  => unknown;\n  /**\n   * Emitted when the audio player errors while streaming audio track\n   * @param queue The queue where this event occurred\n   * @param error The error\n   * @param track The track that is being streamed\n   */\n  [GuildQueueEvent.PlayerError]: (\n  queue: GuildQueue<Meta>,\n  error: Error,\n  track: Track)\n  => unknown;\n  /**\n   * Emitted when the audio player finishes streaming audio track\n   * @param queue The queue where this event occurred\n   * @param track The track that was being streamed\n   */\n  [GuildQueueEvent.PlayerFinish]: (\n  queue: GuildQueue<Meta>,\n  track: Track)\n  => unknown;\n  /**\n   * Emitted when the audio player skips current track\n   * @param queue The queue where this event occurred\n   * @param track The track that was skipped\n   * @param reason The reason for skipping\n   * @param description The description for skipping\n   */\n  [GuildQueueEvent.PlayerSkip]: (\n  queue: GuildQueue<Meta>,\n  track: Track,\n  reason: TrackSkipReason,\n  description: string)\n  => unknown;\n  /**\n   * Emitted when the audio player is triggered\n   * @param queue The queue where this event occurred\n   * @param track The track which was played in this event\n   */\n  [GuildQueueEvent.PlayerTrigger]: (\n  queue: GuildQueue<Meta>,\n  track: Track,\n  reason: PlayerTriggeredReason)\n  => unknown;\n  /**\n   * Emitted when the voice state is updated. Consuming this event may disable default voice state update handler if `Player.isVoiceStateHandlerLocked()` returns `false`.\n   * @param queue The queue where this event occurred\n   * @param oldState The old voice state\n   * @param newState The new voice state\n   */\n  [GuildQueueEvent.VoiceStateUpdate]: (\n  queue: GuildQueue<Meta>,\n  oldState: VoiceState,\n  newState: VoiceState)\n  => unknown;\n  /**\n   * Emitted when audio player is paused\n   * @param queue The queue where this event occurred\n   */\n  [GuildQueueEvent.PlayerPause]: (queue: GuildQueue<Meta>) => unknown;\n  /**\n   * Emitted when audio player is resumed\n   * @param queue The queue where this event occurred\n   */\n  [GuildQueueEvent.PlayerResume]: (queue: GuildQueue<Meta>) => unknown;\n  /**\n   * Emitted when audio player's volume is changed\n   * @param queue The queue where this event occurred\n   * @param oldVolume The old volume\n   * @param newVolume The updated volume\n   */\n  [GuildQueueEvent.VolumeChange]: (\n  queue: GuildQueue<Meta>,\n  oldVolume: number,\n  newVolume: number)\n  => unknown;\n  /**\n   * Emitted when equalizer config is updated\n   * @param queue The queue where this event occurred\n   * @param oldFilters Old filters\n   * @param newFilters New filters\n   */\n  [GuildQueueEvent.EqualizerUpdate]: (\n  queue: GuildQueue<Meta>,\n  oldFilters: EqualizerBand[],\n  newFilters: EqualizerBand[])\n  => unknown;\n  /**\n   * Emitted when biquad filters is updated\n   * @param queue The queue where this event occurred\n   * @param oldFilters Old filters\n   * @param newFilters New filters\n   */\n  [GuildQueueEvent.BiquadFiltersUpdate]: (\n  queue: GuildQueue<Meta>,\n  oldFilters: BiquadFilters | null,\n  newFilters: BiquadFilters | null)\n  => unknown;\n  /**\n   * Emitted when dsp filters is updated\n   * @param queue The queue where this event occurred\n   * @param oldFilters Old filters\n   * @param newFilters New filters\n   */\n  [GuildQueueEvent.DSPUpdate]: (\n  queue: GuildQueue<Meta>,\n  oldFilters: PCMFilters[],\n  newFilters: PCMFilters[])\n  => unknown;\n  /**\n   * Emitted when ffmpeg audio filters is updated\n   * @param queue The queue where this event occurred\n   * @param oldFilters Old filters\n   * @param newFilters New filters\n   */\n  [GuildQueueEvent.AudioFiltersUpdate]: (\n  queue: GuildQueue<Meta>,\n  oldFilters: FiltersName[],\n  newFilters: FiltersName[])\n  => unknown;\n\n  /**\n   * Emitted before streaming an audio track. This event can be used to modify stream config before playing a track.\n   * Listening to this event will pause the execution of audio player until `done()` is invoked.\n   * @param queue The queue where this event occurred\n   * @param track The track that will be streamed\n   * @param config Configurations for streaming\n   * @param done Done callback\n   */\n  [GuildQueueEvent.WillPlayTrack]: (\n  queue: GuildQueue<Meta>,\n  track: Track<unknown>,\n  config: StreamConfig,\n  done: () => void)\n  => unknown;\n  /**\n   * Emitted when a voice channel is populated\n   * @param queue The queue where this event occurred\n   */\n  [GuildQueueEvent.ChannelPopulate]: (queue: GuildQueue<Meta>) => unknown;\n  /**\n   * Emitted when a queue is successfully created\n   * @param queue The queue where this event occurred\n   */\n  [GuildQueueEvent.QueueCreate]: (queue: GuildQueue<Meta>) => unknown;\n  /**\n   * Emitted when a queue is successfully deleted\n   * @param queue The queue where this event occurred\n   */\n  [GuildQueueEvent.QueueDelete]: (queue: GuildQueue<Meta>) => unknown;\n  /**\n   * Emitted when a queue is trying to add similar track for autoplay\n   * @param queue The queue where this event occurred\n   * @param tracks The similar tracks that were found\n   * @param done Done callback\n   */\n  [GuildQueueEvent.WillAutoPlay]: (\n  queue: GuildQueue<Meta>,\n  tracks: Track[],\n  done: (track: Track | null) => void)\n  => unknown;\n  /**\n   * Emitted when sample rate is updated\n   * @param queue The queue where this event occurred\n   * @param oldRate The old sample rate\n   * @param newRate The new sample rate\n   */\n  [GuildQueueEvent.SampleRateUpdate]: (\n  queue: GuildQueue<Meta>,\n  oldRate: number,\n  newRate: number)\n  => unknown;\n  /**\n   * Emitted when a named sample rate filter is updated\n   * @param queue The queue where this event occurred\n   * @param oldRate The old sample rate filter\n   * @param newRate The new sample rate filter\n   */\n  [GuildQueueEvent.SampleRateFilterUpdate]: (\n  queue: GuildQueue<Meta>,\n  oldFilter: CommonResamplerFilterPreset | null,\n  newFilter: CommonResamplerFilterPreset | null)\n  => unknown;\n  /**\n   * Emitted when reverb filter is updated\n   * @param queue The queue where this event occurred\n   * @param oldFilter The old reverb filter\n   * @param newFilter The new reverb filter\n   */\n  [GuildQueueEvent.ReverbUpdate]: (\n  queue: GuildQueue<Meta>,\n  oldFilter: ReverbParameters | null,\n  newFilter: ReverbParameters | null)\n  => unknown;\n  /**\n   * Emitted when compressor filter is updated\n   * @param queue The queue where this event occurred\n   * @param oldFilter The old compressor filter\n   * @param newFilter The new compressor filter\n   */\n  [GuildQueueEvent.CompressorUpdate]: (\n  queue: GuildQueue<Meta>,\n  oldFilter: CompressorParameters | null,\n  newFilter: CompressorParameters | null)\n  => unknown;\n  /**\n   * Emitted when seek is performed\n   * @param queue The queue where this event occurred\n   * @param position The seek position\n   */\n  [GuildQueueEvent.PlayerSeek]: (\n  queue: GuildQueue<Meta>,\n  parameters: SeekerParameters)\n  => unknown;\n}\n\n/**\n * The queue repeat mode. This can be one of:\n * - OFF\n * - TRACK\n * - QUEUE\n * - AUTOPLAY\n */\nexport const QueueRepeatMode = {\n  /**\n   * Disable repeat mode.\n   */\n  OFF: 0,\n  /**\n   * Repeat the current track.\n   */\n  TRACK: 1,\n  /**\n   * Repeat the entire queue.\n   */\n  QUEUE: 2,\n  /**\n   * When last track ends, play similar tracks in the future if queue is empty.\n   */\n  AUTOPLAY: 3\n} as const;\n\nexport type QueueRepeatMode =\n(typeof QueueRepeatMode)[keyof typeof QueueRepeatMode];\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport class GuildQueue<Meta = any> {\n  #transitioning = false;\n  #deleted = false;\n  #shuffle = false;\n  private __current: Track | null = null;\n  public tracks: Queue<Track>;\n  public history = new GuildQueueHistory<Meta>(this);\n  public dispatcher: StreamDispatcher | null = null;\n  public node = new GuildQueuePlayerNode<Meta>(this);\n  public filters = new GuildQueueAudioFilters<Meta>(this);\n  public onBeforeCreateStream: OnBeforeCreateStreamHandler = async () => null;\n  public onAfterCreateStream: OnAfterCreateStreamHandler = async (stream) => ({\n    stream,\n    type: StreamType.Raw\n  });\n  public onStreamExtracted: OnStreamExtractedHandler = async (stream) => stream;\n  public repeatMode: QueueRepeatMode = QueueRepeatMode.OFF;\n  public timeouts = new Collection<string, NodeJS.Timeout>();\n  public stats = new GuildQueueStatistics<Meta>(this);\n  public tasksQueue = new AsyncQueue();\n  public syncedLyricsProvider = new SyncedLyricsProvider(this);\n\n  public constructor(\n  public player: Player,\n  public options: GuildNodeInit<Meta>)\n  {\n    this.tracks = new Queue<Track>(options.queueStrategy);\n    if (TypeUtil.isFunction(options.onBeforeCreateStream))\n    this.onBeforeCreateStream = options.onBeforeCreateStream;\n    if (TypeUtil.isFunction(options.onAfterCreateStream))\n    this.onAfterCreateStream = options.onAfterCreateStream;\n    if (TypeUtil.isFunction(options.onStreamExtracted))\n    this.onStreamExtracted = options.onStreamExtracted;\n    if (!TypeUtil.isNullish(options.repeatMode))\n    this.repeatMode = options.repeatMode;\n\n    options.selfDeaf ??= true;\n    options.maxSize ??= Infinity;\n    options.maxHistorySize ??= Infinity;\n    options.pauseOnEmpty ??= true;\n\n    if (\n    !TypeUtil.isNullish(this.options.biquad) &&\n    !TypeUtil.isBoolean(this.options.biquad))\n    {\n      this.filters._lastFiltersCache.biquad = this.options.biquad;\n    }\n\n    if (Array.isArray(this.options.equalizer)) {\n      this.filters._lastFiltersCache.equalizer = this.options.equalizer;\n    }\n\n    if (Array.isArray(this.options.filterer)) {\n      this.filters._lastFiltersCache.filters = this.options.filterer;\n    }\n\n    if (TypeUtil.isNumber(this.options.resampler)) {\n      this.filters._lastFiltersCache.sampleRate = this.options.resampler;\n    }\n\n    if (TypeUtil.isArray(this.options.ffmpegFilters)) {\n      this.filters.ffmpeg.setDefaults(this.options.ffmpegFilters);\n    }\n\n    if (!TypeUtil.isNumber(options.maxSize)) {\n      throw new InvalidArgTypeError(\n        '[GuildNodeInit.maxSize]',\n        'number',\n        typeof options.maxSize\n      );\n    }\n\n    if (!TypeUtil.isNumber(options.maxHistorySize)) {\n      throw new InvalidArgTypeError(\n        '[GuildNodeInit.maxHistorySize]',\n        'number',\n        typeof options.maxHistorySize\n      );\n    }\n\n    if (options.maxSize < 1) options.maxSize = Infinity;\n    if (options.maxHistorySize < 1) options.maxHistorySize = Infinity;\n\n    if (this.hasDebugger)\n    this.debug(\n      `GuildQueue initialized for guild ${this.options.guild.name} (ID: ${this.options.guild.id})`\n    );\n    this.emit(GuildQueueEvent.QueueCreate, this);\n  }\n\n  /**\n   * Whether this queue can intercept streams\n   */\n  public canIntercept() {\n    return this.options.enableStreamInterceptor;\n  }\n\n  /**\n   * Estimated duration of this queue in ms\n   */\n  public get estimatedDuration() {\n    return this.tracks.store.reduce((a, c) => a + c.durationMS, 0);\n  }\n\n  /**\n   * Formatted duration of this queue\n   */\n  public get durationFormatted() {\n    return Util.buildTimeCode(Util.parseMS(this.estimatedDuration));\n  }\n\n  /**\n   * The sync lyrics provider for this queue.\n   * @example const lyrics = await player.lyrics.search({ q: 'Alan Walker Faded' });\n   * const syncedLyrics = queue.syncedLyrics(lyrics[0]);\n   * console.log(syncedLyrics.at(10_000));\n   * // subscribe to lyrics change\n   * const unsubscribe = syncedLyrics.onChange((lyrics, timestamp) => {\n   *    console.log(lyrics, timestamp);\n   * });\n   * // unsubscribe from lyrics change\n   * unsubscribe(); // or\n   * syncedLyrics.unsubscribe();\n   */\n  public syncedLyrics(lyrics: LrcGetResult | LrcSearchResult) {\n    this.syncedLyricsProvider.load(lyrics?.syncedLyrics ?? '');\n    return this.syncedLyricsProvider;\n  }\n\n  /**\n   * Write a debug message to this queue\n   * @param m The message to write\n   */\n  public debug(m: string) {\n    this.emit(GuildQueueEvent.Debug, this, m);\n  }\n\n  /**\n   * The metadata of this queue\n   */\n  public get metadata() {\n    return this.options.metadata!;\n  }\n\n  public set metadata(m: Meta) {\n    this.options.metadata = m;\n  }\n\n  /**\n   * Set metadata for this queue\n   * @param m Metadata to set\n   */\n  public setMetadata(m: Meta) {\n    this.options.metadata = m;\n  }\n\n  /**\n   * Indicates current track of this queue\n   */\n  public get currentTrack() {\n    return this.dispatcher?.audioResource?.metadata || this.__current;\n  }\n\n  /**\n   * Indicates if this queue was deleted previously\n   */\n  public get deleted() {\n    return this.#deleted;\n  }\n\n  /**\n   * The voice channel of this queue\n   */\n  public get channel() {\n    return this.dispatcher?.channel || null;\n  }\n\n  public set channel(c: VoiceBasedChannel | null) {\n    if (this.dispatcher) {\n      if (c) {\n        this.dispatcher.channel = c;\n      } else {\n        this.delete();\n      }\n    }\n  }\n\n  /**\n   * The voice connection of this queue\n   */\n  public get connection() {\n    return this.dispatcher?.voiceConnection || null;\n  }\n\n  /**\n   * The guild this queue belongs to\n   */\n  public get guild() {\n    return this.options.guild;\n  }\n\n  /**\n   * The id of this queue\n   */\n  public get id() {\n    return this.guild.id;\n  }\n\n  /**\n   * Set transition mode for this queue\n   * @param state The state to set\n   */\n  public setTransitioning(state: boolean) {\n    this.#transitioning = state;\n  }\n\n  /**\n   * if this queue is currently under transition mode\n   */\n  public isTransitioning() {\n    return this.#transitioning;\n  }\n\n  /**\n   * Set repeat mode for this queue\n   * @param mode The repeat mode to apply\n   */\n  public setRepeatMode(mode: QueueRepeatMode) {\n    this.repeatMode = mode;\n  }\n\n  /**\n   * Max size of this queue\n   */\n  public get maxSize() {\n    return this.options.maxSize ?? Infinity;\n  }\n\n  /**\n   * Max size of this queue\n   */\n  public getMaxSize() {\n    return this.maxSize;\n  }\n\n  /**\n   * Gets the size of the queue\n   */\n  public get size() {\n    return this.tracks.size;\n  }\n\n  /**\n   * The size of this queue\n   */\n  public getSize() {\n    return this.size;\n  }\n\n  /**\n   * Max history size of this queue\n   */\n  public get maxHistorySize() {\n    return this.options.maxHistorySize ?? Infinity;\n  }\n\n  /**\n   * Max history size of this queue\n   */\n  public getMaxHistorySize() {\n    return this.maxHistorySize;\n  }\n\n  /**\n   * Set max history size for this queue\n   * @param size The size to set\n   */\n  public setMaxHistorySize(size: number) {\n    if (!TypeUtil.isNumber(size)) {\n      throw new InvalidArgTypeError('size', 'number', typeof size);\n    }\n\n    if (size < 1) size = Infinity;\n\n    this.options.maxHistorySize = size;\n  }\n\n  /**\n   * Set max size for this queue\n   * @param size The size to set\n   */\n  public setMaxSize(size: number) {\n    if (!TypeUtil.isNumber(size)) {\n      throw new InvalidArgTypeError('size', 'number', typeof size);\n    }\n\n    if (size < 1) size = Infinity;\n\n    this.options.maxSize = size;\n  }\n\n  /**\n   * Clear this queue\n   */\n  public clear() {\n    this.tracks.clear();\n    this.history.clear();\n  }\n\n  /**\n   * Check if this queue has no tracks left in it\n   */\n  public isEmpty() {\n    return this.tracks.size < 1;\n  }\n\n  /**\n   * Check if this queue is full\n   */\n  public isFull() {\n    return this.tracks.size >= this.maxSize;\n  }\n\n  /**\n   * Get queue capacity\n   */\n  public getCapacity() {\n    if (this.isFull()) return 0;\n    const cap = this.maxSize - this.size;\n    return cap;\n  }\n\n  /**\n   * Check if this queue currently holds active audio resource\n   */\n  public isPlaying() {\n    return (\n      this.dispatcher?.audioResource != null &&\n      !this.dispatcher.audioResource.ended);\n\n  }\n\n  /**\n   * Add track to the queue. This will emit `audioTracksAdd` when multiple tracks are added, otherwise `audioTrackAdd`.\n   * @param track Track or playlist or array of tracks to add\n   */\n  public addTrack(track: Track | Track[] | Playlist) {\n    const toAdd = track instanceof Playlist ? track.tracks : track;\n    const isMulti = Array.isArray(toAdd);\n\n    VALIDATE_QUEUE_CAP(this, toAdd);\n\n    this.tracks.add(toAdd);\n\n    if (isMulti) {\n      this.emit(GuildQueueEvent.AudioTracksAdd, this, toAdd);\n    } else {\n      this.emit(GuildQueueEvent.AudioTrackAdd, this, toAdd);\n    }\n  }\n\n  /**\n   * Remove a track from queue\n   * @param track The track to remove\n   */\n  public removeTrack(track: TrackResolvable) {\n    return this.node.remove(track);\n  }\n\n  /**\n   * Prepends a track or track resolvable to the queue\n   * @param track The track resolvable to insert\n   * @param index The index to insert the track at (defaults to 0). If > 0, the inserted track will be placed before the track at the given index.\n   */\n  public prepend(track: Track | Queue<Track> | Array<Track>, index = 0): void {\n    if (index < 0 || index > this.tracks.size) {\n      throw new OutOfRangeError(\n        'index',\n        `${index}`,\n        '0',\n        `${this.tracks.size}`\n      );\n    }\n\n    const count = Array.isArray(track) ?\n    track.length :\n    track instanceof Queue ?\n    track.size :\n    1;\n\n    VALIDATE_QUEUE_CAP(this, count);\n\n    const insertionIndex = index === 0 ? 0 : index - 1;\n\n    if (track instanceof Track) {\n      this.node.insert(track, insertionIndex);\n      this.emit(GuildQueueEvent.AudioTrackAdd, this, track);\n      return;\n    }\n\n    const tracks = track instanceof Queue ? track.store : track;\n\n    this.tracks.store.splice(insertionIndex, 0, ...tracks);\n\n    if (!this.options.noEmitInsert) {\n      this.emit(GuildQueueEvent.AudioTracksAdd, this, tracks);\n    }\n  }\n\n  /**\n   * Appends a track or track resolvable to the queue\n   * @param track The track resolvable to insert\n   * @param index The index to insert the track at (defaults to 0). If > 0, the inserted track will be placed after the track at the given index.\n   */\n  public append(track: Track | Queue<Track> | Array<Track>, index = 0): void {\n    if (index < 0 || index > this.tracks.size) {\n      throw new OutOfRangeError(\n        'index',\n        `${index}`,\n        '0',\n        `${this.tracks.size}`\n      );\n    }\n\n    const count = Array.isArray(track) ?\n    track.length :\n    track instanceof Queue ?\n    track.size :\n    1;\n\n    VALIDATE_QUEUE_CAP(this, count);\n\n    if (track instanceof Track) {\n      this.node.insert(track, index);\n      this.emit(GuildQueueEvent.AudioTrackAdd, this, track);\n      return;\n    }\n\n    const tracks = track instanceof Queue ? track.store : track;\n\n    this.tracks.store.splice(index, 0, ...tracks);\n\n    if (!this.options.noEmitInsert) {\n      this.emit(GuildQueueEvent.AudioTracksAdd, this, tracks);\n    }\n  }\n\n  /**\n   * Inserts the track to the given index\n   * @param track The track to insert\n   * @param index The index to insert the track at (defaults to 0)\n   */\n  public insertTrack(track: Track, index = 0): void {\n    return this.node.insert(track, index);\n  }\n\n  /**\n   * Moves a track in the queue\n   * @param from The track to move\n   * @param to The position to move to\n   */\n  public moveTrack(track: TrackResolvable, index = 0): void {\n    return this.node.move(track, index);\n  }\n\n  /**\n   * Copy a track in the queue\n   * @param from The track to clone\n   * @param to The position to clone at\n   */\n  public copyTrack(track: TrackResolvable, index = 0): void {\n    return this.node.copy(track, index);\n  }\n\n  /**\n   * Swap two tracks in the queue\n   * @param src The first track to swap\n   * @param dest The second track to swap\n   */\n  public swapTracks(src: TrackResolvable, dest: TrackResolvable): void {\n    return this.node.swap(src, dest);\n  }\n\n  /**\n   * Create stream dispatcher from the given connection\n   * @param connection The connection to use\n   */\n  public createDispatcher(\n  connection: VoiceConnection,\n  options: Pick<VoiceConnectConfig, 'audioPlayer' | 'timeout'> = {})\n  {\n    if (connection.state.status === VoiceConnectionStatus.Destroyed) {\n      throw new VoiceConnectionDestroyedError();\n    }\n\n    const channel = this.player.client.channels.cache.get(\n      connection.joinConfig.channelId!\n    );\n    if (!channel) throw new NoVoiceChannelError();\n    if (!channel.isVoiceBased())\n    throw new InvalidArgTypeError(\n      'channel',\n      `VoiceBasedChannel (type ${ChannelType.GuildVoice}/${ChannelType.GuildStageVoice})`,\n      String(channel?.type)\n    );\n\n    if (this.dispatcher) {\n      this.#removeListeners(this.dispatcher);\n      this.dispatcher.destroy();\n      this.dispatcher = null;\n    }\n\n    this.dispatcher = new StreamDispatcher(\n      connection,\n      channel,\n      this,\n      options.timeout ?? this.options.connectionTimeout,\n      options.audioPlayer\n    );\n  }\n\n  /**\n   * Connect to a voice channel\n   * @param channelResolvable The voice channel to connect to\n   * @param options Join config\n   */\n  public async connect(\n  channelResolvable: GuildVoiceChannelResolvable,\n  options: VoiceConnectConfig = {})\n  {\n    const channel = this.player.client.channels.resolve(channelResolvable);\n    if (!channel || !channel.isVoiceBased()) {\n      throw new InvalidArgTypeError(\n        'channel',\n        `VoiceBasedChannel (type ${ChannelType.GuildVoice}/${ChannelType.GuildStageVoice})`,\n        String(channel?.type)\n      );\n    }\n\n    if (this.hasDebugger)\n    this.debug(\n      `Connecting to ${\n      channel.type === ChannelType.GuildStageVoice ? 'stage' : 'voice'} channel ${\n      channel.name} (ID: ${channel.id})`\n    );\n\n    if (this.dispatcher && channel.id !== this.dispatcher.channel.id) {\n      if (this.hasDebugger) this.debug('Destroying old connection');\n      this.#removeListeners(this.dispatcher);\n      this.dispatcher.destroy();\n      this.dispatcher = null;\n    }\n\n    this.dispatcher = await this.player.voiceUtils.connect(channel, {\n      deaf: options.deaf ?? this.options.selfDeaf ?? true,\n      maxTime: options?.timeout ?? this.options.connectionTimeout ?? 120_000,\n      queue: this,\n      audioPlayer: options?.audioPlayer,\n      group: options.group ?? this.player.client.user?.id,\n      daveEncryption: options.daveEncryption,\n      decryptionFailureTolerance: options.decryptionFailureTolerance\n    });\n\n    this.emit(GuildQueueEvent.Connection, this);\n\n    if (this.channel!.type === ChannelType.GuildStageVoice) {\n      await this.channel!.guild.members.me!.voice.setSuppressed(false).catch(\n        async () => {\n          return await this.channel!.guild.members.me!.voice.setRequestToSpeak(\n            true\n          ).catch(Util.noop);\n        }\n      );\n    }\n\n    this.#attachListeners(this.dispatcher);\n\n    return this;\n  }\n\n  /**\n   * Enable shuffle mode for this queue\n   * @param dynamic Whether to shuffle the queue dynamically. Defaults to `true`.\n   * Dynamic shuffling will shuffle the queue when the current track ends, without mutating the queue.\n   * If set to `false`, the queue will be shuffled immediately in-place, which cannot be undone.\n   */\n  public enableShuffle(dynamic = true) {\n    if (!dynamic) {\n      this.tracks.shuffle();\n      return true;\n    }\n\n    this.#shuffle = true;\n    return true;\n  }\n\n  /**\n   * Disable shuffle mode for this queue.\n   */\n  public disableShuffle() {\n    this.#shuffle = false;\n    return true;\n  }\n\n  /**\n   * Toggle shuffle mode for this queue.\n   * @param dynamic Whether to shuffle the queue dynamically. Defaults to `true`.\n   * @returns Whether shuffle is enabled or disabled.\n   */\n  public toggleShuffle(dynamic = true) {\n    if (dynamic) {\n      this.#shuffle = !this.#shuffle;\n      return this.#shuffle;\n    } else {\n      this.tracks.shuffle();\n      return true;\n    }\n  }\n\n  /**\n   * Whether shuffle mode is enabled for this queue.\n   */\n  public get isShuffling() {\n    return this.#shuffle;\n  }\n\n  /**\n   * The voice connection latency of this queue\n   */\n  public get ping() {\n    return this.connection?.ping.udp ?? -1;\n  }\n\n  /**\n   * Delete this queue\n   */\n  public delete() {\n    if (this.player.nodes.delete(this.id)) {\n      this.#deleted = true;\n      this.player.events.emit(GuildQueueEvent.QueueDelete, this);\n      this.node.tasksQueue.cancelAll();\n      this.tasksQueue.cancelAll();\n    }\n  }\n\n  /**\n   * Revives this queue\n   * @returns\n   */\n  public revive() {\n    if (!this.deleted || this.player.nodes.has(this.id)) return;\n    this.#deleted = false;\n    this.setTransitioning(false);\n    this.player.nodes.cache.set(this.id, this);\n    this.player.events.emit(GuildQueueEvent.QueueCreate, this);\n  }\n\n  /**\n   * Set self deaf\n   * @param mode On/Off state\n   * @param reason Reason\n   */\n  public setSelfDeaf(mode?: boolean, reason?: string) {\n    return this.guild.members.me!.voice.setDeaf(mode, reason);\n  }\n\n  /**\n   * Set self mute\n   * @param mode On/Off state\n   * @param reason Reason\n   */\n  public setSelfMute(mode?: boolean, reason?: string) {\n    return this.guild.members.me!.voice.setMute(mode, reason);\n  }\n\n  /**\n   * Play a track in this queue\n   * @param track The track to be played\n   * @param options Player node initialization options\n   */\n  public async play(\n  track: TrackLike,\n  options?: PlayerNodeInitializerOptions<Meta>)\n  {\n    if (!this.channel) throw new NoVoiceConnectionError();\n\n    return this.player.play(this.channel, track, options);\n  }\n\n  /**\n   * Emit an event on this queue\n   * @param event The event to emit\n   * @param args The args for the event\n   */\n  public emit<K extends keyof GuildQueueEvents<Meta>>(\n  event: K,\n  ...args: Parameters<GuildQueueEvents<Meta>[K]>)\n  : boolean {\n    if (this.deleted) return false;\n    return this.player.events.emit(event, ...args);\n  }\n\n  #attachListeners(dispatcher: StreamDispatcher) {\n    dispatcher.on('error', (e) => this.emit(GuildQueueEvent.Error, this, e));\n    dispatcher.on(\n      'debug',\n      (m) => this.hasDebugger && this.emit(GuildQueueEvent.Debug, this, m)\n    );\n    dispatcher.on('finish', (r) => this.#performFinish(r));\n    dispatcher.on('start', (r) => this.#performStart(r));\n    dispatcher.on('destroyed', () => {\n      this.#removeListeners(dispatcher);\n      this.dispatcher = null;\n    });\n    dispatcher.on('dsp', (f) => {\n      if (!Object.is(this.filters._lastFiltersCache.filters, f)) {\n        this.emit(\n          GuildQueueEvent.DSPUpdate,\n          this,\n          this.filters._lastFiltersCache.filters,\n          f\n        );\n      }\n      this.filters._lastFiltersCache.filters = f;\n    });\n    dispatcher.on('biquad', (f) => {\n      if (this.filters._lastFiltersCache.biquad !== f) {\n        this.emit(\n          GuildQueueEvent.BiquadFiltersUpdate,\n          this,\n          this.filters._lastFiltersCache.biquad,\n          f\n        );\n      }\n      this.filters._lastFiltersCache.biquad = f;\n    });\n    dispatcher.on('eqBands', (f) => {\n      if (!Object.is(f, this.filters._lastFiltersCache.equalizer)) {\n        this.emit(\n          GuildQueueEvent.EqualizerUpdate,\n          this,\n          this.filters._lastFiltersCache.equalizer,\n          f\n        );\n      }\n      this.filters._lastFiltersCache.equalizer = f;\n    });\n    dispatcher.on('volume', (f) => {\n      if (this.filters._lastFiltersCache.volume !== f)\n      this.emit(\n        GuildQueueEvent.VolumeChange,\n        this,\n        this.filters._lastFiltersCache.volume,\n        f\n      );\n      this.filters._lastFiltersCache.volume = f;\n    });\n\n    // eslint-disable-next-line @typescript-eslint/no-explicit-any\n    const areObjectsDifferent = (a: any, b: any) => {\n      if (!a && !b) return false;\n      if (!a || !b) return true;\n      if (Object.keys(a).length !== Object.keys(b).length) return true;\n      return Object.keys(a).some((k) => a[k] !== b[k]);\n    };\n\n    dispatcher.on('sampleRate', (f) => {\n      if (this.filters._lastFiltersCache.sampleRate !== f.sampleRate) {\n        this.emit(\n          GuildQueueEvent.SampleRateUpdate,\n          this,\n          this.filters._lastFiltersCache.sampleRate,\n          f.sampleRate\n        );\n\n        this.filters._lastFiltersCache.sampleRate = f.sampleRate;\n\n        this.filters.seeker?.setSampleRate(f.sampleRate);\n        this.filters.seeker?.setTotalDuration(this.node.estimatedDuration);\n      }\n\n      if (f.currentFilter !== this.filters._lastFiltersCache.sampleRateFilter) {\n        this.emit(\n          GuildQueueEvent.SampleRateFilterUpdate,\n          this,\n          this.filters._lastFiltersCache.sampleRateFilter ?? null,\n          f.currentFilter\n        );\n        this.filters._lastFiltersCache.sampleRateFilter = f.currentFilter;\n      }\n    });\n    dispatcher.on('reverb', (f) => {\n      if (areObjectsDifferent(f, this.filters._lastFiltersCache.reverb)) {\n        this.emit(\n          GuildQueueEvent.ReverbUpdate,\n          this,\n          this.filters._lastFiltersCache.reverb ?? null,\n          f\n        );\n        this.filters._lastFiltersCache.reverb = f;\n      }\n    });\n    dispatcher.on('seeker', (f) => {\n      if (this.hasDebugger) {\n        this.debug(\n          `Seeker >> Seeked to ${f.seekTarget}ms for Track ${this.currentTrack?.title}`\n        );\n      }\n\n      if (f.seekTarget != null) this.node.setProgress(f.seekTarget);\n\n      this.emit(GuildQueueEvent.PlayerSeek, this, f);\n    });\n\n    dispatcher.on('compressor', (f) => {\n      if (areObjectsDifferent(f, this.filters._lastFiltersCache.compressor)) {\n        this.emit(\n          GuildQueueEvent.CompressorUpdate,\n          this,\n          this.filters._lastFiltersCache.compressor ?? null,\n          f\n        );\n        this.filters._lastFiltersCache.compressor = f;\n      }\n    });\n  }\n\n  public get hasDebugger() {\n    return this.player.events.hasDebugger;\n  }\n\n  #removeListeners<T extends {removeAllListeners: () => unknown;}>(target: T) {\n    target.removeAllListeners();\n  }\n\n  #performStart(resource?: AudioResource<Track>) {\n    const track = resource?.metadata || this.currentTrack;\n    const reason = this.isTransitioning() ? 'filters' : 'normal';\n\n    if (this.hasDebugger)\n    this.debug(\n      `Player triggered for Track ${JSON.stringify({\n        title: track?.title,\n        reason\n      })}`\n    );\n\n    this.emit(GuildQueueEvent.PlayerTrigger, this, track!, reason);\n    if (track && !this.isTransitioning())\n    this.emit(GuildQueueEvent.PlayerStart, this, track);\n    this.setTransitioning(false);\n  }\n\n  #getNextTrack() {\n    if (!this.isShuffling) {\n      return this.tracks.dispatch();\n    }\n\n    const store = this.tracks.store;\n\n    if (!store.length) return;\n\n    const track = Util.randomChoice(store);\n\n    this.tracks.removeOne((t) => {\n      return t.id === track.id;\n    });\n\n    return track;\n  }\n\n  #performFinish(resource?: AudioResource<Track>) {\n    const track = resource?.metadata || this.currentTrack;\n\n    if (this.hasDebugger)\n    this.debug(\n      `Track ${JSON.stringify({\n        title: track?.title,\n        isTransitionMode: this.isTransitioning()\n      })} was marked as finished`\n    );\n\n    if (!this.isTransitioning()) {\n      this.syncedLyricsProvider.unsubscribe();\n      this.syncedLyricsProvider.lyrics.clear();\n      if (this.hasDebugger)\n      this.debug(\n        'Adding track to history and emitting finish event since transition mode is disabled...'\n      );\n      if (track) {\n        this.history.push(track);\n        this.node.resetProgress();\n        this.emit(GuildQueueEvent.PlayerFinish, this, track);\n      }\n      if (this.#deleted) return this.#emitEnd();\n      if (this.tracks.size < 1 && this.repeatMode === QueueRepeatMode.OFF) {\n        if (this.hasDebugger)\n        this.debug(\n          'No more tracks left in the queue to play and repeat mode is off, initiating #emitEnd()'\n        );\n        this.#emitEnd();\n      } else {\n        if (this.repeatMode === QueueRepeatMode.TRACK) {\n          if (this.hasDebugger)\n          this.debug(\n            'Repeat mode is set to track, repeating last track from the history...'\n          );\n          this.__current = this.history.tracks.dispatch() || track;\n          return this.node.play(this.__current!, { queue: false });\n        }\n        if (this.repeatMode === QueueRepeatMode.QUEUE) {\n          if (this.hasDebugger)\n          this.debug(\n            'Repeat mode is set to queue, moving last track from the history to current queue...'\n          );\n          const next = this.history.tracks.dispatch() || track;\n          if (next) this.tracks.add(next);\n        }\n        if (!this.tracks.size && track) {\n          if (this.repeatMode === QueueRepeatMode.AUTOPLAY) {\n            if (this.hasDebugger)\n            this.debug(\n              'Repeat mode is set to autoplay, initiating autoplay handler...'\n            );\n            this.#handleAutoplay(track);\n            return;\n          }\n        } else {\n          if (this.hasDebugger)\n          this.debug('Initializing next track of the queue...');\n          this.__current = this.#getNextTrack()!;\n          this.node.play(this.__current, {\n            queue: false\n          });\n        }\n      }\n    }\n  }\n\n  #emitEnd() {\n    this.__current = null;\n    this.emit(GuildQueueEvent.EmptyQueue, this);\n    if (this.options.leaveOnEnd) {\n      const tm: NodeJS.Timeout = setTimeout(() => {\n        if (this.isPlaying()) return clearTimeout(tm);\n        this.dispatcher?.disconnect();\n      }, this.options.leaveOnEndCooldown).unref();\n    }\n  }\n\n  async #handleAutoplay(track: Track) {\n    try {\n      if (this.hasDebugger)\n      this.debug(\n        `Autoplay >> Finding related tracks for Track ${track.title} (${\n        track.url}) [ext:${\n        track.extractor?.identifier || 'N/A'}]`\n      );\n      const tracks =\n      (await track.extractor?.getRelatedTracks(track, this.history))?.\n      tracks ||\n      (\n      await this.player.extractors.run(async (ext) => {\n        if (this.hasDebugger)\n        this.debug(`Autoplay >> Querying extractor ${ext.identifier}`);\n        const res = await ext.getRelatedTracks(track, this.history);\n        if (!res.tracks.length) {\n          if (this.hasDebugger)\n          this.debug(\n            `Autoplay >> Extractor ${ext.identifier} failed to provide results.`\n          );\n          return false;\n        }\n\n        if (this.hasDebugger)\n        this.debug(\n          `Autoplay >> Extractor ${ext.identifier} successfully returned results.`\n        );\n\n        return res.tracks;\n      }))?.\n      result ||\n      [];\n\n      let resolver: (track: Track | null) => void = Util.noop;\n      const donePromise = new Promise<Track | null>(\n        (resolve) => resolver = resolve\n      );\n\n      const success = this.emit(\n        GuildQueueEvent.WillAutoPlay,\n        this,\n        tracks,\n        resolver!\n      );\n\n      // prevent dangling promise\n      if (!success) {\n        resolver(\n          tracks.length ?\n          (() => {\n            const unique = tracks.filter(\n              (tr) => !this.history.tracks.find((t) => t.url === tr.url)\n            );\n            return unique?.[0] ?? Util.randomChoice(tracks.slice(0, 5));\n          })() :\n          null\n        );\n      }\n\n      const nextTrack = await donePromise;\n\n      if (!nextTrack) {\n        if (this.hasDebugger)\n        this.debug('Autoplay >> No track was found, initiating #emitEnd()');\n        throw 'No track was found';\n      }\n\n      await this.node.play(nextTrack, {\n        queue: false,\n        seek: 0,\n        transitionMode: false\n      });\n    } catch {\n      return this.#emitEnd();\n    }\n  }\n}","import {\n  AudioPlayer,\n  AudioPlayerError,\n  AudioPlayerStatus,\n  AudioResource,\n  createAudioPlayer,\n  createAudioResource,\n  entersState,\n  StreamType,\n  VoiceConnection,\n  VoiceConnectionStatus,\n  VoiceConnectionDisconnectReason } from\n'discord-voip';\nimport { StageChannel, VoiceChannel } from 'discord.js';\nimport type { Readable } from 'stream';\nimport { EventEmitter } from '@discord-player/utils';\nimport { Track } from '../fabric/Track';\nimport { Util } from '../utils/Util';\nimport {\n  EqualizerBand,\n  BiquadFilters,\n  PCMFilters,\n  FiltersChain,\n  CompressorParameters,\n  ReverbParameters,\n  SeekerParameters,\n  ResampleParameters,\n  CommonResamplerFilterPreset,\n  SeekEvent } from\n'@discord-player/equalizer';\nimport { GuildQueue, GuildQueueEvent, PostProcessedResult } from '../queue';\nimport { NoAudioResourceError } from '../errors';\nimport { InterceptedStream } from './InterceptedStream';\n\nexport interface CreateStreamOps {\n  type?: StreamType;\n  data: Track;\n  disableVolume?: boolean;\n  disableEqualizer?: boolean;\n  disableBiquad?: boolean;\n  disableCompressor?: boolean;\n  disableResampler?: boolean;\n  disableReverb?: boolean;\n  disableSeeker?: boolean;\n  eq?: EqualizerBand[];\n  biquadFilter?: BiquadFilters;\n  disableFilters?: boolean;\n  defaultFilters?: PCMFilters[];\n  volume?: number;\n  sampleRate?: number;\n  sampleRateFilters?: CommonResamplerFilterPreset;\n  skipFFmpeg?: boolean;\n  compressor?: {\n    threshold: number;\n    ratio: number;\n    attack: number;\n    release: number;\n    makeupGain: number;\n    kneeWidth: number;\n  };\n  reverb?: {\n    roomSize: number;\n    damping: number;\n    wetLevel: number;\n    dryLevel: number;\n  };\n  seeker?: {\n    seekTarget: number | null;\n    totalDuration: number;\n  };\n}\n\nexport interface VoiceEvents {\n  /* eslint-disable @typescript-eslint/no-explicit-any */\n  error: (error: AudioPlayerError) => any;\n  debug: (message: string) => any;\n  start: (resource: AudioResource<Track>) => any;\n  finish: (resource: AudioResource<Track>) => any;\n  dsp: (filters: PCMFilters[]) => any;\n  eqBands: (filters: EqualizerBand[]) => any;\n  sampleRate: (filters: ResampleParameters) => any;\n  biquad: (filters: BiquadFilters) => any;\n  compressor: (filters: CompressorParameters) => any;\n  reverb: (filters: ReverbParameters) => any;\n  seeker: (filters: SeekerParameters) => any;\n  volume: (volume: number) => any;\n  destroyed: () => any;\n  /* eslint-enable @typescript-eslint/no-explicit-any */\n}\n\nclass StreamDispatcher extends EventEmitter<VoiceEvents> {\n  public voiceConnection: VoiceConnection;\n  public audioPlayer: AudioPlayer;\n  public channel: VoiceChannel | StageChannel;\n  public audioResource?: AudioResource<Track> | null;\n  public dsp = new FiltersChain();\n\n  #interceptor: InterceptedStream | null = null;\n\n  /**\n   * Creates new connection object\n   * @param {VoiceConnection} connection The connection\n   * @param {VoiceChannel|StageChannel} channel The connected channel\n   * @private\n   */\n  constructor(\n  connection: VoiceConnection,\n  channel: VoiceChannel | StageChannel,\n  public queue: GuildQueue,\n  public readonly connectionTimeout: number = 20000,\n  audioPlayer?: AudioPlayer)\n  {\n    super();\n\n    /**\n     * The voice connection\n     * @type {VoiceConnection}\n     */\n    this.voiceConnection = connection;\n\n    /**\n     * The audio player\n     * @type {AudioPlayer}\n     */\n    this.audioPlayer =\n    audioPlayer ||\n    createAudioPlayer({\n      debug: this.queue.hasDebugger\n    });\n\n    /**\n     * The voice channel\n     * @type {VoiceChannel|StageChannel}\n     */\n    this.channel = channel;\n\n    this.voiceConnection.on('debug', (m) => void this.emit('debug', m));\n    this.voiceConnection.on(\n      'error',\n      (error) => void this.emit('error', error as AudioPlayerError)\n    );\n    this.audioPlayer.on('debug', (m) => void this.emit('debug', m));\n    this.audioPlayer.on('error', (error) => void this.emit('error', error));\n\n    this.dsp.onUpdate = () => {\n      if (!this.dsp) return;\n\n      if (this.dsp.filters?.filters) {\n        this.emit('dsp', this.dsp.filters?.filters);\n      }\n\n      if (this.dsp.biquad?.filters) {\n        this.emit('biquad', this.dsp.biquad?.filters);\n      }\n\n      if (this.dsp.equalizer) {\n        this.emit('eqBands', this.dsp.equalizer.getEQ());\n      }\n\n      if (this.dsp.volume) {\n        this.emit('volume', this.dsp.volume.volume);\n      }\n\n      if (this.dsp.resampler) {\n        this.emit('sampleRate', this.dsp.resampler.getParameters());\n      }\n      if (this.dsp.compressor) {\n        this.emit('compressor', this.dsp.compressor.getParameters());\n      }\n\n      if (this.dsp.reverb) {\n        this.emit('reverb', this.dsp.reverb.getParameters());\n      }\n\n      if (this.dsp.seeker) {\n        this.emit('seeker', this.dsp.seeker.getParameters());\n      }\n    };\n\n    this.dsp.onError = (e) => this.emit('error', e as AudioPlayerError);\n\n    this.voiceConnection.\n    on(VoiceConnectionStatus.Disconnected, async (oldState, newState) => {\n      if (newState.reason === VoiceConnectionDisconnectReason.Manual) {\n        this.destroy();\n        return;\n      }\n\n      if (\n      newState.reason === VoiceConnectionDisconnectReason.WebSocketClose &&\n      newState.closeCode === 4014)\n      {\n        try {\n          await entersState(\n            this.voiceConnection,\n            VoiceConnectionStatus.Connecting,\n            this.connectionTimeout\n          );\n        } catch {\n          try {\n            if (\n            this.voiceConnection.state.status !==\n            VoiceConnectionStatus.Destroyed)\n\n            this.destroy();\n          } catch (err) {\n            this.emit('error', err as AudioPlayerError);\n          }\n        }\n      } else if (this.voiceConnection.rejoinAttempts < 5) {\n        await Util.wait((this.voiceConnection.rejoinAttempts + 1) * 5000);\n        this.voiceConnection.rejoin();\n      } else {\n        try {\n          if (\n          this.voiceConnection.state.status !==\n          VoiceConnectionStatus.Destroyed)\n\n          this.destroy();\n        } catch (err) {\n          this.emit('error', err as AudioPlayerError);\n        }\n      }\n    }).\n    on(VoiceConnectionStatus.Destroyed, () => {\n      this.end();\n      this.queue.emit(GuildQueueEvent.ConnectionDestroyed, this.queue);\n    });\n\n    this.audioPlayer.on('stateChange', (oldState, newState) => {\n      if (\n      oldState.status !== AudioPlayerStatus.Paused &&\n      newState.status === AudioPlayerStatus.Paused)\n      {\n        this.queue.emit(GuildQueueEvent.PlayerPause, this.queue);\n      }\n\n      if (\n      oldState.status === AudioPlayerStatus.Paused &&\n      newState.status !== AudioPlayerStatus.Paused)\n      {\n        this.queue.emit(GuildQueueEvent.PlayerResume, this.queue);\n      }\n\n      if (newState.status === AudioPlayerStatus.Playing) {\n        if (\n        oldState.status === AudioPlayerStatus.Idle ||\n        oldState.status === AudioPlayerStatus.Buffering)\n        {\n          return this.emit('start', this.audioResource!);\n        }\n      } else if (\n      newState.status === AudioPlayerStatus.Idle &&\n      oldState.status !== AudioPlayerStatus.Idle)\n      {\n        this.emit('finish', this.audioResource!);\n        this.dsp.destroy();\n        this.audioResource = null;\n      }\n    });\n\n    this.voiceConnection.subscribe(this.audioPlayer);\n  }\n\n  /**\n   * Check if the player has been paused manually\n   */\n  get paused() {\n    return this.audioPlayer.state.status === AudioPlayerStatus.Paused;\n  }\n\n  set paused(val: boolean) {\n    val ? this.pause(true) : this.resume();\n  }\n\n  /**\n   * Whether or not the player is currently paused automatically or manually.\n   */\n  isPaused() {\n    return (\n      this.paused ||\n      this.audioPlayer.state.status === AudioPlayerStatus.AutoPaused);\n\n  }\n\n  /**\n   * Whether or not the player is currently buffering\n   */\n  isBuffering() {\n    return this.audioPlayer.state.status === AudioPlayerStatus.Buffering;\n  }\n\n  /**\n   * Whether or not the player is currently playing\n   */\n  isPlaying() {\n    return this.audioPlayer.state.status === AudioPlayerStatus.Playing;\n  }\n\n  /**\n   * Whether or not the player is currently idle\n   */\n  isIdle() {\n    return this.audioPlayer.state.status === AudioPlayerStatus.Idle;\n  }\n\n  /**\n   * Whether or not the voice connection has been destroyed\n   */\n  isDestroyed() {\n    return (\n      this.voiceConnection.state.status === VoiceConnectionStatus.Destroyed);\n\n  }\n\n  /**\n   * Whether or not the voice connection has been destroyed\n   */\n  isDisconnected() {\n    return (\n      this.voiceConnection.state.status === VoiceConnectionStatus.Disconnected);\n\n  }\n\n  /**\n   * Whether or not the voice connection is ready to play\n   */\n  isReady() {\n    return this.voiceConnection.state.status === VoiceConnectionStatus.Ready;\n  }\n\n  /**\n   * Whether or not the voice connection is signalling\n   */\n  isSignalling() {\n    return (\n      this.voiceConnection.state.status === VoiceConnectionStatus.Signalling);\n\n  }\n\n  /**\n   * Whether or not the voice connection is connecting\n   */\n  isConnecting() {\n    return (\n      this.voiceConnection.state.status === VoiceConnectionStatus.Connecting);\n\n  }\n\n  /**\n   * Creates stream\n   * @param {Readable} src The stream source\n   * @param {object} [ops] Options\n   * @returns {AudioResource}\n   */\n  async createStream(src: Readable, ops: CreateStreamOps) {\n    if (!ops?.disableFilters && this.queue.hasDebugger)\n    this.queue.debug('Initiating DSP filters pipeline...');\n    const stream = !ops?.disableFilters ?\n    this.dsp.create(src, {\n      dsp: {\n        filters: ops?.defaultFilters,\n        disabled: ops?.disableFilters\n      },\n      biquad: ops?.biquadFilter ?\n      {\n        filter: ops.biquadFilter,\n        disabled: ops?.disableBiquad\n      } :\n      undefined,\n      resampler: ops?.sampleRate ?\n      {\n        inputSampleRate: 48000,\n        targetSampleRate: ops?.sampleRate,\n        disabled: ops?.disableResampler\n      } :\n      undefined,\n      equalizer: {\n        bandMultiplier: ops?.eq,\n        disabled: ops?.disableEqualizer\n      },\n      volume: {\n        volume: ops?.volume,\n        disabled: ops?.disableVolume\n      },\n      compressor: ops?.compressor ?\n      {\n        threshold: ops?.compressor.threshold,\n        ratio: ops?.compressor.ratio,\n        attack: ops?.compressor.attack,\n        release: ops?.compressor.release,\n        makeupGain: ops?.compressor.makeupGain,\n        disabled: ops?.disableCompressor,\n        kneeWidth: ops?.compressor.kneeWidth\n      } :\n      undefined,\n      reverb: ops?.reverb ?\n      {\n        roomSize: ops?.reverb.roomSize,\n        damping: ops?.reverb.damping,\n        wetLevel: ops?.reverb.wetLevel,\n        dryLevel: ops?.reverb.dryLevel,\n        disabled: ops?.disableReverb\n      } :\n      undefined,\n      seeker: ops?.seeker ?\n      {\n        disabled: ops?.disableSeeker,\n        seekTarget: ops?.seeker.seekTarget,\n        sampleRate: 48000,\n        channels: 2,\n        totalDuration: ops?.seeker.totalDuration\n      } :\n      undefined\n    }) :\n    src;\n\n    if (this.dsp.seeker) {\n      // used to handle backward seeking\n      this.dsp.seeker.on('seek', (data: SeekEvent) => {\n        this.queue.node.requestSeek(data).catch(() => {});\n      });\n    }\n\n    if (this.queue.hasDebugger) {\n      this.queue.debug('Executing onAfterCreateStream hook...');\n    }\n\n    const postStream = await this.queue.\n    onAfterCreateStream?.(stream, this.queue, ops?.data).\n    catch(\n      () =>\n      ({\n        stream: stream,\n        type: ops?.type ?? StreamType.Arbitrary\n      }) as PostProcessedResult\n    );\n\n    if (this.queue.hasDebugger) this.queue.debug('Preparing AudioResource...');\n\n    const format = postStream?.type ?? ops?.type ?? StreamType.Arbitrary;\n\n    let _stream: Readable;\n\n    if (this.queue.canIntercept()) {\n      this.#interceptor = new InterceptedStream();\n\n      // @ts-ignore\n      (postStream?.stream ?? stream).pipe(this.#interceptor);\n\n      _stream = this.#interceptor;\n\n      await this.queue.player.handleInterceptingStream(\n        this.queue,\n        ops?.data,\n        format,\n        this.#interceptor\n      );\n    } else {\n      _stream = postStream?.stream ?? stream;\n    }\n\n    this.audioResource = createAudioResource(_stream, {\n      inputType: format,\n      metadata: ops?.data as Track,\n      // volume controls happen from AudioFilter DSP utility\n      inlineVolume: false\n    });\n\n    return this.audioResource;\n  }\n\n  public get resampler() {\n    return this.dsp?.resampler;\n  }\n\n  public get filters() {\n    return this.dsp?.filters;\n  }\n\n  public get biquad() {\n    return this.dsp?.biquad || null;\n  }\n\n  public get equalizer() {\n    return this.dsp?.equalizer || null;\n  }\n\n  public get compressor() {\n    return this.dsp?.compressor || null;\n  }\n\n  public get reverb() {\n    return this.dsp?.reverb || null;\n  }\n\n  public get seeker() {\n    return this.dsp?.seeker || null;\n  }\n\n  /**\n   * The player status\n   * @type {AudioPlayerStatus}\n   */\n  get status() {\n    return this.audioPlayer.state.status;\n  }\n\n  /**\n   * Disconnects from voice\n   * @returns {void}\n   */\n  disconnect() {\n    try {\n      if (this.audioPlayer) this.audioPlayer.stop(true);\n      if (this.voiceConnection.state.status !== VoiceConnectionStatus.Destroyed)\n      this.voiceConnection.destroy();\n    } catch {} // eslint-disable-line no-empty\n  }\n\n  /**\n   * Destroys this dispatcher\n   */\n  public destroy() {\n    this.disconnect();\n    // @ts-ignore\n    this.audioPlayer.removeAllListeners();\n    // @ts-ignore\n    this.voiceConnection.removeAllListeners();\n    this.dsp.destroy();\n    this.audioResource = null;\n    this.emit('destroyed');\n  }\n\n  /**\n   * Stops the player\n   * @returns {void}\n   */\n  end() {\n    try {\n      this.audioPlayer.stop();\n      this.dsp.destroy();\n    } catch {\n\n      //\n    }}\n\n  /**\n   * Pauses the stream playback\n   * @param {boolean} [interpolateSilence=false] If true, the player will play 5 packets of silence after pausing to prevent audio glitches.\n   * @returns {boolean}\n   */\n  pause(interpolateSilence?: boolean) {\n    const success = this.audioPlayer.pause(interpolateSilence);\n    return success;\n  }\n\n  /**\n   * Resumes the stream playback\n   * @returns {boolean}\n   */\n  resume() {\n    const success = this.audioPlayer.unpause();\n    return success;\n  }\n\n  /**\n   * Play stream\n   * @param {AudioResource<Track>} [resource=this.audioResource] The audio resource to play\n   * @param {boolean} [opus=false] Whether or not to use opus\n   * @returns {Promise<StreamDispatcher>}\n   */\n  async playStream(resource: AudioResource<Track> = this.audioResource!) {\n    if (!resource) {\n      throw new NoAudioResourceError();\n    }\n    if (resource.ended) {\n      return void this.emit('finish', resource);\n    }\n    if (!this.audioResource) this.audioResource = resource;\n    if (this.voiceConnection.state.status !== VoiceConnectionStatus.Ready) {\n      try {\n        await entersState(\n          this.voiceConnection,\n          VoiceConnectionStatus.Ready,\n          this.connectionTimeout\n        );\n      } catch (err) {\n        return void this.emit('error', err as AudioPlayerError);\n      }\n    }\n\n    try {\n      this.audioPlayer.play(resource);\n    } catch (e) {\n      this.emit('error', e as AudioPlayerError);\n    }\n\n    return this;\n  }\n\n  /**\n   * Sets playback volume\n   * @param {number} value The volume amount\n   * @returns {boolean}\n   */\n  setVolume(value: number) {\n    if (!this.dsp.volume) return false;\n    return this.dsp.volume.setVolume(value);\n  }\n\n  /**\n   * The current volume\n   * @type {number}\n   */\n  get volume() {\n    if (!this.dsp.volume) return 100;\n    return this.dsp.volume.volume;\n  }\n\n  /**\n   * The playback time\n   * @type {number}\n   */\n  get streamTime() {\n    if (!this.audioResource) return 0;\n    return this.audioResource.playbackDuration;\n  }\n}\n\nexport { StreamDispatcher };","import { Queue } from '@discord-player/utils';\nimport { NoResultError } from '../errors';\nimport { Track } from '../fabric/Track';\nimport { GuildQueue, TrackSkipReason } from './GuildQueue';\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport class GuildQueueHistory<Meta = any> {\n  public tracks = new Queue<Track>('LIFO');\n  public constructor(public queue: GuildQueue<Meta>) {}\n\n  /**\n   * Current track in the queue\n   */\n  public get currentTrack() {\n    return (\n      this.queue.dispatcher?.audioResource?.metadata ||\n      // eslint-disable-next-line @typescript-eslint/no-explicit-any\n      (this.queue as any).__current as Track | null);\n\n  }\n\n  /**\n   * Next track in the queue\n   */\n  public get nextTrack() {\n    return this.queue.tracks.at(0) || null;\n  }\n\n  /**\n   * Previous track in the queue\n   */\n  public get previousTrack() {\n    return this.tracks.at(0) || null;\n  }\n\n  /**\n   * If history is disabled\n   */\n  public get disabled() {\n    return this.queue.options.disableHistory;\n  }\n\n  /**\n   * Gets the size of the queue\n   */\n  public get size() {\n    return this.tracks.size;\n  }\n\n  public getSize() {\n    return this.size;\n  }\n\n  /**\n   * If history is empty\n   */\n  public isEmpty() {\n    return this.tracks.size < 1;\n  }\n\n  /**\n   * Add track to track history\n   * @param track The track to add\n   */\n  public push(track: Track | Track[]) {\n    if (this.disabled) return false;\n    this.tracks.add(track);\n\n    this.resize();\n\n    return true;\n  }\n\n  /**\n   * Clear history\n   */\n  public clear() {\n    this.tracks.clear();\n  }\n\n  /**\n   * Play the next track in the queue\n   */\n  public async next() {\n    const track = this.nextTrack;\n    if (!track) {\n      throw new NoResultError('No next track in the queue');\n    }\n\n    this.queue.node.skip({\n      reason: TrackSkipReason.HistoryNext,\n      description: 'Skipped by GuildQueueHistory.next()'\n    });\n  }\n\n  /**\n   * Play the previous track in the queue\n   */\n  public async previous(preserveCurrent = true) {\n    const track = this.tracks.dispatch();\n    if (!track) {\n      throw new NoResultError('No previous track in the queue');\n    }\n\n    const current = this.currentTrack;\n\n    await this.queue.node.play(track, { queue: false });\n    if (current && preserveCurrent) this.queue.node.insert(current, 0);\n  }\n\n  /**\n   * Alias to [GuildQueueHistory].previous()\n   */\n  public back(preserveCurrent = true) {\n    return this.previous(preserveCurrent);\n  }\n\n  /**\n   * Resize history store\n   */\n  public resize() {\n    if (!Number.isFinite(this.queue.maxHistorySize)) return;\n    if (this.tracks.store.length < this.queue.maxHistorySize) return;\n    this.tracks.store.splice(this.queue.maxHistorySize);\n  }\n}","import { AudioResource, StreamType } from 'discord-voip';\nimport { Readable } from 'stream';\nimport { QueryResolver, SearchQueryType } from '../utils/QueryResolver';\nimport { Util, VALIDATE_QUEUE_CAP } from '../utils/Util';\nimport { Track, TrackResolvable } from '../fabric/Track';\nimport { GuildQueue, GuildQueueEvent, TrackSkipReason } from './GuildQueue';\nimport { setTimeout as waitFor } from 'timers/promises';\nimport { AsyncQueue } from '../utils/AsyncQueue';\nimport {\n  InvalidArgTypeError,\n  NoResultError,\n  NoVoiceConnectionError,\n  OutOfRangeError } from\n'../errors';\nimport { TypeUtil } from '../utils/TypeUtil';\nimport { CreateStreamOps } from '../stream/StreamDispatcher';\nimport { ExtractorStreamable } from '../extractors/BaseExtractor';\nimport { OggDemuxer, OpusDecoder, WebmDemuxer } from '@discord-player/opus';\nimport { SeekEvent } from '@discord-player/equalizer';\n\nexport const FFMPEG_SRATE_REGEX = /asetrate=\\d+\\*(\\d(\\.\\d)?)/;\n\nexport interface PlayerProgressbarOptions {\n  /**\n   * If it should render time codes\n   */\n  timecodes?: boolean;\n  /**\n   * If it should create progress bar for the whole queue\n   */\n  length?: number;\n  /**\n   * The bar length\n   */\n  leftChar?: string;\n  /**\n   * The elapsed time track\n   */\n  rightChar?: string;\n  /**\n   * The remaining time track\n   */\n  separator?: string;\n  /**\n   * The separation between timestamp and line\n   */\n  indicator?: string;\n  /**\n   * The indicator\n   */\n  queue?: boolean;\n}\n\nexport interface ResourcePlayOptions {\n  queue?: boolean;\n  seek?: number;\n  transitionMode?: boolean;\n}\n\nexport interface SkipOptions {\n  reason: TrackSkipReason;\n  description: string;\n}\n\nexport interface PlayerTimestamp {\n  current: {\n    label: string;\n    value: number;\n  };\n  total: {\n    label: string;\n    value: number;\n  };\n  progress: number;\n}\n\nexport interface StreamConfig {\n  dispatcherConfig: CreateStreamOps;\n  playerConfig: ResourcePlayOptions;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport class GuildQueuePlayerNode<Meta = any> {\n  #progress = 0;\n  #hasFFmpegOptimization = false;\n  public tasksQueue = new AsyncQueue();\n  public constructor(public queue: GuildQueue<Meta>) {\n    this.#hasFFmpegOptimization = /libopus: (yes|true)/.test(\n      this.queue.player.scanDeps()\n    );\n  }\n\n  /**\n   * If the player is currently in idle mode\n   */\n  public isIdle() {\n    return !!this.queue.dispatcher?.isIdle();\n  }\n\n  /**\n   * If the player is currently buffering the track\n   */\n  public isBuffering() {\n    return !!this.queue.dispatcher?.isBuffering();\n  }\n\n  /**\n   * If the player is currently playing a track\n   */\n  public isPlaying() {\n    return !!this.queue.dispatcher?.isPlaying();\n  }\n\n  /**\n   * If the player is currently paused\n   */\n  public isPaused() {\n    return !!this.queue.dispatcher?.isPaused();\n  }\n\n  /**\n   * Reset progress history\n   */\n  public resetProgress() {\n    this.#progress = 0;\n  }\n\n  /**\n   * Set player progress\n   */\n  public setProgress(progress: number) {\n    this.#progress = progress;\n  }\n\n  /**\n   * The stream time for current session\n   */\n  public get streamTime() {\n    return this.queue.dispatcher?.streamTime ?? 0;\n  }\n\n  /**\n   * Current playback duration with history included\n   */\n  public get playbackTime() {\n    if (this.queue.filters.seeker) {\n      const pos = this.queue.filters.seeker.getPosition();\n      if (pos > 0) return pos;\n    }\n\n    const dur = this.#progress + this.streamTime;\n\n    return dur;\n  }\n\n  /**\n   * Get duration multiplier\n   */\n  public getDurationMultiplier() {\n    const srateFilters = this.queue.filters.ffmpeg.\n    toArray().\n    filter((ff) => FFMPEG_SRATE_REGEX.test(ff));\n    const multipliers = srateFilters.\n    map((m) => {\n      return parseFloat(FFMPEG_SRATE_REGEX.exec(m)?.[1] as string);\n    }).\n    filter((f) => !isNaN(f));\n\n    return !multipliers.length ?\n    1 :\n    multipliers.reduce((accumulator, current) => current + accumulator);\n  }\n\n  /**\n   * Estimated progress of the player\n   */\n  public get estimatedPlaybackTime() {\n    const dur = this.playbackTime;\n    const val = this.getDurationMultiplier() * dur;\n\n    return val;\n  }\n\n  /**\n   * Estimated total duration of the player\n   */\n  public get estimatedDuration() {\n    const dur = this.totalDuration;\n\n    // duration multiplier checks ffmpeg filters that may affect the duration\n    const val = Math.round(dur / this.getDurationMultiplier());\n\n    // we also need to check if we have a native resampler filter as it may also affect the duration\n    if (this.queue.filters.resampler) {\n      // get the resampler ratio if we have one\n      const ratio = this.queue.filters.resampler.getRatio();\n      if (ratio <= 0) return val;\n\n      return Math.round(val / ratio);\n    }\n\n    return val;\n  }\n\n  /**\n   * Total duration of the current audio track\n   */\n  public get totalDuration() {\n    const prefersBridgedMetadata = this.queue.options.preferBridgedMetadata;\n    const track = this.queue.currentTrack;\n\n    if (prefersBridgedMetadata) {\n      const trackHasLegacyMetadata =\n      track?.metadata != null &&\n      typeof track.metadata === 'object' &&\n      'bridge' in track.metadata &&\n      track.metadata.bridge != null;\n      const trackHasMetadata = track?.bridgedTrack != null;\n\n      if (trackHasLegacyMetadata || trackHasMetadata) {\n        const duration =\n        track.bridgedTrack?.durationMS ??\n        (\n        track as Track<{\n          bridge: {\n            duration: number;\n          };\n        }>).\n        metadata?.bridge.duration;\n\n        if (TypeUtil.isNumber(duration)) return duration;\n      }\n    }\n\n    return track?.durationMS ?? 0;\n  }\n\n  /**\n   * Get stream progress\n   * @param ignoreFilters Ignore filters\n   */\n  public getTimestamp(ignoreFilters = false): PlayerTimestamp | null {\n    if (!this.queue.currentTrack) return null;\n\n    const current = ignoreFilters ?\n    this.playbackTime :\n    this.estimatedPlaybackTime;\n    const total = ignoreFilters ? this.totalDuration : this.estimatedDuration;\n\n    return {\n      current: {\n        label: Util.buildTimeCode(Util.parseMS(current)),\n        value: current\n      },\n      total: {\n        label: Util.buildTimeCode(Util.parseMS(total)),\n        value: total\n      },\n      progress: Math.round(current / total * 100)\n    };\n  }\n\n  /**\n   * Create progress bar for current progress\n   * @param options Progress bar options\n   */\n  public createProgressBar(options?: PlayerProgressbarOptions) {\n    const timestamp = this.getTimestamp();\n    if (!timestamp) return null;\n    const {\n      indicator = '\\u{1F518}',\n      leftChar = '\\u25AC',\n      rightChar = '\\u25AC',\n      length = 15,\n      timecodes = true,\n      separator = '\\u2503'\n    } = options || {};\n    if (isNaN(length) || length < 0 || !Number.isFinite(length)) {\n      throw new OutOfRangeError(\n        '[PlayerProgressBarOptions.length]',\n        String(length),\n        '0',\n        'Finite Number'\n      );\n    }\n    const index = Math.round(\n      timestamp.current.value / timestamp.total.value * length\n    );\n    if (index >= 1 && index <= length) {\n      const bar = leftChar.repeat(index - 1).split('');\n      bar.push(indicator);\n      bar.push(rightChar.repeat(length - index));\n      if (timecodes) {\n        return `${timestamp.current.label} ${separator} ${bar.join(\n          ''\n        )} ${separator} ${timestamp.total.label}`;\n      } else {\n        return `${bar.join('')}`;\n      }\n    } else {\n      if (timecodes) {\n        return `${\n        timestamp.current.label} ${\n        separator} ${indicator}${rightChar.repeat(\n          length - 1\n        )} ${separator} ${timestamp.total.label}`;\n      } else {\n        return `${indicator}${rightChar.repeat(length - 1)}`;\n      }\n    }\n  }\n\n  /**\n   * Seek the player\n   * @param duration The duration to seek to\n   */\n  public async seek(duration: number) {\n    if (!this.queue.currentTrack) return false;\n    if (duration === this.estimatedPlaybackTime) return true;\n    if (duration > this.totalDuration) {\n      return this.skip({\n        reason: TrackSkipReason.SEEK_OVER_THRESHOLD,\n        description: new OutOfRangeError(\n          '[duration]',\n          String(duration),\n          '0',\n          String(this.totalDuration)\n        ).message\n      });\n    }\n    if (duration < 0) duration = 0;\n\n    const seeker = this.queue.filters.seeker;\n\n    if (seeker) {\n      seeker.seek(duration);\n      return true;\n    }\n\n    return this.queue.filters.triggerReplay(duration).then((v) => {\n      if (v) {\n        this.queue.emit(GuildQueueEvent.PlayerSeek, this.queue, {\n          currentPosition: this.estimatedPlaybackTime,\n          seekTarget: duration,\n          totalDuration: this.estimatedDuration\n        });\n      }\n\n      return v;\n    });\n  }\n\n  /**\n   * Current volume\n   */\n  public get volume() {\n    return this.queue.dispatcher?.volume ?? 100;\n  }\n\n  /**\n   * Set volume\n   * @param vol Volume amount to set\n   */\n  public setVolume(vol: number) {\n    if (!this.queue.dispatcher) return false;\n    const res = this.queue.dispatcher.setVolume(vol);\n    if (res) this.queue.filters._lastFiltersCache.volume = vol;\n    return res;\n  }\n\n  /**\n   * Set bit rate\n   * @param rate The bit rate to set\n   */\n  public setBitrate(rate: number | 'auto') {\n    this.queue.dispatcher?.audioResource?.encoder?.setBitrate(\n      rate === 'auto' ? this.queue.channel?.bitrate ?? 64000 : rate\n    );\n  }\n\n  /**\n   * Set paused state\n   * @param state The state\n   */\n  public setPaused(state: boolean) {\n    if (state) return this.queue.dispatcher?.pause(true) || false;\n    return this.queue.dispatcher?.resume() || false;\n  }\n\n  /**\n   * Pause the playback\n   */\n  public pause() {\n    return this.setPaused(true);\n  }\n\n  /**\n   * Resume the playback\n   */\n  public resume() {\n    return this.setPaused(false);\n  }\n\n  /**\n   * Skip current track\n   */\n  public skip(options?: SkipOptions) {\n    if (!this.queue.dispatcher) return false;\n    const track = this.queue.currentTrack;\n    if (!track) return false;\n    this.queue.setTransitioning(false);\n    this.queue.dispatcher.end();\n    const { reason, description } = options || {\n      reason: TrackSkipReason.Manual,\n      description: 'The track was skipped manually'\n    };\n    this.queue.emit(\n      GuildQueueEvent.PlayerSkip,\n      this.queue,\n      track,\n      reason,\n      description\n    );\n    return true;\n  }\n\n  /**\n   * Remove the given track from queue\n   * @param track The track to remove\n   * @param emitEvent Whether or not to emit the event @defaultValue true\n   */\n  public remove(track: TrackResolvable, emitEvent = true) {\n    const foundTrack = this.queue.tracks.find((t, idx) => {\n      if (track instanceof Track || typeof track === 'string') {\n        return (typeof track === 'string' ? track : track.id) === t.id;\n      }\n      if (typeof track === 'string') return track === t.id;\n      return idx === track;\n    });\n    if (!foundTrack) return null;\n\n    this.queue.tracks.removeOne((t) => t.id === foundTrack.id);\n\n    if (emitEvent)\n    this.queue.emit(GuildQueueEvent.AudioTrackRemove, this.queue, foundTrack);\n\n    return foundTrack;\n  }\n\n  /**\n   * Jump to specific track on the queue\n   * @param track The track to jump to without removing other tracks\n   */\n  public jump(track: TrackResolvable) {\n    const removed = this.remove(track, false);\n    if (!removed) return false;\n    this.queue.tracks.store.unshift(removed);\n    return this.skip({\n      reason: TrackSkipReason.Jump,\n      description: 'The track was jumped to manually'\n    });\n  }\n\n  /**\n   * Get track position\n   * @param track The track\n   */\n  public getTrackPosition(track: TrackResolvable): number {\n    return this.queue.tracks.toArray().findIndex((t, idx) => {\n      if (track instanceof Track || typeof track === 'string') {\n        return (typeof track === 'string' ? track : track.id) === t.id;\n      }\n      if (typeof track === 'string') return track === t.id;\n      return idx === track;\n    });\n  }\n\n  /**\n   * Skip to the given track, removing others on the way\n   * @param track The track to skip to\n   */\n  public skipTo(track: TrackResolvable) {\n    const idx = this.getTrackPosition(track);\n    if (idx < 0) return false;\n    const removed = this.remove(idx);\n    if (!removed) return false;\n    const toRemove = this.queue.tracks.store.filter((_, i) => i <= idx);\n    this.queue.tracks.store.splice(0, idx, removed);\n    this.queue.emit(GuildQueueEvent.AudioTracksRemove, this.queue, toRemove);\n    return this.skip({\n      reason: TrackSkipReason.SkipTo,\n      description: 'The player was skipped to another track manually'\n    });\n  }\n\n  /**\n   * Insert a track on the given position in queue\n   * @param track The track to insert\n   * @param index The position to insert to, defaults to 0.\n   */\n  public insert(track: Track, index = 0) {\n    if (!(track instanceof Track))\n    throw new InvalidArgTypeError(\n      'track value',\n      'instance of Track',\n      String(track)\n    );\n    VALIDATE_QUEUE_CAP(this.queue, track);\n    this.queue.tracks.store.splice(index, 0, track);\n    if (!this.queue.options.noEmitInsert) {\n      this.queue.emit(GuildQueueEvent.AudioTrackAdd, this.queue, track);\n    }\n  }\n\n  /**\n   * Moves a track in the queue\n   * @param from The track to move\n   * @param to The position to move to\n   */\n  public move(from: TrackResolvable, to: number) {\n    const removed = this.remove(from);\n    if (!removed) {\n      throw new NoResultError('invalid track to move');\n    }\n    this.insert(removed, to);\n  }\n\n  /**\n   * Copy a track in the queue\n   * @param from The track to clone\n   * @param to The position to clone at\n   */\n  public copy(from: TrackResolvable, to: number) {\n    const src = this.queue.tracks.at(this.getTrackPosition(from));\n    if (!src) {\n      throw new NoResultError('invalid track to copy');\n    }\n    this.insert(src, to);\n  }\n\n  /**\n   * Swap two tracks in the queue\n   * @param first The first track to swap\n   * @param second The second track to swap\n   */\n  public swap(first: TrackResolvable, second: TrackResolvable) {\n    const src = this.getTrackPosition(first);\n    if (src < 0) throw new NoResultError('invalid src track to swap');\n\n    const dest = this.getTrackPosition(second);\n    if (dest < 0) throw new NoResultError('invalid dest track to swap');\n\n    const srcT = this.queue.tracks.store[src];\n    const destT = this.queue.tracks.store[dest];\n\n    this.queue.tracks.store[src] = destT;\n    this.queue.tracks.store[dest] = srcT;\n  }\n\n  /**\n   * Stop the playback\n   * @param force Whether or not to forcefully stop the playback\n   */\n  public stop(force = false) {\n    this.queue.tracks.clear();\n    this.queue.history.clear();\n    if (!this.queue.dispatcher) return false;\n    this.queue.dispatcher.end();\n    if (force) {\n      this.queue.dispatcher.destroy();\n      return true;\n    }\n    if (this.queue.options.leaveOnStop) {\n      const tm: NodeJS.Timeout = setTimeout(() => {\n        if (this.isPlaying() || this.queue.tracks.size) return clearTimeout(tm);\n        this.queue.dispatcher?.destroy();\n      }, this.queue.options.leaveOnStopCooldown).unref();\n    }\n    return true;\n  }\n\n  /**\n   * Request the source to seek\n   * @param data The seek parameters\n   */\n  public async requestSeek(data: SeekEvent) {\n    const track = this.queue.currentTrack;\n    if (!track) return false;\n\n    if (track.seekable) {\n      return track.seek(data);\n    }\n\n    return this.queue.filters.triggerReplay(data.position);\n  }\n\n  /**\n   * Play the given track\n   * @param res The track to play\n   * @param options Options for playing the track\n   */\n  public async play(res?: Track | null, options?: ResourcePlayOptions) {\n    if (!this.queue.dispatcher?.voiceConnection) {\n      throw new NoVoiceConnectionError();\n    }\n\n    if (this.queue.hasDebugger)\n    this.queue.debug(\n      `Received play request from guild ${this.queue.guild.name} (ID: ${this.queue.guild.id})`\n    );\n\n    options = Object.assign(\n      {},\n      {\n        queue: this.queue.currentTrack != null,\n        transitionMode: false,\n        seek: 0\n      } as ResourcePlayOptions,\n      options\n    )!;\n\n    if (res && options.queue) {\n      if (this.queue.hasDebugger)\n      this.queue.debug(\n        'Requested option requires to queue the track, adding the given track to queue instead...'\n      );\n      return this.queue.addTrack(res);\n    }\n\n    const track = res || this.queue.tracks.dispatch();\n    if (!track) {\n      const error = new NoResultError(\n        'Play request received but track was not provided'\n      );\n      this.queue.emit(GuildQueueEvent.Error, this.queue, error);\n      return;\n    }\n\n    if (this.queue.hasDebugger)\n    this.queue.debug(\n      'Requested option requires to play the track, initializing...'\n    );\n\n    try {\n      const assignedResource = track.resource;\n\n      if (assignedResource) {\n        if (this.queue.hasDebugger)\n        this.queue.debug(\n          'Track has an audio resource assigned, player will now play the resource directly...'\n        );\n\n        this.queue.setTransitioning(!!options.transitionMode);\n\n        return this.#performPlay(assignedResource);\n      }\n\n      if (this.queue.hasDebugger)\n      this.queue.debug(`Initiating stream extraction process...`);\n      const src = track.raw?.source || track.source;\n      const qt: SearchQueryType =\n      track.queryType || (\n      src === 'spotify' ?\n      'spotifySong' :\n      src === 'apple_music' ?\n      'appleMusicSong' :\n      src);\n      if (this.queue.hasDebugger)\n      this.queue.debug(\n        `Executing onBeforeCreateStream hook (QueryType: ${qt})...`\n      );\n\n      const streamSrc = {\n        error: null as Error | null,\n        stream: null as ExtractorStreamable | null\n      };\n\n      await this.queue.\n      onBeforeCreateStream?.(track, qt || 'arbitrary', this.queue).\n      then(\n        (s) => {\n          if (s) {\n            streamSrc.stream = s;\n          }\n        },\n        (e: Error) => streamSrc.error = e\n      );\n\n      // throw if 'onBeforeCreateStream' panics\n      if (!streamSrc.stream && streamSrc.error)\n      return this.#throw(track, streamSrc.error);\n\n      // default behavior when 'onBeforeCreateStream' did not panic\n      if (!streamSrc.stream) {\n        if (this.queue.hasDebugger)\n        this.queue.debug(\n          'Failed to get stream from onBeforeCreateStream, attempting to extract stream using extractors...'\n        );\n        await this.queue.player.extractors.context.provide(\n          {\n            id: crypto.randomUUID(),\n            attemptedExtractors: new Set<string>(),\n            bridgeAttemptedExtractors: new Set<string>()\n          },\n          () =>\n          this.#createGenericStream(track).\n          then(async (r) => {\n            if (r?.result) {\n              streamSrc.stream =\n              <Readable> (\n              await this.queue.onStreamExtracted?.(\n                r.result,\n                track,\n                this.queue\n              )) ??\n              r.result;\n              return;\n            }\n\n            if (r?.error) {\n              streamSrc.error = r.error;\n              return;\n            }\n\n            streamSrc.stream = streamSrc.error = null;\n          }).\n          catch((e: Error) => streamSrc.error = e)\n        );\n      }\n\n      if (!streamSrc.stream) return this.#throw(track, streamSrc.error);\n\n      if (typeof options.seek === 'number' && options.seek >= 0) {\n        this.#progress = options.seek;\n      } else {\n        this.#progress = 0;\n      }\n\n      const trackStreamConfig: StreamConfig = {\n        dispatcherConfig: {\n          disableBiquad: this.queue.options.disableBiquad,\n          disableEqualizer: this.queue.options.disableEqualizer,\n          disableVolume: this.queue.options.disableVolume,\n          disableFilters: this.queue.options.disableFilterer,\n          disableResampler: this.queue.options.disableResampler,\n          disableCompressor: this.queue.options.disableCompressor,\n          disableReverb: this.queue.options.disableReverb,\n          disableSeeker: this.queue.options.disableSeeker,\n          compressor:\n          this.queue.filters._lastFiltersCache.compressor ?? undefined,\n          reverb: this.queue.filters._lastFiltersCache.reverb ?? undefined,\n          seeker: {\n            seekTarget:\n            options.transitionMode && options.seek != null ?\n            options.seek :\n            null,\n            totalDuration: track.durationMS ?? 0\n          },\n          sampleRate:\n          this.queue.filters._lastFiltersCache.sampleRate ?? (\n          typeof this.queue.options.resampler === 'number' &&\n          this.queue.options.resampler > 0 ?\n          this.queue.options.resampler :\n          undefined),\n          biquadFilter:\n          this.queue.filters._lastFiltersCache.biquad || undefined,\n          eq: this.queue.filters._lastFiltersCache.equalizer,\n          defaultFilters: this.queue.filters._lastFiltersCache.filters,\n          volume: this.queue.filters._lastFiltersCache.volume,\n          data: track,\n          type: StreamType.Raw,\n          skipFFmpeg: this.queue.player.options.skipFFmpeg\n        },\n        playerConfig: options\n      };\n\n      let resolver: () => void = Util.noop;\n      const donePromise = new Promise<void>((resolve) => resolver = resolve);\n\n      const success = this.queue.emit(\n        GuildQueueEvent.WillPlayTrack,\n        this.queue,\n        track,\n        trackStreamConfig,\n        resolver!\n      );\n\n      // prevent dangling promise\n      if (!success) resolver();\n\n      if (this.queue.hasDebugger)\n      this.queue.debug('Waiting for willPlayTrack event to resolve...');\n\n      await donePromise;\n\n      const daspDisabled = [\n      trackStreamConfig.dispatcherConfig.disableBiquad,\n      trackStreamConfig.dispatcherConfig.disableEqualizer,\n      trackStreamConfig.dispatcherConfig.disableFilters,\n      trackStreamConfig.dispatcherConfig.disableResampler,\n      trackStreamConfig.dispatcherConfig.disableVolume,\n      trackStreamConfig.dispatcherConfig.disableCompressor,\n      trackStreamConfig.dispatcherConfig.disableReverb,\n      trackStreamConfig.dispatcherConfig.disableSeeker].\n      every((e) => !!e === true);\n\n      const needsFilters =\n      !!trackStreamConfig.playerConfig.seek ||\n      !!this.queue.filters.ffmpeg.args.length;\n      const shouldSkipFFmpeg =\n      !!trackStreamConfig.dispatcherConfig.skipFFmpeg && !needsFilters;\n\n      let finalStream: Readable;\n\n      const demuxable = (fmt: string) =>\n      [\n      StreamType.Opus,\n      StreamType.WebmOpus,\n      StreamType.OggOpus,\n      StreamType.Raw,\n      'pcm'].\n      includes(fmt as StreamType);\n\n      // skip ffmpeg when possible\n      if (\n      shouldSkipFFmpeg &&\n      !(streamSrc.stream instanceof Readable) &&\n      typeof streamSrc.stream !== 'string' &&\n      demuxable(streamSrc.stream.$fmt))\n      {\n        const { $fmt, stream } = streamSrc.stream;\n        const shouldPCM = !daspDisabled;\n\n        if (this.queue.hasDebugger)\n        this.queue.debug(\n          `skipFFmpeg is set to true and stream is demuxable, creating stream with type ${\n          shouldPCM ? 'pcm' : 'opus'}`\n\n        );\n\n        const isRaw = $fmt === 'pcm' || $fmt === StreamType.Raw;\n\n        // prettier-ignore\n        const opusStream =\n        isRaw || $fmt === StreamType.Opus ?\n        stream :\n        $fmt === StreamType.OggOpus ?\n        // eslint-disable-next-line @typescript-eslint/no-explicit-any\n        stream.pipe(new OggDemuxer() as any) :\n        // eslint-disable-next-line @typescript-eslint/no-explicit-any\n        stream.pipe(new WebmDemuxer() as any);\n\n        if (shouldPCM) {\n          if (isRaw) {\n            finalStream = opusStream;\n          } else {\n            // if we have any filters enabled, we need to decode the opus stream to pcm\n            finalStream = opusStream.pipe(\n              new OpusDecoder({\n                channels: 2,\n                frameSize: 960,\n                rate: 48000\n              })\n            );\n            trackStreamConfig.dispatcherConfig.type = StreamType.Raw;\n          }\n        } else {\n          finalStream = opusStream;\n          trackStreamConfig.dispatcherConfig.type = StreamType.Opus;\n        }\n      } else {\n        // const opus = daspDisabled && this.#hasFFmpegOptimization;\n        // if (opus && this.queue.hasDebugger) this.queue.debug('Disabling PCM output since all filters are disabled and opus encoding is supported...');\n\n        finalStream = this.#createFFmpegStream(\n          streamSrc.stream instanceof Readable ||\n          typeof streamSrc.stream === 'string' ?\n          streamSrc.stream :\n          streamSrc.stream.stream,\n          track,\n          options.seek ?? 0\n          // opus\n        );\n        trackStreamConfig.dispatcherConfig.type = StreamType.Raw;\n        // FIXME: OggOpus results in static noise\n        // trackStreamConfig.dispatcherConfig.type = opus ? StreamType.OggOpus : StreamType.Raw;\n      }\n\n      if (options.transitionMode) {\n        if (this.queue.hasDebugger)\n        this.queue.debug(\n          `Transition mode detected, player will wait for buffering timeout to expire (Timeout: ${this.queue.options.bufferingTimeout}ms)`\n        );\n        await waitFor(this.queue.options.bufferingTimeout);\n        if (this.queue.hasDebugger)\n        this.queue.debug('Buffering timeout has expired!');\n      }\n\n      if (this.queue.hasDebugger)\n      this.queue.debug(\n        `Preparing final stream config: ${JSON.stringify(\n          trackStreamConfig,\n          null,\n          2\n        )}`\n      );\n\n      const dispatcher = this.queue.dispatcher;\n\n      if (!dispatcher) {\n        if (this.queue.hasDebugger) {\n          this.queue.debug(\n            'Dispatcher is not available, this is most likely due to the queue being deleted in the middle of operation. Cancelling the stream...'\n          );\n        }\n\n        finalStream.destroy();\n      } else {\n        const resource = await dispatcher.createStream(\n          finalStream,\n          trackStreamConfig.dispatcherConfig\n        );\n\n        this.queue.setTransitioning(!!options.transitionMode);\n\n        await this.#performPlay(resource);\n      }\n    } catch (e) {\n      if (this.queue.hasDebugger)\n      this.queue.debug(`Failed to initialize audio player: ${e}`);\n      throw e;\n    }\n  }\n\n  #throw(track: Track, error?: Error | null): void {\n    // prettier-ignore\n    const streamDefinitelyFailedMyDearT_TPleaseTrustMeItsNotMyFault =\n    new NoResultError(`Could not extract stream for this track${error ? `\\n\\n${error.stack || error}` : ''}`);\n\n\n    this.queue.emit(\n      GuildQueueEvent.PlayerSkip,\n      this.queue,\n      track,\n      TrackSkipReason.NoStream,\n      streamDefinitelyFailedMyDearT_TPleaseTrustMeItsNotMyFault.message\n    );\n    this.queue.emit(\n      GuildQueueEvent.PlayerError,\n      this.queue,\n      streamDefinitelyFailedMyDearT_TPleaseTrustMeItsNotMyFault,\n      track\n    );\n    const nextTrack = this.queue.tracks.dispatch();\n    if (nextTrack) return void this.play(nextTrack, { queue: false });\n    // @ts-expect-error should be resolved\n    this.queue.dispatcher?.emit('finish', null);\n  }\n\n  async #performPlay(resource: AudioResource<Track>) {\n    if (!this.queue.dispatcher) {\n      if (this.queue.hasDebugger) {\n        this.queue.debug(\n          'Dispatcher is not available, this is most likely due to the queue being deleted in the middle of operation. Cancelling the stream...'\n        );\n      }\n    } else {\n      if (this.queue.hasDebugger)\n      this.queue.debug('Initializing audio player...');\n      await this.queue.dispatcher.playStream(resource);\n      if (this.queue.hasDebugger) this.queue.debug('Dispatching audio...');\n    }\n  }\n\n  async #createGenericStream(track: Track) {\n    if (this.queue.hasDebugger)\n    this.queue.debug(\n      `Attempting to extract stream for Track { title: ${track.title}, url: ${track.url} } using registered extractors`\n    );\n\n    const attemptedExtractors =\n    this.queue.player.extractors.getContext()?.attemptedExtractors ||\n    new Set<string>();\n\n    const streamInfo = await this.queue.player.extractors.run(\n      async (extractor) => {\n        if (\n        this.queue.player.options.blockStreamFrom?.some(\n          (ext) => ext === extractor.identifier\n        ))\n\n        return false;\n        if (attemptedExtractors.has(extractor.identifier)) return false;\n        attemptedExtractors.add(extractor.identifier);\n        const canStream = await extractor.validate(\n          track.url,\n          track.queryType || QueryResolver.resolve(track.url).type\n        );\n        if (!canStream) return false;\n        return await extractor.stream(track);\n      },\n      false\n    );\n\n    if (!streamInfo || !streamInfo.result) {\n      if (this.queue.hasDebugger) {\n        this.queue.debug(\n          `Failed to extract stream for Track { title: ${track.title}, url: ${track.url} } using registered extractors`\n        );\n      }\n\n      if (!this.queue.options.disableFallbackStream) {\n        if (this.queue.hasDebugger)\n        this.queue.debug(\n          `Generic stream extraction failed and fallback stream extraction is enabled`\n        );\n        return this.#createFallbackStream(track);\n      }\n\n      return streamInfo || null;\n    }\n\n    if (this.queue.hasDebugger)\n    this.queue.debug(\n      `Stream extraction was successful for Track { title: ${\n      track.title}, url: ${\n      track.url} } (Extractor: ${\n      streamInfo.extractor?.identifier || 'N/A'})`\n\n    );\n\n    return streamInfo;\n  }\n\n  async #createFallbackStream(track: Track) {\n    if (this.queue.hasDebugger)\n    this.queue.debug(\n      `Attempting to extract stream for Track { title: ${track.title}, url: ${track.url} } using fallback streaming method...`\n    );\n\n    const verifyFallbackStream = this.queue.options.verifyFallbackStream;\n\n    const fallbackStream = await this.queue.player.extractors.run(\n      async (extractor) => {\n        if (extractor.identifier === track.extractor?.identifier) return false;\n        if (\n        this.queue.player.options.blockStreamFrom?.some(\n          (ext) => ext === extractor.identifier\n        ))\n        {\n          return false;\n        }\n\n        const query = `${track.title} ${track.author}`;\n\n        if (verifyFallbackStream) {\n          if (this.queue.hasDebugger) {\n            this.queue.debug(\n              `Fallback stream verification is enabled, validating query for Track { title: ${track.title}, url: ${track.url} } using ${extractor.identifier}...`\n            );\n          }\n\n          const shouldProceed = await extractor.validate(\n            query,\n            track.queryType || track.source\n          );\n\n          if (!shouldProceed) {\n            if (this.queue.hasDebugger)\n            this.queue.debug(\n              `Failed to validate query for Track { title: ${track.title}, url: ${track.url} } using ${extractor.identifier}`\n            );\n            return false;\n          } else {\n            if (this.queue.hasDebugger)\n            this.queue.debug(\n              `Query for Track { title: ${track.title}, url: ${track.url} } was validated using ${extractor.identifier}. Proceeding with extraction...`\n            );\n          }\n        }\n\n        const fallbackTracks = await extractor.handle(query, {\n          requestedBy: track.requestedBy\n        });\n\n        const fallbackTrack = fallbackTracks.tracks[0];\n\n        if (!fallbackTrack) return false;\n\n        const stream = await extractor.stream(fallbackTrack);\n\n        if (!stream) return false;\n\n        track.bridgedTrack = fallbackTrack;\n\n        return stream;\n      },\n      true\n    );\n\n    if (!fallbackStream || !fallbackStream.result) {\n      if (this.queue.hasDebugger)\n      this.queue.debug(\n        `Failed to extract stream for Track { title: ${track.title}, url: ${track.url} } using fallback streaming method`\n      );\n      return fallbackStream || null;\n    }\n\n    track.bridgedExtractor = fallbackStream.extractor;\n\n    return fallbackStream;\n  }\n\n  #createFFmpegStream(\n  stream: Readable | string,\n  track: Track,\n  seek = 0,\n  opus?: boolean)\n  {\n    const ffmpegStream = this.queue.filters.ffmpeg.\n    createStream(stream, {\n      encoderArgs: this.queue.filters.ffmpeg.args,\n      seek: seek / 1000,\n      fmt: opus ? 'opus' : 's16le',\n      requestOptions: track.raw?.requestOptions\n    }).\n    on('error', (err) => {\n      const m = `${err}`.toLowerCase();\n\n      if (this.queue.hasDebugger)\n      this.queue.debug(\n        `Stream closed due to an error from FFmpeg stream: ${\n        err.stack || err.message || err}`\n\n      );\n\n      if (m.includes('premature close') || m.includes('epipe')) return;\n\n      this.queue.emit(GuildQueueEvent.PlayerError, this.queue, err, track);\n    });\n\n    return ffmpegStream;\n  }\n}","import { SnowflakeUtil } from 'discord.js';\n\nexport interface AsyncQueueAcquisitionOptions {\n  /**\n   * AbortSignal to cancel this entry\n   */\n  signal?: AbortSignal;\n}\n\nexport type AsyncQueueExceptionHandler = (exception: Error) => void;\n\nexport class AsyncQueue {\n  /**\n   * The queued entries\n   */\n  public entries: Array<AsyncQueueEntry> = [];\n\n  public exceptionHandler?: AsyncQueueExceptionHandler;\n\n  /**\n   * Clear entries queue\n   * @param consume Whether or not to consume all entries before clearing\n   */\n  public clear(consume = false) {\n    if (consume) {\n      this.entries.forEach((entry) => entry.consume());\n    }\n\n    this.entries = [];\n  }\n\n  /**\n   * The total number of entries in this queue. Returns `0` if no entries are available.\n   */\n  public get size() {\n    return this.entries.length;\n  }\n\n  /**\n   * Acquire an entry.\n   *\n   * @example // lock the queue\n   * const entry = asyncQueue.acquire();\n   * // wait until previous task is completed\n   * await entry.getTask();\n   * // do something expensive\n   * await performSomethingExpensive();\n   * // make sure to release the lock once done\n   * asyncQueue.release();\n   *\n   */\n  public acquire(options?: AsyncQueueAcquisitionOptions) {\n    const entry = new AsyncQueueEntry(this, options);\n\n    if (this.exceptionHandler) entry.getTask().catch(this.exceptionHandler);\n\n    if (this.entries.length === 0) {\n      this.entries.push(entry);\n      entry.consume();\n      return entry;\n    }\n\n    this.entries.push(entry);\n    return entry;\n  }\n\n  /**\n   * Release the current acquisition and move to next entry.\n   */\n  public release(): void {\n    if (!this.entries.length) return;\n\n    this.entries.shift();\n    this.entries[0]?.consume();\n  }\n\n  /**\n   * Cancel all entries\n   */\n  public cancelAll() {\n    this.entries.forEach((entry) => entry.cancel());\n  }\n\n  /**\n   * Remove the given entry from the queue\n   * @param entry The entry to remove\n   */\n  public removeEntry(entry: AsyncQueueEntry) {\n    const entryIdx = this.entries.indexOf(entry);\n\n    if (entryIdx !== -1) {\n      this.entries.splice(entryIdx, 1);\n      return true;\n    }\n\n    return false;\n  }\n}\n\nexport class AsyncQueueEntry {\n  public readonly id = SnowflakeUtil.generate().toString();\n  private readonly promise: Promise<void>;\n  public signal: AbortSignal | null = null;\n  public onAbort: (() => void) | null = null;\n  private resolve!: () => void;\n  private reject!: (err: Error) => void;\n\n  public constructor(\n  public queue: AsyncQueue,\n  public options?: AsyncQueueAcquisitionOptions)\n  {\n    this.promise = new Promise((resolve, reject) => {\n      this.resolve = resolve;\n      this.reject = reject;\n    });\n\n    if (this.options?.signal) {\n      this.setAbortSignal(this.options.signal);\n    }\n  }\n\n  public setAbortSignal(signal: AbortSignal) {\n    if (signal.aborted) return;\n    this.signal = signal;\n    this.onAbort = () => {\n      this.queue.removeEntry(this);\n      this.cancel();\n    };\n\n    this.signal.addEventListener('abort', this.onAbort);\n  }\n\n  public consume() {\n    this.cleanup();\n    this.resolve();\n  }\n\n  public release() {\n    this.consume();\n    this.queue.release();\n  }\n\n  public cancel() {\n    this.cleanup();\n    this.reject(new Error('Cancelled'));\n  }\n\n  public cleanup() {\n    if (this.onAbort) this.signal?.removeEventListener('abort', this.onAbort);\n    this.signal = null;\n    this.onAbort = null;\n  }\n\n  public getTask() {\n    return this.promise;\n  }\n}","import { Readable } from 'stream';\nimport { AudioFilters, FiltersName, QueueFilters } from '../utils/AudioFilters';\nimport { GuildQueue, GuildQueueEvent } from './GuildQueue';\nimport {\n  BiquadFilters,\n  Equalizer,\n  EqualizerBand,\n  PCMFilters } from\n'@discord-player/equalizer';\nimport { FFmpegStreamOptions, createFFmpegStream } from '../utils/FFmpegStream';\nimport { InvalidArgTypeError } from '../errors';\nimport { StreamConfig } from './GuildQueuePlayerNode';\n\ntype Filters = keyof typeof AudioFilters.filters;\n\nconst makeBands = (arr: number[]) => {\n  return Array.from(\n    {\n      length: Equalizer.BAND_COUNT\n    },\n    (_, i) => ({\n      band: i,\n      gain: arr[i] ? arr[i] / 30 : 0\n    })\n  ) as EqualizerBand[];\n};\n\ntype EQPreset = {\n  Flat: EqualizerBand[];\n  Classical: EqualizerBand[];\n  Club: EqualizerBand[];\n  Dance: EqualizerBand[];\n  FullBass: EqualizerBand[];\n  FullBassTreble: EqualizerBand[];\n  FullTreble: EqualizerBand[];\n  Headphones: EqualizerBand[];\n  LargeHall: EqualizerBand[];\n  Live: EqualizerBand[];\n  Party: EqualizerBand[];\n  Pop: EqualizerBand[];\n  Reggae: EqualizerBand[];\n  Rock: EqualizerBand[];\n  Ska: EqualizerBand[];\n  Soft: EqualizerBand[];\n  SoftRock: EqualizerBand[];\n  Techno: EqualizerBand[];\n};\n\nexport const EqualizerConfigurationPreset: Readonly<EQPreset> = Object.freeze({\n  Flat: makeBands([]),\n  Classical: makeBands([\n  -1.11022e-15, -1.11022e-15, -1.11022e-15, -1.11022e-15, -1.11022e-15,\n  -1.11022e-15, -7.2, -7.2, -7.2, -9.6]\n  ),\n  Club: makeBands([\n  -1.11022e-15, -1.11022e-15, 8.0, 5.6, 5.6, 5.6, 3.2, -1.11022e-15,\n  -1.11022e-15, -1.11022e-15]\n  ),\n  Dance: makeBands([\n  9.6, 7.2, 2.4, -1.11022e-15, -1.11022e-15, -5.6, -7.2, -7.2, -1.11022e-15,\n  -1.11022e-15]\n  ),\n  FullBass: makeBands([\n  -8.0, 9.6, 9.6, 5.6, 1.6, -4.0, -8.0, -10.4, -11.2, -11.2]\n  ),\n  FullBassTreble: makeBands([\n  7.2, 5.6, -1.11022e-15, -7.2, -4.8, 1.6, 8.0, 11.2, 12.0, 12.0]\n  ),\n  FullTreble: makeBands([\n  -9.6, -9.6, -9.6, -4.0, 2.4, 11.2, 16.0, 16.0, 16.0, 16.8]\n  ),\n  Headphones: makeBands([\n  4.8, 11.2, 5.6, -3.2, -2.4, 1.6, 4.8, 9.6, 12.8, 14.4]\n  ),\n  LargeHall: makeBands([\n  10.4, 10.4, 5.6, 5.6, -1.11022e-15, -4.8, -4.8, -4.8, -1.11022e-15,\n  -1.11022e-15]\n  ),\n  Live: makeBands([-4.8, -1.11022e-15, 4.0, 5.6, 5.6, 5.6, 4.0, 2.4, 2.4, 2.4]),\n  Party: makeBands([\n  7.2, 7.2, -1.11022e-15, -1.11022e-15, -1.11022e-15, -1.11022e-15,\n  -1.11022e-15, -1.11022e-15, 7.2, 7.2]\n  ),\n  Pop: makeBands([\n  -1.6, 4.8, 7.2, 8.0, 5.6, -1.11022e-15, -2.4, -2.4, -1.6, -1.6]\n  ),\n  Reggae: makeBands([\n  -1.11022e-15, -1.11022e-15, -1.11022e-15, -5.6, -1.11022e-15, 6.4, 6.4,\n  -1.11022e-15, -1.11022e-15, -1.11022e-15]\n  ),\n  Rock: makeBands([8.0, 4.8, -5.6, -8.0, -3.2, 4.0, 8.8, 11.2, 11.2, 11.2]),\n  Ska: makeBands([\n  -2.4, -4.8, -4.0, -1.11022e-15, 4.0, 5.6, 8.8, 9.6, 11.2, 9.6]\n  ),\n  Soft: makeBands([\n  4.8, 1.6, -1.11022e-15, -2.4, -1.11022e-15, 4.0, 8.0, 9.6, 11.2, 12.0]\n  ),\n  SoftRock: makeBands([\n  4.0, 4.0, 2.4, -1.11022e-15, -4.0, -5.6, -3.2, -1.11022e-15, 2.4, 8.8]\n  ),\n  Techno: makeBands([\n  8.0, 5.6, -1.11022e-15, -5.6, -4.8, -1.11022e-15, 8.0, 9.6, 9.6, 8.8]\n  )\n});\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport class FFmpegFilterer<Meta = any> {\n  #ffmpegFilters: Filters[] = [];\n  #inputArgs: string[] = [];\n\n  public constructor(public af: GuildQueueAudioFilters<Meta>) {}\n\n  /**\n   * Indicates whether ffmpeg may be skipped\n   */\n  public get skippable() {\n    return !!this.af.queue.player.options.skipFFmpeg;\n  }\n\n  #setFilters(filters: Filters[]) {\n    const { queue } = this.af;\n    // skip if filters are the same\n    if (\n    filters.every((f) => this.#ffmpegFilters.includes(f)) &&\n    this.#ffmpegFilters.every((f) => filters.includes(f)))\n\n    return Promise.resolve(false);\n    const ignoreFilters =\n    this.filters.some((ff) => ff === 'nightcore' || ff === 'vaporwave') &&\n    !filters.some((ff) => ff === 'nightcore' || ff === 'vaporwave');\n    const seekTime = queue.node.getTimestamp(ignoreFilters)?.current.value || 0;\n    const prev = this.#ffmpegFilters.slice();\n    this.#ffmpegFilters = [...new Set(filters)];\n\n    return this.af.triggerReplay(seekTime).then((t) => {\n      queue.emit(\n        GuildQueueEvent.AudioFiltersUpdate,\n        queue,\n        prev,\n        this.#ffmpegFilters.slice()\n      );\n      return t;\n    });\n  }\n\n  /**\n   * Set input args for FFmpeg\n   */\n  public setInputArgs(args: string[]) {\n    if (!args.every((arg) => typeof arg === 'string'))\n    throw new InvalidArgTypeError('args', 'Array<string>', 'invalid item(s)');\n    this.#inputArgs = args;\n  }\n\n  /**\n   * Get input args\n   */\n  public get inputArgs() {\n    return this.#inputArgs;\n  }\n\n  /**\n   * Get encoder args\n   */\n  public get encoderArgs() {\n    if (!this.filters.length) return [];\n\n    return ['-af', this.toString()];\n  }\n\n  /**\n   * Get final ffmpeg args\n   */\n  public get args() {\n    return this.inputArgs.concat(this.encoderArgs);\n  }\n\n  /**\n   * Create ffmpeg stream\n   * @param source The stream source\n   * @param options The stream options\n   */\n  public createStream(source: string | Readable, options: FFmpegStreamOptions) {\n    if (this.#inputArgs.length)\n    options.encoderArgs = [\n    ...this.#inputArgs,\n    ...(options.encoderArgs || [])];\n\n\n    const stream = createFFmpegStream(source, options);\n\n    return stream;\n  }\n\n  /**\n   * Set ffmpeg filters\n   * @param filters The filters\n   */\n  public setFilters(\n  filters: Filters[] | Record<Filters, boolean> | string[] | boolean)\n  {\n    let _filters: Filters[] = [];\n    if (typeof filters === 'boolean') {\n      _filters = !filters ?\n      [] :\n      Object.keys(AudioFilters.filters) as Filters[];\n    } else if (Array.isArray(filters)) {\n      _filters = filters as Filters[];\n    } else {\n      _filters = Object.entries(filters).\n      filter((res) => res[1] === true).\n      map((m) => m[0]) as Filters[];\n    }\n\n    return this.#setFilters(_filters);\n  }\n\n  /**\n   * Currently active ffmpeg filters\n   */\n  public get filters() {\n    return this.#ffmpegFilters;\n  }\n\n  public set filters(filters: Filters[]) {\n    this.setFilters(filters);\n  }\n\n  /**\n   * Toggle given ffmpeg filter(s)\n   * @param filters The filter(s)\n   */\n  public toggle(filters: Filters[] | Filters) {\n    if (!Array.isArray(filters)) filters = [filters];\n    const fresh: Filters[] = [];\n\n    filters.forEach((f) => {\n      if (this.filters.includes(f)) return;\n      fresh.push(f);\n    });\n\n    return this.#setFilters(\n      this.#ffmpegFilters.filter((r) => !filters.includes(r)).concat(fresh)\n    );\n  }\n\n  /**\n   * Set default filters\n   * @param ff Filters list\n   */\n  public setDefaults(ff: Filters[]) {\n    this.#ffmpegFilters = ff;\n  }\n\n  /**\n   * Get list of enabled filters\n   */\n  public getFiltersEnabled() {\n    return this.#ffmpegFilters;\n  }\n\n  /**\n   * Get list of disabled filters\n   */\n  public getFiltersDisabled() {\n    return AudioFilters.names.filter((f) => !this.#ffmpegFilters.includes(f));\n  }\n\n  /**\n   * Check if the given filter is enabled\n   * @param filter The filter\n   */\n  public isEnabled<T extends Filters>(filter: T): boolean {\n    return this.#ffmpegFilters.includes(filter);\n  }\n\n  /**\n   * Check if the given filter is disabled\n   * @param filter The filter\n   */\n  public isDisabled<T extends Filters>(filter: T): boolean {\n    return !this.isEnabled(filter);\n  }\n\n  /**\n   * Check if the given filter is a valid filter\n   * @param filter The filter to test\n   */\n  public isValidFilter(filter: string): filter is FiltersName {\n    return AudioFilters.has(filter as Filters);\n  }\n\n  /**\n   * Convert current filters to array\n   */\n  public toArray() {\n    return this.filters.map((filter) => AudioFilters.get(filter));\n  }\n\n  /**\n   * Convert current filters to JSON object\n   */\n  public toJSON() {\n    const obj = {} as Record<keyof QueueFilters, string>;\n\n    this.filters.forEach((filter) => obj[filter] = AudioFilters.get(filter));\n\n    return obj;\n  }\n\n  /**\n   * String representation of current filters\n   */\n  public toString() {\n    return AudioFilters.create(this.filters);\n  }\n}\n\nexport interface GuildQueueAFiltersCache {\n  equalizer: EqualizerBand[];\n  biquad: BiquadFilters | null;\n  filters: PCMFilters[];\n  volume: number;\n  sampleRate: number;\n  sampleRateFilter:\n  StreamConfig['dispatcherConfig']['sampleRateFilters'] |\n  null;\n  compressor: StreamConfig['dispatcherConfig']['compressor'] | null;\n  reverb: StreamConfig['dispatcherConfig']['reverb'] | null;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport class GuildQueueAudioFilters<Meta = any> {\n  public graph = new AFilterGraph<Meta>(this);\n  public ffmpeg = new FFmpegFilterer<Meta>(this);\n  public equalizerPresets = EqualizerConfigurationPreset;\n  public _lastFiltersCache: GuildQueueAFiltersCache = {\n    biquad: null,\n    equalizer: [],\n    filters: [],\n    volume: 100,\n    sampleRate: -1,\n    compressor: null,\n    reverb: null,\n    sampleRateFilter: null\n  };\n  public constructor(public queue: GuildQueue<Meta>) {\n    if (typeof this.queue.options.volume === 'number') {\n      this._lastFiltersCache.volume = this.queue.options.volume;\n    }\n  }\n\n  // TODO: enable this in the future\n  // public get ffmpeg(): FFmpegFilterer<Meta> | null {\n  //     if (this.queue.player.options.skipFFmpeg) {\n  //         if (this.#ffmpeg) this.#ffmpeg = null;\n  //         return null;\n  //     }\n\n  //     if (!this.#ffmpeg) {\n  //         this.#ffmpeg = new FFmpegFilterer<Meta>(this);\n  //     }\n\n  //     return this.#ffmpeg;\n  // }\n\n  /**\n   * Volume transformer\n   */\n  public get volume() {\n    return this.queue.dispatcher?.dsp?.volume || null;\n  }\n\n  /**\n   * 15 Band Equalizer\n   */\n  public get equalizer() {\n    return this.queue.dispatcher?.equalizer || null;\n  }\n\n  /**\n   * Digital biquad filters\n   */\n  public get biquad() {\n    return this.queue.dispatcher?.biquad || null;\n  }\n\n  /**\n   * DSP filters\n   */\n  public get filters() {\n    return this.queue.dispatcher?.filters || null;\n  }\n\n  /**\n   * Audio resampler\n   */\n  public get resampler() {\n    return this.queue.dispatcher?.resampler || null;\n  }\n\n  /**\n   * Compressor transformer\n   */\n  public get compressor() {\n    return this.queue.dispatcher?.compressor || null;\n  }\n\n  /**\n   * Reverb transformer\n   */\n  public get reverb() {\n    return this.queue.dispatcher?.reverb || null;\n  }\n\n  /**\n   * PCM Seeker transformer\n   */\n  public get seeker() {\n    return this.queue.dispatcher?.seeker || null;\n  }\n\n  /**\n   * Replay current track in transition mode\n   * @param seek The duration to seek to\n   */\n  public async triggerReplay(seek = 0) {\n    if (!this.queue.currentTrack) return false;\n    const entry = this.queue.node.tasksQueue.acquire();\n    try {\n      await entry.getTask();\n      await this.queue.node.play(this.queue.currentTrack, {\n        queue: false,\n        seek,\n        transitionMode: true\n      });\n      this.queue.node.tasksQueue.release();\n      return true;\n    } catch {\n      this.queue.node.tasksQueue.release();\n      return false;\n    }\n  }\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport class AFilterGraph<Meta = any> {\n  public constructor(public af: GuildQueueAudioFilters<Meta>) {}\n\n  public get ffmpeg() {\n    return this.af.ffmpeg?.filters ?? [];\n  }\n\n  public get equalizer() {\n    return (this.af.equalizer?.bandMultipliers || []).map((m, i) => ({\n      band: i,\n      gain: m\n    })) as EqualizerBand[];\n  }\n\n  public get biquad() {\n    return (\n      this.af.biquad?.getFilterName() as Exclude<\n        BiquadFilters,\n        number> |\n      null || null);\n\n  }\n\n  public get filters() {\n    return this.af.filters?.filters || [];\n  }\n\n  public get volume() {\n    return this.af.volume;\n  }\n\n  public get resampler() {\n    return this.af.resampler;\n  }\n\n  public dump(): FilterGraph {\n    return {\n      ffmpeg: this.ffmpeg,\n      equalizer: this.equalizer,\n      biquad: this.biquad,\n      filters: this.filters,\n      sampleRate: this.resampler?.sampleRate || 48000,\n      volume: this.volume?.volume ?? 100\n    };\n  }\n}\n\nexport interface FilterGraph {\n  ffmpeg: Filters[];\n  equalizer: EqualizerBand[];\n  biquad: Exclude<BiquadFilters, number> | null;\n  filters: PCMFilters[];\n  volume: number;\n  sampleRate: number;\n}","import type { Duplex, Readable } from 'stream';\nimport { FFmpeg, createFFmpegArgs } from '@discord-player/ffmpeg';\nimport type { RequestOptions } from 'http';\n\nexport interface FFmpegStreamOptions {\n  fmt?: string;\n  encoderArgs?: string[];\n  seek?: number;\n  skip?: boolean;\n  cookies?: string;\n  requestOptions?: RequestOptions;\n}\n\nexport function FFMPEG_ARGS_STRING(\nstream: string,\nfmt?: string,\ncookies?: string,\nrequestOptions?: RequestOptions)\n{\n  // Build array manually to handle HTTP options properly\n  const args: string[] = [];\n\n  // Add reconnection options\n  args.push('-reconnect', '1');\n  args.push('-reconnect_streamed', '1');\n  args.push('-reconnect_delay_max', '5');\n\n  // Add HTTP headers if provided - FFmpeg HTTP protocol format, thank god it started working...\n  if (requestOptions?.headers) {\n    const userAgent =\n    requestOptions.headers['user-agent'] ||\n    requestOptions.headers['User-Agent'];\n    if (userAgent) {\n      args.push('-user_agent', String(userAgent));\n    }\n\n    // Add other headers using FFmpeg's headers option\n    const formattedHeaders = formatFFmpegHeaders(\n      requestOptions.headers as NodeJS.Dict<string | string[]>\n    );\n    if (formattedHeaders) {\n      args.push('-headers', formattedHeaders);\n    }\n  }\n\n  // Add cookies if provided\n  if (typeof cookies === 'string') {\n    const cookieValue = !cookies.includes(' ') ? cookies : `\"${cookies}\"`;\n    args.push('-cookies', cookieValue);\n  }\n\n  // Add input URL\n  args.push('-i', stream);\n\n  // Add audio processing options\n  args.push('-analyzeduration', '0');\n  args.push('-loglevel', '0');\n  args.push('-ar', '48000');\n  args.push('-ac', '2');\n  args.push('-f', typeof fmt === 'string' ? fmt : 's16le');\n\n  if (fmt === 'opus') {\n    args.push('-acodec', 'libopus');\n  }\n  return args;\n}\n\nfunction formatFFmpegHeaders(\nheaders: NodeJS.Dict<string | string[]>)\n: string | null {\n  const headerPairs: string[] = [];\n\n  for (const [name, value] of Object.entries(headers)) {\n    if (value && name.toLowerCase() !== 'user-agent') {\n      const valueStr = Array.isArray(value) ? value.join(', ') : String(value);\n      headerPairs.push(`${name}: ${valueStr}`);\n    }\n  }\n\n  return headerPairs.length > 0 ? headerPairs.join('\\r\\n') : null;\n}\n\nexport function FFMPEG_ARGS_PIPED(fmt?: string) {\n  const args = createFFmpegArgs({\n    analyzeduration: 0,\n    loglevel: 0,\n    ar: 48000,\n    ac: 2,\n    f: `${typeof fmt === 'string' ? fmt : 's16le'}`,\n    acodec: fmt === 'opus' ? 'libopus' : null\n  });\n\n  return args;\n}\n\n/**\n * Creates FFmpeg stream\n * @param stream The source stream\n * @param options FFmpeg stream options\n */\nexport function createFFmpegStream(\nstream: Readable | Duplex | string,\noptions?: FFmpegStreamOptions)\n: Readable {\n  if (options?.skip && typeof stream !== 'string') return stream;\n  options ??= {};\n  const args =\n  typeof stream === 'string' ?\n  FFMPEG_ARGS_STRING(\n    stream,\n    options.fmt,\n    options.cookies,\n    options.requestOptions\n  ) :\n  FFMPEG_ARGS_PIPED(options.fmt);\n\n  if (!Number.isNaN(options.seek)) args.unshift('-ss', String(options.seek));\n  if (Array.isArray(options.encoderArgs)) args.push(...options.encoderArgs);\n\n  const transcoder = new FFmpeg({ shell: false, args });\n\n  transcoder.on('close', () => transcoder.destroy());\n\n  if (typeof stream !== 'string') {\n    stream.on('error', () => transcoder.destroy());\n    // eslint-disable-next-line @typescript-eslint/no-explicit-any\n    stream.pipe(transcoder as any);\n  }\n\n  return transcoder;\n}","import { GuildQueue } from './GuildQueue';\n\nexport interface GuildQueueStatisticsMetadata {\n  latency: {\n    eventLoop: number;\n    voiceConnection: number;\n  };\n  status: {\n    buffering: boolean;\n    playing: boolean;\n    paused: boolean;\n    idle: boolean;\n  };\n  tracksCount: number;\n  historySize: number;\n  extractors: number;\n  listeners: number;\n  memoryUsage: NodeJS.MemoryUsage;\n  versions: {\n    node: string;\n    player: string;\n  };\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport class GuildQueueStatistics<Meta = any> {\n  public constructor(public queue: GuildQueue<Meta>) {}\n\n  /**\n   * Generate statistics of this queue\n   */\n  public generate() {\n    return {\n      latency: {\n        eventLoop: this.queue.player.eventLoopLag,\n        voiceConnection: this.queue.ping\n      },\n      status: {\n        buffering: this.queue.node.isBuffering(),\n        playing: this.queue.node.isPlaying(),\n        paused: this.queue.node.isPaused(),\n        idle: this.queue.node.isIdle()\n      },\n      tracksCount: this.queue.tracks.size,\n      historySize: this.queue.history.tracks.size,\n      extractors: this.queue.player.extractors.size,\n      listeners:\n      this.queue.guild.members.me?.voice.channel?.members.filter(\n        (m) => !m.user.bot\n      ).size || 0,\n      memoryUsage: process.memoryUsage(),\n      versions: {\n        node: process.version,\n        player: this.queue.player.version\n      }\n    } as GuildQueueStatisticsMetadata;\n  }\n}","import { NotExistingError } from '../errors';\nimport { LrcGetResult, LrcSearchResult } from '../lrclib/LrcLib';\nimport type { GuildQueue } from './GuildQueue';\n\nexport type LyricsData = Map<number, string>;\nexport type Unsubscribe = () => void;\nexport type LyricsCallback = (lyrics: string, timestamp: number) => unknown;\nexport type LyricsAt = {timestamp: number;line: string;};\n\nconst timestampPattern = /\\[(\\d{2}):(\\d{2})\\.(\\d{2})\\]/;\n\nexport class SyncedLyricsProvider {\n  #loop: NodeJS.Timeout | null = null;\n  #callback: LyricsCallback | null = null;\n  #onUnsubscribe: Unsubscribe | null = null;\n\n  public interval = 100;\n  public readonly lyrics: LyricsData = new Map();\n\n  public constructor(\n  public readonly queue: GuildQueue,\n  public readonly raw?: LrcGetResult | LrcSearchResult)\n  {\n    if (raw?.syncedLyrics) this.load(raw?.syncedLyrics);\n  }\n\n  public isSubscribed() {\n    return this.#callback !== null;\n  }\n\n  public load(lyrics: string) {\n    if (!lyrics) throw new NotExistingError('syncedLyrics');\n\n    this.lyrics.clear();\n    this.unsubscribe();\n\n    const lines = lyrics.split('\\n');\n\n    for (const line of lines) {\n      const match = line.match(timestampPattern);\n\n      if (match) {\n        const [, minutes, seconds, milliseconds] = match;\n        const timestamp =\n        parseInt(minutes) * 60 * 1000 +\n        parseInt(seconds) * 1000 +\n        parseInt(milliseconds);\n\n        this.lyrics.set(timestamp, line.replace(timestampPattern, '').trim());\n      }\n    }\n  }\n\n  /**\n   * Returns the lyrics at a specific time or at the closest time (±2 seconds)\n   * @param time The time in milliseconds\n   */\n  public at(time: number): LyricsAt | null {\n    const lowestTime = this.lyrics.keys().next().value;\n    if (lowestTime == null || time < lowestTime) return null;\n    if (this.lyrics.has(time))\n    return { line: this.lyrics.get(time) as string, timestamp: time };\n\n    const keys = Array.from(this.lyrics.keys());\n\n    const closest = keys.reduce((a, b) =>\n    Math.abs(b - time) < Math.abs(a - time) ? b : a\n    );\n\n    if (closest > time) return null;\n\n    if (Math.abs(closest - time) > 2000) return null;\n\n    const line = this.lyrics.get(closest);\n\n    if (!line) return null;\n\n    return { timestamp: closest, line };\n  }\n\n  /**\n   * Callback for the lyrics change.\n   * @param callback The callback function\n   */\n  public onChange(callback: LyricsCallback) {\n    this.#callback = callback;\n  }\n\n  /**\n   * Callback to detect when the provider is unsubscribed.\n   * @param callback The callback function\n   */\n  public onUnsubscribe(callback: Unsubscribe) {\n    this.#onUnsubscribe = callback;\n  }\n\n  /**\n   * Unsubscribes from the queue.\n   */\n  public unsubscribe() {\n    if (this.#loop) clearInterval(this.#loop);\n    if (this.#onUnsubscribe) this.#onUnsubscribe();\n\n    this.#callback = null;\n    this.#onUnsubscribe = null;\n    this.#loop = null;\n  }\n\n  /**\n   * Subscribes to the queue to monitor the current time.\n   * @returns The unsubscribe function\n   */\n  public subscribe(): Unsubscribe {\n    if (this.#loop) return () => this.unsubscribe();\n\n    this.#createLoop();\n\n    return () => this.unsubscribe();\n  }\n\n  /**\n   * Pauses the lyrics provider.\n   */\n  public pause() {\n    const hasLoop = this.#loop !== null;\n\n    if (hasLoop) {\n      clearInterval(this.#loop!);\n      this.#loop = null;\n    }\n\n    return hasLoop;\n  }\n\n  /**\n   * Resumes the lyrics provider.\n   */\n  public resume() {\n    const hasLoop = this.#loop !== null;\n\n    if (!hasLoop) this.#createLoop();\n\n    return !hasLoop;\n  }\n\n  #createLoop() {\n    if (!this.#callback) return;\n    if (this.#loop) clearInterval(this.#loop);\n\n    let lastValue: LyricsAt | null = null;\n\n    this.#loop = setInterval(() => {\n      if (this.queue.deleted) return this.unsubscribe();\n\n      if (!this.#callback || !this.queue.isPlaying()) return;\n\n      const time = this.queue.node.getTimestamp();\n      if (!time) return;\n\n      const lyrics = this.at(time.current.value);\n\n      if (!lyrics) return;\n\n      if (\n      lastValue !== null &&\n      lyrics.line === lastValue.line &&\n      lyrics.timestamp === lastValue.timestamp)\n\n      return;\n\n      lastValue = lyrics;\n\n      this.#callback(lyrics.line, lyrics.timestamp);\n    }, this.interval).unref();\n  }\n}","import { setTimeout } from 'timers/promises';\nimport { AsyncQueue } from './AsyncQueue';\n\nexport type RequestEntity = () => Promise<Response>;\n\nexport class SequentialBucket {\n  public limit = 1;\n  public remaining = 1;\n  public resetAfter = 0;\n  public queue = new AsyncQueue();\n  public MAX_RETRIES = 5;\n\n  /**\n   * Checks if the bucket is rate limited.\n   */\n  public isRateLimited() {\n    return this.remaining <= 0 && Date.now() < this.resetAfter;\n  }\n\n  /**\n   * Enqueues a request.\n   * @param req The request function to enqueue\n   */\n  public async enqueue(req: RequestEntity) {\n    const entry = this.queue.acquire();\n    await entry.getTask();\n\n    try {\n      return this._request(req);\n    } finally {\n      entry.release();\n    }\n  }\n\n  private async _request(req: RequestEntity, retries = 0): Promise<Response> {\n    while (this.isRateLimited()) {\n      const reset = this.resetAfter - Date.now();\n      await setTimeout(reset);\n    }\n\n    let pass = false;\n\n    try {\n      const res = await req();\n\n      this._patchHeaders(res);\n\n      if (res.status === 429) {\n        const reset = this.resetAfter - Date.now();\n        await setTimeout(reset);\n        return this._request(req);\n      }\n\n      if (!res.ok) {\n        let err: Error;\n\n        try {\n          const body: {\n            code: number;\n            name: string;\n            message: string;\n          } = await res.json();\n\n          const error = new Error(body.message) as Error & {code: number;};\n\n          error.name = body.name;\n          error.code = body.code;\n\n          err = error;\n        } catch {\n          err = new Error(`HTTP Error: ${res.status} ${res.statusText}`);\n        }\n\n        pass = true;\n\n        throw err;\n      }\n\n      return res;\n    } catch (e) {\n      if (pass) throw e;\n\n      const badReq = e instanceof Error && /Error: 4[0-9]{2}/.test(e.message);\n\n      if (!badReq && retries < this.MAX_RETRIES) {\n        return this._request(req, ++retries);\n      }\n\n      throw e;\n    }\n  }\n\n  private _patchHeaders(res: Response) {\n    const limit = Number(res.headers.get('X-RateLimit-Limit'));\n    const remaining = Number(res.headers.get('X-RateLimit-Remaining'));\n    const resetAfter =\n    Number(res.headers.get('X-RateLimit-Reset')) * 1000 + Date.now();\n\n    if (!Number.isNaN(limit)) this.limit = limit;\n    if (!Number.isNaN(remaining)) this.remaining = remaining;\n    if (!Number.isNaN(resetAfter)) this.resetAfter = resetAfter;\n  }\n}","import { InvalidArgTypeError } from '../errors';\nimport type { Player } from '../Player';\nimport { Util } from '../utils/Util';\nimport { SequentialBucket } from '../utils/SequentialBucket';\n\nexport interface LrcSearchParams {\n  /**\n   * The query to search for. Either this or trackName is required.\n   */\n  q?: string;\n  /**\n   * The track name to search for. Either this or query is required.\n   */\n  trackName?: string;\n  /**\n   * The artist name\n   */\n  artistName?: string;\n  /**\n   * The album name\n   */\n  albumName?: string;\n}\n\nexport interface LrcGetParams extends Required<Omit<LrcSearchParams, 'query'>> {\n  /**\n   * The duration of the track\n   */\n  duration: number;\n}\n\nconst toSnakeCase = (obj: Record<string, string>): Record<string, string> => {\n  const snakeObj: Record<string, string> = {};\n\n  for (const [key, value] of Object.entries(obj)) {\n    if (value == null) continue;\n    const newKey = key.replace(\n      /[A-Z]/g,\n      (letter) => `_${letter.toLowerCase()}`\n    );\n    snakeObj[newKey] = value;\n  }\n\n  return snakeObj;\n};\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst createQuery = (params: any) =>\nnew URLSearchParams(toSnakeCase(params)).toString();\n\nexport interface LrcSearchResult {\n  /**\n   * The track id\n   */\n  id: number;\n  /**\n   * The track name\n   */\n  name: string;\n  /**\n   * The artist name\n   */\n  trackName: string;\n  /**\n   * The album name\n   */\n  artistName: string;\n  /**\n   * The album name\n   */\n  albumName: string;\n  /**\n   * The duration of the track\n   */\n  duration: number;\n  /**\n   * The release date of the track\n   */\n  instrumental: boolean;\n  /**\n   * The release date of the track\n   */\n  plainLyrics: string;\n  /**\n   * The release date of the track\n   */\n  syncedLyrics?: string;\n}\n\nexport type LrcGetResult = Omit<LrcSearchResult, 'name'>;\n\nexport class LrcLib {\n  /**\n   * The API URL\n   */\n  public api = 'https://lrclib.net/api';\n  /**\n   * The request timeout. Default is 15 seconds.\n   */\n  public timeout = 15_000;\n  /**\n   * The request bucket\n   */\n  public bucket = new SequentialBucket();\n\n  /**\n   * Creates a new LrcLib instance\n   * @param {Player} player The player instance\n   */\n  public constructor(public readonly player: Player) {}\n\n  /**\n   * Sets the request timeout\n   * @param {number} timeout The timeout in milliseconds\n   */\n  public setRequestTimeout(timeout: number) {\n    this.timeout = timeout;\n  }\n\n  /**\n   * Sets the retry limit. Default is 5.\n   * @param {number} limit The retry limit\n   */\n  public setRetryLimit(limit: number) {\n    this.bucket.MAX_RETRIES = limit;\n  }\n\n  /**\n   * Gets lyrics\n   * @param params The get params\n   */\n  public get(params: LrcGetParams) {\n    const path = `get?${createQuery(params)}`;\n\n    return this.request<LrcSearchResult>(path);\n  }\n\n  /**\n   * Gets lyrics by ID\n   * @param id The lyrics ID\n   */\n  public getById(id: `${number}` | number) {\n    return this.request<LrcSearchResult>(`get/${id}`);\n  }\n\n  /**\n   * Gets cached lyrics\n   * @param params The get params\n   */\n  public getCached(params: LrcGetParams) {\n    const path = `get-cached?${createQuery(params)}`;\n\n    return this.request<LrcSearchResult>(path);\n  }\n\n  /**\n   * Searches for lyrics\n   * @param params The search params\n   */\n  public search(params: LrcSearchParams) {\n    if (!params.q && !params.trackName) {\n      throw new InvalidArgTypeError(\n        'one of q or trackName',\n        'string',\n        [String(params.q), String(params.trackName)].join(', ')\n      );\n    }\n\n    const path = `search?${createQuery(params)}`;\n\n    return this.request<LrcSearchResult[]>(path);\n  }\n\n  /**\n   * Requests the API\n   * @param path The path\n   * @param options The request options\n   */\n  public async request<T>(path: string, options?: RequestInit): Promise<T> {\n    const dispatcher = () => {\n      const { name, version } = Util.getRuntime();\n\n      const runtimeVersion =\n      name === 'unknown' ? version : `${name}/${version}`;\n\n      const init: RequestInit = {\n        method: 'GET',\n        redirect: 'follow',\n        signal: AbortSignal.timeout(this.timeout),\n        ...options,\n        headers: {\n          'User-Agent': `Discord-Player/${this.player.version} ${\n          runtimeVersion ?? ''}`.\n          trimEnd(),\n          'Content-Type': 'application/json',\n          ...options?.headers\n        }\n      };\n\n      this.player.debug(`[LrcLib] Requesting ${path}`);\n\n      return fetch(\n        `${this.api}${path.startsWith('/') ? path : '/' + path}`,\n        init\n      );\n    };\n\n    const res = await this.bucket.enqueue(dispatcher);\n\n    return res.json();\n  }\n}","import { VoiceChannel, StageChannel, Snowflake } from 'discord.js';\nimport {\n  DiscordGatewayAdapterCreator,\n  joinVoiceChannel,\n  VoiceConnection,\n  getVoiceConnection,\n  VoiceConnectionStatus,\n  AudioPlayer } from\n'discord-voip';\nimport { StreamDispatcher } from './StreamDispatcher';\nimport { Collection } from '@discord-player/utils';\nimport { GuildQueue } from '../queue';\nimport type { Player } from '../Player';\nimport { NoGuildQueueError } from '../errors';\n\nclass VoiceUtils {\n  /**\n   * Voice connection cache to store voice connections of the Player components.\n   * This property is deprecated and will be removed in the future.\n   * It only exists for compatibility reasons.\n   * @deprecated\n   */\n  public cache: Collection<Snowflake, StreamDispatcher> = new Collection<\n    Snowflake,\n    StreamDispatcher>(\n  );\n\n  /**\n   * The voice utils constructor\n   */\n  constructor(public player: Player) {}\n\n  /**\n   * Joins a voice channel, creating basic stream dispatch manager\n   * @param {StageChannel|VoiceChannel} channel The voice channel\n   * @param {object} [options] Join options\n   * @returns {Promise<StreamDispatcher>}\n   */\n  public async connect(\n  channel: VoiceChannel | StageChannel,\n  options?: {\n    deaf?: boolean;\n    maxTime?: number;\n    queue: GuildQueue;\n    audioPlayer?: AudioPlayer;\n    group?: string;\n    daveEncryption?: boolean;\n    decryptionFailureTolerance?: number;\n  })\n  : Promise<StreamDispatcher> {\n    if (!options?.queue) throw new NoGuildQueueError();\n    const conn = await this.join(channel, options);\n    const sub = new StreamDispatcher(\n      conn,\n      channel,\n      options.queue,\n      options.maxTime,\n      options.audioPlayer\n    );\n    return sub;\n  }\n\n  /**\n   * Joins a voice channel\n   * @param {StageChannel|VoiceChannel} [channel] The voice/stage channel to join\n   * @param {object} [options] Join options\n   * @returns {VoiceConnection}\n   */\n  public async join(\n  channel: VoiceChannel | StageChannel,\n  options?: {\n    deaf?: boolean;\n    maxTime?: number;\n    group?: string;\n    daveEncryption?: boolean;\n    decryptionFailureTolerance?: number;\n  })\n  {\n    const existingConnection = this.getConnection(\n      channel.guild.id,\n      options?.group\n    );\n\n    if (\n    existingConnection?.joinConfig.channelId === channel?.id &&\n    existingConnection.state.status !== VoiceConnectionStatus.Destroyed)\n    {\n      return existingConnection;\n    }\n\n    const conn = joinVoiceChannel({\n      guildId: channel.guild.id,\n      channelId: channel.id,\n      adapterCreator: channel.guild.\n      voiceAdapterCreator as unknown as DiscordGatewayAdapterCreator,\n      selfDeaf: Boolean(options?.deaf),\n      debug: this.player.events.listenerCount('debug') > 0,\n      group: options?.group,\n      daveEncryption: options?.daveEncryption ?? true,\n      decryptionFailureTolerance: options?.decryptionFailureTolerance ?? 24\n    });\n\n    return conn;\n  }\n\n  /**\n   * Disconnects voice connection\n   * @param {VoiceConnection} connection The voice connection\n   * @returns {void}\n   */\n  public disconnect(connection: VoiceConnection | StreamDispatcher) {\n    if (connection instanceof StreamDispatcher)\n    connection = connection.voiceConnection;\n\n    try {\n      if (connection.state.status !== VoiceConnectionStatus.Destroyed)\n      return connection.destroy();\n    } catch {\n\n      //\n    }}\n\n  /**\n   * Returns Discord Player voice connection\n   * @param {Snowflake} guild The guild id\n   * @returns {StreamDispatcher}\n   */\n  public getConnection(guild: Snowflake, group?: string) {\n    return getVoiceConnection(guild, group);\n  }\n}\n\nexport { VoiceUtils };","import { Player } from '../Player';\nimport { SearchResult } from '../fabric/SearchResult';\nimport { Track } from '../fabric/Track';\nimport { User } from 'discord.js';\nimport { SearchQueryType } from './QueryResolver';\n\nexport interface QueryCacheOptions {\n  checkInterval?: number;\n}\n\n// 5h\nconst DEFAULT_EXPIRY_TIMEOUT = 18_000_000;\n\nexport interface QueryCacheProvider<T> {\n  getData(): Promise<DiscordPlayerQueryResultCache<T>[]>;\n  addData(data: SearchResult): Promise<void>;\n  resolve(context: QueryCacheResolverContext): Promise<SearchResult>;\n}\n\nexport class QueryCache implements QueryCacheProvider<Track> {\n  #defaultCache = new Map<string, DiscordPlayerQueryResultCache<Track>>();\n  public timer: NodeJS.Timer;\n  public constructor(\n  public player: Player,\n  public options: QueryCacheOptions = {\n    checkInterval: DEFAULT_EXPIRY_TIMEOUT\n  })\n  {\n    this.timer = setInterval(\n      this.cleanup.bind(this),\n      this.checkInterval\n    ).unref();\n  }\n\n  public get checkInterval() {\n    return this.options.checkInterval ?? DEFAULT_EXPIRY_TIMEOUT;\n  }\n\n  public async cleanup() {\n    for (const [id, value] of this.#defaultCache) {\n      if (value.hasExpired()) {\n        this.#defaultCache.delete(id);\n      }\n    }\n  }\n\n  public async clear() {\n    this.#defaultCache.clear();\n  }\n\n  public async getData() {\n    return [...this.#defaultCache.values()];\n  }\n\n  public async addData(data: SearchResult) {\n    data.tracks.forEach((d) => {\n      if (this.#defaultCache.has(d.url)) return;\n      this.#defaultCache.set(d.url, new DiscordPlayerQueryResultCache(d));\n    });\n  }\n\n  public async resolve(context: QueryCacheResolverContext) {\n    const result = this.#defaultCache.get(context.query);\n    if (!result)\n    return new SearchResult(this.player, {\n      query: context.query,\n      requestedBy: context.requestedBy,\n      queryType: context.queryType\n    });\n\n    return new SearchResult(this.player, {\n      query: context.query,\n      tracks: [result.data],\n      playlist: null,\n      queryType: context.queryType,\n      requestedBy: context.requestedBy\n    });\n  }\n}\n\nexport class DiscordPlayerQueryResultCache<T = unknown> {\n  public expireAfter = DEFAULT_EXPIRY_TIMEOUT;\n  public constructor(\n  public data: T,\n  expireAfter: number = DEFAULT_EXPIRY_TIMEOUT)\n  {\n    if (typeof expireAfter === 'number') {\n      this.expireAfter = Date.now() + expireAfter;\n    }\n  }\n\n  public hasExpired() {\n    if (\n    typeof this.expireAfter !== 'number' ||\n    isNaN(this.expireAfter) ||\n    this.expireAfter < 1)\n\n    return false;\n    return Date.now() <= this.expireAfter;\n  }\n}\n\nexport interface QueryCacheResolverContext {\n  query: string;\n  requestedBy?: User;\n  queryType?: SearchQueryType | `ext:${string}`;\n}","import { FFmpeg } from '@discord-player/ffmpeg';\nimport {\n  Client,\n  SnowflakeUtil,\n  VoiceState,\n  IntentsBitField,\n  User,\n  GuildVoiceChannelResolvable,\n  version as djsVersion,\n  Events } from\n'discord.js';\nimport {\n  Playlist,\n  Track,\n  SearchResult,\n  SearchOptions,\n  PlaylistInitData } from\n'./fabric';\nimport {\n  GuildQueueEvents,\n  VoiceConnectConfig,\n  GuildNodeCreateOptions,\n  GuildNodeManager,\n  GuildQueue,\n  ResourcePlayOptions,\n  GuildQueueEvent } from\n'./queue';\nimport { VoiceUtils } from './stream/VoiceUtils';\nimport {\n  QueryResolver,\n  QueryType,\n  ResolvedQuery,\n  SearchQueryType } from\n'./utils/QueryResolver';\nimport { Util } from './utils/Util';\nimport {\n  AudioResource,\n  version as dVoiceVersion,\n  StreamType } from\n'discord-voip';\nimport { ExtractorExecutionContext } from './extractors/ExtractorExecutionContext';\nimport { BaseExtractor } from './extractors/BaseExtractor';\nimport { QueryCache, QueryCacheProvider } from './utils/QueryCache';\nimport { PlayerEventsEmitter } from './utils/PlayerEventsEmitter';\nimport { InvalidArgTypeError, NoResultError } from './errors';\nimport { defaultVoiceStateHandler } from './DefaultVoiceStateHandler';\nimport { Context, createContext } from './hooks';\nimport { HooksCtx, SUPER_CONTEXT } from './hooks/common';\nimport { LrcLib } from './lrclib/LrcLib';\nimport { getCompatName, isClientProxy } from './compat/common';\nimport { DependencyReportGenerator } from './utils/DependencyReportGenerator';\nimport { getGlobalRegistry } from './utils/__internal__';\nimport { version as dpVersion } from './version';\nimport {\n  PlayerStreamInterceptor,\n  type PlayerStreamInterceptorOptions } from\n'./PlayerStreamInterceptor';\nimport type { InterceptedStream } from './stream/InterceptedStream';\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\nexport interface PlayerEvents {\n  debug: (message: string) => any;\n  error: (error: Error) => any;\n  voiceStateUpdate: (\n  queue: GuildQueue,\n  oldState: VoiceState,\n  newState: VoiceState)\n  => any;\n}\n\nexport const PlayerEvent = {\n  debug: 'debug',\n  Debug: 'debug',\n  error: 'error',\n  Error: 'error',\n  voiceStateUpdate: 'voiceStateUpdate',\n  VoiceStateUpdate: 'voiceStateUpdate'\n} as const;\nexport type PlayerEvent = (typeof PlayerEvent)[keyof typeof PlayerEvent];\n\nexport interface PlayerNodeInitializationResult<T = any> {\n  track: Track;\n  extractor: BaseExtractor | null;\n  searchResult: SearchResult;\n  queue: GuildQueue<T>;\n}\n\n/* eslint-enable @typescript-eslint/no-explicit-any */\n\nexport type TrackLike =\nstring |\nTrack |\nSearchResult |\nTrack[] |\nPlaylist |\nAudioResource;\n\nexport interface PlayerNodeInitializerOptions<T> extends SearchOptions {\n  nodeOptions?: GuildNodeCreateOptions<T>;\n  connectionOptions?: VoiceConnectConfig;\n  audioPlayerOptions?: ResourcePlayOptions;\n  signal?: AbortSignal;\n  afterSearch?: (result: SearchResult) => Promise<SearchResult>;\n}\n\nexport type VoiceStateHandler = (\nplayer: Player,\nqueue: GuildQueue,\noldVoiceState: VoiceState,\nnewVoiceState: VoiceState)\n=> Awaited<void>;\n\nexport interface PlayerInitOptions {\n  /**\n   * The voice connection timeout\n   */\n  connectionTimeout?: number;\n  /**\n   * Time in ms to re-monitor event loop lag\n   */\n  lagMonitor?: number;\n  /**\n   * Prevent voice state handler from being overridden\n   */\n  lockVoiceStateHandler?: boolean;\n  /**\n   * List of extractors to disable querying metadata from\n   */\n  blockExtractors?: string[];\n  /**\n   * List of extractors to disable streaming from\n   */\n  blockStreamFrom?: string[];\n  /**\n   * Query cache provider\n   */\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  queryCache?: QueryCacheProvider<any> | null;\n  /**\n   * Skip ffmpeg process when possible\n   */\n  skipFFmpeg?: boolean;\n  /**\n   * The probe timeout in milliseconds. Defaults to 5000.\n   */\n  probeTimeout?: number;\n  /**\n   * Configure ffmpeg path\n   */\n  ffmpegPath?: string;\n  /**\n   * Whether to override the fallback context. Defaults to `true`.\n   */\n  overrideFallbackContext?: boolean;\n}\n\nexport class Player extends PlayerEventsEmitter<PlayerEvents> {\n  #lastLatency = -1;\n  #voiceStateUpdateListener = this.handleVoiceState.bind(this);\n  #lagMonitorTimeout: NodeJS.Timeout;\n  #lagMonitorInterval: NodeJS.Timeout;\n  #onVoiceStateUpdate: VoiceStateHandler = defaultVoiceStateHandler;\n  #hooksCtx: Context<HooksCtx> | null = null;\n  /**\n   * The version of discord-player\n   */\n  public static readonly version: string = dpVersion;\n  /**\n   * The unique identifier of this player instance\n   */\n  public readonly id = SnowflakeUtil.generate().toString();\n  /**\n   * The discord.js client\n   */\n  public readonly client!: Client;\n  /**\n   * The player options\n   */\n  public readonly options!: PlayerInitOptions;\n  /**\n   * The player nodes (queue) manager\n   */\n  public nodes = new GuildNodeManager(this);\n  /**\n   * The voice api utilities\n   */\n  public readonly voiceUtils = new VoiceUtils(this);\n  /**\n   * The extractors manager\n   */\n  public extractors = new ExtractorExecutionContext(this);\n  /**\n   * The player events channel\n   */\n  public events = new PlayerEventsEmitter<GuildQueueEvents>([\n  GuildQueueEvent.Error,\n  GuildQueueEvent.PlayerError]\n  );\n  /**\n   * The player version\n   */\n  public readonly version = Player.version;\n  /**\n   * The lyrics api\n   */\n  public readonly lyrics = new LrcLib(this);\n\n  #streamInterceptor: PlayerStreamInterceptor | null = null;\n\n  /**\n   * Creates new Discord Player\n   * @param {Client} client The Discord Client\n   * @param {PlayerInitOptions} [options] The player init options\n   */\n  public constructor(client: Client, options: PlayerInitOptions = {}) {\n    super([PlayerEvent.Error]);\n\n    if (options.ffmpegPath) {\n      if (typeof options.ffmpegPath !== 'string')\n      throw new TypeError(\n        `Expected type \"string\" for options.ffmpegPath. Got ${typeof options.ffmpegPath} instead`\n      );\n\n      process.env.FFMPEG_PATH = options.ffmpegPath;\n    }\n\n    const isCompatMode = isClientProxy(client);\n\n    /**\n     * The discord client\n     * @type {Client}\n     */\n    this.client = client;\n\n    if (!isCompatMode) {\n      try {\n        if (!(client instanceof Client)) {\n          Util.warn(\n            `Client is not an instance of discord.js@${djsVersion} client, some things may not work correctly. This can happen due to corrupt dependencies or having multiple installations of discord.js.`,\n            'InvalidClientInstance'\n          );\n        }\n\n        const ibf =\n        this.client.options.intents instanceof IntentsBitField ?\n        this.client.options.intents :\n        new IntentsBitField(this.client.options.intents);\n\n        if (!ibf.has(IntentsBitField.Flags.GuildVoiceStates)) {\n          Util.warn(\n            'client is missing \"GuildVoiceStates\" intent',\n            'InvalidIntentsBitField'\n          );\n        }\n      } catch {\n\n        // noop\n      }}\n\n    this.options = {\n      lockVoiceStateHandler: false,\n      blockExtractors: [],\n      blockStreamFrom: [],\n      connectionTimeout: 20000,\n      lagMonitor: 30000,\n      queryCache:\n      options.queryCache === null ?\n      null :\n      options.queryCache || new QueryCache(this),\n      skipFFmpeg: true,\n      probeTimeout: 5000,\n      overrideFallbackContext: true,\n      ...options\n    } satisfies PlayerInitOptions;\n\n    if (!isCompatMode) {\n      // @ts-ignore private method\n      this.client.incrementMaxListeners();\n      this.client.on(Events.VoiceStateUpdate, this.#voiceStateUpdateListener);\n    } else {\n      try {\n        // @ts-ignore private method\n        this.client.__dp_voiceStateUpdate_proxy(this.#voiceStateUpdateListener);\n      } catch (e) {\n        Util.warn(\n          'Failed to attach voice state update proxy, voice state handler will not work properly',\n          'CompatModeError'\n        );\n      }\n    }\n\n    if (\n    typeof this.options.lagMonitor === 'number' &&\n    this.options.lagMonitor > 0)\n    {\n      this.#lagMonitorInterval = setInterval(() => {\n        const start = performance.now();\n        this.#lagMonitorTimeout = setTimeout(() => {\n          this.#lastLatency = performance.now() - start;\n          if (this.hasDebugger)\n          this.debug(\n            `[Lag Monitor] Event loop latency: ${this.#lastLatency}ms`\n          );\n        }, 0).unref();\n      }, this.options.lagMonitor).unref();\n    }\n\n    if (this.options.overrideFallbackContext) {\n      getGlobalRegistry().set('@[player]', this);\n    }\n  }\n\n  /**\n   * The hooks context for this player instance.\n   */\n  public get context() {\n    if (!this.#hooksCtx) {\n      this.#hooksCtx = createContext();\n\n      const originalProvider = this.#hooksCtx.provide.bind(this.#hooksCtx);\n\n      this.#hooksCtx.provide = (value, receiver) => {\n        return SUPER_CONTEXT.provide(this, () => {\n          return originalProvider(value, () => {\n            return receiver();\n          });\n        });\n      };\n    }\n\n    return this.#hooksCtx;\n  }\n\n  /**\n   * Override default voice state update handler\n   * @param handler The handler callback\n   */\n  public onVoiceStateUpdate(handler: VoiceStateHandler) {\n    this.#onVoiceStateUpdate = handler;\n  }\n\n  public debug(m: string) {\n    return this.emit('debug', m);\n  }\n\n  /**\n   * Creates new discord-player instance.\n   * @param client The client that instantiated player\n   * @param options Player initializer options\n   */\n  public static create(client: Client, options: PlayerInitOptions = {}) {\n    return new Player(client, options);\n  }\n\n  /**\n   * The current query cache provider in use\n   */\n  public get queryCache() {\n    return this.options.queryCache ?? null;\n  }\n\n  /**\n   * Alias to `Player.nodes`.\n   */\n  public get queues() {\n    return this.nodes;\n  }\n\n  /**\n   * Event loop latency in ms. If your bot is laggy and this returns a number above 20ms for example,\n   * some expensive task is being executed on the current thread which is slowing down the event loop.\n   * @type {number}\n   */\n  public get eventLoopLag() {\n    return this.#lastLatency;\n  }\n\n  /**\n   * Generates statistics that could be useful. Statistics generator is still experimental.\n   * @example ```typescript\n   * const stats = player.generateStatistics();\n   *\n   * console.log(stats);\n   *\n   * // outputs something like\n   * // {\n   * //   queuesCount: number,\n   * //   queryCacheEnabled: boolean,\n   * //   queues: [\n   * //      GuildQueueStatisticsMetadata,\n   * //      GuildQueueStatisticsMetadata,\n   * //      GuildQueueStatisticsMetadata,\n   * //      ...\n   * //   ]\n   * // }\n   * ```\n   */\n  public generateStatistics() {\n    return {\n      queuesCount: this.queues.cache.size,\n      queryCacheEnabled: this.queryCache != null,\n      queues: this.queues.cache.map((m) => m.stats.generate())\n    };\n  }\n\n  /**\n   * Whether the player is in compatibility mode. Compatibility mode is enabled when non-discord.js client is used.\n   */\n  public isCompatMode() {\n    return isClientProxy(this.client);\n  }\n\n  /**\n   * Destroy every single queues managed by this master player instance\n   * @example ```typescript\n   * // use me when you want to immediately terminate every single queues in existence 🔪\n   * await player.destroy();\n   * ```\n   */\n  public async destroy() {\n    this.nodes.cache.forEach((node) => node.delete());\n\n    if (!this.isCompatMode()) {\n      this.client.off(Events.VoiceStateUpdate, this.#voiceStateUpdateListener);\n      // @ts-ignore private method\n      this.client.decrementMaxListeners();\n    }\n\n    this.removeAllListeners();\n    this.events.removeAllListeners();\n    await this.extractors.unregisterAll();\n    if (this.#lagMonitorInterval) clearInterval(this.#lagMonitorInterval);\n    if (this.#lagMonitorTimeout) clearInterval(this.#lagMonitorTimeout);\n  }\n\n  private _handleVoiceState(oldState: VoiceState, newState: VoiceState) {\n    const queue = this.nodes.get(oldState.guild.id);\n    if (!queue || !queue.connection || !queue.channel) return;\n\n    // dispatch voice state update\n    const wasHandled = this.events.emit(\n      GuildQueueEvent.VoiceStateUpdate,\n      queue,\n      oldState,\n      newState\n    );\n    // if the event was handled, return assuming the listener implemented all of the logic below\n    if (wasHandled && !this.options.lockVoiceStateHandler) return;\n\n    return this.#onVoiceStateUpdate(this, queue, oldState, newState);\n  }\n\n  /**\n   * Handles voice state update\n   * @param {VoiceState} oldState The old voice state\n   * @param {VoiceState} newState The new voice state\n   * @returns {void}\n   * @example ```typescript\n   * // passing voice state update data to this method will trigger voice state handler\n   *\n   * client.on('voiceStateUpdate', (oldState, newState) => {\n   *   // this is definitely a rocket science, right here\n   *   player.handleVoiceState(oldState, newState);\n   * });\n   * ```\n   */\n  public handleVoiceState(oldState: VoiceState, newState: VoiceState): void {\n    this._handleVoiceState(oldState, newState);\n  }\n\n  /**\n   * Lock voice state handler. When this method is called, discord-player will keep using the default voice state update handler, even if custom implementation exists.\n   */\n  public lockVoiceStateHandler() {\n    this.options.lockVoiceStateHandler = true;\n  }\n\n  /**\n   * Unlock voice state handler. When this method is called, discord-player will stop using the default voice state update handler if custom implementation exists.\n   */\n  public unlockVoiceStateHandler() {\n    this.options.lockVoiceStateHandler = false;\n  }\n\n  /**\n   * Checks if voice state handler is locked.\n   */\n  public isVoiceStateHandlerLocked() {\n    return !!this.options.lockVoiceStateHandler;\n  }\n\n  /**\n   * Initiate audio player\n   * @param channel The voice channel on which the music should be played\n   * @param query The track or source to play\n   * @param options Options for player\n   * @example ```typescript\n   * // no need to worry about queue management, just use this method 😄\n   * const query = 'this is my super cool search query that I want to play';\n   *\n   * try {\n   *    const { track } = await player.play(voiceChannel, query);\n   *   console.log(`🎉 I am playing ${track.title} 🎉`);\n   * } catch(e) {\n   *   console.log(`😭 Failed to play error oh no:\\n\\n${e}`);\n   * }\n   * ```\n   */\n  public async play<T = unknown>(\n  channel: GuildVoiceChannelResolvable,\n  query: TrackLike,\n  options: PlayerNodeInitializerOptions<T> = {})\n  : Promise<PlayerNodeInitializationResult<T>> {\n    const vc = this.client.channels.resolve(channel);\n    if (!vc?.isVoiceBased())\n    throw new InvalidArgTypeError(\n      'channel',\n      'VoiceBasedChannel',\n      !vc ? 'undefined' : `channel type ${vc.type}`\n    );\n\n    const originalResult =\n    query instanceof SearchResult ? query : await this.search(query, options);\n    const result =\n    (await options.afterSearch?.(originalResult)) || originalResult;\n    if (result.isEmpty()) {\n      throw new NoResultError(\n        `No results found for \"${query}\" (Extractor: ${\n        result.extractor?.identifier || 'N/A'})`\n\n      );\n    }\n\n    const queue = this.nodes.create(vc.guild, options.nodeOptions);\n\n    if (this.hasDebugger) this.debug(`[AsyncQueue] Acquiring an entry...`);\n    const entry = queue.tasksQueue.acquire({ signal: options.signal });\n    if (this.hasDebugger)\n    this.debug(`[AsyncQueue] Entry ${entry.id} was acquired successfully!`);\n\n    if (this.hasDebugger)\n    this.debug(`[AsyncQueue] Waiting for the queue to resolve...`);\n    await entry.getTask();\n    if (this.hasDebugger)\n    this.debug(`[AsyncQueue] Entry ${entry.id} was resolved!`);\n\n    try {\n      if (!queue.channel) await queue.connect(vc, options.connectionOptions);\n\n      if (!result.playlist) {\n        queue.addTrack(result.tracks[0]);\n      } else {\n        queue.addTrack(result.playlist);\n      }\n      if (!queue.isPlaying())\n      await queue.node.play(null, options.audioPlayerOptions);\n    } finally {\n      if (this.hasDebugger)\n      this.debug(`[AsyncQueue] Releasing an entry from the queue...`);\n      queue.tasksQueue.release();\n    }\n\n    return {\n      track: result.tracks[0],\n      extractor: result.extractor,\n      searchResult: result,\n      queue\n    };\n  }\n\n  /**\n   * Search tracks\n   * @param {string | Track | Track[] | Playlist | SearchResult} query The search query\n   * @param {SearchOptions} options The search options\n   * @returns {Promise<SearchResult>}\n   * @example ```typescript\n   * const searchQuery = 'pass url or text or discord-player track constructable objects, we got you covered 😎';\n   * const result = await player.search(searchQuery);\n   *\n   * console.log(result); // Logs `SearchResult` object\n   * ```\n   */\n  public async search(\n  searchQuery: TrackLike,\n  options: SearchOptions = {})\n  : Promise<SearchResult> {\n    if (searchQuery instanceof SearchResult) return searchQuery;\n\n    if (searchQuery instanceof AudioResource) {\n      searchQuery = this.createTrackFromAudioResource(searchQuery);\n    }\n\n    if (options.requestedBy != null)\n    options.requestedBy = this.client.users.resolve(options.requestedBy)!;\n\n    options.blockExtractors ??= this.options.blockExtractors;\n    options.fallbackSearchEngine ??= QueryType.AUTO_SEARCH;\n\n    if (searchQuery instanceof Track) {\n      return new SearchResult(this, {\n        playlist: searchQuery.playlist || null,\n        tracks: [searchQuery],\n        query: searchQuery.title,\n        extractor: searchQuery.extractor,\n        queryType: searchQuery.queryType,\n        requestedBy: options.requestedBy\n      });\n    }\n\n    if (searchQuery instanceof Playlist) {\n      return new SearchResult(this, {\n        playlist: searchQuery,\n        tracks: searchQuery.tracks,\n        query: searchQuery.title,\n        extractor: searchQuery.tracks[0]?.extractor,\n        queryType: QueryType.AUTO,\n        requestedBy: options.requestedBy\n      });\n    }\n\n    if (Array.isArray(searchQuery)) {\n      const tracks = searchQuery.filter((t) => t instanceof Track);\n      return new SearchResult(this, {\n        playlist: null,\n        tracks,\n        query: '@@#%{{UserLoadedContent}}%#@@',\n        extractor: null,\n        queryType: QueryType.AUTO,\n        requestedBy: options.requestedBy\n      });\n    }\n\n    if (this.hasDebugger) this.debug(`Searching ${searchQuery}`);\n\n    let extractor: BaseExtractor | null = null,\n      protocol: string | null = null;\n\n    options.searchEngine ??= QueryType.AUTO;\n    options.fallbackSearchEngine ??= QueryType.AUTO_SEARCH;\n\n    if (this.hasDebugger)\n    this.debug(\n      `Search engine set to ${options.searchEngine}, fallback search engine set to ${options.fallbackSearchEngine}`\n    );\n\n    if (/^\\w+:/.test(searchQuery)) {\n      const [protocolName, ...query] = searchQuery.split(':');\n      if (this.hasDebugger)\n      this.debug(`Protocol ${protocolName} detected in query`);\n\n      const matchingExtractor = this.extractors.store.find(\n        (e) =>\n        !this.extractors.isDisabled(e.identifier) &&\n        e.protocols.includes(protocolName)\n      );\n\n      if (matchingExtractor) {\n        if (this.hasDebugger)\n        this.debug(\n          `Protocol ${protocolName} is supported by ${matchingExtractor.identifier} extractor!`\n        );\n        extractor = matchingExtractor;\n        searchQuery = query.join(':');\n        protocol = protocolName;\n      } else {\n        if (this.hasDebugger)\n        this.debug(\n          `Could not find an extractor that supports ${protocolName} protocol. Falling back to default behavior...`\n        );\n      }\n    }\n\n    const redirected = await QueryResolver.preResolve(searchQuery);\n    const { type: queryType, query } =\n    options.searchEngine === QueryType.AUTO ?\n    QueryResolver.resolve(redirected, options.fallbackSearchEngine) :\n    { type: options.searchEngine, query: redirected } as ResolvedQuery;\n\n    if (this.hasDebugger)\n    this.debug(\n      `Query type identified as ${queryType}${\n      extractor && protocol ?\n      ' but might not be used due to the presence of protocol' :\n      ''}`\n\n    );\n\n    // force particular extractor\n    if (options.searchEngine.startsWith('ext:')) {\n      if (this.hasDebugger)\n      this.debug(`Forcing ${options.searchEngine.substring(4)} extractor...`);\n      extractor = this.extractors.get(options.searchEngine.substring(4))!;\n      if (!extractor)\n      return new SearchResult(this, {\n        query,\n        queryType,\n        extractor,\n        requestedBy: options.requestedBy\n      });\n    }\n\n    // query all extractors\n    if (!extractor) {\n      // cache validation\n      if (!options.ignoreCache) {\n        if (this.hasDebugger) this.debug(`Checking cache...`);\n        const res = await this.queryCache?.resolve({\n          query,\n          queryType,\n          requestedBy: options.requestedBy\n        });\n        // cache hit\n        if (res?.hasTracks()) {\n          if (this.hasDebugger) this.debug(`Cache hit for query ${query}`);\n          return res;\n        }\n\n        if (this.hasDebugger) this.debug(`Cache miss for query ${query}`);\n      }\n\n      if (this.hasDebugger) this.debug(`Executing extractors...`);\n\n      // cache miss\n      extractor =\n      (\n      await this.extractors.run(async (ext) => {\n        if (options.blockExtractors?.includes(ext.identifier)) return false;\n        return ext.validate(query, queryType as SearchQueryType);\n      }))?.\n      extractor || null;\n    }\n\n    // no extractors available\n    if (!extractor) {\n      if (this.hasDebugger) this.debug('Failed to find appropriate extractor');\n      return new SearchResult(this, {\n        query,\n        queryType,\n        requestedBy: options.requestedBy\n      });\n    }\n\n    if (this.hasDebugger)\n    this.debug(\n      `Executing metadata query using ${extractor.identifier} extractor...`\n    );\n    const res = await extractor.\n    handle(query, {\n      type: queryType as SearchQueryType,\n      requestedBy: options.requestedBy as User,\n      requestOptions: options.requestOptions,\n      protocol\n    }).\n    catch(() => null);\n\n    if (res) {\n      if (this.hasDebugger) this.debug('Metadata query was successful!');\n      // Store RequestOptions in track raw data for later use during streaming\n      if (options.requestOptions && res.tracks) {\n        res.tracks.forEach((track) => {\n          if (track.raw) {\n            track.raw.requestOptions = options.requestOptions;\n          } else {\n            track.raw = { requestOptions: options.requestOptions };\n          }\n        });\n      }\n\n      const result = new SearchResult(this, {\n        query,\n        queryType,\n        playlist: res.playlist,\n        tracks: res.tracks,\n        extractor,\n        requestedBy: options.requestedBy\n      });\n\n      if (!options.ignoreCache) {\n        if (this.hasDebugger) this.debug(`Adding data to cache...`);\n        await this.queryCache?.addData(result);\n      }\n\n      return result;\n    }\n\n    if (this.hasDebugger)\n    this.debug(\n      'Failed to find result using appropriate extractor. Querying all extractors...'\n    );\n    const result = await this.extractors.run(\n      async (ext) =>\n      !options.blockExtractors?.includes(ext.identifier) && (\n      await ext.validate(query)) &&\n      ext.handle(query, {\n        type: queryType as SearchQueryType,\n        requestedBy: options.requestedBy as User,\n        requestOptions: options.requestOptions,\n        protocol\n      })\n    );\n    if (!result?.result) {\n      if (this.hasDebugger)\n      this.debug(\n        `Failed to query metadata query using ${\n        result?.extractor.identifier || 'N/A'} extractor.`\n\n      );\n      return new SearchResult(this, {\n        query,\n        queryType,\n        requestedBy: options.requestedBy,\n        extractor: result?.extractor\n      });\n    }\n\n    if (this.hasDebugger)\n    this.debug(\n      `Metadata query was successful using ${result.extractor.identifier}!`\n    );\n\n    // Store RequestOptions in track raw data for later use during streaming\n    if (options.requestOptions && result.result.tracks) {\n      result.result.tracks.forEach((track) => {\n        if (track.raw) {\n          track.raw.requestOptions = options.requestOptions;\n        } else {\n          track.raw = { requestOptions: options.requestOptions };\n        }\n      });\n    }\n\n    const data = new SearchResult(this, {\n      query,\n      queryType,\n      playlist: result.result.playlist,\n      tracks: result.result.tracks,\n      extractor: result.extractor,\n      requestedBy: options.requestedBy\n    });\n\n    if (!options.ignoreCache) {\n      if (this.hasDebugger) this.debug(`Adding data to cache...`);\n      await this.queryCache?.addData(data);\n    }\n\n    return data;\n  }\n\n  /**\n   * Generates a report of the dependencies used by the `discord-voip` module. Useful for debugging.\n   * @example ```typescript\n   * console.log(player.scanDeps());\n   * // -> logs dependencies report\n   * ```\n   * @returns {string}\n   */\n  public scanDeps() {\n    const line = '-'.repeat(50);\n    const runtime =\n    'Bun' in globalThis ? 'Bun' : 'Deno' in globalThis ? 'Deno' : 'Node';\n    const depsReport = [\n    'Discord Player',\n    line,\n    `- discord-player: ${Player.version}${\n    this.isCompatMode() ?\n    ` (${getCompatName(this.client)} compatibility mode)` :\n    ''}`,\n\n    `- discord-voip: ${dVoiceVersion}`,\n    `- discord.js: ${djsVersion}`,\n    `- Node version: ${process.version} (Detected Runtime: ${runtime}, Platform: ${process.platform} [${process.arch}])`,\n    (() => {\n      const info = FFmpeg.resolveSafe();\n      if (!info) return 'FFmpeg/Avconv not found';\n\n      return [\n      `- ffmpeg: ${info.version}`,\n      `- command: ${info.command}`,\n      `- static: ${info.module}`,\n      `- libopus: ${info.result!.includes('--enable-libopus')}`].\n      join('\\n');\n    })(),\n    '\\n',\n    'Loaded Extractors:',\n    line,\n    this.extractors.store.\n    map((m) => {\n      return m.identifier;\n    }).\n    join('\\n') || 'N/A',\n    '\\n\\ndiscord-voip',\n    DependencyReportGenerator.generateString()];\n\n\n    return depsReport.join('\\n');\n  }\n\n  public *[Symbol.iterator]() {\n    yield* this.nodes.cache.values();\n  }\n\n  /**\n   * Creates `Playlist` instance\n   * @param data The data to initialize a playlist\n   */\n  public createPlaylist(data: PlaylistInitData) {\n    return new Playlist(this, data);\n  }\n\n  /**\n   * Creates a track from an audio resource.\n   * @param resource The audio resource\n   */\n  public createTrackFromAudioResource(resource: AudioResource) {\n    const metadata = (resource.metadata || {}) as Record<string, unknown>;\n    const ref = SnowflakeUtil.generate().toString();\n    const maybeTitle =\n    'title' in metadata ? `${metadata.title}` : `Track ${ref}`;\n    const maybeAuthor =\n    'author' in metadata ? `${metadata.author}` : 'Unknown author';\n    const maybeDuration =\n    'duration' in metadata ? `${metadata.duration}` : '00:00';\n    const maybeThumbnail =\n    'thumbnail' in metadata ? `${metadata.thumbnail}` : undefined;\n    const maybeURL =\n    'url' in metadata ? `${metadata.url}` : `discord-player://blob/${ref}`;\n    const maybeDescription =\n    'description' in metadata ?\n    `${metadata.description}` :\n    'No description available.';\n    const maybeViews = 'views' in metadata ? Number(metadata.views) || 0 : 0;\n\n    const track = new Track(this, {\n      title: maybeTitle,\n      author: maybeAuthor,\n      duration: maybeDuration,\n      thumbnail: maybeThumbnail,\n      url: maybeURL,\n      description: maybeDescription,\n      queryType: QueryType.DISCORD_PLAYER_BLOB,\n      source: 'arbitrary',\n      metadata,\n      live: false,\n      views: maybeViews\n    });\n\n    resource.metadata = track;\n\n    track.setResource(resource as AudioResource<Track>);\n\n    return track;\n  }\n\n  /**\n   * Handles intercepting streams\n   * @param stream The stream to intercept\n   */\n  public async handleInterceptingStream(\n  queue: GuildQueue,\n  track: Track,\n  format: StreamType,\n  stream: InterceptedStream)\n  {\n    if (!this.#streamInterceptor) return;\n\n    return this.#streamInterceptor.handle(queue, track, format, stream);\n  }\n\n  /**\n   * Creates a global stream interceptor\n   * @param options The stream interceptor options\n   */\n  public createStreamInterceptor(options: PlayerStreamInterceptorOptions) {\n    if (this.#streamInterceptor) {\n      return this.#streamInterceptor;\n    }\n\n    this.#streamInterceptor = new PlayerStreamInterceptor(this, options);\n\n    return this.#streamInterceptor;\n  }\n}","import { ChannelType, VoiceState } from 'discord.js';\nimport { GuildQueue, GuildQueueEvent } from './queue';\nimport { Player } from './Player';\nimport { Util } from './utils/Util';\n\nfunction handleEmptyChannel(\nplayer: Player,\nqueue: GuildQueue,\nguildId: string)\n{\n  const timeout = setTimeout(() => {\n    if (!Util.isVoiceEmpty(queue.channel!) || !player.nodes.has(queue.guild.id))\n    return;\n    if (queue.options.leaveOnEmpty) queue.delete();\n    player.events.emit(GuildQueueEvent.EmptyChannel, queue);\n  }, queue.options.leaveOnEmptyCooldown || 0).unref();\n  queue.timeouts.set(`empty_${guildId}`, timeout);\n}\n\nfunction handleChannelPopulate(\nplayer: Player,\nqueue: GuildQueue,\nguildId: string)\n{\n  const emptyTimeout = queue.timeouts.get(`empty_${guildId}`);\n  if (!Util.isVoiceEmpty(queue.channel!) && emptyTimeout) {\n    clearTimeout(emptyTimeout);\n    queue.timeouts.delete(`empty_${guildId}`);\n    player.events.emit(GuildQueueEvent.ChannelPopulate, queue);\n  }\n}\n\nfunction handlePauseOnEmpty(queue: GuildQueue) {\n  const isEmpty = Util.isVoiceEmpty(queue.channel!);\n  const wasPausedOnEmpty = Reflect.get(queue, '__pausedOnEmpty');\n\n  if (isEmpty && !wasPausedOnEmpty) {\n    queue.node.setPaused(true);\n    Reflect.set(queue, '__pausedOnEmpty', true);\n    if (queue.hasDebugger) {\n      queue.debug(\n        'Voice channel is empty and options#pauseOnEmpty is true, pausing...'\n      );\n    }\n  } else if (!isEmpty && wasPausedOnEmpty) {\n    queue.node.setPaused(false);\n    Reflect.set(queue, '__pausedOnEmpty', false);\n    if (queue.hasDebugger) {\n      queue.debug(\n        'Voice channel is not empty and options#pauseOnEmpty is true, resuming...'\n      );\n    }\n  }\n}\n\nfunction handleBotVoiceStateUpdate(\nqueue: GuildQueue,\noldState: VoiceState,\nnewState: VoiceState)\n{\n  if (\n  newState.serverMute != null &&\n  oldState.serverMute !== newState.serverMute)\n  {\n    queue.node.setPaused(newState.serverMute);\n    return;\n  }\n\n  if (\n  newState.channel?.type === ChannelType.GuildStageVoice &&\n  newState.suppress != null &&\n  oldState.suppress !== newState.suppress)\n  {\n    queue.node.setPaused(newState.suppress);\n    if (newState.suppress) {\n      newState.guild.members.me?.voice.setRequestToSpeak(true).catch(Util.noop);\n    }\n  }\n}\n\nexport async function defaultVoiceStateHandler(\nplayer: Player,\nqueue: GuildQueue,\noldState: VoiceState,\nnewState: VoiceState)\n{\n  if (!queue?.connection || !queue.channel) return;\n\n  const isBotState = newState.member?.id === newState.guild.members.me?.id;\n  const guildId = oldState.guild.id;\n\n  // Bot disconnected\n  if (isBotState && oldState.channelId && !newState.channelId) {\n    try {\n      queue.delete();\n    } catch {\n\n      /* noop */}\n    return void player.events.emit(GuildQueueEvent.Disconnect, queue);\n  }\n\n  if (queue.options.pauseOnEmpty) {\n    handlePauseOnEmpty(queue);\n  }\n\n  // Bot joined channel or changed state\n  if (\n  isBotState &&\n  newState.channelId && (\n  !oldState.channelId || oldState.channelId !== newState.channelId))\n  {\n    if (queue.connection) queue.channel = newState.channel!;\n    handleBotVoiceStateUpdate(queue, oldState, newState);\n  }\n\n  // Handle channel empty/populate events\n  if (!newState.channelId && oldState.channelId === queue.channel.id) {\n    if (!Util.isVoiceEmpty(queue.channel)) return;\n    handleEmptyChannel(player, queue, guildId);\n  } else if (newState.channelId === queue.channel.id) {\n    handleChannelPopulate(player, queue, guildId);\n  } else if (oldState.channelId !== newState.channelId) {\n    if (\n    newState.channelId !== queue.channel.id &&\n    !Util.isVoiceEmpty(queue.channel))\n\n    return;\n    if (!queue.timeouts.has(`empty_${guildId}`)) {\n      handleEmptyChannel(player, queue, guildId);\n    }\n  }\n}","import { resolve, dirname } from 'node:path';\nimport { FFmpeg, FFmpegLib } from '@discord-player/ffmpeg';\nimport { version } from '../version';\n\nexport interface PackageJSON {\n  name: string;\n  version: string;\n}\n\nexport type MaybeNull<T> = T | null;\n\nexport interface DependenciesReport {\n  core: {\n    'discord-player': string;\n    'discord-voip': string;\n  };\n  libopus: {\n    mediaplex: MaybeNull<string>;\n    '@discordjs/opus': MaybeNull<string>;\n    '@evan/opus': MaybeNull<string>;\n    opusscript: MaybeNull<string>;\n    'node-opus': MaybeNull<string>;\n  };\n  libsodium: {\n    'sodium-native': MaybeNull<string>;\n    sodium: MaybeNull<string>;\n    'libsodium-wrappers': MaybeNull<string>;\n    'sodium-javascript': MaybeNull<string>;\n    '@stablelib/xchacha20poly1305': MaybeNull<string>;\n    '@noble/ciphers': MaybeNull<string>;\n  };\n  DAVE: {\n    '@snazzah/davey': MaybeNull<string>;\n  };\n  ffmpeg: FFmpegReport;\n}\n\nexport type FFmpegReport = Record<\n  FFmpegLib,\n  MaybeNull<{\n    version: string;\n    hasLibopus: boolean;\n  }>>;\n\n\n/**\n * A utility to generate a report of the dependencies used by the discord-player module.\n */\nexport const DependencyReportGenerator = {\n  /**\n   * Finds the package.json file of a package.\n   * @param dir - The directory to start searching from\n   * @param packageName - The name of the package to find\n   * @param depth - The maximum depth to search\n   * @returns The package.json file, or null if not found\n   */\n  findPackageJSON(\n  dir: string,\n  packageName: string,\n  depth: number)\n  : PackageJSON | null {\n    if (depth === 0) return null;\n\n    const target = resolve(dir, 'package.json');\n\n    const next = () =>\n    DependencyReportGenerator.findPackageJSON(\n      resolve(dir, '..'),\n      packageName,\n      depth - 1\n    );\n\n    try {\n      // eslint-disable-next-line @typescript-eslint/no-var-requires\n      const pkgJSON: PackageJSON = require(target);\n\n      if (pkgJSON.name !== packageName) {\n        return next();\n      }\n\n      return pkgJSON;\n    } catch {\n      return next();\n    }\n  },\n  /**\n   * Tries to find the version of a dependency.\n   * @param name - The package to find the version of\n   * @param maxLookupDepth - The maximum depth to search for the package.json file\n   * @returns The version of the package, or null if not found\n   */\n  version(name: string, maxLookupDepth = 3): string | null {\n    try {\n      if (name === 'discord-player') {\n        return version;\n      }\n\n      const pkg = DependencyReportGenerator.findPackageJSON(\n        dirname(require.resolve(name)),\n        name,\n        maxLookupDepth\n      );\n      return pkg?.version ?? null;\n    } catch {\n      return null;\n    }\n  },\n  /**\n   * Generates a report of the dependencies used by the discord-player module.\n   * @returns The report object\n   */\n  generate(): DependenciesReport {\n    const ffmpegReport = {} as FFmpegReport;\n\n    for (const lib of FFmpeg.sources) {\n      ffmpegReport[lib.name] = null;\n    }\n\n    const ffmpeg = FFmpeg.resolveSafe();\n\n    if (ffmpeg) {\n      ffmpegReport[ffmpeg.name] = {\n        hasLibopus: ffmpeg.command.includes('--enable-libopus'),\n        version: ffmpeg.version\n      };\n    }\n\n    return {\n      core: {\n        'discord-player': DependencyReportGenerator.version(\n          'discord-player'\n        ) as string,\n        'discord-voip': DependencyReportGenerator.version(\n          'discord-voip'\n        ) as string\n      },\n      libopus: {\n        mediaplex: DependencyReportGenerator.version('mediaplex'),\n        '@discordjs/opus': DependencyReportGenerator.version('@discordjs/opus'),\n        '@evan/opus': DependencyReportGenerator.version('@evan/opus'),\n        opusscript: DependencyReportGenerator.version('opusscript'),\n        'node-opus': DependencyReportGenerator.version('node-opus')\n      },\n      libsodium: {\n        'sodium-native': DependencyReportGenerator.version('sodium-native'),\n        sodium: DependencyReportGenerator.version('sodium'),\n        'libsodium-wrappers':\n        DependencyReportGenerator.version('libsodium-wrappers'),\n        '@stablelib/xchacha20poly1305': DependencyReportGenerator.version(\n          '@stablelib/xchacha20poly1305'\n        ),\n        'sodium-javascript':\n        DependencyReportGenerator.version('sodium-javascript'),\n        '@noble/ciphers': DependencyReportGenerator.version('@noble/ciphers')\n      },\n      DAVE: {\n        '@snazzah/davey': DependencyReportGenerator.version('@snazzah/davey')\n      },\n      ffmpeg: ffmpegReport\n    };\n  },\n  /**\n   * Generates a string representation of the dependencies report.\n   * @returns The string representation\n   */\n  generateString(): string {\n    const report = DependencyReportGenerator.generate();\n    const line = '-'.repeat(50);\n\n    const output: string[] = [];\n\n    output.push('Dependencies Report');\n    output.push(line);\n\n    const keys = Object.keys(report) as (keyof DependenciesReport)[];\n\n    for (const _key of keys) {\n      const key = _key as keyof DependenciesReport;\n\n      output.push(key);\n\n      const subKeys = Object.keys(report[key]);\n\n      for (const _subKey of subKeys) {\n        const subKey = _subKey as keyof DependenciesReport[typeof key];\n        const value = report[key][subKey] ?? 'N/A';\n\n        output.push(\n          `- ${subKey}: ${\n          typeof value === 'object' ? JSON.stringify(value, null, 2) : value}`\n\n        );\n      }\n\n      output.push('');\n    }\n\n    output.push(line);\n\n    return output.join('\\n');\n  }\n};","import { StreamType } from 'discord-voip';\nimport type { Track } from './fabric';\nimport type { Player } from './Player';\nimport type { GuildQueue } from './queue';\nimport type { InterceptedStream } from './stream/InterceptedStream';\n\ntype Awaitable<T> = T | PromiseLike<T>;\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type ShouldInterceptFunction = <T = any>(\nqueue: GuildQueue<T>,\ntrack: Track,\nformat: StreamType,\nstream: InterceptedStream)\n=> Awaitable<boolean>;\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type OnInterceptedStreamHandler = <T = any>(\nqueue: GuildQueue<T>,\ntrack: Track,\nformat: StreamType,\nstream: InterceptedStream)\n=> Awaitable<void>;\n\nexport interface PlayerStreamInterceptorOptions {\n  /**\n   * Determines whether the stream should be intercepted.\n   */\n  shouldIntercept?: ShouldInterceptFunction;\n}\n\nexport class PlayerStreamInterceptor {\n  #onStream = new Set<OnInterceptedStreamHandler>();\n\n  /**\n   * Creates a new PlayerStreamInterceptor instance.\n   * @param player The player instance\n   * @param options The interceptor options\n   */\n  public constructor(\n  public readonly player: Player,\n  private readonly options: PlayerStreamInterceptorOptions)\n  {}\n\n  /**\n   * Handles the intercepted stream.\n   * @param queue The guild queue\n   * @param track The track\n   * @param stream The intercepted stream\n   * @returns Whether the stream was intercepted\n   */\n  public async handle<T = unknown>(\n  queue: GuildQueue<T>,\n  track: Track,\n  type: StreamType,\n  stream: InterceptedStream)\n  : Promise<boolean> {\n    const filter = this.options.shouldIntercept;\n\n    if (filter) {\n      const result = await filter(queue, track, type, stream);\n      if (!result) return false;\n    }\n\n    const hasListeners = this.#onStream.size;\n\n    if (!hasListeners) return false;\n\n    await Promise.all(\n      [...this.#onStream].map((handler) => handler(queue, track, type, stream))\n    );\n\n    return true;\n  }\n\n  /**\n   * Adds a new intercepted stream listener.\n   * @param handler The handler\n   * @returns A function to remove the listener\n   */\n  public onStream(handler: OnInterceptedStreamHandler): () => void {\n    this.#onStream.add(handler);\n\n    return () => {\n      this.#onStream.delete(handler);\n    };\n  }\n}","\n\n\n\n\n\nexport const version = /* @__MACRO__ getVersion */\"7.2.0\";"]}