{"version":3,"file":"index.cjs","sources":["../../../../src/query/builder/index.ts"],"sourcesContent":["import { CollectionImpl } from '../../collection/index.js'\nimport {\n  Aggregate as AggregateExpr,\n  CollectionRef,\n  Func as FuncExpr,\n  PropRef,\n  QueryRef,\n  Value as ValueExpr,\n  isExpressionLike,\n} from '../ir.js'\nimport {\n  InvalidSourceError,\n  InvalidSourceTypeError,\n  InvalidWhereExpressionError,\n  JoinConditionMustBeEqualityError,\n  OnlyOneSourceAllowedError,\n  QueryMustHaveFromClauseError,\n  SubQueryMustHaveFromClauseError,\n} from '../../errors.js'\nimport {\n  createRefProxy,\n  createRefProxyWithSelected,\n  isRefProxy,\n  toExpression,\n} from './ref-proxy.js'\nimport type { NamespacedRow, SingleResult } from '../../types.js'\nimport type {\n  Aggregate,\n  BasicExpression,\n  JoinClause,\n  OrderBy,\n  OrderByDirection,\n  QueryIR,\n} from '../ir.js'\nimport type {\n  CompareOptions,\n  Context,\n  FunctionalHavingRow,\n  GetResult,\n  GroupByCallback,\n  JoinOnCallback,\n  MergeContextForJoinCallback,\n  MergeContextWithJoinType,\n  OrderByCallback,\n  OrderByOptions,\n  RefsForContext,\n  ResultTypeFromSelect,\n  SchemaFromSource,\n  SelectObject,\n  Source,\n  WhereCallback,\n  WithResult,\n} from './types.js'\n\nexport class BaseQueryBuilder<TContext extends Context = Context> {\n  private readonly query: Partial<QueryIR> = {}\n\n  constructor(query: Partial<QueryIR> = {}) {\n    this.query = { ...query }\n  }\n\n  /**\n   * Creates a CollectionRef or QueryRef from a source object\n   * @param source - An object with a single key-value pair\n   * @param context - Context string for error messages (e.g., \"from clause\", \"join clause\")\n   * @returns A tuple of [alias, ref] where alias is the source key and ref is the created reference\n   */\n  private _createRefForSource<TSource extends Source>(\n    source: TSource,\n    context: string,\n  ): [string, CollectionRef | QueryRef] {\n    // Validate source is a plain object (not null, array, string, etc.)\n    // We use try-catch to handle null/undefined gracefully\n    let keys: Array<string>\n    try {\n      keys = Object.keys(source)\n    } catch {\n      // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n      const type = source === null ? `null` : `undefined`\n      throw new InvalidSourceTypeError(context, type)\n    }\n\n    // Check if it's an array (arrays pass Object.keys but aren't valid sources)\n    if (Array.isArray(source)) {\n      throw new InvalidSourceTypeError(context, `array`)\n    }\n\n    // Validate exactly one key\n    if (keys.length !== 1) {\n      if (keys.length === 0) {\n        throw new InvalidSourceTypeError(context, `empty object`)\n      }\n      // Check if it looks like a string was passed (has numeric keys)\n      if (keys.every((k) => !isNaN(Number(k)))) {\n        throw new InvalidSourceTypeError(context, `string`)\n      }\n      throw new OnlyOneSourceAllowedError(context)\n    }\n\n    const alias = keys[0]!\n    const sourceValue = source[alias]\n\n    // Validate the value is a Collection or QueryBuilder\n    let ref: CollectionRef | QueryRef\n\n    if (sourceValue instanceof CollectionImpl) {\n      ref = new CollectionRef(sourceValue, alias)\n    } else if (sourceValue instanceof BaseQueryBuilder) {\n      const subQuery = sourceValue._getQuery()\n      if (!(subQuery as Partial<QueryIR>).from) {\n        throw new SubQueryMustHaveFromClauseError(context)\n      }\n      ref = new QueryRef(subQuery, alias)\n    } else {\n      throw new InvalidSourceError(alias)\n    }\n\n    return [alias, ref]\n  }\n\n  /**\n   * Specify the source table or subquery for the query\n   *\n   * @param source - An object with a single key-value pair where the key is the table alias and the value is a Collection or subquery\n   * @returns A QueryBuilder with the specified source\n   *\n   * @example\n   * ```ts\n   * // Query from a collection\n   * query.from({ users: usersCollection })\n   *\n   * // Query from a subquery\n   * const activeUsers = query.from({ u: usersCollection }).where(({u}) => u.active)\n   * query.from({ activeUsers })\n   * ```\n   */\n  from<TSource extends Source>(\n    source: TSource,\n  ): QueryBuilder<{\n    baseSchema: SchemaFromSource<TSource>\n    schema: SchemaFromSource<TSource>\n    fromSourceName: keyof TSource & string\n    hasJoins: false\n  }> {\n    const [, from] = this._createRefForSource(source, `from clause`)\n\n    return new BaseQueryBuilder({\n      ...this.query,\n      from,\n    }) as any\n  }\n\n  /**\n   * Join another table or subquery to the current query\n   *\n   * @param source - An object with a single key-value pair where the key is the table alias and the value is a Collection or subquery\n   * @param onCallback - A function that receives table references and returns the join condition\n   * @param type - The type of join: 'inner', 'left', 'right', or 'full' (defaults to 'left')\n   * @returns A QueryBuilder with the joined table available\n   *\n   * @example\n   * ```ts\n   * // Left join users with posts\n   * query\n   *   .from({ users: usersCollection })\n   *   .join({ posts: postsCollection }, ({users, posts}) => eq(users.id, posts.userId))\n   *\n   * // Inner join with explicit type\n   * query\n   *   .from({ u: usersCollection })\n   *   .join({ p: postsCollection }, ({u, p}) => eq(u.id, p.userId), 'inner')\n   * ```\n   *\n   * // Join with a subquery\n   * const activeUsers = query.from({ u: usersCollection }).where(({u}) => u.active)\n   * query\n   *   .from({ activeUsers })\n   *   .join({ p: postsCollection }, ({u, p}) => eq(u.id, p.userId))\n   */\n  join<\n    TSource extends Source,\n    TJoinType extends `inner` | `left` | `right` | `full` = `left`,\n  >(\n    source: TSource,\n    onCallback: JoinOnCallback<\n      MergeContextForJoinCallback<TContext, SchemaFromSource<TSource>>\n    >,\n    type: TJoinType = `left` as TJoinType,\n  ): QueryBuilder<\n    MergeContextWithJoinType<TContext, SchemaFromSource<TSource>, TJoinType>\n  > {\n    const [alias, from] = this._createRefForSource(source, `join clause`)\n\n    // Create a temporary context for the callback\n    const currentAliases = this._getCurrentAliases()\n    const newAliases = [...currentAliases, alias]\n    const refProxy = createRefProxy(newAliases) as RefsForContext<\n      MergeContextForJoinCallback<TContext, SchemaFromSource<TSource>>\n    >\n\n    // Get the join condition expression\n    const onExpression = onCallback(refProxy)\n\n    // Extract left and right from the expression\n    // For now, we'll assume it's an eq function with two arguments\n    let left: BasicExpression\n    let right: BasicExpression\n\n    if (\n      onExpression.type === `func` &&\n      onExpression.name === `eq` &&\n      onExpression.args.length === 2\n    ) {\n      left = onExpression.args[0]!\n      right = onExpression.args[1]!\n    } else {\n      throw new JoinConditionMustBeEqualityError()\n    }\n\n    const joinClause: JoinClause = {\n      from,\n      type,\n      left,\n      right,\n    }\n\n    const existingJoins = this.query.join || []\n\n    return new BaseQueryBuilder({\n      ...this.query,\n      join: [...existingJoins, joinClause],\n    }) as any\n  }\n\n  /**\n   * Perform a LEFT JOIN with another table or subquery\n   *\n   * @param source - An object with a single key-value pair where the key is the table alias and the value is a Collection or subquery\n   * @param onCallback - A function that receives table references and returns the join condition\n   * @returns A QueryBuilder with the left joined table available\n   *\n   * @example\n   * ```ts\n   * // Left join users with posts\n   * query\n   *   .from({ users: usersCollection })\n   *   .leftJoin({ posts: postsCollection }, ({users, posts}) => eq(users.id, posts.userId))\n   * ```\n   */\n  leftJoin<TSource extends Source>(\n    source: TSource,\n    onCallback: JoinOnCallback<\n      MergeContextForJoinCallback<TContext, SchemaFromSource<TSource>>\n    >,\n  ): QueryBuilder<\n    MergeContextWithJoinType<TContext, SchemaFromSource<TSource>, `left`>\n  > {\n    return this.join(source, onCallback, `left`)\n  }\n\n  /**\n   * Perform a RIGHT JOIN with another table or subquery\n   *\n   * @param source - An object with a single key-value pair where the key is the table alias and the value is a Collection or subquery\n   * @param onCallback - A function that receives table references and returns the join condition\n   * @returns A QueryBuilder with the right joined table available\n   *\n   * @example\n   * ```ts\n   * // Right join users with posts\n   * query\n   *   .from({ users: usersCollection })\n   *   .rightJoin({ posts: postsCollection }, ({users, posts}) => eq(users.id, posts.userId))\n   * ```\n   */\n  rightJoin<TSource extends Source>(\n    source: TSource,\n    onCallback: JoinOnCallback<\n      MergeContextForJoinCallback<TContext, SchemaFromSource<TSource>>\n    >,\n  ): QueryBuilder<\n    MergeContextWithJoinType<TContext, SchemaFromSource<TSource>, `right`>\n  > {\n    return this.join(source, onCallback, `right`)\n  }\n\n  /**\n   * Perform an INNER JOIN with another table or subquery\n   *\n   * @param source - An object with a single key-value pair where the key is the table alias and the value is a Collection or subquery\n   * @param onCallback - A function that receives table references and returns the join condition\n   * @returns A QueryBuilder with the inner joined table available\n   *\n   * @example\n   * ```ts\n   * // Inner join users with posts\n   * query\n   *   .from({ users: usersCollection })\n   *   .innerJoin({ posts: postsCollection }, ({users, posts}) => eq(users.id, posts.userId))\n   * ```\n   */\n  innerJoin<TSource extends Source>(\n    source: TSource,\n    onCallback: JoinOnCallback<\n      MergeContextForJoinCallback<TContext, SchemaFromSource<TSource>>\n    >,\n  ): QueryBuilder<\n    MergeContextWithJoinType<TContext, SchemaFromSource<TSource>, `inner`>\n  > {\n    return this.join(source, onCallback, `inner`)\n  }\n\n  /**\n   * Perform a FULL JOIN with another table or subquery\n   *\n   * @param source - An object with a single key-value pair where the key is the table alias and the value is a Collection or subquery\n   * @param onCallback - A function that receives table references and returns the join condition\n   * @returns A QueryBuilder with the full joined table available\n   *\n   * @example\n   * ```ts\n   * // Full join users with posts\n   * query\n   *   .from({ users: usersCollection })\n   *   .fullJoin({ posts: postsCollection }, ({users, posts}) => eq(users.id, posts.userId))\n   * ```\n   */\n  fullJoin<TSource extends Source>(\n    source: TSource,\n    onCallback: JoinOnCallback<\n      MergeContextForJoinCallback<TContext, SchemaFromSource<TSource>>\n    >,\n  ): QueryBuilder<\n    MergeContextWithJoinType<TContext, SchemaFromSource<TSource>, `full`>\n  > {\n    return this.join(source, onCallback, `full`)\n  }\n\n  /**\n   * Filter rows based on a condition\n   *\n   * @param callback - A function that receives table references and returns an expression\n   * @returns A QueryBuilder with the where condition applied\n   *\n   * @example\n   * ```ts\n   * // Simple condition\n   * query\n   *   .from({ users: usersCollection })\n   *   .where(({users}) => gt(users.age, 18))\n   *\n   * // Multiple conditions\n   * query\n   *   .from({ users: usersCollection })\n   *   .where(({users}) => and(\n   *     gt(users.age, 18),\n   *     eq(users.active, true)\n   *   ))\n   *\n   * // Multiple where calls are ANDed together\n   * query\n   *   .from({ users: usersCollection })\n   *   .where(({users}) => gt(users.age, 18))\n   *   .where(({users}) => eq(users.active, true))\n   * ```\n   */\n  where(callback: WhereCallback<TContext>): QueryBuilder<TContext> {\n    const aliases = this._getCurrentAliases()\n    const refProxy = createRefProxy(aliases) as RefsForContext<TContext>\n    const rawExpression = callback(refProxy)\n\n    // Allow bare boolean column references like `.where(({ u }) => u.active)`\n    // by converting ref proxies to PropRef expressions, the same way helper\n    // functions like `not()` and `eq()` do via `toExpression()`.\n    const expression = isRefProxy(rawExpression)\n      ? toExpression(rawExpression)\n      : rawExpression\n\n    // Validate that the callback returned a valid expression\n    // This catches common mistakes like using JavaScript comparison operators (===, !==, etc.)\n    // which return boolean primitives instead of expression objects\n    if (!isExpressionLike(expression)) {\n      throw new InvalidWhereExpressionError(getValueTypeName(expression))\n    }\n\n    const existingWhere = this.query.where || []\n\n    return new BaseQueryBuilder({\n      ...this.query,\n      where: [...existingWhere, expression],\n    }) as any\n  }\n\n  /**\n   * Filter grouped rows based on aggregate conditions\n   *\n   * @param callback - A function that receives table references and returns an expression\n   * @returns A QueryBuilder with the having condition applied\n   *\n   * @example\n   * ```ts\n   * // Filter groups by count\n   * query\n   *   .from({ posts: postsCollection })\n   *   .groupBy(({posts}) => posts.userId)\n   *   .having(({posts}) => gt(count(posts.id), 5))\n   *\n   * // Filter by average\n   * query\n   *   .from({ orders: ordersCollection })\n   *   .groupBy(({orders}) => orders.customerId)\n   *   .having(({orders}) => gt(avg(orders.total), 100))\n   *\n   * // Multiple having calls are ANDed together\n   * query\n   *   .from({ orders: ordersCollection })\n   *   .groupBy(({orders}) => orders.customerId)\n   *   .having(({orders}) => gt(count(orders.id), 5))\n   *   .having(({orders}) => gt(avg(orders.total), 100))\n   * ```\n   */\n  having(callback: WhereCallback<TContext>): QueryBuilder<TContext> {\n    const aliases = this._getCurrentAliases()\n    // Add $selected namespace if SELECT clause exists (either regular or functional)\n    const refProxy = (\n      this.query.select || this.query.fnSelect\n        ? createRefProxyWithSelected(aliases)\n        : createRefProxy(aliases)\n    ) as RefsForContext<TContext>\n    const rawExpression = callback(refProxy)\n\n    // Allow bare boolean column references like `.having(({ $selected }) => $selected.isActive)`\n    // by converting ref proxies to PropRef expressions, the same way helper\n    // functions like `not()` and `eq()` do via `toExpression()`.\n    const expression = isRefProxy(rawExpression)\n      ? toExpression(rawExpression)\n      : rawExpression\n\n    // Validate that the callback returned a valid expression\n    // This catches common mistakes like using JavaScript comparison operators (===, !==, etc.)\n    // which return boolean primitives instead of expression objects\n    if (!isExpressionLike(expression)) {\n      throw new InvalidWhereExpressionError(getValueTypeName(expression))\n    }\n\n    const existingHaving = this.query.having || []\n\n    return new BaseQueryBuilder({\n      ...this.query,\n      having: [...existingHaving, expression],\n    }) as any\n  }\n\n  /**\n   * Select specific columns or computed values from the query\n   *\n   * @param callback - A function that receives table references and returns an object with selected fields or expressions\n   * @returns A QueryBuilder that returns only the selected fields\n   *\n   * @example\n   * ```ts\n   * // Select specific columns\n   * query\n   *   .from({ users: usersCollection })\n   *   .select(({users}) => ({\n   *     name: users.name,\n   *     email: users.email\n   *   }))\n   *\n   * // Select with computed values\n   * query\n   *   .from({ users: usersCollection })\n   *   .select(({users}) => ({\n   *     fullName: concat(users.firstName, ' ', users.lastName),\n   *     ageInMonths: mul(users.age, 12)\n   *   }))\n   *\n   * // Select with aggregates (requires GROUP BY)\n   * query\n   *   .from({ posts: postsCollection })\n   *   .groupBy(({posts}) => posts.userId)\n   *   .select(({posts, count}) => ({\n   *     userId: posts.userId,\n   *     postCount: count(posts.id)\n   *   }))\n   * ```\n   */\n  select<TSelectObject extends SelectObject>(\n    callback: (refs: RefsForContext<TContext>) => TSelectObject,\n  ): QueryBuilder<WithResult<TContext, ResultTypeFromSelect<TSelectObject>>> {\n    const aliases = this._getCurrentAliases()\n    const refProxy = createRefProxy(aliases) as RefsForContext<TContext>\n    const selectObject = callback(refProxy)\n    const select = buildNestedSelect(selectObject)\n\n    return new BaseQueryBuilder({\n      ...this.query,\n      select: select,\n      fnSelect: undefined, // remove the fnSelect clause if it exists\n    }) as any\n  }\n\n  /**\n   * Sort the query results by one or more columns\n   *\n   * @param callback - A function that receives table references and returns the field to sort by\n   * @param direction - Sort direction: 'asc' for ascending, 'desc' for descending (defaults to 'asc')\n   * @returns A QueryBuilder with the ordering applied\n   *\n   * @example\n   * ```ts\n   * // Sort by a single column\n   * query\n   *   .from({ users: usersCollection })\n   *   .orderBy(({users}) => users.name)\n   *\n   * // Sort descending\n   * query\n   *   .from({ users: usersCollection })\n   *   .orderBy(({users}) => users.createdAt, 'desc')\n   *\n   * // Multiple sorts (chain orderBy calls)\n   * query\n   *   .from({ users: usersCollection })\n   *   .orderBy(({users}) => users.lastName)\n   *   .orderBy(({users}) => users.firstName)\n   * ```\n   */\n  orderBy(\n    callback: OrderByCallback<TContext>,\n    options: OrderByDirection | OrderByOptions = `asc`,\n  ): QueryBuilder<TContext> {\n    const aliases = this._getCurrentAliases()\n    // Add $selected namespace if SELECT clause exists (either regular or functional)\n    const refProxy = (\n      this.query.select || this.query.fnSelect\n        ? createRefProxyWithSelected(aliases)\n        : createRefProxy(aliases)\n    ) as RefsForContext<TContext>\n    const result = callback(refProxy)\n\n    const opts: CompareOptions =\n      typeof options === `string`\n        ? { direction: options, nulls: `first` }\n        : {\n            direction: options.direction ?? `asc`,\n            nulls: options.nulls ?? `first`,\n            stringSort: options.stringSort,\n            locale:\n              options.stringSort === `locale` ? options.locale : undefined,\n            localeOptions:\n              options.stringSort === `locale`\n                ? options.localeOptions\n                : undefined,\n          }\n\n    const makeOrderByClause = (res: any) => {\n      return {\n        expression: toExpression(res),\n        compareOptions: opts,\n      }\n    }\n\n    // Create the new OrderBy structure with expression and direction\n    const orderByClauses = Array.isArray(result)\n      ? result.map((r) => makeOrderByClause(r))\n      : [makeOrderByClause(result)]\n\n    const existingOrderBy: OrderBy = this.query.orderBy || []\n\n    return new BaseQueryBuilder({\n      ...this.query,\n      orderBy: [...existingOrderBy, ...orderByClauses],\n    }) as any\n  }\n\n  /**\n   * Group rows by one or more columns for aggregation\n   *\n   * @param callback - A function that receives table references and returns the field(s) to group by\n   * @returns A QueryBuilder with grouping applied (enables aggregate functions in SELECT and HAVING)\n   *\n   * @example\n   * ```ts\n   * // Group by a single column\n   * query\n   *   .from({ posts: postsCollection })\n   *   .groupBy(({posts}) => posts.userId)\n   *   .select(({posts, count}) => ({\n   *     userId: posts.userId,\n   *     postCount: count()\n   *   }))\n   *\n   * // Group by multiple columns\n   * query\n   *   .from({ sales: salesCollection })\n   *   .groupBy(({sales}) => [sales.region, sales.category])\n   *   .select(({sales, sum}) => ({\n   *     region: sales.region,\n   *     category: sales.category,\n   *     totalSales: sum(sales.amount)\n   *   }))\n   * ```\n   */\n  groupBy(callback: GroupByCallback<TContext>): QueryBuilder<TContext> {\n    const aliases = this._getCurrentAliases()\n    const refProxy = createRefProxy(aliases) as RefsForContext<TContext>\n    const result = callback(refProxy)\n\n    const newExpressions = Array.isArray(result)\n      ? result.map((r) => toExpression(r))\n      : [toExpression(result)]\n\n    // Extend existing groupBy expressions (multiple groupBy calls should accumulate)\n    const existingGroupBy = this.query.groupBy || []\n    return new BaseQueryBuilder({\n      ...this.query,\n      groupBy: [...existingGroupBy, ...newExpressions],\n    }) as any\n  }\n\n  /**\n   * Limit the number of rows returned by the query\n   * `orderBy` is required for `limit`\n   *\n   * @param count - Maximum number of rows to return\n   * @returns A QueryBuilder with the limit applied\n   *\n   * @example\n   * ```ts\n   * // Get top 5 posts by likes\n   * query\n   *   .from({ posts: postsCollection })\n   *   .orderBy(({posts}) => posts.likes, 'desc')\n   *   .limit(5)\n   * ```\n   */\n  limit(count: number): QueryBuilder<TContext> {\n    return new BaseQueryBuilder({\n      ...this.query,\n      limit: count,\n    }) as any\n  }\n\n  /**\n   * Skip a number of rows before returning results\n   * `orderBy` is required for `offset`\n   *\n   * @param count - Number of rows to skip\n   * @returns A QueryBuilder with the offset applied\n   *\n   * @example\n   * ```ts\n   * // Get second page of results\n   * query\n   *   .from({ posts: postsCollection })\n   *   .orderBy(({posts}) => posts.createdAt, 'desc')\n   *   .offset(page * pageSize)\n   *   .limit(pageSize)\n   * ```\n   */\n  offset(count: number): QueryBuilder<TContext> {\n    return new BaseQueryBuilder({\n      ...this.query,\n      offset: count,\n    }) as any\n  }\n\n  /**\n   * Specify that the query should return distinct rows.\n   * Deduplicates rows based on the selected columns.\n   * @returns A QueryBuilder with distinct enabled\n   *\n   * @example\n   * ```ts\n   * // Get countries our users are from\n   * query\n   *   .from({ users: usersCollection })\n   *   .select(({users}) => users.country)\n   *   .distinct()\n   * ```\n   */\n  distinct(): QueryBuilder<TContext> {\n    return new BaseQueryBuilder({\n      ...this.query,\n      distinct: true,\n    }) as any\n  }\n\n  /**\n   * Specify that the query should return a single result\n   * @returns A QueryBuilder that returns the first result\n   *\n   * @example\n   * ```ts\n   * // Get the user matching the query\n   * query\n   *   .from({ users: usersCollection })\n   *   .where(({users}) => eq(users.id, 1))\n   *   .findOne()\n   *```\n   */\n  findOne(): QueryBuilder<TContext & SingleResult> {\n    return new BaseQueryBuilder({\n      ...this.query,\n      // TODO: enforcing return only one result with also a default orderBy if none is specified\n      // limit: 1,\n      singleResult: true,\n    })\n  }\n\n  // Helper methods\n  private _getCurrentAliases(): Array<string> {\n    const aliases: Array<string> = []\n\n    // Add the from alias\n    if (this.query.from) {\n      aliases.push(this.query.from.alias)\n    }\n\n    // Add join aliases\n    if (this.query.join) {\n      for (const join of this.query.join) {\n        aliases.push(join.from.alias)\n      }\n    }\n\n    return aliases\n  }\n\n  /**\n   * Functional variants of the query builder\n   * These are imperative function that are called for ery row.\n   * Warning: that these cannot be optimized by the query compiler, and may prevent\n   * some type of optimizations being possible.\n   * @example\n   * ```ts\n   * q.fn.select((row) => ({\n   *   name: row.user.name.toUpperCase(),\n   *   age: row.user.age + 1,\n   * }))\n   * ```\n   */\n  get fn() {\n    const builder = this\n    return {\n      /**\n       * Select fields using a function that operates on each row\n       * Warning: This cannot be optimized by the query compiler\n       *\n       * @param callback - A function that receives a row and returns the selected value\n       * @returns A QueryBuilder with functional selection applied\n       *\n       * @example\n       * ```ts\n       * // Functional select (not optimized)\n       * query\n       *   .from({ users: usersCollection })\n       *   .fn.select(row => ({\n       *     name: row.users.name.toUpperCase(),\n       *     age: row.users.age + 1,\n       *   }))\n       * ```\n       */\n      select<TFuncSelectResult>(\n        callback: (row: TContext[`schema`]) => TFuncSelectResult,\n      ): QueryBuilder<WithResult<TContext, TFuncSelectResult>> {\n        return new BaseQueryBuilder({\n          ...builder.query,\n          select: undefined, // remove the select clause if it exists\n          fnSelect: callback,\n        })\n      },\n      /**\n       * Filter rows using a function that operates on each row\n       * Warning: This cannot be optimized by the query compiler\n       *\n       * @param callback - A function that receives a row and returns a boolean\n       * @returns A QueryBuilder with functional filtering applied\n       *\n       * @example\n       * ```ts\n       * // Functional where (not optimized)\n       * query\n       *   .from({ users: usersCollection })\n       *   .fn.where(row => row.users.name.startsWith('A'))\n       * ```\n       */\n      where(\n        callback: (row: TContext[`schema`]) => any,\n      ): QueryBuilder<TContext> {\n        return new BaseQueryBuilder({\n          ...builder.query,\n          fnWhere: [\n            ...(builder.query.fnWhere || []),\n            callback as (row: NamespacedRow) => any,\n          ],\n        })\n      },\n      /**\n       * Filter grouped rows using a function that operates on each aggregated row\n       * Warning: This cannot be optimized by the query compiler\n       *\n       * @param callback - A function that receives an aggregated row (with $selected when select() was called) and returns a boolean\n       * @returns A QueryBuilder with functional having filter applied\n       *\n       * @example\n       * ```ts\n       * // Functional having (not optimized)\n       * query\n       *   .from({ posts: postsCollection })\n       *   .groupBy(({posts}) => posts.userId)\n       *   .select(({posts}) => ({ userId: posts.userId, count: count(posts.id) }))\n       *   .fn.having(({ $selected }) => $selected.count > 5)\n       * ```\n       */\n      having(\n        callback: (row: FunctionalHavingRow<TContext>) => any,\n      ): QueryBuilder<TContext> {\n        return new BaseQueryBuilder({\n          ...builder.query,\n          fnHaving: [\n            ...(builder.query.fnHaving || []),\n            callback as (row: NamespacedRow) => any,\n          ],\n        })\n      },\n    }\n  }\n\n  _getQuery(): QueryIR {\n    if (!this.query.from) {\n      throw new QueryMustHaveFromClauseError()\n    }\n    return this.query as QueryIR\n  }\n}\n\n// Helper to get a descriptive type name for error messages\nfunction getValueTypeName(value: unknown): string {\n  if (value === null) return `null`\n  if (value === undefined) return `undefined`\n  if (typeof value === `object`) return `object`\n  return typeof value\n}\n\n// Helper to ensure we have a BasicExpression/Aggregate for a value\nfunction toExpr(value: any): BasicExpression | Aggregate {\n  if (value === undefined) return toExpression(null)\n  if (\n    value instanceof AggregateExpr ||\n    value instanceof FuncExpr ||\n    value instanceof PropRef ||\n    value instanceof ValueExpr\n  ) {\n    return value as BasicExpression | Aggregate\n  }\n  return toExpression(value)\n}\n\nfunction isPlainObject(value: any): value is Record<string, any> {\n  return (\n    value !== null &&\n    typeof value === `object` &&\n    !isExpressionLike(value) &&\n    !value.__refProxy\n  )\n}\n\nfunction buildNestedSelect(obj: any): any {\n  if (!isPlainObject(obj)) return toExpr(obj)\n  const out: Record<string, any> = {}\n  for (const [k, v] of Object.entries(obj)) {\n    if (typeof k === `string` && k.startsWith(`__SPREAD_SENTINEL__`)) {\n      // Preserve sentinel key and its value (value is unimportant at compile time)\n      out[k] = v\n      continue\n    }\n    out[k] = buildNestedSelect(v)\n  }\n  return out\n}\n\n// Internal function to build a query from a callback\n// used by liveQueryCollectionOptions.query\nexport function buildQuery<TContext extends Context>(\n  fn: (builder: InitialQueryBuilder) => QueryBuilder<TContext>,\n): QueryIR {\n  const result = fn(new BaseQueryBuilder())\n  return getQueryIR(result)\n}\n\n// Internal function to get the QueryIR from a builder\nexport function getQueryIR(\n  builder: BaseQueryBuilder | QueryBuilder<any> | InitialQueryBuilder,\n): QueryIR {\n  return (builder as unknown as BaseQueryBuilder)._getQuery()\n}\n\n// Type-only exports for the query builder\nexport type InitialQueryBuilder = Pick<BaseQueryBuilder<Context>, `from`>\n\nexport type InitialQueryBuilderConstructor = new () => InitialQueryBuilder\n\nexport type QueryBuilder<TContext extends Context> = Omit<\n  BaseQueryBuilder<TContext>,\n  `from` | `_getQuery`\n>\n\n// Main query builder class alias with the constructor type modified to hide all\n// but the from method on the initial instance\nexport const Query: InitialQueryBuilderConstructor = BaseQueryBuilder\n\n// Helper type to extract context from a QueryBuilder\nexport type ExtractContext<T> =\n  T extends BaseQueryBuilder<infer TContext>\n    ? TContext\n    : T extends QueryBuilder<infer TContext>\n      ? TContext\n      : never\n\n// Helper type to extract the result type from a QueryBuilder (similar to Zod's z.infer)\nexport type QueryResult<T> = GetResult<ExtractContext<T>>\n\n// Export the types from types.ts for convenience\nexport type {\n  Context,\n  ContextSchema,\n  Source,\n  GetResult,\n  RefLeaf as Ref,\n  InferResultType,\n  // Types used in public method signatures that must be exported\n  // for declaration emit to work (see https://github.com/TanStack/db/issues/1012)\n  SchemaFromSource,\n  InferCollectionType,\n  MergeContextWithJoinType,\n  MergeContextForJoinCallback,\n  ApplyJoinOptionalityToMergedSchema,\n  ResultTypeFromSelect,\n  WithResult,\n  JoinOnCallback,\n  RefsForContext,\n  WhereCallback,\n  OrderByCallback,\n  GroupByCallback,\n  SelectObject,\n  FunctionalHavingRow,\n  Prettify,\n} from './types.js'\n"],"names":["InvalidSourceTypeError","OnlyOneSourceAllowedError","CollectionImpl","CollectionRef","SubQueryMustHaveFromClauseError","QueryRef","InvalidSourceError","refProxy","createRefProxy","JoinConditionMustBeEqualityError","isRefProxy","toExpression","isExpressionLike","InvalidWhereExpressionError","createRefProxyWithSelected","QueryMustHaveFromClauseError","AggregateExpr","FuncExpr","PropRef","ValueExpr"],"mappings":";;;;;;AAsDO,MAAM,iBAAqD;AAAA,EAGhE,YAAY,QAA0B,IAAI;AAF1C,SAAiB,QAA0B,CAAA;AAGzC,SAAK,QAAQ,EAAE,GAAG,MAAA;AAAA,EACpB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQQ,oBACN,QACA,SACoC;AAGpC,QAAI;AACJ,QAAI;AACF,aAAO,OAAO,KAAK,MAAM;AAAA,IAC3B,QAAQ;AAEN,YAAM,OAAO,WAAW,OAAO,SAAS;AACxC,YAAM,IAAIA,OAAAA,uBAAuB,SAAS,IAAI;AAAA,IAChD;AAGA,QAAI,MAAM,QAAQ,MAAM,GAAG;AACzB,YAAM,IAAIA,OAAAA,uBAAuB,SAAS,OAAO;AAAA,IACnD;AAGA,QAAI,KAAK,WAAW,GAAG;AACrB,UAAI,KAAK,WAAW,GAAG;AACrB,cAAM,IAAIA,OAAAA,uBAAuB,SAAS,cAAc;AAAA,MAC1D;AAEA,UAAI,KAAK,MAAM,CAAC,MAAM,CAAC,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG;AACxC,cAAM,IAAIA,OAAAA,uBAAuB,SAAS,QAAQ;AAAA,MACpD;AACA,YAAM,IAAIC,OAAAA,0BAA0B,OAAO;AAAA,IAC7C;AAEA,UAAM,QAAQ,KAAK,CAAC;AACpB,UAAM,cAAc,OAAO,KAAK;AAGhC,QAAI;AAEJ,QAAI,uBAAuBC,MAAAA,gBAAgB;AACzC,YAAM,IAAIC,GAAAA,cAAc,aAAa,KAAK;AAAA,IAC5C,WAAW,uBAAuB,kBAAkB;AAClD,YAAM,WAAW,YAAY,UAAA;AAC7B,UAAI,CAAE,SAA8B,MAAM;AACxC,cAAM,IAAIC,OAAAA,gCAAgC,OAAO;AAAA,MACnD;AACA,YAAM,IAAIC,GAAAA,SAAS,UAAU,KAAK;AAAA,IACpC,OAAO;AACL,YAAM,IAAIC,OAAAA,mBAAmB,KAAK;AAAA,IACpC;AAEA,WAAO,CAAC,OAAO,GAAG;AAAA,EACpB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAkBA,KACE,QAMC;AACD,UAAM,CAAA,EAAG,IAAI,IAAI,KAAK,oBAAoB,QAAQ,aAAa;AAE/D,WAAO,IAAI,iBAAiB;AAAA,MAC1B,GAAG,KAAK;AAAA,MACR;AAAA,IAAA,CACD;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA6BA,KAIE,QACA,YAGA,OAAkB,QAGlB;AACA,UAAM,CAAC,OAAO,IAAI,IAAI,KAAK,oBAAoB,QAAQ,aAAa;AAGpE,UAAM,iBAAiB,KAAK,mBAAA;AAC5B,UAAM,aAAa,CAAC,GAAG,gBAAgB,KAAK;AAC5C,UAAMC,aAAWC,SAAAA,eAAe,UAAU;AAK1C,UAAM,eAAe,WAAWD,UAAQ;AAIxC,QAAI;AACJ,QAAI;AAEJ,QACE,aAAa,SAAS,UACtB,aAAa,SAAS,QACtB,aAAa,KAAK,WAAW,GAC7B;AACA,aAAO,aAAa,KAAK,CAAC;AAC1B,cAAQ,aAAa,KAAK,CAAC;AAAA,IAC7B,OAAO;AACL,YAAM,IAAIE,OAAAA,iCAAA;AAAA,IACZ;AAEA,UAAM,aAAyB;AAAA,MAC7B;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAGF,UAAM,gBAAgB,KAAK,MAAM,QAAQ,CAAA;AAEzC,WAAO,IAAI,iBAAiB;AAAA,MAC1B,GAAG,KAAK;AAAA,MACR,MAAM,CAAC,GAAG,eAAe,UAAU;AAAA,IAAA,CACpC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiBA,SACE,QACA,YAKA;AACA,WAAO,KAAK,KAAK,QAAQ,YAAY,MAAM;AAAA,EAC7C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiBA,UACE,QACA,YAKA;AACA,WAAO,KAAK,KAAK,QAAQ,YAAY,OAAO;AAAA,EAC9C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiBA,UACE,QACA,YAKA;AACA,WAAO,KAAK,KAAK,QAAQ,YAAY,OAAO;AAAA,EAC9C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiBA,SACE,QACA,YAKA;AACA,WAAO,KAAK,KAAK,QAAQ,YAAY,MAAM;AAAA,EAC7C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA8BA,MAAM,UAA2D;AAC/D,UAAM,UAAU,KAAK,mBAAA;AACrB,UAAMF,aAAWC,SAAAA,eAAe,OAAO;AACvC,UAAM,gBAAgB,SAASD,UAAQ;AAKvC,UAAM,aAAaG,SAAAA,WAAW,aAAa,IACvCC,SAAAA,aAAa,aAAa,IAC1B;AAKJ,QAAI,CAACC,GAAAA,iBAAiB,UAAU,GAAG;AACjC,YAAM,IAAIC,OAAAA,4BAA4B,iBAAiB,UAAU,CAAC;AAAA,IACpE;AAEA,UAAM,gBAAgB,KAAK,MAAM,SAAS,CAAA;AAE1C,WAAO,IAAI,iBAAiB;AAAA,MAC1B,GAAG,KAAK;AAAA,MACR,OAAO,CAAC,GAAG,eAAe,UAAU;AAAA,IAAA,CACrC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA8BA,OAAO,UAA2D;AAChE,UAAM,UAAU,KAAK,mBAAA;AAErB,UAAMN,aACJ,KAAK,MAAM,UAAU,KAAK,MAAM,WAC5BO,SAAAA,2BAA2B,OAAO,IAClCN,SAAAA,eAAe,OAAO;AAE5B,UAAM,gBAAgB,SAASD,UAAQ;AAKvC,UAAM,aAAaG,SAAAA,WAAW,aAAa,IACvCC,SAAAA,aAAa,aAAa,IAC1B;AAKJ,QAAI,CAACC,GAAAA,iBAAiB,UAAU,GAAG;AACjC,YAAM,IAAIC,OAAAA,4BAA4B,iBAAiB,UAAU,CAAC;AAAA,IACpE;AAEA,UAAM,iBAAiB,KAAK,MAAM,UAAU,CAAA;AAE5C,WAAO,IAAI,iBAAiB;AAAA,MAC1B,GAAG,KAAK;AAAA,MACR,QAAQ,CAAC,GAAG,gBAAgB,UAAU;AAAA,IAAA,CACvC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAoCA,OACE,UACyE;AACzE,UAAM,UAAU,KAAK,mBAAA;AACrB,UAAMN,aAAWC,SAAAA,eAAe,OAAO;AACvC,UAAM,eAAe,SAASD,UAAQ;AACtC,UAAM,SAAS,kBAAkB,YAAY;AAE7C,WAAO,IAAI,iBAAiB;AAAA,MAC1B,GAAG,KAAK;AAAA,MACR;AAAA,MACA,UAAU;AAAA;AAAA,IAAA,CACX;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA4BA,QACE,UACA,UAA6C,OACrB;AACxB,UAAM,UAAU,KAAK,mBAAA;AAErB,UAAMA,aACJ,KAAK,MAAM,UAAU,KAAK,MAAM,WAC5BO,SAAAA,2BAA2B,OAAO,IAClCN,SAAAA,eAAe,OAAO;AAE5B,UAAM,SAAS,SAASD,UAAQ;AAEhC,UAAM,OACJ,OAAO,YAAY,WACf,EAAE,WAAW,SAAS,OAAO,QAAA,IAC7B;AAAA,MACE,WAAW,QAAQ,aAAa;AAAA,MAChC,OAAO,QAAQ,SAAS;AAAA,MACxB,YAAY,QAAQ;AAAA,MACpB,QACE,QAAQ,eAAe,WAAW,QAAQ,SAAS;AAAA,MACrD,eACE,QAAQ,eAAe,WACnB,QAAQ,gBACR;AAAA,IAAA;AAGd,UAAM,oBAAoB,CAAC,QAAa;AACtC,aAAO;AAAA,QACL,YAAYI,SAAAA,aAAa,GAAG;AAAA,QAC5B,gBAAgB;AAAA,MAAA;AAAA,IAEpB;AAGA,UAAM,iBAAiB,MAAM,QAAQ,MAAM,IACvC,OAAO,IAAI,CAAC,MAAM,kBAAkB,CAAC,CAAC,IACtC,CAAC,kBAAkB,MAAM,CAAC;AAE9B,UAAM,kBAA2B,KAAK,MAAM,WAAW,CAAA;AAEvD,WAAO,IAAI,iBAAiB;AAAA,MAC1B,GAAG,KAAK;AAAA,MACR,SAAS,CAAC,GAAG,iBAAiB,GAAG,cAAc;AAAA,IAAA,CAChD;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA8BA,QAAQ,UAA6D;AACnE,UAAM,UAAU,KAAK,mBAAA;AACrB,UAAMJ,aAAWC,SAAAA,eAAe,OAAO;AACvC,UAAM,SAAS,SAASD,UAAQ;AAEhC,UAAM,iBAAiB,MAAM,QAAQ,MAAM,IACvC,OAAO,IAAI,CAAC,MAAMI,SAAAA,aAAa,CAAC,CAAC,IACjC,CAACA,SAAAA,aAAa,MAAM,CAAC;AAGzB,UAAM,kBAAkB,KAAK,MAAM,WAAW,CAAA;AAC9C,WAAO,IAAI,iBAAiB;AAAA,MAC1B,GAAG,KAAK;AAAA,MACR,SAAS,CAAC,GAAG,iBAAiB,GAAG,cAAc;AAAA,IAAA,CAChD;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAkBA,MAAM,OAAuC;AAC3C,WAAO,IAAI,iBAAiB;AAAA,MAC1B,GAAG,KAAK;AAAA,MACR,OAAO;AAAA,IAAA,CACR;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAmBA,OAAO,OAAuC;AAC5C,WAAO,IAAI,iBAAiB;AAAA,MAC1B,GAAG,KAAK;AAAA,MACR,QAAQ;AAAA,IAAA,CACT;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgBA,WAAmC;AACjC,WAAO,IAAI,iBAAiB;AAAA,MAC1B,GAAG,KAAK;AAAA,MACR,UAAU;AAAA,IAAA,CACX;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,UAAiD;AAC/C,WAAO,IAAI,iBAAiB;AAAA,MAC1B,GAAG,KAAK;AAAA;AAAA;AAAA,MAGR,cAAc;AAAA,IAAA,CACf;AAAA,EACH;AAAA;AAAA,EAGQ,qBAAoC;AAC1C,UAAM,UAAyB,CAAA;AAG/B,QAAI,KAAK,MAAM,MAAM;AACnB,cAAQ,KAAK,KAAK,MAAM,KAAK,KAAK;AAAA,IACpC;AAGA,QAAI,KAAK,MAAM,MAAM;AACnB,iBAAW,QAAQ,KAAK,MAAM,MAAM;AAClC,gBAAQ,KAAK,KAAK,KAAK,KAAK;AAAA,MAC9B;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,IAAI,KAAK;AACP,UAAM,UAAU;AAChB,WAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAmBL,OACE,UACuD;AACvD,eAAO,IAAI,iBAAiB;AAAA,UAC1B,GAAG,QAAQ;AAAA,UACX,QAAQ;AAAA;AAAA,UACR,UAAU;AAAA,QAAA,CACX;AAAA,MACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAgBA,MACE,UACwB;AACxB,eAAO,IAAI,iBAAiB;AAAA,UAC1B,GAAG,QAAQ;AAAA,UACX,SAAS;AAAA,YACP,GAAI,QAAQ,MAAM,WAAW,CAAA;AAAA,YAC7B;AAAA,UAAA;AAAA,QACF,CACD;AAAA,MACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAkBA,OACE,UACwB;AACxB,eAAO,IAAI,iBAAiB;AAAA,UAC1B,GAAG,QAAQ;AAAA,UACX,UAAU;AAAA,YACR,GAAI,QAAQ,MAAM,YAAY,CAAA;AAAA,YAC9B;AAAA,UAAA;AAAA,QACF,CACD;AAAA,MACH;AAAA,IAAA;AAAA,EAEJ;AAAA,EAEA,YAAqB;AACnB,QAAI,CAAC,KAAK,MAAM,MAAM;AACpB,YAAM,IAAII,OAAAA,6BAAA;AAAA,IACZ;AACA,WAAO,KAAK;AAAA,EACd;AACF;AAGA,SAAS,iBAAiB,OAAwB;AAChD,MAAI,UAAU,KAAM,QAAO;AAC3B,MAAI,UAAU,OAAW,QAAO;AAChC,MAAI,OAAO,UAAU,SAAU,QAAO;AACtC,SAAO,OAAO;AAChB;AAGA,SAAS,OAAO,OAAyC;AACvD,MAAI,UAAU,OAAW,QAAOJ,SAAAA,aAAa,IAAI;AACjD,MACE,iBAAiBK,GAAAA,aACjB,iBAAiBC,GAAAA,QACjB,iBAAiBC,GAAAA,WACjB,iBAAiBC,UACjB;AACA,WAAO;AAAA,EACT;AACA,SAAOR,SAAAA,aAAa,KAAK;AAC3B;AAEA,SAAS,cAAc,OAA0C;AAC/D,SACE,UAAU,QACV,OAAO,UAAU,YACjB,CAACC,oBAAiB,KAAK,KACvB,CAAC,MAAM;AAEX;AAEA,SAAS,kBAAkB,KAAe;AACxC,MAAI,CAAC,cAAc,GAAG,EAAG,QAAO,OAAO,GAAG;AAC1C,QAAM,MAA2B,CAAA;AACjC,aAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,GAAG,GAAG;AACxC,QAAI,OAAO,MAAM,YAAY,EAAE,WAAW,qBAAqB,GAAG;AAEhE,UAAI,CAAC,IAAI;AACT;AAAA,IACF;AACA,QAAI,CAAC,IAAI,kBAAkB,CAAC;AAAA,EAC9B;AACA,SAAO;AACT;AAIO,SAAS,WACd,IACS;AACT,QAAM,SAAS,GAAG,IAAI,kBAAkB;AACxC,SAAO,WAAW,MAAM;AAC1B;AAGO,SAAS,WACd,SACS;AACT,SAAQ,QAAwC,UAAA;AAClD;AAcO,MAAM,QAAwC;;;;;"}