@adartem/adlib-attributes 0.1.0 → 0.1.1

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/attributes.js.map CHANGED
@@ -1 +1,7 @@
1
- {"version":3,"sources":["../../adlib-utils/src/attributes/keys.ts","../../adlib-utils/src/dom/guards.ts","../../adlib-utils/src/dom/scan.ts","../../adlib-utils/src/env/bool.ts","../../adlib-utils/src/env/index.ts","../src/core/index.ts","../src/runtime/module-map.ts","../src/runtime/runtime.ts","../src/runtime/script-detection.ts","../src/runtime/attributes.ts"],"sourcesContent":["import type { ModuleKey } from '../types';\n\nexport function isModuleKey(value: string): value is ModuleKey {\n return value.startsWith('ad-') && value.length > 3;\n}\n\nexport function normalizeAttributeName(name: string): string {\n return name.startsWith('data-') ? name.slice(5) : name;\n}","export type QuerySelectorAllHost = {\n querySelectorAll(selectors: string): NodeListOf<Element>;\n};\n\n/**\n * Type guard: vérifie que `value` expose bien `querySelectorAll`.\n * - sans `any`\n * - sans accès unsafe\n */\nexport function hasQuerySelectorAll(value: unknown): value is QuerySelectorAllHost {\n if (typeof value !== 'object' || value === null) return false;\n\n // On passe par une signature \"indexée\" typée en unknown,\n // puis on raffine vers Function.\n const v = value as Record<string, unknown>;\n const qsa = v['querySelectorAll'];\n\n return typeof qsa === 'function';\n}","import { isModuleKey, normalizeAttributeName } from '../attributes/keys';\nimport type { ModuleKey } from '../types';\nimport { hasQuerySelectorAll } from './guards';\n\nexport function collectModuleKeysFromDOM(root: ParentNode = document): ModuleKey[] {\n if (!hasQuerySelectorAll(root)) return [];\n\n const found = new Set<string>();\n const elements = root.querySelectorAll<HTMLElement>('*');\n\n for (const el of Array.from(elements)) {\n for (const attr of Array.from(el.attributes)) {\n const normalized = normalizeAttributeName(attr.name);\n if (!isModuleKey(normalized)) continue;\n found.add(normalized);\n }\n }\n\n return Array.from(found) as ModuleKey[];\n}","export function parseBoolAttr(v: string | null): boolean | undefined {\n if (v == null) return undefined;\n const s = v.trim().toLowerCase();\n if (s === '' || s === '1' || s === 'true') return true;\n if (s === '0' || s === 'false') return false;\n return undefined;\n}","export function isBrowser(): boolean {\n return typeof window !== 'undefined' && typeof document !== 'undefined';\n}\n\nexport function isServer(): boolean {\n return !isBrowser();\n}\n\nexport * from './bool';","/* --------------------------------------------------------------------------\n * AdLib Attributes · Core\n *\n * Primitives partagées utilisées par le runtime et les modules d’attributs :\n * - délégation d’événements (listeners uniques sur une racine)\n * - registre de modules (définitions + instances)\n * - cycle de vie (mount/unmount/destroy)\n * - observation DOM (signal de changements, orchestration pilotée par le runtime)\n * -------------------------------------------------------------------------- */\n\nexport type Disposer = () => void;\nexport type Cleanup = void | Disposer;\n\nexport type CoreLogger = {\n debug: (...args: unknown[]) => void;\n warn: (...args: unknown[]) => void;\n error: (...args: unknown[]) => void;\n};\n\nexport type CoreOptions = {\n /** Root document/shadow root to bind listeners & observer (defaults to document). */\n root?: Document | ShadowRoot;\n /** Enable debug logs (printed as console.warn with \"[debug]\"). */\n debug?: boolean;\n /** Auto-mount modules on DOMContentLoaded when using singleton. Default: true. */\n autoMount?: boolean;\n};\n\nexport type DelegatedHandler = (e: Event, matched: Element) => void;\n\nexport type OnOptions = {\n /** If true, this delegated handler will run once then auto-unsubscribe. */\n once?: boolean;\n /** Capture phase for the underlying listener (per event type, first call wins). */\n capture?: boolean;\n /** Passive flag for the underlying listener (per event type, first call wins). */\n passive?: boolean;\n};\n\nexport interface Core {\n /**\n * Event delegation: listen on root and invoke handler when an ancestor matches selector.\n * Returns a disposer to remove this specific handler.\n */\n on: (type: string, selector: string, handler: DelegatedHandler, options?: OnOptions) => Disposer;\n\n /** Emit a CustomEvent from a given element. */\n emit: (el: Element, name: string, detail?: unknown) => void;\n\n /** Register a module definition. */\n register: (def: AdLibModuleDefinition) => void;\n\n /** Unregister a module definition by key. */\n unregister: (key: ModuleKey) => void;\n\n /** Mount a module by key, optionally on a given root. */\n mount: (key: ModuleKey, root?: ParentNode) => void;\n\n /** Unmount a module instance by key. */\n unmount: (key: ModuleKey) => void;\n\n /** Mount all registered modules. */\n mountAll: (root?: ParentNode) => void;\n\n /** Unmount all mounted modules. */\n unmountAll: () => void;\n\n /**\n * Observe dynamic DOM changes on a given root.\n *\n * Rôle :\n * - fournir un signal de changement DOM (ajouts/retraits de nœuds)\n * - permettre au runtime d’orchestrer un rescan/remount si nécessaire\n *\n * Retourne un disposer pour arrêter l’observation.\n */\n observe: (root?: ParentNode) => Disposer;\n\n /** Stop observing dynamic DOM changes. */\n stopObserving: () => void;\n\n /** Destroy core: unmount all, remove listeners, disconnect observer. */\n destroy: () => void;\n\n /** Core logger (debug/warn/error). */\n getLogger: () => CoreLogger;\n}\n\n/** Module key type (ex: 'ad-click'). */\nexport type ModuleKey = `ad-${string}`;\n\nexport interface AdLibModuleInstance {\n key: ModuleKey;\n destroy(): void;\n restart?(options?: { rescan?: boolean }): void;\n}\n\nexport interface AdLibModuleDefinition {\n key: ModuleKey;\n init(core: Core): AdLibModuleInstance;\n}\n\n/* --------------------------------- Internals -------------------------------- */\n\ntype DelegatedEntry = {\n selector: string;\n handler: DelegatedHandler;\n once: boolean;\n};\n\ntype EventListenerInfo = {\n capture: boolean;\n passive: boolean;\n listener: (e: Event) => void;\n entries: DelegatedEntry[];\n};\n\nfunction createLogger(debug = false): CoreLogger {\n return {\n debug: (...args: unknown[]) => {\n if (!debug) return;\n console.warn('[debug]', ...args);\n },\n warn: (...args: unknown[]) => {\n console.warn('[warn]', ...args);\n },\n error: (...args: unknown[]) => {\n console.error('[error]', ...args);\n },\n };\n}\n\nfunction isElement(value: unknown): value is Element {\n // Garde-fou typé : vérifie l’existence de Element (tests / environnements non DOM).\n return typeof Element !== 'undefined' && value instanceof Element;\n}\n\nfunction safeMatches(el: Element, selector: string): boolean {\n try {\n return el.matches(selector);\n } catch {\n return false;\n }\n}\n\nfunction findClosestMatching(target: EventTarget | null, selector: string): Element | null {\n let cur: EventTarget | null = target;\n\n while (cur) {\n if (isElement(cur) && safeMatches(cur, selector)) return cur;\n cur = isElement(cur) ? cur.parentElement : null;\n }\n\n return null;\n}\n\nfunction createDelegatedListener(info: EventListenerInfo) {\n return (e: Event) => {\n // Copie défensive : la liste peut être modifiée par un handler \"once\".\n const entries = info.entries.slice();\n\n for (const entry of entries) {\n const matched = findClosestMatching(e.target, entry.selector);\n if (!matched) continue;\n\n entry.handler(e, matched);\n\n if (entry.once) {\n const idx = info.entries.indexOf(entry);\n if (idx >= 0) info.entries.splice(idx, 1);\n }\n }\n };\n}\n\nfunction resolveObserverTarget(root: ParentNode): Node {\n // MutationObserver attend un Node.\n // - Document => document.documentElement si disponible, sinon le document lui-même\n // - ShadowRoot / Element => observe directement\n if (root instanceof Document) return root.documentElement ?? root;\n return root as unknown as Node;\n}\n\n/* ---------------------------------- Core ---------------------------------- */\n\nexport function createCore(options: CoreOptions = {}): Core {\n const root: Document | ShadowRoot = options.root ?? document;\n const logger = createLogger(!!options.debug);\n\n const defs = new Map<ModuleKey, AdLibModuleDefinition>();\n const instances = new Map<ModuleKey, AdLibModuleInstance>();\n\n const listenersByType = new Map<string, EventListenerInfo>();\n\n function on(type: string, selector: string, handler: DelegatedHandler, opts: OnOptions = {}): Disposer {\n const capture = !!opts.capture;\n const passive = !!opts.passive;\n\n const existing = listenersByType.get(type);\n if (existing) {\n existing.entries.push({ selector, handler, once: !!opts.once });\n\n return () => {\n const idx = existing.entries.findIndex((e) => e.selector === selector && e.handler === handler);\n if (idx >= 0) existing.entries.splice(idx, 1);\n\n // ✅ Si c'était le dernier handler, on retire le listener racine et on nettoie la map\n if (existing.entries.length === 0) {\n root.removeEventListener(type, existing.listener, { capture: existing.capture });\n listenersByType.delete(type);\n }\n };\n }\n\n const info: EventListenerInfo = {\n capture,\n passive,\n entries: [{ selector, handler, once: !!opts.once }],\n listener: () => {},\n };\n\n const listener = createDelegatedListener(info);\n info.listener = listener;\n\n listenersByType.set(type, info);\n\n root.addEventListener(type, listener, { capture, passive });\n\n // ✅ Disposer “handler-level” (pas “type-level”)\n return () => {\n const cur = listenersByType.get(type);\n if (!cur) return;\n\n const idx = cur.entries.findIndex((e) => e.selector === selector && e.handler === handler);\n if (idx >= 0) cur.entries.splice(idx, 1);\n\n if (cur.entries.length === 0) {\n root.removeEventListener(type, cur.listener, { capture: cur.capture });\n listenersByType.delete(type);\n }\n };\n }\n\n function emit(el: Element, name: string, detail?: unknown) {\n const ev = new CustomEvent(name, { detail, bubbles: true });\n el.dispatchEvent(ev);\n }\n\n function register(def: AdLibModuleDefinition) {\n defs.set(def.key, def);\n }\n\n function unregister(key: ModuleKey) {\n defs.delete(key);\n }\n\n function mount(key: ModuleKey, _root?: ParentNode) {\n const def = defs.get(key);\n if (!def) return;\n if (instances.has(key)) return;\n\n const inst = def.init(api);\n instances.set(key, inst);\n }\n\n function unmount(key: ModuleKey) {\n const inst = instances.get(key);\n if (!inst) return;\n inst.destroy();\n instances.delete(key);\n }\n\n function mountAll(_root?: ParentNode) {\n for (const key of defs.keys()) mount(key);\n }\n\n function unmountAll() {\n for (const key of instances.keys()) unmount(key);\n }\n\n let observer: MutationObserver | null = null;\n\n function observe(observedRoot: ParentNode = root): Disposer {\n if (observer) return () => {};\n\n observer = new MutationObserver((_mutations) => {\n // Signal DOM : le runtime est responsable de décider quoi charger / recharger.\n // Le core garantit uniquement une observation stable et désinscriptible.\n });\n\n observer.observe(resolveObserverTarget(observedRoot), {\n subtree: true,\n childList: true,\n attributes: false,\n });\n\n return () => stopObserving();\n }\n\n function stopObserving() {\n if (!observer) return;\n observer.disconnect();\n observer = null;\n }\n\n function destroy() {\n stopObserving();\n unmountAll();\n\n for (const [type, info] of listenersByType.entries()) {\n root.removeEventListener(type, info.listener, { capture: info.capture });\n }\n\n listenersByType.clear();\n defs.clear();\n instances.clear();\n }\n\n function getLogger() {\n return logger;\n }\n\n const api: Core = {\n on,\n emit,\n register,\n unregister,\n mount,\n unmount,\n mountAll,\n unmountAll,\n observe,\n stopObserving,\n destroy,\n getLogger,\n };\n\n return api;\n}\n\n/* ----------------------------- Singleton helpers ---------------------------- */\n\nlet singleton: Core | null = null;\n\nexport function getCoreSingleton(options: CoreOptions = {}): Core {\n if (singleton) return singleton;\n singleton = createCore({ autoMount: true, ...options });\n\n const shouldAutoMount = options.autoMount ?? true;\n if (shouldAutoMount && typeof document !== 'undefined') {\n if (document.readyState === 'loading') {\n document.addEventListener(\n 'DOMContentLoaded',\n () => {\n singleton?.mountAll();\n },\n { once: true }\n );\n } else {\n singleton.mountAll();\n }\n }\n\n return singleton;\n}\n\nexport default createCore;","import type { ModuleKey, RuntimeConfig } from './types';\n\nfunction normalizeOrigin(origin: string): string {\n return origin.trim().replace(/\\/+$/, '');\n}\n\nfunction resolveOrigin(config: RuntimeConfig): string {\n // `base` permet de forcer une origine de chargement (ex: CDN custom).\n // Sinon, on utilise `registry` (ex: jsDelivr / unpkg / registry interne).\n return normalizeOrigin(config.base ?? config.registry);\n}\n\nfunction resolveVersion(config: RuntimeConfig): string {\n const v = (config.version ?? '').trim();\n return v || 'latest';\n}\n\n/**\n * Construit le chemin d'import ESM d'un module à partir de la configuration runtime.\n * Format :\n * {origin}/@adartem/{package}@{version}/dist/index.js\n */\nfunction makeEsmImportPath(origin: string, pkgName: string, version: string): string {\n return `${origin}/@adartem/${pkgName}@${version}/dist/index.js`;\n}\n\nconst PACKAGE_BY_KEY: Record<ModuleKey, string> = {\n 'ad-click': 'ad-click',\n};\n\nexport function getImportPathForModule(key: ModuleKey, config: RuntimeConfig): string | null {\n const origin = resolveOrigin(config);\n const version = resolveVersion(config);\n\n const pkgName = PACKAGE_BY_KEY[key];\n if (!pkgName) return null;\n\n return makeEsmImportPath(origin, pkgName, version);\n}","import { collectModuleKeysFromDOM, isBrowser } from '@adartem/adlib-utils';\n\nimport type { Core } from '../core';\nimport { createCore } from '../core';\nimport { getImportPathForModule } from './module-map';\nimport type {\n AdLibModuleDefinition,\n AdLibRuntime,\n GlobalQueueItem,\n ModuleKey,\n RuntimeConfig,\n RuntimeModuleState,\n RuntimeOptions,\n} from './types';\n\n/**\n * Runtime robuste:\n * - load() : import + init(core) + état\n * - push() : callbacks avant/après load\n * - queue globale window.AdLibAttributesQueue\n * - reload() : destroy module + re-init\n * - auto (optionnel) : scan DOM minimal + MutationObserver\n */\n\ntype QueueEntry = {\n key: ModuleKey;\n cb: (state: RuntimeModuleState) => void;\n};\n\nconst DEFAULT_REGISTRY = 'https://cdn.jsdelivr.net/npm';\n\nfunction stateOf(modules: Record<string, RuntimeModuleState>, key: ModuleKey): RuntimeModuleState {\n return (modules[key] ??= { key, status: 'idle' });\n}\n\nfunction isReadyOrError(s: RuntimeModuleState) {\n return s.status === 'ready' || s.status === 'error';\n}\n\nfunction toError(err: unknown): Error {\n return err instanceof Error ? err : new Error(String(err));\n}\n\nfunction normalizeUrlBase(value?: string): string | undefined {\n const v = (value ?? '').trim();\n if (!v) return undefined;\n return v.replace(/\\/+$/, '');\n}\n\nfunction resolveConfig(options: RuntimeOptions): RuntimeConfig {\n const registry = normalizeUrlBase(options.config?.registry) ?? DEFAULT_REGISTRY;\n const version = (options.config?.version ?? options.version).trim() || options.version;\n\n const out: RuntimeConfig = { registry, version };\n\n const base = normalizeUrlBase(options.config?.base);\n if (base) out.base = base; // ✅ n’ajoute pas la clé si undefined\n\n return out;\n}\n\n/**\n * Valide/normalise le résultat d'un import dynamique vers une AdLibModuleDefinition.\n * Permet d'éviter les `any` et les accès unsafe.\n */\nfunction toModuleDefinition(mod: unknown, expectedKey: ModuleKey): AdLibModuleDefinition {\n const candidate = (() => {\n if (mod && typeof mod === 'object') {\n const record = mod as Record<string, unknown>;\n return record.default ?? mod;\n }\n return mod;\n })();\n\n if (!candidate || typeof candidate !== 'object') {\n throw new Error(`Invalid module definition for ${expectedKey}`);\n }\n\n const def = candidate as Partial<AdLibModuleDefinition>;\n\n if (typeof def.key !== 'string' || typeof def.init !== 'function') {\n throw new Error(`Invalid module definition for ${expectedKey}`);\n }\n\n // Sécurité: clé cohérente\n if (def.key !== expectedKey) {\n throw new Error(`Module key mismatch: expected \"${expectedKey}\", got \"${def.key}\"`);\n }\n\n return def as AdLibModuleDefinition;\n}\n\nexport function createRuntime(options: RuntimeOptions): AdLibRuntime {\n const debug = options.debug ?? false;\n const auto = options.auto ?? false;\n\n // ✅ Ownership: runtime propriétaire uniquement si options.core est absent (null/undefined)\n const ownsCore = options.core == null;\n\n // ✅ Runtime ne récupère jamais le singleton tout seul.\n // - si core injecté => utilisé tel quel, et NON détruit par runtime.destroy()\n // - sinon => core dédié, détruit par runtime.destroy()\n const core: Core =\n options.core ??\n createCore({\n debug,\n autoMount: false,\n });\n\n const logger = core.getLogger();\n const config = resolveConfig(options);\n\n const modules: Record<string, RuntimeModuleState> = {};\n const queue: QueueEntry[] = [];\n\n let observer: MutationObserver | null = null;\n\n function log(...args: unknown[]) {\n if (!debug) return;\n logger.debug('[AdLib Runtime]', ...args);\n }\n\n function logError(...args: unknown[]) {\n logger.error('[AdLib Runtime]', ...args);\n }\n\n function flush(key: ModuleKey, st: RuntimeModuleState) {\n for (let i = queue.length - 1; i >= 0; i--) {\n const entry = queue[i];\n if (!entry) continue;\n if (entry.key === key) {\n queue.splice(i, 1);\n try {\n entry.cb(st);\n } catch (e) {\n logError('push callback failed', key, e);\n }\n }\n }\n }\n\n function destroyModule(key: ModuleKey) {\n const st = modules[key];\n if (!st) return;\n\n try {\n st.instance?.destroy?.();\n } catch (e) {\n logError('destroyModule failed', key, e);\n }\n\n delete st.instance;\n delete st.def;\n delete st.error;\n delete st.promise;\n\n st.status = 'idle';\n }\n\n async function load(key: ModuleKey): Promise<RuntimeModuleState> {\n const st = stateOf(modules, key);\n\n if (st.status === 'ready') return st;\n if (st.status === 'error') return st;\n\n if (st.status === 'loading' && st.promise) return st.promise;\n\n const importPath = getImportPathForModule(key, config);\n if (!importPath) {\n st.status = 'error';\n st.error = new Error(`Unknown module key: ${key}`);\n flush(key, st);\n return st;\n }\n\n st.status = 'loading';\n log('load()', key, '->', importPath);\n\n const promise: Promise<RuntimeModuleState> = (async () => {\n try {\n const mod: unknown = await import(/* @vite-ignore */ importPath);\n const def = toModuleDefinition(mod, key);\n\n st.def = def;\n\n if (!st.instance) {\n st.instance = def.init(core);\n }\n\n st.status = 'ready';\n delete st.error;\n delete st.promise;\n\n flush(key, st);\n return st;\n } catch (err) {\n st.status = 'error';\n st.error = toError(err);\n delete st.promise;\n\n flush(key, st);\n return st;\n }\n })();\n\n st.promise = promise;\n return promise;\n }\n\n async function reload(key: ModuleKey): Promise<RuntimeModuleState> {\n log('reload()', key);\n destroyModule(key);\n return load(key);\n }\n\n function push(key: ModuleKey, cb: (state: RuntimeModuleState) => void) {\n const st = modules[key];\n if (st && isReadyOrError(st)) {\n try {\n cb(st);\n } catch (e) {\n logError('push callback failed', key, e);\n }\n return;\n }\n queue.push({ key, cb });\n }\n\n function autoLoadFromDOM(root: ParentNode = document) {\n const keys = collectModuleKeysFromDOM(root);\n for (const key of keys) void load(key);\n }\n\n function startObserver() {\n if (!isBrowser()) return;\n if (observer) return;\n\n observer = new MutationObserver((mutations) => {\n for (const m of mutations) {\n for (const node of Array.from(m.addedNodes)) {\n if (!(node instanceof HTMLElement)) continue;\n autoLoadFromDOM(node);\n }\n }\n });\n\n observer.observe(document.documentElement, { childList: true, subtree: true });\n }\n\n function stopObserver() {\n observer?.disconnect();\n observer = null;\n }\n\n function destroy(opts?: { keepGlobal?: boolean }) {\n log('destroy()');\n\n stopObserver();\n\n for (const st of Object.values(modules)) {\n try {\n st.instance?.destroy?.();\n } catch (e) {\n logError('destroy module failed', st.key, e);\n }\n }\n\n // ✅ Ownership rule: ne détruit le core QUE si le runtime l'a créé\n if (ownsCore) {\n try {\n core.destroy();\n } catch (e) {\n logError('core.destroy failed', e);\n }\n }\n\n for (const k of Object.keys(modules)) delete modules[k];\n queue.length = 0;\n\n if (!opts?.keepGlobal && typeof window !== 'undefined') {\n delete window.AdLibAttributes;\n }\n }\n\n const runtime: AdLibRuntime = {\n version: options.version,\n config,\n core,\n debug,\n modules,\n load,\n push,\n reload,\n destroy,\n };\n\n if (typeof window !== 'undefined') {\n const globalQ = window.AdLibAttributesQueue;\n if (Array.isArray(globalQ) && globalQ.length > 0) {\n const items: GlobalQueueItem[] = globalQ.splice(0, globalQ.length);\n for (const [key, cb] of items) runtime.push(key, cb);\n }\n }\n\n if (auto && isBrowser()) {\n autoLoadFromDOM(document.body ?? document);\n startObserver();\n }\n\n return runtime;\n}","import { isModuleKey, normalizeAttributeName } from '@adartem/adlib-utils';\n\nimport type { LoaderScriptConfig, LoaderScriptInfo, RuntimeConfig } from './types';\n\n/** Helpers DOM-agnostic (compat jsdom + environnements DOM partiels) */\n\ntype AttrLike = { name: string };\ntype AttributesLike = {\n length: number;\n item(index: number): AttrLike | null;\n};\n\nfunction hasGetAttributeNames(el: unknown): el is { getAttributeNames(): unknown } {\n return (\n typeof el === 'object' &&\n el !== null &&\n typeof (el as { getAttributeNames?: unknown }).getAttributeNames === 'function'\n );\n}\n\nfunction isStringArray(value: unknown): value is string[] {\n return Array.isArray(value) && value.every((v) => typeof v === 'string');\n}\n\nfunction hasAttributesLike(el: unknown): el is { attributes: AttributesLike } {\n if (typeof el !== 'object' || el === null) return false;\n\n const attrs = (el as { attributes?: unknown }).attributes;\n if (typeof attrs !== 'object' || attrs === null) return false;\n\n const a = attrs as Partial<AttributesLike>;\n return typeof a.length === 'number' && typeof a.item === 'function';\n}\n\nfunction hasQuerySelectorAll(\n root: unknown,\n): root is ParentNode & { querySelectorAll(selectors: string): NodeListOf<Element> } {\n if (typeof root !== 'object' || root === null) return false;\n return typeof (root as { querySelectorAll?: unknown }).querySelectorAll === 'function';\n}\n\n/** Safe wrapper (jsdom + navigateurs anciens + environnements DOM partiels) */\nfunction getAttributeNamesSafe(el: Element): string[] {\n // 1) voie moderne: getAttributeNames()\n if (hasGetAttributeNames(el)) {\n const maybe = el.getAttributeNames();\n if (isStringArray(maybe)) return maybe;\n }\n\n // 2) fallback: attributes NamedNodeMap-like (structure minimale)\n if (hasAttributesLike(el)) {\n const out: string[] = [];\n for (let i = 0; i < el.attributes.length; i++) {\n const attr = el.attributes.item(i);\n if (attr && typeof attr.name === 'string' && attr.name) out.push(attr.name);\n }\n return out;\n }\n\n return [];\n}\n\n/**\n * Heuristique “loader script” :\n * - <script type=\"module\" src=\".../attributes.js\">\n * Tolérant aux chemins (CDN, querystring, chemins relatifs/absolus).\n */\nfunction isAttributesLoaderScript(s: HTMLScriptElement): boolean {\n const type = (s.getAttribute('type') ?? '').trim();\n if (type && type !== 'module') return false;\n\n const src = (s.getAttribute('src') ?? '').trim();\n if (!src) return false;\n\n return src.includes('attributes.js');\n}\n\nfunction pickNonEmptyString(value: unknown): string | undefined {\n if (typeof value !== 'string') return undefined;\n const v = value.trim();\n return v ? v : undefined;\n}\n\nfunction parseBoolean(value: unknown, fallback: boolean): boolean {\n if (typeof value !== 'string') return fallback;\n const v = value.trim().toLowerCase();\n if (v === '' || v === 'true' || v === '1' || v === 'yes' || v === 'on') return true;\n if (v === 'false' || v === '0' || v === 'no' || v === 'off') return false;\n return fallback;\n}\n\n/**\n * Source unique de vérité: lit data-adlib-* depuis le <script> et retourne une config normalisée.\n * Conventions dataset camelCase :\n * - data-adlib-registry => dataset.adlibRegistry\n * - data-adlib-version => dataset.adlibVersion\n * - data-adlib-base => dataset.adlibBase\n * - data-adlib-auto => dataset.adlibAuto\n * - data-adlib-debug => dataset.adlibDebug\n */\nfunction readLoaderConfig(s: HTMLScriptElement): LoaderScriptConfig {\n // dataset est standard sur HTMLScriptElement en DOM.\n // Fallback léger pour les environnements DOM incomplets.\n const ds = (s as unknown as { dataset?: Record<string, string> }).dataset ?? {};\n\n const debug = parseBoolean(ds.adlibDebug, false);\n const auto = parseBoolean(ds.adlibAuto, true);\n\n const registry = pickNonEmptyString(ds.adlibRegistry);\n const version = pickNonEmptyString(ds.adlibVersion);\n const base = pickNonEmptyString(ds.adlibBase);\n\n // ✅ exactOptionalPropertyTypes-safe : ne pas inclure les clés si undefined\n const config: Partial<RuntimeConfig> = {};\n if (registry) config.registry = registry;\n if (version) config.version = version;\n if (base) config.base = base;\n\n return { debug, auto, config };\n}\n\nexport function findLoaderScripts(root: ParentNode = document): LoaderScriptInfo[] {\n if (!hasQuerySelectorAll(root)) return [];\n\n const scripts = Array.from(root.querySelectorAll('script'));\n const result: LoaderScriptInfo[] = [];\n\n for (const script of scripts) {\n if (!(script instanceof HTMLScriptElement)) continue;\n if (!isAttributesLoaderScript(script)) continue;\n\n const requested = new Set<LoaderScriptInfo['requestedKeys'][number]>();\n\n for (const rawName of getAttributeNamesSafe(script)) {\n const name = normalizeAttributeName(rawName);\n if (isModuleKey(name)) requested.add(name);\n }\n\n result.push({\n el: script,\n requestedKeys: Array.from(requested),\n loaderConfig: readLoaderConfig(script),\n });\n }\n\n return result;\n}","import { isBrowser } from '@adartem/adlib-utils';\n\nimport { getCoreSingleton } from '../core';\nimport { createRuntime } from './runtime';\nimport { findLoaderScripts } from './script-detection';\nimport type { ModuleKey } from './types';\n\ndeclare const __ADLIB_VERSION__: string | undefined;\n\n// Vitest / dev (TS direct) => la constante n'existe pas\n// Build tsup => la constante est injectée (string)\nconst VERSION = typeof __ADLIB_VERSION__ === 'string' ? __ADLIB_VERSION__ : 'dev';\n\n(function bootstrap() {\n if (!isBrowser()) return;\n\n // Ne pas re-bootstrap si déjà présent\n if (window.AdLibAttributes) return;\n\n const loaders = findLoaderScripts(document);\n const primary = loaders[0];\n\n // ✅ Source unique de vérité: script-detection.ts normalise data-adlib-*\n const debug = primary?.loaderConfig.debug ?? false;\n const auto = primary?.loaderConfig.auto ?? true;\n const config = primary?.loaderConfig.config ?? {};\n\n const core = getCoreSingleton({ root: document, debug });\n const runtime = createRuntime({\n version: VERSION,\n core,\n debug,\n auto,\n config,\n });\n\n // Expose global\n window.AdLibAttributes = runtime;\n\n // 1) Modules demandés via attributs du <script ... attributes.js ...>\n const requested = new Set<ModuleKey>();\n for (const info of loaders) {\n for (const k of info.requestedKeys) requested.add(k);\n }\n\n // 2) Chargement initial\n for (const key of requested) {\n runtime.load(key).catch(() => {\n // le runtime gère déjà l'état error ; ici on évite de throw global\n });\n }\n})();"],"mappings":"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","names":["isModuleKey","value","normalizeAttributeName","name","hasQuerySelectorAll","collectModuleKeysFromDOM","root","found","elements","el","attr","normalized","isBrowser","createLogger","debug","args","isElement","value","safeMatches","el","selector","findClosestMatching","target","cur","createDelegatedListener","info","e","entries","entry","matched","idx","resolveObserverTarget","root","createCore","options","logger","defs","instances","listenersByType","on","type","handler","opts","capture","passive","existing","listener","emit","name","detail","ev","register","def","unregister","key","mount","_root","inst","api","unmount","mountAll","unmountAll","observer","observe","observedRoot","_mutations","stopObserving","destroy","getLogger","singleton","getCoreSingleton","normalizeOrigin","origin","resolveOrigin","config","resolveVersion","makeEsmImportPath","pkgName","version","PACKAGE_BY_KEY","getImportPathForModule","key","DEFAULT_REGISTRY","stateOf","modules","key","isReadyOrError","s","toError","err","normalizeUrlBase","value","v","resolveConfig","options","registry","version","out","base","toModuleDefinition","mod","expectedKey","candidate","def","createRuntime","debug","auto","ownsCore","core","createCore","logger","config","queue","observer","log","args","logError","flush","st","i","entry","e","destroyModule","load","importPath","getImportPathForModule","promise","reload","push","cb","autoLoadFromDOM","root","keys","collectModuleKeysFromDOM","startObserver","isBrowser","mutations","m","node","stopObserver","destroy","opts","k","runtime","globalQ","items","hasGetAttributeNames","el","isStringArray","value","v","hasAttributesLike","attrs","a","hasQuerySelectorAll","root","getAttributeNamesSafe","maybe","out","i","attr","isAttributesLoaderScript","s","type","src","pickNonEmptyString","parseBoolean","fallback","readLoaderConfig","ds","debug","auto","registry","version","base","config","findLoaderScripts","scripts","result","script","requested","rawName","name","normalizeAttributeName","isModuleKey","VERSION","isBrowser","loaders","findLoaderScripts","primary","debug","auto","config","core","getCoreSingleton","runtime","createRuntime","requested","info","k","key"]}
1
+ {
2
+ "version": 3,
3
+ "sources": ["src/attributes.ts", "package.json", "src/load.ts"],
4
+ "sourcesContent": ["import {\n type AdartemAttributeKey,\n type AdartemAttributesCallback,\n attachExternalStylesheets,\n ATTRIBUTES,\n fetchPage,\n waitDOMReady,\n} from '@adartem/adlib-utils';\n\nimport { version } from '../package.json';\nimport { loadAttribute } from './load';\n\nconst ATTRIBUTES_ATTRIBUTE_PREFIX = 'ad-attributes';\nconst ATTRIBUTE_KEYS = new Set(Object.values(ATTRIBUTES));\n\n/**\n * Inits the Adartem Attributes library.\n */\nconst init = () => {\n const { AdartemAttributes } = window;\n\n // Avoid initting the Attributes API more than once.\n // If the API is already initted, just init the individual Attributes and escape.\n if (AdartemAttributes && !Array.isArray(AdartemAttributes)) {\n initAttributes();\n return;\n }\n\n // Collect pre-existing callbacks\n const callbacks = Array.isArray(AdartemAttributes)\n ? (AdartemAttributes as AdartemAttributesCallback[])\n : [];\n\n // Collect library scripts\n const scripts = [\n ...document.querySelectorAll<HTMLScriptElement>(\n `script[type=\"module\"][src=\"${import.meta.url}\"]`,\n ),\n ];\n\n // Init Attributes object\n window.AdartemAttributes = {\n version,\n scripts,\n modules: {},\n process: new Set<AdartemAttributeKey>(),\n utils: {\n fetchPage,\n attachExternalStylesheets,\n },\n\n load: initAttribute,\n\n push(...args) {\n for (const [key, callback] of args) {\n this.modules[key]?.loading?.then(callback);\n }\n },\n\n destroy() {\n for (const solution in this.modules) {\n this.modules[solution as keyof typeof this.modules]?.destroy?.();\n }\n },\n };\n\n // Init Attributes\n initAttributes();\n\n // Run pre-existing callbacks\n window.AdartemAttributes.push(...callbacks);\n};\n\n/**\n * Inits all Attributes that are defined in the current script\n * or in the DOM if fs-attributes-auto is enabled.\n */\nconst initAttributes = () => {\n let autoLoad = false;\n\n for (const script of window.AdartemAttributes.scripts) {\n autoLoad ||= script.getAttribute(`${ATTRIBUTES_ATTRIBUTE_PREFIX}-auto`) === 'true';\n\n for (const key of ATTRIBUTE_KEYS) {\n const isDefined = script.hasAttribute(`ad-${key}`);\n if (!isDefined) continue;\n\n initAttribute(key);\n }\n }\n\n if (!autoLoad) return;\n\n waitDOMReady().then(() => {\n const usedAttributes = new Set<AdartemAttributeKey>();\n const allElements = document.querySelectorAll('*');\n\n for (const element of allElements) {\n for (const name of element.getAttributeNames()) {\n const adMatch = name.match(/^ad-([^-]+)/);\n const key = adMatch?.[1] as AdartemAttributeKey | undefined;\n\n if (key && ATTRIBUTE_KEYS.has(key)) {\n usedAttributes.add(key);\n }\n }\n }\n\n for (const attribute of usedAttributes) {\n initAttribute(attribute);\n }\n });\n};\n\n/**\n * Inits an individual Attribute.\n * @param key\n * @param script The <script> tag that defines the Attribute.\n *\n * @returns A Promise that resolves once the Attribute has loaded and executed.\n */\nconst initAttribute = async (key: AdartemAttributeKey) => {\n // Ensure that the attribute is only initted once\n if (window.AdartemAttributes.process.has(key)) return;\n\n window.AdartemAttributes.process.add(key);\n\n // Init controls\n const controls = (window.AdartemAttributes.modules[key] ||= {});\n\n controls.loading = new Promise((resolve) => {\n controls.resolve = (value) => {\n resolve(value);\n delete controls.resolve;\n };\n });\n\n // Load Attribute package\n try {\n const { init, version } = await loadAttribute(key);\n\n // Init attribute\n const { result, destroy } = (await init()) || {};\n\n // Finalize controls\n controls.version = version;\n\n controls.destroy = () => {\n destroy?.();\n window.AdartemAttributes.process.delete(key);\n };\n\n controls.restart = () => {\n controls.destroy?.();\n return window.AdartemAttributes.load(key);\n };\n\n controls.resolve?.(result);\n\n return result;\n } catch (err) {\n console.error(err);\n }\n};\n\n// Init\ninit();\n", "{\n \"name\": \"@adartem/adlib-attributes\",\n \"version\": \"0.1.1\",\n \"description\": \"ADARTEM AdLib Attributes (ad-*).\",\n \"homepage\": \"https://adartem.fr/attributes\",\n \"license\": \"MIT\",\n \"private\": false,\n \"publishConfig\": { \"access\": \"public\" },\n \"type\": \"module\",\n \"main\": \"attributes.js\", \n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/adartem/adlib.git\",\n \"directory\": \"packages/adlib-attributes\"\n },\n \"files\": [\n \"dist\",\n \"attributes.js\",\n \"attributes.js.map\",\n \"README.md\",\n \"LICENSE\"\n ],\n \"scripts\": {\n \"dev\": \"cross-env NODE_ENV=development tsx ./bin/build.ts\",\n \"build\": \"cross-env NODE_ENV=production tsx ./bin/build.ts\",\n \"lint\": \"eslint ./src && prettier --check ./src\",\n \"lint:fix\": \"eslint ./src --fix && prettier --write ./src\",\n \"typecheck\": \"tsc --noEmit\",\n \"test\": \"vitest run -c ../../vitest.config.ts && pnpm playwright test --pass-with-no-tests\",\n \"test:headed\": \"pnpm playwright test --headed --pass-with-no-tests\"\n },\n \"keywords\": [\n \"adlib\",\n \"adartem\",\n \"attributes\",\n \"runtime\",\n \"cdn\",\n \"declarative\"\n ],\n \"author\": {\n \"name\": \"Adartem\",\n \"url\": \"https://adartem.fr/\"\n },\n \"bugs\": {\n \"url\": \"https://github.com/adartem/adlib/issues\"\n },\n \"dependencies\": {\n \"@adartem/adlib-utils\": \"workspace:*\",\n \"@adartem/ad-list\": \"workspace:*\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.14.9\",\n \"cross-env\": \"^10.1.0\",\n \"esbuild\": \"^0.27.2\",\n \"esbuild-plugin-inline-worker\": \"^0.1.1\",\n \"tsx\": \"^4.19.2\"\n }\n}", "import { type AdartemAttributeKey } from '@adartem/adlib-utils';\n\n/**\n * Dynamically loads an attribute package.\n * @param key\n */\nexport const loadAttribute = async (key: AdartemAttributeKey) => {\n switch (key) {\n case 'list': {\n return import('@adartem/ad-list');\n }\n\n default: {\n throw `Adartem Attribute \"${key}\" is not supported.`;\n }\n }\n};\n"],
5
+ "mappings": "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",
6
+ "names": ["init", "version"]
7
+ }
@@ -0,0 +1,523 @@
1
+ var __create = Object.create;
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __getProtoOf = Object.getPrototypeOf;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __esm = (fn, res) => function __init() {
8
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
9
+ };
10
+ var __commonJS = (cb, mod) => function __require() {
11
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
12
+ };
13
+ var __export = (target, all) => {
14
+ for (var name in all)
15
+ __defProp(target, name, { get: all[name], enumerable: true });
16
+ };
17
+ var __copyProps = (to, from, except, desc) => {
18
+ if (from && typeof from === "object" || typeof from === "function") {
19
+ for (let key of __getOwnPropNames(from))
20
+ if (!__hasOwnProp.call(to, key) && key !== except)
21
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
22
+ }
23
+ return to;
24
+ };
25
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
26
+ // If the importer is in node compatibility mode or this is not an ESM
27
+ // file that has been converted to a CommonJS file using a Babel-
28
+ // compatible transform (i.e. "__esModule" has not been set), then set
29
+ // "default" to the CommonJS "module.exports" for node compatibility.
30
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
31
+ mod
32
+ ));
33
+
34
+ // bin/live-reload.js
35
+ var init_live_reload = __esm({
36
+ "bin/live-reload.js"() {
37
+ "use strict";
38
+ new EventSource(`http://localhost:${3001}/esbuild`).addEventListener(
39
+ "change",
40
+ () => location.reload()
41
+ );
42
+ }
43
+ });
44
+
45
+ // ../adlib-utils/src/helpers/css.ts
46
+ init_live_reload();
47
+
48
+ // ../adlib-utils/src/constants/webflow.ts
49
+ init_live_reload();
50
+ var WEBFLOW_ASSETS_CDN_ORIGIN = "https://cdn.prod.website-files.com";
51
+ var CURRENT_CSS_CLASS = "w--current";
52
+ var SLIDER_CSS_CLASSES = {
53
+ slider: "w-slider",
54
+ slide: "w-slide",
55
+ sliderMask: "w-slider-mask",
56
+ sliderNav: "w-slider-nav",
57
+ sliderDot: "w-slider-dot",
58
+ activeSliderDot: "w-active"
59
+ };
60
+ var TABS_CSS_CLASSES = {
61
+ tabs: "w-tabs",
62
+ tabsContent: "w-tab-content",
63
+ tabPane: "w-tab-pane",
64
+ tabsMenu: "w-tab-menu",
65
+ tabLink: "w-tab-link",
66
+ activeTab: "w--tab-active"
67
+ };
68
+ var CMS_CSS_CLASSES = {
69
+ wrapper: "w-dyn-list",
70
+ list: "w-dyn-items",
71
+ item: "w-dyn-item",
72
+ paginationWrapper: "w-pagination-wrapper",
73
+ paginationNext: "w-pagination-next",
74
+ paginationPrevious: "w-pagination-previous",
75
+ pageCount: "w-page-count",
76
+ emptyState: "w-dyn-empty"
77
+ };
78
+ var FORM_CSS_CLASSES = {
79
+ formBlock: "w-form",
80
+ checkboxField: "w-checkbox",
81
+ checkboxInput: "w-checkbox-input",
82
+ radioField: "w-radio",
83
+ radioInput: "w-radio-input",
84
+ checkboxOrRadioLabel: "w-form-label",
85
+ checkboxOrRadioFocus: "w--redirected-focus",
86
+ checkboxOrRadioChecked: "w--redirected-checked",
87
+ successMessage: "w-form-done",
88
+ errorMessage: "w-form-fail"
89
+ };
90
+ var DROPDOWN_CSS_CLASSES = {
91
+ dropdown: "w-dropdown",
92
+ dropdownToggle: "w-dropdown-toggle",
93
+ dropdownList: "w-dropdown-list"
94
+ };
95
+ var WEBFLOW_BREAKPOINTS = /* @__PURE__ */ new Map([
96
+ ["tiny", "(max-width: 479px)"],
97
+ ["small", "(max-width: 767px)"],
98
+ ["medium", "(max-width: 991px)"],
99
+ ["main", "(min-width: 992px)"]
100
+ ]);
101
+
102
+ // ../adlib-utils/src/helpers/dom.ts
103
+ init_live_reload();
104
+
105
+ // ../adlib-utils/src/helpers/guards.ts
106
+ init_live_reload();
107
+ var isString = (value) => typeof value === "string";
108
+ var isNumber = (value) => typeof value === "number";
109
+ var isBoolean = (value) => typeof value === "boolean";
110
+ var isDate = (value) => value instanceof Date;
111
+ var noop = () => {
112
+ };
113
+ var isNotEmpty = (value) => value !== void 0 && value !== null;
114
+ var isElement = (target) => target instanceof Element;
115
+ var isHTMLInputElement = (target) => target instanceof HTMLInputElement;
116
+ var isHTMLSelectElement = (target) => target instanceof HTMLSelectElement;
117
+ var isHTMLTextAreaElement = (target) => target instanceof HTMLTextAreaElement;
118
+ var isFormField = (element) => isHTMLInputElement(element) || isHTMLSelectElement(element) || isHTMLTextAreaElement(element);
119
+ var isHTMLFormElement = (target) => target instanceof HTMLFormElement;
120
+ var isHTMLAnchorElement = (target) => target instanceof HTMLAnchorElement;
121
+
122
+ // ../adlib-utils/src/helpers/dom.ts
123
+ var cloneNode = (node, deep = true) => node.cloneNode(deep);
124
+
125
+ // ../adlib-utils/src/helpers/css.ts
126
+ var currentPageStylesheets;
127
+ var attachedExternalStylesheets = /* @__PURE__ */ new Set();
128
+ var getCurrentPageStylesheets = () => {
129
+ if (currentPageStylesheets) return currentPageStylesheets;
130
+ const stylesheets = document.querySelectorAll('link[rel="stylesheet"]');
131
+ currentPageStylesheets = /* @__PURE__ */ new Set();
132
+ for (const stylesheet of stylesheets) {
133
+ const { href } = stylesheet;
134
+ try {
135
+ const { origin } = new URL(href);
136
+ if (origin !== WEBFLOW_ASSETS_CDN_ORIGIN) continue;
137
+ currentPageStylesheets.add(href);
138
+ } catch {
139
+ continue;
140
+ }
141
+ }
142
+ return currentPageStylesheets;
143
+ };
144
+ var attachExternalStylesheets = (page) => {
145
+ const currentPageStylesheets2 = getCurrentPageStylesheets();
146
+ const externalStylesheetElements = [
147
+ ...page.documentElement.querySelectorAll('link[rel="stylesheet"]')
148
+ ];
149
+ return Promise.all(
150
+ externalStylesheetElements.map((stylesheet) => {
151
+ const { href } = stylesheet;
152
+ try {
153
+ const { origin } = new URL(href);
154
+ if (origin !== WEBFLOW_ASSETS_CDN_ORIGIN) return;
155
+ if (currentPageStylesheets2.has(href)) return;
156
+ if (attachedExternalStylesheets.has(href)) return;
157
+ attachedExternalStylesheets.add(href);
158
+ return new Promise((resolve) => {
159
+ const clone = cloneNode(stylesheet);
160
+ clone.addEventListener("load", () => resolve(void 0), { once: true });
161
+ document.head.append(clone);
162
+ window.setTimeout(() => resolve(void 0), 1e4);
163
+ });
164
+ } catch {
165
+ return;
166
+ }
167
+ })
168
+ );
169
+ };
170
+
171
+ // ../adlib-utils/src/constants/attributes.ts
172
+ var attributes_exports = {};
173
+ __export(attributes_exports, {
174
+ ACCORDION_ATTRIBUTE: () => ACCORDION_ATTRIBUTE,
175
+ AUTO_VIDEO_ATTRIBUTE: () => AUTO_VIDEO_ATTRIBUTE,
176
+ CODE_HIGHLIGHT_ATTRIBUTE: () => CODE_HIGHLIGHT_ATTRIBUTE,
177
+ COMBO_BOX_ATTRIBUTE: () => COMBO_BOX_ATTRIBUTE,
178
+ COPY_CLIP_ATTRIBUTE: () => COPY_CLIP_ATTRIBUTE,
179
+ DISPLAY_VALUES_ATTRIBUTE: () => DISPLAY_VALUES_ATTRIBUTE,
180
+ DOCS_ATTRIBUTE: () => DOCS_ATTRIBUTE,
181
+ FAV_CUSTOM_ATTRIBUTE: () => FAV_CUSTOM_ATTRIBUTE,
182
+ FORM_SUBMIT_ATTRIBUTE: () => FORM_SUBMIT_ATTRIBUTE,
183
+ INJECT_ATTRIBUTE: () => INJECT_ATTRIBUTE,
184
+ INPUT_ACTIVE_ATTRIBUTE: () => INPUT_ACTIVE_ATTRIBUTE,
185
+ INPUT_COUNTER_ATTRIBUTE: () => INPUT_COUNTER_ATTRIBUTE,
186
+ LIST_ATTRIBUTE: () => LIST_ATTRIBUTE,
187
+ MIRROR_CLICK_ATTRIBUTE: () => MIRROR_CLICK_ATTRIBUTE,
188
+ MIRROR_INPUT_ATTRIBUTE: () => MIRROR_INPUT_ATTRIBUTE,
189
+ MODAL_ATTRIBUTE: () => MODAL_ATTRIBUTE,
190
+ NUMBER_COUNT_ATTRIBUTE: () => NUMBER_COUNT_ATTRIBUTE,
191
+ QUERY_PARAM_ATTRIBUTE: () => QUERY_PARAM_ATTRIBUTE,
192
+ RANGE_SLIDER_ATTRIBUTE: () => RANGE_SLIDER_ATTRIBUTE,
193
+ READ_TIME_ATTRIBUTE: () => READ_TIME_ATTRIBUTE,
194
+ REMOVE_QUERY_ATTRIBUTE: () => REMOVE_QUERY_ATTRIBUTE,
195
+ SCROLL_DISABLE_ATTRIBUTE: () => SCROLL_DISABLE_ATTRIBUTE,
196
+ SELECT_CUSTOM_ATTRIBUTE: () => SELECT_CUSTOM_ATTRIBUTE,
197
+ SLIDER_DOTS_ATTRIBUTE: () => SLIDER_DOTS_ATTRIBUTE,
198
+ SMART_LIGHTBOX_ATTRIBUTE: () => SMART_LIGHTBOX_ATTRIBUTE,
199
+ SOCIAL_SHARE_ATTRIBUTE: () => SOCIAL_SHARE_ATTRIBUTE,
200
+ STAR_RATING_ATTRIBUTE: () => STAR_RATING_ATTRIBUTE,
201
+ TOC_ATTRIBUTE: () => TOC_ATTRIBUTE,
202
+ VIDEO_HLS_ATTRIBUTE: () => VIDEO_HLS_ATTRIBUTE
203
+ });
204
+ init_live_reload();
205
+ var ACCORDION_ATTRIBUTE = "accordion";
206
+ var AUTO_VIDEO_ATTRIBUTE = "autovideo";
207
+ var CODE_HIGHLIGHT_ATTRIBUTE = "codehighlight";
208
+ var COMBO_BOX_ATTRIBUTE = "combobox";
209
+ var INJECT_ATTRIBUTE = "inject";
210
+ var COPY_CLIP_ATTRIBUTE = "copyclip";
211
+ var DISPLAY_VALUES_ATTRIBUTE = "displayvalues";
212
+ var DOCS_ATTRIBUTE = "docs";
213
+ var FAV_CUSTOM_ATTRIBUTE = "favcustom";
214
+ var FORM_SUBMIT_ATTRIBUTE = "formsubmit";
215
+ var INPUT_ACTIVE_ATTRIBUTE = "inputactive";
216
+ var INPUT_COUNTER_ATTRIBUTE = "inputcounter";
217
+ var MIRROR_CLICK_ATTRIBUTE = "mirrorclick";
218
+ var MIRROR_INPUT_ATTRIBUTE = "mirrorinput";
219
+ var MODAL_ATTRIBUTE = "modal";
220
+ var NUMBER_COUNT_ATTRIBUTE = "numbercount";
221
+ var LIST_ATTRIBUTE = "list";
222
+ var QUERY_PARAM_ATTRIBUTE = "queryparam";
223
+ var RANGE_SLIDER_ATTRIBUTE = "rangeslider";
224
+ var SCROLL_DISABLE_ATTRIBUTE = "scrolldisable";
225
+ var SELECT_CUSTOM_ATTRIBUTE = "selectcustom";
226
+ var SLIDER_DOTS_ATTRIBUTE = "sliderdots";
227
+ var SMART_LIGHTBOX_ATTRIBUTE = "smartlightbox";
228
+ var SOCIAL_SHARE_ATTRIBUTE = "socialshare";
229
+ var STAR_RATING_ATTRIBUTE = "starrating";
230
+ var TOC_ATTRIBUTE = "toc";
231
+ var READ_TIME_ATTRIBUTE = "readtime";
232
+ var REMOVE_QUERY_ATTRIBUTE = "removequery";
233
+ var VIDEO_HLS_ATTRIBUTE = "videohls";
234
+
235
+ // ../adlib-utils/src/constants/index.ts
236
+ init_live_reload();
237
+
238
+ // ../adlib-utils/src/constants/a11y.ts
239
+ init_live_reload();
240
+ var ARIA_ROLE_KEY = "role";
241
+ var ARIA_ROLE_VALUES = {
242
+ slider: "slider",
243
+ listbox: "listbox",
244
+ option: "option",
245
+ columnheader: "columnheader",
246
+ link: "link",
247
+ marquee: "marquee",
248
+ button: "button",
249
+ radiogroup: "radiogroup",
250
+ dialog: "dialog"
251
+ };
252
+ var TABINDEX_KEY = "tabindex";
253
+ var ARIA_SELECTED_KEY = "aria-selected";
254
+ var ARIA_HASPOPUP_KEY = "aria-haspopup";
255
+ var ARIA_MULTISELECTABLE_KEY = "aria-multiselectable";
256
+ var ARIA_SORT_KEY = "aria-sort";
257
+ var ARIA_SORT_VALUES = {
258
+ ascending: "ascending",
259
+ descending: "descending"
260
+ };
261
+
262
+ // ../adlib-utils/src/helpers/fetch.ts
263
+ init_live_reload();
264
+
265
+ // ../adlib-utils/src/helpers/webflow.ts
266
+ init_live_reload();
267
+
268
+ // ../adlib-utils/src/helpers/events.ts
269
+ init_live_reload();
270
+ function addListener(target, type, listener, options) {
271
+ if (!target) return noop;
272
+ const targets = Array.isArray(target) ? target : target instanceof Set ? [...target] : [target];
273
+ targets.forEach((target2) => target2.addEventListener(type, listener, options));
274
+ return () => targets.forEach((target2) => target2.removeEventListener(type, listener, options));
275
+ }
276
+ var simulateEvent = (target, events) => {
277
+ if (!Array.isArray(events)) events = [events];
278
+ const eventsSuccess = events.map(
279
+ (event) => target.dispatchEvent(new Event(event, { bubbles: true }))
280
+ );
281
+ return eventsSuccess.every((success) => success);
282
+ };
283
+
284
+ // ../adlib-utils/src/helpers/webflow.ts
285
+ var getSiteId = (page = document) => page.documentElement.getAttribute("data-wf-site");
286
+ var getPublishDate = (page = document) => {
287
+ const publishDatePrefix = "Last Published:";
288
+ for (const node of page.childNodes) {
289
+ if (node.nodeType === Node.COMMENT_NODE && node.textContent?.includes(publishDatePrefix)) {
290
+ const publishDateValue = node.textContent.trim().split(publishDatePrefix)[1];
291
+ if (publishDateValue) return new Date(publishDateValue);
292
+ }
293
+ }
294
+ };
295
+ var restartWebflow = async (modules) => {
296
+ const { Webflow } = window;
297
+ if (!Webflow || !("destroy" in Webflow) || !("ready" in Webflow) || !("require" in Webflow))
298
+ return;
299
+ if (modules && !modules.length) return;
300
+ if (!modules) {
301
+ Webflow.destroy();
302
+ Webflow.ready();
303
+ }
304
+ if (!modules || modules.includes("ix2")) {
305
+ const ix2 = Webflow.require("ix2");
306
+ if (ix2) {
307
+ const { store, actions } = ix2;
308
+ const { eventState } = store.getState().ixSession;
309
+ const stateEntries = Object.entries(eventState);
310
+ if (!modules) ix2.destroy();
311
+ ix2.init();
312
+ await Promise.all(
313
+ stateEntries.map((state) => store.dispatch(actions.eventStateChanged(...state)))
314
+ );
315
+ }
316
+ }
317
+ if (!modules || modules.includes("commerce")) {
318
+ const commerce = Webflow.require("commerce");
319
+ const siteId = getSiteId();
320
+ if (commerce && siteId) {
321
+ commerce.destroy();
322
+ commerce.init({ siteId, apiUrl: "https://render.webflow.com" });
323
+ }
324
+ }
325
+ if (modules?.includes("lightbox")) Webflow.require("lightbox")?.ready();
326
+ if (modules?.includes("slider")) {
327
+ const slider = Webflow.require("slider");
328
+ if (slider) {
329
+ slider.redraw();
330
+ slider.ready();
331
+ }
332
+ }
333
+ if (modules?.includes("tabs")) Webflow.require("tabs")?.redraw();
334
+ return new Promise((resolve) => Webflow.push(() => resolve(void 0)));
335
+ };
336
+ var getCurrentBreakpoint = () => {
337
+ for (const [breakpoint, mediaQuery] of WEBFLOW_BREAKPOINTS) {
338
+ if (window.matchMedia(mediaQuery).matches) {
339
+ return breakpoint;
340
+ }
341
+ }
342
+ return "main";
343
+ };
344
+ var closeDropdown = (dropdownToggle, focusToggle = true) => {
345
+ if (focusToggle) dropdownToggle.focus();
346
+ simulateEvent(dropdownToggle, "w-close");
347
+ };
348
+
349
+ // ../adlib-utils/src/helpers/fetch.ts
350
+ var DB_OBJECT_STORE_NAME = "pages";
351
+ var cache = /* @__PURE__ */ new Map();
352
+ var fetchPage = (source, options = {}) => {
353
+ let url;
354
+ try {
355
+ url = new URL(source, window.location.origin);
356
+ } catch {
357
+ return null;
358
+ }
359
+ const conclude = (page) => page ? cloneNode(page) : null;
360
+ const cached = cache.get(url.href);
361
+ if (cached) {
362
+ return cached.then(conclude);
363
+ }
364
+ const promise = createPromise(url, options);
365
+ cache.set(url.href, promise);
366
+ return promise.then(conclude);
367
+ };
368
+ var createPromise = async (url, { cache: cache2 = true, cacheExternal, cacheKey, cacheVersion }) => {
369
+ try {
370
+ const siteId = getSiteId();
371
+ const publishDate = getPublishDate();
372
+ const dbName = siteId || cacheKey;
373
+ const dbVersion = publishDate?.getTime() ?? cacheVersion ?? 1;
374
+ const db = dbName ? await createCacheDB(dbName, dbVersion) : null;
375
+ if (!cache2 || !db) {
376
+ const result = await fetchAndParsePage(url);
377
+ if (!result) return null;
378
+ const { page: page2 } = result;
379
+ return page2;
380
+ }
381
+ const rawPageFromDB = await getRawPageFromDB(db, url);
382
+ if (rawPageFromDB) {
383
+ const page2 = parseRawPage(rawPageFromDB);
384
+ if (cacheExternal && !isPageSameSite(page2, siteId)) {
385
+ fetchAndCachePageInDB(db, url, siteId, cacheExternal);
386
+ }
387
+ return page2;
388
+ }
389
+ const page = await fetchAndCachePageInDB(db, url, siteId, cacheExternal);
390
+ return page;
391
+ } catch {
392
+ return null;
393
+ }
394
+ };
395
+ var fetchAndParsePage = async (url) => {
396
+ const response = await fetch(url, { headers: { "X-Webflow-App-ID": "adartem" } });
397
+ const rawPage = await response.text();
398
+ const page = parseRawPage(rawPage);
399
+ return { page, rawPage };
400
+ };
401
+ var fetchAndCachePageInDB = async (db, url, siteId, cacheExternal) => {
402
+ const result = await fetchAndParsePage(url);
403
+ if (!result) return null;
404
+ const { page, rawPage } = result;
405
+ const isSameSite = isPageSameSite(page, siteId);
406
+ if (!isSameSite && !cacheExternal) return page;
407
+ await storeRawPageInDB(db, url, rawPage);
408
+ if (isSameSite) {
409
+ cache.delete(url.href);
410
+ }
411
+ return page;
412
+ };
413
+ var isPageSameSite = (page, siteId) => {
414
+ if (!siteId) return false;
415
+ const pageSiteId = getSiteId(page);
416
+ return pageSiteId && pageSiteId === siteId;
417
+ };
418
+ var parseRawPage = (rawPage) => new DOMParser().parseFromString(rawPage, "text/html");
419
+ var createCacheDB = (dbName, dbVersion) => {
420
+ return new Promise((resolve) => {
421
+ try {
422
+ const dbOpenRequest = window.indexedDB.open(dbName, dbVersion);
423
+ dbOpenRequest.onblocked = () => {
424
+ resolve(null);
425
+ };
426
+ dbOpenRequest.onupgradeneeded = () => {
427
+ const db = dbOpenRequest.result;
428
+ if (db.objectStoreNames.contains(DB_OBJECT_STORE_NAME)) {
429
+ db.deleteObjectStore(DB_OBJECT_STORE_NAME);
430
+ }
431
+ db.createObjectStore(DB_OBJECT_STORE_NAME);
432
+ };
433
+ dbOpenRequest.onerror = () => resolve(null);
434
+ dbOpenRequest.onsuccess = () => {
435
+ const db = dbOpenRequest.result;
436
+ db.onversionchange = () => db.close();
437
+ resolve(db);
438
+ };
439
+ } catch {
440
+ resolve(null);
441
+ }
442
+ });
443
+ };
444
+ var getRawPageFromDB = async (db, url) => {
445
+ return new Promise((resolve) => {
446
+ const transaction = db.transaction(DB_OBJECT_STORE_NAME);
447
+ const objectStore = transaction.objectStore(DB_OBJECT_STORE_NAME);
448
+ const request = objectStore.get(url.href);
449
+ request.onerror = () => resolve(null);
450
+ request.onsuccess = () => resolve(request.result);
451
+ });
452
+ };
453
+ var storeRawPageInDB = async (db, url, rawPage) => {
454
+ return new Promise((resolve) => {
455
+ const transaction = db.transaction(DB_OBJECT_STORE_NAME, "readwrite");
456
+ const objectStore = transaction.objectStore(DB_OBJECT_STORE_NAME);
457
+ const request = objectStore.put(rawPage, url.href);
458
+ request.onerror = () => resolve();
459
+ request.onsuccess = () => resolve();
460
+ });
461
+ };
462
+
463
+ // ../adlib-utils/src/helpers/wait.ts
464
+ init_live_reload();
465
+ var waitWebflowReady = async () => {
466
+ return new Promise((resolve) => {
467
+ window.Webflow ||= [];
468
+ window.Webflow.push(resolve);
469
+ });
470
+ };
471
+ var waitDOMReady = async () => {
472
+ return new Promise((resolve) => {
473
+ if (document.readyState === "loading") {
474
+ document.addEventListener("DOMContentLoaded", resolve);
475
+ } else {
476
+ resolve(void 0);
477
+ }
478
+ });
479
+ };
480
+
481
+ export {
482
+ __commonJS,
483
+ __toESM,
484
+ init_live_reload,
485
+ CURRENT_CSS_CLASS,
486
+ SLIDER_CSS_CLASSES,
487
+ TABS_CSS_CLASSES,
488
+ CMS_CSS_CLASSES,
489
+ FORM_CSS_CLASSES,
490
+ DROPDOWN_CSS_CLASSES,
491
+ isString,
492
+ isNumber,
493
+ isBoolean,
494
+ isDate,
495
+ isNotEmpty,
496
+ isElement,
497
+ isHTMLInputElement,
498
+ isHTMLSelectElement,
499
+ isFormField,
500
+ isHTMLFormElement,
501
+ isHTMLAnchorElement,
502
+ cloneNode,
503
+ attachExternalStylesheets,
504
+ addListener,
505
+ simulateEvent,
506
+ ARIA_ROLE_KEY,
507
+ ARIA_ROLE_VALUES,
508
+ TABINDEX_KEY,
509
+ ARIA_SELECTED_KEY,
510
+ ARIA_HASPOPUP_KEY,
511
+ ARIA_MULTISELECTABLE_KEY,
512
+ ARIA_SORT_KEY,
513
+ ARIA_SORT_VALUES,
514
+ LIST_ATTRIBUTE,
515
+ attributes_exports,
516
+ restartWebflow,
517
+ getCurrentBreakpoint,
518
+ closeDropdown,
519
+ fetchPage,
520
+ waitWebflowReady,
521
+ waitDOMReady
522
+ };
523
+ //# sourceMappingURL=chunk-25Q4WE2N.js.map