UNPKG

@sherpahow/sherpa-sdk

Version:

Sherpa JavaScript SDK for in-app help and product tours. Built with TypeScript, Lit web components, and Nano Stores.

784 lines (783 loc) 35 kB
var __async = (__this, __arguments, generator) => { return new Promise((resolve, reject) => { var fulfilled = (value) => { try { step(generator.next(value)); } catch (e2) { reject(e2); } }; var rejected = (value) => { try { step(generator.throw(value)); } catch (e2) { reject(e2); } }; var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected); step((generator = generator.apply(__this, __arguments)).next()); }); }; function t(...t2) { const [e2, ...n2] = t2; switch (g || (g = new SherpaSDK()), e2) { case "boot": const [t3, e3] = n2; g.boot(t3, e3); break; case "shutdown": g.shutdown(); break; case "startTour": const [i2, s2, o2] = n2; g.startTour(i2, s2, o2); break; case "endTour": g.endTour(); break; case "showSearch": g.showSearch(); break; case "hideSearch": g.hideSearch(); break; case "openDocs": const [a2, r2] = n2; g.openDocs(a2, r2); break; case "closeDocs": const [c2] = n2; g.closeDocs(c2); break; case "closeAllDocs": g.closeAllDocs(); break; case "track": const [h2, u2] = n2; g.track(h2, u2); break; case "updateUser": const [d2, w2] = n2; g.updateUser(d2, w2); break; case "onTourStarted": const [l2] = n2; g.onTourStarted(l2); break; case "onTourEnded": const [p2] = n2; g.onTourEnded(p2); break; case "onStepChanged": const [m2] = n2; g.onStepChanged(m2); break; case "onShowSearch": const [f2] = n2; g.onSearchShown(f2); break; case "onHideSearch": const [y] = n2; g.onSearchHidden(y); break; case "clearCallbacks": g.clearCallbacks(); } } import { T as e, t as n, u as i, c as s, a as o, i as a, b as r, d as c } from "./sherpa-search-components-0.0.13.DiA6EslJ.min.js"; import { c as h, b as u, d } from "./sherpa-guide-components-0.0.13.BkF4XA9G.min.js"; class w { constructor() { this.guideComponentsLoaded = null, this.searchComponentLoaded = null, this.docs = /* @__PURE__ */ new Map(), this.storeUnsubscribers = [], this.handleApplyRecommendation = (t2) => __async(this, null, function* () { const e2 = t2, { stepId: n2 } = e2.detail; yield this.tourController.applyRecommendation(n2); }), this.handleNextStep = () => __async(this, null, function* () { yield this.tourController.nextStep(); }), this.handlePreviousStep = () => __async(this, null, function* () { yield this.tourController.previousStep(); }), this.handleGoToStep = (t2) => __async(this, null, function* () { const e2 = t2, { stepId: n2 } = e2.detail; yield this.tourController.goToStep(n2); }), this.handleEndTour = () => __async(this, null, function* () { yield this.tourController.endTour(); }), this.handleCloseTooltip = () => __async(this, null, function* () { this.hideTooltip(); }), this.handleDocsClose = (t2) => { const e2 = t2, { documentId: n2 } = e2.detail; n2 && this.closeDocs(n2); }, this.handleDocsOpen = (t2) => __async(this, null, function* () { const e2 = t2, { docs: n2 } = e2.detail; try { yield this.openDocs(n2); } catch (i2) { } }), this.tourController = e.getInstance(), this.guideComponentsLoadedPromise = this.ensureGuideComponents(), this.searchComponentsLoadedPromise = this.ensureSearchComponent(), this.setupStoreSubscriptions(), this.setupEventListeners(); } static getInstance() { return w.instance || (w.instance = new w()), w.instance; } ensureGuideComponents() { return __async(this, null, function* () { return this.guideComponentsLoaded || (this.guideComponentsLoaded = Promise.all([import("./sherpa-guide-components-0.0.13.BkF4XA9G.min.js").then((t2) => t2.j), import("./sherpa-guide-components-0.0.13.BkF4XA9G.min.js").then((t2) => t2.k), import("./sherpa-guide-components-0.0.13.BkF4XA9G.min.js").then((t2) => t2.l), import("./sherpa-guide-components-0.0.13.BkF4XA9G.min.js").then((t2) => t2.m)]).then(() => { }).catch((t2) => { throw this.guideComponentsLoaded = null, t2; }).then(() => { })), this.guideComponentsLoaded; }); } ensureSearchComponent() { return __async(this, null, function* () { return this.searchComponentLoaded || (this.searchComponentLoaded = Promise.all([import("./sherpa-search-components-0.0.13.DiA6EslJ.min.js").then((t2) => t2.f)]).then(() => { }).catch((t2) => { throw this.searchComponentLoaded = null, t2; })), this.searchComponentLoaded; }); } setupStoreSubscriptions() { return __async(this, null, function* () { yield this.guideComponentsLoadedPromise, yield this.searchComponentsLoadedPromise; const t2 = n.subscribe((t3) => { t3.isActive ? (this.closeAllDocs(), this.showControlPanel().catch(() => { })) : this.performTourEndCleanup(); }), e2 = i.subscribe((t3) => { t3.currentTooltip ? this.showTooltip(t3.currentTooltip.stepId, t3.currentTooltip.element, t3.currentTooltip.guide, t3.currentTooltip.isPersonalizing).catch(() => { }) : this.hideTooltip(), t3.currentBeacon ? this.showBeacon(t3.currentBeacon.stepId, t3.currentBeacon.element).catch(() => { }) : this.hideBeacon(), t3.controlPanelVisible ? this.showControlPanel().catch(() => { }) : this.hideControlPanel(), t3.searchVisible ? this.showSearch().catch(() => { }) : this.hideSearch(); }); this.storeUnsubscribers.push(t2, e2); }); } setupEventListeners() { return __async(this, null, function* () { yield Promise.all([this.guideComponentsLoadedPromise, this.searchComponentsLoadedPromise]), document.addEventListener("apply-recommendation", this.handleApplyRecommendation), document.addEventListener("next-step", this.handleNextStep), document.addEventListener("previous-step", this.handlePreviousStep), document.addEventListener("go-to-step", this.handleGoToStep), document.addEventListener("end-tour", this.handleEndTour), document.addEventListener("close-tooltip", this.handleCloseTooltip), document.addEventListener("close-docs", this.handleDocsClose); }); } showTooltip(t2, e2, i2, o2) { return __async(this, null, function* () { if (yield this.guideComponentsLoadedPromise, this.hideTooltip(), this.hideBeacon(), !n.get().isActive) return; const a2 = document.createElement("sherpa-tooltip"); a2.stepId = t2, a2.targetElement = e2, a2.guide = i2, a2.isPersonalizing = o2 || 0, a2.step = s.get(), document.body.appendChild(a2), this.currentTooltip = a2; }); } hideTooltip() { this.currentTooltip && (this.currentTooltip.remove(), this.currentTooltip = void 0, o.hideTooltip()), document.querySelectorAll("sherpa-tooltip").forEach((t2) => { t2.remove(); }); } updateTooltipPersonalizingState(t2) { this.currentTooltip && (this.currentTooltip.isPersonalizing = t2); } showBeacon(t2, e2) { return __async(this, null, function* () { if (yield this.guideComponentsLoadedPromise, this.hideBeacon(), this.hideTooltip(), !n.get().isActive) return; const i2 = document.createElement("sherpa-beacon"); i2.stepId = t2, i2.targetElement = e2, this.addTargetElementHighlight(e2), this.makeElementClickableForBeacon(e2), document.body.appendChild(i2), this.currentBeacon = i2; }); } hideBeacon() { if (this.currentBeacon) { const t2 = this.currentBeacon; t2.targetElement && (this.removeTargetElementHighlight(t2.targetElement), this.removeBeaconClickableState(t2.targetElement)), this.currentBeacon.remove(), this.currentBeacon = void 0, o.hideBeacon(); } document.querySelectorAll("sherpa-beacon").forEach((t2) => { t2.remove(); }); } addTargetElementHighlight(t2) { const e2 = t2, n2 = e2.style.boxShadow, i2 = e2.style.transition; e2.dataset.sherpaOriginalBoxShadow = n2, e2.dataset.sherpaOriginalTransition = i2, e2.dataset.sherpaHighlighted = "true", e2.style.transition = "box-shadow 0.3s ease-in-out", e2.style.boxShadow = "\n ".concat(n2 ? n2 + ", " : "", "\n 0 0 0 2px rgba(34, 197, 94, 0.6),\n 0 0 0 4px rgba(34, 197, 94, 0.3),\n 0 0 20px rgba(34, 197, 94, 0.2)\n "); const s2 = document.createElement("style"); s2.id = "sherpa-target-highlight-animation", s2.textContent = "\n @keyframes sherpa-target-pulse {\n 0%, 100% {\n box-shadow: ".concat(n2 ? n2 + ", " : "", "\n 0 0 0 2px rgba(34, 197, 94, 0.6),\n 0 0 0 4px rgba(34, 197, 94, 0.3),\n 0 0 20px rgba(34, 197, 94, 0.2);\n }\n 50% {\n box-shadow: ").concat(n2 ? n2 + ", " : "", '\n 0 0 0 2px rgba(34, 197, 94, 0.8),\n 0 0 0 6px rgba(34, 197, 94, 0.4),\n 0 0 30px rgba(34, 197, 94, 0.3);\n }\n }\n \n [data-sherpa-highlighted="true"] {\n animation: sherpa-target-pulse 2s ease-in-out infinite;\n }\n\n @media (prefers-reduced-motion: reduce) {\n [data-sherpa-highlighted="true"] {\n animation: none;\n }\n }\n '), document.getElementById("sherpa-target-highlight-animation") || document.head.appendChild(s2); } removeTargetElementHighlight(t2) { const e2 = t2; "true" === e2.dataset.sherpaHighlighted && (e2.style.boxShadow = e2.dataset.sherpaOriginalBoxShadow || "", e2.style.transition = e2.dataset.sherpaOriginalTransition || "", delete e2.dataset.sherpaOriginalBoxShadow, delete e2.dataset.sherpaOriginalTransition, delete e2.dataset.sherpaHighlighted); } makeElementClickableForBeacon(t2) { const e2 = t2, n2 = e2.style.cursor; e2.dataset.sherpaOriginalPointerEvents = e2.style.pointerEvents, e2.dataset.sherpaOriginalCursor = n2, e2.dataset.sherpaBeaconClickable = "true", "none" === e2.style.pointerEvents && (e2.style.pointerEvents = "auto"), e2.style.cursor = "pointer"; } removeBeaconClickableState(t2) { const e2 = t2; "true" === e2.dataset.sherpaBeaconClickable && (e2.style.pointerEvents = e2.dataset.sherpaOriginalPointerEvents || "", e2.style.cursor = e2.dataset.sherpaOriginalCursor || "", delete e2.dataset.sherpaOriginalPointerEvents, delete e2.dataset.sherpaOriginalCursor, delete e2.dataset.sherpaBeaconClickable); } showControlPanel() { return __async(this, null, function* () { if (yield this.guideComponentsLoadedPromise, this.currentControlPanel) return; const t2 = document.createElement("sherpa-control-panel"), e2 = () => { t2.tourState = n.get(), t2.isFirstStep = a.get(), t2.isLastStep = r.get(), t2.progress = c.get(); }; e2(); const i2 = [n.subscribe(e2), a.subscribe(e2), r.subscribe(e2), c.subscribe(e2)]; t2.t = i2, document.body.appendChild(t2), this.currentControlPanel = t2; }); } hideControlPanel() { if (this.currentControlPanel) { const t2 = this.currentControlPanel.t; t2 && t2.forEach((t3) => t3()), this.currentControlPanel.remove(), this.currentControlPanel = void 0; } } showSearch() { return __async(this, null, function* () { try { if (yield this.searchComponentsLoadedPromise, this.currentSearch) return; const t2 = document.createElement("sherpa-search"); t2.addEventListener("docs-open", this.handleDocsOpen.bind(this)), document.body.appendChild(t2), this.currentSearch = t2; } catch (t2) { throw t2; } }); } hideSearch() { this.currentSearch && (this.currentSearch.remove(), this.currentSearch = void 0); } getNextDocsPosition() { const t2 = (window.innerWidth - 400) / 2, e2 = (window.innerHeight - 500) / 2, n2 = window.innerWidth - 450, i2 = window.innerHeight - 550; return { x: Math.max(50, Math.min(t2, n2)), y: Math.max(50, Math.min(e2, i2)) }; } openDocs(t2, e2) { return __async(this, null, function* () { yield this.guideComponentsLoadedPromise, this.closeAllDocs(); const n2 = (e2 == null ? void 0 : e2.position) || this.getNextDocsPosition(), i2 = document.createElement("sherpa-docs"); i2.document = t2, i2.initialPosition = n2, i2.style.position = "fixed", i2.style.top = "0", i2.style.left = "0", i2.style.width = "100%", i2.style.height = "100%", i2.style.pointerEvents = "none", document.body.appendChild(i2), requestAnimationFrame(() => { i2.visible = 1; }), this.docs.set(t2.id, { document: t2, position: n2, size: "Medium", element: i2 }); }); } closeDocs(t2) { const e2 = this.docs.get(t2); e2 && e2.element && e2.element.remove(), this.docs.delete(t2); } closeAllDocs() { this.docs.forEach((t2) => { t2.element && t2.element.remove(); }), this.docs.clear(); } bringDocsToFront(t2) { const e2 = this.docs.get(t2); e2 && this.docs.set(t2, e2); } hasOpenDocs() { return this.docs.size > 0; } getOpenDocsIds() { return Array.from(this.docs.keys()); } getDocsState(t2) { return this.docs.get(t2); } performTourEndCleanup() { this.hideTooltip(), this.hideBeacon(), this.hideControlPanel(), this.closeAllDocs(), this.cleanupAnimationStyles(), this.cleanupAllElementHighlights(), this.showSearch().catch(() => { }); } cleanupAnimationStyles() { const t2 = document.getElementById("sherpa-target-highlight-animation"); t2 && t2.remove(); } cleanupAllElementHighlights() { document.querySelectorAll('[data-sherpa-highlighted="true"]').forEach((t2) => { this.removeTargetElementHighlight(t2); }), document.querySelectorAll('[data-sherpa-beacon-clickable="true"]').forEach((t2) => { this.removeBeaconClickableState(t2); }); } resetComponentLoadingPromises() { this.guideComponentsLoaded = null, this.searchComponentLoaded = null; } cleanupStoreSubscriptions() { this.storeUnsubscribers.forEach((t2) => { try { t2(); } catch (e2) { } }), this.storeUnsubscribers = []; } static resetInstance() { w.instance && (w.instance.destroy(), w.instance = null); } destroy() { this.hideTooltip(), this.hideBeacon(), this.hideControlPanel(), this.hideSearch(), this.closeAllDocs(), this.cleanupAnimationStyles(), this.cleanupAllElementHighlights(), this.cleanupStoreSubscriptions(), this.resetComponentLoadingPromises(), document.removeEventListener("apply-recommendation", this.handleApplyRecommendation), document.removeEventListener("next-step", this.handleNextStep), document.removeEventListener("previous-step", this.handlePreviousStep), document.removeEventListener("go-to-step", this.handleGoToStep), document.removeEventListener("end-tour", this.handleEndTour), document.removeEventListener("close-tooltip", this.handleCloseTooltip), document.removeEventListener("close-docs", this.handleDocsClose); } getDebugInfo() { return { hasTooltip: !!this.currentTooltip, hasBeacon: !!this.currentBeacon, hasControlPanel: !!this.currentControlPanel, hasSearch: !!this.currentSearch, openDocs: this.getOpenDocsIds(), docsCount: this.docs.size, tourState: n.get(), uiState: i.get() }; } } class l { constructor(t2, e2) { this.navigateFunction = t2, this.location = e2; } navigate(t2) { return __async(this, null, function* () { const e2 = this.capturePageState(); try { let n2; if (t2.startsWith("http://") || t2.startsWith("https://")) { const e3 = new URL(t2); n2 = e3.pathname + e3.search + e3.hash; } else n2 = t2; if (this.navigateFunction(n2), !(yield this.verifyNavigation(t2, n2, e2))) throw Error("React Router navigation verification failed - content may not have loaded"); } catch (n2) { yield this.fallbackToFullPageNavigation(t2); } }); } getCurrentUrl() { return window.location.origin + this.location.pathname + this.location.search + this.location.hash; } canHandle(t2) { try { return t2.startsWith("http://") || t2.startsWith("https://") ? new URL(t2).origin === window.location.origin : 1; } catch (e2) { return 0; } } updateLocation(t2) { this.location = t2; } capturePageState() { return { url: window.location.href, path: window.location.pathname + window.location.search + window.location.hash, title: document.title, bodyHash: this.generateContentHash(document.body), timestamp: Date.now() }; } generateContentHash(t2) { const e2 = t2.textContent || "", n2 = t2.querySelectorAll("*").length, i2 = t2.querySelectorAll("script").length, s2 = t2.querySelectorAll("a").length, o2 = "".concat(e2.length, "-").concat(n2, "-").concat(i2, "-").concat(s2); let a2 = 0; for (let r2 = 0; o2.length > r2; r2++) a2 = (a2 << 5) - a2 + o2.charCodeAt(r2), a2 &= a2; return "" + a2; } verifyNavigation(t2, e2, n2) { return __async(this, null, function* () { for (let s2 = 0; 25 > s2; s2++) { yield this.delay(250); const i3 = this.capturePageState(); if (this.checkUrlMatch(i3.url, i3.path, t2, e2)) { if (i3.bodyHash !== n2.bodyHash || i3.title !== n2.title || 3 > s2) return 1; if (s2 > 10 && (yield this.checkForReactContent(n2))) return 1; } } const i2 = this.capturePageState(); return this.checkUrlMatch(i2.url, i2.path, t2, e2) ? 1 : 0; }); } checkUrlMatch(t2, e2, n2, i2) { if (t2 === n2) return 1; if (e2 === i2) return 1; const s2 = (t3) => t3.replace(/\/+$/, "") || "/"; if (s2(e2) === s2(i2)) return 1; const o2 = e2.split("?")[0].split("#")[0], a2 = i2.split("?")[0].split("#")[0]; return s2(o2) === s2(a2) ? 1 : 0; } checkForReactContent(t2) { return __async(this, null, function* () { yield this.delay(500); const e2 = this.capturePageState(); return [e2.bodyHash !== t2.bodyHash, e2.title !== t2.title, !!document.querySelector("[data-reactroot]"), !!document.querySelector("#root"), !!window.React, !document.querySelector('.loading, .spinner, [data-loading="true"]'), !!document.querySelector('main, [role="main"], .main-content, #main, #content')].some((t3) => t3); }); } fallbackToFullPageNavigation(t2) { return __async(this, null, function* () { window.location.href = t2; }); } delay(t2) { return new Promise((e2) => setTimeout(e2, t2)); } } class p { constructor(t2) { this.router = t2, this.routerType = void 0 !== t2.asPath ? "pages" : "app"; } navigate(t2) { return __async(this, null, function* () { const e2 = this.capturePageState(); try { let n2; if (t2.startsWith("http://") || t2.startsWith("https://")) { const e3 = new URL(t2); n2 = e3.pathname + e3.search + e3.hash; } else n2 = t2; const i2 = this.router.push(n2); if (i2 && "function" == typeof i2.then && (yield i2), !(yield this.verifyNavigation(t2, n2, e2))) throw Error("Next.js navigation verification failed - content may not have loaded"); } catch (n2) { yield this.fallbackToFullPageNavigation(t2); } }); } getCurrentUrl() { return "pages" === this.routerType && this.router.asPath ? window.location.origin + this.router.asPath : window.location.href; } canHandle(t2) { try { return t2.startsWith("http://") || t2.startsWith("https://") ? new URL(t2).origin === window.location.origin : 1; } catch (e2) { return 0; } } capturePageState() { return { url: window.location.href, path: window.location.pathname + window.location.search + window.location.hash, title: document.title, bodyHash: this.generateContentHash(document.body), timestamp: Date.now() }; } generateContentHash(t2) { const e2 = t2.textContent || "", n2 = t2.querySelectorAll("*").length, i2 = t2.querySelectorAll("script").length, s2 = t2.querySelectorAll("a").length, o2 = "".concat(e2.length, "-").concat(n2, "-").concat(i2, "-").concat(s2); let a2 = 0; for (let r2 = 0; o2.length > r2; r2++) a2 = (a2 << 5) - a2 + o2.charCodeAt(r2), a2 &= a2; return "" + a2; } verifyNavigation(t2, e2, n2) { return __async(this, null, function* () { for (let s2 = 0; 25 > s2; s2++) { yield this.delay(250); const i3 = this.capturePageState(); if (this.checkUrlMatch(i3.url, i3.path, t2, e2)) { if (i3.bodyHash !== n2.bodyHash || i3.title !== n2.title || 3 > s2) return 1; if (s2 > 10 && (yield this.checkForNextjsContent(n2))) return 1; } } const i2 = this.capturePageState(); return this.checkUrlMatch(i2.url, i2.path, t2, e2) ? 1 : 0; }); } checkUrlMatch(t2, e2, n2, i2) { if (t2 === n2) return 1; if (e2 === i2) return 1; const s2 = (t3) => t3.replace(/\/+$/, "") || "/"; if (s2(e2) === s2(i2)) return 1; const o2 = e2.split("?")[0].split("#")[0], a2 = i2.split("?")[0].split("#")[0]; return s2(o2) === s2(a2) ? 1 : 0; } checkForNextjsContent(t2) { return __async(this, null, function* () { yield this.delay(500); const e2 = this.capturePageState(); return [e2.bodyHash !== t2.bodyHash, e2.title !== t2.title, !!document.querySelector("[data-nextjs-scroll-focus-boundary]"), !!document.querySelector("#__next"), !!window.__NEXT_DATA__, !document.querySelector('.loading, .spinner, [data-loading="true"]'), !!document.querySelector('main, [role="main"], .main-content, #main, #content')].some((t3) => t3); }); } fallbackToFullPageNavigation(t2) { return __async(this, null, function* () { window.location.href = t2; }); } delay(t2) { return new Promise((e2) => setTimeout(e2, t2)); } } class m { constructor() { this.detectedRouter = null, this.routerInstance = null, this.detectRouter(); } detectRouter() { const t2 = [{ name: "react-router-v6", detect: () => { var _a, _b; return !!window.__reactRouterVersion || document.querySelector("[data-react-router]") || window.React && document.querySelector("a[href]") && !((_b = (_a = document.querySelector("a[href]")) == null ? void 0 : _a.getAttribute("href")) == null ? void 0 : _b.startsWith("http")); }, getInstance: () => window.__reactRouter || window.router }, { name: "nextjs-pages", detect: () => { var _a; return !!window.__NEXT_DATA__ && !!((_a = window.next) == null ? void 0 : _a.router); }, getInstance: () => window.next.router }, { name: "nextjs-app", detect: () => { var _a; return !!window.__NEXT_DATA__ && !((_a = window.next) == null ? void 0 : _a.router); }, getInstance: () => null }, { name: "vue-router-v4", detect: () => !!window.__VUE__ || !!window.Vue || document.querySelector("[data-v-]") || !!window.$router, getInstance: () => window.$router || window.__vueRouter }, { name: "angular", detect: () => !!window.ng || document.querySelector("[ng-app]") || document.querySelector("app-root") || !!window.Zone, getInstance: () => { var _a, _b, _c; return (_c = (_b = (_a = window.ng) == null ? void 0 : _a.getComponent) == null ? void 0 : _b.call(_a, document.querySelector("app-root"))) == null ? void 0 : _c.router; } }, { name: "svelte", detect: () => document.querySelector("[data-sveltekit-hydrate]") || document.querySelector("#svelte") || !!window.__SVELTEKIT__, getInstance: () => { var _a; return ((_a = window.__sveltekit) == null ? void 0 : _a.router) || window.goto; } }, { name: "reach-router", detect: () => !!window.ReachRouter, getInstance: () => window.ReachRouter }, { name: "generic", detect: () => ["router", "$router", "Router", "__router__"].some((t3) => window[t3] && "function" == typeof window[t3].push), getInstance() { const t3 = ["router", "$router", "Router", "__router__"]; return t3.find((t4) => window[t4] && "function" == typeof window[t4].push) ? window[t3.find((t4) => window[t4] && "function" == typeof window[t4].push)] : null; } }]; for (const n2 of t2) try { if (n2.detect()) { this.detectedRouter = n2.name, this.routerInstance = n2.getInstance(); break; } } catch (e2) { } } navigate(t2) { return __async(this, null, function* () { const e2 = this.extractPath(t2), n2 = this.capturePageState(); try { switch (this.detectedRouter) { case "nextjs-pages": yield this.navigateNextjsPages(e2); break; case "nextjs-app": yield this.navigateNextjsApp(e2); break; case "vue-router-v4": yield this.navigateVueRouter(e2); break; case "angular": yield this.navigateAngular(e2); break; case "svelte": yield this.navigateSvelte(e2); break; case "react-router-v6": case "reach-router": case "generic": yield this.navigateGeneric(e2); break; default: throw Error("Navigation not supported for router: " + this.detectedRouter); } if (!(yield this.verifyNavigation(t2, e2, n2))) throw Error("Navigation verification failed - content may not have loaded"); } catch (i2) { yield this.fallbackToFullPageNavigation(t2); } }); } getCurrentUrl() { var _a, _b, _c, _d; switch (this.detectedRouter) { case "nextjs-pages": return window.location.origin + (((_a = this.routerInstance) == null ? void 0 : _a.asPath) || window.location.pathname); case "vue-router-v4": return window.location.origin + (((_d = (_c = (_b = this.routerInstance) == null ? void 0 : _b.currentRoute) == null ? void 0 : _c.value) == null ? void 0 : _d.fullPath) || window.location.pathname); default: return window.location.href; } } canHandle(t2) { if (!this.detectedRouter) return 0; try { return t2.startsWith("http://") || t2.startsWith("https://") ? new URL(t2).origin === window.location.origin : 1; } catch (e2) { return 0; } } extractPath(t2) { if (t2.startsWith("http://") || t2.startsWith("https://")) { const e2 = new URL(t2); return e2.pathname + e2.search + e2.hash; } return t2; } navigateNextjsPages(t2) { return __async(this, null, function* () { if (!this.routerInstance || "function" != typeof this.routerInstance.push) throw Error("Next.js Pages Router instance not available"); yield this.routerInstance.push(t2); }); } navigateNextjsApp(t2) { return __async(this, null, function* () { var _a; const e2 = window.__nextRouter || ((_a = window.next) == null ? void 0 : _a.router) || window.__NEXT_ROUTER__; e2 && "function" == typeof e2.push ? yield e2.push(t2) : (window.history.pushState({}, "", t2), window.dispatchEvent(new PopStateEvent("popstate"))); }); } navigateVueRouter(t2) { return __async(this, null, function* () { if (!this.routerInstance || "function" != typeof this.routerInstance.push) throw Error("Vue Router instance not available"); yield this.routerInstance.push(t2); }); } navigateAngular(t2) { return __async(this, null, function* () { var _a, _b, _c, _d; if (this.routerInstance && "function" == typeof this.routerInstance.navigate) yield this.routerInstance.navigate([t2]); else { const e2 = (_d = (_c = (_b = (_a = window.ng) == null ? void 0 : _a.getInjector) == null ? void 0 : _b.call(_a, document.body)) == null ? void 0 : _c.get) == null ? void 0 : _d.call(_c, "Router"); if (!e2 || "function" != typeof e2.navigate) throw Error("Angular Router instance not available"); yield e2.navigate([t2]); } }); } navigateSvelte(t2) { return __async(this, null, function* () { var _a; if ("function" == typeof this.routerInstance) yield this.routerInstance(t2); else if (this.routerInstance && "function" == typeof this.routerInstance.goto) yield this.routerInstance.goto(t2); else { const e2 = window.goto || ((_a = window.__sveltekit) == null ? void 0 : _a.goto); if ("function" != typeof e2) throw Error("Svelte navigation function not available"); yield e2(t2); } }); } navigateGeneric(t2) { return __async(this, null, function* () { if (!this.routerInstance) throw Error("Generic router instance not available"); if ("function" == typeof this.routerInstance.push) { const e2 = this.routerInstance.push(t2); e2 && "function" == typeof e2.then && (yield e2); } else { if ("function" != typeof this.routerInstance.navigate) throw Error("Generic router navigation method not found"); { const e2 = this.routerInstance.navigate(t2); e2 && "function" == typeof e2.then && (yield e2); } } }); } getRouterInfo() { return { type: this.detectedRouter, instance: this.routerInstance }; } redetectRouter() { this.detectedRouter = null, this.routerInstance = null, this.detectRouter(); } capturePageState() { return { url: window.location.href, path: window.location.pathname + window.location.search + window.location.hash, title: document.title, bodyHash: this.generateContentHash(document.body), timestamp: Date.now() }; } generateContentHash(t2) { const e2 = t2.textContent || "", n2 = t2.querySelectorAll("*").length, i2 = t2.querySelectorAll("script").length, s2 = t2.querySelectorAll("a").length, o2 = "".concat(e2.length, "-").concat(n2, "-").concat(i2, "-").concat(s2); let a2 = 0; for (let r2 = 0; o2.length > r2; r2++) a2 = (a2 << 5) - a2 + o2.charCodeAt(r2), a2 &= a2; return "" + a2; } verifyNavigation(t2, e2, n2) { return __async(this, null, function* () { for (let s2 = 0; 30 > s2; s2++) { yield this.delay(250); const i3 = this.capturePageState(); if (this.checkUrlMatch(i3.url, i3.path, t2, e2)) { if (i3.bodyHash !== n2.bodyHash || i3.title !== n2.title || 5 > s2) return 1; if (s2 > 15 && (yield this.checkForNewContent(n2))) return 1; } } const i2 = this.capturePageState(); return this.checkUrlMatch(i2.url, i2.path, t2, e2) ? 1 : 0; }); } checkUrlMatch(t2, e2, n2, i2) { if (t2 === n2) return 1; if (e2 === i2) return 1; const s2 = (t3) => t3.replace(/\/+$/, "") || "/"; if (s2(e2) === s2(i2)) return 1; const o2 = e2.split("?")[0].split("#")[0], a2 = i2.split("?")[0].split("#")[0]; return s2(o2) === s2(a2) ? 1 : 0; } checkForNewContent(t2) { return __async(this, null, function* () { yield this.delay(500); const e2 = this.capturePageState(); return [e2.bodyHash !== t2.bodyHash, e2.title !== t2.title, !document.querySelector('.loading, .spinner, [data-loading="true"]'), !!document.querySelector('main, [role="main"], .main-content, #main, #content'), this.checkFrameworkSpecificContent()].some((t3) => t3); }); } checkFrameworkSpecificContent() { switch (this.detectedRouter) { case "nextjs-pages": case "nextjs-app": return !!document.querySelector("[data-nextjs-scroll-focus-boundary]") || !!document.querySelector("#__next") || !!window.__NEXT_DATA__; case "vue-router-v4": return !!document.querySelector("[data-v-]") || !!document.querySelector("#app") || !!window.__VUE__; case "angular": return !!document.querySelector("app-root") || !!document.querySelector("[ng-version]") || !!window.ng; case "svelte": return !!document.querySelector("[data-sveltekit-hydrate]") || !!document.querySelector("#svelte") || !!window.__SVELTEKIT__; case "react-router-v6": return !!document.querySelector("[data-reactroot]") || !!document.querySelector("#root") || !!window.React; default: return 0; } } fallbackToFullPageNavigation(t2) { return __async(this, null, function* () { window.location.href = t2; }); } delay(t2) { return new Promise((e2) => setTimeout(e2, t2)); } } const f = Object.freeze({ __proto__: null, UniversalRouterAdapter: m }); let g = null; class SherpaSDK { constructor() { this.isInitialized = 0, this.cssResetApplied = 0, this.tourController = e.getInstance(), this.uiManager = w.getInstance(); } boot(t2, e2) { return __async(this, null, function* () { if (!this.isInitialized) try { (t2 == null ? void 0 : t2.key) && h({ serviceKey: t2.key }), (t2 == null ? void 0 : t2.applyCSSReset) && (u(), this.cssResetApplied = 1), this.isInitialized = 1, e2 && e2(), (t2 == null ? void 0 : t2.showSearch) && o.showSearch(), yield this.checkAndStartPendingTour(); } catch (n2) { throw n2; } }); } shutdown() { this.isInitialized && (this.uiManager.destroy(), o.hideSearch(), this.cssResetApplied && (d(), this.cssResetApplied = 0), this.isInitialized = 0); } startTour(t2, e2, n2) { return __async(this, null, function* () { if (!this.isInitialized) throw Error("SDK not initialized. Call boot() first."); return this.tourController.startTour(t2, e2, n2); }); } endTour() { return __async(this, null, function* () { return this.tourController.endTour(); }); } showSearch() { o.showSearch(); } hideSearch() { o.hideSearch(); } openDocs(t2, e2) { this.uiManager.openDocs(t2, e2); } closeDocs(t2) { this.uiManager.closeDocs(t2); } closeAllDocs() { this.uiManager.closeAllDocs(); } hasOpenDocs() { return this.uiManager.hasOpenDocs(); } track(t2, e2) { } updateUser(t2, e2) { } onTourStarted(t2) { } onTourEnded(t2) { } onStepChanged(t2) { } onSearchShown(t2) { } onSearchHidden(t2) { } clearCallbacks() { } checkAndStartPendingTour() { return __async(this, null, function* () { yield e.checkAndStartPendingTour(), yield this.checkUrlParametersForTour(); }); } checkUrlParametersForTour() { return __async(this, null, function* () { try { const t2 = new URLSearchParams(window.location.search), e2 = t2.get("sherpa") || t2.get("tour"); if (e2) { const [t3, n2 = "url-parameter"] = e2.split(":"); t3 && (yield this.startTour(t3, n2, { source: "url-parameter", originalUrl: window.location.href })); } } catch (t2) { } }); } getDebugInfo() { return { error: "Debug info not available in production" }; } } if ("undefined" != typeof window && window.Sherpa) { const e2 = window.Sherpa.q || []; window.Sherpa = t, e2.forEach((e3) => { try { t(...e3); } catch (n2) { } }); } export { p as N, l as R, SherpaSDK as S, w as U, m as a, f as u };