keystone-design-bootstrap 1.0.103 → 1.0.105-dev.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/README.md +4 -4
  2. package/dist/blog-post-vWzW8yFb.d.ts +50 -0
  3. package/dist/contexts/index.d.ts +13 -0
  4. package/dist/contexts/index.js +173 -0
  5. package/dist/contexts/index.js.map +1 -0
  6. package/dist/design_system/components/DynamicFormFields.d.ts +15 -0
  7. package/dist/design_system/components/DynamicFormFields.js +5176 -0
  8. package/dist/design_system/components/DynamicFormFields.js.map +1 -0
  9. package/dist/design_system/elements/index.d.ts +383 -0
  10. package/dist/design_system/elements/index.js +4007 -0
  11. package/dist/design_system/elements/index.js.map +1 -0
  12. package/dist/design_system/logo/keystone-logo.d.ts +6 -0
  13. package/dist/design_system/logo/keystone-logo.js +145 -0
  14. package/dist/design_system/logo/keystone-logo.js.map +1 -0
  15. package/dist/design_system/sections/index.d.ts +233 -0
  16. package/dist/design_system/sections/index.js +20048 -0
  17. package/dist/design_system/sections/index.js.map +1 -0
  18. package/dist/form-C94A_PX_.d.ts +36 -0
  19. package/dist/index.d.ts +86 -0
  20. package/dist/index.js +20646 -0
  21. package/dist/index.js.map +1 -0
  22. package/dist/lib/component-registry.d.ts +13 -0
  23. package/dist/lib/component-registry.js +36 -0
  24. package/dist/lib/component-registry.js.map +1 -0
  25. package/dist/lib/hooks/index.d.ts +83 -0
  26. package/dist/lib/hooks/index.js +182 -0
  27. package/dist/lib/hooks/index.js.map +1 -0
  28. package/dist/lib/server-api.d.ts +67 -0
  29. package/dist/lib/server-api.js +195 -0
  30. package/dist/lib/server-api.js.map +1 -0
  31. package/dist/package-DeHKpQp7.d.ts +121 -0
  32. package/dist/photos-CmBdWiuZ.d.ts +27 -0
  33. package/dist/themes/index.d.ts +17 -0
  34. package/dist/themes/index.js +29 -0
  35. package/dist/themes/index.js.map +1 -0
  36. package/dist/tracking/index.d.ts +254 -0
  37. package/dist/tracking/index.js +587 -0
  38. package/dist/tracking/index.js.map +1 -0
  39. package/dist/types/index.d.ts +313 -0
  40. package/dist/types/index.js +1 -0
  41. package/dist/types/index.js.map +1 -0
  42. package/dist/utils/cx.d.ts +15 -0
  43. package/dist/utils/cx.js +18 -0
  44. package/dist/utils/cx.js.map +1 -0
  45. package/dist/utils/gradient-placeholder.d.ts +7 -0
  46. package/dist/utils/gradient-placeholder.js +59 -0
  47. package/dist/utils/gradient-placeholder.js.map +1 -0
  48. package/dist/utils/is-react-component.d.ts +21 -0
  49. package/dist/utils/is-react-component.js +20 -0
  50. package/dist/utils/is-react-component.js.map +1 -0
  51. package/dist/utils/markdown-toc.d.ts +14 -0
  52. package/dist/utils/markdown-toc.js +29 -0
  53. package/dist/utils/markdown-toc.js.map +1 -0
  54. package/dist/utils/phone-helpers.d.ts +24 -0
  55. package/dist/utils/phone-helpers.js +26 -0
  56. package/dist/utils/phone-helpers.js.map +1 -0
  57. package/dist/utils/photo-helpers.d.ts +38 -0
  58. package/dist/utils/photo-helpers.js +41 -0
  59. package/dist/utils/photo-helpers.js.map +1 -0
  60. package/dist/website-photos-Cl1YqAno.d.ts +21 -0
  61. package/package.json +1 -1
  62. package/src/design_system/components/ChatWidget.tsx +66 -10
  63. package/src/design_system/portal/LoginForm.tsx +1 -24
  64. package/src/lib/chat-backend.ts +36 -0
  65. package/src/lib/consumer-session.ts +3 -1
  66. package/src/next/layouts/root-layout.tsx +5 -0
  67. package/src/next/routes/chat.ts +215 -18
  68. package/src/next/routes/consumer-auth.ts +49 -124
@@ -0,0 +1,587 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __defProps = Object.defineProperties;
3
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
4
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
7
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
8
+ var __spreadValues = (a, b) => {
9
+ for (var prop in b || (b = {}))
10
+ if (__hasOwnProp.call(b, prop))
11
+ __defNormalProp(a, prop, b[prop]);
12
+ if (__getOwnPropSymbols)
13
+ for (var prop of __getOwnPropSymbols(b)) {
14
+ if (__propIsEnum.call(b, prop))
15
+ __defNormalProp(a, prop, b[prop]);
16
+ }
17
+ return a;
18
+ };
19
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
20
+
21
+ // src/tracking/MetaPixel.tsx
22
+ import { useEffect } from "react";
23
+ import Script from "next/script";
24
+
25
+ // src/tracking/logging.ts
26
+ import { logs } from "@opentelemetry/api-logs";
27
+ import { OTLPLogExporter } from "@opentelemetry/exporter-logs-otlp-http";
28
+ import { resourceFromAttributes } from "@opentelemetry/resources";
29
+ import { BatchLogRecordProcessor, LoggerProvider } from "@opentelemetry/sdk-logs";
30
+ var BUILD_CONSOLE_DISABLED = process.env.NEXT_PUBLIC_LOGGING_DISABLED === "1";
31
+ var BUILD_POSTHOG_DISABLED = process.env.NEXT_PUBLIC_POSTHOG_LOGGING_DISABLED === "1";
32
+ var MAX_PENDING_POSTHOG_LOGS = 500;
33
+ var otelProvider = null;
34
+ var otelLogger = null;
35
+ var otelInitFingerprint = "";
36
+ var pendingPostHogLogs = [];
37
+ var browserConsole = globalThis == null ? void 0 : globalThis["console"];
38
+ var CHANNEL_COLORS = {
39
+ // Shared diagnostics
40
+ "global-client": "#d2a8ff",
41
+ // Section pins (desktop)
42
+ "every-channel-pin": "#9febd7",
43
+ "hero-pin": "#6ecc8b",
44
+ "pricing-pin": "#399587",
45
+ "product-screens-pin": "#4fafa0",
46
+ "social-proof-pin": "#ffbb8a",
47
+ "value-props-pin": "#e0a733",
48
+ "work-pin": "#f57e56",
49
+ // Section pins (mobile)
50
+ "mobile-every-channel-pin": "#7ed9c6",
51
+ "mobile-hero-pin": "#f0eee6",
52
+ "mobile-pricing-pin": "#80d4ff",
53
+ "mobile-product-screens-pin": "#3a9085",
54
+ "mobile-social-proof-pin": "#ffd580",
55
+ "mobile-value-props-pin": "#4fafa0"
56
+ };
57
+ function flattenAttributes(input, prefix = "") {
58
+ const output = {};
59
+ for (const [key, value] of Object.entries(input)) {
60
+ const nextKey = prefix ? `${prefix}.${key}` : key;
61
+ if (value === null || value === void 0) continue;
62
+ if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
63
+ output[nextKey] = value;
64
+ continue;
65
+ }
66
+ if (Array.isArray(value)) {
67
+ output[nextKey] = JSON.stringify(value);
68
+ continue;
69
+ }
70
+ if (typeof value === "object") {
71
+ Object.assign(output, flattenAttributes(value, nextKey));
72
+ continue;
73
+ }
74
+ output[nextKey] = String(value);
75
+ }
76
+ return output;
77
+ }
78
+ function stripTrailingSlash(host) {
79
+ return host.replace(/\/+$/, "");
80
+ }
81
+ function enqueuePendingPostHogLog(entry) {
82
+ if (pendingPostHogLogs.length >= MAX_PENDING_POSTHOG_LOGS) {
83
+ pendingPostHogLogs.shift();
84
+ }
85
+ pendingPostHogLogs.push(entry);
86
+ }
87
+ function flushPendingPostHogLogs() {
88
+ if (!otelLogger || pendingPostHogLogs.length === 0) return;
89
+ while (pendingPostHogLogs.length > 0) {
90
+ const entry = pendingPostHogLogs.shift();
91
+ if (!entry) break;
92
+ emitToPostHog(entry.level, entry.channel, entry.event, entry.detail);
93
+ }
94
+ }
95
+ function initializePostHogLogging(options) {
96
+ var _a, _b, _c, _d, _e, _f;
97
+ if (typeof window === "undefined") return;
98
+ if (!((_a = options.apiKey) == null ? void 0 : _a.trim())) return;
99
+ const apiHost = stripTrailingSlash(((_b = options.apiHost) == null ? void 0 : _b.trim()) || "https://us.i.posthog.com");
100
+ const serviceName = ((_c = options.serviceName) == null ? void 0 : _c.trim()) || "keystone-customer-site";
101
+ const environment = ((_d = options.environment) == null ? void 0 : _d.trim()) || "production";
102
+ const fingerprint = `${apiHost}|${options.apiKey}|${serviceName}|${environment}|${(_e = options.accountId) != null ? _e : ""}|${(_f = options.accountName) != null ? _f : ""}`;
103
+ if (otelLogger && otelInitFingerprint === fingerprint) return;
104
+ if (otelProvider) {
105
+ void otelProvider.shutdown().catch(() => {
106
+ });
107
+ otelProvider = null;
108
+ otelLogger = null;
109
+ }
110
+ const baseAttributes = {
111
+ "service.name": serviceName,
112
+ environment,
113
+ site_domain: window.location.hostname
114
+ };
115
+ if (options.accountId !== void 0) baseAttributes.account_id = options.accountId;
116
+ if (options.accountName) baseAttributes.account_name = options.accountName;
117
+ const exporter = new OTLPLogExporter({
118
+ url: `${apiHost}/i/v1/logs?token=${encodeURIComponent(options.apiKey)}`,
119
+ headers: {
120
+ // Keep request "simple" to avoid CORS preflight in browser.
121
+ "Content-Type": "text/plain"
122
+ }
123
+ });
124
+ otelProvider = new LoggerProvider({
125
+ resource: resourceFromAttributes(baseAttributes),
126
+ processors: [new BatchLogRecordProcessor(exporter)]
127
+ });
128
+ logs.setGlobalLoggerProvider(otelProvider);
129
+ otelLogger = logs.getLogger(serviceName);
130
+ otelInitFingerprint = fingerprint;
131
+ flushPendingPostHogLogs();
132
+ }
133
+ function isConsoleEnabled() {
134
+ if (BUILD_CONSOLE_DISABLED) return false;
135
+ if (typeof window === "undefined") return true;
136
+ return window.__loggingDisabled !== true;
137
+ }
138
+ function isPostHogShippingEnabled() {
139
+ if (BUILD_POSTHOG_DISABLED) return false;
140
+ if (typeof window === "undefined") return false;
141
+ return window.__posthogLoggingDisabled !== true;
142
+ }
143
+ function formatDetail(detail) {
144
+ return Object.entries(detail).map(([k, v]) => `${k}=${typeof v === "number" ? v.toFixed(4) : String(v)}`).join(" ");
145
+ }
146
+ function emitConsole(level, channel, event, detail) {
147
+ var _a, _b, _c, _d;
148
+ const color = (_a = CHANNEL_COLORS[channel]) != null ? _a : "#aaa";
149
+ const detailStr = formatDetail(detail);
150
+ const message = `%c[${channel}] %c${event}%c ${detailStr}`;
151
+ const channelStyle = `color:${color}; font-weight:bold`;
152
+ const eventStyle = level === "error" ? "color:#e94e4e; font-weight:bold" : level === "warn" ? "color:#f5a623; font-weight:bold" : "color:#fff; font-weight:bold";
153
+ const detailStyle = "color:#999; font-weight:normal";
154
+ if (level === "error") {
155
+ (_b = browserConsole == null ? void 0 : browserConsole.error) == null ? void 0 : _b.call(browserConsole, message, channelStyle, eventStyle, detailStyle);
156
+ return;
157
+ }
158
+ if (level === "warn") {
159
+ (_c = browserConsole == null ? void 0 : browserConsole.warn) == null ? void 0 : _c.call(browserConsole, message, channelStyle, eventStyle, detailStyle);
160
+ return;
161
+ }
162
+ (_d = browserConsole == null ? void 0 : browserConsole.log) == null ? void 0 : _d.call(browserConsole, message, channelStyle, eventStyle, detailStyle);
163
+ }
164
+ function emitToPostHog(level, channel, event, detail) {
165
+ if (!otelLogger) return false;
166
+ const severityText = level === "warn" ? "WARNING" : level === "error" ? "ERROR" : "INFO";
167
+ const attributes = flattenAttributes(__spreadValues({ channel }, detail));
168
+ otelLogger.emit({
169
+ severityText,
170
+ body: event,
171
+ attributes
172
+ });
173
+ return true;
174
+ }
175
+ function emit(level, channel, event, detail, options) {
176
+ var _a;
177
+ const shouldShip = ((_a = options == null ? void 0 : options.shipToPostHog) != null ? _a : level !== "info") && isPostHogShippingEnabled();
178
+ if (level !== "info" || isConsoleEnabled()) {
179
+ emitConsole(level, channel, event, detail);
180
+ }
181
+ if (shouldShip) {
182
+ const shipped = emitToPostHog(level, channel, event, detail);
183
+ if (!shipped) {
184
+ enqueuePendingPostHogLog({ level, channel, event, detail });
185
+ }
186
+ }
187
+ }
188
+ function log(channel, event, detail = {}, options) {
189
+ emit("info", channel, event, detail, options);
190
+ }
191
+ function warn(channel, event, detail = {}, options) {
192
+ emit("warn", channel, event, detail, options);
193
+ }
194
+ function error(channel, event, detail = {}, options) {
195
+ emit("error", channel, event, detail, options);
196
+ }
197
+
198
+ // src/tracking/firePixelEvent.ts
199
+ var STORAGE_KEY = "ks_pud";
200
+ async function sha256Hex(str) {
201
+ const buffer = await crypto.subtle.digest("SHA-256", new TextEncoder().encode(str));
202
+ return Array.from(new Uint8Array(buffer)).map((b) => b.toString(16).padStart(2, "0")).join("");
203
+ }
204
+ function getFbq() {
205
+ if (typeof window === "undefined") return void 0;
206
+ return window.fbq;
207
+ }
208
+ function getRegisteredPixelIds() {
209
+ var _a;
210
+ return (_a = window.__ks_pixel_ids) != null ? _a : [];
211
+ }
212
+ function applyStoredUserData(fbq) {
213
+ try {
214
+ const raw = sessionStorage.getItem(STORAGE_KEY);
215
+ if (!raw) return;
216
+ const hashed = JSON.parse(raw);
217
+ if (Object.keys(hashed).length === 0) return;
218
+ getRegisteredPixelIds().forEach((id) => fbq("init", id, hashed));
219
+ } catch (e) {
220
+ }
221
+ }
222
+ async function setPixelUserData(userData) {
223
+ const hashed = {};
224
+ if (userData.email) {
225
+ hashed.em = await sha256Hex(userData.email.trim().toLowerCase());
226
+ }
227
+ if (userData.phone) {
228
+ const digits = userData.phone.replace(/\D/g, "");
229
+ if (digits) hashed.ph = await sha256Hex(digits);
230
+ }
231
+ if (Object.keys(hashed).length === 0) return;
232
+ try {
233
+ sessionStorage.setItem(STORAGE_KEY, JSON.stringify(hashed));
234
+ } catch (e) {
235
+ }
236
+ const fbq = getFbq();
237
+ if (fbq) {
238
+ getRegisteredPixelIds().forEach((id) => fbq("init", id, hashed));
239
+ }
240
+ }
241
+ function firePixelEvent(event, params, eventId) {
242
+ const fbq = getFbq();
243
+ if (!fbq) {
244
+ warn("meta-pixel", "PIXEL_EVENT_SKIPPED_FBQ_NOT_LOADED", { event });
245
+ return;
246
+ }
247
+ applyStoredUserData(fbq);
248
+ const normalized = {};
249
+ if (params == null ? void 0 : params.contentName) normalized.content_name = params.contentName;
250
+ if (params == null ? void 0 : params.contentCategory) normalized.content_category = params.contentCategory;
251
+ const customData = Object.keys(normalized).length > 0 ? normalized : void 0;
252
+ const eventData = eventId ? { eventID: eventId } : void 0;
253
+ log("meta-pixel", "PIXEL_EVENT_FIRED", __spreadValues(__spreadValues({
254
+ event
255
+ }, normalized), eventId ? { eventId } : {}), { shipToPostHog: true });
256
+ fbq("track", event, customData, eventData);
257
+ }
258
+
259
+ // src/tracking/MetaPixel.tsx
260
+ var FBEVENTS_URL = "https://connect.facebook.net/en_US/fbevents.js";
261
+ var PIXEL_SCRIPT = (pixelId) => `
262
+ !function(f,b,e,v,n,t,s)
263
+ {if(f.fbq)return;n=f.fbq=function(){n.callMethod?
264
+ n.callMethod.apply(n,arguments):n.queue.push(arguments)};
265
+ if(!f._fbq)f._fbq=n;n.push=n;n.loaded=!0;n.version='2.0';
266
+ n.queue=[];t=b.createElement(e);t.async=!0;
267
+ t.src=v;s=b.getElementsByTagName(e)[0];
268
+ s.parentNode.insertBefore(t,s)}(window, document,'script','${FBEVENTS_URL}');
269
+ fbq('init', '${pixelId.replace(/'/g, "\\'")}');
270
+ window.__ks_pixel_ids = window.__ks_pixel_ids || [];
271
+ if (window.__ks_pixel_ids.indexOf('${pixelId.replace(/'/g, "\\'")}') === -1) {
272
+ window.__ks_pixel_ids.push('${pixelId.replace(/'/g, "\\'")}');
273
+ }
274
+ `;
275
+ function MetaPixel({ pixelId }) {
276
+ const raw = typeof pixelId === "string" ? pixelId.trim() : "";
277
+ const id = raw && raw !== "null" && /^\d+$/.test(raw) ? raw : "";
278
+ useEffect(() => {
279
+ if (!id) return;
280
+ log("meta-pixel", "PIXEL_INIT", { pixelId: id }, { shipToPostHog: true });
281
+ firePixelEvent("PageView");
282
+ }, [id]);
283
+ if (!id) {
284
+ return null;
285
+ }
286
+ return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(
287
+ Script,
288
+ {
289
+ id: "meta-pixel",
290
+ strategy: "afterInteractive",
291
+ dangerouslySetInnerHTML: { __html: PIXEL_SCRIPT(id) }
292
+ }
293
+ ), /* @__PURE__ */ React.createElement("noscript", null, /* @__PURE__ */ React.createElement(
294
+ "img",
295
+ {
296
+ height: 1,
297
+ width: 1,
298
+ style: { display: "none" },
299
+ src: `https://www.facebook.com/tr?id=${id}&ev=PageView&noscript=1`,
300
+ alt: ""
301
+ }
302
+ )));
303
+ }
304
+
305
+ // src/tracking/MetaPixelTracker.tsx
306
+ import { useEffect as useEffect2 } from "react";
307
+ import { usePathname } from "next/navigation";
308
+ function slugToTitle(slug) {
309
+ return slug.split("-").map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
310
+ }
311
+ var ROUTE_RULES = [
312
+ {
313
+ pattern: /^\/services\/(.+)$/,
314
+ getParams: ([, slug]) => ({ contentName: slugToTitle(slug), contentCategory: "Service" })
315
+ },
316
+ {
317
+ pattern: /^\/locations\/(.+)$/,
318
+ getParams: ([, slug]) => ({ contentName: slugToTitle(slug), contentCategory: "Location" })
319
+ },
320
+ {
321
+ pattern: /^\/services$/,
322
+ getParams: () => ({ contentName: "Services", contentCategory: "Services" })
323
+ },
324
+ {
325
+ pattern: /^\/locations$/,
326
+ getParams: () => ({ contentName: "Locations", contentCategory: "Locations" })
327
+ },
328
+ {
329
+ pattern: /^\/portal$/,
330
+ getParams: () => ({ contentName: "Member Portal", contentCategory: "Pricing" })
331
+ },
332
+ {
333
+ pattern: /^\/service-menu$/,
334
+ getParams: () => ({ contentName: "Service Menu", contentCategory: "Pricing" })
335
+ },
336
+ {
337
+ pattern: /^\/faq$/,
338
+ getParams: () => ({ contentName: "FAQ", contentCategory: "FAQ" })
339
+ },
340
+ {
341
+ pattern: /^\/contact$/,
342
+ getParams: () => ({ contentName: "Contact", contentCategory: "Contact" })
343
+ }
344
+ ];
345
+ function MetaPixelTracker({ bookingUrl }) {
346
+ const pathname = usePathname();
347
+ useEffect2(() => {
348
+ for (const rule of ROUTE_RULES) {
349
+ const match = pathname.match(rule.pattern);
350
+ if (match) {
351
+ const { contentName, contentCategory } = rule.getParams(match);
352
+ firePixelEvent("ViewContent", { contentName, contentCategory });
353
+ break;
354
+ }
355
+ }
356
+ }, [pathname]);
357
+ useEffect2(() => {
358
+ if (!bookingUrl) return;
359
+ const handleClick = (e) => {
360
+ var _a;
361
+ const anchor = e.target.closest("a");
362
+ if ((_a = anchor == null ? void 0 : anchor.href) == null ? void 0 : _a.startsWith(bookingUrl)) {
363
+ firePixelEvent("InitiateCheckout");
364
+ }
365
+ };
366
+ document.addEventListener("click", handleClick);
367
+ return () => document.removeEventListener("click", handleClick);
368
+ }, [bookingUrl]);
369
+ return null;
370
+ }
371
+
372
+ // src/tracking/PostHogProvider.tsx
373
+ import posthog from "posthog-js";
374
+ import { PostHogProvider as PHProvider } from "posthog-js/react";
375
+ import { useEffect as useEffect3, Suspense, useRef } from "react";
376
+ import { usePathname as usePathname2, useSearchParams } from "next/navigation";
377
+ var DEFAULT_HOST = "https://us.i.posthog.com";
378
+ function resolvePageInfo(pathname) {
379
+ var _a;
380
+ if (pathname === "/") return { page_name: "home" };
381
+ const patterns = [
382
+ [/^\/services\/(.+)$/, ([, slug]) => ({ page_name: "service_detail", page_slug: slug })],
383
+ [/^\/locations\/(.+)$/, ([, slug]) => ({ page_name: "location_detail", page_slug: slug })],
384
+ [/^\/blog\/(.+)$/, ([, slug]) => ({ page_name: "blog_post", page_slug: slug })],
385
+ [/^\/jobs\/(.+)$/, ([, slug]) => ({ page_name: "job_detail", page_slug: slug })],
386
+ [/^\/packages\/(.+)$/, ([, slug]) => ({ page_name: "package_detail", page_slug: slug })]
387
+ ];
388
+ for (const [pattern, resolve] of patterns) {
389
+ const match = pathname.match(pattern);
390
+ if (match) return resolve(match);
391
+ }
392
+ const staticNames = {
393
+ "/services": "services",
394
+ "/locations": "locations",
395
+ "/contact": "contact",
396
+ "/about": "about",
397
+ "/blog": "blog",
398
+ "/portal": "portal",
399
+ "/gallery": "gallery",
400
+ "/team": "team",
401
+ "/faq": "faq",
402
+ "/reviews": "reviews",
403
+ "/jobs": "jobs",
404
+ "/packages": "packages",
405
+ "/service-menu": "service_menu",
406
+ "/privacy-policy": "privacy_policy",
407
+ "/terms": "terms_of_service"
408
+ };
409
+ return { page_name: (_a = staticNames[pathname]) != null ? _a : "unknown" };
410
+ }
411
+ function PostHogPageviewTracker() {
412
+ const pathname = usePathname2();
413
+ const searchParams = useSearchParams();
414
+ const latestUrlRef = useRef(null);
415
+ useEffect3(() => {
416
+ if (!pathname) return;
417
+ const search = searchParams == null ? void 0 : searchParams.toString();
418
+ const url = window.location.origin + pathname + (search ? `?${search}` : "");
419
+ const previousUrl = latestUrlRef.current;
420
+ if (previousUrl && previousUrl !== url) {
421
+ const previousPath = (() => {
422
+ try {
423
+ return new URL(previousUrl).pathname;
424
+ } catch (e) {
425
+ return pathname;
426
+ }
427
+ })();
428
+ posthog.capture("$pageleave", {
429
+ $current_url: previousUrl,
430
+ page_path: previousPath
431
+ });
432
+ }
433
+ latestUrlRef.current = url;
434
+ const { page_name, page_slug } = resolvePageInfo(pathname);
435
+ posthog.capture("$pageview", __spreadValues({
436
+ $current_url: url,
437
+ page_name,
438
+ page_path: pathname
439
+ }, page_slug && { page_slug }));
440
+ }, [pathname, searchParams]);
441
+ useEffect3(() => {
442
+ const onPageHide = () => {
443
+ const currentUrl = latestUrlRef.current;
444
+ if (!currentUrl) return;
445
+ const currentPath = (() => {
446
+ try {
447
+ return new URL(currentUrl).pathname;
448
+ } catch (e) {
449
+ return window.location.pathname;
450
+ }
451
+ })();
452
+ posthog.capture("$pageleave", {
453
+ $current_url: currentUrl,
454
+ page_path: currentPath
455
+ });
456
+ };
457
+ window.addEventListener("pagehide", onPageHide);
458
+ return () => {
459
+ window.removeEventListener("pagehide", onPageHide);
460
+ };
461
+ }, []);
462
+ return null;
463
+ }
464
+ function PostHogProvider({ apiKey, apiHost, accountId, accountName, environment, children }) {
465
+ useEffect3(() => {
466
+ posthog.init(apiKey, {
467
+ api_host: apiHost != null ? apiHost : DEFAULT_HOST,
468
+ person_profiles: "identified_only",
469
+ capture_pageview: false
470
+ });
471
+ posthog.register(__spreadProps(__spreadValues(__spreadValues(__spreadValues({}, accountId !== void 0 && { account_id: accountId }), accountName && { account_name: accountName }), environment && { environment }), {
472
+ site_domain: window.location.hostname
473
+ }));
474
+ initializePostHogLogging({
475
+ apiKey,
476
+ apiHost: apiHost != null ? apiHost : DEFAULT_HOST,
477
+ serviceName: "keystone-customer-site",
478
+ environment,
479
+ accountId,
480
+ accountName
481
+ });
482
+ }, [apiKey, apiHost, accountId, accountName, environment]);
483
+ useEffect3(() => {
484
+ const onWindowError = (event) => {
485
+ error(
486
+ "global-client",
487
+ "WINDOW_ERROR",
488
+ {
489
+ message: event.message || "unknown_error",
490
+ filename: event.filename || "unknown_file",
491
+ lineno: event.lineno || 0,
492
+ colno: event.colno || 0,
493
+ stack: event.error instanceof Error ? event.error.stack || "" : ""
494
+ },
495
+ { shipToPostHog: true }
496
+ );
497
+ };
498
+ const onUnhandledRejection = (event) => {
499
+ const reason = event.reason;
500
+ const payload = reason instanceof Error ? { message: reason.message, stack: reason.stack || "" } : { message: String(reason), stack: "" };
501
+ error("global-client", "UNHANDLED_REJECTION", payload, { shipToPostHog: true });
502
+ };
503
+ window.addEventListener("error", onWindowError);
504
+ window.addEventListener("unhandledrejection", onUnhandledRejection);
505
+ return () => {
506
+ window.removeEventListener("error", onWindowError);
507
+ window.removeEventListener("unhandledrejection", onUnhandledRejection);
508
+ };
509
+ }, []);
510
+ return /* @__PURE__ */ React.createElement(PHProvider, { client: posthog }, /* @__PURE__ */ React.createElement(Suspense, { fallback: null }, /* @__PURE__ */ React.createElement(PostHogPageviewTracker, null)), children);
511
+ }
512
+
513
+ // src/tracking/KeystoneAnalyticsTracker.tsx
514
+ import { useEffect as useEffect4 } from "react";
515
+ import { usePathname as usePathname3 } from "next/navigation";
516
+
517
+ // src/tracking/captureEvent.ts
518
+ import posthog2 from "posthog-js";
519
+ function captureEvent(event, ...args) {
520
+ posthog2.capture(event, args[0]);
521
+ }
522
+ function captureCustomEvent(event, properties) {
523
+ posthog2.capture(event, properties);
524
+ }
525
+
526
+ // src/tracking/KeystoneAnalyticsTracker.tsx
527
+ function KeystoneAnalyticsTracker({ bookingUrl }) {
528
+ const pathname = usePathname3();
529
+ useEffect4(() => {
530
+ if (!bookingUrl) return;
531
+ const handleClick = (e) => {
532
+ var _a;
533
+ const anchor = e.target.closest("a");
534
+ if ((_a = anchor == null ? void 0 : anchor.href) == null ? void 0 : _a.startsWith(bookingUrl)) {
535
+ captureEvent("booking_cta_clicked", {
536
+ source_path: pathname,
537
+ booking_url: bookingUrl
538
+ });
539
+ }
540
+ };
541
+ document.addEventListener("click", handleClick);
542
+ return () => document.removeEventListener("click", handleClick);
543
+ }, [bookingUrl, pathname]);
544
+ return null;
545
+ }
546
+
547
+ // src/tracking/GoogleTagManager.tsx
548
+ var GTM_SCRIPT = (containerId) => `
549
+ (function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
550
+ new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
551
+ j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
552
+ 'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
553
+ })(window,document,'script','dataLayer','${containerId.replace(/'/g, "\\'")}');
554
+ `;
555
+ function GoogleTagManager({ containerId }) {
556
+ const raw = typeof containerId === "string" ? containerId.trim() : "";
557
+ const id = raw && raw !== "null" && /^GTM-[A-Z0-9]+$/i.test(raw) ? raw : "";
558
+ if (!id) {
559
+ return null;
560
+ }
561
+ return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("script", { id: "google-tag-manager", dangerouslySetInnerHTML: { __html: GTM_SCRIPT(id) } }), /* @__PURE__ */ React.createElement("noscript", null, /* @__PURE__ */ React.createElement(
562
+ "iframe",
563
+ {
564
+ src: `https://www.googletagmanager.com/ns.html?id=${id}`,
565
+ height: "0",
566
+ width: "0",
567
+ style: { display: "none", visibility: "hidden" },
568
+ title: "google-tag-manager"
569
+ }
570
+ )));
571
+ }
572
+ export {
573
+ CHANNEL_COLORS,
574
+ GoogleTagManager,
575
+ KeystoneAnalyticsTracker,
576
+ MetaPixel,
577
+ MetaPixelTracker,
578
+ PostHogProvider,
579
+ captureCustomEvent,
580
+ captureEvent,
581
+ error,
582
+ firePixelEvent,
583
+ log,
584
+ setPixelUserData,
585
+ warn
586
+ };
587
+ //# sourceMappingURL=index.js.map