{"version":3,"sources":["../../../src/classes/room/index.ts"],"sourcesContent":["import type {\n  Events,\n  Game as GameTypes,\n  Room as RoomTypes,\n  Utils\n} from \"../../types\";\nimport { Client } from \"../client\";\nimport { Game } from \"../game\";\nimport { roomConfigPresets } from \"./presets\";\nimport { ReplayManager } from \"./replayManager\";\n\nexport class Room {\n  private client: Client;\n  private listeners: Parameters<typeof this.client.on>[] = [];\n\n  /** the ID of the room */\n  public id!: string;\n  /** Whether or not the room is public */\n  public public!: boolean;\n  /** The type of the room (public | private) */\n  public type!: RoomTypes.Type;\n  /** Name of the room */\n  public name!: string;\n  /** Safe Name of the room */\n  public name_safe!: string;\n  /** UID of the host */\n  public owner!: string;\n  /** UID of the room creator (this person can reclaim host) */\n  public creator!: string;\n  /** The autostart state of the room */\n  public autostart!: RoomTypes.Autostart;\n  /** The match config for the room */\n  public match!: RoomTypes.Match;\n  /** The maxiumum number of players that can play in the room (override by moving as host) */\n  public userLimit!: number;\n  /** The players in the room */\n  public players!: RoomTypes.Player[];\n  /** The room config */\n  public options!: GameTypes.Options;\n  /** The current state of the room (ingame | lobby) */\n  public state!: RoomTypes.State;\n  /** The time the last game started */\n  public gameStart: number | null = null;\n  /** The replay data for the last played game */\n  public replay: ReplayManager | null = null;\n\n  /** Room chat history */\n  public chats: Events.in.Room[\"room.chat\"][] = [];\n\n  /** @hideconstructor */\n  constructor(client: Client, data: Events.in.Room[\"room.update\"]) {\n    this.client = client;\n\n    this.handleUpdate(data);\n\n    this.init();\n  }\n\n  private handleUpdate(data: Events.in.Room[\"room.update\"]) {\n    this.id = data.id;\n    this.autostart = data.auto;\n\n    [\n      \"public\",\n      \"type\",\n      \"name\",\n      \"name_safe\",\n      \"owner\",\n      \"creator\",\n      \"state\",\n      \"match\",\n      \"players\",\n      \"userLimit\"\n    ].forEach((key) =>\n      Object.assign(this, { [key]: data[key as keyof typeof data] })\n    );\n\n    this.options = data.options;\n  }\n\n  private listen<T extends keyof Events.in.all>(\n    event: T,\n    cb: (data: Events.in.all[T]) => void,\n    once = false\n  ) {\n    this.listeners.push([event, cb] as any);\n    if (once) {\n      this.client.once(event, cb);\n    } else {\n      this.client.on(event, cb);\n    }\n  }\n\n  private init() {\n    const emitPlayers = () =>\n      this.client.emit(\"client.room.players\", this.players);\n    let abortTimeout: NodeJS.Timeout | null = null;\n    this.listen(\"room.update.host\", (data) => {\n      this.owner = data;\n    });\n\n    this.listen(\"room.update.bracket\", (data) => {\n      const idx = this.players.findIndex((p) => p._id === data.uid);\n      if (idx >= 0) this.players[idx].bracket = data.bracket;\n      emitPlayers();\n    });\n\n    this.listen(\"room.update.auto\", (auto) => {\n      this.autostart = auto;\n    });\n\n    this.listen(\"room.update\", this.handleUpdate.bind(this));\n\n    this.listen(\"room.player.add\", (data) => {\n      this.players.push(data);\n      emitPlayers();\n    });\n\n    this.listen(\"room.player.remove\", (data) => {\n      this.players = this.players.filter((p) => p._id !== data);\n      emitPlayers();\n    });\n\n    this.listen(\"game.ready\", (data) => {\n      try {\n        this.client.game = new Game(this.client, data);\n      } catch {\n        return; // not in room, don't do anything\n      }\n      if (data.isNew) {\n        this.gameStart = performance.now();\n        this.replay = new ReplayManager(data.players, this.players);\n\n        this.client.emit(\"client.game.start\", {\n          multi: this.match.ft > 1 || this.match.wb > 1,\n          ft: this.match.ft,\n          wb: this.match.wb,\n\n          players: data.players.map((p) => ({\n            id: p.userid,\n            name: p.options.username,\n            points: 0 as const\n          }))\n        });\n      }\n\n      this.replay?.addRound(data.players);\n    });\n\n    this.listen(\"game.replay\", (event) => this.replay?.pipe(event));\n\n    this.listen(\"game.replay.end\", async ({ gameid, data }) => {\n      this.replay?.die({ gameid, data, game: this.client.game });\n      if (!this.client.game || this.client.game.gameid !== gameid) return;\n      this.client.game.stop();\n      this.client.emit(\"client.game.over\", { reason: \"finish\", data });\n    });\n\n    this.listen(\"game.advance\", () => {\n      this.replay?.endRound({ game: this.client.game });\n      if (this.client.game) {\n        this.client.game = this.client.game.destroy();\n        this.client.emit(\"client.game.over\", { reason: \"end\" });\n      }\n    });\n\n    this.listen(\"game.score\", (data) => {\n      if (this.client.game) {\n        this.client.game = this.client.game.destroy();\n        this.client.emit(\"client.game.over\", { reason: \"end\" });\n      }\n\n      this.client.emit(\"client.game.round.end\", data.victor);\n    });\n\n    this.listen(\"game.abort\", () => {\n      if (abortTimeout) return;\n\n      abortTimeout = setTimeout(() => {\n        abortTimeout = null;\n      }, 50);\n\n      this.client.emit(\"client.game.abort\");\n\n      if (!this.client.game) return;\n      this.client.game = this.client.game.destroy();\n      this.client.emit(\"client.game.over\", { reason: \"abort\" });\n    });\n\n    this.listen(\"game.end\", (data) => {\n      this.client.emit(\"client.game.round.end\", data.leaderboard[0].id);\n\n      const maxWins = data.leaderboard.reduce(\n        (max, item) => Math.max(max, item.wins),\n        0\n      );\n      this.client.emit(\"client.game.end\", {\n        duration: performance.now() - (this.gameStart ?? 0),\n        players: data.leaderboard.map(\n          (item) =>\n            ({\n              id: item.id,\n              name: item.username,\n              points: item.wins,\n              won: item.wins === maxWins,\n              raw: item\n            }) satisfies Events.in.Client[\"client.game.end\"][\"players\"][number]\n        )\n      });\n\n      if (!this.client.game) return;\n      this.client.game = this.client.game.destroy();\n      this.client.emit(\"client.game.over\", { reason: \"end\" });\n    });\n\n    this.listen(\"client.game.end\", () =>\n      this.replay?.end({ self: this.client.user.id })\n    );\n\n    // chat\n    this.listen(\"room.chat\", (item) => this.chats.push(item));\n\n    // get booted\n    this.listen(\"room.kick\", () => this.destroy());\n    this.listen(\"room.leave\", () => this.destroy());\n  }\n\n  /** Whether or not the client is the host */\n  get isHost() {\n    return this.client.user.id === this.owner;\n  }\n\n  private destroy() {\n    this.listeners.forEach((l) => this.client.off(l[0], l[1]));\n    if (this.client.game) {\n      this.client.game.destroy();\n      this.client.emit(\"client.game.over\", { reason: \"leave\" });\n    }\n\n    delete this.client.room;\n  }\n\n  /**\n   * Leave the current room\n   * @example\n   * await client.room!.leave();\n   */\n  async leave() {\n    await this.client.wrap(\"room.leave\", undefined, \"room.leave\");\n    this.destroy();\n  }\n\n  /**\n   * Kick a user from the room for a specified duration (if host)\n   * @param id - id of user to kick\n   * @param duration - duration to kick the user, in seconds\n   * @example\n   * await client.room!.kick('646f633d276f42a80ba44304', 100);\n   */\n  async kick(id: string, duration = 900) {\n    return await this.client.wrap(\n      \"room.kick\",\n      { uid: id, duration },\n      \"room.player.remove\"\n    );\n  }\n\n  /**\n   * Unban a user from the room\n   * @example\n   * client.room!.unban('halp');\n   */\n  unban(username: string) {\n    return this.client.emit(\"room.unban\", username);\n  }\n\n  /**\n   * Send a public message to the room's chat.\n   * The `pinned` parameter is the same as using the `/announce` command in TETR.IO\n   * The `pinned` parameter being true will result in an error if the client is not host.\n   * @example\n   * await client.room!.chat('hi!');\n   * @example\n   * await client.room!.chat('Important info:', true);\n   */\n  async chat(message: string, pinned = false) {\n    return await this.client.wrap(\n      \"room.chat.send\",\n      { content: message, pinned },\n      \"room.chat\"\n    );\n  }\n\n  /**\n   * Clears the chat\n   */\n  async clearChat() {\n    return await this.client.wrap(\n      \"room.chat.clear\",\n      undefined,\n      \"room.chat.clear\"\n    );\n  }\n\n  /**\n   * Sets the room id (only works for supporter accounts)\n   * @example\n   * client.room!.setID('TEST');\n   */\n  async setID(id: string) {\n    return await this.client.wrap(\n      \"room.setid\",\n      id.toUpperCase(),\n      \"room.update\"\n    );\n  }\n\n  /**\n   * Update the room's config, similar to using the /set command in tetr.io\n   * await client.room!.update({ index: 'name', value: 'test room'});\n   * @returns\n   */\n  async update<T extends Utils.DeepKeys<RoomTypes.SetConfig>>(\n    ...options: {\n      index: T;\n      value: Utils.DeepKeyValue<RoomTypes.SetConfig, T>;\n    }[]\n  ) {\n    return await this.client.wrap(\n      \"room.setconfig\",\n      options.map((opt) =>\n        typeof opt.value === \"number\"\n          ? { index: opt.index, value: opt.value.toString() }\n          : opt\n      ),\n      \"room.update\"\n    );\n  }\n\n  /**\n   * Sets the room's preset\n   * @example\n   * await client.room!.usePreset('tetra league (season 1)');\n   */\n  async usePreset(preset: GameTypes.Preset) {\n    return await this.update(...roomConfigPresets[preset]);\n  }\n\n  /**\n   * Start the game\n   */\n  async start() {\n    return await this.client.wrap(\"room.start\", undefined, \"game.ready\");\n  }\n\n  /**\n   * Abort the game\n   */\n  async abort() {\n    return await this.client.wrap(\"room.abort\", undefined, \"game.abort\");\n  }\n\n  /**\n   * Give the host to someone else\n   * @example\n   * await client.room!.transferHost(await client.social.resolve('halp'));\n   */\n  async transferHost(player: string) {\n    return await this.client.wrap(\n      \"room.owner.transfer\",\n      player,\n      \"room.update.host\"\n    );\n  }\n\n  /** Take host if you created the room */\n  async takeHost() {\n    return await this.client.wrap(\n      \"room.owner.revoke\",\n      undefined,\n      \"room.update.host\"\n    );\n  }\n\n  /**\n   * Switch bracket\n   * @example\n   * await client.room!.switch('player');\n   */\n  async switch(bracket: \"player\" | \"spectator\") {\n    if (\n      this.players.some(\n        (p) => p._id === this.client.user.id && p.bracket === bracket\n      )\n    )\n      return;\n\n    return await this.client.wrap(\n      \"room.bracket.switch\",\n      bracket,\n      \"room.update.bracket\"\n    );\n  }\n\n  /**\n   * Move someone's bracket\n   * @example\n   * await client.room!.move('646f633d276f42a80ba44304', 'spectator');\n   */\n  async move(uid: string, bracket: \"player\" | \"spectator\") {\n    const player = this.players.find((p) => p._id === uid);\n    if (!player) {\n      throw new Error(`Player with UID ${uid} not found in room.`);\n    }\n\n    if (player.bracket === bracket) return;\n\n    return await this.client.wrap(\n      \"room.bracket.move\",\n      { uid, bracket },\n      \"room.update.bracket\"\n    );\n  }\n}\n\nexport { ReplayManager } from \"./replayManager\";\n"],"names":["Game","roomConfigPresets","ReplayManager","Room","client","listeners","id","public","type","name","name_safe","owner","creator","autostart","match","userLimit","players","options","state","gameStart","replay","chats","data","handleUpdate","init","auto","forEach","key","Object","assign","listen","event","cb","once","push","on","emitPlayers","emit","abortTimeout","idx","findIndex","p","_id","uid","bracket","bind","filter","game","isNew","performance","now","multi","ft","wb","map","userid","username","points","addRound","pipe","gameid","die","stop","reason","endRound","destroy","victor","setTimeout","leaderboard","maxWins","reduce","max","item","Math","wins","duration","won","raw","end","self","user","isHost","l","off","room","leave","wrap","undefined","kick","unban","chat","message","pinned","content","clearChat","setID","toUpperCase","update","opt","value","index","toString","usePreset","preset","start","abort","transferHost","player","takeHost","switch","some","move","find","Error"],"mappings":"AAOA,SAASA,IAAI,QAAQ,UAAU;AAC/B,SAASC,iBAAiB,QAAQ,YAAY;AAC9C,SAASC,aAAa,QAAQ,kBAAkB;AAEhD,OAAO,MAAMC;IACHC,OAAe;IACfC,YAAiD,EAAE,CAAC;IAE5D,uBAAuB,GACvB,AAAOC,GAAY;IACnB,sCAAsC,GACtC,AAAOC,OAAiB;IACxB,4CAA4C,GAC5C,AAAOC,KAAsB;IAC7B,qBAAqB,GACrB,AAAOC,KAAc;IACrB,0BAA0B,GAC1B,AAAOC,UAAmB;IAC1B,oBAAoB,GACpB,AAAOC,MAAe;IACtB,2DAA2D,GAC3D,AAAOC,QAAiB;IACxB,oCAAoC,GACpC,AAAOC,UAAgC;IACvC,kCAAkC,GAClC,AAAOC,MAAwB;IAC/B,0FAA0F,GAC1F,AAAOC,UAAmB;IAC1B,4BAA4B,GAC5B,AAAOC,QAA6B;IACpC,oBAAoB,GACpB,AAAOC,QAA4B;IACnC,mDAAmD,GACnD,AAAOC,MAAwB;IAC/B,mCAAmC,GACnC,AAAOC,YAA2B,KAAK;IACvC,6CAA6C,GAC7C,AAAOC,SAA+B,KAAK;IAE3C,sBAAsB,GACtB,AAAOC,QAAuC,EAAE,CAAC;IAEjD,qBAAqB,GACrB,YAAYjB,MAAc,EAAEkB,IAAmC,CAAE;QAC/D,IAAI,CAAClB,MAAM,GAAGA;QAEd,IAAI,CAACmB,YAAY,CAACD;QAElB,IAAI,CAACE,IAAI;IACX;IAEQD,aAAaD,IAAmC,EAAE;QACxD,IAAI,CAAChB,EAAE,GAAGgB,KAAKhB,EAAE;QACjB,IAAI,CAACO,SAAS,GAAGS,KAAKG,IAAI;QAE1B;YACE;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;SACD,CAACC,OAAO,CAAC,CAACC,MACTC,OAAOC,MAAM,CAAC,IAAI,EAAE;gBAAE,CAACF,IAAI,EAAEL,IAAI,CAACK,IAAyB;YAAC;QAG9D,IAAI,CAACV,OAAO,GAAGK,KAAKL,OAAO;IAC7B;IAEQa,OACNC,KAAQ,EACRC,EAAoC,EACpCC,OAAO,KAAK,EACZ;QACA,IAAI,CAAC5B,SAAS,CAAC6B,IAAI,CAAC;YAACH;YAAOC;SAAG;QAC/B,IAAIC,MAAM;YACR,IAAI,CAAC7B,MAAM,CAAC6B,IAAI,CAACF,OAAOC;QAC1B,OAAO;YACL,IAAI,CAAC5B,MAAM,CAAC+B,EAAE,CAACJ,OAAOC;QACxB;IACF;IAEQR,OAAO;QACb,MAAMY,cAAc,IAClB,IAAI,CAAChC,MAAM,CAACiC,IAAI,CAAC,uBAAuB,IAAI,CAACrB,OAAO;QACtD,IAAIsB,eAAsC;QAC1C,IAAI,CAACR,MAAM,CAAC,oBAAoB,CAACR;YAC/B,IAAI,CAACX,KAAK,GAAGW;QACf;QAEA,IAAI,CAACQ,MAAM,CAAC,uBAAuB,CAACR;YAClC,MAAMiB,MAAM,IAAI,CAACvB,OAAO,CAACwB,SAAS,CAAC,CAACC,IAAMA,EAAEC,GAAG,KAAKpB,KAAKqB,GAAG;YAC5D,IAAIJ,OAAO,GAAG,IAAI,CAACvB,OAAO,CAACuB,IAAI,CAACK,OAAO,GAAGtB,KAAKsB,OAAO;YACtDR;QACF;QAEA,IAAI,CAACN,MAAM,CAAC,oBAAoB,CAACL;YAC/B,IAAI,CAACZ,SAAS,GAAGY;QACnB;QAEA,IAAI,CAACK,MAAM,CAAC,eAAe,IAAI,CAACP,YAAY,CAACsB,IAAI,CAAC,IAAI;QAEtD,IAAI,CAACf,MAAM,CAAC,mBAAmB,CAACR;YAC9B,IAAI,CAACN,OAAO,CAACkB,IAAI,CAACZ;YAClBc;QACF;QAEA,IAAI,CAACN,MAAM,CAAC,sBAAsB,CAACR;YACjC,IAAI,CAACN,OAAO,GAAG,IAAI,CAACA,OAAO,CAAC8B,MAAM,CAAC,CAACL,IAAMA,EAAEC,GAAG,KAAKpB;YACpDc;QACF;QAEA,IAAI,CAACN,MAAM,CAAC,cAAc,CAACR;YACzB,IAAI;gBACF,IAAI,CAAClB,MAAM,CAAC2C,IAAI,GAAG,IAAI/C,KAAK,IAAI,CAACI,MAAM,EAAEkB;YAC3C,EAAE,OAAM;gBACN,QAAQ,iCAAiC;YAC3C;YACA,IAAIA,KAAK0B,KAAK,EAAE;gBACd,IAAI,CAAC7B,SAAS,GAAG8B,YAAYC,GAAG;gBAChC,IAAI,CAAC9B,MAAM,GAAG,IAAIlB,cAAcoB,KAAKN,OAAO,EAAE,IAAI,CAACA,OAAO;gBAE1D,IAAI,CAACZ,MAAM,CAACiC,IAAI,CAAC,qBAAqB;oBACpCc,OAAO,IAAI,CAACrC,KAAK,CAACsC,EAAE,GAAG,KAAK,IAAI,CAACtC,KAAK,CAACuC,EAAE,GAAG;oBAC5CD,IAAI,IAAI,CAACtC,KAAK,CAACsC,EAAE;oBACjBC,IAAI,IAAI,CAACvC,KAAK,CAACuC,EAAE;oBAEjBrC,SAASM,KAAKN,OAAO,CAACsC,GAAG,CAAC,CAACb,IAAO,CAAA;4BAChCnC,IAAImC,EAAEc,MAAM;4BACZ9C,MAAMgC,EAAExB,OAAO,CAACuC,QAAQ;4BACxBC,QAAQ;wBACV,CAAA;gBACF;YACF;YAEA,IAAI,CAACrC,MAAM,EAAEsC,SAASpC,KAAKN,OAAO;QACpC;QAEA,IAAI,CAACc,MAAM,CAAC,eAAe,CAACC,QAAU,IAAI,CAACX,MAAM,EAAEuC,KAAK5B;QAExD,IAAI,CAACD,MAAM,CAAC,mBAAmB,OAAO,EAAE8B,MAAM,EAAEtC,IAAI,EAAE;YACpD,IAAI,CAACF,MAAM,EAAEyC,IAAI;gBAAED;gBAAQtC;gBAAMyB,MAAM,IAAI,CAAC3C,MAAM,CAAC2C,IAAI;YAAC;YACxD,IAAI,CAAC,IAAI,CAAC3C,MAAM,CAAC2C,IAAI,IAAI,IAAI,CAAC3C,MAAM,CAAC2C,IAAI,CAACa,MAAM,KAAKA,QAAQ;YAC7D,IAAI,CAACxD,MAAM,CAAC2C,IAAI,CAACe,IAAI;YACrB,IAAI,CAAC1D,MAAM,CAACiC,IAAI,CAAC,oBAAoB;gBAAE0B,QAAQ;gBAAUzC;YAAK;QAChE;QAEA,IAAI,CAACQ,MAAM,CAAC,gBAAgB;YAC1B,IAAI,CAACV,MAAM,EAAE4C,SAAS;gBAAEjB,MAAM,IAAI,CAAC3C,MAAM,CAAC2C,IAAI;YAAC;YAC/C,IAAI,IAAI,CAAC3C,MAAM,CAAC2C,IAAI,EAAE;gBACpB,IAAI,CAAC3C,MAAM,CAAC2C,IAAI,GAAG,IAAI,CAAC3C,MAAM,CAAC2C,IAAI,CAACkB,OAAO;gBAC3C,IAAI,CAAC7D,MAAM,CAACiC,IAAI,CAAC,oBAAoB;oBAAE0B,QAAQ;gBAAM;YACvD;QACF;QAEA,IAAI,CAACjC,MAAM,CAAC,cAAc,CAACR;YACzB,IAAI,IAAI,CAAClB,MAAM,CAAC2C,IAAI,EAAE;gBACpB,IAAI,CAAC3C,MAAM,CAAC2C,IAAI,GAAG,IAAI,CAAC3C,MAAM,CAAC2C,IAAI,CAACkB,OAAO;gBAC3C,IAAI,CAAC7D,MAAM,CAACiC,IAAI,CAAC,oBAAoB;oBAAE0B,QAAQ;gBAAM;YACvD;YAEA,IAAI,CAAC3D,MAAM,CAACiC,IAAI,CAAC,yBAAyBf,KAAK4C,MAAM;QACvD;QAEA,IAAI,CAACpC,MAAM,CAAC,cAAc;YACxB,IAAIQ,cAAc;YAElBA,eAAe6B,WAAW;gBACxB7B,eAAe;YACjB,GAAG;YAEH,IAAI,CAAClC,MAAM,CAACiC,IAAI,CAAC;YAEjB,IAAI,CAAC,IAAI,CAACjC,MAAM,CAAC2C,IAAI,EAAE;YACvB,IAAI,CAAC3C,MAAM,CAAC2C,IAAI,GAAG,IAAI,CAAC3C,MAAM,CAAC2C,IAAI,CAACkB,OAAO;YAC3C,IAAI,CAAC7D,MAAM,CAACiC,IAAI,CAAC,oBAAoB;gBAAE0B,QAAQ;YAAQ;QACzD;QAEA,IAAI,CAACjC,MAAM,CAAC,YAAY,CAACR;YACvB,IAAI,CAAClB,MAAM,CAACiC,IAAI,CAAC,yBAAyBf,KAAK8C,WAAW,CAAC,EAAE,CAAC9D,EAAE;YAEhE,MAAM+D,UAAU/C,KAAK8C,WAAW,CAACE,MAAM,CACrC,CAACC,KAAKC,OAASC,KAAKF,GAAG,CAACA,KAAKC,KAAKE,IAAI,GACtC;YAEF,IAAI,CAACtE,MAAM,CAACiC,IAAI,CAAC,mBAAmB;gBAClCsC,UAAU1B,YAAYC,GAAG,KAAM,CAAA,IAAI,CAAC/B,SAAS,IAAI,CAAA;gBACjDH,SAASM,KAAK8C,WAAW,CAACd,GAAG,CAC3B,CAACkB,OACE,CAAA;wBACClE,IAAIkE,KAAKlE,EAAE;wBACXG,MAAM+D,KAAKhB,QAAQ;wBACnBC,QAAQe,KAAKE,IAAI;wBACjBE,KAAKJ,KAAKE,IAAI,KAAKL;wBACnBQ,KAAKL;oBACP,CAAA;YAEN;YAEA,IAAI,CAAC,IAAI,CAACpE,MAAM,CAAC2C,IAAI,EAAE;YACvB,IAAI,CAAC3C,MAAM,CAAC2C,IAAI,GAAG,IAAI,CAAC3C,MAAM,CAAC2C,IAAI,CAACkB,OAAO;YAC3C,IAAI,CAAC7D,MAAM,CAACiC,IAAI,CAAC,oBAAoB;gBAAE0B,QAAQ;YAAM;QACvD;QAEA,IAAI,CAACjC,MAAM,CAAC,mBAAmB,IAC7B,IAAI,CAACV,MAAM,EAAE0D,IAAI;gBAAEC,MAAM,IAAI,CAAC3E,MAAM,CAAC4E,IAAI,CAAC1E,EAAE;YAAC;QAG/C,OAAO;QACP,IAAI,CAACwB,MAAM,CAAC,aAAa,CAAC0C,OAAS,IAAI,CAACnD,KAAK,CAACa,IAAI,CAACsC;QAEnD,aAAa;QACb,IAAI,CAAC1C,MAAM,CAAC,aAAa,IAAM,IAAI,CAACmC,OAAO;QAC3C,IAAI,CAACnC,MAAM,CAAC,cAAc,IAAM,IAAI,CAACmC,OAAO;IAC9C;IAEA,0CAA0C,GAC1C,IAAIgB,SAAS;QACX,OAAO,IAAI,CAAC7E,MAAM,CAAC4E,IAAI,CAAC1E,EAAE,KAAK,IAAI,CAACK,KAAK;IAC3C;IAEQsD,UAAU;QAChB,IAAI,CAAC5D,SAAS,CAACqB,OAAO,CAAC,CAACwD,IAAM,IAAI,CAAC9E,MAAM,CAAC+E,GAAG,CAACD,CAAC,CAAC,EAAE,EAAEA,CAAC,CAAC,EAAE;QACxD,IAAI,IAAI,CAAC9E,MAAM,CAAC2C,IAAI,EAAE;YACpB,IAAI,CAAC3C,MAAM,CAAC2C,IAAI,CAACkB,OAAO;YACxB,IAAI,CAAC7D,MAAM,CAACiC,IAAI,CAAC,oBAAoB;gBAAE0B,QAAQ;YAAQ;QACzD;QAEA,OAAO,IAAI,CAAC3D,MAAM,CAACgF,IAAI;IACzB;IAEA;;;;GAIC,GACD,MAAMC,QAAQ;QACZ,MAAM,IAAI,CAACjF,MAAM,CAACkF,IAAI,CAAC,cAAcC,WAAW;QAChD,IAAI,CAACtB,OAAO;IACd;IAEA;;;;;;GAMC,GACD,MAAMuB,KAAKlF,EAAU,EAAEqE,WAAW,GAAG,EAAE;QACrC,OAAO,MAAM,IAAI,CAACvE,MAAM,CAACkF,IAAI,CAC3B,aACA;YAAE3C,KAAKrC;YAAIqE;QAAS,GACpB;IAEJ;IAEA;;;;GAIC,GACDc,MAAMjC,QAAgB,EAAE;QACtB,OAAO,IAAI,CAACpD,MAAM,CAACiC,IAAI,CAAC,cAAcmB;IACxC;IAEA;;;;;;;;GAQC,GACD,MAAMkC,KAAKC,OAAe,EAAEC,SAAS,KAAK,EAAE;QAC1C,OAAO,MAAM,IAAI,CAACxF,MAAM,CAACkF,IAAI,CAC3B,kBACA;YAAEO,SAASF;YAASC;QAAO,GAC3B;IAEJ;IAEA;;GAEC,GACD,MAAME,YAAY;QAChB,OAAO,MAAM,IAAI,CAAC1F,MAAM,CAACkF,IAAI,CAC3B,mBACAC,WACA;IAEJ;IAEA;;;;GAIC,GACD,MAAMQ,MAAMzF,EAAU,EAAE;QACtB,OAAO,MAAM,IAAI,CAACF,MAAM,CAACkF,IAAI,CAC3B,cACAhF,GAAG0F,WAAW,IACd;IAEJ;IAEA;;;;GAIC,GACD,MAAMC,OACJ,GAAGhF,OAGA,EACH;QACA,OAAO,MAAM,IAAI,CAACb,MAAM,CAACkF,IAAI,CAC3B,kBACArE,QAAQqC,GAAG,CAAC,CAAC4C,MACX,OAAOA,IAAIC,KAAK,KAAK,WACjB;gBAAEC,OAAOF,IAAIE,KAAK;gBAAED,OAAOD,IAAIC,KAAK,CAACE,QAAQ;YAAG,IAChDH,MAEN;IAEJ;IAEA;;;;GAIC,GACD,MAAMI,UAAUC,MAAwB,EAAE;QACxC,OAAO,MAAM,IAAI,CAACN,MAAM,IAAIhG,iBAAiB,CAACsG,OAAO;IACvD;IAEA;;GAEC,GACD,MAAMC,QAAQ;QACZ,OAAO,MAAM,IAAI,CAACpG,MAAM,CAACkF,IAAI,CAAC,cAAcC,WAAW;IACzD;IAEA;;GAEC,GACD,MAAMkB,QAAQ;QACZ,OAAO,MAAM,IAAI,CAACrG,MAAM,CAACkF,IAAI,CAAC,cAAcC,WAAW;IACzD;IAEA;;;;GAIC,GACD,MAAMmB,aAAaC,MAAc,EAAE;QACjC,OAAO,MAAM,IAAI,CAACvG,MAAM,CAACkF,IAAI,CAC3B,uBACAqB,QACA;IAEJ;IAEA,sCAAsC,GACtC,MAAMC,WAAW;QACf,OAAO,MAAM,IAAI,CAACxG,MAAM,CAACkF,IAAI,CAC3B,qBACAC,WACA;IAEJ;IAEA;;;;GAIC,GACD,MAAMsB,OAAOjE,OAA+B,EAAE;QAC5C,IACE,IAAI,CAAC5B,OAAO,CAAC8F,IAAI,CACf,CAACrE,IAAMA,EAAEC,GAAG,KAAK,IAAI,CAACtC,MAAM,CAAC4E,IAAI,CAAC1E,EAAE,IAAImC,EAAEG,OAAO,KAAKA,UAGxD;QAEF,OAAO,MAAM,IAAI,CAACxC,MAAM,CAACkF,IAAI,CAC3B,uBACA1C,SACA;IAEJ;IAEA;;;;GAIC,GACD,MAAMmE,KAAKpE,GAAW,EAAEC,OAA+B,EAAE;QACvD,MAAM+D,SAAS,IAAI,CAAC3F,OAAO,CAACgG,IAAI,CAAC,CAACvE,IAAMA,EAAEC,GAAG,KAAKC;QAClD,IAAI,CAACgE,QAAQ;YACX,MAAM,IAAIM,MAAM,CAAC,gBAAgB,EAAEtE,IAAI,mBAAmB,CAAC;QAC7D;QAEA,IAAIgE,OAAO/D,OAAO,KAAKA,SAAS;QAEhC,OAAO,MAAM,IAAI,CAACxC,MAAM,CAACkF,IAAI,CAC3B,qBACA;YAAE3C;YAAKC;QAAQ,GACf;IAEJ;AACF;AAEA,SAAS1C,aAAa,QAAQ,kBAAkB"}