@flamingo-stack/openframe-frontend-core 0.0.704 → 0.0.705-snapshot.20261006160157

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 (212) hide show
  1. package/dist/{chunk-7LFIKJX2.js → chunk-3EZ4HHAP.js} +3 -3
  2. package/dist/{chunk-I7DFUQMN.js → chunk-3NCM4ZQB.js} +17 -18
  3. package/dist/{chunk-4DQMTBMK.cjs → chunk-3PLDQDE6.cjs} +15 -15
  4. package/dist/{chunk-VTASHWER.js → chunk-4CJMQLB5.js} +4 -4
  5. package/dist/{chunk-VR2ZLFCP.js → chunk-4IBPRIQH.js} +1 -1
  6. package/dist/{chunk-ZQFZSFQI.js → chunk-4ILM7W2R.js} +2 -2
  7. package/dist/{chunk-FXENTYE5.js → chunk-6232S532.js} +3 -3
  8. package/dist/{chunk-MMOODW57.cjs → chunk-6NTPY5QA.cjs} +1887 -94
  9. package/dist/{chunk-2JDVL7UV.js → chunk-7GEBFJT2.js} +1829 -3447
  10. package/dist/{chunk-LDPEQGKT.cjs → chunk-7OFPU7WE.cjs} +942 -2560
  11. package/dist/{chunk-L3IC42IF.cjs → chunk-7SCNMP2B.cjs} +57 -58
  12. package/dist/{chunk-2G546OND.js → chunk-BHI6GVC4.js} +1094 -693
  13. package/dist/{chunk-MP2C3LJ4.js → chunk-CUME3VTQ.js} +1 -1
  14. package/dist/{chunk-WUJNYGO2.js → chunk-CZ7Y7UG4.js} +4 -76
  15. package/dist/{chunk-7JIL3WOH.cjs → chunk-DDVBX42E.cjs} +21 -21
  16. package/dist/{chunk-6WQIUQUC.js → chunk-DWPAAWMR.js} +6 -6
  17. package/dist/{chunk-MFFCUVWG.js → chunk-F57ECE2I.js} +1 -1
  18. package/dist/{chunk-CH5232HV.js → chunk-FI6GMDO7.js} +2455 -662
  19. package/dist/{chunk-NDESEPW5.js → chunk-FXJ3WWUB.js} +68 -0
  20. package/dist/{chunk-4KGXLVCF.js → chunk-G6UMNAVI.js} +57 -61
  21. package/dist/{chunk-LTSTC3N5.cjs → chunk-GWQEYPYM.cjs} +728 -732
  22. package/dist/{chunk-N3TO7JV3.cjs → chunk-HZ7CBXPL.cjs} +89 -89
  23. package/dist/{chunk-XATTBO5X.js → chunk-IKJA3Y7Z.js} +2 -2
  24. package/dist/{chunk-5HBHO5TB.js → chunk-JPG7OHEG.js} +1 -1
  25. package/dist/{chunk-AMYY3PNL.cjs → chunk-K6O43WDL.cjs} +46 -46
  26. package/dist/{chunk-IHU5ANUY.js → chunk-KUC673HM.js} +383 -142
  27. package/dist/{chunk-X72J4ACL.cjs → chunk-LLSUVPQC.cjs} +252 -8
  28. package/dist/{chunk-RKV5B7EU.cjs → chunk-LM7TXMLU.cjs} +72 -4
  29. package/dist/{chunk-XJKZ4IKT.cjs → chunk-LVSFKENJ.cjs} +4 -4
  30. package/dist/{chunk-IZGDG5X6.cjs → chunk-M75XEEGT.cjs} +940 -539
  31. package/dist/{chunk-UK62YTH6.cjs → chunk-MB4PNY7C.cjs} +6 -6
  32. package/dist/{chunk-2YXVWZVF.js → chunk-N45D4ZXQ.js} +959 -715
  33. package/dist/{chunk-Z2VNQQ74.js → chunk-NCPTID44.js} +978 -942
  34. package/dist/{chunk-JEYRXT5L.js → chunk-O2RSAA5M.js} +11 -11
  35. package/dist/{chunk-ABU3TGXA.cjs → chunk-OF6GEI5A.cjs} +3 -3
  36. package/dist/{chunk-OHFS7VOU.cjs → chunk-PLYEKV3N.cjs} +2 -2
  37. package/dist/{chunk-5QJDM6UV.js → chunk-PXOQIA5K.js} +5 -5
  38. package/dist/{chunk-VHCACDKP.cjs → chunk-RQRX4YC3.cjs} +39 -39
  39. package/dist/{chunk-HFJW24JJ.cjs → chunk-RTIPR53L.cjs} +104 -104
  40. package/dist/{chunk-262YQFOS.cjs → chunk-SEKYEWQG.cjs} +26 -26
  41. package/dist/{chunk-SYXQLETR.cjs → chunk-STHZBOQI.cjs} +17 -17
  42. package/dist/{chunk-MI3JUJ75.cjs → chunk-SW5ZV2BN.cjs} +34 -34
  43. package/dist/{chunk-QVSFBSWV.js → chunk-T5TMCHWM.js} +9 -9
  44. package/dist/{chunk-ERCV6HHJ.js → chunk-TE773HEH.js} +10 -10
  45. package/dist/{chunk-C7XGRLT5.cjs → chunk-TQ4LB2DS.cjs} +14 -14
  46. package/dist/{chunk-XOYH2YQE.cjs → chunk-UDFRUKLC.cjs} +2 -2
  47. package/dist/{chunk-XIFOBQRQ.cjs → chunk-UJ33ZXDT.cjs} +6 -6
  48. package/dist/{chunk-C3BWIU7R.cjs → chunk-UVTD52MD.cjs} +14 -86
  49. package/dist/{chunk-N3COXDBH.cjs → chunk-VX4E6YSB.cjs} +41 -5
  50. package/dist/{chunk-HJAYVKWQ.js → chunk-VZICIQW2.js} +15 -15
  51. package/dist/{chunk-MGGGBHYD.cjs → chunk-WCVZCGK5.cjs} +312 -71
  52. package/dist/{chunk-6XIF2Z7I.js → chunk-WMX26HB5.js} +3 -3
  53. package/dist/{chunk-D7BTSVMS.cjs → chunk-Y2GSOUCS.cjs} +2 -2
  54. package/dist/{chunk-NRLJUBCS.js → chunk-YGJKKDDM.js} +6 -6
  55. package/dist/components/case-studies/index.cjs +30 -32
  56. package/dist/components/case-studies/index.js +14 -16
  57. package/dist/components/chat/chat-input.d.ts.map +1 -1
  58. package/dist/components/chat/chat-message-enhanced.d.ts.map +1 -1
  59. package/dist/components/chat/embeddable-chat.d.ts +8 -0
  60. package/dist/components/chat/embeddable-chat.d.ts.map +1 -1
  61. package/dist/components/chat/entity-cards/case-study-card.d.ts +11 -4
  62. package/dist/components/chat/entity-cards/case-study-card.d.ts.map +1 -1
  63. package/dist/components/chat/index.cjs +11 -11
  64. package/dist/components/chat/index.d.ts +1 -1
  65. package/dist/components/chat/index.d.ts.map +1 -1
  66. package/dist/components/chat/index.js +16 -16
  67. package/dist/components/chat/mingo-chat-rail.d.ts +3 -1
  68. package/dist/components/chat/mingo-chat-rail.d.ts.map +1 -1
  69. package/dist/components/chat/utils/icon-library.d.ts.map +1 -1
  70. package/dist/components/contact/index.cjs +12 -14
  71. package/dist/components/contact/index.js +11 -13
  72. package/dist/components/docs/index.cjs +15 -17
  73. package/dist/components/docs/index.js +14 -16
  74. package/dist/components/embeds/index.cjs +12 -14
  75. package/dist/components/embeds/index.js +11 -13
  76. package/dist/components/faq/index.cjs +13 -15
  77. package/dist/components/faq/index.js +12 -14
  78. package/dist/components/features/index.cjs +12 -14
  79. package/dist/components/features/index.js +21 -23
  80. package/dist/components/help-center-pages/index.cjs +118 -120
  81. package/dist/components/help-center-pages/index.js +33 -35
  82. package/dist/components/icons/index.cjs +3 -5
  83. package/dist/components/icons/index.js +9 -11
  84. package/dist/components/icons-v2-generated/index.cjs +3 -5
  85. package/dist/components/icons-v2-generated/index.js +2 -4
  86. package/dist/components/index.cjs +89 -158
  87. package/dist/components/index.d.ts +0 -2
  88. package/dist/components/index.d.ts.map +1 -1
  89. package/dist/components/index.js +333 -402
  90. package/dist/components/loading/page-layout-skeleton.d.ts +1 -1
  91. package/dist/components/meeting-scheduler/index.cjs +62 -64
  92. package/dist/components/meeting-scheduler/index.js +12 -14
  93. package/dist/components/navigation/app-layout-side-panel.d.ts +18 -1
  94. package/dist/components/navigation/app-layout-side-panel.d.ts.map +1 -1
  95. package/dist/components/navigation/index.cjs +30 -16
  96. package/dist/components/navigation/index.d.ts +15 -10
  97. package/dist/components/navigation/index.d.ts.map +1 -1
  98. package/dist/components/navigation/index.js +40 -26
  99. package/dist/components/navigation/mingo-ai-button.d.ts +38 -3
  100. package/dist/components/navigation/mingo-ai-button.d.ts.map +1 -1
  101. package/dist/components/navigation/mobile-nav-sheet-id.d.ts +3 -0
  102. package/dist/components/navigation/mobile-nav-sheet-id.d.ts.map +1 -0
  103. package/dist/components/navigation/mobile-nav-sheet.d.ts +48 -0
  104. package/dist/components/navigation/mobile-nav-sheet.d.ts.map +1 -0
  105. package/dist/components/navigation/nav-item-row.d.ts +27 -0
  106. package/dist/components/navigation/nav-item-row.d.ts.map +1 -0
  107. package/dist/components/navigation/nav-panel.d.ts +43 -0
  108. package/dist/components/navigation/nav-panel.d.ts.map +1 -0
  109. package/dist/components/navigation/navigation-sidebar-item.d.ts +1 -2
  110. package/dist/components/navigation/navigation-sidebar-item.d.ts.map +1 -1
  111. package/dist/components/navigation/site-footer.d.ts +28 -0
  112. package/dist/components/navigation/site-footer.d.ts.map +1 -0
  113. package/dist/components/navigation/site-header.d.ts +61 -0
  114. package/dist/components/navigation/site-header.d.ts.map +1 -0
  115. package/dist/components/navigation/site-nav-link.d.ts +26 -0
  116. package/dist/components/navigation/site-nav-link.d.ts.map +1 -0
  117. package/dist/components/navigation/top-navigation.d.ts +2 -2
  118. package/dist/components/navigation/top-navigation.d.ts.map +1 -1
  119. package/dist/components/onboarding-guides/index.cjs +15 -17
  120. package/dist/components/onboarding-guides/index.js +14 -16
  121. package/dist/components/related-content/index.cjs +10 -8
  122. package/dist/components/related-content/index.js +9 -7
  123. package/dist/components/tickets/index.cjs +16 -18
  124. package/dist/components/tickets/index.js +15 -17
  125. package/dist/components/ui/index.cjs +14 -14
  126. package/dist/components/ui/index.js +19 -19
  127. package/dist/hooks/index.cjs +19 -11
  128. package/dist/hooks/index.d.ts +1 -0
  129. package/dist/hooks/index.d.ts.map +1 -1
  130. package/dist/hooks/index.js +19 -11
  131. package/dist/hooks/ui/index.d.ts +3 -0
  132. package/dist/hooks/ui/index.d.ts.map +1 -1
  133. package/dist/hooks/ui/use-active-section.d.ts +10 -0
  134. package/dist/hooks/ui/use-active-section.d.ts.map +1 -0
  135. package/dist/hooks/ui/use-nav-menus.d.ts +48 -0
  136. package/dist/hooks/ui/use-nav-menus.d.ts.map +1 -0
  137. package/dist/hooks/ui/use-visitor-os.d.ts +15 -0
  138. package/dist/hooks/ui/use-visitor-os.d.ts.map +1 -0
  139. package/dist/hooks/use-location-hash.d.ts +9 -0
  140. package/dist/hooks/use-location-hash.d.ts.map +1 -0
  141. package/dist/index.cjs +58 -21
  142. package/dist/index.js +233 -196
  143. package/dist/types/case-study.d.ts +9 -0
  144. package/dist/types/case-study.d.ts.map +1 -1
  145. package/dist/types/navigation.d.ts +95 -65
  146. package/dist/types/navigation.d.ts.map +1 -1
  147. package/dist/utils/index.cjs +55 -0
  148. package/dist/utils/index.d.ts +1 -0
  149. package/dist/utils/index.d.ts.map +1 -1
  150. package/dist/utils/index.js +50 -1
  151. package/dist/utils/source-icons.d.ts.map +1 -1
  152. package/dist/utils/visitor-os.d.ts +45 -0
  153. package/dist/utils/visitor-os.d.ts.map +1 -0
  154. package/package.json +1 -1
  155. package/src/components/chat/chat-input.tsx +5 -1
  156. package/src/components/chat/chat-message-enhanced.tsx +4 -3
  157. package/src/components/chat/embeddable-chat.tsx +64 -6
  158. package/src/components/chat/entity-cards/case-study-card.tsx +115 -5
  159. package/src/components/chat/index.ts +1 -0
  160. package/src/components/chat/mingo-chat-rail.tsx +24 -7
  161. package/src/components/chat/utils/icon-library.tsx +35 -1
  162. package/src/components/index.ts +0 -2
  163. package/src/components/loading/page-layout-skeleton.tsx +1 -1
  164. package/src/components/navigation/app-layout-side-panel.tsx +30 -2
  165. package/src/components/navigation/index.ts +22 -14
  166. package/src/components/navigation/mingo-ai-button.tsx +139 -63
  167. package/src/components/navigation/mobile-nav-sheet-id.ts +2 -0
  168. package/src/components/navigation/mobile-nav-sheet.tsx +241 -0
  169. package/src/components/navigation/nav-item-row.tsx +129 -0
  170. package/src/components/navigation/nav-panel.tsx +196 -0
  171. package/src/components/navigation/navigation-sidebar-item.tsx +1 -2
  172. package/src/components/navigation/site-footer.tsx +256 -0
  173. package/src/components/navigation/site-header.tsx +339 -0
  174. package/src/components/navigation/site-nav-link.tsx +41 -0
  175. package/src/components/navigation/ticket-alerts-button.tsx +2 -2
  176. package/src/components/navigation/top-navigation.tsx +2 -2
  177. package/src/components/platform/SoftwareSourceBadge.tsx +1 -1
  178. package/src/hooks/index.ts +1 -0
  179. package/src/hooks/ui/index.ts +3 -0
  180. package/src/hooks/ui/use-active-section.ts +44 -0
  181. package/src/hooks/ui/use-nav-menus.ts +200 -0
  182. package/src/hooks/ui/use-visitor-os.ts +33 -0
  183. package/src/hooks/use-location-hash.ts +34 -0
  184. package/src/styles/app-globals.css +13 -0
  185. package/src/styles/chat-animations.css +57 -2
  186. package/src/types/case-study.ts +16 -0
  187. package/src/types/navigation.ts +80 -66
  188. package/src/utils/index.ts +1 -0
  189. package/src/utils/source-icons.ts +13 -0
  190. package/src/utils/visitor-os.ts +84 -0
  191. package/dist/chunk-LMBC5FFP.js +0 -43
  192. package/dist/chunk-O43V3EOS.js +0 -252
  193. package/dist/chunk-QZVSJF2K.cjs +0 -252
  194. package/dist/chunk-RALRPFDW.cjs +0 -43
  195. package/dist/components/footer-waitlist-button.d.ts +0 -29
  196. package/dist/components/footer-waitlist-button.d.ts.map +0 -1
  197. package/dist/components/footer.d.ts +0 -47
  198. package/dist/components/footer.d.ts.map +0 -1
  199. package/dist/components/navigation/client-only-header.d.ts +0 -8
  200. package/dist/components/navigation/client-only-header.d.ts.map +0 -1
  201. package/dist/components/navigation/header-skeleton.d.ts +0 -12
  202. package/dist/components/navigation/header-skeleton.d.ts.map +0 -1
  203. package/dist/components/navigation/header.d.ts +0 -9
  204. package/dist/components/navigation/header.d.ts.map +0 -1
  205. package/dist/components/navigation/mobile-nav-panel.d.ts +0 -10
  206. package/dist/components/navigation/mobile-nav-panel.d.ts.map +0 -1
  207. package/src/components/footer-waitlist-button.tsx +0 -53
  208. package/src/components/footer.tsx +0 -195
  209. package/src/components/navigation/client-only-header.tsx +0 -22
  210. package/src/components/navigation/header-skeleton.tsx +0 -74
  211. package/src/components/navigation/header.tsx +0 -429
  212. package/src/components/navigation/mobile-nav-panel.tsx +0 -155
@@ -9,7 +9,7 @@ import {
9
9
  parseSchemaParams,
10
10
  positiveInt,
11
11
  shouldIncludeInUrl
12
- } from "./chunk-MP2C3LJ4.js";
12
+ } from "./chunk-CUME3VTQ.js";
13
13
  import {
14
14
  ToolIcon,
15
15
  apiErrorMessage,
@@ -18,30 +18,28 @@ import {
18
18
  scrollElementIntoView,
19
19
  useAutoplay,
20
20
  useDebounce
21
- } from "./chunk-WUJNYGO2.js";
21
+ } from "./chunk-CZ7Y7UG4.js";
22
22
  import {
23
23
  useRouter,
24
24
  useSearchParams
25
25
  } from "./chunk-GY4IZG22.js";
26
- import {
27
- FlamingoLogo,
28
- MlgLogo,
29
- OpenmspLogo
30
- } from "./chunk-2YXVWZVF.js";
31
- import {
32
- Chevron02DownIcon,
33
- XmarkIcon
34
- } from "./chunk-Z2VNQQ74.js";
35
26
  import {
36
27
  breakpoints,
37
28
  createLocalStorageAdapter,
38
29
  getPlatformBrandClasses,
39
30
  useMediaQuery
40
- } from "./chunk-NDESEPW5.js";
31
+ } from "./chunk-FXJ3WWUB.js";
41
32
  import {
33
+ FlamingoLogo,
42
34
  MiamiCyberGangLogoFaceOnly,
43
- OpenFrameLogo
44
- } from "./chunk-O43V3EOS.js";
35
+ MlgLogo,
36
+ OpenFrameLogo,
37
+ OpenmspLogo
38
+ } from "./chunk-N45D4ZXQ.js";
39
+ import {
40
+ Chevron02DownIcon,
41
+ XmarkIcon
42
+ } from "./chunk-NCPTID44.js";
45
43
  import {
46
44
  cn
47
45
  } from "./chunk-7RXWKTAP.js";
@@ -897,8 +895,219 @@ function useWindowSize() {
897
895
  // src/hooks/ui/index.ts
898
896
  import { usePreventScroll } from "@react-aria/overlays";
899
897
 
898
+ // src/hooks/ui/use-active-section.ts
899
+ import { useMemo as useMemo3 } from "react";
900
+ function pathOf(href) {
901
+ if (!href || !href.startsWith("/") || href.startsWith("//")) return null;
902
+ const path = href.split(/[?#]/)[0];
903
+ return path.length > 1 ? path.replace(/\/+$/, "") : "/";
904
+ }
905
+ function prefixHolds(prefix, pathname) {
906
+ if (prefix === "/") return pathname === "/";
907
+ return pathname === prefix || pathname.startsWith(`${prefix}/`);
908
+ }
909
+ function resolveActiveSection(menus, pathname) {
910
+ const current = pathOf(pathname ?? void 0);
911
+ if (!current) return null;
912
+ let best = null;
913
+ for (const menu of menus) {
914
+ const prefixes = menu.match?.length ? menu.match : [menu.href];
915
+ for (const raw of prefixes) {
916
+ const prefix = pathOf(raw);
917
+ if (!prefix || !prefixHolds(prefix, current)) continue;
918
+ if (!best || prefix.length > best.length) best = { id: menu.id, length: prefix.length };
919
+ }
920
+ }
921
+ return best?.id ?? null;
922
+ }
923
+ function useActiveSection(menus, pathname) {
924
+ return useMemo3(() => resolveActiveSection(menus, pathname), [menus, pathname]);
925
+ }
926
+
927
+ // src/hooks/ui/use-nav-menus.ts
928
+ import {
929
+ useCallback as useCallback8,
930
+ useEffect as useEffect10,
931
+ useId,
932
+ useRef as useRef8,
933
+ useState as useState10
934
+ } from "react";
935
+ function useNavMenus({
936
+ pathname,
937
+ hoverOpenMs = 150,
938
+ hoverCloseMs = 300
939
+ }) {
940
+ const baseId = useId();
941
+ const [opened, setOpened] = useState10(null);
942
+ const stale = opened !== null && opened.pathname !== pathname;
943
+ if (stale) setOpened(null);
944
+ const openId = opened && !stale ? opened.id : null;
945
+ const triggers = useRef8(/* @__PURE__ */ new Map());
946
+ const panels = useRef8(/* @__PURE__ */ new Map());
947
+ const openTimer = useRef8(null);
948
+ const closeTimer = useRef8(null);
949
+ const openedByHover = useRef8(null);
950
+ const clearTimers = useCallback8(() => {
951
+ if (openTimer.current) clearTimeout(openTimer.current);
952
+ if (closeTimer.current) clearTimeout(closeTimer.current);
953
+ openTimer.current = null;
954
+ closeTimer.current = null;
955
+ }, []);
956
+ useEffect10(() => clearTimers, [clearTimers]);
957
+ const close = useCallback8(() => {
958
+ clearTimers();
959
+ setOpened(null);
960
+ }, [clearTimers]);
961
+ const cancelClose = useCallback8(() => {
962
+ if (closeTimer.current) clearTimeout(closeTimer.current);
963
+ closeTimer.current = null;
964
+ }, []);
965
+ const scheduleClose = useCallback8(() => {
966
+ if (openTimer.current) clearTimeout(openTimer.current);
967
+ openTimer.current = null;
968
+ cancelClose();
969
+ closeTimer.current = setTimeout(() => {
970
+ closeTimer.current = null;
971
+ setOpened(null);
972
+ }, hoverCloseMs);
973
+ }, [cancelClose, hoverCloseMs]);
974
+ useEffect10(() => {
975
+ if (!openId) return void 0;
976
+ const handleKeyDown = (event) => {
977
+ if (event.key !== "Escape") return;
978
+ const trigger = triggers.current.get(openId);
979
+ close();
980
+ trigger?.focus({ preventScroll: true });
981
+ };
982
+ const handlePointerDown = (event) => {
983
+ const target = event.target;
984
+ if (!(target instanceof Node)) return;
985
+ for (const el of triggers.current.values()) if (el.contains(target)) return;
986
+ for (const el of panels.current.values()) if (el.contains(target)) return;
987
+ close();
988
+ };
989
+ document.addEventListener("keydown", handleKeyDown);
990
+ document.addEventListener("pointerdown", handlePointerDown);
991
+ return () => {
992
+ document.removeEventListener("keydown", handleKeyDown);
993
+ document.removeEventListener("pointerdown", handlePointerDown);
994
+ };
995
+ }, [openId, close]);
996
+ const getTriggerProps = useCallback8(
997
+ (id) => ({
998
+ ref: (el) => {
999
+ if (el) triggers.current.set(id, el);
1000
+ else triggers.current.delete(id);
1001
+ },
1002
+ "aria-expanded": openId === id,
1003
+ "aria-controls": `${baseId}-panel-${id}`,
1004
+ onClick: () => {
1005
+ clearTimers();
1006
+ const hovered = openedByHover.current === id;
1007
+ openedByHover.current = null;
1008
+ if (hovered) {
1009
+ setOpened({ id, pathname });
1010
+ return;
1011
+ }
1012
+ setOpened((prev) => prev && prev.id === id && prev.pathname === pathname ? null : { id, pathname });
1013
+ },
1014
+ onMouseEnter: () => {
1015
+ clearTimers();
1016
+ if (openId === id) return;
1017
+ if (openId !== null) {
1018
+ openedByHover.current = id;
1019
+ setOpened({ id, pathname });
1020
+ return;
1021
+ }
1022
+ openTimer.current = setTimeout(() => {
1023
+ openTimer.current = null;
1024
+ openedByHover.current = id;
1025
+ setOpened({ id, pathname });
1026
+ }, hoverOpenMs);
1027
+ },
1028
+ onMouseLeave: scheduleClose
1029
+ }),
1030
+ [baseId, openId, pathname, hoverOpenMs, clearTimers, scheduleClose]
1031
+ );
1032
+ const getPanelProps = useCallback8(
1033
+ (id) => ({
1034
+ ref: (el) => {
1035
+ if (el) panels.current.set(id, el);
1036
+ else panels.current.delete(id);
1037
+ },
1038
+ id: `${baseId}-panel-${id}`,
1039
+ inert: openId !== id,
1040
+ "data-state": openId === id ? "open" : "closed",
1041
+ onMouseEnter: cancelClose,
1042
+ onMouseLeave: scheduleClose
1043
+ }),
1044
+ [baseId, openId, cancelClose, scheduleClose]
1045
+ );
1046
+ return { openId, close, getTriggerProps, getPanelProps };
1047
+ }
1048
+
1049
+ // src/hooks/ui/use-visitor-os.ts
1050
+ import { useSyncExternalStore as useSyncExternalStore2 } from "react";
1051
+
1052
+ // src/utils/visitor-os.ts
1053
+ var DESKTOP_OSES = ["mac", "windows", "linux"];
1054
+ var HINT_PLATFORMS = {
1055
+ macos: "mac",
1056
+ windows: "windows",
1057
+ linux: "linux",
1058
+ "chrome os": "linux",
1059
+ "chromium os": "linux",
1060
+ android: "android",
1061
+ ios: "ios"
1062
+ };
1063
+ function detectVisitorOs(userAgent, hints = {}) {
1064
+ const touchMac = (os) => os === "mac" && (hints.maxTouchPoints ?? 0) > 1 ? "ios" : os;
1065
+ const hinted = HINT_PLATFORMS[(hints.platform ?? "").replace(/"/g, "").trim().toLowerCase()];
1066
+ if (hinted) return touchMac(hinted);
1067
+ const ua = userAgent ?? "";
1068
+ if (!ua) return null;
1069
+ if (/iPhone|iPad|iPod/i.test(ua)) return "ios";
1070
+ if (/Android/i.test(ua)) return "android";
1071
+ if (/Windows NT|Win64|Win32/i.test(ua)) return "windows";
1072
+ if (/Macintosh|Mac OS X/i.test(ua)) return touchMac("mac");
1073
+ if (/Linux|X11|CrOS/i.test(ua)) return "linux";
1074
+ return null;
1075
+ }
1076
+ function desktopOsOf(os) {
1077
+ return os !== null && DESKTOP_OSES.includes(os) ? os : null;
1078
+ }
1079
+ function detectDesktopOs(userAgent, hints) {
1080
+ return desktopOsOf(detectVisitorOs(userAgent, hints));
1081
+ }
1082
+ function usesCommandKey(os) {
1083
+ return os === "mac" || os === "ios";
1084
+ }
1085
+ function shortcutLabel(os, key) {
1086
+ return usesCommandKey(os) ? `\u2318${key}` : `Ctrl ${key}`;
1087
+ }
1088
+
1089
+ // src/hooks/ui/use-visitor-os.ts
1090
+ var UNKNOWN = { known: false, os: null };
1091
+ var KNOWN = /* @__PURE__ */ new Map();
1092
+ var subscribe2 = () => () => {
1093
+ };
1094
+ var getServerSnapshot = () => UNKNOWN;
1095
+ function getSnapshot() {
1096
+ const stated = navigator.userAgentData?.platform;
1097
+ const os = detectVisitorOs(navigator.userAgent, { platform: stated, maxTouchPoints: navigator.maxTouchPoints });
1098
+ let state = KNOWN.get(os);
1099
+ if (!state) {
1100
+ state = { known: true, os };
1101
+ KNOWN.set(os, state);
1102
+ }
1103
+ return state;
1104
+ }
1105
+ function useVisitorOs() {
1106
+ return useSyncExternalStore2(subscribe2, getSnapshot, getServerSnapshot);
1107
+ }
1108
+
900
1109
  // src/hooks/platform/use-platform-config.ts
901
- import { useState as useState10, useEffect as useEffect10 } from "react";
1110
+ import { useState as useState11, useEffect as useEffect11 } from "react";
902
1111
 
903
1112
  // src/utils/platform-config.tsx
904
1113
  import { Globe } from "lucide-react";
@@ -1011,10 +1220,10 @@ function toPlatformConfigs(payload) {
1011
1220
  return configs;
1012
1221
  }
1013
1222
  function usePlatformConfig() {
1014
- const [platforms, setPlatforms] = useState10(platformCache || []);
1015
- const [isLoading, setIsLoading] = useState10(!platformCache);
1016
- const [error, setError] = useState10(null);
1017
- useEffect10(() => {
1223
+ const [platforms, setPlatforms] = useState11(platformCache || []);
1224
+ const [isLoading, setIsLoading] = useState11(!platformCache);
1225
+ const [error, setError] = useState11(null);
1226
+ useEffect11(() => {
1018
1227
  const commit = (data) => {
1019
1228
  setPlatforms((prev) => prev === data ? prev : data);
1020
1229
  setIsLoading(false);
@@ -1082,7 +1291,7 @@ function useValidatePlatform(value) {
1082
1291
  import { toast as sonnerToast2 } from "sonner";
1083
1292
 
1084
1293
  // src/components/ui/toaster.tsx
1085
- import { useState as useState11 } from "react";
1294
+ import { useState as useState12 } from "react";
1086
1295
  import { Toaster as SonnerToaster, toast as sonnerToast } from "sonner";
1087
1296
  import { Fragment, jsx as jsx2, jsxs } from "react/jsx-runtime";
1088
1297
  var dotColorByVariant = {
@@ -1198,7 +1407,7 @@ function CommandApprovalToast({
1198
1407
  defaultExpanded = false,
1199
1408
  className
1200
1409
  }) {
1201
- const [expanded, setExpanded] = useState11(defaultExpanded);
1410
+ const [expanded, setExpanded] = useState12(defaultExpanded);
1202
1411
  const handleApprove = () => {
1203
1412
  onApprove?.();
1204
1413
  sonnerToast.dismiss(id);
@@ -1398,15 +1607,15 @@ var useToast = () => ({
1398
1607
  });
1399
1608
 
1400
1609
  // src/hooks/use-contact-submission.ts
1401
- import { useState as useState12, useCallback as useCallback8, useEffect as useEffect11 } from "react";
1610
+ import { useState as useState13, useCallback as useCallback9, useEffect as useEffect12 } from "react";
1402
1611
  function useContactSubmission(options = {}) {
1403
1612
  const { userId, successRedirectUrl, successToastMessage, onSuccess } = options;
1404
1613
  const { toast: toast2 } = useToast();
1405
1614
  const router = useRouter();
1406
1615
  const { contactUrl } = useRequiredEndpointsRuntime();
1407
- const [isSubmitting, setIsSubmitting] = useState12(false);
1408
- const [isSuccess, setIsSuccess] = useState12(false);
1409
- const submit = useCallback8(
1616
+ const [isSubmitting, setIsSubmitting] = useState13(false);
1617
+ const [isSuccess, setIsSuccess] = useState13(false);
1618
+ const submit = useCallback9(
1410
1619
  async (formData) => {
1411
1620
  if (isSubmitting) return;
1412
1621
  setIsSubmitting(true);
@@ -1444,7 +1653,7 @@ function useContactSubmission(options = {}) {
1444
1653
  },
1445
1654
  [isSubmitting, toast2, userId, successToastMessage, contactUrl]
1446
1655
  );
1447
- useEffect11(() => {
1656
+ useEffect12(() => {
1448
1657
  if (!isSuccess || !successRedirectUrl) return void 0;
1449
1658
  console.log("\u{1F680} Contact submission successful, redirecting to:", successRedirectUrl);
1450
1659
  const timer = setTimeout(() => {
@@ -1457,7 +1666,7 @@ function useContactSubmission(options = {}) {
1457
1666
  }, 1500);
1458
1667
  return () => clearTimeout(timer);
1459
1668
  }, [isSuccess, successRedirectUrl, router]);
1460
- useEffect11(() => {
1669
+ useEffect12(() => {
1461
1670
  if (isSuccess && onSuccess) {
1462
1671
  onSuccess();
1463
1672
  }
@@ -1466,7 +1675,7 @@ function useContactSubmission(options = {}) {
1466
1675
  }
1467
1676
 
1468
1677
  // src/hooks/use-copy-to-clipboard.ts
1469
- import { useCallback as useCallback9, useState as useState13 } from "react";
1678
+ import { useCallback as useCallback10, useState as useState14 } from "react";
1470
1679
  function useCopyToClipboard({
1471
1680
  successTitle = "Copied",
1472
1681
  successDescription = "Copied to clipboard",
@@ -1475,8 +1684,8 @@ function useCopyToClipboard({
1475
1684
  resetDelay = 2e3
1476
1685
  } = {}) {
1477
1686
  const { toast: toast2 } = useToast();
1478
- const [copied, setCopied] = useState13(false);
1479
- const copy = useCallback9(
1687
+ const [copied, setCopied] = useState14(false);
1688
+ const copy = useCallback10(
1480
1689
  async (text) => {
1481
1690
  try {
1482
1691
  await navigator.clipboard.writeText(text);
@@ -1493,7 +1702,7 @@ function useCopyToClipboard({
1493
1702
  }
1494
1703
 
1495
1704
  // src/hooks/use-batch-images.ts
1496
- import { useEffect as useEffect12, useMemo as useMemo3, useState as useState14, useRef as useRef8 } from "react";
1705
+ import { useEffect as useEffect13, useMemo as useMemo4, useState as useState15, useRef as useRef9 } from "react";
1497
1706
  var globalBatchImageConfig = {};
1498
1707
  function configureBatchImageFetch(config) {
1499
1708
  globalBatchImageConfig = { ...globalBatchImageConfig, ...config };
@@ -1566,17 +1775,17 @@ async function batchFetchAuthenticatedImages(imageUrls, config) {
1566
1775
  return results;
1567
1776
  }
1568
1777
  function useBatchImages(imageUrls, config) {
1569
- const [fetchedImages, setFetchedImages] = useState14({});
1570
- const uniqueUrls = useMemo3(
1778
+ const [fetchedImages, setFetchedImages] = useState15({});
1779
+ const uniqueUrls = useMemo4(
1571
1780
  () => Array.from(new Set(imageUrls.filter((url) => Boolean(url)))),
1572
1781
  [imageUrls]
1573
1782
  );
1574
- const requestedUrls = useRef8(/* @__PURE__ */ new Set());
1575
- const fetchedImagesRef = useRef8(fetchedImages);
1576
- useEffect12(() => {
1783
+ const requestedUrls = useRef9(/* @__PURE__ */ new Set());
1784
+ const fetchedImagesRef = useRef9(fetchedImages);
1785
+ useEffect13(() => {
1577
1786
  fetchedImagesRef.current = fetchedImages;
1578
1787
  }, [fetchedImages]);
1579
- useEffect12(
1788
+ useEffect13(
1580
1789
  () => () => {
1581
1790
  Object.values(fetchedImagesRef.current).forEach((blobUrl) => {
1582
1791
  if (blobUrl && blobUrl.startsWith("blob:")) {
@@ -1586,7 +1795,7 @@ function useBatchImages(imageUrls, config) {
1586
1795
  },
1587
1796
  []
1588
1797
  );
1589
- useEffect12(() => {
1798
+ useEffect13(() => {
1590
1799
  const urlsToFetch = uniqueUrls.filter((url) => !requestedUrls.current.has(url));
1591
1800
  if (urlsToFetch.length === 0) {
1592
1801
  return;
@@ -1604,7 +1813,7 @@ function useBatchImages(imageUrls, config) {
1604
1813
  }
1605
1814
 
1606
1815
  // src/hooks/use-authenticated-image.ts
1607
- import { useEffect as useEffect13, useState as useState15, useRef as useRef9 } from "react";
1816
+ import { useEffect as useEffect14, useState as useState16, useRef as useRef10 } from "react";
1608
1817
  var globalImageConfig = {};
1609
1818
  var imageCache = /* @__PURE__ */ new Map();
1610
1819
  var pendingRequests = /* @__PURE__ */ new Map();
@@ -1633,8 +1842,8 @@ function getImageConfig() {
1633
1842
  };
1634
1843
  }
1635
1844
  function useAuthenticatedImage(imageUrl, refreshKey, config) {
1636
- const [settled, setSettled] = useState15(null);
1637
- const currentCacheKeyRef = useRef9(null);
1845
+ const [settled, setSettled] = useState16(null);
1846
+ const currentCacheKeyRef = useRef10(null);
1638
1847
  const { tenantHostUrl, enableDevMode, accessTokenKey } = {
1639
1848
  ...getImageConfig(),
1640
1849
  ...config
@@ -1652,7 +1861,7 @@ function useAuthenticatedImage(imageUrl, refreshKey, config) {
1652
1861
  }
1653
1862
  }
1654
1863
  const cacheKey = fullImageUrl === null ? null : refreshKey ? `${fullImageUrl}?v=${refreshKey}` : fullImageUrl;
1655
- useEffect13(() => {
1864
+ useEffect14(() => {
1656
1865
  if (cacheKey === null) {
1657
1866
  if (currentCacheKeyRef.current) {
1658
1867
  const entry = imageCache.get(currentCacheKeyRef.current);
@@ -1729,7 +1938,7 @@ function useAuthenticatedImage(imageUrl, refreshKey, config) {
1729
1938
  });
1730
1939
  pendingRequests.set(cacheKey, fetchPromise2);
1731
1940
  }, [cacheKey, fullImageUrl, refreshKey, enableDevMode, accessTokenKey]);
1732
- useEffect13(() => {
1941
+ useEffect14(() => {
1733
1942
  return () => {
1734
1943
  if (currentCacheKeyRef.current) {
1735
1944
  const entry = imageCache.get(currentCacheKeyRef.current);
@@ -1750,7 +1959,7 @@ function useAuthenticatedImage(imageUrl, refreshKey, config) {
1750
1959
  }
1751
1960
 
1752
1961
  // src/hooks/state/use-query-params.ts
1753
- import { useEffect as useEffect14, useState as useState16, useMemo as useMemo4, useCallback as useCallback10, useRef as useRef10 } from "react";
1962
+ import { useEffect as useEffect15, useState as useState17, useMemo as useMemo5, useCallback as useCallback11, useRef as useRef11 } from "react";
1754
1963
 
1755
1964
  // src/hooks/state/flatten-schema.ts
1756
1965
  function flattenQueryVariables(queryVariables, introspector2) {
@@ -2201,26 +2410,26 @@ function validateVariables(variables, schema) {
2201
2410
  function useQueryParams(query, options = {}) {
2202
2411
  const router = useRouter();
2203
2412
  const searchParams = useSearchParams();
2204
- const [isLoading, setIsLoading] = useState16(true);
2205
- const [isReady, setIsReady] = useState16(false);
2206
- const [error, setError] = useState16(null);
2207
- const [schema, setSchema] = useState16({});
2208
- const defaultValues = useMemo4(() => options.defaultValues || {}, [options.defaultValues]);
2413
+ const [isLoading, setIsLoading] = useState17(true);
2414
+ const [isReady, setIsReady] = useState17(false);
2415
+ const [error, setError] = useState17(null);
2416
+ const [schema, setSchema] = useState17({});
2417
+ const defaultValues = useMemo5(() => options.defaultValues || {}, [options.defaultValues]);
2209
2418
  const skipIntrospection = options.skipIntrospection || false;
2210
2419
  const debug = options.debug || false;
2211
- const initSourceRef = useRef10({
2420
+ const initSourceRef = useRef11({
2212
2421
  introspectionHeaders: options.introspectionHeaders,
2213
2422
  paramMapping: options.paramMapping,
2214
2423
  defaultValues
2215
2424
  });
2216
- useEffect14(() => {
2425
+ useEffect15(() => {
2217
2426
  initSourceRef.current = {
2218
2427
  introspectionHeaders: options.introspectionHeaders,
2219
2428
  paramMapping: options.paramMapping,
2220
2429
  defaultValues
2221
2430
  };
2222
2431
  });
2223
- useEffect14(() => {
2432
+ useEffect15(() => {
2224
2433
  let cancelled = false;
2225
2434
  async function initialize() {
2226
2435
  try {
@@ -2267,7 +2476,7 @@ function useQueryParams(query, options = {}) {
2267
2476
  cancelled = true;
2268
2477
  };
2269
2478
  }, [query, options.introspectionEndpoint, skipIntrospection, debug]);
2270
- const variables = useMemo4(() => {
2479
+ const variables = useMemo5(() => {
2271
2480
  if (!isReady) {
2272
2481
  return defaultValues;
2273
2482
  }
@@ -2283,7 +2492,7 @@ function useQueryParams(query, options = {}) {
2283
2492
  return defaultValues;
2284
2493
  }
2285
2494
  }, [searchParams, schema, isReady, defaultValues, debug]);
2286
- const params = useMemo4(() => {
2495
+ const params = useMemo5(() => {
2287
2496
  const result = {};
2288
2497
  searchParams.forEach((value, key) => {
2289
2498
  const existing = result[key];
@@ -2297,7 +2506,7 @@ function useQueryParams(query, options = {}) {
2297
2506
  });
2298
2507
  return result;
2299
2508
  }, [searchParams]);
2300
- const updateUrl = useCallback10(
2509
+ const updateUrl = useCallback11(
2301
2510
  (newParams) => {
2302
2511
  const url = newParams.toString() ? `?${newParams.toString()}` : window.location.pathname;
2303
2512
  if (debug) {
@@ -2307,7 +2516,7 @@ function useQueryParams(query, options = {}) {
2307
2516
  },
2308
2517
  [router, debug]
2309
2518
  );
2310
- const setParam = useCallback10(
2519
+ const setParam = useCallback11(
2311
2520
  (key, value) => {
2312
2521
  if (!isReady) {
2313
2522
  console.warn("[useQueryParams] Schema not ready, cannot set param");
@@ -2323,7 +2532,7 @@ function useQueryParams(query, options = {}) {
2323
2532
  },
2324
2533
  [variables, schema, isReady, updateUrl]
2325
2534
  );
2326
- const setParams = useCallback10(
2535
+ const setParams = useCallback11(
2327
2536
  (updates) => {
2328
2537
  if (!isReady) {
2329
2538
  console.warn("[useQueryParams] Schema not ready, cannot set params");
@@ -2339,7 +2548,7 @@ function useQueryParams(query, options = {}) {
2339
2548
  },
2340
2549
  [variables, schema, isReady, updateUrl]
2341
2550
  );
2342
- const clearParamsHandler = useCallback10(
2551
+ const clearParamsHandler = useCallback11(
2343
2552
  (keys) => {
2344
2553
  if (!isReady) {
2345
2554
  console.warn("[useQueryParams] Schema not ready, cannot clear params");
@@ -2355,7 +2564,7 @@ function useQueryParams(query, options = {}) {
2355
2564
  },
2356
2565
  [variables, schema, isReady, updateUrl]
2357
2566
  );
2358
- const resetParams = useCallback10(() => {
2567
+ const resetParams = useCallback11(() => {
2359
2568
  if (debug) {
2360
2569
  console.log("[useQueryParams] Resetting params");
2361
2570
  }
@@ -2390,9 +2599,9 @@ function applyParamMapping(schema, mapping) {
2390
2599
  }
2391
2600
 
2392
2601
  // src/hooks/state/use-api-params.ts
2393
- import { useCallback as useCallback11, useEffect as useEffect15, useMemo as useMemo5, useRef as useRef11, useState as useState17 } from "react";
2602
+ import { useCallback as useCallback12, useEffect as useEffect16, useMemo as useMemo6, useRef as useRef12, useState as useState18 } from "react";
2394
2603
  function useContentStable(value, key) {
2395
- const [cached, setCached] = useState17({ value, key });
2604
+ const [cached, setCached] = useState18({ value, key });
2396
2605
  if (cached.key !== key) setCached({ value, key });
2397
2606
  return cached.key === key ? cached.value : value;
2398
2607
  }
@@ -2419,14 +2628,14 @@ function useApiParams(schema, options = {}) {
2419
2628
  const searchParamsLive = useSearchParams();
2420
2629
  const debug = options.debug || false;
2421
2630
  const searchString = searchParamsLive.toString();
2422
- const pendingRef = useRef11([]);
2423
- const [pendingTail, setPendingTail] = useState17(void 0);
2424
- const syncPendingTail = useCallback11(() => {
2631
+ const pendingRef = useRef12([]);
2632
+ const [pendingTail, setPendingTail] = useState18(void 0);
2633
+ const syncPendingTail = useCallback12(() => {
2425
2634
  setPendingTail(pendingRef.current[pendingRef.current.length - 1]);
2426
2635
  }, []);
2427
- const schemaKey = useMemo5(() => JSON.stringify(schema), [schema]);
2636
+ const schemaKey = useMemo6(() => JSON.stringify(schema), [schema]);
2428
2637
  const stableSchema = useContentStable(schema, schemaKey);
2429
- const flattenedSchema = useMemo5(() => {
2638
+ const flattenedSchema = useMemo6(() => {
2430
2639
  const flattened = {};
2431
2640
  for (const [key, config] of Object.entries(stableSchema)) {
2432
2641
  flattened[key] = {
@@ -2440,7 +2649,7 @@ function useApiParams(schema, options = {}) {
2440
2649
  }
2441
2650
  return flattened;
2442
2651
  }, [stableSchema]);
2443
- const rawParams = useMemo5(() => {
2652
+ const rawParams = useMemo6(() => {
2444
2653
  const result = parseSchemaParams(stableSchema, new URLSearchParams(searchString), {
2445
2654
  absent: options.absent === "null" ? "null" : "undefined"
2446
2655
  });
@@ -2449,17 +2658,17 @@ function useApiParams(schema, options = {}) {
2449
2658
  }
2450
2659
  return result;
2451
2660
  }, [searchString, debug, stableSchema, options.absent]);
2452
- const [paramsCache, setParamsCache] = useState17(() => ({ src: rawParams, value: rawParams }));
2661
+ const [paramsCache, setParamsCache] = useState18(() => ({ src: rawParams, value: rawParams }));
2453
2662
  let stableParams = paramsCache.value;
2454
2663
  if (paramsCache.src !== rawParams) {
2455
2664
  stableParams = reuseArrayRefs(paramsCache.value, rawParams);
2456
2665
  setParamsCache({ src: rawParams, value: stableParams });
2457
2666
  }
2458
2667
  const params = stableParams;
2459
- const addParamToSearchParams = useCallback11((searchParams, key, value) => {
2668
+ const addParamToSearchParams = useCallback12((searchParams, key, value) => {
2460
2669
  for (const [k, v] of createSearchParams({ [key]: value })) searchParams.append(k, v);
2461
2670
  }, []);
2462
- const urlSearchParams = useMemo5(() => {
2671
+ const urlSearchParams = useMemo6(() => {
2463
2672
  const newParams = new URLSearchParams();
2464
2673
  for (const key of Object.keys(stableSchema)) {
2465
2674
  const value = params[key];
@@ -2471,7 +2680,7 @@ function useApiParams(schema, options = {}) {
2471
2680
  }
2472
2681
  return newParams;
2473
2682
  }, [params, flattenedSchema, addParamToSearchParams, stableSchema]);
2474
- const updateUrl = useCallback11(
2683
+ const updateUrl = useCallback12(
2475
2684
  (newParams, keysToRemove = []) => {
2476
2685
  const base = pendingRef.current[pendingRef.current.length - 1] ?? searchString;
2477
2686
  const finalParams = new URLSearchParams(base);
@@ -2506,14 +2715,14 @@ function useApiParams(schema, options = {}) {
2506
2715
  },
2507
2716
  [router, debug, searchString, stableSchema, syncPendingTail]
2508
2717
  );
2509
- useEffect15(() => {
2718
+ useEffect16(() => {
2510
2719
  const queue = pendingRef.current;
2511
2720
  if (queue.length === 0) return;
2512
2721
  const hit = queue.indexOf(searchString);
2513
2722
  pendingRef.current = hit === -1 ? [] : queue.slice(hit + 1);
2514
2723
  syncPendingTail();
2515
2724
  }, [searchString, syncPendingTail]);
2516
- const setParam = useCallback11(
2725
+ const setParam = useCallback12(
2517
2726
  (key, value) => {
2518
2727
  const config = stableSchema[key];
2519
2728
  if (!config) {
@@ -2530,7 +2739,7 @@ function useApiParams(schema, options = {}) {
2530
2739
  },
2531
2740
  [updateUrl, addParamToSearchParams, stableSchema]
2532
2741
  );
2533
- const setParams = useCallback11(
2742
+ const setParams = useCallback12(
2534
2743
  (updates) => {
2535
2744
  const newParams = new URLSearchParams();
2536
2745
  const keysToRemove = [];
@@ -2550,20 +2759,20 @@ function useApiParams(schema, options = {}) {
2550
2759
  },
2551
2760
  [updateUrl, addParamToSearchParams, stableSchema, flattenedSchema]
2552
2761
  );
2553
- const clearParams2 = useCallback11(
2762
+ const clearParams2 = useCallback12(
2554
2763
  (keys) => {
2555
2764
  const newParams = new URLSearchParams();
2556
2765
  updateUrl(newParams, keys);
2557
2766
  },
2558
2767
  [updateUrl]
2559
2768
  );
2560
- const resetParams = useCallback11(() => {
2769
+ const resetParams = useCallback12(() => {
2561
2770
  if (debug) {
2562
2771
  console.log("[useApiParams] Resetting params");
2563
2772
  }
2564
2773
  router.replace(window.location.pathname, { scroll: false });
2565
2774
  }, [router, debug]);
2566
- const pendingParams = useMemo5(() => {
2775
+ const pendingParams = useMemo6(() => {
2567
2776
  if (pendingTail === void 0 || pendingTail === searchString) return params;
2568
2777
  return parseSchemaParams(stableSchema, new URLSearchParams(pendingTail), {
2569
2778
  absent: options.absent === "null" ? "null" : "undefined"
@@ -2581,7 +2790,7 @@ function useApiParams(schema, options = {}) {
2581
2790
  }
2582
2791
 
2583
2792
  // src/hooks/state/use-cursor-pagination-state.ts
2584
- import { useCallback as useCallback12, useEffect as useEffect16, useRef as useRef12, useState as useState18 } from "react";
2793
+ import { useCallback as useCallback13, useEffect as useEffect17, useRef as useRef13, useState as useState19 } from "react";
2585
2794
  var urlSchema = {
2586
2795
  search: { type: "string", default: "" },
2587
2796
  cursor: { type: "string", default: "" }
@@ -2589,21 +2798,21 @@ var urlSchema = {
2589
2798
  function useCursorPaginationState(options) {
2590
2799
  const { onInitialLoad, onSearchChange } = options;
2591
2800
  const { params, setParam, setParams } = useApiParams(urlSchema);
2592
- const [searchInput, setSearchInput] = useState18(params.search || "");
2593
- const [hasLoadedBeyondFirst, setHasLoadedBeyondFirst] = useState18(false);
2594
- const [initialLoadCount, setInitialLoadCount] = useState18(0);
2595
- const lastSearchRef = useRef12(null);
2596
- const isSyncingFromUrl = useRef12(false);
2597
- const isInitialLoadInProgress = useRef12(true);
2598
- const searchInputRef = useRef12(searchInput);
2599
- const onInitialLoadRef = useRef12(onInitialLoad);
2600
- const paramsRef = useRef12(params);
2601
- useEffect16(() => {
2801
+ const [searchInput, setSearchInput] = useState19(params.search || "");
2802
+ const [hasLoadedBeyondFirst, setHasLoadedBeyondFirst] = useState19(false);
2803
+ const [initialLoadCount, setInitialLoadCount] = useState19(0);
2804
+ const lastSearchRef = useRef13(null);
2805
+ const isSyncingFromUrl = useRef13(false);
2806
+ const isInitialLoadInProgress = useRef13(true);
2807
+ const searchInputRef = useRef13(searchInput);
2808
+ const onInitialLoadRef = useRef13(onInitialLoad);
2809
+ const paramsRef = useRef13(params);
2810
+ useEffect17(() => {
2602
2811
  searchInputRef.current = searchInput;
2603
2812
  onInitialLoadRef.current = onInitialLoad;
2604
2813
  paramsRef.current = params;
2605
2814
  });
2606
- useEffect16(() => {
2815
+ useEffect17(() => {
2607
2816
  if (isInitialLoadInProgress.current) return;
2608
2817
  const urlSearch = params.search || "";
2609
2818
  if (urlSearch !== searchInputRef.current) {
@@ -2614,7 +2823,7 @@ function useCursorPaginationState(options) {
2614
2823
  }, 0);
2615
2824
  }
2616
2825
  }, [params.search, initialLoadCount]);
2617
- useEffect16(() => {
2826
+ useEffect17(() => {
2618
2827
  if (isInitialLoadInProgress.current) return;
2619
2828
  if (isSyncingFromUrl.current) return;
2620
2829
  if (searchInput !== params.search) {
@@ -2625,7 +2834,7 @@ function useCursorPaginationState(options) {
2625
2834
  });
2626
2835
  }
2627
2836
  }, [searchInput, params.search, setParams, initialLoadCount]);
2628
- useEffect16(() => {
2837
+ useEffect17(() => {
2629
2838
  if (initialLoadCount === 0) {
2630
2839
  const cursor = paramsRef.current.cursor || null;
2631
2840
  const search = paramsRef.current.search || "";
@@ -2641,7 +2850,7 @@ function useCursorPaginationState(options) {
2641
2850
  });
2642
2851
  }
2643
2852
  }, [initialLoadCount]);
2644
- useEffect16(() => {
2853
+ useEffect17(() => {
2645
2854
  if (isInitialLoadInProgress.current) return;
2646
2855
  if (initialLoadCount === 0) return;
2647
2856
  const currentSearch = params.search || "";
@@ -2653,7 +2862,7 @@ function useCursorPaginationState(options) {
2653
2862
  });
2654
2863
  }
2655
2864
  }, [params.search, onSearchChange, initialLoadCount]);
2656
- const handleNextPage = useCallback12(
2865
+ const handleNextPage = useCallback13(
2657
2866
  async (endCursor, fetchFn) => {
2658
2867
  setParam("cursor", endCursor);
2659
2868
  await fetchFn();
@@ -2661,7 +2870,7 @@ function useCursorPaginationState(options) {
2661
2870
  },
2662
2871
  [setParam]
2663
2872
  );
2664
- const handleResetToFirstPage = useCallback12(
2873
+ const handleResetToFirstPage = useCallback13(
2665
2874
  async (fetchFn) => {
2666
2875
  setParam("cursor", "");
2667
2876
  await fetchFn();
@@ -2683,22 +2892,22 @@ function useCursorPaginationState(options) {
2683
2892
  }
2684
2893
 
2685
2894
  // src/hooks/nats/use-nats-client.ts
2686
- import { useEffect as useEffect17, useMemo as useMemo6, useState as useState19 } from "react";
2895
+ import { useEffect as useEffect18, useMemo as useMemo7, useState as useState20 } from "react";
2687
2896
  function useNatsClient(clientOptions, options = {}) {
2688
2897
  const { autoConnect = true } = options;
2689
- const client = useMemo6(() => {
2898
+ const client = useMemo7(() => {
2690
2899
  if (!clientOptions) return null;
2691
2900
  return createNatsClient(clientOptions);
2692
2901
  }, [clientOptions]);
2693
- const [status, setStatus] = useState19("disconnected");
2694
- const [lastError, setLastError] = useState19(null);
2695
- const [statusClient, setStatusClient] = useState19(client);
2902
+ const [status, setStatus] = useState20("disconnected");
2903
+ const [lastError, setLastError] = useState20(null);
2904
+ const [statusClient, setStatusClient] = useState20(client);
2696
2905
  if (statusClient !== client) {
2697
2906
  setStatusClient(client);
2698
2907
  setStatus("disconnected");
2699
2908
  setLastError(null);
2700
2909
  }
2701
- useEffect17(() => {
2910
+ useEffect18(() => {
2702
2911
  if (!client) return void 0;
2703
2912
  const off = client.onStatus((event) => {
2704
2913
  setStatus(event.status);
@@ -2725,7 +2934,7 @@ function useNatsClient(clientOptions, options = {}) {
2725
2934
  }
2726
2935
 
2727
2936
  // src/hooks/use-scenario-player.ts
2728
- import { useCallback as useCallback13, useEffect as useEffect18, useRef as useRef13, useState as useState20 } from "react";
2937
+ import { useCallback as useCallback14, useEffect as useEffect19, useRef as useRef14, useState as useState21 } from "react";
2729
2938
  var START_MS = 300;
2730
2939
  function useScenarioPlayer({
2731
2940
  scenarioCount,
@@ -2738,14 +2947,14 @@ function useScenarioPlayer({
2738
2947
  }) {
2739
2948
  const auto = useAutoplay(enabled);
2740
2949
  const { reducedMotion, paused, setPaused } = auto;
2741
- const [scenario, setScenario] = useState20(initialScenario);
2742
- const [rawStep, setRawStep] = useState20(startAtEnd ? Number.MAX_SAFE_INTEGER : 0);
2950
+ const [scenario, setScenario] = useState21(initialScenario);
2951
+ const [rawStep, setRawStep] = useState21(startAtEnd ? Number.MAX_SAFE_INTEGER : 0);
2743
2952
  const lastStep = typeof lastStepOption === "function" ? lastStepOption(scenario) : lastStepOption;
2744
2953
  const step = reducedMotion ? lastStep : Math.min(rawStep, lastStep);
2745
2954
  const playing = auto.playing && scenarioCount > 0;
2746
- const starting = useRef13(false);
2747
- const wasPlaying = useRef13(false);
2748
- useEffect18(() => {
2955
+ const starting = useRef14(false);
2956
+ const wasPlaying = useRef14(false);
2957
+ useEffect19(() => {
2749
2958
  if (playing && !wasPlaying.current) starting.current = true;
2750
2959
  wasPlaying.current = playing;
2751
2960
  if (!playing) return void 0;
@@ -2765,14 +2974,14 @@ function useScenarioPlayer({
2765
2974
  );
2766
2975
  return () => clearTimeout(timer);
2767
2976
  }, [playing, rawStep, lastStep, stepMs, holdMs, scenario, scenarioCount]);
2768
- const setStep = useCallback13(
2977
+ const setStep = useCallback14(
2769
2978
  (next) => {
2770
2979
  setRawStep(Math.max(0, Math.min(lastStep, next)));
2771
2980
  setPaused(false);
2772
2981
  },
2773
2982
  [lastStep, setPaused]
2774
2983
  );
2775
- const go = useCallback13(
2984
+ const go = useCallback14(
2776
2985
  (next) => {
2777
2986
  setScenario(next);
2778
2987
  setRawStep(0);
@@ -2886,7 +3095,7 @@ function useAccessCodeIntegration() {
2886
3095
  }
2887
3096
 
2888
3097
  // src/hooks/use-claude-mirror-src.ts
2889
- import { useEffect as useEffect19, useState as useState21 } from "react";
3098
+ import { useEffect as useEffect20, useState as useState22 } from "react";
2890
3099
 
2891
3100
  // src/utils/embed-url-converters.ts
2892
3101
  function toGoogleSheetsEmbedUrl(url) {
@@ -2976,9 +3185,9 @@ async function revalidateMirror(mirrorPath) {
2976
3185
  function useClaudeMirrorSrc(url) {
2977
3186
  const endpoints = useEndpointsRuntime();
2978
3187
  const mirrorPath = toClaudeMirrorPath(url, endpoints?.storageViewBaseUrl);
2979
- const [resolved, setResolved] = useState21(null);
3188
+ const [resolved, setResolved] = useState22(null);
2980
3189
  const state = resolved && resolved.key === mirrorPath ? resolved.value : { src: null, status: mirrorPath ? "probing" : "absent" };
2981
- useEffect19(() => {
3190
+ useEffect20(() => {
2982
3191
  if (!mirrorPath) return void 0;
2983
3192
  let cancelled = false;
2984
3193
  const settle = (value) => {
@@ -3004,12 +3213,33 @@ function useClaudeMirrorSrc(url) {
3004
3213
  return state;
3005
3214
  }
3006
3215
 
3216
+ // src/hooks/use-location-hash.ts
3217
+ import { useSyncExternalStore as useSyncExternalStore3 } from "react";
3218
+ var HASH_EVENTS = ["hashchange", "popstate"];
3219
+ function subscribe3(onChange) {
3220
+ for (const event of HASH_EVENTS) window.addEventListener(event, onChange);
3221
+ return () => {
3222
+ for (const event of HASH_EVENTS) window.removeEventListener(event, onChange);
3223
+ };
3224
+ }
3225
+ function readHash() {
3226
+ const raw = normalizeHashFragment(window.location.hash).replace(/^#/, "");
3227
+ try {
3228
+ return decodeURIComponent(raw);
3229
+ } catch {
3230
+ return raw;
3231
+ }
3232
+ }
3233
+ function useLocationHash() {
3234
+ return useSyncExternalStore3(subscribe3, readHash, () => "");
3235
+ }
3236
+
3007
3237
  // src/hooks/use-scroll-to-hash.ts
3008
- import { useEffect as useEffect20 } from "react";
3238
+ import { useEffect as useEffect21 } from "react";
3009
3239
  var MAX_POLL_FRAMES = 60;
3010
3240
  function useScrollToHash(readyDep = true, options) {
3011
3241
  const headerOffset = options?.headerOffset ?? 0;
3012
- useEffect20(() => {
3242
+ useEffect21(() => {
3013
3243
  if (typeof window === "undefined") return void 0;
3014
3244
  if (readyDep === null || readyDep === false) return void 0;
3015
3245
  let rafId = null;
@@ -3049,7 +3279,7 @@ function useScrollToHash(readyDep = true, options) {
3049
3279
  }
3050
3280
 
3051
3281
  // src/hooks/use-humanity-signals.ts
3052
- import { useCallback as useCallback14, useRef as useRef14, useState as useState22 } from "react";
3282
+ import { useCallback as useCallback15, useRef as useRef15, useState as useState23 } from "react";
3053
3283
 
3054
3284
  // src/utils/humanity-signals.ts
3055
3285
  var HONEYPOT_FIELD = "form_extra_note";
@@ -3111,17 +3341,17 @@ var splitCsvEnv = (s) => s?.split(",").map((t) => t.trim()).filter(Boolean) ?? [
3111
3341
 
3112
3342
  // src/hooks/use-humanity-signals.ts
3113
3343
  function useHumanitySignals() {
3114
- const ref = useRef14(null);
3115
- const [mountedAt] = useState22(() => typeof performance !== "undefined" ? performance.now() : 0);
3116
- const startedAtRef = useRef14(mountedAt);
3117
- const getSignals = useCallback14(
3344
+ const ref = useRef15(null);
3345
+ const [mountedAt] = useState23(() => typeof performance !== "undefined" ? performance.now() : 0);
3346
+ const startedAtRef = useRef15(mountedAt);
3347
+ const getSignals = useCallback15(
3118
3348
  () => ({
3119
3349
  [HONEYPOT_FIELD]: ref.current?.value ?? "",
3120
3350
  [ELAPSED_MS_FIELD]: typeof performance !== "undefined" ? Math.round(performance.now() - startedAtRef.current) : 0
3121
3351
  }),
3122
3352
  []
3123
3353
  );
3124
- const resetSignals = useCallback14(() => {
3354
+ const resetSignals = useCallback15(() => {
3125
3355
  if (ref.current) ref.current.value = "";
3126
3356
  if (typeof performance !== "undefined") startedAtRef.current = performance.now();
3127
3357
  }, []);
@@ -3129,7 +3359,7 @@ function useHumanitySignals() {
3129
3359
  }
3130
3360
 
3131
3361
  // src/hooks/use-form-rescue.ts
3132
- import { useCallback as useCallback15, useEffect as useEffect21, useMemo as useMemo7, useRef as useRef15 } from "react";
3362
+ import { useCallback as useCallback16, useEffect as useEffect22, useMemo as useMemo8, useRef as useRef16 } from "react";
3133
3363
 
3134
3364
  // src/utils/form-rescue.ts
3135
3365
  var FORM_ID_PATTERN = /^[a-z][a-z0-9_]{1,47}$/;
@@ -3343,27 +3573,27 @@ function readUtm() {
3343
3573
  function useFormRescue({ form, fieldNames, onRestore, getSignals }) {
3344
3574
  const draftsUrl = useEndpointsRuntime()?.formDraftsUrl;
3345
3575
  const formId = form?.id ?? null;
3346
- const attemptIdRef = useRef15(null);
3347
- const resumeTokenRef = useRef15(null);
3348
- const latestRef = useRef15(null);
3349
- const dirtyRef = useRef15(false);
3350
- const startedRef = useRef15(false);
3351
- const leadCapturedRef = useRef15(false);
3352
- const completedRef = useRef15(false);
3353
- const timerRef = useRef15(null);
3354
- const fieldNamesRef = useRef15(fieldNames);
3355
- const onRestoreRef = useRef15(onRestore);
3356
- const getSignalsRef = useRef15(getSignals);
3357
- useEffect21(() => {
3576
+ const attemptIdRef = useRef16(null);
3577
+ const resumeTokenRef = useRef16(null);
3578
+ const latestRef = useRef16(null);
3579
+ const dirtyRef = useRef16(false);
3580
+ const startedRef = useRef16(false);
3581
+ const leadCapturedRef = useRef16(false);
3582
+ const completedRef = useRef16(false);
3583
+ const timerRef = useRef16(null);
3584
+ const fieldNamesRef = useRef16(fieldNames);
3585
+ const onRestoreRef = useRef16(onRestore);
3586
+ const getSignalsRef = useRef16(getSignals);
3587
+ useEffect22(() => {
3358
3588
  fieldNamesRef.current = fieldNames;
3359
3589
  onRestoreRef.current = onRestore;
3360
3590
  getSignalsRef.current = getSignals;
3361
3591
  });
3362
- const attemptId = useCallback15(() => {
3592
+ const attemptId = useCallback16(() => {
3363
3593
  if (!attemptIdRef.current) attemptIdRef.current = newAttemptId();
3364
3594
  return attemptIdRef.current;
3365
3595
  }, []);
3366
- const send = useCallback15(
3596
+ const send = useCallback16(
3367
3597
  (keepalive) => {
3368
3598
  if (!formId || !draftsUrl || !dirtyRef.current || completedRef.current || !latestRef.current) return;
3369
3599
  dirtyRef.current = false;
@@ -3394,7 +3624,7 @@ function useFormRescue({ form, fieldNames, onRestore, getSignals }) {
3394
3624
  },
3395
3625
  [attemptId, draftsUrl, formId]
3396
3626
  );
3397
- useEffect21(() => {
3627
+ useEffect22(() => {
3398
3628
  if (!formId || typeof window === "undefined") return void 0;
3399
3629
  let cancelled = false;
3400
3630
  const token = new URLSearchParams(window.location.search).get(FORM_RESCUE_RESUME_PARAM);
@@ -3424,7 +3654,7 @@ function useFormRescue({ form, fieldNames, onRestore, getSignals }) {
3424
3654
  cancelled = true;
3425
3655
  };
3426
3656
  }, [attemptId, draftsUrl, formId]);
3427
- useEffect21(() => {
3657
+ useEffect22(() => {
3428
3658
  if (!formId || typeof document === "undefined") return void 0;
3429
3659
  const onHide = () => {
3430
3660
  if (completedRef.current || !startedRef.current) return;
@@ -3451,7 +3681,7 @@ function useFormRescue({ form, fieldNames, onRestore, getSignals }) {
3451
3681
  if (timerRef.current) clearTimeout(timerRef.current);
3452
3682
  };
3453
3683
  }, [attemptId, formId, send]);
3454
- const track = useCallback15(
3684
+ const track = useCallback16(
3455
3685
  (values, lastField) => {
3456
3686
  if (!formId || completedRef.current) return;
3457
3687
  const names = fieldNamesRef.current;
@@ -3484,14 +3714,14 @@ function useFormRescue({ form, fieldNames, onRestore, getSignals }) {
3484
3714
  },
3485
3715
  [attemptId, formId, send]
3486
3716
  );
3487
- const submitFields = useCallback15(() => {
3717
+ const submitFields = useCallback16(() => {
3488
3718
  if (!formId) return {};
3489
3719
  return {
3490
3720
  [FORM_RESCUE_ATTEMPT_FIELD]: attemptId(),
3491
3721
  ...resumeTokenRef.current ? { [FORM_RESCUE_RESUME_FIELD]: resumeTokenRef.current } : {}
3492
3722
  };
3493
3723
  }, [attemptId, formId]);
3494
- const complete = useCallback15(() => {
3724
+ const complete = useCallback16(() => {
3495
3725
  if (!formId) return;
3496
3726
  if (timerRef.current) {
3497
3727
  clearTimeout(timerRef.current);
@@ -3505,11 +3735,11 @@ function useFormRescue({ form, fieldNames, onRestore, getSignals }) {
3505
3735
  startedRef.current = false;
3506
3736
  leadCapturedRef.current = false;
3507
3737
  }, [attemptId, form, formId]);
3508
- return useMemo7(() => ({ track, submitFields, complete }), [track, submitFields, complete]);
3738
+ return useMemo8(() => ({ track, submitFields, complete }), [track, submitFields, complete]);
3509
3739
  }
3510
3740
 
3511
3741
  // src/hooks/use-rescued-form.ts
3512
- import { useEffect as useEffect22 } from "react";
3742
+ import { useEffect as useEffect23 } from "react";
3513
3743
  function flattenOneLevel(values) {
3514
3744
  const flat = {};
3515
3745
  for (const [key, value] of Object.entries(values)) {
@@ -3533,7 +3763,7 @@ function useRescuedForm(form, { rescue, fields, getSignals, fieldPath }) {
3533
3763
  }
3534
3764
  }
3535
3765
  });
3536
- useEffect22(() => {
3766
+ useEffect23(() => {
3537
3767
  const subscription = watch((values, { name }) => {
3538
3768
  handle.track(flattenOneLevel(values), name ? name.split(".").pop() ?? null : null);
3539
3769
  });
@@ -3558,6 +3788,16 @@ export {
3558
3788
  useTablePagination,
3559
3789
  useThrottle,
3560
3790
  useWindowSize,
3791
+ resolveActiveSection,
3792
+ useActiveSection,
3793
+ useNavMenus,
3794
+ DESKTOP_OSES,
3795
+ detectVisitorOs,
3796
+ desktopOsOf,
3797
+ detectDesktopOs,
3798
+ usesCommandKey,
3799
+ shortcutLabel,
3800
+ useVisitorOs,
3561
3801
  usePreventScroll,
3562
3802
  platformIcons,
3563
3803
  transformPlatformConfigsToOptions,
@@ -3618,6 +3858,7 @@ export {
3618
3858
  toClaudeMirrorPath,
3619
3859
  toClaudeEmbedUrl,
3620
3860
  useClaudeMirrorSrc,
3861
+ useLocationHash,
3621
3862
  useScrollToHash,
3622
3863
  HONEYPOT_FIELD,
3623
3864
  ELAPSED_MS_FIELD,