@uptrademedia/site-kit 1.1.5 → 1.1.7

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 (48) hide show
  1. package/dist/{chunk-YT74LIC4.js → chunk-CTKXFLIF.js} +169 -46
  2. package/dist/chunk-CTKXFLIF.js.map +1 -0
  3. package/dist/{chunk-TGX5Q6UK.js → chunk-FR6DV5QX.js} +36 -27
  4. package/dist/chunk-FR6DV5QX.js.map +1 -0
  5. package/dist/{chunk-NNKC3X7O.mjs → chunk-IARDGI5N.mjs} +36 -27
  6. package/dist/chunk-IARDGI5N.mjs.map +1 -0
  7. package/dist/{chunk-DUH5S5MV.mjs → chunk-TOUIKTXU.mjs} +169 -46
  8. package/dist/chunk-TOUIKTXU.mjs.map +1 -0
  9. package/dist/cli/index.js +331 -800
  10. package/dist/cli/index.js.map +1 -1
  11. package/dist/cli/index.mjs +325 -792
  12. package/dist/cli/index.mjs.map +1 -1
  13. package/dist/commerce/index.d.mts +3 -3
  14. package/dist/commerce/index.d.ts +3 -3
  15. package/dist/commerce/index.js +42 -42
  16. package/dist/commerce/index.mjs +1 -1
  17. package/dist/commerce/server.d.mts +1 -1
  18. package/dist/commerce/server.d.ts +1 -1
  19. package/dist/engage/index.d.mts +3 -1
  20. package/dist/engage/index.d.ts +3 -1
  21. package/dist/engage/index.js +4 -4
  22. package/dist/engage/index.mjs +1 -1
  23. package/dist/index.d.mts +2 -2
  24. package/dist/index.d.ts +2 -2
  25. package/dist/index.js +32 -29
  26. package/dist/index.js.map +1 -1
  27. package/dist/index.mjs +7 -4
  28. package/dist/index.mjs.map +1 -1
  29. package/dist/seo/index.d.mts +1 -1
  30. package/dist/seo/index.d.ts +1 -1
  31. package/dist/seo/index.js +0 -3
  32. package/dist/seo/index.js.map +1 -1
  33. package/dist/seo/index.mjs +1 -1
  34. package/dist/sitemap/index.d.mts +1 -1
  35. package/dist/sitemap/index.d.ts +1 -1
  36. package/dist/sitemap/index.js +0 -4
  37. package/dist/sitemap/index.js.map +1 -1
  38. package/dist/sitemap/index.mjs +1 -2
  39. package/dist/sitemap/index.mjs.map +1 -1
  40. package/dist/{types-Dz2HtHds.d.mts → types-DxhEH2tX.d.mts} +3 -0
  41. package/dist/{types-Dz2HtHds.d.ts → types-DxhEH2tX.d.ts} +3 -0
  42. package/dist/{useEventModal-TppA_tfZ.d.ts → useEventModal-5fIKdIaY.d.ts} +1 -1
  43. package/dist/{useEventModal-cZr3PMWl.d.mts → useEventModal-x_RZRewW.d.mts} +1 -1
  44. package/package.json +39 -39
  45. package/dist/chunk-DUH5S5MV.mjs.map +0 -1
  46. package/dist/chunk-NNKC3X7O.mjs.map +0 -1
  47. package/dist/chunk-TGX5Q6UK.js.map +0 -1
  48. package/dist/chunk-YT74LIC4.js.map +0 -1
@@ -10,9 +10,13 @@ var React2__default = /*#__PURE__*/_interopDefault(React2);
10
10
 
11
11
  // src/engage/ChatWidget.tsx
12
12
  function getApiConfig() {
13
- const apiUrl = typeof window !== "undefined" ? window.__SITE_KIT_API_URL__ || "https://api.uptrademedia.com" : "https://api.uptrademedia.com";
13
+ const isDev = typeof process !== "undefined" && process.env?.NODE_ENV === "development";
14
+ const defaultApiUrl = isDev && process.env?.NEXT_PUBLIC_UPTRADE_API_URL ? process.env.NEXT_PUBLIC_UPTRADE_API_URL : "https://api.uptrademedia.com";
15
+ const defaultSignalUrl = isDev && process.env?.NEXT_PUBLIC_SIGNAL_API_URL ? process.env.NEXT_PUBLIC_SIGNAL_API_URL : "https://signal.uptrademedia.com";
16
+ const apiUrl = typeof window !== "undefined" ? window.__SITE_KIT_API_URL__ || defaultApiUrl : defaultApiUrl;
14
17
  const apiKey = typeof window !== "undefined" ? window.__SITE_KIT_API_KEY__ : void 0;
15
- return { apiUrl, apiKey };
18
+ const signalUrl = typeof window !== "undefined" ? window.__SITE_KIT_SIGNAL_URL__ || defaultSignalUrl : defaultSignalUrl;
19
+ return { apiUrl, apiKey, signalUrl };
16
20
  }
17
21
  function generateVisitorId() {
18
22
  const stored = typeof localStorage !== "undefined" ? localStorage.getItem("engage_visitor_id") : null;
@@ -35,7 +39,7 @@ function isLightColor(hex) {
35
39
  const b = num & 255;
36
40
  return (r * 299 + g * 587 + b * 114) / 1e3 > 160;
37
41
  }
38
- function ChatWidget({ projectId: propProjectId, config, apiUrl: propApiUrl }) {
42
+ function ChatWidget({ projectId: propProjectId, config, apiUrl: propApiUrl, signalUrl: propSignalUrl }) {
39
43
  const [resolvedProjectId, setResolvedProjectId] = React2.useState(propProjectId || null);
40
44
  const projectId = propProjectId || resolvedProjectId || "";
41
45
  const [isOpen, setIsOpen] = React2.useState(false);
@@ -56,6 +60,7 @@ function ChatWidget({ projectId: propProjectId, config, apiUrl: propApiUrl }) {
56
60
  const [lastFailedSend, setLastFailedSend] = React2.useState(null);
57
61
  const [showWelcome, setShowWelcome] = React2.useState(true);
58
62
  const [checkingAvailability, setCheckingAvailability] = React2.useState(false);
63
+ const [checkingHandoff, setCheckingHandoff] = React2.useState(false);
59
64
  React2.useRef(null);
60
65
  const pendingInitialMessageRef = React2.useRef(null);
61
66
  const apiKeyMissingWarnedRef = React2.useRef(false);
@@ -83,6 +88,7 @@ function ChatWidget({ projectId: propProjectId, config, apiUrl: propApiUrl }) {
83
88
  const offlineHeading = widgetConfig?.offline_heading ?? "No agents available right now";
84
89
  const offlineSubheading = handoffOfflinePrompt ?? widgetConfig?.offline_subheading ?? widgetConfig?.form_description ?? widgetConfig?.offline_message ?? config?.offlineMessage ?? "Leave us a message and we'll get back to you!";
85
90
  const baseUrl = propApiUrl || getApiConfig().apiUrl;
91
+ const signalUrl = propSignalUrl || getApiConfig().signalUrl;
86
92
  React2.useEffect(() => {
87
93
  if (propProjectId || resolvedProjectId) return;
88
94
  const { apiKey } = getApiConfig();
@@ -153,11 +159,14 @@ function ChatWidget({ projectId: propProjectId, config, apiUrl: propApiUrl }) {
153
159
  });
154
160
  if (response.ok) {
155
161
  const { data } = await response.json();
156
- const sid = data.id || data.session_id;
162
+ const session = data.session ?? data;
163
+ const sid = session?.id ?? session?.session_id ?? data.id ?? data.session_id;
164
+ const signalEnabled = session?.chat_mode === "ai" || session?.chat_mode === "hybrid";
157
165
  setSessionId(sid);
158
- if (data.messages?.length > 0) {
166
+ const messages2 = session?.messages ?? data.messages ?? [];
167
+ if (messages2.length > 0) {
159
168
  setMessages(
160
- data.messages.map((m) => ({
169
+ messages2.map((m) => ({
161
170
  id: m.id,
162
171
  role: m.role === "visitor" ? "user" : m.role,
163
172
  content: m.content,
@@ -166,13 +175,40 @@ function ChatWidget({ projectId: propProjectId, config, apiUrl: propApiUrl }) {
166
175
  }))
167
176
  );
168
177
  }
169
- return sid;
178
+ return { id: sid, signalEnabled };
170
179
  }
171
180
  } catch (error) {
172
181
  console.error("[ChatWidget] Session init failed:", error);
173
182
  }
174
183
  return null;
175
184
  }, [projectId, visitorId, baseUrl]);
185
+ const sendToSignalApi = React2.useCallback(
186
+ async (content, conversationId) => {
187
+ const url = `${signalUrl.replace(/\/$/, "")}/echo/public/chat`;
188
+ const body = {
189
+ message: content,
190
+ projectId,
191
+ visitorId,
192
+ ...conversationId ? { conversationId } : {},
193
+ pageUrl: typeof window !== "undefined" ? window.location.href : void 0
194
+ };
195
+ const res = await fetch(url, {
196
+ method: "POST",
197
+ headers: { "Content-Type": "application/json" },
198
+ body: JSON.stringify(body)
199
+ });
200
+ const json = await res.json();
201
+ if (!res.ok) {
202
+ throw new Error(json?.error?.message || json?.message || `Signal API error: ${res.status}`);
203
+ }
204
+ const data = json?.data ?? json;
205
+ const aiContent = data?.content ?? data?.response ?? data?.message ?? "I'm sorry, I couldn't process that.";
206
+ const suggestions = data?.suggestions;
207
+ const newConversationId = data?.conversationId ?? conversationId;
208
+ return { content: aiContent, suggestions, conversationId: newConversationId };
209
+ },
210
+ [signalUrl, projectId, visitorId]
211
+ );
176
212
  const handleSocketMessage = React2.useCallback((data) => {
177
213
  switch (data.type || data.event) {
178
214
  case "message": {
@@ -361,13 +397,50 @@ function ChatWidget({ projectId: propProjectId, config, apiUrl: propApiUrl }) {
361
397
  }, [fetchWidgetConfig, checkAvailability]);
362
398
  React2.useEffect(() => {
363
399
  if (isOpen && !showWelcome && !checkingAvailability && !showOfflineForm && !sessionId) {
364
- initSession().then(async (id) => {
365
- if (!id) return;
366
- setConnectionStatus("connecting");
367
- await connectSocket(id);
400
+ initSession().then(async (result) => {
401
+ if (!result?.id) return;
402
+ const { id, signalEnabled } = result;
368
403
  const pending = pendingInitialMessageRef.current;
369
404
  if (pending) {
370
405
  pendingInitialMessageRef.current = null;
406
+ }
407
+ if (signalEnabled && pending) {
408
+ setIsLoading(true);
409
+ setMessages((prev) => [
410
+ ...prev,
411
+ { id: `u-${Date.now()}`, role: "user", content: pending, timestamp: /* @__PURE__ */ new Date() }
412
+ ]);
413
+ try {
414
+ const { content: aiContent, suggestions } = await sendToSignalApi(pending, id);
415
+ setMessages((prev) => [
416
+ ...prev,
417
+ {
418
+ id: `ai-${Date.now()}`,
419
+ role: "assistant",
420
+ content: aiContent,
421
+ timestamp: /* @__PURE__ */ new Date(),
422
+ ...suggestions?.length ? { suggestions } : {}
423
+ }
424
+ ]);
425
+ } catch (err) {
426
+ console.error("[ChatWidget] Signal API error:", err);
427
+ setMessages((prev) => [
428
+ ...prev,
429
+ {
430
+ id: `err-${Date.now()}`,
431
+ role: "assistant",
432
+ content: "I apologize, but I encountered an error. Would you like to speak with a team member?",
433
+ timestamp: /* @__PURE__ */ new Date(),
434
+ suggestions: ["Talk to a person", "Try again"]
435
+ }
436
+ ]);
437
+ } finally {
438
+ setIsLoading(false);
439
+ }
440
+ }
441
+ setConnectionStatus("connecting");
442
+ await connectSocket(id);
443
+ if (!signalEnabled && pending) {
371
444
  const waitForSocket = () => new Promise((resolve) => {
372
445
  const check = (attempts = 0) => {
373
446
  if (socketRef.current?.connected || attempts > 20) {
@@ -388,7 +461,7 @@ function ChatWidget({ projectId: propProjectId, config, apiUrl: propApiUrl }) {
388
461
  return () => {
389
462
  if (pollingIntervalRef.current) clearInterval(pollingIntervalRef.current);
390
463
  };
391
- }, [isOpen, showWelcome, checkingAvailability, showOfflineForm, sessionId, initSession, connectSocket]);
464
+ }, [isOpen, showWelcome, checkingAvailability, showOfflineForm, sessionId, initSession, connectSocket, sendToSignalApi]);
392
465
  const handleToggle = React2.useCallback(() => {
393
466
  setIsOpen((prev) => !prev);
394
467
  }, []);
@@ -478,6 +551,36 @@ function ChatWidget({ projectId: propProjectId, config, apiUrl: propApiUrl }) {
478
551
  setMessages((prev) => [...prev, userMessage]);
479
552
  setInputValue("");
480
553
  setIsLoading(true);
554
+ if (widgetConfig?.signal_enabled && hasText) {
555
+ try {
556
+ const { content: aiContent, suggestions } = await sendToSignalApi(content, sessionId);
557
+ setMessages((prev) => [
558
+ ...prev,
559
+ {
560
+ id: `ai-${Date.now()}`,
561
+ role: "assistant",
562
+ content: aiContent,
563
+ timestamp: /* @__PURE__ */ new Date(),
564
+ ...suggestions?.length ? { suggestions } : {}
565
+ }
566
+ ]);
567
+ } catch (err) {
568
+ console.error("[ChatWidget] Signal API error:", err);
569
+ setMessages((prev) => [
570
+ ...prev,
571
+ {
572
+ id: `err-${Date.now()}`,
573
+ role: "assistant",
574
+ content: "I apologize, but I encountered an error. Would you like to speak with a team member?",
575
+ timestamp: /* @__PURE__ */ new Date(),
576
+ suggestions: ["Talk to a person", "Try again"]
577
+ }
578
+ ]);
579
+ } finally {
580
+ setIsLoading(false);
581
+ }
582
+ return;
583
+ }
481
584
  const socket = socketRef.current;
482
585
  if (socket?.connected) {
483
586
  socket.emit("visitor:message", { content: userMessage.content, attachments: attachments.length ? attachments : void 0 });
@@ -495,7 +598,7 @@ function ChatWidget({ projectId: propProjectId, config, apiUrl: propApiUrl }) {
495
598
  }
496
599
  }, 3e3);
497
600
  },
498
- [inputValue, isLoading, pendingFiles, uploadWidgetFile]
601
+ [inputValue, isLoading, pendingFiles, uploadWidgetFile, widgetConfig?.signal_enabled, sendToSignalApi, sessionId]
499
602
  );
500
603
  const retryFailedSend = React2.useCallback(() => {
501
604
  if (!lastFailedSend || !sessionId) return;
@@ -513,33 +616,48 @@ function ChatWidget({ projectId: propProjectId, config, apiUrl: propApiUrl }) {
513
616
  if (!sessionId) return;
514
617
  const apiKey = ensureApiKey();
515
618
  if (!apiKey) return;
619
+ setCheckingHandoff(true);
516
620
  try {
517
- const availRes = await fetch(`${baseUrl}/engage/widget/availability?projectId=${projectId}`, {
518
- headers: { "x-api-key": apiKey }
519
- });
520
- const avail = availRes.ok ? (await availRes.json()).data : null;
521
- if (avail?.agentsOnline === 0) {
621
+ const firstAvail = await checkAvailability();
622
+ if (firstAvail?.agentsOnline && firstAvail.agentsOnline > 0) {
623
+ setCheckingHandoff(false);
624
+ await fetch(`${baseUrl}/engage/widget/handoff`, {
625
+ method: "POST",
626
+ headers: { "Content-Type": "application/json", "x-api-key": apiKey },
627
+ body: JSON.stringify({ sessionId })
628
+ });
629
+ setMessages((prev) => [
630
+ ...prev,
631
+ { id: `handoff-${Date.now()}`, role: "system", content: "Connecting you with a team member. Please hold on!", timestamp: /* @__PURE__ */ new Date() }
632
+ ]);
633
+ return;
634
+ }
635
+ await new Promise((resolve) => setTimeout(resolve, 5e3));
636
+ const secondAvail = await checkAvailability();
637
+ setCheckingHandoff(false);
638
+ if (secondAvail?.agentsOnline && secondAvail.agentsOnline > 0) {
639
+ await fetch(`${baseUrl}/engage/widget/handoff`, {
640
+ method: "POST",
641
+ headers: { "Content-Type": "application/json", "x-api-key": apiKey },
642
+ body: JSON.stringify({ sessionId })
643
+ });
644
+ setMessages((prev) => [
645
+ ...prev,
646
+ { id: `handoff-${Date.now()}`, role: "system", content: "Connecting you with a team member. Please hold on!", timestamp: /* @__PURE__ */ new Date() }
647
+ ]);
648
+ } else {
522
649
  setHandoffOfflinePrompt(widgetConfig?.offline_subheading ?? "Nobody is online right now. Leave your details and we'll get back to you.");
523
650
  setShowOfflineForm(true);
524
651
  setMessages((prev) => [
525
652
  ...prev,
526
653
  { id: `handoff-offline-${Date.now()}`, role: "system", content: offlineHeading, timestamp: /* @__PURE__ */ new Date() }
527
654
  ]);
528
- return;
529
655
  }
530
- await fetch(`${baseUrl}/engage/widget/handoff`, {
531
- method: "POST",
532
- headers: { "Content-Type": "application/json", "x-api-key": apiKey },
533
- body: JSON.stringify({ sessionId })
534
- });
535
- setMessages((prev) => [
536
- ...prev,
537
- { id: `handoff-${Date.now()}`, role: "system", content: "Connecting you with a team member. Please hold on!", timestamp: /* @__PURE__ */ new Date() }
538
- ]);
539
656
  } catch (error) {
657
+ setCheckingHandoff(false);
540
658
  console.error("[ChatWidget] Handoff request failed:", error);
541
659
  }
542
- }, [sessionId, baseUrl, projectId, widgetConfig, offlineHeading]);
660
+ }, [sessionId, baseUrl, projectId, widgetConfig, offlineHeading, checkAvailability]);
543
661
  const [offlineError, setOfflineError] = React2.useState(null);
544
662
  const handleOfflineSubmit = React2.useCallback(
545
663
  async (e) => {
@@ -840,7 +958,7 @@ function ChatWidget({ projectId: propProjectId, config, apiUrl: propApiUrl }) {
840
958
  )
841
959
  ] }),
842
960
  /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
843
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontSize: 16, fontWeight: 600, color: "#111827", marginBottom: 6 }, children: "Checking for a team member" }),
961
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontSize: 16, fontWeight: 600, color: "#111827", marginBottom: 6 }, children: checkingHandoff ? "Looking for online support" : "Checking for a team member" }),
844
962
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { fontSize: 14, color: "#6b7280", lineHeight: 1.5 }, children: [
845
963
  "One moment please",
846
964
  /* @__PURE__ */ jsxRuntime.jsx("span", { style: { display: "inline-flex", width: 20 }, children: /* @__PURE__ */ jsxRuntime.jsx("span", { style: { animation: "checkDots 1.5s infinite steps(4, end)" }, children: "..." }) })
@@ -1043,11 +1161,11 @@ function ChatWidget({ projectId: propProjectId, config, apiUrl: propApiUrl }) {
1043
1161
  },
1044
1162
  children: [
1045
1163
  Header,
1046
- checkingAvailability ? CheckingScreen : showOfflineForm ? OfflineFormView : showWelcome && welcomeEnabled && messages.length === 0 ? WelcomeScreen : MessagesView,
1164
+ checkingAvailability || checkingHandoff ? CheckingScreen : showOfflineForm ? OfflineFormView : showWelcome && welcomeEnabled && messages.length === 0 ? WelcomeScreen : MessagesView,
1047
1165
  showPoweredBy && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { padding: "6px 0", textAlign: "center", fontSize: 11, color: "#9ca3af", backgroundColor: "#ffffff", borderTop: "1px solid #f3f4f6" }, children: [
1048
1166
  "Powered by",
1049
1167
  " ",
1050
- /* @__PURE__ */ jsxRuntime.jsx("a", { href: "https://uptrademedia.com", target: "_blank", rel: "noopener noreferrer", style: { color: "#6b7280", textDecoration: "none", fontWeight: 500 }, children: "Uptrade" })
1168
+ /* @__PURE__ */ jsxRuntime.jsx("a", { href: "https://uptrademedia.com", target: "_blank", rel: "noopener noreferrer", style: { color: "#6b7280", textDecoration: "none", fontWeight: 500 }, children: "Sonor" })
1051
1169
  ] }),
1052
1170
  /* @__PURE__ */ jsxRuntime.jsx("style", { children: `
1053
1171
  @keyframes chatSlideUp {
@@ -1342,7 +1460,9 @@ function DesignRenderer({
1342
1460
  )) });
1343
1461
  }
1344
1462
  function getApiConfig2() {
1345
- const apiUrl = typeof window !== "undefined" ? window.__SITE_KIT_API_URL__ || "https://api.uptrademedia.com" : "https://api.uptrademedia.com";
1463
+ const isDev = typeof process !== "undefined" && process.env?.NODE_ENV === "development";
1464
+ const defaultApiUrl = isDev && process.env?.NEXT_PUBLIC_UPTRADE_API_URL ? process.env.NEXT_PUBLIC_UPTRADE_API_URL : "https://api.uptrademedia.com";
1465
+ const apiUrl = typeof window !== "undefined" ? window.__SITE_KIT_API_URL__ || defaultApiUrl : defaultApiUrl;
1346
1466
  const apiKey = typeof window !== "undefined" ? window.__SITE_KIT_API_KEY__ : void 0;
1347
1467
  return { apiUrl, apiKey };
1348
1468
  }
@@ -1368,22 +1488,25 @@ function EngageWidget({
1368
1488
  if (debug) console.warn("[Engage] No API key configured");
1369
1489
  return;
1370
1490
  }
1491
+ let visitorId = typeof localStorage !== "undefined" ? localStorage.getItem("engage_visitor_id") : null;
1492
+ if (!visitorId) {
1493
+ visitorId = `visitor_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
1494
+ if (typeof localStorage !== "undefined") localStorage.setItem("engage_visitor_id", visitorId);
1495
+ }
1496
+ const url = typeof window !== "undefined" ? window.location.href : "";
1371
1497
  try {
1372
- const response = await fetch(`${apiUrl}/api/public/engage/elements`, {
1373
- method: "POST",
1374
- headers: {
1375
- "Content-Type": "application/json",
1376
- "x-api-key": apiKey
1377
- },
1378
- body: JSON.stringify({})
1379
- });
1498
+ const response = await fetch(
1499
+ `${apiUrl.replace(/\/$/, "")}/engage/widget/elements?url=${encodeURIComponent(url)}&visitorId=${encodeURIComponent(visitorId)}`,
1500
+ { headers: { "x-api-key": apiKey } }
1501
+ );
1380
1502
  if (!response.ok) {
1381
1503
  if (debug) console.error("[Engage] Error loading elements:", response.statusText);
1382
1504
  return;
1383
1505
  }
1384
- const data = await response.json();
1385
- if (debug) console.log("[Engage] Loaded elements:", data.elements);
1386
- setElements(data.elements || []);
1506
+ const json = await response.json();
1507
+ const elementsList = json.data?.elements ?? json.elements ?? [];
1508
+ if (debug) console.log("[Engage] Loaded elements:", elementsList);
1509
+ setElements(elementsList);
1387
1510
  } catch (error) {
1388
1511
  if (debug) console.error("[Engage] Error loading elements:", error);
1389
1512
  }
@@ -1700,5 +1823,5 @@ function getDeviceType() {
1700
1823
  exports.ChatWidget = ChatWidget;
1701
1824
  exports.DesignRenderer = DesignRenderer;
1702
1825
  exports.EngageWidget = EngageWidget;
1703
- //# sourceMappingURL=chunk-YT74LIC4.js.map
1704
- //# sourceMappingURL=chunk-YT74LIC4.js.map
1826
+ //# sourceMappingURL=chunk-CTKXFLIF.js.map
1827
+ //# sourceMappingURL=chunk-CTKXFLIF.js.map