@walkeros/web-source-browser 4.1.0 → 4.1.1-next-1779822275564
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 +16 -0
- package/dist/dev.js.map +1 -1
- package/dist/dev.mjs.map +1 -1
- package/dist/index.browser.js +1 -1
- package/dist/index.d.mts +4 -1
- package/dist/index.d.ts +4 -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/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# @walkeros/web-source-browser
|
|
2
2
|
|
|
3
|
+
## 4.1.1-next-1779822275564
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- edd3836: The browser source now releases its DOM event listeners, pulse
|
|
8
|
+
intervals, and wait timeouts when the source is destroyed. This prevents
|
|
9
|
+
memory growth and avoids duplicate events when the source is torn down or
|
|
10
|
+
re-initialized.
|
|
11
|
+
- Updated dependencies [b0279ee]
|
|
12
|
+
- Updated dependencies [b0279ee]
|
|
13
|
+
- Updated dependencies [0b7f494]
|
|
14
|
+
- Updated dependencies [edd3836]
|
|
15
|
+
- @walkeros/core@4.1.1-next-1779822275564
|
|
16
|
+
- @walkeros/collector@4.1.1-next-1779822275564
|
|
17
|
+
- @walkeros/web-core@4.1.1-next-1779822275564
|
|
18
|
+
|
|
3
19
|
## 4.1.0
|
|
4
20
|
|
|
5
21
|
### Minor Changes
|
package/dist/dev.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/dev.ts","../src/schemas/index.ts","../src/schemas/settings.ts","../src/schemas/primitives.ts","../src/schemas/tagger.ts","../src/examples/index.ts","../src/examples/env.ts","../src/examples/step.ts","../src/examples/trigger.ts","../src/trigger.ts","../src/walker.ts","../src/triggerVisible.ts","../src/translation.ts"],"sourcesContent":["export * as schemas from './schemas';\nexport * as examples from './examples';\n","import { zodToSchema } from '@walkeros/core/dev';\nimport { SettingsSchema } from './settings';\nimport { TaggerSchema } from './tagger';\n\n// Export primitives\nexport * from './primitives';\n\n// Export Zod schemas and types\nexport { SettingsSchema, type Settings } from './settings';\nexport { TaggerSchema, type TaggerConfig } from './tagger';\n\n// JSON Schema exports (for website PropertyTable and explorer RJSF)\nexport const settings = zodToSchema(SettingsSchema);\nexport const tagger = zodToSchema(TaggerSchema);\n","import { z } from '@walkeros/core/dev';\nimport {\n DataAttributePrefix,\n JavaScriptVarName,\n ScopeSelector,\n} from './primitives';\n\n/**\n * ELB Layer configuration schema\n * Note: Runtime type can be boolean | string | Elb.Layer\n */\nconst ElbLayerConfigSchema = z.union([\n z.boolean(),\n z.string(),\n z.any().describe('Elb.Layer array for async command queuing'),\n]);\n\n/**\n * Browser source settings schema\n */\nexport const SettingsSchema = z.object({\n prefix: DataAttributePrefix.default('data-elb').describe(\n 'Prefix for data attributes (default: data-elb)',\n ),\n\n scope: ScopeSelector.describe(\n 'DOM scope for event tracking (default: document)',\n ),\n\n pageview: z\n .boolean()\n .default(true)\n .describe('Enable automatic pageview tracking'),\n\n elb: JavaScriptVarName.default('elb').describe(\n 'Name for global elb function',\n ),\n\n name: z.string().describe('Custom name for source instance').optional(),\n\n elbLayer: ElbLayerConfigSchema.default('elbLayer').describe(\n 'Enable elbLayer for async command queuing (boolean, string, or Elb.Layer)',\n ),\n});\n\n// Note: We export the inferred type, but types/index.ts will override\n// specific fields with non-serializable types\nexport type Settings = z.infer<typeof SettingsSchema>;\n","import { z } from '@walkeros/core/dev';\n\n/**\n * Data attribute prefix\n * Used for DOM event tracking\n */\nexport const DataAttributePrefix = z\n .string()\n .min(1)\n .regex(/^[a-z][a-z0-9-]*$/, 'Must be lowercase kebab-case')\n .describe('Prefix for data attributes on DOM elements');\n\n/**\n * JavaScript variable name\n * Used for global function names\n */\nexport const JavaScriptVarName = z\n .string()\n .min(1)\n .regex(/^[a-zA-Z_$][a-zA-Z0-9_$]*$/, 'Must be a valid JavaScript identifier')\n .describe('JavaScript variable name');\n\n/**\n * DOM scope selector\n * Note: Runtime type is Element | Document (non-serializable)\n */\nexport const ScopeSelector = z\n .string()\n .describe('DOM scope for event tracking (CSS selector or \"document\")')\n .optional();\n","import { z } from '@walkeros/core/dev';\nimport { DataAttributePrefix } from './primitives';\n\n/**\n * Tagger configuration schema\n * Used for automatic data attribute generation\n */\nexport const TaggerSchema = z.object({\n prefix: DataAttributePrefix.default('data-elb').describe(\n 'Custom prefix for generated data attributes',\n ),\n});\n\nexport type TaggerConfig = z.infer<typeof TaggerSchema>;\n","export * as env from './env';\nexport * as step from './step';\nexport { createTrigger, trigger } from './trigger';\n","import type { Env } from '../types';\nimport type { Elb, Logger } from '@walkeros/core';\n\n/**\n * Example environment configurations for browser source\n *\n * These environments provide standardized mock structures for testing\n * browser event capture without requiring an actual DOM environment.\n */\n\n// Simple no-op function for mocking\nconst noop = () => {};\n\n// Create a properly typed elb/push/command function that returns a promise with PushResult\nconst createMockElbFn = (): Elb.Fn => {\n const fn = (() =>\n Promise.resolve({\n ok: true,\n })) as Elb.Fn;\n return fn;\n};\n\n// Simple no-op logger for demo purposes\nconst noopLogger: Logger.Instance = {\n error: noop,\n warn: noop,\n info: noop,\n debug: noop,\n throw: (message: string | Error) => {\n throw typeof message === 'string' ? new Error(message) : message;\n },\n json: noop,\n scope: () => noopLogger,\n};\n\n/**\n * Mock window object with common browser APIs\n */\nconst createMockWindow = () => ({\n addEventListener: noop,\n removeEventListener: noop,\n location: {\n href: 'https://example.com/page',\n pathname: '/page',\n search: '?query=test',\n hash: '#section',\n host: 'example.com',\n hostname: 'example.com',\n origin: 'https://example.com',\n protocol: 'https:',\n },\n document: {},\n navigator: {\n language: 'en-US',\n userAgent: 'Mozilla/5.0 (Test)',\n },\n screen: {\n width: 1920,\n height: 1080,\n },\n innerWidth: 1920,\n innerHeight: 1080,\n pageXOffset: 0,\n pageYOffset: 0,\n scrollX: 0,\n scrollY: 0,\n});\n\n/**\n * Mock document object with DOM methods\n */\nconst createMockDocument = () => ({\n addEventListener: noop,\n removeEventListener: noop,\n querySelector: noop,\n querySelectorAll: () => [],\n getElementById: noop,\n getElementsByClassName: () => [],\n getElementsByTagName: () => [],\n createElement: () => ({\n setAttribute: noop,\n getAttribute: noop,\n addEventListener: noop,\n removeEventListener: noop,\n }),\n body: {\n appendChild: noop,\n removeChild: noop,\n },\n documentElement: {\n scrollTop: 0,\n scrollLeft: 0,\n },\n readyState: 'complete',\n title: 'Test Page',\n referrer: '',\n cookie: '',\n});\n\n/**\n * Standard mock environment for testing browser source\n *\n * Use this for testing event capture, DOM interactions, and pageview tracking\n * without requiring a real browser environment.\n */\nexport const push: Env = {\n get push() {\n return createMockElbFn();\n },\n get command() {\n return createMockElbFn();\n },\n get elb() {\n return createMockElbFn();\n },\n get window() {\n return createMockWindow() as unknown as typeof window;\n },\n get document() {\n return createMockDocument() as unknown as typeof document;\n },\n logger: noopLogger,\n};\n","import type { Flow } from '@walkeros/core';\n\nexport const pageView: Flow.StepExample = {\n title: 'Page view',\n description:\n 'A page load trigger captures the current URL, title, and referrer as a walker page view event.',\n trigger: {\n type: 'load',\n options: {\n url: 'https://example.com/docs',\n title: 'Documentation',\n referrer: 'https://example.com/',\n },\n },\n in: '',\n out: [\n [\n 'elb',\n {\n name: 'page view',\n data: {\n domain: 'example.com',\n title: 'Documentation',\n referrer: 'https://example.com/',\n id: '/docs',\n },\n context: {},\n globals: {},\n nested: undefined,\n custom: undefined,\n trigger: 'load',\n source: {\n type: 'browser',\n platform: 'web',\n url: 'https://example.com/docs',\n referrer: 'https://example.com/',\n },\n },\n ],\n ],\n};\n\nexport const clickEvent: Flow.StepExample = {\n title: 'Click event',\n description:\n 'A button click with walker data attributes is captured as an entity action event with the mapped label data.',\n trigger: { type: 'click', options: 'button' },\n in: '<button data-elb=\"cta\" data-elb-cta=\"label:Sign Up\" data-elbaction=\"click:click\">Sign Up</button>',\n out: [\n [\n 'elb',\n {\n name: 'cta click',\n entity: 'cta',\n action: 'click',\n data: { label: 'Sign Up' },\n context: {},\n globals: {},\n nested: [],\n source: {\n type: 'browser',\n platform: 'web',\n url: 'https://example.com/',\n referrer: '',\n },\n trigger: 'click',\n },\n ],\n ],\n};\n\nexport const submitEvent: Flow.StepExample = {\n title: 'Submit event',\n description:\n 'A form submit with walker data attributes produces a signup complete event carrying the selected plan.',\n trigger: { type: 'submit', options: 'form' },\n in: '<form data-elb=\"signup\" data-elb-signup=\"plan:premium\" data-elbaction=\"submit:complete\"></form>',\n out: [\n [\n 'elb',\n {\n name: 'signup complete',\n entity: 'signup',\n action: 'complete',\n data: { plan: 'premium' },\n context: {},\n globals: {},\n nested: [],\n source: {\n type: 'browser',\n platform: 'web',\n url: 'https://example.com/',\n referrer: '',\n },\n trigger: 'submit',\n },\n ],\n ],\n};\n\nexport const impressionEvent: Flow.StepExample = {\n title: 'Impression event',\n description:\n 'An intersection observer impression on a div with walker attributes emits a banner view event.',\n trigger: { type: 'impression', options: 'div' },\n in: '<div data-elb=\"banner\" data-elb-banner=\"type:promotional;position:sidebar\" data-elbaction=\"impression:view\"></div>',\n out: [\n [\n 'elb',\n {\n name: 'banner view',\n entity: 'banner',\n action: 'view',\n data: { type: 'promotional', position: 'sidebar' },\n context: {},\n globals: {},\n nested: [],\n source: {\n type: 'browser',\n platform: 'web',\n url: 'https://example.com/',\n referrer: '',\n },\n trigger: 'impression',\n },\n ],\n ],\n};\n\nexport const nestedEntities: Flow.StepExample = {\n title: 'Nested entities',\n description:\n 'A page load produces a page view plus a product view whose nested size entity is captured on the product event.',\n trigger: { type: 'load' },\n in: '<div data-elb=\"product\" data-elb-product=\"id:SKU-42;name:Sneakers\" data-elbaction=\"load:view\"><div data-elb=\"size\" data-elb-size=\"selected:large;inStock:true\"></div></div>',\n out: [\n [\n 'elb',\n {\n name: 'page view',\n data: {\n domain: 'example.com',\n title: '',\n referrer: '',\n id: '/',\n },\n context: {},\n globals: {},\n nested: undefined,\n custom: undefined,\n trigger: 'load',\n source: {\n type: 'browser',\n platform: 'web',\n url: 'https://example.com/',\n referrer: '',\n },\n },\n ],\n [\n 'elb',\n {\n name: 'product view',\n entity: 'product',\n action: 'view',\n data: { id: 'SKU-42', name: 'Sneakers' },\n context: {},\n globals: {},\n nested: [\n {\n entity: 'size',\n data: { selected: 'large', inStock: true },\n context: {},\n nested: [],\n },\n ],\n source: {\n type: 'browser',\n platform: 'web',\n url: 'https://example.com/',\n referrer: '',\n },\n trigger: 'load',\n },\n ],\n ],\n};\n\nexport const dataAttributeTypes: Flow.StepExample = {\n title: 'Data attribute types',\n description:\n 'Walker data attributes parse scalar, boolean, and array values into typed fields on the emitted event.',\n trigger: { type: 'click', options: 'div' },\n in: '<div data-elb=\"product\" data-elb-product=\"price:99.99;available:true;colors[]:red;colors[]:blue\" data-elbaction=\"click:select\"></div>',\n out: [\n [\n 'elb',\n {\n name: 'product select',\n entity: 'product',\n action: 'select',\n data: { price: 99.99, available: true, colors: ['red', 'blue'] },\n context: {},\n globals: {},\n nested: [],\n source: {\n type: 'browser',\n platform: 'web',\n url: 'https://example.com/',\n referrer: '',\n },\n trigger: 'click',\n },\n ],\n ],\n};\n\nexport const contextAndGlobals: Flow.StepExample = {\n title: 'Context and globals',\n description:\n 'Walker context and globals attributes attach ambient metadata to events emitted by the browser source.',\n trigger: { type: 'click', options: '[data-elb=\"cta\"]' },\n in: '<div data-elbcontext=\"test:engagement_flow\" data-elbglobals=\"language:en;plan:premium\"><div data-elb=\"cta\" data-elb-cta=\"label:Try Now\" data-elbaction=\"click:signup\">Try Now</div></div>',\n out: [\n [\n 'elb',\n {\n name: 'cta signup',\n entity: 'cta',\n action: 'signup',\n data: { label: 'Try Now' },\n context: { test: ['engagement_flow', 0] },\n globals: { language: 'en', plan: 'premium' },\n nested: [],\n source: {\n type: 'browser',\n platform: 'web',\n url: 'https://example.com/',\n referrer: '',\n },\n trigger: 'click',\n },\n ],\n ],\n};\n","import type { Trigger, Collector } from '@walkeros/core';\nimport { startFlow } from '@walkeros/collector';\nimport { handleTrigger } from '../trigger';\nimport type { Context } from '../types';\n\ntype BrowserTriggerType =\n | 'load'\n | 'click'\n | 'submit'\n | 'hover'\n | 'scroll'\n | 'impression'\n | 'visible'\n | 'wait'\n | 'pulse';\n\ninterface LoadOptions {\n url?: string;\n title?: string;\n referrer?: string;\n}\n\ninterface BrowserInput {\n trigger: string;\n url?: string;\n title?: string;\n referrer?: string;\n element?: string;\n attributes?: Record<string, string>;\n children?: Record<string, string>[];\n context?: Record<string, unknown>;\n globals?: Record<string, unknown>;\n}\n\n/**\n * Browser source createTrigger.\n *\n * Injects HTML into the DOM, lazily starts the flow, then calls\n * handleTrigger directly — the same convergence point as production.\n * For load triggers, the source's DOM scan during startFlow handles\n * event capture automatically.\n *\n * @example\n * const { trigger } = await createTrigger(config);\n * await trigger('click', 'button')('<button data-elb=\"cta\" data-elbaction=\"click:cta click\">Click</button>');\n *\n * @example\n * // Impression trigger — handleTrigger reads data-elbaction directly\n * await trigger('impression', '[data-elb=\"promo\"]')('<div data-elb=\"promo\" data-elbaction=\"visible:promo seen\">Ad</div>');\n */\nconst createTrigger: Trigger.CreateFn<string, void> = async (\n config: Collector.InitConfig,\n options?: unknown,\n) => {\n const sourceId = (options as { sourceId?: string } | undefined)?.sourceId || 'browser';\n let flow: Trigger.FlowHandle | undefined;\n const doc = document;\n const win = window;\n\n const trigger: Trigger.Fn<string, void> =\n (type?: string, opts?: unknown) => async (content: string) => {\n // 1. Set up environment for load triggers (URL, title, referrer)\n if (type === 'load' || !type) {\n const loadOpts =\n typeof opts === 'object' && opts !== null\n ? (opts as LoadOptions)\n : {};\n if (loadOpts.url) {\n const urlObj = new URL(loadOpts.url);\n win.history.replaceState({}, '', urlObj.pathname);\n }\n if (loadOpts.title) doc.title = loadOpts.title;\n if (loadOpts.referrer) {\n Object.defineProperty(doc, 'referrer', {\n value: loadOpts.referrer,\n configurable: true,\n });\n }\n }\n\n // 2. Inject HTML content into DOM — replaces to create fresh state\n if (content) doc.body.innerHTML = content;\n\n // 3. Lazy startFlow — first call initializes the flow\n // Default run: true so sources scan the DOM and set up listeners\n if (!flow) {\n const result = await startFlow({ ...config, run: config.run ?? true });\n flow = { collector: result.collector, elb: result.elb };\n }\n\n // 4. For load triggers, source already scanned DOM during init — done\n if (!type || type === 'load') return;\n\n // 5. Find target element\n const selector = typeof opts === 'string' ? opts : undefined;\n const target = selector ? doc.querySelector(selector) : null;\n\n if (!target) {\n console.warn(`Trigger: element not found for selector \"${selector}\"`);\n return;\n }\n\n // 6. Build context from live source instance\n const source = flow.collector.sources[sourceId];\n if (!source) {\n console.warn(`Trigger: source \"${sourceId}\" not found in collector`);\n return;\n }\n\n const context: Context = {\n elb: flow.elb,\n settings: source.config.settings as Context['settings'],\n };\n\n // 7. Call handleTrigger directly — same convergence point as production\n await handleTrigger(context, target, type);\n };\n\n return {\n get flow() {\n return flow;\n },\n trigger,\n };\n};\n\n/**\n * Browser source trigger (legacy).\n * Converts step example `in` data into DOM elements and dispatches events.\n */\nconst trigger = (\n input: unknown,\n env: Record<string, unknown>,\n): void | (() => void) => {\n if (!input || typeof input !== 'object') return;\n const data = input as BrowserInput;\n const doc = env.document as Document;\n const win = env.window as Window & typeof globalThis;\n\n const injectDOM = () => {\n if (!data.attributes) return;\n\n const tag = data.element?.match(/^(\\w+)/)?.[1] || 'div';\n const el = doc.createElement(tag);\n\n for (const [key, value] of Object.entries(data.attributes)) {\n el.setAttribute(key, value);\n }\n\n if (data.children) {\n for (const childAttrs of data.children) {\n const child = doc.createElement('div');\n for (const [key, value] of Object.entries(childAttrs)) {\n child.setAttribute(key, value);\n }\n el.appendChild(child);\n }\n }\n\n doc.body.appendChild(el);\n return el;\n };\n\n const isLoad = !data.trigger || data.trigger === 'load';\n\n if (isLoad) {\n if (data.url) {\n const urlObj = new URL(data.url);\n win.history.replaceState({}, '', urlObj.pathname);\n }\n if (data.title) {\n doc.title = data.title;\n }\n if (data.referrer) {\n Object.defineProperty(doc, 'referrer', { value: data.referrer });\n }\n injectDOM();\n return;\n }\n\n // Interactive triggers: inject DOM and dispatch event AFTER source init\n return () => {\n const el = injectDOM();\n if (!el) return;\n\n switch (data.trigger) {\n case 'click':\n el.dispatchEvent(new MouseEvent('click', { bubbles: true }));\n break;\n case 'submit':\n el.dispatchEvent(new Event('submit', { bubbles: true }));\n break;\n case 'hover':\n el.dispatchEvent(new MouseEvent('mouseenter', { bubbles: true }));\n break;\n case 'scroll':\n win.dispatchEvent(new Event('scroll'));\n break;\n }\n };\n};\n\nexport { createTrigger, trigger };\n","import type { WalkerOS, Collector } from '@walkeros/core';\nimport type { Walker } from '@walkeros/web-core';\nimport type { Scope, Settings, Context } 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} from './triggerVisible';\nimport { translateToCoreCollector } from './translation';\n\nlet scrollElements: Walker.ScrollElements = [];\nlet scrollListener: EventListenerOrEventListenerObject | undefined;\n\n// Reset function for testing\nexport function resetScrollListener() {\n scrollListener = undefined;\n scrollElements = [];\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) { readyFn(); return; }\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 scope.addEventListener(\n 'click',\n tryCatch(function (this: Scope, ev: unknown) {\n triggerClick.call(this, context, ev as MouseEvent);\n }) as EventListener,\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 );\n}\n\nexport function initScopeTrigger(context: Context, settings: Settings) {\n const elem = settings.scope;\n\n // Reset all scroll events @TODO check if it's right here\n scrollElements = [];\n\n // Clean up any existing visibility tracking to prevent observer accumulation\n const scope = elem;\n if (!scope) return;\n destroyVisibilityTracking(scope);\n // Initialize visibility tracking for this scope\n initVisibilityTracking(scope, 1000);\n\n // default data-elbaction\n const selectorAction = getElbAttributeName(\n settings.prefix,\n Const.Commands.Action,\n false,\n );\n const doc = (scope as Element).ownerDocument || (scope as Document);\n if (scope !== doc) {\n // Handle the elements action(s), too\n handleActionElem(context, scope as HTMLElement, selectorAction, settings);\n }\n\n // Handle all children action(s)\n queryAllComposed(scope, `[${selectorAction}]`, (elem) => {\n handleActionElem(context, elem as HTMLElement, selectorAction, settings);\n });\n\n if (scrollElements.length) scroll(context, scope, settings);\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\nfunction handleActionElem(\n context: Context,\n elem: HTMLElement,\n selectorAction: string,\n settings: Settings,\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);\n break;\n case Triggers.Load:\n triggerLoad(context, elem);\n break;\n case Triggers.Pulse:\n triggerPulse(context, elem, triggerAction.triggerParams);\n break;\n case Triggers.Scroll:\n triggerScroll(elem, triggerAction.triggerParams);\n break;\n case Triggers.Impression:\n triggerVisible(context, elem);\n break;\n case Triggers.Visible:\n triggerVisible(context, elem, { multiple: true });\n break;\n case Triggers.Wait:\n triggerWait(context, elem, triggerAction.triggerParams);\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)) 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(context: Context, elem: HTMLElement) {\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 );\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 triggerParams: string = '',\n) {\n const doc = elem.ownerDocument;\n 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}\n\nfunction triggerScroll(elem: HTMLElement, triggerParams: string = '') {\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 scrollElements.push([elem, depth]);\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 triggerParams: string = '',\n) {\n setTimeout(\n () => handleTrigger(context, elem, Triggers.Wait),\n parseInt(triggerParams || '') || 15000,\n );\n}\n\nfunction scroll(context: Context, scope: Scope, settings: Settings) {\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 // Distance from top to the bottom of the visible screen\n const windowBottom = win.scrollY + win.innerHeight;\n // Distance from top to the elements relevant content\n const elemTop = (element as HTMLElement).offsetTop;\n\n // Skip calculations if not in viewport yet\n if (windowBottom < elemTop) return true;\n\n // Height of the elements box as 100 percent base\n const elemHeight = element.clientHeight;\n // Distance from top to the elements bottom\n const elemBottom = elemTop + elemHeight;\n // Height of the non-visible pixels below visible screen\n const hidden = elemBottom - windowBottom;\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\n if (!scrollListener) {\n scrollListener = throttle(function () {\n scrollElements = scrolling.call(scope, scrollElements, context);\n });\n\n scope.addEventListener('scroll', scrollListener);\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 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 );\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): [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\n // Get all bubbling-up properties with decreasing priority\n let contextI = 0; // Context counter\n while (parent) {\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 { WalkerOS } from '@walkeros/core';\nimport type { Settings, Context } from './types';\nimport { tryCatch } from '@walkeros/core';\nimport { isVisible } from '@walkeros/web-core';\nimport { handleTrigger, Triggers } from './trigger';\n\n// Cache for element size calculations to reduce DOM queries\nconst elementSizeCache = new WeakMap<\n HTMLElement,\n { isLarge: boolean; lastChecked: number }\n>();\n\n// Cache for basic visibility checks to reduce expensive isVisible() calls\nconst visibilityCache = new WeakMap<\n HTMLElement,\n { isVisible: boolean; lastChecked: number }\n>();\n\n// Module-level visibility state management (stateless source architecture)\ninterface VisibilityState {\n observer?: IntersectionObserver;\n timers: WeakMap<HTMLElement, number>;\n duration: number;\n elementConfigs?: WeakMap<\n HTMLElement,\n { multiple: boolean; blocked: boolean; context: Context; trigger: string }\n >;\n}\n\n// Module-level visibility state keyed by document/scope\nconst visibilityStates = new WeakMap<Document | Element, VisibilityState>();\n\n/**\n * Cached visibility check to reduce expensive isVisible() calls\n */\nfunction isElementVisible(element: HTMLElement): boolean {\n const now = Date.now();\n let cached = visibilityCache.get(element);\n\n // Cache visibility result for 500ms to balance accuracy with performance\n if (!cached || now - cached.lastChecked > 500) {\n const win = element.ownerDocument.defaultView!;\n const doc = element.ownerDocument;\n cached = {\n isVisible: isVisible(element, win, doc),\n lastChecked: now,\n };\n visibilityCache.set(element, cached);\n }\n\n return cached.isVisible;\n}\n\n/**\n * Element cleanup (unobserve + timer + cache cleanup)\n */\nexport function unobserveElement(\n scope: Document | Element,\n element: HTMLElement,\n): void {\n const state = visibilityStates.get(scope);\n if (!state) return;\n\n if (state.observer) {\n state.observer.unobserve(element);\n }\n\n // Clear timer\n const timer = state.timers.get(element);\n if (timer) {\n clearTimeout(timer);\n state.timers.delete(element);\n }\n\n // Clean up caches to prevent memory leaks\n elementSizeCache.delete(element);\n visibilityCache.delete(element);\n}\n\n/**\n * Creates an IntersectionObserver for the given scope\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) => {\n handleIntersection(scope, entry);\n });\n },\n {\n rootMargin: '0px',\n threshold: [0, 0.5],\n },\n ),\n () => undefined,\n )();\n}\n\n/**\n * Handles intersection changes for observed elements\n */\nfunction handleIntersection(\n scope: Document | Element,\n entry: IntersectionObserverEntry,\n): void {\n const target = entry.target as HTMLElement;\n const state = visibilityStates.get(scope);\n\n if (!state) return;\n\n const existingTimer = state.timers.get(target);\n\n if (entry.intersectionRatio > 0) {\n // Optimize: Cache element size calculations to avoid repeated DOM queries\n const now = Date.now();\n let cached = elementSizeCache.get(target);\n\n // Cache element size for 1 second to reduce DOM queries\n if (!cached || now - cached.lastChecked > 1000) {\n const win = target.ownerDocument.defaultView!;\n cached = {\n isLarge: target.offsetHeight > win.innerHeight,\n lastChecked: now,\n };\n elementSizeCache.set(target, cached);\n }\n\n const meetsThreshold = entry.intersectionRatio >= 0.5;\n\n // Optimized visibility strategy:\n // - Standard elements: intersection ratio ≥ 0.5 is sufficient (fast)\n // - Large elements: need additional overlay/occlusion check (slower but necessary)\n const shouldTrigger =\n meetsThreshold || (cached.isLarge && isElementVisible(target));\n\n if (shouldTrigger) {\n // Get element configuration\n const elementConfig = state.elementConfigs?.get(target);\n\n // For multiple triggers, only proceed if this is a re-entry (was not visible, now visible)\n if (elementConfig?.multiple && elementConfig.blocked) return; // Don't trigger again\n\n // Only create timer if none exists\n if (!existingTimer) {\n const targetWin = target.ownerDocument.defaultView!;\n const timer = targetWin.setTimeout(async () => {\n // Final visibility check before triggering (cached for performance)\n if (isElementVisible(target)) {\n // Get element configuration to access context\n const elementConfig = state.elementConfigs?.get(target);\n if (elementConfig?.context) {\n await handleTrigger(\n elementConfig.context,\n target as Element,\n elementConfig.trigger,\n );\n }\n\n // Get fresh element config reference for state update\n const currentConfig = state.elementConfigs?.get(target);\n\n // For multiple triggers, mark as visible after firing\n if (currentConfig?.multiple) {\n currentConfig.blocked = true;\n } else {\n // Clean up and unobserve only if not a multiple trigger\n unobserveElement(scope, target);\n }\n }\n }, state.duration);\n\n state.timers.set(target, timer);\n }\n return;\n }\n }\n\n // Element isn't sufficiently in viewport - clear existing timer\n if (existingTimer) {\n clearTimeout(existingTimer);\n state.timers.delete(target);\n }\n\n // For multiple triggers, mark as not visible for re-entry detection\n const elementConfig = state.elementConfigs?.get(target);\n if (elementConfig?.multiple) {\n elementConfig.blocked = false;\n }\n}\n\n/**\n * Initializes visibility tracking for a scope (document/element)\n */\nexport function initVisibilityTracking(\n scope: Document | Element,\n duration = 1000,\n): void {\n if (visibilityStates.has(scope)) return; // Already initialized\n\n visibilityStates.set(scope, {\n observer: createObserver(scope),\n timers: new WeakMap(),\n duration,\n });\n}\n\n/**\n * Main trigger function for visible elements\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(scope);\n\n if (state?.observer && element) {\n // Store element config for later use in intersection handling\n if (!state.elementConfigs) {\n state.elementConfigs = new WeakMap();\n }\n state.elementConfigs.set(element, {\n multiple: config.multiple ?? false,\n blocked: false,\n context,\n trigger: config.multiple ? 'visible' : 'impression',\n });\n state.observer.observe(element);\n }\n}\n\n/**\n * Destroys visibility tracking for a scope, cleaning up all resources\n */\nexport function destroyVisibilityTracking(scope?: Document | Element): void {\n if (!scope) return; // No scope provided, nothing to clean up\n\n const state = visibilityStates.get(scope);\n if (!state) return;\n\n if (state.observer) {\n state.observer.disconnect();\n }\n\n visibilityStates.delete(scope);\n}\n","import type { WalkerOS, Elb, Collector } from '@walkeros/core';\nimport { isString, isObject, isElementOrDocument } from '@walkeros/core';\nimport type {\n BrowserPushData,\n BrowserPushOptions,\n BrowserPushContext,\n} from './types/elb';\nimport type { Context } 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 - pass through directly to elb (it will route to command)\n if (isString(eventOrCommand) && eventOrCommand.startsWith('walker ')) {\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 = getGlobals(settings.prefix, settings.scope);\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 = getGlobals(settings.prefix, settings.scope);\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"],"mappings":"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","names":["import_dev","import_dev","import_dev","import_collector","import_core","import_collector","import_web_core","trigger","filter","str","trigger","elem","import_core","import_web_core","import_core","settings","event","scopeDoc","scopeWin","trigger","trigger"]}
|
|
1
|
+
{"version":3,"sources":["../src/dev.ts","../src/schemas/index.ts","../src/schemas/settings.ts","../src/schemas/primitives.ts","../src/schemas/tagger.ts","../src/examples/index.ts","../src/examples/env.ts","../src/examples/step.ts","../src/examples/trigger.ts","../src/trigger.ts","../src/walker.ts","../src/triggerVisible.ts","../src/translation.ts"],"sourcesContent":["export * as schemas from './schemas';\nexport * as examples from './examples';\n","import { zodToSchema } from '@walkeros/core/dev';\nimport { SettingsSchema } from './settings';\nimport { TaggerSchema } from './tagger';\n\n// Export primitives\nexport * from './primitives';\n\n// Export Zod schemas and types\nexport { SettingsSchema, type Settings } from './settings';\nexport { TaggerSchema, type TaggerConfig } from './tagger';\n\n// JSON Schema exports (for website PropertyTable and explorer RJSF)\nexport const settings = zodToSchema(SettingsSchema);\nexport const tagger = zodToSchema(TaggerSchema);\n","import { z } from '@walkeros/core/dev';\nimport {\n DataAttributePrefix,\n JavaScriptVarName,\n ScopeSelector,\n} from './primitives';\n\n/**\n * ELB Layer configuration schema\n * Note: Runtime type can be boolean | string | Elb.Layer\n */\nconst ElbLayerConfigSchema = z.union([\n z.boolean(),\n z.string(),\n z.any().describe('Elb.Layer array for async command queuing'),\n]);\n\n/**\n * Browser source settings schema\n */\nexport const SettingsSchema = z.object({\n prefix: DataAttributePrefix.default('data-elb').describe(\n 'Prefix for data attributes (default: data-elb)',\n ),\n\n scope: ScopeSelector.describe(\n 'DOM scope for event tracking (default: document)',\n ),\n\n pageview: z\n .boolean()\n .default(true)\n .describe('Enable automatic pageview tracking'),\n\n elb: JavaScriptVarName.default('elb').describe(\n 'Name for global elb function',\n ),\n\n name: z.string().describe('Custom name for source instance').optional(),\n\n elbLayer: ElbLayerConfigSchema.default('elbLayer').describe(\n 'Enable elbLayer for async command queuing (boolean, string, or Elb.Layer)',\n ),\n});\n\n// Note: We export the inferred type, but types/index.ts will override\n// specific fields with non-serializable types\nexport type Settings = z.infer<typeof SettingsSchema>;\n","import { z } from '@walkeros/core/dev';\n\n/**\n * Data attribute prefix\n * Used for DOM event tracking\n */\nexport const DataAttributePrefix = z\n .string()\n .min(1)\n .regex(/^[a-z][a-z0-9-]*$/, 'Must be lowercase kebab-case')\n .describe('Prefix for data attributes on DOM elements');\n\n/**\n * JavaScript variable name\n * Used for global function names\n */\nexport const JavaScriptVarName = z\n .string()\n .min(1)\n .regex(/^[a-zA-Z_$][a-zA-Z0-9_$]*$/, 'Must be a valid JavaScript identifier')\n .describe('JavaScript variable name');\n\n/**\n * DOM scope selector\n * Note: Runtime type is Element | Document (non-serializable)\n */\nexport const ScopeSelector = z\n .string()\n .describe('DOM scope for event tracking (CSS selector or \"document\")')\n .optional();\n","import { z } from '@walkeros/core/dev';\nimport { DataAttributePrefix } from './primitives';\n\n/**\n * Tagger configuration schema\n * Used for automatic data attribute generation\n */\nexport const TaggerSchema = z.object({\n prefix: DataAttributePrefix.default('data-elb').describe(\n 'Custom prefix for generated data attributes',\n ),\n});\n\nexport type TaggerConfig = z.infer<typeof TaggerSchema>;\n","export * as env from './env';\nexport * as step from './step';\nexport { createTrigger, trigger } from './trigger';\n","import type { Env } from '../types';\nimport type { Elb, Logger } from '@walkeros/core';\n\n/**\n * Example environment configurations for browser source\n *\n * These environments provide standardized mock structures for testing\n * browser event capture without requiring an actual DOM environment.\n */\n\n// Simple no-op function for mocking\nconst noop = () => {};\n\n// Create a properly typed elb/push/command function that returns a promise with PushResult\nconst createMockElbFn = (): Elb.Fn => {\n const fn = (() =>\n Promise.resolve({\n ok: true,\n })) as Elb.Fn;\n return fn;\n};\n\n// Simple no-op logger for demo purposes\nconst noopLogger: Logger.Instance = {\n error: noop,\n warn: noop,\n info: noop,\n debug: noop,\n throw: (message: string | Error) => {\n throw typeof message === 'string' ? new Error(message) : message;\n },\n json: noop,\n scope: () => noopLogger,\n};\n\n/**\n * Mock window object with common browser APIs\n */\nconst createMockWindow = () => ({\n addEventListener: noop,\n removeEventListener: noop,\n location: {\n href: 'https://example.com/page',\n pathname: '/page',\n search: '?query=test',\n hash: '#section',\n host: 'example.com',\n hostname: 'example.com',\n origin: 'https://example.com',\n protocol: 'https:',\n },\n document: {},\n navigator: {\n language: 'en-US',\n userAgent: 'Mozilla/5.0 (Test)',\n },\n screen: {\n width: 1920,\n height: 1080,\n },\n innerWidth: 1920,\n innerHeight: 1080,\n pageXOffset: 0,\n pageYOffset: 0,\n scrollX: 0,\n scrollY: 0,\n});\n\n/**\n * Mock document object with DOM methods\n */\nconst createMockDocument = () => ({\n addEventListener: noop,\n removeEventListener: noop,\n querySelector: noop,\n querySelectorAll: () => [],\n getElementById: noop,\n getElementsByClassName: () => [],\n getElementsByTagName: () => [],\n createElement: () => ({\n setAttribute: noop,\n getAttribute: noop,\n addEventListener: noop,\n removeEventListener: noop,\n }),\n body: {\n appendChild: noop,\n removeChild: noop,\n },\n documentElement: {\n scrollTop: 0,\n scrollLeft: 0,\n },\n readyState: 'complete',\n title: 'Test Page',\n referrer: '',\n cookie: '',\n});\n\n/**\n * Standard mock environment for testing browser source\n *\n * Use this for testing event capture, DOM interactions, and pageview tracking\n * without requiring a real browser environment.\n */\nexport const push: Env = {\n get push() {\n return createMockElbFn();\n },\n get command() {\n return createMockElbFn();\n },\n get elb() {\n return createMockElbFn();\n },\n get window() {\n return createMockWindow() as unknown as typeof window;\n },\n get document() {\n return createMockDocument() as unknown as typeof document;\n },\n logger: noopLogger,\n};\n","import type { Flow } from '@walkeros/core';\n\nexport const pageView: Flow.StepExample = {\n title: 'Page view',\n description:\n 'A page load trigger captures the current URL, title, and referrer as a walker page view event.',\n trigger: {\n type: 'load',\n options: {\n url: 'https://example.com/docs',\n title: 'Documentation',\n referrer: 'https://example.com/',\n },\n },\n in: '',\n out: [\n [\n 'elb',\n {\n name: 'page view',\n data: {\n domain: 'example.com',\n title: 'Documentation',\n referrer: 'https://example.com/',\n id: '/docs',\n },\n context: {},\n globals: {},\n nested: undefined,\n custom: undefined,\n trigger: 'load',\n source: {\n type: 'browser',\n platform: 'web',\n url: 'https://example.com/docs',\n referrer: 'https://example.com/',\n },\n },\n ],\n ],\n};\n\nexport const clickEvent: Flow.StepExample = {\n title: 'Click event',\n description:\n 'A button click with walker data attributes is captured as an entity action event with the mapped label data.',\n trigger: { type: 'click', options: 'button' },\n in: '<button data-elb=\"cta\" data-elb-cta=\"label:Sign Up\" data-elbaction=\"click:click\">Sign Up</button>',\n out: [\n [\n 'elb',\n {\n name: 'cta click',\n entity: 'cta',\n action: 'click',\n data: { label: 'Sign Up' },\n context: {},\n globals: {},\n nested: [],\n source: {\n type: 'browser',\n platform: 'web',\n url: 'https://example.com/',\n referrer: '',\n },\n trigger: 'click',\n },\n ],\n ],\n};\n\nexport const submitEvent: Flow.StepExample = {\n title: 'Submit event',\n description:\n 'A form submit with walker data attributes produces a signup complete event carrying the selected plan.',\n trigger: { type: 'submit', options: 'form' },\n in: '<form data-elb=\"signup\" data-elb-signup=\"plan:premium\" data-elbaction=\"submit:complete\"></form>',\n out: [\n [\n 'elb',\n {\n name: 'signup complete',\n entity: 'signup',\n action: 'complete',\n data: { plan: 'premium' },\n context: {},\n globals: {},\n nested: [],\n source: {\n type: 'browser',\n platform: 'web',\n url: 'https://example.com/',\n referrer: '',\n },\n trigger: 'submit',\n },\n ],\n ],\n};\n\nexport const impressionEvent: Flow.StepExample = {\n title: 'Impression event',\n description:\n 'An intersection observer impression on a div with walker attributes emits a banner view event.',\n trigger: { type: 'impression', options: 'div' },\n in: '<div data-elb=\"banner\" data-elb-banner=\"type:promotional;position:sidebar\" data-elbaction=\"impression:view\"></div>',\n out: [\n [\n 'elb',\n {\n name: 'banner view',\n entity: 'banner',\n action: 'view',\n data: { type: 'promotional', position: 'sidebar' },\n context: {},\n globals: {},\n nested: [],\n source: {\n type: 'browser',\n platform: 'web',\n url: 'https://example.com/',\n referrer: '',\n },\n trigger: 'impression',\n },\n ],\n ],\n};\n\nexport const nestedEntities: Flow.StepExample = {\n title: 'Nested entities',\n description:\n 'A page load produces a page view plus a product view whose nested size entity is captured on the product event.',\n trigger: { type: 'load' },\n in: '<div data-elb=\"product\" data-elb-product=\"id:SKU-42;name:Sneakers\" data-elbaction=\"load:view\"><div data-elb=\"size\" data-elb-size=\"selected:large;inStock:true\"></div></div>',\n out: [\n [\n 'elb',\n {\n name: 'page view',\n data: {\n domain: 'example.com',\n title: '',\n referrer: '',\n id: '/',\n },\n context: {},\n globals: {},\n nested: undefined,\n custom: undefined,\n trigger: 'load',\n source: {\n type: 'browser',\n platform: 'web',\n url: 'https://example.com/',\n referrer: '',\n },\n },\n ],\n [\n 'elb',\n {\n name: 'product view',\n entity: 'product',\n action: 'view',\n data: { id: 'SKU-42', name: 'Sneakers' },\n context: {},\n globals: {},\n nested: [\n {\n entity: 'size',\n data: { selected: 'large', inStock: true },\n context: {},\n nested: [],\n },\n ],\n source: {\n type: 'browser',\n platform: 'web',\n url: 'https://example.com/',\n referrer: '',\n },\n trigger: 'load',\n },\n ],\n ],\n};\n\nexport const dataAttributeTypes: Flow.StepExample = {\n title: 'Data attribute types',\n description:\n 'Walker data attributes parse scalar, boolean, and array values into typed fields on the emitted event.',\n trigger: { type: 'click', options: 'div' },\n in: '<div data-elb=\"product\" data-elb-product=\"price:99.99;available:true;colors[]:red;colors[]:blue\" data-elbaction=\"click:select\"></div>',\n out: [\n [\n 'elb',\n {\n name: 'product select',\n entity: 'product',\n action: 'select',\n data: { price: 99.99, available: true, colors: ['red', 'blue'] },\n context: {},\n globals: {},\n nested: [],\n source: {\n type: 'browser',\n platform: 'web',\n url: 'https://example.com/',\n referrer: '',\n },\n trigger: 'click',\n },\n ],\n ],\n};\n\nexport const contextAndGlobals: Flow.StepExample = {\n title: 'Context and globals',\n description:\n 'Walker context and globals attributes attach ambient metadata to events emitted by the browser source.',\n trigger: { type: 'click', options: '[data-elb=\"cta\"]' },\n in: '<div data-elbcontext=\"test:engagement_flow\" data-elbglobals=\"language:en;plan:premium\"><div data-elb=\"cta\" data-elb-cta=\"label:Try Now\" data-elbaction=\"click:signup\">Try Now</div></div>',\n out: [\n [\n 'elb',\n {\n name: 'cta signup',\n entity: 'cta',\n action: 'signup',\n data: { label: 'Try Now' },\n context: { test: ['engagement_flow', 0] },\n globals: { language: 'en', plan: 'premium' },\n nested: [],\n source: {\n type: 'browser',\n platform: 'web',\n url: 'https://example.com/',\n referrer: '',\n },\n trigger: 'click',\n },\n ],\n ],\n};\n","import type { Trigger, Collector } from '@walkeros/core';\nimport { startFlow } from '@walkeros/collector';\nimport { handleTrigger } from '../trigger';\nimport type { Context } from '../types';\n\ntype BrowserTriggerType =\n | 'load'\n | 'click'\n | 'submit'\n | 'hover'\n | 'scroll'\n | 'impression'\n | 'visible'\n | 'wait'\n | 'pulse';\n\ninterface LoadOptions {\n url?: string;\n title?: string;\n referrer?: string;\n}\n\ninterface BrowserInput {\n trigger: string;\n url?: string;\n title?: string;\n referrer?: string;\n element?: string;\n attributes?: Record<string, string>;\n children?: Record<string, string>[];\n context?: Record<string, unknown>;\n globals?: Record<string, unknown>;\n}\n\n/**\n * Browser source createTrigger.\n *\n * Injects HTML into the DOM, lazily starts the flow, then calls\n * handleTrigger directly — the same convergence point as production.\n * For load triggers, the source's DOM scan during startFlow handles\n * event capture automatically.\n *\n * @example\n * const { trigger } = await createTrigger(config);\n * await trigger('click', 'button')('<button data-elb=\"cta\" data-elbaction=\"click:cta click\">Click</button>');\n *\n * @example\n * // Impression trigger — handleTrigger reads data-elbaction directly\n * await trigger('impression', '[data-elb=\"promo\"]')('<div data-elb=\"promo\" data-elbaction=\"visible:promo seen\">Ad</div>');\n */\nconst createTrigger: Trigger.CreateFn<string, void> = async (\n config: Collector.InitConfig,\n options?: unknown,\n) => {\n const sourceId = (options as { sourceId?: string } | undefined)?.sourceId || 'browser';\n let flow: Trigger.FlowHandle | undefined;\n const doc = document;\n const win = window;\n\n const trigger: Trigger.Fn<string, void> =\n (type?: string, opts?: unknown) => async (content: string) => {\n // 1. Set up environment for load triggers (URL, title, referrer)\n if (type === 'load' || !type) {\n const loadOpts =\n typeof opts === 'object' && opts !== null\n ? (opts as LoadOptions)\n : {};\n if (loadOpts.url) {\n const urlObj = new URL(loadOpts.url);\n win.history.replaceState({}, '', urlObj.pathname);\n }\n if (loadOpts.title) doc.title = loadOpts.title;\n if (loadOpts.referrer) {\n Object.defineProperty(doc, 'referrer', {\n value: loadOpts.referrer,\n configurable: true,\n });\n }\n }\n\n // 2. Inject HTML content into DOM — replaces to create fresh state\n if (content) doc.body.innerHTML = content;\n\n // 3. Lazy startFlow — first call initializes the flow\n // Default run: true so sources scan the DOM and set up listeners\n if (!flow) {\n const result = await startFlow({ ...config, run: config.run ?? true });\n flow = { collector: result.collector, elb: result.elb };\n }\n\n // 4. For load triggers, source already scanned DOM during init — done\n if (!type || type === 'load') return;\n\n // 5. Find target element\n const selector = typeof opts === 'string' ? opts : undefined;\n const target = selector ? doc.querySelector(selector) : null;\n\n if (!target) {\n console.warn(`Trigger: element not found for selector \"${selector}\"`);\n return;\n }\n\n // 6. Build context from live source instance\n const source = flow.collector.sources[sourceId];\n if (!source) {\n console.warn(`Trigger: source \"${sourceId}\" not found in collector`);\n return;\n }\n\n const context: Context = {\n elb: flow.elb,\n settings: source.config.settings as Context['settings'],\n };\n\n // 7. Call handleTrigger directly — same convergence point as production\n await handleTrigger(context, target, type);\n };\n\n return {\n get flow() {\n return flow;\n },\n trigger,\n };\n};\n\n/**\n * Browser source trigger (legacy).\n * Converts step example `in` data into DOM elements and dispatches events.\n */\nconst trigger = (\n input: unknown,\n env: Record<string, unknown>,\n): void | (() => void) => {\n if (!input || typeof input !== 'object') return;\n const data = input as BrowserInput;\n const doc = env.document as Document;\n const win = env.window as Window & typeof globalThis;\n\n const injectDOM = () => {\n if (!data.attributes) return;\n\n const tag = data.element?.match(/^(\\w+)/)?.[1] || 'div';\n const el = doc.createElement(tag);\n\n for (const [key, value] of Object.entries(data.attributes)) {\n el.setAttribute(key, value);\n }\n\n if (data.children) {\n for (const childAttrs of data.children) {\n const child = doc.createElement('div');\n for (const [key, value] of Object.entries(childAttrs)) {\n child.setAttribute(key, value);\n }\n el.appendChild(child);\n }\n }\n\n doc.body.appendChild(el);\n return el;\n };\n\n const isLoad = !data.trigger || data.trigger === 'load';\n\n if (isLoad) {\n if (data.url) {\n const urlObj = new URL(data.url);\n win.history.replaceState({}, '', urlObj.pathname);\n }\n if (data.title) {\n doc.title = data.title;\n }\n if (data.referrer) {\n Object.defineProperty(doc, 'referrer', { value: data.referrer });\n }\n injectDOM();\n return;\n }\n\n // Interactive triggers: inject DOM and dispatch event AFTER source init\n return () => {\n const el = injectDOM();\n if (!el) return;\n\n switch (data.trigger) {\n case 'click':\n el.dispatchEvent(new MouseEvent('click', { bubbles: true }));\n break;\n case 'submit':\n el.dispatchEvent(new Event('submit', { bubbles: true }));\n break;\n case 'hover':\n el.dispatchEvent(new MouseEvent('mouseenter', { bubbles: true }));\n break;\n case 'scroll':\n win.dispatchEvent(new Event('scroll'));\n break;\n }\n };\n};\n\nexport { createTrigger, trigger };\n","import type { WalkerOS, Collector } from '@walkeros/core';\nimport type { Walker } from '@walkeros/web-core';\nimport type { Scope, Settings, Context } 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} 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// one scroll tracker. The state below is shared across all callers\n// because there is only ever one caller. If multi-instance ever becomes\n// a real requirement (e.g., micro-frontends with isolated walker queues),\n// refactor this into a per-instance closure returned by createSource()\n// and route every trigger function through that closure.\nlet scrollElements: Walker.ScrollElements = [];\nlet scrollListener: EventListenerOrEventListenerObject | undefined;\nlet globalAbortController: AbortController | undefined;\nlet pulseIntervals: ReturnType<typeof setInterval>[] = [];\nlet waitTimeouts: ReturnType<typeof setTimeout>[] = [];\n\n// Listeners registered before initTriggers (or after destroyTriggers) would\n// otherwise miss the AbortController and never be removed on teardown. This\n// helper guarantees every listener gets a signal from the current session's\n// controller, lazily creating one when needed.\nfunction ensureAbortController(): AbortController {\n if (!globalAbortController) {\n globalAbortController = new AbortController();\n }\n return globalAbortController;\n}\n\n// Reset function for testing\nexport function resetScrollListener() {\n scrollListener = undefined;\n scrollElements = [];\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 listeners before re-registering\n if (globalAbortController) globalAbortController.abort();\n globalAbortController = new AbortController();\n const { signal } = globalAbortController;\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 },\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 },\n );\n}\n\n// Removes all listeners registered via the global AbortController and\n// resets module-level scroll state. Safe to call before any init.\nexport function destroyTriggers(settings: Settings): void {\n if (globalAbortController) {\n globalAbortController.abort();\n globalAbortController = undefined;\n }\n scrollListener = undefined;\n scrollElements = [];\n pulseIntervals.forEach((id) => clearInterval(id));\n pulseIntervals = [];\n waitTimeouts.forEach((id) => clearTimeout(id));\n waitTimeouts = [];\n}\n\nexport function initScopeTrigger(context: Context, settings: Settings) {\n const elem = settings.scope;\n\n // Reset all scroll events @TODO check if it's right here\n scrollElements = [];\n\n // Clean up any existing visibility tracking to prevent observer accumulation\n const scope = elem;\n if (!scope) return;\n destroyVisibilityTracking(scope);\n // Initialize visibility tracking for this scope\n initVisibilityTracking(scope, 1000);\n\n // default data-elbaction\n const selectorAction = getElbAttributeName(\n settings.prefix,\n Const.Commands.Action,\n false,\n );\n const doc = (scope as Element).ownerDocument || (scope as Document);\n if (scope !== doc) {\n // Handle the elements action(s), too\n handleActionElem(context, scope as HTMLElement, selectorAction, settings);\n }\n\n // Handle all children action(s)\n queryAllComposed(scope, `[${selectorAction}]`, (elem) => {\n handleActionElem(context, elem as HTMLElement, selectorAction, settings);\n });\n\n if (scrollElements.length) scroll(context, scope, settings);\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\nfunction handleActionElem(\n context: Context,\n elem: HTMLElement,\n selectorAction: string,\n settings: Settings,\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);\n break;\n case Triggers.Load:\n triggerLoad(context, elem);\n break;\n case Triggers.Pulse:\n triggerPulse(context, elem, triggerAction.triggerParams);\n break;\n case Triggers.Scroll:\n triggerScroll(elem, triggerAction.triggerParams);\n break;\n case Triggers.Impression:\n triggerVisible(context, elem);\n break;\n case Triggers.Visible:\n triggerVisible(context, elem, { multiple: true });\n break;\n case Triggers.Wait:\n triggerWait(context, elem, triggerAction.triggerParams);\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(context: Context, elem: HTMLElement) {\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: ensureAbortController().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 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 pulseIntervals.push(intervalId);\n}\n\nfunction triggerScroll(elem: HTMLElement, triggerParams: string = '') {\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 scrollElements.push([elem, depth]);\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 triggerParams: string = '',\n) {\n const timeoutId = setTimeout(\n () => handleTrigger(context, elem, Triggers.Wait),\n parseInt(triggerParams || '') || 15000,\n );\n waitTimeouts.push(timeoutId);\n}\n\nfunction scroll(context: Context, scope: Scope, settings: Settings) {\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 // Distance from top to the bottom of the visible screen\n const windowBottom = win.scrollY + win.innerHeight;\n // Distance from top to the elements relevant content\n const elemTop = (element as HTMLElement).offsetTop;\n\n // Skip calculations if not in viewport yet\n if (windowBottom < elemTop) return true;\n\n // Height of the elements box as 100 percent base\n const elemHeight = element.clientHeight;\n // Distance from top to the elements bottom\n const elemBottom = elemTop + elemHeight;\n // Height of the non-visible pixels below visible screen\n const hidden = elemBottom - windowBottom;\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\n if (!scrollListener) {\n scrollListener = throttle(function () {\n scrollElements = scrolling.call(scope, scrollElements, context);\n });\n\n scope.addEventListener('scroll', scrollListener, {\n signal: ensureAbortController().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 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 );\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): [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\n // Get all bubbling-up properties with decreasing priority\n let contextI = 0; // Context counter\n while (parent) {\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 { WalkerOS } from '@walkeros/core';\nimport type { Settings, Context } from './types';\nimport { tryCatch } from '@walkeros/core';\nimport { isVisible } from '@walkeros/web-core';\nimport { handleTrigger, Triggers } from './trigger';\n\n// Cache for element size calculations to reduce DOM queries\nconst elementSizeCache = new WeakMap<\n HTMLElement,\n { isLarge: boolean; lastChecked: number }\n>();\n\n// Cache for basic visibility checks to reduce expensive isVisible() calls\nconst visibilityCache = new WeakMap<\n HTMLElement,\n { isVisible: boolean; lastChecked: number }\n>();\n\n// Module-level visibility state management (stateless source architecture)\ninterface VisibilityState {\n observer?: IntersectionObserver;\n timers: WeakMap<HTMLElement, number>;\n duration: number;\n elementConfigs?: WeakMap<\n HTMLElement,\n { multiple: boolean; blocked: boolean; context: Context; trigger: string }\n >;\n}\n\n// Module-level visibility state keyed by document/scope\nconst visibilityStates = new WeakMap<Document | Element, VisibilityState>();\n\n/**\n * Cached visibility check to reduce expensive isVisible() calls\n */\nfunction isElementVisible(element: HTMLElement): boolean {\n const now = Date.now();\n let cached = visibilityCache.get(element);\n\n // Cache visibility result for 500ms to balance accuracy with performance\n if (!cached || now - cached.lastChecked > 500) {\n const win = element.ownerDocument.defaultView!;\n const doc = element.ownerDocument;\n cached = {\n isVisible: isVisible(element, win, doc),\n lastChecked: now,\n };\n visibilityCache.set(element, cached);\n }\n\n return cached.isVisible;\n}\n\n/**\n * Element cleanup (unobserve + timer + cache cleanup)\n */\nexport function unobserveElement(\n scope: Document | Element,\n element: HTMLElement,\n): void {\n const state = visibilityStates.get(scope);\n if (!state) return;\n\n if (state.observer) {\n state.observer.unobserve(element);\n }\n\n // Clear timer\n const timer = state.timers.get(element);\n if (timer) {\n clearTimeout(timer);\n state.timers.delete(element);\n }\n\n // Clean up caches to prevent memory leaks\n elementSizeCache.delete(element);\n visibilityCache.delete(element);\n}\n\n/**\n * Creates an IntersectionObserver for the given scope\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) => {\n handleIntersection(scope, entry);\n });\n },\n {\n rootMargin: '0px',\n threshold: [0, 0.5],\n },\n ),\n () => undefined,\n )();\n}\n\n/**\n * Handles intersection changes for observed elements\n */\nfunction handleIntersection(\n scope: Document | Element,\n entry: IntersectionObserverEntry,\n): void {\n const target = entry.target as HTMLElement;\n const state = visibilityStates.get(scope);\n\n if (!state) return;\n\n const existingTimer = state.timers.get(target);\n\n if (entry.intersectionRatio > 0) {\n // Optimize: Cache element size calculations to avoid repeated DOM queries\n const now = Date.now();\n let cached = elementSizeCache.get(target);\n\n // Cache element size for 1 second to reduce DOM queries\n if (!cached || now - cached.lastChecked > 1000) {\n const win = target.ownerDocument.defaultView!;\n cached = {\n isLarge: target.offsetHeight > win.innerHeight,\n lastChecked: now,\n };\n elementSizeCache.set(target, cached);\n }\n\n const meetsThreshold = entry.intersectionRatio >= 0.5;\n\n // Optimized visibility strategy:\n // - Standard elements: intersection ratio ≥ 0.5 is sufficient (fast)\n // - Large elements: need additional overlay/occlusion check (slower but necessary)\n const shouldTrigger =\n meetsThreshold || (cached.isLarge && isElementVisible(target));\n\n if (shouldTrigger) {\n // Get element configuration\n const elementConfig = state.elementConfigs?.get(target);\n\n // For multiple triggers, only proceed if this is a re-entry (was not visible, now visible)\n if (elementConfig?.multiple && elementConfig.blocked) return; // Don't trigger again\n\n // Only create timer if none exists\n if (!existingTimer) {\n const targetWin = target.ownerDocument.defaultView!;\n const timer = targetWin.setTimeout(async () => {\n // Final visibility check before triggering (cached for performance)\n if (isElementVisible(target)) {\n // Get element configuration to access context\n const elementConfig = state.elementConfigs?.get(target);\n if (elementConfig?.context) {\n await handleTrigger(\n elementConfig.context,\n target as Element,\n elementConfig.trigger,\n );\n }\n\n // Get fresh element config reference for state update\n const currentConfig = state.elementConfigs?.get(target);\n\n // For multiple triggers, mark as visible after firing\n if (currentConfig?.multiple) {\n currentConfig.blocked = true;\n } else {\n // Clean up and unobserve only if not a multiple trigger\n unobserveElement(scope, target);\n }\n }\n }, state.duration);\n\n state.timers.set(target, timer);\n }\n return;\n }\n }\n\n // Element isn't sufficiently in viewport - clear existing timer\n if (existingTimer) {\n clearTimeout(existingTimer);\n state.timers.delete(target);\n }\n\n // For multiple triggers, mark as not visible for re-entry detection\n const elementConfig = state.elementConfigs?.get(target);\n if (elementConfig?.multiple) {\n elementConfig.blocked = false;\n }\n}\n\n/**\n * Initializes visibility tracking for a scope (document/element)\n */\nexport function initVisibilityTracking(\n scope: Document | Element,\n duration = 1000,\n): void {\n if (visibilityStates.has(scope)) return; // Already initialized\n\n visibilityStates.set(scope, {\n observer: createObserver(scope),\n timers: new WeakMap(),\n duration,\n });\n}\n\n/**\n * Main trigger function for visible elements\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(scope);\n\n if (state?.observer && element) {\n // Store element config for later use in intersection handling\n if (!state.elementConfigs) {\n state.elementConfigs = new WeakMap();\n }\n state.elementConfigs.set(element, {\n multiple: config.multiple ?? false,\n blocked: false,\n context,\n trigger: config.multiple ? 'visible' : 'impression',\n });\n state.observer.observe(element);\n }\n}\n\n/**\n * Destroys visibility tracking for a scope, cleaning up all resources\n */\nexport function destroyVisibilityTracking(scope?: Document | Element): void {\n if (!scope) return; // No scope provided, nothing to clean up\n\n const state = visibilityStates.get(scope);\n if (!state) return;\n\n if (state.observer) {\n state.observer.disconnect();\n }\n\n visibilityStates.delete(scope);\n}\n","import type { WalkerOS, Elb, Collector } from '@walkeros/core';\nimport { isString, isObject, isElementOrDocument } from '@walkeros/core';\nimport type {\n BrowserPushData,\n BrowserPushOptions,\n BrowserPushContext,\n} from './types/elb';\nimport type { Context } 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 - pass through directly to elb (it will route to command)\n if (isString(eventOrCommand) && eventOrCommand.startsWith('walker ')) {\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 = getGlobals(settings.prefix, settings.scope);\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 = getGlobals(settings.prefix, settings.scope);\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"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAAAA,cAA4B;;;ACA5B,IAAAC,cAAkB;;;ACAlB,iBAAkB;AAMX,IAAM,sBAAsB,aAChC,OAAO,EACP,IAAI,CAAC,EACL,MAAM,qBAAqB,8BAA8B,EACzD,SAAS,4CAA4C;AAMjD,IAAM,oBAAoB,aAC9B,OAAO,EACP,IAAI,CAAC,EACL,MAAM,8BAA8B,uCAAuC,EAC3E,SAAS,0BAA0B;AAM/B,IAAM,gBAAgB,aAC1B,OAAO,EACP,SAAS,2DAA2D,EACpE,SAAS;;;ADlBZ,IAAM,uBAAuB,cAAE,MAAM;AAAA,EACnC,cAAE,QAAQ;AAAA,EACV,cAAE,OAAO;AAAA,EACT,cAAE,IAAI,EAAE,SAAS,2CAA2C;AAC9D,CAAC;AAKM,IAAM,iBAAiB,cAAE,OAAO;AAAA,EACrC,QAAQ,oBAAoB,QAAQ,UAAU,EAAE;AAAA,IAC9C;AAAA,EACF;AAAA,EAEA,OAAO,cAAc;AAAA,IACnB;AAAA,EACF;AAAA,EAEA,UAAU,cACP,QAAQ,EACR,QAAQ,IAAI,EACZ,SAAS,oCAAoC;AAAA,EAEhD,KAAK,kBAAkB,QAAQ,KAAK,EAAE;AAAA,IACpC;AAAA,EACF;AAAA,EAEA,MAAM,cAAE,OAAO,EAAE,SAAS,iCAAiC,EAAE,SAAS;AAAA,EAEtE,UAAU,qBAAqB,QAAQ,UAAU,EAAE;AAAA,IACjD;AAAA,EACF;AACF,CAAC;;;AE3CD,IAAAC,cAAkB;AAOX,IAAM,eAAe,cAAE,OAAO;AAAA,EACnC,QAAQ,oBAAoB,QAAQ,UAAU,EAAE;AAAA,IAC9C;AAAA,EACF;AACF,CAAC;;;AHCM,IAAM,eAAW,yBAAY,cAAc;AAC3C,IAAM,aAAS,yBAAY,YAAY;;;AIb9C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA;AAAA;AAAA;AAAA;AAWA,IAAM,OAAO,MAAM;AAAC;AAGpB,IAAM,kBAAkB,MAAc;AACpC,QAAM,MAAM,MACV,QAAQ,QAAQ;AAAA,IACd,IAAI;AAAA,EACN,CAAC;AACH,SAAO;AACT;AAGA,IAAM,aAA8B;AAAA,EAClC,OAAO;AAAA,EACP,MAAM;AAAA,EACN,MAAM;AAAA,EACN,OAAO;AAAA,EACP,OAAO,CAAC,YAA4B;AAClC,UAAM,OAAO,YAAY,WAAW,IAAI,MAAM,OAAO,IAAI;AAAA,EAC3D;AAAA,EACA,MAAM;AAAA,EACN,OAAO,MAAM;AACf;AAKA,IAAM,mBAAmB,OAAO;AAAA,EAC9B,kBAAkB;AAAA,EAClB,qBAAqB;AAAA,EACrB,UAAU;AAAA,IACR,MAAM;AAAA,IACN,UAAU;AAAA,IACV,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,MAAM;AAAA,IACN,UAAU;AAAA,IACV,QAAQ;AAAA,IACR,UAAU;AAAA,EACZ;AAAA,EACA,UAAU,CAAC;AAAA,EACX,WAAW;AAAA,IACT,UAAU;AAAA,IACV,WAAW;AAAA,EACb;AAAA,EACA,QAAQ;AAAA,IACN,OAAO;AAAA,IACP,QAAQ;AAAA,EACV;AAAA,EACA,YAAY;AAAA,EACZ,aAAa;AAAA,EACb,aAAa;AAAA,EACb,aAAa;AAAA,EACb,SAAS;AAAA,EACT,SAAS;AACX;AAKA,IAAM,qBAAqB,OAAO;AAAA,EAChC,kBAAkB;AAAA,EAClB,qBAAqB;AAAA,EACrB,eAAe;AAAA,EACf,kBAAkB,MAAM,CAAC;AAAA,EACzB,gBAAgB;AAAA,EAChB,wBAAwB,MAAM,CAAC;AAAA,EAC/B,sBAAsB,MAAM,CAAC;AAAA,EAC7B,eAAe,OAAO;AAAA,IACpB,cAAc;AAAA,IACd,cAAc;AAAA,IACd,kBAAkB;AAAA,IAClB,qBAAqB;AAAA,EACvB;AAAA,EACA,MAAM;AAAA,IACJ,aAAa;AAAA,IACb,aAAa;AAAA,EACf;AAAA,EACA,iBAAiB;AAAA,IACf,WAAW;AAAA,IACX,YAAY;AAAA,EACd;AAAA,EACA,YAAY;AAAA,EACZ,OAAO;AAAA,EACP,UAAU;AAAA,EACV,QAAQ;AACV;AAQO,IAAM,OAAY;AAAA,EACvB,IAAI,OAAO;AACT,WAAO,gBAAgB;AAAA,EACzB;AAAA,EACA,IAAI,UAAU;AACZ,WAAO,gBAAgB;AAAA,EACzB;AAAA,EACA,IAAI,MAAM;AACR,WAAO,gBAAgB;AAAA,EACzB;AAAA,EACA,IAAI,SAAS;AACX,WAAO,iBAAiB;AAAA,EAC1B;AAAA,EACA,IAAI,WAAW;AACb,WAAO,mBAAmB;AAAA,EAC5B;AAAA,EACA,QAAQ;AACV;;;AC1HA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEO,IAAM,WAA6B;AAAA,EACxC,OAAO;AAAA,EACP,aACE;AAAA,EACF,SAAS;AAAA,IACP,MAAM;AAAA,IACN,SAAS;AAAA,MACP,KAAK;AAAA,MACL,OAAO;AAAA,MACP,UAAU;AAAA,IACZ;AAAA,EACF;AAAA,EACA,IAAI;AAAA,EACJ,KAAK;AAAA,IACH;AAAA,MACE;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,UACJ,QAAQ;AAAA,UACR,OAAO;AAAA,UACP,UAAU;AAAA,UACV,IAAI;AAAA,QACN;AAAA,QACA,SAAS,CAAC;AAAA,QACV,SAAS,CAAC;AAAA,QACV,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,QAAQ;AAAA,UACN,MAAM;AAAA,UACN,UAAU;AAAA,UACV,KAAK;AAAA,UACL,UAAU;AAAA,QACZ;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAEO,IAAM,aAA+B;AAAA,EAC1C,OAAO;AAAA,EACP,aACE;AAAA,EACF,SAAS,EAAE,MAAM,SAAS,SAAS,SAAS;AAAA,EAC5C,IAAI;AAAA,EACJ,KAAK;AAAA,IACH;AAAA,MACE;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,MAAM,EAAE,OAAO,UAAU;AAAA,QACzB,SAAS,CAAC;AAAA,QACV,SAAS,CAAC;AAAA,QACV,QAAQ,CAAC;AAAA,QACT,QAAQ;AAAA,UACN,MAAM;AAAA,UACN,UAAU;AAAA,UACV,KAAK;AAAA,UACL,UAAU;AAAA,QACZ;AAAA,QACA,SAAS;AAAA,MACX;AAAA,IACF;AAAA,EACF;AACF;AAEO,IAAM,cAAgC;AAAA,EAC3C,OAAO;AAAA,EACP,aACE;AAAA,EACF,SAAS,EAAE,MAAM,UAAU,SAAS,OAAO;AAAA,EAC3C,IAAI;AAAA,EACJ,KAAK;AAAA,IACH;AAAA,MACE;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,MAAM,EAAE,MAAM,UAAU;AAAA,QACxB,SAAS,CAAC;AAAA,QACV,SAAS,CAAC;AAAA,QACV,QAAQ,CAAC;AAAA,QACT,QAAQ;AAAA,UACN,MAAM;AAAA,UACN,UAAU;AAAA,UACV,KAAK;AAAA,UACL,UAAU;AAAA,QACZ;AAAA,QACA,SAAS;AAAA,MACX;AAAA,IACF;AAAA,EACF;AACF;AAEO,IAAM,kBAAoC;AAAA,EAC/C,OAAO;AAAA,EACP,aACE;AAAA,EACF,SAAS,EAAE,MAAM,cAAc,SAAS,MAAM;AAAA,EAC9C,IAAI;AAAA,EACJ,KAAK;AAAA,IACH;AAAA,MACE;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,MAAM,EAAE,MAAM,eAAe,UAAU,UAAU;AAAA,QACjD,SAAS,CAAC;AAAA,QACV,SAAS,CAAC;AAAA,QACV,QAAQ,CAAC;AAAA,QACT,QAAQ;AAAA,UACN,MAAM;AAAA,UACN,UAAU;AAAA,UACV,KAAK;AAAA,UACL,UAAU;AAAA,QACZ;AAAA,QACA,SAAS;AAAA,MACX;AAAA,IACF;AAAA,EACF;AACF;AAEO,IAAM,iBAAmC;AAAA,EAC9C,OAAO;AAAA,EACP,aACE;AAAA,EACF,SAAS,EAAE,MAAM,OAAO;AAAA,EACxB,IAAI;AAAA,EACJ,KAAK;AAAA,IACH;AAAA,MACE;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,UACJ,QAAQ;AAAA,UACR,OAAO;AAAA,UACP,UAAU;AAAA,UACV,IAAI;AAAA,QACN;AAAA,QACA,SAAS,CAAC;AAAA,QACV,SAAS,CAAC;AAAA,QACV,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,QAAQ;AAAA,UACN,MAAM;AAAA,UACN,UAAU;AAAA,UACV,KAAK;AAAA,UACL,UAAU;AAAA,QACZ;AAAA,MACF;AAAA,IACF;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,MAAM,EAAE,IAAI,UAAU,MAAM,WAAW;AAAA,QACvC,SAAS,CAAC;AAAA,QACV,SAAS,CAAC;AAAA,QACV,QAAQ;AAAA,UACN;AAAA,YACE,QAAQ;AAAA,YACR,MAAM,EAAE,UAAU,SAAS,SAAS,KAAK;AAAA,YACzC,SAAS,CAAC;AAAA,YACV,QAAQ,CAAC;AAAA,UACX;AAAA,QACF;AAAA,QACA,QAAQ;AAAA,UACN,MAAM;AAAA,UACN,UAAU;AAAA,UACV,KAAK;AAAA,UACL,UAAU;AAAA,QACZ;AAAA,QACA,SAAS;AAAA,MACX;AAAA,IACF;AAAA,EACF;AACF;AAEO,IAAM,qBAAuC;AAAA,EAClD,OAAO;AAAA,EACP,aACE;AAAA,EACF,SAAS,EAAE,MAAM,SAAS,SAAS,MAAM;AAAA,EACzC,IAAI;AAAA,EACJ,KAAK;AAAA,IACH;AAAA,MACE;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,MAAM,EAAE,OAAO,OAAO,WAAW,MAAM,QAAQ,CAAC,OAAO,MAAM,EAAE;AAAA,QAC/D,SAAS,CAAC;AAAA,QACV,SAAS,CAAC;AAAA,QACV,QAAQ,CAAC;AAAA,QACT,QAAQ;AAAA,UACN,MAAM;AAAA,UACN,UAAU;AAAA,UACV,KAAK;AAAA,UACL,UAAU;AAAA,QACZ;AAAA,QACA,SAAS;AAAA,MACX;AAAA,IACF;AAAA,EACF;AACF;AAEO,IAAM,oBAAsC;AAAA,EACjD,OAAO;AAAA,EACP,aACE;AAAA,EACF,SAAS,EAAE,MAAM,SAAS,SAAS,mBAAmB;AAAA,EACtD,IAAI;AAAA,EACJ,KAAK;AAAA,IACH;AAAA,MACE;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,MAAM,EAAE,OAAO,UAAU;AAAA,QACzB,SAAS,EAAE,MAAM,CAAC,mBAAmB,CAAC,EAAE;AAAA,QACxC,SAAS,EAAE,UAAU,MAAM,MAAM,UAAU;AAAA,QAC3C,QAAQ,CAAC;AAAA,QACT,QAAQ;AAAA,UACN,MAAM;AAAA,UACN,UAAU;AAAA,UACV,KAAK;AAAA,UACL,UAAU;AAAA,QACZ;AAAA,QACA,SAAS;AAAA,MACX;AAAA,IACF;AAAA,EACF;AACF;;;ACnPA,IAAAC,oBAA0B;;;ACE1B,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;AAmCO,SAAS,UACd,QACAC,UACA,SAAiB,uBAAM,SAAS,QACjB;AACf,QAAM,SAAwB,CAAC;AAG/B,QAAM,EAAE,SAAS,YAAY,IAAI,kBAAkB,QAAQ,QAAQA,QAAO;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,SAAAD;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;AA8BO,SAAS,kBAAkB,KAA0C;AAC1E,QAAM,SAAsC,CAAC;AAE7C,QAAM,aAAa,eAAe,GAAG;AAErC,aAAW,QAAQ,CAACE,SAAQ;AAC1B,UAAM,CAAC,aAAa,UAAU,IAAI,YAAYA,IAAG;AACjD,UAAM,CAACC,UAAS,aAAa,IAAI,eAAe,WAAW;AAE3D,QAAI,CAACA,SAAS;AAEd,QAAI,CAAC,QAAQ,YAAY,IAAI,eAAe,cAAc,EAAE;AAG5D,aAAS,UAAUA;AAEnB,QAAI,CAAC,OAAOA,QAAO,EAAG,QAAOA,QAAO,IAAI,CAAC;AAEzC,WAAOA,QAAO,EAAE,KAAK,EAAE,SAAAA,UAAS,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,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,MACkE;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;AAGD,MAAI,WAAW;AACf,SAAO,QAAQ;AAEb,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,QACAD,UAC0D;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,eAAeA,QAAO,GAAG;AAC3B,eAAO,EAAE,SAAS,eAAeA,QAAO,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,eAAeA,QAAO,KAAKA,aAAY,SAAS;AAClD,eAAO,EAAE,SAAS,eAAeA,QAAO,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;;;ACzgBA,IAAAE,eAAyB;AACzB,IAAAC,mBAA0B;;;ACF1B,IAAAC,eAAwD;AAajD,SAAS,yBACd,SACA,gBACA,MACA,SACA,aACA,QACA,QACyB;AACzB,QAAM,EAAE,KAAK,UAAAC,UAAS,IAAI;AAG1B,UAAI,uBAAS,cAAc,KAAK,eAAe,WAAW,SAAS,GAAG;AACpE,WAAO,IAAI,gBAAgB,IAA2B;AAAA,EACxD;AAGA,UAAI,uBAAS,cAAc,GAAG;AAC5B,UAAMC,SAAQ;AACd,QAAI,CAACA,OAAM,UAAUD,UAAS,OAAO;AACnC,YAAME,YAAaF,UAAS,MAAkB,iBAC5CA,UAAS;AACX,YAAMG,YAAWD,UAAS;AAC1B,MAAAD,OAAM,SAAS,iBAAiBE,WAAUD,SAAQ;AAAA,IACpD;AAGA,QAAI,CAACD,OAAM,WAAWD,UAAS,OAAO;AACpC,MAAAC,OAAM,UAAU,WAAWD,UAAS,QAAQA,UAAS,KAAK;AAAA,IAC5D;AAEA,WAAO,IAAIC,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,MAChBD,UAAS,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,WAAWA,UAAS,QACnBA,UAAS,MAAkB,iBAC5BA,UAAS,QACX;AACJ,QAAM,WAAW,qCAAU;AAG3B,MAAI,WAAW,UAAU,UAAU;AACjC,cAAU,KAAK,UAAU,MAAM,SAAS,SAAS;AAAA,EACnD;AAGA,QAAM,eAAe,WAAWA,UAAS,QAAQA,UAAS,KAAK;AAG/D,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;;;AHyDA,eAAsB,cACpB,SACA,SACAI,UAEoB;AACpB,QAAM,SAAS,UAAU,SAASA,UAAS,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,SAAAA;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AACF;;;ADrJA,IAAM,gBAAgD,OACpD,QACA,YACG;AACH,QAAM,YAAY,mCAA+C,aAAY;AAC7E,MAAI;AACJ,QAAM,MAAM;AACZ,QAAM,MAAM;AAEZ,QAAMC,WACJ,CAAC,MAAe,SAAmB,OAAO,YAAoB;AA5DlE;AA8DM,QAAI,SAAS,UAAU,CAAC,MAAM;AAC5B,YAAM,WACJ,OAAO,SAAS,YAAY,SAAS,OAChC,OACD,CAAC;AACP,UAAI,SAAS,KAAK;AAChB,cAAM,SAAS,IAAI,IAAI,SAAS,GAAG;AACnC,YAAI,QAAQ,aAAa,CAAC,GAAG,IAAI,OAAO,QAAQ;AAAA,MAClD;AACA,UAAI,SAAS,MAAO,KAAI,QAAQ,SAAS;AACzC,UAAI,SAAS,UAAU;AACrB,eAAO,eAAe,KAAK,YAAY;AAAA,UACrC,OAAO,SAAS;AAAA,UAChB,cAAc;AAAA,QAChB,CAAC;AAAA,MACH;AAAA,IACF;AAGA,QAAI,QAAS,KAAI,KAAK,YAAY;AAIlC,QAAI,CAAC,MAAM;AACT,YAAM,SAAS,UAAM,6BAAU,EAAE,GAAG,QAAQ,MAAK,YAAO,QAAP,YAAc,KAAK,CAAC;AACrE,aAAO,EAAE,WAAW,OAAO,WAAW,KAAK,OAAO,IAAI;AAAA,IACxD;AAGA,QAAI,CAAC,QAAQ,SAAS,OAAQ;AAG9B,UAAM,WAAW,OAAO,SAAS,WAAW,OAAO;AACnD,UAAM,SAAS,WAAW,IAAI,cAAc,QAAQ,IAAI;AAExD,QAAI,CAAC,QAAQ;AACX,cAAQ,KAAK,4CAA4C,QAAQ,GAAG;AACpE;AAAA,IACF;AAGA,UAAM,SAAS,KAAK,UAAU,QAAQ,QAAQ;AAC9C,QAAI,CAAC,QAAQ;AACX,cAAQ,KAAK,oBAAoB,QAAQ,0BAA0B;AACnE;AAAA,IACF;AAEA,UAAM,UAAmB;AAAA,MACvB,KAAK,KAAK;AAAA,MACV,UAAU,OAAO,OAAO;AAAA,IAC1B;AAGA,UAAM,cAAc,SAAS,QAAQ,IAAI;AAAA,EAC3C;AAEF,SAAO;AAAA,IACL,IAAI,OAAO;AACT,aAAO;AAAA,IACT;AAAA,IACA,SAAAA;AAAA,EACF;AACF;AAMA,IAAM,UAAU,CACd,OACA,QACwB;AACxB,MAAI,CAAC,SAAS,OAAO,UAAU,SAAU;AACzC,QAAM,OAAO;AACb,QAAM,MAAM,IAAI;AAChB,QAAM,MAAM,IAAI;AAEhB,QAAM,YAAY,MAAM;AA3I1B;AA4II,QAAI,CAAC,KAAK,WAAY;AAEtB,UAAM,QAAM,gBAAK,YAAL,mBAAc,MAAM,cAApB,mBAAgC,OAAM;AAClD,UAAM,KAAK,IAAI,cAAc,GAAG;AAEhC,eAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,KAAK,UAAU,GAAG;AAC1D,SAAG,aAAa,KAAK,KAAK;AAAA,IAC5B;AAEA,QAAI,KAAK,UAAU;AACjB,iBAAW,cAAc,KAAK,UAAU;AACtC,cAAM,QAAQ,IAAI,cAAc,KAAK;AACrC,mBAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,UAAU,GAAG;AACrD,gBAAM,aAAa,KAAK,KAAK;AAAA,QAC/B;AACA,WAAG,YAAY,KAAK;AAAA,MACtB;AAAA,IACF;AAEA,QAAI,KAAK,YAAY,EAAE;AACvB,WAAO;AAAA,EACT;AAEA,QAAM,SAAS,CAAC,KAAK,WAAW,KAAK,YAAY;AAEjD,MAAI,QAAQ;AACV,QAAI,KAAK,KAAK;AACZ,YAAM,SAAS,IAAI,IAAI,KAAK,GAAG;AAC/B,UAAI,QAAQ,aAAa,CAAC,GAAG,IAAI,OAAO,QAAQ;AAAA,IAClD;AACA,QAAI,KAAK,OAAO;AACd,UAAI,QAAQ,KAAK;AAAA,IACnB;AACA,QAAI,KAAK,UAAU;AACjB,aAAO,eAAe,KAAK,YAAY,EAAE,OAAO,KAAK,SAAS,CAAC;AAAA,IACjE;AACA,cAAU;AACV;AAAA,EACF;AAGA,SAAO,MAAM;AACX,UAAM,KAAK,UAAU;AACrB,QAAI,CAAC,GAAI;AAET,YAAQ,KAAK,SAAS;AAAA,MACpB,KAAK;AACH,WAAG,cAAc,IAAI,WAAW,SAAS,EAAE,SAAS,KAAK,CAAC,CAAC;AAC3D;AAAA,MACF,KAAK;AACH,WAAG,cAAc,IAAI,MAAM,UAAU,EAAE,SAAS,KAAK,CAAC,CAAC;AACvD;AAAA,MACF,KAAK;AACH,WAAG,cAAc,IAAI,WAAW,cAAc,EAAE,SAAS,KAAK,CAAC,CAAC;AAChE;AAAA,MACF,KAAK;AACH,YAAI,cAAc,IAAI,MAAM,QAAQ,CAAC;AACrC;AAAA,IACJ;AAAA,EACF;AACF;","names":["import_dev","import_dev","import_dev","import_collector","import_core","import_collector","import_web_core","trigger","filter","str","trigger","elem","import_core","import_web_core","import_core","settings","event","scopeDoc","scopeWin","trigger","trigger"]}
|