onedollarstats 0.0.15 → 0.0.16

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/dist/index.js CHANGED
@@ -580,16 +580,13 @@ UTM: ${data.utm}`;
580
580
  * @param pathOrProps Optional path string or props object.
581
581
  * @param props Optional props object if path string is provided.
582
582
  */
583
- async event(eventName, pathOrProps, props) {
583
+ async event(eventName, pathOrProps, rawProps) {
584
584
  if (!isClient()) return;
585
585
  const { isLocalhost, isHeadlessBrowser } = getEnvironment();
586
586
  if (isLocalhost && !this.config.devmode || isHeadlessBrowser) return;
587
- const args = {};
588
- if (typeof pathOrProps === "string") {
589
- args.path = resolvePath(pathOrProps);
590
- args.props = props;
591
- } else if (typeof pathOrProps === "object") args.props = pathOrProps;
592
- this.send({ type: eventName, ...args });
587
+ const path = resolvePath(typeof pathOrProps === "string" ? pathOrProps : void 0);
588
+ const props = typeof pathOrProps === "object" ? pathOrProps : rawProps;
589
+ this.send({ type: eventName, path, props });
593
590
  }
594
591
  /**
595
592
  * Records a page view.
package/dist/index.js.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/utils/bot.ts", "../src/utils/environment.ts", "../src/utils/merge-config.ts", "../src/utils/create-modal.ts", "../src/utils/parse-utm-params.ts", "../src/utils/props-parser.ts", "../src/utils/resolve-path.ts", "../src/utils/should-track.ts", "../src/index.ts"],
4
- "sourcesContent": ["/**\n * Bot & crawler detection \u2014 standalone module.\n *\n * Usage:\n * import { detectBot } from '@aspect/fingerprint/bot'\n * const result = detectBot()\n * if (result.isBot) console.log(result.botKind, result.signals)\n *\n * Detects:\n * - Known search engine crawlers (Googlebot, Bingbot, Yandex, Baidu, etc.)\n * - Social media crawlers (Facebook, Twitter, LinkedIn, etc.)\n * - Headless browsers (Puppeteer, Playwright, Selenium, PhantomJS)\n * - General automation tools via navigator.webdriver and injected globals\n * - API tampering / lie detection (prototype spoofing, proxy wrapping)\n *\n * Zero dependencies \u2014 can be imported and used independently of the\n * fingerprinting library.\n */\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\nexport type BotKind =\n | 'search_engine' // Googlebot, Bingbot, Yandex, Baidu, DuckDuckBot, etc.\n | 'social_crawler' // Facebook, Twitter/X, LinkedIn, Slack, Discord, etc.\n | 'headless' // Headless Chrome/Firefox, PhantomJS\n | 'automation' // Selenium, Puppeteer, Playwright (non-headless)\n | 'library' // curl, wget, python-requests, node-fetch, etc.\n | 'unknown_bot' // Signals say bot, but can't classify further\n | 'human' // No bot signals detected\n\nexport interface BotSignals {\n /** navigator.userAgent matched a known bot pattern. */\n userAgentBot: string | null\n /** navigator.webdriver is true. */\n webdriver: boolean\n /** Headless browser indicators detected. */\n headless: boolean\n /** Automation globals found on window. */\n automationGlobals: string[]\n /** Number of API lies (toString/proxy tampering) detected. */\n liesDetected: number\n /** Proxy wrapping detected on native functions. */\n hasProxy: boolean\n /** navigator.languages is empty or missing. */\n missingLanguages: boolean\n /** navigator.plugins is empty (non-mobile). */\n missingPlugins: boolean\n}\n\nexport interface BotDetectionResult {\n /** True when any bot signal fires. */\n isBot: boolean\n /** Classified category of the detected bot. */\n botKind: BotKind\n /** Individual signal results for debugging / logging. */\n signals: BotSignals\n}\n\n// ---------------------------------------------------------------------------\n// Known bot UA patterns\n// ---------------------------------------------------------------------------\n\ninterface BotPattern {\n pattern: RegExp\n kind: BotKind\n name: string\n}\n\nconst BOT_PATTERNS: BotPattern[] = [\n // Search engines\n { pattern: /Googlebot/i, kind: 'search_engine', name: 'Googlebot' },\n { pattern: /Google-InspectionTool/i, kind: 'search_engine', name: 'Googlebot' },\n { pattern: /Storebot-Google/i, kind: 'search_engine', name: 'Googlebot' },\n { pattern: /AdsBot-Google/i, kind: 'search_engine', name: 'Google Ads' },\n { pattern: /Mediapartners-Google/i, kind: 'search_engine', name: 'Google Adsense' },\n { pattern: /bingbot/i, kind: 'search_engine', name: 'Bingbot' },\n { pattern: /msnbot/i, kind: 'search_engine', name: 'MSNBot' },\n { pattern: /YandexBot/i, kind: 'search_engine', name: 'YandexBot' },\n { pattern: /YandexAccessibilityBot/i, kind: 'search_engine', name: 'YandexBot' },\n { pattern: /Baiduspider/i, kind: 'search_engine', name: 'Baidu' },\n { pattern: /DuckDuckBot/i, kind: 'search_engine', name: 'DuckDuckBot' },\n { pattern: /Sogou/i, kind: 'search_engine', name: 'Sogou' },\n { pattern: /Exabot/i, kind: 'search_engine', name: 'Exabot' },\n { pattern: /ia_archiver/i, kind: 'search_engine', name: 'Alexa' },\n { pattern: /SemrushBot/i, kind: 'search_engine', name: 'SemrushBot' },\n { pattern: /AhrefsBot/i, kind: 'search_engine', name: 'AhrefsBot' },\n { pattern: /MJ12bot/i, kind: 'search_engine', name: 'MJ12bot' },\n { pattern: /DotBot/i, kind: 'search_engine', name: 'DotBot' },\n { pattern: /PetalBot/i, kind: 'search_engine', name: 'PetalBot' },\n { pattern: /Applebot/i, kind: 'search_engine', name: 'Applebot' },\n { pattern: /GPTBot/i, kind: 'search_engine', name: 'GPTBot' },\n { pattern: /ChatGPT-User/i, kind: 'search_engine', name: 'ChatGPT' },\n { pattern: /ClaudeBot/i, kind: 'search_engine', name: 'ClaudeBot' },\n { pattern: /CCBot/i, kind: 'search_engine', name: 'Common Crawl' },\n { pattern: /anthropic-ai/i, kind: 'search_engine', name: 'Anthropic' },\n { pattern: /PerplexityBot/i, kind: 'search_engine', name: 'PerplexityBot' },\n\n // Social crawlers\n { pattern: /facebookexternalhit/i, kind: 'social_crawler', name: 'Facebook' },\n { pattern: /Facebot/i, kind: 'social_crawler', name: 'Facebook' },\n { pattern: /Twitterbot/i, kind: 'social_crawler', name: 'Twitter' },\n { pattern: /LinkedInBot/i, kind: 'social_crawler', name: 'LinkedIn' },\n { pattern: /Slackbot/i, kind: 'social_crawler', name: 'Slack' },\n { pattern: /Discordbot/i, kind: 'social_crawler', name: 'Discord' },\n { pattern: /TelegramBot/i, kind: 'social_crawler', name: 'Telegram' },\n { pattern: /WhatsApp/i, kind: 'social_crawler', name: 'WhatsApp' },\n { pattern: /Pinterestbot/i, kind: 'social_crawler', name: 'Pinterest' },\n { pattern: /Snapchat/i, kind: 'social_crawler', name: 'Snapchat' },\n\n // Headless / automation\n { pattern: /HeadlessChrome/i, kind: 'headless', name: 'Headless Chrome' },\n { pattern: /PhantomJS/i, kind: 'headless', name: 'PhantomJS' },\n { pattern: /Selenium/i, kind: 'automation', name: 'Selenium' },\n { pattern: /Puppeteer/i, kind: 'automation', name: 'Puppeteer' },\n\n // HTTP libraries\n { pattern: /curl\\//i, kind: 'library', name: 'curl' },\n { pattern: /Wget\\//i, kind: 'library', name: 'Wget' },\n { pattern: /python-requests/i, kind: 'library', name: 'Python Requests' },\n { pattern: /python-urllib/i, kind: 'library', name: 'Python urllib' },\n { pattern: /node-fetch/i, kind: 'library', name: 'node-fetch' },\n { pattern: /axios\\//i, kind: 'library', name: 'Axios' },\n { pattern: /Go-http-client/i, kind: 'library', name: 'Go HTTP' },\n { pattern: /Java\\//i, kind: 'library', name: 'Java HTTP' },\n { pattern: /libwww-perl/i, kind: 'library', name: 'Perl LWP' },\n { pattern: /Apache-HttpClient/i, kind: 'library', name: 'Apache HttpClient' },\n { pattern: /okhttp/i, kind: 'library', name: 'OkHttp' },\n { pattern: /Scrapy/i, kind: 'library', name: 'Scrapy' },\n\n // Generic catch-all (must be last)\n { pattern: /bot|crawl|spider|slurp|fetch|archiver/i, kind: 'unknown_bot', name: 'generic' },\n]\n\n// ---------------------------------------------------------------------------\n// Automation globals injected by common frameworks\n// ---------------------------------------------------------------------------\n\nconst AUTOMATION_GLOBALS = [\n // Selenium\n '__selenium_unwrapped',\n '__selenium_evaluate',\n '__webdriver_evaluate',\n '__webdriver_script_fn',\n '__webdriver_script_func',\n '__webdriver_script_function',\n '__fxdriver_evaluate',\n '__fxdriver_unwrapped',\n '_Selenium_IDE_Recorder',\n // Puppeteer / CDP\n '__puppeteer_evaluation_script__',\n // PhantomJS\n 'callPhantom',\n '_phantom',\n 'phantom',\n // Nightmare.js\n '__nightmare',\n // Playwright (injects page.exposeFunction bindings)\n '__playwright',\n '__pw_manual',\n // CasperJS\n '__casper',\n // TestCafe\n '__testcafe',\n // WebDriver (generic)\n 'webdriver',\n 'domAutomation',\n 'domAutomationController',\n] as const\n\n// ---------------------------------------------------------------------------\n// Core detection\n// ---------------------------------------------------------------------------\n\n/**\n * Detect whether the current browser context is a bot or crawler.\n * Synchronous and lightweight \u2014 no async APIs needed.\n */\nexport function detectBot(): BotDetectionResult {\n const signals = collectBotSignals()\n\n const isBot =\n signals.userAgentBot !== null ||\n signals.webdriver ||\n signals.headless ||\n signals.automationGlobals.length > 0 ||\n signals.liesDetected > 2 ||\n (signals.liesDetected > 0 && signals.hasProxy)\n\n let botKind: BotKind = 'human'\n if (isBot) {\n if (signals.userAgentBot !== null) {\n // Find the matching pattern to determine kind\n const ua = navigator.userAgent || ''\n const match = BOT_PATTERNS.find(p => p.pattern.test(ua))\n botKind = match?.kind ?? 'unknown_bot'\n } else if (signals.headless) {\n botKind = 'headless'\n } else if (signals.webdriver || signals.automationGlobals.length > 0) {\n botKind = 'automation'\n } else {\n botKind = 'unknown_bot'\n }\n }\n\n return { isBot, botKind, signals }\n}\n\n// ---------------------------------------------------------------------------\n// Signal collectors\n// ---------------------------------------------------------------------------\n\nfunction collectBotSignals(): BotSignals {\n return {\n userAgentBot: detectUserAgentBot(),\n webdriver: detectWebdriver(),\n headless: detectHeadless(),\n automationGlobals: detectAutomationGlobals(),\n ...detectLies(),\n missingLanguages: detectMissingLanguages(),\n missingPlugins: detectMissingPlugins(),\n }\n}\n\n/** Check UA string against known bot patterns. */\nfunction detectUserAgentBot(): string | null {\n const ua = navigator.userAgent || ''\n if (!ua) return 'empty-ua'\n for (const { pattern, name } of BOT_PATTERNS) {\n if (pattern.test(ua)) return name\n }\n return null\n}\n\n/** navigator.webdriver is set by WebDriver-based automation. */\nfunction detectWebdriver(): boolean {\n return !!(navigator as any).webdriver\n}\n\n/** Headless browser indicators. */\nfunction detectHeadless(): boolean {\n const w = window as any\n const n = navigator as any\n\n // Chrome-specific: headless mode omits the chrome runtime object\n if (/Chrome/.test(n.userAgent) && !w.chrome) return true\n\n // HeadlessChrome in UA\n if (/HeadlessChrome/.test(n.userAgent)) return true\n\n // Notification permission is always \"denied\" in headless Chrome\n // (in headed mode it defaults to \"default\")\n try {\n if (Notification.permission === 'denied' && n.permissions) {\n // Double-check: headless also lacks plugins\n if ((!n.plugins || n.plugins.length === 0) && !/Mobile|Android/i.test(n.userAgent)) {\n return true\n }\n }\n } catch { /* permissions API unavailable */ }\n\n return false\n}\n\n/** Detect automation framework globals on window. */\nfunction detectAutomationGlobals(): string[] {\n const w = window as any\n return AUTOMATION_GLOBALS.filter(key => {\n try { return key in w && w[key] !== undefined }\n catch { return false }\n }) as string[]\n}\n\n/**\n * Lie detection \u2014 detect API tampering (proxies, toString spoofing).\n * Extracted from the fingerprint lies module; self-contained here.\n */\nfunction detectLies(): { liesDetected: number; hasProxy: boolean } {\n let liesDetected = 0\n let hasProxy = false\n\n const apisToTest: Array<[string, () => unknown]> = [\n ['Navigator.prototype.userAgent', () => desc(Navigator.prototype, 'userAgent')],\n ['Navigator.prototype.languages', () => desc(Navigator.prototype, 'languages')],\n ['Navigator.prototype.platform', () => desc(Navigator.prototype, 'platform')],\n ['Navigator.prototype.hardwareConcurrency', () => desc(Navigator.prototype, 'hardwareConcurrency')],\n ['Navigator.prototype.webdriver', () => desc(Navigator.prototype, 'webdriver')],\n ['HTMLCanvasElement.prototype.toDataURL', () => HTMLCanvasElement.prototype.toDataURL],\n ['CanvasRenderingContext2D.prototype.fillText', () => CanvasRenderingContext2D.prototype.fillText],\n ['Date.prototype.getTimezoneOffset', () => Date.prototype.getTimezoneOffset],\n ]\n\n for (const [name, accessor] of apisToTest) {\n try {\n const val = accessor()\n if (val === undefined || val === null) continue\n\n // toString format check\n if (typeof val === 'function') {\n const str = Function.prototype.toString.call(val)\n if (!isNativeToString(str)) liesDetected++\n }\n\n // Getter integrity check\n if (name.includes('.prototype.') && typeof val !== 'function') {\n const parts = name.split('.')\n const proto = safeProto(parts[0])\n const prop = parts[parts.length - 1]\n if (proto) {\n const d = Object.getOwnPropertyDescriptor(proto, prop)\n if (d?.get) {\n const gs = Function.prototype.toString.call(d.get)\n if (!isNativeToString(gs)) liesDetected++\n }\n }\n }\n\n // Proxy detection\n if (typeof val === 'function') {\n if (val.toString !== Function.prototype.toString) {\n try {\n const native = Function.prototype.toString.call(val)\n const custom = val.toString()\n if (native !== custom) { liesDetected++; hasProxy = true }\n } catch { liesDetected++; hasProxy = true }\n }\n }\n } catch { /* skip inaccessible */ }\n }\n\n // Meta-test: toString integrity\n try {\n const s = Function.prototype.toString.call(Function.prototype.toString)\n if (!isNativeToString(s)) liesDetected++\n } catch { /* skip */ }\n\n return { liesDetected, hasProxy }\n}\n\n/** Missing navigator.languages is a strong headless indicator. */\nfunction detectMissingLanguages(): boolean {\n const langs = navigator.languages\n return !langs || langs.length === 0\n}\n\n/** Missing plugins on desktop is a headless indicator. */\nfunction detectMissingPlugins(): boolean {\n if (/Mobile|Android/i.test(navigator.userAgent)) return false\n return !navigator.plugins || navigator.plugins.length === 0\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction isNativeToString(str: string): boolean {\n return /^function\\s[^{]*\\{\\s*\\[native code\\]\\s*\\}$/.test(str) ||\n str === 'function () { [native code] }' ||\n /^\\(\\)\\s*=>\\s*\\{\\s*\\[native code\\]\\s*\\}$/.test(str)\n}\n\nfunction desc(proto: object, prop: string) {\n return Object.getOwnPropertyDescriptor(proto, prop)\n}\n\nfunction safeProto(name: string): object | null {\n try { return (window as any)[name]?.prototype ?? null }\n catch { return null }\n}\n", "export const getEnvironment = (): {\n isLocalhost: boolean;\n isHeadlessBrowser: boolean;\n} => ({\n isLocalhost:\n (/^localhost$|^127(\\.[0-9]+){0,2}\\.[0-9]+$|^\\[::1?\\]$/.test(location.hostname) &&\n (location.protocol === \"http:\" || location.protocol === \"https:\")) ||\n location.protocol === \"file:\",\n isHeadlessBrowser: Boolean(\n window.navigator.webdriver ||\n (\"_phantom\" in window && window._phantom) ||\n (\"__nightmare\" in window && window.__nightmare) ||\n (\"Cypress\" in window && window.Cypress)\n )\n});\nexport const isClient = (): boolean => {\n try {\n // Basic checks for window and document\n if (typeof window === \"undefined\" || typeof document === \"undefined\") return false;\n\n // Check for navigator safely\n const ua = typeof navigator !== \"undefined\" ? navigator.userAgent : \"\";\n if (/node|jsdom/i.test(ua)) return false;\n return true;\n } catch {\n return false;\n }\n};\n", "import type { AnalyticsConfig, InternalAnalyticsConfig } from \"../types\";\nimport { getEnvironment } from \"./environment\";\n\nexport const defaultConfig: InternalAnalyticsConfig = {\n hostname: null,\n devmode: false,\n collectorUrl: \"https://collector.onedollarstats.com/events\",\n hashRouting: false,\n autocollect: true,\n excludePages: [],\n includePages: []\n};\n\nexport const mergeConfig = (userConfig: AnalyticsConfig = {}): InternalAnalyticsConfig => {\n const { isLocalhost } = getEnvironment();\n\n const devmode = !isLocalhost ? false : (userConfig.devmode ?? !!userConfig.trackLocalhostAs);\n\n let hostname: string | null;\n if (userConfig.hostname) {\n const trimmed = userConfig.hostname.trim();\n hostname = trimmed || null;\n } else if (devmode && userConfig.trackLocalhostAs) {\n hostname = userConfig.trackLocalhostAs;\n } else {\n hostname = null;\n }\n\n // Merge default config, user config, and computed values\n return { ...defaultConfig, ...userConfig, hostname, devmode };\n};\n", "import { defaultConfig } from \"./merge-config\";\n\nexport const createDebugModal = (debugUrl: string, analyticsUrl: string) => {\n if (!document.getElementById(\"onedollatstats-modal-styles\")) {\n const style = document.createElement(\"style\");\n style.id = \"onedollatstats-modal-styles\";\n style.textContent = CSS;\n document.head.appendChild(style);\n }\n\n // Create modal\n const modal = document.createElement(\"div\");\n modal.className = \"dev-modal\";\n modal.innerHTML = `\n <button class=\"close-btn\">&times;</button>\n <p class=\"title\">onedollarstats debug window</p>\n <p>${icons.info}<span class=\"text\">Tracking localhost as ${debugUrl}</span></p>\n <div id=\"event-log\" style=\"max-height: 100px; overflow-y: auto;\"></div>\n `;\n document.body.appendChild(modal);\n\n // Close handler\n modal.querySelector(\".close-btn\")?.addEventListener(\"click\", () => modal.remove(), { once: true });\n\n // Health check\n if (analyticsUrl === defaultConfig.collectorUrl) {\n const img = new Image(1, 1);\n img.onerror = () => {\n if (modal.querySelector(\"#ad-blocker-warning\")) return;\n const warning = document.createElement(\"p\");\n warning.id = \"ad-blocker-warning\";\n warning.innerHTML = `${icons.warning}<span class=\"text\">Health check failed - ad blocker might be interfering.</span>`;\n modal.querySelector(\".title\")?.insertAdjacentElement(\"afterend\", warning);\n };\n img.src = \"https://collector.onedollarstats.com/pixel-health\";\n }\n\n // Log rendering function\n return (message: string, success: boolean): void => {\n const logContainer = modal.querySelector(\"#event-log\");\n if (!logContainer || modal.querySelector(\"#ad-blocker-warning\")) return;\n\n const entry = document.createElement(\"p\");\n entry.innerHTML = `${success ? icons.success : icons.error}<span class=\"text\">${message}</span>`;\n logContainer.appendChild(entry);\n logContainer.scrollTop = logContainer.scrollHeight;\n };\n};\n\nconst icons = {\n info: `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"gray\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"/><path d=\"M12 16v-4\"/><path d=\"M12 8h.01\"/></svg>`,\n success: `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"green\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"/><path d=\"m9 12 2 2 4-4\"/></svg>`,\n error: `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"red\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"/><path d=\"m15 9-6 6\"/><path d=\"m9 9 6 6\"/></svg>`,\n warning: `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"orange\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3\"/><path d=\"M12 9v4\"/><path d=\"M12 17h.01\"/></svg>`\n} as const;\n\nconst CSS = `\n .dev-modal {\n position: fixed;\n bottom: 20px;\n right: 20px;\n background: #f6f6f7;\n color: #21272F;\n padding: 14px;\n border-radius: 8px;\n max-width: 340px;\n max-height: 180px;\n box-shadow: 0 5px 20px rgba(0,0,0,0.3);\n font-family: sans-serif;\n z-index: 99999;\n animation: slideIn 0.3s ease-out;\n}\n\n.dev-modal .title {\n text-transform: uppercase;\n font-size: 11px;\n font-weight: 500;\n margin: 0 0 6px 0;\n letter-spacing: 0.5px;\n}\n\n.dev-modal p {\n margin: 4px 0;\n font-size: 14px;\n display: flex;\n align-items: flex-start;\n gap: 4px;\n}\n\n.dev-modal .text {\n word-break: break-word;\n}\n\n.dev-modal p svg {\n flex-shrink: 0;\n width: 18px;\n height: 18px;\n margin-top: 1px;\n}\n\n.dev-modal .close-btn {\n position: absolute;\n top: 2px;\n right: 8px;\n background: transparent;\n border: none;\n cursor: pointer;\n font-size: 14px;\n font-weight: bold;\n color: #333;\n}\n\n@keyframes slideIn {\n from {\n opacity: 0;\n transform: translateX(100%);\n }\n to {\n opacity: 1;\n transform: translateX(0);\n }\n}`;\n", "export const parseUtmParams = (urlSearchParams: URLSearchParams) => {\n const utm: Record<string, string> = {};\n const keys = [\"utm_campaign\", \"utm_source\", \"utm_medium\", \"utm_term\", \"utm_content\"] as const;\n\n for (const key of keys) {\n const raw = urlSearchParams.get(key);\n if (!raw) continue;\n\n const decoded = recursiveDecode(raw).trim();\n if (decoded) {\n utm[key] = decoded;\n }\n }\n\n return utm;\n};\n\nconst recursiveDecode = (value: string): string => {\n let current = value;\n let decoded = decodeURIComponent(current);\n\n while (decoded !== current) {\n current = decoded;\n decoded = decodeURIComponent(current);\n }\n\n return current;\n};\n", "export const parseProps = (propsString: string): Record<string, string> | undefined => {\n if (!propsString) return undefined;\n // \"key1=value1;key2=value2\"\n\n const splittedProps = propsString.split(\";\");\n const propsObj: Record<string, string> = {};\n\n for (const keyValueString of splittedProps) {\n const keyValuePair = keyValueString.split(\"=\").map((el) => el.trim());\n if (keyValuePair.length !== 2 || keyValuePair[0] === \"\" || keyValuePair[1] === \"\") continue;\n // @ts-ignore\n propsObj[keyValuePair[0]] = keyValuePair[1];\n }\n\n return Object.keys(propsObj).length === 0 ? undefined : propsObj;\n};\n", "export const resolvePath = (pathOrProps?: string): string => {\n if (pathOrProps) return pathOrProps;\n\n const sources = [\n { value: document.body?.getAttribute(\"data-s-path\"), name: \"data-s-path\" },\n { value: document.body?.getAttribute(\"data-s:path\"), name: \"data-s:path\" }\n ];\n\n // Only keep sources that actually exist\n const existing = sources.filter(({ value }) => value);\n\n if (existing.length > 1) {\n console.warn(\"[onedollarstats] Multiple path sources found. Using priority order:\", existing.map(({ name }) => name).join(\" > \"));\n }\n\n // Return first available value, fallback to location.pathname\n return existing[0]?.value ?? location.pathname;\n};\n", "import type { InternalAnalyticsConfig } from \"../types\";\n\nconst matchesPattern = (path: string, pattern: string): boolean => {\n // Escape special regex characters except '*' which becomes '.*'\n const escaped = pattern.replace(/[.+^${}()|[\\]\\\\]/g, \"\\\\$&\").replace(/\\*/g, \".*\");\n return new RegExp(`^${escaped}$`).test(path);\n};\n\nexport const shouldTrackPath = (path: string, config: InternalAnalyticsConfig): boolean => {\n // Exclude pages first\n if (config.excludePages.some((pattern) => matchesPattern(path, pattern))) return false;\n // If includePages is defined, only allow matching paths\n if (config.includePages.length && !config.includePages.some((pattern) => matchesPattern(path, pattern))) return false;\n return true;\n};\n", "import type { AnalyticsConfig, BaseProps, BodyToSend, Event, InternalAnalyticsConfig, ViewArguments } from \"./types\";\nimport { detectBot } from \"./utils/bot\";\nimport { createDebugModal } from \"./utils/create-modal\";\nimport { getEnvironment, isClient } from \"./utils/environment\";\nimport { mergeConfig } from \"./utils/merge-config\";\nimport { parseUtmParams } from \"./utils/parse-utm-params\";\nimport { parseProps } from \"./utils/props-parser\";\nimport { resolvePath } from \"./utils/resolve-path\";\nimport { shouldTrackPath } from \"./utils/should-track\";\n\nclass AnalyticsTracker {\n private static instance: AnalyticsTracker | null = null;\n\n private autocollectSetupDone = false;\n private config: InternalAnalyticsConfig;\n private lastPage: string | null = null;\n private modalLog: (message: string, success: boolean) => void = () => {};\n\n public static getInstance(userConfig: AnalyticsConfig = {}): AnalyticsTracker {\n // Fresh no-op instance for SSR\n if (!isClient()) return new AnalyticsTracker(userConfig);\n\n if (!AnalyticsTracker.instance) {\n AnalyticsTracker.instance = new AnalyticsTracker(userConfig);\n }\n return AnalyticsTracker.instance;\n }\n\n private constructor(userConfig: AnalyticsConfig = {}) {\n this.config = mergeConfig(userConfig);\n\n // Skip setup in non-client environments\n if (!isClient()) return;\n\n const { isLocalhost } = getEnvironment();\n\n // Debug log on localhost\n if (isLocalhost && this.config.devmode && this.config.hostname) {\n console.log(`[onedollarstats]\\nOneDollarStats connected! Tracking localhost as ${this.config.hostname}`);\n\n this.modalLog = createDebugModal(this.config.hostname, this.config.collectorUrl);\n }\n\n // Auto-start autocollect\n if (this.config.autocollect) this.setupAutocollect();\n }\n\n private async sendWithBeaconOrFetch(stringifiedBody: string, callback: (success: boolean) => void): Promise<void> {\n // First fallback: try sendBeacon\n if (navigator.sendBeacon?.(this.config.collectorUrl, stringifiedBody)) {\n callback(true);\n return;\n }\n\n // Second fallback: use fetch() with keepalive\n fetch(this.config.collectorUrl, {\n method: \"POST\",\n body: stringifiedBody,\n headers: { \"Content-Type\": \"application/json\" },\n keepalive: true\n })\n .then(({ ok }) => callback(ok))\n .catch((err: Error) => {\n console.error(\"[onedollarstats] fetch() failed:\", err.message);\n callback(false);\n });\n }\n\n // Handles localhost replacement, referrer, UTM parameters, and debug mode.\n // Uses img beacon then `navigator.sendBeacon` if available, otherwise falls back to `fetch`.\n private async send(data: Event): Promise<void> {\n const { isLocalhost, isHeadlessBrowser } = getEnvironment();\n if ((isLocalhost && !this.config.devmode) || isHeadlessBrowser) return;\n\n const { isBot, botKind } = detectBot();\n\n if (isBot && botKind !== \"human\") return;\n\n const urlToSend = new URL(this.config.hostname ? `https://${this.config.hostname}${location.pathname}` : location.href);\n\n // Clean query string unless UTM is explicitly provided\n urlToSend.search = \"\";\n if (data.path) urlToSend.pathname = data.path;\n\n const cleanUrl = urlToSend.href.replace(/\\/$/, \"\");\n\n // Determine referrer\n let referrer: string | undefined = data.referrer;\n try {\n if (!referrer && document.referrer && document.referrer !== \"null\") {\n const referrerURL = new URL(document.referrer);\n if (referrerURL.hostname !== urlToSend.hostname) referrer = referrerURL.href;\n }\n } catch {} // ignore malformed referrer\n\n // Build request body\n const body: BodyToSend = {\n u: cleanUrl,\n e: [\n {\n t: data.type,\n h: this.config.hashRouting,\n r: referrer,\n p: data.props\n }\n ],\n debug: this.config.devmode\n };\n\n if (data.utm && Object.keys(data.utm).length > 0) body.qs = data.utm;\n\n if (body.debug) {\n let logMessage = `[onedollarstats]\\nEvent name: ${data.type}\\nEvent collected from: ${cleanUrl}`;\n if (data.props && Object.keys(data.props).length > 0) logMessage += `\\nProps: ${JSON.stringify(data.props, null, 2)}`;\n if (referrer) logMessage += `\\nReferrer: ${referrer}`;\n if (this.config.hashRouting) logMessage += `\\nHashRouting: ${this.config.hashRouting}`;\n if (data.utm && Object.keys(data.utm).length > 0) logMessage += `\\nUTM: ${data.utm}`;\n\n console.log(logMessage);\n }\n\n // Prepare the event payload\n const stringifiedBody = JSON.stringify(body);\n\n // Encode for safe inclusion in a query string (UTF-8 \u2192 Base64)\n const bytes = new TextEncoder().encode(stringifiedBody); // UTF-8 \u2192 bytes\n const bin = String.fromCharCode(...bytes); // bytes \u2192 binary string\n const payloadBase64 = btoa(bin); // binary \u2192 Base64\n\n const safeGetThreshold = 1500; // limit for query-string-containing URLs\n const tryImageBeacon = payloadBase64.length <= safeGetThreshold;\n\n const onComplete = (success: boolean) => this.modalLog(`${data.type} ${success ? \"sent\" : \"failed to send\"}`, success);\n\n if (tryImageBeacon) {\n // Send via image beacon\n const img = new Image(1, 1);\n\n img.onload = () => onComplete(true);\n // If loading image fails (server unavailable, blocked, etc.)\n img.onerror = () => this.sendWithBeaconOrFetch(stringifiedBody, onComplete);\n\n // Primary attempt: send data via image beacon (GET request with query string)\n img.src = `${this.config.collectorUrl}?data=${payloadBase64}`;\n } else await this.sendWithBeaconOrFetch(stringifiedBody, onComplete);\n }\n\n // Prevents duplicate pageviews and respects include/exclude page rules. Automatically parses UTM parameters from URL.\n private trackPageView({ path, props }: ViewArguments, checkBlock: boolean = false) {\n if (!isClient()) return;\n\n const viewPath = resolvePath(path);\n\n const viewProps =\n props ||\n (() => {\n const newProps = {};\n const elements = document.querySelectorAll(\"[data-s\\\\:view-props], [data-s-view-props]\");\n\n for (const el of Array.from(elements)) {\n const propsString = el.getAttribute(\"data-s-view-props\") || el.getAttribute(\"data-s:view-props\");\n if (!propsString) continue;\n const parsedProps = parseProps(propsString);\n Object.assign(newProps, parsedProps);\n }\n\n return Object.keys(newProps).length ? newProps : undefined;\n })();\n\n // Skip duplicate pageviews or excluded pages\n if (!this.config.hashRouting && this.lastPage === viewPath) return;\n\n // Skip page if checkBlock is true and the path should be excluded\n if (checkBlock && !shouldTrackPath(viewPath, this.config)) return;\n\n this.lastPage = viewPath;\n\n const utm = parseUtmParams(new URLSearchParams(location.search));\n this.send({ type: \"PageView\", path: viewPath, props: viewProps, utm });\n }\n\n /**\n * Tracks a custom event.\n * Can accept path string or a props object.\n *\n * @param eventName Name of the event to track.\n * @param pathOrProps Optional path string or props object.\n * @param props Optional props object if path string is provided.\n */\n public async event(eventName: string, pathOrProps?: string | BaseProps, props?: BaseProps) {\n if (!isClient()) return;\n\n const { isLocalhost, isHeadlessBrowser } = getEnvironment();\n if ((isLocalhost && !this.config.devmode) || isHeadlessBrowser) return;\n\n const args: ViewArguments = {};\n if (typeof pathOrProps === \"string\") {\n args.path = resolvePath(pathOrProps);\n\n args.props = props;\n } else if (typeof pathOrProps === \"object\") args.props = pathOrProps;\n\n this.send({ type: eventName, ...args });\n }\n\n /**\n * Records a page view.\n * Can accept path string or a props object.\n *\n * @param pathOrProps Optional path string or props object.\n * @param props Optional props when first arg is a path string.\n */\n public async view(pathOrProps?: string | BaseProps, props?: BaseProps) {\n if (!isClient()) return;\n\n const args: ViewArguments = {};\n\n if (typeof pathOrProps === \"string\") {\n args.path = pathOrProps;\n args.props = props;\n } else if (typeof pathOrProps === \"object\") {\n args.props = pathOrProps;\n }\n\n this.trackPageView(args);\n }\n\n /**\n * Installs global DOM/window listeners exactly once for:\n * - visibilitychange\n * - history.pushState\n * - popstate\n * - hashchange\n * - click autocapture for elements annotated with `data-s:event` & `data-s-event`\n *\n */\n private setupAutocollect() {\n if (!isClient() || this.autocollectSetupDone) return;\n this.autocollectSetupDone = true;\n\n const handlePageView = () => this.trackPageView({}, true);\n\n // visibilitychange\n const onVisibility = () => {\n if (document.visibilityState === \"visible\") handlePageView();\n };\n document.addEventListener(\"visibilitychange\", onVisibility);\n\n // pushState\n const origPush = history.pushState.bind(history);\n history.pushState = (...args) => {\n origPush(...args);\n requestAnimationFrame(() => {\n handlePageView();\n });\n };\n\n // popstate\n window.addEventListener(\"popstate\", handlePageView);\n\n // hashchange\n window.addEventListener(\"hashchange\", handlePageView);\n\n // click autocapture\n const onClick: EventListener = (ev: Event) => {\n const clickEvent = ev as MouseEvent;\n if (clickEvent.type === \"auxclick\" && clickEvent.button !== 1) return;\n\n const target = clickEvent.target as Element | null;\n if (!target) return;\n\n // Check if inside <a> or <button>\n const insideInteractive = !!target.closest(\"a, button\");\n\n let el: Element | null = target;\n let depth = 0;\n\n while (el) {\n const eventName = el.getAttribute(\"data-s-event\") || el.getAttribute(\"data-s:event\");\n if (eventName) {\n const propsAttr = el.getAttribute(\"data-s-event-props\") || el.getAttribute(\"data-s:event-props\");\n const props = propsAttr ? parseProps(propsAttr) : undefined;\n const path = el.getAttribute(\"data-s-event-path\") || el.getAttribute(\"data-s:event-path\") || undefined;\n\n if ((path && !shouldTrackPath(path, this.config)) || !shouldTrackPath(location.pathname, this.config)) {\n return;\n }\n\n this.event(eventName, path ?? props, props);\n return;\n }\n\n el = el.parentElement;\n depth++;\n\n // If not in <a>/<button>, stop after 3 levels\n if (!insideInteractive && depth >= 3) break;\n }\n };\n\n document.addEventListener(\"click\", onClick);\n\n // Fire initial pageview if already visible\n if (document.visibilityState === \"visible\") handlePageView();\n }\n}\n\nexport const configure = (userConfig: AnalyticsConfig = {}) => {\n AnalyticsTracker.getInstance(userConfig);\n};\n\nexport const event = async (eventName: string, pathOrProps?: string | BaseProps, props?: BaseProps) => {\n const instance = AnalyticsTracker.getInstance();\n await instance.event(eventName, pathOrProps, props);\n};\n\nexport const view = async (pathOrProps?: string | BaseProps, props?: BaseProps) => {\n const instance = AnalyticsTracker.getInstance();\n await instance.view(pathOrProps, props);\n};\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * Bot & crawler detection \u2014 standalone module.\n *\n * Usage:\n * import { detectBot } from '@aspect/fingerprint/bot'\n * const result = detectBot()\n * if (result.isBot) console.log(result.botKind, result.signals)\n *\n * Detects:\n * - Known search engine crawlers (Googlebot, Bingbot, Yandex, Baidu, etc.)\n * - Social media crawlers (Facebook, Twitter, LinkedIn, etc.)\n * - Headless browsers (Puppeteer, Playwright, Selenium, PhantomJS)\n * - General automation tools via navigator.webdriver and injected globals\n * - API tampering / lie detection (prototype spoofing, proxy wrapping)\n *\n * Zero dependencies \u2014 can be imported and used independently of the\n * fingerprinting library.\n */\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\nexport type BotKind =\n | 'search_engine' // Googlebot, Bingbot, Yandex, Baidu, DuckDuckBot, etc.\n | 'social_crawler' // Facebook, Twitter/X, LinkedIn, Slack, Discord, etc.\n | 'headless' // Headless Chrome/Firefox, PhantomJS\n | 'automation' // Selenium, Puppeteer, Playwright (non-headless)\n | 'library' // curl, wget, python-requests, node-fetch, etc.\n | 'unknown_bot' // Signals say bot, but can't classify further\n | 'human' // No bot signals detected\n\nexport interface BotSignals {\n /** navigator.userAgent matched a known bot pattern. */\n userAgentBot: string | null\n /** navigator.webdriver is true. */\n webdriver: boolean\n /** Headless browser indicators detected. */\n headless: boolean\n /** Automation globals found on window. */\n automationGlobals: string[]\n /** Number of API lies (toString/proxy tampering) detected. */\n liesDetected: number\n /** Proxy wrapping detected on native functions. */\n hasProxy: boolean\n /** navigator.languages is empty or missing. */\n missingLanguages: boolean\n /** navigator.plugins is empty (non-mobile). */\n missingPlugins: boolean\n}\n\nexport interface BotDetectionResult {\n /** True when any bot signal fires. */\n isBot: boolean\n /** Classified category of the detected bot. */\n botKind: BotKind\n /** Individual signal results for debugging / logging. */\n signals: BotSignals\n}\n\n// ---------------------------------------------------------------------------\n// Known bot UA patterns\n// ---------------------------------------------------------------------------\n\ninterface BotPattern {\n pattern: RegExp\n kind: BotKind\n name: string\n}\n\nconst BOT_PATTERNS: BotPattern[] = [\n // Search engines\n { pattern: /Googlebot/i, kind: 'search_engine', name: 'Googlebot' },\n { pattern: /Google-InspectionTool/i, kind: 'search_engine', name: 'Googlebot' },\n { pattern: /Storebot-Google/i, kind: 'search_engine', name: 'Googlebot' },\n { pattern: /AdsBot-Google/i, kind: 'search_engine', name: 'Google Ads' },\n { pattern: /Mediapartners-Google/i, kind: 'search_engine', name: 'Google Adsense' },\n { pattern: /bingbot/i, kind: 'search_engine', name: 'Bingbot' },\n { pattern: /msnbot/i, kind: 'search_engine', name: 'MSNBot' },\n { pattern: /YandexBot/i, kind: 'search_engine', name: 'YandexBot' },\n { pattern: /YandexAccessibilityBot/i, kind: 'search_engine', name: 'YandexBot' },\n { pattern: /Baiduspider/i, kind: 'search_engine', name: 'Baidu' },\n { pattern: /DuckDuckBot/i, kind: 'search_engine', name: 'DuckDuckBot' },\n { pattern: /Sogou/i, kind: 'search_engine', name: 'Sogou' },\n { pattern: /Exabot/i, kind: 'search_engine', name: 'Exabot' },\n { pattern: /ia_archiver/i, kind: 'search_engine', name: 'Alexa' },\n { pattern: /SemrushBot/i, kind: 'search_engine', name: 'SemrushBot' },\n { pattern: /AhrefsBot/i, kind: 'search_engine', name: 'AhrefsBot' },\n { pattern: /MJ12bot/i, kind: 'search_engine', name: 'MJ12bot' },\n { pattern: /DotBot/i, kind: 'search_engine', name: 'DotBot' },\n { pattern: /PetalBot/i, kind: 'search_engine', name: 'PetalBot' },\n { pattern: /Applebot/i, kind: 'search_engine', name: 'Applebot' },\n { pattern: /GPTBot/i, kind: 'search_engine', name: 'GPTBot' },\n { pattern: /ChatGPT-User/i, kind: 'search_engine', name: 'ChatGPT' },\n { pattern: /ClaudeBot/i, kind: 'search_engine', name: 'ClaudeBot' },\n { pattern: /CCBot/i, kind: 'search_engine', name: 'Common Crawl' },\n { pattern: /anthropic-ai/i, kind: 'search_engine', name: 'Anthropic' },\n { pattern: /PerplexityBot/i, kind: 'search_engine', name: 'PerplexityBot' },\n\n // Social crawlers\n { pattern: /facebookexternalhit/i, kind: 'social_crawler', name: 'Facebook' },\n { pattern: /Facebot/i, kind: 'social_crawler', name: 'Facebook' },\n { pattern: /Twitterbot/i, kind: 'social_crawler', name: 'Twitter' },\n { pattern: /LinkedInBot/i, kind: 'social_crawler', name: 'LinkedIn' },\n { pattern: /Slackbot/i, kind: 'social_crawler', name: 'Slack' },\n { pattern: /Discordbot/i, kind: 'social_crawler', name: 'Discord' },\n { pattern: /TelegramBot/i, kind: 'social_crawler', name: 'Telegram' },\n { pattern: /WhatsApp/i, kind: 'social_crawler', name: 'WhatsApp' },\n { pattern: /Pinterestbot/i, kind: 'social_crawler', name: 'Pinterest' },\n { pattern: /Snapchat/i, kind: 'social_crawler', name: 'Snapchat' },\n\n // Headless / automation\n { pattern: /HeadlessChrome/i, kind: 'headless', name: 'Headless Chrome' },\n { pattern: /PhantomJS/i, kind: 'headless', name: 'PhantomJS' },\n { pattern: /Selenium/i, kind: 'automation', name: 'Selenium' },\n { pattern: /Puppeteer/i, kind: 'automation', name: 'Puppeteer' },\n\n // HTTP libraries\n { pattern: /curl\\//i, kind: 'library', name: 'curl' },\n { pattern: /Wget\\//i, kind: 'library', name: 'Wget' },\n { pattern: /python-requests/i, kind: 'library', name: 'Python Requests' },\n { pattern: /python-urllib/i, kind: 'library', name: 'Python urllib' },\n { pattern: /node-fetch/i, kind: 'library', name: 'node-fetch' },\n { pattern: /axios\\//i, kind: 'library', name: 'Axios' },\n { pattern: /Go-http-client/i, kind: 'library', name: 'Go HTTP' },\n { pattern: /Java\\//i, kind: 'library', name: 'Java HTTP' },\n { pattern: /libwww-perl/i, kind: 'library', name: 'Perl LWP' },\n { pattern: /Apache-HttpClient/i, kind: 'library', name: 'Apache HttpClient' },\n { pattern: /okhttp/i, kind: 'library', name: 'OkHttp' },\n { pattern: /Scrapy/i, kind: 'library', name: 'Scrapy' },\n\n // Generic catch-all (must be last)\n { pattern: /bot|crawl|spider|slurp|fetch|archiver/i, kind: 'unknown_bot', name: 'generic' },\n]\n\n// ---------------------------------------------------------------------------\n// Automation globals injected by common frameworks\n// ---------------------------------------------------------------------------\n\nconst AUTOMATION_GLOBALS = [\n // Selenium\n '__selenium_unwrapped',\n '__selenium_evaluate',\n '__webdriver_evaluate',\n '__webdriver_script_fn',\n '__webdriver_script_func',\n '__webdriver_script_function',\n '__fxdriver_evaluate',\n '__fxdriver_unwrapped',\n '_Selenium_IDE_Recorder',\n // Puppeteer / CDP\n '__puppeteer_evaluation_script__',\n // PhantomJS\n 'callPhantom',\n '_phantom',\n 'phantom',\n // Nightmare.js\n '__nightmare',\n // Playwright (injects page.exposeFunction bindings)\n '__playwright',\n '__pw_manual',\n // CasperJS\n '__casper',\n // TestCafe\n '__testcafe',\n // WebDriver (generic)\n 'webdriver',\n 'domAutomation',\n 'domAutomationController',\n] as const\n\n// ---------------------------------------------------------------------------\n// Core detection\n// ---------------------------------------------------------------------------\n\n/**\n * Detect whether the current browser context is a bot or crawler.\n * Synchronous and lightweight \u2014 no async APIs needed.\n */\nexport function detectBot(): BotDetectionResult {\n const signals = collectBotSignals()\n\n const isBot =\n signals.userAgentBot !== null ||\n signals.webdriver ||\n signals.headless ||\n signals.automationGlobals.length > 0 ||\n signals.liesDetected > 2 ||\n (signals.liesDetected > 0 && signals.hasProxy)\n\n let botKind: BotKind = 'human'\n if (isBot) {\n if (signals.userAgentBot !== null) {\n // Find the matching pattern to determine kind\n const ua = navigator.userAgent || ''\n const match = BOT_PATTERNS.find(p => p.pattern.test(ua))\n botKind = match?.kind ?? 'unknown_bot'\n } else if (signals.headless) {\n botKind = 'headless'\n } else if (signals.webdriver || signals.automationGlobals.length > 0) {\n botKind = 'automation'\n } else {\n botKind = 'unknown_bot'\n }\n }\n\n return { isBot, botKind, signals }\n}\n\n// ---------------------------------------------------------------------------\n// Signal collectors\n// ---------------------------------------------------------------------------\n\nfunction collectBotSignals(): BotSignals {\n return {\n userAgentBot: detectUserAgentBot(),\n webdriver: detectWebdriver(),\n headless: detectHeadless(),\n automationGlobals: detectAutomationGlobals(),\n ...detectLies(),\n missingLanguages: detectMissingLanguages(),\n missingPlugins: detectMissingPlugins(),\n }\n}\n\n/** Check UA string against known bot patterns. */\nfunction detectUserAgentBot(): string | null {\n const ua = navigator.userAgent || ''\n if (!ua) return 'empty-ua'\n for (const { pattern, name } of BOT_PATTERNS) {\n if (pattern.test(ua)) return name\n }\n return null\n}\n\n/** navigator.webdriver is set by WebDriver-based automation. */\nfunction detectWebdriver(): boolean {\n return !!(navigator as any).webdriver\n}\n\n/** Headless browser indicators. */\nfunction detectHeadless(): boolean {\n const w = window as any\n const n = navigator as any\n\n // Chrome-specific: headless mode omits the chrome runtime object\n if (/Chrome/.test(n.userAgent) && !w.chrome) return true\n\n // HeadlessChrome in UA\n if (/HeadlessChrome/.test(n.userAgent)) return true\n\n // Notification permission is always \"denied\" in headless Chrome\n // (in headed mode it defaults to \"default\")\n try {\n if (Notification.permission === 'denied' && n.permissions) {\n // Double-check: headless also lacks plugins\n if ((!n.plugins || n.plugins.length === 0) && !/Mobile|Android/i.test(n.userAgent)) {\n return true\n }\n }\n } catch { /* permissions API unavailable */ }\n\n return false\n}\n\n/** Detect automation framework globals on window. */\nfunction detectAutomationGlobals(): string[] {\n const w = window as any\n return AUTOMATION_GLOBALS.filter(key => {\n try { return key in w && w[key] !== undefined }\n catch { return false }\n }) as string[]\n}\n\n/**\n * Lie detection \u2014 detect API tampering (proxies, toString spoofing).\n * Extracted from the fingerprint lies module; self-contained here.\n */\nfunction detectLies(): { liesDetected: number; hasProxy: boolean } {\n let liesDetected = 0\n let hasProxy = false\n\n const apisToTest: Array<[string, () => unknown]> = [\n ['Navigator.prototype.userAgent', () => desc(Navigator.prototype, 'userAgent')],\n ['Navigator.prototype.languages', () => desc(Navigator.prototype, 'languages')],\n ['Navigator.prototype.platform', () => desc(Navigator.prototype, 'platform')],\n ['Navigator.prototype.hardwareConcurrency', () => desc(Navigator.prototype, 'hardwareConcurrency')],\n ['Navigator.prototype.webdriver', () => desc(Navigator.prototype, 'webdriver')],\n ['HTMLCanvasElement.prototype.toDataURL', () => HTMLCanvasElement.prototype.toDataURL],\n ['CanvasRenderingContext2D.prototype.fillText', () => CanvasRenderingContext2D.prototype.fillText],\n ['Date.prototype.getTimezoneOffset', () => Date.prototype.getTimezoneOffset],\n ]\n\n for (const [name, accessor] of apisToTest) {\n try {\n const val = accessor()\n if (val === undefined || val === null) continue\n\n // toString format check\n if (typeof val === 'function') {\n const str = Function.prototype.toString.call(val)\n if (!isNativeToString(str)) liesDetected++\n }\n\n // Getter integrity check\n if (name.includes('.prototype.') && typeof val !== 'function') {\n const parts = name.split('.')\n const proto = safeProto(parts[0])\n const prop = parts[parts.length - 1]\n if (proto) {\n const d = Object.getOwnPropertyDescriptor(proto, prop)\n if (d?.get) {\n const gs = Function.prototype.toString.call(d.get)\n if (!isNativeToString(gs)) liesDetected++\n }\n }\n }\n\n // Proxy detection\n if (typeof val === 'function') {\n if (val.toString !== Function.prototype.toString) {\n try {\n const native = Function.prototype.toString.call(val)\n const custom = val.toString()\n if (native !== custom) { liesDetected++; hasProxy = true }\n } catch { liesDetected++; hasProxy = true }\n }\n }\n } catch { /* skip inaccessible */ }\n }\n\n // Meta-test: toString integrity\n try {\n const s = Function.prototype.toString.call(Function.prototype.toString)\n if (!isNativeToString(s)) liesDetected++\n } catch { /* skip */ }\n\n return { liesDetected, hasProxy }\n}\n\n/** Missing navigator.languages is a strong headless indicator. */\nfunction detectMissingLanguages(): boolean {\n const langs = navigator.languages\n return !langs || langs.length === 0\n}\n\n/** Missing plugins on desktop is a headless indicator. */\nfunction detectMissingPlugins(): boolean {\n if (/Mobile|Android/i.test(navigator.userAgent)) return false\n return !navigator.plugins || navigator.plugins.length === 0\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction isNativeToString(str: string): boolean {\n return /^function\\s[^{]*\\{\\s*\\[native code\\]\\s*\\}$/.test(str) ||\n str === 'function () { [native code] }' ||\n /^\\(\\)\\s*=>\\s*\\{\\s*\\[native code\\]\\s*\\}$/.test(str)\n}\n\nfunction desc(proto: object, prop: string) {\n return Object.getOwnPropertyDescriptor(proto, prop)\n}\n\nfunction safeProto(name: string): object | null {\n try { return (window as any)[name]?.prototype ?? null }\n catch { return null }\n}\n", "export const getEnvironment = (): {\n isLocalhost: boolean;\n isHeadlessBrowser: boolean;\n} => ({\n isLocalhost:\n (/^localhost$|^127(\\.[0-9]+){0,2}\\.[0-9]+$|^\\[::1?\\]$/.test(location.hostname) &&\n (location.protocol === \"http:\" || location.protocol === \"https:\")) ||\n location.protocol === \"file:\",\n isHeadlessBrowser: Boolean(\n window.navigator.webdriver ||\n (\"_phantom\" in window && window._phantom) ||\n (\"__nightmare\" in window && window.__nightmare) ||\n (\"Cypress\" in window && window.Cypress)\n )\n});\nexport const isClient = (): boolean => {\n try {\n // Basic checks for window and document\n if (typeof window === \"undefined\" || typeof document === \"undefined\") return false;\n\n // Check for navigator safely\n const ua = typeof navigator !== \"undefined\" ? navigator.userAgent : \"\";\n if (/node|jsdom/i.test(ua)) return false;\n return true;\n } catch {\n return false;\n }\n};\n", "import type { AnalyticsConfig, InternalAnalyticsConfig } from \"../types\";\nimport { getEnvironment } from \"./environment\";\n\nexport const defaultConfig: InternalAnalyticsConfig = {\n hostname: null,\n devmode: false,\n collectorUrl: \"https://collector.onedollarstats.com/events\",\n hashRouting: false,\n autocollect: true,\n excludePages: [],\n includePages: []\n};\n\nexport const mergeConfig = (userConfig: AnalyticsConfig = {}): InternalAnalyticsConfig => {\n const { isLocalhost } = getEnvironment();\n\n const devmode = !isLocalhost ? false : (userConfig.devmode ?? !!userConfig.trackLocalhostAs);\n\n let hostname: string | null;\n if (userConfig.hostname) {\n const trimmed = userConfig.hostname.trim();\n hostname = trimmed || null;\n } else if (devmode && userConfig.trackLocalhostAs) {\n hostname = userConfig.trackLocalhostAs;\n } else {\n hostname = null;\n }\n\n // Merge default config, user config, and computed values\n return { ...defaultConfig, ...userConfig, hostname, devmode };\n};\n", "import { defaultConfig } from \"./merge-config\";\n\nexport const createDebugModal = (debugUrl: string, analyticsUrl: string) => {\n if (!document.getElementById(\"onedollatstats-modal-styles\")) {\n const style = document.createElement(\"style\");\n style.id = \"onedollatstats-modal-styles\";\n style.textContent = CSS;\n document.head.appendChild(style);\n }\n\n // Create modal\n const modal = document.createElement(\"div\");\n modal.className = \"dev-modal\";\n modal.innerHTML = `\n <button class=\"close-btn\">&times;</button>\n <p class=\"title\">onedollarstats debug window</p>\n <p>${icons.info}<span class=\"text\">Tracking localhost as ${debugUrl}</span></p>\n <div id=\"event-log\" style=\"max-height: 100px; overflow-y: auto;\"></div>\n `;\n document.body.appendChild(modal);\n\n // Close handler\n modal.querySelector(\".close-btn\")?.addEventListener(\"click\", () => modal.remove(), { once: true });\n\n // Health check\n if (analyticsUrl === defaultConfig.collectorUrl) {\n const img = new Image(1, 1);\n img.onerror = () => {\n if (modal.querySelector(\"#ad-blocker-warning\")) return;\n const warning = document.createElement(\"p\");\n warning.id = \"ad-blocker-warning\";\n warning.innerHTML = `${icons.warning}<span class=\"text\">Health check failed - ad blocker might be interfering.</span>`;\n modal.querySelector(\".title\")?.insertAdjacentElement(\"afterend\", warning);\n };\n img.src = \"https://collector.onedollarstats.com/pixel-health\";\n }\n\n // Log rendering function\n return (message: string, success: boolean): void => {\n const logContainer = modal.querySelector(\"#event-log\");\n if (!logContainer || modal.querySelector(\"#ad-blocker-warning\")) return;\n\n const entry = document.createElement(\"p\");\n entry.innerHTML = `${success ? icons.success : icons.error}<span class=\"text\">${message}</span>`;\n logContainer.appendChild(entry);\n logContainer.scrollTop = logContainer.scrollHeight;\n };\n};\n\nconst icons = {\n info: `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"gray\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"/><path d=\"M12 16v-4\"/><path d=\"M12 8h.01\"/></svg>`,\n success: `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"green\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"/><path d=\"m9 12 2 2 4-4\"/></svg>`,\n error: `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"red\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"/><path d=\"m15 9-6 6\"/><path d=\"m9 9 6 6\"/></svg>`,\n warning: `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"orange\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3\"/><path d=\"M12 9v4\"/><path d=\"M12 17h.01\"/></svg>`\n} as const;\n\nconst CSS = `\n .dev-modal {\n position: fixed;\n bottom: 20px;\n right: 20px;\n background: #f6f6f7;\n color: #21272F;\n padding: 14px;\n border-radius: 8px;\n max-width: 340px;\n max-height: 180px;\n box-shadow: 0 5px 20px rgba(0,0,0,0.3);\n font-family: sans-serif;\n z-index: 99999;\n animation: slideIn 0.3s ease-out;\n}\n\n.dev-modal .title {\n text-transform: uppercase;\n font-size: 11px;\n font-weight: 500;\n margin: 0 0 6px 0;\n letter-spacing: 0.5px;\n}\n\n.dev-modal p {\n margin: 4px 0;\n font-size: 14px;\n display: flex;\n align-items: flex-start;\n gap: 4px;\n}\n\n.dev-modal .text {\n word-break: break-word;\n}\n\n.dev-modal p svg {\n flex-shrink: 0;\n width: 18px;\n height: 18px;\n margin-top: 1px;\n}\n\n.dev-modal .close-btn {\n position: absolute;\n top: 2px;\n right: 8px;\n background: transparent;\n border: none;\n cursor: pointer;\n font-size: 14px;\n font-weight: bold;\n color: #333;\n}\n\n@keyframes slideIn {\n from {\n opacity: 0;\n transform: translateX(100%);\n }\n to {\n opacity: 1;\n transform: translateX(0);\n }\n}`;\n", "export const parseUtmParams = (urlSearchParams: URLSearchParams) => {\n const utm: Record<string, string> = {};\n const keys = [\"utm_campaign\", \"utm_source\", \"utm_medium\", \"utm_term\", \"utm_content\"] as const;\n\n for (const key of keys) {\n const raw = urlSearchParams.get(key);\n if (!raw) continue;\n\n const decoded = recursiveDecode(raw).trim();\n if (decoded) {\n utm[key] = decoded;\n }\n }\n\n return utm;\n};\n\nconst recursiveDecode = (value: string): string => {\n let current = value;\n let decoded = decodeURIComponent(current);\n\n while (decoded !== current) {\n current = decoded;\n decoded = decodeURIComponent(current);\n }\n\n return current;\n};\n", "export const parseProps = (propsString: string): Record<string, string> | undefined => {\n if (!propsString) return undefined;\n // \"key1=value1;key2=value2\"\n\n const splittedProps = propsString.split(\";\");\n const propsObj: Record<string, string> = {};\n\n for (const keyValueString of splittedProps) {\n const keyValuePair = keyValueString.split(\"=\").map((el) => el.trim());\n if (keyValuePair.length !== 2 || keyValuePair[0] === \"\" || keyValuePair[1] === \"\") continue;\n // @ts-ignore\n propsObj[keyValuePair[0]] = keyValuePair[1];\n }\n\n return Object.keys(propsObj).length === 0 ? undefined : propsObj;\n};\n", "export const resolvePath = (pathOrProps?: string): string => {\n if (pathOrProps) return pathOrProps;\n\n const sources = [\n { value: document.body?.getAttribute(\"data-s-path\"), name: \"data-s-path\" },\n { value: document.body?.getAttribute(\"data-s:path\"), name: \"data-s:path\" }\n ];\n\n // Only keep sources that actually exist\n const existing = sources.filter(({ value }) => value);\n\n if (existing.length > 1) {\n console.warn(\"[onedollarstats] Multiple path sources found. Using priority order:\", existing.map(({ name }) => name).join(\" > \"));\n }\n\n // Return first available value, fallback to location.pathname\n return existing[0]?.value ?? location.pathname;\n};\n", "import type { InternalAnalyticsConfig } from \"../types\";\n\nconst matchesPattern = (path: string, pattern: string): boolean => {\n // Escape special regex characters except '*' which becomes '.*'\n const escaped = pattern.replace(/[.+^${}()|[\\]\\\\]/g, \"\\\\$&\").replace(/\\*/g, \".*\");\n return new RegExp(`^${escaped}$`).test(path);\n};\n\nexport const shouldTrackPath = (path: string, config: InternalAnalyticsConfig): boolean => {\n // Exclude pages first\n if (config.excludePages.some((pattern) => matchesPattern(path, pattern))) return false;\n // If includePages is defined, only allow matching paths\n if (config.includePages.length && !config.includePages.some((pattern) => matchesPattern(path, pattern))) return false;\n return true;\n};\n", "import type { AnalyticsConfig, BaseProps, BodyToSend, Event, InternalAnalyticsConfig, ViewArguments } from \"./types\";\nimport { detectBot } from \"./utils/bot\";\nimport { createDebugModal } from \"./utils/create-modal\";\nimport { getEnvironment, isClient } from \"./utils/environment\";\nimport { mergeConfig } from \"./utils/merge-config\";\nimport { parseUtmParams } from \"./utils/parse-utm-params\";\nimport { parseProps } from \"./utils/props-parser\";\nimport { resolvePath } from \"./utils/resolve-path\";\nimport { shouldTrackPath } from \"./utils/should-track\";\n\nclass AnalyticsTracker {\n private static instance: AnalyticsTracker | null = null;\n\n private autocollectSetupDone = false;\n private config: InternalAnalyticsConfig;\n private lastPage: string | null = null;\n private modalLog: (message: string, success: boolean) => void = () => {};\n\n public static getInstance(userConfig: AnalyticsConfig = {}): AnalyticsTracker {\n // Fresh no-op instance for SSR\n if (!isClient()) return new AnalyticsTracker(userConfig);\n\n if (!AnalyticsTracker.instance) {\n AnalyticsTracker.instance = new AnalyticsTracker(userConfig);\n }\n return AnalyticsTracker.instance;\n }\n\n private constructor(userConfig: AnalyticsConfig = {}) {\n this.config = mergeConfig(userConfig);\n\n // Skip setup in non-client environments\n if (!isClient()) return;\n\n const { isLocalhost } = getEnvironment();\n\n // Debug log on localhost\n if (isLocalhost && this.config.devmode && this.config.hostname) {\n console.log(`[onedollarstats]\\nOneDollarStats connected! Tracking localhost as ${this.config.hostname}`);\n\n this.modalLog = createDebugModal(this.config.hostname, this.config.collectorUrl);\n }\n\n // Auto-start autocollect\n if (this.config.autocollect) this.setupAutocollect();\n }\n\n private async sendWithBeaconOrFetch(stringifiedBody: string, callback: (success: boolean) => void): Promise<void> {\n // First fallback: try sendBeacon\n if (navigator.sendBeacon?.(this.config.collectorUrl, stringifiedBody)) {\n callback(true);\n return;\n }\n\n // Second fallback: use fetch() with keepalive\n fetch(this.config.collectorUrl, {\n method: \"POST\",\n body: stringifiedBody,\n headers: { \"Content-Type\": \"application/json\" },\n keepalive: true\n })\n .then(({ ok }) => callback(ok))\n .catch((err: Error) => {\n console.error(\"[onedollarstats] fetch() failed:\", err.message);\n callback(false);\n });\n }\n\n // Handles localhost replacement, referrer, UTM parameters, and debug mode.\n // Uses img beacon then `navigator.sendBeacon` if available, otherwise falls back to `fetch`.\n private async send(data: Event): Promise<void> {\n const { isLocalhost, isHeadlessBrowser } = getEnvironment();\n if ((isLocalhost && !this.config.devmode) || isHeadlessBrowser) return;\n\n const { isBot, botKind } = detectBot();\n\n if (isBot && botKind !== \"human\") return;\n\n const urlToSend = new URL(this.config.hostname ? `https://${this.config.hostname}${location.pathname}` : location.href);\n\n // Clean query string unless UTM is explicitly provided\n urlToSend.search = \"\";\n if (data.path) urlToSend.pathname = data.path;\n\n const cleanUrl = urlToSend.href.replace(/\\/$/, \"\");\n\n // Determine referrer\n let referrer: string | undefined = data.referrer;\n try {\n if (!referrer && document.referrer && document.referrer !== \"null\") {\n const referrerURL = new URL(document.referrer);\n if (referrerURL.hostname !== urlToSend.hostname) referrer = referrerURL.href;\n }\n } catch {} // ignore malformed referrer\n\n // Build request body\n const body: BodyToSend = {\n u: cleanUrl,\n e: [\n {\n t: data.type,\n h: this.config.hashRouting,\n r: referrer,\n p: data.props\n }\n ],\n debug: this.config.devmode\n };\n\n if (data.utm && Object.keys(data.utm).length > 0) body.qs = data.utm;\n\n if (body.debug) {\n let logMessage = `[onedollarstats]\\nEvent name: ${data.type}\\nEvent collected from: ${cleanUrl}`;\n if (data.props && Object.keys(data.props).length > 0) logMessage += `\\nProps: ${JSON.stringify(data.props, null, 2)}`;\n if (referrer) logMessage += `\\nReferrer: ${referrer}`;\n if (this.config.hashRouting) logMessage += `\\nHashRouting: ${this.config.hashRouting}`;\n if (data.utm && Object.keys(data.utm).length > 0) logMessage += `\\nUTM: ${data.utm}`;\n\n console.log(logMessage);\n }\n\n // Prepare the event payload\n const stringifiedBody = JSON.stringify(body);\n\n // Encode for safe inclusion in a query string (UTF-8 \u2192 Base64)\n const bytes = new TextEncoder().encode(stringifiedBody); // UTF-8 \u2192 bytes\n const bin = String.fromCharCode(...bytes); // bytes \u2192 binary string\n const payloadBase64 = btoa(bin); // binary \u2192 Base64\n\n const safeGetThreshold = 1500; // limit for query-string-containing URLs\n const tryImageBeacon = payloadBase64.length <= safeGetThreshold;\n\n const onComplete = (success: boolean) => this.modalLog(`${data.type} ${success ? \"sent\" : \"failed to send\"}`, success);\n\n if (tryImageBeacon) {\n // Send via image beacon\n const img = new Image(1, 1);\n\n img.onload = () => onComplete(true);\n // If loading image fails (server unavailable, blocked, etc.)\n img.onerror = () => this.sendWithBeaconOrFetch(stringifiedBody, onComplete);\n\n // Primary attempt: send data via image beacon (GET request with query string)\n img.src = `${this.config.collectorUrl}?data=${payloadBase64}`;\n } else await this.sendWithBeaconOrFetch(stringifiedBody, onComplete);\n }\n\n // Prevents duplicate pageviews and respects include/exclude page rules. Automatically parses UTM parameters from URL.\n private trackPageView({ path, props }: ViewArguments, checkBlock: boolean = false) {\n if (!isClient()) return;\n\n const viewPath = resolvePath(path);\n\n const viewProps =\n props ||\n (() => {\n const newProps = {};\n const elements = document.querySelectorAll(\"[data-s\\\\:view-props], [data-s-view-props]\");\n\n for (const el of Array.from(elements)) {\n const propsString = el.getAttribute(\"data-s-view-props\") || el.getAttribute(\"data-s:view-props\");\n if (!propsString) continue;\n const parsedProps = parseProps(propsString);\n Object.assign(newProps, parsedProps);\n }\n\n return Object.keys(newProps).length ? newProps : undefined;\n })();\n\n // Skip duplicate pageviews or excluded pages\n if (!this.config.hashRouting && this.lastPage === viewPath) return;\n\n // Skip page if checkBlock is true and the path should be excluded\n if (checkBlock && !shouldTrackPath(viewPath, this.config)) return;\n\n this.lastPage = viewPath;\n\n const utm = parseUtmParams(new URLSearchParams(location.search));\n this.send({ type: \"PageView\", path: viewPath, props: viewProps, utm });\n }\n\n /**\n * Tracks a custom event.\n * Can accept path string or a props object.\n *\n * @param eventName Name of the event to track.\n * @param pathOrProps Optional path string or props object.\n * @param props Optional props object if path string is provided.\n */\n public async event(eventName: string, pathOrProps?: string | BaseProps, rawProps?: BaseProps) {\n if (!isClient()) return;\n\n const { isLocalhost, isHeadlessBrowser } = getEnvironment();\n if ((isLocalhost && !this.config.devmode) || isHeadlessBrowser) return;\n\n const path = resolvePath(typeof pathOrProps === \"string\" ? pathOrProps : undefined);\n const props = typeof pathOrProps === \"object\" ? pathOrProps : rawProps;\n\n this.send({ type: eventName, path, props });\n }\n\n /**\n * Records a page view.\n * Can accept path string or a props object.\n *\n * @param pathOrProps Optional path string or props object.\n * @param props Optional props when first arg is a path string.\n */\n public async view(pathOrProps?: string | BaseProps, props?: BaseProps) {\n if (!isClient()) return;\n\n const args: ViewArguments = {};\n\n if (typeof pathOrProps === \"string\") {\n args.path = pathOrProps;\n args.props = props;\n } else if (typeof pathOrProps === \"object\") {\n args.props = pathOrProps;\n }\n\n this.trackPageView(args);\n }\n\n /**\n * Installs global DOM/window listeners exactly once for:\n * - visibilitychange\n * - history.pushState\n * - popstate\n * - hashchange\n * - click autocapture for elements annotated with `data-s:event` & `data-s-event`\n *\n */\n private setupAutocollect() {\n if (!isClient() || this.autocollectSetupDone) return;\n this.autocollectSetupDone = true;\n\n const handlePageView = () => this.trackPageView({}, true);\n\n // visibilitychange\n const onVisibility = () => {\n if (document.visibilityState === \"visible\") handlePageView();\n };\n document.addEventListener(\"visibilitychange\", onVisibility);\n\n // pushState\n const origPush = history.pushState.bind(history);\n history.pushState = (...args) => {\n origPush(...args);\n requestAnimationFrame(() => {\n handlePageView();\n });\n };\n\n // popstate\n window.addEventListener(\"popstate\", handlePageView);\n\n // hashchange\n window.addEventListener(\"hashchange\", handlePageView);\n\n // click autocapture\n const onClick: EventListener = (ev: Event) => {\n const clickEvent = ev as MouseEvent;\n if (clickEvent.type === \"auxclick\" && clickEvent.button !== 1) return;\n\n const target = clickEvent.target as Element | null;\n if (!target) return;\n\n // Check if inside <a> or <button>\n const insideInteractive = !!target.closest(\"a, button\");\n\n let el: Element | null = target;\n let depth = 0;\n\n while (el) {\n const eventName = el.getAttribute(\"data-s-event\") || el.getAttribute(\"data-s:event\");\n if (eventName) {\n const propsAttr = el.getAttribute(\"data-s-event-props\") || el.getAttribute(\"data-s:event-props\");\n const props = propsAttr ? parseProps(propsAttr) : undefined;\n const path = el.getAttribute(\"data-s-event-path\") || el.getAttribute(\"data-s:event-path\") || undefined;\n\n if ((path && !shouldTrackPath(path, this.config)) || !shouldTrackPath(location.pathname, this.config)) {\n return;\n }\n\n this.event(eventName, path ?? props, props);\n return;\n }\n\n el = el.parentElement;\n depth++;\n\n // If not in <a>/<button>, stop after 3 levels\n if (!insideInteractive && depth >= 3) break;\n }\n };\n\n document.addEventListener(\"click\", onClick);\n\n // Fire initial pageview if already visible\n if (document.visibilityState === \"visible\") handlePageView();\n }\n}\n\nexport const configure = (userConfig: AnalyticsConfig = {}) => {\n AnalyticsTracker.getInstance(userConfig);\n};\n\nexport const event = async (eventName: string, pathOrProps?: string | BaseProps, props?: BaseProps) => {\n const instance = AnalyticsTracker.getInstance();\n await instance.event(eventName, pathOrProps, props);\n};\n\nexport const view = async (pathOrProps?: string | BaseProps, props?: BaseProps) => {\n const instance = AnalyticsTracker.getInstance();\n await instance.view(pathOrProps, props);\n};\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "onedollarstats",
3
- "version": "0.0.15",
3
+ "version": "0.0.16",
4
4
  "description": "A lightweight, zero-dependency analytics tracker for frontend apps",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",