@burdenoff/website-sdk 2026.925.2 → 2026.925.3

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 (35) hide show
  1. package/dist/components/explore.d.mts +1 -1
  2. package/dist/components/explore.d.ts +1 -1
  3. package/dist/components/explore.js +1046 -500
  4. package/dist/components/explore.js.map +1 -1
  5. package/dist/components/explore.mjs +1048 -503
  6. package/dist/components/explore.mjs.map +1 -1
  7. package/dist/components/partners.js +3 -2
  8. package/dist/components/partners.js.map +1 -1
  9. package/dist/components/partners.mjs +3 -2
  10. package/dist/components/partners.mjs.map +1 -1
  11. package/dist/content/index.d.mts +1 -1
  12. package/dist/content/index.d.ts +1 -1
  13. package/dist/content/index.js +3 -2
  14. package/dist/content/index.js.map +1 -1
  15. package/dist/content/index.mjs +3 -2
  16. package/dist/content/index.mjs.map +1 -1
  17. package/dist/{explore-C0RFTKAi.d.ts → explore-Cam_ElSJ.d.ts} +70 -12
  18. package/dist/{explore-DzOf7n4m.d.mts → explore-hTQm-_SF.d.mts} +70 -12
  19. package/dist/hooks/index.js +21 -12
  20. package/dist/hooks/index.js.map +1 -1
  21. package/dist/hooks/index.mjs +21 -12
  22. package/dist/hooks/index.mjs.map +1 -1
  23. package/dist/{index-BMWQNZDX.d.mts → index-gm3pBCJT.d.mts} +8 -2
  24. package/dist/{index-BqHF-G-S.d.ts → index-ySbOLSD5.d.ts} +8 -2
  25. package/dist/index.d.mts +30 -9
  26. package/dist/index.d.ts +30 -9
  27. package/dist/index.js +827 -261
  28. package/dist/index.js.map +1 -1
  29. package/dist/index.mjs +827 -263
  30. package/dist/index.mjs.map +1 -1
  31. package/dist/store/index.js +3 -2
  32. package/dist/store/index.js.map +1 -1
  33. package/dist/store/index.mjs +3 -2
  34. package/dist/store/index.mjs.map +1 -1
  35. package/package.json +1 -1
package/dist/index.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as React from 'react';
2
2
  import { createContext, useMemo, useContext, useState, useCallback, useLayoutEffect, useRef, useEffect, useId, version, Children, isValidElement, cloneElement } from 'react';
3
3
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
4
- import { Instagram, Youtube, Facebook, Github, Linkedin, Twitter, Mail, Phone, MapPin, Clock, Send, CheckCircle, Upload, Globe, ChevronDown, Search, Rocket, ArrowRight, Download, ImageIcon, ChevronRight, Maximize2, Check, ArrowLeft, Sparkles, RotateCcw, Link2, History, Trash2, Paperclip, X, Mic, Square, ArrowUp, Info, ExternalLink, ChevronLeft, BookOpenText, Layers, TriangleAlert, FileText, Copy, ThumbsUp, ThumbsDown, Volume2 } from 'lucide-react';
4
+ import { Instagram, Youtube, Facebook, Github, Linkedin, Twitter, Mail, Phone, MapPin, Clock, Send, CheckCircle, Upload, Globe, ChevronDown, Search, Rocket, ArrowRight, Download, ImageIcon, ChevronRight, Maximize2, Check, ArrowLeft, Sparkles, RotateCcw, Link2, History, Trash2, Paperclip, X, Mic, Square, ArrowUp, Info, ExternalLink, ChevronLeft, BookOpenText, Layers, TriangleAlert, FileText, Film, Play, Copy, ThumbsUp, ThumbsDown, Minimize, Maximize, VideoOff, Volume2 } from 'lucide-react';
5
5
  import ReCAPTCHA4 from 'react-google-recaptcha';
6
6
  import { toast } from 'sonner';
7
7
  import { Helmet } from 'react-helmet-async';
@@ -18,6 +18,7 @@ import { zodResolver } from '@hookform/resolvers/zod';
18
18
  import { useForm } from 'react-hook-form';
19
19
  import { z } from 'zod';
20
20
  import * as DropdownMenu from '@radix-ui/react-dropdown-menu';
21
+ import { createPortal } from 'react-dom';
21
22
 
22
23
  var __defProp = Object.defineProperty;
23
24
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
@@ -1108,13 +1109,14 @@ function Markdown({
1108
1109
  children,
1109
1110
  className,
1110
1111
  inline,
1111
- components
1112
+ components,
1113
+ rehypePlugins
1112
1114
  }) {
1113
1115
  const content = /* @__PURE__ */ jsx(
1114
1116
  ReactMarkdown,
1115
1117
  {
1116
1118
  remarkPlugins: [remarkGfm],
1117
- rehypePlugins: [rehypeSanitize],
1119
+ rehypePlugins: [rehypeSanitize, ...rehypePlugins ?? []],
1118
1120
  components: { ...defaultComponents, ...components },
1119
1121
  ...inline ? { disallowedElements: ["p"], unwrapDisallowed: true } : {},
1120
1122
  children
@@ -6135,6 +6137,13 @@ var EN = {
6135
6137
  readAloud: "Read aloud",
6136
6138
  stopReading: "Stop reading",
6137
6139
  answerTable: "Table",
6140
+ productVideo: "Product video",
6141
+ productVideoTitle: "{product} product video",
6142
+ playVideo: "Play {title}",
6143
+ closeVideo: "Close video",
6144
+ enterFullScreen: "Full screen",
6145
+ exitFullScreen: "Exit full screen",
6146
+ videoUnavailable: "This video can't be played right now.",
6138
6147
  groundedIn: "What this answer is based on",
6139
6148
  sourceCountOne: "1 source",
6140
6149
  sourceCountMany: "{count} sources",
@@ -6236,6 +6245,13 @@ var ZH = {
6236
6245
  readAloud: "\u6717\u8BFB",
6237
6246
  stopReading: "\u505C\u6B62\u6717\u8BFB",
6238
6247
  answerTable: "\u8868\u683C",
6248
+ productVideo: "\u4EA7\u54C1\u89C6\u9891",
6249
+ productVideoTitle: "{product} \u4EA7\u54C1\u89C6\u9891",
6250
+ playVideo: "\u64AD\u653E {title}",
6251
+ closeVideo: "\u5173\u95ED\u89C6\u9891",
6252
+ enterFullScreen: "\u5168\u5C4F",
6253
+ exitFullScreen: "\u9000\u51FA\u5168\u5C4F",
6254
+ videoUnavailable: "\u6682\u65F6\u65E0\u6CD5\u64AD\u653E\u6B64\u89C6\u9891\u3002",
6239
6255
  groundedIn: "\u8FD9\u4E2A\u56DE\u7B54\u7684\u4F9D\u636E",
6240
6256
  sourceCountOne: "1 \u4E2A\u6765\u6E90",
6241
6257
  sourceCountMany: "{count} \u4E2A\u6765\u6E90",
@@ -6333,6 +6349,13 @@ var HI = {
6333
6349
  readAloud: "\u091C\u093C\u094B\u0930 \u0938\u0947 \u092A\u0922\u093C\u0947\u0902",
6334
6350
  stopReading: "\u092A\u0922\u093C\u0928\u093E \u092C\u0902\u0926 \u0915\u0930\u0947\u0902",
6335
6351
  answerTable: "\u0924\u093E\u0932\u093F\u0915\u093E",
6352
+ productVideo: "\u0909\u0924\u094D\u092A\u093E\u0926 \u0935\u0940\u0921\u093F\u092F\u094B",
6353
+ productVideoTitle: "{product} \u0909\u0924\u094D\u092A\u093E\u0926 \u0935\u0940\u0921\u093F\u092F\u094B",
6354
+ playVideo: "{title} \u091A\u0932\u093E\u090F\u0901",
6355
+ closeVideo: "\u0935\u0940\u0921\u093F\u092F\u094B \u092C\u0902\u0926 \u0915\u0930\u0947\u0902",
6356
+ enterFullScreen: "\u092A\u0942\u0930\u094D\u0923 \u0938\u094D\u0915\u094D\u0930\u0940\u0928",
6357
+ exitFullScreen: "\u092A\u0942\u0930\u094D\u0923 \u0938\u094D\u0915\u094D\u0930\u0940\u0928 \u0938\u0947 \u092C\u093E\u0939\u0930 \u0928\u093F\u0915\u0932\u0947\u0902",
6358
+ videoUnavailable: "\u092F\u0939 \u0935\u0940\u0921\u093F\u092F\u094B \u0905\u092D\u0940 \u0928\u0939\u0940\u0902 \u091A\u0932 \u0938\u0915\u0924\u093E\u0964",
6336
6359
  groundedIn: "\u092F\u0939 \u0909\u0924\u094D\u0924\u0930 \u0915\u093F\u0938 \u092A\u0930 \u0906\u0927\u093E\u0930\u093F\u0924 \u0939\u0948",
6337
6360
  sourceCountOne: "1 \u0938\u094D\u0930\u094B\u0924",
6338
6361
  sourceCountMany: "{count} \u0938\u094D\u0930\u094B\u0924",
@@ -6434,6 +6457,13 @@ var ES = {
6434
6457
  readAloud: "Leer en voz alta",
6435
6458
  stopReading: "Dejar de leer",
6436
6459
  answerTable: "Tabla",
6460
+ productVideo: "V\xEDdeo del producto",
6461
+ productVideoTitle: "V\xEDdeo de {product}",
6462
+ playVideo: "Reproducir {title}",
6463
+ closeVideo: "Cerrar v\xEDdeo",
6464
+ enterFullScreen: "Pantalla completa",
6465
+ exitFullScreen: "Salir de pantalla completa",
6466
+ videoUnavailable: "Ahora mismo no se puede reproducir este v\xEDdeo.",
6437
6467
  groundedIn: "En qu\xE9 se basa esta respuesta",
6438
6468
  sourceCountOne: "1 fuente",
6439
6469
  sourceCountMany: "{count} fuentes",
@@ -6535,6 +6565,13 @@ var AR = {
6535
6565
  readAloud: "\u0627\u0642\u0631\u0623 \u0628\u0635\u0648\u062A \u0639\u0627\u0644\u064D",
6536
6566
  stopReading: "\u0625\u064A\u0642\u0627\u0641 \u0627\u0644\u0642\u0631\u0627\u0621\u0629",
6537
6567
  answerTable: "\u062C\u062F\u0648\u0644",
6568
+ productVideo: "\u0641\u064A\u062F\u064A\u0648 \u0627\u0644\u0645\u0646\u062A\u062C",
6569
+ productVideoTitle: "\u0641\u064A\u062F\u064A\u0648 {product}",
6570
+ playVideo: "\u062A\u0634\u063A\u064A\u0644 {title}",
6571
+ closeVideo: "\u0625\u063A\u0644\u0627\u0642 \u0627\u0644\u0641\u064A\u062F\u064A\u0648",
6572
+ enterFullScreen: "\u0645\u0644\u0621 \u0627\u0644\u0634\u0627\u0634\u0629",
6573
+ exitFullScreen: "\u0627\u0644\u062E\u0631\u0648\u062C \u0645\u0646 \u0645\u0644\u0621 \u0627\u0644\u0634\u0627\u0634\u0629",
6574
+ videoUnavailable: "\u062A\u0639\u0630\u0651\u0631 \u062A\u0634\u063A\u064A\u0644 \u0647\u0630\u0627 \u0627\u0644\u0641\u064A\u062F\u064A\u0648 \u0627\u0644\u0622\u0646.",
6538
6575
  groundedIn: "\u0639\u0644\u0649 \u0645\u0627\u0630\u0627 \u062A\u0633\u062A\u0646\u062F \u0647\u0630\u0647 \u0627\u0644\u0625\u062C\u0627\u0628\u0629",
6539
6576
  sourceCountOne: "\u0645\u0635\u062F\u0631 \u0648\u0627\u062D\u062F",
6540
6577
  sourceCountMany: "{count} \u0645\u0635\u0627\u062F\u0631",
@@ -6636,6 +6673,13 @@ var TA = {
6636
6673
  readAloud: "\u0B9A\u0BA4\u0BCD\u0BA4\u0BAE\u0BBE\u0B95\u0BAA\u0BCD \u0BAA\u0B9F\u0BBF",
6637
6674
  stopReading: "\u0BAA\u0B9F\u0BBF\u0BAA\u0BCD\u0BAA\u0BA4\u0BC8 \u0BA8\u0BBF\u0BB1\u0BC1\u0BA4\u0BCD\u0BA4\u0BC1",
6638
6675
  answerTable: "\u0B85\u0B9F\u0BCD\u0B9F\u0BB5\u0BA3\u0BC8",
6676
+ productVideo: "\u0BA4\u0BAF\u0BBE\u0BB0\u0BBF\u0BAA\u0BCD\u0BAA\u0BC1 \u0BB5\u0BC0\u0B9F\u0BBF\u0BAF\u0BCB",
6677
+ productVideoTitle: "{product} \u0BA4\u0BAF\u0BBE\u0BB0\u0BBF\u0BAA\u0BCD\u0BAA\u0BC1 \u0BB5\u0BC0\u0B9F\u0BBF\u0BAF\u0BCB",
6678
+ playVideo: "{title} \u0B87\u0BAF\u0B95\u0BCD\u0B95\u0BC1",
6679
+ closeVideo: "\u0BB5\u0BC0\u0B9F\u0BBF\u0BAF\u0BCB\u0BB5\u0BC8 \u0BAE\u0BC2\u0B9F\u0BC1",
6680
+ enterFullScreen: "\u0BAE\u0BC1\u0BB4\u0BC1\u0BA4\u0BCD \u0BA4\u0BBF\u0BB0\u0BC8",
6681
+ exitFullScreen: "\u0BAE\u0BC1\u0BB4\u0BC1\u0BA4\u0BCD \u0BA4\u0BBF\u0BB0\u0BC8\u0BAF\u0BBF\u0BB2\u0BBF\u0BB0\u0BC1\u0BA8\u0BCD\u0BA4\u0BC1 \u0BB5\u0BC6\u0BB3\u0BBF\u0BAF\u0BC7\u0BB1\u0BC1",
6682
+ videoUnavailable: "\u0B87\u0BA8\u0BCD\u0BA4 \u0BB5\u0BC0\u0B9F\u0BBF\u0BAF\u0BCB\u0BB5\u0BC8 \u0B87\u0BAA\u0BCD\u0BAA\u0BCB\u0BA4\u0BC1 \u0B87\u0BAF\u0B95\u0BCD\u0B95 \u0BAE\u0BC1\u0B9F\u0BBF\u0BAF\u0BB5\u0BBF\u0BB2\u0BCD\u0BB2\u0BC8.",
6639
6683
  groundedIn: "\u0B87\u0BA8\u0BCD\u0BA4\u0BAA\u0BCD \u0BAA\u0BA4\u0BBF\u0BB2\u0BCD \u0B8E\u0BA4\u0BC8 \u0B85\u0B9F\u0BBF\u0BAA\u0BCD\u0BAA\u0B9F\u0BC8\u0BAF\u0BBE\u0B95\u0B95\u0BCD \u0B95\u0BCA\u0BA3\u0BCD\u0B9F\u0BA4\u0BC1",
6640
6684
  sourceCountOne: "1 \u0BAE\u0BC2\u0BB2\u0BAE\u0BCD",
6641
6685
  sourceCountMany: "{count} \u0BAE\u0BC2\u0BB2\u0B99\u0BCD\u0B95\u0BB3\u0BCD",
@@ -6925,7 +6969,14 @@ function answerStrings(locale) {
6925
6969
  ...chrome,
6926
6970
  answerTable: explore.answerTable,
6927
6971
  conceptIllustration: explore.conceptIllustration,
6928
- opensInNewTab: explore.opensInNewTab
6972
+ opensInNewTab: explore.opensInNewTab,
6973
+ productVideo: explore.productVideo,
6974
+ productVideoTitle: explore.productVideoTitle,
6975
+ playVideo: explore.playVideo,
6976
+ closeVideo: explore.closeVideo,
6977
+ enterFullScreen: explore.enterFullScreen,
6978
+ exitFullScreen: explore.exitFullScreen,
6979
+ videoUnavailable: explore.videoUnavailable
6929
6980
  };
6930
6981
  }
6931
6982
  var DATE_TAGS = {
@@ -6993,6 +7044,253 @@ function answerSourceHost(url) {
6993
7044
  return "";
6994
7045
  }
6995
7046
  }
7047
+ function fullscreenSupport() {
7048
+ if (typeof document === "undefined") return null;
7049
+ if (document.fullscreenEnabled && typeof document.documentElement.requestFullscreen === "function") {
7050
+ return "element";
7051
+ }
7052
+ if (typeof HTMLVideoElement !== "undefined" && "webkitEnterFullscreen" in HTMLVideoElement.prototype) {
7053
+ return "video";
7054
+ }
7055
+ return null;
7056
+ }
7057
+ function ignoreRejection(result) {
7058
+ result?.catch(() => void 0);
7059
+ }
7060
+ var VIDEO_DIALOG_CSS = `
7061
+ .boff-explore-video-panel:fullscreen {
7062
+ display: flex;
7063
+ flex-direction: column;
7064
+ gap: 0.75rem;
7065
+ padding: 1rem;
7066
+ background-color: hsl(var(--background));
7067
+ color: hsl(var(--foreground));
7068
+ }
7069
+ .boff-explore-video-panel:fullscreen .boff-explore-video-frame {
7070
+ display: flex;
7071
+ flex: 1 1 auto;
7072
+ min-height: 0;
7073
+ align-items: center;
7074
+ justify-content: center;
7075
+ border: 0;
7076
+ border-radius: 0;
7077
+ box-shadow: none;
7078
+ background-color: hsl(var(--background));
7079
+ }
7080
+ .boff-explore-video-panel:fullscreen video {
7081
+ width: 100%;
7082
+ height: 100%;
7083
+ max-height: none;
7084
+ }
7085
+ `;
7086
+ var DIALOG_BUTTON = "inline-flex h-10 w-10 shrink-0 items-center justify-center rounded-full border border-border bg-card text-foreground transition-colors hover:bg-muted focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring";
7087
+ function ExploreVideoDialog({
7088
+ videoUrl,
7089
+ posterUrl,
7090
+ title,
7091
+ strings: T,
7092
+ dir,
7093
+ onClose
7094
+ }) {
7095
+ const dialogRef = useRef(null);
7096
+ const panelRef = useRef(null);
7097
+ const videoRef = useRef(null);
7098
+ const closeRef = useRef(null);
7099
+ const nativeModalRef = useRef(false);
7100
+ const titleId = useId();
7101
+ const [support] = useState(fullscreenSupport);
7102
+ const [fullscreen, setFullscreen] = useState(false);
7103
+ const [failed, setFailed] = useState(false);
7104
+ useEffect(() => {
7105
+ const dialog = dialogRef.current;
7106
+ if (!dialog) return;
7107
+ if (typeof dialog.showModal === "function") {
7108
+ if (!dialog.open) dialog.showModal();
7109
+ nativeModalRef.current = true;
7110
+ } else {
7111
+ dialog.setAttribute("open", "");
7112
+ nativeModalRef.current = false;
7113
+ }
7114
+ closeRef.current?.focus();
7115
+ ignoreRejection(videoRef.current?.play());
7116
+ return () => {
7117
+ if (dialog.open && typeof dialog.close === "function") dialog.close();
7118
+ };
7119
+ }, []);
7120
+ useEffect(() => {
7121
+ const sync = () => {
7122
+ const current = document.fullscreenElement;
7123
+ setFullscreen(
7124
+ current !== null && dialogRef.current?.contains(current) === true
7125
+ );
7126
+ };
7127
+ const enter = () => setFullscreen(true);
7128
+ const leave = () => setFullscreen(false);
7129
+ const video = videoRef.current;
7130
+ document.addEventListener("fullscreenchange", sync);
7131
+ video?.addEventListener("webkitbeginfullscreen", enter);
7132
+ video?.addEventListener("webkitendfullscreen", leave);
7133
+ return () => {
7134
+ document.removeEventListener("fullscreenchange", sync);
7135
+ video?.removeEventListener("webkitbeginfullscreen", enter);
7136
+ video?.removeEventListener("webkitendfullscreen", leave);
7137
+ };
7138
+ }, [failed]);
7139
+ const leaveFullscreen = useCallback(() => {
7140
+ const current = document.fullscreenElement;
7141
+ if (current && dialogRef.current?.contains(current) && typeof document.exitFullscreen === "function") {
7142
+ ignoreRejection(document.exitFullscreen());
7143
+ }
7144
+ const video = videoRef.current;
7145
+ if (video?.webkitDisplayingFullscreen) video.webkitExitFullscreen?.();
7146
+ }, []);
7147
+ const requestClose = useCallback(() => {
7148
+ videoRef.current?.pause();
7149
+ leaveFullscreen();
7150
+ onClose();
7151
+ }, [leaveFullscreen, onClose]);
7152
+ const toggleFullscreen = useCallback(() => {
7153
+ if (fullscreen) {
7154
+ leaveFullscreen();
7155
+ return;
7156
+ }
7157
+ if (support === "element") {
7158
+ const panel = panelRef.current;
7159
+ if (panel) ignoreRejection(panel.requestFullscreen());
7160
+ return;
7161
+ }
7162
+ const video = videoRef.current;
7163
+ video?.webkitEnterFullscreen?.();
7164
+ }, [fullscreen, leaveFullscreen, support]);
7165
+ const handleClose = useCallback(
7166
+ (event) => {
7167
+ if (event.currentTarget.open) return;
7168
+ requestClose();
7169
+ },
7170
+ [requestClose]
7171
+ );
7172
+ const handleKeyDown = useCallback(
7173
+ (event) => {
7174
+ if (event.key === "Escape" && !nativeModalRef.current) {
7175
+ event.preventDefault();
7176
+ requestClose();
7177
+ }
7178
+ },
7179
+ [requestClose]
7180
+ );
7181
+ const handleStageClick = useCallback(
7182
+ (event) => {
7183
+ if (event.target === event.currentTarget) requestClose();
7184
+ },
7185
+ [requestClose]
7186
+ );
7187
+ if (typeof document === "undefined") return null;
7188
+ const fullscreenLabel = fullscreen ? T.exitFullScreen : T.enterFullScreen;
7189
+ return createPortal(
7190
+ /* @__PURE__ */ jsxs(
7191
+ "dialog",
7192
+ {
7193
+ ref: dialogRef,
7194
+ "data-boff-explore": "video-dialog",
7195
+ "aria-labelledby": titleId,
7196
+ dir,
7197
+ onClose: handleClose,
7198
+ onKeyDown: handleKeyDown,
7199
+ className: "fixed inset-0 z-50 m-0 h-full max-h-none w-full max-w-none overflow-y-auto overscroll-contain border-0 bg-background/95 p-0 text-foreground backdrop-blur-sm",
7200
+ children: [
7201
+ /* @__PURE__ */ jsx("style", { dangerouslySetInnerHTML: { __html: VIDEO_DIALOG_CSS } }),
7202
+ /* @__PURE__ */ jsx(
7203
+ "div",
7204
+ {
7205
+ onClick: handleStageClick,
7206
+ className: "flex min-h-full items-center justify-center p-4 sm:p-6",
7207
+ children: /* @__PURE__ */ jsxs(
7208
+ "div",
7209
+ {
7210
+ ref: panelRef,
7211
+ className: "boff-explore-video-panel flex w-full min-w-0 max-w-[960px] flex-col gap-3",
7212
+ children: [
7213
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
7214
+ /* @__PURE__ */ jsx(
7215
+ "h2",
7216
+ {
7217
+ id: titleId,
7218
+ className: "min-w-0 flex-1 truncate text-sm font-semibold text-foreground sm:text-base",
7219
+ children: title
7220
+ }
7221
+ ),
7222
+ support !== null && !failed ? (
7223
+ // A plain button whose name says what pressing it does NOW, and no
7224
+ // `aria-pressed`: a toggle button's name must not change with its state, or it
7225
+ // announces "Exit full screen, pressed" — two answers to one question.
7226
+ /* @__PURE__ */ jsx(
7227
+ "button",
7228
+ {
7229
+ type: "button",
7230
+ "data-boff-explore": "video-fullscreen",
7231
+ "aria-label": fullscreenLabel,
7232
+ title: fullscreenLabel,
7233
+ onClick: toggleFullscreen,
7234
+ className: DIALOG_BUTTON,
7235
+ children: fullscreen ? /* @__PURE__ */ jsx(Minimize, { "aria-hidden": "true", className: "h-5 w-5" }) : /* @__PURE__ */ jsx(Maximize, { "aria-hidden": "true", className: "h-5 w-5" })
7236
+ }
7237
+ )
7238
+ ) : null,
7239
+ /* @__PURE__ */ jsx(
7240
+ "button",
7241
+ {
7242
+ ref: closeRef,
7243
+ type: "button",
7244
+ "data-boff-explore": "video-close",
7245
+ "aria-label": T.closeVideo,
7246
+ title: T.closeVideo,
7247
+ onClick: requestClose,
7248
+ className: DIALOG_BUTTON,
7249
+ children: /* @__PURE__ */ jsx(X, { "aria-hidden": "true", className: "h-5 w-5" })
7250
+ }
7251
+ )
7252
+ ] }),
7253
+ /* @__PURE__ */ jsx("div", { className: "boff-explore-video-frame overflow-hidden rounded-xl border border-border bg-muted shadow-lg", children: failed ? (
7254
+ // A black box with a spinning control tells the visitor nothing; this says
7255
+ // what happened, in their language.
7256
+ /* @__PURE__ */ jsxs(
7257
+ "div",
7258
+ {
7259
+ role: "alert",
7260
+ className: "flex aspect-video w-full flex-col items-center justify-center gap-2 p-6 text-center text-sm text-muted-foreground",
7261
+ children: [
7262
+ /* @__PURE__ */ jsx(VideoOff, { "aria-hidden": "true", className: "h-6 w-6" }),
7263
+ /* @__PURE__ */ jsx("p", { children: T.videoUnavailable })
7264
+ ]
7265
+ }
7266
+ )
7267
+ ) : /* @__PURE__ */ jsx(
7268
+ "video",
7269
+ {
7270
+ ref: videoRef,
7271
+ "data-boff-explore": "video-player",
7272
+ src: videoUrl,
7273
+ poster: posterUrl,
7274
+ controls: true,
7275
+ controlsList: support === "element" ? "nofullscreen" : void 0,
7276
+ playsInline: true,
7277
+ autoPlay: true,
7278
+ preload: "metadata",
7279
+ onError: () => setFailed(true),
7280
+ className: "block max-h-[80vh] w-full bg-muted object-contain"
7281
+ }
7282
+ ) })
7283
+ ]
7284
+ }
7285
+ )
7286
+ }
7287
+ )
7288
+ ]
7289
+ }
7290
+ ),
7291
+ document.body
7292
+ );
7293
+ }
6996
7294
  var EXPLORE_ANSWER_CSS = `
6997
7295
  /* Nothing inside an answer may widen the page. Model output carries long URLs, code and
6998
7296
  tables \u2014 each of those overflows a phone by default, and one overflowing child makes the
@@ -7025,6 +7323,14 @@ var EXPLORE_ANSWER_CSS = `
7025
7323
  max-width: 100%;
7026
7324
  height: auto;
7027
7325
  }
7326
+ /* A product-video poster fills the card's reserved 16:9 frame and is cropped to it. The
7327
+ blanket \`img { height: auto }\` above \u2014 and ProseStyles' own \u2014 outrank a height utility,
7328
+ and would size it by its own aspect ratio instead, leaving a band of the frame showing
7329
+ whenever a poster is not exactly 16:9. */
7330
+ .boff-explore-body .boff-explore-video-poster {
7331
+ height: 100%;
7332
+ max-width: none;
7333
+ }
7028
7334
 
7029
7335
  /* ---- Comparison and pricing tables ----------------------------------------------------
7030
7336
  The harness emits a comparison, and a set of plans, as a GFM table whose FIRST column is
@@ -7155,28 +7461,81 @@ function inlineImageOrigins(products) {
7155
7461
  }
7156
7462
  return origins;
7157
7463
  }
7158
- function isInlineImageAllowed(src, origins) {
7159
- if (typeof src !== "string" || src === "") return false;
7464
+ var VIDEO_FILE_PATH = /\.(?:mp4|webm|m4v|mov|vtt)$/i;
7465
+ function catalogUrlOf(value, origins) {
7466
+ if (typeof value !== "string" || value === "") return null;
7160
7467
  let url;
7161
7468
  try {
7162
- url = new URL(src);
7469
+ url = new URL(value);
7470
+ } catch {
7471
+ return null;
7472
+ }
7473
+ if (url.protocol !== "https:" || url.username || url.password) return null;
7474
+ return origins.has(url.origin) ? url : null;
7475
+ }
7476
+ function isInlineImageAllowed(src, origins) {
7477
+ const url = catalogUrlOf(src, origins);
7478
+ return url !== null && !VIDEO_FILE_PATH.test(url.pathname);
7479
+ }
7480
+ var INLINE_VIDEO_PATH = /\.(?:mp4|webm)$/i;
7481
+ function isInlineVideoAllowed(href, origins) {
7482
+ const url = catalogUrlOf(href, origins);
7483
+ return url !== null && INLINE_VIDEO_PATH.test(url.pathname);
7484
+ }
7485
+ function apexOriginOf(url) {
7486
+ const apex = url.hostname.replace(/^www\./, "");
7487
+ const port = url.port ? `:${url.port}` : "";
7488
+ return `https://${apex}${port}`;
7489
+ }
7490
+ function productSlugsByOrigin(products) {
7491
+ const slugs = /* @__PURE__ */ new Map();
7492
+ for (const product of products) {
7493
+ let url;
7494
+ try {
7495
+ url = new URL(product.website);
7496
+ } catch {
7497
+ continue;
7498
+ }
7499
+ if (url.protocol !== "https:") continue;
7500
+ const key = apexOriginOf(url);
7501
+ if (!slugs.has(key)) slugs.set(key, product.slug);
7502
+ }
7503
+ return slugs;
7504
+ }
7505
+ function videoProductOf(href, slugs) {
7506
+ const url = new URL(href);
7507
+ return slugs.get(apexOriginOf(url)) ?? url.hostname.replace(/^www\./, "");
7508
+ }
7509
+ function isVideoFileTarget(href) {
7510
+ if (typeof href !== "string") return false;
7511
+ try {
7512
+ return VIDEO_FILE_PATH.test(
7513
+ new URL(href, "https://answer.invalid").pathname
7514
+ );
7163
7515
  } catch {
7164
7516
  return false;
7165
7517
  }
7166
- if (url.protocol !== "https:" || url.username || url.password) return false;
7167
- return origins.has(url.origin);
7168
7518
  }
7169
7519
  var CODE_FENCE = /^\s*(?:```|~~~)/;
7170
7520
  var TABLE_ROW_LINE = /^\s{0,3}\|/;
7171
7521
  var TABLE_DELIMITER_ROW = /^\s{0,3}\|[\s:|-]*-[\s:|-]*$/;
7522
+ var LINKED_IMAGE = /\[!\[([^[\]]*)\]\([^)\s]*(?:\s+"[^"]*")?\)\]\(([^)\s]+)(?:\s+"[^"]*")?\)/g;
7523
+ var IMAGE = /!\[[^[\]]*\]\([^)\s]*(?:\s+"[^"]*")?\)/g;
7524
+ var LINK = /\[([^[\]]+)\]\(([^)\s]+)(?:\s+"[^"]*")?\)/g;
7172
7525
  function readableLine(raw, mode) {
7173
7526
  let line = raw;
7174
- line = line.replace(/!\[[^\]]*\]\([^)\s]*(?:\s+"[^"]*")?\)/g, "");
7175
- line = mode === "speech" ? (
7176
- // A voice reading "h-t-t-p-s colon slash slash…" mid-sentence is noise, and the
7177
- // prompt asks for two to five links in every answer. The label IS the words.
7178
- line.replace(/\[([^\]]+)\]\(([^)\s]+)(?:\s+"[^"]*")?\)/g, "$1")
7179
- ) : line.replace(/\[([^\]]+)\]\(([^)\s]+)(?:\s+"[^"]*")?\)/g, "$1 ($2)");
7527
+ if (line.includes("](")) {
7528
+ line = line.replace(LINKED_IMAGE, (_match, alt, href) => {
7529
+ if (mode === "speech") return "";
7530
+ return alt.trim() === "" ? href : `${alt.trim()} (${href})`;
7531
+ });
7532
+ line = line.replace(IMAGE, "");
7533
+ line = mode === "speech" ? (
7534
+ // A voice reading "h-t-t-p-s colon slash slash…" mid-sentence is noise, and the
7535
+ // prompt asks for two to five links in every answer. The label IS the words.
7536
+ line.replace(LINK, "$1")
7537
+ ) : line.replace(LINK, "$1 ($2)");
7538
+ }
7180
7539
  line = mode === "speech" ? line.replace(/<(https?:\/\/[^>\s]+)>/g, "") : line.replace(/<(https?:\/\/[^>\s]+)>/g, "$1");
7181
7540
  line = line.replace(/^\s{0,3}#{1,6}\s+/, "");
7182
7541
  line = line.replace(/^\s{0,3}>\s?/, "");
@@ -7267,6 +7626,21 @@ function answerSpeechText(markdown) {
7267
7626
  var AnswerScopeContext = createContext(null);
7268
7627
  var InsideLinkContext = createContext(false);
7269
7628
  function AnswerLink(props) {
7629
+ const scope = useContext(AnswerScopeContext);
7630
+ const role = videoRoleOf(props.node);
7631
+ if (role !== void 0 && scope !== null) {
7632
+ const video = role === "card" && scope.enabled ? productVideoOf(props.node) : null;
7633
+ if (video === null) return null;
7634
+ return /* @__PURE__ */ jsx(
7635
+ InlineVideoCard,
7636
+ {
7637
+ href: video.href,
7638
+ poster: video.poster,
7639
+ alt: video.alt,
7640
+ scope
7641
+ }
7642
+ );
7643
+ }
7270
7644
  return /* @__PURE__ */ jsx(InsideLinkContext.Provider, { value: true, children: /* @__PURE__ */ jsx(MarkdownLink, { ...props }) });
7271
7645
  }
7272
7646
  var INLINE_IMAGE_FRAME = "relative inline-block max-w-full overflow-hidden rounded-xl border border-border bg-muted align-top shadow-sm";
@@ -7378,16 +7752,173 @@ function AnswerTableRow({
7378
7752
  });
7379
7753
  return /* @__PURE__ */ jsx("tr", { ...props, children: cells });
7380
7754
  }
7755
+ function linkedImageOf(node) {
7756
+ if (node?.tagName !== "a") return null;
7757
+ const content = (node.children ?? []).filter(
7758
+ (child) => child.tagName !== void 0 || (child.value ?? "").trim() !== ""
7759
+ );
7760
+ const image = content.length === 1 ? content[0] : void 0;
7761
+ if (image?.tagName !== "img") return null;
7762
+ const alt = image.properties?.alt;
7763
+ return {
7764
+ href: node.properties?.href,
7765
+ src: image.properties?.src,
7766
+ alt: typeof alt === "string" ? alt.trim() : ""
7767
+ };
7768
+ }
7769
+ function isCardableVideo(embed, origins) {
7770
+ if (!isInlineVideoAllowed(embed.href, origins) || !isInlineImageAllowed(embed.src, origins)) {
7771
+ return false;
7772
+ }
7773
+ return apexOriginOf(new URL(embed.href)) === apexOriginOf(new URL(embed.src));
7774
+ }
7775
+ var NO_VIDEO_CONTAINERS = /* @__PURE__ */ new Set(["li", "table"]);
7776
+ function rehypeProductVideo(options) {
7777
+ return (tree) => {
7778
+ let claimed = false;
7779
+ const visit = (node, parent, contained) => {
7780
+ const embed = linkedImageOf(node);
7781
+ if (embed !== null && isVideoFileTarget(embed.href)) {
7782
+ const card = !claimed && !contained && parent?.tagName === "p" && isCardableVideo(embed, options.origins);
7783
+ if (card) claimed = true;
7784
+ const data = typeof node.data === "object" ? node.data : null;
7785
+ node.data = { ...data, boffVideo: card ? "card" : "drop" };
7786
+ return;
7787
+ }
7788
+ const inside = contained || node.tagName !== void 0 && NO_VIDEO_CONTAINERS.has(node.tagName);
7789
+ for (const child of node.children ?? []) visit(child, node, inside);
7790
+ };
7791
+ visit(tree, null, false);
7792
+ };
7793
+ }
7794
+ function videoRoleOf(node) {
7795
+ const data = node?.data;
7796
+ if (typeof data !== "object" || data === null || !("boffVideo" in data)) {
7797
+ return void 0;
7798
+ }
7799
+ return data.boffVideo === "card" || data.boffVideo === "drop" ? data.boffVideo : void 0;
7800
+ }
7801
+ function productVideoOf(node) {
7802
+ const embed = linkedImageOf(node);
7803
+ if (embed === null || typeof embed.href !== "string" || typeof embed.src !== "string") {
7804
+ return null;
7805
+ }
7806
+ return { href: embed.href, poster: embed.src, alt: embed.alt };
7807
+ }
7808
+ var CANONICAL_VIDEO_ALT = /^(.+?)\s+product video$/i;
7809
+ function videoTitleOf(alt, T) {
7810
+ const product = CANONICAL_VIDEO_ALT.exec(alt)?.[1]?.trim();
7811
+ if (product) return fill(T.productVideoTitle, { product });
7812
+ return alt === "" ? T.productVideo : alt;
7813
+ }
7814
+ var INLINE_VIDEO_FRAME = "group relative block aspect-video w-full max-w-md overflow-hidden rounded-xl border border-border bg-muted shadow-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring";
7815
+ function InlineVideoCard({
7816
+ href,
7817
+ poster,
7818
+ alt,
7819
+ scope
7820
+ }) {
7821
+ const { strings: T, failed, onFailed, productSlugs } = scope;
7822
+ const [dialogDir, setDialogDir] = useState(null);
7823
+ const buttonRef = useRef(null);
7824
+ const returnFocusRef = useRef(false);
7825
+ const open = dialogDir !== null;
7826
+ useEffect(() => {
7827
+ if (open || !returnFocusRef.current) return;
7828
+ returnFocusRef.current = false;
7829
+ const button = buttonRef.current;
7830
+ if (button?.isConnected) button.focus();
7831
+ }, [open]);
7832
+ const openPlayer = useCallback((event) => {
7833
+ const dir = event.currentTarget.closest("[dir]")?.getAttribute("dir");
7834
+ returnFocusRef.current = true;
7835
+ setDialogDir(dir === "rtl" ? "rtl" : "ltr");
7836
+ }, []);
7837
+ const closePlayer = useCallback(() => setDialogDir(null), []);
7838
+ const name = videoTitleOf(alt, T);
7839
+ const posterFailed = failed.has(poster);
7840
+ return /* @__PURE__ */ jsxs(
7841
+ "span",
7842
+ {
7843
+ "data-boff-explore": "inline-video",
7844
+ "data-product": videoProductOf(href, productSlugs),
7845
+ className: "my-3 block",
7846
+ children: [
7847
+ /* @__PURE__ */ jsxs(
7848
+ "button",
7849
+ {
7850
+ ref: buttonRef,
7851
+ type: "button",
7852
+ "aria-haspopup": "dialog",
7853
+ "aria-label": fill(T.playVideo, { title: name }),
7854
+ onClick: openPlayer,
7855
+ className: INLINE_VIDEO_FRAME,
7856
+ children: [
7857
+ posterFailed ? /* @__PURE__ */ jsx(
7858
+ "span",
7859
+ {
7860
+ "aria-hidden": "true",
7861
+ className: "absolute inset-0 flex items-center justify-center bg-muted text-muted-foreground",
7862
+ children: /* @__PURE__ */ jsx(Film, { className: "h-10 w-10" })
7863
+ }
7864
+ ) : /* @__PURE__ */ jsx(
7865
+ "img",
7866
+ {
7867
+ src: poster,
7868
+ alt: "",
7869
+ loading: "lazy",
7870
+ decoding: "async",
7871
+ onError: () => onFailed(poster),
7872
+ className: "boff-explore-video-poster absolute inset-0 h-full w-full object-cover"
7873
+ }
7874
+ ),
7875
+ /* @__PURE__ */ jsx(
7876
+ "span",
7877
+ {
7878
+ "aria-hidden": "true",
7879
+ className: "pointer-events-none absolute inset-0 flex items-center justify-center",
7880
+ children: /* @__PURE__ */ jsx("span", { className: "flex h-14 w-14 items-center justify-center rounded-full border border-border bg-background/90 text-foreground shadow-md transition-transform group-hover:scale-105", children: /* @__PURE__ */ jsx(Play, { className: "h-6 w-6 fill-current" }) })
7881
+ }
7882
+ ),
7883
+ /* @__PURE__ */ jsx(
7884
+ "span",
7885
+ {
7886
+ "aria-hidden": "true",
7887
+ className: "pointer-events-none absolute start-2 top-2 rounded-full border border-border bg-background/90 px-2 py-0.5 text-[10px] font-semibold uppercase tracking-wide text-foreground shadow-sm",
7888
+ children: T.productVideo
7889
+ }
7890
+ )
7891
+ ]
7892
+ }
7893
+ ),
7894
+ open ? /* @__PURE__ */ jsx(
7895
+ ExploreVideoDialog,
7896
+ {
7897
+ videoUrl: href,
7898
+ posterUrl: poster,
7899
+ title: name,
7900
+ strings: T,
7901
+ dir: dialogDir,
7902
+ onClose: closePlayer
7903
+ }
7904
+ ) : null
7905
+ ]
7906
+ }
7907
+ );
7908
+ }
7381
7909
  var ANSWER_MARKDOWN_COMPONENTS = {
7382
7910
  a: AnswerLink,
7383
7911
  img: InlineConceptImage,
7384
7912
  table: AnswerTable,
7385
7913
  tr: AnswerTableRow
7386
7914
  };
7915
+ var NO_PRODUCT_SLUGS = /* @__PURE__ */ new Map();
7387
7916
  function ExploreAnswerBody({
7388
7917
  children,
7389
7918
  strings,
7390
7919
  imageOrigins,
7920
+ videoOrigins = imageOrigins,
7921
+ productSlugs = NO_PRODUCT_SLUGS,
7391
7922
  enabled = true,
7392
7923
  components,
7393
7924
  className
@@ -7403,16 +7934,21 @@ function ExploreAnswerBody({
7403
7934
  strings,
7404
7935
  enabled,
7405
7936
  origins: imageOrigins,
7937
+ productSlugs,
7406
7938
  failed,
7407
7939
  onFailed
7408
7940
  }),
7409
- [strings, enabled, imageOrigins, failed, onFailed]
7941
+ [strings, enabled, imageOrigins, productSlugs, failed, onFailed]
7942
+ );
7943
+ const rehypePlugins = useMemo(
7944
+ () => [[rehypeProductVideo, { origins: videoOrigins }]],
7945
+ [videoOrigins]
7410
7946
  );
7411
7947
  const overrides = useMemo(
7412
7948
  () => components ? { ...ANSWER_MARKDOWN_COMPONENTS, ...components } : ANSWER_MARKDOWN_COMPONENTS,
7413
7949
  [components]
7414
7950
  );
7415
- return /* @__PURE__ */ jsx("div", { className: cn("boff-prose boff-explore-body min-w-0", className), children: /* @__PURE__ */ jsx(AnswerScopeContext.Provider, { value: scope, children: /* @__PURE__ */ jsx(Markdown, { components: overrides, children }) }) });
7951
+ return /* @__PURE__ */ jsx("div", { className: cn("boff-prose boff-explore-body min-w-0", className), children: /* @__PURE__ */ jsx(AnswerScopeContext.Provider, { value: scope, children: /* @__PURE__ */ jsx(Markdown, { components: overrides, rehypePlugins, children }) }) });
7416
7952
  }
7417
7953
  var PROSE_CSS = `
7418
7954
  .boff-prose {
@@ -7590,60 +8126,239 @@ var PROSE_CSS = `
7590
8126
  function ProseStyles() {
7591
8127
  return /* @__PURE__ */ jsx("style", { dangerouslySetInnerHTML: { __html: PROSE_CSS } });
7592
8128
  }
7593
- var META_DESCRIPTION_LIMIT2 = 160;
7594
- var TITLE_LIMIT = 100;
7595
- var RELATED_LIMIT2 = 4;
7596
- function normaliseSiteUrl2(siteUrl) {
7597
- return siteUrl.trim().replace(/\/+$/, "");
7598
- }
7599
- function absoluteUrl2(base, path) {
7600
- if (/^https?:\/\//i.test(path)) return path;
7601
- return `${base}${path.startsWith("/") ? path : `/${path}`}`;
7602
- }
7603
- function sortByOrder2(answers) {
7604
- return [...answers].sort(
7605
- (a, b) => a.order - b.order || a.slug.localeCompare(b.slug)
7606
- );
7607
- }
7608
- function clampText2(text, limit) {
7609
- if (text.length <= limit) return text;
7610
- const cut = text.slice(0, limit - 1);
7611
- const lastSpace = cut.lastIndexOf(" ");
7612
- return `${(lastSpace > 0 ? cut.slice(0, lastSpace) : cut).replace(/[\s,;:—–-]+$/, "")}\u2026`;
7613
- }
7614
- function questionCount(T, count) {
7615
- return count === 1 ? T.questionCountOne : fill(T.questionCountMany, { count: String(count) });
7616
- }
7617
- function sourceCount(T, count) {
7618
- return count === 1 ? T.sourceCountOne : fill(T.sourceCountMany, { count: String(count) });
7619
- }
7620
- function slugifyAnchor2(value) {
7621
- return value.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
7622
- }
7623
- function publishableSources(sources) {
7624
- const seen = /* @__PURE__ */ new Set();
7625
- const kept = [];
7626
- for (const source of sources) {
7627
- if (!isPublishedSourceUrl(source.url) || seen.has(source.url)) continue;
7628
- seen.add(source.url);
7629
- kept.push(source);
7630
- }
7631
- return kept;
7632
- }
7633
- function groupByTopic(ordered, topics) {
7634
- const byName = /* @__PURE__ */ new Map();
7635
- for (const answer of ordered) {
7636
- const list = byName.get(answer.topic);
7637
- if (list) list.push(answer);
7638
- else byName.set(answer.topic, [answer]);
7639
- }
7640
- const described = [];
7641
- for (const topic of topics ?? []) {
7642
- const list = byName.get(topic.name);
7643
- if (!list) continue;
7644
- described.push({
7645
- name: topic.name,
7646
- description: topic.description,
8129
+
8130
+ // src/data/products.ts
8131
+ var ECOSYSTEM_PRODUCTS = [
8132
+ {
8133
+ slug: "workspaces",
8134
+ name: "Workspaces",
8135
+ websiteUrl: "https://burdenoff.com"
8136
+ },
8137
+ {
8138
+ slug: "vibecontrols",
8139
+ name: "VibeControls",
8140
+ websiteUrl: "https://vibecontrols.com"
8141
+ },
8142
+ // FluidGrids ships on www.fluidgrids.ai — fluidgrids.com only redirects there. The explore
8143
+ // catalog and the site's own sitemap use this origin, and so must the fallback catalog
8144
+ // built from this list, or /explore rejects FluidGrids concept images until it loads.
8145
+ {
8146
+ slug: "fluidgrids",
8147
+ name: "FluidGrids",
8148
+ websiteUrl: "https://www.fluidgrids.ai"
8149
+ },
8150
+ // BotManor ships on www.botmanor.com (the apex redirects there; the old botlit.ai domain
8151
+ // still serves the same site but is no longer the name we link to).
8152
+ { slug: "botlit", name: "BotManor", websiteUrl: "https://www.botmanor.com" },
8153
+ {
8154
+ slug: "bigconsole",
8155
+ name: "BigConsole",
8156
+ websiteUrl: "https://bigconsole.com"
8157
+ },
8158
+ {
8159
+ slug: "semanticfed",
8160
+ name: "SemanticFed",
8161
+ websiteUrl: "https://semanticfed.com"
8162
+ },
8163
+ {
8164
+ slug: "intelwatchtower",
8165
+ name: "IntelWatchtower",
8166
+ websiteUrl: "https://intelwatchtower.com"
8167
+ },
8168
+ { slug: "buildmyiq", name: "BuildMyIQ", websiteUrl: "https://buildmyiq.com" },
8169
+ {
8170
+ slug: "assethandler",
8171
+ name: "AssetHandler",
8172
+ websiteUrl: "https://assethandler.com"
8173
+ },
8174
+ {
8175
+ slug: "crewfoundry",
8176
+ name: "CrewFoundry",
8177
+ websiteUrl: "https://crewfoundry.com"
8178
+ },
8179
+ {
8180
+ slug: "planmagnet",
8181
+ name: "PlanMagnet",
8182
+ websiteUrl: "https://planmagnet.com"
8183
+ },
8184
+ {
8185
+ slug: "eventfullymanaged",
8186
+ name: "EventfullyManaged",
8187
+ websiteUrl: "https://eventfullymanaged.com"
8188
+ },
8189
+ {
8190
+ slug: "headshotmarketing",
8191
+ name: "HeadshotMarketing",
8192
+ websiteUrl: "https://headshotmarketing.com"
8193
+ },
8194
+ {
8195
+ slug: "technospam",
8196
+ name: "TechnoSpam",
8197
+ websiteUrl: "https://technospam.com"
8198
+ },
8199
+ { slug: "kadaikodi", name: "Kadaikodi", websiteUrl: "https://kadaikodi.com" },
8200
+ {
8201
+ slug: "movethewheels",
8202
+ name: "MoveTheWheels",
8203
+ websiteUrl: "https://movethewheels.com"
8204
+ },
8205
+ {
8206
+ slug: "healthybowl",
8207
+ name: "Healthy Bowl",
8208
+ websiteUrl: "https://gethealthybowl.com"
8209
+ },
8210
+ { slug: "ggnomad", name: "GGNomad", websiteUrl: "https://ggnomad.com" },
8211
+ {
8212
+ slug: "timecampus",
8213
+ name: "TimeCampus",
8214
+ websiteUrl: "https://timecampus.com"
8215
+ },
8216
+ {
8217
+ slug: "manufacturedops",
8218
+ name: "ManufacturedOps",
8219
+ websiteUrl: "https://manufacturedops.com"
8220
+ },
8221
+ {
8222
+ slug: "theglobalfuel",
8223
+ name: "TheGlobalFuel",
8224
+ websiteUrl: "https://theglobalfuel.com"
8225
+ },
8226
+ {
8227
+ slug: "housingvista",
8228
+ name: "HousingVista",
8229
+ websiteUrl: "https://housingvista.com"
8230
+ },
8231
+ {
8232
+ slug: "proserviceworld",
8233
+ name: "ProServiceWorld",
8234
+ websiteUrl: "https://proserviceworld.com"
8235
+ },
8236
+ {
8237
+ slug: "mybodyshield",
8238
+ name: "MyBodyShield",
8239
+ websiteUrl: "https://mybodyshield.com"
8240
+ },
8241
+ {
8242
+ slug: "artistrybase",
8243
+ name: "ArtistryBase",
8244
+ websiteUrl: "https://artistrybase.com"
8245
+ },
8246
+ {
8247
+ slug: "theculturepost",
8248
+ name: "TheCulturePost",
8249
+ websiteUrl: "https://theculturepost.com"
8250
+ },
8251
+ { slug: "collabkin", name: "CollabKin", websiteUrl: "https://collabkin.com" },
8252
+ {
8253
+ slug: "comradecircle",
8254
+ name: "ComradeCircle",
8255
+ websiteUrl: "https://comradecircle.com"
8256
+ },
8257
+ {
8258
+ slug: "brainyrich",
8259
+ name: "BrainyRich",
8260
+ websiteUrl: "https://brainyrich.com"
8261
+ },
8262
+ {
8263
+ slug: "cosmicintersection",
8264
+ name: "CosmicIntersection",
8265
+ websiteUrl: "https://cosmicintersection.com"
8266
+ },
8267
+ {
8268
+ slug: "govcitizenhub",
8269
+ name: "GovCitizenHub",
8270
+ websiteUrl: "https://govcitizenhub.com"
8271
+ },
8272
+ {
8273
+ slug: "adaptercloud",
8274
+ name: "AdapterCloud",
8275
+ websiteUrl: "https://adaptercloud.com"
8276
+ },
8277
+ {
8278
+ slug: "subscriberbot",
8279
+ name: "Subscriber Bot",
8280
+ websiteUrl: "https://subscriberbot.com"
8281
+ },
8282
+ {
8283
+ slug: "hookmovies",
8284
+ name: "HookMovies",
8285
+ websiteUrl: "https://hookmovies.com"
8286
+ },
8287
+ {
8288
+ slug: "coolandlovely",
8289
+ name: "CoolAndLovely",
8290
+ websiteUrl: "https://coolandlovely.com"
8291
+ },
8292
+ {
8293
+ slug: "atheletebridge",
8294
+ name: "AthleteBridge",
8295
+ websiteUrl: "https://atheletebridge.com"
8296
+ },
8297
+ {
8298
+ slug: "labsofscience",
8299
+ name: "LabsOfScience",
8300
+ websiteUrl: "https://labsofscience.com"
8301
+ },
8302
+ {
8303
+ slug: "ecoimpacthub",
8304
+ name: "EcoImpactHub",
8305
+ websiteUrl: "https://ecoimpacthub.com"
8306
+ }
8307
+ ];
8308
+ var META_DESCRIPTION_LIMIT2 = 160;
8309
+ var TITLE_LIMIT = 100;
8310
+ var RELATED_LIMIT2 = 4;
8311
+ function normaliseSiteUrl2(siteUrl) {
8312
+ return siteUrl.trim().replace(/\/+$/, "");
8313
+ }
8314
+ function absoluteUrl2(base, path) {
8315
+ if (/^https?:\/\//i.test(path)) return path;
8316
+ return `${base}${path.startsWith("/") ? path : `/${path}`}`;
8317
+ }
8318
+ function sortByOrder2(answers) {
8319
+ return [...answers].sort(
8320
+ (a, b) => a.order - b.order || a.slug.localeCompare(b.slug)
8321
+ );
8322
+ }
8323
+ function clampText2(text, limit) {
8324
+ if (text.length <= limit) return text;
8325
+ const cut = text.slice(0, limit - 1);
8326
+ const lastSpace = cut.lastIndexOf(" ");
8327
+ return `${(lastSpace > 0 ? cut.slice(0, lastSpace) : cut).replace(/[\s,;:—–-]+$/, "")}\u2026`;
8328
+ }
8329
+ function questionCount(T, count) {
8330
+ return count === 1 ? T.questionCountOne : fill(T.questionCountMany, { count: String(count) });
8331
+ }
8332
+ function sourceCount(T, count) {
8333
+ return count === 1 ? T.sourceCountOne : fill(T.sourceCountMany, { count: String(count) });
8334
+ }
8335
+ function slugifyAnchor2(value) {
8336
+ return value.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
8337
+ }
8338
+ function publishableSources(sources) {
8339
+ const seen = /* @__PURE__ */ new Set();
8340
+ const kept = [];
8341
+ for (const source of sources) {
8342
+ if (!isPublishedSourceUrl(source.url) || seen.has(source.url)) continue;
8343
+ seen.add(source.url);
8344
+ kept.push(source);
8345
+ }
8346
+ return kept;
8347
+ }
8348
+ function groupByTopic(ordered, topics) {
8349
+ const byName = /* @__PURE__ */ new Map();
8350
+ for (const answer of ordered) {
8351
+ const list = byName.get(answer.topic);
8352
+ if (list) list.push(answer);
8353
+ else byName.set(answer.topic, [answer]);
8354
+ }
8355
+ const described = [];
8356
+ for (const topic of topics ?? []) {
8357
+ const list = byName.get(topic.name);
8358
+ if (!list) continue;
8359
+ described.push({
8360
+ name: topic.name,
8361
+ description: topic.description,
7647
8362
  answers: list
7648
8363
  });
7649
8364
  byName.delete(topic.name);
@@ -7695,6 +8410,12 @@ var ANSWER_HEADING_SHIFT = {
7695
8410
  h6: demoteHeading("h6")
7696
8411
  };
7697
8412
  var ENGLISH_TEXT = { lang: "en" };
8413
+ var ECOSYSTEM_SITES = ECOSYSTEM_PRODUCTS.map((product) => ({
8414
+ slug: product.slug,
8415
+ website: product.websiteUrl
8416
+ }));
8417
+ var ECOSYSTEM_PRODUCT_SLUGS = productSlugsByOrigin(ECOSYSTEM_SITES);
8418
+ var ECOSYSTEM_ORIGINS = inlineImageOrigins(ECOSYSTEM_SITES);
7698
8419
  function DefaultAnswerLink({
7699
8420
  href,
7700
8421
  className,
@@ -8193,6 +8914,10 @@ function AnswerDetail({
8193
8914
  ]),
8194
8915
  [base, sources, imageOrigins]
8195
8916
  );
8917
+ const answerVideoOrigins = useMemo(
8918
+ () => /* @__PURE__ */ new Set([...answerImageOrigins, ...ECOSYSTEM_ORIGINS]),
8919
+ [answerImageOrigins]
8920
+ );
8196
8921
  const canonical = absoluteUrl2(base, answerPath(answer.slug));
8197
8922
  const answerText = useMemo(
8198
8923
  () => answerSpeechText(answer.answer),
@@ -8354,6 +9079,8 @@ function AnswerDetail({
8354
9079
  {
8355
9080
  strings: T,
8356
9081
  imageOrigins: answerImageOrigins,
9082
+ videoOrigins: answerVideoOrigins,
9083
+ productSlugs: ECOSYSTEM_PRODUCT_SLUGS,
8357
9084
  components: ANSWER_HEADING_SHIFT,
8358
9085
  className: "mt-4",
8359
9086
  children: answer.answer
@@ -8715,185 +9442,6 @@ var EXPLORE_SHARED_CONVERSATION_QUERY = (
8715
9442
  `
8716
9443
  );
8717
9444
 
8718
- // src/data/products.ts
8719
- var ECOSYSTEM_PRODUCTS = [
8720
- {
8721
- slug: "workspaces",
8722
- name: "Workspaces",
8723
- websiteUrl: "https://burdenoff.com"
8724
- },
8725
- {
8726
- slug: "vibecontrols",
8727
- name: "VibeControls",
8728
- websiteUrl: "https://vibecontrols.com"
8729
- },
8730
- // FluidGrids ships on www.fluidgrids.ai — fluidgrids.com only redirects there. The explore
8731
- // catalog and the site's own sitemap use this origin, and so must the fallback catalog
8732
- // built from this list, or /explore rejects FluidGrids concept images until it loads.
8733
- {
8734
- slug: "fluidgrids",
8735
- name: "FluidGrids",
8736
- websiteUrl: "https://www.fluidgrids.ai"
8737
- },
8738
- // BotManor ships on www.botmanor.com (the apex redirects there; the old botlit.ai domain
8739
- // still serves the same site but is no longer the name we link to).
8740
- { slug: "botlit", name: "BotManor", websiteUrl: "https://www.botmanor.com" },
8741
- {
8742
- slug: "bigconsole",
8743
- name: "BigConsole",
8744
- websiteUrl: "https://bigconsole.com"
8745
- },
8746
- {
8747
- slug: "semanticfed",
8748
- name: "SemanticFed",
8749
- websiteUrl: "https://semanticfed.com"
8750
- },
8751
- {
8752
- slug: "intelwatchtower",
8753
- name: "IntelWatchtower",
8754
- websiteUrl: "https://intelwatchtower.com"
8755
- },
8756
- { slug: "buildmyiq", name: "BuildMyIQ", websiteUrl: "https://buildmyiq.com" },
8757
- {
8758
- slug: "assethandler",
8759
- name: "AssetHandler",
8760
- websiteUrl: "https://assethandler.com"
8761
- },
8762
- {
8763
- slug: "crewfoundry",
8764
- name: "CrewFoundry",
8765
- websiteUrl: "https://crewfoundry.com"
8766
- },
8767
- {
8768
- slug: "planmagnet",
8769
- name: "PlanMagnet",
8770
- websiteUrl: "https://planmagnet.com"
8771
- },
8772
- {
8773
- slug: "eventfullymanaged",
8774
- name: "EventfullyManaged",
8775
- websiteUrl: "https://eventfullymanaged.com"
8776
- },
8777
- {
8778
- slug: "headshotmarketing",
8779
- name: "HeadshotMarketing",
8780
- websiteUrl: "https://headshotmarketing.com"
8781
- },
8782
- {
8783
- slug: "technospam",
8784
- name: "TechnoSpam",
8785
- websiteUrl: "https://technospam.com"
8786
- },
8787
- { slug: "kadaikodi", name: "Kadaikodi", websiteUrl: "https://kadaikodi.com" },
8788
- {
8789
- slug: "movethewheels",
8790
- name: "MoveTheWheels",
8791
- websiteUrl: "https://movethewheels.com"
8792
- },
8793
- {
8794
- slug: "healthybowl",
8795
- name: "Healthy Bowl",
8796
- websiteUrl: "https://gethealthybowl.com"
8797
- },
8798
- { slug: "ggnomad", name: "GGNomad", websiteUrl: "https://ggnomad.com" },
8799
- {
8800
- slug: "timecampus",
8801
- name: "TimeCampus",
8802
- websiteUrl: "https://timecampus.com"
8803
- },
8804
- {
8805
- slug: "manufacturedops",
8806
- name: "ManufacturedOps",
8807
- websiteUrl: "https://manufacturedops.com"
8808
- },
8809
- {
8810
- slug: "theglobalfuel",
8811
- name: "TheGlobalFuel",
8812
- websiteUrl: "https://theglobalfuel.com"
8813
- },
8814
- {
8815
- slug: "housingvista",
8816
- name: "HousingVista",
8817
- websiteUrl: "https://housingvista.com"
8818
- },
8819
- {
8820
- slug: "proserviceworld",
8821
- name: "ProServiceWorld",
8822
- websiteUrl: "https://proserviceworld.com"
8823
- },
8824
- {
8825
- slug: "mybodyshield",
8826
- name: "MyBodyShield",
8827
- websiteUrl: "https://mybodyshield.com"
8828
- },
8829
- {
8830
- slug: "artistrybase",
8831
- name: "ArtistryBase",
8832
- websiteUrl: "https://artistrybase.com"
8833
- },
8834
- {
8835
- slug: "theculturepost",
8836
- name: "TheCulturePost",
8837
- websiteUrl: "https://theculturepost.com"
8838
- },
8839
- { slug: "collabkin", name: "CollabKin", websiteUrl: "https://collabkin.com" },
8840
- {
8841
- slug: "comradecircle",
8842
- name: "ComradeCircle",
8843
- websiteUrl: "https://comradecircle.com"
8844
- },
8845
- {
8846
- slug: "brainyrich",
8847
- name: "BrainyRich",
8848
- websiteUrl: "https://brainyrich.com"
8849
- },
8850
- {
8851
- slug: "cosmicintersection",
8852
- name: "CosmicIntersection",
8853
- websiteUrl: "https://cosmicintersection.com"
8854
- },
8855
- {
8856
- slug: "govcitizenhub",
8857
- name: "GovCitizenHub",
8858
- websiteUrl: "https://govcitizenhub.com"
8859
- },
8860
- {
8861
- slug: "adaptercloud",
8862
- name: "AdapterCloud",
8863
- websiteUrl: "https://adaptercloud.com"
8864
- },
8865
- {
8866
- slug: "subscriberbot",
8867
- name: "Subscriber Bot",
8868
- websiteUrl: "https://subscriberbot.com"
8869
- },
8870
- {
8871
- slug: "hookmovies",
8872
- name: "HookMovies",
8873
- websiteUrl: "https://hookmovies.com"
8874
- },
8875
- {
8876
- slug: "coolandlovely",
8877
- name: "CoolAndLovely",
8878
- websiteUrl: "https://coolandlovely.com"
8879
- },
8880
- {
8881
- slug: "atheletebridge",
8882
- name: "AthleteBridge",
8883
- websiteUrl: "https://atheletebridge.com"
8884
- },
8885
- {
8886
- slug: "labsofscience",
8887
- name: "LabsOfScience",
8888
- websiteUrl: "https://labsofscience.com"
8889
- },
8890
- {
8891
- slug: "ecoimpacthub",
8892
- name: "EcoImpactHub",
8893
- websiteUrl: "https://ecoimpacthub.com"
8894
- }
8895
- ];
8896
-
8897
9445
  // src/utils/recaptcha-v3.ts
8898
9446
  var SCRIPT_ID = "boff-recaptcha-v3";
8899
9447
  var SCRIPT_SRC = "https://www.google.com/recaptcha/api.js?render=";
@@ -10011,7 +10559,7 @@ function isHighSurrogate(code) {
10011
10559
  }
10012
10560
  function safeInlineEnd(line) {
10013
10561
  let codeSpan = null;
10014
- let link = null;
10562
+ const links = [];
10015
10563
  const emphasis = [];
10016
10564
  let at = 0;
10017
10565
  while (at < line.length) {
@@ -10020,6 +10568,13 @@ function safeInlineEnd(line) {
10020
10568
  at += 2;
10021
10569
  continue;
10022
10570
  }
10571
+ const innermost = links[links.length - 1];
10572
+ if (innermost !== void 0 && innermost.kind !== "label") {
10573
+ if (char === "(") links.push({ kind: "paren", start: innermost.start });
10574
+ else if (char === ")") links.pop();
10575
+ at += 1;
10576
+ continue;
10577
+ }
10023
10578
  if (char === "`") {
10024
10579
  let run = 1;
10025
10580
  while (line[at + run] === "`") run += 1;
@@ -10032,17 +10587,17 @@ function safeInlineEnd(line) {
10032
10587
  continue;
10033
10588
  }
10034
10589
  if (char === "[") {
10035
- if (link === null) link = line[at - 1] === "!" ? at - 1 : at;
10590
+ links.push({ kind: "label", start: line[at - 1] === "!" ? at - 1 : at });
10036
10591
  at += 1;
10037
10592
  continue;
10038
10593
  }
10039
- if (char === "]") {
10040
- if (link !== null && line[at + 1] !== "(") link = null;
10041
- at += 1;
10042
- continue;
10043
- }
10044
- if (char === ")") {
10045
- link = null;
10594
+ if (char === "]" && innermost !== void 0) {
10595
+ links.pop();
10596
+ if (line[at + 1] === "(") {
10597
+ links.push({ kind: "destination", start: innermost.start });
10598
+ at += 2;
10599
+ continue;
10600
+ }
10046
10601
  at += 1;
10047
10602
  continue;
10048
10603
  }
@@ -10069,9 +10624,11 @@ function safeInlineEnd(line) {
10069
10624
  }
10070
10625
  at += 1;
10071
10626
  }
10072
- const open = [codeSpan, link, emphasis[0]?.start ?? null].filter(
10073
- (value) => value !== null
10074
- );
10627
+ const open = [
10628
+ codeSpan,
10629
+ links[0]?.start ?? null,
10630
+ emphasis[0]?.start ?? null
10631
+ ].filter((value) => value !== null);
10075
10632
  return open.length === 0 ? line.length : Math.min(...open);
10076
10633
  }
10077
10634
  function revealBoundary(text, limit) {
@@ -11933,6 +12490,7 @@ function AssistantBubble({
11933
12490
  message,
11934
12491
  activity,
11935
12492
  imageOrigins,
12493
+ productSlugs,
11936
12494
  productNames,
11937
12495
  speechLang,
11938
12496
  onNavigate,
@@ -12047,6 +12605,7 @@ function AssistantBubble({
12047
12605
  {
12048
12606
  strings: T,
12049
12607
  imageOrigins,
12608
+ productSlugs,
12050
12609
  enabled: completed,
12051
12610
  className: "boff-prose-sm text-card-foreground",
12052
12611
  children: visible
@@ -12804,6 +13363,10 @@ function ExplorePage({
12804
13363
  () => productNamesByOrigin(catalog.products),
12805
13364
  [catalog.products]
12806
13365
  );
13366
+ const productSlugs = useMemo(
13367
+ () => productSlugsByOrigin(catalog.products),
13368
+ [catalog.products]
13369
+ );
12807
13370
  useEffect(() => {
12808
13371
  const el = textareaRef.current;
12809
13372
  if (!el) return;
@@ -13366,6 +13929,7 @@ function ExplorePage({
13366
13929
  message,
13367
13930
  activity,
13368
13931
  imageOrigins,
13932
+ productSlugs,
13369
13933
  productNames,
13370
13934
  speechLang,
13371
13935
  onNavigate,
@@ -18361,6 +18925,6 @@ function shouldRenderSiteFooter(pathname) {
18361
18925
  return !isFooterlessPath(pathname);
18362
18926
  }
18363
18927
 
18364
- export { ANSWERS_PATH, ANSWER_HEADING_SHIFT, ANSWER_PATH_PREFIX, AnswerDetailPage, AnswersPage, BlogListPage, BlogPostPage, Button, CONCEPTS_PATH, CONCEPT_ILLUSTRATION_NOTICE, CONCEPT_PATH_PREFIX, CareersApplyForm, CareersSubmissionForm, CaseStudiesListPage, CaseStudyPage, ChangelogPage, ConceptDetailPage, ConceptsPage, ContactPage, ContentRenderer, ContractsPage, DEFAULT_CONTACT_CATEGORIES, DEFAULT_EXPLORE_EXAMPLE_PROMPTS, DOMAINS_URL, ECOSYSTEM_PRODUCTS, ESCALATE_EXPLORE_CONVERSATION_MUTATION, EXPLORE_CATALOG_QUERY, EXPLORE_CATALOG_QUERY_WITHOUT_HIGHLIGHTS, EXPLORE_ESCALATION_NOTE_SOFT_MAX, EXPLORE_LOCALES, EXPLORE_MESSAGE_QUERY, EXPLORE_PREFILL_MAX_LENGTH, EXPLORE_RECAPTCHA_ACTION, ElectronDownloadLink, ExploreAnswerBody, ExploreAnswerStyles, ExploreCta, ExplorePage, FALLBACK_EXPLORE_LIMITS, FOOTERLESS_ROUTES, Input, Label, LaunchCountdown, Markdown, NewsletterForm, NewsletterPage, PUBLISHED_ANSWER_FIELDS, PageHead, PartnersPage, PressKitPage, PricingPage, PricingSection, ProblemsSolvedSection, ProductCard, ProductProvider, ResourceLinks, RybbitAnalytics, SEND_EXPLORE_MESSAGE_MUTATION, Select, SocialLinks, StarRating, StoreBrowsePage, StoreHomePage, StoreProductDetailPage, Textarea, TypeBadge, UnsubscribePage, WaitlistForm, WaitlistPage, WebSDKClient, WebSDKProvider, WebsiteSwitcher, answerPath, answerPlainText, answerSourceHost, answerSpeechText, answerStrings, buttonVariants, classifyExploreError, cn, conceptPath, detectElectronPlatform, exploreQuestionHref, fetchPublicJobPosting, fetchPublicJobPostings, fetchPublicJobPostingsForSubmission, formatAnswerDate, formatDownloads, formatPrice2 as formatPrice, getAnswerBySlug, getConceptBySlug, getRecaptchaV3Token, inlineImageOrigins, isFooterlessPath, isInlineImageAllowed, isPublishedSourceUrl, isValidUrl, loadRecaptchaV3, looksLikeDeliverableEmail, normalizeRoutePath, shouldRenderSiteFooter, speechLocaleOf, stopSpeaking, useContentPage, useContentPages, useExploreChat, useProduct, useProductConfig, useProgressiveReveal, usePublicJobPosting, usePublicJobPostings, usePublicJobPostingsForSubmission, useSpeechOutput, useWebSDK, useWebSDKConfig };
18928
+ export { ANSWERS_PATH, ANSWER_HEADING_SHIFT, ANSWER_PATH_PREFIX, AnswerDetailPage, AnswersPage, BlogListPage, BlogPostPage, Button, CONCEPTS_PATH, CONCEPT_ILLUSTRATION_NOTICE, CONCEPT_PATH_PREFIX, CareersApplyForm, CareersSubmissionForm, CaseStudiesListPage, CaseStudyPage, ChangelogPage, ConceptDetailPage, ConceptsPage, ContactPage, ContentRenderer, ContractsPage, DEFAULT_CONTACT_CATEGORIES, DEFAULT_EXPLORE_EXAMPLE_PROMPTS, DOMAINS_URL, ECOSYSTEM_PRODUCTS, ESCALATE_EXPLORE_CONVERSATION_MUTATION, EXPLORE_CATALOG_QUERY, EXPLORE_CATALOG_QUERY_WITHOUT_HIGHLIGHTS, EXPLORE_ESCALATION_NOTE_SOFT_MAX, EXPLORE_LOCALES, EXPLORE_MESSAGE_QUERY, EXPLORE_PREFILL_MAX_LENGTH, EXPLORE_RECAPTCHA_ACTION, ElectronDownloadLink, ExploreAnswerBody, ExploreAnswerStyles, ExploreCta, ExplorePage, FALLBACK_EXPLORE_LIMITS, FOOTERLESS_ROUTES, Input, Label, LaunchCountdown, Markdown, NewsletterForm, NewsletterPage, PUBLISHED_ANSWER_FIELDS, PageHead, PartnersPage, PressKitPage, PricingPage, PricingSection, ProblemsSolvedSection, ProductCard, ProductProvider, ResourceLinks, RybbitAnalytics, SEND_EXPLORE_MESSAGE_MUTATION, Select, SocialLinks, StarRating, StoreBrowsePage, StoreHomePage, StoreProductDetailPage, Textarea, TypeBadge, UnsubscribePage, WaitlistForm, WaitlistPage, WebSDKClient, WebSDKProvider, WebsiteSwitcher, answerPath, answerPlainText, answerSourceHost, answerSpeechText, answerStrings, buttonVariants, classifyExploreError, cn, conceptPath, detectElectronPlatform, exploreQuestionHref, fetchPublicJobPosting, fetchPublicJobPostings, fetchPublicJobPostingsForSubmission, formatAnswerDate, formatDownloads, formatPrice2 as formatPrice, getAnswerBySlug, getConceptBySlug, getRecaptchaV3Token, inlineImageOrigins, isFooterlessPath, isInlineImageAllowed, isInlineVideoAllowed, isPublishedSourceUrl, isValidUrl, loadRecaptchaV3, looksLikeDeliverableEmail, normalizeRoutePath, productSlugsByOrigin, shouldRenderSiteFooter, speechLocaleOf, stopSpeaking, useContentPage, useContentPages, useExploreChat, useProduct, useProductConfig, useProgressiveReveal, usePublicJobPosting, usePublicJobPostings, usePublicJobPostingsForSubmission, useSpeechOutput, useWebSDK, useWebSDKConfig };
18365
18929
  //# sourceMappingURL=index.mjs.map
18366
18930
  //# sourceMappingURL=index.mjs.map