1 line
132 KiB
Plaintext
1 line
132 KiB
Plaintext
{"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.2_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/messages.ts","../../../pg-protocol/src/buffer-reader.ts","../../../pg-protocol/src/parser.ts","../../src/errors.ts","../../src/base.ts","../../src/utils.ts"],"sourcesContent":["import type {\n DebugLevel,\n ExecProtocolResult,\n Extensions,\n PGliteInterface,\n PGliteInterfaceExtensions,\n PGliteOptions,\n Transaction,\n} from '../interface.js'\nimport type { PGlite } from '../pglite.js'\nimport { BasePGlite } from '../base.js'\nimport { toPostgresName, uuid } from '../utils.js'\nimport { DumpTarCompressionOptions } from '../fs/tarUtils.js'\nimport { BackendMessage } from '@electric-sql/pg-protocol/messages'\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 * 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 execProtocolStream(message: Uint8Array): Promise<BackendMessage[]> {\n return await this.#rpc('execProtocolStream', 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 tx?: Transaction,\n ): Promise<() => Promise<void>> {\n const pgChannel = toPostgresName(channel)\n const pg = tx ?? this\n if (!this.#notifyListeners.has(pgChannel)) {\n this.#notifyListeners.set(pgChannel, new Set())\n }\n this.#notifyListeners.get(pgChannel)!.add(callback)\n await pg.exec(`LISTEN ${channel}`)\n return async (tx?: Transaction) => {\n await this.unlisten(pgChannel, callback, tx)\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 tx?: Transaction,\n ): Promise<void> {\n await this.waitReady\n const pg = tx ?? this\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 pg.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(\n compression?: DumpTarCompressionOptions,\n ): Promise<File | Blob> {\n return (await this.#rpc('dumpDataDir', compression)) 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 execProtocolStream(message: Uint8Array) {\n const messages = await db.execProtocolStream(message)\n return messages\n },\n async execProtocolRaw(message: Uint8Array) {\n const result = await db.execProtocolRaw(message)\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(compression?: DumpTarCompressionOptions) {\n return await db.dumpDataDir(compression)\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 case 'MERGE':\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","import { Mode } from './types'\n\nexport type MessageName =\n | 'parseComplete'\n | 'bindComplete'\n | 'closeComplete'\n | 'noData'\n | 'portalSuspended'\n | 'replicationStart'\n | 'emptyQuery'\n | 'copyDone'\n | 'copyData'\n | 'rowDescription'\n | 'parameterDescription'\n | 'parameterStatus'\n | 'backendKeyData'\n | 'notification'\n | 'readyForQuery'\n | 'commandComplete'\n | 'dataRow'\n | 'copyInResponse'\n | 'copyOutResponse'\n | 'authenticationOk'\n | 'authenticationMD5Password'\n | 'authenticationCleartextPassword'\n | 'authenticationSASL'\n | 'authenticationSASLContinue'\n | 'authenticationSASLFinal'\n | 'error'\n | 'notice'\n\nexport type BackendMessage = {\n name: MessageName\n length: number\n}\n\nexport const parseComplete: BackendMessage = {\n name: 'parseComplete',\n length: 5,\n}\n\nexport const bindComplete: BackendMessage = {\n name: 'bindComplete',\n length: 5,\n}\n\nexport const closeComplete: BackendMessage = {\n name: 'closeComplete',\n length: 5,\n}\n\nexport const noData: BackendMessage = {\n name: 'noData',\n length: 5,\n}\n\nexport const portalSuspended: BackendMessage = {\n name: 'portalSuspended',\n length: 5,\n}\n\nexport const replicationStart: BackendMessage = {\n name: 'replicationStart',\n length: 4,\n}\n\nexport const emptyQuery: BackendMessage = {\n name: 'emptyQuery',\n length: 4,\n}\n\nexport const copyDone: BackendMessage = {\n name: 'copyDone',\n length: 4,\n}\n\nexport class AuthenticationOk implements BackendMessage {\n public readonly name = 'authenticationOk'\n constructor(public readonly length: number) {}\n}\n\nexport class AuthenticationCleartextPassword implements BackendMessage {\n public readonly name = 'authenticationCleartextPassword'\n constructor(public readonly length: number) {}\n}\n\nexport class AuthenticationMD5Password implements BackendMessage {\n public readonly name = 'authenticationMD5Password'\n constructor(\n public readonly length: number,\n public readonly salt: Uint8Array,\n ) {}\n}\n\nexport class AuthenticationSASL implements BackendMessage {\n public readonly name = 'authenticationSASL'\n constructor(\n public readonly length: number,\n public readonly mechanisms: string[],\n ) {}\n}\n\nexport class AuthenticationSASLContinue implements BackendMessage {\n public readonly name = 'authenticationSASLContinue'\n constructor(\n public readonly length: number,\n public readonly data: string,\n ) {}\n}\n\nexport class AuthenticationSASLFinal implements BackendMessage {\n public readonly name = 'authenticationSASLFinal'\n constructor(\n public readonly length: number,\n public readonly data: string,\n ) {}\n}\n\nexport type AuthenticationMessage =\n | AuthenticationOk\n | AuthenticationCleartextPassword\n | AuthenticationMD5Password\n | AuthenticationSASL\n | AuthenticationSASLContinue\n | AuthenticationSASLFinal\n\ninterface NoticeOrError {\n message: string | undefined\n severity: string | undefined\n code: string | undefined\n detail: string | undefined\n hint: string | undefined\n position: string | undefined\n internalPosition: string | undefined\n internalQuery: string | undefined\n where: string | undefined\n schema: string | undefined\n table: string | undefined\n column: string | undefined\n dataType: string | undefined\n constraint: string | undefined\n file: string | undefined\n line: string | undefined\n routine: string | undefined\n}\n\nexport class DatabaseError extends Error implements NoticeOrError {\n public severity: string | undefined\n public code: string | undefined\n public detail: string | undefined\n public hint: string | undefined\n public position: string | undefined\n public internalPosition: string | undefined\n public internalQuery: string | undefined\n public where: string | undefined\n public schema: string | undefined\n public table: string | undefined\n public column: string | undefined\n public dataType: string | undefined\n public constraint: string | undefined\n public file: string | undefined\n public line: string | undefined\n public routine: string | undefined\n constructor(\n message: string,\n public readonly length: number,\n public readonly name: MessageName,\n ) {\n super(message)\n }\n}\n\nexport class CopyDataMessage implements BackendMessage {\n public readonly name = 'copyData'\n constructor(\n public readonly length: number,\n public readonly chunk: Uint8Array,\n ) {}\n}\n\nexport class CopyResponse implements BackendMessage {\n public readonly columnTypes: number[]\n constructor(\n public readonly length: number,\n public readonly name: MessageName,\n public readonly binary: boolean,\n columnCount: number,\n ) {\n this.columnTypes = new Array(columnCount)\n }\n}\n\nexport class Field {\n constructor(\n public readonly name: string,\n public readonly tableID: number,\n public readonly columnID: number,\n public readonly dataTypeID: number,\n public readonly dataTypeSize: number,\n public readonly dataTypeModifier: number,\n public readonly format: Mode,\n ) {}\n}\n\nexport class RowDescriptionMessage implements BackendMessage {\n public readonly name: MessageName = 'rowDescription'\n public readonly fields: Field[]\n constructor(\n public readonly length: number,\n public readonly fieldCount: number,\n ) {\n this.fields = new Array(this.fieldCount)\n }\n}\n\nexport class ParameterDescriptionMessage implements BackendMessage {\n public readonly name: MessageName = 'parameterDescription'\n public readonly dataTypeIDs: number[]\n constructor(\n public readonly length: number,\n public readonly parameterCount: number,\n ) {\n this.dataTypeIDs = new Array(this.parameterCount)\n }\n}\n\nexport class ParameterStatusMessage implements BackendMessage {\n public readonly name: MessageName = 'parameterStatus'\n constructor(\n public readonly length: number,\n public readonly parameterName: string,\n public readonly parameterValue: string,\n ) {}\n}\n\nexport class BackendKeyDataMessage implements BackendMessage {\n public readonly name: MessageName = 'backendKeyData'\n constructor(\n public readonly length: number,\n public readonly processID: number,\n public readonly secretKey: number,\n ) {}\n}\n\nexport class NotificationResponseMessage implements BackendMessage {\n public readonly name: MessageName = 'notification'\n constructor(\n public readonly length: number,\n public readonly processId: number,\n public readonly channel: string,\n public readonly payload: string,\n ) {}\n}\n\nexport class ReadyForQueryMessage implements BackendMessage {\n public readonly name: MessageName = 'readyForQuery'\n constructor(\n public readonly length: number,\n public readonly status: string,\n ) {}\n}\n\nexport class CommandCompleteMessage implements BackendMessage {\n public readonly name: MessageName = 'commandComplete'\n constructor(\n public readonly length: number,\n public readonly text: string,\n ) {}\n}\n\nexport class DataRowMessage implements BackendMessage {\n public readonly fieldCount: number\n public readonly name: MessageName = 'dataRow'\n constructor(\n public length: number,\n public fields: (string | null)[],\n ) {\n this.fieldCount = fields.length\n }\n}\n\nexport class NoticeMessage implements BackendMessage, NoticeOrError {\n constructor(\n public readonly length: number,\n public readonly message: string | undefined,\n ) {}\n public readonly name = 'notice'\n public severity: string | undefined\n public code: string | undefined\n public detail: string | undefined\n public hint: string | undefined\n public position: string | undefined\n public internalPosition: string | undefined\n public internalQuery: string | undefined\n public where: string | undefined\n public schema: string | undefined\n public table: string | undefined\n public column: string | undefined\n public dataType: string | undefined\n public constraint: string | undefined\n public file: string | undefined\n public line: string | undefined\n public routine: string | undefined\n}\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 && length > 0) {\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 { DatabaseError } from '@electric-sql/pg-protocol/messages'\nimport { QueryOptions } from './interface'\n\nexport interface PGliteError extends DatabaseError {\n query: string | undefined\n params: any[] | undefined\n queryOptions: QueryOptions | undefined\n}\n\nexport function makePGliteError(data: {\n e: DatabaseError\n query: string\n params: any[] | undefined\n options: QueryOptions | undefined\n}) {\n const pgError = data.e as PGliteError\n pgError.query = data.query\n pgError.params = data.params\n pgError.queryOptions = data.options\n return pgError\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 DatabaseError,\n BackendMessage,\n} from '@electric-sql/pg-protocol/messages'\nimport { makePGliteError } from './errors.js'\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\n * @param message The postgres wire protocol message to execute\n * @returns The parsed results of the query\n */\n abstract execProtocolStream(\n message: Uint8Array,\n { syncToFs, onNotice }: ExecProtocolOptions,\n ): Promise<BackendMessage[]>\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 }: 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 /**\n * Listen for notifications on a channel\n */\n abstract listen(\n channel: string,\n callback: (payload: string) => void,\n tx?: Transaction,\n ): Promise<(tx?: Transaction) => Promise<void>>\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 database 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<BackendMessage[]> {\n return await this.execProtocolStream(message, {\n ...options,\n syncToFs: false,\n })\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 parseResults = await this.#execProtocolNoSync(\n serializeProtocol.parse({ text: query, types: options?.paramTypes }),\n options,\n )\n\n const dataTypeIDs = parseDescribeStatementResults(\n await this.#execProtocolNoSync(\n serializeProtocol.describe({ type: 'S' }),\n options,\n ),\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 ...(await this.#execProtocolNoSync(\n serializeProtocol.bind({\n values,\n }),\n options,\n )),\n ...(await this.#execProtocolNoSync(\n serializeProtocol.describe({ type: 'P' }),\n options,\n )),\n ...(await this.#execProtocolNoSync(\n serializeProtocol.execute({}),\n options,\n )),\n ]\n } catch (e) {\n if (e instanceof DatabaseError) {\n const pgError = makePGliteError({ e, options, params, query })\n throw pgError\n }\n throw e\n } finally {\n results.push(\n ...(await this.#execProtocolNoSync(\n serializeProtocol.sync(),\n options,\n )),\n )\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 = await this.#execProtocolNoSync(\n serializeProtocol.query(query),\n options,\n )\n } catch (e) {\n if (e instanceof DatabaseError) {\n const pgError = makePGliteError({\n e,\n options,\n params: undefined,\n query,\n })\n throw pgError\n }\n throw e\n } finally {\n results.push(\n ...(await this.#execProtocolNoSync(\n serializeProtocol.sync(),\n options,\n )),\n )\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 let messages = []\n try {\n await this.#execProtocolNoSync(\n serializeProtocol.parse({ text: query, types: options?.paramTypes }),\n options,\n )\n\n messages = await this.#execProtocolNoSync(\n serializeProtocol.describe({ type: 'S' }),\n options,\n )\n } catch (e) {\n if (e instanceof DatabaseError) {\n const pgError = makePGliteError({\n e,\n options,\n params: undefined,\n query,\n })\n throw pgError\n }\n throw e\n } finally {\n messages.push(\n ...(await this.#execProtocolNoSync(serializeProtocol.sync(), options)),\n )\n }\n\n const paramDescription = messages.find(\n (msg): msg is ParameterDescriptionMessage =>\n msg.name === 'parameterDescription',\n )\n const resultDescription = 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 }\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 listen: async (\n channel: string,\n callback: (payload: string) => void,\n ) => {\n checkClosed()\n return await this.listen(channel, callback, tx)\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 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 const messages = []\n try {\n await pg.execProtocol(serializeProtocol.parse({ text: query }), {\n syncToFs: false,\n })\n\n messages.push(\n ...(\n await pg.execProtocol(serializeProtocol.describe({ type: 'S' }), {\n syncToFs: false,\n })\n ).messages,\n )\n } finally {\n messages.push(\n ...(await pg.execProtocol(serializeProtocol.sync(), { syncToFs: false }))\n .messages,\n )\n }\n\n const dataTypeIDs = parseDescribeStatementResults(messages)\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,OACL,IAAK,QACH,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,CC/GA,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,ECnJO,IAAM8B,EAAN,cAA4B,KAA+B,CAiBhE,YACEC,EACgBC,EACAC,EAChB,CACA,MAAMF,CAAO,EAHG,YAAAC,EACA,UAAAC,CAGlB,CACF,EC1KA,IAAMC,GAAc,IAAI,YAAY,CAAC,ECoCrC,IAAMC,GAAc,EAGdC,GAAa,EAEbC,GAAgBF,GAAcC,GAO9BE,GAAc,IAAI,YAAY,CAAC,ECvC9B,SAASC,GAAgBC,EAK7B,CACD,IAAMC,EAAUD,EAAK,EACrB,OAAAC,EAAQ,MAAQD,EAAK,MACrBC,EAAQ,OAASD,EAAK,OACtBC,EAAQ,aAAeD,EAAK,QACrBC,CACT,CCpBA,IAAAC,EAAAC,EAAAC,EAAAC,EAAAC,GAAAC,EAAAC,GA8BsBC,GAAf,KAEP,CAFO,cAAAC,EAAA,KAAAN,GAGL,iBAAmD,CAAE,GAAGO,EAAY,EACpE,aAA2C,CAAE,GAAGC,EAAQ,EACxDF,EAAA,KAAAR,EAAyB,IAMzBQ,EAAA,KAAAP,EAAiB,IAqFjB,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,CAgBA,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,CAmJA,MAAM,cACJF,EACAE,EAC8B,CAC9B,IAAII,EAAW,CAAC,EAChB,GAAI,CACF,MAAMH,EAAA,KAAKpB,EAAAC,GAAL,UACJuB,EAAkB,MAAM,CAAE,KAAMP,EAAO,MAAOE,GAAS,UAAW,CAAC,EACnEA,GAGFI,EAAW,MAAMH,EAAA,KAAKpB,EAAAC,GAAL,UACfuB,EAAkB,SAAS,CAAE,KAAM,GAAI,CAAC,EACxCL,EAEJ,OAASM,EAAG,CACV,MAAIA,aAAaC,EACCC,GAAgB,CAC9B,EAAAF,EACA,QAAAN,EACA,OAAQ,OACR,MAAAF,CACF,CAAC,EAGGQ,CACR,QAAE,CACAF,EAAS,KACP,GAAI,MAAMH,EAAA,KAAKpB,EAAAC,GAAL,UAAyBuB,EAAkB,KAAK,EAAGL,EAC/D,CACF,CAEA,IAAMS,EAAmBL,EAAS,KAC/BM,GACCA,EAAI,OAAS,sBACjB,EACMC,EAAoBP,EAAS,KAChCM,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,CAOA,MAAM,YAAeE,EAAuD,CAC1E,aAAM,KAAK,YAAY,EAChB,MAAM,KAAK,yBAAyB,SAAY,CACrD,MAAMf,EAAA,KAAKpB,EAAAG,GAAL,UAAc,SACpBQ,EAAA,KAAKZ,EAAiB,IAGtB,IAAIqC,EAAS,GACPC,EAAc,IAAM,CACxB,GAAID,EACF,MAAM,IAAI,MAAM,uBAAuB,CAE3C,EAEME,EAAkB,CACtB,MAAO,MACLrB,EACAC,EACAC,KAEAkB,EAAY,EACL,MAAMjB,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,KAEAkB,EAAY,EACL,MAAMjB,EAAA,KAAKpB,EAAAG,GAAL,UAAcc,EAAOE,IAEpC,SAAU,SAAY,CACpBkB,EAAY,EAGZ,MAAMjB,EAAA,KAAKpB,EAAAG,GAAL,UAAc,YACpBiC,EAAS,EACX,EACA,OAAQ,MACNG,EACAJ,KAEAE,EAAY,EACL,MAAM,KAAK,OAAOE,EAASJ,EAAUG,CAAE,GAEhD,IAAI,QAAS,CACX,OAAOF,CACT,CACF,EAEA,GAAI,CACF,IAAMI,EAAS,MAAML,EAASG,CAAE,EAChC,OAAKF,IACHA,EAAS,GACT,MAAMhB,EAAA,KAAKpB,EAAAG,GAAL,UAAc,WAEtBQ,EAAA,KAAKZ,EAAiB,IACfyC,CACT,OAASf,EAAG,CACV,MAAKW,GACH,MAAMhB,EAAA,KAAKpB,EAAAG,GAAL,UAAc,YAEtBQ,EAAA,KAAKZ,EAAiB,IAChB0B,CACR,CACF,CAAC,CACH,CAUA,MAAM,aAAgBgB,EAAkC,CACtD,OAAO,MAAM,KAAK,mBAAmBA,CAAE,CACzC,CAUF,EA/eE3C,EAAA,YAMAC,EAAA,YAXKC,EAAA,YAqHCC,EAAmB,eACvByC,EACAvB,EAA+B,CAAC,EACL,CAC3B,OAAO,MAAM,KAAK,mBAAmBuB,EAAS,CAC5C,GAAGvB,EACH,SAAU,EACZ,CAAC,CACH,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,IAAIwB,EAAU,CAAC,EAEf,GAAI,CACF,IAAMC,EAAe,MAAMxB,EAAA,KAAKpB,EAAAC,GAAL,UACzBuB,EAAkB,MAAM,CAAE,KAAMP,EAAO,MAAOE,GAAS,UAAW,CAAC,EACnEA,GAGI0B,EAAcC,GAClB,MAAM1B,EAAA,KAAKpB,EAAAC,GAAL,UACJuB,EAAkB,SAAS,CAAE,KAAM,GAAI,CAAC,EACxCL,EAEJ,EAEM4B,EAAS7B,EAAO,IAAI,CAAC8B,EAAOC,IAAM,CACtC,IAAMC,EAAML,EAAYI,CAAC,EACzB,GAAID,GAAU,KACZ,OAAO,KAET,IAAMxB,EAAYL,GAAS,cAAc+B,CAAG,GAAK,KAAK,YAAYA,CAAG,EACrE,OAAI1B,EACKA,EAAUwB,CAAK,EAEfA,EAAM,SAAS,CAE1B,CAAC,EAEDL,EAAU,CACR,GAAGC,EACH,GAAI,MAAMxB,EAAA,KAAKpB,EAAAC,GAAL,UACRuB,EAAkB,KAAK,CACrB,OAAAuB,CACF,CAAC,EACD5B,GAEF,GAAI,MAAMC,EAAA,KAAKpB,EAAAC,GAAL,UACRuB,EAAkB,SAAS,CAAE,KAAM,GAAI,CAAC,EACxCL,GAEF,GAAI,MAAMC,EAAA,KAAKpB,EAAAC,GAAL,UACRuB,EAAkB,QAAQ,CAAC,CAAC,EAC5BL,EAEJ,CACF,OAASM,EAAG,CACV,MAAIA,aAAaC,EACCC,GAAgB,CAAE,EAAAF,EAAG,QAAAN,EAAS,OAAAD,EAAQ,MAAAD,CAAM,CAAC,EAGzDQ,CACR,QAAE,CACAkB,EAAQ,KACN,GAAI,MAAMvB,EAAA,KAAKpB,EAAAC,GAAL,UACRuB,EAAkB,KAAK,EACvBL,EAEJ,CACF,CAEA,MAAM,KAAK,aAAa,EACnBT,EAAA,KAAKX,IACR,MAAM,KAAK,SAAS,EAEtB,IAAMoD,EAAO,MAAM,KAAK,gBAAgB,EACxC,OAAOP,GAAaD,EAAS,KAAK,QAASxB,EAASgC,CAAI,EAAE,CAAC,CAC7D,CAAC,CACH,EASMhD,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,IAAIwB,EAAU,CAAC,EACf,GAAI,CACFA,EAAU,MAAMvB,EAAA,KAAKpB,EAAAC,GAAL,UACduB,EAAkB,MAAMP,CAAK,EAC7BE,EAEJ,OAASM,EAAG,CACV,MAAIA,aAAaC,EACCC,GAAgB,CAC9B,EAAAF,EACA,QAAAN,EACA,OAAQ,OACR,MAAAF,CACF,CAAC,EAGGQ,CACR,QAAE,CACAkB,EAAQ,KACN,GAAI,MAAMvB,EAAA,KAAKpB,EAAAC,GAAL,UACRuB,EAAkB,KAAK,EACvBL,EAEJ,CACF,CACA,KAAK,aAAa,EACbT,EAAA,KAAKX,IACR,MAAM,KAAK,SAAS,EAEtB,IAAMoD,EAAO,MAAM,KAAK,gBAAgB,EACxC,OAAOP,GACLD,EACA,KAAK,QACLxB,EACAgC,CACF,CACF,CAAC,CACH,EAgKA/C,GAAI,YAAIgD,EAAa,CACf,KAAK,MAAQ,GACf,QAAQ,IAAI,GAAGA,CAAI,CAEvB,EC5gBK,IAAMC,GACX,OAAO,SAAY,UACnB,OAAO,QAAQ,UAAa,UAC5B,OAAO,QAAQ,SAAS,MAAS,SAwE5B,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,EAyHO,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,CbxPA,IAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,GAAAC,GAAAC,EAAAC,GAAAC,GAAAC,EAAAC,GAqBaC,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,IACAW,EAAA,KAAAV,GAA+C,CAAC,GAI9CW,EAAA,KAAKrB,EAAiBkB,GACtBG,EAAA,KAAKvB,EAASwB,GAAK,GACnBD,EAAA,KAAKZ,GAAcU,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,CA/ShB,IAAAiC,EAgTQL,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,CAOA,MAAM,mBAAmBA,EAAgD,CACvE,OAAO,MAAMH,EAAA,KAAKhB,EAAAG,GAAL,UAAU,qBAAsBgB,EAC/C,CAMA,MAAM,UAAW,CACf,MAAMH,EAAA,KAAKhB,EAAAG,GAAL,UAAU,WAClB,CAOA,MAAM,OACJiB,EACAL,EACAM,EAC8B,CAC9B,IAAMC,EAAYC,GAAeH,CAAO,EAClCH,EAAKI,GAAM,KACjB,OAAKR,EAAA,KAAKjB,GAAiB,IAAI0B,CAAS,GACtCT,EAAA,KAAKjB,GAAiB,IAAI0B,EAAW,IAAI,GAAK,EAEhDT,EAAA,KAAKjB,GAAiB,IAAI0B,CAAS,EAAG,IAAIP,CAAQ,EAClD,MAAME,EAAG,KAAK,UAAUG,CAAO,EAAE,EAC1B,MAAOC,GAAqB,CACjC,MAAM,KAAK,SAASC,EAAWP,EAAUM,CAAE,CAC7C,CACF,CAOA,MAAM,SACJD,EACAL,EACAM,EACe,CACf,MAAM,KAAK,UACX,IAAMJ,EAAKI,GAAM,KACbN,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,MAAMH,EAAG,KAAK,YAAYG,CAAO,EAAE,CAEvC,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,YACJS,EACsB,CACtB,OAAQ,MAAMR,EAAA,KAAKhB,EAAAG,GAAL,UAAU,cAAeqB,EACzC,CAEA,eAAeT,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,YAAYU,EAAmC,CACnD,MAAMT,EAAA,KAAKhB,EAAAG,GAAL,UAAU,cAAesB,EACjC,CAEA,MAAM,iBAAoD,CACxD,OAAO,MAAMT,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,mBAAsBuB,EAAkC,CAC5D,MAAMV,EAAA,KAAKhB,EAAAG,GAAL,UAAU,qBAChB,GAAI,CACF,OAAO,MAAMuB,EAAG,CAClB,QAAE,CACA,MAAMV,EAAA,KAAKhB,EAAAG,GAAL,UAAU,oBAClB,CACF,CAEA,MAAM,yBAA4BuB,EAAkC,CAClE,MAAMV,EAAA,KAAKhB,EAAAG,GAAL,UAAU,2BAChB,GAAI,CACF,OAAO,MAAMuB,EAAG,CAClB,QAAE,CACA,MAAMV,EAAA,KAAKhB,EAAAG,GAAL,UAAU,0BAClB,CACF,CACF,EAjdEtB,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,GAAA,YACAC,GAAA,YA9BKC,EAAA,YAoFCC,GAAK,eAACO,EAA+B,CAAC,EAAG,CAE7C,OAAW,CAACmB,EAASC,CAAG,IAAK,OAAO,QAAQf,EAAA,KAAKf,GAAW,EAAG,CAC7D,GAAI8B,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,OACThB,EAAA,KAAKd,IAAiB,KAAK8B,EAAO,KAAK,CAE3C,CACF,CAGA,MAAMhB,EAAA,KAAKtB,GAGX,GAAM,CAAE,WAAYwC,EAAG,GAAGC,CAAc,EAAIxB,EAC5CK,EAAA,KAAKxB,GAAe,YAAY,CAC9B,KAAM,OACN,QAAS2C,CACX,CAAC,EAGD,MAAMnB,EAAA,KAAKrB,GAIX,IAAMyC,EAAiB,oBAAoBpB,EAAA,KAAK1B,EAAM,GACtDuB,EAAA,KAAKf,EAAuB,MAAMuC,GAAYD,CAAc,GAG5D,IAAME,EAAqB,oBAAoBtB,EAAA,KAAKvB,EAAS,GAC7DoB,EAAA,KAAKjB,EAAoB,IAAI,iBAAiB0C,CAAkB,GAGhE,IAAMC,EAAe,cAAcvB,EAAA,KAAK1B,EAAM,GAC9CuB,EAAA,KAAKhB,EAAc,IAAI,iBAAiB0C,CAAY,GAEpDvB,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,eACxCkC,KACGC,EACqC,CACxC,IAAMC,EAAS5B,GAAK,EACdQ,EAAiC,CACrC,KAAM,WACN,OAAAoB,EACA,OAAAF,EACA,KAAAC,CACF,EACA,OAAAzB,EAAA,KAAKnB,GAAa,YAAYyB,CAAO,EAC9B,MAAM,IAAI,QACf,CAACP,EAAS4B,IAAW,CACnB,IAAMC,EAAY3B,GAAwB,CACxC,GAAIA,EAAM,KAAK,SAAWyB,EAAQ,OAClCG,EAAQ,EACR,IAAMvB,EAAqCL,EAAM,KACjD,GAAIK,EAAQ,OAAS,aACnBP,EAAQO,EAAQ,MAAM,UACbA,EAAQ,OAAS,YAAa,CACvC,IAAMwB,GAAQ,IAAI,MAAMxB,EAAQ,MAAM,OAAO,EAC7C,OAAO,OAAOwB,GAAOxB,EAAQ,KAAK,EAClCqB,EAAOG,EAAK,CACd,MACEH,EAAO,IAAI,MAAM,iBAAiB,CAAC,CAEvC,EACMI,EAAuB,IAAM,CAEjCF,EAAQ,EACRF,EAAO,IAAIK,EAAoB,CACjC,EACMH,EAAU,IAAM,CACpB7B,EAAA,KAAKnB,GAAa,oBAAoB,UAAW+C,CAAQ,EACzD5B,EAAA,KAAK3B,GAAa,oBAChB,gBACA0D,CACF,CACF,EACA/B,EAAA,KAAK3B,GAAa,iBAChB,gBACA0D,CACF,EACA/B,EAAA,KAAKnB,GAAa,iBAAiB,UAAW+C,CAAQ,CACxD,CACF,CACF,EA8KArC,GAAoB,SAACgB,EAAiB0B,EAAiB,CACrD,IAAMC,EAAYlC,EAAA,KAAKjB,GAAiB,IAAIwB,CAAO,EACnD,GAAI2B,EACF,QAAWN,KAAYM,EACrB,eAAe,IAAMN,EAASK,CAAO,CAAC,EAG1C,QAAWL,KAAY5B,EAAA,KAAKhB,GAC1B,eAAe,IAAM4C,EAASrB,EAAS0B,CAAO,CAAC,CAEnD,EAjaK,IAAME,GAAN3C,GA2dP,eAAsBE,GAAO,CAAE,KAAA0C,CAAK,EAAkB,CAEpD,YAAY,CAAE,KAAM,MAAO,CAAC,EAG5B,IAAMzC,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,EAMMoC,EAAK1C,EAAQ,IAAM,GAAG2C,CAAe,IAAI3C,EAAQ,SAAW,EAAE,GAGpE,YAAY,CAAE,KAAM,QAAS,GAAA0C,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,EAAKzC,CAAO,EAG9B6C,EAAiB,UAAY,MAAOvC,GAAU,CAC5C,IAAM0C,EAAM1C,EAAM,KAClB,OAAQ0C,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,CAACnC,EAAS0B,IAAY,CACtCO,EAAiB,YAAY,CAAE,KAAM,SAAU,QAAAjC,EAAS,QAAA0B,CAAQ,CAAC,CACnE,CAAC,CACH,CAEA,SAASW,GAAWC,EAAezC,EAAYqC,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,QAAerB,GAAY,CAEpC+C,EAAW,MAAM,EACjBL,EAAc,OAAOI,CAAK,EAC1B9C,EAAQ,CACV,CAAC,CACF,EAED,IAAMgD,EAAMC,GAAcH,EAAOzC,CAAE,EAEnC0C,EAAW,iBAAiB,UAAW,MAAO7C,GAAU,CACtD,IAAM0C,EAAM1C,EAAM,KAClB,OAAQ0C,EAAI,KAAM,CAChB,IAAK,WAAY,CACf,MAAMvC,EAAG,UACT,GAAM,CAAE,OAAAsB,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,aAAa5C,EAAqB,CACtC,GAAM,CAAE,SAAA+C,EAAU,KAAAC,CAAK,EAAI,MAAMJ,EAAG,aAAa5C,CAAO,EACxD,GAAIgD,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,mBAAmBhD,EAAqB,CAE5C,OADiB,MAAM4C,EAAG,mBAAmB5C,CAAO,CAEtD,EACA,MAAM,gBAAgBA,EAAqB,CACzC,IAAM2C,EAAS,MAAMC,EAAG,gBAAgB5C,CAAO,EAC/C,GAAI2C,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,YAAYtC,EAAyC,CACzD,OAAO,MAAMuC,EAAG,YAAYvC,CAAW,CACzC,EACA,MAAM,UAAW,CACf,OAAO,MAAMuC,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,QAAenD,GAAY,CACpCmD,EAAG,mBAAmB,IACb,IAAI,QAAeQ,GAAY,CACpCP,EAAmBO,EACnB3D,EAAQ,CACV,CAAC,CACF,CACH,CAAC,CACH,EACA,MAAM,mBAAoB,CACxBoD,IAAmB,EACnBA,EAAmB,IACrB,EACA,MAAM,yBAA0B,CAC9B,OAAO,IAAI,QAAepD,GAAY,CACpCmD,EAAG,yBAAyB,IACnB,IAAI,QAAeQ,GAAY,CACpCN,EAAyBM,EACzB3D,EAAQ,CACV,CAAC,CACF,CACH,CAAC,CACH,EACA,MAAM,yBAA0B,CAC9BqD,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,QAAe3D,GAAY,CACnC,UAAU,MAAM,QAAQ4D,EAAQ,IACvB,IAAI,QAAeC,GAAoB,CAC5CF,EAAUE,EACV7D,EAAQ,CACV,CAAC,CACF,CACH,CAAC,EACM2D,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","DatabaseError","message","length","name","emptyBuffer","CODE_LENGTH","LEN_LENGTH","HEADER_LENGTH","emptyBuffer","makePGliteError","data","pgError","_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","messages","serialize","e","DatabaseError","makePGliteError","paramDescription","msg","resultDescription","queryParams","dataTypeID","resultFields","field","callback","closed","checkClosed","tx","channel","result","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","tx","pgChannel","toPostgresName","compression","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"]} |