{"version":3,"file":"client.cjs","names":["#apiUrl","#runnerWsUrl","#clientWsUrl","#apiKey","#organizationId","#threadCreatedListeners","#threadUpdatedListeners","#threadDeletedListeners","#request","#invokeLifecycleCallback"],"sources":["../../../../src/v2/runtime/intelligence-platform/client.ts"],"sourcesContent":["import { logger } from \"@copilotkit/shared\";\nimport type { BaseEvent } from \"@ag-ui/client\";\n\n/**\n * Error thrown when an Intelligence platform HTTP request returns a non-2xx\n * status. Carries the HTTP {@link status} code so callers can branch on\n * specific failures (e.g. 404 for \"not found\", 409 for \"conflict\") without\n * parsing the error message string.\n *\n * @example\n * ```ts\n * try {\n *   await intelligence.getThread({ threadId });\n * } catch (error) {\n *   if (error instanceof PlatformRequestError && error.status === 404) {\n *     // thread does not exist yet\n *   }\n * }\n * ```\n */\nexport class PlatformRequestError extends Error {\n  constructor(\n    message: string,\n    /** The HTTP status code returned by the platform (e.g. 404, 409, 500). */\n    public readonly status: number,\n  ) {\n    super(message);\n    this.name = \"PlatformRequestError\";\n  }\n}\n\n/**\n * Client for the CopilotKit Intelligence Platform REST API.\n *\n * Construct the client once and pass it to any consumers that need it\n * (e.g. `CopilotRuntime`, `IntelligenceAgentRunner`):\n *\n * ```ts\n * import { CopilotKitIntelligence, CopilotRuntime } from \"@copilotkit/runtime\";\n *\n * const intelligence = new CopilotKitIntelligence({\n *   apiUrl: \"https://api.copilotkit.ai\",\n *   wsUrl: \"wss://api.copilotkit.ai\",\n *   apiKey: process.env.COPILOTKIT_API_KEY!,\n *   organizationId: process.env.COPILOTKIT_ORGANIZATION_ID!,\n * });\n *\n * const runtime = new CopilotRuntime({\n *   agents,\n *   intelligence,\n * });\n * ```\n */\n\n/** Payload passed to `onThreadDeleted` listeners. */\nexport interface ThreadDeletedPayload {\n  threadId: string;\n  userId: string;\n  agentId: string;\n}\n\nexport interface CopilotKitIntelligenceConfig {\n  /** Base URL of the intelligence platform API, e.g. \"https://api.copilotkit.ai\" */\n  apiUrl: string;\n  /** Intelligence websocket base URL. Runner and client socket URLs are derived from this. */\n  wsUrl: string;\n  /** API key for authenticating with the intelligence platform */\n  apiKey: string;\n  /** Organization identifier used for self-hosted Intelligence instances */\n  organizationId: string;\n  /**\n   * Initial listener invoked after a thread is created.\n   * Prefer {@link CopilotKitIntelligence.onThreadCreated} for multiple listeners.\n   */\n  onThreadCreated?: (thread: ThreadSummary) => void;\n  /**\n   * Initial listener invoked after a thread is updated.\n   * Prefer {@link CopilotKitIntelligence.onThreadUpdated} for multiple listeners.\n   */\n  onThreadUpdated?: (thread: ThreadSummary) => void;\n  /**\n   * Initial listener invoked after a thread is deleted.\n   * Prefer {@link CopilotKitIntelligence.onThreadDeleted} for multiple listeners.\n   */\n  onThreadDeleted?: (params: ThreadDeletedPayload) => void;\n}\n\n/**\n * Summary metadata for a single thread returned by the platform.\n *\n * This is the shape returned by list, get, create, and update operations.\n * It does not include the thread's message history — use\n * {@link CopilotKitIntelligence.getThreadMessages} for that.\n */\nexport interface ThreadSummary {\n  /** Platform-assigned unique identifier. */\n  id: string;\n  /** Human-readable display name, or `null` if the thread has not been named. */\n  name: string | null;\n  /** ISO-8601 timestamp of the most recent agent run on this thread. */\n  lastRunAt?: string;\n  /** ISO-8601 timestamp of the most recent metadata update. */\n  lastUpdatedAt?: string;\n  /** ISO-8601 timestamp when the thread was created. */\n  createdAt?: string;\n  /** ISO-8601 timestamp when the thread was last updated. */\n  updatedAt?: string;\n  /** Whether the thread has been archived. Archived threads are excluded from default list results. */\n  archived?: boolean;\n  /** The agent that owns this thread. */\n  agentId?: string;\n  /** The user who created this thread. */\n  createdById?: string;\n  /** The organization this thread belongs to. */\n  organizationId?: string;\n}\n\n/** Response from listing threads for a user/agent pair. */\nexport interface ListThreadsResponse {\n  /** The matching threads, sorted by the platform's default ordering. */\n  threads: ThreadSummary[];\n  /** Join code for subscribing to realtime metadata updates for these threads. */\n  joinCode: string;\n  /** Short-lived token for authenticating the realtime subscription. */\n  joinToken?: string;\n  /** Opaque cursor for fetching the next page. `null` or absent when there are no more pages. */\n  nextCursor?: string | null;\n}\n\n/**\n * Fields that can be updated on a thread via {@link CopilotKitIntelligence.updateThread}.\n *\n * Additional platform-specific fields can be passed as extra keys and will be\n * forwarded to the PATCH request body.\n */\nexport interface UpdateThreadRequest {\n  /** New human-readable display name for the thread. */\n  name?: string;\n  [key: string]: unknown;\n}\n\n/** Parameters for creating a new thread via {@link CopilotKitIntelligence.createThread}. */\nexport interface CreateThreadRequest {\n  /** Client-generated unique identifier for the new thread. */\n  threadId: string;\n  /** The user creating the thread. Used for authorization and scoping. */\n  userId: string;\n  /** The agent this thread belongs to. */\n  agentId: string;\n  /** Optional initial display name. If omitted, the thread is unnamed until explicitly renamed. */\n  name?: string;\n}\n\n/** Credentials returned when locking or joining a thread's realtime channel. */\nexport interface ThreadConnectionResponse {\n  /** Short-lived token for authenticating the Phoenix channel join. */\n  joinToken: string;\n  /** Optional join code that can be shared with other clients to join the same channel. */\n  joinCode?: string;\n  /** Lock metadata echoed back by the platform. */\n  lock?: ThreadLockInfo;\n}\n\nexport interface SubscribeToThreadsRequest {\n  userId: string;\n}\n\nexport interface SubscribeToThreadsResponse {\n  joinToken: string;\n}\n\nexport interface ConnectThreadBootstrapResponse {\n  mode: \"bootstrap\";\n  latestEventId: string | null;\n  events: BaseEvent[];\n}\n\nexport interface ConnectThreadLiveResponse {\n  mode: \"live\";\n  joinToken: string;\n  joinFromEventId: string | null;\n  events: BaseEvent[];\n}\n\nexport type ConnectThreadResponse =\n  | ConnectThreadBootstrapResponse\n  | ConnectThreadLiveResponse\n  | null;\n\n/** A single message within a thread's persisted history. */\nexport interface ThreadMessage {\n  /** Unique identifier for this message. */\n  id: string;\n  /** Message role, e.g. `\"user\"`, `\"assistant\"`, `\"tool\"`. */\n  role: string;\n  /** Text content of the message. May be absent for tool-call-only messages. */\n  content?: string;\n  /** Tool calls initiated by this message (assistant role only). */\n  toolCalls?: Array<{\n    id: string;\n    name: string;\n    /** JSON-encoded arguments passed to the tool. */\n    args: string;\n  }>;\n  /** For tool-result messages, the ID of the tool call this message responds to. */\n  toolCallId?: string;\n}\n\n/** Response from {@link CopilotKitIntelligence.getThreadMessages}. */\nexport interface ThreadMessagesResponse {\n  messages: ThreadMessage[];\n}\n\nexport interface AcquireThreadLockRequest {\n  threadId: string;\n  runId: string;\n  userId: string;\n  /** Custom Redis key prefix for the lock (default: \"thread\"). */\n  lockKeyPrefix?: string;\n  /** Lock TTL in seconds. When set, the lock auto-expires after this duration. */\n  ttlSeconds?: number;\n}\n\nexport interface RenewThreadLockRequest {\n  threadId: string;\n  runId: string;\n  /** New TTL to set on the lock in seconds. */\n  ttlSeconds: number;\n  /** Must match the prefix used when acquiring. */\n  lockKeyPrefix?: string;\n}\n\nexport interface RenewThreadLockResponse {\n  ttlSeconds: number;\n}\n\nexport interface ThreadLockInfo {\n  key: string;\n  ttlSeconds: number | null;\n}\n\ninterface ThreadEnvelope {\n  thread: ThreadSummary;\n}\n\nexport class CopilotKitIntelligence {\n  #apiUrl: string;\n  #runnerWsUrl: string;\n  #clientWsUrl: string;\n  #apiKey: string;\n  #organizationId: string;\n  #threadCreatedListeners = new Set<(thread: ThreadSummary) => void>();\n  #threadUpdatedListeners = new Set<(thread: ThreadSummary) => void>();\n  #threadDeletedListeners = new Set<(params: ThreadDeletedPayload) => void>();\n\n  constructor(config: CopilotKitIntelligenceConfig) {\n    const intelligenceWsUrl = normalizeIntelligenceWsUrl(config.wsUrl);\n\n    this.#apiUrl = config.apiUrl.replace(/\\/$/, \"\");\n    this.#runnerWsUrl = deriveRunnerWsUrl(intelligenceWsUrl);\n    this.#clientWsUrl = deriveClientWsUrl(intelligenceWsUrl);\n    this.#apiKey = config.apiKey;\n    this.#organizationId = config.organizationId;\n\n    if (config.onThreadCreated) {\n      this.onThreadCreated(config.onThreadCreated);\n    }\n    if (config.onThreadUpdated) {\n      this.onThreadUpdated(config.onThreadUpdated);\n    }\n    if (config.onThreadDeleted) {\n      this.onThreadDeleted(config.onThreadDeleted);\n    }\n  }\n\n  /**\n   * Register a listener invoked whenever a thread is created.\n   *\n   * Multiple listeners can be registered. Each call returns an unsubscribe\n   * function that removes the listener when called.\n   *\n   * @param callback - Receives the newly created {@link ThreadSummary}.\n   * @returns A function that removes this listener when called.\n   *\n   * @example\n   * ```ts\n   * const unsubscribe = intelligence.onThreadCreated((thread) => {\n   *   console.log(\"Thread created:\", thread.id);\n   * });\n   * // later…\n   * unsubscribe();\n   * ```\n   */\n  onThreadCreated(callback: (thread: ThreadSummary) => void): () => void {\n    this.#threadCreatedListeners.add(callback);\n    return () => {\n      this.#threadCreatedListeners.delete(callback);\n    };\n  }\n\n  /**\n   * Register a listener invoked whenever a thread is updated (including archive).\n   *\n   * Multiple listeners can be registered. Each call returns an unsubscribe\n   * function that removes the listener when called.\n   *\n   * @param callback - Receives the updated {@link ThreadSummary}.\n   * @returns A function that removes this listener when called.\n   */\n  onThreadUpdated(callback: (thread: ThreadSummary) => void): () => void {\n    this.#threadUpdatedListeners.add(callback);\n    return () => {\n      this.#threadUpdatedListeners.delete(callback);\n    };\n  }\n\n  /**\n   * Register a listener invoked whenever a thread is deleted.\n   *\n   * Multiple listeners can be registered. Each call returns an unsubscribe\n   * function that removes the listener when called.\n   *\n   * @param callback - Receives the {@link ThreadDeletedPayload} identifying\n   *   the deleted thread.\n   * @returns A function that removes this listener when called.\n   */\n  onThreadDeleted(\n    callback: (params: ThreadDeletedPayload) => void,\n  ): () => void {\n    this.#threadDeletedListeners.add(callback);\n    return () => {\n      this.#threadDeletedListeners.delete(callback);\n    };\n  }\n\n  ɵgetApiUrl(): string {\n    return this.#apiUrl;\n  }\n\n  ɵgetRunnerWsUrl(): string {\n    return this.#runnerWsUrl;\n  }\n\n  ɵgetClientWsUrl(): string {\n    return this.#clientWsUrl;\n  }\n\n  ɵgetOrganizationId(): string {\n    return this.#organizationId;\n  }\n\n  ɵgetRunnerAuthToken(): string {\n    return this.#apiKey;\n  }\n\n  async #request<T>(method: string, path: string, body?: unknown): Promise<T> {\n    const url = `${this.#apiUrl}${path}`;\n\n    const headers: Record<string, string> = {\n      Authorization: `Bearer ${this.#apiKey}`,\n      \"Content-Type\": \"application/json\",\n      \"X-Organization-Id\": this.#organizationId,\n    };\n\n    const response = await fetch(url, {\n      method,\n      headers,\n      body: body ? JSON.stringify(body) : undefined,\n    });\n\n    if (!response.ok) {\n      const text = await response.text().catch(() => \"\");\n      logger.error(\n        { status: response.status, body: text, path },\n        \"Intelligence platform request failed\",\n      );\n      throw new PlatformRequestError(\n        `Intelligence platform error ${response.status}: ${text || response.statusText}`,\n        response.status,\n      );\n    }\n\n    const text = await response.text();\n    if (!text) {\n      return undefined as T;\n    }\n    return JSON.parse(text) as T;\n  }\n\n  #invokeLifecycleCallback(\n    callbackName: \"onThreadCreated\" | \"onThreadUpdated\" | \"onThreadDeleted\",\n    payload: ThreadSummary | ThreadDeletedPayload,\n  ): void {\n    const listeners =\n      callbackName === \"onThreadCreated\"\n        ? this.#threadCreatedListeners\n        : callbackName === \"onThreadUpdated\"\n          ? this.#threadUpdatedListeners\n          : this.#threadDeletedListeners;\n\n    for (const callback of listeners) {\n      try {\n        void (callback as (p: typeof payload) => void)(payload);\n      } catch (error) {\n        logger.error(\n          { err: error, callbackName, payload },\n          \"Intelligence lifecycle callback failed\",\n        );\n      }\n    }\n  }\n\n  /**\n   * List all non-archived threads for a given user and agent.\n   *\n   * @param params.userId - User whose threads to list.\n   * @param params.agentId - Agent whose threads to list.\n   * @returns The thread list along with realtime subscription credentials.\n   * @throws {@link PlatformRequestError} on non-2xx responses.\n   */\n  async listThreads(params: {\n    userId: string;\n    agentId: string;\n    includeArchived?: boolean;\n    limit?: number;\n    cursor?: string;\n  }): Promise<ListThreadsResponse> {\n    const query: Record<string, string> = {\n      userId: params.userId,\n      agentId: params.agentId,\n    };\n    if (params.includeArchived) query.includeArchived = \"true\";\n    if (params.limit != null) query.limit = String(params.limit);\n    if (params.cursor) query.cursor = params.cursor;\n\n    const qs = new URLSearchParams(query).toString();\n    return this.#request<ListThreadsResponse>(\"GET\", `/api/threads?${qs}`);\n  }\n\n  async ɵsubscribeToThreads(\n    params: SubscribeToThreadsRequest,\n  ): Promise<SubscribeToThreadsResponse> {\n    return this.#request<SubscribeToThreadsResponse>(\n      \"POST\",\n      \"/api/threads/subscribe\",\n      {\n        userId: params.userId,\n      },\n    );\n  }\n\n  /**\n   * Update thread metadata (e.g. name).\n   *\n   * Triggers the `onThreadUpdated` lifecycle callback on success.\n   *\n   * @returns The updated thread summary.\n   * @throws {@link PlatformRequestError} on non-2xx responses.\n   */\n  async updateThread(params: {\n    threadId: string;\n    userId: string;\n    agentId: string;\n    updates: UpdateThreadRequest;\n  }): Promise<ThreadSummary> {\n    const response = await this.#request<ThreadEnvelope>(\n      \"PATCH\",\n      `/api/threads/${encodeURIComponent(params.threadId)}`,\n      {\n        userId: params.userId,\n        agentId: params.agentId,\n        ...params.updates,\n      },\n    );\n    this.#invokeLifecycleCallback(\"onThreadUpdated\", response.thread);\n    return response.thread;\n  }\n\n  /**\n   * Create a new thread on the platform.\n   *\n   * Triggers the `onThreadCreated` lifecycle callback on success.\n   *\n   * @returns The newly created thread summary.\n   * @throws {@link PlatformRequestError} with status 409 if a thread with the\n   *   same `threadId` already exists.\n   */\n  async createThread(params: CreateThreadRequest): Promise<ThreadSummary> {\n    const response = await this.#request<ThreadEnvelope>(\n      \"POST\",\n      `/api/threads`,\n      {\n        threadId: params.threadId,\n        userId: params.userId,\n        agentId: params.agentId,\n        ...(params.name !== undefined ? { name: params.name } : {}),\n      },\n    );\n    this.#invokeLifecycleCallback(\"onThreadCreated\", response.thread);\n    return response.thread;\n  }\n\n  /**\n   * Fetch a single thread by ID.\n   *\n   * @returns The thread summary.\n   * @throws {@link PlatformRequestError} with status 404 if the thread does\n   *   not exist.\n   */\n  async getThread(params: { threadId: string }): Promise<ThreadSummary> {\n    const response = await this.#request<ThreadEnvelope>(\n      \"GET\",\n      `/api/threads/${encodeURIComponent(params.threadId)}`,\n    );\n    return response.thread;\n  }\n\n  /**\n   * Get an existing thread or create it if it does not exist.\n   *\n   * Handles the race where a concurrent request creates the thread between\n   * the initial 404 and the subsequent `createThread` call by catching the\n   * 409 Conflict and retrying the get.\n   *\n   * Triggers the `onThreadCreated` lifecycle callback when a new thread is\n   * created.\n   *\n   * @returns An object containing the thread and a `created` flag indicating\n   *   whether the thread was newly created (`true`) or already existed (`false`).\n   * @throws {@link PlatformRequestError} on non-2xx responses other than\n   *   404 (get) and 409 (create race).\n   */\n  async getOrCreateThread(\n    params: CreateThreadRequest,\n  ): Promise<{ thread: ThreadSummary; created: boolean }> {\n    try {\n      const thread = await this.getThread({ threadId: params.threadId });\n      return { thread, created: false };\n    } catch (error) {\n      if (!(error instanceof PlatformRequestError && error.status === 404)) {\n        throw error;\n      }\n    }\n\n    try {\n      const thread = await this.createThread(params);\n      return { thread, created: true };\n    } catch (error) {\n      // Another request created the thread between our get and create — retry get.\n      if (error instanceof PlatformRequestError && error.status === 409) {\n        const thread = await this.getThread({ threadId: params.threadId });\n        return { thread, created: false };\n      }\n      throw error;\n    }\n  }\n\n  /**\n   * Fetch the full message history for a thread.\n   *\n   * @returns All persisted messages in chronological order.\n   * @throws {@link PlatformRequestError} on non-2xx responses.\n   */\n  async getThreadMessages(params: {\n    threadId: string;\n  }): Promise<ThreadMessagesResponse> {\n    return this.#request<ThreadMessagesResponse>(\n      \"GET\",\n      `/api/threads/${encodeURIComponent(params.threadId)}/messages`,\n    );\n  }\n\n  /**\n   * Mark a thread as archived.\n   *\n   * Archived threads are excluded from {@link listThreads} results.\n   * Triggers the `onThreadUpdated` lifecycle callback on success.\n   *\n   * @throws {@link PlatformRequestError} on non-2xx responses.\n   */\n  async archiveThread(params: {\n    threadId: string;\n    userId: string;\n    agentId: string;\n  }): Promise<void> {\n    const response = await this.#request<ThreadEnvelope>(\n      \"PATCH\",\n      `/api/threads/${encodeURIComponent(params.threadId)}`,\n      { userId: params.userId, agentId: params.agentId, archived: true },\n    );\n    this.#invokeLifecycleCallback(\"onThreadUpdated\", response.thread);\n  }\n\n  /**\n   * Permanently delete a thread and its message history.\n   *\n   * This is irreversible. Triggers the `onThreadDeleted` lifecycle callback\n   * on success.\n   *\n   * @throws {@link PlatformRequestError} on non-2xx responses.\n   */\n  async deleteThread(params: {\n    threadId: string;\n    userId: string;\n    agentId: string;\n  }): Promise<void> {\n    await this.#request<void>(\n      \"DELETE\",\n      `/api/threads/${encodeURIComponent(params.threadId)}`,\n      {\n        reason: `Deleted via CopilotKit runtime (userId=${params.userId}, agentId=${params.agentId})`,\n      },\n    );\n    this.#invokeLifecycleCallback(\"onThreadDeleted\", params);\n  }\n\n  async ɵacquireThreadLock(\n    params: AcquireThreadLockRequest,\n  ): Promise<ThreadConnectionResponse> {\n    return this.#request<ThreadConnectionResponse>(\n      \"POST\",\n      `/api/threads/${encodeURIComponent(params.threadId)}/lock`,\n      {\n        runId: params.runId,\n        userId: params.userId,\n        ...(params.lockKeyPrefix !== undefined\n          ? { lockKeyPrefix: params.lockKeyPrefix }\n          : {}),\n        ...(params.ttlSeconds !== undefined\n          ? { ttlSeconds: params.ttlSeconds }\n          : {}),\n      },\n    );\n  }\n\n  async ɵrenewThreadLock(\n    params: RenewThreadLockRequest,\n  ): Promise<RenewThreadLockResponse> {\n    return this.#request<RenewThreadLockResponse>(\n      \"PATCH\",\n      `/api/threads/${encodeURIComponent(params.threadId)}/lock`,\n      {\n        runId: params.runId,\n        ttlSeconds: params.ttlSeconds,\n        ...(params.lockKeyPrefix !== undefined\n          ? { lockKeyPrefix: params.lockKeyPrefix }\n          : {}),\n      },\n    );\n  }\n\n  async ɵgetActiveJoinCode(params: {\n    threadId: string;\n    userId: string;\n  }): Promise<ThreadConnectionResponse> {\n    const qs = new URLSearchParams({ userId: params.userId }).toString();\n    return this.#request<ThreadConnectionResponse>(\n      \"GET\",\n      `/api/threads/${encodeURIComponent(params.threadId)}/join-code?${qs}`,\n    );\n  }\n\n  async ɵconnectThread(params: {\n    threadId: string;\n    userId: string;\n    lastSeenEventId?: string | null;\n  }): Promise<ConnectThreadResponse> {\n    const result = await this.#request<\n      ConnectThreadBootstrapResponse | ConnectThreadLiveResponse\n    >(\"POST\", `/api/threads/${encodeURIComponent(params.threadId)}/connect`, {\n      userId: params.userId,\n      ...(params.lastSeenEventId !== undefined\n        ? { lastSeenEventId: params.lastSeenEventId }\n        : {}),\n    });\n\n    // request() returns undefined for empty/204 responses\n    return result ?? null;\n  }\n}\n\nfunction normalizeIntelligenceWsUrl(wsUrl: string): string {\n  return wsUrl.replace(/\\/$/, \"\");\n}\n\nfunction deriveRunnerWsUrl(wsUrl: string): string {\n  if (wsUrl.endsWith(\"/runner\")) {\n    return wsUrl;\n  }\n\n  if (wsUrl.endsWith(\"/client\")) {\n    return `${wsUrl.slice(0, -\"/client\".length)}/runner`;\n  }\n\n  return `${wsUrl}/runner`;\n}\n\nfunction deriveClientWsUrl(wsUrl: string): string {\n  if (wsUrl.endsWith(\"/client\")) {\n    return wsUrl;\n  }\n\n  if (wsUrl.endsWith(\"/runner\")) {\n    return `${wsUrl.slice(0, -\"/runner\".length)}/client`;\n  }\n\n  return `${wsUrl}/client`;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAoBA,IAAa,uBAAb,cAA0C,MAAM;CAC9C,YACE,SAEA,AAAgB,QAChB;AACA,QAAM,QAAQ;EAFE;AAGhB,OAAK,OAAO;;;AA0NhB,IAAa,yBAAb,MAAoC;CAClC;CACA;CACA;CACA;CACA;CACA,0CAA0B,IAAI,KAAsC;CACpE,0CAA0B,IAAI,KAAsC;CACpE,0CAA0B,IAAI,KAA6C;CAE3E,YAAY,QAAsC;EAChD,MAAM,oBAAoB,2BAA2B,OAAO,MAAM;AAElE,QAAKA,SAAU,OAAO,OAAO,QAAQ,OAAO,GAAG;AAC/C,QAAKC,cAAe,kBAAkB,kBAAkB;AACxD,QAAKC,cAAe,kBAAkB,kBAAkB;AACxD,QAAKC,SAAU,OAAO;AACtB,QAAKC,iBAAkB,OAAO;AAE9B,MAAI,OAAO,gBACT,MAAK,gBAAgB,OAAO,gBAAgB;AAE9C,MAAI,OAAO,gBACT,MAAK,gBAAgB,OAAO,gBAAgB;AAE9C,MAAI,OAAO,gBACT,MAAK,gBAAgB,OAAO,gBAAgB;;;;;;;;;;;;;;;;;;;;CAsBhD,gBAAgB,UAAuD;AACrE,QAAKC,uBAAwB,IAAI,SAAS;AAC1C,eAAa;AACX,SAAKA,uBAAwB,OAAO,SAAS;;;;;;;;;;;;CAajD,gBAAgB,UAAuD;AACrE,QAAKC,uBAAwB,IAAI,SAAS;AAC1C,eAAa;AACX,SAAKA,uBAAwB,OAAO,SAAS;;;;;;;;;;;;;CAcjD,gBACE,UACY;AACZ,QAAKC,uBAAwB,IAAI,SAAS;AAC1C,eAAa;AACX,SAAKA,uBAAwB,OAAO,SAAS;;;CAIjD,aAAqB;AACnB,SAAO,MAAKP;;CAGd,kBAA0B;AACxB,SAAO,MAAKC;;CAGd,kBAA0B;AACxB,SAAO,MAAKC;;CAGd,qBAA6B;AAC3B,SAAO,MAAKE;;CAGd,sBAA8B;AAC5B,SAAO,MAAKD;;CAGd,OAAMK,QAAY,QAAgB,MAAc,MAA4B;EAC1E,MAAM,MAAM,GAAG,MAAKR,SAAU;EAE9B,MAAM,UAAkC;GACtC,eAAe,UAAU,MAAKG;GAC9B,gBAAgB;GAChB,qBAAqB,MAAKC;GAC3B;EAED,MAAM,WAAW,MAAM,MAAM,KAAK;GAChC;GACA;GACA,MAAM,OAAO,KAAK,UAAU,KAAK,GAAG;GACrC,CAAC;AAEF,MAAI,CAAC,SAAS,IAAI;GAChB,MAAM,OAAO,MAAM,SAAS,MAAM,CAAC,YAAY,GAAG;AAClD,6BAAO,MACL;IAAE,QAAQ,SAAS;IAAQ,MAAM;IAAM;IAAM,EAC7C,uCACD;AACD,SAAM,IAAI,qBACR,+BAA+B,SAAS,OAAO,IAAI,QAAQ,SAAS,cACpE,SAAS,OACV;;EAGH,MAAM,OAAO,MAAM,SAAS,MAAM;AAClC,MAAI,CAAC,KACH;AAEF,SAAO,KAAK,MAAM,KAAK;;CAGzB,yBACE,cACA,SACM;EACN,MAAM,YACJ,iBAAiB,oBACb,MAAKC,yBACL,iBAAiB,oBACf,MAAKC,yBACL,MAAKC;AAEb,OAAK,MAAM,YAAY,UACrB,KAAI;AACF,GAAM,SAAyC,QAAQ;WAChD,OAAO;AACd,6BAAO,MACL;IAAE,KAAK;IAAO;IAAc;IAAS,EACrC,yCACD;;;;;;;;;;;CAaP,MAAM,YAAY,QAMe;EAC/B,MAAM,QAAgC;GACpC,QAAQ,OAAO;GACf,SAAS,OAAO;GACjB;AACD,MAAI,OAAO,gBAAiB,OAAM,kBAAkB;AACpD,MAAI,OAAO,SAAS,KAAM,OAAM,QAAQ,OAAO,OAAO,MAAM;AAC5D,MAAI,OAAO,OAAQ,OAAM,SAAS,OAAO;EAEzC,MAAM,KAAK,IAAI,gBAAgB,MAAM,CAAC,UAAU;AAChD,SAAO,MAAKC,QAA8B,OAAO,gBAAgB,KAAK;;CAGxE,MAAM,oBACJ,QACqC;AACrC,SAAO,MAAKA,QACV,QACA,0BACA,EACE,QAAQ,OAAO,QAChB,CACF;;;;;;;;;;CAWH,MAAM,aAAa,QAKQ;EACzB,MAAM,WAAW,MAAM,MAAKA,QAC1B,SACA,gBAAgB,mBAAmB,OAAO,SAAS,IACnD;GACE,QAAQ,OAAO;GACf,SAAS,OAAO;GAChB,GAAG,OAAO;GACX,CACF;AACD,QAAKC,wBAAyB,mBAAmB,SAAS,OAAO;AACjE,SAAO,SAAS;;;;;;;;;;;CAYlB,MAAM,aAAa,QAAqD;EACtE,MAAM,WAAW,MAAM,MAAKD,QAC1B,QACA,gBACA;GACE,UAAU,OAAO;GACjB,QAAQ,OAAO;GACf,SAAS,OAAO;GAChB,GAAI,OAAO,SAAS,SAAY,EAAE,MAAM,OAAO,MAAM,GAAG,EAAE;GAC3D,CACF;AACD,QAAKC,wBAAyB,mBAAmB,SAAS,OAAO;AACjE,SAAO,SAAS;;;;;;;;;CAUlB,MAAM,UAAU,QAAsD;AAKpE,UAJiB,MAAM,MAAKD,QAC1B,OACA,gBAAgB,mBAAmB,OAAO,SAAS,GACpD,EACe;;;;;;;;;;;;;;;;;CAkBlB,MAAM,kBACJ,QACsD;AACtD,MAAI;AAEF,UAAO;IAAE,QADM,MAAM,KAAK,UAAU,EAAE,UAAU,OAAO,UAAU,CAAC;IACjD,SAAS;IAAO;WAC1B,OAAO;AACd,OAAI,EAAE,iBAAiB,wBAAwB,MAAM,WAAW,KAC9D,OAAM;;AAIV,MAAI;AAEF,UAAO;IAAE,QADM,MAAM,KAAK,aAAa,OAAO;IAC7B,SAAS;IAAM;WACzB,OAAO;AAEd,OAAI,iBAAiB,wBAAwB,MAAM,WAAW,IAE5D,QAAO;IAAE,QADM,MAAM,KAAK,UAAU,EAAE,UAAU,OAAO,UAAU,CAAC;IACjD,SAAS;IAAO;AAEnC,SAAM;;;;;;;;;CAUV,MAAM,kBAAkB,QAEY;AAClC,SAAO,MAAKA,QACV,OACA,gBAAgB,mBAAmB,OAAO,SAAS,CAAC,WACrD;;;;;;;;;;CAWH,MAAM,cAAc,QAIF;EAChB,MAAM,WAAW,MAAM,MAAKA,QAC1B,SACA,gBAAgB,mBAAmB,OAAO,SAAS,IACnD;GAAE,QAAQ,OAAO;GAAQ,SAAS,OAAO;GAAS,UAAU;GAAM,CACnE;AACD,QAAKC,wBAAyB,mBAAmB,SAAS,OAAO;;;;;;;;;;CAWnE,MAAM,aAAa,QAID;AAChB,QAAM,MAAKD,QACT,UACA,gBAAgB,mBAAmB,OAAO,SAAS,IACnD,EACE,QAAQ,0CAA0C,OAAO,OAAO,YAAY,OAAO,QAAQ,IAC5F,CACF;AACD,QAAKC,wBAAyB,mBAAmB,OAAO;;CAG1D,MAAM,mBACJ,QACmC;AACnC,SAAO,MAAKD,QACV,QACA,gBAAgB,mBAAmB,OAAO,SAAS,CAAC,QACpD;GACE,OAAO,OAAO;GACd,QAAQ,OAAO;GACf,GAAI,OAAO,kBAAkB,SACzB,EAAE,eAAe,OAAO,eAAe,GACvC,EAAE;GACN,GAAI,OAAO,eAAe,SACtB,EAAE,YAAY,OAAO,YAAY,GACjC,EAAE;GACP,CACF;;CAGH,MAAM,iBACJ,QACkC;AAClC,SAAO,MAAKA,QACV,SACA,gBAAgB,mBAAmB,OAAO,SAAS,CAAC,QACpD;GACE,OAAO,OAAO;GACd,YAAY,OAAO;GACnB,GAAI,OAAO,kBAAkB,SACzB,EAAE,eAAe,OAAO,eAAe,GACvC,EAAE;GACP,CACF;;CAGH,MAAM,mBAAmB,QAGa;EACpC,MAAM,KAAK,IAAI,gBAAgB,EAAE,QAAQ,OAAO,QAAQ,CAAC,CAAC,UAAU;AACpE,SAAO,MAAKA,QACV,OACA,gBAAgB,mBAAmB,OAAO,SAAS,CAAC,aAAa,KAClE;;CAGH,MAAM,eAAe,QAIc;AAWjC,SAVe,MAAM,MAAKA,QAExB,QAAQ,gBAAgB,mBAAmB,OAAO,SAAS,CAAC,WAAW;GACvE,QAAQ,OAAO;GACf,GAAI,OAAO,oBAAoB,SAC3B,EAAE,iBAAiB,OAAO,iBAAiB,GAC3C,EAAE;GACP,CAAC,IAGe;;;AAIrB,SAAS,2BAA2B,OAAuB;AACzD,QAAO,MAAM,QAAQ,OAAO,GAAG;;AAGjC,SAAS,kBAAkB,OAAuB;AAChD,KAAI,MAAM,SAAS,UAAU,CAC3B,QAAO;AAGT,KAAI,MAAM,SAAS,UAAU,CAC3B,QAAO,GAAG,MAAM,MAAM,GAAG,GAAkB,CAAC;AAG9C,QAAO,GAAG,MAAM;;AAGlB,SAAS,kBAAkB,OAAuB;AAChD,KAAI,MAAM,SAAS,UAAU,CAC3B,QAAO;AAGT,KAAI,MAAM,SAAS,UAAU,CAC3B,QAAO,GAAG,MAAM,MAAM,GAAG,GAAkB,CAAC;AAG9C,QAAO,GAAG,MAAM"}