{"version":3,"file":"main.modern.mjs","sources":["../../../node_modules/.pnpm/eventemitter3@5.0.1/node_modules/eventemitter3/index.js","../src/utils/misc.ts","../src/client/errors.ts","../src/client/WsClient.ts","../src/builtins.ts","../src/workflow/errors.ts","../src/utils/Disposable.ts","../src/client/Client.ts","../src/workflow/InvokedWorkflow.ts","../src/workflow/Workflow.ts","../src/plugins/Plugin.ts","../src/pipeline/types.ts","../src/plugins/LoginAuthPlugin.ts","../src/pipeline/base.ts","../src/pipeline/efficient.ts","../src/utils/arrayBuffer.ts","../src/utils/tools.ts","../src/main.ts"],"sourcesContent":["'use strict';\n\nvar has = Object.prototype.hasOwnProperty\n  , prefix = '~';\n\n/**\n * Constructor to create a storage for our `EE` objects.\n * An `Events` instance is a plain object whose properties are event names.\n *\n * @constructor\n * @private\n */\nfunction Events() {}\n\n//\n// We try to not inherit from `Object.prototype`. In some engines creating an\n// instance in this way is faster than calling `Object.create(null)` directly.\n// If `Object.create(null)` is not supported we prefix the event names with a\n// character to make sure that the built-in object properties are not\n// overridden or used as an attack vector.\n//\nif (Object.create) {\n  Events.prototype = Object.create(null);\n\n  //\n  // This hack is needed because the `__proto__` property is still inherited in\n  // some old browsers like Android 4, iPhone 5.1, Opera 11 and Safari 5.\n  //\n  if (!new Events().__proto__) prefix = false;\n}\n\n/**\n * Representation of a single event listener.\n *\n * @param {Function} fn The listener function.\n * @param {*} context The context to invoke the listener with.\n * @param {Boolean} [once=false] Specify if the listener is a one-time listener.\n * @constructor\n * @private\n */\nfunction EE(fn, context, once) {\n  this.fn = fn;\n  this.context = context;\n  this.once = once || false;\n}\n\n/**\n * Add a listener for a given event.\n *\n * @param {EventEmitter} emitter Reference to the `EventEmitter` instance.\n * @param {(String|Symbol)} event The event name.\n * @param {Function} fn The listener function.\n * @param {*} context The context to invoke the listener with.\n * @param {Boolean} once Specify if the listener is a one-time listener.\n * @returns {EventEmitter}\n * @private\n */\nfunction addListener(emitter, event, fn, context, once) {\n  if (typeof fn !== 'function') {\n    throw new TypeError('The listener must be a function');\n  }\n\n  var listener = new EE(fn, context || emitter, once)\n    , evt = prefix ? prefix + event : event;\n\n  if (!emitter._events[evt]) emitter._events[evt] = listener, emitter._eventsCount++;\n  else if (!emitter._events[evt].fn) emitter._events[evt].push(listener);\n  else emitter._events[evt] = [emitter._events[evt], listener];\n\n  return emitter;\n}\n\n/**\n * Clear event by name.\n *\n * @param {EventEmitter} emitter Reference to the `EventEmitter` instance.\n * @param {(String|Symbol)} evt The Event name.\n * @private\n */\nfunction clearEvent(emitter, evt) {\n  if (--emitter._eventsCount === 0) emitter._events = new Events();\n  else delete emitter._events[evt];\n}\n\n/**\n * Minimal `EventEmitter` interface that is molded against the Node.js\n * `EventEmitter` interface.\n *\n * @constructor\n * @public\n */\nfunction EventEmitter() {\n  this._events = new Events();\n  this._eventsCount = 0;\n}\n\n/**\n * Return an array listing the events for which the emitter has registered\n * listeners.\n *\n * @returns {Array}\n * @public\n */\nEventEmitter.prototype.eventNames = function eventNames() {\n  var names = []\n    , events\n    , name;\n\n  if (this._eventsCount === 0) return names;\n\n  for (name in (events = this._events)) {\n    if (has.call(events, name)) names.push(prefix ? name.slice(1) : name);\n  }\n\n  if (Object.getOwnPropertySymbols) {\n    return names.concat(Object.getOwnPropertySymbols(events));\n  }\n\n  return names;\n};\n\n/**\n * Return the listeners registered for a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @returns {Array} The registered listeners.\n * @public\n */\nEventEmitter.prototype.listeners = function listeners(event) {\n  var evt = prefix ? prefix + event : event\n    , handlers = this._events[evt];\n\n  if (!handlers) return [];\n  if (handlers.fn) return [handlers.fn];\n\n  for (var i = 0, l = handlers.length, ee = new Array(l); i < l; i++) {\n    ee[i] = handlers[i].fn;\n  }\n\n  return ee;\n};\n\n/**\n * Return the number of listeners listening to a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @returns {Number} The number of listeners.\n * @public\n */\nEventEmitter.prototype.listenerCount = function listenerCount(event) {\n  var evt = prefix ? prefix + event : event\n    , listeners = this._events[evt];\n\n  if (!listeners) return 0;\n  if (listeners.fn) return 1;\n  return listeners.length;\n};\n\n/**\n * Calls each of the listeners registered for a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @returns {Boolean} `true` if the event had listeners, else `false`.\n * @public\n */\nEventEmitter.prototype.emit = function emit(event, a1, a2, a3, a4, a5) {\n  var evt = prefix ? prefix + event : event;\n\n  if (!this._events[evt]) return false;\n\n  var listeners = this._events[evt]\n    , len = arguments.length\n    , args\n    , i;\n\n  if (listeners.fn) {\n    if (listeners.once) this.removeListener(event, listeners.fn, undefined, true);\n\n    switch (len) {\n      case 1: return listeners.fn.call(listeners.context), true;\n      case 2: return listeners.fn.call(listeners.context, a1), true;\n      case 3: return listeners.fn.call(listeners.context, a1, a2), true;\n      case 4: return listeners.fn.call(listeners.context, a1, a2, a3), true;\n      case 5: return listeners.fn.call(listeners.context, a1, a2, a3, a4), true;\n      case 6: return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true;\n    }\n\n    for (i = 1, args = new Array(len -1); i < len; i++) {\n      args[i - 1] = arguments[i];\n    }\n\n    listeners.fn.apply(listeners.context, args);\n  } else {\n    var length = listeners.length\n      , j;\n\n    for (i = 0; i < length; i++) {\n      if (listeners[i].once) this.removeListener(event, listeners[i].fn, undefined, true);\n\n      switch (len) {\n        case 1: listeners[i].fn.call(listeners[i].context); break;\n        case 2: listeners[i].fn.call(listeners[i].context, a1); break;\n        case 3: listeners[i].fn.call(listeners[i].context, a1, a2); break;\n        case 4: listeners[i].fn.call(listeners[i].context, a1, a2, a3); break;\n        default:\n          if (!args) for (j = 1, args = new Array(len -1); j < len; j++) {\n            args[j - 1] = arguments[j];\n          }\n\n          listeners[i].fn.apply(listeners[i].context, args);\n      }\n    }\n  }\n\n  return true;\n};\n\n/**\n * Add a listener for a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @param {Function} fn The listener function.\n * @param {*} [context=this] The context to invoke the listener with.\n * @returns {EventEmitter} `this`.\n * @public\n */\nEventEmitter.prototype.on = function on(event, fn, context) {\n  return addListener(this, event, fn, context, false);\n};\n\n/**\n * Add a one-time listener for a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @param {Function} fn The listener function.\n * @param {*} [context=this] The context to invoke the listener with.\n * @returns {EventEmitter} `this`.\n * @public\n */\nEventEmitter.prototype.once = function once(event, fn, context) {\n  return addListener(this, event, fn, context, true);\n};\n\n/**\n * Remove the listeners of a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @param {Function} fn Only remove the listeners that match this function.\n * @param {*} context Only remove the listeners that have this context.\n * @param {Boolean} once Only remove one-time listeners.\n * @returns {EventEmitter} `this`.\n * @public\n */\nEventEmitter.prototype.removeListener = function removeListener(event, fn, context, once) {\n  var evt = prefix ? prefix + event : event;\n\n  if (!this._events[evt]) return this;\n  if (!fn) {\n    clearEvent(this, evt);\n    return this;\n  }\n\n  var listeners = this._events[evt];\n\n  if (listeners.fn) {\n    if (\n      listeners.fn === fn &&\n      (!once || listeners.once) &&\n      (!context || listeners.context === context)\n    ) {\n      clearEvent(this, evt);\n    }\n  } else {\n    for (var i = 0, events = [], length = listeners.length; i < length; i++) {\n      if (\n        listeners[i].fn !== fn ||\n        (once && !listeners[i].once) ||\n        (context && listeners[i].context !== context)\n      ) {\n        events.push(listeners[i]);\n      }\n    }\n\n    //\n    // Reset the array, or remove it completely if we have no more listeners.\n    //\n    if (events.length) this._events[evt] = events.length === 1 ? events[0] : events;\n    else clearEvent(this, evt);\n  }\n\n  return this;\n};\n\n/**\n * Remove all listeners, or those of the specified event.\n *\n * @param {(String|Symbol)} [event] The event name.\n * @returns {EventEmitter} `this`.\n * @public\n */\nEventEmitter.prototype.removeAllListeners = function removeAllListeners(event) {\n  var evt;\n\n  if (event) {\n    evt = prefix ? prefix + event : event;\n    if (this._events[evt]) clearEvent(this, evt);\n  } else {\n    this._events = new Events();\n    this._eventsCount = 0;\n  }\n\n  return this;\n};\n\n//\n// Alias methods names because people roll like that.\n//\nEventEmitter.prototype.off = EventEmitter.prototype.removeListener;\nEventEmitter.prototype.addListener = EventEmitter.prototype.on;\n\n//\n// Expose the prefix.\n//\nEventEmitter.prefixed = prefix;\n\n//\n// Allow `EventEmitter` to be imported as module namespace.\n//\nEventEmitter.EventEmitter = EventEmitter;\n\n//\n// Expose the module.\n//\nif ('undefined' !== typeof module) {\n  module.exports = EventEmitter;\n}\n","export const uuidv4 = () =>\n  \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, (c) => {\n    const r = (Math.random() * 16) | 0,\n      v = c === \"x\" ? r : (r & 0x3) | 0x8;\n    return v.toString(16);\n  });\n\nexport const isNone = (x: any): x is null | undefined =>\n  x === null || x === undefined;\nexport const debounce = <F extends (...args: any[]) => any>(\n  fn: F,\n  wait_ms: number,\n): ((...args: Parameters<F>) => void) => {\n  let timeout: any = null;\n  return (...args: Parameters<F>): void => {\n    if (timeout) clearTimeout(timeout);\n    timeout = setTimeout(() => fn(...args), wait_ms);\n  };\n};\n","import { ComfyUIClientResponseTypes } from \"./response.types\";\n\nexport class ClientError extends Error {\n  constructor(message: string) {\n    super(message);\n  }\n}\n\n// 等待 prompt 执行超时\nexport class PromptTimeoutError extends ClientError {\n  constructor(prompt_id: string, timeout_ms: number) {\n    super(`Prompt ${prompt_id} timed out after ${timeout_ms} ms`);\n  }\n}\n\n// enqueue prompt 错误\nexport class PromptEnqueueError extends ClientError {\n  constructor(resp: ComfyUIClientResponseTypes.QueuePromptError) {\n    const { error, node_errors } = resp;\n    const message =\n      typeof error === \"string\" ? error : error.errors?.[0].message;\n    const details_message = node_errors ? JSON.stringify(node_errors) : \"\";\n    super(`Failed to enqueue prompt: ${message}, details: ${details_message}`);\n  }\n}\n\n// client enqueue 参数错误\nexport class ClientEnqueueError extends ClientError {\n  constructor(err_msg: string) {\n    super(`Client enqueue error: ${err_msg}`);\n  }\n}\n\n// prompt_id 错误，没有找到对应的 prompt 在 history 中\nexport class PromptNotFoundError extends ClientError {\n  constructor(prompt_id: string) {\n    super(`Prompt [${prompt_id}] not found in history`);\n  }\n}\n\n// task 数据类型错误，可能是 comfyui api 版本变动\nexport class TaskDataTypeError extends ClientError {\n  constructor(task_data: any) {\n    // 此数据类型与预期不符，请尝试更新 comfyui version\n    super(\n      `Task data type error, please try updating comfyui version: ${JSON.stringify(task_data)}`,\n    );\n  }\n}\n// prompt 执行失败，状态不是 success\nexport class PromptExecutionFailedError extends ClientError {\n  constructor(prompt_id: string, status: string) {\n    super(`Prompt ${prompt_id} execution failed with status: ${status}`);\n  }\n}\n\n// client 请求执行失败\nexport class ClientRequestError extends ClientError {\n  constructor(err_msg: string) {\n    super(`Client request error: ${err_msg}`);\n  }\n}\n\n// client polling timeout\nexport class PollingTimeoutError extends ClientError {\n  constructor(timeout_ms: number) {\n    super(`Polling timed out after ${timeout_ms} ms`);\n  }\n}\n\n// client web socket timeout\nexport class WebSocketTimeoutError extends ClientError {\n  constructor(timeout_ms: number) {\n    super(`WebSocket timed out after ${timeout_ms} ms`);\n  }\n}\n\n// connect 参数错误\nexport class ConnectError extends ClientError {\n  constructor(err_msg: string) {\n    super(`Connect error: ${err_msg}`);\n  }\n}\n\n// 解析 ws 数据错误\nexport class WebSocketParseError extends ClientError {\n  constructor(err_msg: string) {\n    super(`WebSocket parse error: ${err_msg}`);\n  }\n}\n\n// http errors\nexport class HttpError extends Error {\n  status: number;\n  json: any;\n\n  constructor(message: string, status: number, json?: any) {\n    super(message);\n    this.name = \"HttpError\";\n    this.status = status;\n    this.json = json;\n  }\n}\n","import { EventEmitter } from \"eventemitter3\";\nimport { ComfyUIClientEvents } from \"./ws.types\";\nimport { uuidv4 } from \"../utils/misc\";\nimport { IComfyApiConfig } from \"./types\";\nimport {\n  ConnectError,\n  HttpError,\n  PollingTimeoutError,\n  WebSocketParseError,\n  WebSocketTimeoutError,\n} from \"./errors\";\n\n/**\n * A client for interacting with the ComfyUI API server using WebSockets.\n *\n * NOTE: CORS policy: Request header field comfy-user is not allowed by Access-Control-Allow-Headers in preflight response. Please config.use empty string in browser.\n *\n * @example\n * ```typescript\n * const client = new WsClient({\n *  api_host: \"YOUR_API_HOST\"\n * });\n *\n * // Connect to the server\n * client.connect();\n *\n * // Listen for status updates\n * client.on(\"status\", (status) => {\n *   console.log(\"Status:\", status);\n * });\n *\n * // when done, close the client\n * client.close();\n */\nexport class WsClient {\n  static DEFAULT_API_HOST = \"127.0.0.1:8188\";\n  static DEFAULT_API_BASE = \"\";\n  static DEFAULT_USER = \"\";\n  static IS_BROWSER = typeof window !== \"undefined\";\n\n  static readBinaryData(buf: ArrayBuffer) {\n    const view = new DataView(buf);\n    const eventType = view.getUint32(0);\n    const imageType = view.getUint32(1);\n\n    switch (eventType) {\n      case 3: {\n        const decoder = new TextDecoder();\n        const data = buf.slice(4);\n        const nodeIdLength = view.getUint32(4);\n        return [\n          {\n            type: \"progress_text\",\n            data: {\n              nodeId: decoder.decode(data.slice(4, 4 + nodeIdLength)),\n              text: decoder.decode(data.slice(4 + nodeIdLength)),\n            },\n          },\n        ] as const;\n      }\n\n      case 1: {\n        const mimeTypes = {\n          1: \"image/jpeg\",\n          2: \"image/png\",\n        } as any;\n\n        const mime = mimeTypes[imageType] || \"image/png\";\n        const image = buf.slice(8);\n\n        const imageBlob = new Blob([image], {\n          type: mime,\n        });\n\n        return [\n          {\n            type: \"b_preview\",\n            data: imageBlob,\n          },\n        ] as const;\n      }\n\n      case 4: {\n        // PREVIEW_IMAGE_WITH_METADATA\n        const decoder4 = new TextDecoder();\n        const metadataLength = view.getUint32(4);\n        const metadataBytes = buf.slice(8, 8 + metadataLength);\n        const metadata = JSON.parse(decoder4.decode(metadataBytes));\n        const imageData4 = buf.slice(8 + metadataLength);\n\n        let imageMime4 = metadata.image_type;\n\n        const imageBlob4 = new Blob([imageData4], {\n          type: imageMime4,\n        });\n\n        return [\n          {\n            type: \"b_preview_with_metadata\",\n            data: {\n              blob: imageBlob4,\n              nodeId: metadata.node_id,\n              displayNodeId: metadata.display_node_id,\n              parentNodeId: metadata.parent_node_id,\n              realNodeId: metadata.real_node_id,\n              promptId: metadata.prompt_id,\n            },\n          },\n          {\n            type: \"b_preview\",\n            data: imageBlob4,\n          },\n        ] as const;\n      }\n      default:\n        throw new WebSocketParseError(\n          `Unknown binary websocket message of type ${eventType}`,\n        );\n    }\n  }\n\n  api_host: string;\n  api_base: string;\n  clientId?: string;\n  socket?: WebSocket | null;\n  WebSocket: typeof WebSocket;\n  ssl: boolean;\n  user: string;\n  fetch: typeof fetch;\n\n  events: EventEmitter<ComfyUIClientEvents & Record<string & {}, any>> =\n    new EventEmitter();\n\n  protected socket_callbacks: Record<string, any> = {};\n\n  get registered() {\n    return this.events.eventNames();\n  }\n\n  constructor(config: IComfyApiConfig) {\n    this.api_host = config.api_host ?? WsClient.DEFAULT_API_HOST;\n    this.api_base = config.api_base ?? WsClient.DEFAULT_API_BASE;\n    this.clientId = config.clientId ?? uuidv4();\n    this.WebSocket = config.WebSocket ?? globalThis.WebSocket;\n    this.ssl = config.ssl ?? false;\n    this.user = config.user ?? WsClient.DEFAULT_USER;\n    if (!globalThis.fetch) {\n      throw new ConnectError(\"fetch is not defined\");\n    }\n    this.fetch = config.fetch ?? globalThis.fetch.bind(globalThis);\n\n    if (!this.WebSocket) {\n      console.warn(\"No WebSocket implementation available, WebSocket disabled\");\n    }\n  }\n\n  /**\n   * Returns the headers for the API request.\n   *\n   * @param {RequestInit} [options] - (Optional) Additional options for the request.\n   * @return {HeadersInit} The headers for the API request.\n   */\n  apiHeaders(options?: RequestInit) {\n    const headers: HeadersInit = {\n      ...(this.user\n        ? {\n            \"Comfy-User\": this.user,\n          }\n        : {}),\n      // \"User-Agent\": `ComfyUIClient/${version}`,\n      Accept: \"*/*\",\n      ...(options?.headers ?? {}),\n    };\n    return headers;\n  }\n\n  /**\n   * Generates the URL for the API endpoint based on the provided route.\n   *\n   * @param {string} route - The route for the API endpoint.\n   * @return {string} The generated URL for the API endpoint.\n   */\n  apiURL(route: string): string {\n    const url = new URL(`http${this.ssl ? \"s\" : \"\"}://${this.api_host}`);\n    let [pathname, query] = (this.api_base + route).split(\"?\");\n    url.pathname = pathname;\n    url.pathname = url.pathname.replace(/\\/+/g, \"/\");\n    if (query) {\n      url.search = query;\n    }\n    if (this.clientId) {\n      url.searchParams.set(\"clientId\", this.clientId);\n    }\n    return url.toString();\n  }\n\n  internalURL(route: string): string {\n    return this.apiURL(`/internal${route}`);\n  }\n\n  /**\n   * Generates a URL for viewing a specific file with the given filename, subfolder, and type.\n   *\n   * @param {string} filename - The name of the file to view.\n   * @param {string} subfolder - The subfolder where the file is located.\n   * @param {string} type - The type of the file.\n   * @return {string} The URL for viewing the file.\n   */\n  viewURL(filename: string, subfolder: string, type: string): string {\n    const query = new URLSearchParams({\n      filename,\n      subfolder,\n      type,\n    }).toString();\n    return `http${this.ssl ? \"s\" : \"\"}://${this.api_host}${\n      this.api_base\n    }/view?${query}`;\n  }\n\n  /**\n   * Generates the WebSocket URL based on the current API host and SSL configuration.\n   *\n   * @return {string} The generated WebSocket URL.\n   */\n  wsURL(): string {\n    const url = new URL(`ws${this.ssl ? \"s\" : \"\"}://${this.api_host}`);\n    url.pathname = \"/ws\";\n    if (this.clientId) {\n      url.searchParams.set(\"clientId\", this.clientId);\n    }\n    return url.toString();\n  }\n\n  /**\n   * Fetches API data based on the provided route and options.\n   *\n   * NOTE: CORS policy: Request header field comfy-user is not allowed by Access-Control-Allow-Headers in preflight response. Please use empty string in browser.\n   *\n   * @param {string} route - The route for the API request.\n   * @param {RequestInit} [options] - (Optional) Additional options for the request.\n   * @return {Promise<Response>} A promise that resolves to the API response.\n   */\n  async fetchApi(route: string, options?: RequestInit): Promise<Response> {\n    const url = this.apiURL(route);\n    const res = await this.fetch(url, {\n      ...options,\n      headers: this.apiHeaders(options),\n    });\n    const { status, statusText } = res;\n\n    if (status < 200 || status >= 400) {\n      throw new HttpError(\n        `Endpoint Bad Request (${status} ${statusText}): ${url}`,\n        status,\n        await res.json(),\n      );\n    }\n\n    return res;\n  }\n\n  /**\n   * Adds an event listener for the specified event type.\n   *\n   * @param {keyof ComfyUIClientEvents | (string & {})} type - The type of event to listen for.\n   * @param {(...args: any) => void} callback - The callback function to be executed when the event is triggered.\n   * @param {any} options - (Optional) Additional options for the event listener.\n   * @return {() => void} A function that removes the event listener when called.\n   */\n  addEventListener<T extends EventEmitter.EventNames<ComfyUIClientEvents>>(\n    type: T,\n    callback: EventEmitter.EventListener<ComfyUIClientEvents, T>,\n    options?: any,\n  ) {\n    this.events.on(type as any, callback as any, options);\n\n    return () => {\n      this.events.off(type as any, callback as any);\n    };\n  }\n\n  /**\n   * Adds an event listener for the specified event type.\n   *\n   * @param {keyof ComfyUIClientEvents | (string & {})} type - The type of event to listen for.\n   * @param {(...args: any) => void} callback - The callback function to be executed when the event is triggered.\n   * @param {any} options - (Optional) Additional options for the event listener.\n   * @return {() => void} A function that removes the event listener when called.\n   */\n  on<T extends EventEmitter.EventNames<ComfyUIClientEvents>>(\n    type: T,\n    callback: EventEmitter.EventListener<ComfyUIClientEvents, T>,\n    options?: any,\n  ) {\n    return this.addEventListener(type, callback, options);\n  }\n\n  /**\n   * Adds an event listener for the specified event type.\n   *\n   * @param {keyof ComfyUIClientEvents | (string & {})} type - The type of event to listen for.\n   * @param {(...args: any) => void} callback - The callback function to be executed when the event is triggered.\n   * @param {any} options - (Optional) Additional options for the event listener.\n   * @return {() => void} A function that removes the event listener when called.\n   */\n  once<T extends EventEmitter.EventNames<ComfyUIClientEvents>>(\n    type: T,\n    callback: EventEmitter.EventListener<ComfyUIClientEvents, T>,\n    options?: any,\n  ) {\n    this.events.once(type as any, callback as any, options);\n\n    return () => {\n      this.events.off(type as any, callback as any);\n    };\n  }\n\n  protected _polling_timer: any = null;\n  protected _polling_interval = 1000;\n  /**\n   * Poll status for colab and other things that don't support websockets.\n   */\n  private startPollingQueue() {\n    if (this._polling_timer) {\n      return;\n    }\n    // FIXME: 优化点\n    // 这里不需要一直 polling ，只有有任务的时候才需要 polling\n    this._polling_timer = setInterval(async () => {\n      try {\n        const resp = await this.fetchApi(\"/prompt\");\n        const status = await resp.json();\n        this.events.emit(\"status\", status);\n      } catch (error) {\n        this.events.emit(\"status\", null);\n      }\n    }, this._polling_interval);\n  }\n\n  protected addSocketCallback<K extends keyof WebSocketEventMap>(\n    socket: WebSocket,\n    type: K,\n    listener: (this: WebSocket, ev: WebSocketEventMap[K]) => any,\n    options?: boolean | AddEventListenerOptions,\n  ) {\n    this.socket_callbacks[type] = listener;\n    socket.addEventListener(type, listener, options);\n    return () => {\n      delete this.socket_callbacks[type];\n      socket.removeEventListener(type, listener, options);\n    };\n  }\n\n  /**\n   * Removes all event listeners from the given WebSocket and clears the socket_callbacks object.\n   */\n  protected removeSocketCallbacks() {\n    if (this.socket) {\n      for (const type in this.socket_callbacks) {\n        const listener = this.socket_callbacks[type];\n        this.socket.removeEventListener(type, listener);\n      }\n    }\n    this.socket_callbacks = {};\n  }\n\n  /**\n   * Creates and connects a WebSocket for realtime updates\n   * @param {boolean} isReconnect If the socket is connection is a reconnect attempt\n   */\n  private createSocket(isReconnect = false) {\n    if (this.socket) {\n      return;\n    }\n    if (!this.WebSocket) {\n      throw new ConnectError(\n        \"WebSocket is not defined, please provide a WebSocket implementation\",\n      );\n    }\n    if (this.closed) {\n      return;\n    }\n\n    let opened = false;\n\n    this.socket = new this.WebSocket(this.wsURL());\n    this.socket.binaryType = \"arraybuffer\";\n\n    this.addSocketCallback(this.socket, \"open\", () => {\n      opened = true;\n      if (isReconnect) {\n        this.events.emit(\"reconnected\");\n      } else {\n        this.events.emit(\"connected\");\n      }\n    });\n\n    this.addSocketCallback(this.socket, \"error\", (ev: Event) => {\n      // Expose websocket errors as unhandled events\n      // Allows for catching 404 and other network errors\n      const err = ev as ErrorEvent;\n      const is404Error = err.message?.includes(\"404\");\n\n      this.events.emit(\"connection_error\", {\n        type: \"404\",\n        message: err.message,\n      });\n\n      if (this.socket) this.socket.close();\n\n      if (!is404Error && !isReconnect && !opened) {\n        this.startPollingQueue();\n      }\n    });\n\n    this.addSocketCallback(this.socket, \"close\", () => {\n      setTimeout(() => {\n        this.socket = null;\n        this.createSocket(true);\n      }, 300);\n      if (opened) {\n        this.events.emit(\"status\", null);\n        this.events.emit(\"reconnecting\");\n      }\n    });\n\n    const isBinaryData = (event: MessageEvent) => {\n      if (typeof event.data === \"string\") {\n        return false;\n      }\n      if (ArrayBuffer && event.data instanceof ArrayBuffer) {\n        return true;\n      }\n      if (Buffer && Buffer.isBuffer(event.data)) {\n        return true;\n      }\n      return false;\n    };\n\n    this.addSocketCallback(this.socket, \"message\", async (event) => {\n      this.events.emit(\"message\", event);\n\n      if (isBinaryData(event)) {\n        const binaryEvents = WsClient.readBinaryData(event.data);\n        for (const ev of binaryEvents) {\n          switch (ev.type) {\n            case \"b_preview\": {\n              // TODO add types\n              this.events.emit(\"b_preview\", ev.data);\n              this.events.emit(\"image_data\", {\n                image: await ev.data.arrayBuffer(),\n                mime: ev.data.type,\n              });\n              break;\n            }\n            case \"b_preview_with_metadata\": {\n              // TODO add types\n              this.events.emit(\"b_preview_with_metadata\", ev.data);\n              this.events.emit(\"image_data\", {\n                image: await ev.data.blob.arrayBuffer(),\n                mime: ev.data.blob.type,\n              });\n              break;\n            }\n            case \"progress_text\": {\n              // TODO add types\n              this.events.emit(\"progress_text\", ev.data);\n              break;\n            }\n            default:\n              return;\n          }\n        }\n      } else {\n        const msg = JSON.parse(event.data);\n\n        switch (msg.type) {\n          case \"status\":\n            if (msg.data.sid) {\n              this.clientId = msg.data.sid;\n            }\n            this.events.emit(\"status\", msg.data.status);\n            break;\n          case \"progress\":\n            this.events.emit(\"progress\", msg.data);\n            break;\n          case \"executing\":\n            this.events.emit(\"executing\", msg.data);\n            break;\n          case \"executed\":\n            this.events.emit(\"executed\", msg.data);\n            break;\n          case \"execution_start\":\n            this.events.emit(\"execution_start\", msg.data);\n            break;\n          case \"execution_error\":\n            this.events.emit(\"execution_error\", msg.data);\n            break;\n          case \"execution_cached\":\n            this.events.emit(\"execution_cached\", msg.data);\n            break;\n          case \"execution_interrupted\":\n            this.events.emit(\"execution_interrupted\", msg.data);\n            break;\n          default:\n            this.events.emit(msg.type, msg.data);\n            break;\n        }\n\n        const is_unhandled_message =\n          msg.type !== \"message\" &&\n          this.registered.includes(msg.type) === false;\n        if (is_unhandled_message) {\n          this.events.emit(\"unhandled\", msg);\n        }\n      }\n    });\n  }\n\n  /**\n   * Initializes sockets and realtime updates\n   *\n   * @deprecated move to client.connect()\n   */\n  init() {\n    this.createSocket();\n  }\n\n  closed = false;\n  /**\n   * Closes the WebSocket connection and cleans up event listeners\n   */\n  close() {\n    if (this.closed) {\n      return;\n    }\n    this.closed = true;\n    this.events.emit(\"close\");\n\n    this.disconnect();\n    this.events.removeAllListeners();\n  }\n\n  /**\n   * Connects to the WebSocket server by creating a new socket connection.\n   *\n   * @param {Object} options - The options for connecting to the server.\n   * @param {Object} options.polling - The options for polling.\n   * @param {boolean} options.polling.enabled - Whether polling is enabled.\n   * @param {number} [options.polling.interval] - The interval for polling.\n   * @param {Object} options.websocket - The options for the WebSocket connection.\n   * @param {boolean} options.websocket.enabled - Whether the WebSocket connection is enabled.\n   * @param {number} [options.timeout_ms] - The timeout for the connection in milliseconds.\n   * @return {Promise<boolean>} - A promise that resolves to true if the connection was successful, false otherwise.\n   */\n  connect({\n    polling = {\n      enabled: false,\n    },\n    websocket = {\n      enabled: true,\n    },\n    timeout_ms = 15 * 1000,\n  }: {\n    polling?: {\n      enabled: boolean;\n      interval?: number;\n    };\n    websocket?: {\n      enabled: boolean;\n    };\n    timeout_ms?: number;\n  } = {}) {\n    if (polling?.enabled) {\n      this._polling_interval = polling.interval ?? this._polling_interval;\n      this.startPollingQueue();\n      return new Promise(async (resolve, reject) => {\n        const timer = setTimeout(() => {\n          reject(new PollingTimeoutError(timeout_ms));\n        }, timeout_ms);\n        // ping to ok or fail\n        const resp = await this.fetchApi(\"/system_stats\");\n        resolve(resp.ok && resp.status === 200);\n        clearTimeout(timer);\n      });\n    }\n    if (websocket?.enabled) {\n      this.createSocket();\n      return new Promise((resolve, reject) => {\n        const timer = setTimeout(() => {\n          reject(new WebSocketTimeoutError(timeout_ms));\n        }, timeout_ms);\n        this.once(\"connected\", () => {\n          resolve(true);\n          clearTimeout(timer);\n        });\n      });\n    }\n    throw new ConnectError(\"You must enable either polling or websocket\");\n  }\n\n  /**\n   * Disconnects the WebSocket connection and cleans up event listeners.\n   */\n  disconnect() {\n    if (!this.socket) {\n      process.nextTick(this._disconnectPolling.bind(this));\n    } else {\n      this._disconnectSocket();\n    }\n    this._disconnectPolling();\n  }\n\n  /**\n   * Disconnects the WebSocket connection and cleans up event listeners.\n   *\n   * @return {void} This function does not return anything.\n   */\n  _disconnectSocket() {\n    const { socket } = this;\n    if (!socket) return;\n    this.socket = null;\n    try {\n      if (socket.readyState === socket.OPEN) {\n        socket.close(1000, \"Client closed\");\n      }\n    } catch (error) {\n      // pass\n    }\n    this.removeSocketCallbacks();\n    if (\"removeAllListeners\" in socket) {\n      (socket.removeAllListeners as any)?.();\n    }\n  }\n\n  /**\n   * Disconnects the polling timer and sets it to null.\n   *\n   * @return {void}\n   */\n  _disconnectPolling() {\n    if (this._polling_timer !== null) {\n      clearInterval(this._polling_timer);\n      this._polling_timer = null;\n    }\n  }\n}\n","import { WorkflowOutputResolver } from \"./client/types\";\nimport { isNone } from \"./utils/misc\";\nimport { WorkflowOutput } from \"./workflow/types\";\n\nexport const RESOLVERS = {\n  image: ((acc, output, { client }) => {\n    if (output === null || output === undefined) {\n      return acc;\n    }\n\n    const output_images: {\n      filename?: string;\n      subfolder?: string;\n      type: string;\n    }[] = (output?.images || []) as any;\n\n    const images_url = output_images\n      .map((image) => {\n        const { filename, subfolder, type } = image;\n        const type_should_be = [\n          // SaveImage node output as \"output\"\n          \"output\",\n          // PreviewImage node output as \"temp\"\n          \"temp\",\n        ];\n        if (\n          isNone(filename) ||\n          isNone(subfolder) ||\n          !type_should_be.includes(type)\n        ) {\n          return null;\n        }\n        return client.viewURL(filename, subfolder, type);\n      })\n      .filter(Boolean) as string[];\n\n    const images = images_url.map((image) => ({\n      type: \"url\" as const,\n      data: image,\n    }));\n    return {\n      ...acc,\n      images: [...acc.images, ...images],\n    };\n  }) as WorkflowOutputResolver<WorkflowOutput>,\n};\n","import { ComfyUiWsTypes } from \"../client/ws.types\";\nimport { InvokedWorkflow } from \"./InvokedWorkflow\";\nimport { IWorkflow } from \"./types\";\nimport { Workflow } from \"./Workflow\";\n\nexport class WorkflowError extends Error {\n  constructor(\n    message: string,\n    readonly task_id: string,\n    readonly workflow?: IWorkflow,\n    readonly invoked?: InvokedWorkflow,\n  ) {\n    super(message);\n  }\n}\n\nexport class WorkflowExecutionError extends WorkflowError {\n  constructor(\n    readonly payload: ComfyUiWsTypes.Messages.ExecutionError,\n    task_id: string,\n    workflow?: IWorkflow,\n    invoked?: InvokedWorkflow<any>,\n  ) {\n    const { exception_message, exception_type } = payload;\n    super(\n      `Execution error: ${exception_message} (${exception_type})`,\n      task_id,\n      workflow,\n      invoked,\n    );\n  }\n}\n\nexport class ClientConnectionError extends Error {\n  constructor(type: string, message: string) {\n    super(`Client connection error (${type}): ${message}`);\n  }\n}\n\n// --- guard errors ---\nexport class WorkflowGuardError extends Error {\n  readonly workflow: IWorkflow;\n\n  constructor(\n    message: string,\n    readonly invoked: InvokedWorkflow<any>,\n  ) {\n    super(message);\n    this.workflow = invoked.workflow;\n  }\n}\n\n// \"This workflow is already enqueued\"\nexport class WorkflowEnqueuedError extends WorkflowGuardError {\n  constructor(invoked: InvokedWorkflow<any>) {\n    super(\"This workflow is already enqueued\", invoked);\n  }\n}\n\n// 工作流没有被 enqueued，或者执行状态还未更新，缺少 task_id\nexport class WorkflowTaskIdError extends WorkflowGuardError {\n  constructor(invoked: InvokedWorkflow<any>) {\n    super(\n      \"This workflow is not enqueued and the execution status cannot be interrupted\",\n      invoked,\n    );\n  }\n}\n\n// 工作流已经 disposed 或者已经 结束\nexport class WorkflowDoneError extends WorkflowGuardError {\n  constructor(invoked: InvokedWorkflow<any>) {\n    const { is_done, is_disposed } = invoked;\n    const message = is_done\n      ? \"This workflow has already finished\"\n      : \"This workflow has been disposed\";\n    super(message, invoked);\n  }\n}\n\n// ws 没有连接\nexport class WorkflowWsError extends WorkflowGuardError {\n  constructor(invoked: InvokedWorkflow<any>) {\n    super(\"WebSocket is not connected\", invoked);\n  }\n}\n\n// 无法获取 任务状态\nexport class WorkflowTaskStatusError extends WorkflowGuardError {\n  constructor(invoked: InvokedWorkflow<any>) {\n    const { task_id } = invoked;\n    super(\n      task_id\n        ? `Cannot get task status for task ${task_id}`\n        : \"Cannot get task status\",\n      invoked,\n    );\n  }\n}\n\n// 执行被 interrupted\nexport class WorkflowInterruptedError extends WorkflowGuardError {\n  constructor(invoked: InvokedWorkflow<any>) {\n    super(\"Execution has been interrupted\", invoked);\n  }\n}\n\n// 参数错误\nexport class WorkflowArgumentError extends WorkflowGuardError {\n  constructor(invoked: InvokedWorkflow<any>, message: string) {\n    super(message, invoked);\n  }\n}\n","export class Disposable {\n  protected _disposed = false;\n  protected _disposed_cbs = [] as any[];\n  public dispose() {\n    if (this._disposed) {\n      return;\n    }\n    this._disposed = true;\n\n    this._disposed_cbs.forEach((cb) => {\n      if (typeof cb === \"function\") {\n        cb();\n      }\n    });\n  }\n  public _connect(cb: () => void) {\n    if (this._disposed) {\n      cb();\n      return;\n    }\n    this._disposed_cbs.push(cb);\n  }\n}\n","import type { Plugin } from \"../plugins/Plugin\";\nimport { WsClient } from \"./WsClient\";\nimport { RESOLVERS } from \"../builtins\";\nimport {\n  WorkflowOutputResolver,\n  EnqueueOptions,\n  IComfyApiConfig,\n  PromptBody,\n  PromptQueueItem,\n  ModelFolderInfo,\n  ModelFile,\n  LogsRawResponse,\n} from \"./types\";\nimport { ComfyUIClientResponseTypes } from \"./response.types\";\nimport { WorkflowOutput } from \"../workflow/types\";\nimport { WorkflowExecutionError } from \"../workflow/errors\";\nimport {\n  ClientEnqueueError,\n  ClientRequestError,\n  PromptEnqueueError,\n  PromptExecutionFailedError,\n  PromptNotFoundError,\n  PromptTimeoutError,\n  TaskDataTypeError,\n} from \"./errors\";\nimport { Disposable } from \"../utils/Disposable\";\n\n/**\n * The Client class provides a high-level interface for interacting with the ComfyUI API.\n *\n * @extends WsClient\n *\n * @example\n * ```typescript\n * const client = new Client({\n *  api_host: \"YOUR_API_HOST\",\n *  clientId: \"YOUR_CLIENT_ID\",\n * });\n *\n * const extensions = await client.getEmbeddings();\n * console.log(extensions);\n * ```\n */\nexport class Client extends WsClient {\n  // NOTE: useless ... just for debug\n  private _plugins = [] as Plugin[];\n\n  constructor(\n    config: Omit<IComfyApiConfig, \"fetch\" | \"WebSocket\"> & {\n      // NOTE: This is written to reduce type issues... because sometimes `as any` is unavoidable\n      fetch?: any;\n      WebSocket?: any;\n    },\n  ) {\n    super(config);\n  }\n\n  /**\n   * Use a plugin by calling its install method on this instance.\n   *\n   * @param {Plugin} plugin - The plugin to install.\n   */\n  use(plugin: Plugin) {\n    plugin.install(this);\n    this._plugins.push(plugin);\n  }\n\n  /**\n   * Gets a list of extension urls\n   * @returns An array of script urls to import\n   */\n  async getExtensions(): Promise<string[]> {\n    const invoke = async () => {\n      const resp = await this.fetchApi(\"/extensions\", { cache: \"no-store\" });\n      return await resp.json();\n    };\n    return invoke();\n  }\n\n  /**\n   * Gets a list of embedding names\n   * @returns An array of script urls to import\n   */\n  async getEmbeddings(): Promise<string[]> {\n    const invoke = async () => {\n      const resp = await this.fetchApi(\"/embeddings\", { cache: \"no-store\" });\n      return await resp.json();\n    };\n    return invoke();\n  }\n\n  /**\n   * Loads node object definitions for the graph\n   * @returns {Promise<ComfyUIClientResponseTypes.ObjectInfo>} The object info for the graph\n   */\n  async getNodeDefs(): Promise<ComfyUIClientResponseTypes.ObjectInfo> {\n    const invoke = async () => {\n      const resp = await this.fetchApi(\"/object_info\", { cache: \"no-store\" });\n      const node_defs = await resp.json();\n      return node_defs;\n    };\n    return invoke();\n  }\n\n  /**\n   *\n   * @param {number} queue_index The index at which to queue the prompt, passing -1 will insert the prompt at the front of the queue\n   * @param {Object} options\n   * @param {Object} options.prompt The prompt to queue\n   * @param {Object} options.workflow This png info to be added to resulting image\n   * @returns {Promise<ComfyUIClientResponseTypes.QueuePrompt>} The response from the server\n   */\n  async queuePrompt(\n    queue_index: number,\n    { prompt, workflow }: { prompt: any; workflow: any },\n  ): Promise<ComfyUIClientResponseTypes.QueuePrompt> {\n    const body: Record<string, unknown> = {\n      client_id: this.clientId,\n      prompt,\n      extra_data: { extra_pnginfo: { workflow } },\n    };\n\n    if (queue_index === -1) {\n      body.front = true;\n    } else if (queue_index !== 0) {\n      body.number = queue_index;\n    }\n\n    const res = await this.fetchApi(\"/prompt\", {\n      method: \"POST\",\n      headers: {\n        \"Content-Type\": \"application/json\",\n      },\n      body: JSON.stringify(body),\n    });\n\n    if (res.status !== 200) {\n      const error_resp = await res.text();\n      try {\n        const error_data = JSON.parse(error_resp);\n        throw new PromptEnqueueError(error_data);\n      } catch (error) {\n        throw new PromptEnqueueError({ error: error_resp, node_errors: {} });\n      }\n    }\n\n    return await res.json();\n  }\n\n  /**\n   * Loads a list of items (queue or history)\n   * @param {\"queue\" | \"history\"} type The type of items to load, queue or history\n   * @returns The items of the specified type grouped by their status\n   */\n  async getItems(type: \"history\"): ReturnType<Client[\"getHistory\"]>;\n  async getItems(type: \"queue\"): ReturnType<Client[\"getQueue\"]>;\n  async getItems(type: \"queue\" | \"history\"): Promise<any> {\n    if (type === \"queue\") {\n      return this.getQueue();\n    }\n    return this.getHistory();\n  }\n\n  /**\n   * Gets the current state of the queue\n   * @returns The currently running and queued items\n   */\n  async getQueue(): Promise<{\n    Running: Array<PromptBody>;\n    Pending: Array<PromptBody>;\n  }> {\n    try {\n      const res = await this.fetchApi(\"/queue\");\n      const data = await res.json();\n      return {\n        Running: data.queue_running,\n        Pending: data.queue_pending,\n      };\n    } catch (error) {\n      console.error(error);\n      return { Running: [], Pending: [] };\n    }\n  }\n\n  /**\n   * Gets the prompt execution history\n   * @returns Prompt history including node outputs\n   */\n  async getHistory(\n    max_items = 200,\n    options?: {\n      offset?: number;\n    },\n  ): Promise<{\n    History: Array<PromptQueueItem>;\n  }> {\n    const { offset } = options || {};\n    // Validate offset parameter\n    if (offset !== undefined && (offset < 0 || !Number.isInteger(offset))) {\n      throw new Error(\n        `Invalid offset parameter: ${offset}. Must be a non-negative integer.`,\n      );\n    }\n    const params = new URLSearchParams({ max_items: max_items.toString() });\n    if (offset !== undefined) {\n      params.set(\"offset\", offset.toString());\n    }\n    try {\n      const res = await this.fetchApi(`/history?${params.toString()}`);\n      return { History: Object.values(await res.json()) };\n    } catch (error) {\n      console.error(error);\n      return { History: [] };\n    }\n  }\n\n  /**\n   * Gets system & device stats\n   * @returns {ComfyUIClientResponseTypes.SystemStatsRoot} System stats such as python version, OS, per device info\n   */\n\n  async getSystemStats(): Promise<ComfyUIClientResponseTypes.SystemStatsRoot> {\n    const res = await this.fetchApi(\"/system_stats\");\n    return res.json();\n  }\n\n  /**\n   * Sends a POST request to the API\n   * @param {string} type The endpoint to post to\n   * @param {any} body Optional POST data\n   */\n  private async postApi(type: string, body: any) {\n    await this.fetchApi(\"/\" + type, {\n      method: \"POST\",\n      headers: {\n        \"Content-Type\": \"application/json\",\n      },\n      body: body ? JSON.stringify(body) : undefined,\n    });\n  }\n\n  /**\n   * Deletes an item from the specified list\n   * @param {\"queue\" | \"history\"} type The type of item to delete, queue or history\n   * @param {any} id The id of the item to delete\n   */\n  async deleteItem(type: \"queue\" | \"history\", id: any) {\n    await this.postApi(type, { delete: [id] });\n  }\n\n  /**\n   * Clears the specified list\n   * @param {\"queue\" | \"history\"} type The type of list to clear, queue or history\n   */\n  async clearItems(type: \"queue\" | \"history\") {\n    await this.postApi(type, { clear: true });\n  }\n\n  /**\n   * Interrupts the execution of the running prompt. If runningPromptId is provided,\n   * it is included in the payload as a helpful hint to the backend.\n   * @param {string | null} [runningPromptId] Optional Running Prompt ID to interrupt\n   */\n  async interrupt(runningPromptId: string | null = null) {\n    await this.postApi(\n      \"interrupt\",\n      runningPromptId ? { prompt_id: runningPromptId } : undefined,\n    );\n  }\n\n  /**\n   * Free up memory by unloading models and freeing memory\n   */\n  async free(params?: { unload_models?: boolean; free_memory?: boolean }) {\n    await this.postApi(\"free\", params);\n  }\n\n  /**\n   * Gets user configuration data and where data should be stored\n   * @returns { Promise<{ storage: \"server\" | \"browser\", users?: Promise<string, unknown>, migrated?: boolean }> }\n   */\n  async getUserConfig() {\n    return (await this.fetchApi(\"/users\")).json();\n  }\n\n  /**\n   * Creates a new user\n   * @param { string } username\n   * @returns The fetch response\n   */\n  async createUser(username: string): Promise<Response> {\n    return this.fetchApi(\"/users\", {\n      method: \"POST\",\n      headers: {\n        \"Content-Type\": \"application/json\",\n      },\n      body: JSON.stringify({ username }),\n    });\n  }\n\n  /**\n   * Gets all setting values for the current user\n   * @returns { Promise<string, unknown> } A dictionary of id -> value\n   */\n  async getSettings(): Promise<Record<string, unknown>> {\n    return (await this.fetchApi(\"/settings\")).json();\n  }\n\n  /**\n   * Gets a setting for the current user\n   * @param { string } id The id of the setting to fetch\n   * @returns { Promise<unknown> } The setting value\n   */\n  async getSetting(id: string): Promise<unknown> {\n    return (await this.fetchApi(`/settings/${encodeURIComponent(id)}`)).json();\n  }\n\n  /**\n   * Stores a dictionary of settings for the current user\n   * @param { Record<string, unknown> } settings Dictionary of setting id -> value to save\n   * @returns { Promise<void> }\n   */\n  async storeSettings(settings: Record<string, unknown>): Promise<Response> {\n    return this.fetchApi(`/settings`, {\n      method: \"POST\",\n      body: JSON.stringify(settings),\n    });\n  }\n\n  /**\n   * Stores a setting for the current user\n   * @param { string } id The id of the setting to update\n   * @param { unknown } value The value of the setting\n   * @returns { Promise<void> }\n   */\n  async storeSetting(id: string, value: unknown): Promise<Response> {\n    return this.fetchApi(`/settings/${encodeURIComponent(id)}`, {\n      method: \"POST\",\n      body: JSON.stringify(value),\n    });\n  }\n\n  /**\n   * Gets a user data file for the current user\n   * @param { string } file The name of the userdata file to load\n   * @param { RequestInit } [options]\n   * @returns { Promise<unknown> } The fetch response object\n   */\n  async getUserData(file: string, options?: RequestInit): Promise<Response> {\n    return this.fetchApi(`/userdata/${encodeURIComponent(file)}`, options);\n  }\n\n  /**\n   * Stores a user data file for the current user\n   * @param { string } file The name of the userdata file to save\n   * @param { any } data The data to save to the file\n   * @param { RequestInit & { stringify?: boolean, throwOnError?: boolean } } [options]\n   * @returns { Promise<void> }\n   */\n  async storeUserData(\n    file: string,\n    data: any,\n    options?: RequestInit & { stringify?: boolean; throwOnError?: boolean },\n  ): Promise<void> {\n    const resp = await this.fetchApi(`/userdata/${encodeURIComponent(file)}`, {\n      method: \"POST\",\n      body: options?.stringify ? JSON.stringify(data) : data,\n      ...options,\n    });\n    if (resp.status !== 200) {\n      const error = await resp.text();\n      throw new ClientRequestError(\n        `Error storing user data file '${file}': ${resp.status} ${error}`,\n      );\n    }\n  }\n\n  // ----------------- experiment apis -----------------\n\n  /**\n   * Gets a list of model folder keys (eg ['checkpoints', 'loras', ...])\n   * @returns The list of model folder keys\n   */\n  async getModelFolders(): Promise<ModelFolderInfo[]> {\n    const res = await this.fetchApi(`/experiment/models`);\n    if (res.status === 404) {\n      return [];\n    }\n    const folderBlacklist = [\"configs\", \"custom_nodes\"];\n    return (await res.json()).filter(\n      (folder: ModelFolderInfo) => !folderBlacklist.includes(folder.name),\n    );\n  }\n\n  /**\n   * Gets a list of models in the specified folder\n   * @param {string} folder The folder to list models from, such as 'checkpoints'\n   * @returns The list of model filenames within the specified folder\n   */\n  async getModels(folder: string): Promise<ModelFile[]> {\n    const res = await this.fetchApi(`/experiment/models/${folder}`);\n    if (res.status === 404) {\n      return [];\n    }\n    return await res.json();\n  }\n\n  /**\n   * Gets the metadata for a model\n   * @param {string} folder The folder containing the model\n   * @param {string} model The model to get metadata for\n   * @returns The metadata for the model\n   */\n  async viewMetadata(folder: string, model: string) {\n    const res = await this.fetchApi(\n      `/view_metadata/${folder}?filename=${encodeURIComponent(model)}`,\n    );\n    const rawResponse = await res.text();\n    if (!rawResponse) {\n      return null;\n    }\n    try {\n      return JSON.parse(rawResponse);\n    } catch (error) {\n      console.error(\n        \"Error viewing metadata\",\n        res.status,\n        res.statusText,\n        rawResponse,\n        error,\n      );\n      return null;\n    }\n  }\n\n  // ----------------- get logs -----------------\n\n  async getLogs(): Promise<string> {\n    const resp = await this.fetchApi(this.internalURL(\"/logs\"));\n    // NOTE: this api will return a JSON string\n    return await resp.json();\n  }\n\n  async getRawLogs(): Promise<LogsRawResponse> {\n    const resp = await this.fetchApi(this.internalURL(\"/logs/raw\"));\n    return await resp.json();\n  }\n\n  // ----------------- get status ++ -----------------\n\n  /**\n   * Retrieves the list of samplers from the node definitions.\n   *\n   * @return {Promise<string[]>} A promise that resolves to an array of strings representing the sampler names.\n   */\n  async getSamplers() {\n    const node_config = await this.getNodeDefs();\n    // find KSampler node\n    const node = node_config[\"KSampler\"];\n    const sampler_name = node?.input?.required?.[\"sampler_name\"]?.[0] || [];\n    return sampler_name as string[];\n  }\n\n  /**\n   * Retrieves the list of schedulers from the node definitions.\n   *\n   * @return {Promise<string[]>} A promise that resolves to an array of strings representing the scheduler names.\n   */\n  async getSchedulers() {\n    const node_config = await this.getNodeDefs();\n    // find Scheduler node\n    const node = node_config[\"KSampler\"];\n    const scheduler_name = node?.input?.required?.[\"scheduler\"]?.[0] || [];\n    return scheduler_name as string[];\n  }\n\n  /**\n   * Retrieves the list of model names from the node definitions.\n   *\n   * @return {Promise<string[]>} A promise that resolves to an array of strings representing the model names.\n   */\n  async getSDModels() {\n    const node_config = await this.getNodeDefs();\n    // find CheckpointLoaderSimple node\n    const node = node_config[\"CheckpointLoaderSimple\"];\n    const model_name = node?.input?.required?.[\"ckpt_name\"]?.[0] || [];\n    return model_name as string[];\n  }\n\n  /**\n   * Retrieves the list of model names from the node definitions.\n   *\n   * @return {Promise<string[]>} A promise that resolves to an array of strings representing the model names.\n   */\n  async getCNetModels() {\n    const node_config = await this.getNodeDefs();\n    // find ControlNetLoader node\n    const node = node_config[\"ControlNetLoader\"];\n    const model_name = node?.input?.required?.[\"control_net_name\"]?.[0] || [];\n    return model_name as string[];\n  }\n\n  /**\n   * Retrieves the list of model names from the node definitions for the UpscaleModelLoader node.\n   *\n   * @return {Promise<string[]>} A promise that resolves to an array of strings representing the model names.\n   */\n  async getUpscaleModels() {\n    const node_config = await this.getNodeDefs();\n    // find UpscaleModelLoader node\n    const node = node_config[\"UpscaleModelLoader\"];\n    const model_name = node?.input?.required?.[\"model_name\"]?.[0] || [];\n    return model_name as string[];\n  }\n\n  /**\n   * Retrieves the list of hypernetwork names from the node definitions.\n   *\n   * @return {Promise<string[]>} A promise that resolves to an array of strings representing the hypernetwork names.\n   */\n  async getHyperNetworks() {\n    const node_config = await this.getNodeDefs();\n    // find HypernetworkLoader node\n    const node = node_config[\"HypernetworkLoader\"];\n    const model_name = node?.input?.required?.[\"hypernetwork_name\"]?.[0] || [];\n    return model_name as string[];\n  }\n\n  /**\n   * Retrieves the list of LoRAs from the node definitions.\n   *\n   * @return {Promise<string[]>} A promise that resolves to an array of strings representing the LoRAs.\n   */\n  async getLoRAs() {\n    const node_config = await this.getNodeDefs();\n    // find LoraLoader node\n    const node = node_config[\"LoraLoader\"];\n    const model_name = node?.input?.required?.[\"lora_name\"]?.[0] || [];\n    return model_name as string[];\n  }\n\n  /**\n   * Retrieves the list of VAE names from the node definitions.\n   *\n   * @return {Promise<string[]>} A promise that resolves to an array of strings representing the VAE names.\n   */\n  async getVAEs() {\n    const node_config = await this.getNodeDefs();\n    // find VAELoader node\n    const node = node_config[\"VAELoader\"];\n    const model_name = node?.input?.required?.[\"vae_name\"]?.[0] || [];\n    return model_name as string[];\n  }\n\n  // ----------------- Prompt ++ -----------------\n\n  /**\n   * Retrieves the status of a prompt based on the provided prompt ID.\n   *\n   * @param {string} prompt_id - The ID of the prompt to check status for.\n   * @return {Object} Object containing the running, pending, and done status of the prompt.\n   */\n  async getPromptStatus(prompt_id: string) {\n    const { Running, Pending } = await this.getQueue();\n    const getId = (task: any) => {\n      if (!task) return null;\n      // old version\n      if (\"prompt\" in task) return task.prompt?.[1];\n      // v4 v5\n      if (Array.isArray(task)) return task[1];\n      throw new TaskDataTypeError(task);\n    };\n    const running = Running.some((task) => getId(task) === prompt_id);\n    const pending = Pending.some((task) => getId(task) === prompt_id);\n    const done = !running && !pending;\n    return {\n      running,\n      pending,\n      done,\n    };\n  }\n\n  /**\n   * Retrieves the outputs of a prompt with the given ID from the history.\n   *\n   * @param {string} prompt_id - The ID of the prompt to retrieve the outputs for.\n   * @return {Promise<Record<string, any>>} A promise that resolves to the outputs of the prompt.\n   * @throws {Error} If the prompt with the given ID is not found in the history or if it failed with a non-\"success\" status.\n   */\n  async getPromptOutputs(prompt_id: string) {\n    const { History: history } = await this.getHistory();\n    const item = history.find((item) => item.prompt[1] === prompt_id);\n    if (!item) throw new PromptNotFoundError(prompt_id);\n\n    const status = item.status?.status_str ?? \"error\";\n    if (status === \"error\")\n      throw new PromptExecutionFailedError(prompt_id, status ?? \"error\");\n\n    return item.outputs;\n  }\n\n  /**\n   * Retrieves the result of a prompt with the given ID, resolved using the provided resolver.\n   *\n   * @param {string} prompt_id - The ID of the prompt to retrieve the result for.\n   * @param {WorkflowOutputResolver<T>} resolver - The resolver to use when resolving the prompt result.\n   * @return {Promise<WorkflowOutput<T>>} A promise that resolves to the result of the prompt.\n   */\n  async getPromptResult<T>(\n    prompt_id: string,\n    resolver: WorkflowOutputResolver<T>,\n  ): Promise<WorkflowOutput<T>>;\n  async getPromptResult(prompt_id: string): Promise<WorkflowOutput>;\n  async getPromptResult(\n    prompt_id: string,\n    resolver?: any,\n  ): Promise<WorkflowOutput> {\n    const outputs = await this.getPromptOutputs(prompt_id);\n    if (typeof resolver !== \"function\") {\n      resolver = RESOLVERS.image;\n    }\n    return Object.entries(outputs).reduce(\n      (acc, [node_id, output]) =>\n        resolver(acc, output, {\n          client: this,\n          prompt_id,\n          node_id,\n        }),\n      {\n        images: [],\n        prompt_id,\n        data: null,\n      } as WorkflowOutput,\n    );\n  }\n\n  /**\n   * Asynchronously waits for the prompt with the provided ID to be done.\n   *\n   * @param {string} prompt_id - The ID of the prompt to wait for.\n   * @param {number} [polling_ms=1000] - The number of milliseconds to wait between checks.\n   * @param {number} [timeout_ms=5 * 60 * 1000] - The maximum number of milliseconds to wait. defaults to 5 minutes. must be greater than 1000ms.\n   * @return {void}\n   */\n  async waitForPrompt(\n    prompt_id: string,\n    polling_ms = 1000,\n    timeout_ms = 5 * 60 * 1000,\n  ) {\n    const start = Date.now();\n    let prompt_status = await this.getPromptStatus(prompt_id);\n    while (!prompt_status.done) {\n      if (timeout_ms >= 0) {\n        if (Date.now() - start > timeout_ms) {\n          throw new PromptTimeoutError(prompt_id, timeout_ms);\n        }\n      }\n\n      await new Promise((resolve) => setTimeout(resolve, polling_ms));\n      prompt_status = await this.getPromptStatus(prompt_id);\n    }\n  }\n\n  /**\n   * Asynchronously waits for the prompt with the provided ID to be done,\n   * using a WebSocket connection to receive updates.\n   *\n   * @param {string} prompt_id - The ID of the prompt to wait for.\n   * @param {WorkflowOutputResolver<T>} resolver - A function to resolve the output of the prompt.\n   * @param {number} [timeout_ms=5 * 60 * 1000] - The maximum number of milliseconds to wait. defaults to 5 minutes. must be greater than 1000ms.\n   * @return {Promise<WorkflowOutput<T>>} A promise that resolves with the output of the prompt.\n   */\n  async waitForPromptWebSocket<T>(\n    prompt_id: string,\n    resolver: WorkflowOutputResolver<T>,\n    timeout_ms = 5 * 60 * 1000,\n  ) {\n    const output: WorkflowOutput<T> = {\n      images: [],\n      prompt_id,\n      data: null as T,\n    };\n    const disposable = new Disposable();\n    return new Promise<WorkflowOutput<T>>((resolve, reject) => {\n      let is_current_ws_executing = false;\n      disposable._connect(\n        this.on(\"executing\", (data) => {\n          is_current_ws_executing = data?.prompt_id === prompt_id;\n        }),\n      );\n      disposable._connect(\n        this.on(\"image_data\", (data) => {\n          if (!is_current_ws_executing) return;\n          output.images.push({\n            type: \"buff\",\n            data: data.image,\n            mime: data.mime,\n          });\n        }),\n      );\n      disposable._connect(\n        this.on(\"executed\", (data) => {\n          const {\n            prompt_id: current_prompt_id,\n            output: executed_output,\n            node: node_id,\n          } = data;\n          if (current_prompt_id !== prompt_id) {\n            return;\n          }\n          const resolved = resolver(output, executed_output, {\n            client: this,\n            prompt_id,\n            node_id,\n          });\n          resolve(resolved);\n        }),\n      );\n      disposable._connect(\n        this.on(\"execution_error\", (data) => {\n          reject(new WorkflowExecutionError(data, prompt_id));\n        }),\n      );\n      const timer = setTimeout(() => {\n        reject(new PromptTimeoutError(prompt_id, timeout_ms));\n      }, timeout_ms);\n      disposable._connect(() => clearTimeout(timer));\n    }).finally(() => {\n      disposable.dispose();\n    });\n  }\n\n  /**\n   * Asynchronously enqueues a prompt with optional workflow and random seed.\n   *\n   * @param {Record<string, unknown>} prompt - The prompt to enqueue.\n   * @param {Object} [options] - The options for enqueueing the prompt.\n   * @param {Record<string, unknown>} [options.workflow] - The workflow for the prompt.\n   * @return {Promise<ComfyUIClientResponseTypes.QueuePromptSuccess>} A promise that resolves with the enqueued prompt response.\n   * @throws {Error} If there is an error in the response.\n   */\n  async _enqueue_prompt(\n    prompt: Record<string, unknown>,\n    options?: {\n      workflow?: Record<string, unknown>;\n    },\n  ) {\n    const resp = await this.queuePrompt(0, {\n      prompt,\n      workflow: options?.workflow,\n    });\n    if (\"error\" in resp) throw new PromptEnqueueError(resp);\n    return resp;\n  }\n\n  /**\n   * Asynchronously runs a prompt with the provided options.\n   *\n   * This function does not use WebSocket, but uses polling to get the result\n   * So if your workflow contains custom ws events, this function will not be able to get these events\n   *\n   * @param {Record<string, unknown>} prompt - The prompt to run.\n   * @param {Object} options - The options for running the prompt.\n   * @param {Record<string, unknown>} options.workflow - The workflow for the prompt, It will be added to the png info of the generated image.\n   * @param {number} [options.polling_ms=1000] - The number of milliseconds to polling query prompt result.\n   * @param {number} [options.timeout_ms=5 * 60 * 1000] - The number of milliseconds to wait for the prompt result. must be greater than 1000.\n   * @return {Promise<WorkflowOutput>} A promise that resolves with the prompt result.\n   *\n   * @deprecated Use `enqueue_polling` instead\n   */\n  async runPrompt(\n    prompt: Record<string, unknown>,\n    options?: {\n      workflow?: Record<string, unknown>;\n      polling_ms?: number;\n      timeout_ms?: number;\n    },\n  ) {\n    const resp = await this._enqueue_prompt(prompt, options);\n    const prompt_id = resp.prompt_id;\n    await this.waitForPrompt(\n      prompt_id,\n      options?.polling_ms,\n      options?.timeout_ms,\n    );\n    return await this.getPromptResult(prompt_id, RESOLVERS.image);\n  }\n\n  /**\n   * Asynchronously enqueues a prompt and waits for the corresponding prompt websocket.\n   *\n   * This function does not use WebSocket, but uses polling to get the result\n   * So if your workflow contains custom ws events, this function will not be able to get these events\n   *\n   * @param {Record<string, unknown>} prompt - The prompt to enqueue.\n   * @param {EnqueueOptions<T>} [options] - The options for enqueueing the prompt.\n   * @return {Promise<WorkflowOutput<T>>} A promise that resolves with the prompt result.\n   */\n  async enqueue_polling<T>(\n    prompt: Record<string, unknown>,\n    options?: EnqueueOptions<T>,\n  ): Promise<WorkflowOutput<T>>;\n  async enqueue_polling(\n    prompt: Record<string, unknown>,\n    options?: EnqueueOptions,\n  ): Promise<WorkflowOutput>;\n  async enqueue_polling(\n    prompt: Record<string, unknown>,\n    options?: any,\n  ): Promise<WorkflowOutput> {\n    if (typeof options?.progress === \"function\") {\n      throw new ClientEnqueueError(\n        \"progress option is not supported in polling mode\",\n      );\n    }\n\n    const resp = await this._enqueue_prompt(prompt, options);\n    const prompt_id = resp.prompt_id;\n    await this.waitForPrompt(\n      prompt_id,\n      options?.polling_ms,\n      options?.timeout_ms,\n    );\n    return await this.getPromptResult(\n      prompt_id,\n      options?.resolver ?? RESOLVERS.image,\n    );\n  }\n\n  /**\n   * Enqueues a prompt and waits for the corresponding prompt websocket.\n   *\n   * @param {Record<string, unknown>} prompt - The prompt to enqueue.\n   * @param {EnqueueOptions<T>} [options] - The options for enqueueing the prompt.\n   * @return {Promise<WorkflowOutput>} A promise that resolves with the prompt result.\n   */\n  async enqueue<T>(\n    prompt: Record<string, unknown>,\n    options?: EnqueueOptions<T>,\n  ): Promise<WorkflowOutput<T>>;\n  async enqueue(\n    prompt: Record<string, unknown>,\n    options?: EnqueueOptions,\n  ): Promise<WorkflowOutput>;\n  async enqueue(prompt: Record<string, unknown>, options?: any) {\n    const resp = await this._enqueue_prompt(prompt, options);\n    const prompt_id = resp.prompt_id;\n\n    const off_progress = this.on_progress(options?.progress, prompt_id);\n    try {\n      return await this.waitForPromptWebSocket(\n        prompt_id,\n        options?.resolver ?? RESOLVERS.image,\n        options?.timeout_ms,\n      );\n    } finally {\n      off_progress();\n    }\n  }\n\n  /**\n   * Listens for progress updates for a specific task.\n   *\n   * @param {EnqueueOptions[\"progress\"]} fn - The progress callback function.\n   * @param {string} task_id - The ID of the task to listen for progress updates.\n   * @return {Function} A function that can be used to remove the progress listener.\n   */\n  on_progress(fn: EnqueueOptions[\"progress\"], task_id: string) {\n    if (!fn) return () => {};\n    return this.on(\"progress\", (_data) => {\n      const data = {\n        // old api response type:\n        ...(\"progress\" in _data ? { ...(_data as any).progress } : {}),\n        // new api: https://github.com/StableCanvas/comfyui-client/issues/6\n        ..._data,\n      };\n      if (data.prompt_id === task_id) {\n        fn(data);\n      }\n    });\n  }\n}\n","import { Client } from \"../client/Client\";\nimport { WorkflowOutputResolver } from \"../client/types\";\nimport type { WorkflowOutput, IWorkflow } from \"./types\";\nimport { RESOLVERS } from \"../builtins\";\nimport { ComfyUIClientEvents, ComfyUiWsTypes } from \"../client/ws.types\";\nimport EventEmitter from \"eventemitter3\";\nimport { Disposable } from \"../utils/Disposable\";\nimport {\n  WorkflowArgumentError,\n  WorkflowDoneError,\n  WorkflowEnqueuedError,\n  WorkflowExecutionError,\n  WorkflowInterruptedError,\n  WorkflowTaskIdError,\n  WorkflowTaskStatusError,\n  WorkflowWsError,\n} from \"./errors\";\nimport { debounce } from \"../utils/misc\";\nimport { ConnectError } from \"../client/errors\";\n\nexport class InvokedWorkflow<T = unknown> extends Disposable {\n  protected _task_id?: string;\n\n  protected _result: WorkflowOutput<T> = {\n    images: [],\n    prompt_id: \"\",\n  };\n\n  is_done = false;\n  enqueued = false;\n\n  workflow: IWorkflow;\n  client: Client;\n  resolver: WorkflowOutputResolver<T>;\n\n  /**\n   * 因为 comfyui 的 websocket events 顺序混乱，在 execution_success 立马结束也可能导致事件丢失\n   *\n   * Because the order of comfyui's websocket events is chaotic, the execution_success event may end immediately, causing events to be lost\n   */\n  delay_done_ms = 500;\n\n  /**\n   *  The current task is being executed via WebSocket; this flag is used to determine whether the current `image_data` originates from this task.\n   */\n  is_current_ws_executing = false;\n\n  constructor(\n    readonly options: {\n      workflow: IWorkflow;\n      client: Client;\n      resolver?: WorkflowOutputResolver<T>;\n      progress?: (p: ComfyUiWsTypes.Messages.Progress) => void;\n      on_error?: (e: Error) => void;\n    },\n  ) {\n    super();\n    const { workflow, client, resolver } = options;\n    this.workflow = workflow;\n    this.client = client;\n    this.resolver = resolver || (RESOLVERS.image as any);\n  }\n\n  public get is_disposed() {\n    return this._disposed;\n  }\n\n  public get task_id() {\n    return this._task_id;\n  }\n\n  protected _enqueue_guard() {\n    if (this.enqueued) throw new WorkflowEnqueuedError(this);\n    this.enqueued = true;\n  }\n\n  protected _task_id_guard() {\n    if (!this._task_id) throw new WorkflowTaskIdError(this);\n    return this._task_id;\n  }\n\n  protected _done_guard() {\n    if (this._disposed || this.is_done) throw new WorkflowDoneError(this);\n  }\n\n  protected _ws_guard() {\n    if (this.client.closed)\n      throw new ConnectError(\n        \"The WebSocket connection has been closed. Please ensure that the client is connected.\",\n      );\n    if (this.client.socket === null) throw new WorkflowWsError(this);\n  }\n\n  protected is_owner_event(...args: any[]) {\n    const [data] = (args as any[]) || [];\n    const { _task_id: task_id } = this;\n    if (!task_id) return false;\n    if (typeof data !== \"object\" || data === null) return false;\n    if (!(\"prompt_id\" in data) || data.prompt_id !== task_id) return false;\n    return true;\n  }\n\n  /**\n   * Adds an event listener for the specified event type.\n   */\n  on<T extends EventEmitter.EventNames<ComfyUIClientEvents>>(\n    type: T,\n    callback: EventEmitter.EventListener<ComfyUIClientEvents, T>,\n    options?: any,\n  ) {\n    this._done_guard();\n    const { client } = this;\n    const off = client.on(type, (...args) => {\n      if (type === \"image_data\" || type === \"b_preview\") {\n        if (!this.is_current_ws_executing) return;\n      } else if (!this.is_owner_event(...args)) return;\n      callback(...args);\n    });\n    this._connect(off);\n    return off;\n  }\n\n  /**\n   * Adds an once event listener for the specified event type.\n   */\n  once<T extends EventEmitter.EventNames<ComfyUIClientEvents>>(\n    type: T,\n    callback: EventEmitter.EventListener<ComfyUIClientEvents, T>,\n    options?: any,\n  ) {\n    this._done_guard();\n    const { client } = this;\n    const off = client.on(type, (...args) => {\n      if (type === \"image_data\" || type === \"b_preview\") {\n        if (!this.is_current_ws_executing) return;\n      } else if (!this.is_owner_event(...args)) return;\n      callback(...args);\n      off();\n    });\n    this._connect(off);\n    return off;\n  }\n\n  /**\n   * Initiates the workflow by enqueuing the prompt and setting up the task ID.\n   *\n   * @return {void}\n   */\n  public async enqueue() {\n    this._enqueue_guard();\n\n    const { client, workflow } = this;\n    const { prompt, workflow: wf } = workflow;\n\n    const { prompt_id } = await client._enqueue_prompt(prompt, {\n      workflow: wf,\n    });\n    this._task_id = prompt_id;\n\n    this.hook_progress();\n    this.hook_image_data();\n    this.hook_executing();\n  }\n\n  protected async hook_progress() {\n    const { progress } = this.options;\n    const { _task_id: _task_id } = this;\n    if (!progress) return;\n    if (typeof progress !== \"function\") {\n      throw new WorkflowArgumentError(\n        this,\n        \"options.progress hook must be a function\",\n      );\n    }\n    if (typeof _task_id !== \"string\") throw new WorkflowTaskIdError(this);\n    const off_progress = this.client.on_progress(progress, _task_id);\n    this._connect(off_progress);\n  }\n\n  protected async hook_executing() {\n    const { client } = this;\n    const task_id = this._task_id_guard();\n    this._connect(\n      client.on(\"executing\", (data) => {\n        this.is_current_ws_executing = data?.prompt_id === task_id;\n      }),\n    );\n  }\n\n  protected async hook_image_data() {\n    const { client } = this;\n    this._connect(\n      client.on(\"image_data\", (data) => {\n        if (this.is_current_ws_executing === false) return;\n\n        this._result.images.push({\n          type: \"buff\",\n          data: data.image,\n          mime: data.mime,\n        });\n      }),\n    );\n  }\n\n  protected resolve_to_result(data: ComfyUiWsTypes.Messages.Executed) {\n    const { client, resolver } = this;\n    const { output, prompt_id, node } = data;\n\n    this._result = resolver(this._result, output, {\n      client,\n      prompt_id: prompt_id,\n      node_id: node,\n    });\n  }\n\n  /**\n   * Retrieves the execution status of the workflow.\n   *\n   * @return {Promise<status>} A promise that resolves with the execution status of the workflow.\n   */\n  public async query() {\n    const task_id = this._task_id_guard();\n    return this.client.getPromptStatus(task_id);\n  }\n\n  /**\n   * Interrupts the execution of the workflow if it is currently enqueued.\n   * Throws an error if the workflow is not enqueued or if the execution status cannot be interrupted.\n   *\n   * @return {Promise<void>} A promise that resolves when the interrupt is successful or rejects with an error.\n   * @throws {Error} If the workflow is not enqueued or if the execution status cannot be interrupted.\n   */\n  public async interrupt() {\n    const id = this._task_id_guard();\n    const { pending, running, done } = await this.query();\n    if (done) return;\n    if (pending) {\n      this.client.deleteItem(\"queue\", id);\n      return;\n    }\n    if (running) {\n      return this.client.interrupt(id);\n    }\n    throw new WorkflowTaskStatusError(this);\n  }\n\n  protected async collect_result() {\n    const { client, resolver } = this;\n    const task_id = this._task_id_guard();\n    const result = await client.getPromptResult(\n      task_id,\n      resolver ?? RESOLVERS.image,\n    );\n    this._result.images = [...this._result.images, ...result.images];\n    this._result.data = this._result.data ?? result.data;\n    return this._result;\n  }\n\n  protected when_interrupted(\n    cb: (data: ComfyUiWsTypes.Messages.ExecutionInterrupted) => any,\n  ) {\n    const task_id = this._task_id_guard();\n    this._connect(\n      this.client.on(\"execution_interrupted\", (data) => {\n        if (data.prompt_id === task_id) {\n          cb(data);\n        }\n      }),\n    );\n  }\n\n  protected when_execution_error(\n    cb: (data: ComfyUiWsTypes.Messages.ExecutionError) => any,\n  ) {\n    const task_id = this._task_id_guard();\n    this._connect(\n      this.client.on(\"execution_error\", (data) => {\n        if (data.prompt_id === task_id) {\n          cb(data);\n        }\n      }),\n    );\n  }\n\n  /**\n   * Listen for the start event of the workflow.\n   * @param {Function} cb - The callback function that will be called when the workflow starts.\n   * @return {Function} A function that can be used to remove the listener.\n   */\n  public on_start(cb: () => void) {\n    const task_id = this._task_id_guard();\n    return this._connect(\n      this.client.on(\"execution_start\", (data) => {\n        if (data.prompt_id === task_id) cb();\n      }),\n    );\n  }\n\n  /**\n   * Waits for the workflow to complete and returns the result.\n   *\n   * *This function does not rely on WebSocket Events, so it will lose events output by WebSocket node\n   *\n   * @param {Object} options - options for waiting\n   * @param {number} [options.polling_ms=1000] - polling interval in milliseconds\n   * @return {Promise} promise that resolves with the result of the workflow\n   */\n  public async wait_polling({ polling_ms }: { polling_ms?: number } = {}) {\n    this._done_guard();\n    const task_id = this._task_id_guard();\n\n    const { client } = this;\n    return new Promise<WorkflowOutput>(async (resolve, reject) => {\n      const done = () => {\n        this.is_done = true;\n        this.dispose();\n      };\n\n      // NOTE: 这里监听如果 client 没有开启 ws 是拿不到的，但是其实可以 client 开启 ws 同时这里仍然使用 polling 来同步状态，所以，这里也监听这个状态\n      this.when_interrupted((data) => {\n        reject(new WorkflowInterruptedError(this));\n        done();\n      });\n      this.when_execution_error((data) => {\n        reject(new WorkflowExecutionError(data, task_id, this.workflow, this));\n        done();\n      });\n\n      try {\n        await client.waitForPrompt(task_id, polling_ms ?? 1000);\n        const result = await this.collect_result();\n        resolve(result);\n      } catch (error) {\n        reject(error);\n      } finally {\n        done();\n      }\n    }).catch((err) => {\n      this.options.on_error?.(err);\n      return Promise.reject(err);\n    });\n  }\n\n  /**\n   * Waits for the workflow to complete and returns the result.\n   *\n   * @return {Promise<WorkflowOutput>} promise that resolves with the result of the workflow\n   */\n  public async wait() {\n    this._done_guard();\n    this._ws_guard();\n\n    const task_id = this._task_id_guard();\n\n    return new Promise<WorkflowOutput>((resolve, reject) => {\n      const done = () => {\n        this.is_done = true;\n        this.dispose();\n      };\n      const maybe_done = debounce(async () => {\n        // NOTE: Because we are performing a delayed query for \"done,\" it's possible that multiple checks will be initiated. Therefore, we need to determine here whether it has already been done. #23\n        if (this.is_done) return;\n        try {\n          const status = await this.query();\n          if (!status.done) {\n            return;\n          }\n          resolve(this._result);\n          done();\n        } catch (error) {\n          reject(error);\n          done();\n        }\n      }, this.delay_done_ms);\n      this.when_interrupted((data) => {\n        reject(new WorkflowInterruptedError(this));\n        done();\n      });\n      this.when_execution_error((data) => {\n        reject(new WorkflowExecutionError(data, task_id, this.workflow, this));\n        done();\n      });\n      // NOTE: The implication here is that if something else triggers the `dispose` method, then this should also guarantee that the promise is resolved.\n      this._connect(maybe_done);\n      this._connect(\n        this.client.on(\"executed\", async (data) => {\n          if (data.prompt_id !== task_id) return;\n          this.resolve_to_result(data);\n          maybe_done();\n        }),\n      );\n      this._connect(\n        this.client.on(\"execution_success\", async (data) => {\n          if (data.prompt_id !== task_id) return;\n          maybe_done();\n        }),\n      );\n    }).catch((err) => {\n      this.options.on_error?.(err);\n      return Promise.reject(err);\n    });\n  }\n}\n","import { Client } from \"../client/Client\";\nimport { InvokedWorkflow } from \"./InvokedWorkflow\";\nimport { WorkflowOutputResolver } from \"../client/types\";\nimport { ComfyUINodeTypes } from \"../schema/comfyui.node.types\";\nimport { WorkflowOutput, WorkflowPromptNode } from \"./types\";\nimport { IWorkflow } from \"./types\";\nimport { ComfyUiWsTypes } from \"../client/ws.types\";\n\nconst deepClone: <T>(obj: T) => T = globalThis.structuredClone\n  ? globalThis.structuredClone\n  : (x) => JSON.parse(JSON.stringify(x));\n\nexport type NodeOutput = [string, number];\n\nexport type NodeClassInputs = Record<\n  string,\n  string | boolean | number | null | undefined | NodeOutput\n>;\n\n// { k: { [k:string]: unknown } } => { k: any }\ntype InputsFormat<T> = {\n  [K in keyof T]: T[K] extends { [k: string]: unknown }\n    ? NodeOutput\n    : T[K] | NodeOutput;\n};\n\nexport interface ComfyUINodeClass<\n  INP extends NodeClassInputs = NodeClassInputs,\n> {\n  (inputs: INP): NodeOutput[];\n}\n\nexport type BuiltinNodeClasses = {\n  [K in keyof Required<ComfyUINodeTypes.NodeTypes>]: Required<\n    Required<ComfyUINodeTypes.NodeTypes>[K]\n  > extends {\n    inputs: infer INP;\n  }\n    ? ComfyUINodeClass<InputsFormat<INP> & NodeClassInputs>\n    : ComfyUINodeClass<NodeClassInputs>;\n};\n\nexport type InvokeOptions<T> = {\n  resolver?: WorkflowOutputResolver<T>;\n  progress?: (p: ComfyUiWsTypes.Messages.Progress) => void;\n  polling_ms?: number;\n};\n\n/**\n * A class for creating a workflow using a fluent API.\n *\n * @example\n * ```typescript\n  const workflow = new Workflow();\n  const {\n    KSampler,\n    CheckpointLoaderSimple,\n    EmptyLatentImage,\n    CLIPTextEncode,\n    VAEDecode,\n    SaveImage,\n    NODE1,\n  } = workflow.classes;\n\n  const seed = Math.floor(Math.random() * 2 ** 32);\n  const pos = \"best quality, 1girl\";\n  const neg = \"worst quality, bad anatomy, embedding:NG_DeepNegative_V1_75T\";\n  const model1_name = \"lofi_v5.baked.fp16.safetensors\";\n  const model2_name = \"case-h-beta.baked.fp16.safetensors\";\n  const sampler_settings = {\n    seed,\n    steps: 35,\n    cfg: 4,\n    sampler_name: \"dpmpp_2m_sde_gpu\",\n    scheduler: \"karras\",\n    denoise: 1,\n  };\n\n  const [model1, clip1, vae1] = CheckpointLoaderSimple({\n    ckpt_name: model1_name,\n  });\n  const [model2, clip2, vae2] = CheckpointLoaderSimple({\n    ckpt_name: model2_name,\n  });\n\n  const dress_case = [\n    \"white yoga\",\n    \"black office\",\n    \"pink sportswear\",\n    \"cosplay\",\n  ];\n\n  const generate_pipeline = (model, clip, vae, pos, neg) => {\n    const [latent_image] = EmptyLatentImage({\n      width: 640,\n      height: 960,\n      batch_size: 1,\n    });\n    const [positive] = CLIPTextEncode({ text: pos, clip });\n    const [negative] = CLIPTextEncode({ text: neg, clip });\n    const [samples] = KSampler({\n      ...sampler_settings,\n      model,\n      positive,\n      negative,\n      latent_image,\n    });\n    const [image] = VAEDecode({ samples, vae });\n    return image;\n  };\n\n  for (const cloth of dress_case) {\n    const input_pos = `${pos}, ${cloth} dress`;\n    const image = generate_pipeline(model1, clip1, vae1, input_pos, neg);\n    SaveImage({\n      images: image,\n      filename_prefix: `${cloth}-lofi-v5`,\n    });\n\n    const input_pos2 = `${pos}, ${cloth} dress`;\n    const image2 = generate_pipeline(model2, clip2, vae2, input_pos2, neg);\n    SaveImage({\n      images: image2,\n      filename_prefix: `${cloth}-case-h-beta`,\n    });\n  }\n\n  return workflow;\n * ```\n */\nexport class Workflow {\n  protected _workflow: IWorkflow = {\n    prompt: {},\n  };\n  protected _last_node_id = 0;\n\n  public classes = this._createClassesProxy() as BuiltinNodeClasses &\n    Record<string, ComfyUINodeClass>;\n\n  protected _createClassesProxy() {\n    const source = {};\n    return new Proxy(source, {\n      get: (target, p, receiver) => {\n        if (p in target) {\n          return (target as any)[p];\n        }\n        return (inputs: Record<string, any>) => {\n          return this.node(p as any, inputs);\n        };\n      },\n    });\n  }\n\n  public node<\n    T extends keyof ComfyUINodeTypes.NodeTypes | (string & {}),\n    C extends T extends keyof ComfyUINodeTypes.NodeTypes\n      ? Required<Required<ComfyUINodeTypes.NodeTypes>[T]>\n      : unknown,\n  >(\n    node_name: T,\n    inputs: C extends { inputs: infer INP } ? INP : Record<string, unknown>,\n  ): Iterable<NodeOutput>;\n  public node(\n    node_name: string,\n    inputs: Record<string, unknown>,\n  ): Iterable<NodeOutput> {\n    const node: WorkflowPromptNode = {\n      class_type: node_name,\n      inputs,\n    } as any;\n    const id = (++this._last_node_id).toString();\n    this._workflow.prompt[id] = node;\n\n    function* outputs() {\n      let i = 0;\n      while (true) {\n        yield [id, i++] as NodeOutput;\n      }\n    }\n\n    const gen = outputs() as any;\n\n    for (let index = 0; index < 24; index++) {\n      gen[index] = [id, index] as NodeOutput;\n    }\n\n    return gen;\n  }\n\n  /**\n   * Resets the workflow by clearing the prompt and setting the workflow to undefined.\n   */\n  public reset() {\n    this._workflow.prompt = {};\n    this._workflow.workflow = undefined;\n    this._last_node_id = 0;\n  }\n\n  /**\n   * Returns the current workflow object.\n   *\n   * @return {IWorkflow} The current workflow object.\n   *\n   * @deprecated use `workflow` instead\n   */\n  public end() {\n    return this.workflow();\n  }\n\n  /**\n   * Returns the current workflow object.\n   *\n   * @return {IWorkflow} The current workflow object.\n   */\n  public workflow() {\n    return deepClone(this._workflow);\n  }\n\n  /**\n   * Guard function to check if the client's WebSocket is connected before attempting to invoke the workflow.\n   *\n   * @throws {Error} If the WebSocket is not connected.\n   *\n   * @param {Client} client - The client to check.\n   *\n   * @private\n   */\n  protected _ws_connected_guard(client: Client) {\n    if (!client.socket || client.socket.readyState !== client.WebSocket.OPEN) {\n      const current_state = {\n        [client.WebSocket.CLOSED]: \"CLOSED\",\n        [client.WebSocket.CONNECTING]: \"CONNECTING\",\n        [client.WebSocket.OPEN]: \"OPEN\",\n        [client.WebSocket.CLOSING]: \"CLOSING\",\n        [-1]: \"UNKNOWN\",\n      }[client.socket?.readyState ?? -1];\n      throw new Error(\n        `WebSocket is not connected, cannot invoke workflow. readyState=${current_state}`,\n      );\n    }\n  }\n\n  /**\n   * Invokes the workflow with the provided client and options.\n   *\n   * @param {Client} client - The client to use for the invocation.\n   * @param {InvokeOptions<T>} [options] - Optional invoke options.\n   * @return {Promise<WorkflowOutput<T>>} A promise resolving to the workflow output.\n   */\n  public invoke<T>(\n    client: Client,\n    options?: InvokeOptions<T>,\n  ): Promise<WorkflowOutput<T>>;\n  public invoke(\n    client: Client,\n    options?: InvokeOptions<unknown>,\n  ): Promise<WorkflowOutput<unknown>>;\n  public async invoke(\n    client: Client,\n    options?: InvokeOptions<unknown>,\n  ): Promise<WorkflowOutput<unknown>> {\n    this._ws_connected_guard(client);\n    const invoked = this.instance(client, options);\n    await invoked.enqueue();\n    const result = invoked.wait();\n    return result;\n  }\n\n  /**\n   * Creates a new invoked workflow instance.\n   *\n   * @param {Client} client - The client used to run the prompt.\n   * @param {InvokeOptions<T>} [options] - Optional invoke options.\n   * @return {InvokedWorkflow<T>} The invoked workflow instance.\n   */\n  public instance<T>(\n    client: Client,\n    options?: InvokeOptions<T>,\n  ): InvokedWorkflow<T>;\n  public instance(\n    client: Client,\n    options?: InvokeOptions<unknown>,\n  ): InvokedWorkflow;\n  public instance(\n    client: Client,\n    options?: InvokeOptions<unknown>,\n  ): InvokedWorkflow {\n    const workflow = this.workflow();\n    const invoked = new InvokedWorkflow({\n      workflow,\n      client,\n      resolver: options?.resolver,\n      progress: options?.progress,\n    });\n    return invoked;\n  }\n\n  /**\n   * Invokes a workflow using the provided client with polling.\n   *\n   * @param {Client} client - The client used to run the prompt.\n   * @param {InvokeOptions<T>} [options] - The options for invoking the workflow.\n   * @return {Promise<WorkflowOutput<T>>} A promise that resolves with the result of the prompt.\n   */\n  public invoke_polling<T>(\n    client: Client,\n    options?: InvokeOptions<T>,\n  ): Promise<WorkflowOutput<T>>;\n  public invoke_polling(\n    client: Client,\n    options?: InvokeOptions<unknown>,\n  ): Promise<WorkflowOutput>;\n  public invoke_polling(client: Client, options?: InvokeOptions<unknown>) {\n    if (typeof options?.progress === \"function\") {\n      throw new Error(\"progress option is not supported in polling mode\");\n    }\n    const { prompt, workflow } = this.workflow();\n    return client.enqueue_polling(prompt, {\n      workflow,\n      resolver: options?.resolver,\n      polling_ms: options?.polling_ms,\n    });\n  }\n}\n","import { Client } from \"../client/Client\";\n\ntype FnHook<\n  N extends keyof Client = keyof Client,\n  Fn extends Client[N] = Client[N],\n> = Fn extends (...args: any) => any\n  ? {\n      type: \"function\";\n      name: N;\n      fn: (original: Fn, ...args: Parameters<Fn>) => ReturnType<Fn>;\n    }\n  : never;\n\ntype PluginHook<\n  N extends keyof Client = keyof Client,\n  Fn extends Client[N] = Client[N],\n> = FnHook<N, Fn>;\n\nexport class Plugin {\n  private hooks = [] as PluginHook[];\n\n  public install(instance: Client) {\n    for (const hook of this.hooks) {\n      const ins = instance as any;\n      const original = ins[hook.name].bind(instance);\n      ins[hook.name] = (...args: Parameters<typeof original>) => {\n        return (hook.fn as any).bind(instance)(original, ...args);\n      };\n    }\n  }\n\n  protected addHook<\n    N extends keyof Client = keyof Client,\n    Fn extends Client[N] = Client[N],\n  >(hook: PluginHook<N, Fn>) {\n    this.hooks.push(hook);\n  }\n}\n","import { Client } from \"../client/Client\";\n\nexport namespace NSPipeline {\n  export const samplers = [\n    \"euler\",\n    \"euler_cfg_pp\",\n    \"euler_ancestral\",\n    \"euler_ancestral_cfg_pp\",\n    \"heun\",\n    \"heunpp2\",\n    \"exp_heun_2_x0\",\n    \"exp_heun_2_x0_sde\",\n    \"dpm_2\",\n    \"dpm_2_ancestral\",\n    \"lms\",\n    \"dpm_fast\",\n    \"dpm_adaptive\",\n    \"dpmpp_2s_ancestral\",\n    \"dpmpp_2s_ancestral_cfg_pp\",\n    \"dpmpp_sde\",\n    \"dpmpp_sde_gpu\",\n    \"dpmpp_2m\",\n    \"dpmpp_2m_cfg_pp\",\n    \"dpmpp_2m_sde\",\n    \"dpmpp_2m_sde_gpu\",\n    \"dpmpp_2m_sde_heun\",\n    \"dpmpp_2m_sde_heun_gpu\",\n    \"dpmpp_3m_sde\",\n    \"dpmpp_3m_sde_gpu\",\n    \"ddpm\",\n    \"lcm\",\n    \"ipndm\",\n    \"ipndm_v\",\n    \"deis\",\n    \"res_multistep\",\n    \"res_multistep_cfg_pp\",\n    \"res_multistep_ancestral\",\n    \"res_multistep_ancestral_cfg_pp\",\n    \"gradient_estimation\",\n    \"gradient_estimation_cfg_pp\",\n    \"er_sde\",\n    \"seeds_2\",\n    \"seeds_3\",\n    \"sa_solver\",\n    \"sa_solver_pece\",\n    \"ddim\",\n    \"uni_pc\",\n    \"uni_pc_bh2\",\n  ] as const;\n  export const schedulers = [\n    \"simple\",\n    \"sgm_uniform\",\n    \"karras\",\n    \"exponential\",\n    \"ddim_uniform\",\n    \"beta\",\n    \"normal\",\n    \"linear_quadratic\",\n    \"kl_optimal\",\n  ] as const;\n\n  export type PipeContext = {\n    seed: number;\n    steps: number;\n    cfg: number;\n    sampler_name: (typeof samplers)[number] | ({} & string);\n    scheduler: (typeof schedulers)[number] | ({} & string);\n    denoise: number;\n    width: number;\n    height: number;\n    batch_size: number;\n    ckpt_name: string;\n    positive: string;\n    negative: string;\n\n    /**\n     * NOTE: dependence custom node: `ETN_LoadImageBase64` and `ETN_LoadMaskBase64`\n     */\n    input_image: Buffer | null;\n    input_mask: Buffer | null;\n    grow_mask_by: number;\n\n    client: Client | null;\n  };\n}\n","import { Plugin } from \"./Plugin\";\n\n/**\n * Provide api-auth support for this https://github.com/liusida/ComfyUI-Login/tree/main extension\n */\nexport class LoginAuthPlugin extends Plugin {\n  constructor(\n    readonly options: {\n      token: string;\n    },\n  ) {\n    super();\n\n    this.addHook({\n      type: \"function\",\n      name: \"apiURL\",\n      fn: (original, ...args) => {\n        const url = original(...args);\n        const urlObj = new URL(url);\n        urlObj.searchParams.set(\"token\", this.options.token);\n        return urlObj.toString();\n      },\n    });\n\n    this.addHook({\n      type: \"function\",\n      name: \"wsURL\",\n      fn: (original, ...args) => {\n        const url = original(...args);\n        const urlObj = new URL(url);\n        urlObj.searchParams.set(\"token\", this.options.token);\n        return urlObj.toString();\n      },\n    });\n  }\n}\n","import EventEmitter from \"eventemitter3\";\nimport { Client } from \"../client/Client\";\nimport { Workflow } from \"../workflow/Workflow\";\nimport { WorkflowOutput } from \"../workflow/types\";\nimport { NSPipeline } from \"./types\";\nimport { ComfyUIClientEvents } from \"../client/ws.types\";\nimport { Disposable } from \"../utils/Disposable\";\nimport { InvokedWorkflow } from \"../workflow/InvokedWorkflow\";\n\ntype PipeContext = NSPipeline.PipeContext;\n\n/**\n * pipe to create a workflow\n */\nexport class BasePipe<\n  CTX extends PipeContext = PipeContext,\n> extends Disposable {\n  /**\n   * Generates a random seed value.\n   *\n   * @return {number} A random integer seed value between 0 and MAX_SAFE_INTEGER.\n   */\n  static nextSeed() {\n    return Math.floor(Math.random() * Number.MAX_SAFE_INTEGER);\n  }\n  static defaultContext: PipeContext = {\n    seed: BasePipe.nextSeed(),\n    steps: 35,\n    cfg: 4,\n    sampler_name: \"dpmpp_2m_sde_gpu\",\n    scheduler: \"karras\",\n    denoise: 1,\n    width: 512,\n    height: 512,\n    batch_size: 1,\n    ckpt_name: \"\",\n\n    input_image: null,\n    input_mask: null,\n    grow_mask_by: 6,\n\n    positive: \"\",\n    negative: \"\",\n\n    client: null,\n  };\n  protected context: CTX;\n  protected _workflow = new Workflow();\n  protected _invoked?: Promise<InvokedWorkflow>;\n\n  constructor(context?: Partial<CTX>) {\n    super();\n    this.context = {\n      ...BasePipe.defaultContext,\n      ...context,\n    } as CTX;\n  }\n\n  protected update(ctx: Record<string, any>) {\n    Object.assign(this.context, ctx);\n  }\n\n  /**\n   * Updates the context with the provided image buffer.\n   *\n   * @param {Buffer} image - The image buffer to update the context with.\n   * @return {this} The current instance of the class for method chaining.\n   */\n  image(image: Buffer) {\n    this.update({\n      input_image: image,\n    });\n    return this;\n  }\n\n  /**\n   * Updates the context with the provided mask buffer.\n   *\n   * @param {Buffer} image - The mask buffer to update the context with.\n   * @return {this} The current instance of the class for method chaining.\n   */\n  mask(image: Buffer) {\n    this.update({\n      input_mask: image,\n    });\n    return this;\n  }\n\n  /**\n   * Updates the context with the provided model checkpoint name.\n   *\n   * @param {string} ckpt_name - The name of the model checkpoint to update the context with.\n   * @return {this} The current instance of the class for method chaining.\n   */\n  model(ckpt_name: string) {\n    this.update({\n      ckpt_name,\n    });\n    return this;\n  }\n\n  /**\n   * Updates the context with the provided width and height, and returns the current instance of the class for method chaining.\n   *\n   * @param {number} w - The width to update the context with.\n   * @param {number} h - The height to update the context with.\n   * @return {this} The current instance of the class for method chaining.\n   */\n  size(w: number, h: number) {\n    this.update({\n      width: w,\n      height: h,\n    });\n    return this;\n  }\n\n  /**\n   * Updates the context with the provided text as the positive prompt.\n   *\n   * @param {string} text - The text to update the context with.\n   * @return {this} The current instance of the class for method chaining.\n   */\n  prompt(text: string) {\n    this.update({\n      positive: text,\n    });\n    return this;\n  }\n\n  /**\n   * Updates the context with the provided text as the negative prompt.\n   *\n   * @param {string} text - The text to update the context with.\n   * @return {this} The current instance of the class for method chaining.\n   */\n  negative(text: string) {\n    this.update({\n      negative: text,\n    });\n    return this;\n  }\n\n  /**\n   * Updates the context with the provided steps and returns the current instance of the class for method chaining.\n   *\n   * @param {number} steps - The number of steps to update the context with.\n   * @return {this} The current instance of the class for method chaining.\n   */\n  steps(steps: number) {\n    this.update({\n      steps,\n    });\n    return this;\n  }\n\n  /**\n   * Updates the context with the provided cfg value.\n   *\n   * @param {number} cfg - The cfg value to update the context with.\n   * @return {this} The current instance of the class for method chaining.\n   */\n  cfg(cfg: number) {\n    this.update({\n      cfg,\n    });\n    return this;\n  }\n\n  /**\n   * Updates the context with the provided seed value or generates a random seed value if none is provided.\n   *\n   * @param {number} [seed=BasePipe.nextSeed()] - The seed value to update the context with. If not provided, a random seed value will be generated.\n   * @return {this} The current instance of the class for method chaining.\n   */\n  seed(seed = BasePipe.nextSeed()) {\n    this.update({\n      seed,\n    });\n    return this;\n  }\n\n  /**\n   * Updates the context with the provided denoise value and returns the current instance of the class for method chaining.\n   *\n   * @param {number} denoise - The denoise value to update the context with.\n   * @return {this} The current instance of the class for method chaining.\n   */\n  denoise(denoise: number) {\n    this.update({\n      denoise,\n    });\n    return this;\n  }\n\n  /**\n   * Updates the context with the provided scheduler value and returns the current instance of the class for method chaining.\n   *\n   * @param {PipeContext[\"scheduler\"]} scheduler - The scheduler value to update the context with.\n   * @return {this} The current instance of the class for method chaining.\n   */\n  scheduler(scheduler: PipeContext[\"scheduler\"]) {\n    this.update({\n      scheduler,\n    });\n    return this;\n  }\n\n  /**\n   * Updates the context with the provided sampler name and returns the current instance of the class for method chaining.\n   *\n   * @param {PipeContext[\"sampler_name\"]} sampler_name - The sampler name to update the context with.\n   * @return {this} The current instance of the class for method chaining.\n   */\n  sampler(sampler_name: PipeContext[\"sampler_name\"]) {\n    this.update({\n      sampler_name,\n    });\n    return this;\n  }\n\n  /**\n   * Updates the context with the provided batch size and returns the current instance of the class for method chaining.\n   *\n   * @param {number} batch_size - The batch size to update the context with.\n   * @return {this} The current instance of the class for method chaining.\n   */\n  batch_size(batch_size: number) {\n    this.update({\n      batch_size,\n    });\n    return this;\n  }\n\n  /**\n   * Updates the context with the provided client and returns the current instance of the class for method chaining.\n   *\n   * @param {Client} client - The client to update the context with.\n   * @return {this} The current instance of the class for method chaining.\n   */\n  with(client: Client) {\n    this.update({\n      client,\n    });\n    return this;\n  }\n\n  /**\n   * Adds an event listener for the specified event type.\n   */\n  on<T extends EventEmitter.EventNames<ComfyUIClientEvents>>(\n    type: T,\n    callback: EventEmitter.EventListener<ComfyUIClientEvents, T>,\n    options?: any,\n  ) {\n    const { _invoked: invoked } = this;\n    if (!invoked) {\n      throw new Error(\"workflow not invoked\");\n    }\n    invoked.then((instance) => {\n      instance.on(type, callback, options);\n    });\n    return this;\n  }\n\n  /**\n   * Adds an once event listener for the specified event type.\n   */\n  once<T extends EventEmitter.EventNames<ComfyUIClientEvents>>(\n    type: T,\n    callback: EventEmitter.EventListener<ComfyUIClientEvents, T>,\n    options?: any,\n  ) {\n    const { _invoked: invoked } = this;\n    if (!invoked) {\n      throw new Error(\"workflow not invoked\");\n    }\n    invoked.then((instance) => {\n      instance.once(type, callback, options);\n    });\n    return this;\n  }\n\n  protected build_latent(vae: any) {\n    const { context, _workflow: workflow } = this;\n    const cls = workflow.classes;\n    const { width, height, batch_size } = context;\n    const { input_image, input_mask, grow_mask_by } = this.context;\n    if (!input_image) {\n      return cls.EmptyLatentImage({\n        width,\n        height,\n        batch_size,\n      })[0];\n    }\n    const pixels = cls.ETN_LoadImageBase64({\n      image: input_image.toString(\"base64\"),\n    })[0];\n    if (!input_mask) {\n      return cls.VAEEncode({\n        pixels,\n        vae,\n      })[0];\n    }\n    const mask = cls.ETN_LoadMaskBase64({\n      mask: input_mask.toString(\"base64\"),\n    })[0];\n    return cls.VAEEncodeForInpaint({\n      pixels,\n      vae,\n      mask,\n      grow_mask_by,\n    })[0];\n  }\n\n  protected build() {\n    const { context, _workflow: workflow } = this;\n    const cls = workflow.classes;\n    const {\n      seed,\n      steps,\n      cfg,\n      scheduler,\n      denoise,\n      ckpt_name,\n      positive,\n      negative,\n      sampler_name,\n    } = context;\n    const [model, clip, vae] = cls.CheckpointLoaderSimple({\n      ckpt_name,\n    });\n    const enc = (text: string) => cls.CLIPTextEncode({ text, clip })[0];\n    const [samples] = cls.KSampler({\n      seed,\n      steps,\n      cfg,\n      sampler_name,\n      scheduler,\n      denoise,\n      model,\n      positive: enc(positive),\n      negative: enc(negative),\n      latent_image: this.build_latent(vae),\n    });\n\n    return { samples, vae, cls };\n  }\n\n  protected _save(filename_prefix?: string) {\n    const { samples, vae, cls } = this.build();\n\n    const images = cls.VAEDecode({ samples, vae })[0];\n    if (filename_prefix) {\n      cls.SaveImage({\n        filename_prefix,\n        images,\n      });\n    } else {\n      cls.SaveImageWebsocket({\n        images,\n      });\n    }\n  }\n\n  protected async read_response(res: WorkflowOutput<unknown>) {\n    const images = [] as {\n      data: ArrayBuffer;\n      mime: string;\n    }[];\n    for (const img of res.images) {\n      switch (img.type) {\n        case \"buff\": {\n          images.push({\n            data: img.data,\n            mime: img.mime,\n          });\n          break;\n        }\n        case \"url\": {\n          const { data: url } = img;\n          const resp = await fetch(url);\n          const mime = resp.headers.get(\"content-type\") ?? \"image/png\";\n          const blob = await resp.blob();\n          images.push({\n            data: await blob.arrayBuffer(),\n            mime,\n          });\n          break;\n        }\n      }\n    }\n    return images;\n  }\n\n  /**\n   * Saves the workflow by invoking the workflow instance and enqueuing it.\n   *\n   * @param {string} [filename_prefix] - The prefix for the saved filename. if not provided, the workflow will be saved as a websocket connection.\n   * @return {this} - Returns the instance of the class for method chaining.\n   * @throws {Error} - Throws an error if the client is not defined.\n   */\n  save(filename_prefix?: string) {\n    const {\n      context: { client },\n      _workflow: workflow,\n    } = this;\n    if (!client) {\n      throw new Error(\"client is not defined\");\n    }\n    this._save(filename_prefix);\n    this._invoked = (async () => {\n      const instance = workflow.instance(client);\n      instance._connect(() => this.dispose());\n      await instance.enqueue();\n      return instance;\n    })();\n    return this;\n  }\n\n  /**\n   * Waits for the workflow to complete and returns the result and the images.\n   *\n   * @return {Promise<{result: WorkflowOutput<unknown>, images: {data: ArrayBuffer, mime: string}[]}>} - A promise that resolves to an object containing the result of the workflow and the images.\n   * @throws {Error} - Throws an error if the workflow has not been invoked.\n   */\n  async wait() {\n    const { _invoked: invoked } = this;\n    if (!invoked) {\n      throw new Error(\"workflow not invoked\");\n    }\n    const result = await (await invoked).wait();\n    const images = await this.read_response(result);\n    return {\n      result,\n      images,\n    };\n  }\n\n  /**\n   * Waits for the workflow to complete and returns the result and the images.\n   *\n   * *This function does not rely on WebSocket Events, so it maybe will lose events output by WebSocket node\n   *\n   * @return {Promise<{result: WorkflowOutput<unknown>, images: {data: ArrayBuffer, mime: string}[]}>} - A promise that resolves to an object containing the result of the workflow and the images.\n   * @throws {Error} - Throws an error if the workflow has not been invoked.\n   */\n  async wait_polling() {\n    const { _invoked: invoked } = this;\n    if (!invoked) {\n      throw new Error(\"workflow not invoked\");\n    }\n    const result = await (await invoked).wait_polling();\n    const images = await this.read_response(result);\n    return {\n      result,\n      images,\n    };\n  }\n}\n","import { BasePipe } from \"./base\";\nimport { NSPipeline } from \"./types\";\n\ninterface EfficientPipeContext extends NSPipeline.PipeContext {\n  vae_name: string;\n  clip_skip: number;\n  token_normalization: \"none\" | \"mean\" | \"length\" | \"length+mean\";\n  weight_interpretation:\n    | \"comfy\"\n    | \"A1111\"\n    | \"compel\"\n    | \"comfy++\"\n    | \"down_weight\";\n\n  loras: {\n    name: string;\n    weight: number;\n    model_strength: number;\n    clip_strength: number;\n  }[];\n  control_net_blocks: {\n    image: Buffer;\n    name: string;\n    strength: number;\n    start: number;\n    end: number;\n  }[];\n}\n\n/**\n * pipe to create a workflow\n *\n * required https://github.com/jags111/efficiency-nodes-comfyui\n */\nexport class EfficientPipe extends BasePipe<EfficientPipeContext> {\n  static defaultContext: EfficientPipeContext = {\n    ...BasePipe.defaultContext,\n    vae_name: \"Baked VAE\",\n    clip_skip: -2,\n    token_normalization: \"none\",\n    weight_interpretation: \"A1111\",\n\n    loras: [],\n    control_net_blocks: [],\n  };\n\n  constructor(context?: Partial<EfficientPipeContext>) {\n    super();\n    this.context = {\n      ...EfficientPipe.defaultContext,\n      ...context,\n    } as EfficientPipeContext;\n  }\n\n  /**\n   * Adds a LoRA (Low-Rank Adaptation) to the EfficientPipe context.\n   *\n   * @param {string} name - The name of the LoRA.\n   * @param {object} options - Optional configuration for the LoRA.\n   * @param {number} [options.weight=1] - The weight of the LoRA.\n   * @param {number} [options.strength=1] - The strength of the LoRA.\n   * @param {number} [options.clip_strength=1] - The clip strength of the LoRA.\n   * @return {EfficientPipe} The EfficientPipe instance for chaining.\n   */\n  lora(\n    name: string,\n    {\n      weight = 1,\n      strength = 1,\n      clip_strength = 1,\n    }: { weight?: number; strength?: number; clip_strength?: number } = {},\n  ) {\n    this.context.loras.push({\n      name,\n      weight,\n      model_strength: strength,\n      clip_strength,\n    });\n    return this;\n  }\n\n  /**\n   * Adds a control net block to the EfficientPipe context.\n   *\n   * @param {string} name - The name of the control net block.\n   * @param {Buffer} image - The image data of the control net block.\n   * @param {object} options - Optional configuration for the control net block.\n   * @param {number} [options.strength=1] - The strength of the control net block.\n   * @param {number} [options.start=0] - The start value of the control net block.\n   * @param {number} [options.end=1] - The end value of the control net block.\n   * @return {EfficientPipe} The EfficientPipe instance for chaining.\n   */\n  cnet(\n    name: string,\n    image: Buffer,\n    {\n      strength = 1,\n      start = 0,\n      end = 1,\n    }: {\n      strength?: number;\n      start?: number;\n      end?: number;\n    } = {},\n  ) {\n    this.context.control_net_blocks.push({\n      image,\n      name,\n      strength,\n      start,\n      end,\n    });\n    return this;\n  }\n\n  protected build_lora_stack() {\n    const { loras } = this.context;\n    if (loras.length === 0) {\n      return undefined;\n    }\n    const { _workflow: workflow } = this;\n    const cls = workflow.classes;\n    const params: any = {\n      lora_count: loras.length,\n    };\n    for (let idx = 0; idx < 50; idx++) {\n      const lora = loras[idx];\n      if (!lora) {\n        params[`lora_name_${idx}`] = \"None\";\n        params[`lora_wt_${idx}`] = 1;\n        params[`model_str_${idx}`] = 1;\n        params[`clip_str_${idx}`] = 1;\n        continue;\n      }\n      const { name, weight, model_strength, clip_strength } = lora;\n      params[`lora_name_${idx}`] = name;\n      params[`lora_wt_${idx}`] = weight;\n      params[`model_str_${idx}`] = model_strength;\n      params[`clip_str_${idx}`] = clip_strength;\n    }\n\n    const [stack] = cls[\"LoRA Stacker\"]({\n      input_mode: \"advanced\",\n      ...params,\n    });\n    return stack;\n  }\n\n  protected build_cnet_block(\n    {\n      image,\n      name,\n      strength,\n      start,\n      end,\n    }: EfficientPipeContext[\"control_net_blocks\"][number],\n    stack: any,\n  ) {\n    const { _workflow: workflow } = this;\n    const { ControlNetLoader, ETN_LoadImageBase64 } = workflow.classes;\n    const cls = workflow.classes;\n    const [model] = ControlNetLoader({\n      control_net_name: name,\n    });\n    const [img] = ETN_LoadImageBase64({\n      image: image.toString(\"base64\"),\n    });\n    const [stack_out] = cls[\"Control Net Stacker\"]({\n      control_net: model,\n      image: img,\n      strength,\n      start_percent: start,\n      end_percent: end,\n      cnet_stack: stack,\n    });\n    return stack_out;\n  }\n\n  protected build_cnet_stack() {\n    const { control_net_blocks } = this.context;\n    if (control_net_blocks.length === 0) {\n      return undefined;\n    }\n    let stack = undefined as any;\n    for (const cnet of control_net_blocks) {\n      stack = this.build_cnet_block(cnet, stack);\n    }\n    return stack;\n  }\n\n  protected build() {\n    const { context, _workflow: workflow } = this;\n    const cls = workflow.classes;\n    const {\n      seed,\n      steps,\n      cfg,\n      scheduler,\n      denoise,\n      ckpt_name,\n      positive,\n      negative,\n      sampler_name,\n      vae_name,\n      clip_skip,\n      token_normalization,\n      weight_interpretation,\n      width,\n      height,\n      batch_size,\n    } = context;\n    const [model, cond_pos, cond_neg, latent, vae, clip, deps] = cls[\n      \"Efficient Loader\"\n    ]({\n      ckpt_name,\n      vae_name,\n      clip_skip,\n      token_normalization,\n      weight_interpretation,\n      empty_latent_height: height,\n      empty_latent_width: width,\n      batch_size,\n      positive,\n      negative,\n\n      lora_stack: this.build_lora_stack(),\n      cnet_stack: this.build_cnet_stack(),\n\n      // NOTE: All lora loads use stack instead of here\n      lora_name: \"None\",\n      lora_model_strength: 1,\n      lora_clip_strength: 1,\n    });\n\n    const [samples] = cls.KSampler({\n      seed,\n      steps,\n      cfg,\n      sampler_name,\n      scheduler,\n      denoise,\n      model,\n      positive: cond_pos,\n      negative: cond_neg,\n      latent_image: this.build_latent(vae),\n    });\n\n    return { samples, vae, cls };\n  }\n}\n","/**\n * [0,0,0] => \"AAAA=\"\n * @param arrayBuffer - The ArrayBuffer to convert to base64.\n * @returns The base64 representation of the ArrayBuffer.\n */\nexport const arrayBufferToBase64 = (arrayBuffer: ArrayBuffer): string => {\n  const bytes = new Uint8Array(arrayBuffer);\n  let binary = \"\";\n  for (let i = 0; i < bytes.byteLength; i++) {\n    binary += String.fromCharCode(bytes[i]);\n  }\n  return globalThis.btoa(binary);\n};\n","import { WorkflowOutput } from \"../workflow/types\";\nimport { arrayBufferToBase64 as a2b } from \"./arrayBuffer\";\n\nconst b64pkg = (b64: string, type: string) => `data:${type};base64,${b64}`;\nconst url2mime = (url: string) =>\n  url.toLowerCase().endsWith(\".png\") ? \"image/png\" : \"image/jpeg\";\n\nexport const outToB64Urls = (\n  result: WorkflowOutput,\n  {\n    fetch = globalThis.fetch,\n  }: {\n    fetch?: typeof globalThis.fetch;\n  } = {},\n): Promise<string[]> =>\n  Promise.all(\n    result.images.map((x) => {\n      switch (x.type) {\n        case \"buff\":\n          return b64pkg(a2b(x.data), x.mime || \"image/png\");\n        case \"url\":\n          return fetch(x.data)\n            .then((res) => res.blob())\n            .then(async (blob) =>\n              b64pkg(a2b(await blob.arrayBuffer()), url2mime(x.data)),\n            );\n        default:\n          // @ts-ignore\n          throw new Error(`Unknown image type: ${x.type}`);\n      }\n    }),\n  );\n","export * from \"./client/WsClient\";\nexport * from \"./client/Client\";\nexport * from \"./workflow/Workflow\";\nexport * from \"./plugins/Plugin\";\nexport * as plugins from \"./plugins\";\nexport * as builtins from \"./builtins\";\nexport * from \"./pipeline\";\n\nexport * from \"./utils/tools\";\n\nexport * from \"./client/types\";\nexport * from \"./client/ws.types\";\nexport * from \"./client/response.types\";\n\nexport * from \"./workflow/types\";\nexport * from \"./pipeline/types\";\n\nexport * from \"./client/errors\";\nexport * from \"./workflow/errors\";\n\nimport { WsClient } from \"./client/WsClient\";\nimport { Client } from \"./client/Client\";\nimport { Workflow } from \"./workflow/Workflow\";\nimport { Plugin } from \"./plugins/Plugin\";\n\n/**\n * @deprecated use `Client` instead\n */\nexport const ComfyUIApiClient = Client;\n\n/**\n * @deprecated use `WsClient` instead\n */\nexport const ComfyUIWsClient = WsClient;\n\n/**\n * @deprecated use `Workflow` instead\n */\nexport const ComfyUIWorkflow = Workflow;\n\n/**\n * @deprecated use `Plugin` instead\n */\nexport const ClientPlugin = Plugin;\n"],"names":["has","Object","prototype","hasOwnProperty","prefix","Events","EE","fn","context","once","this","addListener","emitter","event","TypeError","listener","evt","_events","push","_eventsCount","clearEvent","EventEmitter","create","__proto__","eventNames","events","name","names","call","slice","getOwnPropertySymbols","concat","listeners","handlers","i","l","length","ee","Array","listenerCount","emit","a1","a2","a3","a4","a5","args","len","arguments","removeListener","undefined","apply","j","on","removeAllListeners","off","prefixed","module","exports","isNone","x","ClientError","Error","constructor","message","super","PromptTimeoutError","prompt_id","timeout_ms","PromptEnqueueError","resp","_error$errors","error","node_errors","errors","JSON","stringify","ClientEnqueueError","err_msg","PromptNotFoundError","TaskDataTypeError","task_data","PromptExecutionFailedError","status","ClientRequestError","PollingTimeoutError","WebSocketTimeoutError","ConnectError","WebSocketParseError","HttpError","json","WsClient","readBinaryData","buf","view","DataView","eventType","getUint32","imageType","decoder","TextDecoder","data","nodeIdLength","type","nodeId","decode","text","mime","image","Blob","decoder4","metadataLength","metadataBytes","metadata","parse","imageData4","imageBlob4","image_type","blob","node_id","displayNodeId","display_node_id","parentNodeId","parent_node_id","realNodeId","real_node_id","promptId","registered","config","_config$api_host","_config$api_base","_config$clientId","_config$WebSocket","_config$ssl","_config$user","_config$fetch","api_host","api_base","clientId","socket","WebSocket","ssl","user","fetch","socket_callbacks","_polling_timer","_polling_interval","closed","DEFAULT_API_HOST","DEFAULT_API_BASE","replace","c","r","Math","random","toString","globalThis","DEFAULT_USER","bind","console","warn","apiHeaders","options","_options$headers","_extends","Accept","headers","apiURL","route","url","URL","pathname","query","split","search","searchParams","set","internalURL","viewURL","filename","subfolder","URLSearchParams","wsURL","fetchApi","res","statusText","addEventListener","callback","startPollingQueue","_this","setInterval","async","addSocketCallback","removeEventListener","removeSocketCallbacks","createSocket","isReconnect","_this2","opened","binaryType","ev","_err$message","err","is404Error","includes","close","setTimeout","ArrayBuffer","Buffer","isBuffer","isBinaryData","binaryEvents","arrayBuffer","msg","sid","init","disconnect","connect","polling","enabled","websocket","_polling$interval","_this3","interval","Promise","resolve","reject","timer","ok","clearTimeout","_disconnectSocket","process","nextTick","_disconnectPolling","readyState","OPEN","clearInterval","IS_BROWSER","window","RESOLVERS","acc","output","client","images","map","filter","Boolean","WorkflowError","task_id","workflow","invoked","WorkflowExecutionError","payload","exception_message","exception_type","ClientConnectionError","WorkflowGuardError","WorkflowEnqueuedError","WorkflowTaskIdError","WorkflowDoneError","is_done","WorkflowWsError","WorkflowTaskStatusError","WorkflowInterruptedError","WorkflowArgumentError","Disposable","_disposed","_disposed_cbs","dispose","forEach","cb","_connect","Client","_plugins","use","plugin","install","getExtensions","cache","invoke","getEmbeddings","getNodeDefs","queuePrompt","queue_index","prompt","body","client_id","extra_data","extra_pnginfo","front","number","method","error_resp","error_data","getItems","getQueue","getHistory","Running","queue_running","Pending","queue_pending","max_items","offset","Number","isInteger","params","History","values","getSystemStats","postApi","deleteItem","id","delete","clearItems","clear","interrupt","runningPromptId","free","getUserConfig","createUser","username","getSettings","getSetting","encodeURIComponent","storeSettings","settings","storeSetting","value","getUserData","file","storeUserData","getModelFolders","folderBlacklist","folder","getModels","viewMetadata","model","rawResponse","getLogs","getRawLogs","getSamplers","_node$input","node","input","required","getSchedulers","_node$input2","getSDModels","_node$input3","getCNetModels","_node$input4","getUpscaleModels","_node$input5","getHyperNetworks","_node$input6","getLoRAs","_node$input7","getVAEs","_node$input8","getPromptStatus","getId","task","_task$prompt","isArray","running","some","pending","done","getPromptOutputs","_item$status$status_s","_item$status","history","item","find","status_str","outputs","getPromptResult","resolver","entries","reduce","waitForPrompt","polling_ms","start","Date","now","prompt_status","waitForPromptWebSocket","disposable","is_current_ws_executing","current_prompt_id","executed_output","resolved","finally","_enqueue_prompt","runPrompt","enqueue_polling","_options$resolver","progress","enqueue","off_progress","on_progress","_options$resolver2","_data","InvokedWorkflow","_task_id","_result","enqueued","delay_done_ms","is_disposed","_enqueue_guard","_task_id_guard","_done_guard","_ws_guard","is_owner_event","wf","hook_progress","hook_image_data","hook_executing","resolve_to_result","collect_result","_this$_result$data","result","when_interrupted","when_execution_error","on_start","wait_polling","catch","_this$options$on_erro","_this$options","on_error","wait","maybe_done","debounce","wait_ms","timeout","_this$options$on_erro2","_this$options2","deepClone","structuredClone","Workflow","_workflow","_last_node_id","classes","_createClassesProxy","Proxy","get","target","p","receiver","inputs","node_name","class_type","gen","index","reset","end","_ws_connected_guard","_client$socket$readyS","_client$socket","current_state","CLOSED","CONNECTING","CLOSING","instance","invoke_polling","Plugin","hooks","hook","ins","original","addHook","NSPipeline","urlObj","token","samplers","schedulers","BasePipe","nextSeed","floor","MAX_SAFE_INTEGER","_invoked","defaultContext","update","ctx","assign","input_image","mask","input_mask","ckpt_name","size","w","h","width","height","positive","negative","steps","cfg","seed","denoise","scheduler","sampler","sampler_name","batch_size","with","then","build_latent","vae","cls","grow_mask_by","EmptyLatentImage","pixels","ETN_LoadImageBase64","VAEEncode","ETN_LoadMaskBase64","VAEEncodeForInpaint","build","clip","CheckpointLoaderSimple","enc","CLIPTextEncode","samples","KSampler","latent_image","_save","filename_prefix","VAEDecode","SaveImage","SaveImageWebsocket","read_response","img","_resp$headers$get","save","EfficientPipe","lora","weight","strength","clip_strength","loras","model_strength","cnet","control_net_blocks","build_lora_stack","lora_count","idx","stack","input_mode","build_cnet_block","ControlNetLoader","control_net_name","stack_out","control_net","start_percent","end_percent","cnet_stack","build_cnet_stack","vae_name","clip_skip","token_normalization","weight_interpretation","cond_pos","cond_neg","latent","deps","empty_latent_height","empty_latent_width","lora_stack","lora_name","lora_model_strength","lora_clip_strength","arrayBufferToBase64","bytes","Uint8Array","binary","byteLength","String","fromCharCode","btoa","b64pkg","b64","outToB64Urls","all","a2b","toLowerCase","endsWith","ComfyUIApiClient","ComfyUIWsClient","ComfyUIWorkflow","ClientPlugin"],"mappings":"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"}