{"version":3,"file":"index.cjs","names":["DEP_BRAND","ALL_PATHS","DEP_BRAND"],"sources":["../src/BlocProvider.tsx","../src/buildTrackedProxy.ts","../src/useBloc.ts","../src/config.ts"],"sourcesContent":["import {\n  createContext,\n  useContext,\n  useMemo,\n  type ReactElement,\n  type ReactNode,\n} from 'react';\nimport type { ExtractArgs, StateContainerConstructor } from '@blac/core';\n\n/**\n * Internal context value: a Map from bloc constructor to the args object\n * provided by the nearest BlocProvider for that bloc class.\n *\n * Stored as a WeakMap-keyed record so nested providers for different blocs\n * compose without clobbering each other.\n */\ntype ProvidedArgsMap = Map<StateContainerConstructor, unknown>;\n\nconst ProvidedArgsContext = createContext<ProvidedArgsMap>(new Map());\n\n/**\n * Props for {@link BlocProvider}.\n */\nexport interface BlocProviderProps<T extends StateContainerConstructor> {\n  /**\n   * The bloc class whose args are being provided to descendants.\n   */\n  bloc: T;\n  /**\n   * Args that descendant `useBloc(bloc)` calls will resolve to when no\n   * own `args` are given.\n   */\n  args: ExtractArgs<T>;\n  children: ReactNode;\n}\n\n/**\n * Provides args to descendant `useBloc` calls for a specific bloc class via\n * React context.\n *\n * Descendants calling `useBloc(Bloc)` without their own `args` resolve to the\n * args supplied here. Own `args` on the `useBloc` call always win.\n *\n * Multiple `BlocProvider` wrappers for different bloc classes compose: each\n * provider merges its entry into the inherited map, so nested providers for\n * different blocs do not interfere.\n *\n * @example\n * ```tsx\n * <BlocProvider bloc={UserBloc} args={{ userId: 'alice' }}>\n *   <UserProfile />\n * </BlocProvider>\n * ```\n *\n * @example Per-mount private instance\n * ```tsx\n * const id = useId();\n * <BlocProvider bloc={CartBloc} args={{ _id: id }}>\n *   <CartWidget />\n * </BlocProvider>\n * ```\n */\nexport function BlocProvider<T extends StateContainerConstructor>({\n  bloc,\n  args,\n  children,\n}: BlocProviderProps<T>): ReactElement {\n  const parentMap = useContext(ProvidedArgsContext);\n\n  // Merge our entry into a new Map so sibling/parent providers for other blocs\n  // are preserved. Memoised on (parentMap, bloc, args) identity.\n  const mergedMap = useMemo(() => {\n    const next = new Map(parentMap);\n    next.set(bloc, args);\n    return next;\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [parentMap, bloc, args]);\n\n  return (\n    <ProvidedArgsContext.Provider value={mergedMap}>\n      {children}\n    </ProvidedArgsContext.Provider>\n  );\n}\n\n/**\n * Returns the args provided by the nearest {@link BlocProvider} for the given\n * bloc class, or `undefined` when called outside a matching provider.\n *\n * Used by `useBloc` to inherit provider args when no own `args` are given.\n */\nexport function useProvidedArgs<T extends StateContainerConstructor>(\n  BlocClass: T,\n): ExtractArgs<T> | undefined {\n  const map = useContext(ProvidedArgsContext);\n  return map.get(BlocClass) as ExtractArgs<T> | undefined;\n}\n","import { DEP_BRAND } from '@blac/core';\n\n/**\n * Build a per-consumer proxy pair for a bloc instance.\n *\n * Returns two proxies:\n * - `proxy` — the stable outer proxy returned to the consumer. Getter\n *   properties are invoked with `thisProxy` as `this` so that `this.state`\n *   reads inside getters are redirected to the current render's tracking\n *   proxy. Non-getter properties fall through to the live instance.\n * - `thisProxy` — the inner `this`-proxy used as the receiver for getter\n *   calls. Intercepts `state` to return `trackedStateRef.current` when a\n *   tracking context is active; otherwise falls through to the live value.\n *   When `onDepHandle` is supplied, a read off `this` whose value carries the\n *   `DEP_BRAND` symbol (i.e. a `depend()` handle) is routed through\n *   `onDepHandle`, which returns a per-consumer wrapper whose `.track()` opts\n *   the consumer into cross-bloc reactivity. Core stays decoupled — detection\n *   is purely by the `DEP_BRAND` symbol.\n *\n * Both allocations happen exactly once per bloc acquisition (inside `useMemo`)\n * so the proxies are stable across renders.\n *\n * @param onDepHandle - Optional callback invoked when a getter reads a branded\n *   dep handle off `this`. Receives the original handle and returns the value\n *   to expose in its place (the session-bound wrapper). The callback is\n *   responsible for caching wrappers per handle to avoid re-allocation.\n */\nexport function buildTrackedProxy<T extends object>(\n  instance: T,\n  trackedStateRef: { current: unknown },\n  onDepHandle?: (handle: object) => unknown,\n): { proxy: T; thisProxy: T } {\n  // Build a map of getter descriptors from the prototype chain (excluding\n  // Object.prototype). This is computed once per bloc acquisition so that\n  // the proxy's get trap is O(1) per property access. Both string- and\n  // symbol-keyed getters are collected. Arrow-function class properties\n  // (own, bound in the constructor) are not getters and pass through\n  // unmodified.\n  const getterDescs = new Map<string | symbol, PropertyDescriptor>();\n  let proto = Object.getPrototypeOf(instance);\n  while (proto && proto !== Object.prototype) {\n    const keys: (string | symbol)[] = [\n      ...Object.getOwnPropertyNames(proto),\n      ...Object.getOwnPropertySymbols(proto),\n    ];\n    for (const key of keys) {\n      const desc = Object.getOwnPropertyDescriptor(proto, key);\n      if (desc?.get && !getterDescs.has(key)) getterDescs.set(key, desc);\n    }\n    proto = Object.getPrototypeOf(proto);\n  }\n\n  // `this`-proxy for getter invocations, allocated ONCE per acquisition (the\n  // trap closes over the stable `trackedStateRef`, so it never needs to be\n  // rebuilt per access). Redirects `this.state` to the current render's\n  // tracking proxy so getter reads during JSX record paths; outside render\n  // `trackedStateRef.current` is null and it falls through to live state.\n  // The receiver `r` (this proxy) is threaded through Reflect.get so chained\n  // getter calls (getters reading other getters) stay in tracked context.\n  const thisProxy = new Proxy(instance as object, {\n    get(t, k, r) {\n      if (k === 'state') return trackedStateRef.current ?? Reflect.get(t, k, r);\n      const value = Reflect.get(t, k, r);\n      // A branded dep handle read off `this` (e.g. `this.price`) is routed\n      // through onDepHandle so the consumer's session can wrap `.track()`.\n      if (\n        onDepHandle !== undefined &&\n        (typeof value === 'function' || typeof value === 'object') &&\n        value !== null &&\n        (value as Record<symbol, unknown>)[DEP_BRAND] !== undefined\n      ) {\n        return onDepHandle(value as object);\n      }\n      return value;\n    },\n  });\n\n  // Stable proxy: one allocation per bloc acquisition. Non-getter access is\n  // a single Map lookup + Reflect.get — no prototype walk on the hot path.\n  const proxy = new Proxy(instance as object, {\n    get(target, key, receiver) {\n      const desc = getterDescs.get(key);\n      if (desc?.get) return desc.get.call(thisProxy);\n      return Reflect.get(target, key, receiver);\n    },\n  }) as T;\n\n  return { proxy, thisProxy: thisProxy as T };\n}\n","import {\n  useEffect,\n  useId,\n  useLayoutEffect,\n  useMemo,\n  useReducer,\n  useRef,\n  type RefObject,\n} from 'react';\nimport {\n  DEP_BRAND,\n  getRegistry,\n  resolveInstanceKey,\n  type ExtractArgs,\n  type ExtractState,\n  type InstanceState,\n  type StateContainer,\n  type StateContainerConstructor,\n} from '@blac/core';\nimport {\n  ALL_PATHS,\n  emptyPathSet,\n  trackRender,\n  PathInterner,\n  type PathSet,\n} from '@dirtytalk/structural';\nimport { useProvidedArgs } from './BlocProvider';\nimport { buildTrackedProxy } from './buildTrackedProxy';\nimport type { ComponentRef, UseBlocOptions, UseBlocReturn } from './types';\n\nlet nextConsumerId = 0;\n\n// Registry refId formats for a consumer's primary bloc and its tracked deps.\n// Centralised so the `acquire` and `release` sites can never drift apart — a\n// mismatch would leak the ref and keep the bloc alive past unmount.\nconst primaryRefId = (consumerId: string): string => `useBloc@${consumerId}`;\nconst depRefId = (consumerId: string): string => `useBloc@${consumerId}:dep`;\n\n/**\n * React hook that connects a component to a state container with automatic\n * re-render on state changes.\n *\n * Two tracking modes:\n * - **Auto-tracking** (default): the returned state value is a proxy that\n *   records read paths during render. The component re-renders when any\n *   recorded path changes. Backed by `@dirtytalk/structural`'s\n *   {@link trackRender} + the container's path-scoped `DirtyChannel`.\n * - **Manual select**: pass `options.select` to opt out of auto-tracking.\n *   The hook re-renders only when the returned array's elements change\n *   (per-index `Object.is`).\n *\n * Lifecycle:\n * - The bloc is acquired from the registry on mount and released on\n *   unmount. The instance key is derived from `options.args` (own args),\n *   then the surrounding {@link BlocProvider} context args for this bloc,\n *   then the default key (no args).\n * - `options.onMount` fires after the bloc is acquired; `options.onUnmount`\n *   fires *before* the registry releases its ref, so the bloc is still\n *   alive when the callback runs.\n *\n * Per-mount private instance:\n * ```ts\n * const id = useId();\n * const [state, bloc] = useBloc(MyBloc, { args: { _id: id } });\n * ```\n *\n * @template T - The state container constructor type (inferred from BlocClass)\n * @param BlocClass - The state container class to connect to\n * @param options - Configuration options\n * @returns Tuple of `[state, bloc, ref]`\n *\n * @example Basic usage\n * ```ts\n * const [state, bloc] = useBloc(MyBloc);\n * ```\n *\n * @example Manual select\n * ```ts\n * const [state, bloc] = useBloc(MyBloc, {\n *   select: (state) => [state.count],\n * });\n * ```\n *\n * @example Args-based shared instance\n * ```ts\n * const [state, bloc] = useBloc(UserBloc, { args: { userId: 'alice' } });\n * ```\n */\nexport function useBloc<\n  T extends StateContainerConstructor = StateContainerConstructor,\n>(\n  BlocClass: T,\n  options?: UseBlocOptions<T>,\n): UseBlocReturn<T, ExtractState<T>> {\n  type TBloc = InstanceState<T>;\n\n  const componentRef = useRef<ComponentRef>({});\n\n  // Stable per-consumer id (for the structural container's consumer registry).\n  // Plain counter rather than `useId()` so we don't compete with internal hooks\n  // for SSR id slots.\n  const consumerIdRef = useRef<string | null>(null);\n  if (consumerIdRef.current === null) {\n    consumerIdRef.current = `useBloc-${nextConsumerId++}`;\n  }\n  const consumerId = consumerIdRef.current;\n  // Reserve a useId slot — kept for forwards compatibility and to match\n  // BlocProvider-driven SSR hydration alignment (no-op call).\n  useId();\n\n  // Refs that always carry the latest option callbacks, so the commit effect\n  // can read them without re-keying.\n  const selectRef = useRef(options?.select);\n  selectRef.current = options?.select;\n  const onMountRef = useRef(options?.onMount);\n  onMountRef.current = options?.onMount;\n  const onUnmountRef = useRef(options?.onUnmount);\n  onUnmountRef.current = options?.onUnmount;\n\n  // ---------------------------------------------------------------------------\n  // Identity resolution\n  //\n  // Priority: own args > provider args (for this bloc class) > none.\n  //\n  // Args are user-supplied; callers commonly pass a fresh object literal each\n  // render. Memoising on `args` directly would bust every render. We compute a\n  // structural key (JSON.stringify) for the useMemo dep instead — undefined\n  // args (void-args blocs) collapse to an undefined key.\n  // ---------------------------------------------------------------------------\n  const ownArgs = (options as { args?: ExtractArgs<T> } | undefined)?.args;\n  const ownArgsRef = useRef(ownArgs);\n  ownArgsRef.current = ownArgs;\n  const ownArgsKey =\n    ownArgs === undefined ? undefined : JSON.stringify(ownArgs);\n\n  // Read provided args from the nearest BlocProvider for this bloc class.\n  const providerArgs = useProvidedArgs(BlocClass);\n  const providerArgsRef = useRef(providerArgs);\n  providerArgsRef.current = providerArgs;\n  const providerArgsKey =\n    providerArgs === undefined ? undefined : JSON.stringify(providerArgs);\n\n  // Current render's tracking proxy. Declared before the memo so the stable\n  // ref object can be passed to buildTrackedProxy at acquisition time. The\n  // proxy trap only reads `.current` at invocation time (not during creation),\n  // so it is safe to pass on first mount even though the value is null.\n  // Populated during each auto-track render snapshot (below); cleared to null\n  // by useLayoutEffect after commit.\n  const trackedStateRef = useRef<unknown>(null);\n\n  // ---------------------------------------------------------------------------\n  // Per-consumer cross-bloc session.\n  //\n  // Each render rebuilds a map of every container this consumer is currently\n  // interested in. The PRIMARY bloc is the first uniform entry; every dep\n  // reached through `this.<handle>.track()` inside a tracked getter adds an\n  // entry. The layout-effect reconcile (below) diffs this map vs the previous\n  // render to subscribe new deps and release dropped ones. The session lives in\n  // this hook's refs only — there is no global ambient state, so sibling\n  // renders never cross-contaminate.\n  // ---------------------------------------------------------------------------\n  const sessionRef = useRef<Map<StateContainer, SessionEntry>>(new Map());\n  // Channel subscriptions for DEP containers (the primary keeps its own\n  // dedicated effect). container -> { unsubscribe, interestRef, refId held }.\n  const depSubsRef = useRef<Map<StateContainer, DepSub>>(new Map());\n  // Per-handle wrapper cache, allocated once per bloc acquisition (in the memo)\n  // so wrappers are stable across renders. handle -> session-bound wrapper.\n  const depWrapperCacheRef = useRef<Map<object, unknown>>(new Map());\n\n  const { bloc, instanceKey, trackedBloc } = useMemo<{\n    bloc: TBloc;\n    instanceKey: string;\n    trackedBloc: TBloc;\n  }>(() => {\n    // Own args win over provider args; provider args win over no args.\n    const effectiveArgs =\n      ownArgsRef.current !== undefined\n        ? ownArgsRef.current\n        : providerArgsRef.current;\n\n    const resolvedKey = resolveInstanceKey(BlocClass, effectiveArgs);\n    const refId = primaryRefId(consumerId);\n    const registry = getRegistry();\n    const instance = registry.acquire(BlocClass, resolvedKey, {\n      canCreate: true,\n      countRef: true,\n      refId,\n      args: effectiveArgs,\n    }) as TBloc;\n\n    // Build a session-bound wrapper for a dep handle the first time a getter\n    // reads it off `this`; cache per handle so the wrapper identity is stable.\n    // `onDepHandle` is threaded into each dep's tracked proxy too, so a nested\n    // `this.<otherHandle>.track()` inside a dep's getter records into the SAME\n    // consumer session — that is what makes deep chains (A→B→C) reactive.\n    const onDepHandle = (handle: object): unknown => {\n      const cache = depWrapperCacheRef.current;\n      const cached = cache.get(handle);\n      if (cached !== undefined) return cached;\n      const wrapper = makeDepWrapper(\n        handle as DepHandleLike,\n        consumerId,\n        trackedStateRef,\n        sessionRef,\n        depSubsRef,\n        onDepHandle,\n      );\n      cache.set(handle, wrapper);\n      return wrapper;\n    };\n\n    const { proxy } = buildTrackedProxy(\n      instance as object,\n      trackedStateRef,\n      onDepHandle,\n    );\n\n    return {\n      bloc: instance,\n      instanceKey: resolvedKey,\n      trackedBloc: proxy as TBloc,\n    };\n    // oxlint-disable-next-line react-hooks/exhaustive-deps\n  }, [BlocClass, ownArgsKey, providerArgsKey]);\n\n  // ---------------------------------------------------------------------------\n  // Channel subscription\n  //\n  // We talk directly to `bloc.channel` — the StructuralContainer's path-scoped\n  // DirtyChannel. Subscribing with a dynamic interest function lets us narrow\n  // wakeups per consumer, so a component only re-renders when a path it\n  // actually read changes (rather than on every state change).\n  // ---------------------------------------------------------------------------\n  const [, force] = useReducer((x: number) => x + 1, 0);\n  const pathRef = useRef<PathSet>(emptyPathSet());\n  // Expanded interest: leaf paths PLUS *ancestor-watch* ids for their parents,\n  // so that when `patch` atomically replaces a parent (e.g. the array 'items')\n  // and the consumer tracked a child (e.g. 'items.length'), the intersection\n  // still fires — while a structural pulse-up of a plain-object parent (e.g.\n  // 'user' when a sibling 'user.name' changed) does NOT, because pulse-up marks\n  // are normal ids and ancestor-watch ids only intersect their own lane.\n  // Updated in useLayoutEffect after each render once pathRef.current is\n  // populated.\n  const expandedInterestRef = useRef<PathSet>(emptyPathSet());\n  // For select-mode: cache the last selected array so we can compare against\n  // the next one before forcing a re-render.\n  const lastSelectionRef = useRef<unknown[] | null>(null);\n\n  useEffect(() => {\n    // Subscribe via the channel directly. For auto-track we re-register the\n    // current path interest on each commit (below); for select-mode we use\n    // ALL_PATHS and compare selections in the callback.\n    const channel = (bloc as unknown as StateContainer).channel;\n    const isSelectMode = selectRef.current !== undefined;\n\n    if (isSelectMode) {\n      const unsub = channel.subscribe(\n        () => ALL_PATHS,\n        () => {\n          const select = selectRef.current;\n          if (!select) {\n            force();\n            return;\n          }\n          const next = select(\n            (bloc as unknown as StateContainer).state as ExtractState<T>,\n            bloc as InstanceState<T>,\n          );\n          const prev = lastSelectionRef.current;\n          if (prev !== null && shallowArrayEqual(prev, next)) return;\n          lastSelectionRef.current = next;\n          force();\n        },\n      );\n      return unsub;\n    }\n\n    // Auto-track mode: subscribe with the expanded interest (leaf paths + their\n    // ancestors). This ensures that when `patch` marks a parent path (e.g.\n    // 'items') and the consumer tracked a child (e.g. 'items.length'), the\n    // channel intersection still fires a re-render.\n    //\n    // `expandedInterestRef.current` is updated by the useLayoutEffect below\n    // after each render, so the interest is always fresh at flush time.\n    const unsub = channel.subscribe(\n      () => expandedInterestRef.current,\n      () => force(),\n    );\n    // Register the consumer's leaf paths with the container for skeleton\n    // recomputation, so the source-side diff can skip us when our paths don't\n    // intersect the change.\n    (bloc as unknown as StateContainer).registerConsumerPaths(\n      consumerId,\n      pathRef.current,\n    );\n    return () => {\n      unsub();\n      (bloc as unknown as StateContainer).unregisterConsumer(consumerId);\n    };\n  }, [bloc, consumerId]);\n\n  // ---------------------------------------------------------------------------\n  // Mount / unmount lifecycle.\n  //\n  // Order on unmount: onUnmount(bloc) -> release(...). The bloc must still be\n  // alive when onUnmount runs (release may dispose it).\n  // ---------------------------------------------------------------------------\n  useEffect(() => {\n    onMountRef.current?.(bloc as InstanceType<T>);\n    return () => {\n      onUnmountRef.current?.(bloc as InstanceType<T>);\n      getRegistry().release(\n        BlocClass,\n        instanceKey,\n        false,\n        primaryRefId(consumerId),\n      );\n    };\n    // oxlint-disable-next-line react-hooks/exhaustive-deps\n  }, [bloc, instanceKey]);\n\n  // ---------------------------------------------------------------------------\n  // Snapshot\n  //\n  // - Auto-track: wrap state in trackRender, record paths into pathRef, and\n  //   re-register with the container so the skeleton picks up new interest.\n  // - Select-mode: return state directly; the subscription callback compares\n  //   selections to decide whether to re-render.\n  // ---------------------------------------------------------------------------\n  const rawState = (bloc as unknown as StateContainer).state as ExtractState<T>;\n  let state: ExtractState<T>;\n  if (selectRef.current !== undefined) {\n    state = rawState;\n    // Seed the last selection on the first render so we don't fire an\n    // immediate \"different from null\" wakeup on the first emit.\n    if (lastSelectionRef.current === null) {\n      lastSelectionRef.current = selectRef.current(\n        rawState,\n        bloc as InstanceState<T>,\n      );\n    }\n  } else {\n    const tracked = trackRender(\n      rawState,\n      (bloc as unknown as StateContainer).interner,\n    );\n    state = tracked.value as ExtractState<T>;\n    trackedStateRef.current = tracked.value;\n    pathRef.current = tracked.paths;\n    // Rebuild the per-consumer session for this render. The primary bloc is the\n    // first uniform entry; its `paths` are the SAME PathSet object the proxy\n    // mutates during JSX (so it stays live as getters record leaves). Dep\n    // entries are appended during JSX as `this.<handle>.track()` runs. Cleared\n    // here (not in the layout effect) so a render that no longer tracks a dep\n    // produces a session without it, and the reconcile drops it.\n    const session = sessionRef.current;\n    session.clear();\n    session.set(bloc as unknown as StateContainer, {\n      kind: 'primary',\n      paths: tracked.paths,\n    });\n    // NOTE: registerConsumerPaths is intentionally NOT called here. The\n    // proxy hasn't been accessed yet, so `tracked.paths` is an empty Set\n    // that the proxy will mutate during JSX evaluation. Registering at\n    // this point would store an empty interest with the container and\n    // freeze the skeleton at that snapshot — subsequent emits would\n    // diff against an empty skeleton and silently drop wakeups. The\n    // useLayoutEffect below registers the populated set after render.\n  }\n\n  // After the render commits, pathRef.current is the consumer's actual leaf\n  // interest (populated by the proxy during JSX evaluation). Re-register with\n  // the container so the skeleton reflects the latest paths, and expand the\n  // interest to include ancestor paths for the channel subscription.\n  //\n  // useLayoutEffect runs before the browser paints (and before any emit\n  // triggered by another effect), so the skeleton is fresh by the time the\n  // next emit fires.\n  // oxlint-disable-next-line react-hooks/exhaustive-deps\n  useLayoutEffect(() => {\n    // Clear the render-time tracking proxy now that JSX has been evaluated and\n    // committed. Getters invoked after this point (event handlers, effects,\n    // method→getter chains) fall through to live state instead of reading this\n    // render's frozen snapshot. The render body re-seeds it next render.\n    trackedStateRef.current = null;\n    if (selectRef.current !== undefined) return;\n    const container = bloc as unknown as StateContainer;\n    const paths = pathRef.current;\n    container.registerConsumerPaths(consumerId, paths);\n    // Register the *normal* leaf paths above for the source-side skeleton, then\n    // build the channel interest as leaves + ancestor-watch ids so that an\n    // atomic `patch` replacement of a parent (e.g. the array 'items') wakes a\n    // consumer that tracked a child (e.g. 'items.length').\n    expandedInterestRef.current = expandWithAncestors(\n      paths,\n      container.interner,\n    );\n\n    // -----------------------------------------------------------------------\n    // Reconcile DEP containers (cross-bloc `.track()` interest).\n    //\n    // The primary bloc keeps its own dedicated subscription effect above; this\n    // block manages only the *dep* containers recorded in the session this\n    // render. We diff the new dep set vs the previously-subscribed set:\n    //   - new dep      -> acquire was already done in `.track()`; subscribe its\n    //                     channel + registerConsumerPaths + seed interest.\n    //   - surviving    -> refresh its interest ref (subscribe closure reads it).\n    //   - dropped      -> unsubscribe, unregisterConsumer, and release its ref.\n    // -----------------------------------------------------------------------\n    const subs = depSubsRef.current;\n    const session = sessionRef.current;\n\n    // Pass 1: drop containers no longer in the session.\n    for (const [depContainer, sub] of subs) {\n      if (!session.has(depContainer)) {\n        sub.unsubscribe();\n        depContainer.unregisterConsumer(consumerId);\n        getRegistry().release(sub.Type, sub.key, false, sub.refId);\n        subs.delete(depContainer);\n      }\n    }\n\n    // Pass 2: add/refresh containers in the session (skip the primary).\n    for (const [depContainer, entry] of session) {\n      if (entry.kind === 'primary') continue;\n      const interest = expandWithAncestors(entry.paths, depContainer.interner);\n      depContainer.registerConsumerPaths(consumerId, entry.paths);\n      const existing = subs.get(depContainer);\n      if (existing) {\n        existing.interestRef.current = interest;\n        continue;\n      }\n      const interestRef: { current: PathSet } = { current: interest };\n      const unsubscribe = depContainer.channel.subscribe(\n        () => interestRef.current,\n        () => force(),\n      );\n      subs.set(depContainer, {\n        unsubscribe,\n        interestRef,\n        Type: entry.Type,\n        key: entry.key,\n        refId: entry.refId,\n      });\n    }\n  });\n\n  // Unmount: tear down every dep subscription + ref exactly once. Kept in its\n  // own effect (consumerId is stable for the component's lifetime, so this only\n  // runs on final unmount, not on every reconcile). depSubsRef is mutated in\n  // place by the reconcile, so the captured Map reference still holds the live\n  // set at unmount.\n  useEffect(() => {\n    // Capture the ref's Map (mutated in place across renders) so the cleanup\n    // reads the captured reference rather than depSubsRef.current directly.\n    const subs = depSubsRef.current;\n    return () => {\n      for (const [depContainer, sub] of subs) {\n        sub.unsubscribe();\n        depContainer.unregisterConsumer(consumerId);\n        getRegistry().release(sub.Type, sub.key, false, sub.refId);\n      }\n      subs.clear();\n    };\n  }, [consumerId]);\n\n  return [\n    state,\n    trackedBloc,\n    componentRef as RefObject<ComponentRef>,\n  ] as UseBlocReturn<T, ExtractState<T>>;\n}\n\n// ---------------------------------------------------------------------------\n// Cross-bloc session types + dep-handle wrapper.\n// ---------------------------------------------------------------------------\n\n/**\n * One entry in a consumer's per-render session map. Discriminated on `kind`:\n * the primary bloc is managed by its own dedicated effect, while dep entries\n * carry the registry coordinates the reconcile needs to release their ref.\n */\ntype SessionEntry =\n  | {\n      kind: 'primary';\n      /** Tracked leaf paths recorded against the primary this render. */\n      paths: PathSet;\n    }\n  | {\n      kind: 'dep';\n      /** Tracked leaf paths recorded against this dep this render. */\n      paths: PathSet;\n      /** Constructor for registry release. */\n      Type: StateContainerConstructor;\n      /** Resolved instance key for registry release. */\n      key: string;\n      /** refId held for this dep (released on drop/unmount). */\n      refId: string;\n    };\n\n/** A live dep-channel subscription tracked between renders for reconciliation. */\ninterface DepSub {\n  unsubscribe: () => void;\n  interestRef: { current: PathSet };\n  Type: StateContainerConstructor;\n  key: string;\n  refId: string;\n}\n\n/** Per-access options shared by both dep accessors. */\ninterface DepAccessOptionsLike {\n  args?: unknown;\n}\n\n/** Structural shape of a branded `depend()` handle as seen from React. */\ninterface DepHandleLike {\n  track(options?: DepAccessOptionsLike): [unknown, StateContainer];\n  untracked(options?: DepAccessOptionsLike): StateContainer;\n  readonly [DEP_BRAND]: {\n    Type: StateContainerConstructor;\n    defaultArgs?: unknown;\n  };\n}\n\n/**\n * Build the per-consumer wrapper that replaces a branded dep handle inside a\n * tracked getter's `this`. The wrapper exposes the same accessors as the core\n * handle and overrides `.track()`:\n *\n * - **Inside a render** (`trackedStateRef.current != null`): resolve the dep,\n *   take a refcount (once per consumer), `trackRender` its state, merge the\n *   recorded paths into the session entry, build/reuse a tracked proxy for the\n *   dep so its OWN getters track too, and return `[trackedValue, depProxy]`.\n * - **Outside a render**: degrade to live `[dep.state, dep]` — matches the core\n *   base impl, safe in event handlers/effects/methods.\n *\n * `.untracked()` always returns the live instance with no subscription.\n *\n * Args resolve at call time (`options.args ?? defaultArgs`), so a single handle\n * can resolve different dep instances across calls; tracked-proxy state is\n * therefore cached per resolved instance, not per handle. Guards against a\n * container re-entering tracking within the same render (mutual A↔B deps): if\n * the dep already has a non-primary session entry this render, reuse its proxy\n * + union its paths instead of re-acquiring.\n */\nfunction makeDepWrapper(\n  handle: DepHandleLike,\n  consumerId: string,\n  trackedStateRef: { current: unknown },\n  sessionRef: { current: Map<StateContainer, SessionEntry> },\n  depSubsRef: { current: Map<StateContainer, DepSub> },\n  onDepHandle: (handle: object) => unknown,\n): DepHandleLike {\n  const brand = handle[DEP_BRAND];\n  const refId = depRefId(consumerId);\n  const registry = getRegistry();\n  // Per-resolved-instance tracked-state ref + proxy. Call-time args mean one\n  // handle can resolve several instances, so cache is keyed by the instance.\n  const perDep = new Map<\n    StateContainer,\n    { ref: { current: unknown }; proxy: StateContainer }\n  >();\n\n  const resolve = (options?: DepAccessOptionsLike) => {\n    const args = options?.args ?? brand.defaultArgs;\n    const key = registry.resolveKey(brand.Type, undefined, args);\n    const dep = registry.ensure(\n      brand.Type,\n      key,\n      args,\n    ) as unknown as StateContainer;\n    return { dep, key, args };\n  };\n\n  const wrapper = {\n    untracked: (options?: DepAccessOptionsLike) => resolve(options).dep,\n    track: (options?: DepAccessOptionsLike) => {\n      const { dep, key, args } = resolve(options);\n\n      // Outside a render: live values, no subscription (core base behavior).\n      if (trackedStateRef.current == null) {\n        return [dep.state, dep];\n      }\n\n      const session = sessionRef.current;\n      const existing = session.get(dep);\n\n      // Take a refcount the FIRST time this dep is tracked, held across renders\n      // and released by the reconcile (on drop) or unmount. The session map is\n      // rebuilt every render, so it can't tell us whether we already hold a ref;\n      // `depSubsRef` does — it persists across renders and is populated by the\n      // reconcile after the first tracking render. If neither the (cleared) per-\n      // render session nor the persistent sub set knows this dep, acquire once.\n      // React runs the layout-effect reconcile before the next render, so the\n      // sub is registered before a subsequent track sees it → no double-acquire.\n      if (existing === undefined && !depSubsRef.current.has(dep)) {\n        registry.acquire(brand.Type, key, {\n          canCreate: true,\n          countRef: true,\n          refId,\n          args,\n        });\n      }\n\n      const tracked = trackRender(dep.state, dep.interner);\n      let cache = perDep.get(dep);\n      if (cache === undefined) {\n        const ref = { current: tracked.value as unknown };\n        cache = { ref, proxy: buildTrackedProxy(dep, ref, onDepHandle).proxy };\n        perDep.set(dep, cache);\n      } else {\n        cache.ref.current = tracked.value;\n      }\n\n      if (existing !== undefined) {\n        // Re-entry this render (`.track()` twice, or a mutual cycle): union the\n        // new paths into the existing entry rather than re-acquiring.\n        existing.paths = unionPaths(existing.paths, tracked.paths);\n      } else {\n        session.set(dep, {\n          kind: 'dep',\n          paths: tracked.paths,\n          Type: brand.Type,\n          key,\n          refId,\n        });\n      }\n\n      return [tracked.value, cache.proxy];\n    },\n  } as DepHandleLike;\n\n  Object.defineProperty(wrapper, DEP_BRAND, {\n    value: brand,\n    enumerable: false,\n    writable: false,\n    configurable: false,\n  });\n\n  return wrapper;\n}\n\n/** Union two PathSets (ALL_PATHS dominates). */\nfunction unionPaths(a: PathSet, b: PathSet): PathSet {\n  if (a === ALL_PATHS || b === ALL_PATHS) return ALL_PATHS;\n  const out = new Set<number>(a as Set<number>);\n  for (const id of b as Set<number>) out.add(id);\n  return out;\n}\n\nconst shallowArrayEqual = (a: unknown[], b: unknown[]): boolean => {\n  if (a === b) return true;\n  if (a.length !== b.length) return false;\n  for (let i = 0; i < a.length; i++) {\n    if (!Object.is(a[i], b[i])) return false;\n  }\n  return true;\n};\n\n/**\n * Expand a PathSet to include an *ancestor-watch* id for every ancestor of\n * every tracked leaf.\n *\n * The auto-tracker records leaf paths (e.g. `'items.length'`), but\n * `StructuralContainer.patch` can only mark the parent (`'items'`) when it\n * replaces a value atomically (arrays, `null`, primitives — it can't see\n * inside). Without expansion, a subscriber with interest `{'items.length'}`\n * would miss a `patch`-triggered atomic-replacement of `items`.\n *\n * Ancestors are added under the interner's *ancestor-watch* lane\n * (`internAncestor`), NOT as normal ids. The source emits a matching\n * ancestor-watch mark only for paths it replaces atomically — never for a\n * plain-object structural pulse-up. So `{'items.length'}` wakes when the array\n * `items` is replaced, but `{'user.email'}` does NOT wake when a sibling\n * `user.name` changes and pulses `user` up: pulse-up `user` is a normal id and\n * the ancestor-watch `user` only intersects another ancestor-watch `user`.\n *\n * Example: leaf `'a.b.c'` adds ancestor-watch ids for `'a.b'` and `'a'` (but\n * NOT the `''` root — a root change is covered by `ALL_PATHS` from the source,\n * and `''` would wake this consumer on every field change).\n */\nfunction expandWithAncestors(paths: PathSet, interner: PathInterner): PathSet {\n  if (paths === ALL_PATHS) return ALL_PATHS;\n  const leafPaths = paths as Set<number>;\n  if (leafPaths.size === 0) return paths;\n\n  const expanded = new Set<number>(leafPaths);\n  for (const id of leafPaths) {\n    const str = interner.lookup(id);\n    // Add all non-root ancestor segments as *ancestor-watch* ids: 'a.b.c' →\n    // watch 'a.b' and 'a'. These live in the interner's ancestor lane so they\n    // only intersect the source's atomic-replacement marks (`internAncestor`),\n    // never a structural pulse-up mark of the same path. That is what lets a\n    // descendant-reader (e.g. `items.length`) wake on an array/null replacement\n    // without a sibling-leaf reader (`user.email`) waking when a sibling\n    // (`user.name`) changes and pulses up through `user`.\n    let idx = str.lastIndexOf('.');\n    while (idx > 0) {\n      const ancestor = str.slice(0, idx);\n      expanded.add(interner.internAncestor(ancestor));\n      idx = ancestor.lastIndexOf('.');\n    }\n  }\n  return expanded;\n}\n","/**\n * Global configuration for `@blac/react`.\n *\n * The hook's tracking model is fixed: when `useBloc` is called without a\n * `select`, render-time auto-tracking is used (via\n * `@dirtytalk/structural`'s `trackRender`). When `select` is provided,\n * re-renders are driven by per-index `Object.is` over the returned array.\n *\n * Reserved for forwards-compatible knobs; currently empty.\n */\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type\nexport interface BlacReactConfig {}\n\nconst defaultConfig: BlacReactConfig = {};\n\nlet globalConfig: BlacReactConfig = { ...defaultConfig };\n\n/**\n * Configure global defaults for `@blac/react` hooks.\n *\n * @param config - Partial configuration to merge with current globals\n */\nexport function configureBlacReact(config: Partial<BlacReactConfig>): void {\n  globalConfig = { ...globalConfig, ...config };\n}\n\n/**\n * Get the current global configuration.\n * @internal\n */\nexport function getBlacReactConfig(): BlacReactConfig {\n  return globalConfig;\n}\n\n/**\n * Reset configuration to defaults (useful for testing).\n * @internal\n */\nexport function resetBlacReactConfig(): void {\n  globalConfig = { ...defaultConfig };\n}\n"],"mappings":";;;;;;AAkBA,MAAM,uBAAA,GAAA,MAAA,+BAAqD,IAAI,IAAI,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4CpE,SAAgB,aAAkD,EAChE,MACA,MACA,YACqC;CACrC,MAAM,aAAA,GAAA,MAAA,YAAuB,mBAAmB;CAIhD,MAAM,aAAA,GAAA,MAAA,eAA0B;EAC9B,MAAM,OAAO,IAAI,IAAI,SAAS;EAC9B,KAAK,IAAI,MAAM,IAAI;EACnB,OAAO;CAET,GAAG;EAAC;EAAW;EAAM;CAAI,CAAC;CAE1B,OACE,iBAAA,GAAA,kBAAA,KAAC,oBAAoB,UAArB;EAA8B,OAAO;EAClC;CAC2B,CAAA;AAElC;;;;;;;AAQA,SAAgB,gBACd,WAC4B;CAE5B,QAAA,GAAA,MAAA,YADuB,mBACd,EAAE,IAAI,SAAS;AAC1B;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACrEA,SAAgB,kBACd,UACA,iBACA,aAC4B;CAO5B,MAAM,8BAAc,IAAI,IAAyC;CACjE,IAAI,QAAQ,OAAO,eAAe,QAAQ;CAC1C,OAAO,SAAS,UAAU,OAAO,WAAW;EAC1C,MAAM,OAA4B,CAChC,GAAG,OAAO,oBAAoB,KAAK,GACnC,GAAG,OAAO,sBAAsB,KAAK,CACvC;EACA,KAAK,MAAM,OAAO,MAAM;GACtB,MAAM,OAAO,OAAO,yBAAyB,OAAO,GAAG;GACvD,IAAI,MAAM,OAAO,CAAC,YAAY,IAAI,GAAG,GAAG,YAAY,IAAI,KAAK,IAAI;EACnE;EACA,QAAQ,OAAO,eAAe,KAAK;CACrC;CASA,MAAM,YAAY,IAAI,MAAM,UAAoB,EAC9C,IAAI,GAAG,GAAG,GAAG;EACX,IAAI,MAAM,SAAS,OAAO,gBAAgB,WAAW,QAAQ,IAAI,GAAG,GAAG,CAAC;EACxE,MAAM,QAAQ,QAAQ,IAAI,GAAG,GAAG,CAAC;EAGjC,IACE,gBAAgB,KAAA,MACf,OAAO,UAAU,cAAc,OAAO,UAAU,aACjD,UAAU,QACT,MAAkCA,WAAAA,eAAe,KAAA,GAElD,OAAO,YAAY,KAAe;EAEpC,OAAO;CACT,EACF,CAAC;CAYD,OAAO;EAAE,OAAA,IARS,MAAM,UAAoB,EAC1C,IAAI,QAAQ,KAAK,UAAU;GACzB,MAAM,OAAO,YAAY,IAAI,GAAG;GAChC,IAAI,MAAM,KAAK,OAAO,KAAK,IAAI,KAAK,SAAS;GAC7C,OAAO,QAAQ,IAAI,QAAQ,KAAK,QAAQ;EAC1C,EACF,CAEa;EAAc;CAAe;AAC5C;;;AC1DA,IAAI,iBAAiB;AAKrB,MAAM,gBAAgB,eAA+B,WAAW;AAChE,MAAM,YAAY,eAA+B,WAAW,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoDvE,SAAgB,QAGd,WACA,SACmC;CAGnC,MAAM,gBAAA,GAAA,MAAA,QAAoC,CAAC,CAAC;CAK5C,MAAM,iBAAA,GAAA,MAAA,QAAsC,IAAI;CAChD,IAAI,cAAc,YAAY,MAC5B,cAAc,UAAU,WAAW;CAErC,MAAM,aAAa,cAAc;CAGjC,CAAA,GAAA,MAAA,OAAM;CAIN,MAAM,aAAA,GAAA,MAAA,QAAmB,SAAS,MAAM;CACxC,UAAU,UAAU,SAAS;CAC7B,MAAM,cAAA,GAAA,MAAA,QAAoB,SAAS,OAAO;CAC1C,WAAW,UAAU,SAAS;CAC9B,MAAM,gBAAA,GAAA,MAAA,QAAsB,SAAS,SAAS;CAC9C,aAAa,UAAU,SAAS;CAYhC,MAAM,UAAW,SAAmD;CACpE,MAAM,cAAA,GAAA,MAAA,QAAoB,OAAO;CACjC,WAAW,UAAU;CACrB,MAAM,aACJ,YAAY,KAAA,IAAY,KAAA,IAAY,KAAK,UAAU,OAAO;CAG5D,MAAM,eAAe,gBAAgB,SAAS;CAC9C,MAAM,mBAAA,GAAA,MAAA,QAAyB,YAAY;CAC3C,gBAAgB,UAAU;CAC1B,MAAM,kBACJ,iBAAiB,KAAA,IAAY,KAAA,IAAY,KAAK,UAAU,YAAY;CAQtE,MAAM,mBAAA,GAAA,MAAA,QAAkC,IAAI;CAa5C,MAAM,cAAA,GAAA,MAAA,wBAAuD,IAAI,IAAI,CAAC;CAGtE,MAAM,cAAA,GAAA,MAAA,wBAAiD,IAAI,IAAI,CAAC;CAGhE,MAAM,sBAAA,GAAA,MAAA,wBAAkD,IAAI,IAAI,CAAC;CAEjE,MAAM,EAAE,MAAM,aAAa,iBAAA,GAAA,MAAA,eAIlB;EAEP,MAAM,gBACJ,WAAW,YAAY,KAAA,IACnB,WAAW,UACX,gBAAgB;EAEtB,MAAM,eAAA,GAAA,WAAA,oBAAiC,WAAW,aAAa;EAC/D,MAAM,QAAQ,aAAa,UAAU;EAErC,MAAM,YAAA,GAAA,WAAA,aAAkB,EAAE,QAAQ,WAAW,aAAa;GACxD,WAAW;GACX,UAAU;GACV;GACA,MAAM;EACR,CAAC;EAOD,MAAM,eAAe,WAA4B;GAC/C,MAAM,QAAQ,mBAAmB;GACjC,MAAM,SAAS,MAAM,IAAI,MAAM;GAC/B,IAAI,WAAW,KAAA,GAAW,OAAO;GACjC,MAAM,UAAU,eACd,QACA,YACA,iBACA,YACA,YACA,WACF;GACA,MAAM,IAAI,QAAQ,OAAO;GACzB,OAAO;EACT;EAEA,MAAM,EAAE,UAAU,kBAChB,UACA,iBACA,WACF;EAEA,OAAO;GACL,MAAM;GACN,aAAa;GACb,aAAa;EACf;CAEF,GAAG;EAAC;EAAW;EAAY;CAAe,CAAC;CAU3C,MAAM,GAAG,UAAA,GAAA,MAAA,aAAqB,MAAc,IAAI,GAAG,CAAC;CACpD,MAAM,WAAA,GAAA,MAAA,SAAA,GAAA,sBAAA,cAAuC,CAAC;CAS9C,MAAM,uBAAA,GAAA,MAAA,SAAA,GAAA,sBAAA,cAAmD,CAAC;CAG1D,MAAM,oBAAA,GAAA,MAAA,QAA4C,IAAI;CAEtD,CAAA,GAAA,MAAA,iBAAgB;EAId,MAAM,UAAW,KAAmC;EAGpD,IAFqB,UAAU,YAAY,KAAA,GAqBzC,OAlBc,QAAQ,gBACdC,sBAAAA,iBACA;GACJ,MAAM,SAAS,UAAU;GACzB,IAAI,CAAC,QAAQ;IACX,MAAM;IACN;GACF;GACA,MAAM,OAAO,OACV,KAAmC,OACpC,IACF;GACA,MAAM,OAAO,iBAAiB;GAC9B,IAAI,SAAS,QAAQ,kBAAkB,MAAM,IAAI,GAAG;GACpD,iBAAiB,UAAU;GAC3B,MAAM;EACR,CAES;EAUb,MAAM,QAAQ,QAAQ,gBACd,oBAAoB,eACpB,MAAM,CACd;EAIA,KAAoC,sBAClC,YACA,QAAQ,OACV;EACA,aAAa;GACX,MAAM;GACN,KAAoC,mBAAmB,UAAU;EACnE;CACF,GAAG,CAAC,MAAM,UAAU,CAAC;CAQrB,CAAA,GAAA,MAAA,iBAAgB;EACd,WAAW,UAAU,IAAuB;EAC5C,aAAa;GACX,aAAa,UAAU,IAAuB;GAC9C,CAAA,GAAA,WAAA,aAAY,EAAE,QACZ,WACA,aACA,OACA,aAAa,UAAU,CACzB;EACF;CAEF,GAAG,CAAC,MAAM,WAAW,CAAC;CAUtB,MAAM,WAAY,KAAmC;CACrD,IAAI;CACJ,IAAI,UAAU,YAAY,KAAA,GAAW;EACnC,QAAQ;EAGR,IAAI,iBAAiB,YAAY,MAC/B,iBAAiB,UAAU,UAAU,QACnC,UACA,IACF;CAEJ,OAAO;EACL,MAAM,WAAA,GAAA,sBAAA,aACJ,UACC,KAAmC,QACtC;EACA,QAAQ,QAAQ;EAChB,gBAAgB,UAAU,QAAQ;EAClC,QAAQ,UAAU,QAAQ;EAO1B,MAAM,UAAU,WAAW;EAC3B,QAAQ,MAAM;EACd,QAAQ,IAAI,MAAmC;GAC7C,MAAM;GACN,OAAO,QAAQ;EACjB,CAAC;CAQH;CAWA,CAAA,GAAA,MAAA,uBAAsB;EAKpB,gBAAgB,UAAU;EAC1B,IAAI,UAAU,YAAY,KAAA,GAAW;EACrC,MAAM,YAAY;EAClB,MAAM,QAAQ,QAAQ;EACtB,UAAU,sBAAsB,YAAY,KAAK;EAKjD,oBAAoB,UAAU,oBAC5B,OACA,UAAU,QACZ;EAaA,MAAM,OAAO,WAAW;EACxB,MAAM,UAAU,WAAW;EAG3B,KAAK,MAAM,CAAC,cAAc,QAAQ,MAChC,IAAI,CAAC,QAAQ,IAAI,YAAY,GAAG;GAC9B,IAAI,YAAY;GAChB,aAAa,mBAAmB,UAAU;GAC1C,CAAA,GAAA,WAAA,aAAY,EAAE,QAAQ,IAAI,MAAM,IAAI,KAAK,OAAO,IAAI,KAAK;GACzD,KAAK,OAAO,YAAY;EAC1B;EAIF,KAAK,MAAM,CAAC,cAAc,UAAU,SAAS;GAC3C,IAAI,MAAM,SAAS,WAAW;GAC9B,MAAM,WAAW,oBAAoB,MAAM,OAAO,aAAa,QAAQ;GACvE,aAAa,sBAAsB,YAAY,MAAM,KAAK;GAC1D,MAAM,WAAW,KAAK,IAAI,YAAY;GACtC,IAAI,UAAU;IACZ,SAAS,YAAY,UAAU;IAC/B;GACF;GACA,MAAM,cAAoC,EAAE,SAAS,SAAS;GAC9D,MAAM,cAAc,aAAa,QAAQ,gBACjC,YAAY,eACZ,MAAM,CACd;GACA,KAAK,IAAI,cAAc;IACrB;IACA;IACA,MAAM,MAAM;IACZ,KAAK,MAAM;IACX,OAAO,MAAM;GACf,CAAC;EACH;CACF,CAAC;CAOD,CAAA,GAAA,MAAA,iBAAgB;EAGd,MAAM,OAAO,WAAW;EACxB,aAAa;GACX,KAAK,MAAM,CAAC,cAAc,QAAQ,MAAM;IACtC,IAAI,YAAY;IAChB,aAAa,mBAAmB,UAAU;IAC1C,CAAA,GAAA,WAAA,aAAY,EAAE,QAAQ,IAAI,MAAM,IAAI,KAAK,OAAO,IAAI,KAAK;GAC3D;GACA,KAAK,MAAM;EACb;CACF,GAAG,CAAC,UAAU,CAAC;CAEf,OAAO;EACL;EACA;EACA;CACF;AACF;;;;;;;;;;;;;;;;;;;;;;AA0EA,SAAS,eACP,QACA,YACA,iBACA,YACA,YACA,aACe;CACf,MAAM,QAAQ,OAAOC,WAAAA;CACrB,MAAM,QAAQ,SAAS,UAAU;CACjC,MAAM,YAAA,GAAA,WAAA,aAAuB;CAG7B,MAAM,yBAAS,IAAI,IAGjB;CAEF,MAAM,WAAW,YAAmC;EAClD,MAAM,OAAO,SAAS,QAAQ,MAAM;EACpC,MAAM,MAAM,SAAS,WAAW,MAAM,MAAM,KAAA,GAAW,IAAI;EAM3D,OAAO;GAAE,KALG,SAAS,OACnB,MAAM,MACN,KACA,IAES;GAAG;GAAK;EAAK;CAC1B;CAEA,MAAM,UAAU;EACd,YAAY,YAAmC,QAAQ,OAAO,EAAE;EAChE,QAAQ,YAAmC;GACzC,MAAM,EAAE,KAAK,KAAK,SAAS,QAAQ,OAAO;GAG1C,IAAI,gBAAgB,WAAW,MAC7B,OAAO,CAAC,IAAI,OAAO,GAAG;GAGxB,MAAM,UAAU,WAAW;GAC3B,MAAM,WAAW,QAAQ,IAAI,GAAG;GAUhC,IAAI,aAAa,KAAA,KAAa,CAAC,WAAW,QAAQ,IAAI,GAAG,GACvD,SAAS,QAAQ,MAAM,MAAM,KAAK;IAChC,WAAW;IACX,UAAU;IACV;IACA;GACF,CAAC;GAGH,MAAM,WAAA,GAAA,sBAAA,aAAsB,IAAI,OAAO,IAAI,QAAQ;GACnD,IAAI,QAAQ,OAAO,IAAI,GAAG;GAC1B,IAAI,UAAU,KAAA,GAAW;IACvB,MAAM,MAAM,EAAE,SAAS,QAAQ,MAAiB;IAChD,QAAQ;KAAE;KAAK,OAAO,kBAAkB,KAAK,KAAK,WAAW,EAAE;IAAM;IACrE,OAAO,IAAI,KAAK,KAAK;GACvB,OACE,MAAM,IAAI,UAAU,QAAQ;GAG9B,IAAI,aAAa,KAAA,GAGf,SAAS,QAAQ,WAAW,SAAS,OAAO,QAAQ,KAAK;QAEzD,QAAQ,IAAI,KAAK;IACf,MAAM;IACN,OAAO,QAAQ;IACf,MAAM,MAAM;IACZ;IACA;GACF,CAAC;GAGH,OAAO,CAAC,QAAQ,OAAO,MAAM,KAAK;EACpC;CACF;CAEA,OAAO,eAAe,SAASA,WAAAA,WAAW;EACxC,OAAO;EACP,YAAY;EACZ,UAAU;EACV,cAAc;CAChB,CAAC;CAED,OAAO;AACT;;AAGA,SAAS,WAAW,GAAY,GAAqB;CACnD,IAAI,MAAMD,sBAAAA,aAAa,MAAMA,sBAAAA,WAAW,OAAOA,sBAAAA;CAC/C,MAAM,MAAM,IAAI,IAAY,CAAgB;CAC5C,KAAK,MAAM,MAAM,GAAkB,IAAI,IAAI,EAAE;CAC7C,OAAO;AACT;AAEA,MAAM,qBAAqB,GAAc,MAA0B;CACjE,IAAI,MAAM,GAAG,OAAO;CACpB,IAAI,EAAE,WAAW,EAAE,QAAQ,OAAO;CAClC,KAAK,IAAI,IAAI,GAAG,IAAI,EAAE,QAAQ,KAC5B,IAAI,CAAC,OAAO,GAAG,EAAE,IAAI,EAAE,EAAE,GAAG,OAAO;CAErC,OAAO;AACT;;;;;;;;;;;;;;;;;;;;;;;AAwBA,SAAS,oBAAoB,OAAgB,UAAiC;CAC5E,IAAI,UAAUA,sBAAAA,WAAW,OAAOA,sBAAAA;CAChC,MAAM,YAAY;CAClB,IAAI,UAAU,SAAS,GAAG,OAAO;CAEjC,MAAM,WAAW,IAAI,IAAY,SAAS;CAC1C,KAAK,MAAM,MAAM,WAAW;EAC1B,MAAM,MAAM,SAAS,OAAO,EAAE;EAQ9B,IAAI,MAAM,IAAI,YAAY,GAAG;EAC7B,OAAO,MAAM,GAAG;GACd,MAAM,WAAW,IAAI,MAAM,GAAG,GAAG;GACjC,SAAS,IAAI,SAAS,eAAe,QAAQ,CAAC;GAC9C,MAAM,SAAS,YAAY,GAAG;EAChC;CACF;CACA,OAAO;AACT;ACjrBA,IAAI,eAAgC,CAAmB;;;;;;AAOvD,SAAgB,mBAAmB,QAAwC;CACzE,eAAe;EAAE,GAAG;EAAc,GAAG;CAAO;AAC9C"}