{"version":3,"sources":["../../src/worker/index.ts","../../../../node_modules/.pnpm/tsup@8.3.0_@microsoft+api-extractor@7.47.7_@types+node@20.16.11__postcss@8.4.47_tsx@4.19.1_typescript@5.6.3/node_modules/tsup/assets/cjs_shims.js","../../src/templating.ts","../../src/types.ts","../../src/parse.ts","../../../pg-protocol/src/string-utils.ts","../../../pg-protocol/src/buffer-writer.ts","../../../pg-protocol/src/serializer.ts","../../../pg-protocol/src/buffer-reader.ts","../../../pg-protocol/src/parser.ts","../../src/base.ts","../../src/utils.ts"],"sourcesContent":["import type {\n  DataTransferContainer,\n  DebugLevel,\n  ExecProtocolResult,\n  Extensions,\n  PGliteInterface,\n  PGliteInterfaceExtensions,\n  PGliteOptions,\n} from '../interface.js'\nimport type { PGlite } from '../pglite.js'\nimport { BasePGlite } from '../base.js'\nimport { toPostgresName, uuid } from '../utils.js'\n\nexport type PGliteWorkerOptions<E extends Extensions = Extensions> =\n  PGliteOptions<E> & {\n    meta?: any\n    id?: string\n  }\n\nexport class PGliteWorker\n  extends BasePGlite\n  implements PGliteInterface, AsyncDisposable\n{\n  #initPromise: Promise<void>\n  #debug: DebugLevel = 0\n\n  #ready = false\n  #closed = false\n  #isLeader = false\n\n  #eventTarget = new EventTarget()\n\n  #tabId: string\n\n  #connected = false\n\n  #workerProcess: Worker\n  #workerID?: string\n  #workerHerePromise?: Promise<void>\n  #workerReadyPromise?: Promise<void>\n\n  #broadcastChannel?: BroadcastChannel\n  #tabChannel?: BroadcastChannel\n  #releaseTabCloseLock?: () => void\n\n  #notifyListeners = new Map<string, Set<(payload: string) => void>>()\n  #globalNotifyListeners = new Set<(channel: string, payload: string) => void>()\n\n  #extensions: Extensions\n  #extensionsClose: Array<() => Promise<void>> = []\n\n  constructor(worker: Worker, options?: PGliteWorkerOptions) {\n    super()\n    this.#workerProcess = worker\n    this.#tabId = uuid()\n    this.#extensions = options?.extensions ?? {}\n\n    this.#workerHerePromise = new Promise<void>((resolve) => {\n      this.#workerProcess.addEventListener(\n        'message',\n        (event) => {\n          if (event.data.type === 'here') {\n            resolve()\n          } else {\n            throw new Error('Invalid message')\n          }\n        },\n        { once: true },\n      )\n    })\n\n    this.#workerReadyPromise = new Promise<void>((resolve) => {\n      const callback = (event: MessageEvent<any>) => {\n        if (event.data.type === 'ready') {\n          this.#workerID = event.data.id\n          this.#workerProcess.removeEventListener('message', callback)\n          resolve()\n        }\n      }\n      this.#workerProcess.addEventListener('message', callback)\n    })\n\n    this.#initPromise = this.#init(options)\n  }\n\n  /**\n   * Create a new PGlite instance with extensions on the Typescript interface\n   * This also awaits the instance to be ready before resolving\n   * (The main constructor does enable extensions, however due to the limitations\n   * of Typescript, the extensions are not available on the instance interface)\n   * @param worker The worker to use\n   * @param options Optional options\n   * @returns A promise that resolves to the PGlite instance when it's ready.\n   */\n  static async create<O extends PGliteWorkerOptions>(\n    worker: Worker,\n    options?: O,\n  ): Promise<PGliteWorker & PGliteInterfaceExtensions<O['extensions']>> {\n    const pg = new PGliteWorker(worker, options)\n    await pg.#initPromise\n    return pg as PGliteWorker & PGliteInterfaceExtensions<O['extensions']>\n  }\n\n  async #init(options: PGliteWorkerOptions = {}) {\n    // Setup the extensions\n    for (const [extName, ext] of Object.entries(this.#extensions)) {\n      if (ext instanceof URL) {\n        throw new Error(\n          'URL extensions are not supported on the client side of a worker',\n        )\n      } else {\n        const extRet = await ext.setup(this, {}, true)\n        if (extRet.emscriptenOpts) {\n          console.warn(\n            `PGlite extension ${extName} returned emscriptenOpts, these are not supported on the client side of a worker`,\n          )\n        }\n        if (extRet.namespaceObj) {\n          const instance = this as any\n          instance[extName] = extRet.namespaceObj\n        }\n        if (extRet.bundlePath) {\n          console.warn(\n            `PGlite extension ${extName} returned bundlePath, this is not supported on the client side of a worker`,\n          )\n        }\n        if (extRet.init) {\n          await extRet.init()\n        }\n        if (extRet.close) {\n          this.#extensionsClose.push(extRet.close)\n        }\n      }\n    }\n\n    // Wait for the worker let us know it's here\n    await this.#workerHerePromise\n\n    // Send the worker the options\n    const { extensions: _, ...workerOptions } = options\n    this.#workerProcess.postMessage({\n      type: 'init',\n      options: workerOptions,\n    })\n\n    // Wait for the worker let us know it's ready\n    await this.#workerReadyPromise\n\n    // Acquire the tab close lock, this is released then the tab, or this\n    // PGliteWorker instance, is closed\n    const tabCloseLockId = `pglite-tab-close:${this.#tabId}`\n    this.#releaseTabCloseLock = await acquireLock(tabCloseLockId)\n\n    // Start the broadcast channel used to communicate with tabs and leader election\n    const broadcastChannelId = `pglite-broadcast:${this.#workerID}`\n    this.#broadcastChannel = new BroadcastChannel(broadcastChannelId)\n\n    // Start the tab channel used to communicate with the leader directly\n    const tabChannelId = `pglite-tab:${this.#tabId}`\n    this.#tabChannel = new BroadcastChannel(tabChannelId)\n\n    this.#broadcastChannel.addEventListener('message', async (event) => {\n      if (event.data.type === 'leader-here') {\n        this.#connected = false\n        this.#eventTarget.dispatchEvent(new Event('leader-change'))\n        this.#leaderNotifyLoop()\n      } else if (event.data.type === 'notify') {\n        this.#receiveNotification(event.data.channel, event.data.payload)\n      }\n    })\n\n    this.#tabChannel.addEventListener('message', async (event) => {\n      if (event.data.type === 'connected') {\n        this.#connected = true\n        this.#eventTarget.dispatchEvent(new Event('connected'))\n        this.#debug = await this.#rpc('getDebugLevel')\n        this.#ready = true\n      }\n    })\n\n    this.#workerProcess.addEventListener('message', async (event) => {\n      if (event.data.type === 'leader-now') {\n        this.#isLeader = true\n        this.#eventTarget.dispatchEvent(new Event('leader-change'))\n      }\n    })\n\n    this.#leaderNotifyLoop()\n\n    // Init array types\n    // We don't await this as it will result in a deadlock\n    // It immediately takes out the transaction lock as so another query\n    this._initArrayTypes()\n  }\n\n  async #leaderNotifyLoop() {\n    if (!this.#connected) {\n      this.#broadcastChannel!.postMessage({\n        type: 'tab-here',\n        id: this.#tabId,\n      })\n      setTimeout(() => this.#leaderNotifyLoop(), 16)\n    }\n  }\n\n  async #rpc<Method extends WorkerRpcMethod>(\n    method: Method,\n    ...args: Parameters<WorkerApi[Method]>\n  ): Promise<ReturnType<WorkerApi[Method]>> {\n    const callId = uuid()\n    const message: WorkerRpcCall<Method> = {\n      type: 'rpc-call',\n      callId,\n      method,\n      args,\n    }\n    this.#tabChannel!.postMessage(message)\n    return await new Promise<ReturnType<WorkerApi[Method]>>(\n      (resolve, reject) => {\n        const listener = (event: MessageEvent) => {\n          if (event.data.callId !== callId) return\n          cleanup()\n          const message: WorkerRpcResponse<Method> = event.data\n          if (message.type === 'rpc-return') {\n            resolve(message.result)\n          } else if (message.type === 'rpc-error') {\n            const error = new Error(message.error.message)\n            Object.assign(error, message.error)\n            reject(error)\n          } else {\n            reject(new Error('Invalid message'))\n          }\n        }\n        const leaderChangeListener = () => {\n          // If the leader changes, throw an error to reject the promise\n          cleanup()\n          reject(new LeaderChangedError())\n        }\n        const cleanup = () => {\n          this.#tabChannel!.removeEventListener('message', listener)\n          this.#eventTarget.removeEventListener(\n            'leader-change',\n            leaderChangeListener,\n          )\n        }\n        this.#eventTarget.addEventListener(\n          'leader-change',\n          leaderChangeListener,\n        )\n        this.#tabChannel!.addEventListener('message', listener)\n      },\n    )\n  }\n\n  get waitReady() {\n    return new Promise<void>((resolve) => {\n      this.#initPromise.then(() => {\n        if (!this.#connected) {\n          resolve(\n            new Promise<void>((resolve) => {\n              this.#eventTarget.addEventListener('connected', () => {\n                resolve()\n              })\n            }),\n          )\n        } else {\n          resolve()\n        }\n      })\n    })\n  }\n\n  get debug() {\n    return this.#debug\n  }\n\n  /**\n   * The ready state of the database\n   */\n  get ready() {\n    return this.#ready\n  }\n\n  /**\n   * The closed state of the database\n   */\n  get closed() {\n    return this.#closed\n  }\n\n  /**\n   * The leader state of this tab\n   */\n  get isLeader() {\n    return this.#isLeader\n  }\n\n  /**\n   * Close the database\n   * @returns Promise that resolves when the connection to shared PGlite is closed\n   */\n  async close() {\n    if (this.#closed) {\n      return\n    }\n    this.#closed = true\n    this.#broadcastChannel?.close()\n    this.#tabChannel?.close()\n    this.#releaseTabCloseLock?.()\n    this.#workerProcess.terminate()\n  }\n\n  /**\n   * Close the database when the object exits scope\n   * Stage 3 ECMAScript Explicit Resource Management\n   * https://www.typescriptlang.org/docs/handbook/release-notes/typescript-5-2.html#using-declarations-and-explicit-resource-management\n   */\n  async [Symbol.asyncDispose]() {\n    await this.close()\n  }\n\n  /**\n   * Execute a postgres wire protocol message directly without wrapping the response.\n   * Only use if `execProtocol()` doesn't suite your needs.\n   *\n   * **Warning:** This bypasses PGlite's protocol wrappers that manage error/notice messages,\n   * transactions, and notification listeners. Only use if you need to bypass these wrappers and\n   * don't intend to use the above features.\n   *\n   * @param message The postgres wire protocol message to execute\n   * @returns The direct message data response produced by Postgres\n   */\n  async execProtocolRaw(message: Uint8Array): Promise<Uint8Array> {\n    return (await this.#rpc('execProtocolRaw', message)) as Uint8Array\n  }\n\n  /**\n   * Execute a postgres wire protocol message\n   * @param message The postgres wire protocol message to execute\n   * @returns The result of the query\n   */\n  async execProtocol(message: Uint8Array): Promise<ExecProtocolResult> {\n    return await this.#rpc('execProtocol', message)\n  }\n\n  /**\n   * Sync the database to the filesystem\n   * @returns Promise that resolves when the database is synced to the filesystem\n   */\n  async syncToFs() {\n    await this.#rpc('syncToFs')\n  }\n\n  /**\n   * Listen for a notification\n   * @param channel The channel to listen on\n   * @param callback The callback to call when a notification is received\n   */\n  async listen(\n    channel: string,\n    callback: (payload: string) => void,\n  ): Promise<() => Promise<void>> {\n    const pgChannel = toPostgresName(channel)\n\n    if (!this.#notifyListeners.has(pgChannel)) {\n      this.#notifyListeners.set(pgChannel, new Set())\n    }\n    this.#notifyListeners.get(pgChannel)!.add(callback)\n    await this.exec(`LISTEN ${channel}`)\n    return async () => {\n      await this.unlisten(pgChannel, callback)\n    }\n  }\n\n  /**\n   * Stop listening for a notification\n   * @param channel The channel to stop listening on\n   * @param callback The callback to remove\n   */\n  async unlisten(\n    channel: string,\n    callback?: (payload: string) => void,\n  ): Promise<void> {\n    await this.waitReady\n    if (callback) {\n      this.#notifyListeners.get(channel)?.delete(callback)\n    } else {\n      this.#notifyListeners.delete(channel)\n    }\n    if (this.#notifyListeners.get(channel)?.size === 0) {\n      // As we currently have a dedicated worker we can just unlisten\n      await this.exec(`UNLISTEN ${channel}`)\n    }\n  }\n\n  /**\n   * Listen to notifications\n   * @param callback The callback to call when a notification is received\n   */\n  onNotification(callback: (channel: string, payload: string) => void) {\n    this.#globalNotifyListeners.add(callback)\n    return () => {\n      this.#globalNotifyListeners.delete(callback)\n    }\n  }\n\n  /**\n   * Stop listening to notifications\n   * @param callback The callback to remove\n   */\n  offNotification(callback: (channel: string, payload: string) => void) {\n    this.#globalNotifyListeners.delete(callback)\n  }\n\n  #receiveNotification(channel: string, payload: string) {\n    const listeners = this.#notifyListeners.get(channel)\n    if (listeners) {\n      for (const listener of listeners) {\n        queueMicrotask(() => listener(payload))\n      }\n    }\n    for (const listener of this.#globalNotifyListeners) {\n      queueMicrotask(() => listener(channel, payload))\n    }\n  }\n\n  async dumpDataDir(): Promise<File | Blob> {\n    return (await this.#rpc('dumpDataDir')) as File | Blob\n  }\n\n  onLeaderChange(callback: () => void) {\n    this.#eventTarget.addEventListener('leader-change', callback)\n    return () => {\n      this.#eventTarget.removeEventListener('leader-change', callback)\n    }\n  }\n\n  offLeaderChange(callback: () => void) {\n    this.#eventTarget.removeEventListener('leader-change', callback)\n  }\n\n  async _handleBlob(blob?: File | Blob): Promise<void> {\n    await this.#rpc('_handleBlob', blob)\n  }\n\n  async _getWrittenBlob(): Promise<File | Blob | undefined> {\n    return await this.#rpc('_getWrittenBlob')\n  }\n\n  async _cleanupBlob(): Promise<void> {\n    await this.#rpc('_cleanupBlob')\n  }\n\n  async _checkReady() {\n    await this.waitReady\n  }\n\n  async _runExclusiveQuery<T>(fn: () => Promise<T>): Promise<T> {\n    await this.#rpc('_acquireQueryLock')\n    try {\n      return await fn()\n    } finally {\n      await this.#rpc('_releaseQueryLock')\n    }\n  }\n\n  async _runExclusiveTransaction<T>(fn: () => Promise<T>): Promise<T> {\n    await this.#rpc('_acquireTransactionLock')\n    try {\n      return await fn()\n    } finally {\n      await this.#rpc('_releaseTransactionLock')\n    }\n  }\n}\n\nexport interface WorkerOptions {\n  init: (options: Exclude<PGliteWorkerOptions, 'extensions'>) => Promise<PGlite>\n}\n\nexport async function worker({ init }: WorkerOptions) {\n  // Send a message to the main thread to let it know we are here\n  postMessage({ type: 'here' })\n\n  // Await the main thread to send us the options\n  const options = await new Promise<Exclude<PGliteWorkerOptions, 'extensions'>>(\n    (resolve) => {\n      addEventListener(\n        'message',\n        (event) => {\n          if (event.data.type === 'init') {\n            resolve(event.data.options)\n          }\n        },\n        { once: true },\n      )\n    },\n  )\n\n  // ID for this multi-tab worker - this is used to identify the group of workers\n  // that are trying to elect a leader for a shared PGlite instance.\n  // It defaults to the URL of the worker, and the dataDir if provided\n  // but can be overridden by the options.\n  const id = options.id ?? `${import.meta.url}:${options.dataDir ?? ''}`\n\n  // Let the main thread know we are ready\n  postMessage({ type: 'ready', id })\n\n  const electionLockId = `pglite-election-lock:${id}`\n  const broadcastChannelId = `pglite-broadcast:${id}`\n  const broadcastChannel = new BroadcastChannel(broadcastChannelId)\n  const connectedTabs = new Set<string>()\n\n  // Await the main lock which is used to elect the leader\n  // We don't release this lock, its automatically released when the worker or\n  // tab is closed\n  await acquireLock(electionLockId)\n\n  // Now we are the leader, start the worker\n  const dbPromise = init(options)\n\n  // Start listening for messages from tabs\n  broadcastChannel.onmessage = async (event) => {\n    const msg = event.data\n    switch (msg.type) {\n      case 'tab-here':\n        // A new tab has joined,\n        connectTab(msg.id, await dbPromise, connectedTabs)\n        break\n    }\n  }\n\n  // Notify the other tabs that we are the leader\n  broadcastChannel.postMessage({ type: 'leader-here', id })\n\n  // Let the main thread know we are the leader\n  postMessage({ type: 'leader-now' })\n\n  const db = await dbPromise\n\n  // Listen for notifications and broadcast them to all tabs\n  db.onNotification((channel, payload) => {\n    broadcastChannel.postMessage({ type: 'notify', channel, payload })\n  })\n}\n\nfunction connectTab(tabId: string, pg: PGlite, connectedTabs: Set<string>) {\n  if (connectedTabs.has(tabId)) {\n    return\n  }\n  connectedTabs.add(tabId)\n  const tabChannelId = `pglite-tab:${tabId}`\n  const tabCloseLockId = `pglite-tab-close:${tabId}`\n  const tabChannel = new BroadcastChannel(tabChannelId)\n\n  // Use a tab close lock to unsubscribe the tab\n  navigator.locks.request(tabCloseLockId, () => {\n    return new Promise<void>((resolve) => {\n      // The tab has been closed, unsubscribe the tab broadcast channel\n      tabChannel.close()\n      connectedTabs.delete(tabId)\n      resolve()\n    })\n  })\n\n  const api = makeWorkerApi(tabId, pg)\n\n  tabChannel.addEventListener('message', async (event) => {\n    const msg = event.data\n    switch (msg.type) {\n      case 'rpc-call': {\n        await pg.waitReady\n        const { callId, method, args } = msg as WorkerRpcCall<WorkerRpcMethod>\n        try {\n          // @ts-ignore no apparent reason why it fails\n          const result = (await api[method](...args)) as WorkerRpcResult<\n            typeof method\n          >['result']\n          tabChannel.postMessage({\n            type: 'rpc-return',\n            callId,\n            result,\n          } satisfies WorkerRpcResult<typeof method>)\n        } catch (error) {\n          console.error(error)\n          tabChannel.postMessage({\n            type: 'rpc-error',\n            callId,\n            error: { message: (error as Error).message },\n          } satisfies WorkerRpcError)\n        }\n        break\n      }\n    }\n  })\n\n  // Send a message to the tab to let it know it's connected\n  tabChannel.postMessage({ type: 'connected' })\n}\n\nfunction makeWorkerApi(tabId: string, db: PGlite) {\n  let queryLockRelease: (() => void) | null = null\n  let transactionLockRelease: (() => void) | null = null\n\n  // If the tab is closed and it is holding a lock, release the the locks\n  // and rollback any pending transactions\n  const tabCloseLockId = `pglite-tab-close:${tabId}`\n  acquireLock(tabCloseLockId).then(() => {\n    if (transactionLockRelease) {\n      // rollback any pending transactions\n      db.exec('ROLLBACK')\n    }\n    queryLockRelease?.()\n    transactionLockRelease?.()\n  })\n\n  return {\n    async getDebugLevel() {\n      return db.debug\n    },\n    async close() {\n      await db.close()\n    },\n    async execProtocol(message: Uint8Array) {\n      const { messages, data } = await db.execProtocol(message)\n      if (data.byteLength !== data.buffer.byteLength) {\n        const buffer = new ArrayBuffer(data.byteLength)\n        const dataCopy = new Uint8Array(buffer)\n        dataCopy.set(data)\n        return { messages, data: dataCopy }\n      } else {\n        return { messages, data }\n      }\n    },\n    async execProtocolRaw(\n      message: Uint8Array,\n      options: { dataTransferContainer?: DataTransferContainer } = {},\n    ) {\n      const result = await db.execProtocolRaw(message, options)\n      if (result.byteLength !== result.buffer.byteLength) {\n        // The data is a slice of a larger buffer, this is potentially the whole\n        // memory of the WASM module. We copy it to a new Uint8Array and return that.\n        const buffer = new ArrayBuffer(result.byteLength)\n        const resultCopy = new Uint8Array(buffer)\n        resultCopy.set(result)\n        return resultCopy\n      } else {\n        return result\n      }\n    },\n    async dumpDataDir() {\n      return await db.dumpDataDir()\n    },\n    async syncToFs() {\n      return await db.syncToFs()\n    },\n    async _handleBlob(blob?: File | Blob) {\n      return await db._handleBlob(blob)\n    },\n    async _getWrittenBlob() {\n      return await db._getWrittenBlob()\n    },\n    async _cleanupBlob() {\n      return await db._cleanupBlob()\n    },\n    async _checkReady() {\n      return await db._checkReady()\n    },\n    async _acquireQueryLock() {\n      return new Promise<void>((resolve) => {\n        db._runExclusiveQuery(() => {\n          return new Promise<void>((release) => {\n            queryLockRelease = release\n            resolve()\n          })\n        })\n      })\n    },\n    async _releaseQueryLock() {\n      queryLockRelease?.()\n      queryLockRelease = null\n    },\n    async _acquireTransactionLock() {\n      return new Promise<void>((resolve) => {\n        db._runExclusiveTransaction(() => {\n          return new Promise<void>((release) => {\n            transactionLockRelease = release\n            resolve()\n          })\n        })\n      })\n    },\n    async _releaseTransactionLock() {\n      transactionLockRelease?.()\n      transactionLockRelease = null\n    },\n  }\n}\n\nexport class LeaderChangedError extends Error {\n  constructor() {\n    super('Leader changed, pending operation in indeterminate state')\n  }\n}\n\nasync function acquireLock(lockId: string) {\n  let release\n  await new Promise<void>((resolve) => {\n    navigator.locks.request(lockId, () => {\n      return new Promise<void>((releaseCallback) => {\n        release = releaseCallback\n        resolve()\n      })\n    })\n  })\n  return release\n}\n\ntype WorkerApi = ReturnType<typeof makeWorkerApi>\n\ntype WorkerRpcMethod = keyof WorkerApi\n\ntype WorkerRpcCall<Method extends WorkerRpcMethod> = {\n  type: 'rpc-call'\n  callId: string\n  method: Method\n  args: Parameters<WorkerApi[Method]>\n}\n\ntype WorkerRpcResult<Method extends WorkerRpcMethod> = {\n  type: 'rpc-return'\n  callId: string\n  result: ReturnType<WorkerApi[Method]>\n}\n\ntype WorkerRpcError = {\n  type: 'rpc-error'\n  callId: string\n  error: any\n}\n\ntype WorkerRpcResponse<Method extends WorkerRpcMethod> =\n  | WorkerRpcResult<Method>\n  | WorkerRpcError\n","// Shim globals in cjs bundle\n// There's a weird bug that esbuild will always inject importMetaUrl\n// if we export it as `const importMetaUrl = ... __filename ...`\n// But using a function will not cause this issue\n\nconst getImportMetaUrl = () =>\n  typeof document === 'undefined'\n    ? new URL(`file:${__filename}`).href\n    : (document.currentScript && document.currentScript.src) ||\n      new URL('main.js', document.baseURI).href\n\nexport const importMetaUrl = /* @__PURE__ */ getImportMetaUrl()\n","const TemplateType = {\n  part: 'part',\n  container: 'container',\n} as const\n\ninterface TemplatePart {\n  _templateType: typeof TemplateType.part\n  str: string\n}\n\ninterface TemplateContainer {\n  _templateType: typeof TemplateType.container\n  strings: TemplateStringsArray\n  values: any[]\n}\n\ninterface TemplatedQuery {\n  query: string\n  params: any[]\n}\n\nfunction addToLastAndPushWithSuffix(\n  arr: string[],\n  suffix: string,\n  ...values: string[]\n) {\n  const lastArrIdx = arr.length - 1\n  const lastValIdx = values.length - 1\n\n  // no-op\n  if (lastValIdx === -1) return\n\n  // overwrite last element\n  if (lastValIdx === 0) {\n    arr[lastArrIdx] = arr[lastArrIdx] + values[0] + suffix\n    return\n  }\n\n  // sandwich values between array and suffix\n  arr[lastArrIdx] = arr[lastArrIdx] + values[0]\n  arr.push(...values.slice(1, lastValIdx))\n  arr.push(values[lastValIdx] + suffix)\n}\n\n/**\n * Templating utility that allows nesting multiple SQL strings without\n * losing the automatic parametrization capabilities of {@link query}.\n *\n * @example\n * ```ts\n * query`SELECT * FROM tale ${withFilter ? sql`WHERE foo = ${fooVar}` : sql``}`\n * // > { query: 'SELECT * FROM tale WHERE foo = $1', params: [fooVar] }\n * // or\n * // > { query: 'SELECT * FROM tale', params: [] }\n * ```\n */\nexport function sql(\n  strings: TemplateStringsArray,\n  ...values: any[]\n): TemplateContainer {\n  const parsedStrings = [strings[0]] as string[] & {\n    raw: string[]\n  }\n  parsedStrings.raw = [strings.raw[0]]\n\n  const parsedValues: any[] = []\n  for (let i = 0; i < values.length; i++) {\n    const value = values[i]\n    const nextStringIdx = i + 1\n\n    // if value is a template tag, collapse into last string\n    if (value?._templateType === TemplateType.part) {\n      addToLastAndPushWithSuffix(\n        parsedStrings,\n        strings[nextStringIdx],\n        value.str,\n      )\n      addToLastAndPushWithSuffix(\n        parsedStrings.raw,\n        strings.raw[nextStringIdx],\n        value.str,\n      )\n      continue\n    }\n\n    // if value is an output of this method, append in place\n    if (value?._templateType === TemplateType.container) {\n      addToLastAndPushWithSuffix(\n        parsedStrings,\n        strings[nextStringIdx],\n        ...value.strings,\n      )\n      addToLastAndPushWithSuffix(\n        parsedStrings.raw,\n        strings.raw[nextStringIdx],\n        ...value.strings.raw,\n      )\n      parsedValues.push(...value.values)\n      continue\n    }\n\n    // otherwise keep reconstructing\n    parsedStrings.push(strings[nextStringIdx])\n    parsedStrings.raw.push(strings.raw[nextStringIdx])\n    parsedValues.push(value)\n  }\n\n  return {\n    _templateType: 'container',\n    strings: parsedStrings,\n    values: parsedValues,\n  }\n}\n\n/**\n * Allows adding identifiers into a query template string without\n * parametrizing them. This method will automatically escape identifiers.\n *\n * @example\n * ```ts\n * query`SELECT * FROM ${identifier`foo`} WHERE ${identifier`id`} = ${id}`\n * // > { query: 'SELECT * FROM \"foo\" WHERE \"id\" = $1', params: [id] }\n * ```\n */\nexport function identifier(\n  strings: TemplateStringsArray,\n  ...values: any[]\n): TemplatePart {\n  return {\n    _templateType: 'part',\n    str: `\"${String.raw(strings, ...values)}\"`,\n  }\n}\n\n/**\n * Allows adding raw strings into a query template string without\n * parametrizing or modifying them in any way.\n *\n * @example\n * ```ts\n * query`SELECT * FROM foo ${raw`WHERE id = ${2+3}`}`\n * // > { query: 'SELECT * FROM foo WHERE id = 5', params: [] }\n * ```\n */\n\nexport function raw(\n  strings: TemplateStringsArray,\n  ...values: any[]\n): TemplatePart {\n  return {\n    _templateType: 'part',\n    str: String.raw(strings, ...values),\n  }\n}\n\n/**\n * Generates a parametrized query from a templated query string, assigning\n * the provided values to the appropriate named parameters.\n *\n * You can use templating helpers like {@link identifier} and {@link raw} to\n * add identifiers and raw strings to the query without making them parameters,\n * and you can use {@link sql} to nest multiple queries and create utilities.\n *\n * @example\n * ```ts\n * query`SELECT * FROM ${identifier`foo`} WHERE id = ${id} and name = ${name}`\n * // > { query: 'SELECT * FROM \"foo\" WHERE id = $1 and name = $2', params: [id, name] }\n * ```\n */\nexport function query(\n  strings: TemplateStringsArray,\n  ...values: any[]\n): TemplatedQuery {\n  const { strings: queryStringParts, values: params } = sql(strings, ...values)\n  return {\n    query: [\n      queryStringParts[0],\n      ...params.flatMap((_, idx) => [`$${idx + 1}`, queryStringParts[idx + 1]]),\n    ].join(''),\n    params: params,\n  }\n}\n","/*\nBased on postgres.js types.js\nhttps://github.com/porsager/postgres/blob/master/src/types.js\nPublished under the Unlicense:\nhttps://github.com/porsager/postgres/blob/master/UNLICENSE \n*/\n\nimport type { ParserOptions } from './interface.js'\n\nconst JSON_parse = globalThis.JSON.parse\nconst JSON_stringify = globalThis.JSON.stringify\n\nexport const BOOL = 16,\n  BYTEA = 17,\n  CHAR = 18,\n  INT8 = 20,\n  INT2 = 21,\n  INT4 = 23,\n  REGPROC = 24,\n  TEXT = 25,\n  OID = 26,\n  TID = 27,\n  XID = 28,\n  CID = 29,\n  JSON = 114,\n  XML = 142,\n  PG_NODE_TREE = 194,\n  SMGR = 210,\n  PATH = 602,\n  POLYGON = 604,\n  CIDR = 650,\n  FLOAT4 = 700,\n  FLOAT8 = 701,\n  ABSTIME = 702,\n  RELTIME = 703,\n  TINTERVAL = 704,\n  CIRCLE = 718,\n  MACADDR8 = 774,\n  MONEY = 790,\n  MACADDR = 829,\n  INET = 869,\n  ACLITEM = 1033,\n  BPCHAR = 1042,\n  VARCHAR = 1043,\n  DATE = 1082,\n  TIME = 1083,\n  TIMESTAMP = 1114,\n  TIMESTAMPTZ = 1184,\n  INTERVAL = 1186,\n  TIMETZ = 1266,\n  BIT = 1560,\n  VARBIT = 1562,\n  NUMERIC = 1700,\n  REFCURSOR = 1790,\n  REGPROCEDURE = 2202,\n  REGOPER = 2203,\n  REGOPERATOR = 2204,\n  REGCLASS = 2205,\n  REGTYPE = 2206,\n  UUID = 2950,\n  TXID_SNAPSHOT = 2970,\n  PG_LSN = 3220,\n  PG_NDISTINCT = 3361,\n  PG_DEPENDENCIES = 3402,\n  TSVECTOR = 3614,\n  TSQUERY = 3615,\n  GTSVECTOR = 3642,\n  REGCONFIG = 3734,\n  REGDICTIONARY = 3769,\n  JSONB = 3802,\n  REGNAMESPACE = 4089,\n  REGROLE = 4096\n\nexport const types = {\n  string: {\n    to: TEXT,\n    from: [TEXT, VARCHAR, BPCHAR],\n    serialize: (x: string | number) => {\n      if (typeof x === 'string') {\n        return x\n      } else if (typeof x === 'number') {\n        return x.toString()\n      } else {\n        throw new Error('Invalid input for string type')\n      }\n    },\n    parse: (x: string) => x,\n  },\n  number: {\n    to: 0,\n    from: [INT2, INT4, OID, FLOAT4, FLOAT8],\n    serialize: (x: number) => x.toString(),\n    parse: (x: string) => +x,\n  },\n  bigint: {\n    to: INT8,\n    from: [INT8],\n    serialize: (x: bigint) => x.toString(),\n    parse: (x: string) => {\n      const n = BigInt(x)\n      if (n < Number.MIN_SAFE_INTEGER || n > Number.MAX_SAFE_INTEGER) {\n        return n // return BigInt\n      } else {\n        return Number(n) // in range of standard JS numbers so return number\n      }\n    },\n  },\n  json: {\n    to: JSON,\n    from: [JSON, JSONB],\n    serialize: (x: any) => {\n      if (typeof x === 'string') {\n        return x\n      } else {\n        return JSON_stringify(x)\n      }\n    },\n    parse: (x: string) => JSON_parse(x),\n  },\n  boolean: {\n    to: BOOL,\n    from: [BOOL],\n    serialize: (x: boolean) => {\n      if (typeof x !== 'boolean') {\n        throw new Error('Invalid input for boolean type')\n      }\n      return x ? 't' : 'f'\n    },\n    parse: (x: string) => x === 't',\n  },\n  date: {\n    to: TIMESTAMPTZ,\n    from: [DATE, TIMESTAMP, TIMESTAMPTZ],\n    serialize: (x: Date | string | number) => {\n      if (typeof x === 'string') {\n        return x\n      } else if (typeof x === 'number') {\n        return new Date(x).toISOString()\n      } else if (x instanceof Date) {\n        return x.toISOString()\n      } else {\n        throw new Error('Invalid input for date type')\n      }\n    },\n    parse: (x: string | number) => new Date(x),\n  },\n  bytea: {\n    to: BYTEA,\n    from: [BYTEA],\n    serialize: (x: Uint8Array) => {\n      if (!(x instanceof Uint8Array)) {\n        throw new Error('Invalid input for bytea type')\n      }\n      return (\n        '\\\\x' +\n        Array.from(x)\n          .map((byte) => byte.toString(16).padStart(2, '0'))\n          .join('')\n      )\n    },\n    parse: (x: string): Uint8Array => {\n      const hexString = x.slice(2)\n      return Uint8Array.from({ length: hexString.length / 2 }, (_, idx) =>\n        parseInt(hexString.substring(idx * 2, (idx + 1) * 2), 16),\n      )\n    },\n  },\n} satisfies TypeHandlers\n\nexport type Parser = (x: string, typeId?: number) => any\nexport type Serializer = (x: any) => string\n\nexport type TypeHandler = {\n  to: number\n  from: number | number[]\n  serialize: Serializer\n  parse: Parser\n}\n\nexport type TypeHandlers = {\n  [key: string]: TypeHandler\n}\n\nconst defaultHandlers = typeHandlers(types)\n\nexport const parsers = defaultHandlers.parsers\nexport const serializers = defaultHandlers.serializers\n\nexport function parseType(\n  x: string | null,\n  type: number,\n  parsers?: ParserOptions,\n): any {\n  if (x === null) {\n    return null\n  }\n  const handler = parsers?.[type] ?? defaultHandlers.parsers[type]\n  if (handler) {\n    return handler(x, type)\n  } else {\n    return x\n  }\n}\n\nfunction typeHandlers(types: TypeHandlers) {\n  return Object.keys(types).reduce(\n    ({ parsers, serializers }, k) => {\n      const { to, from, serialize, parse } = types[k]\n      serializers[to] = serialize\n      serializers[k] = serialize\n      parsers[k] = parse\n      if (Array.isArray(from)) {\n        from.forEach((f) => {\n          parsers[f] = parse\n          serializers[f] = serialize\n        })\n      } else {\n        parsers[from] = parse\n        serializers[from] = serialize\n      }\n      return { parsers, serializers }\n    },\n    {\n      parsers: {} as {\n        [key: number | string]: (x: string, typeId?: number) => any\n      },\n      serializers: {} as {\n        [key: number | string]: Serializer\n      },\n    },\n  )\n}\n\nconst escapeBackslash = /\\\\/g\nconst escapeQuote = /\"/g\n\nfunction arrayEscape(x: string) {\n  return x.replace(escapeBackslash, '\\\\\\\\').replace(escapeQuote, '\\\\\"')\n}\n\nexport function arraySerializer(\n  xs: any,\n  serializer: Serializer | undefined,\n  typarray: number,\n): string {\n  if (Array.isArray(xs) === false) return xs\n\n  if (!xs.length) return '{}'\n\n  const first = xs[0]\n  // Only _box (1020) has the ';' delimiter for arrays, all other types use the ',' delimiter\n  const delimiter = typarray === 1020 ? ';' : ','\n\n  if (Array.isArray(first)) {\n    return `{${xs.map((x) => arraySerializer(x, serializer, typarray)).join(delimiter)}}`\n  } else {\n    return `{${xs\n      .map((x) => {\n        if (x === undefined) {\n          x = null\n          // TODO: Add an option to specify how to handle undefined values\n        }\n        return x === null\n          ? 'null'\n          : '\"' + arrayEscape(serializer ? serializer(x) : x.toString()) + '\"'\n      })\n      .join(delimiter)}}`\n  }\n}\n\nconst arrayParserState = {\n  i: 0,\n  char: null as string | null,\n  str: '',\n  quoted: false,\n  last: 0,\n  p: null as string | null,\n}\n\nexport function arrayParser(x: string, parser: Parser, typarray: number) {\n  arrayParserState.i = arrayParserState.last = 0\n  return arrayParserLoop(arrayParserState, x, parser, typarray)[0]\n}\n\nfunction arrayParserLoop(\n  s: typeof arrayParserState,\n  x: string,\n  parser: Parser | undefined,\n  typarray: number,\n): any[] {\n  const xs = []\n  // Only _box (1020) has the ';' delimiter for arrays, all other types use the ',' delimiter\n  const delimiter = typarray === 1020 ? ';' : ','\n  for (; s.i < x.length; s.i++) {\n    s.char = x[s.i]\n    if (s.quoted) {\n      if (s.char === '\\\\') {\n        s.str += x[++s.i]\n      } else if (s.char === '\"') {\n        xs.push(parser ? parser(s.str) : s.str)\n        s.str = ''\n        s.quoted = x[s.i + 1] === '\"'\n        s.last = s.i + 2\n      } else {\n        s.str += s.char\n      }\n    } else if (s.char === '\"') {\n      s.quoted = true\n    } else if (s.char === '{') {\n      s.last = ++s.i\n      xs.push(arrayParserLoop(s, x, parser, typarray))\n    } else if (s.char === '}') {\n      s.quoted = false\n      s.last < s.i &&\n        xs.push(parser ? parser(x.slice(s.last, s.i)) : x.slice(s.last, s.i))\n      s.last = s.i + 1\n      break\n    } else if (s.char === delimiter && s.p !== '}' && s.p !== '\"') {\n      xs.push(parser ? parser(x.slice(s.last, s.i)) : x.slice(s.last, s.i))\n      s.last = s.i + 1\n    }\n    s.p = s.char\n  }\n  s.last < s.i &&\n    xs.push(\n      parser ? parser(x.slice(s.last, s.i + 1)) : x.slice(s.last, s.i + 1),\n    )\n  return xs\n}\n","import {\n  BackendMessage,\n  RowDescriptionMessage,\n  DataRowMessage,\n  CommandCompleteMessage,\n  ParameterDescriptionMessage,\n} from '@electric-sql/pg-protocol/messages'\nimport type { Results, QueryOptions } from './interface.js'\nimport { parseType, type Parser } from './types.js'\n\n/**\n * This function is used to parse the results of either a simple or extended query.\n * https://www.postgresql.org/docs/current/protocol-flow.html#PROTOCOL-FLOW-SIMPLE-QUERY\n */\nexport function parseResults(\n  messages: Array<BackendMessage>,\n  defaultParsers: Record<number | string, Parser>,\n  options?: QueryOptions,\n  blob?: Blob,\n): Array<Results> {\n  const resultSets: Results[] = []\n  let currentResultSet: Results = { rows: [], fields: [] }\n  let affectedRows = 0\n  const parsers = { ...defaultParsers, ...options?.parsers }\n\n  messages.forEach((message) => {\n    switch (message.name) {\n      case 'rowDescription': {\n        const msg = message as RowDescriptionMessage\n        currentResultSet.fields = msg.fields.map((field) => ({\n          name: field.name,\n          dataTypeID: field.dataTypeID,\n        }))\n        break\n      }\n      case 'dataRow': {\n        if (!currentResultSet) break\n        const msg = message as DataRowMessage\n        if (options?.rowMode === 'array') {\n          currentResultSet.rows.push(\n            msg.fields.map((field, i) =>\n              parseType(field, currentResultSet!.fields[i].dataTypeID, parsers),\n            ),\n          )\n        } else {\n          // rowMode === \"object\"\n          currentResultSet.rows.push(\n            Object.fromEntries(\n              msg.fields.map((field, i) => [\n                currentResultSet!.fields[i].name,\n                parseType(\n                  field,\n                  currentResultSet!.fields[i].dataTypeID,\n                  parsers,\n                ),\n              ]),\n            ),\n          )\n        }\n        break\n      }\n      case 'commandComplete': {\n        const msg = message as CommandCompleteMessage\n        affectedRows += retrieveRowCount(msg)\n\n        resultSets.push({\n          ...currentResultSet,\n          affectedRows,\n          ...(blob ? { blob } : {}),\n        })\n\n        currentResultSet = { rows: [], fields: [] }\n        break\n      }\n    }\n  })\n\n  if (resultSets.length === 0) {\n    resultSets.push({\n      affectedRows: 0,\n      rows: [],\n      fields: [],\n    })\n  }\n\n  return resultSets\n}\n\nfunction retrieveRowCount(msg: CommandCompleteMessage): number {\n  const parts = msg.text.split(' ')\n  switch (parts[0]) {\n    case 'INSERT':\n      return parseInt(parts[2], 10)\n    case 'UPDATE':\n    case 'DELETE':\n    case 'COPY':\n      return parseInt(parts[1], 10)\n    default:\n      return 0\n  }\n}\n\n/** Get the dataTypeIDs from a list of messages, if it's available. */\nexport function parseDescribeStatementResults(\n  messages: Array<BackendMessage>,\n): number[] {\n  const message = messages.find(\n    (msg): msg is ParameterDescriptionMessage =>\n      msg.name === 'parameterDescription',\n  )\n\n  if (message) {\n    return message.dataTypeIDs\n  }\n\n  return []\n}\n","/**\n * Calculates the byte length of a UTF-8 encoded string\n * Adapted from https://stackoverflow.com/a/23329386\n * @param str - UTF-8 encoded string\n * @returns byte length of string\n */\nfunction byteLengthUtf8(str: string): number {\n  let byteLength = str.length\n  for (let i = str.length - 1; i >= 0; i--) {\n    const code = str.charCodeAt(i)\n    if (code > 0x7f && code <= 0x7ff) byteLength++\n    else if (code > 0x7ff && code <= 0xffff) byteLength += 2\n    if (code >= 0xdc00 && code <= 0xdfff) i-- // trail surrogate\n  }\n  return byteLength\n}\n\nexport { byteLengthUtf8 }\n","import { byteLengthUtf8 } from './string-utils'\n\nexport class Writer {\n  #bufferView: DataView\n  #offset: number = 5\n\n  readonly #littleEndian = false as const\n  readonly #encoder = new TextEncoder()\n  readonly #headerPosition: number = 0\n  constructor(private size = 256) {\n    this.#bufferView = this.#allocateBuffer(size)\n  }\n\n  #allocateBuffer(size: number): DataView {\n    return new DataView(new ArrayBuffer(size))\n  }\n\n  #ensure(size: number): void {\n    const remaining = this.#bufferView.byteLength - this.#offset\n    if (remaining < size) {\n      const oldBuffer = this.#bufferView.buffer\n      // exponential growth factor of around ~ 1.5\n      // https://stackoverflow.com/questions/2269063/buffer-growth-strategy\n      const newSize = oldBuffer.byteLength + (oldBuffer.byteLength >> 1) + size\n      this.#bufferView = this.#allocateBuffer(newSize)\n      new Uint8Array(this.#bufferView.buffer).set(new Uint8Array(oldBuffer))\n    }\n  }\n\n  public addInt32(num: number): Writer {\n    this.#ensure(4)\n    this.#bufferView.setInt32(this.#offset, num, this.#littleEndian)\n    this.#offset += 4\n    return this\n  }\n\n  public addInt16(num: number): Writer {\n    this.#ensure(2)\n    this.#bufferView.setInt16(this.#offset, num, this.#littleEndian)\n    this.#offset += 2\n    return this\n  }\n\n  public addCString(string: string): Writer {\n    if (string) {\n      // TODO(msfstef): might be faster to extract `addString` code and\n      // ensure length + 1 once rather than length and then +1?\n      this.addString(string)\n    }\n\n    // set null terminator\n    this.#ensure(1)\n    this.#bufferView.setUint8(this.#offset, 0)\n    this.#offset++\n    return this\n  }\n\n  public addString(string: string = ''): Writer {\n    const length = byteLengthUtf8(string)\n    this.#ensure(length)\n    this.#encoder.encodeInto(\n      string,\n      new Uint8Array(this.#bufferView.buffer, this.#offset),\n    )\n    this.#offset += length\n    return this\n  }\n\n  public add(otherBuffer: ArrayBuffer): Writer {\n    this.#ensure(otherBuffer.byteLength)\n    new Uint8Array(this.#bufferView.buffer).set(\n      new Uint8Array(otherBuffer),\n      this.#offset,\n    )\n\n    this.#offset += otherBuffer.byteLength\n    return this\n  }\n\n  #join(code?: number): ArrayBuffer {\n    if (code) {\n      this.#bufferView.setUint8(this.#headerPosition, code)\n      // length is everything in this packet minus the code\n      const length = this.#offset - (this.#headerPosition + 1)\n      this.#bufferView.setInt32(\n        this.#headerPosition + 1,\n        length,\n        this.#littleEndian,\n      )\n    }\n    return this.#bufferView.buffer.slice(code ? 0 : 5, this.#offset)\n  }\n\n  public flush(code?: number): Uint8Array {\n    const result = this.#join(code)\n    this.#offset = 5\n    this.#bufferView = this.#allocateBuffer(this.size)\n    return new Uint8Array(result)\n  }\n}\n","import { Writer } from './buffer-writer'\nimport { byteLengthUtf8 } from './string-utils'\n\nconst enum code {\n  startup = 0x70,\n  query = 0x51,\n  parse = 0x50,\n  bind = 0x42,\n  execute = 0x45,\n  flush = 0x48,\n  sync = 0x53,\n  end = 0x58,\n  close = 0x43,\n  describe = 0x44,\n  copyFromChunk = 0x64,\n  copyDone = 0x63,\n  copyFail = 0x66,\n}\n\ntype LegalValue = string | ArrayBuffer | ArrayBufferView | null\n\nconst writer = new Writer()\n\nconst startup = (opts: Record<string, string>): Uint8Array => {\n  // protocol version\n  writer.addInt16(3).addInt16(0)\n  for (const key of Object.keys(opts)) {\n    writer.addCString(key).addCString(opts[key])\n  }\n\n  writer.addCString('client_encoding').addCString('UTF8')\n\n  const bodyBuffer = writer.addCString('').flush()\n  // this message is sent without a code\n\n  const length = bodyBuffer.byteLength + 4\n\n  return new Writer().addInt32(length).add(bodyBuffer).flush()\n}\n\nconst requestSsl = (): Uint8Array => {\n  const bufferView = new DataView(new ArrayBuffer(8))\n  bufferView.setInt32(0, 8, false)\n  bufferView.setInt32(4, 80877103, false)\n  return new Uint8Array(bufferView.buffer)\n}\n\nconst password = (password: string): Uint8Array => {\n  return writer.addCString(password).flush(code.startup)\n}\n\nconst sendSASLInitialResponseMessage = (\n  mechanism: string,\n  initialResponse: string,\n): Uint8Array => {\n  // 0x70 = 'p'\n  writer\n    .addCString(mechanism)\n    .addInt32(byteLengthUtf8(initialResponse))\n    .addString(initialResponse)\n\n  return writer.flush(code.startup)\n}\n\nconst sendSCRAMClientFinalMessage = (additionalData: string): Uint8Array => {\n  return writer.addString(additionalData).flush(code.startup)\n}\n\nconst query = (text: string): Uint8Array => {\n  return writer.addCString(text).flush(code.query)\n}\n\ntype ParseOpts = {\n  name?: string\n  types?: number[]\n  text: string\n}\n\nconst emptyValueArray: LegalValue[] = []\n\nconst parse = (query: ParseOpts): Uint8Array => {\n  // expect something like this:\n  // { name: 'queryName',\n  //   text: 'select * from blah',\n  //   types: ['int8', 'bool'] }\n\n  // normalize missing query names to allow for null\n  const name = query.name ?? ''\n  if (name.length > 63) {\n    /* eslint-disable no-console */\n    console.error(\n      'Warning! Postgres only supports 63 characters for query names.',\n    )\n    console.error('You supplied %s (%s)', name, name.length)\n    console.error(\n      'This can cause conflicts and silent errors executing queries',\n    )\n    /* eslint-enable no-console */\n  }\n\n  const buffer = writer\n    .addCString(name) // name of query\n    .addCString(query.text) // actual query text\n    .addInt16(query.types?.length ?? 0)\n\n  query.types?.forEach((type) => buffer.addInt32(type))\n\n  return writer.flush(code.parse)\n}\n\ntype ValueMapper = (param: unknown, index: number) => LegalValue\n\ntype BindOpts = {\n  portal?: string\n  binary?: boolean\n  statement?: string\n  values?: LegalValue[]\n  // optional map from JS value to postgres value per parameter\n  valueMapper?: ValueMapper\n}\n\nconst paramWriter = new Writer()\n\n// make this a const enum so typescript will inline the value\nconst enum ParamType {\n  STRING = 0,\n  BINARY = 1,\n}\n\nconst writeValues = (values: LegalValue[], valueMapper?: ValueMapper): void => {\n  for (let i = 0; i < values.length; i++) {\n    const mappedVal = valueMapper ? valueMapper(values[i], i) : values[i]\n    if (mappedVal === null) {\n      // add the param type (string) to the writer\n      writer.addInt16(ParamType.STRING)\n      // write -1 to the param writer to indicate null\n      paramWriter.addInt32(-1)\n    } else if (\n      mappedVal instanceof ArrayBuffer ||\n      ArrayBuffer.isView(mappedVal)\n    ) {\n      const buffer = ArrayBuffer.isView(mappedVal)\n        ? mappedVal.buffer.slice(\n            mappedVal.byteOffset,\n            mappedVal.byteOffset + mappedVal.byteLength,\n          )\n        : mappedVal\n      // add the param type (binary) to the writer\n      writer.addInt16(ParamType.BINARY)\n      // add the buffer to the param writer\n      paramWriter.addInt32(buffer.byteLength)\n      paramWriter.add(buffer)\n    } else {\n      // add the param type (string) to the writer\n      writer.addInt16(ParamType.STRING)\n      paramWriter.addInt32(byteLengthUtf8(mappedVal))\n      paramWriter.addString(mappedVal)\n    }\n  }\n}\n\nconst bind = (config: BindOpts = {}): Uint8Array => {\n  // normalize config\n  const portal = config.portal ?? ''\n  const statement = config.statement ?? ''\n  const binary = config.binary ?? false\n  const values = config.values ?? emptyValueArray\n  const len = values.length\n\n  writer.addCString(portal).addCString(statement)\n  writer.addInt16(len)\n\n  writeValues(values, config.valueMapper)\n\n  writer.addInt16(len)\n  writer.add(paramWriter.flush())\n\n  // format code\n  writer.addInt16(binary ? ParamType.BINARY : ParamType.STRING)\n  return writer.flush(code.bind)\n}\n\ntype ExecOpts = {\n  portal?: string\n  rows?: number\n}\n\nconst emptyExecute = new Uint8Array([\n  code.execute,\n  0x00,\n  0x00,\n  0x00,\n  0x09,\n  0x00,\n  0x00,\n  0x00,\n  0x00,\n  0x00,\n])\n\nconst execute = (config?: ExecOpts): Uint8Array => {\n  // this is the happy path for most queries\n  if (!config || (!config.portal && !config.rows)) {\n    return emptyExecute\n  }\n\n  const portal = config.portal ?? ''\n  const rows = config.rows ?? 0\n\n  const portalLength = byteLengthUtf8(portal)\n  const len = 4 + portalLength + 1 + 4\n  // one extra bit for code\n  const bufferView = new DataView(new ArrayBuffer(1 + len))\n  bufferView.setUint8(0, code.execute)\n  bufferView.setInt32(1, len, false)\n  new TextEncoder().encodeInto(portal, new Uint8Array(bufferView.buffer, 5))\n  bufferView.setUint8(portalLength + 5, 0) // null terminate portal cString\n  bufferView.setUint32(bufferView.byteLength - 4, rows, false)\n  return new Uint8Array(bufferView.buffer)\n}\n\nconst cancel = (processID: number, secretKey: number): Uint8Array => {\n  const bufferView = new DataView(new ArrayBuffer(16))\n  bufferView.setInt32(0, 16, false)\n  bufferView.setInt16(4, 1234, false)\n  bufferView.setInt16(6, 5678, false)\n  bufferView.setInt32(8, processID, false)\n  bufferView.setInt32(12, secretKey, false)\n  return new Uint8Array(bufferView.buffer)\n}\n\ntype PortalOpts = {\n  type: 'S' | 'P'\n  name?: string\n}\n\nconst cstringMessage = (code: code, string: string): Uint8Array => {\n  const writer = new Writer()\n  writer.addCString(string)\n  return writer.flush(code)\n}\n\nconst emptyDescribePortal = writer.addCString('P').flush(code.describe)\nconst emptyDescribeStatement = writer.addCString('S').flush(code.describe)\n\nconst describe = (msg: PortalOpts): Uint8Array => {\n  return msg.name\n    ? cstringMessage(code.describe, `${msg.type}${msg.name ?? ''}`)\n    : msg.type === 'P'\n      ? emptyDescribePortal\n      : emptyDescribeStatement\n}\n\nconst close = (msg: PortalOpts): Uint8Array => {\n  const text = `${msg.type}${msg.name ?? ''}`\n  return cstringMessage(code.close, text)\n}\n\nconst copyData = (chunk: ArrayBuffer): Uint8Array => {\n  return writer.add(chunk).flush(code.copyFromChunk)\n}\n\nconst copyFail = (message: string): Uint8Array => {\n  return cstringMessage(code.copyFail, message)\n}\n\nconst codeOnlyBuffer = (code: code): Uint8Array =>\n  new Uint8Array([code, 0x00, 0x00, 0x00, 0x04])\n\nconst flushBuffer = codeOnlyBuffer(code.flush)\nconst syncBuffer = codeOnlyBuffer(code.sync)\nconst endBuffer = codeOnlyBuffer(code.end)\nconst copyDoneBuffer = codeOnlyBuffer(code.copyDone)\n\nconst serialize = {\n  startup,\n  password,\n  requestSsl,\n  sendSASLInitialResponseMessage,\n  sendSCRAMClientFinalMessage,\n  query,\n  parse,\n  bind,\n  execute,\n  describe,\n  close,\n  flush: () => flushBuffer,\n  sync: () => syncBuffer,\n  end: () => endBuffer,\n  copyData,\n  copyDone: () => copyDoneBuffer,\n  copyFail,\n  cancel,\n}\n\nexport { serialize }\n","const emptyBuffer = new ArrayBuffer(0)\n\nexport class BufferReader {\n  #bufferView: DataView = new DataView(emptyBuffer)\n  #offset: number\n\n  // TODO(bmc): support non-utf8 encoding?\n  readonly #encoding: string = 'utf-8' as const\n  readonly #decoder = new TextDecoder(this.#encoding)\n  readonly #littleEndian: boolean = false as const\n\n  constructor(offset: number = 0) {\n    this.#offset = offset\n  }\n\n  public setBuffer(offset: number, buffer: ArrayBuffer): void {\n    this.#offset = offset\n    this.#bufferView = new DataView(buffer)\n  }\n\n  public int16(): number {\n    // const result = this.buffer.readInt16BE(this.#offset)\n    const result = this.#bufferView.getInt16(this.#offset, this.#littleEndian)\n    this.#offset += 2\n    return result\n  }\n\n  public byte(): number {\n    // const result = this.bufferView[this.#offset]\n    const result = this.#bufferView.getUint8(this.#offset)\n    this.#offset++\n    return result\n  }\n\n  public int32(): number {\n    // const result = this.buffer.readInt32BE(this.#offset)\n    const result = this.#bufferView.getInt32(this.#offset, this.#littleEndian)\n    this.#offset += 4\n    return result\n  }\n\n  public string(length: number): string {\n    // const result = this.#bufferView.toString(\n    //   this.#encoding,\n    //   this.#offset,\n    //   this.#offset + length,\n    // )\n    // this.#offset += length\n\n    const result = this.#decoder.decode(this.bytes(length))\n    return result\n  }\n\n  public cstring(): string {\n    // const start = this.#offset\n    // let end = start\n    // while (this.#bufferView[end++] !== 0) {}\n\n    const start = this.#offset\n    let end = start\n    while (this.#bufferView.getUint8(end++) !== 0) {\n      // no-op - increment until terminator reached\n    }\n    const result = this.string(end - start - 1)\n    this.#offset = end\n    return result\n  }\n\n  public bytes(length: number): Uint8Array {\n    // const result = this.buffer.slice(this.#offset, this.#offset + length)\n    const result = this.#bufferView.buffer.slice(\n      this.#offset,\n      this.#offset + length,\n    )\n    this.#offset += length\n    return new Uint8Array(result)\n  }\n}\n","import {\n  bindComplete,\n  parseComplete,\n  closeComplete,\n  noData,\n  portalSuspended,\n  copyDone,\n  replicationStart,\n  emptyQuery,\n  ReadyForQueryMessage,\n  CommandCompleteMessage,\n  CopyDataMessage,\n  CopyResponse,\n  NotificationResponseMessage,\n  RowDescriptionMessage,\n  ParameterDescriptionMessage,\n  Field,\n  DataRowMessage,\n  ParameterStatusMessage,\n  BackendKeyDataMessage,\n  DatabaseError,\n  BackendMessage,\n  MessageName,\n  NoticeMessage,\n  AuthenticationMessage,\n  AuthenticationOk,\n  AuthenticationCleartextPassword,\n  AuthenticationMD5Password,\n  AuthenticationSASL,\n  AuthenticationSASLContinue,\n  AuthenticationSASLFinal,\n} from './messages'\nimport { BufferParameter, Modes } from './types'\nimport { BufferReader } from './buffer-reader'\n\n// every message is prefixed with a single bye\nconst CODE_LENGTH = 1 as const\n// every message has an int32 length which includes itself but does\n// NOT include the code in the length\nconst LEN_LENGTH = 4 as const\n\nconst HEADER_LENGTH = CODE_LENGTH + LEN_LENGTH\n\nexport type Packet = {\n  code: number\n  packet: ArrayBuffer\n}\n\nconst emptyBuffer = new ArrayBuffer(0)\n\nconst enum MessageCodes {\n  DataRow = 0x44, // D\n  ParseComplete = 0x31, // 1\n  BindComplete = 0x32, // 2\n  CloseComplete = 0x33, // 3\n  CommandComplete = 0x43, // C\n  ReadyForQuery = 0x5a, // Z\n  NoData = 0x6e, // n\n  NotificationResponse = 0x41, // A\n  AuthenticationResponse = 0x52, // R\n  ParameterStatus = 0x53, // S\n  BackendKeyData = 0x4b, // K\n  ErrorMessage = 0x45, // E\n  NoticeMessage = 0x4e, // N\n  RowDescriptionMessage = 0x54, // T\n  ParameterDescriptionMessage = 0x74, // t\n  PortalSuspended = 0x73, // s\n  ReplicationStart = 0x57, // W\n  EmptyQuery = 0x49, // I\n  CopyIn = 0x47, // G\n  CopyOut = 0x48, // H\n  CopyDone = 0x63, // c\n  CopyData = 0x64, // d\n}\n\nexport type MessageCallback = (msg: BackendMessage) => void\n\nexport class Parser {\n  #bufferView: DataView = new DataView(emptyBuffer)\n  #bufferRemainingLength: number = 0\n  #bufferOffset: number = 0\n  #reader = new BufferReader()\n\n  public parse(buffer: BufferParameter, callback: MessageCallback) {\n    this.#mergeBuffer(\n      ArrayBuffer.isView(buffer)\n        ? buffer.buffer.slice(\n            buffer.byteOffset,\n            buffer.byteOffset + buffer.byteLength,\n          )\n        : buffer,\n    )\n    const bufferFullLength = this.#bufferOffset + this.#bufferRemainingLength\n    let offset = this.#bufferOffset\n    while (offset + HEADER_LENGTH <= bufferFullLength) {\n      // code is 1 byte long - it identifies the message type\n      const code = this.#bufferView.getUint8(offset)\n      // length is 1 Uint32BE - it is the length of the message EXCLUDING the code\n      const length = this.#bufferView.getUint32(offset + CODE_LENGTH, false)\n      const fullMessageLength = CODE_LENGTH + length\n      if (fullMessageLength + offset <= bufferFullLength) {\n        const message = this.#handlePacket(\n          offset + HEADER_LENGTH,\n          code,\n          length,\n          this.#bufferView.buffer,\n        )\n        callback(message)\n        offset += fullMessageLength\n      } else {\n        break\n      }\n    }\n    if (offset === bufferFullLength) {\n      // No more use for the buffer\n      this.#bufferView = new DataView(emptyBuffer)\n      this.#bufferRemainingLength = 0\n      this.#bufferOffset = 0\n    } else {\n      // Adjust the cursors of remainingBuffer\n      this.#bufferRemainingLength = bufferFullLength - offset\n      this.#bufferOffset = offset\n    }\n  }\n\n  #mergeBuffer(buffer: ArrayBuffer): void {\n    if (this.#bufferRemainingLength > 0) {\n      const newLength = this.#bufferRemainingLength + buffer.byteLength\n      const newFullLength = newLength + this.#bufferOffset\n      if (newFullLength > this.#bufferView.byteLength) {\n        // We can't concat the new buffer with the remaining one\n        let newBuffer: ArrayBuffer\n        if (\n          newLength <= this.#bufferView.byteLength &&\n          this.#bufferOffset >= this.#bufferRemainingLength\n        ) {\n          // We can move the relevant part to the beginning of the buffer instead of allocating a new buffer\n          newBuffer = this.#bufferView.buffer\n        } else {\n          // Allocate a new larger buffer\n          let newBufferLength = this.#bufferView.byteLength * 2\n          while (newLength >= newBufferLength) {\n            newBufferLength *= 2\n          }\n          newBuffer = new ArrayBuffer(newBufferLength)\n        }\n        // Move the remaining buffer to the new one\n        new Uint8Array(newBuffer).set(\n          new Uint8Array(\n            this.#bufferView.buffer,\n            this.#bufferOffset,\n            this.#bufferRemainingLength,\n          ),\n        )\n        this.#bufferView = new DataView(newBuffer)\n        this.#bufferOffset = 0\n      }\n\n      // Concat the new buffer with the remaining one\n      new Uint8Array(this.#bufferView.buffer).set(\n        new Uint8Array(buffer),\n        this.#bufferOffset + this.#bufferRemainingLength,\n      )\n      this.#bufferRemainingLength = newLength\n    } else {\n      this.#bufferView = new DataView(buffer)\n      this.#bufferOffset = 0\n      this.#bufferRemainingLength = buffer.byteLength\n    }\n  }\n\n  #handlePacket(\n    offset: number,\n    code: number,\n    length: number,\n    bytes: ArrayBuffer,\n  ): BackendMessage {\n    switch (code) {\n      case MessageCodes.BindComplete:\n        return bindComplete\n      case MessageCodes.ParseComplete:\n        return parseComplete\n      case MessageCodes.CloseComplete:\n        return closeComplete\n      case MessageCodes.NoData:\n        return noData\n      case MessageCodes.PortalSuspended:\n        return portalSuspended\n      case MessageCodes.CopyDone:\n        return copyDone\n      case MessageCodes.ReplicationStart:\n        return replicationStart\n      case MessageCodes.EmptyQuery:\n        return emptyQuery\n      case MessageCodes.DataRow:\n        return this.#parseDataRowMessage(offset, length, bytes)\n      case MessageCodes.CommandComplete:\n        return this.#parseCommandCompleteMessage(offset, length, bytes)\n      case MessageCodes.ReadyForQuery:\n        return this.#parseReadyForQueryMessage(offset, length, bytes)\n      case MessageCodes.NotificationResponse:\n        return this.#parseNotificationMessage(offset, length, bytes)\n      case MessageCodes.AuthenticationResponse:\n        return this.#parseAuthenticationResponse(offset, length, bytes)\n      case MessageCodes.ParameterStatus:\n        return this.#parseParameterStatusMessage(offset, length, bytes)\n      case MessageCodes.BackendKeyData:\n        return this.#parseBackendKeyData(offset, length, bytes)\n      case MessageCodes.ErrorMessage:\n        return this.#parseErrorMessage(offset, length, bytes, 'error')\n      case MessageCodes.NoticeMessage:\n        return this.#parseErrorMessage(offset, length, bytes, 'notice')\n      case MessageCodes.RowDescriptionMessage:\n        return this.#parseRowDescriptionMessage(offset, length, bytes)\n      case MessageCodes.ParameterDescriptionMessage:\n        return this.#parseParameterDescriptionMessage(offset, length, bytes)\n      case MessageCodes.CopyIn:\n        return this.#parseCopyInMessage(offset, length, bytes)\n      case MessageCodes.CopyOut:\n        return this.#parseCopyOutMessage(offset, length, bytes)\n      case MessageCodes.CopyData:\n        return this.#parseCopyData(offset, length, bytes)\n      default:\n        return new DatabaseError(\n          'received invalid response: ' + code.toString(16),\n          length,\n          'error',\n        )\n    }\n  }\n\n  #parseReadyForQueryMessage(\n    offset: number,\n    length: number,\n    bytes: ArrayBuffer,\n  ) {\n    this.#reader.setBuffer(offset, bytes)\n    const status = this.#reader.string(1)\n    return new ReadyForQueryMessage(length, status)\n  }\n\n  #parseCommandCompleteMessage(\n    offset: number,\n    length: number,\n    bytes: ArrayBuffer,\n  ) {\n    this.#reader.setBuffer(offset, bytes)\n    const text = this.#reader.cstring()\n    return new CommandCompleteMessage(length, text)\n  }\n\n  #parseCopyData(offset: number, length: number, bytes: ArrayBuffer) {\n    const chunk = bytes.slice(offset, offset + (length - 4))\n    return new CopyDataMessage(length, new Uint8Array(chunk))\n  }\n\n  #parseCopyInMessage(offset: number, length: number, bytes: ArrayBuffer) {\n    return this.#parseCopyMessage(offset, length, bytes, 'copyInResponse')\n  }\n\n  #parseCopyOutMessage(offset: number, length: number, bytes: ArrayBuffer) {\n    return this.#parseCopyMessage(offset, length, bytes, 'copyOutResponse')\n  }\n\n  #parseCopyMessage(\n    offset: number,\n    length: number,\n    bytes: ArrayBuffer,\n    messageName: MessageName,\n  ) {\n    this.#reader.setBuffer(offset, bytes)\n    const isBinary = this.#reader.byte() !== 0\n    const columnCount = this.#reader.int16()\n    const message = new CopyResponse(length, messageName, isBinary, columnCount)\n    for (let i = 0; i < columnCount; i++) {\n      message.columnTypes[i] = this.#reader.int16()\n    }\n    return message\n  }\n\n  #parseNotificationMessage(\n    offset: number,\n    length: number,\n    bytes: ArrayBuffer,\n  ) {\n    this.#reader.setBuffer(offset, bytes)\n    const processId = this.#reader.int32()\n    const channel = this.#reader.cstring()\n    const payload = this.#reader.cstring()\n    return new NotificationResponseMessage(length, processId, channel, payload)\n  }\n\n  #parseRowDescriptionMessage(\n    offset: number,\n    length: number,\n    bytes: ArrayBuffer,\n  ) {\n    this.#reader.setBuffer(offset, bytes)\n    const fieldCount = this.#reader.int16()\n    const message = new RowDescriptionMessage(length, fieldCount)\n    for (let i = 0; i < fieldCount; i++) {\n      message.fields[i] = this.#parseField()\n    }\n    return message\n  }\n\n  #parseField(): Field {\n    const name = this.#reader.cstring()\n    const tableID = this.#reader.int32()\n    const columnID = this.#reader.int16()\n    const dataTypeID = this.#reader.int32()\n    const dataTypeSize = this.#reader.int16()\n    const dataTypeModifier = this.#reader.int32()\n    const mode = this.#reader.int16() === 0 ? Modes.text : Modes.binary\n    return new Field(\n      name,\n      tableID,\n      columnID,\n      dataTypeID,\n      dataTypeSize,\n      dataTypeModifier,\n      mode,\n    )\n  }\n\n  #parseParameterDescriptionMessage(\n    offset: number,\n    length: number,\n    bytes: ArrayBuffer,\n  ) {\n    this.#reader.setBuffer(offset, bytes)\n    const parameterCount = this.#reader.int16()\n    const message = new ParameterDescriptionMessage(length, parameterCount)\n    for (let i = 0; i < parameterCount; i++) {\n      message.dataTypeIDs[i] = this.#reader.int32()\n    }\n    return message\n  }\n\n  #parseDataRowMessage(offset: number, length: number, bytes: ArrayBuffer) {\n    this.#reader.setBuffer(offset, bytes)\n    const fieldCount = this.#reader.int16()\n    const fields: (string | null)[] = new Array(fieldCount)\n    for (let i = 0; i < fieldCount; i++) {\n      const len = this.#reader.int32()\n      // a -1 for length means the value of the field is null\n      fields[i] = len === -1 ? null : this.#reader.string(len)\n    }\n    return new DataRowMessage(length, fields)\n  }\n\n  #parseParameterStatusMessage(\n    offset: number,\n    length: number,\n    bytes: ArrayBuffer,\n  ) {\n    this.#reader.setBuffer(offset, bytes)\n    const name = this.#reader.cstring()\n    const value = this.#reader.cstring()\n    return new ParameterStatusMessage(length, name, value)\n  }\n\n  #parseBackendKeyData(offset: number, length: number, bytes: ArrayBuffer) {\n    this.#reader.setBuffer(offset, bytes)\n    const processID = this.#reader.int32()\n    const secretKey = this.#reader.int32()\n    return new BackendKeyDataMessage(length, processID, secretKey)\n  }\n\n  #parseAuthenticationResponse(\n    offset: number,\n    length: number,\n    bytes: ArrayBuffer,\n  ): AuthenticationMessage {\n    this.#reader.setBuffer(offset, bytes)\n    const code = this.#reader.int32()\n    switch (code) {\n      case 0:\n        return new AuthenticationOk(length)\n      case 3:\n        return new AuthenticationCleartextPassword(length)\n\n      case 5:\n        return new AuthenticationMD5Password(length, this.#reader.bytes(4))\n\n      case 10: {\n        const mechanisms: string[] = []\n        while (true) {\n          const mechanism = this.#reader.cstring()\n          if (mechanism.length === 0) {\n            return new AuthenticationSASL(length, mechanisms)\n          }\n          mechanisms.push(mechanism)\n        }\n      }\n      case 11:\n        return new AuthenticationSASLContinue(\n          length,\n          this.#reader.string(length - 8),\n        )\n\n      case 12:\n        return new AuthenticationSASLFinal(\n          length,\n          this.#reader.string(length - 8),\n        )\n\n      default:\n        throw new Error('Unknown authenticationOk message type ' + code)\n    }\n  }\n\n  #parseErrorMessage(\n    offset: number,\n    length: number,\n    bytes: ArrayBuffer,\n    name: MessageName,\n  ) {\n    this.#reader.setBuffer(offset, bytes)\n    const fields: Record<string, string> = {}\n    let fieldType = this.#reader.string(1)\n    while (fieldType !== '\\0') {\n      fields[fieldType] = this.#reader.cstring()\n      fieldType = this.#reader.string(1)\n    }\n\n    const messageValue = fields.M\n\n    const message =\n      name === 'notice'\n        ? new NoticeMessage(length, messageValue)\n        : new DatabaseError(messageValue, length, name)\n\n    message.severity = fields.S\n    message.code = fields.C\n    message.detail = fields.D\n    message.hint = fields.H\n    message.position = fields.P\n    message.internalPosition = fields.p\n    message.internalQuery = fields.q\n    message.where = fields.W\n    message.schema = fields.s\n    message.table = fields.t\n    message.column = fields.c\n    message.dataType = fields.d\n    message.constraint = fields.n\n    message.file = fields.F\n    message.line = fields.L\n    message.routine = fields.R\n    return message\n  }\n}\n","import { query as queryTemplate } from './templating.js'\nimport { parseDescribeStatementResults, parseResults } from './parse.js'\nimport {\n  type Serializer,\n  type Parser,\n  serializers,\n  parsers,\n  arraySerializer,\n  arrayParser,\n} from './types.js'\nimport type {\n  DebugLevel,\n  PGliteInterface,\n  Results,\n  Transaction,\n  QueryOptions,\n  ExecProtocolOptions,\n  ExecProtocolResult,\n  DescribeQueryResult,\n} from './interface.js'\n\nimport { serialize as serializeProtocol } from '@electric-sql/pg-protocol'\nimport {\n  RowDescriptionMessage,\n  ParameterDescriptionMessage,\n} from '@electric-sql/pg-protocol/messages'\n\nexport abstract class BasePGlite\n  implements Pick<PGliteInterface, 'query' | 'sql' | 'exec' | 'transaction'>\n{\n  serializers: Record<number | string, Serializer> = { ...serializers }\n  parsers: Record<number | string, Parser> = { ...parsers }\n  #arrayTypesInitialized = false\n\n  // # Abstract properties:\n  abstract debug: DebugLevel\n\n  // # Private properties:\n  #inTransaction = false\n\n  // # Abstract methods:\n\n  /**\n   * Execute a postgres wire protocol message\n   * @param message The postgres wire protocol message to execute\n   * @returns The result of the query\n   */\n  abstract execProtocol(\n    message: Uint8Array,\n    { syncToFs, onNotice }: ExecProtocolOptions,\n  ): Promise<ExecProtocolResult>\n\n  /**\n   * Execute a postgres wire protocol message directly without wrapping the response.\n   * Only use if `execProtocol()` doesn't suite your needs.\n   *\n   * **Warning:** This bypasses PGlite's protocol wrappers that manage error/notice messages,\n   * transactions, and notification listeners. Only use if you need to bypass these wrappers and\n   * don't intend to use the above features.\n   *\n   * @param message The postgres wire protocol message to execute\n   * @returns The direct message data response produced by Postgres\n   */\n  abstract execProtocolRaw(\n    message: Uint8Array,\n    { syncToFs, dataTransferContainer }: ExecProtocolOptions,\n  ): Promise<Uint8Array>\n\n  /**\n   * Sync the database to the filesystem\n   * @returns Promise that resolves when the database is synced to the filesystem\n   */\n  abstract syncToFs(): Promise<void>\n\n  /**\n   * Handle a file attached to the current query\n   * @param file The file to handle\n   */\n  abstract _handleBlob(blob?: File | Blob): Promise<void>\n\n  /**\n   * Get the written file\n   */\n  abstract _getWrittenBlob(): Promise<File | Blob | undefined>\n\n  /**\n   * Cleanup the current file\n   */\n  abstract _cleanupBlob(): Promise<void>\n\n  abstract _checkReady(): Promise<void>\n  abstract _runExclusiveQuery<T>(fn: () => Promise<T>): Promise<T>\n  abstract _runExclusiveTransaction<T>(fn: () => Promise<T>): Promise<T>\n\n  // # Concrete implementations:\n\n  /**\n   * Initialize the array types\n   * The oid if the type of an element and the typarray is the oid of the type of the\n   * array.\n   * We extract these from the databaes then create the serializers/parsers for\n   * each type.\n   * This should be called at the end of #init() in the implementing class.\n   */\n  async _initArrayTypes({ force = false } = {}) {\n    if (this.#arrayTypesInitialized && !force) return\n    this.#arrayTypesInitialized = true\n\n    const types = await this.query<{ oid: number; typarray: number }>(`\n      SELECT b.oid, b.typarray\n      FROM pg_catalog.pg_type a\n      LEFT JOIN pg_catalog.pg_type b ON b.oid = a.typelem\n      WHERE a.typcategory = 'A'\n      GROUP BY b.oid, b.typarray\n      ORDER BY b.oid\n    `)\n\n    for (const type of types.rows) {\n      this.serializers[type.typarray] = (x) =>\n        arraySerializer(x, this.serializers[type.oid], type.typarray)\n      this.parsers[type.typarray] = (x) =>\n        arrayParser(x, this.parsers[type.oid], type.typarray)\n    }\n  }\n\n  async #execProtocolNoSync(\n    message: Uint8Array,\n    options: ExecProtocolOptions = {},\n  ): Promise<ExecProtocolResult> {\n    return await this.execProtocol(message, { ...options, syncToFs: false })\n  }\n\n  /**\n   * Re-syncs the array types from the database\n   * This is useful if you add a new type to the database and want to use it, otherwise pglite won't recognize it.\n   */\n  async refreshArrayTypes() {\n    await this._initArrayTypes({ force: true })\n  }\n\n  /**\n   * Execute a single SQL statement\n   * This uses the \"Extended Query\" postgres wire protocol message.\n   * @param query The query to execute\n   * @param params Optional parameters for the query\n   * @returns The result of the query\n   */\n  async query<T>(\n    query: string,\n    params?: any[],\n    options?: QueryOptions,\n  ): Promise<Results<T>> {\n    await this._checkReady()\n    // We wrap the public query method in the transaction mutex to ensure that\n    // only one query can be executed at a time and not concurrently with a\n    // transaction.\n    return await this._runExclusiveTransaction(async () => {\n      return await this.#runQuery<T>(query, params, options)\n    })\n  }\n\n  /**\n   * Execute a single SQL statement like with {@link PGlite.query}, but with a\n   * templated statement where template values will be treated as parameters.\n   *\n   * You can use helpers from `/template` to further format the query with\n   * identifiers, raw SQL, and nested statements.\n   *\n   * This uses the \"Extended Query\" postgres wire protocol message.\n   *\n   * @param query The query to execute with parameters as template values\n   * @returns The result of the query\n   *\n   * @example\n   * ```ts\n   * const results = await db.sql`SELECT * FROM ${identifier`foo`} WHERE id = ${id}`\n   * ```\n   */\n  async sql<T>(\n    sqlStrings: TemplateStringsArray,\n    ...params: any[]\n  ): Promise<Results<T>> {\n    const { query, params: actualParams } = queryTemplate(sqlStrings, ...params)\n    return await this.query(query, actualParams)\n  }\n\n  /**\n   * Execute a SQL query, this can have multiple statements.\n   * This uses the \"Simple Query\" postgres wire protocol message.\n   * @param query The query to execute\n   * @returns The result of the query\n   */\n  async exec(query: string, options?: QueryOptions): Promise<Array<Results>> {\n    await this._checkReady()\n    // We wrap the public exec method in the transaction mutex to ensure that\n    // only one query can be executed at a time and not concurrently with a\n    // transaction.\n    return await this._runExclusiveTransaction(async () => {\n      return await this.#runExec(query, options)\n    })\n  }\n\n  /**\n   * Internal method to execute a query\n   * Not protected by the transaction mutex, so it can be used inside a transaction\n   * @param query The query to execute\n   * @param params Optional parameters for the query\n   * @returns The result of the query\n   */\n  async #runQuery<T>(\n    query: string,\n    params: any[] = [],\n    options?: QueryOptions,\n  ): Promise<Results<T>> {\n    return await this._runExclusiveQuery(async () => {\n      // We need to parse, bind and execute a query with parameters\n      this.#log('runQuery', query, params, options)\n      await this._handleBlob(options?.blob)\n\n      let results\n\n      try {\n        const { messages: parseResults } = await this.#execProtocolNoSync(\n          serializeProtocol.parse({ text: query, types: options?.paramTypes }),\n          options,\n        )\n\n        const dataTypeIDs = parseDescribeStatementResults(\n          (\n            await this.#execProtocolNoSync(\n              serializeProtocol.describe({ type: 'S' }),\n              options,\n            )\n          ).messages,\n        )\n\n        const values = params.map((param, i) => {\n          const oid = dataTypeIDs[i]\n          if (param === null || param === undefined) {\n            return null\n          }\n          const serialize = options?.serializers?.[oid] ?? this.serializers[oid]\n          if (serialize) {\n            return serialize(param)\n          } else {\n            return param.toString()\n          }\n        })\n\n        results = [\n          ...parseResults,\n          ...(\n            await this.#execProtocolNoSync(\n              serializeProtocol.bind({\n                values,\n              }),\n              options,\n            )\n          ).messages,\n          ...(\n            await this.#execProtocolNoSync(\n              serializeProtocol.describe({ type: 'P' }),\n              options,\n            )\n          ).messages,\n          ...(\n            await this.#execProtocolNoSync(\n              serializeProtocol.execute({}),\n              options,\n            )\n          ).messages,\n        ]\n      } finally {\n        await this.#execProtocolNoSync(serializeProtocol.sync(), options)\n      }\n\n      await this._cleanupBlob()\n      if (!this.#inTransaction) {\n        await this.syncToFs()\n      }\n      const blob = await this._getWrittenBlob()\n      return parseResults(results, this.parsers, options, blob)[0] as Results<T>\n    })\n  }\n\n  /**\n   * Internal method to execute a query\n   * Not protected by the transaction mutex, so it can be used inside a transaction\n   * @param query The query to execute\n   * @param params Optional parameters for the query\n   * @returns The result of the query\n   */\n  async #runExec(\n    query: string,\n    options?: QueryOptions,\n  ): Promise<Array<Results>> {\n    return await this._runExclusiveQuery(async () => {\n      // No params so we can just send the query\n      this.#log('runExec', query, options)\n      await this._handleBlob(options?.blob)\n      let results\n      try {\n        results = (\n          await this.#execProtocolNoSync(\n            serializeProtocol.query(query),\n            options,\n          )\n        ).messages\n      } finally {\n        await this.#execProtocolNoSync(serializeProtocol.sync(), options)\n      }\n      this._cleanupBlob()\n      if (!this.#inTransaction) {\n        await this.syncToFs()\n      }\n      const blob = await this._getWrittenBlob()\n      return parseResults(\n        results,\n        this.parsers,\n        options,\n        blob,\n      ) as Array<Results>\n    })\n  }\n\n  /**\n   * Describe a query\n   * @param query The query to describe\n   * @returns A description of the result types for the query\n   */\n  async describeQuery(\n    query: string,\n    options?: QueryOptions,\n  ): Promise<DescribeQueryResult> {\n    try {\n      await this.#execProtocolNoSync(\n        serializeProtocol.parse({ text: query, types: options?.paramTypes }),\n        options,\n      )\n\n      const describeResults = await this.#execProtocolNoSync(\n        serializeProtocol.describe({ type: 'S' }),\n        options,\n      )\n      const paramDescription = describeResults.messages.find(\n        (msg): msg is ParameterDescriptionMessage =>\n          msg.name === 'parameterDescription',\n      )\n      const resultDescription = describeResults.messages.find(\n        (msg): msg is RowDescriptionMessage => msg.name === 'rowDescription',\n      )\n\n      const queryParams =\n        paramDescription?.dataTypeIDs.map((dataTypeID) => ({\n          dataTypeID,\n          serializer: this.serializers[dataTypeID],\n        })) ?? []\n\n      const resultFields =\n        resultDescription?.fields.map((field) => ({\n          name: field.name,\n          dataTypeID: field.dataTypeID,\n          parser: this.parsers[field.dataTypeID],\n        })) ?? []\n\n      return { queryParams, resultFields }\n    } finally {\n      await this.#execProtocolNoSync(serializeProtocol.sync(), options)\n    }\n  }\n\n  /**\n   * Execute a transaction\n   * @param callback A callback function that takes a transaction object\n   * @returns The result of the transaction\n   */\n  async transaction<T>(callback: (tx: Transaction) => Promise<T>): Promise<T> {\n    await this._checkReady()\n    return await this._runExclusiveTransaction(async () => {\n      await this.#runExec('BEGIN')\n      this.#inTransaction = true\n\n      // Once a transaction is closed, we throw an error if it's used again\n      let closed = false\n      const checkClosed = () => {\n        if (closed) {\n          throw new Error('Transaction is closed')\n        }\n      }\n\n      const tx: Transaction = {\n        query: async <T>(\n          query: string,\n          params?: any[],\n          options?: QueryOptions,\n        ): Promise<Results<T>> => {\n          checkClosed()\n          return await this.#runQuery(query, params, options)\n        },\n        sql: async <T>(\n          sqlStrings: TemplateStringsArray,\n          ...params: any[]\n        ): Promise<Results<T>> => {\n          const { query, params: actualParams } = queryTemplate(\n            sqlStrings,\n            ...params,\n          )\n          return await this.#runQuery(query, actualParams)\n        },\n        exec: async (\n          query: string,\n          options?: QueryOptions,\n        ): Promise<Array<Results>> => {\n          checkClosed()\n          return await this.#runExec(query, options)\n        },\n        rollback: async () => {\n          checkClosed()\n          // Rollback and set the closed flag to prevent further use of this\n          // transaction\n          await this.#runExec('ROLLBACK')\n          closed = true\n        },\n        get closed() {\n          return closed\n        },\n      }\n\n      try {\n        const result = await callback(tx)\n        if (!closed) {\n          closed = true\n          await this.#runExec('COMMIT')\n        }\n        this.#inTransaction = false\n        return result\n      } catch (e) {\n        if (!closed) {\n          await this.#runExec('ROLLBACK')\n        }\n        this.#inTransaction = false\n        throw e\n      }\n    })\n  }\n\n  /**\n   * Run a function exclusively, no other transactions or queries will be allowed\n   * while the function is running.\n   * This is useful when working with the execProtocol methods as they are not blocked,\n   * and do not block the locks used by transactions and queries.\n   * @param fn The function to run\n   * @returns The result of the function\n   */\n  async runExclusive<T>(fn: () => Promise<T>): Promise<T> {\n    return await this._runExclusiveQuery(fn)\n  }\n\n  /**\n   * Internal log function\n   */\n  #log(...args: any[]) {\n    if (this.debug > 0) {\n      console.log(...args)\n    }\n  }\n}\n","import type { PGliteInterface, Transaction } from './interface.js'\nimport { serialize as serializeProtocol } from '@electric-sql/pg-protocol'\nimport { parseDescribeStatementResults } from './parse.js'\nimport { TEXT } from './types.js'\n\nexport const IN_NODE =\n  typeof process === 'object' &&\n  typeof process.versions === 'object' &&\n  typeof process.versions.node === 'string'\n\nlet wasmDownloadPromise: Promise<Response> | undefined\n\nexport async function startWasmDownload() {\n  if (IN_NODE || wasmDownloadPromise) {\n    return\n  }\n  const moduleUrl = new URL('../release/pglite.wasm', import.meta.url)\n  wasmDownloadPromise = fetch(moduleUrl)\n}\n\n// This is a global cache of the PGlite Wasm module to avoid having to re-download or\n// compile it on subsequent calls.\nlet cachedWasmModule: WebAssembly.Module | undefined\n\nexport async function instantiateWasm(\n  imports: WebAssembly.Imports,\n  module?: WebAssembly.Module,\n): Promise<{\n  instance: WebAssembly.Instance\n  module: WebAssembly.Module\n}> {\n  if (module || cachedWasmModule) {\n    WebAssembly.instantiate(module || cachedWasmModule!, imports)\n    return {\n      instance: await WebAssembly.instantiate(\n        module || cachedWasmModule!,\n        imports,\n      ),\n      module: module || cachedWasmModule!,\n    }\n  }\n  const moduleUrl = new URL('../release/pglite.wasm', import.meta.url)\n  if (IN_NODE) {\n    const fs = await import('fs/promises')\n    const buffer = await fs.readFile(moduleUrl)\n    const { module: newModule, instance } = await WebAssembly.instantiate(\n      buffer,\n      imports,\n    )\n    cachedWasmModule = newModule\n    return {\n      instance,\n      module: newModule,\n    }\n  } else {\n    if (!wasmDownloadPromise) {\n      wasmDownloadPromise = fetch(moduleUrl)\n    }\n    const response = await wasmDownloadPromise\n    const { module: newModule, instance } =\n      await WebAssembly.instantiateStreaming(response, imports)\n    cachedWasmModule = newModule\n    return {\n      instance,\n      module: newModule,\n    }\n  }\n}\n\nexport async function getFsBundle(): Promise<ArrayBuffer> {\n  const fsBundleUrl = new URL('../release/pglite.data', import.meta.url)\n  if (IN_NODE) {\n    const fs = await import('fs/promises')\n    const fileData = await fs.readFile(fsBundleUrl)\n    return fileData.buffer\n  } else {\n    const response = await fetch(fsBundleUrl)\n    return response.arrayBuffer()\n  }\n}\n\nexport const uuid = (): string => {\n  // best case, `crypto.randomUUID` is available\n  if (globalThis.crypto?.randomUUID) {\n    return globalThis.crypto.randomUUID()\n  }\n\n  const bytes = new Uint8Array(16)\n\n  if (globalThis.crypto?.getRandomValues) {\n    // `crypto.getRandomValues` is available even in non-secure contexts\n    globalThis.crypto.getRandomValues(bytes)\n  } else {\n    // fallback to Math.random, if the Crypto API is completely missing\n    for (let i = 0; i < bytes.length; i++) {\n      bytes[i] = Math.floor(Math.random() * 256)\n    }\n  }\n\n  bytes[6] = (bytes[6] & 0x0f) | 0x40 // Set the 4 most significant bits to 0100\n  bytes[8] = (bytes[8] & 0x3f) | 0x80 // Set the 2 most significant bits to 10\n\n  const hexValues: string[] = []\n  bytes.forEach((byte) => {\n    hexValues.push(byte.toString(16).padStart(2, '0'))\n  })\n\n  return (\n    hexValues.slice(0, 4).join('') +\n    '-' +\n    hexValues.slice(4, 6).join('') +\n    '-' +\n    hexValues.slice(6, 8).join('') +\n    '-' +\n    hexValues.slice(8, 10).join('') +\n    '-' +\n    hexValues.slice(10).join('')\n  )\n}\n\n/**\n * Formats a query with parameters\n * Expects that any tables/relations referenced in the query exist in the database\n * due to requiring them to be present to describe the parameters types.\n * `tx` is optional, and to be used when formatQuery is called during a transaction.\n * @param pg - The PGlite instance\n * @param query - The query to format\n * @param params - The parameters to format the query with\n * @param tx - The transaction to use, defaults to the PGlite instance\n * @returns The formatted query\n */\nexport async function formatQuery(\n  pg: PGliteInterface,\n  query: string,\n  params?: any[] | null,\n  tx?: Transaction | PGliteInterface,\n) {\n  if (!params || params.length === 0) {\n    // no params so no formatting needed\n    return query\n  }\n\n  tx = tx ?? pg\n\n  // Get the types of the parameters\n  let dataTypeIDs: number[]\n  try {\n    await pg.execProtocol(serializeProtocol.parse({ text: query }), {\n      syncToFs: false,\n    })\n\n    dataTypeIDs = parseDescribeStatementResults(\n      (\n        await pg.execProtocol(serializeProtocol.describe({ type: 'S' }), {\n          syncToFs: false,\n        })\n      ).messages,\n    )\n  } finally {\n    await pg.execProtocol(serializeProtocol.sync(), { syncToFs: false })\n  }\n\n  // replace $1, $2, etc with  %1L, %2L, etc\n  const subbedQuery = query.replace(/\\$([0-9]+)/g, (_, num) => {\n    return '%' + num + 'L'\n  })\n\n  const ret = await tx.query<{\n    query: string\n  }>(\n    `SELECT format($1, ${params.map((_, i) => `$${i + 2}`).join(', ')}) as query`,\n    [subbedQuery, ...params],\n    { paramTypes: [TEXT, ...dataTypeIDs] },\n  )\n  return ret.rows[0].query\n}\n\n/**\n * Debounce a function to ensure that only one instance of the function is running at\n * a time.\n * - If the function is called while an instance is already running, the new\n * call is scheduled to run after the current instance completes.\n * - If there is already a scheduled call, it is replaced with the new call.\n * @param fn - The function to debounce\n * @returns A debounced version of the function\n */\nexport function debounceMutex<A extends any[], R>(\n  fn: (...args: A) => Promise<R>,\n): (...args: A) => Promise<R | void> {\n  let next:\n    | {\n        args: A\n        resolve: (value: R | void) => void\n        reject: (reason?: any) => void\n      }\n    | undefined = undefined\n\n  let isRunning = false\n  const processNext = async () => {\n    if (!next) {\n      isRunning = false\n      return\n    }\n    isRunning = true\n    const { args, resolve, reject } = next\n    next = undefined\n    try {\n      const ret = await fn(...args)\n      resolve(ret)\n    } catch (e) {\n      reject(e)\n    } finally {\n      processNext()\n    }\n  }\n  return async (...args: A) => {\n    if (next) {\n      next.resolve(undefined)\n    }\n    const promise = new Promise<R | void>((resolve, reject) => {\n      next = { args, resolve, reject }\n    })\n    if (!isRunning) {\n      processNext()\n    }\n    return promise\n  }\n}\n\n/**\n * Postgresql handles quoted names as CaseSensitive and unquoted as lower case.\n * If input is quoted, returns an unquoted string (same casing)\n * If input is unquoted, returns a lower-case string\n */\nexport function toPostgresName(input: string): string {\n  let output\n  if (input.startsWith('\"') && input.endsWith('\"')) {\n    // Postgres sensitive case\n    output = input.substring(1, input.length - 1)\n  } else {\n    // Postgres case insensitive - all to lower\n    output = input.toLowerCase()\n  }\n  return output\n}\n"],"mappings":"23BAAA,IAAAA,GAAA,GAAAC,GAAAD,GAAA,wBAAAE,GAAA,iBAAAC,GAAA,WAAAC,KAAA,eAAAC,GAAAL,ICKA,IAAMM,GAAmB,IACvB,OAAO,SAAa,IAChB,IAAI,IAAI,QAAQ,UAAU,EAAE,EAAE,KAC7B,SAAS,eAAiB,SAAS,cAAc,KAClD,IAAI,IAAI,UAAW,SAAS,OAAO,EAAE,KAE9BC,EAAgCD,GAAiB,ECX9D,IAAME,GAAe,CACnB,KAAM,OACN,UAAW,WACb,EAkBA,SAASC,GACPC,EACAC,KACGC,EACH,CACA,IAAMC,EAAaH,EAAI,OAAS,EAC1BI,EAAaF,EAAO,OAAS,EAGnC,GAAIE,IAAe,GAGnB,IAAIA,IAAe,EAAG,CACpBJ,EAAIG,CAAU,EAAIH,EAAIG,CAAU,EAAID,EAAO,CAAC,EAAID,EAChD,MACF,CAGAD,EAAIG,CAAU,EAAIH,EAAIG,CAAU,EAAID,EAAO,CAAC,EAC5CF,EAAI,KAAK,GAAGE,EAAO,MAAM,EAAGE,CAAU,CAAC,EACvCJ,EAAI,KAAKE,EAAOE,CAAU,EAAIH,CAAM,EACtC,CAcO,SAASI,GACdC,KACGJ,EACgB,CACnB,IAAMK,EAAgB,CAACD,EAAQ,CAAC,CAAC,EAGjCC,EAAc,IAAM,CAACD,EAAQ,IAAI,CAAC,CAAC,EAEnC,IAAME,EAAsB,CAAC,EAC7B,QAAS,EAAI,EAAG,EAAIN,EAAO,OAAQ,IAAK,CACtC,IAAMO,EAAQP,EAAO,CAAC,EAChBQ,EAAgB,EAAI,EAG1B,GAAID,GAAO,gBAAkBX,GAAa,KAAM,CAC9CC,GACEQ,EACAD,EAAQI,CAAa,EACrBD,EAAM,GACR,EACAV,GACEQ,EAAc,IACdD,EAAQ,IAAII,CAAa,EACzBD,EAAM,GACR,EACA,QACF,CAGA,GAAIA,GAAO,gBAAkBX,GAAa,UAAW,CACnDC,GACEQ,EACAD,EAAQI,CAAa,EACrB,GAAGD,EAAM,OACX,EACAV,GACEQ,EAAc,IACdD,EAAQ,IAAII,CAAa,EACzB,GAAGD,EAAM,QAAQ,GACnB,EACAD,EAAa,KAAK,GAAGC,EAAM,MAAM,EACjC,QACF,CAGAF,EAAc,KAAKD,EAAQI,CAAa,CAAC,EACzCH,EAAc,IAAI,KAAKD,EAAQ,IAAII,CAAa,CAAC,EACjDF,EAAa,KAAKC,CAAK,CACzB,CAEA,MAAO,CACL,cAAe,YACf,QAASF,EACT,OAAQC,CACV,CACF,CAyDO,SAASG,GACdC,KACGC,EACa,CAChB,GAAM,CAAE,QAASC,EAAkB,OAAQC,CAAO,EAAIC,GAAIJ,EAAS,GAAGC,CAAM,EAC5E,MAAO,CACL,MAAO,CACLC,EAAiB,CAAC,EAClB,GAAGC,EAAO,QAAQ,CAACE,EAAGC,IAAQ,CAAC,IAAIA,EAAM,CAAC,GAAIJ,EAAiBI,EAAM,CAAC,CAAC,CAAC,CAC1E,EAAE,KAAK,EAAE,EACT,OAAQH,CACV,CACF,CC5KA,IAAMI,GAAa,WAAW,KAAK,MAC7BC,GAAiB,WAAW,KAAK,UAE1BC,GAAO,GAClBC,GAAQ,GADH,IAGLC,GAAO,GACPC,GAAO,GACPC,GAAO,GALF,IAOLC,GAAO,GACPC,GAAM,GARD,IAYLC,GAAO,IAZF,IAmBLC,GAAS,IACTC,GAAS,IApBJ,IA8BLC,GAAS,KACTC,GAAU,KACVC,GAAO,KAhCF,IAkCLC,GAAY,KACZC,GAAc,KAnCT,IAyDLC,GAAQ,KAIH,IAAMC,GAAQ,CACnB,OAAQ,CACN,GAAIC,GACJ,KAAM,CAACA,GAAMC,GAASC,EAAM,EAC5B,UAAYC,GAAuB,CACjC,GAAI,OAAOA,GAAM,SACf,OAAOA,EACF,GAAI,OAAOA,GAAM,SACtB,OAAOA,EAAE,SAAS,EAElB,MAAM,IAAI,MAAM,+BAA+B,CAEnD,EACA,MAAQA,GAAcA,CACxB,EACA,OAAQ,CACN,GAAI,EACJ,KAAM,CAACC,GAAMC,GAAMC,GAAKC,GAAQC,EAAM,EACtC,UAAYL,GAAcA,EAAE,SAAS,EACrC,MAAQA,GAAc,CAACA,CACzB,EACA,OAAQ,CACN,GAAIM,GACJ,KAAM,CAACA,EAAI,EACX,UAAYN,GAAcA,EAAE,SAAS,EACrC,MAAQA,GAAc,CACpB,IAAMO,EAAI,OAAOP,CAAC,EAClB,OAAIO,EAAI,OAAO,kBAAoBA,EAAI,OAAO,iBACrCA,EAEA,OAAOA,CAAC,CAEnB,CACF,EACA,KAAM,CACJ,GAAIC,GACJ,KAAM,CAACA,GAAMC,EAAK,EAClB,UAAYT,GACN,OAAOA,GAAM,SACRA,EAEAU,GAAeV,CAAC,EAG3B,MAAQA,GAAcW,GAAWX,CAAC,CACpC,EACA,QAAS,CACP,GAAIY,GACJ,KAAM,CAACA,EAAI,EACX,UAAYZ,GAAe,CACzB,GAAI,OAAOA,GAAM,UACf,MAAM,IAAI,MAAM,gCAAgC,EAElD,OAAOA,EAAI,IAAM,GACnB,EACA,MAAQA,GAAcA,IAAM,GAC9B,EACA,KAAM,CACJ,GAAIa,GACJ,KAAM,CAACC,GAAMC,GAAWF,EAAW,EACnC,UAAYb,GAA8B,CACxC,GAAI,OAAOA,GAAM,SACf,OAAOA,EACF,GAAI,OAAOA,GAAM,SACtB,OAAO,IAAI,KAAKA,CAAC,EAAE,YAAY,EAC1B,GAAIA,aAAa,KACtB,OAAOA,EAAE,YAAY,EAErB,MAAM,IAAI,MAAM,6BAA6B,CAEjD,EACA,MAAQA,GAAuB,IAAI,KAAKA,CAAC,CAC3C,EACA,MAAO,CACL,GAAIgB,GACJ,KAAM,CAACA,EAAK,EACZ,UAAYhB,GAAkB,CAC5B,GAAI,EAAEA,aAAa,YACjB,MAAM,IAAI,MAAM,8BAA8B,EAEhD,MACE,MACA,MAAM,KAAKA,CAAC,EACT,IAAKiB,GAASA,EAAK,SAAS,EAAE,EAAE,SAAS,EAAG,GAAG,CAAC,EAChD,KAAK,EAAE,CAEd,EACA,MAAQjB,GAA0B,CAChC,IAAMkB,EAAYlB,EAAE,MAAM,CAAC,EAC3B,OAAO,WAAW,KAAK,CAAE,OAAQkB,EAAU,OAAS,CAAE,EAAG,CAACC,EAAGC,IAC3D,SAASF,EAAU,UAAUE,EAAM,GAAIA,EAAM,GAAK,CAAC,EAAG,EAAE,CAC1D,CACF,CACF,CACF,EAgBMC,GAAkBC,GAAa1B,EAAK,EAE7B2B,GAAUF,GAAgB,QAC1BG,GAAcH,GAAgB,YAEpC,SAASI,GACdzB,EACA0B,EACAH,EACK,CACL,GAAIvB,IAAM,KACR,OAAO,KAET,IAAM2B,EAAUJ,IAAUG,CAAI,GAAKL,GAAgB,QAAQK,CAAI,EAC/D,OAAIC,EACKA,EAAQ3B,EAAG0B,CAAI,EAEf1B,CAEX,CAEA,SAASsB,GAAa1B,EAAqB,CACzC,OAAO,OAAO,KAAKA,CAAK,EAAE,OACxB,CAAC,CAAE,QAAA2B,EAAS,YAAAC,CAAY,EAAGI,IAAM,CAC/B,GAAM,CAAE,GAAAC,EAAI,KAAAC,EAAM,UAAAC,EAAW,MAAAC,CAAM,EAAIpC,EAAMgC,CAAC,EAC9C,OAAAJ,EAAYK,CAAE,EAAIE,EAClBP,EAAYI,CAAC,EAAIG,EACjBR,EAAQK,CAAC,EAAII,EACT,MAAM,QAAQF,CAAI,EACpBA,EAAK,QAASG,GAAM,CAClBV,EAAQU,CAAC,EAAID,EACbR,EAAYS,CAAC,EAAIF,CACnB,CAAC,GAEDR,EAAQO,CAAI,EAAIE,EAChBR,EAAYM,CAAI,EAAIC,GAEf,CAAE,QAAAR,EAAS,YAAAC,CAAY,CAChC,EACA,CACE,QAAS,CAAC,EAGV,YAAa,CAAC,CAGhB,CACF,CACF,CAEA,IAAMU,GAAkB,MAClBC,GAAc,KAEpB,SAASC,GAAYpC,EAAW,CAC9B,OAAOA,EAAE,QAAQkC,GAAiB,MAAM,EAAE,QAAQC,GAAa,KAAK,CACtE,CAEO,SAASE,GACdC,EACAC,EACAC,EACQ,CACR,GAAI,MAAM,QAAQF,CAAE,IAAM,GAAO,OAAOA,EAExC,GAAI,CAACA,EAAG,OAAQ,MAAO,KAEvB,IAAMG,EAAQH,EAAG,CAAC,EAEZI,EAAYF,IAAa,KAAO,IAAM,IAE5C,OAAI,MAAM,QAAQC,CAAK,EACd,IAAIH,EAAG,IAAKtC,GAAMqC,GAAgBrC,EAAGuC,EAAYC,CAAQ,CAAC,EAAE,KAAKE,CAAS,CAAC,IAE3E,IAAIJ,EACR,IAAKtC,IACAA,IAAM,SACRA,EAAI,MAGCA,IAAM,KACT,OACA,IAAMoC,GAAYG,EAAaA,EAAWvC,CAAC,EAAIA,EAAE,SAAS,CAAC,EAAI,IACpE,EACA,KAAK0C,CAAS,CAAC,GAEtB,CAEA,IAAMC,GAAmB,CACvB,EAAG,EACH,KAAM,KACN,IAAK,GACL,OAAQ,GACR,KAAM,EACN,EAAG,IACL,EAEO,SAASC,GAAY5C,EAAW6C,EAAgBL,EAAkB,CACvE,OAAAG,GAAiB,EAAIA,GAAiB,KAAO,EACtCG,GAAgBH,GAAkB3C,EAAG6C,EAAQL,CAAQ,EAAE,CAAC,CACjE,CAEA,SAASM,GACPC,EACA/C,EACA6C,EACAL,EACO,CACP,IAAMF,EAAK,CAAC,EAENI,EAAYF,IAAa,KAAO,IAAM,IAC5C,KAAOO,EAAE,EAAI/C,EAAE,OAAQ+C,EAAE,IAAK,CAE5B,GADAA,EAAE,KAAO/C,EAAE+C,EAAE,CAAC,EACVA,EAAE,OACAA,EAAE,OAAS,KACbA,EAAE,KAAO/C,EAAE,EAAE+C,EAAE,CAAC,EACPA,EAAE,OAAS,KACpBT,EAAG,KAAKO,EAASA,EAAOE,EAAE,GAAG,EAAIA,EAAE,GAAG,EACtCA,EAAE,IAAM,GACRA,EAAE,OAAS/C,EAAE+C,EAAE,EAAI,CAAC,IAAM,IAC1BA,EAAE,KAAOA,EAAE,EAAI,GAEfA,EAAE,KAAOA,EAAE,aAEJA,EAAE,OAAS,IACpBA,EAAE,OAAS,WACFA,EAAE,OAAS,IACpBA,EAAE,KAAO,EAAEA,EAAE,EACbT,EAAG,KAAKQ,GAAgBC,EAAG/C,EAAG6C,EAAQL,CAAQ,CAAC,UACtCO,EAAE,OAAS,IAAK,CACzBA,EAAE,OAAS,GACXA,EAAE,KAAOA,EAAE,GACTT,EAAG,KAAKO,EAASA,EAAO7C,EAAE,MAAM+C,EAAE,KAAMA,EAAE,CAAC,CAAC,EAAI/C,EAAE,MAAM+C,EAAE,KAAMA,EAAE,CAAC,CAAC,EACtEA,EAAE,KAAOA,EAAE,EAAI,EACf,KACF,MAAWA,EAAE,OAASL,GAAaK,EAAE,IAAM,KAAOA,EAAE,IAAM,MACxDT,EAAG,KAAKO,EAASA,EAAO7C,EAAE,MAAM+C,EAAE,KAAMA,EAAE,CAAC,CAAC,EAAI/C,EAAE,MAAM+C,EAAE,KAAMA,EAAE,CAAC,CAAC,EACpEA,EAAE,KAAOA,EAAE,EAAI,GAEjBA,EAAE,EAAIA,EAAE,IACV,CACA,OAAAA,EAAE,KAAOA,EAAE,GACTT,EAAG,KACDO,EAASA,EAAO7C,EAAE,MAAM+C,EAAE,KAAMA,EAAE,EAAI,CAAC,CAAC,EAAI/C,EAAE,MAAM+C,EAAE,KAAMA,EAAE,EAAI,CAAC,CACrE,EACKT,CACT,CC1TO,SAASU,GACdC,EACAC,EACAC,EACAC,EACgB,CAChB,IAAMC,EAAwB,CAAC,EAC3BC,EAA4B,CAAE,KAAM,CAAC,EAAG,OAAQ,CAAC,CAAE,EACnDC,EAAe,EACbC,EAAU,CAAE,GAAGN,EAAgB,GAAGC,GAAS,OAAQ,EAEzD,OAAAF,EAAS,QAASQ,GAAY,CAC5B,OAAQA,EAAQ,KAAM,CACpB,IAAK,iBAAkB,CACrB,IAAMC,EAAMD,EACZH,EAAiB,OAASI,EAAI,OAAO,IAAKC,IAAW,CACnD,KAAMA,EAAM,KACZ,WAAYA,EAAM,UACpB,EAAE,EACF,KACF,CACA,IAAK,UAAW,CACd,GAAI,CAACL,EAAkB,MACvB,IAAMI,EAAMD,EACRN,GAAS,UAAY,QACvBG,EAAiB,KAAK,KACpBI,EAAI,OAAO,IAAI,CAACC,EAAOC,IACrBC,GAAUF,EAAOL,EAAkB,OAAOM,CAAC,EAAE,WAAYJ,CAAO,CAClE,CACF,EAGAF,EAAiB,KAAK,KACpB,OAAO,YACLI,EAAI,OAAO,IAAI,CAACC,EAAOC,IAAM,CAC3BN,EAAkB,OAAOM,CAAC,EAAE,KAC5BC,GACEF,EACAL,EAAkB,OAAOM,CAAC,EAAE,WAC5BJ,CACF,CACF,CAAC,CACH,CACF,EAEF,KACF,CACA,IAAK,kBAAmB,CAEtBD,GAAgBO,GADJL,CACwB,EAEpCJ,EAAW,KAAK,CACd,GAAGC,EACH,aAAAC,EACA,GAAIH,EAAO,CAAE,KAAAA,CAAK,EAAI,CAAC,CACzB,CAAC,EAEDE,EAAmB,CAAE,KAAM,CAAC,EAAG,OAAQ,CAAC,CAAE,EAC1C,KACF,CACF,CACF,CAAC,EAEGD,EAAW,SAAW,GACxBA,EAAW,KAAK,CACd,aAAc,EACd,KAAM,CAAC,EACP,OAAQ,CAAC,CACX,CAAC,EAGIA,CACT,CAEA,SAASS,GAAiBJ,EAAqC,CAC7D,IAAMK,EAAQL,EAAI,KAAK,MAAM,GAAG,EAChC,OAAQK,EAAM,CAAC,EAAG,CAChB,IAAK,SACH,OAAO,SAASA,EAAM,CAAC,EAAG,EAAE,EAC9B,IAAK,SACL,IAAK,SACL,IAAK,OACH,OAAO,SAASA,EAAM,CAAC,EAAG,EAAE,EAC9B,QACE,MAAO,EACX,CACF,CAGO,SAASC,GACdf,EACU,CACV,IAAMQ,EAAUR,EAAS,KACtBS,GACCA,EAAI,OAAS,sBACjB,EAEA,OAAID,EACKA,EAAQ,YAGV,CAAC,CACV,CC9GA,SAASQ,EAAeC,EAAqB,CAC3C,IAAIC,EAAaD,EAAI,OACrB,QAASE,EAAIF,EAAI,OAAS,EAAGE,GAAK,EAAGA,IAAK,CACxC,IAAMC,EAAOH,EAAI,WAAWE,CAAC,EACzBC,EAAO,KAAQA,GAAQ,KAAOF,IACzBE,EAAO,MAASA,GAAQ,QAAQF,GAAc,GACnDE,GAAQ,OAAUA,GAAQ,OAAQD,GACxC,CACA,OAAOD,CACT,CCfA,IAAAG,EAAAC,EAAAC,EAAAC,GAAAC,EAAAC,EAAAC,GAAAC,EAAAC,GAEaC,EAAN,KAAa,CAOlB,YAAoBC,EAAO,IAAK,CAAZ,UAAAA,EAPfC,EAAA,KAAAN,GACLM,EAAA,KAAAX,GACAW,EAAA,KAAAV,EAAkB,GAElBU,EAAA,KAAST,EAAgB,IACzBS,EAAA,KAASR,GAAW,IAAI,aACxBQ,EAAA,KAASP,EAA0B,GAEjCQ,EAAA,KAAKZ,EAAca,EAAA,KAAKR,EAAAC,IAAL,UAAqBI,GAC1C,CAkBO,SAASI,EAAqB,CACnC,OAAAD,EAAA,KAAKR,EAAAE,GAAL,UAAa,GACbQ,EAAA,KAAKf,GAAY,SAASe,EAAA,KAAKd,GAASa,EAAKC,EAAA,KAAKb,EAAa,EAC/DU,EAAA,KAAKX,EAALc,EAAA,KAAKd,GAAW,GACT,IACT,CAEO,SAASa,EAAqB,CACnC,OAAAD,EAAA,KAAKR,EAAAE,GAAL,UAAa,GACbQ,EAAA,KAAKf,GAAY,SAASe,EAAA,KAAKd,GAASa,EAAKC,EAAA,KAAKb,EAAa,EAC/DU,EAAA,KAAKX,EAALc,EAAA,KAAKd,GAAW,GACT,IACT,CAEO,WAAWe,EAAwB,CACxC,OAAIA,GAGF,KAAK,UAAUA,CAAM,EAIvBH,EAAA,KAAKR,EAAAE,GAAL,UAAa,GACbQ,EAAA,KAAKf,GAAY,SAASe,EAAA,KAAKd,GAAS,CAAC,EACzCgB,GAAA,KAAKhB,GAAL,IACO,IACT,CAEO,UAAUe,EAAiB,GAAY,CAC5C,IAAME,EAASC,EAAeH,CAAM,EACpC,OAAAH,EAAA,KAAKR,EAAAE,GAAL,UAAaW,GACbH,EAAA,KAAKZ,IAAS,WACZa,EACA,IAAI,WAAWD,EAAA,KAAKf,GAAY,OAAQe,EAAA,KAAKd,EAAO,CACtD,EACAW,EAAA,KAAKX,EAALc,EAAA,KAAKd,GAAWiB,GACT,IACT,CAEO,IAAIE,EAAkC,CAC3C,OAAAP,EAAA,KAAKR,EAAAE,GAAL,UAAaa,EAAY,YACzB,IAAI,WAAWL,EAAA,KAAKf,GAAY,MAAM,EAAE,IACtC,IAAI,WAAWoB,CAAW,EAC1BL,EAAA,KAAKd,EACP,EAEAW,EAAA,KAAKX,EAALc,EAAA,KAAKd,GAAWmB,EAAY,YACrB,IACT,CAgBO,MAAMC,EAA2B,CACtC,IAAMC,EAAST,EAAA,KAAKR,EAAAG,IAAL,UAAWa,GAC1B,OAAAT,EAAA,KAAKX,EAAU,GACfW,EAAA,KAAKZ,EAAca,EAAA,KAAKR,EAAAC,IAAL,UAAqB,KAAK,OACtC,IAAI,WAAWgB,CAAM,CAC9B,CACF,EAhGEtB,EAAA,YACAC,EAAA,YAESC,EAAA,YACAC,GAAA,YACAC,EAAA,YANJC,EAAA,YAWLC,GAAe,SAACI,EAAwB,CACtC,OAAO,IAAI,SAAS,IAAI,YAAYA,CAAI,CAAC,CAC3C,EAEAH,EAAO,SAACG,EAAoB,CAE1B,GADkBK,EAAA,KAAKf,GAAY,WAAae,EAAA,KAAKd,GACrCS,EAAM,CACpB,IAAMa,EAAYR,EAAA,KAAKf,GAAY,OAG7BwB,EAAUD,EAAU,YAAcA,EAAU,YAAc,GAAKb,EACrEE,EAAA,KAAKZ,EAAca,EAAA,KAAKR,EAAAC,IAAL,UAAqBkB,IACxC,IAAI,WAAWT,EAAA,KAAKf,GAAY,MAAM,EAAE,IAAI,IAAI,WAAWuB,CAAS,CAAC,CACvE,CACF,EAoDAf,GAAK,SAACa,EAA4B,CAChC,GAAIA,EAAM,CACRN,EAAA,KAAKf,GAAY,SAASe,EAAA,KAAKX,GAAiBiB,CAAI,EAEpD,IAAMH,EAASH,EAAA,KAAKd,IAAWc,EAAA,KAAKX,GAAkB,GACtDW,EAAA,KAAKf,GAAY,SACfe,EAAA,KAAKX,GAAkB,EACvBc,EACAH,EAAA,KAAKb,EACP,CACF,CACA,OAAOa,EAAA,KAAKf,GAAY,OAAO,MAAMqB,EAAO,EAAI,EAAGN,EAAA,KAAKd,EAAO,CACjE,ECtEF,IAAMwB,EAAS,IAAIC,EAEbC,GAAWC,GAA6C,CAE5DH,EAAO,SAAS,CAAC,EAAE,SAAS,CAAC,EAC7B,QAAWI,KAAO,OAAO,KAAKD,CAAI,EAChCH,EAAO,WAAWI,CAAG,EAAE,WAAWD,EAAKC,CAAG,CAAC,EAG7CJ,EAAO,WAAW,iBAAiB,EAAE,WAAW,MAAM,EAEtD,IAAMK,EAAaL,EAAO,WAAW,EAAE,EAAE,MAAM,EAGzCM,EAASD,EAAW,WAAa,EAEvC,OAAO,IAAIJ,EAAO,EAAE,SAASK,CAAM,EAAE,IAAID,CAAU,EAAE,MAAM,CAC7D,EAEME,GAAa,IAAkB,CACnC,IAAMC,EAAa,IAAI,SAAS,IAAI,YAAY,CAAC,CAAC,EAClD,OAAAA,EAAW,SAAS,EAAG,EAAG,EAAK,EAC/BA,EAAW,SAAS,EAAG,SAAU,EAAK,EAC/B,IAAI,WAAWA,EAAW,MAAM,CACzC,EAEMC,GAAYA,GACTT,EAAO,WAAWS,CAAQ,EAAE,MAAM,GAAY,EAGjDC,GAAiC,CACrCC,EACAC,KAGAZ,EACG,WAAWW,CAAS,EACpB,SAASE,EAAeD,CAAe,CAAC,EACxC,UAAUA,CAAe,EAErBZ,EAAO,MAAM,GAAY,GAG5Bc,GAA+BC,GAC5Bf,EAAO,UAAUe,CAAc,EAAE,MAAM,GAAY,EAGtDC,GAASC,GACNjB,EAAO,WAAWiB,CAAI,EAAE,MAAM,EAAU,EAS3CC,GAAgC,CAAC,EAEjCC,GAASH,GAAiC,CAO9C,IAAMI,EAAOJ,EAAM,MAAQ,GACvBI,EAAK,OAAS,KAEhB,QAAQ,MACN,gEACF,EACA,QAAQ,MAAM,uBAAwBA,EAAMA,EAAK,MAAM,EACvD,QAAQ,MACN,8DACF,GAIF,IAAMC,EAASrB,EACZ,WAAWoB,CAAI,EACf,WAAWJ,EAAM,IAAI,EACrB,SAASA,EAAM,OAAO,QAAU,CAAC,EAEpC,OAAAA,EAAM,OAAO,QAASM,GAASD,EAAO,SAASC,CAAI,CAAC,EAE7CtB,EAAO,MAAM,EAAU,CAChC,EAaMuB,EAAc,IAAItB,EAQxB,IAAMuB,GAAc,CAACC,EAAsBC,IAAoC,CAC7E,QAASC,EAAI,EAAGA,EAAIF,EAAO,OAAQE,IAAK,CACtC,IAAMC,EAAYF,EAAcA,EAAYD,EAAOE,CAAC,EAAGA,CAAC,EAAIF,EAAOE,CAAC,EACpE,GAAIC,IAAc,KAEhBC,EAAO,SAAS,CAAgB,EAEhCC,EAAY,SAAS,EAAE,UAEvBF,aAAqB,aACrB,YAAY,OAAOA,CAAS,EAC5B,CACA,IAAMG,EAAS,YAAY,OAAOH,CAAS,EACvCA,EAAU,OAAO,MACfA,EAAU,WACVA,EAAU,WAAaA,EAAU,UACnC,EACAA,EAEJC,EAAO,SAAS,CAAgB,EAEhCC,EAAY,SAASC,EAAO,UAAU,EACtCD,EAAY,IAAIC,CAAM,CACxB,MAEEF,EAAO,SAAS,CAAgB,EAChCC,EAAY,SAASE,EAAeJ,CAAS,CAAC,EAC9CE,EAAY,UAAUF,CAAS,CAEnC,CACF,EAEMK,GAAO,CAACC,EAAmB,CAAC,IAAkB,CAElD,IAAMC,EAASD,EAAO,QAAU,GAC1BE,EAAYF,EAAO,WAAa,GAChCG,EAASH,EAAO,QAAU,GAC1BT,EAASS,EAAO,QAAUI,GAC1BC,EAAMd,EAAO,OAEnB,OAAAI,EAAO,WAAWM,CAAM,EAAE,WAAWC,CAAS,EAC9CP,EAAO,SAASU,CAAG,EAEnBf,GAAYC,EAAQS,EAAO,WAAW,EAEtCL,EAAO,SAASU,CAAG,EACnBV,EAAO,IAAIC,EAAY,MAAM,CAAC,EAG9BD,EAAO,SAASQ,EAAS,EAAmB,CAAgB,EACrDR,EAAO,MAAM,EAAS,CAC/B,EAOMW,GAAe,IAAI,WAAW,CAClC,GACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,CACF,CAAC,EAEKC,GAAWP,GAAkC,CAEjD,GAAI,CAACA,GAAW,CAACA,EAAO,QAAU,CAACA,EAAO,KACxC,OAAOM,GAGT,IAAML,EAASD,EAAO,QAAU,GAC1BQ,EAAOR,EAAO,MAAQ,EAEtBS,EAAeX,EAAeG,CAAM,EACpCI,EAAM,EAAII,EAAe,EAAI,EAE7BC,EAAa,IAAI,SAAS,IAAI,YAAY,EAAIL,CAAG,CAAC,EACxD,OAAAK,EAAW,SAAS,EAAG,EAAY,EACnCA,EAAW,SAAS,EAAGL,EAAK,EAAK,EACjC,IAAI,YAAY,EAAE,WAAWJ,EAAQ,IAAI,WAAWS,EAAW,OAAQ,CAAC,CAAC,EACzEA,EAAW,SAASD,EAAe,EAAG,CAAC,EACvCC,EAAW,UAAUA,EAAW,WAAa,EAAGF,EAAM,EAAK,EACpD,IAAI,WAAWE,EAAW,MAAM,CACzC,EAEMC,GAAS,CAACC,EAAmBC,IAAkC,CACnE,IAAMH,EAAa,IAAI,SAAS,IAAI,YAAY,EAAE,CAAC,EACnD,OAAAA,EAAW,SAAS,EAAG,GAAI,EAAK,EAChCA,EAAW,SAAS,EAAG,KAAM,EAAK,EAClCA,EAAW,SAAS,EAAG,KAAM,EAAK,EAClCA,EAAW,SAAS,EAAGE,EAAW,EAAK,EACvCF,EAAW,SAAS,GAAIG,EAAW,EAAK,EACjC,IAAI,WAAWH,EAAW,MAAM,CACzC,EAOMI,GAAiB,CAACC,EAAYC,IAA+B,CACjE,IAAMrB,EAAS,IAAIsB,EACnB,OAAAtB,EAAO,WAAWqB,CAAM,EACjBrB,EAAO,MAAMoB,CAAI,CAC1B,EAEMG,GAAsBvB,EAAO,WAAW,GAAG,EAAE,MAAM,EAAa,EAChEwB,GAAyBxB,EAAO,WAAW,GAAG,EAAE,MAAM,EAAa,EAEnEyB,GAAYC,GACTA,EAAI,KACPP,GAAe,GAAe,GAAGO,EAAI,IAAI,GAAGA,EAAI,MAAQ,EAAE,EAAE,EAC5DA,EAAI,OAAS,IACXH,GACAC,GAGFG,GAASD,GAAgC,CAC7C,IAAME,EAAO,GAAGF,EAAI,IAAI,GAAGA,EAAI,MAAQ,EAAE,GACzC,OAAOP,GAAe,GAAYS,CAAI,CACxC,EAEMC,GAAYC,GACT9B,EAAO,IAAI8B,CAAK,EAAE,MAAM,GAAkB,EAG7CC,GAAYC,GACTb,GAAe,IAAea,CAAO,EAGxCC,GAAkBb,GACtB,IAAI,WAAW,CAACA,EAAM,EAAM,EAAM,EAAM,CAAI,CAAC,EAEzCc,GAAcD,GAAe,EAAU,EACvCE,GAAaF,GAAe,EAAS,EACrCG,GAAYH,GAAe,EAAQ,EACnCI,GAAiBJ,GAAe,EAAa,EAE7CK,EAAY,CAChB,QAAAC,GACA,SAAAC,GACA,WAAAC,GACA,+BAAAC,GACA,4BAAAC,GACA,MAAAC,GACA,MAAAC,GACA,KAAAzC,GACA,QAAAQ,GACA,SAAAa,GACA,MAAAE,GACA,MAAO,IAAMO,GACb,KAAM,IAAMC,GACZ,IAAK,IAAMC,GACX,SAAAP,GACA,SAAU,IAAMQ,GAChB,SAAAN,GACA,OAAAf,EACF,ECrSA,IAAM8B,GAAc,IAAI,YAAY,CAAC,ECoCrC,IAAMC,GAAc,EAGdC,GAAa,EAEbC,GAAgBF,GAAcC,GAO9BE,GAAc,IAAI,YAAY,CAAC,EChDrC,IAAAC,EAAAC,EAAAC,EAAAC,EAAAC,GAAAC,EAAAC,GA2BsBC,GAAf,KAEP,CAFO,cAAAC,EAAA,KAAAN,GAGL,iBAAmD,CAAE,GAAGO,EAAY,EACpE,aAA2C,CAAE,GAAGC,EAAQ,EACxDF,EAAA,KAAAR,EAAyB,IAMzBQ,EAAA,KAAAP,EAAiB,IAkEjB,MAAM,gBAAgB,CAAE,MAAAU,EAAQ,EAAM,EAAI,CAAC,EAAG,CAC5C,GAAIC,EAAA,KAAKZ,IAA0B,CAACW,EAAO,OAC3CE,EAAA,KAAKb,EAAyB,IAE9B,IAAMc,EAAQ,MAAM,KAAK,MAAyC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,KAOjE,EAED,QAAWC,KAAQD,EAAM,KACvB,KAAK,YAAYC,EAAK,QAAQ,EAAKC,GACjCC,GAAgBD,EAAG,KAAK,YAAYD,EAAK,GAAG,EAAGA,EAAK,QAAQ,EAC9D,KAAK,QAAQA,EAAK,QAAQ,EAAKC,GAC7BE,GAAYF,EAAG,KAAK,QAAQD,EAAK,GAAG,EAAGA,EAAK,QAAQ,CAE1D,CAaA,MAAM,mBAAoB,CACxB,MAAM,KAAK,gBAAgB,CAAE,MAAO,EAAK,CAAC,CAC5C,CASA,MAAM,MACJI,EACAC,EACAC,EACqB,CACrB,aAAM,KAAK,YAAY,EAIhB,MAAM,KAAK,yBAAyB,SAClC,MAAMC,EAAA,KAAKpB,EAAAE,IAAL,UAAkBe,EAAOC,EAAQC,EAC/C,CACH,CAmBA,MAAM,IACJE,KACGH,EACkB,CACrB,GAAM,CAAE,MAAAD,EAAO,OAAQK,CAAa,EAAIL,GAAcI,EAAY,GAAGH,CAAM,EAC3E,OAAO,MAAM,KAAK,MAAMD,EAAOK,CAAY,CAC7C,CAQA,MAAM,KAAKL,EAAeE,EAAiD,CACzE,aAAM,KAAK,YAAY,EAIhB,MAAM,KAAK,yBAAyB,SAClC,MAAMC,EAAA,KAAKpB,EAAAG,GAAL,UAAcc,EAAOE,EACnC,CACH,CAkIA,MAAM,cACJF,EACAE,EAC8B,CAC9B,GAAI,CACF,MAAMC,EAAA,KAAKpB,EAAAC,GAAL,UACJsB,EAAkB,MAAM,CAAE,KAAMN,EAAO,MAAOE,GAAS,UAAW,CAAC,EACnEA,GAGF,IAAMK,EAAkB,MAAMJ,EAAA,KAAKpB,EAAAC,GAAL,UAC5BsB,EAAkB,SAAS,CAAE,KAAM,GAAI,CAAC,EACxCJ,GAEIM,EAAmBD,EAAgB,SAAS,KAC/CE,GACCA,EAAI,OAAS,sBACjB,EACMC,EAAoBH,EAAgB,SAAS,KAChDE,GAAsCA,EAAI,OAAS,gBACtD,EAEME,EACJH,GAAkB,YAAY,IAAKI,IAAgB,CACjD,WAAAA,EACA,WAAY,KAAK,YAAYA,CAAU,CACzC,EAAE,GAAK,CAAC,EAEJC,EACJH,GAAmB,OAAO,IAAKI,IAAW,CACxC,KAAMA,EAAM,KACZ,WAAYA,EAAM,WAClB,OAAQ,KAAK,QAAQA,EAAM,UAAU,CACvC,EAAE,GAAK,CAAC,EAEV,MAAO,CAAE,YAAAH,EAAa,aAAAE,CAAa,CACrC,QAAE,CACA,MAAMV,EAAA,KAAKpB,EAAAC,GAAL,UAAyBsB,EAAkB,KAAK,EAAGJ,EAC3D,CACF,CAOA,MAAM,YAAea,EAAuD,CAC1E,aAAM,KAAK,YAAY,EAChB,MAAM,KAAK,yBAAyB,SAAY,CACrD,MAAMZ,EAAA,KAAKpB,EAAAG,GAAL,UAAc,SACpBQ,EAAA,KAAKZ,EAAiB,IAGtB,IAAIkC,EAAS,GACPC,EAAc,IAAM,CACxB,GAAID,EACF,MAAM,IAAI,MAAM,uBAAuB,CAE3C,EAEME,EAAkB,CACtB,MAAO,MACLlB,EACAC,EACAC,KAEAe,EAAY,EACL,MAAMd,EAAA,KAAKpB,EAAAE,IAAL,UAAee,EAAOC,EAAQC,IAE7C,IAAK,MACHE,KACGH,IACqB,CACxB,GAAM,CAAE,MAAAD,EAAO,OAAQK,CAAa,EAAIL,GACtCI,EACA,GAAGH,CACL,EACA,OAAO,MAAME,EAAA,KAAKpB,EAAAE,IAAL,UAAee,EAAOK,EACrC,EACA,KAAM,MACJL,EACAE,KAEAe,EAAY,EACL,MAAMd,EAAA,KAAKpB,EAAAG,GAAL,UAAcc,EAAOE,IAEpC,SAAU,SAAY,CACpBe,EAAY,EAGZ,MAAMd,EAAA,KAAKpB,EAAAG,GAAL,UAAc,YACpB8B,EAAS,EACX,EACA,IAAI,QAAS,CACX,OAAOA,CACT,CACF,EAEA,GAAI,CACF,IAAMG,EAAS,MAAMJ,EAASG,CAAE,EAChC,OAAKF,IACHA,EAAS,GACT,MAAMb,EAAA,KAAKpB,EAAAG,GAAL,UAAc,WAEtBQ,EAAA,KAAKZ,EAAiB,IACfqC,CACT,OAASC,EAAG,CACV,MAAKJ,GACH,MAAMb,EAAA,KAAKpB,EAAAG,GAAL,UAAc,YAEtBQ,EAAA,KAAKZ,EAAiB,IAChBsC,CACR,CACF,CAAC,CACH,CAUA,MAAM,aAAgBC,EAAkC,CACtD,OAAO,MAAM,KAAK,mBAAmBA,CAAE,CACzC,CAUF,EAlbExC,EAAA,YAMAC,EAAA,YAXKC,EAAA,YAkGCC,EAAmB,eACvBsC,EACApB,EAA+B,CAAC,EACH,CAC7B,OAAO,MAAM,KAAK,aAAaoB,EAAS,CAAE,GAAGpB,EAAS,SAAU,EAAM,CAAC,CACzE,EA+EMjB,GAAY,eAChBe,EACAC,EAAgB,CAAC,EACjBC,EACqB,CACrB,OAAO,MAAM,KAAK,mBAAmB,SAAY,CAE/CC,EAAA,KAAKpB,EAAAI,IAAL,UAAU,WAAYa,EAAOC,EAAQC,GACrC,MAAM,KAAK,YAAYA,GAAS,IAAI,EAEpC,IAAIqB,EAEJ,GAAI,CACF,GAAM,CAAE,SAAUC,CAAa,EAAI,MAAMrB,EAAA,KAAKpB,EAAAC,GAAL,UACvCsB,EAAkB,MAAM,CAAE,KAAMN,EAAO,MAAOE,GAAS,UAAW,CAAC,EACnEA,GAGIuB,EAAcC,IAEhB,MAAMvB,EAAA,KAAKpB,EAAAC,GAAL,UACJsB,EAAkB,SAAS,CAAE,KAAM,GAAI,CAAC,EACxCJ,IAEF,QACJ,EAEMyB,EAAS1B,EAAO,IAAI,CAAC2B,EAAOC,IAAM,CACtC,IAAMC,EAAML,EAAYI,CAAC,EACzB,GAAID,GAAU,KACZ,OAAO,KAET,IAAMtB,EAAYJ,GAAS,cAAc4B,CAAG,GAAK,KAAK,YAAYA,CAAG,EACrE,OAAIxB,EACKA,EAAUsB,CAAK,EAEfA,EAAM,SAAS,CAE1B,CAAC,EAEDL,EAAU,CACR,GAAGC,EACH,IACE,MAAMrB,EAAA,KAAKpB,EAAAC,GAAL,UACJsB,EAAkB,KAAK,CACrB,OAAAqB,CACF,CAAC,EACDzB,IAEF,SACF,IACE,MAAMC,EAAA,KAAKpB,EAAAC,GAAL,UACJsB,EAAkB,SAAS,CAAE,KAAM,GAAI,CAAC,EACxCJ,IAEF,SACF,IACE,MAAMC,EAAA,KAAKpB,EAAAC,GAAL,UACJsB,EAAkB,QAAQ,CAAC,CAAC,EAC5BJ,IAEF,QACJ,CACF,QAAE,CACA,MAAMC,EAAA,KAAKpB,EAAAC,GAAL,UAAyBsB,EAAkB,KAAK,EAAGJ,EAC3D,CAEA,MAAM,KAAK,aAAa,EACnBT,EAAA,KAAKX,IACR,MAAM,KAAK,SAAS,EAEtB,IAAMiD,EAAO,MAAM,KAAK,gBAAgB,EACxC,OAAOP,GAAaD,EAAS,KAAK,QAASrB,EAAS6B,CAAI,EAAE,CAAC,CAC7D,CAAC,CACH,EASM7C,EAAQ,eACZc,EACAE,EACyB,CACzB,OAAO,MAAM,KAAK,mBAAmB,SAAY,CAE/CC,EAAA,KAAKpB,EAAAI,IAAL,UAAU,UAAWa,EAAOE,GAC5B,MAAM,KAAK,YAAYA,GAAS,IAAI,EACpC,IAAIqB,EACJ,GAAI,CACFA,GACE,MAAMpB,EAAA,KAAKpB,EAAAC,GAAL,UACJsB,EAAkB,MAAMN,CAAK,EAC7BE,IAEF,QACJ,QAAE,CACA,MAAMC,EAAA,KAAKpB,EAAAC,GAAL,UAAyBsB,EAAkB,KAAK,EAAGJ,EAC3D,CACA,KAAK,aAAa,EACbT,EAAA,KAAKX,IACR,MAAM,KAAK,SAAS,EAEtB,IAAMiD,EAAO,MAAM,KAAK,gBAAgB,EACxC,OAAOP,GACLD,EACA,KAAK,QACLrB,EACA6B,CACF,CACF,CAAC,CACH,EA0IA5C,GAAI,YAAI6C,EAAa,CACf,KAAK,MAAQ,GACf,QAAQ,IAAI,GAAGA,CAAI,CAEvB,EC5cK,IAAMC,GACX,OAAO,SAAY,UACnB,OAAO,QAAQ,UAAa,UAC5B,OAAO,QAAQ,SAAS,MAAS,SAyE5B,IAAMC,GAAO,IAAc,CAEhC,GAAI,WAAW,QAAQ,WACrB,OAAO,WAAW,OAAO,WAAW,EAGtC,IAAMC,EAAQ,IAAI,WAAW,EAAE,EAE/B,GAAI,WAAW,QAAQ,gBAErB,WAAW,OAAO,gBAAgBA,CAAK,MAGvC,SAASC,EAAI,EAAGA,EAAID,EAAM,OAAQC,IAChCD,EAAMC,CAAC,EAAI,KAAK,MAAM,KAAK,OAAO,EAAI,GAAG,EAI7CD,EAAM,CAAC,EAAKA,EAAM,CAAC,EAAI,GAAQ,GAC/BA,EAAM,CAAC,EAAKA,EAAM,CAAC,EAAI,GAAQ,IAE/B,IAAME,EAAsB,CAAC,EAC7B,OAAAF,EAAM,QAASG,GAAS,CACtBD,EAAU,KAAKC,EAAK,SAAS,EAAE,EAAE,SAAS,EAAG,GAAG,CAAC,CACnD,CAAC,EAGCD,EAAU,MAAM,EAAG,CAAC,EAAE,KAAK,EAAE,EAC7B,IACAA,EAAU,MAAM,EAAG,CAAC,EAAE,KAAK,EAAE,EAC7B,IACAA,EAAU,MAAM,EAAG,CAAC,EAAE,KAAK,EAAE,EAC7B,IACAA,EAAU,MAAM,EAAG,EAAE,EAAE,KAAK,EAAE,EAC9B,IACAA,EAAU,MAAM,EAAE,EAAE,KAAK,EAAE,CAE/B,EAoHO,SAASE,GAAeC,EAAuB,CACpD,IAAIC,EACJ,OAAID,EAAM,WAAW,GAAG,GAAKA,EAAM,SAAS,GAAG,EAE7CC,EAASD,EAAM,UAAU,EAAGA,EAAM,OAAS,CAAC,EAG5CC,EAASD,EAAM,YAAY,EAEtBC,CACT,CXpPA,IAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,GAAAC,EAAAC,GAAAC,GAAAC,EAAAC,GAmBaC,GAAN,MAAMA,WACHC,EAEV,CA6BE,YAAYC,EAAgBC,EAA+B,CACzD,MAAM,EAjCHC,EAAA,KAAAT,GAILS,EAAA,KAAA5B,GACA4B,EAAA,KAAA3B,EAAqB,GAErB2B,EAAA,KAAA1B,EAAS,IACT0B,EAAA,KAAAzB,EAAU,IACVyB,EAAA,KAAAxB,EAAY,IAEZwB,EAAA,KAAAvB,EAAe,IAAI,aAEnBuB,EAAA,KAAAtB,GAEAsB,EAAA,KAAArB,EAAa,IAEbqB,EAAA,KAAApB,GACAoB,EAAA,KAAAnB,GACAmB,EAAA,KAAAlB,GACAkB,EAAA,KAAAjB,GAEAiB,EAAA,KAAAhB,GACAgB,EAAA,KAAAf,GACAe,EAAA,KAAAd,GAEAc,EAAA,KAAAb,EAAmB,IAAI,KACvBa,EAAA,KAAAZ,EAAyB,IAAI,KAE7BY,EAAA,KAAAX,GACAW,EAAA,KAAAV,GAA+C,CAAC,GAI9CW,EAAA,KAAKrB,EAAiBkB,GACtBG,EAAA,KAAKvB,EAASwB,GAAK,GACnBD,EAAA,KAAKZ,EAAcU,GAAS,YAAc,CAAC,GAE3CE,EAAA,KAAKnB,EAAqB,IAAI,QAAeqB,GAAY,CACvDC,EAAA,KAAKxB,GAAe,iBAClB,UACCyB,GAAU,CACT,GAAIA,EAAM,KAAK,OAAS,OACtBF,EAAQ,MAER,OAAM,IAAI,MAAM,iBAAiB,CAErC,EACA,CAAE,KAAM,EAAK,CACf,CACF,CAAC,GAEDF,EAAA,KAAKlB,EAAsB,IAAI,QAAeoB,GAAY,CACxD,IAAMG,EAAYD,GAA6B,CACzCA,EAAM,KAAK,OAAS,UACtBJ,EAAA,KAAKpB,EAAYwB,EAAM,KAAK,IAC5BD,EAAA,KAAKxB,GAAe,oBAAoB,UAAW0B,CAAQ,EAC3DH,EAAQ,EAEZ,EACAC,EAAA,KAAKxB,GAAe,iBAAiB,UAAW0B,CAAQ,CAC1D,CAAC,GAEDL,EAAA,KAAK7B,EAAemC,EAAA,KAAKhB,EAAAC,IAAL,UAAWO,GACjC,CAWA,aAAa,OACXD,EACAC,EACoE,CACpE,IAAMS,EAAK,IAAIZ,GAAaE,EAAQC,CAAO,EAC3C,aAAMK,EAAAI,EAAGpC,GACFoC,CACT,CAyJA,IAAI,WAAY,CACd,OAAO,IAAI,QAAeL,GAAY,CACpCC,EAAA,KAAKhC,GAAa,KAAK,IAAM,CACtBgC,EAAA,KAAKzB,GASRwB,EAAQ,EARRA,EACE,IAAI,QAAeA,GAAY,CAC7BC,EAAA,KAAK3B,GAAa,iBAAiB,YAAa,IAAM,CACpD0B,EAAQ,CACV,CAAC,CACH,CAAC,CACH,CAIJ,CAAC,CACH,CAAC,CACH,CAEA,IAAI,OAAQ,CACV,OAAOC,EAAA,KAAK/B,EACd,CAKA,IAAI,OAAQ,CACV,OAAO+B,EAAA,KAAK9B,EACd,CAKA,IAAI,QAAS,CACX,OAAO8B,EAAA,KAAK7B,EACd,CAKA,IAAI,UAAW,CACb,OAAO6B,EAAA,KAAK5B,EACd,CAMA,MAAM,OAAQ,CA7ShB,IAAAiC,EA8SQL,EAAA,KAAK7B,KAGT0B,EAAA,KAAK1B,EAAU,IACf6B,EAAA,KAAKpB,IAAmB,MAAM,EAC9BoB,EAAA,KAAKnB,IAAa,MAAM,GACxBwB,EAAAL,EAAA,KAAKlB,KAAL,MAAAuB,EAAA,WACAL,EAAA,KAAKxB,GAAe,UAAU,EAChC,CAOA,MAAO,OAAO,YAAY,GAAI,CAC5B,MAAM,KAAK,MAAM,CACnB,CAaA,MAAM,gBAAgB8B,EAA0C,CAC9D,OAAQ,MAAMH,EAAA,KAAKhB,EAAAG,GAAL,UAAU,kBAAmBgB,EAC7C,CAOA,MAAM,aAAaA,EAAkD,CACnE,OAAO,MAAMH,EAAA,KAAKhB,EAAAG,GAAL,UAAU,eAAgBgB,EACzC,CAMA,MAAM,UAAW,CACf,MAAMH,EAAA,KAAKhB,EAAAG,GAAL,UAAU,WAClB,CAOA,MAAM,OACJiB,EACAL,EAC8B,CAC9B,IAAMM,EAAYC,GAAeF,CAAO,EAExC,OAAKP,EAAA,KAAKjB,GAAiB,IAAIyB,CAAS,GACtCR,EAAA,KAAKjB,GAAiB,IAAIyB,EAAW,IAAI,GAAK,EAEhDR,EAAA,KAAKjB,GAAiB,IAAIyB,CAAS,EAAG,IAAIN,CAAQ,EAClD,MAAM,KAAK,KAAK,UAAUK,CAAO,EAAE,EAC5B,SAAY,CACjB,MAAM,KAAK,SAASC,EAAWN,CAAQ,CACzC,CACF,CAOA,MAAM,SACJK,EACAL,EACe,CACf,MAAM,KAAK,UACPA,EACFF,EAAA,KAAKjB,GAAiB,IAAIwB,CAAO,GAAG,OAAOL,CAAQ,EAEnDF,EAAA,KAAKjB,GAAiB,OAAOwB,CAAO,EAElCP,EAAA,KAAKjB,GAAiB,IAAIwB,CAAO,GAAG,OAAS,GAE/C,MAAM,KAAK,KAAK,YAAYA,CAAO,EAAE,CAEzC,CAMA,eAAeL,EAAsD,CACnE,OAAAF,EAAA,KAAKhB,GAAuB,IAAIkB,CAAQ,EACjC,IAAM,CACXF,EAAA,KAAKhB,GAAuB,OAAOkB,CAAQ,CAC7C,CACF,CAMA,gBAAgBA,EAAsD,CACpEF,EAAA,KAAKhB,GAAuB,OAAOkB,CAAQ,CAC7C,CAcA,MAAM,aAAoC,CACxC,OAAQ,MAAMC,EAAA,KAAKhB,EAAAG,GAAL,UAAU,cAC1B,CAEA,eAAeY,EAAsB,CACnC,OAAAF,EAAA,KAAK3B,GAAa,iBAAiB,gBAAiB6B,CAAQ,EACrD,IAAM,CACXF,EAAA,KAAK3B,GAAa,oBAAoB,gBAAiB6B,CAAQ,CACjE,CACF,CAEA,gBAAgBA,EAAsB,CACpCF,EAAA,KAAK3B,GAAa,oBAAoB,gBAAiB6B,CAAQ,CACjE,CAEA,MAAM,YAAYQ,EAAmC,CACnD,MAAMP,EAAA,KAAKhB,EAAAG,GAAL,UAAU,cAAeoB,EACjC,CAEA,MAAM,iBAAoD,CACxD,OAAO,MAAMP,EAAA,KAAKhB,EAAAG,GAAL,UAAU,kBACzB,CAEA,MAAM,cAA8B,CAClC,MAAMa,EAAA,KAAKhB,EAAAG,GAAL,UAAU,eAClB,CAEA,MAAM,aAAc,CAClB,MAAM,KAAK,SACb,CAEA,MAAM,mBAAsBqB,EAAkC,CAC5D,MAAMR,EAAA,KAAKhB,EAAAG,GAAL,UAAU,qBAChB,GAAI,CACF,OAAO,MAAMqB,EAAG,CAClB,QAAE,CACA,MAAMR,EAAA,KAAKhB,EAAAG,GAAL,UAAU,oBAClB,CACF,CAEA,MAAM,yBAA4BqB,EAAkC,CAClE,MAAMR,EAAA,KAAKhB,EAAAG,GAAL,UAAU,2BAChB,GAAI,CACF,OAAO,MAAMqB,EAAG,CAClB,QAAE,CACA,MAAMR,EAAA,KAAKhB,EAAAG,GAAL,UAAU,0BAClB,CACF,CACF,EAncEtB,EAAA,YACAC,EAAA,YAEAC,EAAA,YACAC,EAAA,YACAC,EAAA,YAEAC,EAAA,YAEAC,EAAA,YAEAC,EAAA,YAEAC,EAAA,YACAC,EAAA,YACAC,EAAA,YACAC,EAAA,YAEAC,EAAA,YACAC,EAAA,YACAC,EAAA,YAEAC,EAAA,YACAC,EAAA,YAEAC,EAAA,YACAC,GAAA,YA9BKC,EAAA,YAoFCC,GAAK,eAACO,EAA+B,CAAC,EAAG,CAE7C,OAAW,CAACiB,EAASC,CAAG,IAAK,OAAO,QAAQb,EAAA,KAAKf,EAAW,EAAG,CAC7D,GAAI4B,aAAe,IACjB,MAAM,IAAI,MACR,iEACF,EACK,CACL,IAAMC,EAAS,MAAMD,EAAI,MAAM,KAAM,CAAC,EAAG,EAAI,EAM7C,GALIC,EAAO,gBACT,QAAQ,KACN,oBAAoBF,CAAO,kFAC7B,EAEEE,EAAO,aAAc,CACvB,IAAMC,EAAW,KACjBA,EAASH,CAAO,EAAIE,EAAO,YAC7B,CACIA,EAAO,YACT,QAAQ,KACN,oBAAoBF,CAAO,4EAC7B,EAEEE,EAAO,MACT,MAAMA,EAAO,KAAK,EAEhBA,EAAO,OACTd,EAAA,KAAKd,IAAiB,KAAK4B,EAAO,KAAK,CAE3C,CACF,CAGA,MAAMd,EAAA,KAAKtB,GAGX,GAAM,CAAE,WAAYsC,EAAG,GAAGC,CAAc,EAAItB,EAC5CK,EAAA,KAAKxB,GAAe,YAAY,CAC9B,KAAM,OACN,QAASyC,CACX,CAAC,EAGD,MAAMjB,EAAA,KAAKrB,GAIX,IAAMuC,EAAiB,oBAAoBlB,EAAA,KAAK1B,EAAM,GACtDuB,EAAA,KAAKf,EAAuB,MAAMqC,GAAYD,CAAc,GAG5D,IAAME,EAAqB,oBAAoBpB,EAAA,KAAKvB,EAAS,GAC7DoB,EAAA,KAAKjB,EAAoB,IAAI,iBAAiBwC,CAAkB,GAGhE,IAAMC,EAAe,cAAcrB,EAAA,KAAK1B,EAAM,GAC9CuB,EAAA,KAAKhB,EAAc,IAAI,iBAAiBwC,CAAY,GAEpDrB,EAAA,KAAKpB,GAAkB,iBAAiB,UAAW,MAAOqB,GAAU,CAC9DA,EAAM,KAAK,OAAS,eACtBJ,EAAA,KAAKtB,EAAa,IAClByB,EAAA,KAAK3B,GAAa,cAAc,IAAI,MAAM,eAAe,CAAC,EAC1D8B,EAAA,KAAKhB,EAAAE,IAAL,YACSY,EAAM,KAAK,OAAS,UAC7BE,EAAA,KAAKhB,EAAAI,IAAL,UAA0BU,EAAM,KAAK,QAASA,EAAM,KAAK,QAE7D,CAAC,EAEDD,EAAA,KAAKnB,GAAY,iBAAiB,UAAW,MAAOoB,GAAU,CACxDA,EAAM,KAAK,OAAS,cACtBJ,EAAA,KAAKtB,EAAa,IAClByB,EAAA,KAAK3B,GAAa,cAAc,IAAI,MAAM,WAAW,CAAC,EACtDwB,EAAA,KAAK5B,EAAS,MAAMkC,EAAA,KAAKhB,EAAAG,GAAL,UAAU,kBAC9BO,EAAA,KAAK3B,EAAS,IAElB,CAAC,EAED8B,EAAA,KAAKxB,GAAe,iBAAiB,UAAW,MAAOyB,GAAU,CAC3DA,EAAM,KAAK,OAAS,eACtBJ,EAAA,KAAKzB,EAAY,IACjB4B,EAAA,KAAK3B,GAAa,cAAc,IAAI,MAAM,eAAe,CAAC,EAE9D,CAAC,EAED8B,EAAA,KAAKhB,EAAAE,IAAL,WAKA,KAAK,gBAAgB,CACvB,EAEMA,GAAiB,gBAAG,CACnBW,EAAA,KAAKzB,KACRyB,EAAA,KAAKpB,GAAmB,YAAY,CAClC,KAAM,WACN,GAAIoB,EAAA,KAAK1B,EACX,CAAC,EACD,WAAW,IAAM6B,EAAA,KAAKhB,EAAAE,IAAL,WAA0B,EAAE,EAEjD,EAEMC,EAAoC,eACxCgC,KACGC,EACqC,CACxC,IAAMC,EAAS1B,GAAK,EACdQ,EAAiC,CACrC,KAAM,WACN,OAAAkB,EACA,OAAAF,EACA,KAAAC,CACF,EACA,OAAAvB,EAAA,KAAKnB,GAAa,YAAYyB,CAAO,EAC9B,MAAM,IAAI,QACf,CAACP,EAAS0B,IAAW,CACnB,IAAMC,EAAYzB,GAAwB,CACxC,GAAIA,EAAM,KAAK,SAAWuB,EAAQ,OAClCG,EAAQ,EACR,IAAMrB,EAAqCL,EAAM,KACjD,GAAIK,EAAQ,OAAS,aACnBP,EAAQO,EAAQ,MAAM,UACbA,EAAQ,OAAS,YAAa,CACvC,IAAMsB,GAAQ,IAAI,MAAMtB,EAAQ,MAAM,OAAO,EAC7C,OAAO,OAAOsB,GAAOtB,EAAQ,KAAK,EAClCmB,EAAOG,EAAK,CACd,MACEH,EAAO,IAAI,MAAM,iBAAiB,CAAC,CAEvC,EACMI,EAAuB,IAAM,CAEjCF,EAAQ,EACRF,EAAO,IAAIK,EAAoB,CACjC,EACMH,EAAU,IAAM,CACpB3B,EAAA,KAAKnB,GAAa,oBAAoB,UAAW6C,CAAQ,EACzD1B,EAAA,KAAK3B,GAAa,oBAChB,gBACAwD,CACF,CACF,EACA7B,EAAA,KAAK3B,GAAa,iBAChB,gBACAwD,CACF,EACA7B,EAAA,KAAKnB,GAAa,iBAAiB,UAAW6C,CAAQ,CACxD,CACF,CACF,EAkKAnC,GAAoB,SAACgB,EAAiBwB,EAAiB,CACrD,IAAMC,EAAYhC,EAAA,KAAKjB,GAAiB,IAAIwB,CAAO,EACnD,GAAIyB,EACF,QAAWN,KAAYM,EACrB,eAAe,IAAMN,EAASK,CAAO,CAAC,EAG1C,QAAWL,KAAY1B,EAAA,KAAKhB,GAC1B,eAAe,IAAM0C,EAASnB,EAASwB,CAAO,CAAC,CAEnD,EArZK,IAAME,GAANzC,GA6cP,eAAsBE,GAAO,CAAE,KAAAwC,CAAK,EAAkB,CAEpD,YAAY,CAAE,KAAM,MAAO,CAAC,EAG5B,IAAMvC,EAAU,MAAM,IAAI,QACvBI,GAAY,CACX,iBACE,UACCE,GAAU,CACLA,EAAM,KAAK,OAAS,QACtBF,EAAQE,EAAM,KAAK,OAAO,CAE9B,EACA,CAAE,KAAM,EAAK,CACf,CACF,CACF,EAMMkC,EAAKxC,EAAQ,IAAM,GAAGyC,CAAe,IAAIzC,EAAQ,SAAW,EAAE,GAGpE,YAAY,CAAE,KAAM,QAAS,GAAAwC,CAAG,CAAC,EAEjC,IAAME,EAAiB,wBAAwBF,CAAE,GAC3Cf,EAAqB,oBAAoBe,CAAE,GAC3CG,EAAmB,IAAI,iBAAiBlB,CAAkB,EAC1DmB,EAAgB,IAAI,IAK1B,MAAMpB,GAAYkB,CAAc,EAGhC,IAAMG,EAAYN,EAAKvC,CAAO,EAG9B2C,EAAiB,UAAY,MAAOrC,GAAU,CAC5C,IAAMwC,EAAMxC,EAAM,KAClB,OAAQwC,EAAI,KAAM,CAChB,IAAK,WAEHC,GAAWD,EAAI,GAAI,MAAMD,EAAWD,CAAa,EACjD,KACJ,CACF,EAGAD,EAAiB,YAAY,CAAE,KAAM,cAAe,GAAAH,CAAG,CAAC,EAGxD,YAAY,CAAE,KAAM,YAAa,CAAC,GAEvB,MAAMK,GAGd,eAAe,CAACjC,EAASwB,IAAY,CACtCO,EAAiB,YAAY,CAAE,KAAM,SAAU,QAAA/B,EAAS,QAAAwB,CAAQ,CAAC,CACnE,CAAC,CACH,CAEA,SAASW,GAAWC,EAAevC,EAAYmC,EAA4B,CACzE,GAAIA,EAAc,IAAII,CAAK,EACzB,OAEFJ,EAAc,IAAII,CAAK,EACvB,IAAMtB,EAAe,cAAcsB,CAAK,GAClCzB,EAAiB,oBAAoByB,CAAK,GAC1CC,EAAa,IAAI,iBAAiBvB,CAAY,EAGpD,UAAU,MAAM,QAAQH,EAAgB,IAC/B,IAAI,QAAenB,GAAY,CAEpC6C,EAAW,MAAM,EACjBL,EAAc,OAAOI,CAAK,EAC1B5C,EAAQ,CACV,CAAC,CACF,EAED,IAAM8C,EAAMC,GAAcH,EAAOvC,CAAE,EAEnCwC,EAAW,iBAAiB,UAAW,MAAO3C,GAAU,CACtD,IAAMwC,EAAMxC,EAAM,KAClB,OAAQwC,EAAI,KAAM,CAChB,IAAK,WAAY,CACf,MAAMrC,EAAG,UACT,GAAM,CAAE,OAAAoB,EAAQ,OAAAF,EAAQ,KAAAC,CAAK,EAAIkB,EACjC,GAAI,CAEF,IAAMM,EAAU,MAAMF,EAAIvB,CAAM,EAAE,GAAGC,CAAI,EAGzCqB,EAAW,YAAY,CACrB,KAAM,aACN,OAAApB,EACA,OAAAuB,CACF,CAA0C,CAC5C,OAASnB,EAAO,CACd,QAAQ,MAAMA,CAAK,EACnBgB,EAAW,YAAY,CACrB,KAAM,YACN,OAAApB,EACA,MAAO,CAAE,QAAUI,EAAgB,OAAQ,CAC7C,CAA0B,CAC5B,CACA,KACF,CACF,CACF,CAAC,EAGDgB,EAAW,YAAY,CAAE,KAAM,WAAY,CAAC,CAC9C,CAEA,SAASE,GAAcH,EAAeK,EAAY,CAChD,IAAIC,EAAwC,KACxCC,EAA8C,KAI5ChC,EAAiB,oBAAoByB,CAAK,GAChD,OAAAxB,GAAYD,CAAc,EAAE,KAAK,IAAM,CACjCgC,GAEFF,EAAG,KAAK,UAAU,EAEpBC,IAAmB,EACnBC,IAAyB,CAC3B,CAAC,EAEM,CACL,MAAM,eAAgB,CACpB,OAAOF,EAAG,KACZ,EACA,MAAM,OAAQ,CACZ,MAAMA,EAAG,MAAM,CACjB,EACA,MAAM,aAAa1C,EAAqB,CACtC,GAAM,CAAE,SAAA6C,EAAU,KAAAC,CAAK,EAAI,MAAMJ,EAAG,aAAa1C,CAAO,EACxD,GAAI8C,EAAK,aAAeA,EAAK,OAAO,WAAY,CAC9C,IAAMC,EAAS,IAAI,YAAYD,EAAK,UAAU,EACxCE,EAAW,IAAI,WAAWD,CAAM,EACtC,OAAAC,EAAS,IAAIF,CAAI,EACV,CAAE,SAAAD,EAAU,KAAMG,CAAS,CACpC,KACE,OAAO,CAAE,SAAAH,EAAU,KAAAC,CAAK,CAE5B,EACA,MAAM,gBACJ9C,EACAX,EAA6D,CAAC,EAC9D,CACA,IAAMoD,EAAS,MAAMC,EAAG,gBAAgB1C,EAASX,CAAO,EACxD,GAAIoD,EAAO,aAAeA,EAAO,OAAO,WAAY,CAGlD,IAAMM,EAAS,IAAI,YAAYN,EAAO,UAAU,EAC1CQ,EAAa,IAAI,WAAWF,CAAM,EACxC,OAAAE,EAAW,IAAIR,CAAM,EACdQ,CACT,KACE,QAAOR,CAEX,EACA,MAAM,aAAc,CAClB,OAAO,MAAMC,EAAG,YAAY,CAC9B,EACA,MAAM,UAAW,CACf,OAAO,MAAMA,EAAG,SAAS,CAC3B,EACA,MAAM,YAAYtC,EAAoB,CACpC,OAAO,MAAMsC,EAAG,YAAYtC,CAAI,CAClC,EACA,MAAM,iBAAkB,CACtB,OAAO,MAAMsC,EAAG,gBAAgB,CAClC,EACA,MAAM,cAAe,CACnB,OAAO,MAAMA,EAAG,aAAa,CAC/B,EACA,MAAM,aAAc,CAClB,OAAO,MAAMA,EAAG,YAAY,CAC9B,EACA,MAAM,mBAAoB,CACxB,OAAO,IAAI,QAAejD,GAAY,CACpCiD,EAAG,mBAAmB,IACb,IAAI,QAAeQ,GAAY,CACpCP,EAAmBO,EACnBzD,EAAQ,CACV,CAAC,CACF,CACH,CAAC,CACH,EACA,MAAM,mBAAoB,CACxBkD,IAAmB,EACnBA,EAAmB,IACrB,EACA,MAAM,yBAA0B,CAC9B,OAAO,IAAI,QAAelD,GAAY,CACpCiD,EAAG,yBAAyB,IACnB,IAAI,QAAeQ,GAAY,CACpCN,EAAyBM,EACzBzD,EAAQ,CACV,CAAC,CACF,CACH,CAAC,CACH,EACA,MAAM,yBAA0B,CAC9BmD,IAAyB,EACzBA,EAAyB,IAC3B,CACF,CACF,CAEO,IAAMpB,GAAN,cAAiC,KAAM,CAC5C,aAAc,CACZ,MAAM,0DAA0D,CAClE,CACF,EAEA,eAAeX,GAAYsC,EAAgB,CACzC,IAAID,EACJ,aAAM,IAAI,QAAezD,GAAY,CACnC,UAAU,MAAM,QAAQ0D,EAAQ,IACvB,IAAI,QAAeC,GAAoB,CAC5CF,EAAUE,EACV3D,EAAQ,CACV,CAAC,CACF,CACH,CAAC,EACMyD,CACT","names":["worker_exports","__export","LeaderChangedError","PGliteWorker","worker","__toCommonJS","getImportMetaUrl","importMetaUrl","TemplateType","addToLastAndPushWithSuffix","arr","suffix","values","lastArrIdx","lastValIdx","sql","strings","parsedStrings","parsedValues","value","nextStringIdx","query","strings","values","queryStringParts","params","sql","_","idx","JSON_parse","JSON_stringify","BOOL","BYTEA","INT8","INT2","INT4","TEXT","OID","JSON","FLOAT4","FLOAT8","BPCHAR","VARCHAR","DATE","TIMESTAMP","TIMESTAMPTZ","JSONB","types","TEXT","VARCHAR","BPCHAR","x","INT2","INT4","OID","FLOAT4","FLOAT8","INT8","n","JSON","JSONB","JSON_stringify","JSON_parse","BOOL","TIMESTAMPTZ","DATE","TIMESTAMP","BYTEA","byte","hexString","_","idx","defaultHandlers","typeHandlers","parsers","serializers","parseType","type","handler","k","to","from","serialize","parse","f","escapeBackslash","escapeQuote","arrayEscape","arraySerializer","xs","serializer","typarray","first","delimiter","arrayParserState","arrayParser","parser","arrayParserLoop","s","parseResults","messages","defaultParsers","options","blob","resultSets","currentResultSet","affectedRows","parsers","message","msg","field","i","parseType","retrieveRowCount","parts","parseDescribeStatementResults","byteLengthUtf8","str","byteLength","i","code","_bufferView","_offset","_littleEndian","_encoder","_headerPosition","_Writer_instances","allocateBuffer_fn","ensure_fn","join_fn","Writer","size","__privateAdd","__privateSet","__privateMethod","num","__privateGet","string","__privateWrapper","length","byteLengthUtf8","otherBuffer","code","result","oldBuffer","newSize","writer","Writer","startup","opts","key","bodyBuffer","length","requestSsl","bufferView","password","sendSASLInitialResponseMessage","mechanism","initialResponse","byteLengthUtf8","sendSCRAMClientFinalMessage","additionalData","query","text","emptyValueArray","parse","name","buffer","type","paramWriter","writeValues","values","valueMapper","i","mappedVal","writer","paramWriter","buffer","byteLengthUtf8","bind","config","portal","statement","binary","emptyValueArray","len","emptyExecute","execute","rows","portalLength","bufferView","cancel","processID","secretKey","cstringMessage","code","string","Writer","emptyDescribePortal","emptyDescribeStatement","describe","msg","close","text","copyData","chunk","copyFail","message","codeOnlyBuffer","flushBuffer","syncBuffer","endBuffer","copyDoneBuffer","serialize","startup","password","requestSsl","sendSASLInitialResponseMessage","sendSCRAMClientFinalMessage","query","parse","emptyBuffer","CODE_LENGTH","LEN_LENGTH","HEADER_LENGTH","emptyBuffer","_arrayTypesInitialized","_inTransaction","_BasePGlite_instances","execProtocolNoSync_fn","runQuery_fn","runExec_fn","log_fn","BasePGlite","__privateAdd","serializers","parsers","force","__privateGet","__privateSet","types","type","x","arraySerializer","arrayParser","query","params","options","__privateMethod","sqlStrings","actualParams","serialize","describeResults","paramDescription","msg","resultDescription","queryParams","dataTypeID","resultFields","field","callback","closed","checkClosed","tx","result","e","fn","message","results","parseResults","dataTypeIDs","parseDescribeStatementResults","values","param","i","oid","blob","args","IN_NODE","uuid","bytes","i","hexValues","byte","toPostgresName","input","output","_initPromise","_debug","_ready","_closed","_isLeader","_eventTarget","_tabId","_connected","_workerProcess","_workerID","_workerHerePromise","_workerReadyPromise","_broadcastChannel","_tabChannel","_releaseTabCloseLock","_notifyListeners","_globalNotifyListeners","_extensions","_extensionsClose","_PGliteWorker_instances","init_fn","leaderNotifyLoop_fn","rpc_fn","receiveNotification_fn","_PGliteWorker","BasePGlite","worker","options","__privateAdd","__privateSet","uuid","resolve","__privateGet","event","callback","__privateMethod","pg","_a","message","channel","pgChannel","toPostgresName","blob","fn","extName","ext","extRet","instance","_","workerOptions","tabCloseLockId","acquireLock","broadcastChannelId","tabChannelId","method","args","callId","reject","listener","cleanup","error","leaderChangeListener","LeaderChangedError","payload","listeners","PGliteWorker","init","id","importMetaUrl","electionLockId","broadcastChannel","connectedTabs","dbPromise","msg","connectTab","tabId","tabChannel","api","makeWorkerApi","result","db","queryLockRelease","transactionLockRelease","messages","data","buffer","dataCopy","resultCopy","release","lockId","releaseCallback"]}