@walkeros/web-source-browser 4.3.0-next-1784055686454 → 4.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +5 -4
- package/dist/dev.js.map +1 -1
- package/dist/dev.mjs.map +1 -1
- package/dist/index.browser.js +1 -1
- package/dist/index.es5.js +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/dist/walkerOS.json +1 -1
- package/package.json +4 -4
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/trigger.ts","../src/walker.ts","../src/triggerVisible.ts","../src/translation.ts","../src/elbLayer.ts","../src/config.ts","../src/types/index.ts","../src/tagger.ts"],"sourcesContent":["import type { Source, On } from '@walkeros/core';\nimport type { Scope, Types, Env } from './types';\nimport type { BrowserPush, BrowserArguments } from './types/elb';\nimport { isString } from '@walkeros/core';\nimport { createPushResult } from '@walkeros/collector';\nimport {\n initTriggers,\n initScopeTrigger,\n processLoadTriggers,\n ready,\n destroyTriggers,\n} from './trigger';\nimport type { ElbLayerController } from './elbLayer';\nimport { createElbLayer } from './elbLayer';\nimport { translateToCoreCollector } from './translation';\nimport { getPageViewData, getUser } from './walker';\nimport { getConfig } from './config';\n\nexport * as SourceBrowser from './types';\n\n/**\n * Window-scoped single-instance sentinel. The browser source must be\n * single-instance per window: one elbLayer adoption, one set of DOM\n * listeners, one `window.elb`. A second/synchronous load of the tag on the\n * same page is a SEPARATE module instance, so a module-scoped counter cannot\n * see it (each load starts at 0). The marker therefore lives on the window\n * itself. A Symbol key avoids collision with page globals and is\n * non-enumerable by nature.\n */\nconst SINGLE_INSTANCE_KEY = Symbol.for('@walkeros/web-source-browser:instance');\n\ntype EnvWindow = Window & typeof globalThis;\n\nfunction resolveGuardWindow(\n envWindow: EnvWindow | undefined,\n): EnvWindow | undefined {\n return (\n envWindow ||\n (typeof globalThis.window !== 'undefined' ? globalThis.window : undefined)\n );\n}\n\n/** For tests only. Clears the window-scoped single-instance sentinel. */\nexport function __resetInstanceCountForTests(): void {\n const win = resolveGuardWindow(undefined);\n if (win) Reflect.deleteProperty(win, SINGLE_INSTANCE_KEY);\n}\n\n/** For tests only. Reads the window-scoped single-instance sentinel so tests\n * assert against the real key, not a copied string. */\nexport function __readInstanceGuardForTests(): unknown {\n const win = resolveGuardWindow(undefined);\n return win ? Reflect.get(win, SINGLE_INSTANCE_KEY) : undefined;\n}\n\n/**\n * Inert source instance returned on a second load within the same window.\n * It satisfies the `Source.Instance` contract but performs no side effects:\n * `init` does not adopt elbLayer or bind DOM triggers, `push` resolves to a\n * successful no-op result, and `on`/`destroy` do nothing. This keeps a double\n * load from re-adopting `window.elbLayer` (the production crash vector)\n * without surfacing an error to the host page.\n */\nfunction createInertInstance(): Source.Instance<Types> {\n const fullConfig: Source.Config<Types> = {\n settings: getConfig({}, undefined),\n };\n const push: BrowserPush = ((..._args: Parameters<BrowserArguments>) =>\n Promise.resolve(createPushResult({ ok: true }))) satisfies BrowserPush;\n return {\n type: 'browser',\n config: fullConfig,\n push,\n on: async () => {},\n init: async () => {},\n destroy: async () => {},\n };\n}\n\n// Export walker utility functions\nexport {\n getAllEvents,\n getEvents,\n getGlobals,\n getUser,\n getElbAttributeName,\n getElbValues,\n} from './walker';\n\n// Export tagger functionality\nexport { createTagger } from './tagger';\nexport type { TaggerConfig, TaggerInstance } from './tagger';\n\n/**\n * Browser source implementation using environment injection.\n *\n * The factory body is side-effect-free: it constructs the Instance and\n * captures closure state. All eager setup (elbLayer drain, DOM listeners,\n * `window.elb` assignment) lives in the `init` lifecycle method, which\n * the collector calls after every source factory has registered. The\n * collector strictly gates `on()` delivery: lifecycle events are queued\n * in `instance.queueOn` until the source is started.\n */\nexport const sourceBrowser: Source.Init<Types> = async (context) => {\n const { config, env, logger } = context;\n const { elb, command, window, document } = env;\n\n const userSettings = config?.settings || {};\n const actualWindow =\n window ||\n (typeof globalThis.window !== 'undefined' ? globalThis.window : undefined);\n const actualDocument =\n document ||\n (typeof globalThis.document !== 'undefined'\n ? globalThis.document\n : undefined);\n\n // Single-instance per window. A second load on the same page is a separate\n // module instance, so the marker lives on the window, not in module scope.\n // Window-less environments (SSR/node/test without a window) are not guarded.\n const guardWindow = resolveGuardWindow(actualWindow);\n if (guardWindow) {\n if (Reflect.get(guardWindow, SINGLE_INSTANCE_KEY))\n return createInertInstance();\n // Set before init() runs so a synchronous second load is caught before\n // this first instance performs its own factory/init side effects.\n Object.defineProperty(guardWindow, SINGLE_INSTANCE_KEY, {\n value: true,\n enumerable: false,\n configurable: true,\n writable: false,\n });\n }\n\n const settings: Source.Settings<Types> = getConfig(\n userSettings,\n actualDocument as Document | undefined,\n );\n\n const fullConfig: Source.Config<Types> = {\n settings,\n };\n\n const translationContext = {\n elb,\n settings,\n initScope: initScopeTrigger,\n };\n\n // The append-only elbLayer controller (created in init when elbLayer is\n // enabled) and the window.elb function we install, retained so destroy can\n // tear down exactly what this instance set up.\n let controller: ElbLayerController | undefined;\n let installedWindowElb: BrowserPush | undefined;\n\n // Helper to send pageview event if enabled. Returns the dispatch promise so\n // the enqueued run-chain link resolves when the pageview actually completes.\n const sendPageview = (s: Source.Settings<Types>) => {\n if (!s.pageview) return;\n const [data, contextData] = getPageViewData(\n s.prefix || 'data-elb',\n s.scope as Scope,\n );\n return translateToCoreCollector(\n translationContext,\n 'page view',\n data,\n 'load',\n contextData,\n );\n };\n\n // Collect declarative user identity (data-elbuser) from the scope and set it as\n // persistent collector state via the existing `walker user` command. Returns the\n // dispatch promise so the run chain can order it strictly before the pageview,\n // or undefined when no data-elbuser is present (absent = no push, never a wipe).\n const sendUser = (s: Source.Settings<Types>) => {\n const user = getUser(s.prefix || 'data-elb', s.scope as Scope);\n if (!Object.keys(user).length) return;\n return translateToCoreCollector(translationContext, 'walker user', user);\n };\n\n // Lifecycle method — eager. The collector calls this AFTER all source\n // factories have registered. Side effects allowed: adopts window.elbLayer\n // via the controller, sets up DOM listeners, installs window.elb.\n const init = async () => {\n if (!actualWindow || !actualDocument) return;\n\n // Build the append-only layer controller. It routes through the real\n // translationContext, so `walker init` reaches initScope and events flow\n // through the same funnel as direct window.elb calls.\n const activeController =\n settings.elbLayer !== false\n ? createElbLayer(translationContext, {\n name: isString(settings.elbLayer) ? settings.elbLayer : 'elbLayer',\n window: actualWindow,\n logger,\n })\n : undefined;\n controller = activeController;\n\n // Setup global triggers (click, submit) when DOM is ready\n await ready(initTriggers, translationContext, settings);\n\n // Single writer for window.elb. With a controller, calls append to the\n // layer and route through the shared chain; without one (elbLayer:false)\n // they route directly via the source's push. `activeController` is a const\n // so its truthy narrowing survives into the arrow closure — the `let\n // controller` field would widen back to `| undefined` and force a cast.\n if (isString(settings.elb) && settings.elb) {\n const windowElb: BrowserPush = activeController\n ? (((...args: Parameters<BrowserArguments>) =>\n activeController.intake(args)) satisfies BrowserPush)\n : push;\n installedWindowElb = windowElb;\n Reflect.set(actualWindow, settings.elb, windowElb);\n }\n };\n\n // Lifecycle handler — fired by the collector only when this source is\n // started (config.init=true AND config.require empty). Pre-start events\n // are buffered in instance.queueOn by the collector and replayed on start.\n const handleEvent = async (event: On.Types) => {\n switch (event) {\n case 'run':\n if (actualDocument && actualWindow) {\n processLoadTriggers(translationContext, settings);\n if (controller) {\n // Replay the recorded backlog, then set the user, then the pageview, on\n // one FIFO chain so the pageview (and every later event) carries the user.\n controller.start();\n // Fire-and-forget: the enqueue link is now rejectable, so swallow\n // its rejection here to avoid an unhandled-rejection warning.\n controller.enqueue(() => sendUser(settings)).catch(() => {});\n controller.enqueue(() => sendPageview(settings)).catch(() => {});\n } else {\n // No controller: await the user command so collector.user is set before\n // the pageview's enrichment reads it. `sendUser` returns undefined when\n // no data-elbuser is present, so this is a no-op await in that case.\n await sendUser(settings);\n sendPageview(settings);\n }\n }\n break;\n\n default:\n break;\n }\n };\n\n const push: BrowserPush = ((...args: Parameters<BrowserArguments>) => {\n const [event, data, options, context, nested, custom] = args;\n return translateToCoreCollector(\n translationContext,\n event,\n data,\n options,\n context,\n nested,\n custom,\n );\n }) satisfies BrowserPush;\n\n // Return stateless source instance with event handler and push method\n return {\n type: 'browser',\n config: fullConfig,\n push,\n on: handleEvent,\n init,\n destroy: async () => {\n // Iterates the scope registry: aborts root + per-scope listeners, clears\n // every scope's intervals/timeouts, and disconnects the shared\n // per-document observer(s). Reaches sub-scopes from `walker init <el>`,\n // not just the source's own document scope.\n destroyTriggers(settings);\n\n // Restore the layer's native push and forget controller state.\n controller?.destroy();\n\n // Remove window.elb only if it is still the function we installed — never\n // clobber a foreign global.\n if (actualWindow && isString(settings.elb) && settings.elb) {\n if (Reflect.get(actualWindow, settings.elb) === installedWindowElb)\n Reflect.deleteProperty(actualWindow, settings.elb);\n }\n\n // Clear the single-instance sentinel so a destroyed source can be\n // recreated on the same window.\n if (guardWindow) Reflect.deleteProperty(guardWindow, SINGLE_INSTANCE_KEY);\n\n // Drop references so a stray post-destroy run finds nothing to drive.\n controller = undefined;\n installedWindowElb = undefined;\n },\n };\n};\n\nexport default sourceBrowser;\n","import type { WalkerOS, Collector } from '@walkeros/core';\nimport type { Walker } from '@walkeros/web-core';\nimport type { Scope, InitScope, Settings, Context, ScopeState } from './types';\nimport { throttle, tryCatch } from '@walkeros/core';\nimport { Const, onApply } from '@walkeros/collector';\nimport { elb as elbOrg, getAttribute } from '@walkeros/web-core';\nimport {\n getElbAttributeName,\n getEvents,\n getPageViewData,\n getTriggerActions,\n queryAllComposed,\n} from './walker';\nimport {\n initVisibilityTracking,\n triggerVisible,\n destroyVisibilityTracking,\n unobserveElement,\n} from './triggerVisible';\nimport { translateToCoreCollector } from './translation';\n\n// Module-level state is intentional. The walker.js browser source is\n// single-instance per window: one elb queue, one set of DOM listeners.\n// If multi-instance ever becomes a real requirement (e.g., micro-frontends\n// with isolated walker queues), refactor this into a per-instance closure\n// returned by createSource() and route every trigger function through it.\n//\n// Root click/submit delegation lives on an instance-level controller, aborted\n// only by destroyTriggers (or re-arming initGlobalTrigger). It is deliberately\n// SEPARATE from the per-scope controllers below: a sub-scope re-init must\n// never tear down page-wide click/submit.\nlet rootAbortController: AbortController | undefined;\n\n// Iterable on purpose: destroyTriggers must enumerate every active scope to\n// reach sub-scope intervals/observers (a WeakMap could not back full teardown).\n// Note: this holds strong references to init'd scope nodes (including detached\n// DOM elements). A node init'd via `walker init <el>` and later removed from\n// the DOM without a re-init or source destroy is retained until re-init\n// replaces its entry or destroyTriggers clears the Map. Bounded by the\n// source/page session and accepted per plan §4.\nconst scopeStates = new Map<InitScope, ScopeState>();\n\n// Per-element teardown record. The reaper reads this to release exactly ONE\n// element's resources (its pulse intervals, its wait timeouts, its hover\n// listener, its visibility observation, its scroll entry) without touching the\n// rest of the scope. `scope` is the owning scope key: it selects both the owner\n// bucket (via scopeStates) and the unobserveElement key, so an element removed\n// inside a different scope's subtree is still released from its true owner.\nexport interface ElementRegistration {\n scope: InitScope;\n intervalIds: ReturnType<typeof setInterval>[];\n timeoutIds: ReturnType<typeof setTimeout>[];\n hoverAbort?: AbortController;\n scroll: boolean; // presence flag: the element itself keys into bucket.scrollElements\n observed: boolean; // presence flag: the element itself keys into bucket.observed\n}\n\n// Source-wide registry: the single authority for \"has ANY scope already wired\n// this element?\". A WeakMap is not enumerable, so the per-scope\n// ScopeState.registered set is its enumerable companion — reset/teardown iterate\n// that set to release a scope's elements from here. Invariant:\n// el ∈ bucket.registered ⟺ elementRegistry.get(el).scope === that bucket's scope.\nconst elementRegistry = new WeakMap<HTMLElement, ElementRegistration>();\n\n// Register an element as wired by `scope`, in both the enumerable per-scope set\n// and the source-wide registry. No-op (returns false) if any scope already\n// registered it (cross-scope dedup) or the scope has no live bucket. The owning\n// bucket is derived from scopeStates, never passed in, so the\n// registered/registry invariant is structural — a caller cannot register an\n// element into a bucket that mismatches `scope`.\nexport function registerElement(\n scope: InitScope,\n el: HTMLElement,\n registration: ElementRegistration,\n): boolean {\n if (elementRegistry.has(el)) return false;\n const bucket = scopeStates.get(scope);\n if (!bucket) return false;\n registration.scope = scope;\n bucket.registered.add(el);\n elementRegistry.set(el, registration);\n return true;\n}\n\n// Source-wide \"already wired?\" check: true if ANY scope registered the element.\nexport function isRegistered(el: HTMLElement): boolean {\n return elementRegistry.has(el);\n}\n\n// Release one element and un-register it, so it can register again on re-add or\n// re-scan. Self-derives the OWNING bucket from registration.scope (never a\n// caller's scope): an element owned by the document scope but removed inside a\n// sub-scope observer's subtree is still released from its true owner, keeping\n// the registered/registry invariant intact.\nexport function reapElement(el: HTMLElement): void {\n const registration = elementRegistry.get(el);\n if (!registration) return;\n\n const bucket = scopeStates.get(registration.scope);\n\n // Clear each id AND splice it from the owner's flat arrays, so a long\n // inject/remove session does not accrue dead ids there.\n registration.intervalIds.forEach((id) => {\n clearInterval(id);\n if (bucket) {\n const index = bucket.intervalIds.indexOf(id);\n if (index !== -1) bucket.intervalIds.splice(index, 1);\n }\n });\n registration.timeoutIds.forEach((id) => {\n clearTimeout(id);\n if (bucket) {\n const index = bucket.timeoutIds.indexOf(id);\n if (index !== -1) bucket.timeoutIds.splice(index, 1);\n }\n });\n\n registration.hoverAbort?.abort();\n\n if (registration.observed) {\n unobserveElement(registration.scope, el);\n bucket?.observed.delete(el);\n }\n\n if (registration.scroll && bucket) {\n // scrollElements is a [HTMLElement, number] tuple array — remove EVERY entry\n // for this element. A multi-scroll element (data-elbaction=\"scroll:50;scroll:75\")\n // pushes one tuple per trigger, so removing only the first would strand the\n // rest and fire a phantom scroll on the detached element.\n bucket.scrollElements = bucket.scrollElements.filter(\n ([element]) => element !== el,\n );\n }\n\n bucket?.registered.delete(el);\n elementRegistry.delete(el);\n}\n\n// Tear down a scope's prior state (if any), then install a fresh empty bucket.\nexport function resetScope(scope: InitScope): ScopeState {\n const previous = scopeStates.get(scope);\n if (previous) {\n previous.abort.abort(); // removes scroll listener (hover is per-element)\n // The flat clears below are the defensive baseline: they blanket-clear\n // every id/observation the scope holds. The reap loop that follows is a\n // superset per element — it additionally aborts hover, deletes the registry\n // entry, and splices the flat arrays — and it re-clears/re-unobserves the\n // same resources, which is idempotent and harmless. Both are kept so a\n // future resource that lands in a flat array without going through\n // registerScanElement (→ `registered`) is still torn down here.\n previous.intervalIds.forEach((id) => clearInterval(id));\n previous.timeoutIds.forEach((id) => clearTimeout(id));\n previous.observed.forEach((element) => unobserveElement(scope, element));\n // Release each element's per-element resources (crucially its hover\n // listener) and clear the registry so the elements can re-register on the\n // fresh scan. Snapshot the set — reapElement deletes from it as it goes.\n // reapElement self-derives this same still-current bucket (the fresh one is\n // not installed until below).\n [...previous.registered].forEach((element) => reapElement(element));\n previous.mutationObservers.forEach((observer) => observer.disconnect());\n }\n\n const fresh: ScopeState = {\n abort: new AbortController(),\n intervalIds: [],\n timeoutIds: [],\n scrollElements: [],\n observed: new Set(),\n registered: new Set(),\n mutationObservers: [],\n };\n scopeStates.set(scope, fresh);\n return fresh;\n}\n\n// Test-only accessor: exposes a scope's live bucket so suites can assert its\n// observer/registration counts and spy on real observer instances. Not\n// re-exported through src/index.ts, so the public package surface is unchanged.\nexport function getScopeState(scope: InitScope): ScopeState | undefined {\n return scopeStates.get(scope);\n}\n\n// Reset function for testing: clears each active scope's scroll state.\nexport function resetScrollListener() {\n scopeStates.forEach((state) => {\n state.scrollElements = [];\n state.scrollListener = undefined;\n });\n}\n\nexport const createElb: (customLayer?: unknown) => unknown = (customLayer?) => {\n return (\n customLayer\n ? function () {\n (customLayer as unknown[]).push(arguments);\n }\n : elbOrg\n ) as unknown;\n};\n\nexport const Triggers: { [key: string]: Walker.Trigger } = {\n Click: 'click',\n Custom: 'custom',\n Hover: 'hover',\n Load: 'load',\n Pulse: 'pulse',\n Scroll: 'scroll',\n Submit: 'submit',\n Impression: 'impression',\n Visible: 'visible',\n Wait: 'wait',\n} as const;\n\nexport async function ready(\n fn: (context: Context, settings: Settings) => void,\n context: Context,\n settings: Settings,\n): Promise<void> {\n const readyFn = () => {\n fn(context, settings);\n };\n\n const scope = settings.scope;\n if (!scope) {\n readyFn();\n return;\n }\n const doc = (scope as Element).ownerDocument || (scope as Document);\n if (doc.readyState !== 'loading') {\n readyFn();\n } else {\n doc.addEventListener('DOMContentLoaded', readyFn);\n }\n}\n\n// Called once during source initialization to setup global listeners\nexport function initTriggers(context: Context, settings: Settings) {\n if (!settings.scope) return; // Skip if no scope available\n const requiredSettings = settings as Required<Settings>;\n initGlobalTrigger(context, requiredSettings);\n}\n\n// Called on each walker run to process load triggers\nexport function processLoadTriggers(context: Context, settings: Settings) {\n if (!settings.scope) return; // Skip if no scope available\n const requiredSettings = settings as Required<Settings>;\n initScopeTrigger(context, requiredSettings);\n}\n\nexport function initGlobalTrigger(context: Context, settings: Settings): void {\n const scope = settings.scope;\n\n if (!scope) return;\n\n // Abort any previously registered root listeners before re-registering.\n // This controller owns ONLY the root click/submit delegation.\n if (rootAbortController) rootAbortController.abort();\n rootAbortController = new AbortController();\n const { signal } = rootAbortController;\n\n scope.addEventListener(\n 'click',\n tryCatch(function (this: Scope, ev: unknown) {\n triggerClick.call(this, context, ev as MouseEvent);\n }) as EventListener,\n { signal, capture: settings.capture },\n );\n scope.addEventListener(\n 'submit',\n tryCatch(function (this: Scope, ev: unknown) {\n triggerSubmit.call(this, context, ev as SubmitEvent);\n }) as EventListener,\n { signal, capture: settings.capture },\n );\n}\n\n// Full teardown: aborts the root click/submit controller, then enumerates the\n// scope registry so EVERY active scope (document and sub-scopes alike) has its\n// hover/scroll listeners aborted, intervals/timeouts cleared, and shared\n// per-document observer disconnected. Safe to call before any init.\nexport function destroyTriggers(_settings?: Settings): void {\n if (rootAbortController) {\n rootAbortController.abort();\n rootAbortController = undefined;\n }\n\n // Two passes over the scope registry. `visibilityStates` is keyed per owner\n // document (one shared observer state), while `scopeStates` holds many\n // entries per document (the document scope plus every `walker init <el>`\n // sub-scope). unobserveElement reads that shared per-document state, so every\n // scope's armed dwell timers must be cancelled BEFORE any scope tears the\n // shared state down; otherwise the first same-document destroy deletes the\n // state and later scopes' unobserve calls no-op, leaking their timers.\n scopeStates.forEach((state, scope) => {\n state.abort.abort();\n // Stop watching observe containers first, so no mutation callback fires\n // mid-teardown against a half-cleared scope.\n state.mutationObservers.forEach((observer) => observer.disconnect());\n // Flat clears are the defensive baseline superset (see resetScope): they\n // blanket-clear the scope's ids/observations. The reap loop below is the\n // per-element superset — additionally aborting hover and deleting registry\n // entries — and its re-clear/re-unobserve is idempotent.\n state.intervalIds.forEach((id) => clearInterval(id));\n state.timeoutIds.forEach((id) => clearTimeout(id));\n // Cancel armed visibility dwell timers and detach observed elements while\n // the shared per-document state still exists. Mirrors resetScope's cleanup.\n state.observed.forEach((element) => unobserveElement(scope, element));\n // Release per-element resources. Hover listeners now live on per-element\n // controllers, so state.abort.abort() above no longer covers them — reap\n // each registered element to abort its hoverAbort and clear its registry\n // entry. Snapshot the set — reapElement deletes from it as it goes.\n [...state.registered].forEach((element) => reapElement(element));\n });\n\n scopeStates.forEach((_state, scope) => {\n // Normalizes to the owner document and disconnects the shared observer;\n // the second call for a same-document sub-scope is a harmless no-op.\n destroyVisibilityTracking(scope);\n });\n\n scopeStates.clear();\n}\n\n// Scope is the single carrier: it lives only in context.settings.scope. The\n// optional second argument is kept for signature compatibility (the Context\n// `initScope` slot calls this with a single, scope-aligned context) but is not\n// read. `walker init <el>` and `walker run` (document) are the same path,\n// differing only in the scope the carrier holds. Re-running on a scope tears\n// down that scope's prior state, then attaches fresh = one fresh init.\nexport function initScopeTrigger(context: Context, _settings?: Settings) {\n const scope = context.settings.scope;\n if (!scope) return;\n\n const bucket = resetScope(scope);\n\n // Idempotent \"ensure\" of the per-document observer (one per ownerDocument).\n // Never disconnect on a sub-scope re-init — resetScope already unobserved\n // this scope's elements above.\n initVisibilityTracking(scope, 1000);\n\n // default data-elbaction\n const selectorAction = getElbAttributeName(\n context.settings.prefix,\n Const.Commands.Action,\n false,\n );\n const doc = (scope as Element).ownerDocument || (scope as Document);\n const win = doc.defaultView;\n // The element self-check only applies to an Element sub-scope. A ShadowRoot\n // scope has no getAttribute, so calling handleActionElem on it would throw;\n // it is scanned by queryAllComposed below instead. A Document scope has\n // scope === doc, so it never enters this branch.\n if (scope !== doc && win && scope instanceof win.Element) {\n // Handle the elements action(s), too\n registerScanElement(context, scope, selectorAction, bucket, scope);\n }\n\n // Handle all children action(s)\n queryAllComposed(scope, `[${selectorAction}]`, (elem) => {\n registerScanElement(context, elem, selectorAction, bucket, scope);\n });\n\n if (bucket.scrollElements.length) scroll(context, scope, bucket);\n\n // Watch [<prefix>observe] containers so tagged content injected later is\n // auto-registered (and reaped on removal) without a manual `walker init`.\n observeContainers(context, scope, bucket, selectorAction);\n}\n\n// Attach a MutationObserver to each OUTERMOST [<prefix>observe] container per\n// tree in this scope. Nesting-skip: a container contained by another candidate\n// is skipped, because a subtree:true observer already sees descendant additions\n// and nested observers double-report a single deep insertion. Node.contains does\n// not cross shadow boundaries, so a shadow-hosted container is never \"contained\"\n// by a light-DOM ancestor and correctly keeps its own observer.\nfunction observeContainers(\n context: Context,\n scope: InitScope,\n bucket: ScopeState,\n selectorAction: string,\n) {\n const doc = (scope as Element).ownerDocument || (scope as Document);\n const win = doc.defaultView;\n // Guard like createObserver's win.IntersectionObserver check so a window-less\n // environment simply no-ops instead of throwing.\n if (!win || !win.MutationObserver) return;\n\n const selectorObserve = getElbAttributeName(\n context.settings.prefix,\n 'observe',\n false,\n );\n\n // Candidate containers: the scope element itself (sub-scope self-check) plus\n // every discovered descendant, across open shadow roots.\n const containers: Element[] = [];\n if (\n scope !== doc &&\n scope instanceof win.Element &&\n scope.matches(`[${selectorObserve}]`)\n ) {\n containers.push(scope);\n }\n queryAllComposed(scope, `[${selectorObserve}]`, (el) => containers.push(el));\n\n containers.forEach((container) => {\n // Outermost-per-tree, but scope-LOCAL: `contains` only dedups candidates\n // discovered by THIS scope. Two scopes observing overlapping trees (a\n // document-scope container and a `walker init <el>` sub-scope container over\n // the same subtree) are NOT deduped here — the source-wide element registry\n // (isRegistered) makes their overlapping adds safe instead (Amendment 3, a\n // documented v1 limitation).\n const nested = containers.some(\n (other) => other !== container && other.contains(container),\n );\n if (nested) return;\n\n const observer = new win.MutationObserver(\n tryCatch((records: MutationRecord[]) => {\n // Re-read the LIVE bucket every callback: a resetScope between async\n // callbacks installs a fresh bucket and aborts this one; if the scope\n // was destroyed, bail. Never close over the creation-time bucket.\n const live = scopeStates.get(scope);\n if (!live) return;\n\n records.forEach((record) => {\n record.addedNodes.forEach((node) =>\n handleAddedNode(context, node, selectorAction, live, scope),\n );\n // Re-arm the scroll listener once per record: an added node may have\n // registered a scroll trigger into live.scrollElements. scroll() guards\n // duplicate listeners, so once-per-record is sufficient and cheap.\n if (live.scrollElements.length) scroll(context, scope, live);\n record.removedNodes.forEach((node) =>\n handleRemovedNode(context, node),\n );\n });\n }),\n );\n observer.observe(container, { childList: true, subtree: true });\n bucket.mutationObservers.push(observer);\n });\n}\n\nexport async function handleTrigger(\n context: Context,\n element: Element,\n trigger: string,\n // @TODO add triggerParams to filter for specific trigger\n): Promise<unknown[]> {\n const events = getEvents(element, trigger, context.settings.prefix);\n return Promise.all(\n events.map((event: Walker.Event) =>\n translateToCoreCollector(context, {\n name: `${event.entity} ${event.action}`,\n ...event,\n trigger,\n }),\n ),\n );\n}\n\n// Discover + register a single scanned node. Returns the built registration\n// (or undefined if the node was skipped), so callers/tests can inspect the\n// per-element resources it recorded. Guards up front: element nodes only\n// (nodeType === 1, narrowed cast-free via `instanceof win.HTMLElement`), not\n// already registered by any scope, and carrying the action attribute.\nexport function registerScanElement(\n context: Context,\n node: Node,\n selectorAction: string,\n bucket: ScopeState,\n scope: InitScope,\n): ElementRegistration | undefined {\n if (node.nodeType !== 1) return undefined;\n const win = node.ownerDocument?.defaultView;\n if (!win || !(node instanceof win.HTMLElement)) return undefined;\n if (isRegistered(node)) return undefined;\n if (!getAttribute(node, selectorAction)) return undefined;\n\n const registration: ElementRegistration = {\n scope,\n intervalIds: [],\n timeoutIds: [],\n scroll: false,\n observed: false,\n };\n handleActionElem(context, node, selectorAction, bucket, registration);\n registerElement(scope, node, registration);\n return registration;\n}\n\n// The removed-node path the MutationObserver callback invokes. Element nodes\n// only (text/comment have no .matches/.querySelectorAll and would throw). Reaps\n// `removedEl` itself and each tagged descendant that ANY scope registered.\n// reapElement is single-arg and self-derives the OWNING bucket from\n// registration.scope (Amendment 2): a document-scope-owned element removed\n// inside a sub-scope observer's subtree is released from its true owner, not the\n// remover's scope — never pass a caller's scope/bucket here.\nexport function handleRemovedNode(context: Context, removedEl: Node): void {\n if (removedEl.nodeType !== 1) return;\n const win = removedEl.ownerDocument?.defaultView;\n if (!win || !(removedEl instanceof win.HTMLElement)) return;\n\n const selectorAction = getElbAttributeName(\n context.settings.prefix,\n Const.Commands.Action,\n false,\n );\n\n if (isRegistered(removedEl)) reapElement(removedEl);\n queryAllComposed(removedEl, `[${selectorAction}]`, (el) => {\n if (el instanceof win.HTMLElement && isRegistered(el)) reapElement(el);\n });\n}\n\n// The added-node path the MutationObserver callback invokes, mirroring\n// handleRemovedNode. HTMLElement nodes only: this narrowing is deliberate, not\n// merely a text/comment guard. Text/comment nodes lack .matches/.querySelectorAll\n// and would throw, but an SVGElement HAS them — it is excluded on purpose because\n// the whole registration pipeline (the elementRegistry WeakMap, the bucket\n// HTMLElement sets, handleActionElem) is HTMLElement-typed. Do not widen to\n// Element. addedNodes holds only the top-level inserted node, so walk its tagged\n// descendants too. Registers into the passed live bucket (the caller re-reads it\n// per callback); unlike the reaper, the add path must be told where to register.\nfunction handleAddedNode(\n context: Context,\n node: Node,\n selectorAction: string,\n bucket: ScopeState,\n scope: InitScope,\n): void {\n const win = node.ownerDocument?.defaultView;\n if (!win || !(node instanceof win.HTMLElement)) return;\n registerScanElement(context, node, selectorAction, bucket, scope);\n queryAllComposed(node, `[${selectorAction}]`, (el) => {\n registerScanElement(context, el, selectorAction, bucket, scope);\n });\n}\n\nfunction handleActionElem(\n context: Context,\n elem: HTMLElement,\n selectorAction: string,\n bucket: ScopeState,\n registration: ElementRegistration,\n) {\n const actionAttr = getAttribute(elem, selectorAction);\n\n if (!actionAttr) return;\n\n // TriggersActionGroups ([trigger: string]: TriggerActions)\n Object.values(getTriggerActions(actionAttr)).forEach((triggerActions) =>\n // TriggerActions (Array<TriggerAction>)\n triggerActions.forEach((triggerAction: Walker.TriggerActions[0]) => {\n // TriggerAction ({ trigger, triggerParams, action, actionParams })\n switch (triggerAction.trigger) {\n case Triggers.Hover:\n triggerHover(context, elem, registration);\n break;\n case Triggers.Load:\n triggerLoad(context, elem);\n break;\n case Triggers.Pulse:\n triggerPulse(\n context,\n elem,\n bucket,\n registration,\n triggerAction.triggerParams,\n );\n break;\n case Triggers.Scroll:\n triggerScroll(\n elem,\n bucket,\n registration,\n triggerAction.triggerParams,\n );\n break;\n case Triggers.Impression:\n triggerVisible(context, elem);\n bucket.observed.add(elem);\n registration.observed = true;\n break;\n case Triggers.Visible:\n triggerVisible(context, elem, { multiple: true });\n bucket.observed.add(elem);\n registration.observed = true;\n break;\n case Triggers.Wait:\n triggerWait(\n context,\n elem,\n bucket,\n registration,\n triggerAction.triggerParams,\n );\n break;\n }\n }),\n );\n}\n\n/**\n * Get the actual event target, piercing open shadow DOM boundaries.\n * Uses composedPath() to find the real target inside shadow roots.\n * For closed shadow DOM, falls back to the host element (by design).\n */\nfunction getComposedTarget(ev: Event): Element | undefined {\n const path = ev.composedPath?.();\n const target = path?.length ? path[0] : ev.target;\n if (!target || typeof target !== 'object' || !('tagName' in target))\n return undefined;\n return target as Element;\n}\n\nfunction triggerClick(context: Context, ev: MouseEvent) {\n const target = getComposedTarget(ev);\n if (target) handleTrigger(context, target, Triggers.Click);\n}\n\nfunction triggerHover(\n context: Context,\n elem: HTMLElement,\n registration: ElementRegistration,\n) {\n // Per-element controller: the reaper aborts exactly this element's hover\n // listener without tearing down the scope. Reuse one controller per element\n // so multiple hover actions on the same element share (and are all released\n // by) a single abort.\n if (!registration.hoverAbort) registration.hoverAbort = new AbortController();\n elem.addEventListener(\n 'mouseenter',\n tryCatch(function (this: Document, ev: MouseEvent) {\n const target = getComposedTarget(ev);\n if (target) handleTrigger(context, target, Triggers.Hover);\n }),\n { signal: registration.hoverAbort.signal },\n );\n}\n\nfunction triggerLoad(context: Context, elem: HTMLElement) {\n handleTrigger(context, elem, Triggers.Load);\n}\n\nfunction triggerPulse(\n context: Context,\n elem: HTMLElement,\n bucket: ScopeState,\n registration: ElementRegistration,\n triggerParams: string = '',\n) {\n const doc = elem.ownerDocument;\n const intervalId = setInterval(\n () => {\n // Only trigger when tab is active\n if (!doc.hidden) handleTrigger(context, elem, Triggers.Pulse);\n },\n parseInt(triggerParams || '') || 15000,\n );\n bucket.intervalIds.push(intervalId);\n registration.intervalIds.push(intervalId);\n}\n\nfunction triggerScroll(\n elem: HTMLElement,\n bucket: ScopeState,\n registration: ElementRegistration,\n triggerParams: string = '',\n) {\n // Scroll depth in percent, default 50%\n const depth = parseInt(triggerParams || '') || 50;\n\n // Ignore invalid parameters\n if (depth < 0 || depth > 100) return;\n\n bucket.scrollElements.push([elem, depth]);\n registration.scroll = true;\n}\n\nfunction triggerSubmit(context: Context, ev: SubmitEvent) {\n const target = getComposedTarget(ev);\n if (target) handleTrigger(context, target, Triggers.Submit);\n}\n\nfunction triggerWait(\n context: Context,\n elem: HTMLElement,\n bucket: ScopeState,\n registration: ElementRegistration,\n triggerParams: string = '',\n) {\n const timeoutId = setTimeout(\n () => handleTrigger(context, elem, Triggers.Wait),\n parseInt(triggerParams || '') || 15000,\n );\n bucket.timeoutIds.push(timeoutId);\n registration.timeoutIds.push(timeoutId);\n}\n\nfunction scroll(context: Context, scope: InitScope, bucket: ScopeState) {\n const doc = (scope as Element).ownerDocument || (scope as Document);\n const win = doc.defaultView!;\n const scrolling = (\n scrollElements: Walker.ScrollElements,\n context: Context,\n ) => {\n return scrollElements.filter(([element, depth]: [Element, number]) => {\n // getBoundingClientRect is viewport-relative and composes across shadow\n // boundaries, so scroll depth is correct for shadow-nested elements.\n const rect = (element as HTMLElement).getBoundingClientRect();\n\n // Skip calculations if not in viewport yet (element top below the fold)\n if (win.innerHeight < rect.top) return true;\n\n // Height of the elements box as 100 percent base\n const elemHeight = rect.height || element.clientHeight;\n // Distance from the viewport top to the elements bottom\n const elemBottom = rect.top + elemHeight;\n // Height of the non-visible pixels below the visible screen\n const hidden = elemBottom - win.innerHeight;\n // Visible percentage of the element\n const scrollDepth = (1 - hidden / (elemHeight || 1)) * 100;\n\n // Check if the elements visibility skipped the required border\n if (scrollDepth >= depth) {\n // Enough scrolling, it's time\n handleTrigger(context, element, Triggers.Scroll);\n\n // Remove the element from scrollEvents\n return false;\n }\n\n // Keep observing the element\n return true;\n });\n };\n\n // Don't add unnecessary scroll listeners. The bucket is fresh per init, so\n // the scope's prior scroll listener was already aborted via its controller.\n if (!bucket.scrollListener) {\n bucket.scrollListener = throttle(function () {\n bucket.scrollElements = scrolling.call(\n scope,\n bucket.scrollElements,\n context,\n );\n });\n\n // A ShadowRoot never receives page scroll events, so a listener on it would\n // never fire; attach to the owner document instead. Element/Document scopes\n // keep their existing target.\n const scrollTarget = scope instanceof win.ShadowRoot ? doc : scope;\n scrollTarget.addEventListener('scroll', bucket.scrollListener, {\n signal: bucket.abort.signal,\n });\n }\n}\n","import type { WalkerOS } from '@walkeros/core';\nimport type { Walker } from '@walkeros/web-core';\nimport type { Scope } from './types';\nimport { assign, castValue, isArray, trim } from '@walkeros/core';\nimport { Const } from '@walkeros/collector';\nimport { getAttribute } from '@walkeros/web-core';\n\nexport function getElbAttributeName(\n prefix: string,\n name?: string,\n isProperty = true,\n): string {\n // separate dynamic properties from walker Const.Commands\n const separator = isProperty ? '-' : '';\n name = name != undefined ? separator + name : '';\n return prefix + name;\n}\n\nexport function getElbValues(\n prefix: string,\n element: Element,\n name: string,\n isProperty = true,\n): WalkerOS.Properties {\n const attributeValue =\n getAttribute(element, getElbAttributeName(prefix, name, isProperty)) || '';\n\n const elbValues = splitAttribute(attributeValue).reduce((values, str) => {\n let [key, val]: Walker.KeyVal = splitKeyVal(str);\n\n if (!key) return values;\n\n // Handle keys without value\n if (!val) {\n // Manually remove the : from key on empty values\n if (key.endsWith(':')) key = key.slice(0, -1);\n val = '';\n }\n\n // Dynamic values\n if (val.startsWith('#')) {\n val = val.slice(1); // Remove # symbol\n try {\n // Read property value from element\n let dynamicValue = (element as Element)[val as keyof Element];\n if (!dynamicValue && val === 'selected') {\n // Try to read selected value with chance of error\n dynamicValue = (element as HTMLSelectElement).options[\n (element as HTMLSelectElement).selectedIndex\n ].text;\n }\n\n val = String(dynamicValue);\n } catch (error) {\n val = '';\n }\n }\n\n if (key.endsWith('[]')) {\n key = key.slice(0, -2); // Remove [] symbol\n if (!isArray(values[key])) values[key] = [];\n (values[key] as WalkerOS.PropertyType[]).push(castValue(val));\n } else {\n values[key] = castValue(val);\n }\n\n return values;\n }, {} as WalkerOS.Properties);\n\n return elbValues;\n}\n\nexport function getAllEvents(\n scope: Scope,\n prefix: string = Const.Commands.Prefix,\n): Walker.Events {\n const actualScope = scope;\n if (!actualScope) return [];\n let events: Walker.Events = [];\n const action = Const.Commands.Action;\n const actionSelector = `[${getElbAttributeName(prefix, action, false)}]`;\n\n const processElementEvents = (elem: Element) => {\n Object.keys(getElbValues(prefix, elem, action, false)).forEach(\n (trigger) => {\n events = events.concat(getEvents(elem, trigger, prefix));\n },\n );\n };\n\n // Check if the scope element itself has action attributes\n const doc =\n (actualScope as Element).ownerDocument || (actualScope as Document);\n if (\n actualScope !== doc &&\n (actualScope as Element).matches?.(actionSelector)\n ) {\n processElementEvents(actualScope as Element);\n }\n\n queryAllComposed(actualScope, actionSelector, processElementEvents);\n\n return events;\n}\n\nexport function getEvents(\n target: Element,\n trigger: string,\n prefix: string = Const.Commands.Prefix,\n): Walker.Events {\n const events: Walker.Events = [];\n\n // Check for actions and get entity collection strategy\n const { actions, nearestOnly } = resolveAttributes(prefix, target, trigger);\n\n // Stop if there's no valid action combo\n if (!actions.length) return events;\n\n actions.forEach((triggerAction) => {\n const filter = splitAttribute(triggerAction.actionParams || '', ',').reduce(\n (filter, param) => {\n filter[trim(param)] = true;\n return filter;\n },\n {} as Walker.Filter,\n );\n\n // Get entities - using nearestOnly flag to determine collection strategy\n const entities = getEntities(prefix, target, filter, nearestOnly);\n\n // Use page as default entity if no one was set\n if (!entities.length) {\n const entity = 'page';\n // Only use explicit page properties and ignore generic properties\n const entitySelector = `[${getElbAttributeName(prefix, entity)}]`;\n\n // Get matching properties from the element and its parents\n const [data, context] = getThisAndParentProperties(\n target,\n entitySelector,\n prefix,\n entity,\n );\n\n entities.push({\n entity, // page\n data, // Consider only upper data\n nested: [], // Skip nested in this faked page case\n context,\n });\n }\n\n // Return a list of full events\n entities.forEach((entity) => {\n events.push({\n entity: entity.entity,\n action: triggerAction.action,\n data: entity.data,\n trigger,\n context: entity.context,\n nested: entity.nested ?? [],\n });\n });\n });\n\n return events;\n}\n\nexport function getGlobals(\n prefix: string = Const.Commands.Prefix,\n scope?: Scope,\n): WalkerOS.Properties {\n if (!scope) return {};\n const globalsName = getElbAttributeName(\n prefix,\n Const.Commands.Globals,\n false,\n );\n const globalSelector = `[${globalsName}]`;\n let values = {};\n\n queryAll(scope, globalSelector, (element) => {\n values = assign(\n values,\n getElbValues(prefix, element, Const.Commands.Globals, false),\n );\n });\n\n return values;\n}\n\nexport function getUser(\n prefix: string = Const.Commands.Prefix,\n scope?: Scope,\n): WalkerOS.User {\n if (!scope) return {};\n const userName = getElbAttributeName(prefix, Const.Commands.User, false);\n const userSelector = `[${userName}]`;\n let values: WalkerOS.User = {};\n\n queryAll(scope, userSelector, (element) => {\n values = assign(\n values,\n getElbValues(prefix, element, Const.Commands.User, false),\n );\n });\n\n return values;\n}\n\nexport function getPageViewData(\n prefix: string,\n scope: Scope,\n): [WalkerOS.Properties, WalkerOS.OrderedProperties] {\n // static page view\n const doc = (scope as Element).ownerDocument || (scope as Document);\n const win = doc.defaultView!;\n const loc = win.location;\n const page = 'page';\n const scopeElement =\n 'body' in scope ? (scope as Document).body : (scope as Element);\n const [data, context] = getThisAndParentProperties(\n scopeElement,\n `[${getElbAttributeName(prefix, page)}]`,\n prefix,\n page,\n );\n data.domain = loc.hostname;\n data.title = doc.title;\n data.referrer = doc.referrer;\n\n if (loc.search) data.search = loc.search;\n if (loc.hash) data.hash = loc.hash;\n\n // @TODO get all nested entities\n return [data, context];\n}\n\nexport function getTriggerActions(str: string): Walker.TriggersActionGroups {\n const values: Walker.TriggersActionGroups = {};\n\n const attributes = splitAttribute(str);\n\n attributes.forEach((str) => {\n const [triggerAttr, actionAttr] = splitKeyVal(str);\n const [trigger, triggerParams] = parseAttribute(triggerAttr);\n\n if (!trigger) return;\n\n let [action, actionParams] = parseAttribute(actionAttr || '');\n\n // Shortcut if trigger and action are the same (click:click)\n action = action || trigger;\n\n if (!values[trigger]) values[trigger] = [];\n\n values[trigger].push({ trigger, triggerParams, action, actionParams });\n });\n\n return values;\n}\n\nexport function getEntities(\n prefix: string,\n target: Element,\n filter?: Walker.Filter,\n nearestOnly = false,\n): WalkerOS.Entities {\n const entities: WalkerOS.Entities = [];\n let element = target as Node['parentElement'];\n\n // Unset empty filter object\n filter = Object.keys(filter || {}).length !== 0 ? filter : undefined;\n\n while (element) {\n const entity = getEntity(prefix, element, target, filter);\n if (entity) {\n entities.push(entity);\n if (nearestOnly) break; // Stop after first entity for data-elbaction\n }\n\n element = getParent(prefix, element);\n }\n\n return entities;\n}\n\nfunction getEntity(\n prefix: string,\n element: Element,\n origin?: Element,\n filter?: Walker.Filter,\n): WalkerOS.Entity | null {\n const entity = getAttribute(element, getElbAttributeName(prefix));\n\n // It's not a (valid) entity element or should be filtered\n if (!entity || (filter && !filter[entity])) return null;\n\n const scopeElems = [element]; // All related elements\n const dataSelector = `[${getElbAttributeName(\n prefix,\n entity,\n )}],[${getElbAttributeName(prefix, '')}]`; // [data-elb-entity,data-elb-]\n const linkName = getElbAttributeName(prefix, Const.Commands.Link, false); // data-elblink\n\n let data: WalkerOS.Properties = {};\n const nested: WalkerOS.Entities = [];\n const [parentData, context] = getThisAndParentProperties(\n origin || element,\n dataSelector,\n prefix,\n entity,\n true, // collect scoped generic (data-elb_) for real entities\n );\n\n // Add linked elements (data-elblink)\n queryAllComposed(element, `[${linkName}]`, (link) => {\n const [linkId, linkState]: Walker.KeyVal = splitKeyVal(\n getAttribute(link, linkName),\n );\n\n // Get all linked child elements if link is a parent\n // Note: Searches entire document including shadow roots.\n // Acceptable because link-parent usage is rare in practice.\n if (linkState === 'parent')\n queryAllComposed(\n element.ownerDocument.body,\n `[${linkName}=\"${linkId}:child\"]`,\n (wormhole) => {\n scopeElems.push(wormhole);\n\n // A linked child can also be an entity\n const nestedEntity = getEntity(prefix, wormhole);\n if (nestedEntity) nested.push(nestedEntity);\n },\n );\n });\n\n // Get all property elements including linked elements\n const propertyElems: Array<Element> = [];\n scopeElems.forEach((elem) => {\n // Also check for property on same level\n if (elem.matches(dataSelector)) propertyElems.push(elem);\n\n queryAllComposed(elem, dataSelector, (elem) => propertyElems.push(elem));\n });\n\n // Get properties\n let genericData: WalkerOS.Properties = {};\n propertyElems.forEach((child) => {\n // Eventually override closer properties\n genericData = assign(genericData, getElbValues(prefix, child, ''));\n data = assign(data, getElbValues(prefix, child, entity));\n });\n\n // Merge properties with the hierarchy generic > data > parent\n data = assign(assign(genericData, data), parentData);\n\n // Get nested entities\n scopeElems.forEach((elem) => {\n queryAllComposed(\n elem,\n `[${getElbAttributeName(prefix)}]`,\n (nestedEntityElement) => {\n const nestedEntity = getEntity(prefix, nestedEntityElement);\n if (nestedEntity) nested.push(nestedEntity);\n },\n );\n });\n\n return { entity, data, context, nested };\n}\n\nfunction getParent(prefix: string, elem: HTMLElement): HTMLElement | null {\n const linkName = getElbAttributeName(prefix, Const.Commands.Link, false); // data-elblink\n\n // Link\n if (elem.matches(`[${linkName}]`)) {\n const [linkId, linkState]: Walker.KeyVal = splitKeyVal(\n getAttribute(elem, linkName),\n );\n if (linkState === 'child') {\n // Link-parent lookup does not cross shadow boundaries.\n // Uses simple queryAll (no shadow recursion) since this runs\n // during per-event entity traversal.\n const doc = elem.ownerDocument;\n let found: HTMLElement | null = null;\n queryAll(doc, `[${linkName}=\"${linkId}:parent\"]`, (el) => {\n if (!found) found = el as HTMLElement;\n });\n return found;\n }\n }\n\n // Shadow DOM traversal\n const win = elem.ownerDocument.defaultView!;\n if (\n !elem.parentElement &&\n elem.getRootNode &&\n elem.getRootNode() instanceof win.ShadowRoot\n ) {\n return (elem.getRootNode() as ShadowRoot).host as HTMLElement;\n }\n\n return elem.parentElement;\n}\n\nfunction getThisAndParentProperties(\n element: Element,\n entitySelector: string,\n prefix: string,\n type: string,\n collectScoped = false,\n): [data: WalkerOS.Properties, context: WalkerOS.OrderedProperties] {\n let data: WalkerOS.Properties = {};\n const context: WalkerOS.OrderedProperties = {};\n let parent = element as Node['parentElement'];\n const contextSelector = `[${getElbAttributeName(\n prefix,\n Const.Commands.Context,\n false,\n )}]`;\n const scopedName = Const.Commands.Scoped; // '_' -> data-elb_\n const scopedSelector = `[${getElbAttributeName(prefix, scopedName, false)}]`;\n\n // Get all bubbling-up properties with decreasing priority\n let contextI = 0; // Context counter\n while (parent) {\n // Scoped generic (data-elb_): same generic tier, bubble-up only.\n // The synthetic page entity ignores generics, so it skips scoped too.\n // Guard on scopedName so a falsy command constant degrades to \"no scoped\n // collection\" instead of an empty suffix that would match the bare prefix.\n if (collectScoped && scopedName && parent.matches(scopedSelector)) {\n data = assign(getElbValues(prefix, parent, scopedName, false), data);\n }\n\n // Properties\n if (parent.matches(entitySelector)) {\n // Get higher properties first\n data = assign(getElbValues(prefix, parent, ''), data); // Generic\n data = assign(getElbValues(prefix, parent, type), data); // Explicit\n }\n\n // Context\n if (parent.matches(contextSelector)) {\n Object.entries(\n getElbValues(prefix, parent, Const.Commands.Context, false),\n ).forEach(([key, val]) => {\n // Don't override context with same but higher key\n if (val && !context[key]) context[key] = [val, contextI];\n });\n\n // Increase context counter with each parent level\n ++contextI;\n }\n\n parent = getParent(prefix, parent);\n }\n\n return [data, context];\n}\n\nfunction queryAll(\n scope: Document | Element,\n selector: string,\n fn: (element: Element) => void,\n): void {\n scope.querySelectorAll(selector).forEach(fn);\n}\n\n// Shadow-aware version that recurses into open shadow roots.\n// Use for discovery (init) and entity-scoped queries (small subtrees).\n// Avoid for per-event document-scoped queries (e.g. getGlobals).\nexport function queryAllComposed(\n scope: Document | Element | ShadowRoot,\n selector: string,\n fn: (element: Element) => void,\n): void {\n scope.querySelectorAll(selector).forEach(fn);\n\n const doc = (scope as Element).ownerDocument || (scope as Document);\n const win = doc.defaultView!;\n if (scope instanceof win.Element && scope.shadowRoot) {\n queryAllComposed(scope.shadowRoot, selector, fn);\n }\n scope.querySelectorAll('*').forEach((el) => {\n if (el.shadowRoot) {\n queryAllComposed(el.shadowRoot, selector, fn);\n }\n });\n}\n\nfunction resolveAttributes(\n prefix: string,\n target: Element,\n trigger: string,\n): { actions: Walker.TriggerActions; nearestOnly: boolean } {\n let element = target as Node['parentElement'];\n\n while (element) {\n // Check for data-elbactions first (takes precedence)\n const multiAttribute = getAttribute(\n element,\n getElbAttributeName(prefix, Const.Commands.Actions, false),\n );\n\n if (multiAttribute) {\n const triggerActions = getTriggerActions(multiAttribute);\n if (triggerActions[trigger]) {\n return { actions: triggerActions[trigger], nearestOnly: false };\n }\n }\n\n // Check for data-elbaction (nearest entity only)\n const singleAttribute = getAttribute(\n element,\n getElbAttributeName(prefix, Const.Commands.Action, false),\n );\n\n if (singleAttribute) {\n const triggerActions = getTriggerActions(singleAttribute);\n // Action found on element or is not a click trigger\n if (triggerActions[trigger] || trigger !== 'click') {\n return { actions: triggerActions[trigger] || [], nearestOnly: true };\n }\n }\n\n element = getParent(prefix, element);\n }\n\n return { actions: [], nearestOnly: false };\n}\n\nfunction splitAttribute(str: string, separator = ';'): Walker.Attributes {\n const values: Walker.Attributes = [];\n\n if (!str) return values;\n\n const reg = new RegExp(`(?:[^${separator}']+|'[^']*')+`, 'ig');\n return str.match(reg) || [];\n}\n\nfunction splitKeyVal(str: string): Walker.KeyVal {\n const [key, value] = str.split(/:(.+)/, 2);\n return [trim(key), trim(value)];\n}\n\nfunction parseAttribute(str: string): Walker.KeyVal {\n // action(a, b, c)\n const [key, value] = str.split('(', 2);\n const param = value ? value.slice(0, -1) : ''; // Remove the )\n // key = 'action'\n // param = 'a, b, c'\n return [key, param];\n}\n","import type { Context, InitScope } from './types';\nimport { tryCatch } from '@walkeros/core';\nimport { isVisible } from '@walkeros/web-core';\nimport { handleTrigger, Triggers } from './trigger';\n\n// Fraction of the element, or of the viewport, whichever is smaller, that must\n// be on screen along each axis.\nconst COVERAGE = 0.5;\n\n/**\n * Decide from the observer entry alone whether an element is showing enough of\n * itself to start the dwell clock. Reads no DOM and forces no layout: every\n * rect here was computed by the browser during this frame's layout pass.\n *\n * `intersectionRatio` cannot be used directly. It is a fraction of the\n * element's own area, so an element bigger than the viewport along an axis can\n * never show COVERAGE of itself along it: a 716px card in a 450px viewport\n * tops out at 0.63, and an 8000px section tops out at 0.1. Clamping the\n * requirement to `min(element, viewport)` per axis makes the bar reachable for\n * any geometry, and gives the property customers actually expect: shrinking the\n * viewport can only make the trigger fire earlier, never later.\n *\n * The clamp is per axis rather than by area on purpose. An area clamp collapses\n * back to the element-relative rule whenever the element's area is smaller than\n * the viewport's, which is exactly the wide-but-short case (a 3000x80 row tops\n * out at ratio 0.48 and never fires).\n */\nexport function isEligible(\n entry: IntersectionObserverEntry,\n win: Window,\n): boolean {\n if (!entry.isIntersecting) return false;\n\n const box = entry.boundingClientRect;\n // A zero-area target reports intersectionRatio 1 while it is intersecting\n // (spec 2.2.12). It has nothing on screen; never start a dwell for it.\n if (box.width <= 0 || box.height <= 0) return false;\n\n // rootBounds is null when the target lives in a cross-origin iframe. Falling\n // back to the window keeps the arithmetic finite: a NaN would compare false\n // and silently disable the trigger for every such element.\n const rootWidth = entry.rootBounds ? entry.rootBounds.width : win.innerWidth;\n const rootHeight = entry.rootBounds\n ? entry.rootBounds.height\n : win.innerHeight;\n if (rootWidth <= 0 || rootHeight <= 0) return false;\n\n const visible = entry.intersectionRect;\n const needWidth = COVERAGE * Math.min(box.width, rootWidth);\n const needHeight = COVERAGE * Math.min(box.height, rootHeight);\n\n return visible.width >= needWidth && visible.height >= needHeight;\n}\n\n// Threshold grid for the observer.\n//\n// An entry is queued only when the crossed threshold INDEX changes; a bare ratio\n// change queues nothing. The grid is therefore not a performance dial, it is the\n// SAMPLING RATE of the predicate: the trigger can only notice an element became\n// eligible at a grid crossing, which quantizes the arm point UPWARD to the next\n// threshold.\n//\n// A coarse grid makes that error large. Eligibility for an element of height H in\n// a viewport of height V lands at ratio COVERAGE * V/H, which for a 716px card in\n// a 450px viewport is 0.314. A grid whose next step above that is 0.4 would not\n// arm until 287px was showing, against a true bar of 225px.\n//\n// A uniform 1% grid keeps the error within about 1% of the element and costs\n// effectively nothing: the observer queues at most ONE entry per target per frame\n// however many thresholds there are.\nconst THRESHOLDS = Array.from({ length: 101 }, (_, index) => index / 100);\n\ninterface ElementConfig {\n multiple: boolean;\n blocked: boolean;\n context: Context;\n trigger: string;\n}\n\ninterface VisibilityState {\n observer?: IntersectionObserver;\n resizeObserver?: ResizeObserver;\n timers: WeakMap<HTMLElement, number>;\n duration: number;\n configs: WeakMap<HTMLElement, ElementConfig[]>;\n // Elements last seen without a layout box. A 0x0 target reports ratio 1, so\n // growing one into view never changes the threshold index and the observer\n // stays silent; the ResizeObserver re-observes to force a fresh entry.\n zeroArea: WeakSet<HTMLElement>;\n}\n\n// Module-level visibility state keyed by the owner document. Both an element\n// sub-scope and its document normalize to the same key (see getScopeKey), so\n// there is exactly one IntersectionObserver per document: create-key and\n// lookup-key can never diverge, and iframes still get their own observer.\nconst visibilityStates = new WeakMap<Document | Element, VisibilityState>();\n\n/**\n * Normalize any scope (document or element) to its owner document. The\n * IntersectionObserver root is always the viewport, so per-sub-scope observers\n * would be meaningless; keying by ownerDocument gives one shared observer per\n * document and keeps the create/lookup keys aligned.\n */\nexport function getScopeKey(scope: InitScope): Document | Element {\n return (scope as Element).ownerDocument || (scope as Document);\n}\n\nfunction createObserver(\n scope: Document | Element,\n): IntersectionObserver | undefined {\n const doc = (scope as Element).ownerDocument || (scope as Document);\n const win = doc.defaultView;\n if (!win || !win.IntersectionObserver) return undefined;\n\n return tryCatch(\n () =>\n new win.IntersectionObserver(\n (entries) => {\n entries.forEach((entry) => handleIntersection(scope, entry));\n },\n { rootMargin: '0px', threshold: THRESHOLDS },\n ),\n () => undefined,\n )();\n}\n\nfunction handleIntersection(\n scope: Document | Element,\n entry: IntersectionObserverEntry,\n): void {\n const target = entry.target as HTMLElement;\n const state = visibilityStates.get(getScopeKey(scope));\n if (!state) return;\n\n const win = target.ownerDocument.defaultView;\n if (!win) return;\n\n const configs = state.configs.get(target);\n // An entry can be queued before an unobserve lands. Never arm a dwell for an\n // element the module has already released.\n if (!configs || !configs.length) return;\n\n const existingTimer = state.timers.get(target);\n\n if (isEligible(entry, win)) {\n // Every trigger on this element has fired and is waiting to re-enter.\n if (configs.every((config) => config.blocked)) return;\n\n if (!existingTimer) {\n const timer = win.setTimeout(() => {\n fire(getScopeKey(scope), target);\n }, state.duration);\n state.timers.set(target, timer);\n }\n return;\n }\n\n // Below the bar: cancel the armed dwell and re-arm the repeating triggers.\n if (existingTimer) {\n clearTimeout(existingTimer);\n state.timers.delete(target);\n }\n configs.forEach((config) => {\n if (config.multiple) config.blocked = false;\n });\n}\n\nasync function fire(\n scope: Document | Element,\n target: HTMLElement,\n): Promise<void> {\n const state = visibilityStates.get(scope);\n if (!state) return;\n\n // Release the timer on EVERY path, before anything can bail. Leaving a fired\n // timer id behind makes `!existingTimer` false forever, which permanently\n // prevents the element from arming again: it is dead for the page session.\n state.timers.delete(target);\n\n const doc = target.ownerDocument;\n const win = doc.defaultView;\n if (!win) return;\n\n // Never count an impression the user could not possibly have seen. Re-arm\n // rather than drop: a page opened in a background tab has every above-the-fold\n // element already eligible, and its geometry will never change again, so the\n // observer would queue no further entry and the impression would be lost for\n // the whole session even after the user foregrounds the tab and reads the\n // page. Background timers are throttled to roughly one per second, so the\n // retry is cheap, and it stops as soon as the tab is visible.\n if (doc.visibilityState !== 'visible') {\n state.timers.set(\n target,\n win.setTimeout(() => {\n fire(scope, target);\n }, state.duration),\n );\n return;\n }\n\n // The one and only occlusion check, uncached, on one element.\n if (!isVisible(target, win, doc)) return;\n\n const configs = state.configs.get(target);\n if (!configs) return;\n\n const pending = configs.filter((config) => !config.blocked);\n if (!pending.length) return;\n\n // Commit state BEFORE awaiting. handleTrigger can outlast the dwell on a slow\n // destination, and a late write would clobber state that the not-eligible\n // branch has since reset, swallowing the element's next event.\n pending.forEach((config) => {\n if (config.multiple) config.blocked = true;\n });\n\n const remaining = configs.filter((config) => config.multiple);\n if (remaining.length) {\n state.configs.set(target, remaining);\n } else {\n // Single-shot impressions are done. Unobserve before the await so a second\n // dwell cannot arm and double-fire while the destination is in flight.\n unobserveElement(scope, target);\n }\n\n await Promise.all(\n pending.map((config) =>\n handleTrigger(config.context, target, config.trigger),\n ),\n );\n}\n\nexport function unobserveElement(scope: InitScope, element: HTMLElement): void {\n const state = visibilityStates.get(getScopeKey(scope));\n if (!state) return;\n\n state.observer?.unobserve(element);\n state.resizeObserver?.unobserve(element);\n state.configs.delete(element);\n state.zeroArea.delete(element);\n\n const timer = state.timers.get(element);\n if (timer) {\n clearTimeout(timer);\n state.timers.delete(element);\n }\n}\n\n/**\n * Rescue the one case an IntersectionObserver cannot report.\n *\n * A zero-area target reports intersectionRatio 1 while it intersects (spec\n * 2.2.12). When a framework mounts an element empty and renders it a frame\n * later, the ratio goes 1 -> 1, the threshold index never changes, and the\n * observer queues NO entry - at any threshold density. Re-observing resets the\n * observer's per-target bookkeeping (previousThresholdIndex back to -1), which\n * forces a fresh entry on the next frame.\n *\n * Gated on the zero -> laid-out transition, so a resizing animation cannot turn\n * this into a per-frame re-observe storm.\n */\nfunction createResizeObserver(\n scope: Document | Element,\n): ResizeObserver | undefined {\n const doc = (scope as Element).ownerDocument || (scope as Document);\n const win = doc.defaultView;\n if (!win || !win.ResizeObserver) return undefined;\n\n return tryCatch(\n () =>\n new win.ResizeObserver((entries) => {\n const state = visibilityStates.get(scope);\n if (!state?.observer) return;\n\n entries.forEach((entry) => {\n const target = entry.target as HTMLElement;\n const { width, height } = entry.contentRect;\n const isZero = width <= 0 || height <= 0;\n\n if (isZero) {\n state.zeroArea.add(target);\n return;\n }\n\n if (!state.zeroArea.has(target)) return;\n state.zeroArea.delete(target);\n\n state.observer?.unobserve(target);\n state.observer?.observe(target);\n });\n }),\n () => undefined,\n )();\n}\n\nexport function initVisibilityTracking(\n scope: InitScope,\n duration = 1000,\n): void {\n const key = getScopeKey(scope);\n if (visibilityStates.has(key)) return;\n\n visibilityStates.set(key, {\n observer: createObserver(key),\n resizeObserver: createResizeObserver(key),\n timers: new WeakMap(),\n duration,\n configs: new WeakMap(),\n zeroArea: new WeakSet(),\n });\n}\n\nexport function triggerVisible(\n context: Context,\n element: HTMLElement,\n config: { multiple?: boolean } = { multiple: false },\n): void {\n const scope = context.settings.scope;\n if (!scope) return;\n const state = visibilityStates.get(getScopeKey(scope));\n if (!state?.observer || !element) return;\n\n const multiple = config.multiple ?? false;\n const configs = state.configs.get(element) ?? [];\n configs.push({\n multiple,\n blocked: false,\n context,\n trigger: multiple ? Triggers.Visible : Triggers.Impression,\n });\n state.configs.set(element, configs);\n\n // One element can carry both `impression` and `visible`; observe it once.\n if (configs.length > 1) return;\n\n const box = element.getBoundingClientRect();\n if (box.width <= 0 || box.height <= 0) state.zeroArea.add(element);\n\n state.observer.observe(element);\n state.resizeObserver?.observe(element);\n}\n\nexport function destroyVisibilityTracking(scope?: InitScope): void {\n if (!scope) return;\n const key = getScopeKey(scope);\n const state = visibilityStates.get(key);\n if (!state) return;\n\n state.observer?.disconnect();\n state.resizeObserver?.disconnect();\n visibilityStates.delete(key);\n}\n","import type { WalkerOS, Elb, Collector } from '@walkeros/core';\nimport { isString, isObject, isElementOrDocument } from '@walkeros/core';\nimport { createPushResult } from '@walkeros/collector';\nimport type {\n BrowserPushData,\n BrowserPushOptions,\n BrowserPushContext,\n} from './types/elb';\nimport type { Context, Settings, InitScope, Scope } from './types';\nimport { getEntities, getGlobals } from './walker';\n\n/**\n * Translation layer that converts flexible browser source inputs\n * to the strict core collector format\n */\nexport function translateToCoreCollector(\n context: Context,\n eventOrCommand: unknown,\n data?: BrowserPushData,\n options?: BrowserPushOptions,\n pushContext?: BrowserPushContext,\n nested?: WalkerOS.Entities,\n custom?: WalkerOS.Properties,\n): Promise<Elb.PushResult> {\n const { elb, settings } = context;\n\n // Handle walker commands. `walker init` is browser-only (re-scans a DOM\n // scope for `data-elb*` tags and fires load triggers) and is dispatched\n // here because the collector must stay DOM-free. All other walker\n // commands route through elb to commonHandleCommand on the collector.\n // `initScope` arrives on `context` from the source factory to avoid a\n // static import of `./trigger` (which would form a load-time cycle).\n if (isString(eventOrCommand) && eventOrCommand.startsWith('walker ')) {\n if (eventOrCommand === 'walker init' && context.initScope) {\n const scopes = normalizeInitScopes(data, settings);\n for (const scope of scopes) {\n // Scope is a single carrier: build a scope-aligned context so the\n // trigger pipeline reads the new scope from context.settings.scope\n // everywhere (no diverging positional scope param).\n context.initScope({ ...context, settings: { ...settings, scope } });\n }\n return Promise.resolve(createPushResult({ ok: true }));\n }\n return elb(eventOrCommand, data as WalkerOS.Properties);\n }\n\n // Handle event objects - add source and globals if missing\n if (isObject(eventOrCommand)) {\n const event = eventOrCommand;\n if (!event.source && settings.scope) {\n const scopeDoc = ((settings.scope as Element).ownerDocument ||\n settings.scope) as Document;\n const scopeWin = scopeDoc.defaultView!;\n event.source = getBrowserSource(scopeWin, scopeDoc);\n }\n\n // Add globals if not already present\n if (!event.globals && settings.scope) {\n event.globals = isGlobalsScope(settings.scope)\n ? getGlobals(settings.prefix, settings.scope)\n : {};\n }\n\n return elb(event);\n }\n\n // Extract entity name from event string\n const [entity] = String(\n isObject(eventOrCommand) ? eventOrCommand.name : eventOrCommand,\n ).split(' ');\n\n // Get data and context either from elements or parameters\n let eventData = isObject(data) ? (data as WalkerOS.Properties) : {};\n let eventContext: WalkerOS.OrderedProperties = {};\n\n let elemParameter: undefined | Element;\n let dataIsElem = false;\n\n // Check if data parameter is an element\n if (isElementOrDocument(data)) {\n elemParameter = data as Element;\n dataIsElem = true;\n }\n\n // Check if contextData parameter is an element\n if (isElementOrDocument(pushContext)) {\n elemParameter = pushContext as Element;\n } else if (isObject(pushContext) && Object.keys(pushContext).length) {\n eventContext = pushContext as WalkerOS.OrderedProperties;\n }\n\n // Extract data from element if provided\n if (elemParameter) {\n const entityObj = getEntities(\n settings.prefix || 'data-elb',\n elemParameter,\n ).find((obj) => obj.entity === entity);\n if (entityObj) {\n if (dataIsElem) eventData = entityObj.data;\n if (entityObj.context) eventContext = entityObj.context;\n }\n }\n\n // Derive win/doc from scope for browser-specific APIs\n const scopeDoc = settings.scope\n ? (((settings.scope as Element).ownerDocument ||\n settings.scope) as Document)\n : undefined;\n const scopeWin = scopeDoc?.defaultView;\n\n // Special handling for page events\n if (entity === 'page' && scopeWin) {\n eventData.id = eventData.id || scopeWin.location.pathname;\n }\n\n // Collect globals from the DOM scope\n const eventGlobals =\n settings.scope && isGlobalsScope(settings.scope)\n ? getGlobals(settings.prefix, settings.scope)\n : {};\n\n // Build unified event from various elb usage patterns\n const event: WalkerOS.DeepPartialEvent = {\n name: String(eventOrCommand || ''),\n data: eventData,\n context: eventContext,\n globals: eventGlobals,\n nested,\n custom,\n trigger: isString(options) ? options : '',\n source:\n scopeWin && scopeDoc ? getBrowserSource(scopeWin, scopeDoc) : undefined,\n };\n\n return elb(event);\n}\n\n/**\n * Create source information for browser events\n */\nfunction getBrowserSource(win: Window, doc: Document): WalkerOS.Source {\n return {\n type: 'browser',\n platform: 'web',\n url: win.location.href,\n referrer: doc.referrer,\n };\n}\n\n/**\n * Local type guard: narrows `unknown` to `Element | Document`. Prefers the\n * native `instanceof` check (works in browsers and JSDOM) and falls back to\n * the WhatWG DOM `nodeType` property for realms where the global Element or\n * Document constructors are not in scope (cross-frame, certain test\n * runners). Returns an accurate `Element | Document` union so callers do\n * not need casts.\n */\nfunction isDomScope(value: unknown): value is InitScope {\n if (!value || typeof value !== 'object') return false;\n if (typeof Element !== 'undefined' && value instanceof Element) return true;\n if (typeof Document !== 'undefined' && value instanceof Document) return true;\n if (typeof ShadowRoot !== 'undefined' && value instanceof ShadowRoot)\n return true;\n if ('nodeType' in value) {\n const nodeType = value.nodeType;\n // 1 = ELEMENT_NODE, 9 = DOCUMENT_NODE, 11 = DOCUMENT_FRAGMENT_NODE (the\n // node type of a ShadowRoot) per the WhatWG DOM standard. Accepting 11\n // lets `walker init` target a retained closed shadow root, which discovery\n // can never reach from the document.\n return nodeType === 1 || nodeType === 9 || nodeType === 11;\n }\n return false;\n}\n\n/**\n * getGlobals accepts the narrow Scope (Document | Element). Scope is kept narrow\n * deliberately: widening it to ShadowRoot would ripple into its sibling scans\n * getPageViewData/getAllEvents, whose bodies call .matches/.body/getAttribute\n * and throw on a ShadowRoot. So a ShadowRoot init scope contributes no globals\n * ({}) by design; this guard narrows the widened carrier back to what getGlobals\n * accepts.\n */\nfunction isGlobalsScope(scope: InitScope): scope is Scope {\n return scope.nodeType !== 11; // exclude ShadowRoot (DOCUMENT_FRAGMENT_NODE)\n}\n\n/**\n * Normalize the `data` argument of `elb('walker init', data)` to an array\n * of Element/Document/ShadowRoot scopes. Falls back to `settings.scope` (or\n * `document` if settings.scope is not a DOM node) when no scope is provided.\n */\nfunction normalizeInitScopes(\n data: unknown,\n settings: Settings,\n): Array<InitScope> {\n if (isDomScope(data)) return [data];\n if (Array.isArray(data)) {\n const filtered: Array<InitScope> = [];\n for (const entry of data) {\n if (isDomScope(entry)) filtered.push(entry);\n }\n return filtered;\n }\n if (typeof data === 'undefined') {\n const fallback = settings.scope;\n if (isDomScope(fallback)) return [fallback];\n if (typeof globalThis.document !== 'undefined') {\n return [globalThis.document];\n }\n }\n return [];\n}\n","import type { Elb, Logger } from '@walkeros/core';\nimport { isString, isObject } from '@walkeros/core';\nimport { createPushResult } from '@walkeros/collector';\nimport type { Context } from './types';\nimport { translateToCoreCollector } from './translation';\n\n/**\n * Controller for the append-only `window.elbLayer` command queue.\n *\n * The layer is never spliced, truncated, or cleared: every pushed entry is\n * appended raw so inspection reflects the page's full input history. Two lanes\n * run over it. `walker *` commands process immediately from controller creation,\n * serialized on a pre-start command chain. Non-command events are recorded but\n * held until `start()`, then replayed from a cursor in original push order. The\n * command chain seeds the post-start chain, so the last pre-start command\n * strictly precedes the first replayed event.\n *\n * A drained boundary is persisted on the array (see DRAIN_MARKER) so a\n * controller adopting an already-populated array (destroy/recreate on the same\n * window) resumes PAST what a prior controller dispatched instead of replaying\n * the whole backlog and double-firing every command and event.\n */\nexport interface ElbLayerController {\n /** Append an entry to the layer and route it. Returns the processing result. */\n intake(entry: unknown[]): Promise<Elb.PushResult>;\n /** Begin consuming recorded events. Idempotent: a second call is a no-op. */\n start(): void;\n /**\n * Append arbitrary work to the FIFO chain, after everything queued so far.\n * `fn` must not await the controller's own chain: calling `enqueue`/`intake`\n * from inside a chain item and awaiting the result deadlocks (it waits on a\n * promise scheduled behind itself). Pushing new entries mid-dispatch is safe\n * — that appends a link, it does not await one.\n */\n enqueue<T>(fn: () => Promise<T> | T): Promise<T>;\n /** Restore the array's native push and forget internal state. */\n destroy(): void;\n}\n\n/**\n * Drained-boundary marker persisted on the layer array. Stored under a\n * non-enumerable Symbol so it never appears in inspection, iteration, or JSON:\n * the array stays append-only and reflects the page's full input history, yet a\n * later controller can read where the lanes already drained. `Symbol.for` keeps\n * the key stable across module instances, matching the window single-instance\n * sentinel convention.\n */\nconst DRAIN_MARKER = Symbol.for(\n '@walkeros/web-source-browser:elbLayer-drained',\n);\n\ninterface DrainMarker {\n // Leading entries whose command lane has drained: every `walker *` command at\n // a lower index has already been routed.\n commands: number;\n // Leading entries whose event lane has drained: every non-command event at a\n // lower index has already been replayed.\n events: number;\n}\n\nconst isDrainMarker = (value: unknown): value is DrainMarker =>\n isObject(value) &&\n typeof value.commands === 'number' &&\n typeof value.events === 'number';\n\n// Return the array's existing marker (the same object, so this controller's\n// writes persist on the array) or install a fresh zeroed one. Non-enumerable +\n// configurable so it stays invisible to inspection yet re-readable later.\nconst readOrCreateDrainMarker = (arr: unknown[]): DrainMarker => {\n const existing: unknown = Reflect.get(arr, DRAIN_MARKER);\n if (isDrainMarker(existing)) return existing;\n const fresh: DrainMarker = { commands: 0, events: 0 };\n Object.defineProperty(arr, DRAIN_MARKER, {\n value: fresh,\n writable: true,\n enumerable: false,\n configurable: true,\n });\n return fresh;\n};\n\nexport function createElbLayer(\n context: Context,\n config: { name?: string; window?: Window; logger?: Logger.Instance } = {},\n): ElbLayerController {\n const layerName = config.name || 'elbLayer';\n const windowObj = config.window;\n const logger = config.logger;\n\n const ok = (): Elb.PushResult => createPushResult({ ok: true });\n\n // Window-less environments (SSR/node) cannot host a layer. Return an inert\n // controller so callers never branch on undefined.\n if (!windowObj) {\n return {\n intake: () => Promise.resolve(ok()),\n start: () => {},\n enqueue: <T>(fn: () => Promise<T> | T) =>\n Promise.resolve().then(() => fn()),\n destroy: () => {},\n };\n }\n\n // Ensure the named array exists without ever replacing an existing one.\n const existing = Reflect.get(windowObj, layerName);\n let layer: unknown[];\n if (Array.isArray(existing)) {\n layer = existing;\n } else {\n layer = [];\n Reflect.set(windowObj, layerName, layer);\n }\n\n // Adopt any drained boundary a prior controller left on this array. A fresh\n // array reads {0, 0}, reproducing the original replay-the-whole-backlog-once\n // behavior; a recreated one resumes past what already ran.\n const drain = readOrCreateDrainMarker(layer);\n let started = false;\n let commandCursor = drain.commands;\n let eventCursor = drain.events;\n let cmdTail: Promise<Elb.PushResult> = Promise.resolve(ok());\n let tail: Promise<unknown> = Promise.resolve();\n\n // Mirror the live cursors onto the array-backed marker so the next controller\n // adopting this array (destroy/recreate) resumes from the current boundary.\n const persistDrain = (): void => {\n drain.commands = commandCursor;\n drain.events = eventCursor;\n };\n\n const route = (item: unknown): Promise<Elb.PushResult> => {\n if (Array.isArray(item)) {\n const [eventOrCommand, ...rest] = item;\n return translateToCoreCollector(context, eventOrCommand, ...rest);\n }\n return translateToCoreCollector(context, item);\n };\n\n // One bad entry must not break the chain: isolate each route so a throw\n // resolves ok:false and the FIFO continues.\n const routeSafe = async (item: unknown[]): Promise<Elb.PushResult> => {\n try {\n return await route(item);\n } catch (error) {\n logger?.warn('elbLayer entry failed', { error, item });\n return createPushResult({ ok: false });\n }\n };\n\n const isCommandEntry = (item: unknown[]): boolean => {\n const first = item[0];\n return isString(first) && first.startsWith('walker ');\n };\n\n const process = (item: unknown[], index: number): Promise<Elb.PushResult> => {\n if (!started) {\n if (isCommandEntry(item)) {\n // A prior controller on this array already routed commands below the\n // marker boundary — never route them a second time.\n if (index < commandCursor) return Promise.resolve(ok());\n const link = cmdTail.then(() => routeSafe(item));\n cmdTail = link;\n commandCursor = index + 1;\n persistDrain();\n return link;\n }\n // Pre-start event: recorded in the layer, replayed on start().\n return Promise.resolve(ok());\n }\n // Post-start every entry serializes on the shared tail and drains both\n // lanes. A later start() is barred by the started flag, so these are never\n // replayed.\n const link = tail.then(() => routeSafe(item));\n tail = link;\n commandCursor = index + 1;\n eventCursor = index + 1;\n persistDrain();\n return link;\n };\n\n const appendAndProcess = (raw: unknown): Promise<Elb.PushResult> => {\n const normalized = normalizeItem(raw);\n // Append the raw arg so inspection shows exactly what the page pushed.\n // Index-assign, not layer.push(raw): push here is our own wrappedPush\n // override, so calling it would recurse into this function.\n const index = layer.length;\n layer[index] = raw;\n if (!normalized) return Promise.resolve(ok());\n return process(normalized, index);\n };\n\n // Live capture: normalize, append raw, route. Returns the array's new length\n // to honor the Array.push contract.\n const wrappedPush = (...args: unknown[]): number => {\n for (const arg of args) appendAndProcess(arg);\n return layer.length;\n };\n layer.push = wrappedPush;\n\n // Backlog present at creation flows through the same lanes without being\n // re-appended: commands run now via the command chain, events wait for start.\n const backlogLength = layer.length;\n for (let i = 0; i < backlogLength; i++) {\n const normalized = normalizeItem(layer[i]);\n if (normalized) process(normalized, i);\n }\n\n const intake = (entry: unknown[]): Promise<Elb.PushResult> =>\n appendAndProcess(entry);\n\n const start = (): void => {\n // Runs at most once (started flag). A second call must not re-seed tail\n // from cmdTail — that would rewind the chain past work enqueued after\n // start and orphan it. The cursor only marks the pre-start backlog boundary.\n if (started) return;\n started = true;\n // Seed the post-start chain from the command chain so the last pre-start\n // command strictly precedes the first replayed event.\n tail = cmdTail;\n for (let i = eventCursor; i < layer.length; i++) {\n const normalized = normalizeItem(layer[i]);\n if (!normalized) continue;\n if (isCommandEntry(normalized)) continue; // already ran pre-start\n const item = normalized;\n tail = tail.then(() => routeSafe(item));\n }\n // Both lanes are now drained up to the current length: every pre-start\n // command ran on intake and every recorded event has been scheduled. Record\n // the boundary so a later controller adopting this array resumes past it.\n eventCursor = layer.length;\n commandCursor = layer.length;\n persistDrain();\n };\n\n const enqueue = <T>(fn: () => Promise<T> | T): Promise<T> => {\n const link = tail.then(() => fn());\n // A rejected enqueue must not wedge the shared chain: advance tail through a\n // swallow so later enqueues and post-start events still run. The returned\n // link stays rejectable so awaiting callers still observe the rejection.\n tail = link.then(\n () => undefined,\n () => undefined,\n );\n return link;\n };\n\n const destroy = (): void => {\n // Drop the own-property override so pushes fall back to Array.prototype.push.\n Reflect.deleteProperty(layer, 'push');\n started = false;\n commandCursor = 0;\n eventCursor = 0;\n cmdTail = Promise.resolve(ok());\n tail = Promise.resolve();\n // The array's drained marker is intentionally KEPT: it is the append-only\n // array's memory of what already ran, so a recreate resumes past it.\n };\n\n return { intake, start, enqueue, destroy };\n}\n\n/**\n * Normalize a queue item into an Array (or null if invalid/empty).\n */\nfunction normalizeItem(pushedItem: unknown): unknown[] | null {\n const item = isArguments(pushedItem)\n ? [...Array.from(pushedItem)]\n : isArrayLike(pushedItem)\n ? Array.from(pushedItem as ArrayLike<unknown>)\n : [pushedItem];\n if (!Array.isArray(item) || item.length === 0) return null;\n if (item.length === 1 && !item[0]) return null;\n const firstParam = item[0];\n if (isObject(firstParam) && Object.keys(firstParam as object).length === 0) {\n return null;\n }\n if (\n !isObject(firstParam) &&\n isString(firstParam) &&\n firstParam.trim() === ''\n ) {\n return null;\n }\n return item;\n}\n\n/**\n * Check if value is arguments object\n */\nfunction isArguments(value: unknown): value is IArguments {\n return (\n value != null &&\n typeof value === 'object' &&\n Object.prototype.toString.call(value) === '[object Arguments]'\n );\n}\n\n/**\n * Check if value is array-like (has length property)\n */\nfunction isArrayLike(value: unknown): boolean {\n return (\n value != null &&\n typeof value === 'object' &&\n 'length' in value &&\n typeof (value as unknown[]).length === 'number'\n );\n}\n","import type { InitSettings, Settings } from './types';\n\n/**\n * Get browser source configuration with defaults\n * @param initSettings - Initial settings to override defaults\n * @param envDocument - Document from environment (optional)\n * @returns Complete settings object with all defaults applied\n */\nexport function getConfig(\n initSettings: InitSettings = {},\n envDocument?: Document,\n): Settings {\n return {\n prefix: 'data-elb',\n pageview: true,\n capture: true,\n elb: 'elb',\n elbLayer: 'elbLayer',\n scope: envDocument || undefined,\n ...initSettings,\n };\n}\n","import type { Source, Elb } from '@walkeros/core';\nimport type { Walker } from '@walkeros/web-core';\nimport type { SettingsSchema } from '../schemas';\nimport type { z } from '@walkeros/core/dev';\n\n// Export browser-specific elb types\nexport * from './elb';\nimport type { BrowserPush } from './elb';\n\ndeclare module '@walkeros/core' {\n interface SourceMap {\n browser: {\n type: 'browser';\n platform: 'web';\n url?: string;\n referrer?: string;\n };\n }\n}\n\n// Base settings from Zod schema\ntype BaseSettings = z.infer<typeof SettingsSchema>;\n\n// InitSettings: what users provide (all optional)\n// Override specific fields with non-serializable types\nexport interface InitSettings extends Partial<\n Omit<BaseSettings, 'scope' | 'elbLayer'>\n> {\n scope?: InitScope;\n elbLayer?: boolean | string | Elb.Layer;\n}\n\n// Settings: resolved configuration\n// Override specific fields with non-serializable types\nexport interface Settings extends Omit<BaseSettings, 'scope' | 'elbLayer'> {\n scope?: InitScope;\n elbLayer: boolean | string | Elb.Layer;\n}\n\nexport interface Mapping {}\n\nexport type Push = BrowserPush;\n\nexport interface Env extends Source.BaseEnv {\n elb: Elb.Fn;\n window?: Window & typeof globalThis;\n document?: Document;\n}\n\nexport type Types = Source.Types<Settings, Mapping, Push, Env, InitSettings>;\n\nexport type Config = Source.Config<Types>;\n\nexport interface Context {\n elb: Elb.Fn;\n settings: Settings;\n // Scope travels in context.settings.scope; the implementation reads it from\n // there. Called with a single, scope-aligned context for `walker init`.\n initScope?: (context: Context) => void;\n}\n\n// Scope types live in the leaf `./scope` module so `types/elb.ts` can reuse\n// them without a circular import. Imported for local use (Settings.scope below)\n// and re-exported so `SourceBrowser.Scope` / `.InitScope` stay part of the\n// public surface.\nexport type { Scope, InitScope } from './scope';\nimport type { InitScope } from './scope';\n\n// Everything a single scope's init installs, bucketed so a re-init can tear the\n// scope's prior state down before attaching fresh. Keyed by the scope node, so\n// `walker run` (document) and `walker init <el>` (element) own independent\n// buckets that never reach into each other.\nexport interface ScopeState {\n abort: AbortController; // this scope's scroll listener (hover is per-element)\n intervalIds: ReturnType<typeof setInterval>[]; // pulse\n timeoutIds: ReturnType<typeof setTimeout>[]; // wait\n scrollElements: Walker.ScrollElements; // this scope's scroll targets\n scrollListener?: EventListenerOrEventListenerObject;\n observed: Set<HTMLElement>; // elements registered on the shared per-doc observer\n registered: Set<HTMLElement>; // every element this scope has wired triggers for\n mutationObservers: MutationObserver[]; // this scope's observe-container observers\n}\n","import type { WalkerOS } from '@walkeros/core';\nimport { isString, isDefined } from '@walkeros/core';\n\nexport interface TaggerConfig {\n prefix?: string;\n}\n\nexport interface TaggerInstance {\n entity: (name: string) => TaggerInstance;\n data: ((key: string, value: WalkerOS.Property) => TaggerInstance) &\n ((data: WalkerOS.Properties) => TaggerInstance);\n scoped: ((key: string, value: WalkerOS.Property) => TaggerInstance) &\n ((scoped: WalkerOS.Properties) => TaggerInstance);\n action: ((trigger: string, action?: string) => TaggerInstance) &\n ((actions: Record<string, string>) => TaggerInstance);\n actions: ((trigger: string, action?: string) => TaggerInstance) &\n ((actions: Record<string, string>) => TaggerInstance);\n context: ((key: string, value: WalkerOS.Property) => TaggerInstance) &\n ((context: WalkerOS.Properties) => TaggerInstance);\n globals: ((key: string, value: WalkerOS.Property) => TaggerInstance) &\n ((globals: WalkerOS.Properties) => TaggerInstance);\n link: ((id: string, type: string) => TaggerInstance) &\n ((links: Record<string, string>) => TaggerInstance);\n get: () => Record<string, string>;\n}\n\n/**\n * Creates a new tagger instance for generating walkerOS data attributes.\n *\n * @param config The configuration for the tagger.\n * @returns A new tagger instance.\n */\nexport function createTagger(\n config: TaggerConfig = {},\n): (entity?: string) => TaggerInstance {\n const prefix = config.prefix || 'data-elb';\n\n return function (entity?: string): TaggerInstance {\n // Internal state\n let currentEntity: string | undefined = undefined; // Only set via .entity() method\n let namingEntity: string | undefined = entity; // Used for data attribute naming\n const dataProperties: Record<string, WalkerOS.Properties> = {};\n const scopedProperties: WalkerOS.Properties = {};\n const actionProperties: Record<string, string> = {};\n const actionsProperties: Record<string, string> = {};\n const contextProperties: WalkerOS.Properties = {};\n const globalProperties: WalkerOS.Properties = {};\n const linkProperties: Record<string, string> = {};\n\n // Helper function to escape special characters\n function escapeValue(value: WalkerOS.Property | undefined): string {\n if (!isDefined(value) || value === null) return 'undefined';\n\n let str = String(value);\n\n // Escape backslashes first, then other characters\n str = str.replace(/\\\\/g, '\\\\\\\\');\n str = str.replace(/;/g, '\\\\;');\n str = str.replace(/:/g, '\\\\:');\n str = str.replace(/'/g, \"\\\\'\");\n\n return str;\n }\n\n // Helper function to serialize key-value pairs\n function serializeKeyValue(obj: WalkerOS.Properties): string {\n return Object.entries(obj)\n .map(([key, value]) => `${key}:${escapeValue(value)}`)\n .join(';');\n }\n\n const instance: TaggerInstance = {\n entity(name: string): TaggerInstance {\n currentEntity = name;\n namingEntity = name; // Always update naming scope when entity is set\n return instance;\n },\n\n data(\n keyOrData: string | WalkerOS.Properties,\n value?: WalkerOS.Property,\n ): TaggerInstance {\n const entityKey = namingEntity ?? '';\n\n if (!dataProperties[entityKey]) {\n dataProperties[entityKey] = {};\n }\n\n if (isString(keyOrData)) {\n dataProperties[entityKey][keyOrData] = value;\n } else {\n Object.assign(dataProperties[entityKey], keyOrData);\n }\n\n return instance;\n },\n\n scoped(\n keyOrScoped: string | WalkerOS.Properties,\n value?: WalkerOS.Property,\n ): TaggerInstance {\n if (isString(keyOrScoped)) {\n scopedProperties[keyOrScoped] = value;\n } else {\n Object.assign(scopedProperties, keyOrScoped);\n }\n\n return instance;\n },\n\n action(\n triggerOrActions: string | Record<string, string>,\n actionValue?: string,\n ): TaggerInstance {\n if (isString(triggerOrActions)) {\n if (isDefined(actionValue)) {\n // Two parameters: trigger and action\n actionProperties[triggerOrActions] = actionValue;\n } else {\n // Single parameter: could be \"trigger:action\" or just \"trigger\"\n if (triggerOrActions.includes(':')) {\n const [trigger, action] = triggerOrActions.split(':', 2);\n actionProperties[trigger] = action;\n } else {\n actionProperties[triggerOrActions] = triggerOrActions;\n }\n }\n } else {\n Object.assign(actionProperties, triggerOrActions);\n }\n\n return instance;\n },\n\n actions(\n triggerOrActions: string | Record<string, string>,\n actionValue?: string,\n ): TaggerInstance {\n if (isString(triggerOrActions)) {\n if (isDefined(actionValue)) {\n // Two parameters: trigger and action\n actionsProperties[triggerOrActions] = actionValue;\n } else {\n // Single parameter: could be \"trigger:action\" or just \"trigger\"\n if (triggerOrActions.includes(':')) {\n const [trigger, action] = triggerOrActions.split(':', 2);\n actionsProperties[trigger] = action;\n } else {\n actionsProperties[triggerOrActions] = triggerOrActions;\n }\n }\n } else {\n Object.assign(actionsProperties, triggerOrActions);\n }\n\n return instance;\n },\n\n context(\n keyOrContext: string | WalkerOS.Properties,\n value?: WalkerOS.Property,\n ): TaggerInstance {\n if (isString(keyOrContext)) {\n contextProperties[keyOrContext] = value;\n } else {\n Object.assign(contextProperties, keyOrContext);\n }\n\n return instance;\n },\n\n globals(\n keyOrGlobals: string | WalkerOS.Properties,\n value?: WalkerOS.Property,\n ): TaggerInstance {\n if (isString(keyOrGlobals)) {\n globalProperties[keyOrGlobals] = value;\n } else {\n Object.assign(globalProperties, keyOrGlobals);\n }\n\n return instance;\n },\n\n link(\n idOrLinks: string | Record<string, string>,\n type?: string,\n ): TaggerInstance {\n if (isString(idOrLinks)) {\n linkProperties[idOrLinks] = type!;\n } else {\n Object.assign(linkProperties, idOrLinks);\n }\n\n return instance;\n },\n\n get(): Record<string, string> {\n const attributes: Record<string, string> = {};\n\n // Add entity attribute if set\n if (currentEntity) {\n attributes[prefix] = currentEntity;\n }\n\n // Add data attributes\n Object.entries(dataProperties).forEach(([entityKey, props]) => {\n if (Object.keys(props).length > 0) {\n const attrName = entityKey\n ? `${prefix}-${entityKey}`\n : `${prefix}-`;\n attributes[attrName] = serializeKeyValue(props);\n }\n });\n\n // Add scoped generic attribute (data-elb_): branch-scoped, bubble-up\n // only. Suffix must match Const.Commands.Scoped ('_').\n if (Object.keys(scopedProperties).length > 0) {\n attributes[`${prefix}_`] = serializeKeyValue(scopedProperties);\n }\n\n // Add action attributes\n if (Object.keys(actionProperties).length > 0) {\n attributes[`${prefix}action`] = serializeKeyValue(actionProperties);\n }\n\n // Add actions attributes (for all entities)\n if (Object.keys(actionsProperties).length > 0) {\n attributes[`${prefix}actions`] = serializeKeyValue(actionsProperties);\n }\n\n // Add context attributes\n if (Object.keys(contextProperties).length > 0) {\n attributes[`${prefix}context`] = serializeKeyValue(contextProperties);\n }\n\n // Add global attributes\n if (Object.keys(globalProperties).length > 0) {\n attributes[`${prefix}globals`] = serializeKeyValue(globalProperties);\n }\n\n // Add link attributes\n if (Object.keys(linkProperties).length > 0) {\n attributes[`${prefix}link`] = serializeKeyValue(linkProperties);\n }\n\n return attributes;\n },\n };\n\n return instance;\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,IAAAA,eAAyB;AACzB,IAAAC,oBAAiC;;;ACDjC,IAAAC,eAAmC;AACnC,IAAAC,oBAA+B;AAC/B,IAAAC,mBAA4C;;;ACF5C,kBAAiD;AACjD,uBAAsB;AACtB,sBAA6B;AAEtB,SAAS,oBACd,QACA,MACA,aAAa,MACL;AAER,QAAM,YAAY,aAAa,MAAM;AACrC,SAAO,QAAQ,SAAY,YAAY,OAAO;AAC9C,SAAO,SAAS;AAClB;AAEO,SAAS,aACd,QACA,SACA,MACA,aAAa,MACQ;AACrB,QAAM,qBACJ,8BAAa,SAAS,oBAAoB,QAAQ,MAAM,UAAU,CAAC,KAAK;AAE1E,QAAM,YAAY,eAAe,cAAc,EAAE,OAAO,CAAC,QAAQ,QAAQ;AACvE,QAAI,CAAC,KAAK,GAAG,IAAmB,YAAY,GAAG;AAE/C,QAAI,CAAC,IAAK,QAAO;AAGjB,QAAI,CAAC,KAAK;AAER,UAAI,IAAI,SAAS,GAAG,EAAG,OAAM,IAAI,MAAM,GAAG,EAAE;AAC5C,YAAM;AAAA,IACR;AAGA,QAAI,IAAI,WAAW,GAAG,GAAG;AACvB,YAAM,IAAI,MAAM,CAAC;AACjB,UAAI;AAEF,YAAI,eAAgB,QAAoB,GAAoB;AAC5D,YAAI,CAAC,gBAAgB,QAAQ,YAAY;AAEvC,yBAAgB,QAA8B,QAC3C,QAA8B,aACjC,EAAE;AAAA,QACJ;AAEA,cAAM,OAAO,YAAY;AAAA,MAC3B,SAAS,OAAO;AACd,cAAM;AAAA,MACR;AAAA,IACF;AAEA,QAAI,IAAI,SAAS,IAAI,GAAG;AACtB,YAAM,IAAI,MAAM,GAAG,EAAE;AACrB,UAAI,KAAC,qBAAQ,OAAO,GAAG,CAAC,EAAG,QAAO,GAAG,IAAI,CAAC;AAC1C,MAAC,OAAO,GAAG,EAA8B,SAAK,uBAAU,GAAG,CAAC;AAAA,IAC9D,OAAO;AACL,aAAO,GAAG,QAAI,uBAAU,GAAG;AAAA,IAC7B;AAEA,WAAO;AAAA,EACT,GAAG,CAAC,CAAwB;AAE5B,SAAO;AACT;AAEO,SAAS,aACd,OACA,SAAiB,uBAAM,SAAS,QACjB;AA3EjB;AA4EE,QAAM,cAAc;AACpB,MAAI,CAAC,YAAa,QAAO,CAAC;AAC1B,MAAI,SAAwB,CAAC;AAC7B,QAAM,SAAS,uBAAM,SAAS;AAC9B,QAAM,iBAAiB,IAAI,oBAAoB,QAAQ,QAAQ,KAAK,CAAC;AAErE,QAAM,uBAAuB,CAAC,SAAkB;AAC9C,WAAO,KAAK,aAAa,QAAQ,MAAM,QAAQ,KAAK,CAAC,EAAE;AAAA,MACrD,CAAC,YAAY;AACX,iBAAS,OAAO,OAAO,UAAU,MAAM,SAAS,MAAM,CAAC;AAAA,MACzD;AAAA,IACF;AAAA,EACF;AAGA,QAAM,MACH,YAAwB,iBAAkB;AAC7C,MACE,gBAAgB,SACf,iBAAwB,YAAxB,qCAAkC,kBACnC;AACA,yBAAqB,WAAsB;AAAA,EAC7C;AAEA,mBAAiB,aAAa,gBAAgB,oBAAoB;AAElE,SAAO;AACT;AAEO,SAAS,UACd,QACA,SACA,SAAiB,uBAAM,SAAS,QACjB;AACf,QAAM,SAAwB,CAAC;AAG/B,QAAM,EAAE,SAAS,YAAY,IAAI,kBAAkB,QAAQ,QAAQ,OAAO;AAG1E,MAAI,CAAC,QAAQ,OAAQ,QAAO;AAE5B,UAAQ,QAAQ,CAAC,kBAAkB;AACjC,UAAM,SAAS,eAAe,cAAc,gBAAgB,IAAI,GAAG,EAAE;AAAA,MACnE,CAACC,SAAQ,UAAU;AACjB,QAAAA,YAAO,kBAAK,KAAK,CAAC,IAAI;AACtB,eAAOA;AAAA,MACT;AAAA,MACA,CAAC;AAAA,IACH;AAGA,UAAM,WAAW,YAAY,QAAQ,QAAQ,QAAQ,WAAW;AAGhE,QAAI,CAAC,SAAS,QAAQ;AACpB,YAAM,SAAS;AAEf,YAAM,iBAAiB,IAAI,oBAAoB,QAAQ,MAAM,CAAC;AAG9D,YAAM,CAAC,MAAM,OAAO,IAAI;AAAA,QACtB;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAEA,eAAS,KAAK;AAAA,QACZ;AAAA;AAAA,QACA;AAAA;AAAA,QACA,QAAQ,CAAC;AAAA;AAAA,QACT;AAAA,MACF,CAAC;AAAA,IACH;AAGA,aAAS,QAAQ,CAAC,WAAW;AAzJjC;AA0JM,aAAO,KAAK;AAAA,QACV,QAAQ,OAAO;AAAA,QACf,QAAQ,cAAc;AAAA,QACtB,MAAM,OAAO;AAAA,QACb;AAAA,QACA,SAAS,OAAO;AAAA,QAChB,SAAQ,YAAO,WAAP,YAAiB,CAAC;AAAA,MAC5B,CAAC;AAAA,IACH,CAAC;AAAA,EACH,CAAC;AAED,SAAO;AACT;AAEO,SAAS,WACd,SAAiB,uBAAM,SAAS,QAChC,OACqB;AACrB,MAAI,CAAC,MAAO,QAAO,CAAC;AACpB,QAAM,cAAc;AAAA,IAClB;AAAA,IACA,uBAAM,SAAS;AAAA,IACf;AAAA,EACF;AACA,QAAM,iBAAiB,IAAI,WAAW;AACtC,MAAI,SAAS,CAAC;AAEd,WAAS,OAAO,gBAAgB,CAAC,YAAY;AAC3C,iBAAS;AAAA,MACP;AAAA,MACA,aAAa,QAAQ,SAAS,uBAAM,SAAS,SAAS,KAAK;AAAA,IAC7D;AAAA,EACF,CAAC;AAED,SAAO;AACT;AAEO,SAAS,QACd,SAAiB,uBAAM,SAAS,QAChC,OACe;AACf,MAAI,CAAC,MAAO,QAAO,CAAC;AACpB,QAAM,WAAW,oBAAoB,QAAQ,uBAAM,SAAS,MAAM,KAAK;AACvE,QAAM,eAAe,IAAI,QAAQ;AACjC,MAAI,SAAwB,CAAC;AAE7B,WAAS,OAAO,cAAc,CAAC,YAAY;AACzC,iBAAS;AAAA,MACP;AAAA,MACA,aAAa,QAAQ,SAAS,uBAAM,SAAS,MAAM,KAAK;AAAA,IAC1D;AAAA,EACF,CAAC;AAED,SAAO;AACT;AAEO,SAAS,gBACd,QACA,OACmD;AAEnD,QAAM,MAAO,MAAkB,iBAAkB;AACjD,QAAM,MAAM,IAAI;AAChB,QAAM,MAAM,IAAI;AAChB,QAAM,OAAO;AACb,QAAM,eACJ,UAAU,QAAS,MAAmB,OAAQ;AAChD,QAAM,CAAC,MAAM,OAAO,IAAI;AAAA,IACtB;AAAA,IACA,IAAI,oBAAoB,QAAQ,IAAI,CAAC;AAAA,IACrC;AAAA,IACA;AAAA,EACF;AACA,OAAK,SAAS,IAAI;AAClB,OAAK,QAAQ,IAAI;AACjB,OAAK,WAAW,IAAI;AAEpB,MAAI,IAAI,OAAQ,MAAK,SAAS,IAAI;AAClC,MAAI,IAAI,KAAM,MAAK,OAAO,IAAI;AAG9B,SAAO,CAAC,MAAM,OAAO;AACvB;AAEO,SAAS,kBAAkB,KAA0C;AAC1E,QAAM,SAAsC,CAAC;AAE7C,QAAM,aAAa,eAAe,GAAG;AAErC,aAAW,QAAQ,CAACC,SAAQ;AAC1B,UAAM,CAAC,aAAa,UAAU,IAAI,YAAYA,IAAG;AACjD,UAAM,CAAC,SAAS,aAAa,IAAI,eAAe,WAAW;AAE3D,QAAI,CAAC,QAAS;AAEd,QAAI,CAAC,QAAQ,YAAY,IAAI,eAAe,cAAc,EAAE;AAG5D,aAAS,UAAU;AAEnB,QAAI,CAAC,OAAO,OAAO,EAAG,QAAO,OAAO,IAAI,CAAC;AAEzC,WAAO,OAAO,EAAE,KAAK,EAAE,SAAS,eAAe,QAAQ,aAAa,CAAC;AAAA,EACvE,CAAC;AAED,SAAO;AACT;AAEO,SAAS,YACd,QACA,QACA,QACA,cAAc,OACK;AACnB,QAAM,WAA8B,CAAC;AACrC,MAAI,UAAU;AAGd,WAAS,OAAO,KAAK,UAAU,CAAC,CAAC,EAAE,WAAW,IAAI,SAAS;AAE3D,SAAO,SAAS;AACd,UAAM,SAAS,UAAU,QAAQ,SAAS,QAAQ,MAAM;AACxD,QAAI,QAAQ;AACV,eAAS,KAAK,MAAM;AACpB,UAAI,YAAa;AAAA,IACnB;AAEA,cAAU,UAAU,QAAQ,OAAO;AAAA,EACrC;AAEA,SAAO;AACT;AAEA,SAAS,UACP,QACA,SACA,QACA,QACwB;AACxB,QAAM,aAAS,8BAAa,SAAS,oBAAoB,MAAM,CAAC;AAGhE,MAAI,CAAC,UAAW,UAAU,CAAC,OAAO,MAAM,EAAI,QAAO;AAEnD,QAAM,aAAa,CAAC,OAAO;AAC3B,QAAM,eAAe,IAAI;AAAA,IACvB;AAAA,IACA;AAAA,EACF,CAAC,MAAM,oBAAoB,QAAQ,EAAE,CAAC;AACtC,QAAM,WAAW,oBAAoB,QAAQ,uBAAM,SAAS,MAAM,KAAK;AAEvE,MAAI,OAA4B,CAAC;AACjC,QAAM,SAA4B,CAAC;AACnC,QAAM,CAAC,YAAY,OAAO,IAAI;AAAA,IAC5B,UAAU;AAAA,IACV;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA,EACF;AAGA,mBAAiB,SAAS,IAAI,QAAQ,KAAK,CAAC,SAAS;AACnD,UAAM,CAAC,QAAQ,SAAS,IAAmB;AAAA,UACzC,8BAAa,MAAM,QAAQ;AAAA,IAC7B;AAKA,QAAI,cAAc;AAChB;AAAA,QACE,QAAQ,cAAc;AAAA,QACtB,IAAI,QAAQ,KAAK,MAAM;AAAA,QACvB,CAAC,aAAa;AACZ,qBAAW,KAAK,QAAQ;AAGxB,gBAAM,eAAe,UAAU,QAAQ,QAAQ;AAC/C,cAAI,aAAc,QAAO,KAAK,YAAY;AAAA,QAC5C;AAAA,MACF;AAAA,EACJ,CAAC;AAGD,QAAM,gBAAgC,CAAC;AACvC,aAAW,QAAQ,CAAC,SAAS;AAE3B,QAAI,KAAK,QAAQ,YAAY,EAAG,eAAc,KAAK,IAAI;AAEvD,qBAAiB,MAAM,cAAc,CAACC,UAAS,cAAc,KAAKA,KAAI,CAAC;AAAA,EACzE,CAAC;AAGD,MAAI,cAAmC,CAAC;AACxC,gBAAc,QAAQ,CAAC,UAAU;AAE/B,sBAAc,oBAAO,aAAa,aAAa,QAAQ,OAAO,EAAE,CAAC;AACjE,eAAO,oBAAO,MAAM,aAAa,QAAQ,OAAO,MAAM,CAAC;AAAA,EACzD,CAAC;AAGD,aAAO,wBAAO,oBAAO,aAAa,IAAI,GAAG,UAAU;AAGnD,aAAW,QAAQ,CAAC,SAAS;AAC3B;AAAA,MACE;AAAA,MACA,IAAI,oBAAoB,MAAM,CAAC;AAAA,MAC/B,CAAC,wBAAwB;AACvB,cAAM,eAAe,UAAU,QAAQ,mBAAmB;AAC1D,YAAI,aAAc,QAAO,KAAK,YAAY;AAAA,MAC5C;AAAA,IACF;AAAA,EACF,CAAC;AAED,SAAO,EAAE,QAAQ,MAAM,SAAS,OAAO;AACzC;AAEA,SAAS,UAAU,QAAgB,MAAuC;AACxE,QAAM,WAAW,oBAAoB,QAAQ,uBAAM,SAAS,MAAM,KAAK;AAGvE,MAAI,KAAK,QAAQ,IAAI,QAAQ,GAAG,GAAG;AACjC,UAAM,CAAC,QAAQ,SAAS,IAAmB;AAAA,UACzC,8BAAa,MAAM,QAAQ;AAAA,IAC7B;AACA,QAAI,cAAc,SAAS;AAIzB,YAAM,MAAM,KAAK;AACjB,UAAI,QAA4B;AAChC,eAAS,KAAK,IAAI,QAAQ,KAAK,MAAM,aAAa,CAAC,OAAO;AACxD,YAAI,CAAC,MAAO,SAAQ;AAAA,MACtB,CAAC;AACD,aAAO;AAAA,IACT;AAAA,EACF;AAGA,QAAM,MAAM,KAAK,cAAc;AAC/B,MACE,CAAC,KAAK,iBACN,KAAK,eACL,KAAK,YAAY,aAAa,IAAI,YAClC;AACA,WAAQ,KAAK,YAAY,EAAiB;AAAA,EAC5C;AAEA,SAAO,KAAK;AACd;AAEA,SAAS,2BACP,SACA,gBACA,QACA,MACA,gBAAgB,OACkD;AAClE,MAAI,OAA4B,CAAC;AACjC,QAAM,UAAsC,CAAC;AAC7C,MAAI,SAAS;AACb,QAAM,kBAAkB,IAAI;AAAA,IAC1B;AAAA,IACA,uBAAM,SAAS;AAAA,IACf;AAAA,EACF,CAAC;AACD,QAAM,aAAa,uBAAM,SAAS;AAClC,QAAM,iBAAiB,IAAI,oBAAoB,QAAQ,YAAY,KAAK,CAAC;AAGzE,MAAI,WAAW;AACf,SAAO,QAAQ;AAKb,QAAI,iBAAiB,cAAc,OAAO,QAAQ,cAAc,GAAG;AACjE,iBAAO,oBAAO,aAAa,QAAQ,QAAQ,YAAY,KAAK,GAAG,IAAI;AAAA,IACrE;AAGA,QAAI,OAAO,QAAQ,cAAc,GAAG;AAElC,iBAAO,oBAAO,aAAa,QAAQ,QAAQ,EAAE,GAAG,IAAI;AACpD,iBAAO,oBAAO,aAAa,QAAQ,QAAQ,IAAI,GAAG,IAAI;AAAA,IACxD;AAGA,QAAI,OAAO,QAAQ,eAAe,GAAG;AACnC,aAAO;AAAA,QACL,aAAa,QAAQ,QAAQ,uBAAM,SAAS,SAAS,KAAK;AAAA,MAC5D,EAAE,QAAQ,CAAC,CAAC,KAAK,GAAG,MAAM;AAExB,YAAI,OAAO,CAAC,QAAQ,GAAG,EAAG,SAAQ,GAAG,IAAI,CAAC,KAAK,QAAQ;AAAA,MACzD,CAAC;AAGD,QAAE;AAAA,IACJ;AAEA,aAAS,UAAU,QAAQ,MAAM;AAAA,EACnC;AAEA,SAAO,CAAC,MAAM,OAAO;AACvB;AAEA,SAAS,SACP,OACA,UACA,IACM;AACN,QAAM,iBAAiB,QAAQ,EAAE,QAAQ,EAAE;AAC7C;AAKO,SAAS,iBACd,OACA,UACA,IACM;AACN,QAAM,iBAAiB,QAAQ,EAAE,QAAQ,EAAE;AAE3C,QAAM,MAAO,MAAkB,iBAAkB;AACjD,QAAM,MAAM,IAAI;AAChB,MAAI,iBAAiB,IAAI,WAAW,MAAM,YAAY;AACpD,qBAAiB,MAAM,YAAY,UAAU,EAAE;AAAA,EACjD;AACA,QAAM,iBAAiB,GAAG,EAAE,QAAQ,CAAC,OAAO;AAC1C,QAAI,GAAG,YAAY;AACjB,uBAAiB,GAAG,YAAY,UAAU,EAAE;AAAA,IAC9C;AAAA,EACF,CAAC;AACH;AAEA,SAAS,kBACP,QACA,QACA,SAC0D;AAC1D,MAAI,UAAU;AAEd,SAAO,SAAS;AAEd,UAAM,qBAAiB;AAAA,MACrB;AAAA,MACA,oBAAoB,QAAQ,uBAAM,SAAS,SAAS,KAAK;AAAA,IAC3D;AAEA,QAAI,gBAAgB;AAClB,YAAM,iBAAiB,kBAAkB,cAAc;AACvD,UAAI,eAAe,OAAO,GAAG;AAC3B,eAAO,EAAE,SAAS,eAAe,OAAO,GAAG,aAAa,MAAM;AAAA,MAChE;AAAA,IACF;AAGA,UAAM,sBAAkB;AAAA,MACtB;AAAA,MACA,oBAAoB,QAAQ,uBAAM,SAAS,QAAQ,KAAK;AAAA,IAC1D;AAEA,QAAI,iBAAiB;AACnB,YAAM,iBAAiB,kBAAkB,eAAe;AAExD,UAAI,eAAe,OAAO,KAAK,YAAY,SAAS;AAClD,eAAO,EAAE,SAAS,eAAe,OAAO,KAAK,CAAC,GAAG,aAAa,KAAK;AAAA,MACrE;AAAA,IACF;AAEA,cAAU,UAAU,QAAQ,OAAO;AAAA,EACrC;AAEA,SAAO,EAAE,SAAS,CAAC,GAAG,aAAa,MAAM;AAC3C;AAEA,SAAS,eAAe,KAAa,YAAY,KAAwB;AACvE,QAAM,SAA4B,CAAC;AAEnC,MAAI,CAAC,IAAK,QAAO;AAEjB,QAAM,MAAM,IAAI,OAAO,QAAQ,SAAS,iBAAiB,IAAI;AAC7D,SAAO,IAAI,MAAM,GAAG,KAAK,CAAC;AAC5B;AAEA,SAAS,YAAY,KAA4B;AAC/C,QAAM,CAAC,KAAK,KAAK,IAAI,IAAI,MAAM,SAAS,CAAC;AACzC,SAAO,KAAC,kBAAK,GAAG,OAAG,kBAAK,KAAK,CAAC;AAChC;AAEA,SAAS,eAAe,KAA4B;AAElD,QAAM,CAAC,KAAK,KAAK,IAAI,IAAI,MAAM,KAAK,CAAC;AACrC,QAAM,QAAQ,QAAQ,MAAM,MAAM,GAAG,EAAE,IAAI;AAG3C,SAAO,CAAC,KAAK,KAAK;AACpB;;;ACziBA,IAAAC,eAAyB;AACzB,IAAAC,mBAA0B;AAK1B,IAAM,WAAW;AAoBV,SAAS,WACd,OACA,KACS;AACT,MAAI,CAAC,MAAM,eAAgB,QAAO;AAElC,QAAM,MAAM,MAAM;AAGlB,MAAI,IAAI,SAAS,KAAK,IAAI,UAAU,EAAG,QAAO;AAK9C,QAAM,YAAY,MAAM,aAAa,MAAM,WAAW,QAAQ,IAAI;AAClE,QAAM,aAAa,MAAM,aACrB,MAAM,WAAW,SACjB,IAAI;AACR,MAAI,aAAa,KAAK,cAAc,EAAG,QAAO;AAE9C,QAAM,UAAU,MAAM;AACtB,QAAM,YAAY,WAAW,KAAK,IAAI,IAAI,OAAO,SAAS;AAC1D,QAAM,aAAa,WAAW,KAAK,IAAI,IAAI,QAAQ,UAAU;AAE7D,SAAO,QAAQ,SAAS,aAAa,QAAQ,UAAU;AACzD;AAkBA,IAAM,aAAa,MAAM,KAAK,EAAE,QAAQ,IAAI,GAAG,CAAC,GAAG,UAAU,QAAQ,GAAG;AAyBxE,IAAM,mBAAmB,oBAAI,QAA6C;AAQnE,SAAS,YAAY,OAAsC;AAChE,SAAQ,MAAkB,iBAAkB;AAC9C;AAEA,SAAS,eACP,OACkC;AAClC,QAAM,MAAO,MAAkB,iBAAkB;AACjD,QAAM,MAAM,IAAI;AAChB,MAAI,CAAC,OAAO,CAAC,IAAI,qBAAsB,QAAO;AAE9C,aAAO;AAAA,IACL,MACE,IAAI,IAAI;AAAA,MACN,CAAC,YAAY;AACX,gBAAQ,QAAQ,CAAC,UAAU,mBAAmB,OAAO,KAAK,CAAC;AAAA,MAC7D;AAAA,MACA,EAAE,YAAY,OAAO,WAAW,WAAW;AAAA,IAC7C;AAAA,IACF,MAAM;AAAA,EACR,EAAE;AACJ;AAEA,SAAS,mBACP,OACA,OACM;AACN,QAAM,SAAS,MAAM;AACrB,QAAM,QAAQ,iBAAiB,IAAI,YAAY,KAAK,CAAC;AACrD,MAAI,CAAC,MAAO;AAEZ,QAAM,MAAM,OAAO,cAAc;AACjC,MAAI,CAAC,IAAK;AAEV,QAAM,UAAU,MAAM,QAAQ,IAAI,MAAM;AAGxC,MAAI,CAAC,WAAW,CAAC,QAAQ,OAAQ;AAEjC,QAAM,gBAAgB,MAAM,OAAO,IAAI,MAAM;AAE7C,MAAI,WAAW,OAAO,GAAG,GAAG;AAE1B,QAAI,QAAQ,MAAM,CAAC,WAAW,OAAO,OAAO,EAAG;AAE/C,QAAI,CAAC,eAAe;AAClB,YAAM,QAAQ,IAAI,WAAW,MAAM;AACjC,aAAK,YAAY,KAAK,GAAG,MAAM;AAAA,MACjC,GAAG,MAAM,QAAQ;AACjB,YAAM,OAAO,IAAI,QAAQ,KAAK;AAAA,IAChC;AACA;AAAA,EACF;AAGA,MAAI,eAAe;AACjB,iBAAa,aAAa;AAC1B,UAAM,OAAO,OAAO,MAAM;AAAA,EAC5B;AACA,UAAQ,QAAQ,CAAC,WAAW;AAC1B,QAAI,OAAO,SAAU,QAAO,UAAU;AAAA,EACxC,CAAC;AACH;AAEA,eAAe,KACb,OACA,QACe;AACf,QAAM,QAAQ,iBAAiB,IAAI,KAAK;AACxC,MAAI,CAAC,MAAO;AAKZ,QAAM,OAAO,OAAO,MAAM;AAE1B,QAAM,MAAM,OAAO;AACnB,QAAM,MAAM,IAAI;AAChB,MAAI,CAAC,IAAK;AASV,MAAI,IAAI,oBAAoB,WAAW;AACrC,UAAM,OAAO;AAAA,MACX;AAAA,MACA,IAAI,WAAW,MAAM;AACnB,aAAK,OAAO,MAAM;AAAA,MACpB,GAAG,MAAM,QAAQ;AAAA,IACnB;AACA;AAAA,EACF;AAGA,MAAI,KAAC,4BAAU,QAAQ,KAAK,GAAG,EAAG;AAElC,QAAM,UAAU,MAAM,QAAQ,IAAI,MAAM;AACxC,MAAI,CAAC,QAAS;AAEd,QAAM,UAAU,QAAQ,OAAO,CAAC,WAAW,CAAC,OAAO,OAAO;AAC1D,MAAI,CAAC,QAAQ,OAAQ;AAKrB,UAAQ,QAAQ,CAAC,WAAW;AAC1B,QAAI,OAAO,SAAU,QAAO,UAAU;AAAA,EACxC,CAAC;AAED,QAAM,YAAY,QAAQ,OAAO,CAAC,WAAW,OAAO,QAAQ;AAC5D,MAAI,UAAU,QAAQ;AACpB,UAAM,QAAQ,IAAI,QAAQ,SAAS;AAAA,EACrC,OAAO;AAGL,qBAAiB,OAAO,MAAM;AAAA,EAChC;AAEA,QAAM,QAAQ;AAAA,IACZ,QAAQ;AAAA,MAAI,CAAC,WACX,cAAc,OAAO,SAAS,QAAQ,OAAO,OAAO;AAAA,IACtD;AAAA,EACF;AACF;AAEO,SAAS,iBAAiB,OAAkB,SAA4B;AAxO/E;AAyOE,QAAM,QAAQ,iBAAiB,IAAI,YAAY,KAAK,CAAC;AACrD,MAAI,CAAC,MAAO;AAEZ,cAAM,aAAN,mBAAgB,UAAU;AAC1B,cAAM,mBAAN,mBAAsB,UAAU;AAChC,QAAM,QAAQ,OAAO,OAAO;AAC5B,QAAM,SAAS,OAAO,OAAO;AAE7B,QAAM,QAAQ,MAAM,OAAO,IAAI,OAAO;AACtC,MAAI,OAAO;AACT,iBAAa,KAAK;AAClB,UAAM,OAAO,OAAO,OAAO;AAAA,EAC7B;AACF;AAeA,SAAS,qBACP,OAC4B;AAC5B,QAAM,MAAO,MAAkB,iBAAkB;AACjD,QAAM,MAAM,IAAI;AAChB,MAAI,CAAC,OAAO,CAAC,IAAI,eAAgB,QAAO;AAExC,aAAO;AAAA,IACL,MACE,IAAI,IAAI,eAAe,CAAC,YAAY;AAClC,YAAM,QAAQ,iBAAiB,IAAI,KAAK;AACxC,UAAI,EAAC,+BAAO,UAAU;AAEtB,cAAQ,QAAQ,CAAC,UAAU;AAlRnC;AAmRU,cAAM,SAAS,MAAM;AACrB,cAAM,EAAE,OAAO,OAAO,IAAI,MAAM;AAChC,cAAM,SAAS,SAAS,KAAK,UAAU;AAEvC,YAAI,QAAQ;AACV,gBAAM,SAAS,IAAI,MAAM;AACzB;AAAA,QACF;AAEA,YAAI,CAAC,MAAM,SAAS,IAAI,MAAM,EAAG;AACjC,cAAM,SAAS,OAAO,MAAM;AAE5B,oBAAM,aAAN,mBAAgB,UAAU;AAC1B,oBAAM,aAAN,mBAAgB,QAAQ;AAAA,MAC1B,CAAC;AAAA,IACH,CAAC;AAAA,IACH,MAAM;AAAA,EACR,EAAE;AACJ;AAEO,SAAS,uBACd,OACA,WAAW,KACL;AACN,QAAM,MAAM,YAAY,KAAK;AAC7B,MAAI,iBAAiB,IAAI,GAAG,EAAG;AAE/B,mBAAiB,IAAI,KAAK;AAAA,IACxB,UAAU,eAAe,GAAG;AAAA,IAC5B,gBAAgB,qBAAqB,GAAG;AAAA,IACxC,QAAQ,oBAAI,QAAQ;AAAA,IACpB;AAAA,IACA,SAAS,oBAAI,QAAQ;AAAA,IACrB,UAAU,oBAAI,QAAQ;AAAA,EACxB,CAAC;AACH;AAEO,SAAS,eACd,SACA,SACA,SAAiC,EAAE,UAAU,MAAM,GAC7C;AA5TR;AA6TE,QAAM,QAAQ,QAAQ,SAAS;AAC/B,MAAI,CAAC,MAAO;AACZ,QAAM,QAAQ,iBAAiB,IAAI,YAAY,KAAK,CAAC;AACrD,MAAI,EAAC,+BAAO,aAAY,CAAC,QAAS;AAElC,QAAM,YAAW,YAAO,aAAP,YAAmB;AACpC,QAAM,WAAU,WAAM,QAAQ,IAAI,OAAO,MAAzB,YAA8B,CAAC;AAC/C,UAAQ,KAAK;AAAA,IACX;AAAA,IACA,SAAS;AAAA,IACT;AAAA,IACA,SAAS,WAAW,SAAS,UAAU,SAAS;AAAA,EAClD,CAAC;AACD,QAAM,QAAQ,IAAI,SAAS,OAAO;AAGlC,MAAI,QAAQ,SAAS,EAAG;AAExB,QAAM,MAAM,QAAQ,sBAAsB;AAC1C,MAAI,IAAI,SAAS,KAAK,IAAI,UAAU,EAAG,OAAM,SAAS,IAAI,OAAO;AAEjE,QAAM,SAAS,QAAQ,OAAO;AAC9B,cAAM,mBAAN,mBAAsB,QAAQ;AAChC;AAEO,SAAS,0BAA0B,OAAyB;AAtVnE;AAuVE,MAAI,CAAC,MAAO;AACZ,QAAM,MAAM,YAAY,KAAK;AAC7B,QAAM,QAAQ,iBAAiB,IAAI,GAAG;AACtC,MAAI,CAAC,MAAO;AAEZ,cAAM,aAAN,mBAAgB;AAChB,cAAM,mBAAN,mBAAsB;AACtB,mBAAiB,OAAO,GAAG;AAC7B;;;AC9VA,IAAAC,eAAwD;AACxD,IAAAC,oBAAiC;AAa1B,SAAS,yBACd,SACA,gBACA,MACA,SACA,aACA,QACA,QACyB;AACzB,QAAM,EAAE,KAAK,SAAS,IAAI;AAQ1B,UAAI,uBAAS,cAAc,KAAK,eAAe,WAAW,SAAS,GAAG;AACpE,QAAI,mBAAmB,iBAAiB,QAAQ,WAAW;AACzD,YAAM,SAAS,oBAAoB,MAAM,QAAQ;AACjD,iBAAW,SAAS,QAAQ;AAI1B,gBAAQ,UAAU,EAAE,GAAG,SAAS,UAAU,EAAE,GAAG,UAAU,MAAM,EAAE,CAAC;AAAA,MACpE;AACA,aAAO,QAAQ,YAAQ,oCAAiB,EAAE,IAAI,KAAK,CAAC,CAAC;AAAA,IACvD;AACA,WAAO,IAAI,gBAAgB,IAA2B;AAAA,EACxD;AAGA,UAAI,uBAAS,cAAc,GAAG;AAC5B,UAAMC,SAAQ;AACd,QAAI,CAACA,OAAM,UAAU,SAAS,OAAO;AACnC,YAAMC,YAAa,SAAS,MAAkB,iBAC5C,SAAS;AACX,YAAMC,YAAWD,UAAS;AAC1B,MAAAD,OAAM,SAAS,iBAAiBE,WAAUD,SAAQ;AAAA,IACpD;AAGA,QAAI,CAACD,OAAM,WAAW,SAAS,OAAO;AACpC,MAAAA,OAAM,UAAU,eAAe,SAAS,KAAK,IACzC,WAAW,SAAS,QAAQ,SAAS,KAAK,IAC1C,CAAC;AAAA,IACP;AAEA,WAAO,IAAIA,MAAK;AAAA,EAClB;AAGA,QAAM,CAAC,MAAM,IAAI;AAAA,QACf,uBAAS,cAAc,IAAI,eAAe,OAAO;AAAA,EACnD,EAAE,MAAM,GAAG;AAGX,MAAI,gBAAY,uBAAS,IAAI,IAAK,OAA+B,CAAC;AAClE,MAAI,eAA2C,CAAC;AAEhD,MAAI;AACJ,MAAI,aAAa;AAGjB,UAAI,kCAAoB,IAAI,GAAG;AAC7B,oBAAgB;AAChB,iBAAa;AAAA,EACf;AAGA,UAAI,kCAAoB,WAAW,GAAG;AACpC,oBAAgB;AAAA,EAClB,eAAW,uBAAS,WAAW,KAAK,OAAO,KAAK,WAAW,EAAE,QAAQ;AACnE,mBAAe;AAAA,EACjB;AAGA,MAAI,eAAe;AACjB,UAAM,YAAY;AAAA,MAChB,SAAS,UAAU;AAAA,MACnB;AAAA,IACF,EAAE,KAAK,CAAC,QAAQ,IAAI,WAAW,MAAM;AACrC,QAAI,WAAW;AACb,UAAI,WAAY,aAAY,UAAU;AACtC,UAAI,UAAU,QAAS,gBAAe,UAAU;AAAA,IAClD;AAAA,EACF;AAGA,QAAM,WAAW,SAAS,QACnB,SAAS,MAAkB,iBAC5B,SAAS,QACX;AACJ,QAAM,WAAW,qCAAU;AAG3B,MAAI,WAAW,UAAU,UAAU;AACjC,cAAU,KAAK,UAAU,MAAM,SAAS,SAAS;AAAA,EACnD;AAGA,QAAM,eACJ,SAAS,SAAS,eAAe,SAAS,KAAK,IAC3C,WAAW,SAAS,QAAQ,SAAS,KAAK,IAC1C,CAAC;AAGP,QAAM,QAAmC;AAAA,IACvC,MAAM,OAAO,kBAAkB,EAAE;AAAA,IACjC,MAAM;AAAA,IACN,SAAS;AAAA,IACT,SAAS;AAAA,IACT;AAAA,IACA;AAAA,IACA,aAAS,uBAAS,OAAO,IAAI,UAAU;AAAA,IACvC,QACE,YAAY,WAAW,iBAAiB,UAAU,QAAQ,IAAI;AAAA,EAClE;AAEA,SAAO,IAAI,KAAK;AAClB;AAKA,SAAS,iBAAiB,KAAa,KAAgC;AACrE,SAAO;AAAA,IACL,MAAM;AAAA,IACN,UAAU;AAAA,IACV,KAAK,IAAI,SAAS;AAAA,IAClB,UAAU,IAAI;AAAA,EAChB;AACF;AAUA,SAAS,WAAW,OAAoC;AACtD,MAAI,CAAC,SAAS,OAAO,UAAU,SAAU,QAAO;AAChD,MAAI,OAAO,YAAY,eAAe,iBAAiB,QAAS,QAAO;AACvE,MAAI,OAAO,aAAa,eAAe,iBAAiB,SAAU,QAAO;AACzE,MAAI,OAAO,eAAe,eAAe,iBAAiB;AACxD,WAAO;AACT,MAAI,cAAc,OAAO;AACvB,UAAM,WAAW,MAAM;AAKvB,WAAO,aAAa,KAAK,aAAa,KAAK,aAAa;AAAA,EAC1D;AACA,SAAO;AACT;AAUA,SAAS,eAAe,OAAkC;AACxD,SAAO,MAAM,aAAa;AAC5B;AAOA,SAAS,oBACP,MACA,UACkB;AAClB,MAAI,WAAW,IAAI,EAAG,QAAO,CAAC,IAAI;AAClC,MAAI,MAAM,QAAQ,IAAI,GAAG;AACvB,UAAM,WAA6B,CAAC;AACpC,eAAW,SAAS,MAAM;AACxB,UAAI,WAAW,KAAK,EAAG,UAAS,KAAK,KAAK;AAAA,IAC5C;AACA,WAAO;AAAA,EACT;AACA,MAAI,OAAO,SAAS,aAAa;AAC/B,UAAM,WAAW,SAAS;AAC1B,QAAI,WAAW,QAAQ,EAAG,QAAO,CAAC,QAAQ;AAC1C,QAAI,OAAO,WAAW,aAAa,aAAa;AAC9C,aAAO,CAAC,WAAW,QAAQ;AAAA,IAC7B;AAAA,EACF;AACA,SAAO,CAAC;AACV;;;AHpLA,IAAI;AASJ,IAAM,cAAc,oBAAI,IAA2B;AAsBnD,IAAM,kBAAkB,oBAAI,QAA0C;AAQ/D,SAAS,gBACd,OACA,IACA,cACS;AACT,MAAI,gBAAgB,IAAI,EAAE,EAAG,QAAO;AACpC,QAAM,SAAS,YAAY,IAAI,KAAK;AACpC,MAAI,CAAC,OAAQ,QAAO;AACpB,eAAa,QAAQ;AACrB,SAAO,WAAW,IAAI,EAAE;AACxB,kBAAgB,IAAI,IAAI,YAAY;AACpC,SAAO;AACT;AAGO,SAAS,aAAa,IAA0B;AACrD,SAAO,gBAAgB,IAAI,EAAE;AAC/B;AAOO,SAAS,YAAY,IAAuB;AA9FnD;AA+FE,QAAM,eAAe,gBAAgB,IAAI,EAAE;AAC3C,MAAI,CAAC,aAAc;AAEnB,QAAM,SAAS,YAAY,IAAI,aAAa,KAAK;AAIjD,eAAa,YAAY,QAAQ,CAAC,OAAO;AACvC,kBAAc,EAAE;AAChB,QAAI,QAAQ;AACV,YAAM,QAAQ,OAAO,YAAY,QAAQ,EAAE;AAC3C,UAAI,UAAU,GAAI,QAAO,YAAY,OAAO,OAAO,CAAC;AAAA,IACtD;AAAA,EACF,CAAC;AACD,eAAa,WAAW,QAAQ,CAAC,OAAO;AACtC,iBAAa,EAAE;AACf,QAAI,QAAQ;AACV,YAAM,QAAQ,OAAO,WAAW,QAAQ,EAAE;AAC1C,UAAI,UAAU,GAAI,QAAO,WAAW,OAAO,OAAO,CAAC;AAAA,IACrD;AAAA,EACF,CAAC;AAED,qBAAa,eAAb,mBAAyB;AAEzB,MAAI,aAAa,UAAU;AACzB,qBAAiB,aAAa,OAAO,EAAE;AACvC,qCAAQ,SAAS,OAAO;AAAA,EAC1B;AAEA,MAAI,aAAa,UAAU,QAAQ;AAKjC,WAAO,iBAAiB,OAAO,eAAe;AAAA,MAC5C,CAAC,CAAC,OAAO,MAAM,YAAY;AAAA,IAC7B;AAAA,EACF;AAEA,mCAAQ,WAAW,OAAO;AAC1B,kBAAgB,OAAO,EAAE;AAC3B;AAGO,SAAS,WAAW,OAA8B;AACvD,QAAM,WAAW,YAAY,IAAI,KAAK;AACtC,MAAI,UAAU;AACZ,aAAS,MAAM,MAAM;AAQrB,aAAS,YAAY,QAAQ,CAAC,OAAO,cAAc,EAAE,CAAC;AACtD,aAAS,WAAW,QAAQ,CAAC,OAAO,aAAa,EAAE,CAAC;AACpD,aAAS,SAAS,QAAQ,CAAC,YAAY,iBAAiB,OAAO,OAAO,CAAC;AAMvE,KAAC,GAAG,SAAS,UAAU,EAAE,QAAQ,CAAC,YAAY,YAAY,OAAO,CAAC;AAClE,aAAS,kBAAkB,QAAQ,CAAC,aAAa,SAAS,WAAW,CAAC;AAAA,EACxE;AAEA,QAAM,QAAoB;AAAA,IACxB,OAAO,IAAI,gBAAgB;AAAA,IAC3B,aAAa,CAAC;AAAA,IACd,YAAY,CAAC;AAAA,IACb,gBAAgB,CAAC;AAAA,IACjB,UAAU,oBAAI,IAAI;AAAA,IAClB,YAAY,oBAAI,IAAI;AAAA,IACpB,mBAAmB,CAAC;AAAA,EACtB;AACA,cAAY,IAAI,OAAO,KAAK;AAC5B,SAAO;AACT;AA2BO,IAAM,WAA8C;AAAA,EACzD,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,MAAM;AAAA,EACN,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,YAAY;AAAA,EACZ,SAAS;AAAA,EACT,MAAM;AACR;AAEA,eAAsB,MACpB,IACA,SACA,UACe;AACf,QAAM,UAAU,MAAM;AACpB,OAAG,SAAS,QAAQ;AAAA,EACtB;AAEA,QAAM,QAAQ,SAAS;AACvB,MAAI,CAAC,OAAO;AACV,YAAQ;AACR;AAAA,EACF;AACA,QAAM,MAAO,MAAkB,iBAAkB;AACjD,MAAI,IAAI,eAAe,WAAW;AAChC,YAAQ;AAAA,EACV,OAAO;AACL,QAAI,iBAAiB,oBAAoB,OAAO;AAAA,EAClD;AACF;AAGO,SAAS,aAAa,SAAkB,UAAoB;AACjE,MAAI,CAAC,SAAS,MAAO;AACrB,QAAM,mBAAmB;AACzB,oBAAkB,SAAS,gBAAgB;AAC7C;AAGO,SAAS,oBAAoB,SAAkB,UAAoB;AACxE,MAAI,CAAC,SAAS,MAAO;AACrB,QAAM,mBAAmB;AACzB,mBAAiB,SAAS,gBAAgB;AAC5C;AAEO,SAAS,kBAAkB,SAAkB,UAA0B;AAC5E,QAAM,QAAQ,SAAS;AAEvB,MAAI,CAAC,MAAO;AAIZ,MAAI,oBAAqB,qBAAoB,MAAM;AACnD,wBAAsB,IAAI,gBAAgB;AAC1C,QAAM,EAAE,OAAO,IAAI;AAEnB,QAAM;AAAA,IACJ;AAAA,QACA,uBAAS,SAAuB,IAAa;AAC3C,mBAAa,KAAK,MAAM,SAAS,EAAgB;AAAA,IACnD,CAAC;AAAA,IACD,EAAE,QAAQ,SAAS,SAAS,QAAQ;AAAA,EACtC;AACA,QAAM;AAAA,IACJ;AAAA,QACA,uBAAS,SAAuB,IAAa;AAC3C,oBAAc,KAAK,MAAM,SAAS,EAAiB;AAAA,IACrD,CAAC;AAAA,IACD,EAAE,QAAQ,SAAS,SAAS,QAAQ;AAAA,EACtC;AACF;AAMO,SAAS,gBAAgB,WAA4B;AAC1D,MAAI,qBAAqB;AACvB,wBAAoB,MAAM;AAC1B,0BAAsB;AAAA,EACxB;AASA,cAAY,QAAQ,CAAC,OAAO,UAAU;AACpC,UAAM,MAAM,MAAM;AAGlB,UAAM,kBAAkB,QAAQ,CAAC,aAAa,SAAS,WAAW,CAAC;AAKnE,UAAM,YAAY,QAAQ,CAAC,OAAO,cAAc,EAAE,CAAC;AACnD,UAAM,WAAW,QAAQ,CAAC,OAAO,aAAa,EAAE,CAAC;AAGjD,UAAM,SAAS,QAAQ,CAAC,YAAY,iBAAiB,OAAO,OAAO,CAAC;AAKpE,KAAC,GAAG,MAAM,UAAU,EAAE,QAAQ,CAAC,YAAY,YAAY,OAAO,CAAC;AAAA,EACjE,CAAC;AAED,cAAY,QAAQ,CAAC,QAAQ,UAAU;AAGrC,8BAA0B,KAAK;AAAA,EACjC,CAAC;AAED,cAAY,MAAM;AACpB;AAQO,SAAS,iBAAiB,SAAkB,WAAsB;AACvE,QAAM,QAAQ,QAAQ,SAAS;AAC/B,MAAI,CAAC,MAAO;AAEZ,QAAM,SAAS,WAAW,KAAK;AAK/B,yBAAuB,OAAO,GAAI;AAGlC,QAAM,iBAAiB;AAAA,IACrB,QAAQ,SAAS;AAAA,IACjB,wBAAM,SAAS;AAAA,IACf;AAAA,EACF;AACA,QAAM,MAAO,MAAkB,iBAAkB;AACjD,QAAM,MAAM,IAAI;AAKhB,MAAI,UAAU,OAAO,OAAO,iBAAiB,IAAI,SAAS;AAExD,wBAAoB,SAAS,OAAO,gBAAgB,QAAQ,KAAK;AAAA,EACnE;AAGA,mBAAiB,OAAO,IAAI,cAAc,KAAK,CAAC,SAAS;AACvD,wBAAoB,SAAS,MAAM,gBAAgB,QAAQ,KAAK;AAAA,EAClE,CAAC;AAED,MAAI,OAAO,eAAe,OAAQ,QAAO,SAAS,OAAO,MAAM;AAI/D,oBAAkB,SAAS,OAAO,QAAQ,cAAc;AAC1D;AAQA,SAAS,kBACP,SACA,OACA,QACA,gBACA;AACA,QAAM,MAAO,MAAkB,iBAAkB;AACjD,QAAM,MAAM,IAAI;AAGhB,MAAI,CAAC,OAAO,CAAC,IAAI,iBAAkB;AAEnC,QAAM,kBAAkB;AAAA,IACtB,QAAQ,SAAS;AAAA,IACjB;AAAA,IACA;AAAA,EACF;AAIA,QAAM,aAAwB,CAAC;AAC/B,MACE,UAAU,OACV,iBAAiB,IAAI,WACrB,MAAM,QAAQ,IAAI,eAAe,GAAG,GACpC;AACA,eAAW,KAAK,KAAK;AAAA,EACvB;AACA,mBAAiB,OAAO,IAAI,eAAe,KAAK,CAAC,OAAO,WAAW,KAAK,EAAE,CAAC;AAE3E,aAAW,QAAQ,CAAC,cAAc;AAOhC,UAAM,SAAS,WAAW;AAAA,MACxB,CAAC,UAAU,UAAU,aAAa,MAAM,SAAS,SAAS;AAAA,IAC5D;AACA,QAAI,OAAQ;AAEZ,UAAM,WAAW,IAAI,IAAI;AAAA,UACvB,uBAAS,CAAC,YAA8B;AAItC,cAAM,OAAO,YAAY,IAAI,KAAK;AAClC,YAAI,CAAC,KAAM;AAEX,gBAAQ,QAAQ,CAAC,WAAW;AAC1B,iBAAO,WAAW;AAAA,YAAQ,CAAC,SACzB,gBAAgB,SAAS,MAAM,gBAAgB,MAAM,KAAK;AAAA,UAC5D;AAIA,cAAI,KAAK,eAAe,OAAQ,QAAO,SAAS,OAAO,IAAI;AAC3D,iBAAO,aAAa;AAAA,YAAQ,CAAC,SAC3B,kBAAkB,SAAS,IAAI;AAAA,UACjC;AAAA,QACF,CAAC;AAAA,MACH,CAAC;AAAA,IACH;AACA,aAAS,QAAQ,WAAW,EAAE,WAAW,MAAM,SAAS,KAAK,CAAC;AAC9D,WAAO,kBAAkB,KAAK,QAAQ;AAAA,EACxC,CAAC;AACH;AAEA,eAAsB,cACpB,SACA,SACA,SAEoB;AACpB,QAAM,SAAS,UAAU,SAAS,SAAS,QAAQ,SAAS,MAAM;AAClE,SAAO,QAAQ;AAAA,IACb,OAAO;AAAA,MAAI,CAAC,UACV,yBAAyB,SAAS;AAAA,QAChC,MAAM,GAAG,MAAM,MAAM,IAAI,MAAM,MAAM;AAAA,QACrC,GAAG;AAAA,QACH;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AACF;AAOO,SAAS,oBACd,SACA,MACA,gBACA,QACA,OACiC;AAzdnC;AA0dE,MAAI,KAAK,aAAa,EAAG,QAAO;AAChC,QAAM,OAAM,UAAK,kBAAL,mBAAoB;AAChC,MAAI,CAAC,OAAO,EAAE,gBAAgB,IAAI,aAAc,QAAO;AACvD,MAAI,aAAa,IAAI,EAAG,QAAO;AAC/B,MAAI,KAAC,+BAAa,MAAM,cAAc,EAAG,QAAO;AAEhD,QAAM,eAAoC;AAAA,IACxC;AAAA,IACA,aAAa,CAAC;AAAA,IACd,YAAY,CAAC;AAAA,IACb,QAAQ;AAAA,IACR,UAAU;AAAA,EACZ;AACA,mBAAiB,SAAS,MAAM,gBAAgB,QAAQ,YAAY;AACpE,kBAAgB,OAAO,MAAM,YAAY;AACzC,SAAO;AACT;AASO,SAAS,kBAAkB,SAAkB,WAAuB;AAnf3E;AAofE,MAAI,UAAU,aAAa,EAAG;AAC9B,QAAM,OAAM,eAAU,kBAAV,mBAAyB;AACrC,MAAI,CAAC,OAAO,EAAE,qBAAqB,IAAI,aAAc;AAErD,QAAM,iBAAiB;AAAA,IACrB,QAAQ,SAAS;AAAA,IACjB,wBAAM,SAAS;AAAA,IACf;AAAA,EACF;AAEA,MAAI,aAAa,SAAS,EAAG,aAAY,SAAS;AAClD,mBAAiB,WAAW,IAAI,cAAc,KAAK,CAAC,OAAO;AACzD,QAAI,cAAc,IAAI,eAAe,aAAa,EAAE,EAAG,aAAY,EAAE;AAAA,EACvE,CAAC;AACH;AAWA,SAAS,gBACP,SACA,MACA,gBACA,QACA,OACM;AAnhBR;AAohBE,QAAM,OAAM,UAAK,kBAAL,mBAAoB;AAChC,MAAI,CAAC,OAAO,EAAE,gBAAgB,IAAI,aAAc;AAChD,sBAAoB,SAAS,MAAM,gBAAgB,QAAQ,KAAK;AAChE,mBAAiB,MAAM,IAAI,cAAc,KAAK,CAAC,OAAO;AACpD,wBAAoB,SAAS,IAAI,gBAAgB,QAAQ,KAAK;AAAA,EAChE,CAAC;AACH;AAEA,SAAS,iBACP,SACA,MACA,gBACA,QACA,cACA;AACA,QAAM,iBAAa,+BAAa,MAAM,cAAc;AAEpD,MAAI,CAAC,WAAY;AAGjB,SAAO,OAAO,kBAAkB,UAAU,CAAC,EAAE;AAAA,IAAQ,CAAC;AAAA;AAAA,MAEpD,eAAe,QAAQ,CAAC,kBAA4C;AAElE,gBAAQ,cAAc,SAAS;AAAA,UAC7B,KAAK,SAAS;AACZ,yBAAa,SAAS,MAAM,YAAY;AACxC;AAAA,UACF,KAAK,SAAS;AACZ,wBAAY,SAAS,IAAI;AACzB;AAAA,UACF,KAAK,SAAS;AACZ;AAAA,cACE;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA,cAAc;AAAA,YAChB;AACA;AAAA,UACF,KAAK,SAAS;AACZ;AAAA,cACE;AAAA,cACA;AAAA,cACA;AAAA,cACA,cAAc;AAAA,YAChB;AACA;AAAA,UACF,KAAK,SAAS;AACZ,2BAAe,SAAS,IAAI;AAC5B,mBAAO,SAAS,IAAI,IAAI;AACxB,yBAAa,WAAW;AACxB;AAAA,UACF,KAAK,SAAS;AACZ,2BAAe,SAAS,MAAM,EAAE,UAAU,KAAK,CAAC;AAChD,mBAAO,SAAS,IAAI,IAAI;AACxB,yBAAa,WAAW;AACxB;AAAA,UACF,KAAK,SAAS;AACZ;AAAA,cACE;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA,cAAc;AAAA,YAChB;AACA;AAAA,QACJ;AAAA,MACF,CAAC;AAAA;AAAA,EACH;AACF;AAOA,SAAS,kBAAkB,IAAgC;AAjmB3D;AAkmBE,QAAM,QAAO,QAAG,iBAAH;AACb,QAAM,UAAS,6BAAM,UAAS,KAAK,CAAC,IAAI,GAAG;AAC3C,MAAI,CAAC,UAAU,OAAO,WAAW,YAAY,EAAE,aAAa;AAC1D,WAAO;AACT,SAAO;AACT;AAEA,SAAS,aAAa,SAAkB,IAAgB;AACtD,QAAM,SAAS,kBAAkB,EAAE;AACnC,MAAI,OAAQ,eAAc,SAAS,QAAQ,SAAS,KAAK;AAC3D;AAEA,SAAS,aACP,SACA,MACA,cACA;AAKA,MAAI,CAAC,aAAa,WAAY,cAAa,aAAa,IAAI,gBAAgB;AAC5E,OAAK;AAAA,IACH;AAAA,QACA,uBAAS,SAA0B,IAAgB;AACjD,YAAM,SAAS,kBAAkB,EAAE;AACnC,UAAI,OAAQ,eAAc,SAAS,QAAQ,SAAS,KAAK;AAAA,IAC3D,CAAC;AAAA,IACD,EAAE,QAAQ,aAAa,WAAW,OAAO;AAAA,EAC3C;AACF;AAEA,SAAS,YAAY,SAAkB,MAAmB;AACxD,gBAAc,SAAS,MAAM,SAAS,IAAI;AAC5C;AAEA,SAAS,aACP,SACA,MACA,QACA,cACA,gBAAwB,IACxB;AACA,QAAM,MAAM,KAAK;AACjB,QAAM,aAAa;AAAA,IACjB,MAAM;AAEJ,UAAI,CAAC,IAAI,OAAQ,eAAc,SAAS,MAAM,SAAS,KAAK;AAAA,IAC9D;AAAA,IACA,SAAS,iBAAiB,EAAE,KAAK;AAAA,EACnC;AACA,SAAO,YAAY,KAAK,UAAU;AAClC,eAAa,YAAY,KAAK,UAAU;AAC1C;AAEA,SAAS,cACP,MACA,QACA,cACA,gBAAwB,IACxB;AAEA,QAAM,QAAQ,SAAS,iBAAiB,EAAE,KAAK;AAG/C,MAAI,QAAQ,KAAK,QAAQ,IAAK;AAE9B,SAAO,eAAe,KAAK,CAAC,MAAM,KAAK,CAAC;AACxC,eAAa,SAAS;AACxB;AAEA,SAAS,cAAc,SAAkB,IAAiB;AACxD,QAAM,SAAS,kBAAkB,EAAE;AACnC,MAAI,OAAQ,eAAc,SAAS,QAAQ,SAAS,MAAM;AAC5D;AAEA,SAAS,YACP,SACA,MACA,QACA,cACA,gBAAwB,IACxB;AACA,QAAM,YAAY;AAAA,IAChB,MAAM,cAAc,SAAS,MAAM,SAAS,IAAI;AAAA,IAChD,SAAS,iBAAiB,EAAE,KAAK;AAAA,EACnC;AACA,SAAO,WAAW,KAAK,SAAS;AAChC,eAAa,WAAW,KAAK,SAAS;AACxC;AAEA,SAAS,OAAO,SAAkB,OAAkB,QAAoB;AACtE,QAAM,MAAO,MAAkB,iBAAkB;AACjD,QAAM,MAAM,IAAI;AAChB,QAAM,YAAY,CAChB,gBACAG,aACG;AACH,WAAO,eAAe,OAAO,CAAC,CAAC,SAAS,KAAK,MAAyB;AAGpE,YAAM,OAAQ,QAAwB,sBAAsB;AAG5D,UAAI,IAAI,cAAc,KAAK,IAAK,QAAO;AAGvC,YAAM,aAAa,KAAK,UAAU,QAAQ;AAE1C,YAAM,aAAa,KAAK,MAAM;AAE9B,YAAM,SAAS,aAAa,IAAI;AAEhC,YAAM,eAAe,IAAI,UAAU,cAAc,MAAM;AAGvD,UAAI,eAAe,OAAO;AAExB,sBAAcA,UAAS,SAAS,SAAS,MAAM;AAG/C,eAAO;AAAA,MACT;AAGA,aAAO;AAAA,IACT,CAAC;AAAA,EACH;AAIA,MAAI,CAAC,OAAO,gBAAgB;AAC1B,WAAO,qBAAiB,uBAAS,WAAY;AAC3C,aAAO,iBAAiB,UAAU;AAAA,QAChC;AAAA,QACA,OAAO;AAAA,QACP;AAAA,MACF;AAAA,IACF,CAAC;AAKD,UAAM,eAAe,iBAAiB,IAAI,aAAa,MAAM;AAC7D,iBAAa,iBAAiB,UAAU,OAAO,gBAAgB;AAAA,MAC7D,QAAQ,OAAO,MAAM;AAAA,IACvB,CAAC;AAAA,EACH;AACF;;;AIrvBA,IAAAC,eAAmC;AACnC,IAAAC,oBAAiC;AA6CjC,IAAM,eAAe,uBAAO;AAAA,EAC1B;AACF;AAWA,IAAM,gBAAgB,CAAC,cACrB,uBAAS,KAAK,KACd,OAAO,MAAM,aAAa,YAC1B,OAAO,MAAM,WAAW;AAK1B,IAAM,0BAA0B,CAAC,QAAgC;AAC/D,QAAM,WAAoB,QAAQ,IAAI,KAAK,YAAY;AACvD,MAAI,cAAc,QAAQ,EAAG,QAAO;AACpC,QAAM,QAAqB,EAAE,UAAU,GAAG,QAAQ,EAAE;AACpD,SAAO,eAAe,KAAK,cAAc;AAAA,IACvC,OAAO;AAAA,IACP,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,cAAc;AAAA,EAChB,CAAC;AACD,SAAO;AACT;AAEO,SAAS,eACd,SACA,SAAuE,CAAC,GACpD;AACpB,QAAM,YAAY,OAAO,QAAQ;AACjC,QAAM,YAAY,OAAO;AACzB,QAAM,SAAS,OAAO;AAEtB,QAAM,KAAK,UAAsB,oCAAiB,EAAE,IAAI,KAAK,CAAC;AAI9D,MAAI,CAAC,WAAW;AACd,WAAO;AAAA,MACL,QAAQ,MAAM,QAAQ,QAAQ,GAAG,CAAC;AAAA,MAClC,OAAO,MAAM;AAAA,MAAC;AAAA,MACd,SAAS,CAAI,OACX,QAAQ,QAAQ,EAAE,KAAK,MAAM,GAAG,CAAC;AAAA,MACnC,SAAS,MAAM;AAAA,MAAC;AAAA,IAClB;AAAA,EACF;AAGA,QAAM,WAAW,QAAQ,IAAI,WAAW,SAAS;AACjD,MAAI;AACJ,MAAI,MAAM,QAAQ,QAAQ,GAAG;AAC3B,YAAQ;AAAA,EACV,OAAO;AACL,YAAQ,CAAC;AACT,YAAQ,IAAI,WAAW,WAAW,KAAK;AAAA,EACzC;AAKA,QAAM,QAAQ,wBAAwB,KAAK;AAC3C,MAAI,UAAU;AACd,MAAI,gBAAgB,MAAM;AAC1B,MAAI,cAAc,MAAM;AACxB,MAAI,UAAmC,QAAQ,QAAQ,GAAG,CAAC;AAC3D,MAAI,OAAyB,QAAQ,QAAQ;AAI7C,QAAM,eAAe,MAAY;AAC/B,UAAM,WAAW;AACjB,UAAM,SAAS;AAAA,EACjB;AAEA,QAAM,QAAQ,CAAC,SAA2C;AACxD,QAAI,MAAM,QAAQ,IAAI,GAAG;AACvB,YAAM,CAAC,gBAAgB,GAAG,IAAI,IAAI;AAClC,aAAO,yBAAyB,SAAS,gBAAgB,GAAG,IAAI;AAAA,IAClE;AACA,WAAO,yBAAyB,SAAS,IAAI;AAAA,EAC/C;AAIA,QAAM,YAAY,OAAO,SAA6C;AACpE,QAAI;AACF,aAAO,MAAM,MAAM,IAAI;AAAA,IACzB,SAAS,OAAO;AACd,uCAAQ,KAAK,yBAAyB,EAAE,OAAO,KAAK;AACpD,iBAAO,oCAAiB,EAAE,IAAI,MAAM,CAAC;AAAA,IACvC;AAAA,EACF;AAEA,QAAM,iBAAiB,CAAC,SAA6B;AACnD,UAAM,QAAQ,KAAK,CAAC;AACpB,eAAO,uBAAS,KAAK,KAAK,MAAM,WAAW,SAAS;AAAA,EACtD;AAEA,QAAM,UAAU,CAAC,MAAiB,UAA2C;AAC3E,QAAI,CAAC,SAAS;AACZ,UAAI,eAAe,IAAI,GAAG;AAGxB,YAAI,QAAQ,cAAe,QAAO,QAAQ,QAAQ,GAAG,CAAC;AACtD,cAAMC,QAAO,QAAQ,KAAK,MAAM,UAAU,IAAI,CAAC;AAC/C,kBAAUA;AACV,wBAAgB,QAAQ;AACxB,qBAAa;AACb,eAAOA;AAAA,MACT;AAEA,aAAO,QAAQ,QAAQ,GAAG,CAAC;AAAA,IAC7B;AAIA,UAAM,OAAO,KAAK,KAAK,MAAM,UAAU,IAAI,CAAC;AAC5C,WAAO;AACP,oBAAgB,QAAQ;AACxB,kBAAc,QAAQ;AACtB,iBAAa;AACb,WAAO;AAAA,EACT;AAEA,QAAM,mBAAmB,CAAC,QAA0C;AAClE,UAAM,aAAa,cAAc,GAAG;AAIpC,UAAM,QAAQ,MAAM;AACpB,UAAM,KAAK,IAAI;AACf,QAAI,CAAC,WAAY,QAAO,QAAQ,QAAQ,GAAG,CAAC;AAC5C,WAAO,QAAQ,YAAY,KAAK;AAAA,EAClC;AAIA,QAAM,cAAc,IAAI,SAA4B;AAClD,eAAW,OAAO,KAAM,kBAAiB,GAAG;AAC5C,WAAO,MAAM;AAAA,EACf;AACA,QAAM,OAAO;AAIb,QAAM,gBAAgB,MAAM;AAC5B,WAAS,IAAI,GAAG,IAAI,eAAe,KAAK;AACtC,UAAM,aAAa,cAAc,MAAM,CAAC,CAAC;AACzC,QAAI,WAAY,SAAQ,YAAY,CAAC;AAAA,EACvC;AAEA,QAAM,SAAS,CAAC,UACd,iBAAiB,KAAK;AAExB,QAAM,QAAQ,MAAY;AAIxB,QAAI,QAAS;AACb,cAAU;AAGV,WAAO;AACP,aAAS,IAAI,aAAa,IAAI,MAAM,QAAQ,KAAK;AAC/C,YAAM,aAAa,cAAc,MAAM,CAAC,CAAC;AACzC,UAAI,CAAC,WAAY;AACjB,UAAI,eAAe,UAAU,EAAG;AAChC,YAAM,OAAO;AACb,aAAO,KAAK,KAAK,MAAM,UAAU,IAAI,CAAC;AAAA,IACxC;AAIA,kBAAc,MAAM;AACpB,oBAAgB,MAAM;AACtB,iBAAa;AAAA,EACf;AAEA,QAAM,UAAU,CAAI,OAAyC;AAC3D,UAAM,OAAO,KAAK,KAAK,MAAM,GAAG,CAAC;AAIjC,WAAO,KAAK;AAAA,MACV,MAAM;AAAA,MACN,MAAM;AAAA,IACR;AACA,WAAO;AAAA,EACT;AAEA,QAAM,UAAU,MAAY;AAE1B,YAAQ,eAAe,OAAO,MAAM;AACpC,cAAU;AACV,oBAAgB;AAChB,kBAAc;AACd,cAAU,QAAQ,QAAQ,GAAG,CAAC;AAC9B,WAAO,QAAQ,QAAQ;AAAA,EAGzB;AAEA,SAAO,EAAE,QAAQ,OAAO,SAAS,QAAQ;AAC3C;AAKA,SAAS,cAAc,YAAuC;AAC5D,QAAM,OAAO,YAAY,UAAU,IAC/B,CAAC,GAAG,MAAM,KAAK,UAAU,CAAC,IAC1B,YAAY,UAAU,IACpB,MAAM,KAAK,UAAgC,IAC3C,CAAC,UAAU;AACjB,MAAI,CAAC,MAAM,QAAQ,IAAI,KAAK,KAAK,WAAW,EAAG,QAAO;AACtD,MAAI,KAAK,WAAW,KAAK,CAAC,KAAK,CAAC,EAAG,QAAO;AAC1C,QAAM,aAAa,KAAK,CAAC;AACzB,UAAI,uBAAS,UAAU,KAAK,OAAO,KAAK,UAAoB,EAAE,WAAW,GAAG;AAC1E,WAAO;AAAA,EACT;AACA,MACE,KAAC,uBAAS,UAAU,SACpB,uBAAS,UAAU,KACnB,WAAW,KAAK,MAAM,IACtB;AACA,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAKA,SAAS,YAAY,OAAqC;AACxD,SACE,SAAS,QACT,OAAO,UAAU,YACjB,OAAO,UAAU,SAAS,KAAK,KAAK,MAAM;AAE9C;AAKA,SAAS,YAAY,OAAyB;AAC5C,SACE,SAAS,QACT,OAAO,UAAU,YACjB,YAAY,SACZ,OAAQ,MAAoB,WAAW;AAE3C;;;AC3SO,SAAS,UACd,eAA6B,CAAC,GAC9B,aACU;AACV,SAAO;AAAA,IACL,QAAQ;AAAA,IACR,UAAU;AAAA,IACV,SAAS;AAAA,IACT,KAAK;AAAA,IACL,UAAU;AAAA,IACV,OAAO,eAAe;AAAA,IACtB,GAAG;AAAA,EACL;AACF;;;ACrBA;;;ACCA,IAAAC,eAAoC;AA+B7B,SAAS,aACd,SAAuB,CAAC,GACa;AACrC,QAAM,SAAS,OAAO,UAAU;AAEhC,SAAO,SAAU,QAAiC;AAEhD,QAAI,gBAAoC;AACxC,QAAI,eAAmC;AACvC,UAAM,iBAAsD,CAAC;AAC7D,UAAM,mBAAwC,CAAC;AAC/C,UAAM,mBAA2C,CAAC;AAClD,UAAM,oBAA4C,CAAC;AACnD,UAAM,oBAAyC,CAAC;AAChD,UAAM,mBAAwC,CAAC;AAC/C,UAAM,iBAAyC,CAAC;AAGhD,aAAS,YAAY,OAA8C;AACjE,UAAI,KAAC,wBAAU,KAAK,KAAK,UAAU,KAAM,QAAO;AAEhD,UAAI,MAAM,OAAO,KAAK;AAGtB,YAAM,IAAI,QAAQ,OAAO,MAAM;AAC/B,YAAM,IAAI,QAAQ,MAAM,KAAK;AAC7B,YAAM,IAAI,QAAQ,MAAM,KAAK;AAC7B,YAAM,IAAI,QAAQ,MAAM,KAAK;AAE7B,aAAO;AAAA,IACT;AAGA,aAAS,kBAAkB,KAAkC;AAC3D,aAAO,OAAO,QAAQ,GAAG,EACtB,IAAI,CAAC,CAAC,KAAK,KAAK,MAAM,GAAG,GAAG,IAAI,YAAY,KAAK,CAAC,EAAE,EACpD,KAAK,GAAG;AAAA,IACb;AAEA,UAAM,WAA2B;AAAA,MAC/B,OAAO,MAA8B;AACnC,wBAAgB;AAChB,uBAAe;AACf,eAAO;AAAA,MACT;AAAA,MAEA,KACE,WACA,OACgB;AAChB,cAAM,YAAY,sCAAgB;AAElC,YAAI,CAAC,eAAe,SAAS,GAAG;AAC9B,yBAAe,SAAS,IAAI,CAAC;AAAA,QAC/B;AAEA,gBAAI,uBAAS,SAAS,GAAG;AACvB,yBAAe,SAAS,EAAE,SAAS,IAAI;AAAA,QACzC,OAAO;AACL,iBAAO,OAAO,eAAe,SAAS,GAAG,SAAS;AAAA,QACpD;AAEA,eAAO;AAAA,MACT;AAAA,MAEA,OACE,aACA,OACgB;AAChB,gBAAI,uBAAS,WAAW,GAAG;AACzB,2BAAiB,WAAW,IAAI;AAAA,QAClC,OAAO;AACL,iBAAO,OAAO,kBAAkB,WAAW;AAAA,QAC7C;AAEA,eAAO;AAAA,MACT;AAAA,MAEA,OACE,kBACA,aACgB;AAChB,gBAAI,uBAAS,gBAAgB,GAAG;AAC9B,kBAAI,wBAAU,WAAW,GAAG;AAE1B,6BAAiB,gBAAgB,IAAI;AAAA,UACvC,OAAO;AAEL,gBAAI,iBAAiB,SAAS,GAAG,GAAG;AAClC,oBAAM,CAAC,SAAS,MAAM,IAAI,iBAAiB,MAAM,KAAK,CAAC;AACvD,+BAAiB,OAAO,IAAI;AAAA,YAC9B,OAAO;AACL,+BAAiB,gBAAgB,IAAI;AAAA,YACvC;AAAA,UACF;AAAA,QACF,OAAO;AACL,iBAAO,OAAO,kBAAkB,gBAAgB;AAAA,QAClD;AAEA,eAAO;AAAA,MACT;AAAA,MAEA,QACE,kBACA,aACgB;AAChB,gBAAI,uBAAS,gBAAgB,GAAG;AAC9B,kBAAI,wBAAU,WAAW,GAAG;AAE1B,8BAAkB,gBAAgB,IAAI;AAAA,UACxC,OAAO;AAEL,gBAAI,iBAAiB,SAAS,GAAG,GAAG;AAClC,oBAAM,CAAC,SAAS,MAAM,IAAI,iBAAiB,MAAM,KAAK,CAAC;AACvD,gCAAkB,OAAO,IAAI;AAAA,YAC/B,OAAO;AACL,gCAAkB,gBAAgB,IAAI;AAAA,YACxC;AAAA,UACF;AAAA,QACF,OAAO;AACL,iBAAO,OAAO,mBAAmB,gBAAgB;AAAA,QACnD;AAEA,eAAO;AAAA,MACT;AAAA,MAEA,QACE,cACA,OACgB;AAChB,gBAAI,uBAAS,YAAY,GAAG;AAC1B,4BAAkB,YAAY,IAAI;AAAA,QACpC,OAAO;AACL,iBAAO,OAAO,mBAAmB,YAAY;AAAA,QAC/C;AAEA,eAAO;AAAA,MACT;AAAA,MAEA,QACE,cACA,OACgB;AAChB,gBAAI,uBAAS,YAAY,GAAG;AAC1B,2BAAiB,YAAY,IAAI;AAAA,QACnC,OAAO;AACL,iBAAO,OAAO,kBAAkB,YAAY;AAAA,QAC9C;AAEA,eAAO;AAAA,MACT;AAAA,MAEA,KACE,WACA,MACgB;AAChB,gBAAI,uBAAS,SAAS,GAAG;AACvB,yBAAe,SAAS,IAAI;AAAA,QAC9B,OAAO;AACL,iBAAO,OAAO,gBAAgB,SAAS;AAAA,QACzC;AAEA,eAAO;AAAA,MACT;AAAA,MAEA,MAA8B;AAC5B,cAAM,aAAqC,CAAC;AAG5C,YAAI,eAAe;AACjB,qBAAW,MAAM,IAAI;AAAA,QACvB;AAGA,eAAO,QAAQ,cAAc,EAAE,QAAQ,CAAC,CAAC,WAAW,KAAK,MAAM;AAC7D,cAAI,OAAO,KAAK,KAAK,EAAE,SAAS,GAAG;AACjC,kBAAM,WAAW,YACb,GAAG,MAAM,IAAI,SAAS,KACtB,GAAG,MAAM;AACb,uBAAW,QAAQ,IAAI,kBAAkB,KAAK;AAAA,UAChD;AAAA,QACF,CAAC;AAID,YAAI,OAAO,KAAK,gBAAgB,EAAE,SAAS,GAAG;AAC5C,qBAAW,GAAG,MAAM,GAAG,IAAI,kBAAkB,gBAAgB;AAAA,QAC/D;AAGA,YAAI,OAAO,KAAK,gBAAgB,EAAE,SAAS,GAAG;AAC5C,qBAAW,GAAG,MAAM,QAAQ,IAAI,kBAAkB,gBAAgB;AAAA,QACpE;AAGA,YAAI,OAAO,KAAK,iBAAiB,EAAE,SAAS,GAAG;AAC7C,qBAAW,GAAG,MAAM,SAAS,IAAI,kBAAkB,iBAAiB;AAAA,QACtE;AAGA,YAAI,OAAO,KAAK,iBAAiB,EAAE,SAAS,GAAG;AAC7C,qBAAW,GAAG,MAAM,SAAS,IAAI,kBAAkB,iBAAiB;AAAA,QACtE;AAGA,YAAI,OAAO,KAAK,gBAAgB,EAAE,SAAS,GAAG;AAC5C,qBAAW,GAAG,MAAM,SAAS,IAAI,kBAAkB,gBAAgB;AAAA,QACrE;AAGA,YAAI,OAAO,KAAK,cAAc,EAAE,SAAS,GAAG;AAC1C,qBAAW,GAAG,MAAM,MAAM,IAAI,kBAAkB,cAAc;AAAA,QAChE;AAEA,eAAO;AAAA,MACT;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AACF;;;AR/NA,IAAM,sBAAsB,uBAAO,IAAI,uCAAuC;AAI9E,SAAS,mBACP,WACuB;AACvB,SACE,cACC,OAAO,WAAW,WAAW,cAAc,WAAW,SAAS;AAEpE;AAGO,SAAS,+BAAqC;AACnD,QAAM,MAAM,mBAAmB,MAAS;AACxC,MAAI,IAAK,SAAQ,eAAe,KAAK,mBAAmB;AAC1D;AAIO,SAAS,8BAAuC;AACrD,QAAM,MAAM,mBAAmB,MAAS;AACxC,SAAO,MAAM,QAAQ,IAAI,KAAK,mBAAmB,IAAI;AACvD;AAUA,SAAS,sBAA8C;AACrD,QAAM,aAAmC;AAAA,IACvC,UAAU,UAAU,CAAC,GAAG,MAAS;AAAA,EACnC;AACA,QAAM,QAAqB,IAAI,UAC7B,QAAQ,YAAQ,oCAAiB,EAAE,IAAI,KAAK,CAAC,CAAC;AAChD,SAAO;AAAA,IACL,MAAM;AAAA,IACN,QAAQ;AAAA,IACR;AAAA,IACA,IAAI,YAAY;AAAA,IAAC;AAAA,IACjB,MAAM,YAAY;AAAA,IAAC;AAAA,IACnB,SAAS,YAAY;AAAA,IAAC;AAAA,EACxB;AACF;AA0BO,IAAM,gBAAoC,OAAO,YAAY;AAClE,QAAM,EAAE,QAAQ,KAAK,OAAO,IAAI;AAChC,QAAM,EAAE,KAAK,SAAS,QAAQ,SAAS,IAAI;AAE3C,QAAM,gBAAe,iCAAQ,aAAY,CAAC;AAC1C,QAAM,eACJ,WACC,OAAO,WAAW,WAAW,cAAc,WAAW,SAAS;AAClE,QAAM,iBACJ,aACC,OAAO,WAAW,aAAa,cAC5B,WAAW,WACX;AAKN,QAAM,cAAc,mBAAmB,YAAY;AACnD,MAAI,aAAa;AACf,QAAI,QAAQ,IAAI,aAAa,mBAAmB;AAC9C,aAAO,oBAAoB;AAG7B,WAAO,eAAe,aAAa,qBAAqB;AAAA,MACtD,OAAO;AAAA,MACP,YAAY;AAAA,MACZ,cAAc;AAAA,MACd,UAAU;AAAA,IACZ,CAAC;AAAA,EACH;AAEA,QAAM,WAAmC;AAAA,IACvC;AAAA,IACA;AAAA,EACF;AAEA,QAAM,aAAmC;AAAA,IACvC;AAAA,EACF;AAEA,QAAM,qBAAqB;AAAA,IACzB;AAAA,IACA;AAAA,IACA,WAAW;AAAA,EACb;AAKA,MAAI;AACJ,MAAI;AAIJ,QAAM,eAAe,CAAC,MAA8B;AAClD,QAAI,CAAC,EAAE,SAAU;AACjB,UAAM,CAAC,MAAM,WAAW,IAAI;AAAA,MAC1B,EAAE,UAAU;AAAA,MACZ,EAAE;AAAA,IACJ;AACA,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAMA,QAAM,WAAW,CAAC,MAA8B;AAC9C,UAAM,OAAO,QAAQ,EAAE,UAAU,YAAY,EAAE,KAAc;AAC7D,QAAI,CAAC,OAAO,KAAK,IAAI,EAAE,OAAQ;AAC/B,WAAO,yBAAyB,oBAAoB,eAAe,IAAI;AAAA,EACzE;AAKA,QAAM,OAAO,YAAY;AACvB,QAAI,CAAC,gBAAgB,CAAC,eAAgB;AAKtC,UAAM,mBACJ,SAAS,aAAa,QAClB,eAAe,oBAAoB;AAAA,MACjC,UAAM,uBAAS,SAAS,QAAQ,IAAI,SAAS,WAAW;AAAA,MACxD,QAAQ;AAAA,MACR;AAAA,IACF,CAAC,IACD;AACN,iBAAa;AAGb,UAAM,MAAM,cAAc,oBAAoB,QAAQ;AAOtD,YAAI,uBAAS,SAAS,GAAG,KAAK,SAAS,KAAK;AAC1C,YAAM,YAAyB,oBACzB,IAAI,SACJ,iBAAiB,OAAO,IAAI,KAC9B;AACJ,2BAAqB;AACrB,cAAQ,IAAI,cAAc,SAAS,KAAK,SAAS;AAAA,IACnD;AAAA,EACF;AAKA,QAAM,cAAc,OAAO,UAAoB;AAC7C,YAAQ,OAAO;AAAA,MACb,KAAK;AACH,YAAI,kBAAkB,cAAc;AAClC,8BAAoB,oBAAoB,QAAQ;AAChD,cAAI,YAAY;AAGd,uBAAW,MAAM;AAGjB,uBAAW,QAAQ,MAAM,SAAS,QAAQ,CAAC,EAAE,MAAM,MAAM;AAAA,YAAC,CAAC;AAC3D,uBAAW,QAAQ,MAAM,aAAa,QAAQ,CAAC,EAAE,MAAM,MAAM;AAAA,YAAC,CAAC;AAAA,UACjE,OAAO;AAIL,kBAAM,SAAS,QAAQ;AACvB,yBAAa,QAAQ;AAAA,UACvB;AAAA,QACF;AACA;AAAA,MAEF;AACE;AAAA,IACJ;AAAA,EACF;AAEA,QAAM,QAAqB,IAAI,SAAuC;AACpE,UAAM,CAAC,OAAO,MAAM,SAASC,UAAS,QAAQ,MAAM,IAAI;AACxD,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACAA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAGA,SAAO;AAAA,IACL,MAAM;AAAA,IACN,QAAQ;AAAA,IACR;AAAA,IACA,IAAI;AAAA,IACJ;AAAA,IACA,SAAS,YAAY;AAKnB,sBAAgB,QAAQ;AAGxB,+CAAY;AAIZ,UAAI,oBAAgB,uBAAS,SAAS,GAAG,KAAK,SAAS,KAAK;AAC1D,YAAI,QAAQ,IAAI,cAAc,SAAS,GAAG,MAAM;AAC9C,kBAAQ,eAAe,cAAc,SAAS,GAAG;AAAA,MACrD;AAIA,UAAI,YAAa,SAAQ,eAAe,aAAa,mBAAmB;AAGxE,mBAAa;AACb,2BAAqB;AAAA,IACvB;AAAA,EACF;AACF;AAEA,IAAO,gBAAQ;","names":["import_core","import_collector","import_core","import_collector","import_web_core","filter","str","elem","import_core","import_web_core","import_core","import_collector","event","scopeDoc","scopeWin","context","import_core","import_collector","link","import_core","context"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/trigger.ts","../src/walker.ts","../src/triggerVisible.ts","../src/translation.ts","../src/elbLayer.ts","../src/config.ts","../src/types/index.ts","../src/tagger.ts"],"sourcesContent":["import type { Source, On } from '@walkeros/core';\nimport type { Scope, Types, Env } from './types';\nimport type { BrowserPush, BrowserArguments } from './types/elb';\nimport { isString } from '@walkeros/core';\nimport { createPushResult } from '@walkeros/collector';\nimport {\n initTriggers,\n initScopeTrigger,\n processLoadTriggers,\n ready,\n destroyTriggers,\n} from './trigger';\nimport type { ElbLayerController } from './elbLayer';\nimport { createElbLayer } from './elbLayer';\nimport { translateToCoreCollector } from './translation';\nimport { getPageViewData, getUser } from './walker';\nimport { getConfig } from './config';\n\nexport * as SourceBrowser from './types';\n\n/**\n * Window-scoped single-instance sentinel. The browser source must be\n * single-instance per window: one elbLayer adoption, one set of DOM\n * listeners, one `window.elb`. A second/synchronous load of the tag on the\n * same page is a SEPARATE module instance, so a module-scoped counter cannot\n * see it (each load starts at 0). The marker therefore lives on the window\n * itself. A Symbol key avoids collision with page globals and is\n * non-enumerable by nature.\n */\nconst SINGLE_INSTANCE_KEY = Symbol.for('@walkeros/web-source-browser:instance');\n\ntype EnvWindow = Window & typeof globalThis;\n\nfunction resolveGuardWindow(\n envWindow: EnvWindow | undefined,\n): EnvWindow | undefined {\n return (\n envWindow ||\n (typeof globalThis.window !== 'undefined' ? globalThis.window : undefined)\n );\n}\n\n/** For tests only. Clears the window-scoped single-instance sentinel. */\nexport function __resetInstanceCountForTests(): void {\n const win = resolveGuardWindow(undefined);\n if (win) Reflect.deleteProperty(win, SINGLE_INSTANCE_KEY);\n}\n\n/** For tests only. Reads the window-scoped single-instance sentinel so tests\n * assert against the real key, not a copied string. */\nexport function __readInstanceGuardForTests(): unknown {\n const win = resolveGuardWindow(undefined);\n return win ? Reflect.get(win, SINGLE_INSTANCE_KEY) : undefined;\n}\n\n/**\n * Inert source instance returned on a second load within the same window.\n * It satisfies the `Source.Instance` contract but performs no side effects:\n * `init` does not adopt elbLayer or bind DOM triggers, `push` resolves to a\n * successful no-op result, and `on`/`destroy` do nothing. This keeps a double\n * load from re-adopting `window.elbLayer` (the production crash vector)\n * without surfacing an error to the host page.\n */\nfunction createInertInstance(): Source.Instance<Types> {\n const fullConfig: Source.Config<Types> = {\n settings: getConfig({}, undefined),\n };\n const push: BrowserPush = ((..._args: Parameters<BrowserArguments>) =>\n Promise.resolve(createPushResult({ ok: true }))) satisfies BrowserPush;\n return {\n type: 'browser',\n config: fullConfig,\n push,\n on: async () => {},\n init: async () => {},\n destroy: async () => {},\n };\n}\n\n// Export walker utility functions\nexport {\n getAllEvents,\n getEvents,\n getGlobals,\n getUser,\n getElbAttributeName,\n getElbValues,\n} from './walker';\n\n// Export tagger functionality\nexport { createTagger } from './tagger';\nexport type { TaggerConfig, TaggerInstance } from './tagger';\n\n/**\n * Browser source implementation using environment injection.\n *\n * The factory body is side-effect-free: it constructs the Instance and\n * captures closure state. All eager setup (elbLayer drain, DOM listeners,\n * `window.elb` assignment) lives in the `init` lifecycle method, which\n * the collector calls after every source factory has registered. The\n * collector strictly gates `on()` delivery: lifecycle events are queued\n * in `instance.queueOn` until the source is started.\n */\nexport const sourceBrowser: Source.Init<Types> = async (context) => {\n const { config, env, logger } = context;\n const { elb, command, window, document } = env;\n\n const userSettings = config?.settings || {};\n const actualWindow =\n window ||\n (typeof globalThis.window !== 'undefined' ? globalThis.window : undefined);\n const actualDocument =\n document ||\n (typeof globalThis.document !== 'undefined'\n ? globalThis.document\n : undefined);\n\n // Single-instance per window. A second load on the same page is a separate\n // module instance, so the marker lives on the window, not in module scope.\n // Window-less environments (SSR/node/test without a window) are not guarded.\n const guardWindow = resolveGuardWindow(actualWindow);\n if (guardWindow) {\n if (Reflect.get(guardWindow, SINGLE_INSTANCE_KEY))\n return createInertInstance();\n // Set before init() runs so a synchronous second load is caught before\n // this first instance performs its own factory/init side effects.\n Object.defineProperty(guardWindow, SINGLE_INSTANCE_KEY, {\n value: true,\n enumerable: false,\n configurable: true,\n writable: false,\n });\n }\n\n const settings: Source.Settings<Types> = getConfig(\n userSettings,\n actualDocument as Document | undefined,\n );\n\n const fullConfig: Source.Config<Types> = {\n settings,\n };\n\n const translationContext = {\n elb,\n settings,\n initScope: initScopeTrigger,\n };\n\n // The append-only elbLayer controller (created in init when elbLayer is\n // enabled) and the window.elb function we install, retained so destroy can\n // tear down exactly what this instance set up.\n let controller: ElbLayerController | undefined;\n let installedWindowElb: BrowserPush | undefined;\n\n // Helper to send pageview event if enabled. Returns the dispatch promise so\n // the enqueued run-chain link resolves when the pageview actually completes.\n const sendPageview = (s: Source.Settings<Types>) => {\n if (!s.pageview) return;\n const [data, contextData] = getPageViewData(\n s.prefix || 'data-elb',\n s.scope as Scope,\n );\n return translateToCoreCollector(\n translationContext,\n 'page view',\n data,\n 'load',\n contextData,\n );\n };\n\n // Collect declarative user identity (data-elbuser) from the scope and set it as\n // persistent collector state via the existing `walker user` command. Returns the\n // dispatch promise so the run chain can order it strictly before the pageview,\n // or undefined when no data-elbuser is present (absent = no push, never a wipe).\n const sendUser = (s: Source.Settings<Types>) => {\n const user = getUser(s.prefix || 'data-elb', s.scope as Scope);\n if (!Object.keys(user).length) return;\n return translateToCoreCollector(translationContext, 'walker user', user);\n };\n\n // Lifecycle method — eager. The collector calls this AFTER all source\n // factories have registered. Side effects allowed: adopts window.elbLayer\n // via the controller, sets up DOM listeners, installs window.elb.\n const init = async () => {\n if (!actualWindow || !actualDocument) return;\n\n // Build the append-only layer controller. It routes through the real\n // translationContext, so `walker init` reaches initScope and events flow\n // through the same funnel as direct window.elb calls.\n const activeController =\n settings.elbLayer !== false\n ? createElbLayer(translationContext, {\n name: isString(settings.elbLayer) ? settings.elbLayer : 'elbLayer',\n window: actualWindow,\n logger,\n })\n : undefined;\n controller = activeController;\n\n // Setup global triggers (click, submit) when DOM is ready\n await ready(initTriggers, translationContext, settings);\n\n // Single writer for window.elb. With a controller, calls append to the\n // layer and route through the shared chain; without one (elbLayer:false)\n // they route directly via the source's push. `activeController` is a const\n // so its truthy narrowing survives into the arrow closure — the `let\n // controller` field would widen back to `| undefined` and force a cast.\n if (isString(settings.elb) && settings.elb) {\n const windowElb: BrowserPush = activeController\n ? (((...args: Parameters<BrowserArguments>) =>\n activeController.intake(args)) satisfies BrowserPush)\n : push;\n installedWindowElb = windowElb;\n Reflect.set(actualWindow, settings.elb, windowElb);\n }\n };\n\n // Lifecycle handler — fired by the collector only when this source is\n // started (config.init=true AND config.require empty). Pre-start events\n // are buffered in instance.queueOn by the collector and replayed on start.\n const handleEvent = async (event: On.Types) => {\n switch (event) {\n case 'run':\n if (actualDocument && actualWindow) {\n processLoadTriggers(translationContext, settings);\n if (controller) {\n // Replay the recorded backlog, then set the user, then the pageview, on\n // one FIFO chain so the pageview (and every later event) carries the user.\n controller.start();\n // Fire-and-forget: the enqueue link is now rejectable, so swallow\n // its rejection here to avoid an unhandled-rejection warning.\n controller.enqueue(() => sendUser(settings)).catch(() => {});\n controller.enqueue(() => sendPageview(settings)).catch(() => {});\n } else {\n // No controller: await the user command so collector.user is set before\n // the pageview's enrichment reads it. `sendUser` returns undefined when\n // no data-elbuser is present, so this is a no-op await in that case.\n await sendUser(settings);\n sendPageview(settings);\n }\n }\n break;\n\n default:\n break;\n }\n };\n\n const push: BrowserPush = ((...args: Parameters<BrowserArguments>) => {\n const [event, data, options, context, nested, custom] = args;\n return translateToCoreCollector(\n translationContext,\n event,\n data,\n options,\n context,\n nested,\n custom,\n );\n }) satisfies BrowserPush;\n\n // Return stateless source instance with event handler and push method\n return {\n type: 'browser',\n config: fullConfig,\n push,\n on: handleEvent,\n init,\n destroy: async () => {\n // Iterates the scope registry: aborts root + per-scope listeners, clears\n // every scope's intervals/timeouts, and disconnects the shared\n // per-document observer(s). Reaches sub-scopes from `walker init <el>`,\n // not just the source's own document scope.\n destroyTriggers(settings);\n\n // Restore the layer's native push and forget controller state.\n controller?.destroy();\n\n // Remove window.elb only if it is still the function we installed — never\n // clobber a foreign global.\n if (actualWindow && isString(settings.elb) && settings.elb) {\n if (Reflect.get(actualWindow, settings.elb) === installedWindowElb)\n Reflect.deleteProperty(actualWindow, settings.elb);\n }\n\n // Clear the single-instance sentinel so a destroyed source can be\n // recreated on the same window.\n if (guardWindow) Reflect.deleteProperty(guardWindow, SINGLE_INSTANCE_KEY);\n\n // Drop references so a stray post-destroy run finds nothing to drive.\n controller = undefined;\n installedWindowElb = undefined;\n },\n };\n};\n\nexport default sourceBrowser;\n","import type { WalkerOS, Collector } from '@walkeros/core';\nimport type { Walker } from '@walkeros/web-core';\nimport type { Scope, InitScope, Settings, Context, ScopeState } from './types';\nimport { throttle, tryCatch } from '@walkeros/core';\nimport { Const, onApply } from '@walkeros/collector';\nimport { elb as elbOrg, getAttribute } from '@walkeros/web-core';\nimport {\n getElbAttributeName,\n getEvents,\n getPageViewData,\n getTriggerActions,\n queryAllComposed,\n} from './walker';\nimport {\n initVisibilityTracking,\n triggerVisible,\n destroyVisibilityTracking,\n unobserveElement,\n} from './triggerVisible';\nimport { translateToCoreCollector } from './translation';\n\n// Module-level state is intentional. The walker.js browser source is\n// single-instance per window: one elb queue, one set of DOM listeners.\n// If multi-instance ever becomes a real requirement (e.g., micro-frontends\n// with isolated walker queues), refactor this into a per-instance closure\n// returned by createSource() and route every trigger function through it.\n//\n// Root click/submit delegation lives on an instance-level controller, aborted\n// only by destroyTriggers (or re-arming initGlobalTrigger). It is deliberately\n// SEPARATE from the per-scope controllers below: a sub-scope re-init must\n// never tear down page-wide click/submit.\nlet rootAbortController: AbortController | undefined;\n\n// Iterable on purpose: destroyTriggers must enumerate every active scope to\n// reach sub-scope intervals/observers (a WeakMap could not back full teardown).\n// Note: this holds strong references to init'd scope nodes (including detached\n// DOM elements). A node init'd via `walker init <el>` and later removed from\n// the DOM without a re-init or source destroy is retained until re-init\n// replaces its entry or destroyTriggers clears the Map. Bounded by the\n// source/page session and accepted per plan §4.\nconst scopeStates = new Map<InitScope, ScopeState>();\n\n// Per-element teardown record. The reaper reads this to release exactly ONE\n// element's resources (its pulse intervals, its wait timeouts, its hover\n// listener, its visibility observation, its scroll entry) without touching the\n// rest of the scope. `scope` is the owning scope key: it selects both the owner\n// bucket (via scopeStates) and the unobserveElement key, so an element removed\n// inside a different scope's subtree is still released from its true owner.\nexport interface ElementRegistration {\n scope: InitScope;\n intervalIds: ReturnType<typeof setInterval>[];\n timeoutIds: ReturnType<typeof setTimeout>[];\n hoverAbort?: AbortController;\n scroll: boolean; // presence flag: the element itself keys into bucket.scrollElements\n observed: boolean; // presence flag: the element itself keys into bucket.observed\n}\n\n// Source-wide registry: the single authority for \"has ANY scope already wired\n// this element?\". A WeakMap is not enumerable, so the per-scope\n// ScopeState.registered set is its enumerable companion — reset/teardown iterate\n// that set to release a scope's elements from here. Invariant:\n// el ∈ bucket.registered ⟺ elementRegistry.get(el).scope === that bucket's scope.\nconst elementRegistry = new WeakMap<HTMLElement, ElementRegistration>();\n\n// Register an element as wired by `scope`, in both the enumerable per-scope set\n// and the source-wide registry. No-op (returns false) if any scope already\n// registered it (cross-scope dedup) or the scope has no live bucket. The owning\n// bucket is derived from scopeStates, never passed in, so the\n// registered/registry invariant is structural — a caller cannot register an\n// element into a bucket that mismatches `scope`.\nexport function registerElement(\n scope: InitScope,\n el: HTMLElement,\n registration: ElementRegistration,\n): boolean {\n if (elementRegistry.has(el)) return false;\n const bucket = scopeStates.get(scope);\n if (!bucket) return false;\n registration.scope = scope;\n bucket.registered.add(el);\n elementRegistry.set(el, registration);\n return true;\n}\n\n// Source-wide \"already wired?\" check: true if ANY scope registered the element.\nexport function isRegistered(el: HTMLElement): boolean {\n return elementRegistry.has(el);\n}\n\n// Release one element and un-register it, so it can register again on re-add or\n// re-scan. Self-derives the OWNING bucket from registration.scope (never a\n// caller's scope): an element owned by the document scope but removed inside a\n// sub-scope observer's subtree is still released from its true owner, keeping\n// the registered/registry invariant intact.\nexport function reapElement(el: HTMLElement): void {\n const registration = elementRegistry.get(el);\n if (!registration) return;\n\n const bucket = scopeStates.get(registration.scope);\n\n // Clear each id AND splice it from the owner's flat arrays, so a long\n // inject/remove session does not accrue dead ids there.\n registration.intervalIds.forEach((id) => {\n clearInterval(id);\n if (bucket) {\n const index = bucket.intervalIds.indexOf(id);\n if (index !== -1) bucket.intervalIds.splice(index, 1);\n }\n });\n registration.timeoutIds.forEach((id) => {\n clearTimeout(id);\n if (bucket) {\n const index = bucket.timeoutIds.indexOf(id);\n if (index !== -1) bucket.timeoutIds.splice(index, 1);\n }\n });\n\n registration.hoverAbort?.abort();\n\n if (registration.observed) {\n unobserveElement(registration.scope, el);\n bucket?.observed.delete(el);\n }\n\n if (registration.scroll && bucket) {\n // scrollElements is a [HTMLElement, number] tuple array — remove EVERY entry\n // for this element. A multi-scroll element (data-elbaction=\"scroll:50;scroll:75\")\n // pushes one tuple per trigger, so removing only the first would strand the\n // rest and fire a phantom scroll on the detached element.\n bucket.scrollElements = bucket.scrollElements.filter(\n ([element]) => element !== el,\n );\n }\n\n bucket?.registered.delete(el);\n elementRegistry.delete(el);\n}\n\n// Tear down a scope's prior state (if any), then install a fresh empty bucket.\nexport function resetScope(scope: InitScope): ScopeState {\n const previous = scopeStates.get(scope);\n if (previous) {\n previous.abort.abort(); // removes scroll listener (hover is per-element)\n // The flat clears below are the defensive baseline: they blanket-clear\n // every id/observation the scope holds. The reap loop that follows is a\n // superset per element — it additionally aborts hover, deletes the registry\n // entry, and splices the flat arrays — and it re-clears/re-unobserves the\n // same resources, which is idempotent and harmless. Both are kept so a\n // future resource that lands in a flat array without going through\n // registerScanElement (→ `registered`) is still torn down here.\n previous.intervalIds.forEach((id) => clearInterval(id));\n previous.timeoutIds.forEach((id) => clearTimeout(id));\n previous.observed.forEach((element) => unobserveElement(scope, element));\n // Release each element's per-element resources (crucially its hover\n // listener) and clear the registry so the elements can re-register on the\n // fresh scan. Snapshot the set — reapElement deletes from it as it goes.\n // reapElement self-derives this same still-current bucket (the fresh one is\n // not installed until below).\n [...previous.registered].forEach((element) => reapElement(element));\n previous.mutationObservers.forEach((observer) => observer.disconnect());\n }\n\n const fresh: ScopeState = {\n abort: new AbortController(),\n intervalIds: [],\n timeoutIds: [],\n scrollElements: [],\n observed: new Set(),\n registered: new Set(),\n mutationObservers: [],\n };\n scopeStates.set(scope, fresh);\n return fresh;\n}\n\n// Test-only accessor: exposes a scope's live bucket so suites can assert its\n// observer/registration counts and spy on real observer instances. Not\n// re-exported through src/index.ts, so the public package surface is unchanged.\nexport function getScopeState(scope: InitScope): ScopeState | undefined {\n return scopeStates.get(scope);\n}\n\n// Reset function for testing: clears each active scope's scroll state.\nexport function resetScrollListener() {\n scopeStates.forEach((state) => {\n state.scrollElements = [];\n state.scrollListener = undefined;\n });\n}\n\nexport const createElb: (customLayer?: unknown) => unknown = (customLayer?) => {\n return (\n customLayer\n ? function () {\n (customLayer as unknown[]).push(arguments);\n }\n : elbOrg\n ) as unknown;\n};\n\nexport const Triggers: { [key: string]: Walker.Trigger } = {\n Click: 'click',\n Custom: 'custom',\n Hover: 'hover',\n Load: 'load',\n Pulse: 'pulse',\n Scroll: 'scroll',\n Submit: 'submit',\n Impression: 'impression',\n Visible: 'visible',\n Wait: 'wait',\n} as const;\n\nexport async function ready(\n fn: (context: Context, settings: Settings) => void,\n context: Context,\n settings: Settings,\n): Promise<void> {\n const readyFn = () => {\n fn(context, settings);\n };\n\n const scope = settings.scope;\n if (!scope) {\n readyFn();\n return;\n }\n const doc = (scope as Element).ownerDocument || (scope as Document);\n if (doc.readyState !== 'loading') {\n readyFn();\n } else {\n doc.addEventListener('DOMContentLoaded', readyFn);\n }\n}\n\n// Called once during source initialization to setup global listeners\nexport function initTriggers(context: Context, settings: Settings) {\n if (!settings.scope) return; // Skip if no scope available\n const requiredSettings = settings as Required<Settings>;\n initGlobalTrigger(context, requiredSettings);\n}\n\n// Called on each walker run to process load triggers\nexport function processLoadTriggers(context: Context, settings: Settings) {\n if (!settings.scope) return; // Skip if no scope available\n const requiredSettings = settings as Required<Settings>;\n initScopeTrigger(context, requiredSettings);\n}\n\nexport function initGlobalTrigger(context: Context, settings: Settings): void {\n const scope = settings.scope;\n\n if (!scope) return;\n\n // Abort any previously registered root listeners before re-registering.\n // This controller owns ONLY the root click/submit delegation.\n if (rootAbortController) rootAbortController.abort();\n rootAbortController = new AbortController();\n const { signal } = rootAbortController;\n\n scope.addEventListener(\n 'click',\n tryCatch(function (this: Scope, ev: unknown) {\n triggerClick.call(this, context, ev as MouseEvent);\n }) as EventListener,\n { signal, capture: settings.capture },\n );\n scope.addEventListener(\n 'submit',\n tryCatch(function (this: Scope, ev: unknown) {\n triggerSubmit.call(this, context, ev as SubmitEvent);\n }) as EventListener,\n { signal, capture: settings.capture },\n );\n}\n\n// Full teardown: aborts the root click/submit controller, then enumerates the\n// scope registry so EVERY active scope (document and sub-scopes alike) has its\n// hover/scroll listeners aborted, intervals/timeouts cleared, and shared\n// per-document observer disconnected. Safe to call before any init.\nexport function destroyTriggers(_settings?: Settings): void {\n if (rootAbortController) {\n rootAbortController.abort();\n rootAbortController = undefined;\n }\n\n // Two passes over the scope registry. `visibilityStates` is keyed per owner\n // document (one shared observer state), while `scopeStates` holds many\n // entries per document (the document scope plus every `walker init <el>`\n // sub-scope). unobserveElement reads that shared per-document state, so every\n // scope's armed dwell timers must be cancelled BEFORE any scope tears the\n // shared state down; otherwise the first same-document destroy deletes the\n // state and later scopes' unobserve calls no-op, leaking their timers.\n scopeStates.forEach((state, scope) => {\n state.abort.abort();\n // Stop watching observe containers first, so no mutation callback fires\n // mid-teardown against a half-cleared scope.\n state.mutationObservers.forEach((observer) => observer.disconnect());\n // Flat clears are the defensive baseline superset (see resetScope): they\n // blanket-clear the scope's ids/observations. The reap loop below is the\n // per-element superset — additionally aborting hover and deleting registry\n // entries — and its re-clear/re-unobserve is idempotent.\n state.intervalIds.forEach((id) => clearInterval(id));\n state.timeoutIds.forEach((id) => clearTimeout(id));\n // Cancel armed visibility dwell timers and detach observed elements while\n // the shared per-document state still exists. Mirrors resetScope's cleanup.\n state.observed.forEach((element) => unobserveElement(scope, element));\n // Release per-element resources. Hover listeners now live on per-element\n // controllers, so state.abort.abort() above no longer covers them — reap\n // each registered element to abort its hoverAbort and clear its registry\n // entry. Snapshot the set — reapElement deletes from it as it goes.\n [...state.registered].forEach((element) => reapElement(element));\n });\n\n scopeStates.forEach((_state, scope) => {\n // Normalizes to the owner document and disconnects the shared observer;\n // the second call for a same-document sub-scope is a harmless no-op.\n destroyVisibilityTracking(scope);\n });\n\n scopeStates.clear();\n}\n\n// Scope is the single carrier: it lives only in context.settings.scope. The\n// optional second argument is kept for signature compatibility (the Context\n// `initScope` slot calls this with a single, scope-aligned context) but is not\n// read. `walker init <el>` and `walker run` (document) are the same path,\n// differing only in the scope the carrier holds. Re-running on a scope tears\n// down that scope's prior state, then attaches fresh = one fresh init.\nexport function initScopeTrigger(context: Context, _settings?: Settings) {\n const scope = context.settings.scope;\n if (!scope) return;\n\n const bucket = resetScope(scope);\n\n // Idempotent \"ensure\" of the per-document observer (one per ownerDocument).\n // Never disconnect on a sub-scope re-init — resetScope already unobserved\n // this scope's elements above.\n initVisibilityTracking(scope, 1000);\n\n // default data-elbaction\n const selectorAction = getElbAttributeName(\n context.settings.prefix,\n Const.Commands.Action,\n false,\n );\n const doc = (scope as Element).ownerDocument || (scope as Document);\n const win = doc.defaultView;\n // The element self-check only applies to an Element sub-scope. A ShadowRoot\n // scope has no getAttribute, so calling handleActionElem on it would throw;\n // it is scanned by queryAllComposed below instead. A Document scope has\n // scope === doc, so it never enters this branch.\n if (scope !== doc && win && scope instanceof win.Element) {\n // Handle the elements action(s), too\n registerScanElement(context, scope, selectorAction, bucket, scope);\n }\n\n // Handle all children action(s)\n queryAllComposed(scope, `[${selectorAction}]`, (elem) => {\n registerScanElement(context, elem, selectorAction, bucket, scope);\n });\n\n if (bucket.scrollElements.length) scroll(context, scope, bucket);\n\n // Watch [<prefix>observe] containers so tagged content injected later is\n // auto-registered (and reaped on removal) without a manual `walker init`.\n observeContainers(context, scope, bucket, selectorAction);\n}\n\n// Attach a MutationObserver to each OUTERMOST [<prefix>observe] container per\n// tree in this scope. Nesting-skip: a container contained by another candidate\n// is skipped, because a subtree:true observer already sees descendant additions\n// and nested observers double-report a single deep insertion. Node.contains does\n// not cross shadow boundaries, so a shadow-hosted container is never \"contained\"\n// by a light-DOM ancestor and correctly keeps its own observer.\nfunction observeContainers(\n context: Context,\n scope: InitScope,\n bucket: ScopeState,\n selectorAction: string,\n) {\n const doc = (scope as Element).ownerDocument || (scope as Document);\n const win = doc.defaultView;\n // Guard like createObserver's win.IntersectionObserver check so a window-less\n // environment simply no-ops instead of throwing.\n if (!win || !win.MutationObserver) return;\n\n const selectorObserve = getElbAttributeName(\n context.settings.prefix,\n 'observe',\n false,\n );\n\n // Candidate containers: the scope element itself (sub-scope self-check) plus\n // every discovered descendant, across open shadow roots.\n const containers: Element[] = [];\n if (\n scope !== doc &&\n scope instanceof win.Element &&\n scope.matches(`[${selectorObserve}]`)\n ) {\n containers.push(scope);\n }\n queryAllComposed(scope, `[${selectorObserve}]`, (el) => containers.push(el));\n\n containers.forEach((container) => {\n // Outermost-per-tree, but scope-LOCAL: `contains` only dedups candidates\n // discovered by THIS scope. Two scopes observing overlapping trees (a\n // document-scope container and a `walker init <el>` sub-scope container over\n // the same subtree) are NOT deduped here — the source-wide element registry\n // (isRegistered) makes their overlapping adds safe instead (Amendment 3, a\n // documented v1 limitation).\n const nested = containers.some(\n (other) => other !== container && other.contains(container),\n );\n if (nested) return;\n\n const observer = new win.MutationObserver(\n tryCatch((records: MutationRecord[]) => {\n // Re-read the LIVE bucket every callback: a resetScope between async\n // callbacks installs a fresh bucket and aborts this one; if the scope\n // was destroyed, bail. Never close over the creation-time bucket.\n const live = scopeStates.get(scope);\n if (!live) return;\n\n records.forEach((record) => {\n record.addedNodes.forEach((node) =>\n handleAddedNode(context, node, selectorAction, live, scope),\n );\n // Re-arm the scroll listener once per record: an added node may have\n // registered a scroll trigger into live.scrollElements. scroll() guards\n // duplicate listeners, so once-per-record is sufficient and cheap.\n if (live.scrollElements.length) scroll(context, scope, live);\n record.removedNodes.forEach((node) =>\n handleRemovedNode(context, node),\n );\n });\n }),\n );\n observer.observe(container, { childList: true, subtree: true });\n bucket.mutationObservers.push(observer);\n });\n}\n\nexport async function handleTrigger(\n context: Context,\n element: Element,\n trigger: string,\n // @TODO add triggerParams to filter for specific trigger\n): Promise<unknown[]> {\n const events = getEvents(element, trigger, context.settings.prefix);\n return Promise.all(\n events.map((event: Walker.Event) =>\n translateToCoreCollector(context, {\n name: `${event.entity} ${event.action}`,\n ...event,\n trigger,\n }),\n ),\n );\n}\n\n// Discover + register a single scanned node. Returns the built registration\n// (or undefined if the node was skipped), so callers/tests can inspect the\n// per-element resources it recorded. Guards up front: element nodes only\n// (nodeType === 1, narrowed cast-free via `instanceof win.HTMLElement`), not\n// already registered by any scope, and carrying the action attribute.\nexport function registerScanElement(\n context: Context,\n node: Node,\n selectorAction: string,\n bucket: ScopeState,\n scope: InitScope,\n): ElementRegistration | undefined {\n if (node.nodeType !== 1) return undefined;\n const win = node.ownerDocument?.defaultView;\n if (!win || !(node instanceof win.HTMLElement)) return undefined;\n if (isRegistered(node)) return undefined;\n if (!getAttribute(node, selectorAction)) return undefined;\n\n const registration: ElementRegistration = {\n scope,\n intervalIds: [],\n timeoutIds: [],\n scroll: false,\n observed: false,\n };\n handleActionElem(context, node, selectorAction, bucket, registration);\n registerElement(scope, node, registration);\n return registration;\n}\n\n// The removed-node path the MutationObserver callback invokes. Element nodes\n// only (text/comment have no .matches/.querySelectorAll and would throw). Reaps\n// `removedEl` itself and each tagged descendant that ANY scope registered.\n// reapElement is single-arg and self-derives the OWNING bucket from\n// registration.scope (Amendment 2): a document-scope-owned element removed\n// inside a sub-scope observer's subtree is released from its true owner, not the\n// remover's scope — never pass a caller's scope/bucket here.\nexport function handleRemovedNode(context: Context, removedEl: Node): void {\n if (removedEl.nodeType !== 1) return;\n const win = removedEl.ownerDocument?.defaultView;\n if (!win || !(removedEl instanceof win.HTMLElement)) return;\n\n const selectorAction = getElbAttributeName(\n context.settings.prefix,\n Const.Commands.Action,\n false,\n );\n\n if (isRegistered(removedEl)) reapElement(removedEl);\n queryAllComposed(removedEl, `[${selectorAction}]`, (el) => {\n if (el instanceof win.HTMLElement && isRegistered(el)) reapElement(el);\n });\n}\n\n// The added-node path the MutationObserver callback invokes, mirroring\n// handleRemovedNode. HTMLElement nodes only: this narrowing is deliberate, not\n// merely a text/comment guard. Text/comment nodes lack .matches/.querySelectorAll\n// and would throw, but an SVGElement HAS them — it is excluded on purpose because\n// the whole registration pipeline (the elementRegistry WeakMap, the bucket\n// HTMLElement sets, handleActionElem) is HTMLElement-typed. Do not widen to\n// Element. addedNodes holds only the top-level inserted node, so walk its tagged\n// descendants too. Registers into the passed live bucket (the caller re-reads it\n// per callback); unlike the reaper, the add path must be told where to register.\nfunction handleAddedNode(\n context: Context,\n node: Node,\n selectorAction: string,\n bucket: ScopeState,\n scope: InitScope,\n): void {\n const win = node.ownerDocument?.defaultView;\n if (!win || !(node instanceof win.HTMLElement)) return;\n registerScanElement(context, node, selectorAction, bucket, scope);\n queryAllComposed(node, `[${selectorAction}]`, (el) => {\n registerScanElement(context, el, selectorAction, bucket, scope);\n });\n}\n\nfunction handleActionElem(\n context: Context,\n elem: HTMLElement,\n selectorAction: string,\n bucket: ScopeState,\n registration: ElementRegistration,\n) {\n const actionAttr = getAttribute(elem, selectorAction);\n\n if (!actionAttr) return;\n\n // TriggersActionGroups ([trigger: string]: TriggerActions)\n Object.values(getTriggerActions(actionAttr)).forEach((triggerActions) =>\n // TriggerActions (Array<TriggerAction>)\n triggerActions.forEach((triggerAction: Walker.TriggerActions[0]) => {\n // TriggerAction ({ trigger, triggerParams, action, actionParams })\n switch (triggerAction.trigger) {\n case Triggers.Hover:\n triggerHover(context, elem, registration);\n break;\n case Triggers.Load:\n triggerLoad(context, elem);\n break;\n case Triggers.Pulse:\n triggerPulse(\n context,\n elem,\n bucket,\n registration,\n triggerAction.triggerParams,\n );\n break;\n case Triggers.Scroll:\n triggerScroll(\n elem,\n bucket,\n registration,\n triggerAction.triggerParams,\n );\n break;\n case Triggers.Impression:\n triggerVisible(context, elem);\n bucket.observed.add(elem);\n registration.observed = true;\n break;\n case Triggers.Visible:\n triggerVisible(context, elem, { multiple: true });\n bucket.observed.add(elem);\n registration.observed = true;\n break;\n case Triggers.Wait:\n triggerWait(\n context,\n elem,\n bucket,\n registration,\n triggerAction.triggerParams,\n );\n break;\n }\n }),\n );\n}\n\n/**\n * Get the actual event target, piercing open shadow DOM boundaries.\n * Uses composedPath() to find the real target inside shadow roots.\n * For closed shadow DOM, falls back to the host element (by design).\n */\nfunction getComposedTarget(ev: Event): Element | undefined {\n const path = ev.composedPath?.();\n const target = path?.length ? path[0] : ev.target;\n if (!target || typeof target !== 'object' || !('tagName' in target))\n return undefined;\n return target as Element;\n}\n\nfunction triggerClick(context: Context, ev: MouseEvent) {\n const target = getComposedTarget(ev);\n if (target) handleTrigger(context, target, Triggers.Click);\n}\n\nfunction triggerHover(\n context: Context,\n elem: HTMLElement,\n registration: ElementRegistration,\n) {\n // Per-element controller: the reaper aborts exactly this element's hover\n // listener without tearing down the scope. Reuse one controller per element\n // so multiple hover actions on the same element share (and are all released\n // by) a single abort.\n if (!registration.hoverAbort) registration.hoverAbort = new AbortController();\n elem.addEventListener(\n 'mouseenter',\n tryCatch(function (this: Document, ev: MouseEvent) {\n const target = getComposedTarget(ev);\n if (target) handleTrigger(context, target, Triggers.Hover);\n }),\n { signal: registration.hoverAbort.signal },\n );\n}\n\nfunction triggerLoad(context: Context, elem: HTMLElement) {\n handleTrigger(context, elem, Triggers.Load);\n}\n\nfunction triggerPulse(\n context: Context,\n elem: HTMLElement,\n bucket: ScopeState,\n registration: ElementRegistration,\n triggerParams: string = '',\n) {\n const doc = elem.ownerDocument;\n const intervalId = setInterval(\n () => {\n // Only trigger when tab is active\n if (!doc.hidden) handleTrigger(context, elem, Triggers.Pulse);\n },\n parseInt(triggerParams || '') || 15000,\n );\n bucket.intervalIds.push(intervalId);\n registration.intervalIds.push(intervalId);\n}\n\nfunction triggerScroll(\n elem: HTMLElement,\n bucket: ScopeState,\n registration: ElementRegistration,\n triggerParams: string = '',\n) {\n // Scroll depth in percent, default 50%\n const depth = parseInt(triggerParams || '') || 50;\n\n // Ignore invalid parameters\n if (depth < 0 || depth > 100) return;\n\n bucket.scrollElements.push([elem, depth]);\n registration.scroll = true;\n}\n\nfunction triggerSubmit(context: Context, ev: SubmitEvent) {\n const target = getComposedTarget(ev);\n if (target) handleTrigger(context, target, Triggers.Submit);\n}\n\nfunction triggerWait(\n context: Context,\n elem: HTMLElement,\n bucket: ScopeState,\n registration: ElementRegistration,\n triggerParams: string = '',\n) {\n const timeoutId = setTimeout(\n () => handleTrigger(context, elem, Triggers.Wait),\n parseInt(triggerParams || '') || 15000,\n );\n bucket.timeoutIds.push(timeoutId);\n registration.timeoutIds.push(timeoutId);\n}\n\nfunction scroll(context: Context, scope: InitScope, bucket: ScopeState) {\n const doc = (scope as Element).ownerDocument || (scope as Document);\n const win = doc.defaultView!;\n const scrolling = (\n scrollElements: Walker.ScrollElements,\n context: Context,\n ) => {\n return scrollElements.filter(([element, depth]: [Element, number]) => {\n // getBoundingClientRect is viewport-relative and composes across shadow\n // boundaries, so scroll depth is correct for shadow-nested elements.\n const rect = (element as HTMLElement).getBoundingClientRect();\n\n // Skip calculations if not in viewport yet (element top below the fold)\n if (win.innerHeight < rect.top) return true;\n\n // Height of the elements box as 100 percent base\n const elemHeight = rect.height || element.clientHeight;\n // Distance from the viewport top to the elements bottom\n const elemBottom = rect.top + elemHeight;\n // Height of the non-visible pixels below the visible screen\n const hidden = elemBottom - win.innerHeight;\n // Visible percentage of the element\n const scrollDepth = (1 - hidden / (elemHeight || 1)) * 100;\n\n // Check if the elements visibility skipped the required border\n if (scrollDepth >= depth) {\n // Enough scrolling, it's time\n handleTrigger(context, element, Triggers.Scroll);\n\n // Remove the element from scrollEvents\n return false;\n }\n\n // Keep observing the element\n return true;\n });\n };\n\n // Don't add unnecessary scroll listeners. The bucket is fresh per init, so\n // the scope's prior scroll listener was already aborted via its controller.\n if (!bucket.scrollListener) {\n bucket.scrollListener = throttle(function () {\n bucket.scrollElements = scrolling.call(\n scope,\n bucket.scrollElements,\n context,\n );\n });\n\n // A ShadowRoot never receives page scroll events, so a listener on it would\n // never fire; attach to the owner document instead. Element/Document scopes\n // keep their existing target.\n const scrollTarget = scope instanceof win.ShadowRoot ? doc : scope;\n scrollTarget.addEventListener('scroll', bucket.scrollListener, {\n signal: bucket.abort.signal,\n });\n }\n}\n","import type { WalkerOS } from '@walkeros/core';\nimport type { Walker } from '@walkeros/web-core';\nimport type { Scope } from './types';\nimport { assign, castValue, isArray, trim } from '@walkeros/core';\nimport { Const } from '@walkeros/collector';\nimport { getAttribute } from '@walkeros/web-core';\n\nexport function getElbAttributeName(\n prefix: string,\n name?: string,\n isProperty = true,\n): string {\n // separate dynamic properties from walker Const.Commands\n const separator = isProperty ? '-' : '';\n name = name != undefined ? separator + name : '';\n return prefix + name;\n}\n\nexport function getElbValues(\n prefix: string,\n element: Element,\n name: string,\n isProperty = true,\n): WalkerOS.Properties {\n const attributeValue =\n getAttribute(element, getElbAttributeName(prefix, name, isProperty)) || '';\n\n const elbValues = splitAttribute(attributeValue).reduce((values, str) => {\n let [key, val]: Walker.KeyVal = splitKeyVal(str);\n\n if (!key) return values;\n\n // Handle keys without value\n if (!val) {\n // Manually remove the : from key on empty values\n if (key.endsWith(':')) key = key.slice(0, -1);\n val = '';\n }\n\n // Dynamic values\n if (val.startsWith('#')) {\n val = val.slice(1); // Remove # symbol\n try {\n // Read property value from element\n let dynamicValue = (element as Element)[val as keyof Element];\n if (!dynamicValue && val === 'selected') {\n // Try to read selected value with chance of error\n dynamicValue = (element as HTMLSelectElement).options[\n (element as HTMLSelectElement).selectedIndex\n ].text;\n }\n\n val = String(dynamicValue);\n } catch (error) {\n val = '';\n }\n }\n\n if (key.endsWith('[]')) {\n key = key.slice(0, -2); // Remove [] symbol\n if (!isArray(values[key])) values[key] = [];\n (values[key] as WalkerOS.PropertyType[]).push(castValue(val));\n } else {\n values[key] = castValue(val);\n }\n\n return values;\n }, {} as WalkerOS.Properties);\n\n return elbValues;\n}\n\nexport function getAllEvents(\n scope: Scope,\n prefix: string = Const.Commands.Prefix,\n): Walker.Events {\n const actualScope = scope;\n if (!actualScope) return [];\n let events: Walker.Events = [];\n const action = Const.Commands.Action;\n const actionSelector = `[${getElbAttributeName(prefix, action, false)}]`;\n\n const processElementEvents = (elem: Element) => {\n Object.keys(getElbValues(prefix, elem, action, false)).forEach(\n (trigger) => {\n events = events.concat(getEvents(elem, trigger, prefix));\n },\n );\n };\n\n // Check if the scope element itself has action attributes\n const doc =\n (actualScope as Element).ownerDocument || (actualScope as Document);\n if (\n actualScope !== doc &&\n (actualScope as Element).matches?.(actionSelector)\n ) {\n processElementEvents(actualScope as Element);\n }\n\n queryAllComposed(actualScope, actionSelector, processElementEvents);\n\n return events;\n}\n\nexport function getEvents(\n target: Element,\n trigger: string,\n prefix: string = Const.Commands.Prefix,\n): Walker.Events {\n const events: Walker.Events = [];\n\n // Check for actions and get entity collection strategy\n const { actions, nearestOnly } = resolveAttributes(prefix, target, trigger);\n\n // Stop if there's no valid action combo\n if (!actions.length) return events;\n\n actions.forEach((triggerAction) => {\n const filter = splitAttribute(triggerAction.actionParams || '', ',').reduce(\n (filter, param) => {\n filter[trim(param)] = true;\n return filter;\n },\n {} as Walker.Filter,\n );\n\n // Get entities - using nearestOnly flag to determine collection strategy\n const entities = getEntities(prefix, target, filter, nearestOnly);\n\n // Use page as default entity if no one was set\n if (!entities.length) {\n const entity = 'page';\n // Only use explicit page properties and ignore generic properties\n const entitySelector = `[${getElbAttributeName(prefix, entity)}]`;\n\n // Get matching properties from the element and its parents\n const [data, context] = getThisAndParentProperties(\n target,\n entitySelector,\n prefix,\n entity,\n );\n\n entities.push({\n entity, // page\n data, // Consider only upper data\n nested: [], // Skip nested in this faked page case\n context,\n });\n }\n\n // Return a list of full events\n entities.forEach((entity) => {\n events.push({\n entity: entity.entity,\n action: triggerAction.action,\n data: entity.data,\n trigger,\n context: entity.context,\n nested: entity.nested ?? [],\n });\n });\n });\n\n return events;\n}\n\nexport function getGlobals(\n prefix: string = Const.Commands.Prefix,\n scope?: Scope,\n): WalkerOS.Properties {\n if (!scope) return {};\n const globalsName = getElbAttributeName(\n prefix,\n Const.Commands.Globals,\n false,\n );\n const globalSelector = `[${globalsName}]`;\n let values = {};\n\n queryAll(scope, globalSelector, (element) => {\n values = assign(\n values,\n getElbValues(prefix, element, Const.Commands.Globals, false),\n );\n });\n\n return values;\n}\n\nexport function getUser(\n prefix: string = Const.Commands.Prefix,\n scope?: Scope,\n): WalkerOS.User {\n if (!scope) return {};\n const userName = getElbAttributeName(prefix, Const.Commands.User, false);\n const userSelector = `[${userName}]`;\n let values: WalkerOS.User = {};\n\n queryAll(scope, userSelector, (element) => {\n values = assign(\n values,\n getElbValues(prefix, element, Const.Commands.User, false),\n );\n });\n\n return values;\n}\n\nexport function getPageViewData(\n prefix: string,\n scope: Scope,\n): [WalkerOS.Properties, WalkerOS.OrderedProperties] {\n // static page view\n const doc = (scope as Element).ownerDocument || (scope as Document);\n const win = doc.defaultView!;\n const loc = win.location;\n const page = 'page';\n const scopeElement =\n 'body' in scope ? (scope as Document).body : (scope as Element);\n const [data, context] = getThisAndParentProperties(\n scopeElement,\n `[${getElbAttributeName(prefix, page)}]`,\n prefix,\n page,\n );\n data.domain = loc.hostname;\n data.title = doc.title;\n data.referrer = doc.referrer;\n\n if (loc.search) data.search = loc.search;\n if (loc.hash) data.hash = loc.hash;\n\n // @TODO get all nested entities\n return [data, context];\n}\n\nexport function getTriggerActions(str: string): Walker.TriggersActionGroups {\n const values: Walker.TriggersActionGroups = {};\n\n const attributes = splitAttribute(str);\n\n attributes.forEach((str) => {\n const [triggerAttr, actionAttr] = splitKeyVal(str);\n const [trigger, triggerParams] = parseAttribute(triggerAttr);\n\n if (!trigger) return;\n\n let [action, actionParams] = parseAttribute(actionAttr || '');\n\n // Shortcut if trigger and action are the same (click:click)\n action = action || trigger;\n\n if (!values[trigger]) values[trigger] = [];\n\n values[trigger].push({ trigger, triggerParams, action, actionParams });\n });\n\n return values;\n}\n\nexport function getEntities(\n prefix: string,\n target: Element,\n filter?: Walker.Filter,\n nearestOnly = false,\n): WalkerOS.Entities {\n const entities: WalkerOS.Entities = [];\n let element = target as Node['parentElement'];\n\n // Unset empty filter object\n filter = Object.keys(filter || {}).length !== 0 ? filter : undefined;\n\n while (element) {\n const entity = getEntity(prefix, element, target, filter);\n if (entity) {\n entities.push(entity);\n if (nearestOnly) break; // Stop after first entity for data-elbaction\n }\n\n element = getParent(prefix, element);\n }\n\n return entities;\n}\n\nfunction getEntity(\n prefix: string,\n element: Element,\n origin?: Element,\n filter?: Walker.Filter,\n): WalkerOS.Entity | null {\n const entity = getAttribute(element, getElbAttributeName(prefix));\n\n // It's not a (valid) entity element or should be filtered\n if (!entity || (filter && !filter[entity])) return null;\n\n const scopeElems = [element]; // All related elements\n const dataSelector = `[${getElbAttributeName(\n prefix,\n entity,\n )}],[${getElbAttributeName(prefix, '')}]`; // [data-elb-entity,data-elb-]\n const linkName = getElbAttributeName(prefix, Const.Commands.Link, false); // data-elblink\n\n let data: WalkerOS.Properties = {};\n const nested: WalkerOS.Entities = [];\n const [parentData, context] = getThisAndParentProperties(\n origin || element,\n dataSelector,\n prefix,\n entity,\n true, // collect scoped generic (data-elb_) for real entities\n );\n\n // Add linked elements (data-elblink)\n queryAllComposed(element, `[${linkName}]`, (link) => {\n const [linkId, linkState]: Walker.KeyVal = splitKeyVal(\n getAttribute(link, linkName),\n );\n\n // Get all linked child elements if link is a parent\n // Note: Searches entire document including shadow roots.\n // Acceptable because link-parent usage is rare in practice.\n if (linkState === 'parent')\n queryAllComposed(\n element.ownerDocument.body,\n `[${linkName}=\"${linkId}:child\"]`,\n (wormhole) => {\n scopeElems.push(wormhole);\n\n // A linked child can also be an entity\n const nestedEntity = getEntity(prefix, wormhole);\n if (nestedEntity) nested.push(nestedEntity);\n },\n );\n });\n\n // Get all property elements including linked elements\n const propertyElems: Array<Element> = [];\n scopeElems.forEach((elem) => {\n // Also check for property on same level\n if (elem.matches(dataSelector)) propertyElems.push(elem);\n\n queryAllComposed(elem, dataSelector, (elem) => propertyElems.push(elem));\n });\n\n // Get properties\n let genericData: WalkerOS.Properties = {};\n propertyElems.forEach((child) => {\n // Eventually override closer properties\n genericData = assign(genericData, getElbValues(prefix, child, ''));\n data = assign(data, getElbValues(prefix, child, entity));\n });\n\n // Merge properties with the hierarchy generic > data > parent\n data = assign(assign(genericData, data), parentData);\n\n // Get nested entities\n scopeElems.forEach((elem) => {\n queryAllComposed(\n elem,\n `[${getElbAttributeName(prefix)}]`,\n (nestedEntityElement) => {\n const nestedEntity = getEntity(prefix, nestedEntityElement);\n if (nestedEntity) nested.push(nestedEntity);\n },\n );\n });\n\n return { entity, data, context, nested };\n}\n\nfunction getParent(prefix: string, elem: HTMLElement): HTMLElement | null {\n const linkName = getElbAttributeName(prefix, Const.Commands.Link, false); // data-elblink\n\n // Link\n if (elem.matches(`[${linkName}]`)) {\n const [linkId, linkState]: Walker.KeyVal = splitKeyVal(\n getAttribute(elem, linkName),\n );\n if (linkState === 'child') {\n // Link-parent lookup does not cross shadow boundaries.\n // Uses simple queryAll (no shadow recursion) since this runs\n // during per-event entity traversal.\n const doc = elem.ownerDocument;\n let found: HTMLElement | null = null;\n queryAll(doc, `[${linkName}=\"${linkId}:parent\"]`, (el) => {\n if (!found) found = el as HTMLElement;\n });\n return found;\n }\n }\n\n // Shadow DOM traversal\n const win = elem.ownerDocument.defaultView!;\n if (\n !elem.parentElement &&\n elem.getRootNode &&\n elem.getRootNode() instanceof win.ShadowRoot\n ) {\n return (elem.getRootNode() as ShadowRoot).host as HTMLElement;\n }\n\n return elem.parentElement;\n}\n\nfunction getThisAndParentProperties(\n element: Element,\n entitySelector: string,\n prefix: string,\n type: string,\n collectScoped = false,\n): [data: WalkerOS.Properties, context: WalkerOS.OrderedProperties] {\n let data: WalkerOS.Properties = {};\n const context: WalkerOS.OrderedProperties = {};\n let parent = element as Node['parentElement'];\n const contextSelector = `[${getElbAttributeName(\n prefix,\n Const.Commands.Context,\n false,\n )}]`;\n const scopedName = Const.Commands.Scoped; // '_' -> data-elb_\n const scopedSelector = `[${getElbAttributeName(prefix, scopedName, false)}]`;\n\n // Get all bubbling-up properties with decreasing priority\n let contextI = 0; // Context counter\n while (parent) {\n // Scoped generic (data-elb_): same generic tier, bubble-up only.\n // The synthetic page entity ignores generics, so it skips scoped too.\n // Guard on scopedName so a falsy command constant degrades to \"no scoped\n // collection\" instead of an empty suffix that would match the bare prefix.\n if (collectScoped && scopedName && parent.matches(scopedSelector)) {\n data = assign(getElbValues(prefix, parent, scopedName, false), data);\n }\n\n // Properties\n if (parent.matches(entitySelector)) {\n // Get higher properties first\n data = assign(getElbValues(prefix, parent, ''), data); // Generic\n data = assign(getElbValues(prefix, parent, type), data); // Explicit\n }\n\n // Context\n if (parent.matches(contextSelector)) {\n Object.entries(\n getElbValues(prefix, parent, Const.Commands.Context, false),\n ).forEach(([key, val]) => {\n // Don't override context with same but higher key\n if (val && !context[key]) context[key] = [val, contextI];\n });\n\n // Increase context counter with each parent level\n ++contextI;\n }\n\n parent = getParent(prefix, parent);\n }\n\n return [data, context];\n}\n\nfunction queryAll(\n scope: Document | Element,\n selector: string,\n fn: (element: Element) => void,\n): void {\n scope.querySelectorAll(selector).forEach(fn);\n}\n\n// Shadow-aware version that recurses into open shadow roots.\n// Use for discovery (init) and entity-scoped queries (small subtrees).\n// Avoid for per-event document-scoped queries (e.g. getGlobals).\nexport function queryAllComposed(\n scope: Document | Element | ShadowRoot,\n selector: string,\n fn: (element: Element) => void,\n): void {\n scope.querySelectorAll(selector).forEach(fn);\n\n const doc = (scope as Element).ownerDocument || (scope as Document);\n const win = doc.defaultView!;\n if (scope instanceof win.Element && scope.shadowRoot) {\n queryAllComposed(scope.shadowRoot, selector, fn);\n }\n scope.querySelectorAll('*').forEach((el) => {\n if (el.shadowRoot) {\n queryAllComposed(el.shadowRoot, selector, fn);\n }\n });\n}\n\nfunction resolveAttributes(\n prefix: string,\n target: Element,\n trigger: string,\n): { actions: Walker.TriggerActions; nearestOnly: boolean } {\n let element = target as Node['parentElement'];\n\n while (element) {\n // Check for data-elbactions first (takes precedence)\n const multiAttribute = getAttribute(\n element,\n getElbAttributeName(prefix, Const.Commands.Actions, false),\n );\n\n if (multiAttribute) {\n const triggerActions = getTriggerActions(multiAttribute);\n if (triggerActions[trigger]) {\n return { actions: triggerActions[trigger], nearestOnly: false };\n }\n }\n\n // Check for data-elbaction (nearest entity only)\n const singleAttribute = getAttribute(\n element,\n getElbAttributeName(prefix, Const.Commands.Action, false),\n );\n\n if (singleAttribute) {\n const triggerActions = getTriggerActions(singleAttribute);\n // Action found on element or is not a click trigger\n if (triggerActions[trigger] || trigger !== 'click') {\n return { actions: triggerActions[trigger] || [], nearestOnly: true };\n }\n }\n\n element = getParent(prefix, element);\n }\n\n return { actions: [], nearestOnly: false };\n}\n\nfunction splitAttribute(str: string, separator = ';'): Walker.Attributes {\n const values: Walker.Attributes = [];\n\n if (!str) return values;\n\n const reg = new RegExp(`(?:[^${separator}']+|'[^']*')+`, 'ig');\n return str.match(reg) || [];\n}\n\nfunction splitKeyVal(str: string): Walker.KeyVal {\n const [key, value] = str.split(/:(.+)/, 2);\n return [trim(key), trim(value)];\n}\n\nfunction parseAttribute(str: string): Walker.KeyVal {\n // action(a, b, c)\n const [key, value] = str.split('(', 2);\n const param = value ? value.slice(0, -1) : ''; // Remove the )\n // key = 'action'\n // param = 'a, b, c'\n return [key, param];\n}\n","import type { Context, InitScope } from './types';\nimport { tryCatch } from '@walkeros/core';\nimport { isVisible } from '@walkeros/web-core';\nimport { handleTrigger, Triggers } from './trigger';\n\n// Fraction of the element, or of the viewport, whichever is smaller, that must\n// be on screen along each axis.\nconst COVERAGE = 0.5;\n\n/**\n * Decide from the observer entry alone whether an element is showing enough of\n * itself to start the dwell clock. Reads no DOM and forces no layout: every\n * rect here was computed by the browser during this frame's layout pass.\n *\n * `intersectionRatio` cannot be used directly. It is a fraction of the\n * element's own area, so an element bigger than the viewport along an axis can\n * never show COVERAGE of itself along it: a 716px card in a 450px viewport\n * tops out at 0.63, and an 8000px section tops out at 0.1. Clamping the\n * requirement to `min(element, viewport)` per axis makes the bar reachable for\n * any geometry, and gives the property customers actually expect: shrinking the\n * viewport can only make the trigger fire earlier, never later.\n *\n * The clamp is per axis rather than by area on purpose. An area clamp collapses\n * back to the element-relative rule whenever the element's area is smaller than\n * the viewport's, which is exactly the wide-but-short case (a 3000x80 row tops\n * out at ratio 0.48 and never fires).\n */\nexport function isEligible(\n entry: IntersectionObserverEntry,\n win: Window,\n): boolean {\n if (!entry.isIntersecting) return false;\n\n const box = entry.boundingClientRect;\n // A zero-area target reports intersectionRatio 1 while it is intersecting\n // (spec 2.2.12). It has nothing on screen; never start a dwell for it.\n if (box.width <= 0 || box.height <= 0) return false;\n\n // rootBounds is null when the target lives in a cross-origin iframe. Falling\n // back to the window keeps the arithmetic finite: a NaN would compare false\n // and silently disable the trigger for every such element.\n const rootWidth = entry.rootBounds ? entry.rootBounds.width : win.innerWidth;\n const rootHeight = entry.rootBounds\n ? entry.rootBounds.height\n : win.innerHeight;\n if (rootWidth <= 0 || rootHeight <= 0) return false;\n\n const visible = entry.intersectionRect;\n const needWidth = COVERAGE * Math.min(box.width, rootWidth);\n const needHeight = COVERAGE * Math.min(box.height, rootHeight);\n\n return visible.width >= needWidth && visible.height >= needHeight;\n}\n\n// Threshold grid for the observer.\n//\n// An entry is queued only when the crossed threshold INDEX changes; a bare ratio\n// change queues nothing. The grid is therefore not a performance dial, it is the\n// SAMPLING RATE of the predicate: the trigger can only notice an element became\n// eligible at a grid crossing, which quantizes the arm point UPWARD to the next\n// threshold.\n//\n// A coarse grid makes that error large. Eligibility for an element of height H in\n// a viewport of height V lands at ratio COVERAGE * V/H, which for a 716px card in\n// a 450px viewport is 0.314. A grid whose next step above that is 0.4 would not\n// arm until 287px was showing, against a true bar of 225px.\n//\n// A uniform 1% grid keeps the error within about 1% of the element and costs\n// effectively nothing: the observer queues at most ONE entry per target per frame\n// however many thresholds there are.\nconst THRESHOLDS = Array.from({ length: 101 }, (_, index) => index / 100);\n\ninterface ElementConfig {\n multiple: boolean;\n blocked: boolean;\n context: Context;\n trigger: string;\n}\n\ninterface VisibilityState {\n observer?: IntersectionObserver;\n resizeObserver?: ResizeObserver;\n timers: WeakMap<HTMLElement, number>;\n duration: number;\n configs: WeakMap<HTMLElement, ElementConfig[]>;\n // Elements last seen without a layout box. A 0x0 target reports ratio 1, so\n // growing one into view never changes the threshold index and the observer\n // stays silent; the ResizeObserver re-observes to force a fresh entry.\n zeroArea: WeakSet<HTMLElement>;\n}\n\n// Module-level visibility state keyed by the owner document. Both an element\n// sub-scope and its document normalize to the same key (see getScopeKey), so\n// there is exactly one IntersectionObserver per document: create-key and\n// lookup-key can never diverge, and iframes still get their own observer.\nconst visibilityStates = new WeakMap<Document | Element, VisibilityState>();\n\n/**\n * Normalize any scope (document or element) to its owner document. The\n * IntersectionObserver root is always the viewport, so per-sub-scope observers\n * would be meaningless; keying by ownerDocument gives one shared observer per\n * document and keeps the create/lookup keys aligned.\n */\nexport function getScopeKey(scope: InitScope): Document | Element {\n return (scope as Element).ownerDocument || (scope as Document);\n}\n\nfunction createObserver(\n scope: Document | Element,\n): IntersectionObserver | undefined {\n const doc = (scope as Element).ownerDocument || (scope as Document);\n const win = doc.defaultView;\n if (!win || !win.IntersectionObserver) return undefined;\n\n return tryCatch(\n () =>\n new win.IntersectionObserver(\n (entries) => {\n entries.forEach((entry) => handleIntersection(scope, entry));\n },\n { rootMargin: '0px', threshold: THRESHOLDS },\n ),\n () => undefined,\n )();\n}\n\nfunction handleIntersection(\n scope: Document | Element,\n entry: IntersectionObserverEntry,\n): void {\n const target = entry.target as HTMLElement;\n const state = visibilityStates.get(getScopeKey(scope));\n if (!state) return;\n\n const win = target.ownerDocument.defaultView;\n if (!win) return;\n\n const configs = state.configs.get(target);\n // An entry can be queued before an unobserve lands. Never arm a dwell for an\n // element the module has already released.\n if (!configs || !configs.length) return;\n\n const existingTimer = state.timers.get(target);\n\n if (isEligible(entry, win)) {\n // Every trigger on this element has fired and is waiting to re-enter.\n if (configs.every((config) => config.blocked)) return;\n\n if (!existingTimer) {\n const timer = win.setTimeout(() => {\n fire(getScopeKey(scope), target);\n }, state.duration);\n state.timers.set(target, timer);\n }\n return;\n }\n\n // Below the bar: cancel the armed dwell and re-arm the repeating triggers.\n if (existingTimer) {\n clearTimeout(existingTimer);\n state.timers.delete(target);\n }\n configs.forEach((config) => {\n if (config.multiple) config.blocked = false;\n });\n}\n\nasync function fire(\n scope: Document | Element,\n target: HTMLElement,\n fromHidden = false,\n): Promise<void> {\n const state = visibilityStates.get(scope);\n if (!state) return;\n\n // Release the timer on EVERY path, before anything can bail. Leaving a fired\n // timer id behind makes `!existingTimer` false forever, which permanently\n // prevents the element from arming again: it is dead for the page session.\n state.timers.delete(target);\n\n const doc = target.ownerDocument;\n const win = doc.defaultView;\n if (!win) return;\n\n // Never count an impression the user could not possibly have seen. Re-arm\n // rather than drop: a page opened in a background tab has every above-the-fold\n // element already eligible, and its geometry will never change again, so the\n // observer would queue no further entry and the impression would be lost for\n // the whole session even after the user foregrounds the tab and reads the\n // page. Background timers are throttled to roughly one per second, so the\n // retry is cheap, and it stops as soon as the tab is visible.\n if (doc.visibilityState !== 'visible') {\n state.timers.set(\n target,\n win.setTimeout(() => {\n fire(scope, target, true);\n }, state.duration),\n );\n return;\n }\n\n // The expiring timer was armed while the tab was hidden, so its dwell was\n // spent hidden no matter when the user foregrounded: firing here could count\n // an impression after ~0ms of actually visible time. Require one fresh,\n // fully visible dwell instead.\n if (fromHidden) {\n state.timers.set(\n target,\n win.setTimeout(() => {\n fire(scope, target);\n }, state.duration),\n );\n return;\n }\n\n // The one and only occlusion check, uncached, on one element. A failed check\n // re-arms rather than drops: occlusion can clear without any geometry or\n // intersection change (an overlay dismissed, a carousel slide swapped in\n // place), so the observer would queue no entry and the impression would be\n // lost for the session. The retry stops on its own when the element leaves\n // the eligible band (the below-the-bar branch cancels the timer) or is\n // unobserved.\n if (!isVisible(target, win, doc)) {\n state.timers.set(\n target,\n win.setTimeout(() => {\n fire(scope, target);\n }, state.duration),\n );\n return;\n }\n\n const configs = state.configs.get(target);\n if (!configs) return;\n\n const pending = configs.filter((config) => !config.blocked);\n if (!pending.length) return;\n\n // Commit state BEFORE awaiting. handleTrigger can outlast the dwell on a slow\n // destination, and a late write would clobber state that the not-eligible\n // branch has since reset, swallowing the element's next event.\n pending.forEach((config) => {\n if (config.multiple) config.blocked = true;\n });\n\n const remaining = configs.filter((config) => config.multiple);\n if (remaining.length) {\n state.configs.set(target, remaining);\n } else {\n // Single-shot impressions are done. Unobserve before the await so a second\n // dwell cannot arm and double-fire while the destination is in flight.\n unobserveElement(scope, target);\n }\n\n await Promise.all(\n pending.map((config) =>\n handleTrigger(config.context, target, config.trigger),\n ),\n );\n}\n\nexport function unobserveElement(scope: InitScope, element: HTMLElement): void {\n const state = visibilityStates.get(getScopeKey(scope));\n if (!state) return;\n\n state.observer?.unobserve(element);\n state.resizeObserver?.unobserve(element);\n state.configs.delete(element);\n state.zeroArea.delete(element);\n\n const timer = state.timers.get(element);\n if (timer) {\n clearTimeout(timer);\n state.timers.delete(element);\n }\n}\n\n/**\n * Rescue the one case an IntersectionObserver cannot report.\n *\n * A zero-area target reports intersectionRatio 1 while it intersects (spec\n * 2.2.12). When a framework mounts an element empty and renders it a frame\n * later, the ratio goes 1 -> 1, the threshold index never changes, and the\n * observer queues NO entry - at any threshold density. Re-observing resets the\n * observer's per-target bookkeeping (previousThresholdIndex back to -1), which\n * forces a fresh entry on the next frame.\n *\n * Gated on the zero -> laid-out transition, so a resizing animation cannot turn\n * this into a per-frame re-observe storm.\n */\nfunction createResizeObserver(\n scope: Document | Element,\n): ResizeObserver | undefined {\n const doc = (scope as Element).ownerDocument || (scope as Document);\n const win = doc.defaultView;\n if (!win || !win.ResizeObserver) return undefined;\n\n return tryCatch(\n () =>\n new win.ResizeObserver((entries) => {\n const state = visibilityStates.get(scope);\n if (!state?.observer) return;\n\n entries.forEach((entry) => {\n const target = entry.target as HTMLElement;\n const { width, height } = entry.contentRect;\n const isZero = width <= 0 || height <= 0;\n\n if (isZero) {\n state.zeroArea.add(target);\n return;\n }\n\n if (!state.zeroArea.has(target)) return;\n state.zeroArea.delete(target);\n\n state.observer?.unobserve(target);\n state.observer?.observe(target);\n });\n }),\n () => undefined,\n )();\n}\n\nexport function initVisibilityTracking(\n scope: InitScope,\n duration = 1000,\n): void {\n const key = getScopeKey(scope);\n if (visibilityStates.has(key)) return;\n\n visibilityStates.set(key, {\n observer: createObserver(key),\n resizeObserver: createResizeObserver(key),\n timers: new WeakMap(),\n duration,\n configs: new WeakMap(),\n zeroArea: new WeakSet(),\n });\n}\n\nexport function triggerVisible(\n context: Context,\n element: HTMLElement,\n config: { multiple?: boolean } = { multiple: false },\n): void {\n const scope = context.settings.scope;\n if (!scope) return;\n const state = visibilityStates.get(getScopeKey(scope));\n if (!state?.observer || !element) return;\n\n const multiple = config.multiple ?? false;\n const configs = state.configs.get(element) ?? [];\n const hadConfigs = configs.length > 0;\n const trigger = multiple ? Triggers.Visible : Triggers.Impression;\n // Overlapping scans re-register the same element (a document run, then\n // `walker init` on a container that was already inside it). Replace the\n // same-trigger registration instead of appending, or every re-scan would\n // add another config and one dwell would fire duplicate events. An element\n // carries at most one `impression` plus one `visible` config.\n const entry: ElementConfig = { multiple, blocked: false, context, trigger };\n const existing = configs.findIndex(\n (existingConfig) => existingConfig.trigger === trigger,\n );\n if (existing >= 0) configs[existing] = entry;\n else configs.push(entry);\n state.configs.set(element, configs);\n\n // One element can carry both `impression` and `visible`; observe it once.\n if (hadConfigs) return;\n\n const box = element.getBoundingClientRect();\n if (box.width <= 0 || box.height <= 0) state.zeroArea.add(element);\n\n state.observer.observe(element);\n state.resizeObserver?.observe(element);\n}\n\nexport function destroyVisibilityTracking(scope?: InitScope): void {\n if (!scope) return;\n const key = getScopeKey(scope);\n const state = visibilityStates.get(key);\n if (!state) return;\n\n state.observer?.disconnect();\n state.resizeObserver?.disconnect();\n visibilityStates.delete(key);\n}\n","import type { WalkerOS, Elb, Collector } from '@walkeros/core';\nimport { isString, isObject, isElementOrDocument } from '@walkeros/core';\nimport { createPushResult } from '@walkeros/collector';\nimport type {\n BrowserPushData,\n BrowserPushOptions,\n BrowserPushContext,\n} from './types/elb';\nimport type { Context, Settings, InitScope, Scope } from './types';\nimport { getEntities, getGlobals } from './walker';\n\n/**\n * Translation layer that converts flexible browser source inputs\n * to the strict core collector format\n */\nexport function translateToCoreCollector(\n context: Context,\n eventOrCommand: unknown,\n data?: BrowserPushData,\n options?: BrowserPushOptions,\n pushContext?: BrowserPushContext,\n nested?: WalkerOS.Entities,\n custom?: WalkerOS.Properties,\n): Promise<Elb.PushResult> {\n const { elb, settings } = context;\n\n // Handle walker commands. `walker init` is browser-only (re-scans a DOM\n // scope for `data-elb*` tags and fires load triggers) and is dispatched\n // here because the collector must stay DOM-free. All other walker\n // commands route through elb to commonHandleCommand on the collector.\n // `initScope` arrives on `context` from the source factory to avoid a\n // static import of `./trigger` (which would form a load-time cycle).\n if (isString(eventOrCommand) && eventOrCommand.startsWith('walker ')) {\n if (eventOrCommand === 'walker init' && context.initScope) {\n const scopes = normalizeInitScopes(data, settings);\n for (const scope of scopes) {\n // Scope is a single carrier: build a scope-aligned context so the\n // trigger pipeline reads the new scope from context.settings.scope\n // everywhere (no diverging positional scope param).\n context.initScope({ ...context, settings: { ...settings, scope } });\n }\n return Promise.resolve(createPushResult({ ok: true }));\n }\n return elb(eventOrCommand, data as WalkerOS.Properties);\n }\n\n // Handle event objects - add source and globals if missing\n if (isObject(eventOrCommand)) {\n const event = eventOrCommand;\n if (!event.source && settings.scope) {\n const scopeDoc = ((settings.scope as Element).ownerDocument ||\n settings.scope) as Document;\n const scopeWin = scopeDoc.defaultView!;\n event.source = getBrowserSource(scopeWin, scopeDoc);\n }\n\n // Add globals if not already present\n if (!event.globals && settings.scope) {\n event.globals = isGlobalsScope(settings.scope)\n ? getGlobals(settings.prefix, settings.scope)\n : {};\n }\n\n return elb(event);\n }\n\n // Extract entity name from event string\n const [entity] = String(\n isObject(eventOrCommand) ? eventOrCommand.name : eventOrCommand,\n ).split(' ');\n\n // Get data and context either from elements or parameters\n let eventData = isObject(data) ? (data as WalkerOS.Properties) : {};\n let eventContext: WalkerOS.OrderedProperties = {};\n\n let elemParameter: undefined | Element;\n let dataIsElem = false;\n\n // Check if data parameter is an element\n if (isElementOrDocument(data)) {\n elemParameter = data as Element;\n dataIsElem = true;\n }\n\n // Check if contextData parameter is an element\n if (isElementOrDocument(pushContext)) {\n elemParameter = pushContext as Element;\n } else if (isObject(pushContext) && Object.keys(pushContext).length) {\n eventContext = pushContext as WalkerOS.OrderedProperties;\n }\n\n // Extract data from element if provided\n if (elemParameter) {\n const entityObj = getEntities(\n settings.prefix || 'data-elb',\n elemParameter,\n ).find((obj) => obj.entity === entity);\n if (entityObj) {\n if (dataIsElem) eventData = entityObj.data;\n if (entityObj.context) eventContext = entityObj.context;\n }\n }\n\n // Derive win/doc from scope for browser-specific APIs\n const scopeDoc = settings.scope\n ? (((settings.scope as Element).ownerDocument ||\n settings.scope) as Document)\n : undefined;\n const scopeWin = scopeDoc?.defaultView;\n\n // Special handling for page events\n if (entity === 'page' && scopeWin) {\n eventData.id = eventData.id || scopeWin.location.pathname;\n }\n\n // Collect globals from the DOM scope\n const eventGlobals =\n settings.scope && isGlobalsScope(settings.scope)\n ? getGlobals(settings.prefix, settings.scope)\n : {};\n\n // Build unified event from various elb usage patterns\n const event: WalkerOS.DeepPartialEvent = {\n name: String(eventOrCommand || ''),\n data: eventData,\n context: eventContext,\n globals: eventGlobals,\n nested,\n custom,\n trigger: isString(options) ? options : '',\n source:\n scopeWin && scopeDoc ? getBrowserSource(scopeWin, scopeDoc) : undefined,\n };\n\n return elb(event);\n}\n\n/**\n * Create source information for browser events\n */\nfunction getBrowserSource(win: Window, doc: Document): WalkerOS.Source {\n return {\n type: 'browser',\n platform: 'web',\n url: win.location.href,\n referrer: doc.referrer,\n };\n}\n\n/**\n * Local type guard: narrows `unknown` to `Element | Document`. Prefers the\n * native `instanceof` check (works in browsers and JSDOM) and falls back to\n * the WhatWG DOM `nodeType` property for realms where the global Element or\n * Document constructors are not in scope (cross-frame, certain test\n * runners). Returns an accurate `Element | Document` union so callers do\n * not need casts.\n */\nfunction isDomScope(value: unknown): value is InitScope {\n if (!value || typeof value !== 'object') return false;\n if (typeof Element !== 'undefined' && value instanceof Element) return true;\n if (typeof Document !== 'undefined' && value instanceof Document) return true;\n if (typeof ShadowRoot !== 'undefined' && value instanceof ShadowRoot)\n return true;\n if ('nodeType' in value) {\n const nodeType = value.nodeType;\n // 1 = ELEMENT_NODE, 9 = DOCUMENT_NODE, 11 = DOCUMENT_FRAGMENT_NODE (the\n // node type of a ShadowRoot) per the WhatWG DOM standard. Accepting 11\n // lets `walker init` target a retained closed shadow root, which discovery\n // can never reach from the document.\n return nodeType === 1 || nodeType === 9 || nodeType === 11;\n }\n return false;\n}\n\n/**\n * getGlobals accepts the narrow Scope (Document | Element). Scope is kept narrow\n * deliberately: widening it to ShadowRoot would ripple into its sibling scans\n * getPageViewData/getAllEvents, whose bodies call .matches/.body/getAttribute\n * and throw on a ShadowRoot. So a ShadowRoot init scope contributes no globals\n * ({}) by design; this guard narrows the widened carrier back to what getGlobals\n * accepts.\n */\nfunction isGlobalsScope(scope: InitScope): scope is Scope {\n return scope.nodeType !== 11; // exclude ShadowRoot (DOCUMENT_FRAGMENT_NODE)\n}\n\n/**\n * Normalize the `data` argument of `elb('walker init', data)` to an array\n * of Element/Document/ShadowRoot scopes. Falls back to `settings.scope` (or\n * `document` if settings.scope is not a DOM node) when no scope is provided.\n */\nfunction normalizeInitScopes(\n data: unknown,\n settings: Settings,\n): Array<InitScope> {\n if (isDomScope(data)) return [data];\n if (Array.isArray(data)) {\n const filtered: Array<InitScope> = [];\n for (const entry of data) {\n if (isDomScope(entry)) filtered.push(entry);\n }\n return filtered;\n }\n if (typeof data === 'undefined') {\n const fallback = settings.scope;\n if (isDomScope(fallback)) return [fallback];\n if (typeof globalThis.document !== 'undefined') {\n return [globalThis.document];\n }\n }\n return [];\n}\n","import type { Elb, Logger } from '@walkeros/core';\nimport { isString, isObject } from '@walkeros/core';\nimport { createPushResult } from '@walkeros/collector';\nimport type { Context } from './types';\nimport { translateToCoreCollector } from './translation';\n\n/**\n * Controller for the append-only `window.elbLayer` command queue.\n *\n * The layer is never spliced, truncated, or cleared: every pushed entry is\n * appended raw so inspection reflects the page's full input history. Two lanes\n * run over it. `walker *` commands process immediately from controller creation,\n * serialized on a pre-start command chain. Non-command events are recorded but\n * held until `start()`, then replayed from a cursor in original push order. The\n * command chain seeds the post-start chain, so the last pre-start command\n * strictly precedes the first replayed event.\n *\n * A drained boundary is persisted on the array (see DRAIN_MARKER) so a\n * controller adopting an already-populated array (destroy/recreate on the same\n * window) resumes PAST what a prior controller dispatched instead of replaying\n * the whole backlog and double-firing every command and event.\n */\nexport interface ElbLayerController {\n /** Append an entry to the layer and route it. Returns the processing result. */\n intake(entry: unknown[]): Promise<Elb.PushResult>;\n /** Begin consuming recorded events. Idempotent: a second call is a no-op. */\n start(): void;\n /**\n * Append arbitrary work to the FIFO chain, after everything queued so far.\n * `fn` must not await the controller's own chain: calling `enqueue`/`intake`\n * from inside a chain item and awaiting the result deadlocks (it waits on a\n * promise scheduled behind itself). Pushing new entries mid-dispatch is safe\n * — that appends a link, it does not await one.\n */\n enqueue<T>(fn: () => Promise<T> | T): Promise<T>;\n /** Restore the array's native push and forget internal state. */\n destroy(): void;\n}\n\n/**\n * Drained-boundary marker persisted on the layer array. Stored under a\n * non-enumerable Symbol so it never appears in inspection, iteration, or JSON:\n * the array stays append-only and reflects the page's full input history, yet a\n * later controller can read where the lanes already drained. `Symbol.for` keeps\n * the key stable across module instances, matching the window single-instance\n * sentinel convention.\n */\nconst DRAIN_MARKER = Symbol.for(\n '@walkeros/web-source-browser:elbLayer-drained',\n);\n\ninterface DrainMarker {\n // Leading entries whose command lane has drained: every `walker *` command at\n // a lower index has already been routed.\n commands: number;\n // Leading entries whose event lane has drained: every non-command event at a\n // lower index has already been replayed.\n events: number;\n}\n\nconst isDrainMarker = (value: unknown): value is DrainMarker =>\n isObject(value) &&\n typeof value.commands === 'number' &&\n typeof value.events === 'number';\n\n// Return the array's existing marker (the same object, so this controller's\n// writes persist on the array) or install a fresh zeroed one. Non-enumerable +\n// configurable so it stays invisible to inspection yet re-readable later.\nconst readOrCreateDrainMarker = (arr: unknown[]): DrainMarker => {\n const existing: unknown = Reflect.get(arr, DRAIN_MARKER);\n if (isDrainMarker(existing)) return existing;\n const fresh: DrainMarker = { commands: 0, events: 0 };\n Object.defineProperty(arr, DRAIN_MARKER, {\n value: fresh,\n writable: true,\n enumerable: false,\n configurable: true,\n });\n return fresh;\n};\n\nexport function createElbLayer(\n context: Context,\n config: { name?: string; window?: Window; logger?: Logger.Instance } = {},\n): ElbLayerController {\n const layerName = config.name || 'elbLayer';\n const windowObj = config.window;\n const logger = config.logger;\n\n const ok = (): Elb.PushResult => createPushResult({ ok: true });\n\n // Window-less environments (SSR/node) cannot host a layer. Return an inert\n // controller so callers never branch on undefined.\n if (!windowObj) {\n return {\n intake: () => Promise.resolve(ok()),\n start: () => {},\n enqueue: <T>(fn: () => Promise<T> | T) =>\n Promise.resolve().then(() => fn()),\n destroy: () => {},\n };\n }\n\n // Ensure the named array exists without ever replacing an existing one.\n const existing = Reflect.get(windowObj, layerName);\n let layer: unknown[];\n if (Array.isArray(existing)) {\n layer = existing;\n } else {\n layer = [];\n Reflect.set(windowObj, layerName, layer);\n }\n\n // Adopt any drained boundary a prior controller left on this array. A fresh\n // array reads {0, 0}, reproducing the original replay-the-whole-backlog-once\n // behavior; a recreated one resumes past what already ran.\n const drain = readOrCreateDrainMarker(layer);\n let started = false;\n let commandCursor = drain.commands;\n let eventCursor = drain.events;\n let cmdTail: Promise<Elb.PushResult> = Promise.resolve(ok());\n let tail: Promise<unknown> = Promise.resolve();\n\n // Mirror the live cursors onto the array-backed marker so the next controller\n // adopting this array (destroy/recreate) resumes from the current boundary.\n const persistDrain = (): void => {\n drain.commands = commandCursor;\n drain.events = eventCursor;\n };\n\n const route = (item: unknown): Promise<Elb.PushResult> => {\n if (Array.isArray(item)) {\n const [eventOrCommand, ...rest] = item;\n return translateToCoreCollector(context, eventOrCommand, ...rest);\n }\n return translateToCoreCollector(context, item);\n };\n\n // One bad entry must not break the chain: isolate each route so a throw\n // resolves ok:false and the FIFO continues.\n const routeSafe = async (item: unknown[]): Promise<Elb.PushResult> => {\n try {\n return await route(item);\n } catch (error) {\n logger?.warn('elbLayer entry failed', { error, item });\n return createPushResult({ ok: false });\n }\n };\n\n const isCommandEntry = (item: unknown[]): boolean => {\n const first = item[0];\n return isString(first) && first.startsWith('walker ');\n };\n\n const process = (item: unknown[], index: number): Promise<Elb.PushResult> => {\n if (!started) {\n if (isCommandEntry(item)) {\n // A prior controller on this array already routed commands below the\n // marker boundary — never route them a second time.\n if (index < commandCursor) return Promise.resolve(ok());\n const link = cmdTail.then(() => routeSafe(item));\n cmdTail = link;\n commandCursor = index + 1;\n persistDrain();\n return link;\n }\n // Pre-start event: recorded in the layer, replayed on start().\n return Promise.resolve(ok());\n }\n // Post-start every entry serializes on the shared tail and drains both\n // lanes. A later start() is barred by the started flag, so these are never\n // replayed.\n const link = tail.then(() => routeSafe(item));\n tail = link;\n commandCursor = index + 1;\n eventCursor = index + 1;\n persistDrain();\n return link;\n };\n\n const appendAndProcess = (raw: unknown): Promise<Elb.PushResult> => {\n const normalized = normalizeItem(raw);\n // Append the raw arg so inspection shows exactly what the page pushed.\n // Index-assign, not layer.push(raw): push here is our own wrappedPush\n // override, so calling it would recurse into this function.\n const index = layer.length;\n layer[index] = raw;\n if (!normalized) return Promise.resolve(ok());\n return process(normalized, index);\n };\n\n // Live capture: normalize, append raw, route. Returns the array's new length\n // to honor the Array.push contract.\n const wrappedPush = (...args: unknown[]): number => {\n for (const arg of args) appendAndProcess(arg);\n return layer.length;\n };\n layer.push = wrappedPush;\n\n // Backlog present at creation flows through the same lanes without being\n // re-appended: commands run now via the command chain, events wait for start.\n const backlogLength = layer.length;\n for (let i = 0; i < backlogLength; i++) {\n const normalized = normalizeItem(layer[i]);\n if (normalized) process(normalized, i);\n }\n\n const intake = (entry: unknown[]): Promise<Elb.PushResult> =>\n appendAndProcess(entry);\n\n const start = (): void => {\n // Runs at most once (started flag). A second call must not re-seed tail\n // from cmdTail — that would rewind the chain past work enqueued after\n // start and orphan it. The cursor only marks the pre-start backlog boundary.\n if (started) return;\n started = true;\n // Seed the post-start chain from the command chain so the last pre-start\n // command strictly precedes the first replayed event.\n tail = cmdTail;\n for (let i = eventCursor; i < layer.length; i++) {\n const normalized = normalizeItem(layer[i]);\n if (!normalized) continue;\n if (isCommandEntry(normalized)) continue; // already ran pre-start\n const item = normalized;\n tail = tail.then(() => routeSafe(item));\n }\n // Both lanes are now drained up to the current length: every pre-start\n // command ran on intake and every recorded event has been scheduled. Record\n // the boundary so a later controller adopting this array resumes past it.\n eventCursor = layer.length;\n commandCursor = layer.length;\n persistDrain();\n };\n\n const enqueue = <T>(fn: () => Promise<T> | T): Promise<T> => {\n const link = tail.then(() => fn());\n // A rejected enqueue must not wedge the shared chain: advance tail through a\n // swallow so later enqueues and post-start events still run. The returned\n // link stays rejectable so awaiting callers still observe the rejection.\n tail = link.then(\n () => undefined,\n () => undefined,\n );\n return link;\n };\n\n const destroy = (): void => {\n // Drop the own-property override so pushes fall back to Array.prototype.push.\n Reflect.deleteProperty(layer, 'push');\n started = false;\n commandCursor = 0;\n eventCursor = 0;\n cmdTail = Promise.resolve(ok());\n tail = Promise.resolve();\n // The array's drained marker is intentionally KEPT: it is the append-only\n // array's memory of what already ran, so a recreate resumes past it.\n };\n\n return { intake, start, enqueue, destroy };\n}\n\n/**\n * Normalize a queue item into an Array (or null if invalid/empty).\n */\nfunction normalizeItem(pushedItem: unknown): unknown[] | null {\n const item = isArguments(pushedItem)\n ? [...Array.from(pushedItem)]\n : isArrayLike(pushedItem)\n ? Array.from(pushedItem as ArrayLike<unknown>)\n : [pushedItem];\n if (!Array.isArray(item) || item.length === 0) return null;\n if (item.length === 1 && !item[0]) return null;\n const firstParam = item[0];\n if (isObject(firstParam) && Object.keys(firstParam as object).length === 0) {\n return null;\n }\n if (\n !isObject(firstParam) &&\n isString(firstParam) &&\n firstParam.trim() === ''\n ) {\n return null;\n }\n return item;\n}\n\n/**\n * Check if value is arguments object\n */\nfunction isArguments(value: unknown): value is IArguments {\n return (\n value != null &&\n typeof value === 'object' &&\n Object.prototype.toString.call(value) === '[object Arguments]'\n );\n}\n\n/**\n * Check if value is array-like (has length property)\n */\nfunction isArrayLike(value: unknown): boolean {\n return (\n value != null &&\n typeof value === 'object' &&\n 'length' in value &&\n typeof (value as unknown[]).length === 'number'\n );\n}\n","import type { InitSettings, Settings } from './types';\n\n/**\n * Get browser source configuration with defaults\n * @param initSettings - Initial settings to override defaults\n * @param envDocument - Document from environment (optional)\n * @returns Complete settings object with all defaults applied\n */\nexport function getConfig(\n initSettings: InitSettings = {},\n envDocument?: Document,\n): Settings {\n return {\n prefix: 'data-elb',\n pageview: true,\n capture: true,\n elb: 'elb',\n elbLayer: 'elbLayer',\n scope: envDocument || undefined,\n ...initSettings,\n };\n}\n","import type { Source, Elb } from '@walkeros/core';\nimport type { Walker } from '@walkeros/web-core';\nimport type { SettingsSchema } from '../schemas';\nimport type { z } from '@walkeros/core/dev';\n\n// Export browser-specific elb types\nexport * from './elb';\nimport type { BrowserPush } from './elb';\n\ndeclare module '@walkeros/core' {\n interface SourceMap {\n browser: {\n type: 'browser';\n platform: 'web';\n url?: string;\n referrer?: string;\n };\n }\n}\n\n// Base settings from Zod schema\ntype BaseSettings = z.infer<typeof SettingsSchema>;\n\n// InitSettings: what users provide (all optional)\n// Override specific fields with non-serializable types\nexport interface InitSettings extends Partial<\n Omit<BaseSettings, 'scope' | 'elbLayer'>\n> {\n scope?: InitScope;\n elbLayer?: boolean | string | Elb.Layer;\n}\n\n// Settings: resolved configuration\n// Override specific fields with non-serializable types\nexport interface Settings extends Omit<BaseSettings, 'scope' | 'elbLayer'> {\n scope?: InitScope;\n elbLayer: boolean | string | Elb.Layer;\n}\n\nexport interface Mapping {}\n\nexport type Push = BrowserPush;\n\nexport interface Env extends Source.BaseEnv {\n elb: Elb.Fn;\n window?: Window & typeof globalThis;\n document?: Document;\n}\n\nexport type Types = Source.Types<Settings, Mapping, Push, Env, InitSettings>;\n\nexport type Config = Source.Config<Types>;\n\nexport interface Context {\n elb: Elb.Fn;\n settings: Settings;\n // Scope travels in context.settings.scope; the implementation reads it from\n // there. Called with a single, scope-aligned context for `walker init`.\n initScope?: (context: Context) => void;\n}\n\n// Scope types live in the leaf `./scope` module so `types/elb.ts` can reuse\n// them without a circular import. Imported for local use (Settings.scope below)\n// and re-exported so `SourceBrowser.Scope` / `.InitScope` stay part of the\n// public surface.\nexport type { Scope, InitScope } from './scope';\nimport type { InitScope } from './scope';\n\n// Everything a single scope's init installs, bucketed so a re-init can tear the\n// scope's prior state down before attaching fresh. Keyed by the scope node, so\n// `walker run` (document) and `walker init <el>` (element) own independent\n// buckets that never reach into each other.\nexport interface ScopeState {\n abort: AbortController; // this scope's scroll listener (hover is per-element)\n intervalIds: ReturnType<typeof setInterval>[]; // pulse\n timeoutIds: ReturnType<typeof setTimeout>[]; // wait\n scrollElements: Walker.ScrollElements; // this scope's scroll targets\n scrollListener?: EventListenerOrEventListenerObject;\n observed: Set<HTMLElement>; // elements registered on the shared per-doc observer\n registered: Set<HTMLElement>; // every element this scope has wired triggers for\n mutationObservers: MutationObserver[]; // this scope's observe-container observers\n}\n","import type { WalkerOS } from '@walkeros/core';\nimport { isString, isDefined } from '@walkeros/core';\n\nexport interface TaggerConfig {\n prefix?: string;\n}\n\nexport interface TaggerInstance {\n entity: (name: string) => TaggerInstance;\n data: ((key: string, value: WalkerOS.Property) => TaggerInstance) &\n ((data: WalkerOS.Properties) => TaggerInstance);\n scoped: ((key: string, value: WalkerOS.Property) => TaggerInstance) &\n ((scoped: WalkerOS.Properties) => TaggerInstance);\n action: ((trigger: string, action?: string) => TaggerInstance) &\n ((actions: Record<string, string>) => TaggerInstance);\n actions: ((trigger: string, action?: string) => TaggerInstance) &\n ((actions: Record<string, string>) => TaggerInstance);\n context: ((key: string, value: WalkerOS.Property) => TaggerInstance) &\n ((context: WalkerOS.Properties) => TaggerInstance);\n globals: ((key: string, value: WalkerOS.Property) => TaggerInstance) &\n ((globals: WalkerOS.Properties) => TaggerInstance);\n link: ((id: string, type: string) => TaggerInstance) &\n ((links: Record<string, string>) => TaggerInstance);\n get: () => Record<string, string>;\n}\n\n/**\n * Creates a new tagger instance for generating walkerOS data attributes.\n *\n * @param config The configuration for the tagger.\n * @returns A new tagger instance.\n */\nexport function createTagger(\n config: TaggerConfig = {},\n): (entity?: string) => TaggerInstance {\n const prefix = config.prefix || 'data-elb';\n\n return function (entity?: string): TaggerInstance {\n // Internal state\n let currentEntity: string | undefined = undefined; // Only set via .entity() method\n let namingEntity: string | undefined = entity; // Used for data attribute naming\n const dataProperties: Record<string, WalkerOS.Properties> = {};\n const scopedProperties: WalkerOS.Properties = {};\n const actionProperties: Record<string, string> = {};\n const actionsProperties: Record<string, string> = {};\n const contextProperties: WalkerOS.Properties = {};\n const globalProperties: WalkerOS.Properties = {};\n const linkProperties: Record<string, string> = {};\n\n // Helper function to escape special characters\n function escapeValue(value: WalkerOS.Property | undefined): string {\n if (!isDefined(value) || value === null) return 'undefined';\n\n let str = String(value);\n\n // Escape backslashes first, then other characters\n str = str.replace(/\\\\/g, '\\\\\\\\');\n str = str.replace(/;/g, '\\\\;');\n str = str.replace(/:/g, '\\\\:');\n str = str.replace(/'/g, \"\\\\'\");\n\n return str;\n }\n\n // Helper function to serialize key-value pairs\n function serializeKeyValue(obj: WalkerOS.Properties): string {\n return Object.entries(obj)\n .map(([key, value]) => `${key}:${escapeValue(value)}`)\n .join(';');\n }\n\n const instance: TaggerInstance = {\n entity(name: string): TaggerInstance {\n currentEntity = name;\n namingEntity = name; // Always update naming scope when entity is set\n return instance;\n },\n\n data(\n keyOrData: string | WalkerOS.Properties,\n value?: WalkerOS.Property,\n ): TaggerInstance {\n const entityKey = namingEntity ?? '';\n\n if (!dataProperties[entityKey]) {\n dataProperties[entityKey] = {};\n }\n\n if (isString(keyOrData)) {\n dataProperties[entityKey][keyOrData] = value;\n } else {\n Object.assign(dataProperties[entityKey], keyOrData);\n }\n\n return instance;\n },\n\n scoped(\n keyOrScoped: string | WalkerOS.Properties,\n value?: WalkerOS.Property,\n ): TaggerInstance {\n if (isString(keyOrScoped)) {\n scopedProperties[keyOrScoped] = value;\n } else {\n Object.assign(scopedProperties, keyOrScoped);\n }\n\n return instance;\n },\n\n action(\n triggerOrActions: string | Record<string, string>,\n actionValue?: string,\n ): TaggerInstance {\n if (isString(triggerOrActions)) {\n if (isDefined(actionValue)) {\n // Two parameters: trigger and action\n actionProperties[triggerOrActions] = actionValue;\n } else {\n // Single parameter: could be \"trigger:action\" or just \"trigger\"\n if (triggerOrActions.includes(':')) {\n const [trigger, action] = triggerOrActions.split(':', 2);\n actionProperties[trigger] = action;\n } else {\n actionProperties[triggerOrActions] = triggerOrActions;\n }\n }\n } else {\n Object.assign(actionProperties, triggerOrActions);\n }\n\n return instance;\n },\n\n actions(\n triggerOrActions: string | Record<string, string>,\n actionValue?: string,\n ): TaggerInstance {\n if (isString(triggerOrActions)) {\n if (isDefined(actionValue)) {\n // Two parameters: trigger and action\n actionsProperties[triggerOrActions] = actionValue;\n } else {\n // Single parameter: could be \"trigger:action\" or just \"trigger\"\n if (triggerOrActions.includes(':')) {\n const [trigger, action] = triggerOrActions.split(':', 2);\n actionsProperties[trigger] = action;\n } else {\n actionsProperties[triggerOrActions] = triggerOrActions;\n }\n }\n } else {\n Object.assign(actionsProperties, triggerOrActions);\n }\n\n return instance;\n },\n\n context(\n keyOrContext: string | WalkerOS.Properties,\n value?: WalkerOS.Property,\n ): TaggerInstance {\n if (isString(keyOrContext)) {\n contextProperties[keyOrContext] = value;\n } else {\n Object.assign(contextProperties, keyOrContext);\n }\n\n return instance;\n },\n\n globals(\n keyOrGlobals: string | WalkerOS.Properties,\n value?: WalkerOS.Property,\n ): TaggerInstance {\n if (isString(keyOrGlobals)) {\n globalProperties[keyOrGlobals] = value;\n } else {\n Object.assign(globalProperties, keyOrGlobals);\n }\n\n return instance;\n },\n\n link(\n idOrLinks: string | Record<string, string>,\n type?: string,\n ): TaggerInstance {\n if (isString(idOrLinks)) {\n linkProperties[idOrLinks] = type!;\n } else {\n Object.assign(linkProperties, idOrLinks);\n }\n\n return instance;\n },\n\n get(): Record<string, string> {\n const attributes: Record<string, string> = {};\n\n // Add entity attribute if set\n if (currentEntity) {\n attributes[prefix] = currentEntity;\n }\n\n // Add data attributes\n Object.entries(dataProperties).forEach(([entityKey, props]) => {\n if (Object.keys(props).length > 0) {\n const attrName = entityKey\n ? `${prefix}-${entityKey}`\n : `${prefix}-`;\n attributes[attrName] = serializeKeyValue(props);\n }\n });\n\n // Add scoped generic attribute (data-elb_): branch-scoped, bubble-up\n // only. Suffix must match Const.Commands.Scoped ('_').\n if (Object.keys(scopedProperties).length > 0) {\n attributes[`${prefix}_`] = serializeKeyValue(scopedProperties);\n }\n\n // Add action attributes\n if (Object.keys(actionProperties).length > 0) {\n attributes[`${prefix}action`] = serializeKeyValue(actionProperties);\n }\n\n // Add actions attributes (for all entities)\n if (Object.keys(actionsProperties).length > 0) {\n attributes[`${prefix}actions`] = serializeKeyValue(actionsProperties);\n }\n\n // Add context attributes\n if (Object.keys(contextProperties).length > 0) {\n attributes[`${prefix}context`] = serializeKeyValue(contextProperties);\n }\n\n // Add global attributes\n if (Object.keys(globalProperties).length > 0) {\n attributes[`${prefix}globals`] = serializeKeyValue(globalProperties);\n }\n\n // Add link attributes\n if (Object.keys(linkProperties).length > 0) {\n attributes[`${prefix}link`] = serializeKeyValue(linkProperties);\n }\n\n return attributes;\n },\n };\n\n return instance;\n };\n}\n"],"mappings":"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","names":["import_core","import_collector","import_core","import_collector","import_web_core","filter","str","elem","import_core","import_web_core","import_core","import_collector","event","scopeDoc","scopeWin","context","import_core","import_collector","link","import_core","context"]}
|