@flamingo-stack/openframe-frontend-core 0.0.296-snapshot.20260621021605 → 0.0.296

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 (276) hide show
  1. package/README.md +0 -9
  2. package/dist/chunk-26PKDALD.js +2379 -0
  3. package/dist/chunk-26PKDALD.js.map +1 -0
  4. package/dist/chunk-3MCHAFHB.js +89 -0
  5. package/dist/chunk-3MCHAFHB.js.map +1 -0
  6. package/dist/{chunk-PI4WSYQV.js → chunk-3ZXUQQL4.js} +2 -2
  7. package/dist/{chunk-WMSTJAZT.cjs → chunk-5E2HOSSH.cjs} +51 -913
  8. package/dist/chunk-5E2HOSSH.cjs.map +1 -0
  9. package/dist/{chunk-IL47XWV5.js → chunk-5P3B2LZW.js} +14 -8
  10. package/dist/{chunk-IL47XWV5.js.map → chunk-5P3B2LZW.js.map} +1 -1
  11. package/dist/chunk-66AANIOC.cjs +619 -0
  12. package/dist/chunk-66AANIOC.cjs.map +1 -0
  13. package/dist/{chunk-AD6C23QY.js → chunk-6GCI7JOE.js} +7 -8
  14. package/dist/{chunk-AD6C23QY.js.map → chunk-6GCI7JOE.js.map} +1 -1
  15. package/dist/chunk-6JINAOI7.cjs +311 -0
  16. package/dist/chunk-6JINAOI7.cjs.map +1 -0
  17. package/dist/{chunk-2QG57XOJ.js → chunk-7RIYT7ZH.js} +205 -1067
  18. package/dist/chunk-7RIYT7ZH.js.map +1 -0
  19. package/dist/{chunk-L6PSSIUQ.cjs → chunk-AQOWFSMB.cjs} +1 -1
  20. package/dist/chunk-AQOWFSMB.cjs.map +1 -0
  21. package/dist/chunk-BOCFIKYS.cjs +3009 -0
  22. package/dist/chunk-BOCFIKYS.cjs.map +1 -0
  23. package/dist/{chunk-54KNMC2R.cjs → chunk-D3LEFMOA.cjs} +3 -3
  24. package/dist/{chunk-54KNMC2R.cjs.map → chunk-D3LEFMOA.cjs.map} +1 -1
  25. package/dist/chunk-D652TJBQ.js +3009 -0
  26. package/dist/chunk-D652TJBQ.js.map +1 -0
  27. package/dist/{chunk-PWQUAVA3.js → chunk-E4XABBSU.js} +98 -338
  28. package/dist/chunk-E4XABBSU.js.map +1 -0
  29. package/dist/{chunk-JALO4TAZ.js → chunk-EL6QLAWX.js} +55 -357
  30. package/dist/chunk-EL6QLAWX.js.map +1 -0
  31. package/dist/{chunk-6C526VNN.cjs → chunk-EYEW6PTA.cjs} +118 -358
  32. package/dist/chunk-EYEW6PTA.cjs.map +1 -0
  33. package/dist/chunk-FQJK446R.js +1606 -0
  34. package/dist/chunk-FQJK446R.js.map +1 -0
  35. package/dist/{chunk-4PSQS3SW.cjs → chunk-GLLDTKZK.cjs} +9 -7
  36. package/dist/chunk-GLLDTKZK.cjs.map +1 -0
  37. package/dist/{chunk-FQOTC3UU.cjs → chunk-IE6OU3WQ.cjs} +16 -318
  38. package/dist/chunk-IE6OU3WQ.cjs.map +1 -0
  39. package/dist/chunk-J54Z3OCR.cjs +1606 -0
  40. package/dist/chunk-J54Z3OCR.cjs.map +1 -0
  41. package/dist/{chunk-PC746XCO.js → chunk-K2PFPBMF.js} +5563 -15048
  42. package/dist/chunk-K2PFPBMF.js.map +1 -0
  43. package/dist/chunk-KXCRGTRN.cjs +2379 -0
  44. package/dist/chunk-KXCRGTRN.cjs.map +1 -0
  45. package/dist/{chunk-IZ7JSBFP.js → chunk-LCNMR277.js} +1 -1
  46. package/dist/chunk-LCNMR277.js.map +1 -0
  47. package/dist/chunk-LFGGF7OT.cjs +449 -0
  48. package/dist/chunk-LFGGF7OT.cjs.map +1 -0
  49. package/dist/chunk-M2OCXTNT.js +311 -0
  50. package/dist/chunk-M2OCXTNT.js.map +1 -0
  51. package/dist/{chunk-L7ULJKG7.js → chunk-MBFWU2EM.js} +10 -6
  52. package/dist/{chunk-L7ULJKG7.js.map → chunk-MBFWU2EM.js.map} +1 -1
  53. package/dist/chunk-ME4EVDFP.js +619 -0
  54. package/dist/chunk-ME4EVDFP.js.map +1 -0
  55. package/dist/chunk-OQ6X7ZOC.js +449 -0
  56. package/dist/chunk-OQ6X7ZOC.js.map +1 -0
  57. package/dist/{chunk-4TLE6VLU.js → chunk-OY7OF7E7.js} +24 -30
  58. package/dist/chunk-OY7OF7E7.js.map +1 -0
  59. package/dist/chunk-POKKCWKF.js +354 -0
  60. package/dist/chunk-POKKCWKF.js.map +1 -0
  61. package/dist/{chunk-GUTS7HGA.cjs → chunk-QHIXS3W2.cjs} +2514 -11999
  62. package/dist/chunk-QHIXS3W2.cjs.map +1 -0
  63. package/dist/chunk-TFSYSWPS.cjs +89 -0
  64. package/dist/chunk-TFSYSWPS.cjs.map +1 -0
  65. package/dist/{chunk-53FUMSZ5.cjs → chunk-W6M2FLLT.cjs} +46 -40
  66. package/dist/chunk-W6M2FLLT.cjs.map +1 -0
  67. package/dist/{chunk-3JIQVE7T.js → chunk-WHMATDVP.js} +15 -9
  68. package/dist/{chunk-3JIQVE7T.js.map → chunk-WHMATDVP.js.map} +1 -1
  69. package/dist/{chunk-YBYI62OE.cjs → chunk-X647HY3F.cjs} +37 -33
  70. package/dist/chunk-X647HY3F.cjs.map +1 -0
  71. package/dist/{chunk-UNVE2SDJ.cjs → chunk-X6BV7MB7.cjs} +31 -37
  72. package/dist/chunk-X6BV7MB7.cjs.map +1 -0
  73. package/dist/{chunk-7OVGB2DQ.cjs → chunk-XREEV72C.cjs} +25 -19
  74. package/dist/chunk-XREEV72C.cjs.map +1 -0
  75. package/dist/chunk-YETA25JW.cjs +354 -0
  76. package/dist/chunk-YETA25JW.cjs.map +1 -0
  77. package/dist/{chunk-FCDQNTDG.cjs → chunk-YIGPRLQY.cjs} +20 -21
  78. package/dist/chunk-YIGPRLQY.cjs.map +1 -0
  79. package/dist/{chunk-X4DOXQRT.js → chunk-ZP4AVIZP.js} +6 -4
  80. package/dist/{chunk-X4DOXQRT.js.map → chunk-ZP4AVIZP.js.map} +1 -1
  81. package/dist/components/chat/index.cjs +18 -8
  82. package/dist/components/chat/index.cjs.map +1 -1
  83. package/dist/components/chat/index.js +85 -75
  84. package/dist/components/contact/index.cjs +15 -8
  85. package/dist/components/contact/index.cjs.map +1 -1
  86. package/dist/components/contact/index.js +14 -7
  87. package/dist/components/docs/doc-viewer.d.ts +2 -39
  88. package/dist/components/docs/doc-viewer.d.ts.map +1 -1
  89. package/dist/components/docs/index.cjs +9 -17
  90. package/dist/components/docs/index.cjs.map +1 -1
  91. package/dist/components/docs/index.d.ts +0 -4
  92. package/dist/components/docs/index.d.ts.map +1 -1
  93. package/dist/components/docs/index.js +8 -16
  94. package/dist/components/docs/use-document-tree.d.ts.map +1 -1
  95. package/dist/components/embeds/embed-iframe.d.ts.map +1 -1
  96. package/dist/components/embeds/index.cjs +15 -38
  97. package/dist/components/embeds/index.cjs.map +1 -1
  98. package/dist/components/embeds/index.d.ts +0 -8
  99. package/dist/components/embeds/index.d.ts.map +1 -1
  100. package/dist/components/embeds/index.js +17 -40
  101. package/dist/components/faq/index.cjs +16 -9
  102. package/dist/components/faq/index.cjs.map +1 -1
  103. package/dist/components/faq/index.js +15 -8
  104. package/dist/components/features/index.cjs +16 -8
  105. package/dist/components/features/index.cjs.map +1 -1
  106. package/dist/components/features/index.js +32 -24
  107. package/dist/components/index.cjs +452 -257
  108. package/dist/components/index.cjs.map +1 -1
  109. package/dist/components/index.js +976 -781
  110. package/dist/components/index.js.map +1 -1
  111. package/dist/components/layout/page-layout.d.ts +1 -10
  112. package/dist/components/layout/page-layout.d.ts.map +1 -1
  113. package/dist/components/layout/title-block.d.ts +1 -17
  114. package/dist/components/layout/title-block.d.ts.map +1 -1
  115. package/dist/components/navigation/index.cjs +15 -7
  116. package/dist/components/navigation/index.cjs.map +1 -1
  117. package/dist/components/navigation/index.js +17 -9
  118. package/dist/components/onboarding-guides/index.cjs +36 -35
  119. package/dist/components/onboarding-guides/index.cjs.map +1 -1
  120. package/dist/components/onboarding-guides/index.js +14 -13
  121. package/dist/components/onboarding-guides/index.js.map +1 -1
  122. package/dist/components/onboarding-guides/onboarding-guide-detail-view.d.ts +1 -1
  123. package/dist/components/onboarding-guides/onboarding-guide-detail-view.d.ts.map +1 -1
  124. package/dist/components/related-content/index.cjs +16 -9
  125. package/dist/components/related-content/index.cjs.map +1 -1
  126. package/dist/components/related-content/index.js +15 -8
  127. package/dist/components/shared/dev-section/dev-section-page.d.ts +0 -9
  128. package/dist/components/shared/dev-section/dev-section-page.d.ts.map +1 -1
  129. package/dist/components/shared/dev-section/dev-section-view.d.ts.map +1 -1
  130. package/dist/components/shared/dev-section/index.d.ts +1 -1
  131. package/dist/components/shared/dev-section/index.d.ts.map +1 -1
  132. package/dist/components/shared/doc-search/use-doc-search.d.ts.map +1 -1
  133. package/dist/components/shared/legal-document/legal-document-page.d.ts.map +1 -1
  134. package/dist/components/shared/product-release/release-detail-page.d.ts.map +1 -1
  135. package/dist/components/tickets/index.cjs +112 -100
  136. package/dist/components/tickets/index.cjs.map +1 -1
  137. package/dist/components/tickets/index.js +32 -20
  138. package/dist/components/tickets/index.js.map +1 -1
  139. package/dist/components/ui/file-manager/index.cjs +52 -50
  140. package/dist/components/ui/file-manager/index.cjs.map +1 -1
  141. package/dist/components/ui/file-manager/index.js +6 -4
  142. package/dist/components/ui/file-manager/index.js.map +1 -1
  143. package/dist/components/ui/index.cjs +19 -13
  144. package/dist/components/ui/index.cjs.map +1 -1
  145. package/dist/components/ui/index.d.ts +0 -2
  146. package/dist/components/ui/index.d.ts.map +1 -1
  147. package/dist/components/ui/index.js +139 -133
  148. package/dist/components/ui/release-changelog-section.d.ts +2 -6
  149. package/dist/components/ui/release-changelog-section.d.ts.map +1 -1
  150. package/dist/components/ui/simple-markdown-renderer.d.ts +8 -2
  151. package/dist/components/ui/simple-markdown-renderer.d.ts.map +1 -1
  152. package/dist/contexts/chat-runtime-context.d.ts +0 -14
  153. package/dist/contexts/chat-runtime-context.d.ts.map +1 -1
  154. package/dist/contexts/index.cjs +3 -3
  155. package/dist/contexts/index.js +5 -5
  156. package/dist/embed-shims/index.cjs +3 -3
  157. package/dist/embed-shims/index.cjs.map +1 -1
  158. package/dist/embed-shims/index.js +4 -4
  159. package/dist/hooks/index.cjs +9 -4
  160. package/dist/hooks/index.cjs.map +1 -1
  161. package/dist/hooks/index.js +11 -6
  162. package/dist/index.cjs +20 -14
  163. package/dist/index.cjs.map +1 -1
  164. package/dist/index.js +364 -358
  165. package/dist/types/doc-source.d.ts +1 -31
  166. package/dist/types/doc-source.d.ts.map +1 -1
  167. package/dist/utils/index.cjs +0 -4
  168. package/dist/utils/index.cjs.map +1 -1
  169. package/dist/utils/index.d.ts +0 -1
  170. package/dist/utils/index.d.ts.map +1 -1
  171. package/dist/utils/index.js +1 -4
  172. package/dist/utils/index.js.map +1 -1
  173. package/package.json +1 -7
  174. package/src/components/chat/embeddable-chat.tsx +1 -1
  175. package/src/components/docs/doc-viewer.tsx +19 -111
  176. package/src/components/docs/index.ts +0 -17
  177. package/src/components/docs/use-document-tree.ts +0 -21
  178. package/src/components/embeds/embed-iframe.tsx +9 -7
  179. package/src/components/embeds/index.ts +0 -30
  180. package/src/components/embeds/og-link-preview.tsx +13 -13
  181. package/src/components/layout/page-layout.tsx +1 -14
  182. package/src/components/layout/title-block.tsx +62 -40
  183. package/src/components/onboarding-guides/onboarding-guide-detail-view.tsx +3 -3
  184. package/src/components/shared/dev-section/dev-section-page.tsx +1 -9
  185. package/src/components/shared/dev-section/dev-section-view.tsx +9 -14
  186. package/src/components/shared/dev-section/index.ts +1 -1
  187. package/src/components/shared/doc-search/use-doc-search.ts +3 -7
  188. package/src/components/shared/legal-document/legal-document-page.tsx +2 -2
  189. package/src/components/shared/product-release/release-detail-page.tsx +4 -6
  190. package/src/components/ui/index.ts +0 -2
  191. package/src/components/ui/release-changelog-section.tsx +2 -7
  192. package/src/components/ui/simple-markdown-renderer.tsx +11 -7
  193. package/src/contexts/chat-runtime-context.tsx +0 -14
  194. package/src/types/doc-source.ts +1 -33
  195. package/src/utils/index.ts +0 -1
  196. package/dist/chunk-2QG57XOJ.js.map +0 -1
  197. package/dist/chunk-4PSQS3SW.cjs.map +0 -1
  198. package/dist/chunk-4TLE6VLU.js.map +0 -1
  199. package/dist/chunk-53FUMSZ5.cjs.map +0 -1
  200. package/dist/chunk-6C526VNN.cjs.map +0 -1
  201. package/dist/chunk-7OVGB2DQ.cjs.map +0 -1
  202. package/dist/chunk-F5OB2YAL.cjs +0 -144
  203. package/dist/chunk-F5OB2YAL.cjs.map +0 -1
  204. package/dist/chunk-FBWXMMRB.cjs +0 -2
  205. package/dist/chunk-FBWXMMRB.cjs.map +0 -1
  206. package/dist/chunk-FCDQNTDG.cjs.map +0 -1
  207. package/dist/chunk-FQOTC3UU.cjs.map +0 -1
  208. package/dist/chunk-GUTS7HGA.cjs.map +0 -1
  209. package/dist/chunk-GZ4C3XW6.js +0 -2
  210. package/dist/chunk-GZ4C3XW6.js.map +0 -1
  211. package/dist/chunk-IZ7JSBFP.js.map +0 -1
  212. package/dist/chunk-JALO4TAZ.js.map +0 -1
  213. package/dist/chunk-L6PSSIUQ.cjs.map +0 -1
  214. package/dist/chunk-PC746XCO.js.map +0 -1
  215. package/dist/chunk-PWQUAVA3.js.map +0 -1
  216. package/dist/chunk-SA2WPJVO.js +0 -144
  217. package/dist/chunk-SA2WPJVO.js.map +0 -1
  218. package/dist/chunk-UNVE2SDJ.cjs.map +0 -1
  219. package/dist/chunk-WMSTJAZT.cjs.map +0 -1
  220. package/dist/chunk-YBYI62OE.cjs.map +0 -1
  221. package/dist/components/case-studies/index.cjs +0 -126
  222. package/dist/components/case-studies/index.cjs.map +0 -1
  223. package/dist/components/case-studies/index.d.ts +0 -2
  224. package/dist/components/case-studies/index.d.ts.map +0 -1
  225. package/dist/components/case-studies/index.js +0 -126
  226. package/dist/components/case-studies/index.js.map +0 -1
  227. package/dist/components/case-studies/share-experience-section.d.ts +0 -48
  228. package/dist/components/case-studies/share-experience-section.d.ts.map +0 -1
  229. package/dist/components/docs/docs-hub-page.d.ts +0 -46
  230. package/dist/components/docs/docs-hub-page.d.ts.map +0 -1
  231. package/dist/components/docs/skeletons.d.ts +0 -32
  232. package/dist/components/docs/skeletons.d.ts.map +0 -1
  233. package/dist/components/docs/use-docs-resolve-link.d.ts +0 -20
  234. package/dist/components/docs/use-docs-resolve-link.d.ts.map +0 -1
  235. package/dist/components/embeds/embed-container.d.ts +0 -37
  236. package/dist/components/embeds/embed-container.d.ts.map +0 -1
  237. package/dist/components/embeds/file-download-card.d.ts +0 -18
  238. package/dist/components/embeds/file-download-card.d.ts.map +0 -1
  239. package/dist/components/embeds/linkedin-embed-client.d.ts +0 -8
  240. package/dist/components/embeds/linkedin-embed-client.d.ts.map +0 -1
  241. package/dist/components/embeds/markdown-image.d.ts +0 -5
  242. package/dist/components/embeds/markdown-image.d.ts.map +0 -1
  243. package/dist/components/embeds/reddit-embed-client.d.ts +0 -7
  244. package/dist/components/embeds/reddit-embed-client.d.ts.map +0 -1
  245. package/dist/components/embeds/rich-markdown-runtime.d.ts +0 -46
  246. package/dist/components/embeds/rich-markdown-runtime.d.ts.map +0 -1
  247. package/dist/components/embeds/twitter-embed-client.d.ts +0 -8
  248. package/dist/components/embeds/twitter-embed-client.d.ts.map +0 -1
  249. package/dist/components/layout/page-header.d.ts +0 -78
  250. package/dist/components/layout/page-header.d.ts.map +0 -1
  251. package/dist/components/layout/page-with-header.d.ts +0 -67
  252. package/dist/components/layout/page-with-header.d.ts.map +0 -1
  253. package/dist/components/ui/rich-markdown-renderer.d.ts +0 -34
  254. package/dist/components/ui/rich-markdown-renderer.d.ts.map +0 -1
  255. package/dist/utils/page-header-constants.d.ts +0 -15
  256. package/dist/utils/page-header-constants.d.ts.map +0 -1
  257. package/dist/utils/social-embed-cache.d.ts +0 -29
  258. package/dist/utils/social-embed-cache.d.ts.map +0 -1
  259. package/src/components/case-studies/index.ts +0 -4
  260. package/src/components/case-studies/share-experience-section.tsx +0 -185
  261. package/src/components/docs/docs-hub-page.tsx +0 -149
  262. package/src/components/docs/skeletons.tsx +0 -138
  263. package/src/components/docs/use-docs-resolve-link.ts +0 -52
  264. package/src/components/embeds/embed-container.tsx +0 -80
  265. package/src/components/embeds/file-download-card.tsx +0 -54
  266. package/src/components/embeds/linkedin-embed-client.tsx +0 -100
  267. package/src/components/embeds/markdown-image.tsx +0 -88
  268. package/src/components/embeds/reddit-embed-client.tsx +0 -550
  269. package/src/components/embeds/rich-markdown-runtime.tsx +0 -79
  270. package/src/components/embeds/twitter-embed-client.tsx +0 -308
  271. package/src/components/layout/page-header.tsx +0 -182
  272. package/src/components/layout/page-with-header.tsx +0 -110
  273. package/src/components/ui/rich-markdown-renderer.tsx +0 -1203
  274. package/src/utils/page-header-constants.ts +0 -15
  275. package/src/utils/social-embed-cache.ts +0 -391
  276. /package/dist/{chunk-PI4WSYQV.js.map → chunk-3ZXUQQL4.js.map} +0 -0
@@ -1,17 +1,34 @@
1
1
  "use client";
2
+ import {
3
+ ELAPSED_MS_FIELD,
4
+ HONEYPOT_FIELD,
5
+ ToolTypeValues,
6
+ consumeAccessCode,
7
+ normalizeHashFragment,
8
+ scrollElementIntoView,
9
+ transformPlatformConfigsToOptions,
10
+ validateAccessCode,
11
+ validateAndConsumeAccessCode
12
+ } from "./chunk-OQ6X7ZOC.js";
2
13
  import {
3
14
  useRequiredEndpointsRuntime
4
15
  } from "./chunk-MJNXIEV2.js";
16
+ import {
17
+ createNatsClient
18
+ } from "./chunk-PHWQLKVE.js";
19
+ import {
20
+ contentFetch
21
+ } from "./chunk-3MCHAFHB.js";
22
+ import {
23
+ useDebounce
24
+ } from "./chunk-POKKCWKF.js";
5
25
  import {
6
26
  init_next_navigation,
7
27
  useRouter,
8
28
  useSearchParams
9
29
  } from "./chunk-PLJLE4A4.js";
10
30
  import {
11
- FlamingoLogo,
12
- MiamiCyberGangLogoFaceOnly,
13
- OpenFrameLogo,
14
- OpenmspLogo
31
+ OpenFrameLogo
15
32
  } from "./chunk-V4IIBNTA.js";
16
33
  import {
17
34
  cn,
@@ -26,108 +43,12 @@ import {
26
43
  TacticalRmmLogoIcon,
27
44
  XmarkIcon
28
45
  } from "./chunk-J7AV6H63.js";
29
- import {
30
- createNatsClient
31
- } from "./chunk-PHWQLKVE.js";
32
-
33
- // src/hooks/ui/use-auto-limit-tags.ts
34
- import { useCallback, useEffect, useRef, useState } from "react";
35
- function useAutoLimitTags({
36
- count,
37
- limitTags = "auto",
38
- placeholder = "",
39
- reserveInputWidth = true
40
- }) {
41
- const middleRef = useRef(null);
42
- const measureRef = useRef(null);
43
- const textMeasureRef = useRef(null);
44
- const badgeRef = useRef(null);
45
- const inputRef = useRef(null);
46
- const [visibleCount, setVisibleCount] = useState(count);
47
- const recalculate = useCallback(() => {
48
- if (limitTags !== "auto") {
49
- setVisibleCount(Math.min(limitTags, count));
50
- return;
51
- }
52
- const middle = middleRef.current;
53
- const measure = measureRef.current;
54
- if (!middle || !measure) {
55
- setVisibleCount(count);
56
- return;
57
- }
58
- if (count === 0) {
59
- setVisibleCount(0);
60
- return;
61
- }
62
- const cs = getComputedStyle(middle);
63
- const padL = parseFloat(cs.paddingLeft) || 0;
64
- const padR = parseFloat(cs.paddingRight) || 0;
65
- const gap = parseFloat(cs.gap) || 0;
66
- const middleW = middle.clientWidth;
67
- let inputReservedW = 0;
68
- let trailingGap = 0;
69
- if (reserveInputWidth) {
70
- const textW = textMeasureRef.current?.offsetWidth ?? 60;
71
- const inputMinW = inputRef.current ? parseFloat(getComputedStyle(inputRef.current).minWidth) || 60 : 60;
72
- inputReservedW = Math.max(textW + 8, inputMinW);
73
- trailingGap = gap;
74
- }
75
- const available = middleW - padL - padR - inputReservedW - trailingGap;
76
- const tagEls = Array.from(measure.children);
77
- const widths = tagEls.map((el) => el.offsetWidth);
78
- let total = 0;
79
- for (let i = 0; i < widths.length; i++) {
80
- total += widths[i] + (i > 0 ? gap : 0);
81
- }
82
- if (total <= available) {
83
- setVisibleCount(count);
84
- return;
85
- }
86
- const badgeW = badgeRef.current?.offsetWidth ?? 40;
87
- const spaceWithBadge = available - badgeW - gap;
88
- let used = 0;
89
- let fitCount = 0;
90
- for (let i = 0; i < widths.length; i++) {
91
- const need = widths[i] + (i > 0 ? gap : 0);
92
- if (used + need > spaceWithBadge) break;
93
- used += need;
94
- fitCount++;
95
- }
96
- setVisibleCount(Math.max(0, fitCount));
97
- }, [count, limitTags, placeholder, reserveInputWidth]);
98
- useEffect(() => {
99
- recalculate();
100
- }, [recalculate]);
101
- useEffect(() => {
102
- const el = middleRef.current;
103
- if (!el) return;
104
- const ro = new ResizeObserver(recalculate);
105
- ro.observe(el);
106
- return () => ro.disconnect();
107
- }, [recalculate]);
108
- return { visibleCount, middleRef, measureRef, textMeasureRef, badgeRef, inputRef };
109
- }
110
-
111
- // src/hooks/ui/use-debounce.ts
112
- import { useState as useState2, useEffect as useEffect2 } from "react";
113
- function useDebounce(value, delay = 500) {
114
- const [debouncedValue, setDebouncedValue] = useState2(value);
115
- useEffect2(() => {
116
- const timer = setTimeout(() => {
117
- setDebouncedValue(value);
118
- }, delay);
119
- return () => {
120
- clearTimeout(timer);
121
- };
122
- }, [value, delay]);
123
- return debouncedValue;
124
- }
125
46
 
126
47
  // src/hooks/ui/use-header-height.ts
127
- import { useEffect as useEffect3, useState as useState3 } from "react";
48
+ import { useEffect, useState } from "react";
128
49
  function useHeaderHeight(defaultHeight = 64) {
129
- const [height, setHeight] = useState3(defaultHeight);
130
- useEffect3(() => {
50
+ const [height, setHeight] = useState(defaultHeight);
51
+ useEffect(() => {
131
52
  const measure = () => {
132
53
  let total = 0;
133
54
  const header2 = document.querySelector("header");
@@ -166,22 +87,22 @@ function useHeaderHeight(defaultHeight = 64) {
166
87
  }
167
88
 
168
89
  // src/hooks/ui/use-horizontal-scrollbar.ts
169
- import { useRef as useRef2, useState as useState4, useCallback as useCallback2 } from "react";
90
+ import { useRef, useState as useState2, useCallback } from "react";
170
91
  function useHorizontalScrollbar() {
171
- const scrollElRef = useRef2(null);
172
- const trackRef = useRef2(null);
173
- const thumbRef = useRef2(null);
174
- const roRef = useRef2(null);
175
- const moRef = useRef2(null);
176
- const [thumbRatio, setThumbRatio] = useState4(0);
177
- const [canScrollLeft, setCanScrollLeft] = useState4(false);
178
- const [canScrollRight, setCanScrollRight] = useState4(false);
179
- const prevCanScrollLeftRef = useRef2(false);
180
- const prevCanScrollRightRef = useRef2(false);
181
- const isDraggingRef = useRef2(false);
182
- const dragStartRef = useRef2({ mouseX: 0, scrollLeft: 0 });
183
- const rafIdRef = useRef2(0);
184
- const syncThumbToDOM = useCallback2(() => {
92
+ const scrollElRef = useRef(null);
93
+ const trackRef = useRef(null);
94
+ const thumbRef = useRef(null);
95
+ const roRef = useRef(null);
96
+ const moRef = useRef(null);
97
+ const [thumbRatio, setThumbRatio] = useState2(0);
98
+ const [canScrollLeft, setCanScrollLeft] = useState2(false);
99
+ const [canScrollRight, setCanScrollRight] = useState2(false);
100
+ const prevCanScrollLeftRef = useRef(false);
101
+ const prevCanScrollRightRef = useRef(false);
102
+ const isDraggingRef = useRef(false);
103
+ const dragStartRef = useRef({ mouseX: 0, scrollLeft: 0 });
104
+ const rafIdRef = useRef(0);
105
+ const syncThumbToDOM = useCallback(() => {
185
106
  const el = scrollElRef.current;
186
107
  const thumb = thumbRef.current;
187
108
  if (!el || !thumb) return;
@@ -194,7 +115,7 @@ function useHorizontalScrollbar() {
194
115
  const fraction = Math.min(Math.max(el.scrollLeft, 0), maxScroll) / maxScroll;
195
116
  thumb.style.left = `${fraction * (1 - ratio) * 100}%`;
196
117
  }, []);
197
- const syncEdgeFades = useCallback2(() => {
118
+ const syncEdgeFades = useCallback(() => {
198
119
  const el = scrollElRef.current;
199
120
  if (!el) return;
200
121
  const maxScroll = el.scrollWidth - el.clientWidth;
@@ -222,7 +143,7 @@ function useHorizontalScrollbar() {
222
143
  setCanScrollRight(right);
223
144
  }
224
145
  }, []);
225
- const measure = useCallback2(() => {
146
+ const measure = useCallback(() => {
226
147
  const el = scrollElRef.current;
227
148
  if (!el) return;
228
149
  const ratio = el.clientWidth / el.scrollWidth;
@@ -230,7 +151,7 @@ function useHorizontalScrollbar() {
230
151
  syncThumbToDOM();
231
152
  syncEdgeFades();
232
153
  }, [syncThumbToDOM, syncEdgeFades]);
233
- const scrollRef = useCallback2((node) => {
154
+ const scrollRef = useCallback((node) => {
234
155
  if (roRef.current) {
235
156
  roRef.current.disconnect();
236
157
  roRef.current = null;
@@ -272,7 +193,7 @@ function useHorizontalScrollbar() {
272
193
  setCanScrollRight(false);
273
194
  }
274
195
  }, [measure, syncThumbToDOM, syncEdgeFades]);
275
- const onScroll = useCallback2(() => {
196
+ const onScroll = useCallback(() => {
276
197
  if (isDraggingRef.current) return;
277
198
  if (rafIdRef.current) cancelAnimationFrame(rafIdRef.current);
278
199
  rafIdRef.current = requestAnimationFrame(() => {
@@ -280,7 +201,7 @@ function useHorizontalScrollbar() {
280
201
  syncEdgeFades();
281
202
  });
282
203
  }, [syncThumbToDOM, syncEdgeFades]);
283
- const onTrackClick = useCallback2((e) => {
204
+ const onTrackClick = useCallback((e) => {
284
205
  if (e.target.closest("[data-scrollbar-thumb]")) return;
285
206
  const track = trackRef.current;
286
207
  const el = scrollElRef.current;
@@ -298,13 +219,13 @@ function useHorizontalScrollbar() {
298
219
  const targetScrollLeft = targetFraction * (el.scrollWidth - el.clientWidth);
299
220
  el.scrollTo({ left: targetScrollLeft, behavior: "smooth" });
300
221
  }, []);
301
- const onTrackWheel = useCallback2((e) => {
222
+ const onTrackWheel = useCallback((e) => {
302
223
  const el = scrollElRef.current;
303
224
  if (!el) return;
304
225
  e.preventDefault();
305
226
  el.scrollLeft += e.deltaX || e.deltaY;
306
227
  }, []);
307
- const onThumbPointerDown = useCallback2((e) => {
228
+ const onThumbPointerDown = useCallback((e) => {
308
229
  e.preventDefault();
309
230
  e.stopPropagation();
310
231
  const el = scrollElRef.current;
@@ -315,7 +236,7 @@ function useHorizontalScrollbar() {
315
236
  target.setPointerCapture(e.pointerId);
316
237
  target.style.cursor = "grabbing";
317
238
  }, []);
318
- const onThumbPointerMove = useCallback2((e) => {
239
+ const onThumbPointerMove = useCallback((e) => {
319
240
  if (!isDraggingRef.current) return;
320
241
  const el = scrollElRef.current;
321
242
  const track = trackRef.current;
@@ -335,7 +256,7 @@ function useHorizontalScrollbar() {
335
256
  syncThumbToDOM();
336
257
  syncEdgeFades();
337
258
  }, [syncThumbToDOM, syncEdgeFades]);
338
- const onThumbPointerUp = useCallback2((e) => {
259
+ const onThumbPointerUp = useCallback((e) => {
339
260
  isDraggingRef.current = false;
340
261
  const target = e.currentTarget;
341
262
  target.releasePointerCapture(e.pointerId);
@@ -358,7 +279,7 @@ function useHorizontalScrollbar() {
358
279
  }
359
280
 
360
281
  // src/hooks/ui/use-image-edge-color.ts
361
- import { useState as useState5, useEffect as useEffect4 } from "react";
282
+ import { useState as useState3, useEffect as useEffect2 } from "react";
362
283
  function extractEdgeColor(img) {
363
284
  const canvas = document.createElement("canvas");
364
285
  const ctx = canvas.getContext("2d");
@@ -414,8 +335,8 @@ function extractEdgeColor(img) {
414
335
  return `rgb(${r}, ${g}, ${b})`;
415
336
  }
416
337
  function useImageEdgeColor(imageUrl, fallback = "#000000") {
417
- const [color, setColor] = useState5(fallback);
418
- useEffect4(() => {
338
+ const [color, setColor] = useState3(fallback);
339
+ useEffect2(() => {
419
340
  if (!imageUrl) {
420
341
  setColor(fallback);
421
342
  return;
@@ -444,9 +365,9 @@ function useImageEdgeColor(imageUrl, fallback = "#000000") {
444
365
  }
445
366
 
446
367
  // src/hooks/ui/use-local-storage.ts
447
- import { useEffect as useEffect5, useRef as useRef3, useState as useState6 } from "react";
368
+ import { useEffect as useEffect3, useRef as useRef2, useState as useState4 } from "react";
448
369
  function useLocalStorage(key, initialValue) {
449
- const [storedValue, setStoredValue] = useState6(() => {
370
+ const [storedValue, setStoredValue] = useState4(() => {
450
371
  try {
451
372
  if (typeof window !== "undefined") {
452
373
  const item = window.localStorage.getItem(key);
@@ -457,9 +378,9 @@ function useLocalStorage(key, initialValue) {
457
378
  }
458
379
  return initialValue;
459
380
  });
460
- const isInitialized = useRef3(true);
461
- const isFromStorageEvent = useRef3(false);
462
- useEffect5(() => {
381
+ const isInitialized = useRef2(true);
382
+ const isFromStorageEvent = useRef2(false);
383
+ useEffect3(() => {
463
384
  if (!isInitialized.current) return;
464
385
  const handleStorageChange = (e) => {
465
386
  if (e.key === key && e.newValue !== null) {
@@ -498,7 +419,7 @@ function useLocalStorage(key, initialValue) {
498
419
  window.removeEventListener("localStorageUpdate", handleCustomStorageUpdate);
499
420
  };
500
421
  }, [key]);
501
- useEffect5(() => {
422
+ useEffect3(() => {
502
423
  if (!isInitialized.current) return;
503
424
  if (isFromStorageEvent.current) {
504
425
  isFromStorageEvent.current = false;
@@ -524,9 +445,9 @@ function useLocalStorage(key, initialValue) {
524
445
  }
525
446
 
526
447
  // src/hooks/ui/use-media-query.ts
527
- import { useLayoutEffect, useState as useState7 } from "react";
448
+ import { useLayoutEffect, useState as useState5 } from "react";
528
449
  function useMediaQuery(query) {
529
- const [matches, setMatches] = useState7(void 0);
450
+ const [matches, setMatches] = useState5(void 0);
530
451
  useLayoutEffect(() => {
531
452
  const matchMedia = window.matchMedia(query);
532
453
  const handleChange = () => {
@@ -559,24 +480,24 @@ function useLgUp() {
559
480
  }
560
481
 
561
482
  // src/hooks/ui/use-memoized-callback.ts
562
- import { useCallback as useCallback3, useRef as useRef4 } from "react";
483
+ import { useCallback as useCallback2, useRef as useRef3 } from "react";
563
484
  function useMemoizedCallback(callback, dependencies) {
564
- const callbackRef = useRef4(callback);
565
- const dependenciesRef = useRef4(dependencies);
485
+ const callbackRef = useRef3(callback);
486
+ const dependenciesRef = useRef3(dependencies);
566
487
  callbackRef.current = callback;
567
488
  const depsChanged = dependencies.some((dep, i) => !Object.is(dep, dependenciesRef.current[i]));
568
489
  if (depsChanged) {
569
490
  dependenciesRef.current = dependencies;
570
491
  }
571
- return useCallback3(((...args) => callbackRef.current(...args)), [depsChanged]);
492
+ return useCallback2(((...args) => callbackRef.current(...args)), [depsChanged]);
572
493
  }
573
494
 
574
495
  // src/hooks/ui/use-notification-permission.ts
575
- import { useCallback as useCallback4, useEffect as useEffect6, useState as useState8 } from "react";
496
+ import { useCallback as useCallback3, useEffect as useEffect4, useState as useState6 } from "react";
576
497
  function useNotificationPermission() {
577
- const [supported, setSupported] = useState8(false);
578
- const [permission, setPermission] = useState8("default");
579
- useEffect6(() => {
498
+ const [supported, setSupported] = useState6(false);
499
+ const [permission, setPermission] = useState6("default");
500
+ useEffect4(() => {
580
501
  if (typeof window === "undefined" || !("Notification" in window)) return;
581
502
  setSupported(true);
582
503
  const sync = () => setPermission(Notification.permission);
@@ -597,7 +518,7 @@ function useNotificationPermission() {
597
518
  window.removeEventListener("focus", sync);
598
519
  };
599
520
  }, []);
600
- const request = useCallback4(async () => {
521
+ const request = useCallback3(async () => {
601
522
  if (typeof window === "undefined" || !("Notification" in window)) {
602
523
  return "denied";
603
524
  }
@@ -612,7 +533,7 @@ function useNotificationPermission() {
612
533
  }
613
534
 
614
535
  // src/hooks/ui/use-onboarding-state.ts
615
- import { useState as useState9, useEffect as useEffect7, useCallback as useCallback5 } from "react";
536
+ import { useState as useState7, useEffect as useEffect5, useCallback as useCallback4 } from "react";
616
537
 
617
538
  // src/utils/onboarding-storage.ts
618
539
  var DEFAULT_STATE = {
@@ -687,9 +608,9 @@ function dismissOnboarding(key) {
687
608
 
688
609
  // src/hooks/ui/use-onboarding-state.ts
689
610
  function useOnboardingState(storageKey = "openframe-onboarding-state") {
690
- const [state, setState] = useState9(() => loadOnboardingState(storageKey));
691
- const [, forceUpdate] = useState9(0);
692
- useEffect7(() => {
611
+ const [state, setState] = useState7(() => loadOnboardingState(storageKey));
612
+ const [, forceUpdate] = useState7(0);
613
+ useEffect5(() => {
693
614
  const handleStorageUpdate = (e) => {
694
615
  if (e.detail.key === storageKey) {
695
616
  const newState = loadOnboardingState(storageKey);
@@ -703,38 +624,38 @@ function useOnboardingState(storageKey = "openframe-onboarding-state") {
703
624
  window.removeEventListener("localStorageUpdate", handleStorageUpdate);
704
625
  };
705
626
  }, [storageKey]);
706
- const markComplete = useCallback5((stepId) => {
627
+ const markComplete = useCallback4((stepId) => {
707
628
  console.log(`\u{1F3AF} markComplete called for: "${stepId}"`);
708
629
  const newState = markStepComplete(storageKey, stepId);
709
630
  setState(newState);
710
631
  forceUpdate((prev) => prev + 1);
711
632
  }, [storageKey]);
712
- const markSkipped = useCallback5((stepId) => {
633
+ const markSkipped = useCallback4((stepId) => {
713
634
  console.log(`\u23ED\uFE0F markSkipped called for: "${stepId}"`);
714
635
  const newState = markStepSkipped(storageKey, stepId);
715
636
  setState(newState);
716
637
  forceUpdate((prev) => prev + 1);
717
638
  }, [storageKey]);
718
- const dismissOnboarding2 = useCallback5(() => {
639
+ const dismissOnboarding2 = useCallback4(() => {
719
640
  console.log(`\u{1F6AB} dismissOnboarding called`);
720
641
  const newState = dismissOnboarding(storageKey);
721
642
  setState(newState);
722
643
  forceUpdate((prev) => prev + 1);
723
644
  }, [storageKey]);
724
- const markMultipleComplete2 = useCallback5((stepIds) => {
645
+ const markMultipleComplete2 = useCallback4((stepIds) => {
725
646
  console.log(`\u{1F3AF} markMultipleComplete called for:`, stepIds);
726
647
  const newState = markMultipleComplete(storageKey, stepIds);
727
648
  setState(newState);
728
649
  forceUpdate((prev) => prev + 1);
729
650
  console.log(`\u{1F4DD} State after batch:`, newState);
730
651
  }, [storageKey]);
731
- const isStepComplete = useCallback5((stepId) => {
652
+ const isStepComplete = useCallback4((stepId) => {
732
653
  return state.completedSteps.includes(stepId);
733
654
  }, [state.completedSteps]);
734
- const isStepSkipped = useCallback5((stepId) => {
655
+ const isStepSkipped = useCallback4((stepId) => {
735
656
  return state.skippedSteps.includes(stepId);
736
657
  }, [state.skippedSteps]);
737
- const allStepsComplete = useCallback5((steps) => {
658
+ const allStepsComplete = useCallback4((steps) => {
738
659
  return steps.every((step) => isStepComplete(step.id) || isStepSkipped(step.id));
739
660
  }, [isStepComplete, isStepSkipped]);
740
661
  return {
@@ -750,19 +671,19 @@ function useOnboardingState(storageKey = "openframe-onboarding-state") {
750
671
  }
751
672
 
752
673
  // src/hooks/ui/use-search.ts
753
- import { useState as useState10, useEffect as useEffect8, useCallback as useCallback6 } from "react";
674
+ import { useState as useState8, useEffect as useEffect6, useCallback as useCallback5 } from "react";
754
675
  function useSearch(config) {
755
676
  const { searchFn, mapResult, debounceMs = 300, minQueryLength = 2 } = config;
756
- const [query, setQuery] = useState10("");
757
- const [results, setResults] = useState10([]);
758
- const [isLoading, setIsLoading] = useState10(false);
759
- const [error, setError] = useState10(null);
677
+ const [query, setQuery] = useState8("");
678
+ const [results, setResults] = useState8([]);
679
+ const [isLoading, setIsLoading] = useState8(false);
680
+ const [error, setError] = useState8(null);
760
681
  const debouncedQuery = useDebounce(query, debounceMs);
761
- const clearResults = useCallback6(() => {
682
+ const clearResults = useCallback5(() => {
762
683
  setResults([]);
763
684
  setError(null);
764
685
  }, []);
765
- useEffect8(() => {
686
+ useEffect6(() => {
766
687
  if (!debouncedQuery || debouncedQuery.length < minQueryLength) {
767
688
  setResults([]);
768
689
  setIsLoading(false);
@@ -835,11 +756,11 @@ function useTablePagination(config) {
835
756
  }
836
757
 
837
758
  // src/hooks/ui/use-throttle.ts
838
- import { useState as useState11, useEffect as useEffect9, useRef as useRef5 } from "react";
759
+ import { useState as useState9, useEffect as useEffect7, useRef as useRef4 } from "react";
839
760
  function useThrottle(value, limit = 200) {
840
- const [throttledValue, setThrottledValue] = useState11(value);
841
- const lastUpdated = useRef5(Date.now());
842
- useEffect9(() => {
761
+ const [throttledValue, setThrottledValue] = useState9(value);
762
+ const lastUpdated = useRef4(Date.now());
763
+ useEffect7(() => {
843
764
  const now = Date.now();
844
765
  const elapsed = now - lastUpdated.current;
845
766
  if (elapsed >= limit) {
@@ -859,13 +780,13 @@ function useThrottle(value, limit = 200) {
859
780
  }
860
781
 
861
782
  // src/hooks/ui/use-window-size.ts
862
- import { useLayoutEffect as useLayoutEffect2, useState as useState12 } from "react";
783
+ import { useLayoutEffect as useLayoutEffect2, useState as useState10 } from "react";
863
784
  function useWindowSize() {
864
- const [windowSize, setWindowSize] = useState12({
785
+ const [windowSize, setWindowSize] = useState10({
865
786
  width: 0,
866
787
  height: 0
867
788
  });
868
- const [isClient, setIsClient] = useState12(false);
789
+ const [isClient, setIsClient] = useState10(false);
869
790
  useLayoutEffect2(() => {
870
791
  setIsClient(true);
871
792
  if (!isClient) return;
@@ -883,188 +804,14 @@ function useWindowSize() {
883
804
  }
884
805
 
885
806
  // src/hooks/platform/use-platform-config.ts
886
- import { useState as useState13, useEffect as useEffect10 } from "react";
887
-
888
- // src/utils/platform-config.tsx
889
- import { Globe } from "lucide-react";
890
- import { jsx } from "react/jsx-runtime";
891
- var platformIcons = {
892
- openframe: /* @__PURE__ */ jsx(OpenFrameLogo, { className: "h-5 w-5", lowerPathColor: "#FFC008", upperPathColor: "#ffffff" }),
893
- openmsp: /* @__PURE__ */ jsx(OpenmspLogo, { className: "h-5 w-5" }),
894
- flamingo: /* @__PURE__ */ jsx(FlamingoLogo, { className: "h-5 w-5", fill: "#EC4899" }),
895
- "flamingo-teaser": /* @__PURE__ */ jsx(FlamingoLogo, { className: "h-5 w-5", fill: "#EC4899" }),
896
- "marketing-hub": /* @__PURE__ */ jsx(FlamingoLogo, { className: "h-5 w-5", fill: "#F357BB" }),
897
- "product-hub": /* @__PURE__ */ jsx(FlamingoLogo, { className: "h-5 w-5", fill: "#5EA62E" }),
898
- "revenue-hub": /* @__PURE__ */ jsx(FlamingoLogo, { className: "h-5 w-5", fill: "#FFC008" }),
899
- "people-hub": /* @__PURE__ */ jsx(FlamingoLogo, { className: "h-5 w-5", fill: "#5EFAF0" }),
900
- "company-hub": /* @__PURE__ */ jsx(FlamingoLogo, { className: "h-5 w-5", fill: "#f36666" }),
901
- tmcg: /* @__PURE__ */ jsx(MiamiCyberGangLogoFaceOnly, { className: "h-5 w-5" }),
902
- universal: /* @__PURE__ */ jsx(Globe, { className: "h-5 w-5 text-[#10B981]" })
903
- };
904
- var platformColors = {
905
- openmsp: "bg-[#3B82F6]",
906
- openframe: "bg-[#8B5CF6]",
907
- flamingo: "bg-[#EC4899]",
908
- "flamingo-teaser": "bg-[#F59E0B]",
909
- "marketing-hub": "bg-[#F357BB]",
910
- "product-hub": "bg-[#5EA62E]",
911
- "revenue-hub": "bg-[#FFC008]",
912
- "people-hub": "bg-[#5EFAF0]",
913
- "company-hub": "bg-[#f36666]",
914
- tmcg: "bg-[#FF6B6B]",
915
- universal: "bg-[#10B981]"
916
- };
917
- var platformDisplayNames = {
918
- openmsp: "OpenMSP",
919
- openframe: "OpenFrame",
920
- flamingo: "Flamingo",
921
- "flamingo-teaser": "Flamingo Teaser",
922
- "marketing-hub": "Flamingo Marketing Hub",
923
- "product-hub": "Flamingo Product Hub",
924
- "revenue-hub": "Flamingo Revenue Hub",
925
- "people-hub": "Flamingo People Hub",
926
- "company-hub": "Flamingo Company Hub",
927
- tmcg: "TMCG",
928
- universal: "Universal"
929
- };
930
- var platformDescriptions = {
931
- openmsp: "Comprehensive directory and comparison platform for managed service providers (MSPs) and technology vendors. Reduce vendor costs and discover open-source alternatives.",
932
- openframe: "AI-driven open-source security operations center (SOC) and endpoint detection platform for MSPs.",
933
- flamingo: "AI-driven open-source OS for MSPs. Swap bloated vendor tools for open ones. Automate the boring crap. Take your margin back.",
934
- "flamingo-teaser": "Preview of Flamingo - the AI-driven open-source OS for MSPs.",
935
- tmcg: "The Miami Cyber Gang - A cybersecurity community focused on education and collaboration.",
936
- universal: "Cross-platform universal content."
937
- };
938
- var platformSlogans = {
939
- openmsp: "Find Your Perfect MSP Partner",
940
- openframe: "Open-Source Security Operations",
941
- flamingo: "Open-Source OS for MSPs",
942
- "flamingo-teaser": "Coming Soon: Open-Source OS for MSPs",
943
- tmcg: "Miami Cyber Community",
944
- universal: "Universal Platform"
945
- };
946
- var platformHexColors = {
947
- openmsp: "#FFC008",
948
- openframe: "#FFC008",
949
- flamingo: "#FF6B9D",
950
- universal: "#FFC008",
951
- "flamingo-teaser": "#F59E0B",
952
- "marketing-hub": "#F357BB",
953
- "product-hub": "#5EA62E",
954
- "revenue-hub": "#FFC008",
955
- "people-hub": "#5EFAF0",
956
- "company-hub": "#f36666",
957
- tmcg: "#FF6B6B"
958
- };
959
- var platformIconNames = {
960
- openmsp: "openmsp-logo",
961
- openframe: "openframe-logo",
962
- flamingo: "flamingo-logo",
963
- universal: "globe",
964
- "flamingo-teaser": "flamingo-logo",
965
- "marketing-hub": "flamingo-logo",
966
- "product-hub": "flamingo-logo",
967
- "revenue-hub": "flamingo-logo",
968
- "people-hub": "flamingo-logo",
969
- "company-hub": "flamingo-logo",
970
- tmcg: "tmcg-logo"
971
- };
972
- function getDefaultColorForPlatform(platformName) {
973
- return platformHexColors[platformName] || platformHexColors.universal;
974
- }
975
- function getDefaultIconForPlatform(platformName) {
976
- return platformIconNames[platformName] || platformIconNames.universal;
977
- }
978
- function transformPlatformConfigsToOptions(platformConfigs) {
979
- return platformConfigs.map((platform) => ({
980
- id: platform.id,
981
- // Database UUID for matching
982
- name: platform.name,
983
- // Platform name enum
984
- displayName: platform.display_name,
985
- // Human-readable name
986
- description: platform.description,
987
- icon: platformIcons[platform.name] || platformIcons.universal,
988
- color: platformColors[platform.name] || platformColors.universal
989
- }));
990
- }
991
- function getPlatformIcon(platformName) {
992
- return platformIcons[platformName] || platformIcons.universal;
993
- }
994
- function getPlatformColor(platformName) {
995
- return platformColors[platformName] || platformColors.universal;
996
- }
997
- function getPlatformDisplayName(platformName) {
998
- return platformDisplayNames[platformName] || platformName;
999
- }
1000
- function getPlatformDescription(platformName) {
1001
- return platformDescriptions[platformName] || platformName;
1002
- }
1003
- function getPlatformSlogan(platformName) {
1004
- return platformSlogans[platformName] || platformName;
1005
- }
1006
- function getSmallPlatformIcon(platformName) {
1007
- const className = "h-4 w-4 flex-shrink-0";
1008
- switch (platformName) {
1009
- case "openframe":
1010
- return /* @__PURE__ */ jsx(OpenFrameLogo, { className, lowerPathColor: "#FFC008", upperPathColor: "#ffffff" });
1011
- case "openmsp":
1012
- return /* @__PURE__ */ jsx(OpenmspLogo, { className, frontBubbleColor: "#f1f1f1", innerFrontBubbleColor: "#000000", backBubbleColor: "#FFC008" });
1013
- case "flamingo":
1014
- case "flamingo-teaser":
1015
- return /* @__PURE__ */ jsx(FlamingoLogo, { className: `${className}`, fill: "#EC4899" });
1016
- case "marketing-hub":
1017
- return /* @__PURE__ */ jsx(FlamingoLogo, { className, fill: "var(--ods-flamingo-pink-base)" });
1018
- case "product-hub":
1019
- return /* @__PURE__ */ jsx(FlamingoLogo, { className, fill: "var(--ods-attention-green-success)" });
1020
- case "revenue-hub":
1021
- return /* @__PURE__ */ jsx(FlamingoLogo, { className, fill: "var(--ods-attention-yellow-warning)" });
1022
- case "people-hub":
1023
- return /* @__PURE__ */ jsx(FlamingoLogo, { className, fill: "var(--ods-flamingo-cyan-base)" });
1024
- case "company-hub":
1025
- return /* @__PURE__ */ jsx(FlamingoLogo, { className, fill: "var(--ods-attention-red-error)" });
1026
- case "tmcg":
1027
- return /* @__PURE__ */ jsx(MiamiCyberGangLogoFaceOnly, { className });
1028
- case "universal":
1029
- default:
1030
- return /* @__PURE__ */ jsx(Globe, { className });
1031
- }
1032
- }
1033
- function getPlatformIconComponent(platformName, className = "h-6 w-6") {
1034
- switch (platformName) {
1035
- case "openframe":
1036
- return /* @__PURE__ */ jsx(OpenFrameLogo, { className });
1037
- case "openmsp":
1038
- return /* @__PURE__ */ jsx(OpenmspLogo, { className, color: "#f1f1f1" });
1039
- case "flamingo":
1040
- case "flamingo-teaser":
1041
- return /* @__PURE__ */ jsx(FlamingoLogo, { className: `${className} text-white` });
1042
- case "marketing-hub":
1043
- return /* @__PURE__ */ jsx(FlamingoLogo, { className, fill: "var(--ods-flamingo-pink-base)" });
1044
- case "product-hub":
1045
- return /* @__PURE__ */ jsx(FlamingoLogo, { className, fill: "var(--ods-attention-green-success)" });
1046
- case "revenue-hub":
1047
- return /* @__PURE__ */ jsx(FlamingoLogo, { className, fill: "var(--ods-attention-yellow-warning)" });
1048
- case "people-hub":
1049
- return /* @__PURE__ */ jsx(FlamingoLogo, { className, fill: "var(--ods-flamingo-cyan-base)" });
1050
- case "company-hub":
1051
- return /* @__PURE__ */ jsx(FlamingoLogo, { className, fill: "var(--ods-attention-red-error)" });
1052
- case "tmcg":
1053
- return /* @__PURE__ */ jsx(MiamiCyberGangLogoFaceOnly, { size: 24, className });
1054
- case "universal":
1055
- default:
1056
- return /* @__PURE__ */ jsx(Globe, { className });
1057
- }
1058
- }
1059
-
1060
- // src/hooks/platform/use-platform-config.ts
807
+ import { useState as useState11, useEffect as useEffect8 } from "react";
1061
808
  var platformCache = null;
1062
809
  var fetchPromise = null;
1063
810
  function usePlatformConfig() {
1064
- const [platforms, setPlatforms] = useState13(platformCache || []);
1065
- const [isLoading, setIsLoading] = useState13(!platformCache);
1066
- const [error, setError] = useState13(null);
1067
- useEffect10(() => {
811
+ const [platforms, setPlatforms] = useState11(platformCache || []);
812
+ const [isLoading, setIsLoading] = useState11(!platformCache);
813
+ const [error, setError] = useState11(null);
814
+ useEffect8(() => {
1068
815
  if (platformCache) {
1069
816
  setPlatforms(platformCache);
1070
817
  setIsLoading(false);
@@ -1135,35 +882,11 @@ import { toast as sonnerToast2 } from "sonner";
1135
882
  import * as React from "react";
1136
883
  import { Toaster as SonnerToaster, toast as sonnerToast } from "sonner";
1137
884
 
1138
- // src/types/tool.types.ts
1139
- var ToolTypeValues = {
1140
- TACTICAL_RMM: "TACTICAL_RMM",
1141
- FLEET_MDM: "FLEET_MDM",
1142
- MESHCENTRAL: "MESHCENTRAL",
1143
- AUTHENTIK: "AUTHENTIK",
1144
- OPENFRAME: "OPENFRAME",
1145
- OPENFRAME_CHAT: "OPENFRAME_CHAT",
1146
- OPENFRAME_CLIENT: "OPENFRAME_CLIENT",
1147
- OSQUERY: "OSQUERY",
1148
- SYSTEM: "SYSTEM"
1149
- };
1150
- var toolLabels = {
1151
- TACTICAL_RMM: "Tactical",
1152
- FLEET_MDM: "Fleet",
1153
- MESHCENTRAL: "MeshCentral",
1154
- AUTHENTIK: "Authentik",
1155
- OPENFRAME: "OpenFrame",
1156
- OPENFRAME_CHAT: "OpenFrame Chat",
1157
- OPENFRAME_CLIENT: "OpenFrame Client",
1158
- OSQUERY: "Osquery",
1159
- SYSTEM: "System"
1160
- };
1161
-
1162
885
  // src/components/tool-icon.tsx
1163
- import { Fragment, jsx as jsx2 } from "react/jsx-runtime";
886
+ import { Fragment, jsx } from "react/jsx-runtime";
1164
887
  var renderOpenFrameLogo = (_size, className) => (
1165
888
  // eslint-disable-next-line deprecation/deprecation
1166
- /* @__PURE__ */ jsx2(
889
+ /* @__PURE__ */ jsx(
1167
890
  OpenFrameLogo,
1168
891
  {
1169
892
  className: className ?? "h-4 w-auto",
@@ -1173,22 +896,22 @@ var renderOpenFrameLogo = (_size, className) => (
1173
896
  )
1174
897
  );
1175
898
  var toolIconMap = {
1176
- [ToolTypeValues.FLEET_MDM]: (size, className) => /* @__PURE__ */ jsx2(FleetMdmLogoGreyIcon, { size, className }),
1177
- [ToolTypeValues.MESHCENTRAL]: (size, className) => /* @__PURE__ */ jsx2(MeshcentralLogoGreyIcon, { size, className }),
1178
- [ToolTypeValues.TACTICAL_RMM]: (size, className) => /* @__PURE__ */ jsx2(TacticalRmmLogoIcon, { size, className }),
899
+ [ToolTypeValues.FLEET_MDM]: (size, className) => /* @__PURE__ */ jsx(FleetMdmLogoGreyIcon, { size, className }),
900
+ [ToolTypeValues.MESHCENTRAL]: (size, className) => /* @__PURE__ */ jsx(MeshcentralLogoGreyIcon, { size, className }),
901
+ [ToolTypeValues.TACTICAL_RMM]: (size, className) => /* @__PURE__ */ jsx(TacticalRmmLogoIcon, { size, className }),
1179
902
  [ToolTypeValues.OPENFRAME]: renderOpenFrameLogo,
1180
903
  [ToolTypeValues.OPENFRAME_CHAT]: renderOpenFrameLogo,
1181
904
  [ToolTypeValues.OPENFRAME_CLIENT]: renderOpenFrameLogo,
1182
- [ToolTypeValues.AUTHENTIK]: (size, className) => /* @__PURE__ */ jsx2(AuthentikLogoGreyIcon, { size, className }),
1183
- [ToolTypeValues.OSQUERY]: (size, className) => /* @__PURE__ */ jsx2(OsqueryLogoGreyIcon, { size, className }),
905
+ [ToolTypeValues.AUTHENTIK]: (size, className) => /* @__PURE__ */ jsx(AuthentikLogoGreyIcon, { size, className }),
906
+ [ToolTypeValues.OSQUERY]: (size, className) => /* @__PURE__ */ jsx(OsqueryLogoGreyIcon, { size, className }),
1184
907
  [ToolTypeValues.SYSTEM]: () => null
1185
908
  };
1186
- var ToolIcon = ({ toolType, size = 16, className }) => /* @__PURE__ */ jsx2(Fragment, { children: toolIconMap[toolType]?.(size, className) ?? null });
909
+ var ToolIcon = ({ toolType, size = 16, className }) => /* @__PURE__ */ jsx(Fragment, { children: toolIconMap[toolType]?.(size, className) ?? null });
1187
910
  ToolIcon.displayName = "ToolIcon";
1188
911
 
1189
912
  // src/components/ui/toaster.tsx
1190
913
  init_cn();
1191
- import { Fragment as Fragment2, jsx as jsx3, jsxs } from "react/jsx-runtime";
914
+ import { Fragment as Fragment2, jsx as jsx2, jsxs } from "react/jsx-runtime";
1192
915
  var dotColorByVariant = {
1193
916
  default: "bg-ods-text-secondary",
1194
917
  success: "bg-ods-success",
@@ -1221,22 +944,22 @@ function ToastHeader({
1221
944
  className
1222
945
  ),
1223
946
  children: [
1224
- /* @__PURE__ */ jsx3("div", { className: "flex size-6 shrink-0 items-center justify-center", children: /* @__PURE__ */ jsx3("span", { className: cn("size-[9px] rounded-full", dotColorByVariant[variant]) }) }),
947
+ /* @__PURE__ */ jsx2("div", { className: "flex size-6 shrink-0 items-center justify-center", children: /* @__PURE__ */ jsx2("span", { className: cn("size-[9px] rounded-full", dotColorByVariant[variant]) }) }),
1225
948
  /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-1 flex-col justify-center font-['DM_Sans'] font-medium", children: [
1226
- title ? /* @__PURE__ */ jsx3("p", { className: "truncate pr-5 text-[18px] leading-6 text-ods-text-primary", title: typeof title === "string" ? title : void 0, children: title }) : null,
1227
- description ? /* @__PURE__ */ jsx3("p", { className: "text-[14px] leading-5 text-ods-text-secondary line-clamp-3", title: typeof description === "string" ? description : void 0, children: description }) : null
949
+ title ? /* @__PURE__ */ jsx2("p", { className: "truncate pr-5 text-[18px] leading-6 text-ods-text-primary", title: typeof title === "string" ? title : void 0, children: title }) : null,
950
+ description ? /* @__PURE__ */ jsx2("p", { className: "text-[14px] leading-5 text-ods-text-secondary line-clamp-3", title: typeof description === "string" ? description : void 0, children: description }) : null
1228
951
  ] }),
1229
- dismissible ? /* @__PURE__ */ jsx3(
952
+ dismissible ? /* @__PURE__ */ jsx2(
1230
953
  "button",
1231
954
  {
1232
955
  type: "button",
1233
956
  "aria-label": "Close",
1234
957
  onClick: () => sonnerToast.dismiss(id),
1235
958
  className: "absolute right-[7px] top-[7px] flex size-4 items-center justify-center text-ods-text-secondary transition-colors hover:text-ods-text-primary",
1236
- children: /* @__PURE__ */ jsx3(XmarkIcon, { size: 16 })
959
+ children: /* @__PURE__ */ jsx2(XmarkIcon, { size: 16 })
1237
960
  }
1238
961
  ) : null,
1239
- showProgress && duration !== Infinity && duration > 0 ? /* @__PURE__ */ jsx3(
962
+ showProgress && duration !== Infinity && duration > 0 ? /* @__PURE__ */ jsx2(
1240
963
  "div",
1241
964
  {
1242
965
  className: cn(
@@ -1261,7 +984,7 @@ function ToastCard({
1261
984
  dismissible = true,
1262
985
  className
1263
986
  }) {
1264
- return /* @__PURE__ */ jsx3(
987
+ return /* @__PURE__ */ jsx2(
1265
988
  "div",
1266
989
  {
1267
990
  role: "status",
@@ -1269,7 +992,7 @@ function ToastCard({
1269
992
  "w-[368px] max-w-[calc(100vw-32px)] overflow-hidden rounded-md border border-ods-border bg-ods-card shadow-lg",
1270
993
  className
1271
994
  ),
1272
- children: /* @__PURE__ */ jsx3(
995
+ children: /* @__PURE__ */ jsx2(
1273
996
  ToastHeader,
1274
997
  {
1275
998
  id,
@@ -1318,7 +1041,7 @@ function CommandApprovalToast({
1318
1041
  className
1319
1042
  ),
1320
1043
  children: [
1321
- /* @__PURE__ */ jsx3(
1044
+ /* @__PURE__ */ jsx2(
1322
1045
  ToastHeader,
1323
1046
  {
1324
1047
  id,
@@ -1331,7 +1054,7 @@ function CommandApprovalToast({
1331
1054
  className: "border-b border-ods-border"
1332
1055
  }
1333
1056
  ),
1334
- /* @__PURE__ */ jsx3(
1057
+ /* @__PURE__ */ jsx2(
1335
1058
  "div",
1336
1059
  {
1337
1060
  className: "grid transition-[grid-template-rows] duration-300 ease-out",
@@ -1339,13 +1062,13 @@ function CommandApprovalToast({
1339
1062
  "aria-hidden": !expanded,
1340
1063
  children: /* @__PURE__ */ jsxs("div", { className: "overflow-hidden", children: [
1341
1064
  /* @__PURE__ */ jsxs("div", { className: "flex h-11 w-full items-center gap-2 border-b border-ods-border bg-ods-card px-3 py-2", children: [
1342
- /* @__PURE__ */ jsx3("p", { className: "min-w-0 flex-1 truncate font-['DM_Sans'] text-[14px] font-medium leading-5 text-ods-text-primary", title: command, children: command }),
1343
- toolType ? /* @__PURE__ */ jsx3(ToolIcon, { toolType, size: 16 }) : null
1065
+ /* @__PURE__ */ jsx2("p", { className: "min-w-0 flex-1 truncate font-['DM_Sans'] text-[14px] font-medium leading-5 text-ods-text-primary", title: command, children: command }),
1066
+ toolType ? /* @__PURE__ */ jsx2(ToolIcon, { toolType, size: 16 }) : null
1344
1067
  ] }),
1345
1068
  /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2 bg-ods-bg p-3", children: [
1346
- approvalDescription ? /* @__PURE__ */ jsx3("p", { className: "font-['DM_Sans'] text-[14px] font-medium leading-5 text-ods-text-secondary", children: approvalDescription }) : null,
1069
+ approvalDescription ? /* @__PURE__ */ jsx2("p", { className: "font-['DM_Sans'] text-[14px] font-medium leading-5 text-ods-text-secondary", children: approvalDescription }) : null,
1347
1070
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-4", children: [
1348
- /* @__PURE__ */ jsx3(
1071
+ /* @__PURE__ */ jsx2(
1349
1072
  "button",
1350
1073
  {
1351
1074
  type: "button",
@@ -1355,7 +1078,7 @@ function CommandApprovalToast({
1355
1078
  children: approveLabel
1356
1079
  }
1357
1080
  ),
1358
- /* @__PURE__ */ jsx3(
1081
+ /* @__PURE__ */ jsx2(
1359
1082
  "button",
1360
1083
  {
1361
1084
  type: "button",
@@ -1378,8 +1101,8 @@ function CommandApprovalToast({
1378
1101
  className: "flex w-full items-center gap-2 bg-ods-card px-3 py-2 text-left font-['DM_Sans'] text-[14px] font-medium leading-5 text-ods-text-primary transition-colors hover:bg-ods-bg-hover",
1379
1102
  "aria-expanded": false,
1380
1103
  children: [
1381
- /* @__PURE__ */ jsx3("span", { className: "flex-1", children: "Show Command" }),
1382
- /* @__PURE__ */ jsx3(Chevron02DownIcon, { size: 16 })
1104
+ /* @__PURE__ */ jsx2("span", { className: "flex-1", children: "Show Command" }),
1105
+ /* @__PURE__ */ jsx2(Chevron02DownIcon, { size: 16 })
1383
1106
  ]
1384
1107
  }
1385
1108
  )
@@ -1396,13 +1119,13 @@ function Toaster({
1396
1119
  } = {}) {
1397
1120
  const { classNames: userClassNames, ...restToastOptions } = toastOptions ?? {};
1398
1121
  return /* @__PURE__ */ jsxs(Fragment2, { children: [
1399
- /* @__PURE__ */ jsx3("style", { children: `
1122
+ /* @__PURE__ */ jsx2("style", { children: `
1400
1123
  @keyframes toast-progress {
1401
1124
  from { transform: scaleX(1); }
1402
1125
  to { transform: scaleX(0); }
1403
1126
  }
1404
1127
  ` }),
1405
- /* @__PURE__ */ jsx3(
1128
+ /* @__PURE__ */ jsx2(
1406
1129
  SonnerToaster,
1407
1130
  {
1408
1131
  position,
@@ -1432,7 +1155,7 @@ function showToast(options) {
1432
1155
  ...rest
1433
1156
  } = opts;
1434
1157
  return sonnerToast.custom(
1435
- (id) => /* @__PURE__ */ jsx3(
1158
+ (id) => /* @__PURE__ */ jsx2(
1436
1159
  ToastCard,
1437
1160
  {
1438
1161
  id,
@@ -1464,7 +1187,7 @@ function showCommandApprovalToast(options) {
1464
1187
  ...rest
1465
1188
  } = options;
1466
1189
  return sonnerToast.custom(
1467
- (id) => /* @__PURE__ */ jsx3(
1190
+ (id) => /* @__PURE__ */ jsx2(
1468
1191
  CommandApprovalToast,
1469
1192
  {
1470
1193
  id,
@@ -1513,270 +1236,16 @@ var useToast = () => ({
1513
1236
  });
1514
1237
 
1515
1238
  // src/hooks/use-contact-submission.ts
1516
- import { useState as useState15, useCallback as useCallback7, useEffect as useEffect11 } from "react";
1239
+ import { useState as useState13, useCallback as useCallback6, useEffect as useEffect9 } from "react";
1517
1240
  init_next_navigation();
1518
-
1519
- // src/utils/local-storage-adapter.ts
1520
- function getStorage(backend) {
1521
- if (typeof window === "undefined") return null;
1522
- try {
1523
- return backend === "session" ? window.sessionStorage : window.localStorage;
1524
- } catch {
1525
- return null;
1526
- }
1527
- }
1528
- function createLocalStorageAdapter(options) {
1529
- const tag = options.logTag ?? "[local-storage]";
1530
- const backend = options.backend ?? "local";
1531
- const resolveKey = () => {
1532
- const ns = options.namespace?.();
1533
- return ns ? `${ns}.${options.key}` : options.key;
1534
- };
1535
- return {
1536
- resolveKey,
1537
- load() {
1538
- const storage = getStorage(backend);
1539
- if (!storage) return null;
1540
- try {
1541
- const raw = storage.getItem(resolveKey());
1542
- if (!raw) return null;
1543
- const parsed = JSON.parse(raw);
1544
- if (options.validate && !options.validate(parsed)) return null;
1545
- return parsed;
1546
- } catch (err) {
1547
- console.warn(`${tag} parse failed for key ${resolveKey()}:`, err);
1548
- return null;
1549
- }
1550
- },
1551
- save(value) {
1552
- const storage = getStorage(backend);
1553
- if (!storage) return;
1554
- try {
1555
- storage.setItem(resolveKey(), JSON.stringify(value));
1556
- } catch (err) {
1557
- console.warn(`${tag} write failed for key ${resolveKey()}:`, err);
1558
- }
1559
- },
1560
- clear() {
1561
- const storage = getStorage(backend);
1562
- if (!storage) return;
1563
- try {
1564
- storage.removeItem(resolveKey());
1565
- } catch (err) {
1566
- console.warn(`${tag} clear failed for key ${resolveKey()}:`, err);
1567
- }
1568
- }
1569
- };
1570
- }
1571
-
1572
- // src/utils/app-config.ts
1573
- function getAppType() {
1574
- return process.env.NEXT_PUBLIC_APP_TYPE || "openmsp";
1575
- }
1576
-
1577
- // src/utils/embed-proxy-auth-storage.ts
1578
- function isValidPersistedAuth(value) {
1579
- if (!value || typeof value !== "object") return false;
1580
- const v = value;
1581
- if (typeof v.secret !== "string" || v.secret.trim().length === 0 || typeof v.email !== "string" || v.email.trim().length === 0) return false;
1582
- if (v.firstName != null && typeof v.firstName !== "string") return false;
1583
- if (v.lastName != null && typeof v.lastName !== "string") return false;
1584
- if (v.avatarUrl != null && typeof v.avatarUrl !== "string") return false;
1585
- return true;
1586
- }
1587
- var adapter = createLocalStorageAdapter({
1588
- // Storage key unchanged from the legacy chat-prefixed helper. Renaming
1589
- // it would silently log every existing admin out — the key is a
1590
- // storage contract, not a code identifier.
1591
- key: "chat.proxy-auth.v1",
1592
- namespace: () => getAppType(),
1593
- validate: isValidPersistedAuth,
1594
- logTag: "[embed-proxy-auth-storage]",
1595
- // localStorage — survives tab close, new tabs, and browser restarts.
1596
- // Admin re-pasting creds every tab cycle was the dev-experience
1597
- // tradeoff prior `sessionStorage` setup demanded — rejected. See
1598
- // file-level doc comment for the security tradeoff rationale.
1599
- backend: "local"
1600
- });
1601
- function normalizeOptional(value) {
1602
- if (!value) return void 0;
1603
- const trimmed = value.trim();
1604
- return trimmed.length > 0 ? trimmed : void 0;
1605
- }
1606
- function getEmbedProxyAuth() {
1607
- const persisted = adapter.load();
1608
- if (!persisted) return null;
1609
- return {
1610
- secret: persisted.secret,
1611
- email: persisted.email.trim().toLowerCase(),
1612
- firstName: normalizeOptional(persisted.firstName),
1613
- lastName: normalizeOptional(persisted.lastName),
1614
- avatarUrl: normalizeOptional(persisted.avatarUrl)
1615
- };
1616
- }
1617
- function getPersistedProxyEmail() {
1618
- const persisted = adapter.load();
1619
- return persisted?.email.trim().toLowerCase() ?? null;
1620
- }
1621
- function setEmbedProxyAuth(value) {
1622
- adapter.save({
1623
- secret: value.secret,
1624
- email: value.email.trim().toLowerCase(),
1625
- firstName: normalizeOptional(value.firstName),
1626
- lastName: normalizeOptional(value.lastName),
1627
- avatarUrl: normalizeOptional(value.avatarUrl)
1628
- });
1629
- }
1630
- function clearEmbedProxyAuth() {
1631
- adapter.clear();
1632
- }
1633
- function applyProxyAuth(url, baseHeaders = { "Content-Type": "application/json" }) {
1634
- const auth = getEmbedProxyAuth();
1635
- const headers = { ...baseHeaders };
1636
- if (auth?.secret) {
1637
- headers.Authorization = `Bearer ${auth.secret}`;
1638
- }
1639
- if (auth?.email) {
1640
- headers["X-Chat-Act-As"] = auth.email;
1641
- }
1642
- if (auth?.firstName) headers["X-Chat-First-Name"] = auth.firstName;
1643
- if (auth?.lastName) headers["X-Chat-Last-Name"] = auth.lastName;
1644
- if (auth?.avatarUrl) headers["X-Chat-Avatar-Url"] = auth.avatarUrl;
1645
- return { url, headers };
1646
- }
1647
-
1648
- // src/utils/embed-authed-fetch.ts
1649
- var ADAPTER_GLOBAL_KEY = "__embedAuthedFetchAdapter__";
1650
- function getRegisteredAuthAdapter() {
1651
- if (typeof globalThis === "undefined") return null;
1652
- return globalThis[ADAPTER_GLOBAL_KEY] ?? null;
1653
- }
1654
- function storeRegisteredAuthAdapter(adapter2) {
1655
- if (typeof globalThis === "undefined") return;
1656
- globalThis[ADAPTER_GLOBAL_KEY] = adapter2;
1657
- }
1658
- function setEmbedAuthAdapter(adapter2) {
1659
- if (adapter2 && getRegisteredAuthAdapter() && process.env.NODE_ENV !== "production") {
1660
- console.warn(
1661
- "[setEmbedAuthAdapter] overwriting a previously-registered auth adapter. Two chat-runtime providers should not coexist \u2014 verify mount order and pass `null` from the unmounting provider."
1662
- );
1663
- }
1664
- storeRegisteredAuthAdapter(adapter2);
1665
- }
1666
- function hasEmbedAuthAdapter() {
1667
- return getRegisteredAuthAdapter() !== null;
1668
- }
1669
- function embedAuthedFetch(url, init = {}) {
1670
- assertSameOrigin(url);
1671
- let baseHeaders;
1672
- if (init.headers === void 0) {
1673
- baseHeaders = { "Content-Type": "application/json" };
1674
- } else {
1675
- baseHeaders = {};
1676
- if (init.headers instanceof Headers) {
1677
- init.headers.forEach((v, k) => {
1678
- baseHeaders[k] = v;
1679
- });
1680
- } else if (Array.isArray(init.headers)) {
1681
- for (const [k, v] of init.headers) baseHeaders[k] = v;
1682
- } else {
1683
- Object.assign(baseHeaders, init.headers);
1684
- }
1685
- }
1686
- return fetchWithRefresh(url, init, baseHeaders, false);
1687
- }
1688
- var IN_FLIGHT_REFRESH_GLOBAL_KEY = "__embedAuthedFetchInFlightRefresh__";
1689
- function getInFlightRefresh() {
1690
- if (typeof globalThis === "undefined") return null;
1691
- return globalThis[IN_FLIGHT_REFRESH_GLOBAL_KEY] ?? null;
1692
- }
1693
- function setInFlightRefresh(refresh) {
1694
- if (typeof globalThis === "undefined") return;
1695
- globalThis[IN_FLIGHT_REFRESH_GLOBAL_KEY] = refresh;
1696
- }
1697
- function dedupedRefresh() {
1698
- const adapter2 = getRegisteredAuthAdapter();
1699
- if (!adapter2?.refresh) return Promise.resolve(false);
1700
- let inFlightRefresh = getInFlightRefresh();
1701
- if (!inFlightRefresh) {
1702
- inFlightRefresh = Promise.resolve().then(() => adapter2.refresh()).catch(() => false).finally(() => {
1703
- setInFlightRefresh(null);
1704
- });
1705
- setInFlightRefresh(inFlightRefresh);
1706
- }
1707
- return inFlightRefresh;
1708
- }
1709
- async function fetchWithRefresh(url, init, baseHeaders, isRetry) {
1710
- const { url: authedUrl, headers } = applyProxyAuth(url, { ...baseHeaders });
1711
- const adapter2 = getRegisteredAuthAdapter();
1712
- if (adapter2?.getHeaders) {
1713
- for (const [k, v] of Object.entries(adapter2.getHeaders())) {
1714
- if (v !== void 0) headers[k] = v;
1715
- }
1716
- }
1717
- const credentials = adapter2?.credentials ?? init.credentials ?? "same-origin";
1718
- const response = await fetch(authedUrl, {
1719
- ...init,
1720
- headers,
1721
- // Default `same-origin` carries Supabase cookies for the MPH proxy-
1722
- // auth model. Hosts on different origins (openframe-frontend ↔
1723
- // openframe gateway) register `credentials: 'include'` via the
1724
- // adapter to make their own cookies travel cross-origin (CORS +
1725
- // `SameSite=None` must be configured server-side for that to work).
1726
- credentials
1727
- });
1728
- if (response.status === 401 && !isRetry && adapter2?.refresh) {
1729
- const refreshed = await dedupedRefresh();
1730
- if (refreshed) {
1731
- return fetchWithRefresh(url, init, baseHeaders, true);
1732
- }
1733
- }
1734
- return response;
1735
- }
1736
- function assertSameOrigin(url) {
1737
- if (typeof window === "undefined") return;
1738
- let target;
1739
- let pageOrigin;
1740
- try {
1741
- target = new URL(url, window.location.href);
1742
- pageOrigin = new URL(window.location.href).origin;
1743
- } catch {
1744
- throw new Error(`embedAuthedFetch: refusing to fetch malformed URL (${JSON.stringify(url)})`);
1745
- }
1746
- if (target.protocol !== "http:" && target.protocol !== "https:") {
1747
- throw new Error(
1748
- `embedAuthedFetch: refusing non-http(s) URL (${target.protocol}) \u2014 pass a relative /api/* path instead`
1749
- );
1750
- }
1751
- if (target.origin !== pageOrigin) {
1752
- if (process.env.NODE_ENV !== "production") {
1753
- console.warn(
1754
- `[embedAuthedFetch] cross-origin fetch to ${target.origin} allowed in dev (NODE_ENV !== 'production'). Production builds will reject this \u2014 wire a same-origin proxy before shipping.`
1755
- );
1756
- return;
1757
- }
1758
- throw new Error(
1759
- `embedAuthedFetch: refusing cross-origin fetch to ${target.origin} \u2014 pass a relative /api/* path instead`
1760
- );
1761
- }
1762
- }
1763
-
1764
- // src/utils/embed-content-fetch.ts
1765
- var contentFetch = (input, init) => {
1766
- if (!hasEmbedAuthAdapter()) return fetch(input, init);
1767
- const url = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
1768
- return embedAuthedFetch(url, init);
1769
- };
1770
-
1771
- // src/hooks/use-contact-submission.ts
1772
1241
  function useContactSubmission(options = {}) {
1773
1242
  const { userId, successRedirectUrl, successToastMessage, onSuccess } = options;
1774
1243
  const { toast: toast2 } = useToast();
1775
1244
  const router = useRouter();
1776
1245
  const { contactUrl } = useRequiredEndpointsRuntime();
1777
- const [isSubmitting, setIsSubmitting] = useState15(false);
1778
- const [isSuccess, setIsSuccess] = useState15(false);
1779
- const submit = useCallback7(async (formData) => {
1246
+ const [isSubmitting, setIsSubmitting] = useState13(false);
1247
+ const [isSuccess, setIsSuccess] = useState13(false);
1248
+ const submit = useCallback6(async (formData) => {
1780
1249
  if (isSubmitting) return;
1781
1250
  setIsSubmitting(true);
1782
1251
  try {
@@ -1811,7 +1280,7 @@ function useContactSubmission(options = {}) {
1811
1280
  setIsSubmitting(false);
1812
1281
  }
1813
1282
  }, [isSubmitting, toast2, userId, successToastMessage, contactUrl]);
1814
- useEffect11(() => {
1283
+ useEffect9(() => {
1815
1284
  if (isSuccess && successRedirectUrl) {
1816
1285
  console.log("\u{1F680} Contact submission successful, redirecting to:", successRedirectUrl);
1817
1286
  const timer = setTimeout(() => {
@@ -1825,7 +1294,7 @@ function useContactSubmission(options = {}) {
1825
1294
  return () => clearTimeout(timer);
1826
1295
  }
1827
1296
  }, [isSuccess, successRedirectUrl, router]);
1828
- useEffect11(() => {
1297
+ useEffect9(() => {
1829
1298
  if (isSuccess && onSuccess) {
1830
1299
  onSuccess();
1831
1300
  }
@@ -1834,19 +1303,19 @@ function useContactSubmission(options = {}) {
1834
1303
  }
1835
1304
 
1836
1305
  // src/hooks/use-quick-action-hint.ts
1837
- import { useEffect as useEffect12, useState as useState16, useRef as useRef6, useCallback as useCallback8 } from "react";
1306
+ import { useEffect as useEffect10, useState as useState14, useRef as useRef5, useCallback as useCallback7 } from "react";
1838
1307
  function useQuickActionHint({
1839
1308
  actionCount,
1840
1309
  cycleDuration = 5e3,
1841
1310
  enabled = true
1842
1311
  }) {
1843
- const [activeHintIndex, setActiveHintIndex] = useState16(-1);
1844
- const containerRef = useRef6(null);
1845
- const timeoutRef = useRef6(null);
1846
- const cycleCountRef = useRef6(0);
1847
- const currentIndexRef = useRef6(0);
1848
- const sequenceRef = useRef6([]);
1849
- const shuffleIndices = useCallback8((length) => {
1312
+ const [activeHintIndex, setActiveHintIndex] = useState14(-1);
1313
+ const containerRef = useRef5(null);
1314
+ const timeoutRef = useRef5(null);
1315
+ const cycleCountRef = useRef5(0);
1316
+ const currentIndexRef = useRef5(0);
1317
+ const sequenceRef = useRef5([]);
1318
+ const shuffleIndices = useCallback7((length) => {
1850
1319
  const indices = Array.from({ length }, (_, i) => i);
1851
1320
  for (let i = indices.length - 1; i > 0; i--) {
1852
1321
  const j = Math.floor(Math.random() * (i + 1));
@@ -1854,7 +1323,7 @@ function useQuickActionHint({
1854
1323
  }
1855
1324
  return indices;
1856
1325
  }, []);
1857
- const stopHint = useCallback8(() => {
1326
+ const stopHint = useCallback7(() => {
1858
1327
  if (timeoutRef.current) {
1859
1328
  clearTimeout(timeoutRef.current);
1860
1329
  timeoutRef.current = null;
@@ -1864,7 +1333,7 @@ function useQuickActionHint({
1864
1333
  currentIndexRef.current = 0;
1865
1334
  sequenceRef.current = [];
1866
1335
  }, []);
1867
- const advanceHint = useCallback8(() => {
1336
+ const advanceHint = useCallback7(() => {
1868
1337
  if (currentIndexRef.current === 0) {
1869
1338
  sequenceRef.current = shuffleIndices(actionCount);
1870
1339
  }
@@ -1877,7 +1346,7 @@ function useQuickActionHint({
1877
1346
  }
1878
1347
  timeoutRef.current = setTimeout(advanceHint, cycleDuration);
1879
1348
  }, [actionCount, cycleDuration, shuffleIndices]);
1880
- useEffect12(() => {
1349
+ useEffect10(() => {
1881
1350
  if (!enabled || actionCount === 0) {
1882
1351
  return;
1883
1352
  }
@@ -1903,7 +1372,7 @@ function useQuickActionHint({
1903
1372
  }
1904
1373
 
1905
1374
  // src/hooks/use-copy-to-clipboard.ts
1906
- import { useCallback as useCallback9, useState as useState17 } from "react";
1375
+ import { useCallback as useCallback8, useState as useState15 } from "react";
1907
1376
  function useCopyToClipboard({
1908
1377
  successTitle = "Copied",
1909
1378
  successDescription = "Copied to clipboard",
@@ -1912,8 +1381,8 @@ function useCopyToClipboard({
1912
1381
  resetDelay = 2e3
1913
1382
  } = {}) {
1914
1383
  const { toast: toast2 } = useToast();
1915
- const [copied, setCopied] = useState17(false);
1916
- const copy = useCallback9(
1384
+ const [copied, setCopied] = useState15(false);
1385
+ const copy = useCallback8(
1917
1386
  async (text) => {
1918
1387
  try {
1919
1388
  await navigator.clipboard.writeText(text);
@@ -1930,7 +1399,7 @@ function useCopyToClipboard({
1930
1399
  }
1931
1400
 
1932
1401
  // src/hooks/use-batch-images.ts
1933
- import { useEffect as useEffect13, useMemo as useMemo2, useState as useState18, useRef as useRef7 } from "react";
1402
+ import { useEffect as useEffect11, useMemo as useMemo2, useState as useState16, useRef as useRef6 } from "react";
1934
1403
  var globalBatchImageConfig = {};
1935
1404
  function configureBatchImageFetch(config) {
1936
1405
  globalBatchImageConfig = { ...globalBatchImageConfig, ...config };
@@ -2003,14 +1472,14 @@ async function batchFetchAuthenticatedImages(imageUrls, config) {
2003
1472
  return results;
2004
1473
  }
2005
1474
  function useBatchImages(imageUrls, config) {
2006
- const [fetchedImages, setFetchedImages] = useState18({});
2007
- const [loading, setLoading] = useState18(false);
1475
+ const [fetchedImages, setFetchedImages] = useState16({});
1476
+ const [loading, setLoading] = useState16(false);
2008
1477
  const uniqueUrls = useMemo2(
2009
1478
  () => Array.from(new Set(imageUrls.filter((url) => Boolean(url)))),
2010
1479
  [imageUrls]
2011
1480
  );
2012
- const requestedUrls = useRef7(/* @__PURE__ */ new Set());
2013
- useEffect13(() => {
1481
+ const requestedUrls = useRef6(/* @__PURE__ */ new Set());
1482
+ useEffect11(() => {
2014
1483
  if (uniqueUrls.length === 0) {
2015
1484
  setFetchedImages({});
2016
1485
  return;
@@ -2040,7 +1509,7 @@ function useBatchImages(imageUrls, config) {
2040
1509
  }
2041
1510
 
2042
1511
  // src/hooks/use-authenticated-image.ts
2043
- import { useEffect as useEffect14, useState as useState19, useRef as useRef8 } from "react";
1512
+ import { useEffect as useEffect12, useState as useState17, useRef as useRef7 } from "react";
2044
1513
  var globalImageConfig = {};
2045
1514
  var imageCache = /* @__PURE__ */ new Map();
2046
1515
  var pendingRequests = /* @__PURE__ */ new Map();
@@ -2069,11 +1538,11 @@ function getImageConfig() {
2069
1538
  };
2070
1539
  }
2071
1540
  function useAuthenticatedImage(imageUrl, refreshKey, config) {
2072
- const [fetchedImageUrl, setFetchedImageUrl] = useState19();
2073
- const [isLoading, setIsLoading] = useState19(false);
2074
- const [error, setError] = useState19(null);
2075
- const currentCacheKeyRef = useRef8(null);
2076
- useEffect14(() => {
1541
+ const [fetchedImageUrl, setFetchedImageUrl] = useState17();
1542
+ const [isLoading, setIsLoading] = useState17(false);
1543
+ const [error, setError] = useState17(null);
1544
+ const currentCacheKeyRef = useRef7(null);
1545
+ useEffect12(() => {
2077
1546
  if (!imageUrl) {
2078
1547
  setFetchedImageUrl(void 0);
2079
1548
  setIsLoading(false);
@@ -2184,7 +1653,7 @@ function useAuthenticatedImage(imageUrl, refreshKey, config) {
2184
1653
  });
2185
1654
  pendingRequests.set(cacheKey, fetchPromise2);
2186
1655
  }, [imageUrl, refreshKey, config]);
2187
- useEffect14(() => {
1656
+ useEffect12(() => {
2188
1657
  return () => {
2189
1658
  if (currentCacheKeyRef.current) {
2190
1659
  const entry = imageCache.get(currentCacheKeyRef.current);
@@ -2199,7 +1668,7 @@ function useAuthenticatedImage(imageUrl, refreshKey, config) {
2199
1668
 
2200
1669
  // src/hooks/state/use-query-params.ts
2201
1670
  init_next_navigation();
2202
- import { useEffect as useEffect15, useState as useState20, useMemo as useMemo3, useCallback as useCallback10 } from "react";
1671
+ import { useEffect as useEffect13, useState as useState18, useMemo as useMemo3, useCallback as useCallback9 } from "react";
2203
1672
 
2204
1673
  // src/hooks/state/graphql-parser.ts
2205
1674
  import {
@@ -2661,14 +2130,14 @@ var introspector = new GraphQLIntrospector();
2661
2130
  function useQueryParams(query, options = {}) {
2662
2131
  const router = useRouter();
2663
2132
  const searchParams = useSearchParams();
2664
- const [isLoading, setIsLoading] = useState20(true);
2665
- const [isReady, setIsReady] = useState20(false);
2666
- const [error, setError] = useState20(null);
2667
- const [schema, setSchema] = useState20({});
2133
+ const [isLoading, setIsLoading] = useState18(true);
2134
+ const [isReady, setIsReady] = useState18(false);
2135
+ const [error, setError] = useState18(null);
2136
+ const [schema, setSchema] = useState18({});
2668
2137
  const defaultValues = options.defaultValues || {};
2669
2138
  const skipIntrospection = options.skipIntrospection || false;
2670
2139
  const debug = options.debug || false;
2671
- useEffect15(() => {
2140
+ useEffect13(() => {
2672
2141
  async function initialize() {
2673
2142
  try {
2674
2143
  if (debug) console.log("[useQueryParams] Initializing...");
@@ -2738,14 +2207,14 @@ function useQueryParams(query, options = {}) {
2738
2207
  });
2739
2208
  return result;
2740
2209
  }, [searchParams]);
2741
- const updateUrl = useCallback10((newParams) => {
2210
+ const updateUrl = useCallback9((newParams) => {
2742
2211
  const url = newParams.toString() ? `?${newParams.toString()}` : window.location.pathname;
2743
2212
  if (debug) {
2744
2213
  console.log("[useQueryParams] Updating URL:", url);
2745
2214
  }
2746
2215
  router.replace(url, { scroll: false });
2747
2216
  }, [router, debug]);
2748
- const setParam = useCallback10((key, value) => {
2217
+ const setParam = useCallback9((key, value) => {
2749
2218
  if (!isReady) {
2750
2219
  console.warn("[useQueryParams] Schema not ready, cannot set param");
2751
2220
  return;
@@ -2759,7 +2228,7 @@ function useQueryParams(query, options = {}) {
2759
2228
  console.error("[useQueryParams] Failed to set param:", err);
2760
2229
  }
2761
2230
  }, [variables, schema, isReady, updateUrl]);
2762
- const setParams = useCallback10((updates) => {
2231
+ const setParams = useCallback9((updates) => {
2763
2232
  if (!isReady) {
2764
2233
  console.warn("[useQueryParams] Schema not ready, cannot set params");
2765
2234
  return;
@@ -2773,7 +2242,7 @@ function useQueryParams(query, options = {}) {
2773
2242
  console.error("[useQueryParams] Failed to set params:", err);
2774
2243
  }
2775
2244
  }, [variables, schema, isReady, updateUrl]);
2776
- const clearParamsHandler = useCallback10((keys) => {
2245
+ const clearParamsHandler = useCallback9((keys) => {
2777
2246
  if (!isReady) {
2778
2247
  console.warn("[useQueryParams] Schema not ready, cannot clear params");
2779
2248
  return;
@@ -2787,7 +2256,7 @@ function useQueryParams(query, options = {}) {
2787
2256
  console.error("[useQueryParams] Failed to clear params:", err);
2788
2257
  }
2789
2258
  }, [variables, schema, isReady, updateUrl]);
2790
- const resetParams = useCallback10(() => {
2259
+ const resetParams = useCallback9(() => {
2791
2260
  if (debug) {
2792
2261
  console.log("[useQueryParams] Resetting params");
2793
2262
  }
@@ -2820,9 +2289,9 @@ function applyParamMapping(schema, mapping) {
2820
2289
 
2821
2290
  // src/hooks/state/use-api-params.ts
2822
2291
  init_next_navigation();
2823
- import { useCallback as useCallback11, useMemo as useMemo4, useRef as useRef9 } from "react";
2292
+ import { useCallback as useCallback10, useMemo as useMemo4, useRef as useRef8 } from "react";
2824
2293
  function useContentStable(value, key) {
2825
- const ref = useRef9(void 0);
2294
+ const ref = useRef8(void 0);
2826
2295
  if (ref.current && ref.current.key === key) return ref.current.value;
2827
2296
  ref.current = { value, key };
2828
2297
  return value;
@@ -2855,7 +2324,7 @@ function useApiParams(schema, options = {}) {
2855
2324
  }
2856
2325
  return flattened;
2857
2326
  }, [schemaKey]);
2858
- const prevParamsRef = useRef9(void 0);
2327
+ const prevParamsRef = useRef8(void 0);
2859
2328
  const params = useMemo4(() => {
2860
2329
  const sp = new URLSearchParams(searchString);
2861
2330
  const result = {};
@@ -2879,7 +2348,7 @@ function useApiParams(schema, options = {}) {
2879
2348
  prevParamsRef.current = result;
2880
2349
  return result;
2881
2350
  }, [searchString, schemaKey, debug]);
2882
- const addParamToSearchParams = useCallback11((searchParams, key, value) => {
2351
+ const addParamToSearchParams = useCallback10((searchParams, key, value) => {
2883
2352
  if (value === void 0 || value === "" || value === null) {
2884
2353
  return;
2885
2354
  }
@@ -2907,7 +2376,7 @@ function useApiParams(schema, options = {}) {
2907
2376
  }
2908
2377
  return newParams;
2909
2378
  }, [params, schemaKey, flattenedSchema, addParamToSearchParams]);
2910
- const updateUrl = useCallback11((newParams, keysToRemove = []) => {
2379
+ const updateUrl = useCallback10((newParams, keysToRemove = []) => {
2911
2380
  const finalParams = new URLSearchParams(searchString);
2912
2381
  keysToRemove.forEach((key) => {
2913
2382
  if (key in stableSchema) {
@@ -2943,7 +2412,7 @@ function useApiParams(schema, options = {}) {
2943
2412
  }
2944
2413
  return false;
2945
2414
  };
2946
- const setParam = useCallback11((key, value) => {
2415
+ const setParam = useCallback10((key, value) => {
2947
2416
  const config = stableSchema[key];
2948
2417
  if (!config) {
2949
2418
  console.warn(`[useApiParams] Unknown parameter: ${key}`);
@@ -2957,7 +2426,7 @@ function useApiParams(schema, options = {}) {
2957
2426
  updateUrl(newParams);
2958
2427
  }
2959
2428
  }, [schemaKey, updateUrl, addParamToSearchParams]);
2960
- const setParams = useCallback11((updates) => {
2429
+ const setParams = useCallback10((updates) => {
2961
2430
  const newParams = new URLSearchParams();
2962
2431
  const keysToRemove = [];
2963
2432
  for (const [key, value] of Object.entries(updates)) {
@@ -2974,11 +2443,11 @@ function useApiParams(schema, options = {}) {
2974
2443
  }
2975
2444
  updateUrl(newParams, keysToRemove);
2976
2445
  }, [schemaKey, updateUrl, addParamToSearchParams]);
2977
- const clearParams2 = useCallback11((keys) => {
2446
+ const clearParams2 = useCallback10((keys) => {
2978
2447
  const newParams = new URLSearchParams();
2979
2448
  updateUrl(newParams, keys);
2980
2449
  }, [updateUrl]);
2981
- const resetParams = useCallback11(() => {
2450
+ const resetParams = useCallback10(() => {
2982
2451
  if (debug) {
2983
2452
  console.log("[useApiParams] Resetting params");
2984
2453
  }
@@ -3015,7 +2484,7 @@ function createSearchParams(params) {
3015
2484
  }
3016
2485
 
3017
2486
  // src/hooks/state/use-cursor-pagination-state.ts
3018
- import { useCallback as useCallback12, useEffect as useEffect16, useRef as useRef10, useState as useState21 } from "react";
2487
+ import { useCallback as useCallback11, useEffect as useEffect14, useRef as useRef9, useState as useState19 } from "react";
3019
2488
  var urlSchema = {
3020
2489
  search: { type: "string", default: "" },
3021
2490
  cursor: { type: "string", default: "" }
@@ -3026,13 +2495,13 @@ function useCursorPaginationState(options) {
3026
2495
  onSearchChange
3027
2496
  } = options;
3028
2497
  const { params, setParam, setParams } = useApiParams(urlSchema);
3029
- const [searchInput, setSearchInput] = useState21(params.search || "");
3030
- const [hasLoadedBeyondFirst, setHasLoadedBeyondFirst] = useState21(false);
3031
- const [initialLoadCount, setInitialLoadCount] = useState21(0);
3032
- const lastSearchRef = useRef10(null);
3033
- const isSyncingFromUrl = useRef10(false);
3034
- const isInitialLoadInProgress = useRef10(true);
3035
- useEffect16(() => {
2498
+ const [searchInput, setSearchInput] = useState19(params.search || "");
2499
+ const [hasLoadedBeyondFirst, setHasLoadedBeyondFirst] = useState19(false);
2500
+ const [initialLoadCount, setInitialLoadCount] = useState19(0);
2501
+ const lastSearchRef = useRef9(null);
2502
+ const isSyncingFromUrl = useRef9(false);
2503
+ const isInitialLoadInProgress = useRef9(true);
2504
+ useEffect14(() => {
3036
2505
  if (isInitialLoadInProgress.current) return;
3037
2506
  const urlSearch = params.search || "";
3038
2507
  if (urlSearch !== searchInput) {
@@ -3043,7 +2512,7 @@ function useCursorPaginationState(options) {
3043
2512
  }, 0);
3044
2513
  }
3045
2514
  }, [params.search, initialLoadCount]);
3046
- useEffect16(() => {
2515
+ useEffect14(() => {
3047
2516
  if (isInitialLoadInProgress.current) return;
3048
2517
  if (isSyncingFromUrl.current) return;
3049
2518
  if (searchInput !== params.search) {
@@ -3054,7 +2523,7 @@ function useCursorPaginationState(options) {
3054
2523
  });
3055
2524
  }
3056
2525
  }, [searchInput, params.search, setParams, initialLoadCount]);
3057
- useEffect16(() => {
2526
+ useEffect14(() => {
3058
2527
  if (initialLoadCount === 0) {
3059
2528
  const cursor = params.cursor || null;
3060
2529
  const search = params.search || "";
@@ -3068,7 +2537,7 @@ function useCursorPaginationState(options) {
3068
2537
  });
3069
2538
  }
3070
2539
  }, []);
3071
- useEffect16(() => {
2540
+ useEffect14(() => {
3072
2541
  if (isInitialLoadInProgress.current) return;
3073
2542
  if (initialLoadCount === 0) return;
3074
2543
  const currentSearch = params.search || "";
@@ -3078,7 +2547,7 @@ function useCursorPaginationState(options) {
3078
2547
  onSearchChange(currentSearch);
3079
2548
  }
3080
2549
  }, [params.search, onSearchChange, initialLoadCount]);
3081
- const handleNextPage = useCallback12(
2550
+ const handleNextPage = useCallback11(
3082
2551
  async (endCursor, fetchFn) => {
3083
2552
  setParam("cursor", endCursor);
3084
2553
  await fetchFn();
@@ -3086,7 +2555,7 @@ function useCursorPaginationState(options) {
3086
2555
  },
3087
2556
  [setParam]
3088
2557
  );
3089
- const handleResetToFirstPage = useCallback12(
2558
+ const handleResetToFirstPage = useCallback11(
3090
2559
  async (fetchFn) => {
3091
2560
  setParam("cursor", "");
3092
2561
  await fetchFn();
@@ -3108,16 +2577,16 @@ function useCursorPaginationState(options) {
3108
2577
  }
3109
2578
 
3110
2579
  // src/hooks/nats/use-nats-client.ts
3111
- import { useEffect as useEffect17, useMemo as useMemo5, useState as useState22 } from "react";
2580
+ import { useEffect as useEffect15, useMemo as useMemo5, useState as useState20 } from "react";
3112
2581
  function useNatsClient(clientOptions, options = {}) {
3113
2582
  const { autoConnect = true } = options;
3114
2583
  const client = useMemo5(() => {
3115
2584
  if (!clientOptions) return null;
3116
2585
  return createNatsClient(clientOptions);
3117
2586
  }, [clientOptions]);
3118
- const [status, setStatus] = useState22("disconnected");
3119
- const [lastError, setLastError] = useState22(null);
3120
- useEffect17(() => {
2587
+ const [status, setStatus] = useState20("disconnected");
2588
+ const [lastError, setLastError] = useState20(null);
2589
+ useEffect15(() => {
3121
2590
  if (!client) {
3122
2591
  setStatus("disconnected");
3123
2592
  setLastError(null);
@@ -3147,125 +2616,8 @@ function useNatsClient(clientOptions, options = {}) {
3147
2616
  };
3148
2617
  }
3149
2618
 
3150
- // src/hooks/use-near-viewport.ts
3151
- import { useEffect as useEffect18, useRef as useRef11, useState as useState23, useCallback as useCallback13 } from "react";
3152
- var observers = /* @__PURE__ */ new Map();
3153
- var subscribers = /* @__PURE__ */ new WeakMap();
3154
- function getObserverFor(rootMargin) {
3155
- const existing = observers.get(rootMargin);
3156
- if (existing) return existing;
3157
- const io = new IntersectionObserver(
3158
- (entries) => {
3159
- entries.forEach((entry) => {
3160
- if (!entry.isIntersecting) return;
3161
- const cb = subscribers.get(entry.target);
3162
- if (cb) {
3163
- cb();
3164
- io.unobserve(entry.target);
3165
- subscribers.delete(entry.target);
3166
- }
3167
- });
3168
- },
3169
- { rootMargin }
3170
- );
3171
- observers.set(rootMargin, io);
3172
- return io;
3173
- }
3174
- function useNearViewport(rootMargin = "500px") {
3175
- const [isNear, setIsNear] = useState23(false);
3176
- const elRef = useRef11(null);
3177
- const ref = useCallback13(
3178
- (node) => {
3179
- const prev = elRef.current;
3180
- if (prev) {
3181
- const stillOurs = subscribers.get(prev);
3182
- if (stillOurs) {
3183
- subscribers.delete(prev);
3184
- observers.get(rootMargin)?.unobserve(prev);
3185
- }
3186
- }
3187
- elRef.current = node;
3188
- if (!node) return;
3189
- const cb = () => setIsNear(true);
3190
- subscribers.set(node, cb);
3191
- getObserverFor(rootMargin).observe(node);
3192
- },
3193
- [rootMargin]
3194
- );
3195
- useEffect18(() => {
3196
- return () => {
3197
- const el = elRef.current;
3198
- if (!el) return;
3199
- if (subscribers.get(el)) {
3200
- subscribers.delete(el);
3201
- observers.get(rootMargin)?.unobserve(el);
3202
- }
3203
- };
3204
- }, [rootMargin]);
3205
- return { ref, isNear };
3206
- }
3207
-
3208
2619
  // src/hooks/use-access-code-integration.ts
3209
2620
  import React2 from "react";
3210
-
3211
- // src/utils/access-code-client.ts
3212
- async function validateAccessCode(email, code, endpoints) {
3213
- try {
3214
- const response = await fetch(endpoints.validateUrl, {
3215
- method: "POST",
3216
- headers: {
3217
- "Content-Type": "application/json"
3218
- },
3219
- body: JSON.stringify({ email, code })
3220
- });
3221
- if (!response.ok) {
3222
- const error = await response.json().catch(() => ({}));
3223
- throw new Error(error.error || "Validation request failed");
3224
- }
3225
- return await response.json();
3226
- } catch (error) {
3227
- return {
3228
- valid: false,
3229
- message: error instanceof Error ? error.message : "Validation failed"
3230
- };
3231
- }
3232
- }
3233
- async function consumeAccessCode(email, code, endpoints) {
3234
- try {
3235
- const response = await fetch(endpoints.consumeUrl, {
3236
- method: "POST",
3237
- headers: {
3238
- "Content-Type": "application/json"
3239
- },
3240
- body: JSON.stringify({ email, code })
3241
- });
3242
- if (!response.ok) {
3243
- const error = await response.json().catch(() => ({}));
3244
- throw new Error(error.error || "Consumption request failed");
3245
- }
3246
- return await response.json();
3247
- } catch (error) {
3248
- return {
3249
- success: false,
3250
- consumed: false,
3251
- message: error instanceof Error ? error.message : "Consumption failed"
3252
- };
3253
- }
3254
- }
3255
- async function validateAndConsumeAccessCode(email, code, endpoints) {
3256
- const validation = await validateAccessCode(email, code, endpoints);
3257
- if (!validation.valid) {
3258
- return validation;
3259
- }
3260
- const consumption = await consumeAccessCode(email, code, endpoints);
3261
- return {
3262
- ...validation,
3263
- consumed: consumption.consumed,
3264
- message: consumption.consumed ? `Access granted for ${validation.cohort_name}` : consumption.message || validation.message
3265
- };
3266
- }
3267
-
3268
- // src/hooks/use-access-code-integration.ts
3269
2621
  function useAccessCodeIntegration() {
3270
2622
  const runtime = useRequiredEndpointsRuntime();
3271
2623
  const endpoints = runtime.accessCode;
@@ -3307,158 +2659,12 @@ function useAccessCodeIntegration() {
3307
2659
  };
3308
2660
  }
3309
2661
 
3310
- // src/hooks/use-og-placeholder.ts
3311
- import { useMemo as useMemo6 } from "react";
3312
- function useOgPlaceholder(buildUrl, title, siteName = "", enabled = true, aspect = "wide") {
3313
- return useMemo6(() => {
3314
- if (!enabled || !title) return null;
3315
- const options = {};
3316
- if (siteName) options.site = siteName;
3317
- if (aspect === "square") options.aspect = "square";
3318
- return buildUrl(title, options);
3319
- }, [buildUrl, title, siteName, enabled, aspect]);
3320
- }
3321
-
3322
- // src/hooks/use-scroll-to-hash.ts
3323
- import { useEffect as useEffect19 } from "react";
3324
-
3325
- // src/utils/scroll-into-view.ts
3326
- var activeRaf = 0;
3327
- var teardownActive = null;
3328
- function cancelActiveScroll() {
3329
- if (activeRaf) {
3330
- cancelAnimationFrame(activeRaf);
3331
- activeRaf = 0;
3332
- }
3333
- if (teardownActive) {
3334
- teardownActive();
3335
- teardownActive = null;
3336
- }
3337
- }
3338
- var easeOutCubic = (t) => 1 - Math.pow(1 - t, 3);
3339
- function getScrollableAncestor(el) {
3340
- for (let node = el.parentElement; node; node = node.parentElement) {
3341
- const overflowY = getComputedStyle(node).overflowY;
3342
- if ((overflowY === "auto" || overflowY === "scroll" || overflowY === "overlay") && node.scrollHeight > node.clientHeight) {
3343
- return node;
3344
- }
3345
- }
3346
- return null;
3347
- }
3348
- function scrollElementIntoView(target, options = {}) {
3349
- if (typeof window === "undefined" || !target) return;
3350
- const { headerOffset = 0, behavior = "smooth", adjustTargetY, durationMs = 320 } = options;
3351
- const container = getScrollableAncestor(target);
3352
- const readCurrent = () => container ? container.scrollTop : window.scrollY;
3353
- const writeTo = (y) => {
3354
- if (container) container.scrollTop = y;
3355
- else window.scrollTo(0, y);
3356
- };
3357
- const computeTarget = () => {
3358
- const raw = container ? container.scrollTop + (target.getBoundingClientRect().top - container.getBoundingClientRect().top) - headerOffset : target.getBoundingClientRect().top + window.scrollY - headerOffset;
3359
- const adjusted = adjustTargetY ? adjustTargetY(raw) : raw;
3360
- const maxScroll = container ? Math.max(0, container.scrollHeight - container.clientHeight) : Math.max(0, document.documentElement.scrollHeight - window.innerHeight);
3361
- return Math.min(Math.max(0, adjusted), maxScroll);
3362
- };
3363
- cancelActiveScroll();
3364
- const prefersReduced = typeof window.matchMedia === "function" && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
3365
- if (behavior === "instant" || behavior === "auto" || prefersReduced) {
3366
- writeTo(computeTarget());
3367
- return;
3368
- }
3369
- let startY = null;
3370
- let startTime = 0;
3371
- const onUserGesture = () => cancelActiveScroll();
3372
- window.addEventListener("wheel", onUserGesture, { passive: true });
3373
- window.addEventListener("touchmove", onUserGesture, { passive: true });
3374
- teardownActive = () => {
3375
- window.removeEventListener("wheel", onUserGesture);
3376
- window.removeEventListener("touchmove", onUserGesture);
3377
- };
3378
- const step = (now) => {
3379
- if (startY === null) {
3380
- startY = readCurrent();
3381
- startTime = now;
3382
- }
3383
- const targetY = computeTarget();
3384
- const t = Math.min(1, (now - startTime) / durationMs);
3385
- const y = startY + (targetY - startY) * easeOutCubic(t);
3386
- writeTo(y);
3387
- if (t < 1) {
3388
- activeRaf = requestAnimationFrame(step);
3389
- } else {
3390
- writeTo(computeTarget());
3391
- activeRaf = 0;
3392
- if (teardownActive) {
3393
- teardownActive();
3394
- teardownActive = null;
3395
- }
3396
- }
3397
- };
3398
- activeRaf = requestAnimationFrame(step);
3399
- }
3400
-
3401
- // src/utils/same-page-hash-nav.ts
3402
- var STICKY_HEADER_OFFSET_PX = 96;
3403
- var HUB_HEADER_OFFSET_PX = 80;
3404
- function normalizeHashFragment(hash) {
3405
- if (!hash) return "";
3406
- const second = hash.indexOf("#", 1);
3407
- return second < 0 ? hash : hash.slice(0, second);
3408
- }
3409
- function navigateSamePageHash(target, options = {}) {
3410
- if (typeof window === "undefined") return false;
3411
- const { headerOffset = 0, history: historyMode = "push" } = options;
3412
- const normalizedTarget = target.startsWith("#") ? window.location.pathname + window.location.search + target : target;
3413
- let url;
3414
- try {
3415
- url = new URL(normalizedTarget, window.location.href);
3416
- } catch {
3417
- return false;
3418
- }
3419
- if (url.origin !== window.location.origin || url.pathname !== window.location.pathname || url.search !== window.location.search) {
3420
- return false;
3421
- }
3422
- const current = window.location.pathname + window.location.search + window.location.hash;
3423
- const normalizedHash = normalizeHashFragment(url.hash);
3424
- if (process.env.NODE_ENV === "development" && normalizedHash !== url.hash) {
3425
- console.warn(
3426
- `[navigateSamePageHash] malformed fragment "${url.hash}" \u2192 normalizing to "${normalizedHash}". Fix the upstream composer.`
3427
- );
3428
- }
3429
- const next = url.pathname + url.search + normalizedHash;
3430
- const id = normalizedHash && normalizedHash !== "#" ? normalizedHash.slice(1) : "";
3431
- if (!id && next !== current) return false;
3432
- if (next !== current) {
3433
- const oldURL = window.location.href;
3434
- if (historyMode === "replace") {
3435
- window.history.replaceState(null, "", next);
3436
- } else {
3437
- window.history.pushState(null, "", next);
3438
- }
3439
- window.dispatchEvent(new HashChangeEvent("hashchange", {
3440
- oldURL,
3441
- newURL: window.location.href
3442
- }));
3443
- }
3444
- const el = id ? document.getElementById(id) : null;
3445
- if (id && !el && process.env.NODE_ENV === "development") {
3446
- console.warn(
3447
- `[navigateSamePageHash] anchor "#${id}" not found \u2014 scrolling to top.`
3448
- );
3449
- }
3450
- scrollElementIntoView(el ?? document.documentElement, {
3451
- behavior: "smooth",
3452
- headerOffset
3453
- });
3454
- return true;
3455
- }
3456
-
3457
2662
  // src/hooks/use-scroll-to-hash.ts
2663
+ import { useEffect as useEffect16 } from "react";
3458
2664
  var MAX_POLL_FRAMES = 60;
3459
2665
  function useScrollToHash(readyDep = true, options) {
3460
2666
  const headerOffset = options?.headerOffset ?? 0;
3461
- useEffect19(() => {
2667
+ useEffect16(() => {
3462
2668
  if (typeof window === "undefined") return;
3463
2669
  if (readyDep === null || readyDep === false) return;
3464
2670
  let rafId = null;
@@ -3498,40 +2704,18 @@ function useScrollToHash(readyDep = true, options) {
3498
2704
  }
3499
2705
 
3500
2706
  // src/hooks/use-humanity-signals.ts
3501
- import { useCallback as useCallback14, useRef as useRef12 } from "react";
3502
-
3503
- // src/utils/humanity-signals.ts
3504
- var HONEYPOT_FIELD = "contact_url_confirm";
3505
- var ELAPSED_MS_FIELD = "form_elapsed_ms";
3506
- var DEFAULT_MIN_FILL_MS = 700;
3507
- function extractHumanitySignals(body) {
3508
- const b = body ?? {};
3509
- const rawHp = b[HONEYPOT_FIELD];
3510
- const honeypot = rawHp == null ? "" : String(rawHp);
3511
- const rawMs = b[ELAPSED_MS_FIELD];
3512
- const elapsedMs = typeof rawMs === "number" && Number.isFinite(rawMs) ? rawMs : null;
3513
- return { honeypot, elapsedMs };
3514
- }
3515
- function evaluateHumanitySignals(body, opts) {
3516
- const { honeypot, elapsedMs } = extractHumanitySignals(body);
3517
- if (honeypot.trim() !== "") return { ok: false, reason: "honeypot" };
3518
- if (elapsedMs !== null && elapsedMs < opts.minFillMs) return { ok: false, reason: "too_fast" };
3519
- return { ok: true };
3520
- }
3521
- var splitCsvEnv = (s) => s?.split(",").map((t) => t.trim()).filter(Boolean) ?? [];
3522
-
3523
- // src/hooks/use-humanity-signals.ts
2707
+ import { useCallback as useCallback12, useRef as useRef10 } from "react";
3524
2708
  function useHumanitySignals() {
3525
- const ref = useRef12(null);
3526
- const mountedAt = useRef12(typeof performance !== "undefined" ? performance.now() : 0);
3527
- const getSignals = useCallback14(
2709
+ const ref = useRef10(null);
2710
+ const mountedAt = useRef10(typeof performance !== "undefined" ? performance.now() : 0);
2711
+ const getSignals = useCallback12(
3528
2712
  () => ({
3529
2713
  [HONEYPOT_FIELD]: ref.current?.value ?? "",
3530
2714
  [ELAPSED_MS_FIELD]: typeof performance !== "undefined" ? Math.round(performance.now() - mountedAt.current) : 0
3531
2715
  }),
3532
2716
  []
3533
2717
  );
3534
- const resetSignals = useCallback14(() => {
2718
+ const resetSignals = useCallback12(() => {
3535
2719
  if (ref.current) ref.current.value = "";
3536
2720
  if (typeof performance !== "undefined") mountedAt.current = performance.now();
3537
2721
  }, []);
@@ -3539,8 +2723,6 @@ function useHumanitySignals() {
3539
2723
  }
3540
2724
 
3541
2725
  export {
3542
- useAutoLimitTags,
3543
- useDebounce,
3544
2726
  useHeaderHeight,
3545
2727
  useHorizontalScrollbar,
3546
2728
  useImageEdgeColor,
@@ -3557,28 +2739,9 @@ export {
3557
2739
  useTablePagination,
3558
2740
  useThrottle,
3559
2741
  useWindowSize,
3560
- platformIcons,
3561
- platformColors,
3562
- platformDisplayNames,
3563
- platformDescriptions,
3564
- platformSlogans,
3565
- platformHexColors,
3566
- platformIconNames,
3567
- getDefaultColorForPlatform,
3568
- getDefaultIconForPlatform,
3569
- transformPlatformConfigsToOptions,
3570
- getPlatformIcon,
3571
- getPlatformColor,
3572
- getPlatformDisplayName,
3573
- getPlatformDescription,
3574
- getPlatformSlogan,
3575
- getSmallPlatformIcon,
3576
- getPlatformIconComponent,
3577
2742
  usePlatformConfig,
3578
2743
  usePlatformByValue,
3579
2744
  useValidatePlatform,
3580
- ToolTypeValues,
3581
- toolLabels,
3582
2745
  ToolIcon,
3583
2746
  dotColorByVariant,
3584
2747
  progressColorByVariant,
@@ -3589,15 +2752,6 @@ export {
3589
2752
  showCommandApprovalToast,
3590
2753
  toast,
3591
2754
  useToast,
3592
- getAppType,
3593
- getEmbedProxyAuth,
3594
- getPersistedProxyEmail,
3595
- setEmbedProxyAuth,
3596
- clearEmbedProxyAuth,
3597
- applyProxyAuth,
3598
- setEmbedAuthAdapter,
3599
- embedAuthedFetch,
3600
- contentFetch,
3601
2755
  useContactSubmission,
3602
2756
  useQuickActionHint,
3603
2757
  useCopyToClipboard,
@@ -3630,24 +2784,8 @@ export {
3630
2784
  createSearchParams,
3631
2785
  useCursorPaginationState,
3632
2786
  useNatsClient,
3633
- useNearViewport,
3634
- validateAccessCode,
3635
- consumeAccessCode,
3636
- validateAndConsumeAccessCode,
3637
2787
  useAccessCodeIntegration,
3638
- useOgPlaceholder,
3639
- scrollElementIntoView,
3640
- STICKY_HEADER_OFFSET_PX,
3641
- HUB_HEADER_OFFSET_PX,
3642
- normalizeHashFragment,
3643
- navigateSamePageHash,
3644
2788
  useScrollToHash,
3645
- HONEYPOT_FIELD,
3646
- ELAPSED_MS_FIELD,
3647
- DEFAULT_MIN_FILL_MS,
3648
- extractHumanitySignals,
3649
- evaluateHumanitySignals,
3650
- splitCsvEnv,
3651
2789
  useHumanitySignals
3652
2790
  };
3653
- //# sourceMappingURL=chunk-2QG57XOJ.js.map
2791
+ //# sourceMappingURL=chunk-7RIYT7ZH.js.map