{
  "version": 3,
  "sources": ["../../../../src/workers/shared/remote-proxy-client.worker.ts", "../../../../src/workers/shared/constants.ts", "../../../../../../node_modules/.pnpm/capnweb@0.5.0/node_modules/capnweb/src/symbols.ts", "../../../../../../node_modules/.pnpm/capnweb@0.5.0/node_modules/capnweb/src/inject-workers-module.ts", "../../../../../../node_modules/.pnpm/capnweb@0.5.0/node_modules/capnweb/src/core.ts", "../../../../../../node_modules/.pnpm/capnweb@0.5.0/node_modules/capnweb/src/serialize.ts", "../../../../../../node_modules/.pnpm/capnweb@0.5.0/node_modules/capnweb/src/rpc.ts", "../../../../../../node_modules/.pnpm/capnweb@0.5.0/node_modules/capnweb/src/websocket.ts", "../../../../../../node_modules/.pnpm/capnweb@0.5.0/node_modules/capnweb/src/batch.ts", "../../../../../../node_modules/.pnpm/capnweb@0.5.0/node_modules/capnweb/src/messageport.ts", "../../../../../../node_modules/.pnpm/capnweb@0.5.0/node_modules/capnweb/src/map.ts", "../../../../../../node_modules/.pnpm/capnweb@0.5.0/node_modules/capnweb/src/streams.ts", "../../../../../../node_modules/.pnpm/capnweb@0.5.0/node_modules/capnweb/src/index.ts", "../../../../src/workers/shared/remote-bindings-utils.ts"],
  "sourcesContent": ["import { WorkerEntrypoint } from \"cloudflare:workers\";\nimport { SharedBindings } from \"./constants\";\nimport {\n\tmakeFetch,\n\tmakeRemoteProxyStub,\n\tthrowRemoteRequired,\n} from \"./remote-bindings-utils\";\nimport type { RemoteBindingEnv } from \"./remote-bindings-utils\";\n\n/** Generic remote proxy client for bindings. */\nexport default class Client extends WorkerEntrypoint<RemoteBindingEnv> {\n\tfetch(request: Request): Promise<Response> {\n\t\treturn makeFetch(\n\t\t\tthis.env.remoteProxyConnectionString,\n\t\t\tthis.env.binding,\n\t\t\tundefined,\n\t\t\tthis.env.cfTraceId,\n\t\t\tthis.env[SharedBindings.MAYBE_SERVICE_LOOPBACK]\n\t\t)(request);\n\t}\n\n\tconstructor(ctx: ExecutionContext, env: RemoteBindingEnv) {\n\t\tsuper(ctx, env);\n\n\t\tconst stub = env.remoteProxyConnectionString\n\t\t\t? makeRemoteProxyStub(\n\t\t\t\t\tenv.remoteProxyConnectionString,\n\t\t\t\t\tenv.binding,\n\t\t\t\t\tundefined,\n\t\t\t\t\tenv.cfTraceId,\n\t\t\t\t\tenv[SharedBindings.MAYBE_SERVICE_LOOPBACK]\n\t\t\t\t)\n\t\t\t: undefined;\n\n\t\treturn new Proxy(this, {\n\t\t\tget: (target, prop) => {\n\t\t\t\tif (Reflect.has(target, prop)) {\n\t\t\t\t\treturn Reflect.get(target, prop);\n\t\t\t\t}\n\t\t\t\tif (!stub) {\n\t\t\t\t\tthrowRemoteRequired(env.binding);\n\t\t\t\t}\n\t\t\t\treturn Reflect.get(stub, prop);\n\t\t\t},\n\t\t});\n\t}\n}\n", "export const SharedHeaders = {\n\tLOG_LEVEL: \"MF-Log-Level\",\n} as const;\n\nexport const SharedBindings = {\n\tTEXT_NAMESPACE: \"MINIFLARE_NAMESPACE\",\n\tDURABLE_OBJECT_NAMESPACE_OBJECT: \"MINIFLARE_OBJECT\",\n\tMAYBE_SERVICE_BLOBS: \"MINIFLARE_BLOBS\",\n\tMAYBE_SERVICE_LOOPBACK: \"MINIFLARE_LOOPBACK\",\n\tMAYBE_JSON_ENABLE_CONTROL_ENDPOINTS: \"MINIFLARE_ENABLE_CONTROL_ENDPOINTS\",\n\tMAYBE_JSON_ENABLE_STICKY_BLOBS: \"MINIFLARE_STICKY_BLOBS\",\n} as const;\n\nexport enum LogLevel {\n\tNONE,\n\tERROR,\n\tWARN,\n\tINFO,\n\tDEBUG,\n\tVERBOSE,\n}\n", "// Copyright (c) 2025 Cloudflare, Inc.\n// Licensed under the MIT license found in the LICENSE.txt file or at:\n//     https://opensource.org/license/mit\n\nexport let WORKERS_MODULE_SYMBOL = Symbol(\"workers-module\");\n", "// Copyright (c) 2025 Cloudflare, Inc.\n// Licensed under the MIT license found in the LICENSE.txt file or at:\n//     https://opensource.org/license/mit\n\nimport { WORKERS_MODULE_SYMBOL } from \"./symbols.js\";\n\n// Import cloudflare:workers and stick it in the global scope where in can be used conditionally.\n// As long as inject-workers-module.ts is imported before the rest of the library, this allows the\n// library to set up automatic interoperability with Cloudflare Workers' built-in RPC.\n//\n// Meanwhile, we define our `exports` in package.json such that when building on Workers, this\n// module is in fact imported first.\nimport * as cfw from \"cloudflare:workers\";\n(globalThis as any)[WORKERS_MODULE_SYMBOL] = cfw;\n", "// Copyright (c) 2025 Cloudflare, Inc.\n// Licensed under the MIT license found in the LICENSE.txt file or at:\n//     https://opensource.org/license/mit\n\nimport type { RpcTargetBranded, __RPC_TARGET_BRAND } from \"./types.js\";\nimport { WORKERS_MODULE_SYMBOL } from \"./symbols.js\"\n\n// Polyfill Symbol.dispose for browsers that don't support it yet\nif (!Symbol.dispose) {\n  (Symbol as any).dispose = Symbol.for('dispose');\n}\nif (!Symbol.asyncDispose) {\n  (Symbol as any).asyncDispose = Symbol.for('asyncDispose');\n}\n\n// Polyfill Promise.withResolvers() for old Safari versions (ugh), Hermes (React Native), and\n// maybe others.\nif (!Promise.withResolvers) {\n  Promise.withResolvers = function<T>(): PromiseWithResolvers<T> {\n    let resolve: (value: T | PromiseLike<T>) => void;\n    let reject: (reason?: any) => void;\n    const promise = new Promise<T>((res, rej) => {\n      resolve = res;\n      reject = rej;\n    });\n    return { promise, resolve: resolve!, reject: reject! };\n  };\n}\n\nlet workersModule: any = (globalThis as any)[WORKERS_MODULE_SYMBOL];\n\nexport interface RpcTarget {\n  [__RPC_TARGET_BRAND]: never;\n};\n\nexport let RpcTarget = workersModule ? workersModule.RpcTarget : class {};\n\nexport type PropertyPath = (string | number)[];\n\ntype TypeForRpc = \"unsupported\" | \"primitive\" | \"object\" | \"function\" | \"array\" | \"date\" |\n    \"bigint\" | \"bytes\" | \"stub\" | \"rpc-promise\" | \"rpc-target\" | \"rpc-thenable\" | \"error\" |\n    \"undefined\" | \"writable\" | \"readable\" | \"headers\" | \"request\" | \"response\";\n\nconst AsyncFunction = (async function () {}).constructor;\n\nexport function typeForRpc(value: unknown): TypeForRpc {\n  switch (typeof value) {\n    case \"boolean\":\n    case \"number\":\n    case \"string\":\n      return \"primitive\";\n\n    case \"undefined\":\n      return \"undefined\";\n\n    case \"object\":\n    case \"function\":\n      // Test by prototype, below.\n      break;\n\n    case \"bigint\":\n      return \"bigint\";\n\n    default:\n      return \"unsupported\";\n  }\n\n  // Ugh JavaScript, why is `typeof null` equal to \"object\" but null isn't otherwise anything like\n  // an object?\n  if (value === null) {\n    return \"primitive\";\n  }\n\n  // Aside from RpcTarget, we generally don't support serializing *subclasses* of serializable\n  // types, so we switch on the exact prototype rather than use `instanceof` here.\n  let prototype = Object.getPrototypeOf(value);\n  switch (prototype) {\n    case Object.prototype:\n      return \"object\";\n\n    case Function.prototype:\n    case AsyncFunction.prototype:\n      return \"function\";\n\n    case Array.prototype:\n      return \"array\";\n\n    case Date.prototype:\n      return \"date\";\n\n    case Uint8Array.prototype:\n      return \"bytes\";\n\n    case WritableStream.prototype:\n      return \"writable\";\n\n    case ReadableStream.prototype:\n      return \"readable\";\n\n    case Headers.prototype:\n      return \"headers\";\n\n    case Request.prototype:\n      return \"request\";\n\n    case Response.prototype:\n      return \"response\";\n\n    // TODO: All other structured clone types.\n\n    case RpcStub.prototype:\n      return \"stub\";\n\n    case RpcPromise.prototype:\n      return \"rpc-promise\";\n\n    // TODO: Promise<T> or thenable\n\n    default:\n      if (workersModule) {\n        // TODO: We also need to match `RpcPromise` and `RpcProperty`, but they currently aren't\n        //   exported by cloudflare:workers.\n        if (prototype == workersModule.RpcStub.prototype ||\n            value instanceof workersModule.ServiceStub) {\n          return \"rpc-target\";\n        } else if (prototype == workersModule.RpcPromise.prototype ||\n                   prototype == workersModule.RpcProperty.prototype) {\n          // Like rpc-target, but should be wrapped in RpcPromise, so that it can be pull()ed,\n          // which will await the thenable.\n          return \"rpc-thenable\";\n        }\n      }\n\n      if (value instanceof RpcTarget) {\n        return \"rpc-target\";\n      }\n\n      if (value instanceof Error) {\n        return \"error\";\n      }\n\n      return \"unsupported\";\n  }\n}\n\nfunction mapNotLoaded(): never {\n  throw new Error(\"RPC map() implementation was not loaded.\");\n}\n\n// map() is implemented in `map.ts`. We can't import it here because it would create an import\n// cycle, so instead we define two hook functions that map.ts will overwrite when it is imported.\nexport let mapImpl: MapImpl = { applyMap: mapNotLoaded, sendMap: mapNotLoaded };\n\ntype MapImpl = {\n  // Applies a map function to an input value (usually an array).\n  applyMap(input: unknown, parent: object | undefined, owner: RpcPayload | null,\n           captures: StubHook[], instructions: unknown[])\n          : StubHook;\n\n  // Implements the .map() method of RpcStub.\n  sendMap(hook: StubHook, path: PropertyPath, func: (value: RpcPromise) => unknown)\n         : RpcPromise;\n}\n\nfunction streamNotLoaded(): never {\n  throw new Error(\"Stream implementation was not loaded.\");\n}\n\n// Stream support is implemented in `streams.ts`. We can't import it here because it would create\n// an import cycle, so instead we define hook functions that streams.ts will overwrite.\nexport let streamImpl: StreamImpl = {\n  createWritableStreamHook: streamNotLoaded,\n  createWritableStreamFromHook: streamNotLoaded,\n  createReadableStreamHook: streamNotLoaded\n};\n\nexport type StreamImpl = {\n  // Creates a StubHook wrapping a local WritableStream for export.\n  // The hook will call getWriter() on the stream, locking it.\n  createWritableStreamHook(stream: WritableStream): StubHook;\n\n  // Creates a proxy WritableStream that forwards writes to a remote hook.\n  createWritableStreamFromHook(hook: StubHook): WritableStream;\n\n  // Creates a minimal StubHook wrapping a local ReadableStream for disposal tracking.\n  // The hook's dispose() will cancel the stream.\n  createReadableStreamHook(stream: ReadableStream): StubHook;\n}\n\n// Inner interface backing an RpcStub or RpcPromise.\n//\n// A hook may eventually resolve to a \"payload\".\n//\n// Declared as `abstract class` to allow `instanceof StubHook`, used by `RpcStub` constructor.\n//\n// This is conceptually similar to the Cap'n Proto C++ class `ClientHook`.\nexport abstract class StubHook {\n  // Call a function at the given property path with the given arguments. Returns a hook for the\n  // promise for the result.\n  abstract call(path: PropertyPath, args: RpcPayload): StubHook;\n\n  // Like call(), but designed for streaming calls (e.g. WritableStream writes). Returns:\n  // - promise: A Promise<void> for the completion of the call.\n  // - size: If the call was remote, the byte size of the serialized message. For local calls,\n  //   undefined is returned, indicating the caller should await the promise to serialize writes\n  //   (no overlapping).\n  stream(path: PropertyPath, args: RpcPayload): {promise: Promise<void>, size?: number} {\n    // Default implementation: delegate to call() + pull(). No size is returned, so the caller\n    // knows this is a local call and should await the promise directly.\n    let hook = this.call(path, args);\n    let pulled = hook.pull();\n    let promise: Promise<void>;\n    if (pulled instanceof Promise) {\n      promise = pulled.then(p => { p.dispose(); });\n    } else {\n      pulled.dispose();\n      promise = Promise.resolve();\n    }\n    return { promise };\n  }\n\n  // Apply a map operation.\n  //\n  // `captures` is a list of external stubs which are used as part of the mapper function.\n  // NOTE: The callee takes ownership of `captures`.\n  //\n  // `instructions` is a JSON-serializable value describing the mapper function as a series of\n  // steps. Each step is an expression to evaluate, in the usual RPC expression format. The last\n  // instruction is the return value.\n  //\n  // Each instruction can refer to the results of any of the instructions before it, as well as to\n  // the captures, as if they were imports on the import table. In particular:\n  // * The value 0 is the input to the mapper function (e.g. one element of the array being mapped).\n  // * Positive values are 1-based indexes into the instruction table, representing the results of\n  //   previous instructions.\n  // * Negative values are -1-based indexes into the capture list.\n  abstract map(path: PropertyPath, captures: StubHook[], instructions: unknown[]): StubHook;\n\n  // Read the property at the given path. Returns a StubHook representing a promise for that\n  // property. This behaves very similarly to call(), except that no actual function is invoked\n  // on the remote end, the property is simply returned. (Well, if the property has a getter, then\n  // that will be invoked...)\n  //\n  // (In the case that this stub is a promise with a resolution payload, get() implies cloning\n  // a branch of the payload, making a deep copy of any pass-by-value content.)\n  abstract get(path: PropertyPath): StubHook;\n\n  // Create a clone of this StubHook, which can be disposed independently.\n  //\n  // The returned hook is NOT considered a promise, so will not resolve to a payload (you can use\n  // `get([])` to get a promise for a cloned payload).\n  abstract dup(): StubHook;\n\n  // Requests resolution of a StubHook that represents a promise, and eventually produces the\n  // payload.\n  //\n  // pull() should not be called on capabilities that aren't promises. It may never resolve or it\n  // may throw an exception.\n  //\n  // If pull() is never called (on a remote promise), the RPC system will not transmit the\n  // resolution at all. This allows a promise to be used strictly for pipelining.\n  //\n  // If the payload is already available, pull() returns it immediately, instead of returning a\n  // promise. This allows the caller to skip the microtask queue which is sometimes necessary to\n  // maintain e-order guarantees.\n  //\n  // The returned RpcPayload is the same one backing the StubHook itself. If the caller delivers\n  // or disposes the payload directly, then it should not call dispose() on the hook. If the caller\n  // does not intend to consume the StubHook, the caller must take responsibility for cloning the\n  // payload.\n  //\n  // You can call pull() multiple times, but it will return the same RpcPayload every time, and\n  // that payload should only be disposed once.\n  //\n  // If pull() returns a promise which rejects, the StubHook does not need to be disposed.\n  abstract pull(): RpcPayload | Promise<RpcPayload>;\n\n  // Called to prevent this stub from generating unhandled rejection events if it throws without\n  // having been pulled. Without this, if a client \"push\"es a call that immediately throws before\n  // the client manages to \"pull\" it or use it in a pipeline, this may be treated by the system as\n  // an unhandled rejection. Unfortunately, this unhandled rejection would be reported in the\n  // callee rather than the caller, possibly causing the callee to crash or log spurious errors,\n  // even though it's really up to the caller to deal with the exception!\n  abstract ignoreUnhandledRejections(): void;\n\n  // Attempts to cancel any outstanding promise backing this hook, and disposes the payload that\n  // pull() would return (if any). If a pull() promise is outstanding, it may still resolve (with\n  // a disposed payload) or it may reject. It's safe to call dispose() multiple times.\n  abstract dispose(): void;\n\n  abstract onBroken(callback: (error: any) => void): void;\n}\n\nexport class ErrorStubHook extends StubHook {\n  constructor(private error: any) { super(); }\n\n  call(path: PropertyPath, args: RpcPayload): StubHook { return this; }\n  map(path: PropertyPath, captures: StubHook[], instructions: unknown[]): StubHook { return this; }\n  get(path: PropertyPath): StubHook { return this; }\n  dup(): StubHook { return this; }\n  pull(): RpcPayload | Promise<RpcPayload> { return Promise.reject(this.error); }\n  ignoreUnhandledRejections(): void {}\n  dispose(): void {}\n  onBroken(callback: (error: any) => void): void {\n    try {\n      callback(this.error);\n    } catch (err) {\n      // Don't throw back into the RPC system. Treat this as an unhandled rejection.\n      Promise.resolve(err);\n    }\n  }\n};\n\nconst DISPOSED_HOOK: StubHook = new ErrorStubHook(\n    new Error(\"Attempted to use RPC stub after it has been disposed.\"));\n\n// A call interceptor can be used to intercept all RPC stub invocations within some synchronous\n// scope. This is used to implement record/replay\ntype CallInterceptor = (hook: StubHook, path: PropertyPath, params: RpcPayload) => StubHook;\nlet doCall: CallInterceptor = (hook: StubHook, path: PropertyPath, params: RpcPayload) => {\n  return hook.call(path, params);\n}\n\nexport function withCallInterceptor<T>(interceptor: CallInterceptor, callback: () => T): T {\n  let oldValue = doCall;\n  doCall = interceptor;\n  try {\n    return callback();\n  } finally {\n    doCall = oldValue;\n  }\n}\n\n// Private symbol which may be used to unwrap the real stub through the Proxy.\nlet RAW_STUB = Symbol(\"realStub\");\n\nexport interface RpcStub extends Disposable {\n  // Declare magic `RAW_STUB` key that unwraps the proxy.\n  [RAW_STUB]: this;\n}\n\nconst PROXY_HANDLERS: ProxyHandler<{raw: RpcStub}> = {\n  apply(target: {raw: RpcStub}, thisArg: any, argumentsList: any[]) {\n    let stub = target.raw;\n    return new RpcPromise(doCall(stub.hook,\n        stub.pathIfPromise || [], RpcPayload.fromAppParams(argumentsList)), []);\n  },\n\n  get(target: {raw: RpcStub}, prop: string | symbol, receiver: any) {\n    let stub = target.raw;\n    if (prop === RAW_STUB) {\n      return stub;\n    } else if (prop in RpcPromise.prototype) {\n      // Any method or property declared on RpcPromise (including inherited from RpcStub or\n      // Object) should pass through to the target object, as trying to turn these into RPCs will\n      // likely be problematic.\n      //\n      // Note we don't just check `prop in target` because we intentionally want to hide the\n      // properties `hook` and `path`.\n      return (<any>stub)[prop];\n    } else if (typeof prop === \"string\") {\n      // Return promise for property.\n      return new RpcPromise(stub.hook,\n          stub.pathIfPromise ? [...stub.pathIfPromise, prop] : [prop]);\n    } else if (prop === Symbol.dispose &&\n          (!stub.pathIfPromise || stub.pathIfPromise.length == 0)) {\n      // We only advertise Symbol.dispose on stubs and root promises, not properties.\n      return () => {\n        stub.hook.dispose();\n        stub.hook = DISPOSED_HOOK;\n      };\n    } else {\n      return undefined;\n    }\n  },\n\n  has(target: {raw: RpcStub}, prop: string | symbol) {\n    let stub = target.raw;\n    if (prop === RAW_STUB) {\n      return true;\n    } else if (prop in RpcPromise.prototype) {\n      return prop in stub;\n    } else if (typeof prop === \"string\") {\n      return true;\n    } else if (prop === Symbol.dispose &&\n          (!stub.pathIfPromise || stub.pathIfPromise.length == 0)) {\n      return true;\n    } else {\n      return false;\n    }\n  },\n\n  construct(target: {raw: RpcStub}, args: any) {\n    throw new Error(\"An RPC stub cannot be used as a constructor.\");\n  },\n\n  defineProperty(target: {raw: RpcStub}, property: string | symbol, attributes: PropertyDescriptor)\n      : boolean {\n    throw new Error(\"Can't define properties on RPC stubs.\");\n  },\n\n  deleteProperty(target: {raw: RpcStub}, p: string | symbol): boolean {\n    throw new Error(\"Can't delete properties on RPC stubs.\");\n  },\n\n  getOwnPropertyDescriptor(target: {raw: RpcStub}, p: string | symbol): PropertyDescriptor | undefined {\n    // Treat all properties as prototype properties. That's probably fine?\n    return undefined;\n  },\n\n  getPrototypeOf(target: {raw: RpcStub}): object | null {\n    return Object.getPrototypeOf(target.raw);\n  },\n\n  isExtensible(target: {raw: RpcStub}): boolean {\n    return false;\n  },\n\n  ownKeys(target: {raw: RpcStub}): ArrayLike<string | symbol> {\n    return [];\n  },\n\n  preventExtensions(target: {raw: RpcStub}): boolean {\n    // Extensions are not possible anyway.\n    return true;\n  },\n\n  set(target: {raw: RpcStub}, p: string | symbol, newValue: any, receiver: any): boolean {\n    throw new Error(\"Can't assign properties on RPC stubs.\");\n  },\n\n  setPrototypeOf(target: {raw: RpcStub}, v: object | null): boolean {\n    throw new Error(\"Can't override prototype of RPC stubs.\");\n  },\n};\n\n// Implementation of RpcStub.\n//\n// Note that the in the public API, we override the type of RpcStub to reflect the interface\n// exposed by the proxy. That happens in index.ts. But for internal purposes, it's easier to just\n// omit the type parameter.\nexport class RpcStub extends RpcTarget {\n  // Although `hook` and `path` are declared `public` here, they are effectively hidden by the\n  // proxy.\n  constructor(hook: StubHook, pathIfPromise?: PropertyPath) {\n    super();\n\n    if (!(hook instanceof StubHook)) {\n      // Application invoked the constructor to explicitly construct a stub backed by some value\n      // (usually an RpcTarget). (Note we override the types as seen by the app, which is why\n      // the app can pass something that isn't a StubHook -- within the implementation, though,\n      // we always pass StubHook.)\n      let value = <any>hook;\n      if (value instanceof RpcTarget || value instanceof Function) {\n        hook = TargetStubHook.create(value, undefined);\n      } else {\n        // We adopt the value with \"return\" semantics since we want to take ownership of any stubs\n        // within.\n        hook = new PayloadStubHook(RpcPayload.fromAppReturn(value));\n      }\n\n      // Don't let app set this.\n      if (pathIfPromise) {\n        throw new TypeError(\"RpcStub constructor expected one argument, received two.\");\n      }\n    }\n\n    this.hook = hook;\n    this.pathIfPromise = pathIfPromise;\n\n    // Proxy has an unfortunate rule that it will only be considered callable if the underlying\n    // `target` is callable, i.e. a function. So our target *must* be callable. So we use a\n    // dummy function.\n    let func: any = () => {};\n    func.raw = this;\n    return new Proxy(func, PROXY_HANDLERS);\n  }\n\n  public hook: StubHook;\n  public pathIfPromise?: PropertyPath;\n\n  dup(): RpcStub {\n    // Unfortunately the method will be invoked with `this` being the Proxy, not the `RpcPromise`\n    // itself, so we have to unwrap it.\n\n    // Note dup() intentionally resets the path to empty and turns the result into a stub.\n    // TODO: Maybe it should actually return the same type? But I think that's not what it does\n    //   in Workers RPC today? (Need to check.) Alternatively, should there be an optional\n    //   parameter to specify promise vs. stub?\n    let target = this[RAW_STUB];\n    if (target.pathIfPromise) {\n      return new RpcStub(target.hook.get(target.pathIfPromise));\n    } else {\n      return new RpcStub(target.hook.dup());\n    }\n  }\n\n  onRpcBroken(callback: (error: any) => void) {\n    this[RAW_STUB].hook.onBroken(callback);\n  }\n\n  map(func: (value: RpcPromise) => unknown): RpcPromise {\n    let {hook, pathIfPromise} = this[RAW_STUB];\n    return mapImpl.sendMap(hook, pathIfPromise || [], func);\n  }\n\n  toString() {\n    return \"[object RpcStub]\";\n  }\n}\n\nexport class RpcPromise extends RpcStub {\n  // TODO: Support passing target value or promise to constructor.\n  constructor(hook: StubHook, pathIfPromise: PropertyPath) {\n    super(hook, pathIfPromise);\n  }\n\n  then(onfulfilled?: ((value: unknown) => unknown) | undefined | null,\n       onrejected?: ((reason: any) => unknown) | undefined | null)\n       : Promise<unknown> {\n    return pullPromise(this).then(...arguments);\n  }\n\n  catch(onrejected?: ((reason: any) => unknown) | undefined | null): Promise<unknown> {\n    return pullPromise(this).catch(...arguments);\n  }\n\n  finally(onfinally?: (() => void) | undefined | null): Promise<unknown> {\n    return pullPromise(this).finally(...arguments);\n  }\n\n  toString() {\n    return \"[object RpcPromise]\";\n  }\n}\n\n// Given a stub (still wrapped in a Proxy), extract the underlying `StubHook`.\n//\n// The caller takes ownership, meaning it's expected that the original stub will never be disposed\n// itself, but the caller is responsible for calling `dispose()` on the returned hook.\n//\n// However, if the stub points to a property of some other stub or promise, then no ownership is\n// \"transferred\" because properties do not actually have disposers. However, the returned hook is\n// a new hook that aliases that property, but does actually need to be disposed.\n//\n// The result is a promise (i.e. can be pull()ed) if and only if the input is a promise.\nexport function unwrapStubTakingOwnership(stub: RpcStub): StubHook {\n  let {hook, pathIfPromise} = stub[RAW_STUB];\n\n  if (pathIfPromise && pathIfPromise.length > 0) {\n    return hook.get(pathIfPromise);\n  } else {\n    return hook;\n  }\n}\n\n// Given a stub (still wrapped in a Proxy), extract the underlying `StubHook`, and duplicate it,\n// returning the duplicate.\n//\n// The caller is responsible for disposing the returned hook, but the original stub also still\n// needs to be disposed by its owner (unless it is a property, which never needs disposal).\n//\n// The result is a promise (i.e. can be pull()ed) if and only if the input is a promise. Note that\n// this differs from the semantics of the actual `dup()` method.\nexport function unwrapStubAndDup(stub: RpcStub): StubHook {\n  let {hook, pathIfPromise} = stub[RAW_STUB];\n\n  if (pathIfPromise) {\n    return hook.get(pathIfPromise);\n  } else {\n    return hook.dup();\n  }\n}\n\n// Unwrap a stub returning the underlying `StubHook`, returning `undefined` if it is a property\n// stub.\n//\n// This function is agnostic to ownership transfer. Exactly one of `stub` or the return `hook` must\n// eventually be disposed (unless `undefined` is returned, in which case neither need to be\n// disposed, as properties are not normally disposable).\nexport function unwrapStubNoProperties(stub: RpcStub): StubHook | undefined {\n  let {hook, pathIfPromise} = stub[RAW_STUB];\n\n  if (pathIfPromise && pathIfPromise.length > 0) {\n    return undefined;\n  }\n\n  return hook;\n}\n\n// Unwrap a stub returning the underlying `StubHook`. If it's a property, return the `StubHook`\n// representing the stub or promise of which is is a property.\n//\n// This function is agnostic to ownership transfer. Exactly one of `stub` or the return `hook` must\n// eventually be disposed.\nexport function unwrapStubOrParent(stub: RpcStub): StubHook {\n  return stub[RAW_STUB].hook;\n}\n\n// Given a stub (still wrapped in a Proxy), extract the `hook` and `pathIfPromise` properties.\n//\n// This function is agnostic to ownership transfer. Exactly one of `stub` or the return `hook` must\n// eventually be disposed.\nexport function unwrapStubAndPath(stub: RpcStub): {hook: StubHook, pathIfPromise?: PropertyPath} {\n  return stub[RAW_STUB];\n}\n\n// Given a promise stub (still wrapped in a Proxy), pull the remote promise and deliver the\n// payload. This is a helper used to implement the then/catch/finally methods of RpcPromise.\nasync function pullPromise(promise: RpcPromise): Promise<unknown> {\n  let {hook, pathIfPromise} = promise[RAW_STUB];\n  if (pathIfPromise!.length > 0) {\n    // If this isn't the root promise, we have to clone it and pull the clone. This is a little\n    // weird in terms of disposal: There's no way for the app to dispose/cancel the promise while\n    // waiting because it never actually got a direct disposable reference. It has to dispose\n    // the result.\n    hook = hook.get(pathIfPromise!);\n  }\n  let payload = await hook.pull();\n  return payload.deliverResolve();\n}\n\n// =======================================================================================\n// RpcPayload\n\nexport type LocatedPromise = {parent: object, property: string | number, promise: RpcPromise};\n\n// Represents the params to an RPC call, or the resolution of an RPC promise, as it passes\n// through the system.\n//\n// `RpcPayload` is a linear type -- it is passed to or returned from a call, ownership is being\n// transferred. The payload in turn owns all the stubs within it. Disposing the payload disposes\n// the stubs.\n//\n// Hypothetically, when an `RpcPayload` is first constructed from a message structure passed from\n// the app, it ought to be deep-copied, for a few reasons:\n// - To ensure subsequent modifications of the data structure by the app aren't reflected in the\n//   already-sent message.\n// - To find all stubs in the message tree, to take ownership of them.\n// - To find all RpcTargets in the message tree, to wrap them in stubs.\n//\n// However, most payloads are immediately serialized to send across the wire. Said serialization\n// *also* has to make a deep copy, and takes ownership of all stubs found within. In the case that\n// the payload is immediately serialized, then making a deep copy first is wasteful.\n//\n// So, as an optimization, RpcPayload does not necessarily make a copy right away. Instead, it\n// keeps track of whether it's still pointing at the message structure received directly from the\n// app. In that case, the serializer can operate on the original structure directly, making it\n// more efficient.\n//\n// On the receiving end, when an RpcPayload is deserialized from the wire, the payload can safely\n// be delivered directly to the app without a copy. However, if the app makes a loopback call to\n// itself, the payload may never cross the wire. In this case, a deep copy must be made before\n// delivering the final message to the app. There are really two reasons for this copy:\n// - We obviously don't want the caller and callee sharing in-memory mutable data structures, as\n//   this would lead to vasty different behavior than what you'd see when doing RPC across a\n//   network connection.\n// - Before delivering the message to the application, all promises embedded in the message must\n//   be resolved. This is what makes pipelining possible: the sender of a message can place\n//   `RpcPromise`s in it that refer back to values in the recipient's process. These will be filled\n//   in just before delivering the message to the recipient, so that there's no need to transmit\n//   these values back and forth across the wire. It would be unreasonable to expect the\n//   application itself to check the message for promises and resolve them all, so instead the\n//   system automatically resolves all promises upfront, replacing them with their resolutions.\n//   This modifies the payload in-place -- but this of course requires that the payload is\n//   operating on a copy of the message, not the original provided from the sending app.\n//\n// For both the purposes of disposal and substituting promises with their resolutions, it is\n// necessary at some point to make a list of all the stubs (including promise stubs) present in\n// the message. Again, `RpcPayload` tries to minimize the number of times that the whole message\n// needs to be walked, so it implements the following policy:\n// * When constructing a payload from an app-provided message object, the message is not walked\n//   upfront. We do not know yet what stubs it contains.\n// * When deserializing a payload from the wire, we build a list of stubs as part of the\n//   deserialization process.\n// * If we need to deep-copy an app-provided message, we make a list of stubs then.\n// * Hence, we have a list of stubs if and only if the message structure was NOT provided directly\n//   by the application.\n// * If an app-provided payload is serialized, the serializer finds the stubs. (It also typically\n//   takes ownership of the stubs, effectively consuming the payload, so there's no need to build\n//   a list of the stubs.)\n// * If an app-provided payload is disposed, then we have to walk the message at that time to\n//   dispose all stubs within. But, note that when a payload is serialized -- with the serializer\n//   taking ownership of stubs -- then the payload will NOT be disposed explicitly, so this step\n//   will not be needed.\nexport class RpcPayload {\n  // Create a payload from a value passed as params to an RPC from the app.\n  //\n  // The payload does NOT take ownership of any stubs in `value`, and but promises not to modify\n  // `value`. If the payload is delivered locally, `value` will be deep-copied first, so as not\n  // to have the sender and recipient end up sharing the same mutable object. `value` will not be\n  // touched again after the call returns synchronously (returns a promise) -- by that point,\n  // the value has either been copied or serialized to the wire.\n  public static fromAppParams(value: unknown): RpcPayload {\n    return new RpcPayload(value, \"params\");\n  }\n\n  // Create a payload from a value return from an RPC implementation by the app.\n  //\n  // Unlike fromAppParams(), in this case the payload takes ownership of all stubs in `value`, and\n  // may hold onto `value` for an arbitrarily long time (e.g. to serve pipelined requests). It\n  // will still avoid modifying `value` and will make a deep copy if it is delivered locally.\n  public static fromAppReturn(value: unknown): RpcPayload {\n    return new RpcPayload(value, \"return\");\n  }\n\n  // Combine an array of payloads into a single payload whose value is an array. Ownership of all\n  // stubs is transferred from the inputs to the outputs, hence if the output is disposed, the\n  // inputs should not be. (In case of exception, nothing is disposed, though.)\n  public static fromArray(array: RpcPayload[]): RpcPayload {\n    let hooks: StubHook[] = [];\n    let promises: LocatedPromise[] = [];\n\n    let resultArray: unknown[] = [];\n\n    for (let payload of array) {\n      payload.ensureDeepCopied();\n      for (let hook of payload.hooks!) {\n        hooks.push(hook);\n      }\n      for (let promise of payload.promises!) {\n        if (promise.parent === payload) {\n          // This promise is the root of the source payload. We need to reparent it to its proper\n          // location in the result array.\n          promise = {\n            parent: resultArray,\n            property: resultArray.length,\n            promise: promise.promise\n          };\n        }\n        promises.push(promise);\n      }\n      resultArray.push(payload.value);\n    }\n\n    return new RpcPayload(resultArray, \"owned\", hooks, promises);\n  }\n\n  // Create a payload from a value parsed off the wire using Evaluator.evaluate().\n  //\n  // A payload is constructed with a null value and the given hooks and promises arrays. The value\n  // is expected to be filled in by the evaluator, and the hooks and promises arrays are expected\n  // to be extended with stubs found during parsing. (This weird usage model is necessary so that\n  // if the root value turns out to be a promise, its `parent` in `promises` can be the payload\n  // object itself.)\n  //\n  // When done, the payload takes ownership of the final value and all the stubs within. It may\n  // modify the value in preparation for delivery, and may deliver the value directly to the app\n  // without copying.\n  public static forEvaluate(hooks: StubHook[], promises: LocatedPromise[]) {\n    return new RpcPayload(null, \"owned\", hooks, promises);\n  }\n\n  // Deep-copy the given value, including dup()ing all stubs.\n  //\n  // If `value` is a function, it should be bound to `oldParent` as its `this`.\n  //\n  // If deep-copying from a branch of some other RpcPayload, it must be provided, to make sure\n  // RpcTargets found within don't get duplicate stubs.\n  public static deepCopyFrom(\n      value: unknown, oldParent: object | undefined, owner: RpcPayload | null): RpcPayload {\n    let result = new RpcPayload(null, \"owned\", [], []);\n    result.value = result.deepCopy(value, oldParent, \"value\", result, /*dupStubs=*/true, owner);\n    return result;\n  }\n\n  // Private constructor; use factory functions above to construct.\n  private constructor(\n    // The payload value.\n    public value: unknown,\n\n    // What is the provenance of `value`?\n    // \"params\": It came from the app, in params to a call. We must dupe any stubs within.\n    // \"return\": It came from the app, returned from a call. We take ownership of all stubs within.\n    // \"owned\": This value belongs fully to us, either because it was deserialized from the wire\n    //   or because we deep-copied a value from the app.\n    private source: \"params\" | \"return\" | \"owned\",\n\n    // `hooks` and `promises` are filled in only if `value` belongs to us (`source` is \"owned\") and\n    // so can safely be delivered to the app. If `value` came from then app in the first place,\n    // then it cannot be delivered back to the app nor modified by us without first deep-copying\n    // it. `hooks` and `promises` will be computed as part of the deep-copy.\n\n    // All non-promise stubs found in `value`. This list is needed only for the purpose of being\n    // able to dispose them when desired. This intentionally doesn't inculde promises because they\n    // are already covered by `promises`, below.\n    private hooks?: StubHook[],\n\n    // All promises found in `value`. The locations of each promise are provided to allow\n    // substitutions later.\n    private promises?: LocatedPromise[]\n  ) {}\n\n  // For `source === \"return\"` payloads only, this tracks any StubHooks created around RpcTargets\n  // or WritableStreams found in the payload at the time that it is serialized (or deep-copied) for\n  // return, so that we can make sure they are not disposed before the pipeline ends.\n  //\n  // This is initialized on first use.\n  private rpcTargets?: Map<RpcTarget | Function | WritableStream | ReadableStream, StubHook>;\n\n  // Get the StubHook representing the given RpcTarget found inside this payload.\n  public getHookForRpcTarget(target: RpcTarget | Function, parent: object | undefined,\n                             dupStubs: boolean = true): StubHook {\n    if (this.source === \"params\") {\n      if (dupStubs) {\n        // We aren't supposed to take ownership of stubs appearing in params -- we're supposed to\n        // dupe them. But an RpcTarget isn't a stub. If we create a stub around it, the stub takes\n        // ownership.\n        //\n        // Usually, people passing raw RpcTargets into functions actually want the call to take\n        // ownership -- that is, they want to have the disposer called later.\n        //\n        // But, if the RpcTarget happens to implement a `dup()` method, we will go ahead and call\n        // that method, and wrap whatever it returns instead. This method wouldn't actually be\n        // available over RPC anyway (since calling `dup()` on the client-side stub just dupes the\n        // stub), so if an `RpcTarget` implements this, it must intend for us to use it.\n        //\n        // This is particularly important for the case of workerd-native RpcStubs, that is, stubs\n        // from the built-in RPC system, rather than the pure-JS implementation of Cap'n Web.\n        // We treat those stubs as RpcTargets. But, we do need to dup() them, just like we would\n        // our own stubs.\n\n        let dupable = target as any;\n        if (typeof dupable.dup === \"function\") {\n          target = dupable.dup();\n        }\n      }\n\n      return TargetStubHook.create(target, parent);\n    } else if (this.source === \"return\") {\n      // If dupStubs is true, we want to both make sure the map contains the stub, and also return\n      // a dup of that stub.\n      //\n      // If dupStubs is false, then we are being called as part of ensureDeepCopy(), i.e. replacing\n      // ourselves with a deep copy. In this case we actually want the copy to end up owning all\n      // the hooks, and the map to be left empty. So what we do in this case is:\n      // * If the target is not in the map, we just create it, but don't populate the map.\n      // * If the target *is* in the map, we *remove* the hook from the map, and return it.\n\n      let hook = this.rpcTargets?.get(target);\n      if (hook) {\n        if (dupStubs) {\n          return hook.dup();\n        } else {\n          this.rpcTargets?.delete(target);\n          return hook;\n        }\n      } else {\n        hook = TargetStubHook.create(target, parent);\n        if (dupStubs) {\n          if (!this.rpcTargets) {\n            this.rpcTargets = new Map;\n          }\n          this.rpcTargets.set(target, hook);\n          return hook.dup();\n        } else {\n          return hook;\n        }\n      }\n    } else {\n      throw new Error(\"owned payload shouldn't contain raw RpcTargets\");\n    }\n  }\n\n  // Get the StubHook representing the given WritableStream found inside this payload.\n  public getHookForWritableStream(stream: WritableStream, parent: object | undefined,\n                                  dupStubs: boolean = true): StubHook {\n    if (this.source === \"params\") {\n      // For params, we always create a new hook. WritableStreams don't have a dup() method,\n      // and it wouldn't really make sense anyway since we're locking the stream by calling\n      // getWriter().\n      return streamImpl.createWritableStreamHook(stream);\n    } else if (this.source === \"return\") {\n      // Similar logic to getHookForRpcTarget().\n      let hook = this.rpcTargets?.get(stream);\n      if (hook) {\n        if (dupStubs) {\n          return hook.dup();\n        } else {\n          this.rpcTargets?.delete(stream);\n          return hook;\n        }\n      } else {\n        hook = streamImpl.createWritableStreamHook(stream);\n        if (dupStubs) {\n          if (!this.rpcTargets) {\n            this.rpcTargets = new Map;\n          }\n          this.rpcTargets.set(stream, hook);\n          return hook.dup();\n        } else {\n          return hook;\n        }\n      }\n    } else {\n      throw new Error(\"owned payload shouldn't contain raw WritableStreams\");\n    }\n  }\n\n  // Get the StubHook representing the given ReadableStream found inside this payload.\n  public getHookForReadableStream(stream: ReadableStream, parent: object | undefined,\n                                  dupStubs: boolean = true): StubHook {\n    if (this.source === \"params\") {\n      return streamImpl.createReadableStreamHook(stream);\n    } else if (this.source === \"return\") {\n      let hook = this.rpcTargets?.get(stream);\n      if (hook) {\n        if (dupStubs) {\n          return hook.dup();\n        } else {\n          this.rpcTargets?.delete(stream);\n          return hook;\n        }\n      } else {\n        hook = streamImpl.createReadableStreamHook(stream);\n        if (dupStubs) {\n          if (!this.rpcTargets) {\n            this.rpcTargets = new Map;\n          }\n          this.rpcTargets.set(stream, hook);\n          return hook.dup();\n        } else {\n          return hook;\n        }\n      }\n    } else {\n      throw new Error(\"owned payload shouldn't contain raw ReadableStreams\");\n    }\n  }\n\n  private deepCopy(\n      value: unknown, oldParent: object | undefined, property: string | number, parent: object,\n      dupStubs: boolean, owner: RpcPayload | null): unknown {\n    let kind = typeForRpc(value);\n    switch (kind) {\n      case \"unsupported\":\n        // This will throw later on when someone tries to do something with it.\n        return value;\n\n      case \"primitive\":\n      case \"bigint\":\n      case \"date\":\n      case \"bytes\":\n      case \"error\":\n      case \"undefined\":\n        // immutable, no need to copy\n        // TODO: Should errors be copied if they have own properties?\n        return value;\n\n      case \"array\": {\n        // We have to construct the new array first, then fill it in, so we can pass it as the\n        // parent.\n        let array = <Array<unknown>>value;\n        let len = array.length;\n        let result = new Array(len);\n        for (let i = 0; i < len; i++) {\n          result[i] = this.deepCopy(array[i], array, i, result, dupStubs, owner);\n        }\n        return result;\n      }\n\n      case \"object\": {\n        // Plain object. Unfortunately there's no way to pre-allocate the right shape.\n        let result: Record<string, unknown> = {};\n        let object = <Record<string, unknown>>value;\n        for (let i in object) {\n          result[i] = this.deepCopy(object[i], object, i, result, dupStubs, owner);\n        }\n        return result;\n      }\n\n      case \"stub\":\n      case \"rpc-promise\": {\n        let stub = <RpcStub>value;\n        let hook: StubHook;\n        if (dupStubs) {\n          hook = unwrapStubAndDup(stub);\n        } else {\n          hook = unwrapStubTakingOwnership(stub);\n        }\n        if (stub instanceof RpcPromise) {\n          let promise = new RpcPromise(hook, []);\n          this.promises!.push({parent, property, promise});\n          return promise;\n        } else {\n          this.hooks!.push(hook);\n          return new RpcStub(hook);\n        }\n      }\n\n      case \"function\":\n      case \"rpc-target\": {\n        let target = <RpcTarget | Function>value;\n        let hook: StubHook;\n        if (owner) {\n          hook = owner.getHookForRpcTarget(target, oldParent, dupStubs);\n        } else {\n          hook = TargetStubHook.create(target, oldParent);\n        }\n        this.hooks!.push(hook);\n        return new RpcStub(hook);\n      }\n\n      case \"rpc-thenable\": {\n        let target = <RpcTarget>value;\n        let promise: RpcPromise;\n        if (owner) {\n          promise = new RpcPromise(owner.getHookForRpcTarget(target, oldParent, dupStubs), []);\n        } else {\n          promise = new RpcPromise(TargetStubHook.create(target, oldParent), []);\n        }\n        this.promises!.push({parent, property, promise});\n        return promise;\n      }\n\n      case \"writable\": {\n        let stream = <WritableStream>value;\n        let hook: StubHook;\n        if (owner) {\n          hook = owner.getHookForWritableStream(stream, oldParent, dupStubs);\n        } else {\n          hook = streamImpl.createWritableStreamHook(stream);\n        }\n        this.hooks!.push(hook);\n        return stream;\n      }\n\n      case \"readable\": {\n        // Note that we don't use tee() here because we treat streams as reference types -- we\n        // actually want to share the same body. tee()ing the stream would force the runtime to\n        // buffer a copy of the whole body which would usually never be read.\n        let stream = <ReadableStream>value;\n        let hook: StubHook;\n        if (owner) {\n          hook = owner.getHookForReadableStream(stream, oldParent, dupStubs);\n        } else {\n          hook = streamImpl.createReadableStreamHook(stream);\n        }\n        this.hooks!.push(hook);\n        return stream;\n      }\n\n      case \"headers\":\n        return new Headers(<Headers>value);\n\n      case \"request\": {\n        let req = <Request>value;\n        if (req.body) {\n          // Note \"deep-copy\" of a ReadableStream always returns the same stream, but we still\n          // need to run it in order to handle refcounting / disposal properly.\n          this.deepCopy(req.body, req, \"body\", req, dupStubs, owner);\n        }\n\n        // Make an actual copy of the object, e.g. so the headers are copied.\n        // Note that it would be incorrect to use clone() here since that would tee() the body\n        // stream.\n        return new Request(req);\n      }\n\n      case \"response\": {\n        let resp = <Response>value;\n        if (resp.body) {\n          // Note \"deep-copy\" of a ReadableStream always returns the same stream, but we still\n          // need to run it in order to handle refcounting / disposal properly.\n          this.deepCopy(resp.body, resp, \"body\", resp, dupStubs, owner);\n        }\n\n        // Make an actual copy of the object, e.g. so the headers are copied.\n        // Note that it would be incorrect to use clone() here since that would tee() the body\n        // stream.\n        return new Response(resp.body, resp);\n      }\n\n      default:\n        kind satisfies never;\n        throw new Error(\"unreachable\");\n    }\n  }\n\n  // Ensures that if the value originally came from an unowned source, we have replaced it with a\n  // deep copy.\n  public ensureDeepCopied() {\n    if (this.source !== \"owned\") {\n      // If we came from call params, we need to dupe any stubs. Otherwise (we came from a return),\n      // we take ownership of all stubs.\n      let dupStubs = this.source === \"params\";\n\n      this.hooks = [];\n      this.promises = [];\n\n      // Deep-copy the value.\n      try {\n        this.value = this.deepCopy(this.value, undefined, \"value\", this, dupStubs, this);\n      } catch (err) {\n        // Roll back the change.\n        this.hooks = undefined;\n        this.promises = undefined;\n        throw err;\n      }\n\n      // We now own the value.\n      this.source = \"owned\";\n\n      // `rpcTargets` should have been left empty. We can throw it out.\n      if (this.rpcTargets && this.rpcTargets.size > 0) {\n        throw new Error(\"Not all rpcTargets were accounted for in deep-copy?\");\n      }\n      this.rpcTargets = undefined;\n    }\n  }\n\n  // Resolve all promises in this payload and then assign the final value into `parent[property]`.\n  private deliverTo(parent: object, property: string | number, promises: Promise<any>[]): void {\n    this.ensureDeepCopied();\n\n    if (this.value instanceof RpcPromise) {\n      RpcPayload.deliverRpcPromiseTo(this.value, parent, property, promises);\n    } else {\n      (<any>parent)[property] = this.value;\n\n      for (let record of this.promises!) {\n        // Note that because we already did ensureDeepCopied(), replacing each promise with its\n        // resolution does not interfere with disposal later on -- disposal will be based on the\n        // `promises` list, so will still properly dispose each promise, which in turn disposes\n        // the promise's eventual payload.\n        RpcPayload.deliverRpcPromiseTo(record.promise, record.parent, record.property, promises);\n      }\n    }\n  }\n\n  private static deliverRpcPromiseTo(\n      promise: RpcPromise, parent: object, property: string | number,\n      promises: Promise<unknown>[]) {\n    // deepCopy() should have replaced any property stubs with normal promise stubs.\n    let hook = unwrapStubNoProperties(promise);\n    if (!hook) {\n      throw new Error(\"property promises should have been resolved earlier\");\n    }\n\n    let inner = hook.pull();\n    if (inner instanceof RpcPayload) {\n      // Immediately resolved to payload.\n      inner.deliverTo(parent, property, promises);\n    } else {\n      // It's a promise.\n      promises.push(inner.then(payload => {\n        let subPromises: Promise<unknown>[] = [];\n        payload.deliverTo(parent, property, subPromises);\n        if (subPromises.length > 0) {\n          return Promise.all(subPromises);\n        }\n      }));\n    }\n  }\n\n  // Call the given function with the payload as an argument. The call is made synchronously if\n  // possible, in order to maintain e-order. However, if any RpcPromises exist in the payload,\n  // they are awaited and substituted before calling the function. The result of the call is\n  // wrapped into another payload.\n  //\n  // The payload is automatically disposed after the call completes. The caller should not call\n  // dispose().\n  public async deliverCall(func: Function, thisArg: object | undefined): Promise<RpcPayload> {\n    try {\n      let promises: Promise<void>[] = [];\n      this.deliverTo(this, \"value\", promises);\n\n      // WARNING: It is critical that if the promises list is empty, we do not await anything, so\n      //   that the function is called immediately and synchronously. Otherwise, we might violate\n      //   e-order.\n      if (promises.length > 0) {\n        await Promise.all(promises);\n      }\n\n      // Call the function.\n      let result = Function.prototype.apply.call(func, thisArg, this.value);\n\n      if (result instanceof RpcPromise) {\n        // Special case: If the function immediately returns RpcPromise, we don't want to await it,\n        // since that will actually wait for the promise. Instead we want to construct a payload\n        // around it directly.\n        return RpcPayload.fromAppReturn(result);\n      } else {\n        // In all other cases, await the result (which may or may not be a promise, but `await`\n        // will just pass through non-promises).\n        return RpcPayload.fromAppReturn(await result);\n      }\n    } finally {\n      this.dispose();\n    }\n  }\n\n  // Produce a promise for this payload for return to the application. Any RpcPromises in the\n  // payload are awaited and substituted with their results first.\n  //\n  // The returned object will have a disposer which disposes the payload. The caller should not\n  // separately dispose it.\n  public async deliverResolve(): Promise<unknown> {\n    try {\n      let promises: Promise<void>[] = [];\n      this.deliverTo(this, \"value\", promises);\n\n      if (promises.length > 0) {\n        await Promise.all(promises);\n      }\n\n      let result = this.value;\n\n      // Add disposer to result.\n      if (result instanceof Object) {\n        if (!(Symbol.dispose in result)) {\n          // We want the disposer to be non-enumerable as otherwise it gets in the way of things\n          // like unit tests trying to deep-compare the result to an object.\n          Object.defineProperty(result, Symbol.dispose, {\n            // NOTE: Using `this.dispose.bind(this)` here causes Playwright's build of\n            //   Chromium 140.0.7339.16 to fail when the object is assigned to a `using` variable,\n            //   with the error:\n            //       TypeError: Symbol(Symbol.dispose) is not a function\n            //   I cannot reproduce this problem in Chrome 140.0.7339.127 nor in Node or workerd,\n            //   so maybe it was a short-lived V8 bug or something. To be safe, though, we use\n            //   `() => this.dispose()`, which seems to always work.\n            value: () => this.dispose(),\n            writable: true,\n            enumerable: false,\n            configurable: true,\n          });\n        }\n      }\n\n      return result;\n    } catch (err) {\n      // Automatically dispose since the application will never receive the disposable...\n      this.dispose();\n      throw err;\n    }\n  }\n\n  public dispose() {\n    if (this.source === \"owned\") {\n      // Oh good, we can just run through them.\n      this.hooks!.forEach(hook => hook.dispose());\n      this.promises!.forEach(promise => promise.promise[Symbol.dispose]());\n    } else if (this.source === \"return\") {\n      // Value received directly from app as a return value. We take ownership of all stubs, so we\n      // must recursively scan it for things to dispose.\n      this.disposeImpl(this.value, undefined);\n      if (this.rpcTargets && this.rpcTargets.size > 0) {\n        throw new Error(\"Not all rpcTargets were accounted for in disposeImpl()?\");\n      }\n    } else {\n      // this.source is \"params\". We don't own the stubs within.\n    }\n\n    // Make dispose() idempotent.\n    this.source = \"owned\";\n    this.hooks = [];\n    this.promises = [];\n  }\n\n  // Recursive dispose, called only when `source` is \"return\".\n  private disposeImpl(value: unknown, parent: object | undefined) {\n    let kind = typeForRpc(value);\n    switch (kind) {\n      case \"unsupported\":\n      case \"primitive\":\n      case \"bigint\":\n      case \"bytes\":\n      case \"date\":\n      case \"error\":\n      case \"undefined\":\n        return;\n\n      case \"array\": {\n        let array = <Array<unknown>>value;\n        let len = array.length;\n        for (let i = 0; i < len; i++) {\n          this.disposeImpl(array[i], array);\n        }\n        return;\n      }\n\n      case \"object\": {\n        let object = <Record<string, unknown>>value;\n        for (let i in object) {\n          this.disposeImpl(object[i], object);\n        }\n        return;\n      }\n\n      case \"stub\":\n      case \"rpc-promise\": {\n        let stub = <RpcStub>value;\n        let hook = unwrapStubNoProperties(stub);\n        if (hook) {\n          hook.dispose();\n        }\n        return;\n      }\n\n      case \"function\":\n      case \"rpc-target\": {\n        let target = <RpcTarget | Function>value;\n        let hook = this.rpcTargets?.get(target);\n        if (hook) {\n          // We created a hook around this target earlier. Dispose it now.\n          hook.dispose();\n          this.rpcTargets!.delete(target);\n        } else {\n          // There never was a stub pointing at this target. This could be because:\n          // * The call was used only for promise pipelining, so the result was never serialized,\n          //   so it never got added to `rpcTargets`.\n          // * The same RpcTarget appears in the results twice, and we already disposed the hook\n          //   when we saw it earlier. Note that it's intentional that we should call the disposer\n          //   twice if the same object appears twice.\n          disposeRpcTarget(target);\n        }\n        return;\n      }\n\n      case \"rpc-thenable\":\n        // Since thenables are promises, we don't own them, so we don't dispose them.\n        return;\n\n      case \"headers\":\n        // Headers have no owned resources to dispose.\n        return;\n\n      case \"request\": {\n        // The body may be a ReadableStream that has an associated hook in rpcTargets.\n        let req = <Request>value;\n        if (req.body) this.disposeImpl(req.body, req);\n        // TODO: When we support AbortSignal, we may need to dispose request.signal here?\n        return;\n      }\n\n      case \"response\": {\n        // The body may be a ReadableStream that has an associated hook in rpcTargets.\n        let resp = <Response>value;\n        if (resp.body) this.disposeImpl(resp.body, resp);\n        // TODO: When we support WebSocket, we may need to dispose response.webSocket here?\n        return;\n      }\n\n      case \"writable\": {\n        let stream = <WritableStream>value;\n        let hook = this.rpcTargets?.get(stream);\n        if (hook) {\n          this.rpcTargets!.delete(stream);\n        } else {\n          // Create a hook just so we can call its disposer for consistent behavior, which will\n          // abort the stream.\n          hook = streamImpl.createWritableStreamHook(stream);\n        }\n\n        hook.dispose();\n\n        return;\n      }\n\n      case \"readable\": {\n        let stream = <ReadableStream>value;\n        let hook = this.rpcTargets?.get(stream);\n        if (hook) {\n          this.rpcTargets!.delete(stream);\n        } else {\n          // Create a hook just so we can call its disposer for consistent behavior, which will\n          // cancel the stream.\n          hook = streamImpl.createReadableStreamHook(stream);\n        }\n\n        hook.dispose();\n\n        return;\n      }\n\n      default:\n        kind satisfies never;\n        return;\n    }\n  }\n\n  // Ignore unhandled rejections in all promises in this payload -- that is, all promises that\n  // *would* be awaited if this payload were to be delivered. See the similarly-named method of\n  // StubHook for explanation.\n  ignoreUnhandledRejections(): void {\n    if (this.hooks) {\n      // Propagate to all stubs and promises.\n      this.hooks.forEach(hook => {\n        hook.ignoreUnhandledRejections();\n      });\n      this.promises!.forEach(\n          promise => unwrapStubOrParent(promise.promise).ignoreUnhandledRejections());\n    } else {\n      // Ugh we have to walk the tree.\n      this.ignoreUnhandledRejectionsImpl(this.value);\n    }\n  }\n\n  private ignoreUnhandledRejectionsImpl(value: unknown) {\n    let kind = typeForRpc(value);\n    switch (kind) {\n      case \"unsupported\":\n      case \"primitive\":\n      case \"bigint\":\n      case \"bytes\":\n      case \"date\":\n      case \"error\":\n      case \"undefined\":\n      case \"function\":\n      case \"rpc-target\":\n      case \"writable\":\n      case \"readable\":\n      case \"headers\":\n      case \"request\":\n      case \"response\":\n        return;\n\n      case \"array\": {\n        let array = <Array<unknown>>value;\n        let len = array.length;\n        for (let i = 0; i < len; i++) {\n          this.ignoreUnhandledRejectionsImpl(array[i]);\n        }\n        return;\n      }\n\n      case \"object\": {\n        let object = <Record<string, unknown>>value;\n        for (let i in object) {\n          this.ignoreUnhandledRejectionsImpl(object[i]);\n        }\n        return;\n      }\n\n      case \"stub\":\n      case \"rpc-promise\":\n        unwrapStubOrParent(<RpcStub>value).ignoreUnhandledRejections();\n        return;\n\n      case \"rpc-thenable\":\n        (<any>value).then((_: any) => {}, (_: any) => {});\n        return;\n\n      default:\n        kind satisfies never;\n        return;\n    }\n  }\n};\n\n// =======================================================================================\n// Local StubHook implementations\n\n// Result of followPath().\ntype FollowPathResult = {\n  // Path led to a regular value.\n\n  value: unknown,              // the value\n  parent: object | undefined,  // the immediate parent (useful as `this` if making a call)\n  owner: RpcPayload | null,    // RpcPayload that owns the value, if any\n\n  hook?: never,\n  remainingPath?: never,\n} | {\n  // Path leads into another stub, which needs to be called recursively.\n\n  hook: StubHook,               // StubHook of the inner stub.\n  remainingPath: PropertyPath,  // Path to pass to `hook` when recursing.\n\n  value?: never,\n  parent?: never,\n  owner?: never,\n};\n\nfunction followPath(value: unknown, parent: object | undefined,\n                    path: PropertyPath, owner: RpcPayload | null): FollowPathResult {\n  for (let i = 0; i < path.length; i++) {\n    parent = <object>value;\n\n    let part = path[i];\n    if (part in Object.prototype) {\n      // Don't allow messing with Object.prototype properties over RPC. We block these even if\n      // the specific object has overridden them for consistency with the deserialization code,\n      // which will refuse to deserialize an object containing such properties. Anyway, it's\n      // impossible for a normal client to even request these because accessing Object prototype\n      // properties on a stub will resolve to the local prototype property, not making an RPC at\n      // all.\n      value = undefined;\n      continue;\n    }\n\n    let kind = typeForRpc(value);\n    switch (kind) {\n      case \"object\":\n      case \"function\":\n        // Must be own property, NOT inherited from a prototype.\n        if (Object.hasOwn(<object>value, part)) {\n          value = (<any>value)[part];\n        } else {\n          value = undefined;\n        }\n        break;\n\n      case \"array\":\n        // For arrays, restrict specifically to numeric indexes, to be consistent with\n        // serialization, which only sends a flat list.\n        if (Number.isInteger(part) && <number>part >= 0) {\n          value = (<any>value)[part];\n        } else {\n          value = undefined;\n        }\n        break;\n\n      case \"rpc-target\":\n      case \"rpc-thenable\": {\n        // Must be prototype property, and must NOT be inherited from `Object`.\n        if (Object.hasOwn(<object>value, part)) {\n          // We throw an error in this case, rather than return undefined, because otherwise\n          // people tend to get confused about this. If you don't want it to be possible to\n          // probe the existence of your instance properties, make them properly private (prefix\n          // with #).\n          throw new TypeError(\n              `Attempted to access property '${part}', which is an instance property of the ` +\n              `RpcTarget. To avoid leaking private internals, instance properties cannot be ` +\n              `accessed over RPC. If you want to make this property available over RPC, define ` +\n              `it as a method or getter on the class, instead of an instance property.`);\n        } else {\n          value = (<any>value)[part];\n        }\n\n        // Since we're descending into the RpcTarget, the rest of the path is not \"owned\" by any\n        // RpcPayload.\n        owner = null;\n        break;\n      }\n\n      case \"stub\":\n      case \"rpc-promise\": {\n        let {hook: hook, pathIfPromise} = unwrapStubAndPath(<RpcStub>value);\n        return { hook, remainingPath:\n            pathIfPromise ? pathIfPromise.concat(path.slice(i)) : path.slice(i) };\n      }\n\n      case \"writable\":\n        // TODO: How do we pipeline on WritableStream? We can't expose the literal WritableStream\n        //   interface because the caller would call getWriter() which would conflict with the\n        //   RPC system calling it later. Perhaps the caller needs to somehow indicate, on the\n        //   client side, \"this pipelined property is expected to be a WritableStream\", and then\n        //   we can give them a WritableStream, and somehow this correctly pipelines... idk.\n        value = undefined;\n        break;\n\n      case \"readable\":\n        // TODO: Do we want to support pipelining on ReadableStream at all? It doesn't seem like\n        //   it really makes sense... you might as well just wait for the promise for the\n        //   ReadableStream to resolve, and then read it, because you'll get bytes just as fast.\n        value = undefined;\n        break;\n\n      case \"primitive\":\n      case \"bigint\":\n      case \"bytes\":\n      case \"date\":\n      case \"error\":\n      case \"headers\":\n      case \"request\":\n      case \"response\":\n        // These have no properties that can be accessed remotely.\n        value = undefined;\n        break;\n\n      case \"undefined\":\n        // Intentionally produce TypeError.\n        value = (value as any)[part];\n        break;\n\n      case \"unsupported\": {\n        if (i === 0) {\n          throw new TypeError(`RPC stub points at a non-serializable type.`);\n        } else {\n          let prefix = path.slice(0, i).join(\".\");\n          let remainder = path.slice(0, i).join(\".\");\n          throw new TypeError(\n              `'${prefix}' is not a serializable type, so property ${remainder} cannot ` +\n              `be accessed.`);\n        }\n      }\n\n      default:\n        kind satisfies never;\n        throw new TypeError(\"unreachable\");\n    }\n  }\n\n  // If we reached a promise, we actually want the caller to forward to the promise, not return\n  // the promise itself.\n  if (value instanceof RpcPromise) {\n    let {hook: hook, pathIfPromise} = unwrapStubAndPath(<RpcStub>value);\n    return { hook, remainingPath: pathIfPromise || [] };\n  }\n\n  // We don't validate the final value itself because we don't know the intended use yet. If it's\n  // for a call, any callable is valid. If it's for get(), then any serializable value is valid.\n  return {\n    value,\n    parent,\n    owner,\n  };\n}\n\n// Shared base class for PayloadStubHook and TargetStubHook.\nabstract class ValueStubHook extends StubHook {\n  protected abstract getValue(): {value: unknown, owner: RpcPayload | null};\n\n  call(path: PropertyPath, args: RpcPayload): StubHook {\n    try {\n      let {value, owner} = this.getValue();\n      let followResult = followPath(value, undefined, path, owner);\n\n      if (followResult.hook) {\n        return followResult.hook.call(followResult.remainingPath, args);\n      }\n\n      // It's a local function.\n      if (typeof followResult.value != \"function\") {\n        throw new TypeError(`'${path.join('.')}' is not a function.`);\n      }\n      let promise = args.deliverCall(followResult.value, followResult.parent);\n      return new PromiseStubHook(promise.then(payload => {\n        return new PayloadStubHook(payload);\n      }));\n    } catch (err) {\n      return new ErrorStubHook(err);\n    }\n  }\n\n  map(path: PropertyPath, captures: StubHook[], instructions: unknown[]): StubHook {\n    try {\n      let followResult: FollowPathResult;\n      try {\n        let {value, owner} = this.getValue();\n        followResult = followPath(value, undefined, path, owner);;\n      } catch (err) {\n        // Oops, we need to dispose the captures of which we took ownership.\n        for (let cap of captures) {\n          cap.dispose();\n        }\n        throw err;\n      }\n\n      if (followResult.hook) {\n        return followResult.hook.map(followResult.remainingPath, captures, instructions);\n      }\n\n      return mapImpl.applyMap(\n          followResult.value, followResult.parent, followResult.owner, captures, instructions);\n    } catch (err) {\n      return new ErrorStubHook(err);\n    }\n  }\n\n  get(path: PropertyPath): StubHook {\n    try {\n      let {value, owner} = this.getValue();\n\n      if (path.length === 0 && owner === null) {\n        // The only way this happens is if someone sends \"pipeline\" and references a\n        // TargetStubHook, but they shouldn't do that, because TargetStubHook never backs a\n        // promise, and a non-promise cannot be converted to a promise.\n        // TODO: Is this still correct for rpc-thenable?\n        throw new Error(\"Can't dup an RpcTarget stub as a promise.\");\n      }\n\n      let followResult = followPath(value, undefined, path, owner);\n\n      if (followResult.hook) {\n        return followResult.hook.get(followResult.remainingPath);\n      }\n\n      // Note that if `followResult.owner` is null, then we've descended into the contents of an\n      // RpcTarget. In that case, if this deep copy discovers an RpcTarget embedded in the result,\n      // it will create a new stub for it. If that RpcTarget has a disposer, it'll be disposed when\n      // that stub is disposed. If the same RpcTarget is returned in *another* get(), it create\n      // *another* stub, which calls the disposer *another* time. This can be quite weird -- the\n      // disposer may be called any number of times, including zero if the property is never read\n      // at all. Unfortunately, that's just the way it is. The application can avoid this problem by\n      // wrapping the RpcTarget in an RpcStub itself, proactively, and using that as the property --\n      // then, each time the property is get()ed, a dup() of that stub is returned.\n      return new PayloadStubHook(RpcPayload.deepCopyFrom(\n          followResult.value, followResult.parent, followResult.owner));\n    } catch (err) {\n      return new ErrorStubHook(err);\n    }\n  }\n}\n\n// StubHook wrapping an RpcPayload in local memory.\n//\n// This is used for:\n// - Resolution of a promise.\n//   - Initially on the server side, where it can be pull()ed and used in pipelining.\n//   - On the client side, after pull() has transmitted the payload.\n// - Implementing RpcTargets, on the server side.\n//   - Since the payload's root is an RpcTarget, pull()ing it will just duplicate the stub.\nexport class PayloadStubHook extends ValueStubHook {\n  constructor(payload: RpcPayload) {\n    super();\n    this.payload = payload;\n  }\n\n  private payload?: RpcPayload;  // cleared when disposed\n\n  private getPayload(): RpcPayload {\n    if (this.payload) {\n      return this.payload;\n    } else {\n      throw new Error(\"Attempted to use an RPC StubHook after it was disposed.\");\n    }\n  }\n\n  protected getValue() {\n    let payload = this.getPayload();\n    return {value: payload.value, owner: payload};\n  }\n\n  dup(): StubHook {\n    // Although dup() is documented as not copying the payload, what this really means is that\n    // you aren't expected to be able to pull() from a dup()ed hook if it is remote. However,\n    // PayloadStubHook already has the value locally, and there's nothing we can do except clone\n    // it here.\n    //\n    // TODO: Should we prohibit pull()ing from the clone? The fact that it'll be wrapped as\n    //   RpcStub instead of RpcPromise should already prevent this...\n    let thisPayload = this.getPayload();\n    return new PayloadStubHook(RpcPayload.deepCopyFrom(\n        thisPayload.value, undefined, thisPayload));\n  }\n\n  pull(): RpcPayload | Promise<RpcPayload> {\n    // Reminder: pull() intentionally returns the hook's own payload and not a clone. The caller\n    // only needs to dispose one of the hook or the payload. It is the caller's responsibility\n    // to not dispose the payload if they intend to keep the hook around.\n    return this.getPayload();\n  }\n\n  ignoreUnhandledRejections(): void {\n    if (this.payload) {\n      this.payload.ignoreUnhandledRejections();\n    }\n  }\n\n  dispose(): void {\n    if (this.payload) {\n      this.payload.dispose();\n      this.payload = undefined;\n    }\n  }\n\n  onBroken(callback: (error: any) => void): void {\n    if (this.payload) {\n      if (this.payload.value instanceof RpcStub) {\n        // Payload is a single stub, we should forward onRpcBroken to it.\n        // TODO: Consider prohibiting PayloadStubHook created around a single stub; should always\n        //   use the underlying stub's hook instead?\n        this.payload.value.onRpcBroken(callback);\n      }\n\n      // TODO: Should native stubs be able to implement onRpcBroken?\n    }\n  }\n}\n\nfunction disposeRpcTarget(target: RpcTarget | Function) {\n  if (Symbol.dispose in target) {\n    try {\n      ((<Disposable><any>target)[Symbol.dispose])();\n    } catch (err) {\n      // We don't actually want to throw from dispose() as this will create trouble for\n      // the RPC state machine. Instead, treat the application's error as an unhandled\n      // rejection.\n      Promise.reject(err);\n    }\n  }\n}\n\n// Many TargetStubHooks could point at the same RpcTarget. We store a refcount in a separate\n// object that they all share.\n//\n// We can't store the refcount on the RpcTarget itself because if the application chooses to pass\n// the same RpcTarget into the RPC system multiple times, we need to call this disposer multiple\n// times for consistency.\ntype BoxedRefcount = { count: number };\n\n// StubHook which wraps an RpcTarget. This has similarities to PayloadStubHook (especially when\n// the root of the payload happens to be an RpcTarget), but there can only be one RpcPayload\n// pointing at an RpcTarget whereas there can be several TargetStubHooks pointing at it. Also,\n// TargetStubHook cannot be pull()ed, because it always backs an RpcStub, not an RpcPromise.\nclass TargetStubHook extends ValueStubHook {\n  // Constructs a TargetStubHook that is not duplicated from an existing hook.\n  //\n  // If `value` is a function, `parent` is bound as its \"this\".\n  static create(value: RpcTarget | Function, parent: object | undefined) {\n    if (typeof value !== \"function\") {\n      // If the target isn't callable, we don't need to pass a `this` to it, so drop `parent`.\n      // NOTE: `typeof value === \"function\"` checks if the value is callable. This technically\n      //   works even for `RpcTarget` implementations that are callable, not just plain functions.\n      parent = undefined;\n    }\n    return new TargetStubHook(value, parent);\n  }\n\n  private constructor(target: RpcTarget | Function,\n                      parent?: object | undefined,\n                      dupFrom?: TargetStubHook) {\n    super();\n    this.target = target;\n    this.parent = parent;\n    if (dupFrom) {\n      if (dupFrom.refcount) {\n        this.refcount = dupFrom.refcount;\n        ++this.refcount.count;\n      }\n    } else if (Symbol.dispose in target) {\n      // Disposer present, so we need to refcount.\n      this.refcount = {count: 1};\n    }\n  }\n\n  private target?: RpcTarget | Function;  // cleared when disposed\n  private parent?: object | undefined;  // `this` parameter when calling `target`\n  private refcount?: BoxedRefcount;  // undefined if not needed (because target has no disposer)\n\n  private getTarget(): RpcTarget | Function {\n    if (this.target) {\n      return this.target;\n    } else {\n      throw new Error(\"Attempted to use an RPC StubHook after it was disposed.\");\n    }\n  }\n\n  protected getValue() {\n    return {value: this.getTarget(), owner: null};\n  }\n\n  dup(): StubHook {\n    return new TargetStubHook(this.getTarget(), this.parent, this);\n  }\n\n  pull(): RpcPayload | Promise<RpcPayload> {\n    let target = this.getTarget();\n    if (\"then\" in target) {\n      // If the target is itself thenable, we allow it to be treated as a promise. This is used\n      // in particular to support wrapping a workerd-native RpcPromise or RpcProperty.\n      return Promise.resolve(target).then(resolution => {\n        return RpcPayload.fromAppReturn(resolution);\n      });\n    } else {\n      // This shouldn't be called since RpcTarget always becomes RpcStub, not RpcPromise, and you\n      // can only pull a promise.\n      return Promise.reject(new Error(\"Tried to resolve a non-promise stub.\"));\n    }\n  }\n\n  ignoreUnhandledRejections(): void {\n    // Nothing to do.\n  }\n\n  dispose(): void {\n    if (this.target) {\n      if (this.refcount) {\n        if (--this.refcount.count == 0) {\n          disposeRpcTarget(this.target);\n        }\n      }\n\n      this.target = undefined;\n    }\n  }\n\n  onBroken(callback: (error: any) => void): void {\n    // TODO: Should RpcTargets be able to implement onRpcBroken?\n  }\n}\n\n// StubHook derived from a Promise for some other StubHook. Waits for the promise and then\n// forward calls, being careful to honor e-order.\nexport class PromiseStubHook extends StubHook {\n  private promise: Promise<StubHook>;\n  private resolution: StubHook | undefined;\n\n  constructor(promise: Promise<StubHook>) {\n    super();\n\n    this.promise = promise.then(res => { this.resolution = res; return res; });\n  }\n\n  call(path: PropertyPath, args: RpcPayload): StubHook {\n    // Note: We can't use `resolution` even if it's available because it could technically break\n    //   e-order: A call() that arrives just after the resolution could be delivered faster than\n    //   a call() that arrives just before. Keeping the promise around and always waiting on it\n    //   avoids the problem.\n    // TODO: Is there a way around this?\n\n    // Once call() returns (synchronously), we can no longer touch the original args. Since we\n    // can't serialize them yet, we have to deep-copy them now.\n    args.ensureDeepCopied();\n\n    return new PromiseStubHook(this.promise.then(hook => hook.call(path, args)));\n  }\n\n  stream(path: PropertyPath, args: RpcPayload): {promise: Promise<void>, size?: number} {\n    // Not yet resolved — we don't know if this will be local or remote. Deep-copy args and wait.\n    // No size is returned because we can't know yet; this means the caller will await the promise,\n    // which is the safe default (serialized writes).\n    args.ensureDeepCopied();\n    let promise = this.promise.then(hook => {\n      let result = hook.stream(path, args);\n      return result.promise;\n    });\n    return { promise };\n  }\n\n  map(path: PropertyPath, captures: StubHook[], instructions: unknown[]): StubHook {\n    return new PromiseStubHook(this.promise.then(\n        hook => hook.map(path, captures, instructions),\n        err => {\n          for (let cap of captures) {\n            cap.dispose();\n          }\n          throw err;\n        }));\n  }\n\n  get(path: PropertyPath): StubHook {\n    // Note: e-order matters for get(), just like call(), in case the property has a getter.\n    return new PromiseStubHook(this.promise.then(hook => hook.get(path)));\n  }\n\n  dup(): StubHook {\n    if (this.resolution) {\n      return this.resolution.dup();\n    } else {\n      return new PromiseStubHook(this.promise.then(hook => hook.dup()));\n    }\n  }\n\n  pull(): RpcPayload | Promise<RpcPayload> {\n    // Luckily, resolutions are not subject to e-order, so it's safe to use `this.resolution`\n    // here. In fact, it is required to maintain e-order elsewhere: If this promise is being used\n    // as the input to some other local call (via promise pipelining), we need to make sure that\n    // other call is not delayed at all when this promise is already resolved.\n    if (this.resolution) {\n      return this.resolution.pull();\n    } else {\n      return this.promise.then(hook => hook.pull());\n    }\n  }\n\n  ignoreUnhandledRejections(): void {\n    if (this.resolution) {\n      this.resolution.ignoreUnhandledRejections();\n    } else {\n      this.promise.then(res => {\n        res.ignoreUnhandledRejections();\n      }, err => {\n        // Ignore the error!\n      });\n    }\n  }\n\n  dispose(): void {\n    if (this.resolution) {\n      this.resolution.dispose();\n    } else {\n      this.promise.then(hook => {\n        hook.dispose();\n      }, err => {\n        // nothing to dispose\n      });\n    }\n  }\n\n  onBroken(callback: (error: any) => void): void {\n    if (this.resolution) {\n      this.resolution.onBroken(callback);\n    } else {\n      this.promise.then(hook => {\n        hook.onBroken(callback);\n      }, callback);\n    }\n  }\n}\n", "// Copyright (c) 2025 Cloudflare, Inc.\n// Licensed under the MIT license found in the LICENSE.txt file or at:\n//     https://opensource.org/license/mit\n\nimport { StubHook, RpcPayload, typeForRpc, RpcStub, RpcPromise, LocatedPromise, RpcTarget, unwrapStubAndPath, streamImpl, PromiseStubHook, PayloadStubHook } from \"./core.js\";\n\nexport type ImportId = number;\nexport type ExportId = number;\n\n// =======================================================================================\n\nexport interface Exporter {\n  exportStub(hook: StubHook): ExportId;\n  exportPromise(hook: StubHook): ExportId;\n  getImport(hook: StubHook): ImportId | undefined;\n\n  // If a serialization error occurs after having exported some capabilities, this will be called\n  // to roll back the exports.\n  unexport(ids: Array<ExportId>): void;\n\n  // Creates a pipe by sending a [\"pipe\"] message, then starts pumping the given ReadableStream\n  // into the pipe's writable end. Returns the import ID assigned to the pipe. `hook` should be\n  // disposed when the pipe finishes.\n  createPipe(readable: ReadableStream, hook: StubHook): ImportId;\n\n  onSendError(error: Error): Error | void;\n}\n\nclass NullExporter implements Exporter {\n  exportStub(stub: StubHook): never {\n    throw new Error(\"Cannot serialize RPC stubs without an RPC session.\");\n  }\n  exportPromise(stub: StubHook): never {\n    throw new Error(\"Cannot serialize RPC stubs without an RPC session.\");\n  }\n  getImport(hook: StubHook): ImportId | undefined {\n    return undefined;\n  }\n  unexport(ids: Array<ExportId>): void {}\n  createPipe(readable: ReadableStream): never {\n    throw new Error(\"Cannot create pipes without an RPC session.\");\n  }\n\n  onSendError(error: Error): Error | void {}\n}\n\nconst NULL_EXPORTER = new NullExporter();\n\n// Maps error name to error class for deserialization.\nconst ERROR_TYPES: Record<string, any> = {\n  Error, EvalError, RangeError, ReferenceError, SyntaxError, TypeError, URIError, AggregateError,\n  // TODO: DOMError? Others?\n};\n\n// Polyfill type for UInt8Array.toBase64(), which has started landing in JS runtimes but is not\n// supported everywhere just yet.\ninterface Uint8Array {\n  toBase64?(options?: {\n    alphabet?: \"base64\" | \"base64url\",\n    omitPadding?: boolean\n  }): string;\n};\n\ninterface FromBase64 {\n  fromBase64?(text: string, options?: {\n    alphabet?: \"base64\" | \"base64url\",\n    lastChunkHandling?: \"loose\" | \"strict\" | \"stop-before-partial\"\n  }): Uint8Array;\n}\n\n// Converts fully-hydrated messages into object trees that are JSON-serializable for sending over\n// the wire. This is used to implement serialization -- but it doesn't take the last step of\n// actually converting to a string. (The name is meant to be the opposite of \"Evaluator\", which\n// implements the opposite direction.)\nexport class Devaluator {\n  private constructor(private exporter: Exporter, private source: RpcPayload | undefined) {}\n\n  // Devaluate the given value.\n  // * value: The value to devaluate.\n  // * parent: The value's parent object, which would be used as `this` if the value were called\n  //     as a function.\n  // * exporter: Callbacks to the RPC session for exporting capabilities found in this message.\n  // * source: The RpcPayload which contains the value, and therefore owns stubs within.\n  //\n  // Returns: The devaluated value, ready to be JSON-serialized.\n  public static devaluate(\n      value: unknown, parent?: object, exporter: Exporter = NULL_EXPORTER, source?: RpcPayload)\n      : unknown {\n    let devaluator = new Devaluator(exporter, source);\n    try {\n      return devaluator.devaluateImpl(value, parent, 0);\n    } catch (err) {\n      if (devaluator.exports) {\n        try {\n          exporter.unexport(devaluator.exports);\n        } catch (err) {\n          // probably a side effect of the original error, ignore it\n        }\n      }\n      throw err;\n    }\n  }\n\n  private exports?: Array<ExportId>;\n\n  private devaluateImpl(value: unknown, parent: object | undefined, depth: number): unknown {\n    if (depth >= 64) {\n      throw new Error(\n          \"Serialization exceeded maximum allowed depth. (Does the message contain cycles?)\");\n    }\n\n    let kind = typeForRpc(value);\n    switch (kind) {\n      case \"unsupported\": {\n        let msg;\n        try {\n          msg = `Cannot serialize value: ${value}`;\n        } catch (err) {\n          msg = \"Cannot serialize value: (couldn't stringify value)\";\n        }\n        throw new TypeError(msg);\n      }\n\n      case \"primitive\":\n        if (typeof value === \"number\" && !isFinite(value)) {\n          if (value === Infinity) {\n            return [\"inf\"];\n          } else if (value === -Infinity) {\n            return [\"-inf\"];\n          } else {\n            return [\"nan\"];\n          }\n        } else {\n          // Supported directly by JSON.\n          return value;\n        }\n\n      case \"object\": {\n        let object = <Record<string, unknown>>value;\n        let result: Record<string, unknown> = {};\n        for (let key in object) {\n          result[key] = this.devaluateImpl(object[key], object, depth + 1);\n        }\n        return result;\n      }\n\n      case \"array\": {\n        let array = <Array<unknown>>value;\n        let len = array.length;\n        let result = new Array(len);\n        for (let i = 0; i < len; i++) {\n          result[i] = this.devaluateImpl(array[i], array, depth + 1);\n        }\n        // Wrap literal arrays in an outer one-element array, to \"escape\" them.\n        return [result];\n      }\n\n      case \"bigint\":\n        return [\"bigint\", (<bigint>value).toString()];\n\n      case \"date\":\n        return [\"date\", (<Date>value).getTime()];\n\n      case \"bytes\": {\n        let bytes = value as Uint8Array;\n        if (bytes.toBase64) {\n          return [\"bytes\", bytes.toBase64({omitPadding: true})];\n        } else {\n          return [\"bytes\",\n              btoa(String.fromCharCode.apply(null, bytes as number[]).replace(/=*$/, \"\"))];\n        }\n      }\n\n      case \"headers\":\n        // The `Headers` TS type apparently doesn't declare itself as being\n        // Iterable<[string, string]>, but it is.\n        return [\"headers\", [...<Iterable<[string, string]>>value]];\n\n      case \"request\": {\n        let req = <Request>value;\n        let init: Record<string, unknown> = {};\n\n        // For many properties below, the official Fetch spec says they must always be present,\n        // but some platforms don't support them. So, we check both whether the property exists,\n        // and whether it is equal to the default, before bothering to add it to `init`.\n\n        if (req.method !== \"GET\") init.method = req.method;\n\n        let headers = [...<Iterable<[string, string]>><any>req.headers];\n        if (headers.length > 0) {\n          // Note that we don't need to serialize this as [\"headers\", headers] because we are only\n          // trying to create a valid RequestInit object.\n          init.headers = headers;\n        }\n\n        if (req.body) {\n          init.body = this.devaluateImpl(req.body, req, depth + 1);\n\n          // Apparently the fetch spec technically requires that `duplex` be specified when a\n          // body is specified, and Chrome in fact requires this, and requires the value is \"half\".\n          // Workers hasn't implemented this (and actually supports full duplex by default, lol).\n          // The TS types for Request currently don't define this property, but it is there (on\n          // Chrome at least).\n          init.duplex = (<any>req).duplex || \"half\";\n        } else if (req.body === undefined &&\n            ![\"GET\", \"HEAD\", \"OPTIONS\", \"TRACE\", \"DELETE\"].includes(req.method)) {\n          // If the body is undefined rather than null, most likely we're on a platform that\n          // doesn't support request body streams (*cough*Firefox*cough*). We'll need to hack\n          // around this by using `req.arrayBuffer()` to get the body. Unfortunately this is async,\n          // so we can't just embed the resulting body into the message we are constructing. We\n          // will actually have to construct a ReadableStream. Ugh!\n\n          let bodyPromise = req.arrayBuffer();\n\n          let readable = new ReadableStream<Uint8Array>({\n            async start(controller) {\n              try {\n                // `as Uint8Array` is needed here to work around some sort of weird bug in the TS\n                // types where `new Uint8Array` somehow doesn't return a `Uint8Array`. Instead it\n                // somehow returns `Uint8Array<ArrayBuffer>` -- but `Uint8Array` is not a generic\n                // type! WTF?\n                // TODO(cleanup): This is apparently fixed in TS 6.\n                controller.enqueue(new Uint8Array(await bodyPromise) as Uint8Array);\n                controller.close();\n              } catch (err) {\n                controller.error(err);\n              }\n            }\n          });\n\n          // We can't recurse to devaluateImpl() to serialize the body because it'll call\n          // source.getHookForReadableStream(), adding a hook on the payload which isn't actually\n          // reachable by walking the payload, which will cause trouble later. So we have to\n          // inline it a bit here...\n          let hook = streamImpl.createReadableStreamHook(readable);\n          let importId = this.exporter.createPipe(readable, hook);\n          init.body = [\"readable\", importId];\n          init.duplex = (<any>req).duplex || \"half\";\n        }\n\n        if (req.cache && req.cache !== \"default\") init.cache = req.cache;\n        if (req.redirect !== \"follow\") init.redirect = req.redirect;\n        if (req.integrity) init.integrity = req.integrity;\n\n        // These properties are only meaningful in browsers and not supported by most WinterCG\n        // (server-side) platforms.\n        if (req.mode && req.mode !== \"cors\") init.mode = req.mode;\n        if (req.credentials && req.credentials !== \"same-origin\") {\n          init.credentials = req.credentials;\n        }\n        if (req.referrer && req.referrer !== \"about:client\") init.referrer = req.referrer;\n        if (req.referrerPolicy) init.referrerPolicy = req.referrerPolicy;\n        if (req.keepalive) init.keepalive = req.keepalive;\n\n        // These properties are specific to Cloudflare Workers. Cast the request to `any` to\n        // silence type errors on other platforms.\n        let cfReq = req as any;\n        if (cfReq.cf) init.cf = cfReq.cf;\n        if (cfReq.encodeResponseBody && cfReq.encodeResponseBody !== \"automatic\") {\n          init.encodeResponseBody = cfReq.encodeResponseBody;\n        }\n\n        // TODO: Support request.signal. Annoyingly, all `Request`s have a `signal` property even\n        //   if none was passed to the constructor, and there's no way to tell if it's a real\n        //   signal. So for now, since we don't support AbortSignal yet, all we can do is ignore\n        //   it; we can't throw an error if it's present.\n\n        return [\"request\", req.url, init];\n      }\n\n      case \"response\": {\n        let resp = <Response>value;\n        let body = this.devaluateImpl(resp.body, resp, depth + 1);\n        let init: Record<string, unknown> = {};\n\n        if (resp.status !== 200) init.status = resp.status;\n        if (resp.statusText) init.statusText = resp.statusText;\n\n        let headers = [...<Iterable<[string, string]>><any>resp.headers];\n        if (headers.length > 0) {\n          // Note that we don't need to serialize this as [\"headers\", headers] because we are only\n          // trying to create a valid ResponseInit object.\n          init.headers = headers;\n        }\n\n        // These properties are specific to Cloudflare Workers. Cast the request to `any` to\n        // silence type errors on other platforms.\n        let cfResp = resp as any;\n        if (cfResp.cf) init.cf = cfResp.cf;\n        if (cfResp.encodeBody && cfResp.encodeBody !== \"automatic\") {\n          init.encodeBody = cfResp.encodeBody;\n        }\n        if (cfResp.webSocket) {\n          // As of this writing, we don't support WebSocket, but we might someday.\n          throw new TypeError(\"Can't serialize a Response containing a webSocket.\");\n        }\n\n        return [\"response\", body, init];\n      }\n\n      case \"error\": {\n        let e = <Error>value;\n\n        // TODO:\n        // - Determine type by checking prototype rather than `name`, which can be overridden?\n        // - Serialize cause / suppressed error / etc.\n        // - Serialize added properties.\n\n        let rewritten = this.exporter.onSendError(e);\n        if (rewritten) {\n          e = rewritten;\n        }\n\n        let result = [\"error\", e.name, e.message];\n        if (rewritten && rewritten.stack) {\n          result.push(rewritten.stack);\n        }\n        return result;\n      }\n\n      case \"undefined\":\n        return [\"undefined\"];\n\n      case \"stub\":\n      case \"rpc-promise\": {\n        if (!this.source) {\n          throw new Error(\"Can't serialize RPC stubs in this context.\");\n        }\n\n        let {hook, pathIfPromise} = unwrapStubAndPath(<RpcStub>value);\n        let importId = this.exporter.getImport(hook);\n        if (importId !== undefined) {\n          if (pathIfPromise) {\n            // It's a promise pointing back to the peer, so we are doing pipelining here.\n            if (pathIfPromise.length > 0) {\n              return [\"pipeline\", importId, pathIfPromise];\n            } else {\n              return [\"pipeline\", importId];\n            }\n          } else {\n            return [\"import\", importId];\n          }\n        }\n\n        if (pathIfPromise) {\n          hook = hook.get(pathIfPromise);\n        } else {\n          hook = hook.dup();\n        }\n\n        return this.devaluateHook(pathIfPromise ? \"promise\" : \"export\", hook);\n      }\n\n      case \"function\":\n      case \"rpc-target\": {\n        if (!this.source) {\n          throw new Error(\"Can't serialize RPC stubs in this context.\");\n        }\n\n        let hook = this.source.getHookForRpcTarget(<RpcTarget|Function>value, parent);\n        return this.devaluateHook(\"export\", hook);\n      }\n\n      case \"rpc-thenable\": {\n        if (!this.source) {\n          throw new Error(\"Can't serialize RPC stubs in this context.\");\n        }\n\n        let hook = this.source.getHookForRpcTarget(<RpcTarget>value, parent);\n        return this.devaluateHook(\"promise\", hook);\n      }\n\n      case \"writable\": {\n        if (!this.source) {\n          throw new Error(\"Can't serialize WritableStream in this context.\");\n        }\n\n        let hook = this.source.getHookForWritableStream(<WritableStream>value, parent);\n        return this.devaluateHook(\"writable\", hook);\n      }\n\n      case \"readable\": {\n        if (!this.source) {\n          throw new Error(\"Can't serialize ReadableStream in this context.\");\n        }\n\n        let ws = <ReadableStream>value;\n        let hook = this.source.getHookForReadableStream(ws, parent);\n\n        // Create a pipe and start pumping the ReadableStream into it.\n        let importId = this.exporter.createPipe(ws, hook);\n\n        return [\"readable\", importId];\n      }\n\n      default:\n        kind satisfies never;\n        throw new Error(\"unreachable\");\n    }\n  }\n\n  private devaluateHook(type: \"export\" | \"promise\" | \"writable\", hook: StubHook): unknown {\n    if (!this.exports) this.exports = [];\n    let exportId = type === \"promise\" ? this.exporter.exportPromise(hook)\n                                      : this.exporter.exportStub(hook);\n    this.exports.push(exportId);\n    return [type, exportId];\n  }\n}\n\n/**\n * Serialize a value, using Cap'n Web's underlying serialization. This won't be able to serialize\n * RPC stubs, but it will support basic data types.\n */\nexport function serialize(value: unknown): string {\n  return JSON.stringify(Devaluator.devaluate(value));\n}\n\n// =======================================================================================\n\nexport interface Importer {\n  importStub(idx: ImportId): StubHook;\n  importPromise(idx: ImportId): StubHook;\n  getExport(idx: ExportId): StubHook | undefined;\n\n  // Retrieves the ReadableStream end of a pipe created by a [\"pipe\"] message.\n  // The exportId must refer to an export that was created as a pipe.\n  // This can only be called once per pipe.\n  getPipeReadable(exportId: ExportId): ReadableStream;\n}\n\nclass NullImporter implements Importer {\n  importStub(idx: ImportId): never {\n    throw new Error(\"Cannot deserialize RPC stubs without an RPC session.\");\n  }\n  importPromise(idx: ImportId): never {\n    throw new Error(\"Cannot deserialize RPC stubs without an RPC session.\");\n  }\n  getExport(idx: ExportId): StubHook | undefined {\n    return undefined;\n  }\n  getPipeReadable(exportId: ExportId): never {\n    throw new Error(\"Cannot retrieve pipe readable without an RPC session.\");\n  }\n}\n\nconst NULL_IMPORTER = new NullImporter();\n\n// Some runtimes (Firefox) don't support `request.body` as a stream, but we receive request bodies\n// as streams. We'll need to read the body into an ArrayBuffer and recreate the request. This is\n// asynchronous, so we'll have to swap in a promise here. This potentially breaks e-order but\n// that's something people will just have to live with when sending a Request to a Firefox\n// endpoint (probably rare).\nfunction fixBrokenRequestBody(request: Request, body: ReadableStream): RpcPromise {\n  // Reuse built-in code to read the stream into an array.\n  let promise = new Response(body).arrayBuffer().then(arrayBuffer => {\n    let bytes = new Uint8Array(arrayBuffer);\n    let result = new Request(request, {body: bytes});\n    return new PayloadStubHook(RpcPayload.fromAppReturn(result));\n  });\n  return new RpcPromise(new PromiseStubHook(promise), []);\n}\n\n// Takes object trees parse from JSON and converts them into fully-hydrated JavaScript objects for\n// delivery to the app. This is used to implement deserialization, except that it doesn't actually\n// start from a raw string.\nexport class Evaluator {\n  constructor(private importer: Importer) {}\n\n  private hooks: StubHook[] = [];\n  private promises: LocatedPromise[] = [];\n\n  public evaluate(value: unknown): RpcPayload {\n    let payload = RpcPayload.forEvaluate(this.hooks, this.promises);\n    try {\n      payload.value = this.evaluateImpl(value, payload, \"value\");\n      return payload;\n    } catch (err) {\n      payload.dispose();\n      throw err;\n    }\n  }\n\n  // Evaluate the value without destroying it.\n  public evaluateCopy(value: unknown): RpcPayload {\n    return this.evaluate(structuredClone(value));\n  }\n\n  private evaluateImpl(value: unknown, parent: object, property: string | number): unknown {\n    if (value instanceof Array) {\n      if (value.length == 1 && value[0] instanceof Array) {\n        // Escaped array. Evaluate the contents.\n        let result = value[0];\n        for (let i = 0; i < result.length; i++) {\n          result[i] = this.evaluateImpl(result[i], result, i);\n        }\n        return result;\n      } else switch (value[0]) {\n        case \"bigint\":\n          if (typeof value[1] == \"string\") {\n            return BigInt(value[1]);\n          }\n          break;\n        case \"date\":\n          if (typeof value[1] == \"number\") {\n            return new Date(value[1]);\n          }\n          break;\n        case \"bytes\": {\n          let b64 = Uint8Array as FromBase64;\n          if (typeof value[1] == \"string\") {\n            if (b64.fromBase64) {\n              return b64.fromBase64(value[1]);\n            } else {\n              let bs = atob(value[1]);\n              let len = bs.length;\n              let bytes = new Uint8Array(len);\n              for (let i = 0; i < len; i++) {\n                bytes[i] = bs.charCodeAt(i);\n              }\n              return bytes;\n            }\n          }\n          break;\n        }\n        case \"error\":\n          if (value.length >= 3 && typeof value[1] === \"string\" && typeof value[2] === \"string\") {\n            let cls = ERROR_TYPES[value[1]] || Error;\n            let result = new cls(value[2]);\n            if (typeof value[3] === \"string\") {\n              result.stack = value[3];\n            }\n            return result;\n          }\n          break;\n        case \"undefined\":\n          if (value.length === 1) {\n            return undefined;\n          }\n          break;\n        case \"inf\":\n          return Infinity;\n        case \"-inf\":\n          return -Infinity;\n        case \"nan\":\n          return NaN;\n\n        case \"headers\":\n          // We only need to validate that the parameter is an array, so as not to invoke an\n          // unexpected variant of the Headers constructor. So long as it is an array then we can\n          // rely on the constructor to perform type checking.\n          if (value.length === 2 && value[1] instanceof Array) {\n            return new Headers(value[1] as [string, string][]);\n          }\n          break;\n\n        case \"request\": {\n          if (value.length !== 3 || typeof value[1] !== \"string\") break;\n          let url = value[1] as string;\n          let init = value[2];\n          if (typeof init !== \"object\" || init === null) break;\n\n          // Evaluate specific properties which are expected to contain non-trivial types.\n          if (init.body) {\n            init.body = this.evaluateImpl(init.body, init, \"body\");\n            if (init.body === null ||\n                typeof init.body === \"string\" ||\n                init.body instanceof Uint8Array ||\n                init.body instanceof ReadableStream) {\n              // Acceptable types.\n            } else {\n              throw new TypeError(\"Request body must be of type ReadableStream.\");\n            }\n          }\n          if (init.signal) {\n            init.signal = this.evaluateImpl(init.signal, init, \"signal\");\n            if (!(init.signal instanceof AbortSignal)) {\n              throw new TypeError(\"Request siganl must be of type AbortSignal.\");\n            }\n          }\n\n          // Type-check `headers` is an array because the constructor allows multiple\n          // representations and we don't want to allow the others.\n          if (init.headers && !(init.headers instanceof Array)) {\n            throw new TypeError(\"Request headers must be serialized as an array of pairs.\");\n          }\n\n          // We assume the `Request` constructor can type-check the remaining properties.\n          let result = new Request(url, init as RequestInit);\n\n          if (init.body instanceof ReadableStream && result.body === undefined) {\n            // Oh no! We must be on Firefox where request bodies are not supported, but we had a\n            // body.\n            let promise = fixBrokenRequestBody(result, init.body);\n            this.promises.push({promise, parent, property});\n            return promise;\n          } else {\n            return result;\n          }\n        }\n\n        case \"response\": {\n          if (value.length !== 3) break;\n\n          let body = this.evaluateImpl(value[1], parent, property);\n          if (body === null ||\n              typeof body === \"string\" ||\n              body instanceof Uint8Array ||\n              body instanceof ReadableStream) {\n            // Acceptable types.\n          } else {\n            throw new TypeError(\"Response body must be of type ReadableStream.\");\n          }\n\n          let init = value[2];\n          if (typeof init !== \"object\" || init === null) break;\n\n          // Evaluate specific properties which are expected to contain non-trivial types.\n          if (init.webSocket) {\n            // `response.webSocket` is a Cloudflare Workers extension. Not (yet?) supported for\n            // serialization.\n            throw new TypeError(\"Can't deserialize a Response containing a webSocket.\");\n          }\n\n          // Type-check `headers` is an array because the constructor allows multiple\n          // representations and we don't want to allow the others.\n          if (init.headers && !(init.headers instanceof Array)) {\n            throw new TypeError(\"Request headers must be serialized as an array of pairs.\");\n          }\n\n          return new Response(body as BodyInit | null, init as ResponseInit);\n        }\n\n        case \"import\":\n        case \"pipeline\": {\n          // It's an \"import\" from the perspective of the sender, so it's an export from our\n          // side. In other words, the sender is passing our own object back to us.\n\n          if (value.length < 2 || value.length > 4) {\n            break;   // report error below\n          }\n\n          // First parameter is import ID (from the sender's perspective, so export ID from\n          // ours).\n          if (typeof value[1] != \"number\") {\n            break;   // report error below\n          }\n\n          let hook = this.importer.getExport(value[1]);\n          if (!hook) {\n            throw new Error(`no such entry on exports table: ${value[1]}`);\n          }\n\n          let isPromise = value[0] == \"pipeline\";\n\n          let addStub = (hook: StubHook) => {\n            if (isPromise) {\n              let promise = new RpcPromise(hook, []);\n              this.promises.push({promise, parent, property});\n              return promise;\n            } else {\n              this.hooks.push(hook);\n              return new RpcPromise(hook, []);\n            }\n          };\n\n          if (value.length == 2) {\n            // Just referencing the export itself.\n            if (isPromise) {\n              // We need to use hook.get([]) to make sure we get a promise hook.\n              return addStub(hook.get([]));\n            } else {\n              // dup() returns a stub hook.\n              return addStub(hook.dup());\n            }\n          }\n\n          // Second parameter, if given, is a property path.\n          let path = value[2];\n          if (!(path instanceof Array)) {\n            break;  // report error below\n          }\n          if (!path.every(\n              part => { return typeof part == \"string\" || typeof part == \"number\"; })) {\n            break;  // report error below\n          }\n\n          if (value.length == 3) {\n            // Just referencing the path, not a call.\n            return addStub(hook.get(path));\n          }\n\n          // Third parameter, if given, is call arguments. The sender has identified a function\n          // and wants us to call it.\n          //\n          // Usually this is used with \"pipeline\", in which case we evaluate to an\n          // RpcPromise. However, this can be used with \"import\", in which case the caller is\n          // asking that the result be coerced to RpcStub. This distinction matters if the\n          // result of this evaluation is to be passed as arguments to another call -- promises\n          // must be resolved in advance, but stubs can be passed immediately.\n          let args = value[3];\n          if (!(args instanceof Array)) {\n            break;  // report error below\n          }\n\n          // We need a new evaluator for the args, to build a separate payload.\n          let subEval = new Evaluator(this.importer);\n          args = subEval.evaluate([args]);\n\n          return addStub(hook.call(path, args));\n        }\n\n        case \"remap\": {\n          if (value.length !== 5 ||\n              typeof value[1] !== \"number\" ||\n              !(value[2] instanceof Array) ||\n              !(value[3] instanceof Array) ||\n              !(value[4] instanceof Array)) {\n            break;   // report error below\n          }\n\n          let hook = this.importer.getExport(value[1]);\n          if (!hook) {\n            throw new Error(`no such entry on exports table: ${value[1]}`);\n          }\n\n          let path = value[2];\n          if (!path.every(\n              part => { return typeof part == \"string\" || typeof part == \"number\"; })) {\n            break;  // report error below\n          }\n\n          let captures: StubHook[] = value[3].map(cap => {\n            if (!(cap instanceof Array) ||\n                cap.length !== 2 ||\n                (cap[0] !== \"import\" && cap[0] !== \"export\") ||\n                typeof cap[1] !== \"number\") {\n              throw new TypeError(`unknown map capture: ${JSON.stringify(cap)}`);\n            }\n\n            if (cap[0] === \"export\") {\n              return this.importer.importStub(cap[1]);\n            } else {\n              let exp = this.importer.getExport(cap[1]);\n              if (!exp) {\n                throw new Error(`no such entry on exports table: ${cap[1]}`);\n              }\n              return exp.dup();\n            }\n          });\n\n          let instructions = value[4];\n\n          let resultHook = hook.map(path, captures, instructions);\n\n          let promise = new RpcPromise(resultHook, []);\n          this.promises.push({promise, parent, property});\n          return promise;\n        }\n\n        case \"export\":\n        case \"promise\":\n          // It's an \"export\" from the perspective of the sender, i.e. they sent us a new object\n          // which we want to import.\n          //\n          // \"promise\" is same as \"export\" but should not be delivered to the application. If any\n          // promises appear in a value, they must be resolved and substituted with their results\n          // before delivery. Note that if the value being evaluated appeared in call params, or\n          // appeared in a resolve message for a promise that is being pulled, then the new promise\n          // is automatically also being pulled, otherwise it is not.\n          if (typeof value[1] == \"number\") {\n            if (value[0] == \"promise\") {\n              let hook = this.importer.importPromise(value[1]);\n              let promise = new RpcPromise(hook, []);\n              this.promises.push({parent, property, promise});\n              return promise;\n            } else {\n              let hook = this.importer.importStub(value[1]);\n              this.hooks.push(hook);\n              return new RpcStub(hook);\n            }\n          }\n          break;\n\n        case \"writable\":\n          // It's a WritableStream export from the sender. We import it and create a proxy\n          // WritableStream that forwards writes to the remote end.\n          if (typeof value[1] == \"number\") {\n            let hook = this.importer.importStub(value[1]);\n            let stream = streamImpl.createWritableStreamFromHook(hook);\n            // Track the stream for disposal.\n            this.hooks.push(hook);\n            return stream;\n          }\n          break;\n\n        case \"readable\":\n          // References the readable end of a pipe. The import ID (from the sender's perspective)\n          // is our export ID.\n          if (typeof value[1] == \"number\") {\n            let stream = this.importer.getPipeReadable(value[1]);\n            // Track the stream for disposal so that if the payload is disposed before the\n            // app reads the stream, the ReadableStream is properly canceled.\n            let hook = streamImpl.createReadableStreamHook(stream);\n            this.hooks.push(hook);\n            return stream;\n          }\n          break;\n      }\n      throw new TypeError(`unknown special value: ${JSON.stringify(value)}`);\n    } else if (value instanceof Object) {\n      let result = <Record<string, unknown>>value;\n      for (let key in result) {\n        if (key in Object.prototype || key === \"toJSON\") {\n          // Out of an abundance of caution, we will ignore properties that override properties\n          // of Object.prototype. It's especially important that we don't allow `__proto__` as it\n          // may lead to prototype pollution. We also would rather not allow, e.g., `toString()`,\n          // as overriding this could lead to various mischief.\n          //\n          // We also block `toJSON()` for similar reasons -- even though Object.prototype doesn't\n          // actually define it, `JSON.stringify()` treats it specially and we don't want someone\n          // snooping on JSON calls.\n          //\n          // We do still evaluate the inner value so that we can properly release any stubs.\n          this.evaluateImpl(result[key], result, key);\n          delete result[key];\n        } else {\n          result[key] = this.evaluateImpl(result[key], result, key);\n        }\n      }\n      return result;\n    } else {\n      // Other JSON types just pass through.\n      return value;\n    }\n  }\n}\n\n/**\n * Deserialize a value serialized using serialize().\n */\nexport function deserialize(value: string): unknown {\n  let payload = new Evaluator(NULL_IMPORTER).evaluate(JSON.parse(value));\n  payload.dispose();  // should be no-op but just in case\n  return payload.value;\n}\n", "// Copyright (c) 2025 Cloudflare, Inc.\n// Licensed under the MIT license found in the LICENSE.txt file or at:\n//     https://opensource.org/license/mit\n\nimport { StubHook, RpcPayload, RpcStub, PropertyPath, PayloadStubHook, ErrorStubHook, RpcTarget, unwrapStubAndPath, streamImpl } from \"./core.js\";\nimport { Devaluator, Evaluator, ExportId, ImportId, Exporter, Importer, serialize } from \"./serialize.js\";\n\n/**\n * Interface for an RPC transport, which is a simple bidirectional message stream. Implement this\n * interface if the built-in transports (e.g. for HTTP batch and WebSocket) don't meet your needs.\n */\nexport interface RpcTransport {\n  /**\n   * Sends a message to the other end.\n   */\n  send(message: string): Promise<void>;\n\n  /**\n   * Receives a message sent by the other end.\n   *\n   * If and when the transport becomes disconnected, this will reject. The thrown error will be\n   * propagated to all outstanding calls and future calls on any stubs associated with the session.\n   * If there are no outstanding calls (and none are made in the future), then the error does not\n   * propagate anywhere -- this is considered a \"clean\" shutdown.\n   */\n  receive(): Promise<string>;\n\n  /**\n   * Indicates that the RPC system has suffered an error that prevents the session from continuing.\n   * The transport should ideally try to send any queued messages if it can, and then close the\n   * connection. (It's not strictly necessary to deliver queued messages, but the last message sent\n   * before abort() is called is often an \"abort\" message, which communicates the error to the\n   * peer, so if that is dropped, the peer may have less information about what happened.)\n   */\n  abort?(reason: any): void;\n}\n\n// Entry on the exports table.\ntype ExportTableEntry = {\n  hook: StubHook,\n  refcount: number,\n  pull?: Promise<void>,\n\n  // If true, the export should be automatically released (with refcount 1) after its \"resolve\"\n  // or \"reject\" message is sent. This is set for exports created by [\"stream\"] messages.\n  autoRelease?: boolean,\n\n  // If this export was created by a [\"pipe\"] message, this holds the ReadableStream end of the\n  // pipe. It is consumed (and set to undefined) when a [\"readable\", importId] expression\n  // references this export.\n  pipeReadable?: ReadableStream\n};\n\n// Entry on the imports table.\nclass ImportTableEntry {\n  constructor(public session: RpcSessionImpl, public importId: number, pulling: boolean) {\n    if (pulling) {\n      this.activePull = Promise.withResolvers<void>();\n    }\n  }\n\n  public localRefcount: number = 0;\n  public remoteRefcount: number = 1;\n\n  private activePull?: PromiseWithResolvers<void>;\n  public resolution?: StubHook;\n\n  // List of integer indexes into session.onBrokenCallbacks which are callbacks registered on\n  // this import. Initialized on first use (so `undefined` is the same as an empty list).\n  private onBrokenRegistrations?: number[];\n\n  resolve(resolution: StubHook) {\n    // TODO: Need embargo handling here? PayloadStubHook needs to be wrapped in a\n    // PromiseStubHook awaiting the embargo I suppose. Previous notes on embargoes:\n    // - Resolve message specifies last call that was received before the resolve. The introducer is\n    //   responsible for any embargoes up to that point.\n    // - Any further calls forwarded by the introducer after that point MUST immediately resolve to\n    //   a forwarded call. The caller is responsible for ensuring the last of these is handed off\n    //   before direct calls can be delivered.\n\n    if (this.localRefcount == 0) {\n      // Already disposed (canceled), so ignore the resolution and don't send a redundant release.\n      resolution.dispose();\n      return;\n    }\n\n    this.resolution = resolution;\n    this.sendRelease();\n\n    if (this.onBrokenRegistrations) {\n      // Delete all our callback registrations from this session and re-register them on the\n      // target stub.\n      for (let i of this.onBrokenRegistrations) {\n        let callback = this.session.onBrokenCallbacks[i];\n        let endIndex = this.session.onBrokenCallbacks.length;\n        resolution.onBroken(callback);\n        if (this.session.onBrokenCallbacks[endIndex] === callback) {\n          // Oh, calling onBroken() just registered the callback back on this connection again.\n          // But when the connection dies, we want all the callbacks to be called in the order in\n          // which they were registered. So we don't want this one pushed to the back of the line\n          // here. So, let's remove the newly-added registration and keep the original.\n          // TODO: This is quite hacky, think about whether this is really the right answer.\n          delete this.session.onBrokenCallbacks[endIndex];\n        } else {\n          // The callback is now registered elsewhere, so delete it from our session.\n          delete this.session.onBrokenCallbacks[i];\n        }\n      }\n      this.onBrokenRegistrations = undefined;\n    }\n\n    if (this.activePull) {\n      this.activePull.resolve();\n      this.activePull = undefined;\n    }\n  }\n\n  async awaitResolution(): Promise<RpcPayload> {\n    if (!this.activePull) {\n      this.session.sendPull(this.importId);\n      this.activePull = Promise.withResolvers<void>();\n    }\n    await this.activePull.promise;\n    return this.resolution!.pull();\n  }\n\n  dispose() {\n    if (this.resolution) {\n      this.resolution.dispose();\n    } else {\n      this.abort(new Error(\"RPC was canceled because the RpcPromise was disposed.\"));\n      this.sendRelease();\n    }\n  }\n\n  abort(error: any) {\n    if (!this.resolution) {\n      this.resolution = new ErrorStubHook(error);\n\n      if (this.activePull) {\n        this.activePull.reject(error);\n        this.activePull = undefined;\n      }\n\n      // The RpcSession itself will have called all our callbacks so we don't need to track the\n      // registrations anymore.\n      this.onBrokenRegistrations = undefined;\n    }\n  }\n\n  onBroken(callback: (error: any) => void): void {\n    if (this.resolution) {\n      this.resolution.onBroken(callback);\n    } else {\n      let index = this.session.onBrokenCallbacks.length;\n      this.session.onBrokenCallbacks.push(callback);\n\n      if (!this.onBrokenRegistrations) this.onBrokenRegistrations = [];\n      this.onBrokenRegistrations.push(index);\n    }\n  }\n\n  private sendRelease() {\n    if (this.remoteRefcount > 0) {\n      this.session.sendRelease(this.importId, this.remoteRefcount);\n      this.remoteRefcount = 0;\n    }\n  }\n};\n\nclass RpcImportHook extends StubHook {\n  public entry?: ImportTableEntry;  // undefined when we're disposed\n\n  // `pulling` is true if we already expect that this import is going to be resolved later, and\n  // null if this import is not allowed to be pulled (i.e. it's a stub not a promise).\n  constructor(public isPromise: boolean, entry: ImportTableEntry) {\n    super();\n    ++entry.localRefcount;\n    this.entry = entry;\n  }\n\n  collectPath(path: PropertyPath): RpcImportHook {\n    return this;\n  }\n\n  getEntry(): ImportTableEntry {\n    if (this.entry) {\n      return this.entry;\n    } else {\n      // Shouldn't get here in practice since the holding stub should have replaced the hook when\n      // disposed.\n      throw new Error(\"This RpcImportHook was already disposed.\");\n    }\n  }\n\n  // -------------------------------------------------------------------------------------\n  // implements StubHook\n\n  call(path: PropertyPath, args: RpcPayload): StubHook {\n    let entry = this.getEntry();\n    if (entry.resolution) {\n      return entry.resolution.call(path, args);\n    } else {\n      return entry.session.sendCall(entry.importId, path, args);\n    }\n  }\n\n  stream(path: PropertyPath, args: RpcPayload): {promise: Promise<void>, size?: number} {\n    let entry = this.getEntry();\n    if (entry.resolution) {\n      return entry.resolution.stream(path, args);\n    } else {\n      return entry.session.sendStream(entry.importId, path, args);\n    }\n  }\n\n  map(path: PropertyPath, captures: StubHook[], instructions: unknown[]): StubHook {\n    let entry: ImportTableEntry;\n    try {\n      entry = this.getEntry();\n    } catch (err) {\n      for (let cap of captures) {\n        cap.dispose();\n      }\n      throw err;\n    }\n\n    if (entry.resolution) {\n      return entry.resolution.map(path, captures, instructions);\n    } else {\n      return entry.session.sendMap(entry.importId, path, captures, instructions);\n    }\n  }\n\n  get(path: PropertyPath): StubHook {\n    let entry = this.getEntry();\n    if (entry.resolution) {\n      return entry.resolution.get(path);\n    } else {\n      return entry.session.sendCall(entry.importId, path);\n    }\n  }\n\n  dup(): RpcImportHook {\n    return new RpcImportHook(false, this.getEntry());\n  }\n\n  pull(): RpcPayload | Promise<RpcPayload> {\n    let entry = this.getEntry();\n\n    if (!this.isPromise) {\n      throw new Error(\"Can't pull this hook because it's not a promise hook.\");\n    }\n\n    if (entry.resolution) {\n      return entry.resolution.pull();\n    }\n\n    return entry.awaitResolution();\n  }\n\n  ignoreUnhandledRejections(): void {\n    // We don't actually have to do anything here because this method only has to ignore rejections\n    // if pull() is *not* called, and if pull() is not called then we won't generate any rejections\n    // anyway.\n  }\n\n  dispose(): void {\n    let entry = this.entry;\n    this.entry = undefined;\n    if (entry) {\n      if (--entry.localRefcount === 0) {\n        entry.dispose();\n      }\n    }\n  }\n\n  onBroken(callback: (error: any) => void): void {\n    if (this.entry) {\n      this.entry.onBroken(callback);\n    }\n  }\n}\n\nclass RpcMainHook extends RpcImportHook {\n  private session?: RpcSessionImpl;\n\n  constructor(entry: ImportTableEntry) {\n    super(false, entry);\n    this.session = entry.session;\n  }\n\n  dispose(): void {\n    if (this.session) {\n      let session = this.session;\n      this.session = undefined;\n      session.shutdown();\n    }\n  }\n}\n\n/**\n * Options to customize behavior of an RPC session. All functions which start a session should\n * optionally accept this.\n */\nexport type RpcSessionOptions = {\n  /**\n   * If provided, this function will be called whenever an `Error` object is serialized (for any\n   * reason, not just because it was thrown). This can be used to log errors, and also to redact\n   * them.\n   *\n   * If `onSendError` returns an Error object, than object will be substituted in place of the\n   * original. If it has a stack property, the stack will be sent to the client.\n   *\n   * If `onSendError` doesn't return anything (or is not provided at all), the default behavior is\n   * to serialize the error with the stack omitted.\n   */\n  onSendError?: (error: Error) => Error | void;\n};\n\nclass RpcSessionImpl implements Importer, Exporter {\n  private exports: Array<ExportTableEntry> = [];\n  private reverseExports: Map<StubHook, ExportId> = new Map();\n  private imports: Array<ImportTableEntry> = [];\n  private abortReason?: any;\n  private cancelReadLoop: (error: any) => void;\n\n  // We assign positive numbers to imports we initiate, and negative numbers to exports we\n  // initiate. So the next import ID is just `imports.length`, but the next export ID needs\n  // to be tracked explicitly.\n  private nextExportId = -1;\n\n  // If set, call this when all incoming calls are complete.\n  private onBatchDone?: Omit<PromiseWithResolvers<void>, \"promise\">;\n\n  // How many promises is our peer expecting us to resolve?\n  private pullCount = 0;\n\n  // Sparse array of onBrokenCallback registrations. Items are strictly appended to the end but\n  // may be deleted from the middle (hence leaving the array sparse).\n  onBrokenCallbacks: ((error: any) => void)[] = [];\n\n  constructor(private transport: RpcTransport, mainHook: StubHook,\n      private options: RpcSessionOptions) {\n    // Export zero is automatically the bootstrap object.\n    this.exports.push({hook: mainHook, refcount: 1});\n\n    // Import zero is the other side's bootstrap object.\n    this.imports.push(new ImportTableEntry(this, 0, false));\n\n    let rejectFunc: (error: any) => void;;\n    let abortPromise = new Promise<never>((resolve, reject) => { rejectFunc = reject; });\n    this.cancelReadLoop = rejectFunc!;\n\n    this.readLoop(abortPromise).catch(err => this.abort(err));\n  }\n\n  // Should only be called once immediately after construction.\n  getMainImport(): RpcImportHook {\n    return new RpcMainHook(this.imports[0]);\n  }\n\n  shutdown(): void {\n    // TODO(someday): Should we add some sort of \"clean shutdown\" mechanism? This gets the job\n    //   done just fine for the moment.\n    this.abort(new Error(\"RPC session was shut down by disposing the main stub\"), false);\n  }\n\n  exportStub(hook: StubHook): ExportId {\n    if (this.abortReason) throw this.abortReason;\n\n    let existingExportId = this.reverseExports.get(hook);\n    if (existingExportId !== undefined) {\n      ++this.exports[existingExportId].refcount;\n      return existingExportId;\n    } else {\n      let exportId = this.nextExportId--;\n      this.exports[exportId] = { hook, refcount: 1 };\n      this.reverseExports.set(hook, exportId);\n      // TODO: Use onBroken().\n      return exportId;\n    }\n  }\n\n  exportPromise(hook: StubHook): ExportId {\n    if (this.abortReason) throw this.abortReason;\n\n    // Promises always use a new ID because otherwise the recipient could miss the resolution.\n    let exportId = this.nextExportId--;\n    this.exports[exportId] = { hook, refcount: 1 };\n    this.reverseExports.set(hook, exportId);\n\n    // Automatically start resolving any promises we send.\n    this.ensureResolvingExport(exportId);\n    return exportId;\n  }\n\n  unexport(ids: Array<ExportId>): void {\n    for (let id of ids) {\n      this.releaseExport(id, 1);\n    }\n  }\n\n  private releaseExport(exportId: ExportId, refcount: number) {\n    let entry = this.exports[exportId];\n    if (!entry) {\n      throw new Error(`no such export ID: ${exportId}`);\n    }\n    if (entry.refcount < refcount) {\n      throw new Error(`refcount would go negative: ${entry.refcount} < ${refcount}`);\n    }\n    entry.refcount -= refcount;\n    if (entry.refcount === 0) {\n      delete this.exports[exportId];\n      this.reverseExports.delete(entry.hook);\n      entry.hook.dispose();\n    }\n  }\n\n  onSendError(error: Error): Error | void {\n    if (this.options.onSendError) {\n      return this.options.onSendError(error);\n    }\n  }\n\n  private ensureResolvingExport(exportId: ExportId) {\n    let exp = this.exports[exportId];\n    if (!exp) {\n      throw new Error(`no such export ID: ${exportId}`);\n    }\n    if (!exp.pull) {\n      let resolve = async () => {\n        let hook = exp.hook;\n        for (;;) {\n          let payload = await hook.pull();\n          if (payload.value instanceof RpcStub) {\n            let {hook: inner, pathIfPromise} = unwrapStubAndPath(payload.value);\n            if (pathIfPromise && pathIfPromise.length == 0) {\n              if (this.getImport(hook) === undefined) {\n                // Optimization: The resolution is just another promise, and it is not a promise\n                // pointing back to the peer. So if we send a resolve message, it's just going to\n                // resolve to another new promise export, which is just going to have to wait for\n                // another resolve message later. This intermediate resolve message gives the peer\n                // no useful information, so let's skip it and just wait for the chained\n                // resolution.\n                hook = inner;\n                continue;\n              }\n            }\n          }\n\n          return payload;\n        }\n      };\n\n      let autoRelease = exp.autoRelease;\n\n      ++this.pullCount;\n      exp.pull = resolve().then(\n        payload => {\n          // We don't transfer ownership of stubs in the payload since the payload\n          // belongs to the hook which sticks around to handle pipelined requests.\n          let value = Devaluator.devaluate(payload.value, undefined, this, payload);\n          this.send([\"resolve\", exportId, value]);\n          if (autoRelease) this.releaseExport(exportId, 1);\n        },\n        error => {\n          this.send([\"reject\", exportId, Devaluator.devaluate(error, undefined, this)]);\n          if (autoRelease) this.releaseExport(exportId, 1);\n        }\n      ).catch(\n        error => {\n          // If serialization failed, report the serialization error, which should\n          // itself always be serializable.\n          try {\n            this.send([\"reject\", exportId, Devaluator.devaluate(error, undefined, this)]);\n            if (autoRelease) this.releaseExport(exportId, 1);\n          } catch (error2) {\n            // TODO: Shouldn't happen, now what?\n            this.abort(error2);\n          }\n        }\n      ).finally(() => {\n        if (--this.pullCount === 0) {\n          if (this.onBatchDone) {\n            this.onBatchDone.resolve();\n          }\n        }\n      });\n    }\n  }\n\n  getImport(hook: StubHook): ImportId | undefined {\n    if (hook instanceof RpcImportHook && hook.entry && hook.entry.session === this) {\n      return hook.entry.importId;\n    } else {\n      return undefined;\n    }\n  }\n\n  importStub(idx: ImportId): RpcImportHook {\n    if (this.abortReason) throw this.abortReason;\n\n    let entry = this.imports[idx];\n    if (!entry) {\n      entry = new ImportTableEntry(this, idx, false);\n      this.imports[idx] = entry;\n    }\n    return new RpcImportHook(/*isPromise=*/false, entry);\n  }\n\n  importPromise(idx: ImportId): StubHook {\n    if (this.abortReason) throw this.abortReason;\n\n    if (this.imports[idx]) {\n      // Can't reuse an existing ID for a promise!\n      return new ErrorStubHook(new Error(\n          \"Bug in RPC system: The peer sent a promise reusing an existing export ID.\"));\n    }\n\n    // Create an already-pulling hook.\n    let entry = new ImportTableEntry(this, idx, true);\n    this.imports[idx] = entry;\n    return new RpcImportHook(/*isPromise=*/true, entry);\n  }\n\n  getExport(idx: ExportId): StubHook | undefined {\n    return this.exports[idx]?.hook;\n  }\n\n  getPipeReadable(exportId: ExportId): ReadableStream {\n    let entry = this.exports[exportId];\n    if (!entry || !entry.pipeReadable) {\n      throw new Error(`Export ${exportId} is not a pipe or its readable end was already consumed.`);\n    }\n    let readable = entry.pipeReadable;\n    entry.pipeReadable = undefined;\n    return readable;\n  }\n\n  createPipe(readable: ReadableStream, readableHook: StubHook): ImportId {\n    if (this.abortReason) throw this.abortReason;\n\n    this.send([\"pipe\"]);\n\n    let importId = this.imports.length;\n    // The pipe import is not a promise -- it's immediately usable as a writable stream.\n    let entry = new ImportTableEntry(this, importId, false);\n    this.imports.push(entry);\n\n    // Create a proxy WritableStream from the import hook and pump the ReadableStream into it.\n    let hook = new RpcImportHook(/*isPromise=*/false, entry);\n    let writable = streamImpl.createWritableStreamFromHook(hook);\n    readable.pipeTo(writable).catch(() => {\n      // Errors are handled by the writable stream's error handling -- either the write fails\n      // and the writable side reports it, or the readable side errors and pipeTo aborts the\n      // writable side. Either way, the hook's disposal will handle cleanup.\n    }).finally(() => readableHook.dispose());\n\n    return importId;\n  }\n\n  // Serializes and sends a message. Returns the byte length of the serialized message.\n  private send(msg: any): number {\n    if (this.abortReason !== undefined) {\n      // Ignore sends after we've aborted.\n      return 0;\n    }\n\n    let msgText: string;\n    try {\n      msgText = JSON.stringify(msg);\n    } catch (err) {\n      // If JSON stringification failed, there's something wrong with the devaluator, as it should\n      // not allow non-JSONable values to be injected in the first place.\n      try { this.abort(err); } catch (err2) {}\n      throw err;\n    }\n\n    this.transport.send(msgText)\n        // If send fails, abort the connection, but don't try to send an abort message since\n        // that'll probably also fail.\n        .catch(err => this.abort(err, false));\n\n    return msgText.length;\n  }\n\n  sendCall(id: ImportId, path: PropertyPath, args?: RpcPayload): RpcImportHook {\n    if (this.abortReason) throw this.abortReason;\n\n    let value: Array<any> = [\"pipeline\", id, path];\n    if (args) {\n      let devalue = Devaluator.devaluate(args.value, undefined, this, args);\n\n      // HACK: Since the args is an array, devaluator will wrap in a second array. Need to unwrap.\n      // TODO: Clean this up somehow.\n      value.push((<Array<unknown>>devalue)[0]);\n\n      // Serializing the payload takes ownership of all stubs within, so the payload itself does\n      // not need to be disposed.\n    }\n    this.send([\"push\", value]);\n\n    let entry = new ImportTableEntry(this, this.imports.length, false);\n    this.imports.push(entry);\n    return new RpcImportHook(/*isPromise=*/true, entry);\n  }\n\n  sendStream(id: ImportId, path: PropertyPath, args: RpcPayload)\n      : {promise: Promise<void>, size: number} {\n    if (this.abortReason) throw this.abortReason;\n\n    let value: Array<any> = [\"pipeline\", id, path];\n    let devalue = Devaluator.devaluate(args.value, undefined, this, args);\n\n    // HACK: Since the args is an array, devaluator will wrap in a second array. Need to unwrap.\n    // TODO: Clean this up somehow.\n    value.push((<Array<unknown>>devalue)[0]);\n\n    let size = this.send([\"stream\", value]);\n\n    // Create the import entry in \"already pulling\" state (pulling=true), since stream messages\n    // are automatically pulled. Set remoteRefcount to 0 so that resolve() won't send a release\n    // message — the server implicitly releases the export after sending the resolve. Set\n    // localRefcount to 1 so that resolve() doesn't treat this as already-disposed.\n    let importId = this.imports.length;\n    let entry = new ImportTableEntry(this, importId, /*pulling=*/true);\n    entry.remoteRefcount = 0;\n    entry.localRefcount = 1;\n    this.imports.push(entry);\n\n    // Await the resolution, then dispose the result payload and clean up the import table entry.\n    // (Normally, sendRelease() cleans up the import table, but since remoteRefcount is 0, we\n    // need to do it manually.)\n    let promise = entry.awaitResolution().then(\n      p => { p.dispose(); delete this.imports[importId]; },\n      err => { delete this.imports[importId]; throw err; }\n    );\n\n    return { promise, size };\n  }\n\n  sendMap(id: ImportId, path: PropertyPath, captures: StubHook[], instructions: unknown[])\n      : RpcImportHook {\n    if (this.abortReason) {\n      for (let cap of captures) {\n        cap.dispose();\n      }\n      throw this.abortReason;\n    }\n\n    let devaluedCaptures = captures.map(hook => {\n      let importId = this.getImport(hook);\n      if (importId !== undefined) {\n        return [\"import\", importId];\n      } else {\n        return [\"export\", this.exportStub(hook)];\n      }\n    });\n\n    let value = [\"remap\", id, path, devaluedCaptures, instructions];\n\n    this.send([\"push\", value]);\n\n    let entry = new ImportTableEntry(this, this.imports.length, false);\n    this.imports.push(entry);\n    return new RpcImportHook(/*isPromise=*/true, entry);\n  }\n\n  sendPull(id: ImportId) {\n    if (this.abortReason) throw this.abortReason;\n\n    this.send([\"pull\", id]);\n  }\n\n  sendRelease(id: ImportId, remoteRefcount: number) {\n    if (this.abortReason) return;\n\n    this.send([\"release\", id, remoteRefcount]);\n    delete this.imports[id];\n  }\n\n  abort(error: any, trySendAbortMessage: boolean = true) {\n    // Don't double-abort.\n    if (this.abortReason !== undefined) return;\n\n    this.cancelReadLoop(error);\n\n    if (trySendAbortMessage) {\n      try {\n        this.transport.send(JSON.stringify([\"abort\", Devaluator\n            .devaluate(error, undefined, this)]))\n            .catch(err => {});\n      } catch (err) {\n        // ignore, probably the whole reason we're aborting is because the transport is broken\n      }\n    }\n\n    if (error === undefined) {\n      // Shouldn't happen, but if it does, avoid setting `abortReason` to `undefined`.\n      error = \"undefined\";\n    }\n\n    this.abortReason = error;\n    if (this.onBatchDone) {\n      this.onBatchDone.reject(error);\n    }\n\n    if (this.transport.abort) {\n      // Call transport's abort handler, but guard against buggy app code.\n      try {\n        this.transport.abort(error);\n      } catch (err) {\n        // Treat as unhandled rejection.\n        Promise.resolve(err);\n      }\n    }\n\n    // WATCH OUT: these are sparse arrays. `for/let/of` will iterate only positive indexes\n    // including deleted indexes -- bad. We need to use `for/let/in` instead.\n    for (let i in this.onBrokenCallbacks) {\n      try {\n        this.onBrokenCallbacks[i](error);\n      } catch (err) {\n        // Treat as unhandled rejection.\n        Promise.resolve(err);\n      }\n    }\n    for (let i in this.imports) {\n      this.imports[i].abort(error);\n    }\n    for (let i in this.exports) {\n      this.exports[i].hook.dispose();\n    }\n  }\n\n  private async readLoop(abortPromise: Promise<never>) {\n    while (!this.abortReason) {\n      let msg = JSON.parse(await Promise.race([this.transport.receive(), abortPromise]));\n      if (this.abortReason) break;  // check again before processing\n\n      if (msg instanceof Array) {\n        switch (msg[0]) {\n          case \"push\":  // [\"push\", Expression]\n            if (msg.length > 1) {\n              let payload = new Evaluator(this).evaluate(msg[1]);\n              let hook = new PayloadStubHook(payload);\n\n              // It's possible for a rejection to occur before the client gets a chance to send\n              // a \"pull\" message or to use the promise in a pipeline. We don't want that to be\n              // treated as an unhandled rejection on our end.\n              hook.ignoreUnhandledRejections();\n\n              this.exports.push({ hook, refcount: 1 });\n              continue;\n            }\n            break;\n\n          case \"stream\": {  // [\"stream\", Expression]\n            // Like \"push\", but:\n            // - Promise pipelining on the result is not supported.\n            // - The export is automatically considered \"pulled\".\n            // - Once the \"resolve\" is sent, the export is implicitly released.\n            if (msg.length > 1) {\n              let payload = new Evaluator(this).evaluate(msg[1]);\n              let hook = new PayloadStubHook(payload);\n              hook.ignoreUnhandledRejections();\n\n              let exportId = this.exports.length;\n              this.exports.push({ hook, refcount: 1, autoRelease: true });\n\n              // Automatically pull since stream messages are always pulled.\n              this.ensureResolvingExport(exportId);\n              continue;\n            }\n            break;\n          }\n\n          case \"pipe\": {  // [\"pipe\"]\n            // Create a TransformStream. The writable end becomes the export (so the sender can\n            // write/close/abort it). The readable end is stashed for later retrieval via\n            // [\"readable\", importId].\n            let { readable, writable } = new TransformStream();\n            let hook = streamImpl.createWritableStreamHook(writable);\n            this.exports.push({ hook, refcount: 1, pipeReadable: readable });\n            continue;\n          }\n\n          case \"pull\": {  // [\"pull\", ImportId]\n            let exportId = msg[1];\n            if (typeof exportId == \"number\") {\n              this.ensureResolvingExport(exportId);\n              continue;\n            }\n            break;\n          }\n\n          case \"resolve\":   // [\"resolve\", ExportId, Expression]\n          case \"reject\": {  // [\"reject\", ExportId, Expression]\n            let importId = msg[1];\n            if (typeof importId == \"number\" && msg.length > 2) {\n              let imp = this.imports[importId];\n              if (imp) {\n                if (msg[0] == \"resolve\") {\n                  imp.resolve(new PayloadStubHook(new Evaluator(this).evaluate(msg[2])));\n                } else {\n                  // HACK: We expect errors are always simple values (no stubs) so we can just\n                  //   pull the value out of the payload.\n                  let payload = new Evaluator(this).evaluate(msg[2]);\n                  payload.dispose();  // just in case -- should be no-op\n                  imp.resolve(new ErrorStubHook(payload.value));\n                }\n              } else {\n                // Import ID is not found on the table. Probably we released it already, in which\n                // case we do not care about the resolution, so whatever.\n\n                if (msg[0] == \"resolve\") {\n                  // We need to evaluate the resolution and immediately dispose it so that we\n                  // release any stubs it contains.\n                  new Evaluator(this).evaluate(msg[2]).dispose();\n                }\n              }\n              continue;\n            }\n            break;\n          }\n\n          case \"release\": {\n            let exportId = msg[1];\n            let refcount = msg[2];\n            if (typeof exportId == \"number\" && typeof refcount == \"number\") {\n              this.releaseExport(exportId, refcount);\n              continue;\n            }\n            break;\n          }\n\n          case \"abort\": {\n            let payload = new Evaluator(this).evaluate(msg[1]);\n            payload.dispose();  // just in case -- should be no-op\n            this.abort(payload, false);\n            break;\n          }\n        }\n      }\n\n      throw new Error(`bad RPC message: ${JSON.stringify(msg)}`);\n    }\n  }\n\n  async drain(): Promise<void> {\n    if (this.abortReason) {\n      throw this.abortReason;\n    }\n\n    if (this.pullCount > 0) {\n      let {promise, resolve, reject} = Promise.withResolvers<void>();\n      this.onBatchDone = {resolve, reject};\n      await promise;\n    }\n  }\n\n  getStats(): {imports: number, exports: number} {\n    let result = {imports: 0, exports: 0};\n    // We can't just use `.length` because the arrays can be sparse and can have negative indexes.\n    for (let i in this.imports) {\n      ++result.imports;\n    }\n    for (let i in this.exports) {\n      ++result.exports;\n    }\n    return result;\n  }\n}\n\n// Public interface that wraps RpcSession and hides private implementation details (even from\n// JavaScript with no type enforcement).\nexport class RpcSession {\n  #session: RpcSessionImpl;\n  #mainStub: RpcStub;\n\n  constructor(transport: RpcTransport, localMain?: any, options: RpcSessionOptions = {}) {\n    let mainHook: StubHook;\n    if (localMain) {\n      mainHook = new PayloadStubHook(RpcPayload.fromAppReturn(localMain));\n    } else {\n      mainHook = new ErrorStubHook(new Error(\"This connection has no main object.\"));\n    }\n    this.#session = new RpcSessionImpl(transport, mainHook, options);\n    this.#mainStub = new RpcStub(this.#session.getMainImport());\n  }\n\n  getRemoteMain(): RpcStub {\n    return this.#mainStub;\n  }\n\n  getStats(): {imports: number, exports: number} {\n    return this.#session.getStats();\n  }\n\n  drain(): Promise<void> {\n    return this.#session.drain();\n  }\n}\n", "// Copyright (c) 2025 Cloudflare, Inc.\n// Licensed under the MIT license found in the LICENSE.txt file or at:\n//     https://opensource.org/license/mit\n\n/// <reference types=\"@cloudflare/workers-types\" />\n\nimport { RpcStub } from \"./core.js\";\nimport { RpcTransport, RpcSession, RpcSessionOptions } from \"./rpc.js\";\n\nexport function newWebSocketRpcSession(\n    webSocket: WebSocket | string, localMain?: any, options?: RpcSessionOptions): RpcStub {\n  if (typeof webSocket === \"string\") {\n    webSocket = new WebSocket(webSocket);\n  }\n\n  let transport = new WebSocketTransport(webSocket);\n  let rpc = new RpcSession(transport, localMain, options);\n  return rpc.getRemoteMain();\n}\n\n/**\n * For use in Cloudflare Workers: Construct an HTTP response that starts a WebSocket RPC session\n * with the given `localMain`.\n */\nexport function newWorkersWebSocketRpcResponse(\n    request: Request, localMain?: any, options?: RpcSessionOptions): Response {\n  if (request.headers.get(\"Upgrade\")?.toLowerCase() !== \"websocket\") {\n    return new Response(\"This endpoint only accepts WebSocket requests.\", { status: 400 });\n  }\n\n  let pair = new WebSocketPair();\n  let server = pair[0];\n  server.accept()\n  newWebSocketRpcSession(server, localMain, options);\n  return new Response(null, {\n    status: 101,\n    webSocket: pair[1],\n  });\n}\n\nclass WebSocketTransport implements RpcTransport {\n  constructor (webSocket: WebSocket) {\n    this.#webSocket = webSocket;\n\n    if (webSocket.readyState === WebSocket.CONNECTING) {\n      this.#sendQueue = [];\n      webSocket.addEventListener(\"open\", event => {\n        try {\n          for (let message of this.#sendQueue!) {\n            webSocket.send(message);\n          }\n        } catch (err) {\n          this.#receivedError(err);\n        }\n        this.#sendQueue = undefined;\n      });\n    }\n\n    webSocket.addEventListener(\"message\", (event: MessageEvent<any>) => {\n      if (this.#error) {\n        // Ignore further messages.\n      } else if (typeof event.data === \"string\") {\n        if (this.#receiveResolver) {\n          this.#receiveResolver(event.data);\n          this.#receiveResolver = undefined;\n          this.#receiveRejecter = undefined;\n        } else {\n          this.#receiveQueue.push(event.data);\n        }\n      } else {\n        this.#receivedError(new TypeError(\"Received non-string message from WebSocket.\"));\n      }\n    });\n\n    webSocket.addEventListener(\"close\", (event: CloseEvent) => {\n      this.#receivedError(new Error(`Peer closed WebSocket: ${event.code} ${event.reason}`));\n    });\n\n    webSocket.addEventListener(\"error\", (event: Event) => {\n      this.#receivedError(new Error(`WebSocket connection failed.`));\n    });\n  }\n\n  #webSocket: WebSocket;\n  #sendQueue?: string[];  // only if not opened yet\n  #receiveResolver?: (message: string) => void;\n  #receiveRejecter?: (err: any) => void;\n  #receiveQueue: string[] = [];\n  #error?: any;\n\n  async send(message: string): Promise<void> {\n    if (this.#sendQueue === undefined) {\n      this.#webSocket.send(message);\n    } else {\n      // Not open yet, queue for later.\n      this.#sendQueue.push(message);\n    }\n  }\n\n  async receive(): Promise<string> {\n    if (this.#receiveQueue.length > 0) {\n      return this.#receiveQueue.shift()!;\n    } else if (this.#error) {\n      throw this.#error;\n    } else {\n      return new Promise<string>((resolve, reject) => {\n        this.#receiveResolver = resolve;\n        this.#receiveRejecter = reject;\n      });\n    }\n  }\n\n  abort?(reason: any): void {\n    let message: string;\n    if (reason instanceof Error) {\n      message = reason.message;\n    } else {\n      message = `${reason}`;\n    }\n    this.#webSocket.close(3000, message);\n\n    if (!this.#error) {\n      this.#error = reason;\n      // No need to call receiveRejecter(); RPC implementation will stop listening anyway.\n    }\n  }\n\n  #receivedError(reason: any) {\n    if (!this.#error) {\n      this.#error = reason;\n      if (this.#receiveRejecter) {\n        this.#receiveRejecter(reason);\n        this.#receiveResolver = undefined;\n        this.#receiveRejecter = undefined;\n      }\n    }\n  }\n}\n", "// Copyright (c) 2025 Cloudflare, Inc.\n// Licensed under the MIT license found in the LICENSE.txt file or at:\n//     https://opensource.org/license/mit\n\nimport { RpcStub } from \"./core.js\";\nimport { RpcTransport, RpcSession, RpcSessionOptions } from \"./rpc.js\";\nimport type { IncomingMessage, ServerResponse, OutgoingHttpHeader, OutgoingHttpHeaders } from \"node:http\";\n\ntype SendBatchFunc = (batch: string[]) => Promise<string[]>;\n\nclass BatchClientTransport implements RpcTransport {\n  constructor(sendBatch: SendBatchFunc) {\n    this.#promise = this.#scheduleBatch(sendBatch);\n  }\n\n  #promise: Promise<void>;\n  #aborted: any;\n\n  #batchToSend: string[] | null = [];\n  #batchToReceive: string[] | null = null;\n\n  async send(message: string): Promise<void> {\n    // If the batch was already sent, we just ignore the message, because throwing may cause the\n    // RPC system to abort prematurely. Once the last receive() is done then we'll throw an error\n    // that aborts the RPC system at the right time and will propagate to all other requests.\n    if (this.#batchToSend !== null) {\n      this.#batchToSend.push(message);\n    }\n  }\n\n  async receive(): Promise<string> {\n    if (!this.#batchToReceive) {\n      await this.#promise;\n    }\n\n    let msg = this.#batchToReceive!.shift();\n    if (msg !== undefined) {\n      return msg;\n    } else {\n      // No more messages. An error thrown here will propagate out of any calls that are still\n      // open.\n      throw new Error(\"Batch RPC request ended.\");\n    }\n  }\n\n  abort?(reason: any): void {\n    this.#aborted = reason;\n  }\n\n  async #scheduleBatch(sendBatch: SendBatchFunc) {\n    // Wait for microtask queue to clear before sending a batch.\n    //\n    // Note that simply waiting for one turn of the microtask queue (await Promise.resolve()) is\n    // not good enough here as the application needs a chance to call `.then()` on every RPC\n    // promise in order to explicitly indicate they want the results. Unfortunately, `await`ing\n    // a thenable does not call `.then()` immediately -- for some reason it waits for a turn of\n    // the microtask queue first, *then* calls `.then()`.\n    await new Promise(resolve => setTimeout(resolve, 0));\n\n    if (this.#aborted !== undefined) {\n      throw this.#aborted;\n    }\n\n    let batch = this.#batchToSend!;\n    this.#batchToSend = null;\n    this.#batchToReceive = await sendBatch(batch);\n  }\n}\n\nexport function newHttpBatchRpcSession(\n    urlOrRequest: string | Request, options?: RpcSessionOptions): RpcStub {\n  let sendBatch: SendBatchFunc = async (batch: string[]) => {\n    let response = await fetch(urlOrRequest, {\n      method: \"POST\",\n      body: batch.join(\"\\n\"),\n    });\n\n    if (!response.ok) {\n      response.body?.cancel();\n      throw new Error(`RPC request failed: ${response.status} ${response.statusText}`);\n    }\n\n    let body = await response.text();\n    return body == \"\" ? [] : body.split(\"\\n\");\n  };\n\n  let transport = new BatchClientTransport(sendBatch);\n  let rpc = new RpcSession(transport, undefined, options);\n  return rpc.getRemoteMain();\n}\n\nclass BatchServerTransport implements RpcTransport {\n  constructor(batch: string[]) {\n    this.#batchToReceive = batch;\n  }\n\n  #batchToSend: string[] = [];\n  #batchToReceive: string[];\n  #allReceived: PromiseWithResolvers<void> = Promise.withResolvers<void>();\n\n  async send(message: string): Promise<void> {\n    this.#batchToSend.push(message);\n  }\n\n  async receive(): Promise<string> {\n    let msg = this.#batchToReceive!.shift();\n    if (msg !== undefined) {\n      return msg;\n    } else {\n      // No more messages.\n      this.#allReceived.resolve();\n      return new Promise(r => {});\n    }\n  }\n\n  abort?(reason: any): void {\n    this.#allReceived.reject(reason);\n  }\n\n  whenAllReceived() {\n    return this.#allReceived.promise;\n  }\n\n  getResponseBody(): string {\n    return this.#batchToSend.join(\"\\n\");\n  }\n}\n\n/**\n * Implements the server end of an HTTP batch session, using standard Fetch API types to represent\n * HTTP requests and responses.\n *\n * @param request The request received from the client initiating the session.\n * @param localMain The main stub or RpcTarget which the server wishes to expose to the client.\n * @param options Optional RPC session options.\n * @returns The HTTP response to return to the client. Note that the returned object has mutable\n *     headers, so you can modify them using e.g. `response.headers.set(\"Foo\", \"bar\")`.\n */\nexport async function newHttpBatchRpcResponse(\n    request: Request, localMain: any, options?: RpcSessionOptions): Promise<Response> {\n  if (request.method !== \"POST\") {\n    return new Response(\"This endpoint only accepts POST requests.\", { status: 405 });\n  }\n\n  let body = await request.text();\n  let batch = body === \"\" ? [] : body.split(\"\\n\");\n\n  let transport = new BatchServerTransport(batch);\n  let rpc = new RpcSession(transport, localMain, options);\n\n  // TODO: Arguably we should arrange so any attempts to pull promise resolutions from the client\n  //   will reject rather than just hang. But it IS valid to make server->client calls in order to\n  //   then pipeline the result into something returned to the client. We don't want the errors to\n  //   prematurely cancel anything that would eventually complete. So for now we just say, it's the\n  //   app's responsibility to not wait on any server -> client calls since they will never\n  //   complete.\n\n  await transport.whenAllReceived();\n  await rpc.drain();\n\n  // TODO: Ask RpcSession to dispose everything it is still holding on to?\n\n  return new Response(transport.getResponseBody());\n}\n\n/**\n * Implements the server end of an HTTP batch session using traditional Node.js HTTP APIs.\n *\n * @param request The request received from the client initiating the session.\n * @param response The response object, to which the response should be written.\n * @param localMain The main stub or RpcTarget which the server wishes to expose to the client.\n * @param options Optional RPC session options. You can also pass headers to set on the response.\n */\nexport async function nodeHttpBatchRpcResponse(\n    request: IncomingMessage, response: ServerResponse,\n    localMain: any,\n    options?: RpcSessionOptions & {\n      headers?: OutgoingHttpHeaders | OutgoingHttpHeader[],\n    }): Promise<void> {\n  if (request.method !== \"POST\") {\n    response.writeHead(405, \"This endpoint only accepts POST requests.\");\n  }\n\n  let body = await new Promise<string>((resolve, reject) => {\n    let chunks: Buffer[] = [];\n    request.on(\"data\", chunk => {\n      chunks.push(chunk);\n    });\n    request.on(\"end\", () => {\n      resolve(Buffer.concat(chunks).toString());\n    });\n    request.on(\"error\", reject);\n  });\n  let batch = body === \"\" ? [] : body.split(\"\\n\");\n\n  let transport = new BatchServerTransport(batch);\n  let rpc = new RpcSession(transport, localMain, options);\n\n  await transport.whenAllReceived();\n  await rpc.drain();\n\n  response.writeHead(200, options?.headers);\n  response.end(transport.getResponseBody());\n}\n", "// Copyright (c) 2025 Cloudflare, Inc.\n// Licensed under the MIT license found in the LICENSE.txt file or at:\n//     https://opensource.org/license/mit\n\nimport { RpcStub } from \"./core.js\";\nimport { RpcTransport, RpcSession, RpcSessionOptions } from \"./rpc.js\";\n\n// Start a MessagePort session given a MessagePort or a pair of MessagePorts.\n//\n// `localMain` is the main RPC interface to expose to the peer. Returns a stub for the main\n// interface exposed from the peer.\nexport function newMessagePortRpcSession(\n    port: MessagePort, localMain?: any, options?: RpcSessionOptions): RpcStub {\n  let transport = new MessagePortTransport(port);\n  let rpc = new RpcSession(transport, localMain, options);\n  return rpc.getRemoteMain();\n}\n\nclass MessagePortTransport implements RpcTransport {\n  constructor (port: MessagePort) {\n    this.#port = port;\n\n    // Start listening for messages\n    port.start();\n\n    port.addEventListener(\"message\", (event: MessageEvent<any>) => {\n      if (this.#error) {\n        // Ignore further messages.\n      } else if (event.data === null) {\n        // Peer is signaling that they're closing the connection\n        this.#receivedError(new Error(\"Peer closed MessagePort connection.\"));\n      } else if (typeof event.data === \"string\") {\n        if (this.#receiveResolver) {\n          this.#receiveResolver(event.data);\n          this.#receiveResolver = undefined;\n          this.#receiveRejecter = undefined;\n        } else {\n          this.#receiveQueue.push(event.data);\n        }\n      } else {\n        this.#receivedError(new TypeError(\"Received non-string message from MessagePort.\"));\n      }\n    });\n\n    port.addEventListener(\"messageerror\", (event: MessageEvent) => {\n      this.#receivedError(new Error(\"MessagePort message error.\"));\n    });\n  }\n\n  #port: MessagePort;\n  #receiveResolver?: (message: string) => void;\n  #receiveRejecter?: (err: any) => void;\n  #receiveQueue: string[] = [];\n  #error?: any;\n\n  async send(message: string): Promise<void> {\n    if (this.#error) {\n      throw this.#error;\n    }\n    this.#port.postMessage(message);\n  }\n\n  async receive(): Promise<string> {\n    if (this.#receiveQueue.length > 0) {\n      return this.#receiveQueue.shift()!;\n    } else if (this.#error) {\n      throw this.#error;\n    } else {\n      return new Promise<string>((resolve, reject) => {\n        this.#receiveResolver = resolve;\n        this.#receiveRejecter = reject;\n      });\n    }\n  }\n\n  abort?(reason: any): void {\n    // Send close signal to peer before closing\n    try {\n      this.#port.postMessage(null);\n    } catch (err) {\n      // Ignore errors when sending close signal - port might already be closed\n    }\n\n    this.#port.close();\n\n    if (!this.#error) {\n      this.#error = reason;\n      // No need to call receiveRejecter(); RPC implementation will stop listening anyway.\n    }\n  }\n\n  #receivedError(reason: any) {\n    if (!this.#error) {\n      this.#error = reason;\n      if (this.#receiveRejecter) {\n        this.#receiveRejecter(reason);\n        this.#receiveResolver = undefined;\n        this.#receiveRejecter = undefined;\n      }\n    }\n  }\n}", "// Copyright (c) 2025 Cloudflare, Inc.\n// Licensed under the MIT license found in the LICENSE.txt file or at:\n//     https://opensource.org/license/mit\n\nimport { StubHook, PropertyPath, RpcPayload, RpcStub, RpcPromise, withCallInterceptor, ErrorStubHook, mapImpl, PayloadStubHook, unwrapStubAndPath, unwrapStubNoProperties } from \"./core.js\";\nimport { Devaluator, Exporter, Importer, ExportId, ImportId, Evaluator } from \"./serialize.js\";\n\nlet currentMapBuilder: MapBuilder | undefined;\n\n// We use this type signature when building the instructions for type checking purposes. It\n// describes a subset of the overall RPC protocol.\nexport type MapInstruction =\n    | [\"pipeline\", number, PropertyPath]\n    | [\"pipeline\", number, PropertyPath, unknown]\n    | [\"remap\", number, PropertyPath, [\"import\", number][], MapInstruction[]]\n\nclass MapBuilder implements Exporter {\n  private context:\n    | {parent: undefined, captures: StubHook[], subject: StubHook, path: PropertyPath}\n    | {parent: MapBuilder, captures: number[], subject: number, path: PropertyPath};\n  private captureMap: Map<StubHook, number> = new Map();\n\n  private instructions: MapInstruction[] = [];\n\n  constructor(subject: StubHook, path: PropertyPath) {\n    if (currentMapBuilder) {\n      this.context = {\n        parent: currentMapBuilder,\n        captures: [],\n        subject: currentMapBuilder.capture(subject),\n        path\n      };\n    } else {\n      this.context = {\n        parent: undefined,\n        captures: [],\n        subject,\n        path\n      };\n    }\n\n    currentMapBuilder = this;\n  }\n\n  unregister() {\n    currentMapBuilder = this.context.parent;\n  }\n\n  makeInput(): MapVariableHook {\n    return new MapVariableHook(this, 0);\n  }\n\n  makeOutput(result: RpcPayload): StubHook {\n    let devalued: unknown;\n    try {\n      devalued = Devaluator.devaluate(result.value, undefined, this, result);\n    } finally {\n      result.dispose();\n    }\n\n    // The result is the final instruction. This doesn't actually fit our MapInstruction type\n    // signature, so we cheat a bit.\n    this.instructions.push(<any>devalued);\n\n    if (this.context.parent) {\n      this.context.parent.instructions.push(\n        [\"remap\", this.context.subject, this.context.path,\n                  this.context.captures.map(cap => [\"import\", cap]),\n                  this.instructions]\n      );\n      return new MapVariableHook(this.context.parent, this.context.parent.instructions.length);\n    } else {\n      return this.context.subject.map(this.context.path, this.context.captures, this.instructions);\n    }\n  }\n\n  pushCall(hook: StubHook, path: PropertyPath, params: RpcPayload): StubHook {\n    let devalued = Devaluator.devaluate(params.value, undefined, this, params);\n    // HACK: Since the args is an array, devaluator will wrap in a second array. Need to unwrap.\n    // TODO: Clean this up somehow.\n    devalued = (<Array<unknown>>devalued)[0];\n\n    let subject = this.capture(hook.dup());\n    this.instructions.push([\"pipeline\", subject, path, devalued]);\n    return new MapVariableHook(this, this.instructions.length);\n  }\n\n  pushGet(hook: StubHook, path: PropertyPath): StubHook {\n    let subject = this.capture(hook.dup());\n    this.instructions.push([\"pipeline\", subject, path]);\n    return new MapVariableHook(this, this.instructions.length);\n  }\n\n  capture(hook: StubHook): number {\n    if (hook instanceof MapVariableHook && hook.mapper === this) {\n      // Oh, this is already our own hook.\n      return hook.idx;\n    }\n\n    // TODO: Well, the hooks passed in are always unique, so they'll never exist in captureMap.\n    //   I suppose this is a problem with RPC as well. We need a way to identify hooks that are\n    //   dupes of the same target.\n    let result = this.captureMap.get(hook);\n    if (result === undefined) {\n      if (this.context.parent) {\n        let parentIdx = this.context.parent.capture(hook);\n        this.context.captures.push(parentIdx);\n      } else {\n        this.context.captures.push(hook);\n      }\n      result = -this.context.captures.length;\n      this.captureMap.set(hook, result);\n    }\n    return result;\n  }\n\n  // ---------------------------------------------------------------------------\n  // implements Exporter\n\n  exportStub(hook: StubHook): ExportId {\n    // It appears someone did something like:\n    //\n    //     stub.map(x => { return x.doSomething(new MyRpcTarget()); })\n    //\n    // That... won't work. They need to do this instead:\n    //\n    //     using myTargetStub = new RpcStub(new MyRpcTarget());\n    //     stub.map(x => { return x.doSomething(myTargetStub.dup()); })\n    //\n    // TODO(someday): Consider carefully if the inline syntax is maybe OK. If so, perhaps the\n    //   serializer could try calling `getImport()` even for known-local hooks.\n    // TODO(someday): Do we need to support rpc-thenable somehow?\n    throw new Error(\n        \"Can't construct an RpcTarget or RPC callback inside a mapper function. Try creating a \" +\n        \"new RpcStub outside the callback first, then using it inside the callback.\");\n  }\n  exportPromise(hook: StubHook): ExportId {\n    return this.exportStub(hook);\n  }\n  getImport(hook: StubHook): ImportId | undefined {\n    return this.capture(hook);\n  }\n\n  unexport(ids: Array<ExportId>): void {\n    // Presumably this MapBuilder is cooked anyway, so we don't really have to release anything.\n  }\n\n  createPipe(readable: ReadableStream): never {\n    throw new Error(\"Cannot send ReadableStream inside a mapper function.\");\n  }\n\n  onSendError(error: Error): Error | void {\n    // TODO(someday): Can we use the error-sender hook from the RPC system somehow?\n  }\n};\n\nmapImpl.sendMap = (hook: StubHook, path: PropertyPath, func: (promise: RpcPromise) => unknown) => {\n  let builder = new MapBuilder(hook, path);\n  let result: RpcPayload;\n  try {\n    result = RpcPayload.fromAppReturn(withCallInterceptor(builder.pushCall.bind(builder), () => {\n      return func(new RpcPromise(builder.makeInput(), []));\n    }));\n  } finally {\n    builder.unregister();\n  }\n\n  // Detect misuse: Map callbacks cannot be async.\n  if (result instanceof Promise) {\n    // Squelch unhandled rejections from the map function itself -- it'll probably just throw\n    // something about pulling a MapVariableHook.\n    result.catch(err => {});\n\n    // Throw an understandable error.\n    throw new Error(\"RPC map() callbacks cannot be async.\");\n  }\n\n  return new RpcPromise(builder.makeOutput(result), []);\n}\n\nfunction throwMapperBuilderUseError(): never {\n  throw new Error(\n      \"Attempted to use an abstract placeholder from a mapper function. Please make sure your \" +\n      \"map function has no side effects.\");\n}\n\n// StubHook which represents a variable in a map function.\nclass MapVariableHook extends StubHook {\n  constructor(public mapper: MapBuilder, public idx: number) {\n    super();\n  }\n\n  // We don't have anything we actually need to dispose, so dup() can just return the same hook.\n  dup(): StubHook { return this; }\n  dispose(): void {}\n\n  get(path: PropertyPath): StubHook {\n    // This can actually be invoked as part of serialization, so we'll need to support it.\n    if (path.length == 0) {\n      // Since this hook cannot be pulled anyway, and dispose() is a no-op, we can actually just\n      // return the same hook again to represent getting the empty path.\n      return this;\n    } else if (currentMapBuilder) {\n      return currentMapBuilder.pushGet(this, path);\n    } else {\n      throwMapperBuilderUseError();\n    }\n  }\n\n  // Other methods should never be called.\n  call(path: PropertyPath, args: RpcPayload): StubHook {\n    // Can't be called; all calls are intercepted.\n    throwMapperBuilderUseError();\n  }\n\n  map(path: PropertyPath, captures: StubHook[], instructions: unknown[]): StubHook {\n    // Can't be called; all map()s are intercepted.\n    throwMapperBuilderUseError();\n  }\n\n  pull(): RpcPayload | Promise<RpcPayload> {\n    // Map functions cannot await.\n    throwMapperBuilderUseError();\n  }\n\n  ignoreUnhandledRejections(): void {\n    // Probably never called but whatever.\n  }\n\n  onBroken(callback: (error: any) => void): void {\n    throwMapperBuilderUseError();\n  }\n}\n\n// =======================================================================================\n\nclass MapApplicator implements Importer {\n  private variables: StubHook[];\n\n  constructor(private captures: StubHook[], input: StubHook) {\n    this.variables = [input];\n  }\n\n  dispose() {\n    for (let variable of this.variables) {\n      variable.dispose();\n    }\n  }\n\n  apply(instructions: unknown[]): RpcPayload {\n    try {\n      if (instructions.length < 1) {\n        throw new Error(\"Invalid empty mapper function.\");\n      }\n\n      for (let instruction of instructions.slice(0, -1)) {\n        let payload = new Evaluator(this).evaluateCopy(instruction);\n\n        // The payload almost always contains a single stub. As an optimization, unwrap it.\n        if (payload.value instanceof RpcStub) {\n          let hook = unwrapStubNoProperties(payload.value);\n          if (hook) {\n            this.variables.push(hook);\n            continue;\n          }\n        }\n\n        this.variables.push(new PayloadStubHook(payload));\n      }\n\n      return new Evaluator(this).evaluateCopy(instructions[instructions.length - 1]);\n    } finally {\n      for (let variable of this.variables) {\n        variable.dispose();\n      }\n    }\n  }\n\n  importStub(idx: ImportId): StubHook {\n    // This implies we saw an \"export\" appear inside the body of a mapper function. This should be\n    // impossible because exportStub()/exportPromise() throw exceptions in MapBuilder.\n    throw new Error(\"A mapper function cannot refer to exports.\");\n  }\n  importPromise(idx: ImportId): StubHook {\n    return this.importStub(idx);\n  }\n\n  getExport(idx: ExportId): StubHook | undefined {\n    if (idx < 0) {\n      return this.captures[-idx - 1];\n    } else {\n      return this.variables[idx];\n    }\n  }\n\n  getPipeReadable(exportId: ExportId): never {\n    throw new Error(\"A mapper function cannot use pipe readables.\");\n  }\n}\n\nfunction applyMapToElement(input: unknown, parent: object | undefined, owner: RpcPayload | null,\n                           captures: StubHook[], instructions: unknown[]): RpcPayload {\n  // TODO(perf): I wonder if we could use .fromAppParams() instead of .deepCopyFrom()? It\n  //   maybe wouldn't correctly handle the case of RpcTargets in the input, so we need a variant\n  //   which takes an `owner`, which does add some complexity.\n  let inputHook = new PayloadStubHook(RpcPayload.deepCopyFrom(input, parent, owner));\n  let mapper = new MapApplicator(captures, inputHook);\n  try {\n    return mapper.apply(instructions);\n  } finally {\n    mapper.dispose();\n  }\n}\n\nmapImpl.applyMap = (input: unknown, parent: object | undefined, owner: RpcPayload | null,\n                    captures: StubHook[], instructions: unknown[]) => {\n  try {\n    let result: RpcPayload;\n    if (input instanceof RpcPromise) {\n      // The caller is responsible for making sure the input is not a promise, since we can't\n      // then know if it would resolve to an array later.\n      throw new Error(\"applyMap() can't be called on RpcPromise\");\n    } else if (input instanceof Array) {\n      let payloads: RpcPayload[] = [];\n      try {\n        for (let elem of input) {\n          payloads.push(applyMapToElement(elem, input, owner, captures, instructions));\n        }\n      } catch (err) {\n        for (let payload of payloads) {\n          payload.dispose();\n        }\n        throw err;\n      }\n\n      result = RpcPayload.fromArray(payloads);\n    } else if (input === null || input === undefined) {\n      result = RpcPayload.fromAppReturn(input);\n    } else {\n      result = applyMapToElement(input, parent, owner, captures, instructions);\n    }\n\n    // TODO(perf): We should probably return a hook that allows pipelining but whose pull() doesn't\n    //   resolve until all promises in the payload have been substituted.\n    return new PayloadStubHook(result);\n  } finally {\n    for (let cap of captures) {\n      cap.dispose();\n    }\n  }\n}\n\nexport function forceInitMap() {}\n", "// Copyright (c) 2026 Cloudflare, Inc.\n// Licensed under the MIT license found in the LICENSE.txt file or at:\n//     https://opensource.org/license/mit\n\nimport {\n  StubHook, RpcPayload, PropertyPath, ErrorStubHook, PayloadStubHook, PromiseStubHook, streamImpl\n} from \"./core.js\";\n\n// =======================================================================================\n// WritableStreamStubHook - wraps a local WritableStream for export\n\n// Many WritableStreamStubHooks could point at the same WritableStream. We store a refcount in a\n// separate object that they all share.\ntype BoxedWriterState = {\n  refcount: number;\n  writer: WritableStreamDefaultWriter;\n  closed: boolean;\n};\n\nclass WritableStreamStubHook extends StubHook {\n  private state?: BoxedWriterState;  // undefined when disposed\n\n  // Creates a new WritableStreamStubHook that is not duplicated from an existing hook.\n  static create(stream: WritableStream): WritableStreamStubHook {\n    let writer = stream.getWriter();  // Locks the stream\n    return new WritableStreamStubHook({ refcount: 1, writer, closed: false });\n  }\n\n  private constructor(state: BoxedWriterState, dupFrom?: WritableStreamStubHook) {\n    super();\n    this.state = state;\n    if (dupFrom) {\n      ++state.refcount;\n    }\n  }\n\n  private getState(): BoxedWriterState {\n    if (this.state) {\n      return this.state;\n    } else {\n      throw new Error(\"Attempted to use a WritableStreamStubHook after it was disposed.\");\n    }\n  }\n\n  call(path: PropertyPath, args: RpcPayload): StubHook {\n    try {\n      let state = this.getState();\n\n      if (path.length !== 1 || typeof path[0] !== \"string\") {\n        throw new Error(\"WritableStream stub only supports direct method calls\");\n      }\n\n      const method = path[0];\n\n      if (method !== \"write\" && method !== \"close\" && method !== \"abort\") {\n        args.dispose();\n        throw new Error(`Unknown WritableStream method: ${method}`);\n      }\n\n      // Mark as closed if close() or abort() is called.\n      if (method === \"close\" || method === \"abort\") {\n        state.closed = true;\n      }\n\n      let func = state.writer[method] as Function;\n      let promise = args.deliverCall(func, state.writer);\n      return new PromiseStubHook(promise.then(payload => new PayloadStubHook(payload)));\n    } catch (err) {\n      return new ErrorStubHook(err);\n    }\n  }\n\n  map(path: PropertyPath, captures: StubHook[], instructions: unknown[]): StubHook {\n    // WritableStreams don't support map operations.\n    for (let cap of captures) {\n      cap.dispose();\n    }\n    return new ErrorStubHook(new Error(\"Cannot use map() on a WritableStream\"));\n  }\n\n  get(path: PropertyPath): StubHook {\n    // WritableStreams don't expose properties over RPC.\n    return new ErrorStubHook(new Error(\"Cannot access properties on a WritableStream stub\"));\n  }\n\n  dup(): StubHook {\n    let state = this.getState();\n    return new WritableStreamStubHook(state, this);\n  }\n\n  pull(): RpcPayload | Promise<RpcPayload> {\n    // WritableStreams can't be pulled - they're not promises.\n    return Promise.reject(new Error(\"Cannot pull a WritableStream stub\"));\n  }\n\n  ignoreUnhandledRejections(): void {\n    // Nothing to do.\n  }\n\n  dispose(): void {\n    let state = this.state;\n    this.state = undefined;\n    if (state) {\n      if (--state.refcount === 0) {\n        if (!state.closed) {\n          // Abort the stream if not cleanly closed.\n          state.writer.abort(new Error(\"WritableStream RPC stub was disposed without calling close()\"))\n              .catch(() => {});  // Ignore errors from abort.\n        }\n        state.writer.releaseLock();\n      }\n    }\n  }\n\n  onBroken(callback: (error: any) => void): void {\n    // WritableStream stubs don't really have a \"broken\" state in the same way.\n    // The caller would notice when write/close/abort fails.\n  }\n}\n\n// =======================================================================================\n// FlowController - BDP-based dynamic flow control for stream writes\n//\n// Estimates the bandwidth-delay product (BDP) of a stream by observing write sends and acks,\n// and dynamically adjusts the window size to match. The window is set to the estimated BDP\n// multiplied by a growth factor, so that the sender always pushes slightly more than the\n// estimated capacity — naturally probing for increased bandwidth.\n//\n// The algorithm works in two phases:\n// - Startup: The window is allowed to double each RTT (STARTUP_GROWTH_FACTOR = 2), enabling\n//   rapid discovery of available bandwidth. Startup ends when the window stops growing\n//   meaningfully for STARTUP_EXIT_ROUNDS consecutive RTT rounds.\n// - Steady state: The window grows by at most STEADY_GROWTH_FACTOR (1.25) per RTT and\n//   shrinks by at most DECAY_FACTOR (0.90) per RTT, providing stability.\n\n// Flow control constants — tunable.\n//\n// Initial window size in bytes. Used before we have any bandwidth estimate.\nconst INITIAL_WINDOW = 256 * 1024;\n// Maximum window size in bytes.\nconst MAX_WINDOW = 1024 * 1024 * 1024;\n// Minimum window size in bytes.\nconst MIN_WINDOW = 64 * 1024;\n// During startup, we allow the window to grow by up to this factor per RTT.\nconst STARTUP_GROWTH_FACTOR = 2;\n// In steady state, we allow the window to grow by up to this factor per RTT.\nconst STEADY_GROWTH_FACTOR = 1.25;\n// Allowed reduction in window size per RTT.\nconst DECAY_FACTOR = 0.90;\n// Number of consecutive non-increasing ack rounds before exiting startup.\nconst STARTUP_EXIT_ROUNDS = 3;\n\n// Opaque token returned by onSend() that must be passed back to onAck(). Carries the\n// send-time snapshot needed to compute delivery rate and apply the window collar.\nexport type SendToken = {\n  sentTime: number;\n  size: number;\n  deliveredAtSend: number;\n  deliveredTimeAtSend: number;\n  windowAtSend: number;\n  windowFullAtSend: boolean;\n};\n\n// Exported for testing purposes only -- otherwise this is only used internally by\n// createWritableStreamFromHook().\nexport class FlowController {\n  // The current window size in bytes. The sender blocks when bytesInFlight >= window.\n  window = INITIAL_WINDOW;\n\n  // Total bytes currently in flight (sent but not yet acked).\n  bytesInFlight = 0;\n\n  // Whether we're still in the startup phase.\n  inStartupPhase = true;\n\n  // ----- BDP estimation state (private) -----\n\n  // Total bytes acked so far.\n  private delivered = 0;\n  // Time of most recent ack.\n  private deliveredTime = 0;\n  // Time when the very first ack was received.\n  private firstAckTime = 0;\n  private firstAckDelivered = 0;\n  // Global minimum RTT observed (milliseconds).\n  private minRtt = Infinity;\n\n  // For startup exit: count of consecutive RTT rounds where the window didn't meaningfully grow.\n  private roundsWithoutIncrease = 0;\n  // Window size at the start of the current round, for startup exit detection.\n  private lastRoundWindow = 0;\n  // Time when the current round started.\n  private roundStartTime = 0;\n\n  constructor(private now: () => number) {}\n\n  // Called when a write of `size` bytes is about to be sent. Returns a token that must be\n  // passed to onAck() when the ack arrives, and whether the sender should block (window full).\n  onSend(size: number): { token: SendToken, shouldBlock: boolean } {\n    this.bytesInFlight += size;\n\n    let token: SendToken = {\n      sentTime: this.now(),\n      size,\n      deliveredAtSend: this.delivered,\n      deliveredTimeAtSend: this.deliveredTime,\n      windowAtSend: this.window,\n      windowFullAtSend: this.bytesInFlight >= this.window,\n    };\n\n    return { token, shouldBlock: token.windowFullAtSend };\n  }\n\n  // Called when a previously-sent write fails. Restores bytesInFlight without updating\n  // any BDP estimates.\n  onError(token: SendToken): void {\n    this.bytesInFlight -= token.size;\n  }\n\n  // Called when an ack is received for a previously-sent write. Updates BDP estimates and\n  // the window. Returns whether a blocked sender should now unblock.\n  onAck(token: SendToken): boolean {\n    let ackTime = this.now();\n\n    // Update delivery tracking metrics.\n    this.delivered += token.size;\n    this.deliveredTime = ackTime;\n    this.bytesInFlight -= token.size;\n\n    // Update RTT estimate.\n    let rtt = ackTime - token.sentTime;\n    this.minRtt = Math.min(this.minRtt, rtt);\n\n    // Update bandwidth estimate and window.\n    if (this.firstAckTime === 0) {\n      // This is the very first ack. We can't estimate bandwidth yet since we need to look\n      // at the interval between acks.\n      this.firstAckTime = ackTime;\n      this.firstAckDelivered = this.delivered;\n    } else {\n      let baseTime;\n      let baseDelivered;\n\n      if (token.deliveredTimeAtSend === 0) {\n        // This write was sent before any acks had been received, but wasn't the very first\n        // write. We can estimate bandwidth starting from the first ack.\n        baseTime = this.firstAckTime;\n        baseDelivered = this.firstAckDelivered;\n      } else {\n        baseTime = token.deliveredTimeAtSend;\n        baseDelivered = token.deliveredAtSend;\n      }\n\n      let interval = ackTime - baseTime;\n      let bytes = this.delivered - baseDelivered;\n      let bandwidth = bytes / interval;\n\n      // Choose our target growth factor depending on whether we're at startup or steady\n      // state.\n      let growthFactor = this.inStartupPhase ? STARTUP_GROWTH_FACTOR : STEADY_GROWTH_FACTOR;\n\n      // Calculate new window to be our calculated bandwidth-delay product, plus a growth\n      // factor to account for the possibility that bandwidth is constrained only due to\n      // the window having been too small.\n      let newWindow = bandwidth * this.minRtt * growthFactor;\n\n      // Don't allow the window to grow too quickly -- it can only grow by at most\n      // `growthFactor` for each RTT.\n      newWindow = Math.min(newWindow, token.windowAtSend * growthFactor);\n\n      if (token.windowFullAtSend) {\n        // Don't allow the window to shrink too quickly.\n        newWindow = Math.max(newWindow, token.windowAtSend * DECAY_FACTOR);\n      } else {\n        // Don't allow the window to shrink at all if we weren't saturating it -- in this\n        // case the sending app is not fully utilizing the connection, so no backpressure is\n        // needed. We clamp to this.window here, not this.windowAtSend, since we don't want to\n        // undo previous shrinkage, when alternating between sends that saturated and ones that\n        // didn't.\n        newWindow = Math.max(newWindow, this.window);\n      }\n\n      // Clamp to min/max values.\n      this.window = Math.max(Math.min(newWindow, MAX_WINDOW), MIN_WINDOW);\n\n      // Check if the startup phase is done.\n      if (this.inStartupPhase && token.sentTime >= this.roundStartTime) {\n        if (this.window > this.lastRoundWindow * STEADY_GROWTH_FACTOR) {\n          // Saw a significant increase this round, so reset the counter.\n          this.roundsWithoutIncrease = 0;\n        } else {\n          // Window size didn't increase enough this round.\n          if (++this.roundsWithoutIncrease >= STARTUP_EXIT_ROUNDS) {\n            // After three rounds with insufficient increase, exit startup mode.\n            this.inStartupPhase = false;\n          }\n        }\n\n        // Advance to next round.\n        this.roundStartTime = ackTime;\n        this.lastRoundWindow = this.window;\n      }\n    }\n\n    return this.bytesInFlight < this.window;\n  }\n}\n\n// =======================================================================================\n// createWritableStreamFromHook - creates a proxy WritableStream that forwards to a remote hook\n\nfunction createWritableStreamFromHook(hook: StubHook): WritableStream {\n  let pendingError: any = undefined;\n  let hookDisposed = false;\n\n  let fc = new FlowController(() => performance.now());\n\n  // If a previous write blocked waiting for the window to open, this resolver will unblock it.\n  let windowResolve: (() => void) | undefined;\n  let windowReject: ((e: unknown) => void) | undefined;\n\n  const disposeHook = () => {\n    if (!hookDisposed) {\n      hookDisposed = true;\n      hook.dispose();\n    }\n  };\n\n  return new WritableStream({\n    write(chunk, controller) {\n      // If we already have an error, fail immediately.\n      if (pendingError !== undefined) {\n        throw pendingError;\n      }\n\n      const payload = RpcPayload.fromAppParams([chunk]);\n      const { promise, size } = hook.stream([\"write\"], payload);\n\n      if (size === undefined) {\n        // Local call — await the promise directly to serialize writes (no overlapping).\n        // We still need to detect errors to set pendingError.\n        return promise.catch((err) => {\n          if (pendingError === undefined) {\n            pendingError = err;\n          }\n          throw err;\n        });\n      } else {\n        // Remote call — use window-based flow control.\n        let { token, shouldBlock } = fc.onSend(size);\n\n        // When the response comes back, update the window size based on BDP estimates.\n        promise.then(() => {\n          let hasCapacity = fc.onAck(token);\n\n          if (hasCapacity && windowResolve) {\n            windowResolve();\n            windowResolve = undefined;\n            windowReject = undefined;\n          }\n        }, (err) => {\n          fc.onError(token);\n          if (pendingError === undefined) {\n            pendingError = err;\n            controller.error(err);\n            disposeHook();\n          }\n          // Unblock any write waiting on backpressure -- reject it so the\n          // stream finishes erroring instead of hanging forever.\n          if (windowReject) {\n            windowReject(err);\n            windowResolve = undefined;\n            windowReject = undefined;\n          }\n        });\n\n        // If we've filled (or exceeded) the window, block until acks free up space.\n        if (shouldBlock) {\n          return new Promise<void>((resolve, reject) => {\n            windowResolve = resolve;\n            windowReject = reject;\n          });\n        }\n      }\n    },\n\n    async close() {\n      if (pendingError !== undefined) {\n        disposeHook();\n        throw pendingError;\n      }\n\n      // Send close(). Per the RPC protocol, if any previous write failed, close() will also\n      // fail with that error -- so there's no need to await pending writes first.\n      const { promise } = hook.stream([\"close\"], RpcPayload.fromAppParams([]));\n\n      try {\n        await promise;\n      } catch (err) {\n        // If a write error was detected (possibly while we were waiting for close()), prefer\n        // throwing that, since the close error is likely just a consequence (e.g. \"can't close\n        // errored stream\").\n        throw pendingError ?? err;\n      } finally {\n        disposeHook();\n      }\n    },\n\n    abort(reason) {\n      if (pendingError !== undefined) {\n        return;\n      }\n\n      pendingError = reason ?? new Error(\"WritableStream was aborted\");\n      if (windowReject) {\n        windowReject(pendingError);\n        windowResolve = undefined;\n        windowReject = undefined;\n      }\n\n      const { promise } = hook.stream([\"abort\"], RpcPayload.fromAppParams([reason]));\n      promise.then(() => disposeHook(), () => disposeHook());\n    }\n  });\n}\n\n// =======================================================================================\n// ReadableStreamStubHook - wraps a local ReadableStream for disposal tracking\n//\n// This hook exists solely to live in RpcPayload.hooks so that the ReadableStream is properly\n// disposed (canceled) when the payload is disposed. It does not handle any RPC operations --\n// the actual data transfer is handled by pumping the stream into a pipe's WritableStream via\n// pipeTo(). All methods other than dispose(), dup(), and ignoreUnhandledRejections() throw errors.\n\n// Many ReadableStreamStubHooks could point at the same ReadableStream. We store a refcount in a\n// separate object that they all share.\ntype BoxedReadableState = {\n  refcount: number;\n  stream: ReadableStream;\n  canceled: boolean;\n};\n\nclass ReadableStreamStubHook extends StubHook {\n  private state?: BoxedReadableState;  // undefined when disposed\n\n  // Creates a new ReadableStreamStubHook.\n  static create(stream: ReadableStream): ReadableStreamStubHook {\n    return new ReadableStreamStubHook({ refcount: 1, stream, canceled: false });\n  }\n\n  private constructor(state: BoxedReadableState, dupFrom?: ReadableStreamStubHook) {\n    super();\n    this.state = state;\n    if (dupFrom) {\n      ++state.refcount;\n    }\n  }\n\n  call(path: PropertyPath, args: RpcPayload): StubHook {\n    args.dispose();\n    return new ErrorStubHook(new Error(\"Cannot call methods on a ReadableStream stub\"));\n  }\n\n  map(path: PropertyPath, captures: StubHook[], instructions: unknown[]): StubHook {\n    for (let cap of captures) {\n      cap.dispose();\n    }\n    return new ErrorStubHook(new Error(\"Cannot use map() on a ReadableStream\"));\n  }\n\n  get(path: PropertyPath): StubHook {\n    return new ErrorStubHook(new Error(\"Cannot access properties on a ReadableStream stub\"));\n  }\n\n  dup(): StubHook {\n    let state = this.state;\n    if (!state) {\n      throw new Error(\"Attempted to dup a ReadableStreamStubHook after it was disposed.\");\n    }\n    return new ReadableStreamStubHook(state, this);\n  }\n\n  pull(): RpcPayload | Promise<RpcPayload> {\n    return Promise.reject(new Error(\"Cannot pull a ReadableStream stub\"));\n  }\n\n  ignoreUnhandledRejections(): void {\n    // Nothing to do.\n  }\n\n  dispose(): void {\n    let state = this.state;\n    this.state = undefined;\n    if (state) {\n      if (--state.refcount === 0) {\n        if (!state.canceled) {\n          state.canceled = true;\n\n          // Don't try to cancel the stream if it's locked. It won't work anyway -- it'll throw\n          // an exception, which we'd ignore anyway.\n          //\n          // This is a little janky but it makes some sense: If someone has locked the stream, they\n          // have taken responsibility for fully reading it. The only reason we really need to\n          // cancel when this hook is disposed is to handle the case where an application receives\n          // a ReadableStream but completely ignores it -- we want it to be canceled naturally when\n          // the payload is disposed.\n          if (!state.stream.locked) {\n            state.stream.cancel(\n                new Error(\"ReadableStream RPC stub was disposed without being consumed\"))\n                .catch(() => {});  // Ignore errors from cancel.\n          }\n        }\n      }\n    }\n  }\n\n  onBroken(callback: (error: any) => void): void {\n    // ReadableStream stubs don't have a \"broken\" state.\n  }\n}\n\n// =======================================================================================\n// Install the implementations into streamImpl\n\nstreamImpl.createWritableStreamHook = WritableStreamStubHook.create;\nstreamImpl.createWritableStreamFromHook = createWritableStreamFromHook;\nstreamImpl.createReadableStreamHook = ReadableStreamStubHook.create;\n\nexport function forceInitStreams() {}\n", "// Copyright (c) 2025 Cloudflare, Inc.\n// Licensed under the MIT license found in the LICENSE.txt file or at:\n//     https://opensource.org/license/mit\n\nimport { RpcTarget as RpcTargetImpl, RpcStub as RpcStubImpl, RpcPromise as RpcPromiseImpl } from \"./core.js\";\nimport { serialize, deserialize } from \"./serialize.js\";\nimport { RpcTransport, RpcSession as RpcSessionImpl, RpcSessionOptions } from \"./rpc.js\";\nimport { RpcTargetBranded, RpcCompatible, Stub, Stubify, __RPC_TARGET_BRAND } from \"./types.js\";\nimport { newWebSocketRpcSession as newWebSocketRpcSessionImpl,\n         newWorkersWebSocketRpcResponse } from \"./websocket.js\";\nimport { newHttpBatchRpcSession as newHttpBatchRpcSessionImpl,\n         newHttpBatchRpcResponse, nodeHttpBatchRpcResponse } from \"./batch.js\";\nimport { newMessagePortRpcSession as newMessagePortRpcSessionImpl } from \"./messageport.js\";\nimport { forceInitMap } from \"./map.js\";\nimport { forceInitStreams } from \"./streams.js\";\n\nforceInitMap();\nforceInitStreams();\n\n// Re-export public API types.\nexport { serialize, deserialize, newWorkersWebSocketRpcResponse, newHttpBatchRpcResponse,\n         nodeHttpBatchRpcResponse };\nexport type { RpcTransport, RpcSessionOptions, RpcCompatible };\n\n// Hack the type system to make RpcStub's types work nicely!\n/**\n * Represents a reference to a remote object, on which methods may be remotely invoked via RPC.\n *\n * `RpcStub` can represent any interface (when using TypeScript, you pass the specific interface\n * type as `T`, but this isn't known at runtime). The way this works is, `RpcStub` is actually a\n * `Proxy`. It makes itself appear as if every possible method / property name is defined. You can\n * invoke any method name, and the invocation will be sent to the server. If it turns out that no\n * such method exists on the remote object, an exception is thrown back. But the client does not\n * actually know, until that point, what methods exist.\n */\nexport type RpcStub<T extends RpcCompatible<T>> = Stub<T>;\nexport const RpcStub: {\n  new <T extends RpcCompatible<T>>(value: T): RpcStub<T>;\n} = <any>RpcStubImpl;\n\n/**\n * Represents the result of an RPC call.\n *\n * Also used to represent properties. That is, `stub.foo` evaluates to an `RpcPromise` for the\n * value of `foo`.\n *\n * This isn't actually a JavaScript `Promise`. It does, however, have `then()`, `catch()`, and\n * `finally()` methods, like `Promise` does, and because it has a `then()` method, JavaScript will\n * allow you to treat it like a promise, e.g. you can `await` it.\n *\n * An `RpcPromise` is also a proxy, just like `RpcStub`, where calling methods or awaiting\n * properties will make a pipelined network request.\n *\n * Note that and `RpcPromise` is \"lazy\": the actual final result is not requested from the server\n * until you actually `await` the promise (or call `then()`, etc. on it). This is an optimization:\n * if you only intend to use the promise for pipelining and you never await it, then there's no\n * need to transmit the resolution!\n */\nexport type RpcPromise<T extends RpcCompatible<T>> = Stub<T> & Promise<Stubify<T>>;\nexport const RpcPromise: {\n  // Note: Cannot construct directly!\n} = <any>RpcPromiseImpl;\n\n/**\n * Use to construct an `RpcSession` on top of a custom `RpcTransport`.\n *\n * Most people won't use this. You only need it if you've implemented your own `RpcTransport`.\n */\nexport interface RpcSession<T extends RpcCompatible<T> = undefined> {\n  getRemoteMain(): RpcStub<T>;\n  getStats(): {imports: number, exports: number};\n\n  // Waits until the peer is not waiting on any more promise resolutions from us. This is useful\n  // in particular to decide when a batch is complete.\n  drain(): Promise<void>;\n}\nexport const RpcSession: {\n  new <T extends RpcCompatible<T> = undefined>(\n      transport: RpcTransport, localMain?: any, options?: RpcSessionOptions): RpcSession<T>;\n} = <any>RpcSessionImpl;\n\n// RpcTarget needs some hackage too to brand it properly and account for the implementation\n// conditionally being imported from \"cloudflare:workers\".\n/**\n * Classes which are intended to be passed by reference and called over RPC must extend\n * `RpcTarget`. A class which does not extend `RpcTarget` (and which doesn't have built-in support\n * from the RPC system) cannot be passed in an RPC message at all; an exception will be thrown.\n *\n * Note that on Cloudflare Workers, this `RpcTarget` is an alias for the one exported from the\n * \"cloudflare:workers\" module, so they can be used interchangably.\n */\nexport interface RpcTarget extends RpcTargetBranded {};\nexport const RpcTarget: {\n  new(): RpcTarget;\n} = RpcTargetImpl;\n\n/**\n * Empty interface used as default type parameter for sessions where the other side doesn't\n * necessarily export a main interface.\n */\ninterface Empty {}\n\n/**\n * Start a WebSocket session given either an already-open WebSocket or a URL.\n *\n * @param webSocket Either the `wss://` URL to connect to, or an already-open WebSocket object to\n * use.\n * @param localMain The main RPC interface to expose to the peer. Returns a stub for the main\n * interface exposed from the peer.\n */\nexport let newWebSocketRpcSession:<T extends RpcCompatible<T> = Empty>\n    (webSocket: WebSocket | string, localMain?: any, options?: RpcSessionOptions) => RpcStub<T> =\n    <any>newWebSocketRpcSessionImpl;\n\n/**\n * Initiate an HTTP batch session from the client side.\n *\n * The parameters to this method have exactly the same signature as `fetch()`, but the return\n * value is an RpcStub. You can customize anything about the request except for the method\n * (it will always be set to POST) and the body (which the RPC system will fill in).\n */\nexport let newHttpBatchRpcSession:<T extends RpcCompatible<T>>\n    (urlOrRequest: string | Request, options?: RpcSessionOptions) => RpcStub<T> =\n    <any>newHttpBatchRpcSessionImpl;\n\n/**\n * Initiate an RPC session over a MessagePort, which is particularly useful for communicating\n * between an iframe and its parent frame in a browser context. Each side should call this function\n * on its own end of the MessageChannel.\n */\nexport let newMessagePortRpcSession:<T extends RpcCompatible<T> = Empty>\n    (port: MessagePort, localMain?: any, options?: RpcSessionOptions) => RpcStub<T> =\n    <any>newMessagePortRpcSessionImpl;\n\n/**\n * Implements unified handling of HTTP-batch and WebSocket responses for the Cloudflare Workers\n * Runtime.\n *\n * SECURITY WARNING: This function accepts cross-origin requests. If you do not want this, you\n * should validate the `Origin` header before calling this, or use `newHttpBatchRpcSession()` and\n * `newWebSocketRpcSession()` directly with appropriate security measures for each type of request.\n * But if your API uses in-band authorization (i.e. it has an RPC method that takes the user's\n * credentials as parameters and returns the authorized API), then cross-origin requests should\n * be safe.\n */\nexport async function newWorkersRpcResponse(request: Request, localMain: any) {\n  if (request.method === \"POST\") {\n    let response = await newHttpBatchRpcResponse(request, localMain);\n    // Since we're exposing the same API over WebSocket, too, and WebSocket always allows\n    // cross-origin requests, the API necessarily must be safe for cross-origin use (e.g. because\n    // it uses in-band authorization, as recommended in the readme). So, we might as well allow\n    // batch requests to be made cross-origin as well.\n    response.headers.set(\"Access-Control-Allow-Origin\", \"*\");\n    return response;\n  } else if (request.headers.get(\"Upgrade\")?.toLowerCase() === \"websocket\") {\n    return newWorkersWebSocketRpcResponse(request, localMain);\n  } else {\n    return new Response(\"This endpoint only accepts POST or WebSocket requests.\", { status: 400 });\n  }\n}\n", "import { newWebSocketRpcSession } from \"capnweb\";\nimport type { SharedBindings } from \"./constants\";\n\n/**\n * Common environment type for remote binding workers.\n */\nexport type RemoteBindingEnv = {\n\tremoteProxyConnectionString?: string;\n\tbinding: string;\n\tcfTraceId?: string;\n\t// Optional loopback service used to surface diagnostics back to the\n\t// Miniflare host (e.g. a Cloudflare Access block detected on the response\n\t// from the remote-bindings proxy server).\n\t[SharedBindings.MAYBE_SERVICE_LOOPBACK]?: Fetcher;\n};\n\n/** Headers sent alongside proxy requests to provide additional context. */\nexport type ProxyMetadata = {\n\t\"MF-Dispatch-Namespace-Options\"?: string;\n};\n\n/**\n * Throws a consistent error when a binding requires remote mode but isn't configured for it.\n */\nexport function throwRemoteRequired(bindingName: string): never {\n\tthrow new Error(`Binding ${bindingName} needs to be run remotely`);\n}\n\n/**\n * Build a plain-text body for the Cloudflare Access block substitution\n * response. We replace the original Access HTML so that:\n *  - Bindings that propagate the response body into an error message (e.g.\n *    `env.AI.run()` \u2192 `InferenceUpstreamError: \u2026`) get something readable\n *    instead of a wall of HTML.\n *  - Service-binding `.fetch()` callers that pipe the response back to a\n *    browser see the same actionable guidance as the terminal warning.\n *\n * The first line is the \"headline\" so error-message parsers that only show\n * the first line of the body still surface the key information.\n */\nfunction buildAccessBlockResponseBody(\n\tbindingName: string,\n\tproxyUrl: string\n): string {\n\treturn [\n\t\t`Cloudflare Access blocked this remote bindings request (binding \"${bindingName}\").`,\n\t\t``,\n\t\t`The local remote-bindings proxy client tried to reach ${proxyUrl}, but the`,\n\t\t`remote workers.dev proxy server returned a Cloudflare Access block page.`,\n\t\t``,\n\t\t`If your Cloudflare account protects workers.dev with Access, set the`,\n\t\t`CLOUDFLARE_ACCESS_CLIENT_ID and CLOUDFLARE_ACCESS_CLIENT_SECRET environment`,\n\t\t`variables (Service Token credentials), or run`,\n\t\t`  cloudflared access login <your-workers.dev-host>`,\n\t\t`for interactive authentication.`,\n\t\t``,\n\t\t`See https://developers.cloudflare.com/cloudflare-one/access-controls/service-credentials/service-tokens/`,\n\t].join(\"\\n\");\n}\n\n/**\n * If the response from the remote-bindings proxy server is a Cloudflare Access\n * block page, report it to the Miniflare host via the loopback service so that\n * a single, actionable warning can be surfaced to the user. Also substitutes\n * the original HTML body for a readable plain-text body so that the warning\n * surfaces in error messages (for bindings that propagate the body) and in\n * browsers (for bindings whose response is piped back to the client).\n *\n * The remote-bindings proxy CLIENT worker only ever calls the\n * `remoteProxyConnectionString`, so a 403 with a Cloudflare Access body here\n * is unambiguously an Access block \u2014 never a user-worker 403.\n *\n * Dedup of the warning is performed on the Miniflare/Node side; the worker\n * just fires the loopback notification for every blocked request.\n */\nasync function maybeReportCloudflareAccessBlock(\n\tresponse: Response,\n\tbindingName: string,\n\tproxyUrl: string,\n\tloopback: Fetcher | undefined\n): Promise<Response> {\n\tif (!loopback || response.status !== 403) {\n\t\treturn response;\n\t}\n\tlet text: string;\n\ttry {\n\t\ttext = await response.clone().text();\n\t} catch {\n\t\treturn response;\n\t}\n\t// Cloudflare Access block pages reliably contain the literal string\n\t// \"Cloudflare Access\" in the HTML body (title: \"Error \u30FB Cloudflare Access\").\n\t// Combined with the 403 status and the fact that this worker only ever\n\t// calls the remote-bindings proxy URL, this is a low-false-positive signal.\n\tif (!text.includes(\"Cloudflare Access\")) {\n\t\treturn response;\n\t}\n\tawait loopback.fetch(\"http://localhost/core/remote-bindings-access-warning\", {\n\t\tmethod: \"POST\",\n\t\theaders: {\n\t\t\t\"MF-Binding\": bindingName,\n\t\t\t\"MF-Proxy-URL\": proxyUrl,\n\t\t},\n\t});\n\t// Replace the original Access HTML body with our own readable plain-text\n\t// guidance. Headers are not copied from the original response \u2014 they may\n\t// include Access-specific cookies and other artefacts that aren't relevant\n\t// to the synthesised body.\n\treturn new Response(buildAccessBlockResponseBody(bindingName, proxyUrl), {\n\t\tstatus: response.status,\n\t\tstatusText: response.statusText,\n\t\theaders: { \"Content-Type\": \"text/plain; charset=utf-8\" },\n\t});\n}\n\nexport function makeFetch(\n\tremoteProxyConnectionString: string | undefined,\n\tbindingName: string,\n\textraHeaders?: Headers,\n\tcfTraceId?: string,\n\tloopback?: Fetcher\n) {\n\treturn async (\n\t\tinput: RequestInfo | URL,\n\t\tinit?: RequestInit\n\t): Promise<Response> => {\n\t\tif (!remoteProxyConnectionString) {\n\t\t\tthrowRemoteRequired(bindingName);\n\t\t}\n\t\tconst request = new Request(input, init);\n\n\t\tconst proxiedHeaders = new Headers(extraHeaders);\n\t\tfor (const [name, value] of request.headers) {\n\t\t\t// The `Upgrade` header needs to be special-cased to prevent:\n\t\t\t//   TypeError: Worker tried to return a WebSocket in a response to a request which did not contain the header \"Upgrade: websocket\"\n\t\t\tif (name === \"upgrade\") {\n\t\t\t\tproxiedHeaders.set(name, value);\n\t\t\t} else {\n\t\t\t\tproxiedHeaders.set(`MF-Header-${name}`, value);\n\t\t\t}\n\t\t}\n\t\tproxiedHeaders.set(\"MF-URL\", request.url);\n\t\tproxiedHeaders.set(\"MF-Binding\", bindingName);\n\t\tif (cfTraceId) {\n\t\t\t// Set directly on the outgoing request so Cloudflare's edge tracing picks it up\n\t\t\tproxiedHeaders.set(\"cf-trace-id\", cfTraceId);\n\t\t\t// Also forward through to the binding call via the MF-Header proxy mechanism\n\t\t\tproxiedHeaders.set(\"MF-Header-cf-trace-id\", cfTraceId);\n\t\t}\n\t\tconst req = new Request(request, {\n\t\t\theaders: proxiedHeaders,\n\t\t});\n\n\t\tconst response = await fetch(remoteProxyConnectionString, req);\n\t\t// Awaited (rather than fire-and-forget) so the loopback POST isn't\n\t\t// cancelled when the proxy client returns. The happy path\n\t\t// (non-403) short-circuits before any body read or loopback call,\n\t\t// so this adds no latency to successful requests.\n\t\treturn await maybeReportCloudflareAccessBlock(\n\t\t\tresponse,\n\t\t\tbindingName,\n\t\t\tremoteProxyConnectionString,\n\t\t\tloopback\n\t\t);\n\t};\n}\n\n/**\n * Create a remote proxy stub that proxies to a remote binding via capnweb.\n *\n * Intercepts `.fetch()` to use plain HTTP; forwards other accesses to capnweb.\n */\nexport function makeRemoteProxyStub(\n\tremoteProxyConnectionString: string,\n\tbindingName: string,\n\tmetadata?: ProxyMetadata,\n\tcfTraceId?: string,\n\tloopback?: Fetcher\n): Fetcher {\n\tconst url = new URL(remoteProxyConnectionString);\n\turl.protocol = url.protocol === \"https:\" ? \"wss:\" : \"ws:\";\n\turl.searchParams.set(\"MF-Binding\", bindingName);\n\tif (metadata) {\n\t\tfor (const [key, value] of Object.entries(metadata)) {\n\t\t\tif (value !== undefined) {\n\t\t\t\turl.searchParams.set(key, value);\n\t\t\t}\n\t\t}\n\t}\n\n\ttype ProxiedService = Omit<Service, \"connect\" | \"fetch\"> & {\n\t\tfetch: typeof fetch;\n\t\tconnect: never;\n\t};\n\tconst stub = newWebSocketRpcSession(url.href) as unknown as ProxiedService;\n\n\tconst headers = metadata\n\t\t? new Headers(\n\t\t\t\tObject.entries(metadata).filter(\n\t\t\t\t\t(entry): entry is [string, string] => entry[1] !== undefined\n\t\t\t\t)\n\t\t\t)\n\t\t: undefined;\n\n\treturn new Proxy<ProxiedService>(stub, {\n\t\tget(_, p) {\n\t\t\tif (p === \"fetch\") {\n\t\t\t\treturn makeFetch(\n\t\t\t\t\tremoteProxyConnectionString,\n\t\t\t\t\tbindingName,\n\t\t\t\t\theaders,\n\t\t\t\t\tcfTraceId,\n\t\t\t\t\tloopback\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn Reflect.get(stub, p);\n\t\t},\n\t});\n}\n"],
  "mappings": ";AAAA,SAAS,wBAAwB;;;ACI1B,IAAM,iBAAiB;AAAA,EAC7B,gBAAgB;AAAA,EAChB,iCAAiC;AAAA,EACjC,qBAAqB;AAAA,EACrB,wBAAwB;AAAA,EACxB,qCAAqC;AAAA,EACrC,gCAAgC;AACjC;;;;ACPO,IAAI,wBAAA,uBAA+B,gBAAgB;ACSzD,WAAmB,qBAAqB,IAAI;ACLxC,OAAO,YACT,OAAe,UAAU,uBAAO,IAAI,SAAS;AAE3C,OAAO,iBACT,OAAe,eAAe,uBAAO,IAAI,cAAc;AAKrD,QAAQ,kBACX,QAAQ,gBAAgB,WAAuC;AAC7D,MAAI,SACA;AAKJ,SAAO,EAAE,SAJO,IAAI,QAAW,CAAC,KAAK,QAAQ;AAC3C,cAAU,KACV,SAAS;EACX,CAAC,GACiB,SAAmB,OAAA;AACvC;AAGF,IAAI,gBAAsB,WAAmB,qBAAqB,GAMvD,YAAY,gBAAgB,cAAc,YAAY,MAAM;AAAC,GAQlE,iBAAiB,iBAAkB;AAAC,GAAG;AAEtC,SAAS,WAAW,OAA4B;AACrD,UAAQ,OAAO,OAAA;IACb,KAAK;IACL,KAAK;IACL,KAAK;AACH,aAAO;IAET,KAAK;AACH,aAAO;IAET,KAAK;IACL,KAAK;AAEH;IAEF,KAAK;AACH,aAAO;IAET;AACE,aAAO;EAAA;AAKX,MAAI,UAAU;AACZ,WAAO;AAKT,MAAI,YAAY,OAAO,eAAe,KAAK;AAC3C,UAAQ,WAAA;IACN,KAAK,OAAO;AACV,aAAO;IAET,KAAK,SAAS;IACd,KAAK,cAAc;AACjB,aAAO;IAET,KAAK,MAAM;AACT,aAAO;IAET,KAAK,KAAK;AACR,aAAO;IAET,KAAK,WAAW;AACd,aAAO;IAET,KAAK,eAAe;AAClB,aAAO;IAET,KAAK,eAAe;AAClB,aAAO;IAET,KAAK,QAAQ;AACX,aAAO;IAET,KAAK,QAAQ;AACX,aAAO;IAET,KAAK,SAAS;AACZ,aAAO;;IAIT,KAAK,QAAQ;AACX,aAAO;IAET,KAAK,WAAW;AACd,aAAO;;IAIT;AACE,UAAI,eAAe;AAGjB,YAAI,aAAa,cAAc,QAAQ,aACnC,iBAAiB,cAAc;AACjC,iBAAO;AACT,YAAW,aAAa,cAAc,WAAW,aACtC,aAAa,cAAc,YAAY;AAGhD,iBAAO;MAEX;AAEA,aAAI,iBAAiB,YACZ,eAGL,iBAAiB,QACZ,UAGF;EAAA;AAEb;AAEA,SAAS,eAAsB;AAC7B,QAAM,IAAI,MAAM,0CAA0C;AAC5D;AAIO,IAAI,UAAmB,EAAE,UAAU,cAAc,SAAS,aAAA;AAajE,SAAS,kBAAyB;AAChC,QAAM,IAAI,MAAM,uCAAuC;AACzD;AAIO,IAAI,aAAyB;EAClC,0BAA0B;EAC1B,8BAA8B;EAC9B,0BAA0B;AAC5B,GAsBsB,WAAf,MAAwB;;;;;;EAU7B,OAAO,MAAoB,MAA2D;AAIpF,QAAI,SADO,KAAK,KAAK,MAAM,IAAI,EACb,KAAA,GACd;AACJ,WAAI,kBAAkB,UACpB,UAAU,OAAO,KAAK,CAAA,MAAK;AAAE,QAAE,QAAA;IAAW,CAAC,KAE3C,OAAO,QAAA,GACP,UAAU,QAAQ,QAAA,IAEb,EAAE,QAAA;EACX;AAwEF,GAEa,gBAAN,cAA4B,SAAS;EAC1C,YAAoB,OAAY;AAAE,UAAA,GAAd,KAAA,QAAA;EAAuB;EAE3C,KAAK,MAAoB,MAA4B;AAAE,WAAO;EAAM;EACpE,IAAI,MAAoB,UAAsB,cAAmC;AAAE,WAAO;EAAM;EAChG,IAAI,MAA8B;AAAE,WAAO;EAAM;EACjD,MAAgB;AAAE,WAAO;EAAM;EAC/B,OAAyC;AAAE,WAAO,QAAQ,OAAO,KAAK,KAAK;EAAG;EAC9E,4BAAkC;EAAC;EACnC,UAAgB;EAAC;EACjB,SAAS,UAAsC;AAC7C,QAAI;AACF,eAAS,KAAK,KAAK;IACrB,SAAS,KAAK;AAEZ,cAAQ,QAAQ,GAAG;IACrB;EACF;AACF,GAEM,gBAA0B,IAAI;EAChC,IAAI,MAAM,uDAAuD;AAAC,GAKlE,SAA0B,CAAC,MAAgB,MAAoB,WAC1D,KAAK,KAAK,MAAM,MAAM;AAGxB,SAAS,oBAAuB,aAA8B,UAAsB;AACzF,MAAI,WAAW;AACf,WAAS;AACT,MAAI;AACF,WAAO,SAAA;EACT,UAAA;AACE,aAAS;EACX;AACF;AAGA,IAAI,WAAA,uBAAkB,UAAU,GAO1B,iBAA+C;EACnD,MAAM,QAAwB,SAAc,eAAsB;AAChE,QAAI,OAAO,OAAO;AAClB,WAAO,IAAI,WAAW;MAAO,KAAK;MAC9B,KAAK,iBAAiB,CAAA;MAAI,WAAW,cAAc,aAAa;IAAA,GAAI,CAAA,CAAE;EAC5E;EAEA,IAAI,QAAwB,MAAuB,UAAe;AAChE,QAAI,OAAO,OAAO;AAClB,WAAI,SAAS,WACJ,OACE,QAAQ,WAAW,YAOf,KAAM,IAAI,IACd,OAAO,QAAS,WAElB,IAAI;MAAW,KAAK;MACvB,KAAK,gBAAgB,CAAC,GAAG,KAAK,eAAe,IAAI,IAAI,CAAC,IAAI;IAAA,IACrD,SAAS,OAAO,YACpB,CAAC,KAAK,iBAAiB,KAAK,cAAc,UAAU,KAElD,MAAM;AACX,WAAK,KAAK,QAAA,GACV,KAAK,OAAO;IACd,IAEA;EAEJ;EAEA,IAAI,QAAwB,MAAuB;AACjD,QAAI,OAAO,OAAO;AAClB,WAAI,SAAS,WACJ,KACE,QAAQ,WAAW,YACrB,QAAQ,OACN,OAAO,QAAS,WAClB,KACE,SAAS,OAAO,YACpB,CAAC,KAAK,iBAAiB,KAAK,cAAc,UAAU;EAK7D;EAEA,UAAU,QAAwB,MAAW;AAC3C,UAAM,IAAI,MAAM,8CAA8C;EAChE;EAEA,eAAe,QAAwB,UAA2B,YACpD;AACZ,UAAM,IAAI,MAAM,uCAAuC;EACzD;EAEA,eAAe,QAAwB,GAA6B;AAClE,UAAM,IAAI,MAAM,uCAAuC;EACzD;EAEA,yBAAyB,QAAwB,GAAoD;EAGrG;EAEA,eAAe,QAAuC;AACpD,WAAO,OAAO,eAAe,OAAO,GAAG;EACzC;EAEA,aAAa,QAAiC;AAC5C,WAAO;EACT;EAEA,QAAQ,QAAoD;AAC1D,WAAO,CAAA;EACT;EAEA,kBAAkB,QAAiC;AAEjD,WAAO;EACT;EAEA,IAAI,QAAwB,GAAoB,UAAe,UAAwB;AACrF,UAAM,IAAI,MAAM,uCAAuC;EACzD;EAEA,eAAe,QAAwB,GAA2B;AAChE,UAAM,IAAI,MAAM,wCAAwC;EAC1D;AACF,GAOa,UAAN,MAAM,iBAAgB,UAAU;;;EAGrC,YAAY,MAAgB,eAA8B;AAGxD,QAFA,MAAA,GAEI,EAAE,gBAAgB,WAAW;AAK/B,UAAI,QAAa;AAUjB,UATI,iBAAiB,aAAa,iBAAiB,WACjD,OAAO,eAAe,OAAO,OAAO,MAAS,IAI7C,OAAO,IAAI,gBAAgB,WAAW,cAAc,KAAK,CAAC,GAIxD;AACF,cAAM,IAAI,UAAU,0DAA0D;IAElF;AAEA,SAAK,OAAO,MACZ,KAAK,gBAAgB;AAKrB,QAAI,OAAY,MAAM;IAAC;AACvB,gBAAK,MAAM,MACJ,IAAI,MAAM,MAAM,cAAc;EACvC;EAEO;EACA;EAEP,MAAe;AAQb,QAAI,SAAS,KAAK,QAAQ;AAC1B,WAAI,OAAO,gBACF,IAAI,SAAQ,OAAO,KAAK,IAAI,OAAO,aAAa,CAAC,IAEjD,IAAI,SAAQ,OAAO,KAAK,IAAA,CAAK;EAExC;EAEA,YAAY,UAAgC;AAC1C,SAAK,QAAQ,EAAE,KAAK,SAAS,QAAQ;EACvC;EAEA,IAAI,MAAkD;AACpD,QAAI,EAAC,MAAM,cAAA,IAAiB,KAAK,QAAQ;AACzC,WAAO,QAAQ,QAAQ,MAAM,iBAAiB,CAAA,GAAI,IAAI;EACxD;EAEA,WAAW;AACT,WAAO;EACT;AACF,GAEa,aAAN,cAAyB,QAAQ;;EAEtC,YAAY,MAAgB,eAA6B;AACvD,UAAM,MAAM,aAAa;EAC3B;EAEA,KAAK,aACA,YACmB;AACtB,WAAO,YAAY,IAAI,EAAE,KAAK,GAAG,SAAS;EAC5C;EAEA,MAAM,YAA8E;AAClF,WAAO,YAAY,IAAI,EAAE,MAAM,GAAG,SAAS;EAC7C;EAEA,QAAQ,WAA+D;AACrE,WAAO,YAAY,IAAI,EAAE,QAAQ,GAAG,SAAS;EAC/C;EAEA,WAAW;AACT,WAAO;EACT;AACF;AAYO,SAAS,0BAA0B,MAAyB;AACjE,MAAI,EAAC,MAAM,cAAA,IAAiB,KAAK,QAAQ;AAEzC,SAAI,iBAAiB,cAAc,SAAS,IACnC,KAAK,IAAI,aAAa,IAEtB;AAEX;AAUO,SAAS,iBAAiB,MAAyB;AACxD,MAAI,EAAC,MAAM,cAAA,IAAiB,KAAK,QAAQ;AAEzC,SAAI,gBACK,KAAK,IAAI,aAAa,IAEtB,KAAK,IAAA;AAEhB;AAQO,SAAS,uBAAuB,MAAqC;AAC1E,MAAI,EAAC,MAAM,cAAA,IAAiB,KAAK,QAAQ;AAEzC,MAAI,mBAAiB,cAAc,SAAS;AAI5C,WAAO;AACT;AAOO,SAAS,mBAAmB,MAAyB;AAC1D,SAAO,KAAK,QAAQ,EAAE;AACxB;AAMO,SAAS,kBAAkB,MAA+D;AAC/F,SAAO,KAAK,QAAQ;AACtB;AAIA,eAAe,YAAY,SAAuC;AAChE,MAAI,EAAC,MAAM,cAAA,IAAiB,QAAQ,QAAQ;AAC5C,SAAI,cAAe,SAAS,MAK1B,OAAO,KAAK,IAAI,aAAc,KAElB,MAAM,KAAK,KAAA,GACV,eAAA;AACjB;AAiEO,IAAM,aAAN,MAAM,YAAW;;EAkFd,YAEC,OAOC,QAUA,OAIA,UACR;AAtBO,SAAA,QAAA,OAOC,KAAA,SAAA,QAUA,KAAA,QAAA,OAIA,KAAA,WAAA;EACP;;;;;;;;EAlGH,OAAc,cAAc,OAA4B;AACtD,WAAO,IAAI,YAAW,OAAO,QAAQ;EACvC;;;;;;EAOA,OAAc,cAAc,OAA4B;AACtD,WAAO,IAAI,YAAW,OAAO,QAAQ;EACvC;;;;EAKA,OAAc,UAAU,OAAiC;AACvD,QAAI,QAAoB,CAAA,GACpB,WAA6B,CAAA,GAE7B,cAAyB,CAAA;AAE7B,aAAS,WAAW,OAAO;AACzB,cAAQ,iBAAA;AACR,eAAS,QAAQ,QAAQ;AACvB,cAAM,KAAK,IAAI;AAEjB,eAAS,WAAW,QAAQ;AAC1B,QAAI,QAAQ,WAAW,YAGrB,UAAU;UACR,QAAQ;UACR,UAAU,YAAY;UACtB,SAAS,QAAQ;QAAA,IAGrB,SAAS,KAAK,OAAO;AAEvB,kBAAY,KAAK,QAAQ,KAAK;IAChC;AAEA,WAAO,IAAI,YAAW,aAAa,SAAS,OAAO,QAAQ;EAC7D;;;;;;;;;;;;EAaA,OAAc,YAAY,OAAmB,UAA4B;AACvE,WAAO,IAAI,YAAW,MAAM,SAAS,OAAO,QAAQ;EACtD;;;;;;;EAQA,OAAc,aACV,OAAgB,WAA+B,OAAsC;AACvF,QAAI,SAAS,IAAI,YAAW,MAAM,SAAS,CAAA,GAAI,CAAA,CAAE;AACjD,kBAAO,QAAQ,OAAO;MAAS;MAAO;MAAW;MAAS;;MAAqB;MAAM;IAAA,GAC9E;EACT;;;;;;EAkCQ;;EAGD,oBAAoB,QAA8B,QAC9B,WAAoB,IAAgB;AAC7D,QAAI,KAAK,WAAW,UAAU;AAC5B,UAAI,UAAU;AAkBZ,YAAI,UAAU;AACd,QAAI,OAAO,QAAQ,OAAQ,eACzB,SAAS,QAAQ,IAAA;MAErB;AAEA,aAAO,eAAe,OAAO,QAAQ,MAAM;IAC7C,WAAW,KAAK,WAAW,UAAU;AAUnC,UAAI,OAAO,KAAK,YAAY,IAAI,MAAM;AACtC,aAAI,OACE,WACK,KAAK,IAAA,KAEZ,KAAK,YAAY,OAAO,MAAM,GACvB,SAGT,OAAO,eAAe,OAAO,QAAQ,MAAM,GACvC,YACG,KAAK,eACR,KAAK,aAAa,oBAAI,IAAA,IAExB,KAAK,WAAW,IAAI,QAAQ,IAAI,GACzB,KAAK,IAAA,KAEL;IAGb;AACE,YAAM,IAAI,MAAM,gDAAgD;EAEpE;;EAGO,yBAAyB,QAAwB,QACxB,WAAoB,IAAgB;AAClE,QAAI,KAAK,WAAW;AAIlB,aAAO,WAAW,yBAAyB,MAAM;AACnD,QAAW,KAAK,WAAW,UAAU;AAEnC,UAAI,OAAO,KAAK,YAAY,IAAI,MAAM;AACtC,aAAI,OACE,WACK,KAAK,IAAA,KAEZ,KAAK,YAAY,OAAO,MAAM,GACvB,SAGT,OAAO,WAAW,yBAAyB,MAAM,GAC7C,YACG,KAAK,eACR,KAAK,aAAa,oBAAI,IAAA,IAExB,KAAK,WAAW,IAAI,QAAQ,IAAI,GACzB,KAAK,IAAA,KAEL;IAGb;AACE,YAAM,IAAI,MAAM,qDAAqD;EAEzE;;EAGO,yBAAyB,QAAwB,QACxB,WAAoB,IAAgB;AAClE,QAAI,KAAK,WAAW;AAClB,aAAO,WAAW,yBAAyB,MAAM;AACnD,QAAW,KAAK,WAAW,UAAU;AACnC,UAAI,OAAO,KAAK,YAAY,IAAI,MAAM;AACtC,aAAI,OACE,WACK,KAAK,IAAA,KAEZ,KAAK,YAAY,OAAO,MAAM,GACvB,SAGT,OAAO,WAAW,yBAAyB,MAAM,GAC7C,YACG,KAAK,eACR,KAAK,aAAa,oBAAI,IAAA,IAExB,KAAK,WAAW,IAAI,QAAQ,IAAI,GACzB,KAAK,IAAA,KAEL;IAGb;AACE,YAAM,IAAI,MAAM,qDAAqD;EAEzE;EAEQ,SACJ,OAAgB,WAA+B,UAA2B,QAC1E,UAAmB,OAAmC;AAExD,YADW,WAAW,KAAK,GACnB;MACN,KAAK;AAEH,eAAO;MAET,KAAK;MACL,KAAK;MACL,KAAK;MACL,KAAK;MACL,KAAK;MACL,KAAK;AAGH,eAAO;MAET,KAAK,SAAS;AAGZ,YAAI,QAAwB,OACxB,MAAM,MAAM,QACZ,SAAS,IAAI,MAAM,GAAG;AAC1B,iBAAS,IAAI,GAAG,IAAI,KAAK;AACvB,iBAAO,CAAC,IAAI,KAAK,SAAS,MAAM,CAAC,GAAG,OAAO,GAAG,QAAQ,UAAU,KAAK;AAEvE,eAAO;MACT;MAEA,KAAK,UAAU;AAEb,YAAI,SAAkC,CAAA,GAClC,SAAkC;AACtC,iBAAS,KAAK;AACZ,iBAAO,CAAC,IAAI,KAAK,SAAS,OAAO,CAAC,GAAG,QAAQ,GAAG,QAAQ,UAAU,KAAK;AAEzE,eAAO;MACT;MAEA,KAAK;MACL,KAAK,eAAe;AAClB,YAAI,OAAgB,OAChB;AAMJ,YALI,WACF,OAAO,iBAAiB,IAAI,IAE5B,OAAO,0BAA0B,IAAI,GAEnC,gBAAgB,YAAY;AAC9B,cAAI,UAAU,IAAI,WAAW,MAAM,CAAA,CAAE;AACrC,sBAAK,SAAU,KAAK,EAAC,QAAQ,UAAU,QAAA,CAAQ,GACxC;QACT;AACE,sBAAK,MAAO,KAAK,IAAI,GACd,IAAI,QAAQ,IAAI;MAE3B;MAEA,KAAK;MACL,KAAK,cAAc;AACjB,YAAI,SAA+B,OAC/B;AACJ,eAAI,QACF,OAAO,MAAM,oBAAoB,QAAQ,WAAW,QAAQ,IAE5D,OAAO,eAAe,OAAO,QAAQ,SAAS,GAEhD,KAAK,MAAO,KAAK,IAAI,GACd,IAAI,QAAQ,IAAI;MACzB;MAEA,KAAK,gBAAgB;AACnB,YAAI,SAAoB,OACpB;AACJ,eAAI,QACF,UAAU,IAAI,WAAW,MAAM,oBAAoB,QAAQ,WAAW,QAAQ,GAAG,CAAA,CAAE,IAEnF,UAAU,IAAI,WAAW,eAAe,OAAO,QAAQ,SAAS,GAAG,CAAA,CAAE,GAEvE,KAAK,SAAU,KAAK,EAAC,QAAQ,UAAU,QAAA,CAAQ,GACxC;MACT;MAEA,KAAK,YAAY;AACf,YAAI,SAAyB,OACzB;AACJ,eAAI,QACF,OAAO,MAAM,yBAAyB,QAAQ,WAAW,QAAQ,IAEjE,OAAO,WAAW,yBAAyB,MAAM,GAEnD,KAAK,MAAO,KAAK,IAAI,GACd;MACT;MAEA,KAAK,YAAY;AAIf,YAAI,SAAyB,OACzB;AACJ,eAAI,QACF,OAAO,MAAM,yBAAyB,QAAQ,WAAW,QAAQ,IAEjE,OAAO,WAAW,yBAAyB,MAAM,GAEnD,KAAK,MAAO,KAAK,IAAI,GACd;MACT;MAEA,KAAK;AACH,eAAO,IAAI,QAAiB,KAAK;MAEnC,KAAK,WAAW;AACd,YAAI,MAAe;AACnB,eAAI,IAAI,QAGN,KAAK,SAAS,IAAI,MAAM,KAAK,QAAQ,KAAK,UAAU,KAAK,GAMpD,IAAI,QAAQ,GAAG;MACxB;MAEA,KAAK,YAAY;AACf,YAAI,OAAiB;AACrB,eAAI,KAAK,QAGP,KAAK,SAAS,KAAK,MAAM,MAAM,QAAQ,MAAM,UAAU,KAAK,GAMvD,IAAI,SAAS,KAAK,MAAM,IAAI;MACrC;MAEA;AAEE,cAAM,IAAI,MAAM,aAAa;IAAA;EAEnC;;;EAIO,mBAAmB;AACxB,QAAI,KAAK,WAAW,SAAS;AAG3B,UAAI,WAAW,KAAK,WAAW;AAE/B,WAAK,QAAQ,CAAA,GACb,KAAK,WAAW,CAAA;AAGhB,UAAI;AACF,aAAK,QAAQ,KAAK,SAAS,KAAK,OAAO,QAAW,SAAS,MAAM,UAAU,IAAI;MACjF,SAAS,KAAK;AAEZ,mBAAK,QAAQ,QACb,KAAK,WAAW,QACV;MACR;AAMA,UAHA,KAAK,SAAS,SAGV,KAAK,cAAc,KAAK,WAAW,OAAO;AAC5C,cAAM,IAAI,MAAM,qDAAqD;AAEvE,WAAK,aAAa;IACpB;EACF;;EAGQ,UAAU,QAAgB,UAA2B,UAAgC;AAG3F,QAFA,KAAK,iBAAA,GAED,KAAK,iBAAiB;AACxB,kBAAW,oBAAoB,KAAK,OAAO,QAAQ,UAAU,QAAQ;SAChE;AACC,aAAQ,QAAQ,IAAI,KAAK;AAE/B,eAAS,UAAU,KAAK;AAKtB,oBAAW,oBAAoB,OAAO,SAAS,OAAO,QAAQ,OAAO,UAAU,QAAQ;IAE3F;EACF;EAEA,OAAe,oBACX,SAAqB,QAAgB,UACrC,UAA8B;AAEhC,QAAI,OAAO,uBAAuB,OAAO;AACzC,QAAI,CAAC;AACH,YAAM,IAAI,MAAM,qDAAqD;AAGvE,QAAI,QAAQ,KAAK,KAAA;AACjB,IAAI,iBAAiB,cAEnB,MAAM,UAAU,QAAQ,UAAU,QAAQ,IAG1C,SAAS,KAAK,MAAM,KAAK,CAAA,YAAW;AAClC,UAAI,cAAkC,CAAA;AAEtC,UADA,QAAQ,UAAU,QAAQ,UAAU,WAAW,GAC3C,YAAY,SAAS;AACvB,eAAO,QAAQ,IAAI,WAAW;IAElC,CAAC,CAAC;EAEN;;;;;;;;EASA,MAAa,YAAY,MAAgB,SAAkD;AACzF,QAAI;AACF,UAAI,WAA4B,CAAA;AAChC,WAAK,UAAU,MAAM,SAAS,QAAQ,GAKlC,SAAS,SAAS,KACpB,MAAM,QAAQ,IAAI,QAAQ;AAI5B,UAAI,SAAS,SAAS,UAAU,MAAM,KAAK,MAAM,SAAS,KAAK,KAAK;AAEpE,aAAI,kBAAkB,aAIb,YAAW,cAAc,MAAM,IAI/B,YAAW,cAAc,MAAM,MAAM;IAEhD,UAAA;AACE,WAAK,QAAA;IACP;EACF;;;;;;EAOA,MAAa,iBAAmC;AAC9C,QAAI;AACF,UAAI,WAA4B,CAAA;AAChC,WAAK,UAAU,MAAM,SAAS,QAAQ,GAElC,SAAS,SAAS,KACpB,MAAM,QAAQ,IAAI,QAAQ;AAG5B,UAAI,SAAS,KAAK;AAGlB,aAAI,kBAAkB,WACd,OAAO,WAAW,UAGtB,OAAO,eAAe,QAAQ,OAAO,SAAS;;;;;;;;QAQ5C,OAAO,MAAM,KAAK,QAAA;QAClB,UAAU;QACV,YAAY;QACZ,cAAc;MAAA,CACf,IAIE;IACT,SAAS,KAAK;AAEZ,iBAAK,QAAA,GACC;IACR;EACF;EAEO,UAAU;AACf,QAAI,KAAK,WAAW;AAElB,WAAK,MAAO,QAAQ,CAAA,SAAQ,KAAK,QAAA,CAAS,GAC1C,KAAK,SAAU,QAAQ,CAAA,YAAW,QAAQ,QAAQ,OAAO,OAAO,EAAA,CAAG;aAC1D,KAAK,WAAW,aAGzB,KAAK,YAAY,KAAK,OAAO,MAAS,GAClC,KAAK,cAAc,KAAK,WAAW,OAAO;AAC5C,YAAM,IAAI,MAAM,yDAAyD;AAO7E,SAAK,SAAS,SACd,KAAK,QAAQ,CAAA,GACb,KAAK,WAAW,CAAA;EAClB;;EAGQ,YAAY,OAAgB,QAA4B;AAE9D,YADW,WAAW,KAAK,GACnB;MACN,KAAK;MACL,KAAK;MACL,KAAK;MACL,KAAK;MACL,KAAK;MACL,KAAK;MACL,KAAK;AACH;MAEF,KAAK,SAAS;AACZ,YAAI,QAAwB,OACxB,MAAM,MAAM;AAChB,iBAAS,IAAI,GAAG,IAAI,KAAK;AACvB,eAAK,YAAY,MAAM,CAAC,GAAG,KAAK;AAElC;MACF;MAEA,KAAK,UAAU;AACb,YAAI,SAAkC;AACtC,iBAAS,KAAK;AACZ,eAAK,YAAY,OAAO,CAAC,GAAG,MAAM;AAEpC;MACF;MAEA,KAAK;MACL,KAAK,eAAe;AAElB,YAAI,OAAO,uBADS,KACkB;AACtC,QAAI,QACF,KAAK,QAAA;AAEP;MACF;MAEA,KAAK;MACL,KAAK,cAAc;AACjB,YAAI,SAA+B,OAC/B,OAAO,KAAK,YAAY,IAAI,MAAM;AACtC,QAAI,QAEF,KAAK,QAAA,GACL,KAAK,WAAY,OAAO,MAAM,KAQ9B,iBAAiB,MAAM;AAEzB;MACF;MAEA,KAAK;AAEH;MAEF,KAAK;AAEH;MAEF,KAAK,WAAW;AAEd,YAAI,MAAe;AACnB,QAAI,IAAI,QAAM,KAAK,YAAY,IAAI,MAAM,GAAG;AAE5C;MACF;MAEA,KAAK,YAAY;AAEf,YAAI,OAAiB;AACrB,QAAI,KAAK,QAAM,KAAK,YAAY,KAAK,MAAM,IAAI;AAE/C;MACF;MAEA,KAAK,YAAY;AACf,YAAI,SAAyB,OACzB,OAAO,KAAK,YAAY,IAAI,MAAM;AACtC,QAAI,OACF,KAAK,WAAY,OAAO,MAAM,IAI9B,OAAO,WAAW,yBAAyB,MAAM,GAGnD,KAAK,QAAA;AAEL;MACF;MAEA,KAAK,YAAY;AACf,YAAI,SAAyB,OACzB,OAAO,KAAK,YAAY,IAAI,MAAM;AACtC,QAAI,OACF,KAAK,WAAY,OAAO,MAAM,IAI9B,OAAO,WAAW,yBAAyB,MAAM,GAGnD,KAAK,QAAA;AAEL;MACF;MAEA;AAEE;IAAA;EAEN;;;;EAKA,4BAAkC;AAChC,IAAI,KAAK,SAEP,KAAK,MAAM,QAAQ,CAAA,SAAQ;AACzB,WAAK,0BAAA;IACP,CAAC,GACD,KAAK,SAAU;MACX,CAAA,YAAW,mBAAmB,QAAQ,OAAO,EAAE,0BAAA;IAA0B,KAG7E,KAAK,8BAA8B,KAAK,KAAK;EAEjD;EAEQ,8BAA8B,OAAgB;AAEpD,YADW,WAAW,KAAK,GACnB;MACN,KAAK;MACL,KAAK;MACL,KAAK;MACL,KAAK;MACL,KAAK;MACL,KAAK;MACL,KAAK;MACL,KAAK;MACL,KAAK;MACL,KAAK;MACL,KAAK;MACL,KAAK;MACL,KAAK;MACL,KAAK;AACH;MAEF,KAAK,SAAS;AACZ,YAAI,QAAwB,OACxB,MAAM,MAAM;AAChB,iBAAS,IAAI,GAAG,IAAI,KAAK;AACvB,eAAK,8BAA8B,MAAM,CAAC,CAAC;AAE7C;MACF;MAEA,KAAK,UAAU;AACb,YAAI,SAAkC;AACtC,iBAAS,KAAK;AACZ,eAAK,8BAA8B,OAAO,CAAC,CAAC;AAE9C;MACF;MAEA,KAAK;MACL,KAAK;AACH,2BAA4B,KAAK,EAAE,0BAAA;AACnC;MAEF,KAAK;AACG,cAAO,KAAK,CAAC,MAAW;QAAC,GAAG,CAAC,MAAW;QAAC,CAAC;AAChD;MAEF;AAEE;IAAA;EAEN;AACF;AA0BA,SAAS,WAAW,OAAgB,QAChB,MAAoB,OAA4C;AAClF,WAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,aAAiB;AAEjB,QAAI,OAAO,KAAK,CAAC;AACjB,QAAI,QAAQ,OAAO,WAAW;AAO5B,cAAQ;AACR;IACF;AAGA,YADW,WAAW,KAAK,GACnB;MACN,KAAK;MACL,KAAK;AAEH,QAAI,OAAO,OAAe,OAAO,IAAI,IACnC,QAAc,MAAO,IAAI,IAEzB,QAAQ;AAEV;MAEF,KAAK;AAGH,QAAI,OAAO,UAAU,IAAI,KAAa,QAAQ,IAC5C,QAAc,MAAO,IAAI,IAEzB,QAAQ;AAEV;MAEF,KAAK;MACL,KAAK,gBAAgB;AAEnB,YAAI,OAAO,OAAe,OAAO,IAAI;AAKnC,gBAAM,IAAI;YACN,iCAAiC,IAAI;UAAA;AAKzC,gBAAc,MAAO,IAAI,GAK3B,QAAQ;AACR;MACF;MAEA,KAAK;MACL,KAAK,eAAe;AAClB,YAAI,EAAC,MAAY,cAAA,IAAiB,kBAA2B,KAAK;AAClE,eAAO,EAAE,MAAM,eACX,gBAAgB,cAAc,OAAO,KAAK,MAAM,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,EAAA;MACxE;MAEA,KAAK;AAMH,gBAAQ;AACR;MAEF,KAAK;AAIH,gBAAQ;AACR;MAEF,KAAK;MACL,KAAK;MACL,KAAK;MACL,KAAK;MACL,KAAK;MACL,KAAK;MACL,KAAK;MACL,KAAK;AAEH,gBAAQ;AACR;MAEF,KAAK;AAEH,gBAAS,MAAc,IAAI;AAC3B;MAEF,KAAK,eAAe;AAClB,YAAI,MAAM;AACR,gBAAM,IAAI,UAAU,6CAA6C;AAC5D;AACL,cAAI,SAAS,KAAK,MAAM,GAAG,CAAC,EAAE,KAAK,GAAG,GAClC,YAAY,KAAK,MAAM,GAAG,CAAC,EAAE,KAAK,GAAG;AACzC,gBAAM,IAAI;YACN,IAAI,MAAM,6CAA6C,SAAS;UAAA;QAEtE;MACF;MAEA;AAEE,cAAM,IAAI,UAAU,aAAa;IAAA;EAEvC;AAIA,MAAI,iBAAiB,YAAY;AAC/B,QAAI,EAAC,MAAY,cAAA,IAAiB,kBAA2B,KAAK;AAClE,WAAO,EAAE,MAAM,eAAe,iBAAiB,CAAA,EAAC;EAClD;AAIA,SAAO;IACL;IACA;IACA;EAAA;AAEJ;AAGA,IAAe,gBAAf,cAAqC,SAAS;EAG5C,KAAK,MAAoB,MAA4B;AACnD,QAAI;AACF,UAAI,EAAC,OAAO,MAAA,IAAS,KAAK,SAAA,GACtB,eAAe,WAAW,OAAO,QAAW,MAAM,KAAK;AAE3D,UAAI,aAAa;AACf,eAAO,aAAa,KAAK,KAAK,aAAa,eAAe,IAAI;AAIhE,UAAI,OAAO,aAAa,SAAS;AAC/B,cAAM,IAAI,UAAU,IAAI,KAAK,KAAK,GAAG,CAAC,sBAAsB;AAE9D,UAAI,UAAU,KAAK,YAAY,aAAa,OAAO,aAAa,MAAM;AACtE,aAAO,IAAI,gBAAgB,QAAQ,KAAK,CAAA,YAC/B,IAAI,gBAAgB,OAAO,CACnC,CAAC;IACJ,SAAS,KAAK;AACZ,aAAO,IAAI,cAAc,GAAG;IAC9B;EACF;EAEA,IAAI,MAAoB,UAAsB,cAAmC;AAC/E,QAAI;AACF,UAAI;AACJ,UAAI;AACF,YAAI,EAAC,OAAO,MAAA,IAAS,KAAK,SAAA;AAC1B,uBAAe,WAAW,OAAO,QAAW,MAAM,KAAK;MACzD,SAAS,KAAK;AAEZ,iBAAS,OAAO;AACd,cAAI,QAAA;AAEN,cAAM;MACR;AAEA,aAAI,aAAa,OACR,aAAa,KAAK,IAAI,aAAa,eAAe,UAAU,YAAY,IAG1E,QAAQ;QACX,aAAa;QAAO,aAAa;QAAQ,aAAa;QAAO;QAAU;MAAA;IAC7E,SAAS,KAAK;AACZ,aAAO,IAAI,cAAc,GAAG;IAC9B;EACF;EAEA,IAAI,MAA8B;AAChC,QAAI;AACF,UAAI,EAAC,OAAO,MAAA,IAAS,KAAK,SAAA;AAE1B,UAAI,KAAK,WAAW,KAAK,UAAU;AAKjC,cAAM,IAAI,MAAM,2CAA2C;AAG7D,UAAI,eAAe,WAAW,OAAO,QAAW,MAAM,KAAK;AAE3D,aAAI,aAAa,OACR,aAAa,KAAK,IAAI,aAAa,aAAa,IAYlD,IAAI,gBAAgB,WAAW;QAClC,aAAa;QAAO,aAAa;QAAQ,aAAa;MAAA,CAAM;IAClE,SAAS,KAAK;AACZ,aAAO,IAAI,cAAc,GAAG;IAC9B;EACF;AACF,GAUa,kBAAN,MAAM,yBAAwB,cAAc;EACjD,YAAY,SAAqB;AAC/B,UAAA,GACA,KAAK,UAAU;EACjB;EAEQ;;EAEA,aAAyB;AAC/B,QAAI,KAAK;AACP,aAAO,KAAK;AAEZ,UAAM,IAAI,MAAM,yDAAyD;EAE7E;EAEU,WAAW;AACnB,QAAI,UAAU,KAAK,WAAA;AACnB,WAAO,EAAC,OAAO,QAAQ,OAAO,OAAO,QAAA;EACvC;EAEA,MAAgB;AAQd,QAAI,cAAc,KAAK,WAAA;AACvB,WAAO,IAAI,iBAAgB,WAAW;MAClC,YAAY;MAAO;MAAW;IAAA,CAAY;EAChD;EAEA,OAAyC;AAIvC,WAAO,KAAK,WAAA;EACd;EAEA,4BAAkC;AAChC,IAAI,KAAK,WACP,KAAK,QAAQ,0BAAA;EAEjB;EAEA,UAAgB;AACd,IAAI,KAAK,YACP,KAAK,QAAQ,QAAA,GACb,KAAK,UAAU;EAEnB;EAEA,SAAS,UAAsC;AAC7C,IAAI,KAAK,WACH,KAAK,QAAQ,iBAAiB,WAIhC,KAAK,QAAQ,MAAM,YAAY,QAAQ;EAK7C;AACF;AAEA,SAAS,iBAAiB,QAA8B;AACtD,MAAI,OAAO,WAAW;AACpB,QAAI;AACiB,aAAQ,OAAO,OAAO,EAAA;IAC3C,SAAS,KAAK;AAIZ,cAAQ,OAAO,GAAG;IACpB;AAEJ;AAcA,IAAM,iBAAN,MAAM,wBAAuB,cAAc;;;;EAIzC,OAAO,OAAO,OAA6B,QAA4B;AACrE,WAAI,OAAO,SAAU,eAInB,SAAS,SAEJ,IAAI,gBAAe,OAAO,MAAM;EACzC;EAEQ,YAAY,QACA,QACA,SAA0B;AAC5C,UAAA,GACA,KAAK,SAAS,QACd,KAAK,SAAS,QACV,UACE,QAAQ,aACV,KAAK,WAAW,QAAQ,UACxB,EAAE,KAAK,SAAS,SAET,OAAO,WAAW,WAE3B,KAAK,WAAW,EAAC,OAAO,EAAA;EAE5B;EAEQ;;EACA;;EACA;;EAEA,YAAkC;AACxC,QAAI,KAAK;AACP,aAAO,KAAK;AAEZ,UAAM,IAAI,MAAM,yDAAyD;EAE7E;EAEU,WAAW;AACnB,WAAO,EAAC,OAAO,KAAK,UAAA,GAAa,OAAO,KAAA;EAC1C;EAEA,MAAgB;AACd,WAAO,IAAI,gBAAe,KAAK,UAAA,GAAa,KAAK,QAAQ,IAAI;EAC/D;EAEA,OAAyC;AACvC,QAAI,SAAS,KAAK,UAAA;AAClB,WAAI,UAAU,SAGL,QAAQ,QAAQ,MAAM,EAAE,KAAK,CAAA,eAC3B,WAAW,cAAc,UAAU,CAC3C,IAIM,QAAQ,OAAO,IAAI,MAAM,sCAAsC,CAAC;EAE3E;EAEA,4BAAkC;EAElC;EAEA,UAAgB;AACd,IAAI,KAAK,WACH,KAAK,YACH,EAAE,KAAK,SAAS,SAAS,KAC3B,iBAAiB,KAAK,MAAM,GAIhC,KAAK,SAAS;EAElB;EAEA,SAAS,UAAsC;EAE/C;AACF,GAIa,kBAAN,MAAM,yBAAwB,SAAS;EACpC;EACA;EAER,YAAY,SAA4B;AACtC,UAAA,GAEA,KAAK,UAAU,QAAQ,KAAK,CAAA,SAAS,KAAK,aAAa,KAAY,IAAM;EAC3E;EAEA,KAAK,MAAoB,MAA4B;AASnD,gBAAK,iBAAA,GAEE,IAAI,iBAAgB,KAAK,QAAQ,KAAK,CAAA,SAAQ,KAAK,KAAK,MAAM,IAAI,CAAC,CAAC;EAC7E;EAEA,OAAO,MAAoB,MAA2D;AAIpF,gBAAK,iBAAA,GAKE,EAAE,SAJK,KAAK,QAAQ,KAAK,CAAA,SACjB,KAAK,OAAO,MAAM,IAAI,EACrB,OACf,EACQ;EACX;EAEA,IAAI,MAAoB,UAAsB,cAAmC;AAC/E,WAAO,IAAI,iBAAgB,KAAK,QAAQ;MACpC,CAAA,SAAQ,KAAK,IAAI,MAAM,UAAU,YAAY;MAC7C,CAAA,QAAO;AACL,iBAAS,OAAO;AACd,cAAI,QAAA;AAEN,cAAM;MACR;IAAA,CAAE;EACR;EAEA,IAAI,MAA8B;AAEhC,WAAO,IAAI,iBAAgB,KAAK,QAAQ,KAAK,CAAA,SAAQ,KAAK,IAAI,IAAI,CAAC,CAAC;EACtE;EAEA,MAAgB;AACd,WAAI,KAAK,aACA,KAAK,WAAW,IAAA,IAEhB,IAAI,iBAAgB,KAAK,QAAQ,KAAK,CAAA,SAAQ,KAAK,IAAA,CAAK,CAAC;EAEpE;EAEA,OAAyC;AAKvC,WAAI,KAAK,aACA,KAAK,WAAW,KAAA,IAEhB,KAAK,QAAQ,KAAK,CAAA,SAAQ,KAAK,KAAA,CAAM;EAEhD;EAEA,4BAAkC;AAChC,IAAI,KAAK,aACP,KAAK,WAAW,0BAAA,IAEhB,KAAK,QAAQ,KAAK,CAAA,QAAO;AACvB,UAAI,0BAAA;IACN,GAAG,CAAA,QAAO;IAEV,CAAC;EAEL;EAEA,UAAgB;AACd,IAAI,KAAK,aACP,KAAK,WAAW,QAAA,IAEhB,KAAK,QAAQ,KAAK,CAAA,SAAQ;AACxB,WAAK,QAAA;IACP,GAAG,CAAA,QAAO;IAEV,CAAC;EAEL;EAEA,SAAS,UAAsC;AAC7C,IAAI,KAAK,aACP,KAAK,WAAW,SAAS,QAAQ,IAEjC,KAAK,QAAQ,KAAK,CAAA,SAAQ;AACxB,WAAK,SAAS,QAAQ;IACxB,GAAG,QAAQ;EAEf;AACF,GC36DM,eAAN,MAAuC;EACrC,WAAW,MAAuB;AAChC,UAAM,IAAI,MAAM,oDAAoD;EACtE;EACA,cAAc,MAAuB;AACnC,UAAM,IAAI,MAAM,oDAAoD;EACtE;EACA,UAAU,MAAsC;EAEhD;EACA,SAAS,KAA4B;EAAC;EACtC,WAAW,UAAiC;AAC1C,UAAM,IAAI,MAAM,6CAA6C;EAC/D;EAEA,YAAY,OAA4B;EAAC;AAC3C,GAEM,gBAAgB,IAAI,aAAA,GAGpB,cAAmC;EACvC;EAAO;EAAW;EAAY;EAAgB;EAAa;EAAW;EAAU;;AAElF,GAsBa,aAAN,MAAM,YAAW;EACd,YAAoB,UAA4B,QAAgC;AAA5D,SAAA,WAAA,UAA4B,KAAA,SAAA;EAAiC;;;;;;;;;EAUzF,OAAc,UACV,OAAgB,QAAiB,WAAqB,eAAe,QAC3D;AACZ,QAAI,aAAa,IAAI,YAAW,UAAU,MAAM;AAChD,QAAI;AACF,aAAO,WAAW,cAAc,OAAO,QAAQ,CAAC;IAClD,SAAS,KAAK;AACZ,UAAI,WAAW;AACb,YAAI;AACF,mBAAS,SAAS,WAAW,OAAO;QACtC,QAAc;QAEd;AAEF,YAAM;IACR;EACF;EAEQ;EAEA,cAAc,OAAgB,QAA4B,OAAwB;AACxF,QAAI,SAAS;AACX,YAAM,IAAI;QACN;MAAA;AAIN,YADW,WAAW,KAAK,GACnB;MACN,KAAK,eAAe;AAClB,YAAI;AACJ,YAAI;AACF,gBAAM,2BAA2B,KAAK;QACxC,QAAc;AACZ,gBAAM;QACR;AACA,cAAM,IAAI,UAAU,GAAG;MACzB;MAEA,KAAK;AACH,eAAI,OAAO,SAAU,YAAY,CAAC,SAAS,KAAK,IAC1C,UAAU,QACL,CAAC,KAAK,IACJ,UAAU,SACZ,CAAC,MAAM,IAEP,CAAC,KAAK,IAIR;MAGX,KAAK,UAAU;AACb,YAAI,SAAkC,OAClC,SAAkC,CAAA;AACtC,iBAAS,OAAO;AACd,iBAAO,GAAG,IAAI,KAAK,cAAc,OAAO,GAAG,GAAG,QAAQ,QAAQ,CAAC;AAEjE,eAAO;MACT;MAEA,KAAK,SAAS;AACZ,YAAI,QAAwB,OACxB,MAAM,MAAM,QACZ,SAAS,IAAI,MAAM,GAAG;AAC1B,iBAAS,IAAI,GAAG,IAAI,KAAK;AACvB,iBAAO,CAAC,IAAI,KAAK,cAAc,MAAM,CAAC,GAAG,OAAO,QAAQ,CAAC;AAG3D,eAAO,CAAC,MAAM;MAChB;MAEA,KAAK;AACH,eAAO,CAAC,UAAmB,MAAO,SAAA,CAAU;MAE9C,KAAK;AACH,eAAO,CAAC,QAAe,MAAO,QAAA,CAAS;MAEzC,KAAK,SAAS;AACZ,YAAI,QAAQ;AACZ,eAAI,MAAM,WACD,CAAC,SAAS,MAAM,SAAS,EAAC,aAAa,GAAA,CAAK,CAAC,IAE7C;UAAC;UACJ,KAAK,OAAO,aAAa,MAAM,MAAM,KAAiB,EAAE,QAAQ,OAAO,EAAE,CAAC;QAAA;MAElF;MAEA,KAAK;AAGH,eAAO,CAAC,WAAW,CAAC,GAA+B,KAAK,CAAC;MAE3D,KAAK,WAAW;AACd,YAAI,MAAe,OACf,OAAgC,CAAA;AAMpC,QAAI,IAAI,WAAW,UAAO,KAAK,SAAS,IAAI;AAE5C,YAAI,UAAU,CAAC,GAAoC,IAAI,OAAO;AAO9D,YANI,QAAQ,SAAS,MAGnB,KAAK,UAAU,UAGb,IAAI;AACN,eAAK,OAAO,KAAK,cAAc,IAAI,MAAM,KAAK,QAAQ,CAAC,GAOvD,KAAK,SAAe,IAAK,UAAU;iBAC1B,IAAI,SAAS,UACpB,CAAC,CAAC,OAAO,QAAQ,WAAW,SAAS,QAAQ,EAAE,SAAS,IAAI,MAAM,GAAG;AAOvE,cAAI,cAAc,IAAI,YAAA,GAElB,WAAW,IAAI,eAA2B;YAC5C,MAAM,MAAM,YAAY;AACtB,kBAAI;AAMF,2BAAW,QAAQ,IAAI,WAAW,MAAM,WAAW,CAAe,GAClE,WAAW,MAAA;cACb,SAAS,KAAK;AACZ,2BAAW,MAAM,GAAG;cACtB;YACF;UAAA,CACD,GAMG,OAAO,WAAW,yBAAyB,QAAQ,GACnD,WAAW,KAAK,SAAS,WAAW,UAAU,IAAI;AACtD,eAAK,OAAO,CAAC,YAAY,QAAQ,GACjC,KAAK,SAAe,IAAK,UAAU;QACrC;AAEA,QAAI,IAAI,SAAS,IAAI,UAAU,cAAW,KAAK,QAAQ,IAAI,QACvD,IAAI,aAAa,aAAU,KAAK,WAAW,IAAI,WAC/C,IAAI,cAAW,KAAK,YAAY,IAAI,YAIpC,IAAI,QAAQ,IAAI,SAAS,WAAQ,KAAK,OAAO,IAAI,OACjD,IAAI,eAAe,IAAI,gBAAgB,kBACzC,KAAK,cAAc,IAAI,cAErB,IAAI,YAAY,IAAI,aAAa,mBAAgB,KAAK,WAAW,IAAI,WACrE,IAAI,mBAAgB,KAAK,iBAAiB,IAAI,iBAC9C,IAAI,cAAW,KAAK,YAAY,IAAI;AAIxC,YAAI,QAAQ;AACZ,eAAI,MAAM,OAAI,KAAK,KAAK,MAAM,KAC1B,MAAM,sBAAsB,MAAM,uBAAuB,gBAC3D,KAAK,qBAAqB,MAAM,qBAQ3B,CAAC,WAAW,IAAI,KAAK,IAAI;MAClC;MAEA,KAAK,YAAY;AACf,YAAI,OAAiB,OACjB,OAAO,KAAK,cAAc,KAAK,MAAM,MAAM,QAAQ,CAAC,GACpD,OAAgC,CAAA;AAEpC,QAAI,KAAK,WAAW,QAAK,KAAK,SAAS,KAAK,SACxC,KAAK,eAAY,KAAK,aAAa,KAAK;AAE5C,YAAI,UAAU,CAAC,GAAoC,KAAK,OAAO;AAC/D,QAAI,QAAQ,SAAS,MAGnB,KAAK,UAAU;AAKjB,YAAI,SAAS;AAKb,YAJI,OAAO,OAAI,KAAK,KAAK,OAAO,KAC5B,OAAO,cAAc,OAAO,eAAe,gBAC7C,KAAK,aAAa,OAAO,aAEvB,OAAO;AAET,gBAAM,IAAI,UAAU,oDAAoD;AAG1E,eAAO,CAAC,YAAY,MAAM,IAAI;MAChC;MAEA,KAAK,SAAS;AACZ,YAAI,IAAW,OAOX,YAAY,KAAK,SAAS,YAAY,CAAC;AAC3C,QAAI,cACF,IAAI;AAGN,YAAI,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO;AACxC,eAAI,aAAa,UAAU,SACzB,OAAO,KAAK,UAAU,KAAK,GAEtB;MACT;MAEA,KAAK;AACH,eAAO,CAAC,WAAW;MAErB,KAAK;MACL,KAAK,eAAe;AAClB,YAAI,CAAC,KAAK;AACR,gBAAM,IAAI,MAAM,4CAA4C;AAG9D,YAAI,EAAC,MAAM,cAAA,IAAiB,kBAA2B,KAAK,GACxD,WAAW,KAAK,SAAS,UAAU,IAAI;AAC3C,eAAI,aAAa,SACX,gBAEE,cAAc,SAAS,IAClB,CAAC,YAAY,UAAU,aAAa,IAEpC,CAAC,YAAY,QAAQ,IAGvB,CAAC,UAAU,QAAQ,KAI1B,gBACF,OAAO,KAAK,IAAI,aAAa,IAE7B,OAAO,KAAK,IAAA,GAGP,KAAK,cAAc,gBAAgB,YAAY,UAAU,IAAI;MACtE;MAEA,KAAK;MACL,KAAK,cAAc;AACjB,YAAI,CAAC,KAAK;AACR,gBAAM,IAAI,MAAM,4CAA4C;AAG9D,YAAI,OAAO,KAAK,OAAO,oBAAwC,OAAO,MAAM;AAC5E,eAAO,KAAK,cAAc,UAAU,IAAI;MAC1C;MAEA,KAAK,gBAAgB;AACnB,YAAI,CAAC,KAAK;AACR,gBAAM,IAAI,MAAM,4CAA4C;AAG9D,YAAI,OAAO,KAAK,OAAO,oBAA+B,OAAO,MAAM;AACnE,eAAO,KAAK,cAAc,WAAW,IAAI;MAC3C;MAEA,KAAK,YAAY;AACf,YAAI,CAAC,KAAK;AACR,gBAAM,IAAI,MAAM,iDAAiD;AAGnE,YAAI,OAAO,KAAK,OAAO,yBAAyC,OAAO,MAAM;AAC7E,eAAO,KAAK,cAAc,YAAY,IAAI;MAC5C;MAEA,KAAK,YAAY;AACf,YAAI,CAAC,KAAK;AACR,gBAAM,IAAI,MAAM,iDAAiD;AAGnE,YAAI,KAAqB,OACrB,OAAO,KAAK,OAAO,yBAAyB,IAAI,MAAM;AAK1D,eAAO,CAAC,YAFO,KAAK,SAAS,WAAW,IAAI,IAAI,CAEpB;MAC9B;MAEA;AAEE,cAAM,IAAI,MAAM,aAAa;IAAA;EAEnC;EAEQ,cAAc,MAAyC,MAAyB;AACtF,IAAK,KAAK,YAAS,KAAK,UAAU,CAAA;AAClC,QAAI,WAAW,SAAS,YAAY,KAAK,SAAS,cAAc,IAAI,IAChC,KAAK,SAAS,WAAW,IAAI;AACjE,gBAAK,QAAQ,KAAK,QAAQ,GACnB,CAAC,MAAM,QAAQ;EACxB;AACF;AAuBA,IAAM,eAAN,MAAuC;EACrC,WAAW,KAAsB;AAC/B,UAAM,IAAI,MAAM,sDAAsD;EACxE;EACA,cAAc,KAAsB;AAClC,UAAM,IAAI,MAAM,sDAAsD;EACxE;EACA,UAAU,KAAqC;EAE/C;EACA,gBAAgB,UAA2B;AACzC,UAAM,IAAI,MAAM,uDAAuD;EACzE;AACF,GAEM,gBAAgB,IAAI,aAAA;AAO1B,SAAS,qBAAqB,SAAkB,MAAkC;AAEhF,MAAI,UAAU,IAAI,SAAS,IAAI,EAAE,YAAA,EAAc,KAAK,CAAA,gBAAe;AACjE,QAAI,QAAQ,IAAI,WAAW,WAAW,GAClC,SAAS,IAAI,QAAQ,SAAS,EAAC,MAAM,MAAA,CAAM;AAC/C,WAAO,IAAI,gBAAgB,WAAW,cAAc,MAAM,CAAC;EAC7D,CAAC;AACD,SAAO,IAAI,WAAW,IAAI,gBAAgB,OAAO,GAAG,CAAA,CAAE;AACxD;AAKO,IAAM,YAAN,MAAM,WAAU;EACrB,YAAoB,UAAoB;AAApB,SAAA,WAAA;EAAqB;EAEjC,QAAoB,CAAA;EACpB,WAA6B,CAAA;EAE9B,SAAS,OAA4B;AAC1C,QAAI,UAAU,WAAW,YAAY,KAAK,OAAO,KAAK,QAAQ;AAC9D,QAAI;AACF,qBAAQ,QAAQ,KAAK,aAAa,OAAO,SAAS,OAAO,GAClD;IACT,SAAS,KAAK;AACZ,oBAAQ,QAAA,GACF;IACR;EACF;;EAGO,aAAa,OAA4B;AAC9C,WAAO,KAAK,SAAS,gBAAgB,KAAK,CAAC;EAC7C;EAEQ,aAAa,OAAgB,QAAgB,UAAoC;AACvF,QAAI,iBAAiB,OAAO;AAC1B,UAAI,MAAM,UAAU,KAAK,MAAM,CAAC,aAAa,OAAO;AAElD,YAAI,SAAS,MAAM,CAAC;AACpB,iBAAS,IAAI,GAAG,IAAI,OAAO,QAAQ;AACjC,iBAAO,CAAC,IAAI,KAAK,aAAa,OAAO,CAAC,GAAG,QAAQ,CAAC;AAEpD,eAAO;MACT,MAAO,SAAQ,MAAM,CAAC,GAAA;QACpB,KAAK;AACH,cAAI,OAAO,MAAM,CAAC,KAAK;AACrB,mBAAO,OAAO,MAAM,CAAC,CAAC;AAExB;QACF,KAAK;AACH,cAAI,OAAO,MAAM,CAAC,KAAK;AACrB,mBAAO,IAAI,KAAK,MAAM,CAAC,CAAC;AAE1B;QACF,KAAK,SAAS;AACZ,cAAI,MAAM;AACV,cAAI,OAAO,MAAM,CAAC,KAAK,UAAU;AAC/B,gBAAI,IAAI;AACN,qBAAO,IAAI,WAAW,MAAM,CAAC,CAAC;AACzB;AACL,kBAAI,KAAK,KAAK,MAAM,CAAC,CAAC,GAClB,MAAM,GAAG,QACT,QAAQ,IAAI,WAAW,GAAG;AAC9B,uBAAS,IAAI,GAAG,IAAI,KAAK;AACvB,sBAAM,CAAC,IAAI,GAAG,WAAW,CAAC;AAE5B,qBAAO;YACT;UACF;AACA;QACF;QACA,KAAK;AACH,cAAI,MAAM,UAAU,KAAK,OAAO,MAAM,CAAC,KAAM,YAAY,OAAO,MAAM,CAAC,KAAM,UAAU;AACrF,gBAAI,MAAM,YAAY,MAAM,CAAC,CAAC,KAAK,OAC/B,SAAS,IAAI,IAAI,MAAM,CAAC,CAAC;AAC7B,mBAAI,OAAO,MAAM,CAAC,KAAM,aACtB,OAAO,QAAQ,MAAM,CAAC,IAEjB;UACT;AACA;QACF,KAAK;AACH,cAAI,MAAM,WAAW;AACnB;AAEF;QACF,KAAK;AACH,iBAAO;QACT,KAAK;AACH,iBAAO;QACT,KAAK;AACH,iBAAO;QAET,KAAK;AAIH,cAAI,MAAM,WAAW,KAAK,MAAM,CAAC,aAAa;AAC5C,mBAAO,IAAI,QAAQ,MAAM,CAAC,CAAuB;AAEnD;QAEF,KAAK,WAAW;AACd,cAAI,MAAM,WAAW,KAAK,OAAO,MAAM,CAAC,KAAM,SAAU;AACxD,cAAI,MAAM,MAAM,CAAC,GACb,OAAO,MAAM,CAAC;AAClB,cAAI,OAAO,QAAS,YAAY,SAAS,KAAM;AAG/C,cAAI,KAAK,SACP,KAAK,OAAO,KAAK,aAAa,KAAK,MAAM,MAAM,MAAM,GACjD,OAAK,SAAS,QACd,OAAO,KAAK,QAAS,YACrB,KAAK,gBAAgB,cACrB,KAAK,gBAAgB;AAGvB,kBAAM,IAAI,UAAU,8CAA8C;AAGtE,cAAI,KAAK,WACP,KAAK,SAAS,KAAK,aAAa,KAAK,QAAQ,MAAM,QAAQ,GACvD,EAAE,KAAK,kBAAkB;AAC3B,kBAAM,IAAI,UAAU,6CAA6C;AAMrE,cAAI,KAAK,WAAW,EAAE,KAAK,mBAAmB;AAC5C,kBAAM,IAAI,UAAU,0DAA0D;AAIhF,cAAI,SAAS,IAAI,QAAQ,KAAK,IAAmB;AAEjD,cAAI,KAAK,gBAAgB,kBAAkB,OAAO,SAAS,QAAW;AAGpE,gBAAI,UAAU,qBAAqB,QAAQ,KAAK,IAAI;AACpD,wBAAK,SAAS,KAAK,EAAC,SAAS,QAAQ,SAAA,CAAS,GACvC;UACT;AACE,mBAAO;QAEX;QAEA,KAAK,YAAY;AACf,cAAI,MAAM,WAAW,EAAG;AAExB,cAAI,OAAO,KAAK,aAAa,MAAM,CAAC,GAAG,QAAQ,QAAQ;AACvD,cAAI,WAAS,QACT,OAAO,QAAS,YAChB,gBAAgB,cAChB,gBAAgB,gBAGlB,OAAM,IAAI,UAAU,+CAA+C;AAGrE,cAAI,OAAO,MAAM,CAAC;AAClB,cAAI,OAAO,QAAS,YAAY,SAAS,KAAM;AAG/C,cAAI,KAAK;AAGP,kBAAM,IAAI,UAAU,sDAAsD;AAK5E,cAAI,KAAK,WAAW,EAAE,KAAK,mBAAmB;AAC5C,kBAAM,IAAI,UAAU,0DAA0D;AAGhF,iBAAO,IAAI,SAAS,MAAyB,IAAoB;QACnE;QAEA,KAAK;QACL,KAAK,YAAY;AAUf,cANI,MAAM,SAAS,KAAK,MAAM,SAAS,KAMnC,OAAO,MAAM,CAAC,KAAK;AACrB;AAGF,cAAI,OAAO,KAAK,SAAS,UAAU,MAAM,CAAC,CAAC;AAC3C,cAAI,CAAC;AACH,kBAAM,IAAI,MAAM,mCAAmC,MAAM,CAAC,CAAC,EAAE;AAG/D,cAAI,YAAY,MAAM,CAAC,KAAK,YAExB,UAAU,CAACA,UAAmB;AAChC,gBAAI,WAAW;AACb,kBAAI,UAAU,IAAI,WAAWA,OAAM,CAAA,CAAE;AACrC,0BAAK,SAAS,KAAK,EAAC,SAAS,QAAQ,SAAA,CAAS,GACvC;YACT;AACE,0BAAK,MAAM,KAAKA,KAAI,GACb,IAAI,WAAWA,OAAM,CAAA,CAAE;UAElC;AAEA,cAAI,MAAM,UAAU;AAElB,mBAES,QAFL,YAEa,KAAK,IAAI,CAAA,CAAE,IAGX,KAAK,IAAA,CAHO;AAQ/B,cAAI,OAAO,MAAM,CAAC;AAIlB,cAHI,EAAE,gBAAgB,UAGlB,CAAC,KAAK;YACN,CAAA,SAAiB,OAAO,QAAQ,YAAY,OAAO,QAAQ;UAAU;AACvE;AAGF,cAAI,MAAM,UAAU;AAElB,mBAAO,QAAQ,KAAK,IAAI,IAAI,CAAC;AAW/B,cAAI,OAAO,MAAM,CAAC;AAClB,cAAI,EAAE,gBAAgB;AACpB;AAKF,wBADc,IAAI,WAAU,KAAK,QAAQ,EAC1B,SAAS,CAAC,IAAI,CAAC,GAEvB,QAAQ,KAAK,KAAK,MAAM,IAAI,CAAC;QACtC;QAEA,KAAK,SAAS;AACZ,cAAI,MAAM,WAAW,KACjB,OAAO,MAAM,CAAC,KAAM,YACpB,EAAE,MAAM,CAAC,aAAa,UACtB,EAAE,MAAM,CAAC,aAAa,UACtB,EAAE,MAAM,CAAC,aAAa;AACxB;AAGF,cAAI,OAAO,KAAK,SAAS,UAAU,MAAM,CAAC,CAAC;AAC3C,cAAI,CAAC;AACH,kBAAM,IAAI,MAAM,mCAAmC,MAAM,CAAC,CAAC,EAAE;AAG/D,cAAI,OAAO,MAAM,CAAC;AAClB,cAAI,CAAC,KAAK;YACN,CAAA,SAAiB,OAAO,QAAQ,YAAY,OAAO,QAAQ;UAAU;AACvE;AAGF,cAAI,WAAuB,MAAM,CAAC,EAAE,IAAI,CAAA,QAAO;AAC7C,gBAAI,EAAE,eAAe,UACjB,IAAI,WAAW,KACd,IAAI,CAAC,MAAM,YAAY,IAAI,CAAC,MAAM,YACnC,OAAO,IAAI,CAAC,KAAM;AACpB,oBAAM,IAAI,UAAU,wBAAwB,KAAK,UAAU,GAAG,CAAC,EAAE;AAGnE,gBAAI,IAAI,CAAC,MAAM;AACb,qBAAO,KAAK,SAAS,WAAW,IAAI,CAAC,CAAC;AACjC;AACL,kBAAI,MAAM,KAAK,SAAS,UAAU,IAAI,CAAC,CAAC;AACxC,kBAAI,CAAC;AACH,sBAAM,IAAI,MAAM,mCAAmC,IAAI,CAAC,CAAC,EAAE;AAE7D,qBAAO,IAAI,IAAA;YACb;UACF,CAAC,GAEG,eAAe,MAAM,CAAC,GAEtB,aAAa,KAAK,IAAI,MAAM,UAAU,YAAY,GAElD,UAAU,IAAI,WAAW,YAAY,CAAA,CAAE;AAC3C,sBAAK,SAAS,KAAK,EAAC,SAAS,QAAQ,SAAA,CAAS,GACvC;QACT;QAEA,KAAK;QACL,KAAK;AASH,cAAI,OAAO,MAAM,CAAC,KAAK;AACrB,gBAAI,MAAM,CAAC,KAAK,WAAW;AACzB,kBAAI,OAAO,KAAK,SAAS,cAAc,MAAM,CAAC,CAAC,GAC3C,UAAU,IAAI,WAAW,MAAM,CAAA,CAAE;AACrC,0BAAK,SAAS,KAAK,EAAC,QAAQ,UAAU,QAAA,CAAQ,GACvC;YACT,OAAO;AACL,kBAAI,OAAO,KAAK,SAAS,WAAW,MAAM,CAAC,CAAC;AAC5C,0BAAK,MAAM,KAAK,IAAI,GACb,IAAI,QAAQ,IAAI;YACzB;AAEF;QAEF,KAAK;AAGH,cAAI,OAAO,MAAM,CAAC,KAAK,UAAU;AAC/B,gBAAI,OAAO,KAAK,SAAS,WAAW,MAAM,CAAC,CAAC,GACxC,SAAS,WAAW,6BAA6B,IAAI;AAEzD,wBAAK,MAAM,KAAK,IAAI,GACb;UACT;AACA;QAEF,KAAK;AAGH,cAAI,OAAO,MAAM,CAAC,KAAK,UAAU;AAC/B,gBAAI,SAAS,KAAK,SAAS,gBAAgB,MAAM,CAAC,CAAC,GAG/C,OAAO,WAAW,yBAAyB,MAAM;AACrD,wBAAK,MAAM,KAAK,IAAI,GACb;UACT;AACA;MAAA;AAEJ,YAAM,IAAI,UAAU,0BAA0B,KAAK,UAAU,KAAK,CAAC,EAAE;IACvE,WAAW,iBAAiB,QAAQ;AAClC,UAAI,SAAkC;AACtC,eAAS,OAAO;AACd,QAAI,OAAO,OAAO,aAAa,QAAQ,YAWrC,KAAK,aAAa,OAAO,GAAG,GAAG,QAAQ,GAAG,GAC1C,OAAO,OAAO,GAAG,KAEjB,OAAO,GAAG,IAAI,KAAK,aAAa,OAAO,GAAG,GAAG,QAAQ,GAAG;AAG5D,aAAO;IACT;AAEE,aAAO;EAEX;AACF;AC9wBA,IAAM,mBAAN,MAAuB;EACrB,YAAmB,SAAgC,UAAkB,SAAkB;AAApE,SAAA,UAAA,SAAgC,KAAA,WAAA,UAC7C,YACF,KAAK,aAAa,QAAQ,cAAA;EAE9B;EAEO,gBAAwB;EACxB,iBAAyB;EAExB;EACD;;;EAIC;EAER,QAAQ,YAAsB;AAS5B,QAAI,KAAK,iBAAiB,GAAG;AAE3B,iBAAW,QAAA;AACX;IACF;AAKA,QAHA,KAAK,aAAa,YAClB,KAAK,YAAA,GAED,KAAK,uBAAuB;AAG9B,eAAS,KAAK,KAAK,uBAAuB;AACxC,YAAI,WAAW,KAAK,QAAQ,kBAAkB,CAAC,GAC3C,WAAW,KAAK,QAAQ,kBAAkB;AAC9C,mBAAW,SAAS,QAAQ,GACxB,KAAK,QAAQ,kBAAkB,QAAQ,MAAM,WAM/C,OAAO,KAAK,QAAQ,kBAAkB,QAAQ,IAG9C,OAAO,KAAK,QAAQ,kBAAkB,CAAC;MAE3C;AACA,WAAK,wBAAwB;IAC/B;AAEA,IAAI,KAAK,eACP,KAAK,WAAW,QAAA,GAChB,KAAK,aAAa;EAEtB;EAEA,MAAM,kBAAuC;AAC3C,WAAK,KAAK,eACR,KAAK,QAAQ,SAAS,KAAK,QAAQ,GACnC,KAAK,aAAa,QAAQ,cAAA,IAE5B,MAAM,KAAK,WAAW,SACf,KAAK,WAAY,KAAA;EAC1B;EAEA,UAAU;AACR,IAAI,KAAK,aACP,KAAK,WAAW,QAAA,KAEhB,KAAK,MAAM,IAAI,MAAM,uDAAuD,CAAC,GAC7E,KAAK,YAAA;EAET;EAEA,MAAM,OAAY;AAChB,IAAK,KAAK,eACR,KAAK,aAAa,IAAI,cAAc,KAAK,GAErC,KAAK,eACP,KAAK,WAAW,OAAO,KAAK,GAC5B,KAAK,aAAa,SAKpB,KAAK,wBAAwB;EAEjC;EAEA,SAAS,UAAsC;AAC7C,QAAI,KAAK;AACP,WAAK,WAAW,SAAS,QAAQ;SAC5B;AACL,UAAI,QAAQ,KAAK,QAAQ,kBAAkB;AAC3C,WAAK,QAAQ,kBAAkB,KAAK,QAAQ,GAEvC,KAAK,0BAAuB,KAAK,wBAAwB,CAAA,IAC9D,KAAK,sBAAsB,KAAK,KAAK;IACvC;EACF;EAEQ,cAAc;AACpB,IAAI,KAAK,iBAAiB,MACxB,KAAK,QAAQ,YAAY,KAAK,UAAU,KAAK,cAAc,GAC3D,KAAK,iBAAiB;EAE1B;AACF,GAEM,gBAAN,MAAM,uBAAsB,SAAS;;;;EAKnC,YAAmB,WAAoB,OAAyB;AAC9D,UAAA,GADiB,KAAA,YAAA,WAEjB,EAAE,MAAM,eACR,KAAK,QAAQ;EACf;EARO;EAUP,YAAY,MAAmC;AAC7C,WAAO;EACT;EAEA,WAA6B;AAC3B,QAAI,KAAK;AACP,aAAO,KAAK;AAIZ,UAAM,IAAI,MAAM,0CAA0C;EAE9D;;;EAKA,KAAK,MAAoB,MAA4B;AACnD,QAAI,QAAQ,KAAK,SAAA;AACjB,WAAI,MAAM,aACD,MAAM,WAAW,KAAK,MAAM,IAAI,IAEhC,MAAM,QAAQ,SAAS,MAAM,UAAU,MAAM,IAAI;EAE5D;EAEA,OAAO,MAAoB,MAA2D;AACpF,QAAI,QAAQ,KAAK,SAAA;AACjB,WAAI,MAAM,aACD,MAAM,WAAW,OAAO,MAAM,IAAI,IAElC,MAAM,QAAQ,WAAW,MAAM,UAAU,MAAM,IAAI;EAE9D;EAEA,IAAI,MAAoB,UAAsB,cAAmC;AAC/E,QAAI;AACJ,QAAI;AACF,cAAQ,KAAK,SAAA;IACf,SAAS,KAAK;AACZ,eAAS,OAAO;AACd,YAAI,QAAA;AAEN,YAAM;IACR;AAEA,WAAI,MAAM,aACD,MAAM,WAAW,IAAI,MAAM,UAAU,YAAY,IAEjD,MAAM,QAAQ,QAAQ,MAAM,UAAU,MAAM,UAAU,YAAY;EAE7E;EAEA,IAAI,MAA8B;AAChC,QAAI,QAAQ,KAAK,SAAA;AACjB,WAAI,MAAM,aACD,MAAM,WAAW,IAAI,IAAI,IAEzB,MAAM,QAAQ,SAAS,MAAM,UAAU,IAAI;EAEtD;EAEA,MAAqB;AACnB,WAAO,IAAI,eAAc,IAAO,KAAK,SAAA,CAAU;EACjD;EAEA,OAAyC;AACvC,QAAI,QAAQ,KAAK,SAAA;AAEjB,QAAI,CAAC,KAAK;AACR,YAAM,IAAI,MAAM,uDAAuD;AAGzE,WAAI,MAAM,aACD,MAAM,WAAW,KAAA,IAGnB,MAAM,gBAAA;EACf;EAEA,4BAAkC;EAIlC;EAEA,UAAgB;AACd,QAAI,QAAQ,KAAK;AACjB,SAAK,QAAQ,QACT,SACE,EAAE,MAAM,kBAAkB,KAC5B,MAAM,QAAA;EAGZ;EAEA,SAAS,UAAsC;AAC7C,IAAI,KAAK,SACP,KAAK,MAAM,SAAS,QAAQ;EAEhC;AACF,GAEM,cAAN,cAA0B,cAAc;EAC9B;EAER,YAAY,OAAyB;AACnC,UAAM,IAAO,KAAK,GAClB,KAAK,UAAU,MAAM;EACvB;EAEA,UAAgB;AACd,QAAI,KAAK,SAAS;AAChB,UAAI,UAAU,KAAK;AACnB,WAAK,UAAU,QACf,QAAQ,SAAA;IACV;EACF;AACF,GAqBM,iBAAN,MAAmD;EAsBjD,YAAoB,WAAyB,UACjC,SAA4B;AADpB,SAAA,YAAA,WACR,KAAA,UAAA,SAEV,KAAK,QAAQ,KAAK,EAAC,MAAM,UAAU,UAAU,EAAA,CAAE,GAG/C,KAAK,QAAQ,KAAK,IAAI,iBAAiB,MAAM,GAAG,EAAK,CAAC;AAEtD,QAAI,YACA,eAAe,IAAI,QAAe,CAAC,SAAS,WAAW;AAAE,mBAAa;IAAQ,CAAC;AACnF,SAAK,iBAAiB,YAEtB,KAAK,SAAS,YAAY,EAAE,MAAM,CAAA,QAAO,KAAK,MAAM,GAAG,CAAC;EAC1D;EAlCQ,UAAmC,CAAA;EACnC,iBAAA,oBAA8C,IAAA;EAC9C,UAAmC,CAAA;EACnC;EACA;;;;EAKA,eAAe;;EAGf;;EAGA,YAAY;;;EAIpB,oBAA8C,CAAA;;EAkB9C,gBAA+B;AAC7B,WAAO,IAAI,YAAY,KAAK,QAAQ,CAAC,CAAC;EACxC;EAEA,WAAiB;AAGf,SAAK,MAAM,IAAI,MAAM,sDAAsD,GAAG,EAAK;EACrF;EAEA,WAAW,MAA0B;AACnC,QAAI,KAAK,YAAa,OAAM,KAAK;AAEjC,QAAI,mBAAmB,KAAK,eAAe,IAAI,IAAI;AACnD,QAAI,qBAAqB;AACvB,eAAE,KAAK,QAAQ,gBAAgB,EAAE,UAC1B;AACF;AACL,UAAI,WAAW,KAAK;AACpB,kBAAK,QAAQ,QAAQ,IAAI,EAAE,MAAM,UAAU,EAAA,GAC3C,KAAK,eAAe,IAAI,MAAM,QAAQ,GAE/B;IACT;EACF;EAEA,cAAc,MAA0B;AACtC,QAAI,KAAK,YAAa,OAAM,KAAK;AAGjC,QAAI,WAAW,KAAK;AACpB,gBAAK,QAAQ,QAAQ,IAAI,EAAE,MAAM,UAAU,EAAA,GAC3C,KAAK,eAAe,IAAI,MAAM,QAAQ,GAGtC,KAAK,sBAAsB,QAAQ,GAC5B;EACT;EAEA,SAAS,KAA4B;AACnC,aAAS,MAAM;AACb,WAAK,cAAc,IAAI,CAAC;EAE5B;EAEQ,cAAc,UAAoB,UAAkB;AAC1D,QAAI,QAAQ,KAAK,QAAQ,QAAQ;AACjC,QAAI,CAAC;AACH,YAAM,IAAI,MAAM,sBAAsB,QAAQ,EAAE;AAElD,QAAI,MAAM,WAAW;AACnB,YAAM,IAAI,MAAM,+BAA+B,MAAM,QAAQ,MAAM,QAAQ,EAAE;AAE/E,UAAM,YAAY,UACd,MAAM,aAAa,MACrB,OAAO,KAAK,QAAQ,QAAQ,GAC5B,KAAK,eAAe,OAAO,MAAM,IAAI,GACrC,MAAM,KAAK,QAAA;EAEf;EAEA,YAAY,OAA4B;AACtC,QAAI,KAAK,QAAQ;AACf,aAAO,KAAK,QAAQ,YAAY,KAAK;EAEzC;EAEQ,sBAAsB,UAAoB;AAChD,QAAI,MAAM,KAAK,QAAQ,QAAQ;AAC/B,QAAI,CAAC;AACH,YAAM,IAAI,MAAM,sBAAsB,QAAQ,EAAE;AAElD,QAAI,CAAC,IAAI,MAAM;AACb,UAAI,UAAU,YAAY;AACxB,YAAI,OAAO,IAAI;AACf,mBAAS;AACP,cAAI,UAAU,MAAM,KAAK,KAAA;AACzB,cAAI,QAAQ,iBAAiB,SAAS;AACpC,gBAAI,EAAC,MAAM,OAAO,cAAA,IAAiB,kBAAkB,QAAQ,KAAK;AAClE,gBAAI,iBAAiB,cAAc,UAAU,KACvC,KAAK,UAAU,IAAI,MAAM,QAAW;AAOtC,qBAAO;AACP;YACF;UAEJ;AAEA,iBAAO;QACT;MACF,GAEI,cAAc,IAAI;AAEtB,QAAE,KAAK,WACP,IAAI,OAAO,QAAA,EAAU;QACnB,CAAA,YAAW;AAGT,cAAI,QAAQ,WAAW,UAAU,QAAQ,OAAO,QAAW,MAAM,OAAO;AACxE,eAAK,KAAK,CAAC,WAAW,UAAU,KAAK,CAAC,GAClC,eAAa,KAAK,cAAc,UAAU,CAAC;QACjD;QACA,CAAA,UAAS;AACP,eAAK,KAAK,CAAC,UAAU,UAAU,WAAW,UAAU,OAAO,QAAW,IAAI,CAAC,CAAC,GACxE,eAAa,KAAK,cAAc,UAAU,CAAC;QACjD;MAAA,EACA;QACA,CAAA,UAAS;AAGP,cAAI;AACF,iBAAK,KAAK,CAAC,UAAU,UAAU,WAAW,UAAU,OAAO,QAAW,IAAI,CAAC,CAAC,GACxE,eAAa,KAAK,cAAc,UAAU,CAAC;UACjD,SAAS,QAAQ;AAEf,iBAAK,MAAM,MAAM;UACnB;QACF;MAAA,EACA,QAAQ,MAAM;AACd,QAAI,EAAE,KAAK,cAAc,KACnB,KAAK,eACP,KAAK,YAAY,QAAA;MAGvB,CAAC;IACH;EACF;EAEA,UAAU,MAAsC;AAC9C,QAAI,gBAAgB,iBAAiB,KAAK,SAAS,KAAK,MAAM,YAAY;AACxE,aAAO,KAAK,MAAM;EAItB;EAEA,WAAW,KAA8B;AACvC,QAAI,KAAK,YAAa,OAAM,KAAK;AAEjC,QAAI,QAAQ,KAAK,QAAQ,GAAG;AAC5B,WAAK,UACH,QAAQ,IAAI,iBAAiB,MAAM,KAAK,EAAK,GAC7C,KAAK,QAAQ,GAAG,IAAI,QAEf,IAAI;;MAA4B;MAAO;IAAA;EAChD;EAEA,cAAc,KAAyB;AACrC,QAAI,KAAK,YAAa,OAAM,KAAK;AAEjC,QAAI,KAAK,QAAQ,GAAG;AAElB,aAAO,IAAI,cAAc,IAAI;QACzB;MAAA,CAA4E;AAIlF,QAAI,QAAQ,IAAI,iBAAiB,MAAM,KAAK,EAAI;AAChD,gBAAK,QAAQ,GAAG,IAAI,OACb,IAAI;;MAA4B;MAAM;IAAA;EAC/C;EAEA,UAAU,KAAqC;AAC7C,WAAO,KAAK,QAAQ,GAAG,GAAG;EAC5B;EAEA,gBAAgB,UAAoC;AAClD,QAAI,QAAQ,KAAK,QAAQ,QAAQ;AACjC,QAAI,CAAC,SAAS,CAAC,MAAM;AACnB,YAAM,IAAI,MAAM,UAAU,QAAQ,0DAA0D;AAE9F,QAAI,WAAW,MAAM;AACrB,iBAAM,eAAe,QACd;EACT;EAEA,WAAW,UAA0B,cAAkC;AACrE,QAAI,KAAK,YAAa,OAAM,KAAK;AAEjC,SAAK,KAAK,CAAC,MAAM,CAAC;AAElB,QAAI,WAAW,KAAK,QAAQ,QAExB,QAAQ,IAAI,iBAAiB,MAAM,UAAU,EAAK;AACtD,SAAK,QAAQ,KAAK,KAAK;AAGvB,QAAI,OAAO,IAAI;;MAA4B;MAAO;IAAA,GAC9C,WAAW,WAAW,6BAA6B,IAAI;AAC3D,oBAAS,OAAO,QAAQ,EAAE,MAAM,MAAM;IAItC,CAAC,EAAE,QAAQ,MAAM,aAAa,QAAA,CAAS,GAEhC;EACT;;EAGQ,KAAK,KAAkB;AAC7B,QAAI,KAAK,gBAAgB;AAEvB,aAAO;AAGT,QAAI;AACJ,QAAI;AACF,gBAAU,KAAK,UAAU,GAAG;IAC9B,SAAS,KAAK;AAGZ,UAAI;AAAE,aAAK,MAAM,GAAG;MAAG,QAAe;MAAC;AACvC,YAAM;IACR;AAEA,gBAAK,UAAU,KAAK,OAAO,EAGtB,MAAM,CAAA,QAAO,KAAK,MAAM,KAAK,EAAK,CAAC,GAEjC,QAAQ;EACjB;EAEA,SAAS,IAAc,MAAoB,MAAkC;AAC3E,QAAI,KAAK,YAAa,OAAM,KAAK;AAEjC,QAAI,QAAoB,CAAC,YAAY,IAAI,IAAI;AAC7C,QAAI,MAAM;AACR,UAAI,UAAU,WAAW,UAAU,KAAK,OAAO,QAAW,MAAM,IAAI;AAIpE,YAAM,KAAsB,QAAS,CAAC,CAAC;IAIzC;AACA,SAAK,KAAK,CAAC,QAAQ,KAAK,CAAC;AAEzB,QAAI,QAAQ,IAAI,iBAAiB,MAAM,KAAK,QAAQ,QAAQ,EAAK;AACjE,gBAAK,QAAQ,KAAK,KAAK,GAChB,IAAI;;MAA4B;MAAM;IAAA;EAC/C;EAEA,WAAW,IAAc,MAAoB,MACA;AAC3C,QAAI,KAAK,YAAa,OAAM,KAAK;AAEjC,QAAI,QAAoB,CAAC,YAAY,IAAI,IAAI,GACzC,UAAU,WAAW,UAAU,KAAK,OAAO,QAAW,MAAM,IAAI;AAIpE,UAAM,KAAsB,QAAS,CAAC,CAAC;AAEvC,QAAI,OAAO,KAAK,KAAK,CAAC,UAAU,KAAK,CAAC,GAMlC,WAAW,KAAK,QAAQ,QACxB,QAAQ,IAAI;MAAiB;MAAM;;MAAsB;IAAA;AAC7D,iBAAM,iBAAiB,GACvB,MAAM,gBAAgB,GACtB,KAAK,QAAQ,KAAK,KAAK,GAUhB,EAAE,SALK,MAAM,gBAAA,EAAkB;MACpC,CAAA,MAAK;AAAE,UAAE,QAAA,GAAW,OAAO,KAAK,QAAQ,QAAQ;MAAG;MACnD,CAAA,QAAO;AAAE,qBAAO,KAAK,QAAQ,QAAQ,GAAS;MAAK;IAAA,GAGnC,KAAA;EACpB;EAEA,QAAQ,IAAc,MAAoB,UAAsB,cAC5C;AAClB,QAAI,KAAK,aAAa;AACpB,eAAS,OAAO;AACd,YAAI,QAAA;AAEN,YAAM,KAAK;IACb;AAEA,QAAI,mBAAmB,SAAS,IAAI,CAAA,SAAQ;AAC1C,UAAI,WAAW,KAAK,UAAU,IAAI;AAClC,aAAI,aAAa,SACR,CAAC,UAAU,QAAQ,IAEnB,CAAC,UAAU,KAAK,WAAW,IAAI,CAAC;IAE3C,CAAC,GAEG,QAAQ,CAAC,SAAS,IAAI,MAAM,kBAAkB,YAAY;AAE9D,SAAK,KAAK,CAAC,QAAQ,KAAK,CAAC;AAEzB,QAAI,QAAQ,IAAI,iBAAiB,MAAM,KAAK,QAAQ,QAAQ,EAAK;AACjE,gBAAK,QAAQ,KAAK,KAAK,GAChB,IAAI;;MAA4B;MAAM;IAAA;EAC/C;EAEA,SAAS,IAAc;AACrB,QAAI,KAAK,YAAa,OAAM,KAAK;AAEjC,SAAK,KAAK,CAAC,QAAQ,EAAE,CAAC;EACxB;EAEA,YAAY,IAAc,gBAAwB;AAChD,IAAI,KAAK,gBAET,KAAK,KAAK,CAAC,WAAW,IAAI,cAAc,CAAC,GACzC,OAAO,KAAK,QAAQ,EAAE;EACxB;EAEA,MAAM,OAAY,sBAA+B,IAAM;AAErD,QAAI,KAAK,gBAAgB,QAIzB;UAFA,KAAK,eAAe,KAAK,GAErB;AACF,YAAI;AACF,eAAK,UAAU,KAAK,KAAK,UAAU,CAAC,SAAS,WACxC,UAAU,OAAO,QAAW,IAAI,CAAC,CAAC,CAAC,EACnC,MAAM,CAAA,QAAO;UAAC,CAAC;QACtB,QAAc;QAEd;AAaF,UAVI,UAAU,WAEZ,QAAQ,cAGV,KAAK,cAAc,OACf,KAAK,eACP,KAAK,YAAY,OAAO,KAAK,GAG3B,KAAK,UAAU;AAEjB,YAAI;AACF,eAAK,UAAU,MAAM,KAAK;QAC5B,SAAS,KAAK;AAEZ,kBAAQ,QAAQ,GAAG;QACrB;AAKF,eAAS,KAAK,KAAK;AACjB,YAAI;AACF,eAAK,kBAAkB,CAAC,EAAE,KAAK;QACjC,SAAS,KAAK;AAEZ,kBAAQ,QAAQ,GAAG;QACrB;AAEF,eAAS,KAAK,KAAK;AACjB,aAAK,QAAQ,CAAC,EAAE,MAAM,KAAK;AAE7B,eAAS,KAAK,KAAK;AACjB,aAAK,QAAQ,CAAC,EAAE,KAAK,QAAA;;EAEzB;EAEA,MAAc,SAAS,cAA8B;AACnD,WAAO,CAAC,KAAK,eAAa;AACxB,UAAI,MAAM,KAAK,MAAM,MAAM,QAAQ,KAAK,CAAC,KAAK,UAAU,QAAA,GAAW,YAAY,CAAC,CAAC;AACjF,UAAI,KAAK,YAAa;AAEtB,UAAI,eAAe;AACjB,gBAAQ,IAAI,CAAC,GAAA;UACX,KAAK;AACH,gBAAI,IAAI,SAAS,GAAG;AAClB,kBAAI,UAAU,IAAI,UAAU,IAAI,EAAE,SAAS,IAAI,CAAC,CAAC,GAC7C,OAAO,IAAI,gBAAgB,OAAO;AAKtC,mBAAK,0BAAA,GAEL,KAAK,QAAQ,KAAK,EAAE,MAAM,UAAU,EAAA,CAAG;AACvC;YACF;AACA;UAEF,KAAK,UAAU;AAKb,gBAAI,IAAI,SAAS,GAAG;AAClB,kBAAI,UAAU,IAAI,UAAU,IAAI,EAAE,SAAS,IAAI,CAAC,CAAC,GAC7C,OAAO,IAAI,gBAAgB,OAAO;AACtC,mBAAK,0BAAA;AAEL,kBAAI,WAAW,KAAK,QAAQ;AAC5B,mBAAK,QAAQ,KAAK,EAAE,MAAM,UAAU,GAAG,aAAa,GAAA,CAAM,GAG1D,KAAK,sBAAsB,QAAQ;AACnC;YACF;AACA;UACF;UAEA,KAAK,QAAQ;AAIX,gBAAI,EAAE,UAAU,SAAA,IAAa,IAAI,gBAAA,GAC7B,OAAO,WAAW,yBAAyB,QAAQ;AACvD,iBAAK,QAAQ,KAAK,EAAE,MAAM,UAAU,GAAG,cAAc,SAAA,CAAU;AAC/D;UACF;UAEA,KAAK,QAAQ;AACX,gBAAI,WAAW,IAAI,CAAC;AACpB,gBAAI,OAAO,YAAY,UAAU;AAC/B,mBAAK,sBAAsB,QAAQ;AACnC;YACF;AACA;UACF;UAEA,KAAK;;UACL,KAAK,UAAU;AACb,gBAAI,WAAW,IAAI,CAAC;AACpB,gBAAI,OAAO,YAAY,YAAY,IAAI,SAAS,GAAG;AACjD,kBAAI,MAAM,KAAK,QAAQ,QAAQ;AAC/B,kBAAI;AACF,oBAAI,IAAI,CAAC,KAAK;AACZ,sBAAI,QAAQ,IAAI,gBAAgB,IAAI,UAAU,IAAI,EAAE,SAAS,IAAI,CAAC,CAAC,CAAC,CAAC;qBAChE;AAGL,sBAAI,UAAU,IAAI,UAAU,IAAI,EAAE,SAAS,IAAI,CAAC,CAAC;AACjD,0BAAQ,QAAA,GACR,IAAI,QAAQ,IAAI,cAAc,QAAQ,KAAK,CAAC;gBAC9C;;AAKA,gBAAI,IAAI,CAAC,KAAK,aAGZ,IAAI,UAAU,IAAI,EAAE,SAAS,IAAI,CAAC,CAAC,EAAE,QAAA;AAGzC;YACF;AACA;UACF;UAEA,KAAK,WAAW;AACd,gBAAI,WAAW,IAAI,CAAC,GAChB,WAAW,IAAI,CAAC;AACpB,gBAAI,OAAO,YAAY,YAAY,OAAO,YAAY,UAAU;AAC9D,mBAAK,cAAc,UAAU,QAAQ;AACrC;YACF;AACA;UACF;UAEA,KAAK,SAAS;AACZ,gBAAI,UAAU,IAAI,UAAU,IAAI,EAAE,SAAS,IAAI,CAAC,CAAC;AACjD,oBAAQ,QAAA,GACR,KAAK,MAAM,SAAS,EAAK;AACzB;UACF;QAAA;AAIJ,YAAM,IAAI,MAAM,oBAAoB,KAAK,UAAU,GAAG,CAAC,EAAE;IAC3D;EACF;EAEA,MAAM,QAAuB;AAC3B,QAAI,KAAK;AACP,YAAM,KAAK;AAGb,QAAI,KAAK,YAAY,GAAG;AACtB,UAAI,EAAC,SAAS,SAAS,OAAA,IAAU,QAAQ,cAAA;AACzC,WAAK,cAAc,EAAC,SAAS,OAAA,GAC7B,MAAM;IACR;EACF;EAEA,WAA+C;AAC7C,QAAI,SAAS,EAAC,SAAS,GAAG,SAAS,EAAA;AAEnC,aAAS,KAAK,KAAK;AACjB,QAAE,OAAO;AAEX,aAAS,KAAK,KAAK;AACjB,QAAE,OAAO;AAEX,WAAO;EACT;AACF,GAIa,aAAN,MAAiB;EACtB;EACA;EAEA,YAAY,WAAyB,WAAiB,UAA6B,CAAA,GAAI;AACrF,QAAI;AACJ,IAAI,YACF,WAAW,IAAI,gBAAgB,WAAW,cAAc,SAAS,CAAC,IAElE,WAAW,IAAI,cAAc,IAAI,MAAM,qCAAqC,CAAC,GAE/E,KAAK,WAAW,IAAI,eAAe,WAAW,UAAU,OAAO,GAC/D,KAAK,YAAY,IAAI,QAAQ,KAAK,SAAS,cAAA,CAAe;EAC5D;EAEA,gBAAyB;AACvB,WAAO,KAAK;EACd;EAEA,WAA+C;AAC7C,WAAO,KAAK,SAAS,SAAA;EACvB;EAEA,QAAuB;AACrB,WAAO,KAAK,SAAS,MAAA;EACvB;AACF;AC93BO,SAAS,uBACZ,WAA+B,WAAiB,SAAsC;AACxF,EAAI,OAAO,aAAc,aACvB,YAAY,IAAI,UAAU,SAAS;AAGrC,MAAI,YAAY,IAAI,mBAAmB,SAAS;AAEhD,SADU,IAAI,WAAW,WAAW,WAAW,OAAO,EAC3C,cAAA;AACb;AAsBA,IAAM,qBAAN,MAAiD;EAC/C,YAAa,WAAsB;AACjC,SAAK,aAAa,WAEd,UAAU,eAAe,UAAU,eACrC,KAAK,aAAa,CAAA,GAClB,UAAU,iBAAiB,QAAQ,CAAA,UAAS;AAC1C,UAAI;AACF,iBAAS,WAAW,KAAK;AACvB,oBAAU,KAAK,OAAO;MAE1B,SAAS,KAAK;AACZ,aAAK,eAAe,GAAG;MACzB;AACA,WAAK,aAAa;IACpB,CAAC,IAGH,UAAU,iBAAiB,WAAW,CAAC,UAA6B;AAClE,MAAI,KAAK,WAEE,OAAO,MAAM,QAAS,WAC3B,KAAK,oBACP,KAAK,iBAAiB,MAAM,IAAI,GAChC,KAAK,mBAAmB,QACxB,KAAK,mBAAmB,UAExB,KAAK,cAAc,KAAK,MAAM,IAAI,IAGpC,KAAK,eAAe,IAAI,UAAU,6CAA6C,CAAC;IAEpF,CAAC,GAED,UAAU,iBAAiB,SAAS,CAAC,UAAsB;AACzD,WAAK,eAAe,IAAI,MAAM,0BAA0B,MAAM,IAAI,IAAI,MAAM,MAAM,EAAE,CAAC;IACvF,CAAC,GAED,UAAU,iBAAiB,SAAS,CAAC,UAAiB;AACpD,WAAK,eAAe,IAAI,MAAM,8BAA8B,CAAC;IAC/D,CAAC;EACH;EAEA;EACA;;EACA;EACA;EACA,gBAA0B,CAAA;EAC1B;EAEA,MAAM,KAAK,SAAgC;AACzC,IAAI,KAAK,eAAe,SACtB,KAAK,WAAW,KAAK,OAAO,IAG5B,KAAK,WAAW,KAAK,OAAO;EAEhC;EAEA,MAAM,UAA2B;AAC/B,QAAI,KAAK,cAAc,SAAS;AAC9B,aAAO,KAAK,cAAc,MAAA;AAC5B,QAAW,KAAK;AACd,YAAM,KAAK;AAEX,WAAO,IAAI,QAAgB,CAAC,SAAS,WAAW;AAC9C,WAAK,mBAAmB,SACxB,KAAK,mBAAmB;IAC1B,CAAC;EAEL;EAEA,MAAO,QAAmB;AACxB,QAAI;AACJ,IAAI,kBAAkB,QACpB,UAAU,OAAO,UAEjB,UAAU,GAAG,MAAM,IAErB,KAAK,WAAW,MAAM,KAAM,OAAO,GAE9B,KAAK,WACR,KAAK,SAAS;EAGlB;EAEA,eAAe,QAAa;AAC1B,IAAK,KAAK,WACR,KAAK,SAAS,QACV,KAAK,qBACP,KAAK,iBAAiB,MAAM,GAC5B,KAAK,mBAAmB,QACxB,KAAK,mBAAmB;EAG9B;AACF;AGlIA,IAAI,mBASE,aAAN,MAAqC;EAC3B;EAGA,aAAA,oBAAwC,IAAA;EAExC,eAAiC,CAAA;EAEzC,YAAY,SAAmB,MAAoB;AACjD,IAAI,oBACF,KAAK,UAAU;MACb,QAAQ;MACR,UAAU,CAAA;MACV,SAAS,kBAAkB,QAAQ,OAAO;MAC1C;IAAA,IAGF,KAAK,UAAU;MACb,QAAQ;MACR,UAAU,CAAA;MACV;MACA;IAAA,GAIJ,oBAAoB;EACtB;EAEA,aAAa;AACX,wBAAoB,KAAK,QAAQ;EACnC;EAEA,YAA6B;AAC3B,WAAO,IAAI,gBAAgB,MAAM,CAAC;EACpC;EAEA,WAAW,QAA8B;AACvC,QAAI;AACJ,QAAI;AACF,iBAAW,WAAW,UAAU,OAAO,OAAO,QAAW,MAAM,MAAM;IACvE,UAAA;AACE,aAAO,QAAA;IACT;AAMA,WAFA,KAAK,aAAa,KAAU,QAAQ,GAEhC,KAAK,QAAQ,UACf,KAAK,QAAQ,OAAO,aAAa;MAC/B;QAAC;QAAS,KAAK,QAAQ;QAAS,KAAK,QAAQ;QACnC,KAAK,QAAQ,SAAS,IAAI,CAAA,QAAO,CAAC,UAAU,GAAG,CAAC;QAChD,KAAK;MAAA;IAAY,GAEtB,IAAI,gBAAgB,KAAK,QAAQ,QAAQ,KAAK,QAAQ,OAAO,aAAa,MAAM,KAEhF,KAAK,QAAQ,QAAQ,IAAI,KAAK,QAAQ,MAAM,KAAK,QAAQ,UAAU,KAAK,YAAY;EAE/F;EAEA,SAAS,MAAgB,MAAoB,QAA8B;AACzE,QAAI,WAAW,WAAW,UAAU,OAAO,OAAO,QAAW,MAAM,MAAM;AAGzE,eAA4B,SAAU,CAAC;AAEvC,QAAI,UAAU,KAAK,QAAQ,KAAK,IAAA,CAAK;AACrC,gBAAK,aAAa,KAAK,CAAC,YAAY,SAAS,MAAM,QAAQ,CAAC,GACrD,IAAI,gBAAgB,MAAM,KAAK,aAAa,MAAM;EAC3D;EAEA,QAAQ,MAAgB,MAA8B;AACpD,QAAI,UAAU,KAAK,QAAQ,KAAK,IAAA,CAAK;AACrC,gBAAK,aAAa,KAAK,CAAC,YAAY,SAAS,IAAI,CAAC,GAC3C,IAAI,gBAAgB,MAAM,KAAK,aAAa,MAAM;EAC3D;EAEA,QAAQ,MAAwB;AAC9B,QAAI,gBAAgB,mBAAmB,KAAK,WAAW;AAErD,aAAO,KAAK;AAMd,QAAI,SAAS,KAAK,WAAW,IAAI,IAAI;AACrC,QAAI,WAAW,QAAW;AACxB,UAAI,KAAK,QAAQ,QAAQ;AACvB,YAAI,YAAY,KAAK,QAAQ,OAAO,QAAQ,IAAI;AAChD,aAAK,QAAQ,SAAS,KAAK,SAAS;MACtC;AACE,aAAK,QAAQ,SAAS,KAAK,IAAI;AAEjC,eAAS,CAAC,KAAK,QAAQ,SAAS,QAChC,KAAK,WAAW,IAAI,MAAM,MAAM;IAClC;AACA,WAAO;EACT;;;EAKA,WAAW,MAA0B;AAanC,UAAM,IAAI;MACN;IAAA;EAEN;EACA,cAAc,MAA0B;AACtC,WAAO,KAAK,WAAW,IAAI;EAC7B;EACA,UAAU,MAAsC;AAC9C,WAAO,KAAK,QAAQ,IAAI;EAC1B;EAEA,SAAS,KAA4B;EAErC;EAEA,WAAW,UAAiC;AAC1C,UAAM,IAAI,MAAM,sDAAsD;EACxE;EAEA,YAAY,OAA4B;EAExC;AACF;AAEA,QAAQ,UAAU,CAAC,MAAgB,MAAoB,SAA2C;AAChG,MAAI,UAAU,IAAI,WAAW,MAAM,IAAI,GACnC;AACJ,MAAI;AACF,aAAS,WAAW,cAAc,oBAAoB,QAAQ,SAAS,KAAK,OAAO,GAAG,MAC7E,KAAK,IAAI,WAAW,QAAQ,UAAA,GAAa,CAAA,CAAE,CAAC,CACpD,CAAC;EACJ,UAAA;AACE,YAAQ,WAAA;EACV;AAGA,MAAI,kBAAkB;AAGpB,iBAAO,MAAM,CAAA,QAAO;IAAC,CAAC,GAGhB,IAAI,MAAM,sCAAsC;AAGxD,SAAO,IAAI,WAAW,QAAQ,WAAW,MAAM,GAAG,CAAA,CAAE;AACtD;AAEA,SAAS,6BAAoC;AAC3C,QAAM,IAAI;IACN;EAAA;AAEN;AAGA,IAAM,kBAAN,cAA8B,SAAS;EACrC,YAAmB,QAA2B,KAAa;AACzD,UAAA,GADiB,KAAA,SAAA,QAA2B,KAAA,MAAA;EAE9C;;EAGA,MAAgB;AAAE,WAAO;EAAM;EAC/B,UAAgB;EAAC;EAEjB,IAAI,MAA8B;AAEhC,QAAI,KAAK,UAAU;AAGjB,aAAO;AACT,QAAW;AACT,aAAO,kBAAkB,QAAQ,MAAM,IAAI;AAE3C,+BAAA;EAEJ;;EAGA,KAAK,MAAoB,MAA4B;AAEnD,+BAAA;EACF;EAEA,IAAI,MAAoB,UAAsB,cAAmC;AAE/E,+BAAA;EACF;EAEA,OAAyC;AAEvC,+BAAA;EACF;EAEA,4BAAkC;EAElC;EAEA,SAAS,UAAsC;AAC7C,+BAAA;EACF;AACF,GAIM,gBAAN,MAAwC;EAGtC,YAAoB,UAAsB,OAAiB;AAAvC,SAAA,WAAA,UAClB,KAAK,YAAY,CAAC,KAAK;EACzB;EAJQ;EAMR,UAAU;AACR,aAAS,YAAY,KAAK;AACxB,eAAS,QAAA;EAEb;EAEA,MAAM,cAAqC;AACzC,QAAI;AACF,UAAI,aAAa,SAAS;AACxB,cAAM,IAAI,MAAM,gCAAgC;AAGlD,eAAS,eAAe,aAAa,MAAM,GAAG,EAAE,GAAG;AACjD,YAAI,UAAU,IAAI,UAAU,IAAI,EAAE,aAAa,WAAW;AAG1D,YAAI,QAAQ,iBAAiB,SAAS;AACpC,cAAI,OAAO,uBAAuB,QAAQ,KAAK;AAC/C,cAAI,MAAM;AACR,iBAAK,UAAU,KAAK,IAAI;AACxB;UACF;QACF;AAEA,aAAK,UAAU,KAAK,IAAI,gBAAgB,OAAO,CAAC;MAClD;AAEA,aAAO,IAAI,UAAU,IAAI,EAAE,aAAa,aAAa,aAAa,SAAS,CAAC,CAAC;IAC/E,UAAA;AACE,eAAS,YAAY,KAAK;AACxB,iBAAS,QAAA;IAEb;EACF;EAEA,WAAW,KAAyB;AAGlC,UAAM,IAAI,MAAM,4CAA4C;EAC9D;EACA,cAAc,KAAyB;AACrC,WAAO,KAAK,WAAW,GAAG;EAC5B;EAEA,UAAU,KAAqC;AAC7C,WAAI,MAAM,IACD,KAAK,SAAS,CAAC,MAAM,CAAC,IAEtB,KAAK,UAAU,GAAG;EAE7B;EAEA,gBAAgB,UAA2B;AACzC,UAAM,IAAI,MAAM,8CAA8C;EAChE;AACF;AAEA,SAAS,kBAAkB,OAAgB,QAA4B,OAC5C,UAAsB,cAAqC;AAIpF,MAAI,YAAY,IAAI,gBAAgB,WAAW,aAAa,OAAO,QAAQ,KAAK,CAAC,GAC7E,SAAS,IAAI,cAAc,UAAU,SAAS;AAClD,MAAI;AACF,WAAO,OAAO,MAAM,YAAY;EAClC,UAAA;AACE,WAAO,QAAA;EACT;AACF;AAEA,QAAQ,WAAW,CAAC,OAAgB,QAA4B,OAC5C,UAAsB,iBAA4B;AACpE,MAAI;AACF,QAAI;AACJ,QAAI,iBAAiB;AAGnB,YAAM,IAAI,MAAM,0CAA0C;AAC5D,QAAW,iBAAiB,OAAO;AACjC,UAAI,WAAyB,CAAA;AAC7B,UAAI;AACF,iBAAS,QAAQ;AACf,mBAAS,KAAK,kBAAkB,MAAM,OAAO,OAAO,UAAU,YAAY,CAAC;MAE/E,SAAS,KAAK;AACZ,iBAAS,WAAW;AAClB,kBAAQ,QAAA;AAEV,cAAM;MACR;AAEA,eAAS,WAAW,UAAU,QAAQ;IACxC,MAAA,CAAW,SAAU,OACnB,SAAS,WAAW,cAAc,KAAK,IAEvC,SAAS,kBAAkB,OAAO,QAAQ,OAAO,UAAU,YAAY;AAKzE,WAAO,IAAI,gBAAgB,MAAM;EACnC,UAAA;AACE,aAAS,OAAO;AACd,UAAI,QAAA;EAER;AACF;AC3UA,IAAM,yBAAN,MAAM,gCAA+B,SAAS;EACpC;;;EAGR,OAAO,OAAO,QAAgD;AAC5D,QAAI,SAAS,OAAO,UAAA;AACpB,WAAO,IAAI,wBAAuB,EAAE,UAAU,GAAG,QAAQ,QAAQ,GAAA,CAAO;EAC1E;EAEQ,YAAY,OAAyB,SAAkC;AAC7E,UAAA,GACA,KAAK,QAAQ,OACT,WACF,EAAE,MAAM;EAEZ;EAEQ,WAA6B;AACnC,QAAI,KAAK;AACP,aAAO,KAAK;AAEZ,UAAM,IAAI,MAAM,kEAAkE;EAEtF;EAEA,KAAK,MAAoB,MAA4B;AACnD,QAAI;AACF,UAAI,QAAQ,KAAK,SAAA;AAEjB,UAAI,KAAK,WAAW,KAAK,OAAO,KAAK,CAAC,KAAM;AAC1C,cAAM,IAAI,MAAM,uDAAuD;AAGzE,UAAM,SAAS,KAAK,CAAC;AAErB,UAAI,WAAW,WAAW,WAAW,WAAW,WAAW;AACzD,mBAAK,QAAA,GACC,IAAI,MAAM,kCAAkC,MAAM,EAAE;AAI5D,OAAI,WAAW,WAAW,WAAW,aACnC,MAAM,SAAS;AAGjB,UAAI,OAAO,MAAM,OAAO,MAAM,GAC1B,UAAU,KAAK,YAAY,MAAM,MAAM,MAAM;AACjD,aAAO,IAAI,gBAAgB,QAAQ,KAAK,CAAA,YAAW,IAAI,gBAAgB,OAAO,CAAC,CAAC;IAClF,SAAS,KAAK;AACZ,aAAO,IAAI,cAAc,GAAG;IAC9B;EACF;EAEA,IAAI,MAAoB,UAAsB,cAAmC;AAE/E,aAAS,OAAO;AACd,UAAI,QAAA;AAEN,WAAO,IAAI,cAAc,IAAI,MAAM,sCAAsC,CAAC;EAC5E;EAEA,IAAI,MAA8B;AAEhC,WAAO,IAAI,cAAc,IAAI,MAAM,mDAAmD,CAAC;EACzF;EAEA,MAAgB;AACd,QAAI,QAAQ,KAAK,SAAA;AACjB,WAAO,IAAI,wBAAuB,OAAO,IAAI;EAC/C;EAEA,OAAyC;AAEvC,WAAO,QAAQ,OAAO,IAAI,MAAM,mCAAmC,CAAC;EACtE;EAEA,4BAAkC;EAElC;EAEA,UAAgB;AACd,QAAI,QAAQ,KAAK;AACjB,SAAK,QAAQ,QACT,SACE,EAAE,MAAM,aAAa,MAClB,MAAM,UAET,MAAM,OAAO,MAAM,IAAI,MAAM,8DAA8D,CAAC,EACvF,MAAM,MAAM;IAAC,CAAC,GAErB,MAAM,OAAO,YAAA;EAGnB;EAEA,SAAS,UAAsC;EAG/C;AACF,GAoBM,iBAAiB,MAAM,MAEvB,aAAa,OAAO,OAAO,MAE3B,aAAa,KAAK,MAElB,wBAAwB,GAExB,uBAAuB,MAEvB,eAAe,KAEf,sBAAsB,GAef,iBAAN,MAAqB;EA6B1B,YAAoB,KAAmB;AAAnB,SAAA,MAAA;EAAoB;;EA3BxC,SAAS;;EAGT,gBAAgB;;EAGhB,iBAAiB;;;EAKT,YAAY;;EAEZ,gBAAgB;;EAEhB,eAAe;EACf,oBAAoB;;EAEpB,SAAS;;EAGT,wBAAwB;;EAExB,kBAAkB;;EAElB,iBAAiB;;;EAMzB,OAAO,MAA0D;AAC/D,SAAK,iBAAiB;AAEtB,QAAI,QAAmB;MACrB,UAAU,KAAK,IAAA;MACf;MACA,iBAAiB,KAAK;MACtB,qBAAqB,KAAK;MAC1B,cAAc,KAAK;MACnB,kBAAkB,KAAK,iBAAiB,KAAK;IAAA;AAG/C,WAAO,EAAE,OAAO,aAAa,MAAM,iBAAA;EACrC;;;EAIA,QAAQ,OAAwB;AAC9B,SAAK,iBAAiB,MAAM;EAC9B;;;EAIA,MAAM,OAA2B;AAC/B,QAAI,UAAU,KAAK,IAAA;AAGnB,SAAK,aAAa,MAAM,MACxB,KAAK,gBAAgB,SACrB,KAAK,iBAAiB,MAAM;AAG5B,QAAI,MAAM,UAAU,MAAM;AAI1B,QAHA,KAAK,SAAS,KAAK,IAAI,KAAK,QAAQ,GAAG,GAGnC,KAAK,iBAAiB;AAGxB,WAAK,eAAe,SACpB,KAAK,oBAAoB,KAAK;SACzB;AACL,UAAI,UACA;AAEJ,MAAI,MAAM,wBAAwB,KAGhC,WAAW,KAAK,cAChB,gBAAgB,KAAK,sBAErB,WAAW,MAAM,qBACjB,gBAAgB,MAAM;AAGxB,UAAI,WAAW,UAAU,UAErB,aADQ,KAAK,YAAY,iBACL,UAIpB,eAAe,KAAK,iBAAiB,wBAAwB,sBAK7D,YAAY,YAAY,KAAK,SAAS;AAI1C,kBAAY,KAAK,IAAI,WAAW,MAAM,eAAe,YAAY,GAE7D,MAAM,mBAER,YAAY,KAAK,IAAI,WAAW,MAAM,eAAe,YAAY,IAOjE,YAAY,KAAK,IAAI,WAAW,KAAK,MAAM,GAI7C,KAAK,SAAS,KAAK,IAAI,KAAK,IAAI,WAAW,UAAU,GAAG,UAAU,GAG9D,KAAK,kBAAkB,MAAM,YAAY,KAAK,mBAC5C,KAAK,SAAS,KAAK,kBAAkB,uBAEvC,KAAK,wBAAwB,IAGzB,EAAE,KAAK,yBAAyB,wBAElC,KAAK,iBAAiB,KAK1B,KAAK,iBAAiB,SACtB,KAAK,kBAAkB,KAAK;IAEhC;AAEA,WAAO,KAAK,gBAAgB,KAAK;EACnC;AACF;AAKA,SAAS,6BAA6B,MAAgC;AACpE,MAAI,cACA,eAAe,IAEf,KAAK,IAAI,eAAe,MAAM,YAAY,IAAA,CAAK,GAG/C,eACA,cAEE,cAAc,MAAM;AACxB,IAAK,iBACH,eAAe,IACf,KAAK,QAAA;EAET;AAEA,SAAO,IAAI,eAAe;IACxB,MAAM,OAAO,YAAY;AAEvB,UAAI,iBAAiB;AACnB,cAAM;AAGR,UAAM,UAAU,WAAW,cAAc,CAAC,KAAK,CAAC,GAC1C,EAAE,SAAS,KAAA,IAAS,KAAK,OAAO,CAAC,OAAO,GAAG,OAAO;AAExD,UAAI,SAAS;AAGX,eAAO,QAAQ,MAAM,CAAC,QAAQ;AAC5B,gBAAI,iBAAiB,WACnB,eAAe,MAEX;QACR,CAAC;AACI;AAEL,YAAI,EAAE,OAAO,YAAA,IAAgB,GAAG,OAAO,IAAI;AA4B3C,YAzBA,QAAQ,KAAK,MAAM;AAGjB,UAFkB,GAAG,MAAM,KAAK,KAEb,kBACjB,cAAA,GACA,gBAAgB,QAChB,eAAe;QAEnB,GAAG,CAAC,QAAQ;AACV,aAAG,QAAQ,KAAK,GACZ,iBAAiB,WACnB,eAAe,KACf,WAAW,MAAM,GAAG,GACpB,YAAA,IAIE,iBACF,aAAa,GAAG,GAChB,gBAAgB,QAChB,eAAe;QAEnB,CAAC,GAGG;AACF,iBAAO,IAAI,QAAc,CAAC,SAAS,WAAW;AAC5C,4BAAgB,SAChB,eAAe;UACjB,CAAC;MAEL;IACF;IAEA,MAAM,QAAQ;AACZ,UAAI,iBAAiB;AACnB,0BAAA,GACM;AAKR,UAAM,EAAE,QAAA,IAAY,KAAK,OAAO,CAAC,OAAO,GAAG,WAAW,cAAc,CAAA,CAAE,CAAC;AAEvE,UAAI;AACF,cAAM;MACR,SAAS,KAAK;AAIZ,cAAM,gBAAgB;MACxB,UAAA;AACE,oBAAA;MACF;IACF;IAEA,MAAM,QAAQ;AACZ,UAAI,iBAAiB;AACnB;AAGF,qBAAe,UAAU,IAAI,MAAM,4BAA4B,GAC3D,iBACF,aAAa,YAAY,GACzB,gBAAgB,QAChB,eAAe;AAGjB,UAAM,EAAE,QAAA,IAAY,KAAK,OAAO,CAAC,OAAO,GAAG,WAAW,cAAc,CAAC,MAAM,CAAC,CAAC;AAC7E,cAAQ,KAAK,MAAM,YAAA,GAAe,MAAM,YAAA,CAAa;IACvD;EAAA,CACD;AACH;AAkBA,IAAM,yBAAN,MAAM,gCAA+B,SAAS;EACpC;;;EAGR,OAAO,OAAO,QAAgD;AAC5D,WAAO,IAAI,wBAAuB,EAAE,UAAU,GAAG,QAAQ,UAAU,GAAA,CAAO;EAC5E;EAEQ,YAAY,OAA2B,SAAkC;AAC/E,UAAA,GACA,KAAK,QAAQ,OACT,WACF,EAAE,MAAM;EAEZ;EAEA,KAAK,MAAoB,MAA4B;AACnD,gBAAK,QAAA,GACE,IAAI,cAAc,IAAI,MAAM,8CAA8C,CAAC;EACpF;EAEA,IAAI,MAAoB,UAAsB,cAAmC;AAC/E,aAAS,OAAO;AACd,UAAI,QAAA;AAEN,WAAO,IAAI,cAAc,IAAI,MAAM,sCAAsC,CAAC;EAC5E;EAEA,IAAI,MAA8B;AAChC,WAAO,IAAI,cAAc,IAAI,MAAM,mDAAmD,CAAC;EACzF;EAEA,MAAgB;AACd,QAAI,QAAQ,KAAK;AACjB,QAAI,CAAC;AACH,YAAM,IAAI,MAAM,kEAAkE;AAEpF,WAAO,IAAI,wBAAuB,OAAO,IAAI;EAC/C;EAEA,OAAyC;AACvC,WAAO,QAAQ,OAAO,IAAI,MAAM,mCAAmC,CAAC;EACtE;EAEA,4BAAkC;EAElC;EAEA,UAAgB;AACd,QAAI,QAAQ,KAAK;AACjB,SAAK,QAAQ,QACT,SACE,EAAE,MAAM,aAAa,MAClB,MAAM,aACT,MAAM,WAAW,IAUZ,MAAM,OAAO,UAChB,MAAM,OAAO;MACT,IAAI,MAAM,6DAA6D;IAAA,EACtE,MAAM,MAAM;IAAC,CAAC;EAK7B;EAEA,SAAS,UAAsC;EAE/C;AACF;AAKA,WAAW,2BAA2B,uBAAuB;AAC7D,WAAW,+BAA+B;AAC1C,WAAW,2BAA2B,uBAAuB;AChatD,IAAIC,0BAEF;;;ACxFF,SAAS,oBAAoB,aAA4B;AAC/D,QAAM,IAAI,MAAM,WAAW,WAAW,2BAA2B;AAClE;AAcA,SAAS,6BACR,aACA,UACS;AACT,SAAO;AAAA,IACN,oEAAoE,WAAW;AAAA,IAC/E;AAAA,IACA,yDAAyD,QAAQ;AAAA,IACjE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACD,EAAE,KAAK;AAAA,CAAI;AACZ;AAiBA,eAAe,iCACd,UACA,aACA,UACA,UACoB;AACpB,MAAI,CAAC,YAAY,SAAS,WAAW;AACpC,WAAO;AAER,MAAI;AACJ,MAAI;AACH,WAAO,MAAM,SAAS,MAAM,EAAE,KAAK;AAAA,EACpC,QAAQ;AACP,WAAO;AAAA,EACR;AAKA,SAAK,KAAK,SAAS,mBAAmB,KAGtC,MAAM,SAAS,MAAM,wDAAwD;AAAA,IAC5E,QAAQ;AAAA,IACR,SAAS;AAAA,MACR,cAAc;AAAA,MACd,gBAAgB;AAAA,IACjB;AAAA,EACD,CAAC,GAKM,IAAI,SAAS,6BAA6B,aAAa,QAAQ,GAAG;AAAA,IACxE,QAAQ,SAAS;AAAA,IACjB,YAAY,SAAS;AAAA,IACrB,SAAS,EAAE,gBAAgB,4BAA4B;AAAA,EACxD,CAAC,KAjBO;AAkBT;AAEO,SAAS,UACf,6BACA,aACA,cACA,WACA,UACC;AACD,SAAO,OACN,OACA,SACuB;AACvB,IAAK,+BACJ,oBAAoB,WAAW;AAEhC,QAAM,UAAU,IAAI,QAAQ,OAAO,IAAI,GAEjC,iBAAiB,IAAI,QAAQ,YAAY;AAC/C,aAAW,CAAC,MAAM,KAAK,KAAK,QAAQ;AAGnC,MAAI,SAAS,YACZ,eAAe,IAAI,MAAM,KAAK,IAE9B,eAAe,IAAI,aAAa,IAAI,IAAI,KAAK;AAG/C,mBAAe,IAAI,UAAU,QAAQ,GAAG,GACxC,eAAe,IAAI,cAAc,WAAW,GACxC,cAEH,eAAe,IAAI,eAAe,SAAS,GAE3C,eAAe,IAAI,yBAAyB,SAAS;AAEtD,QAAM,MAAM,IAAI,QAAQ,SAAS;AAAA,MAChC,SAAS;AAAA,IACV,CAAC,GAEK,WAAW,MAAM,MAAM,6BAA6B,GAAG;AAK7D,WAAO,MAAM;AAAA,MACZ;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACD;AAAA,EACD;AACD;AAOO,SAAS,oBACf,6BACA,aACA,UACA,WACA,UACU;AACV,MAAM,MAAM,IAAI,IAAI,2BAA2B;AAG/C,MAFA,IAAI,WAAW,IAAI,aAAa,WAAW,SAAS,OACpD,IAAI,aAAa,IAAI,cAAc,WAAW,GAC1C;AACH,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,QAAQ;AACjD,MAAI,UAAU,UACb,IAAI,aAAa,IAAI,KAAK,KAAK;AASlC,MAAM,OAAO,wBAAuB,IAAI,IAAI,GAEtC,UAAU,WACb,IAAI;AAAA,IACJ,OAAO,QAAQ,QAAQ,EAAE;AAAA,MACxB,CAAC,UAAqC,MAAM,CAAC,MAAM;AAAA,IACpD;AAAA,EACD,IACC;AAEH,SAAO,IAAI,MAAsB,MAAM;AAAA,IACtC,IAAI,GAAG,GAAG;AACT,aAAI,MAAM,UACF;AAAA,QACN;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACD,IAEM,QAAQ,IAAI,MAAM,CAAC;AAAA,IAC3B;AAAA,EACD,CAAC;AACF;;;AbhNA,IAAqB,SAArB,cAAoC,iBAAmC;AAAA,EACtE,MAAM,SAAqC;AAC1C,WAAO;AAAA,MACN,KAAK,IAAI;AAAA,MACT,KAAK,IAAI;AAAA,MACT;AAAA,MACA,KAAK,IAAI;AAAA,MACT,KAAK,IAAI,eAAe,sBAAsB;AAAA,IAC/C,EAAE,OAAO;AAAA,EACV;AAAA,EAEA,YAAY,KAAuB,KAAuB;AACzD,UAAM,KAAK,GAAG;AAEd,QAAM,OAAO,IAAI,8BACd;AAAA,MACA,IAAI;AAAA,MACJ,IAAI;AAAA,MACJ;AAAA,MACA,IAAI;AAAA,MACJ,IAAI,eAAe,sBAAsB;AAAA,IAC1C,IACC;AAEH,WAAO,IAAI,MAAM,MAAM;AAAA,MACtB,KAAK,CAAC,QAAQ,SACT,QAAQ,IAAI,QAAQ,IAAI,IACpB,QAAQ,IAAI,QAAQ,IAAI,KAE3B,QACJ,oBAAoB,IAAI,OAAO,GAEzB,QAAQ,IAAI,MAAM,IAAI;AAAA,IAE/B,CAAC;AAAA,EACF;AACD;",
  "names": ["hook", "newWebSocketRpcSession"]
}
