{"version":3,"file":"btree-index.cjs","sources":["../../../src/indexes/btree-index.ts"],"sourcesContent":["import { compareKeys } from '@tanstack/db-ivm'\nimport { BTree } from '../utils/btree.js'\nimport {\n  defaultComparator,\n  denormalizeUndefined,\n  normalizeForBTree,\n} from '../utils/comparison.js'\nimport { BaseIndex } from './base-index.js'\nimport type { CompareOptions } from '../query/builder/types.js'\nimport type { BasicExpression } from '../query/ir.js'\nimport type { IndexOperation } from './base-index.js'\n\n/**\n * Options for Ordered index\n */\nexport interface BTreeIndexOptions {\n  compareFn?: (a: any, b: any) => number\n  compareOptions?: CompareOptions\n}\n\n/**\n * Options for range queries\n */\nexport interface RangeQueryOptions {\n  from?: any\n  to?: any\n  fromInclusive?: boolean\n  toInclusive?: boolean\n}\n\n/**\n * B+Tree index for sorted data with range queries\n * This maintains items in sorted order and provides efficient range operations\n */\nexport class BTreeIndex<\n  TKey extends string | number = string | number,\n> extends BaseIndex<TKey> {\n  public readonly supportedOperations = new Set<IndexOperation>([\n    `eq`,\n    `gt`,\n    `gte`,\n    `lt`,\n    `lte`,\n    `in`,\n  ])\n\n  // Internal data structures - private to hide implementation details\n  // The `orderedEntries` B+ tree is used for efficient range queries\n  // The `valueMap` is used for O(1) lookups of PKs by indexed value\n  private orderedEntries: BTree<any, undefined> // we don't associate values with the keys of the B+ tree (the keys are indexed values)\n  private valueMap = new Map<any, Set<TKey>>() // instead we store a mapping of indexed values to a set of PKs\n  private indexedKeys = new Set<TKey>()\n  private compareFn: (a: any, b: any) => number = defaultComparator\n\n  constructor(\n    id: number,\n    expression: BasicExpression,\n    name?: string,\n    options?: any,\n  ) {\n    super(id, expression, name, options)\n\n    // Get the base compare function\n    const baseCompareFn = options?.compareFn ?? defaultComparator\n\n    // Wrap it to denormalize sentinels before comparison\n    // This ensures UNDEFINED_SENTINEL is converted back to undefined\n    // before being passed to the baseCompareFn (which can be user-provided and is unaware of the UNDEFINED_SENTINEL)\n    this.compareFn = (a: any, b: any) =>\n      baseCompareFn(denormalizeUndefined(a), denormalizeUndefined(b))\n\n    if (options?.compareOptions) {\n      this.compareOptions = options!.compareOptions\n    }\n    this.orderedEntries = new BTree(this.compareFn)\n  }\n\n  protected initialize(_options?: BTreeIndexOptions): void {}\n\n  /**\n   * Adds a value to the index\n   */\n  add(key: TKey, item: any): void {\n    let indexedValue: any\n    try {\n      indexedValue = this.evaluateIndexExpression(item)\n    } catch (error) {\n      throw new Error(\n        `Failed to evaluate index expression for key ${key}: ${error}`,\n      )\n    }\n\n    // Normalize the value for Map key usage\n    const normalizedValue = normalizeForBTree(indexedValue)\n\n    // Check if this value already exists\n    if (this.valueMap.has(normalizedValue)) {\n      // Add to existing set\n      this.valueMap.get(normalizedValue)!.add(key)\n    } else {\n      // Create new set for this value\n      const keySet = new Set<TKey>([key])\n      this.valueMap.set(normalizedValue, keySet)\n      this.orderedEntries.set(normalizedValue, undefined)\n    }\n\n    this.indexedKeys.add(key)\n    this.updateTimestamp()\n  }\n\n  /**\n   * Removes a value from the index\n   */\n  remove(key: TKey, item: any): void {\n    let indexedValue: any\n    try {\n      indexedValue = this.evaluateIndexExpression(item)\n    } catch (error) {\n      console.warn(\n        `Failed to evaluate index expression for key ${key} during removal:`,\n        error,\n      )\n      return\n    }\n\n    // Normalize the value for Map key usage\n    const normalizedValue = normalizeForBTree(indexedValue)\n\n    if (this.valueMap.has(normalizedValue)) {\n      const keySet = this.valueMap.get(normalizedValue)!\n      keySet.delete(key)\n\n      // If set is now empty, remove the entry entirely\n      if (keySet.size === 0) {\n        this.valueMap.delete(normalizedValue)\n\n        // Remove from ordered entries\n        this.orderedEntries.delete(normalizedValue)\n      }\n    }\n\n    this.indexedKeys.delete(key)\n    this.updateTimestamp()\n  }\n\n  /**\n   * Updates a value in the index\n   */\n  update(key: TKey, oldItem: any, newItem: any): void {\n    this.remove(key, oldItem)\n    this.add(key, newItem)\n  }\n\n  /**\n   * Builds the index from a collection of entries\n   */\n  build(entries: Iterable<[TKey, any]>): void {\n    this.clear()\n\n    for (const [key, item] of entries) {\n      this.add(key, item)\n    }\n  }\n\n  /**\n   * Clears all data from the index\n   */\n  clear(): void {\n    this.orderedEntries.clear()\n    this.valueMap.clear()\n    this.indexedKeys.clear()\n    this.updateTimestamp()\n  }\n\n  /**\n   * Performs a lookup operation\n   */\n  lookup(operation: IndexOperation, value: any): Set<TKey> {\n    const startTime = performance.now()\n\n    let result: Set<TKey>\n\n    switch (operation) {\n      case `eq`:\n        result = this.equalityLookup(value)\n        break\n      case `gt`:\n        result = this.rangeQuery({ from: value, fromInclusive: false })\n        break\n      case `gte`:\n        result = this.rangeQuery({ from: value, fromInclusive: true })\n        break\n      case `lt`:\n        result = this.rangeQuery({ to: value, toInclusive: false })\n        break\n      case `lte`:\n        result = this.rangeQuery({ to: value, toInclusive: true })\n        break\n      case `in`:\n        result = this.inArrayLookup(value)\n        break\n      default:\n        throw new Error(`Operation ${operation} not supported by BTreeIndex`)\n    }\n\n    this.trackLookup(startTime)\n    return result\n  }\n\n  /**\n   * Gets the number of indexed keys\n   */\n  get keyCount(): number {\n    return this.indexedKeys.size\n  }\n\n  // Public methods for backward compatibility (used by tests)\n\n  /**\n   * Performs an equality lookup\n   */\n  equalityLookup(value: any): Set<TKey> {\n    const normalizedValue = normalizeForBTree(value)\n    return new Set(this.valueMap.get(normalizedValue) ?? [])\n  }\n\n  /**\n   * Performs a range query with options\n   * This is more efficient for compound queries like \"WHERE a > 5 AND a < 10\"\n   */\n  rangeQuery(options: RangeQueryOptions = {}): Set<TKey> {\n    const { from, to, fromInclusive = true, toInclusive = true } = options\n    const result = new Set<TKey>()\n\n    // Check if from/to were explicitly provided (even if undefined)\n    // vs not provided at all (should use min/max key)\n    const hasFrom = `from` in options\n    const hasTo = `to` in options\n\n    const fromKey = hasFrom\n      ? normalizeForBTree(from)\n      : this.orderedEntries.minKey()\n    const toKey = hasTo ? normalizeForBTree(to) : this.orderedEntries.maxKey()\n\n    this.orderedEntries.forRange(\n      fromKey,\n      toKey,\n      toInclusive,\n      (indexedValue, _) => {\n        if (!fromInclusive && this.compareFn(indexedValue, from) === 0) {\n          // the B+ tree `forRange` method does not support exclusive lower bounds\n          // so we need to exclude it manually\n          return\n        }\n\n        const keys = this.valueMap.get(indexedValue)\n        if (keys) {\n          keys.forEach((key) => result.add(key))\n        }\n      },\n    )\n\n    return result\n  }\n\n  /**\n   * Performs a reversed range query\n   */\n  rangeQueryReversed(options: RangeQueryOptions = {}): Set<TKey> {\n    const { from, to, fromInclusive = true, toInclusive = true } = options\n    const hasFrom = `from` in options\n    const hasTo = `to` in options\n\n    // Swap from/to for reversed query, respecting explicit undefined values\n    return this.rangeQuery({\n      from: hasTo ? to : this.orderedEntries.maxKey(),\n      to: hasFrom ? from : this.orderedEntries.minKey(),\n      fromInclusive: toInclusive,\n      toInclusive: fromInclusive,\n    })\n  }\n\n  /**\n   * Internal method for taking items from the index.\n   * @param n - The number of items to return\n   * @param nextPair - Function to get the next pair from the BTree\n   * @param from - Already normalized! undefined means \"start from beginning/end\", sentinel means \"start from the key undefined\"\n   * @param filterFn - Optional filter function\n   * @param reversed - Whether to reverse the order of keys within each value\n   */\n  private takeInternal(\n    n: number,\n    nextPair: (k?: any) => [any, any] | undefined,\n    from: any,\n    filterFn?: (key: TKey) => boolean,\n    reversed: boolean = false,\n  ): Array<TKey> {\n    const keysInResult: Set<TKey> = new Set()\n    const result: Array<TKey> = []\n    let pair: [any, any] | undefined\n    let key = from // Use as-is - it's already normalized by the caller\n\n    while ((pair = nextPair(key)) !== undefined && result.length < n) {\n      key = pair[0]\n      const keys = this.valueMap.get(key) as\n        | Set<Exclude<TKey, undefined>>\n        | undefined\n      if (keys && keys.size > 0) {\n        // Sort keys for deterministic order, reverse if needed\n        const sorted = Array.from(keys).sort(compareKeys)\n        if (reversed) sorted.reverse()\n        for (const ks of sorted) {\n          if (result.length >= n) break\n          if (!keysInResult.has(ks) && (filterFn?.(ks) ?? true)) {\n            result.push(ks)\n            keysInResult.add(ks)\n          }\n        }\n      }\n    }\n\n    return result\n  }\n\n  /**\n   * Returns the next n items after the provided item.\n   * @param n - The number of items to return\n   * @param from - The item to start from (exclusive).\n   * @returns The next n items after the provided key.\n   */\n  take(n: number, from: any, filterFn?: (key: TKey) => boolean): Array<TKey> {\n    const nextPair = (k?: any) => this.orderedEntries.nextHigherPair(k)\n    // Normalize the from value\n    const normalizedFrom = normalizeForBTree(from)\n    return this.takeInternal(n, nextPair, normalizedFrom, filterFn)\n  }\n\n  /**\n   * Returns the first n items from the beginning.\n   * @param n - The number of items to return\n   * @param filterFn - Optional filter function\n   * @returns The first n items\n   */\n  takeFromStart(n: number, filterFn?: (key: TKey) => boolean): Array<TKey> {\n    const nextPair = (k?: any) => this.orderedEntries.nextHigherPair(k)\n    // Pass undefined to mean \"start from beginning\" (BTree's native behavior)\n    return this.takeInternal(n, nextPair, undefined, filterFn)\n  }\n\n  /**\n   * Returns the next n items **before** the provided item (in descending order).\n   * @param n - The number of items to return\n   * @param from - The item to start from (exclusive). Required.\n   * @returns The next n items **before** the provided key.\n   */\n  takeReversed(\n    n: number,\n    from: any,\n    filterFn?: (key: TKey) => boolean,\n  ): Array<TKey> {\n    const nextPair = (k?: any) => this.orderedEntries.nextLowerPair(k)\n    // Normalize the from value\n    const normalizedFrom = normalizeForBTree(from)\n    return this.takeInternal(n, nextPair, normalizedFrom, filterFn, true)\n  }\n\n  /**\n   * Returns the last n items from the end.\n   * @param n - The number of items to return\n   * @param filterFn - Optional filter function\n   * @returns The last n items\n   */\n  takeReversedFromEnd(\n    n: number,\n    filterFn?: (key: TKey) => boolean,\n  ): Array<TKey> {\n    const nextPair = (k?: any) => this.orderedEntries.nextLowerPair(k)\n    // Pass undefined to mean \"start from end\" (BTree's native behavior)\n    return this.takeInternal(n, nextPair, undefined, filterFn, true)\n  }\n\n  /**\n   * Performs an IN array lookup\n   */\n  inArrayLookup(values: Array<any>): Set<TKey> {\n    const result = new Set<TKey>()\n\n    for (const value of values) {\n      const normalizedValue = normalizeForBTree(value)\n      const keys = this.valueMap.get(normalizedValue)\n      if (keys) {\n        keys.forEach((key) => result.add(key))\n      }\n    }\n\n    return result\n  }\n\n  // Getter methods for testing compatibility\n  get indexedKeysSet(): Set<TKey> {\n    return this.indexedKeys\n  }\n\n  get orderedEntriesArray(): Array<[any, Set<TKey>]> {\n    return this.orderedEntries\n      .keysArray()\n      .map((key) => [\n        denormalizeUndefined(key),\n        this.valueMap.get(key) ?? new Set(),\n      ])\n  }\n\n  get orderedEntriesArrayReversed(): Array<[any, Set<TKey>]> {\n    return this.takeReversedFromEnd(this.orderedEntries.size).map((key) => [\n      denormalizeUndefined(key),\n      this.valueMap.get(key) ?? new Set(),\n    ])\n  }\n\n  get valueMapData(): Map<any, Set<TKey>> {\n    // Return a new Map with denormalized keys\n    const result = new Map<any, Set<TKey>>()\n    for (const [key, value] of this.valueMap) {\n      result.set(denormalizeUndefined(key), value)\n    }\n    return result\n  }\n}\n"],"names":["BaseIndex","defaultComparator","denormalizeUndefined","BTree","normalizeForBTree","compareKeys"],"mappings":";;;;;;AAkCO,MAAM,mBAEHA,UAAAA,UAAgB;AAAA,EAkBxB,YACE,IACA,YACA,MACA,SACA;AACA,UAAM,IAAI,YAAY,MAAM,OAAO;AAvBrC,SAAgB,0CAA0B,IAAoB;AAAA,MAC5D;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IAAA,CACD;AAMD,SAAQ,+BAAe,IAAA;AACvB,SAAQ,kCAAkB,IAAA;AAC1B,SAAQ,YAAwCC,WAAAA;AAW9C,UAAM,gBAAgB,SAAS,aAAaA,WAAAA;AAK5C,SAAK,YAAY,CAAC,GAAQ,MACxB,cAAcC,WAAAA,qBAAqB,CAAC,GAAGA,gCAAqB,CAAC,CAAC;AAEhE,QAAI,SAAS,gBAAgB;AAC3B,WAAK,iBAAiB,QAAS;AAAA,IACjC;AACA,SAAK,iBAAiB,IAAIC,YAAM,KAAK,SAAS;AAAA,EAChD;AAAA,EAEU,WAAW,UAAoC;AAAA,EAAC;AAAA;AAAA;AAAA;AAAA,EAK1D,IAAI,KAAW,MAAiB;AAC9B,QAAI;AACJ,QAAI;AACF,qBAAe,KAAK,wBAAwB,IAAI;AAAA,IAClD,SAAS,OAAO;AACd,YAAM,IAAI;AAAA,QACR,+CAA+C,GAAG,KAAK,KAAK;AAAA,MAAA;AAAA,IAEhE;AAGA,UAAM,kBAAkBC,WAAAA,kBAAkB,YAAY;AAGtD,QAAI,KAAK,SAAS,IAAI,eAAe,GAAG;AAEtC,WAAK,SAAS,IAAI,eAAe,EAAG,IAAI,GAAG;AAAA,IAC7C,OAAO;AAEL,YAAM,SAAS,oBAAI,IAAU,CAAC,GAAG,CAAC;AAClC,WAAK,SAAS,IAAI,iBAAiB,MAAM;AACzC,WAAK,eAAe,IAAI,iBAAiB,MAAS;AAAA,IACpD;AAEA,SAAK,YAAY,IAAI,GAAG;AACxB,SAAK,gBAAA;AAAA,EACP;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,KAAW,MAAiB;AACjC,QAAI;AACJ,QAAI;AACF,qBAAe,KAAK,wBAAwB,IAAI;AAAA,IAClD,SAAS,OAAO;AACd,cAAQ;AAAA,QACN,+CAA+C,GAAG;AAAA,QAClD;AAAA,MAAA;AAEF;AAAA,IACF;AAGA,UAAM,kBAAkBA,WAAAA,kBAAkB,YAAY;AAEtD,QAAI,KAAK,SAAS,IAAI,eAAe,GAAG;AACtC,YAAM,SAAS,KAAK,SAAS,IAAI,eAAe;AAChD,aAAO,OAAO,GAAG;AAGjB,UAAI,OAAO,SAAS,GAAG;AACrB,aAAK,SAAS,OAAO,eAAe;AAGpC,aAAK,eAAe,OAAO,eAAe;AAAA,MAC5C;AAAA,IACF;AAEA,SAAK,YAAY,OAAO,GAAG;AAC3B,SAAK,gBAAA;AAAA,EACP;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,KAAW,SAAc,SAAoB;AAClD,SAAK,OAAO,KAAK,OAAO;AACxB,SAAK,IAAI,KAAK,OAAO;AAAA,EACvB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,SAAsC;AAC1C,SAAK,MAAA;AAEL,eAAW,CAAC,KAAK,IAAI,KAAK,SAAS;AACjC,WAAK,IAAI,KAAK,IAAI;AAAA,IACpB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,QAAc;AACZ,SAAK,eAAe,MAAA;AACpB,SAAK,SAAS,MAAA;AACd,SAAK,YAAY,MAAA;AACjB,SAAK,gBAAA;AAAA,EACP;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,WAA2B,OAAuB;AACvD,UAAM,YAAY,YAAY,IAAA;AAE9B,QAAI;AAEJ,YAAQ,WAAA;AAAA,MACN,KAAK;AACH,iBAAS,KAAK,eAAe,KAAK;AAClC;AAAA,MACF,KAAK;AACH,iBAAS,KAAK,WAAW,EAAE,MAAM,OAAO,eAAe,OAAO;AAC9D;AAAA,MACF,KAAK;AACH,iBAAS,KAAK,WAAW,EAAE,MAAM,OAAO,eAAe,MAAM;AAC7D;AAAA,MACF,KAAK;AACH,iBAAS,KAAK,WAAW,EAAE,IAAI,OAAO,aAAa,OAAO;AAC1D;AAAA,MACF,KAAK;AACH,iBAAS,KAAK,WAAW,EAAE,IAAI,OAAO,aAAa,MAAM;AACzD;AAAA,MACF,KAAK;AACH,iBAAS,KAAK,cAAc,KAAK;AACjC;AAAA,MACF;AACE,cAAM,IAAI,MAAM,aAAa,SAAS,8BAA8B;AAAA,IAAA;AAGxE,SAAK,YAAY,SAAS;AAC1B,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,WAAmB;AACrB,WAAO,KAAK,YAAY;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,eAAe,OAAuB;AACpC,UAAM,kBAAkBA,WAAAA,kBAAkB,KAAK;AAC/C,WAAO,IAAI,IAAI,KAAK,SAAS,IAAI,eAAe,KAAK,EAAE;AAAA,EACzD;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,WAAW,UAA6B,IAAe;AACrD,UAAM,EAAE,MAAM,IAAI,gBAAgB,MAAM,cAAc,SAAS;AAC/D,UAAM,6BAAa,IAAA;AAInB,UAAM,UAAU,UAAU;AAC1B,UAAM,QAAQ,QAAQ;AAEtB,UAAM,UAAU,UACZA,WAAAA,kBAAkB,IAAI,IACtB,KAAK,eAAe,OAAA;AACxB,UAAM,QAAQ,QAAQA,WAAAA,kBAAkB,EAAE,IAAI,KAAK,eAAe,OAAA;AAElE,SAAK,eAAe;AAAA,MAClB;AAAA,MACA;AAAA,MACA;AAAA,MACA,CAAC,cAAc,MAAM;AACnB,YAAI,CAAC,iBAAiB,KAAK,UAAU,cAAc,IAAI,MAAM,GAAG;AAG9D;AAAA,QACF;AAEA,cAAM,OAAO,KAAK,SAAS,IAAI,YAAY;AAC3C,YAAI,MAAM;AACR,eAAK,QAAQ,CAAC,QAAQ,OAAO,IAAI,GAAG,CAAC;AAAA,QACvC;AAAA,MACF;AAAA,IAAA;AAGF,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,mBAAmB,UAA6B,IAAe;AAC7D,UAAM,EAAE,MAAM,IAAI,gBAAgB,MAAM,cAAc,SAAS;AAC/D,UAAM,UAAU,UAAU;AAC1B,UAAM,QAAQ,QAAQ;AAGtB,WAAO,KAAK,WAAW;AAAA,MACrB,MAAM,QAAQ,KAAK,KAAK,eAAe,OAAA;AAAA,MACvC,IAAI,UAAU,OAAO,KAAK,eAAe,OAAA;AAAA,MACzC,eAAe;AAAA,MACf,aAAa;AAAA,IAAA,CACd;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUQ,aACN,GACA,UACA,MACA,UACA,WAAoB,OACP;AACb,UAAM,mCAA8B,IAAA;AACpC,UAAM,SAAsB,CAAA;AAC5B,QAAI;AACJ,QAAI,MAAM;AAEV,YAAQ,OAAO,SAAS,GAAG,OAAO,UAAa,OAAO,SAAS,GAAG;AAChE,YAAM,KAAK,CAAC;AACZ,YAAM,OAAO,KAAK,SAAS,IAAI,GAAG;AAGlC,UAAI,QAAQ,KAAK,OAAO,GAAG;AAEzB,cAAM,SAAS,MAAM,KAAK,IAAI,EAAE,KAAKC,iBAAW;AAChD,YAAI,iBAAiB,QAAA;AACrB,mBAAW,MAAM,QAAQ;AACvB,cAAI,OAAO,UAAU,EAAG;AACxB,cAAI,CAAC,aAAa,IAAI,EAAE,MAAM,WAAW,EAAE,KAAK,OAAO;AACrD,mBAAO,KAAK,EAAE;AACd,yBAAa,IAAI,EAAE;AAAA,UACrB;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,KAAK,GAAW,MAAW,UAAgD;AACzE,UAAM,WAAW,CAAC,MAAY,KAAK,eAAe,eAAe,CAAC;AAElE,UAAM,iBAAiBD,WAAAA,kBAAkB,IAAI;AAC7C,WAAO,KAAK,aAAa,GAAG,UAAU,gBAAgB,QAAQ;AAAA,EAChE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,cAAc,GAAW,UAAgD;AACvE,UAAM,WAAW,CAAC,MAAY,KAAK,eAAe,eAAe,CAAC;AAElE,WAAO,KAAK,aAAa,GAAG,UAAU,QAAW,QAAQ;AAAA,EAC3D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,aACE,GACA,MACA,UACa;AACb,UAAM,WAAW,CAAC,MAAY,KAAK,eAAe,cAAc,CAAC;AAEjE,UAAM,iBAAiBA,WAAAA,kBAAkB,IAAI;AAC7C,WAAO,KAAK,aAAa,GAAG,UAAU,gBAAgB,UAAU,IAAI;AAAA,EACtE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,oBACE,GACA,UACa;AACb,UAAM,WAAW,CAAC,MAAY,KAAK,eAAe,cAAc,CAAC;AAEjE,WAAO,KAAK,aAAa,GAAG,UAAU,QAAW,UAAU,IAAI;AAAA,EACjE;AAAA;AAAA;AAAA;AAAA,EAKA,cAAc,QAA+B;AAC3C,UAAM,6BAAa,IAAA;AAEnB,eAAW,SAAS,QAAQ;AAC1B,YAAM,kBAAkBA,WAAAA,kBAAkB,KAAK;AAC/C,YAAM,OAAO,KAAK,SAAS,IAAI,eAAe;AAC9C,UAAI,MAAM;AACR,aAAK,QAAQ,CAAC,QAAQ,OAAO,IAAI,GAAG,CAAC;AAAA,MACvC;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,IAAI,iBAA4B;AAC9B,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAI,sBAA+C;AACjD,WAAO,KAAK,eACT,UAAA,EACA,IAAI,CAAC,QAAQ;AAAA,MACZF,WAAAA,qBAAqB,GAAG;AAAA,MACxB,KAAK,SAAS,IAAI,GAAG,yBAAS,IAAA;AAAA,IAAI,CACnC;AAAA,EACL;AAAA,EAEA,IAAI,8BAAuD;AACzD,WAAO,KAAK,oBAAoB,KAAK,eAAe,IAAI,EAAE,IAAI,CAAC,QAAQ;AAAA,MACrEA,WAAAA,qBAAqB,GAAG;AAAA,MACxB,KAAK,SAAS,IAAI,GAAG,yBAAS,IAAA;AAAA,IAAI,CACnC;AAAA,EACH;AAAA,EAEA,IAAI,eAAoC;AAEtC,UAAM,6BAAa,IAAA;AACnB,eAAW,CAAC,KAAK,KAAK,KAAK,KAAK,UAAU;AACxC,aAAO,IAAIA,WAAAA,qBAAqB,GAAG,GAAG,KAAK;AAAA,IAC7C;AACA,WAAO;AAAA,EACT;AACF;;"}