@burdenoff/website-sdk 2026.828.7 → 2026.829.1
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.
- package/dist/components/explore.js +401 -189
- package/dist/components/explore.js.map +1 -1
- package/dist/components/explore.mjs +403 -191
- package/dist/components/explore.mjs.map +1 -1
- package/dist/hooks/index.js +110 -68
- package/dist/hooks/index.js.map +1 -1
- package/dist/hooks/index.mjs +110 -68
- package/dist/hooks/index.mjs.map +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +401 -189
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +401 -189
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -5993,21 +5993,37 @@ function getRecognitionCtor() {
|
|
|
5993
5993
|
const w = window;
|
|
5994
5994
|
return w.SpeechRecognition ?? w.webkitSpeechRecognition ?? null;
|
|
5995
5995
|
}
|
|
5996
|
+
function isTouchDevice() {
|
|
5997
|
+
if (typeof window === "undefined" || !window.matchMedia) return false;
|
|
5998
|
+
try {
|
|
5999
|
+
return window.matchMedia("(pointer: coarse)").matches;
|
|
6000
|
+
} catch {
|
|
6001
|
+
return false;
|
|
6002
|
+
}
|
|
6003
|
+
}
|
|
5996
6004
|
var MIC_DENIED_MESSAGE = "Microphone access was blocked. Allow it in your browser's site settings to dictate.";
|
|
6005
|
+
var MIC_UNAVAILABLE_MESSAGE = "Dictation isn't available in this browser. You can type instead.";
|
|
6006
|
+
var RELEASE_SETTLE_MS = 250;
|
|
6007
|
+
var RETRY_DELAY_MS = 350;
|
|
6008
|
+
var sleep = (ms) => new Promise((resolve) => {
|
|
6009
|
+
setTimeout(resolve, ms);
|
|
6010
|
+
});
|
|
5997
6011
|
async function ensureMicrophoneAccess() {
|
|
5998
6012
|
const media = typeof navigator === "undefined" ? void 0 : navigator.mediaDevices;
|
|
5999
|
-
if (!media?.getUserMedia)
|
|
6013
|
+
if (!media?.getUserMedia)
|
|
6014
|
+
return { ok: true, confirmed: false, primed: false };
|
|
6000
6015
|
try {
|
|
6001
6016
|
const status = await navigator.permissions?.query({
|
|
6002
6017
|
name: "microphone"
|
|
6003
6018
|
});
|
|
6004
|
-
if (status?.state === "granted")
|
|
6019
|
+
if (status?.state === "granted")
|
|
6020
|
+
return { ok: true, confirmed: true, primed: false };
|
|
6005
6021
|
} catch {
|
|
6006
6022
|
}
|
|
6007
6023
|
try {
|
|
6008
6024
|
const stream = await media.getUserMedia({ audio: true });
|
|
6009
6025
|
for (const track of stream.getTracks()) track.stop();
|
|
6010
|
-
return { ok: true, confirmed: true };
|
|
6026
|
+
return { ok: true, confirmed: true, primed: true };
|
|
6011
6027
|
} catch (error) {
|
|
6012
6028
|
const name = typeof error === "object" && error !== null && "name" in error ? String(error.name) : "";
|
|
6013
6029
|
if (name === "NotAllowedError" || name === "SecurityError") {
|
|
@@ -6051,19 +6067,17 @@ function useSpeechInput({
|
|
|
6051
6067
|
const recognitionRef = React.useRef(null);
|
|
6052
6068
|
const startTokenRef = React.useRef(0);
|
|
6053
6069
|
const micConfirmedRef = React.useRef(false);
|
|
6054
|
-
const
|
|
6055
|
-
const
|
|
6056
|
-
(Ctor, token) => {
|
|
6057
|
-
beginRecognitionRef.current?.(Ctor, token);
|
|
6058
|
-
},
|
|
6059
|
-
[]
|
|
6060
|
-
);
|
|
6070
|
+
const wantsListeningRef = React.useRef(false);
|
|
6071
|
+
const retriedRef = React.useRef(false);
|
|
6061
6072
|
const finalRef = React.useRef(onFinalTranscript);
|
|
6062
6073
|
const errorRef = React.useRef(onError);
|
|
6063
6074
|
finalRef.current = onFinalTranscript;
|
|
6064
6075
|
errorRef.current = onError;
|
|
6076
|
+
const langRef = React.useRef(lang);
|
|
6077
|
+
langRef.current = lang;
|
|
6065
6078
|
const stop = React.useCallback(() => {
|
|
6066
6079
|
startTokenRef.current += 1;
|
|
6080
|
+
wantsListeningRef.current = false;
|
|
6067
6081
|
setListening(false);
|
|
6068
6082
|
setInterim("");
|
|
6069
6083
|
const recognition = recognitionRef.current;
|
|
@@ -6072,83 +6086,111 @@ function useSpeechInput({
|
|
|
6072
6086
|
recognition.stop();
|
|
6073
6087
|
} catch {
|
|
6074
6088
|
}
|
|
6075
|
-
setListening(false);
|
|
6076
|
-
setInterim("");
|
|
6077
6089
|
}, []);
|
|
6078
|
-
const
|
|
6090
|
+
const openSession = React.useCallback((token) => {
|
|
6079
6091
|
const Ctor = getRecognitionCtor();
|
|
6080
|
-
if (!Ctor) return;
|
|
6081
|
-
|
|
6082
|
-
|
|
6083
|
-
|
|
6092
|
+
if (!Ctor || token !== startTokenRef.current) return;
|
|
6093
|
+
const recognition = new Ctor();
|
|
6094
|
+
recognition.lang = langRef.current ?? (typeof navigator === "undefined" ? "en-US" : navigator.language || "en-US");
|
|
6095
|
+
recognition.continuous = !isTouchDevice();
|
|
6096
|
+
recognition.interimResults = true;
|
|
6097
|
+
recognition.maxAlternatives = 1;
|
|
6098
|
+
recognition.onstart = () => {
|
|
6099
|
+
if (token !== startTokenRef.current) return;
|
|
6100
|
+
setError(null);
|
|
6101
|
+
setListening(true);
|
|
6102
|
+
};
|
|
6103
|
+
recognition.onresult = (event) => {
|
|
6104
|
+
if (token !== startTokenRef.current) return;
|
|
6105
|
+
let settled = "";
|
|
6106
|
+
let pending = "";
|
|
6107
|
+
for (let i = event.resultIndex; i < event.results.length; i += 1) {
|
|
6108
|
+
const result = event.results[i];
|
|
6109
|
+
if (!result) continue;
|
|
6110
|
+
const text = result[0]?.transcript ?? "";
|
|
6111
|
+
if (result.isFinal) settled += text;
|
|
6112
|
+
else pending += text;
|
|
6113
|
+
}
|
|
6114
|
+
setInterim(pending);
|
|
6115
|
+
if (settled.trim() !== "") finalRef.current(settled);
|
|
6116
|
+
};
|
|
6117
|
+
recognition.onerror = (event) => {
|
|
6118
|
+
if (token !== startTokenRef.current) return;
|
|
6119
|
+
if ((event.error === "not-allowed" || event.error === "service-not-allowed") && micConfirmedRef.current && !retriedRef.current) {
|
|
6120
|
+
retriedRef.current = true;
|
|
6121
|
+
void sleep(RETRY_DELAY_MS).then(() => {
|
|
6122
|
+
if (token !== startTokenRef.current || !wantsListeningRef.current)
|
|
6123
|
+
return;
|
|
6124
|
+
openSessionRef.current?.(token);
|
|
6125
|
+
});
|
|
6126
|
+
return;
|
|
6127
|
+
}
|
|
6128
|
+
const message = micConfirmedRef.current && (event.error === "not-allowed" || event.error === "service-not-allowed") ? MIC_UNAVAILABLE_MESSAGE : describeError(event.error);
|
|
6129
|
+
wantsListeningRef.current = false;
|
|
6130
|
+
setListening(false);
|
|
6131
|
+
setInterim("");
|
|
6132
|
+
if (message !== "") {
|
|
6133
|
+
setError(message);
|
|
6134
|
+
errorRef.current?.(message);
|
|
6135
|
+
}
|
|
6136
|
+
};
|
|
6137
|
+
recognition.onend = () => {
|
|
6138
|
+
if (token !== startTokenRef.current) return;
|
|
6139
|
+
setInterim("");
|
|
6140
|
+
if (wantsListeningRef.current && isTouchDevice()) {
|
|
6141
|
+
void sleep(120).then(() => {
|
|
6142
|
+
if (token !== startTokenRef.current || !wantsListeningRef.current)
|
|
6143
|
+
return;
|
|
6144
|
+
openSessionRef.current?.(token);
|
|
6145
|
+
});
|
|
6146
|
+
return;
|
|
6147
|
+
}
|
|
6148
|
+
setListening(false);
|
|
6149
|
+
};
|
|
6150
|
+
recognitionRef.current = recognition;
|
|
6151
|
+
try {
|
|
6152
|
+
recognition.start();
|
|
6153
|
+
} catch {
|
|
6154
|
+
wantsListeningRef.current = false;
|
|
6155
|
+
setListening(false);
|
|
6156
|
+
}
|
|
6157
|
+
}, []);
|
|
6158
|
+
const openSessionRef = React.useRef(null);
|
|
6159
|
+
openSessionRef.current = openSession;
|
|
6160
|
+
const start = React.useCallback(() => {
|
|
6161
|
+
if (!getRecognitionCtor()) return;
|
|
6084
6162
|
startTokenRef.current += 1;
|
|
6085
6163
|
const token = startTokenRef.current;
|
|
6086
|
-
|
|
6164
|
+
wantsListeningRef.current = true;
|
|
6165
|
+
retriedRef.current = false;
|
|
6166
|
+
micConfirmedRef.current = false;
|
|
6167
|
+
setError(null);
|
|
6168
|
+
setListening(true);
|
|
6169
|
+
void ensureMicrophoneAccess().then(async (access) => {
|
|
6087
6170
|
if (token !== startTokenRef.current) return;
|
|
6088
|
-
micConfirmedRef.current = access.ok && access.confirmed;
|
|
6089
6171
|
if (!access.ok) {
|
|
6172
|
+
wantsListeningRef.current = false;
|
|
6090
6173
|
setListening(false);
|
|
6091
6174
|
setError(access.message);
|
|
6092
6175
|
errorRef.current?.(access.message);
|
|
6093
6176
|
return;
|
|
6094
6177
|
}
|
|
6095
|
-
|
|
6096
|
-
|
|
6097
|
-
|
|
6098
|
-
const beginRecognitionImpl = React.useCallback(
|
|
6099
|
-
(Ctor, token) => {
|
|
6100
|
-
const recognition = new Ctor();
|
|
6101
|
-
recognition.lang = lang ?? (typeof navigator === "undefined" ? "en-US" : navigator.language || "en-US");
|
|
6102
|
-
recognition.continuous = true;
|
|
6103
|
-
recognition.interimResults = true;
|
|
6104
|
-
recognition.maxAlternatives = 1;
|
|
6105
|
-
recognition.onstart = () => {
|
|
6178
|
+
micConfirmedRef.current = access.confirmed;
|
|
6179
|
+
if (access.primed) {
|
|
6180
|
+
await sleep(RELEASE_SETTLE_MS);
|
|
6106
6181
|
if (token !== startTokenRef.current) return;
|
|
6107
|
-
setError(null);
|
|
6108
|
-
setListening(true);
|
|
6109
|
-
};
|
|
6110
|
-
recognition.onresult = (event) => {
|
|
6111
|
-
let settled = "";
|
|
6112
|
-
let pending = "";
|
|
6113
|
-
for (let i = event.resultIndex; i < event.results.length; i += 1) {
|
|
6114
|
-
const result = event.results[i];
|
|
6115
|
-
if (!result) continue;
|
|
6116
|
-
const text = result[0]?.transcript ?? "";
|
|
6117
|
-
if (result.isFinal) settled += text;
|
|
6118
|
-
else pending += text;
|
|
6119
|
-
}
|
|
6120
|
-
setInterim(pending);
|
|
6121
|
-
if (settled.trim() !== "") finalRef.current(settled);
|
|
6122
|
-
};
|
|
6123
|
-
recognition.onerror = (event) => {
|
|
6124
|
-
const message = micConfirmedRef.current && (event.error === "not-allowed" || event.error === "service-not-allowed") ? "Dictation isn't available in this browser. You can type instead." : describeError(event.error);
|
|
6125
|
-
setListening(false);
|
|
6126
|
-
setInterim("");
|
|
6127
|
-
if (message !== "") {
|
|
6128
|
-
setError(message);
|
|
6129
|
-
errorRef.current?.(message);
|
|
6130
|
-
}
|
|
6131
|
-
};
|
|
6132
|
-
recognition.onend = () => {
|
|
6133
|
-
setListening(false);
|
|
6134
|
-
setInterim("");
|
|
6135
|
-
};
|
|
6136
|
-
recognitionRef.current = recognition;
|
|
6137
|
-
try {
|
|
6138
|
-
recognition.start();
|
|
6139
|
-
} catch {
|
|
6140
|
-
setListening(false);
|
|
6141
6182
|
}
|
|
6142
|
-
|
|
6143
|
-
|
|
6144
|
-
);
|
|
6145
|
-
beginRecognitionRef.current = beginRecognitionImpl;
|
|
6183
|
+
openSessionRef.current?.(token);
|
|
6184
|
+
});
|
|
6185
|
+
}, []);
|
|
6146
6186
|
const toggle = React.useCallback(() => {
|
|
6147
6187
|
if (listening) stop();
|
|
6148
6188
|
else start();
|
|
6149
6189
|
}, [listening, start, stop]);
|
|
6150
6190
|
React.useEffect(
|
|
6151
6191
|
() => () => {
|
|
6192
|
+
startTokenRef.current += 1;
|
|
6193
|
+
wantsListeningRef.current = false;
|
|
6152
6194
|
const recognition = recognitionRef.current;
|
|
6153
6195
|
if (!recognition) return;
|
|
6154
6196
|
recognition.onresult = null;
|
|
@@ -6207,6 +6249,50 @@ var EXPLORE_CSS = `
|
|
|
6207
6249
|
border-radius: 9999px;
|
|
6208
6250
|
background-clip: content-box;
|
|
6209
6251
|
}
|
|
6252
|
+
|
|
6253
|
+
/* The product strip scrolls inside itself; a visible scrollbar would read as a broken
|
|
6254
|
+
layout rather than an affordance, and reserving its gutter shifts the chips. */
|
|
6255
|
+
.boff-explore-strip {
|
|
6256
|
+
scrollbar-width: none;
|
|
6257
|
+
-ms-overflow-style: none;
|
|
6258
|
+
}
|
|
6259
|
+
.boff-explore-strip::-webkit-scrollbar { display: none; }
|
|
6260
|
+
|
|
6261
|
+
@keyframes boff-explore-fade-in {
|
|
6262
|
+
from { opacity: 0; transform: translateY(2px); }
|
|
6263
|
+
to { opacity: 1; transform: none; }
|
|
6264
|
+
}
|
|
6265
|
+
.boff-explore-fade { animation: boff-explore-fade-in 220ms ease-out; }
|
|
6266
|
+
@media (prefers-reduced-motion: reduce) {
|
|
6267
|
+
.boff-explore-fade { animation: none; }
|
|
6268
|
+
}
|
|
6269
|
+
|
|
6270
|
+
/* Nothing inside an answer may widen the page. Model output carries long URLs, code and
|
|
6271
|
+
tables \u2014 each of those overflows a phone by default, and one overflowing child makes the
|
|
6272
|
+
WHOLE document horizontally scrollable, not just the bubble. */
|
|
6273
|
+
.boff-explore-body,
|
|
6274
|
+
.boff-explore-body p,
|
|
6275
|
+
.boff-explore-body li,
|
|
6276
|
+
.boff-explore-body a,
|
|
6277
|
+
.boff-explore-body h1,
|
|
6278
|
+
.boff-explore-body h2,
|
|
6279
|
+
.boff-explore-body h3 {
|
|
6280
|
+
overflow-wrap: anywhere;
|
|
6281
|
+
word-break: break-word;
|
|
6282
|
+
}
|
|
6283
|
+
.boff-explore-body pre {
|
|
6284
|
+
overflow-x: auto;
|
|
6285
|
+
max-width: 100%;
|
|
6286
|
+
}
|
|
6287
|
+
.boff-explore-body table {
|
|
6288
|
+
display: block;
|
|
6289
|
+
overflow-x: auto;
|
|
6290
|
+
max-width: 100%;
|
|
6291
|
+
}
|
|
6292
|
+
.boff-explore-body img {
|
|
6293
|
+
max-width: 100%;
|
|
6294
|
+
height: auto;
|
|
6295
|
+
}
|
|
6210
6296
|
`;
|
|
6211
6297
|
function ExploreStyles() {
|
|
6212
6298
|
return /* @__PURE__ */ jsxRuntime.jsx("style", { dangerouslySetInnerHTML: { __html: EXPLORE_CSS } });
|
|
@@ -6228,7 +6314,6 @@ var CAPABILITIES = [
|
|
|
6228
6314
|
body: "Get the sources and next steps \u2014 pricing, docs, a demo \u2014 without hunting."
|
|
6229
6315
|
}
|
|
6230
6316
|
];
|
|
6231
|
-
var PRODUCT_CHIP_PREVIEW = 12;
|
|
6232
6317
|
var CTA_VARIANTS = {
|
|
6233
6318
|
CONTACT: "default",
|
|
6234
6319
|
WAITLIST: "default",
|
|
@@ -6429,7 +6514,7 @@ function AssistantBubble({
|
|
|
6429
6514
|
),
|
|
6430
6515
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 flex-1 space-y-3", children: [
|
|
6431
6516
|
body ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-2xl rounded-tl-md border border-border bg-card px-4 py-3 shadow-sm", children: [
|
|
6432
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "boff-prose boff-prose-sm text-card-foreground", children: /* @__PURE__ */ jsxRuntime.jsx(Markdown, { children: body }) }),
|
|
6517
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "boff-prose boff-prose-sm boff-explore-body min-w-0 text-card-foreground", children: /* @__PURE__ */ jsxRuntime.jsx(Markdown, { children: body }) }),
|
|
6433
6518
|
streaming ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "boff-explore-caret", "aria-hidden": "true" }) : null
|
|
6434
6519
|
] }) : null,
|
|
6435
6520
|
streaming ? /* @__PURE__ */ jsxRuntime.jsx(ThinkingIndicator, { activity }) : null,
|
|
@@ -6491,6 +6576,200 @@ function ErrorBanner({
|
|
|
6491
6576
|
}
|
|
6492
6577
|
);
|
|
6493
6578
|
}
|
|
6579
|
+
function PromptCarousel({
|
|
6580
|
+
prompts,
|
|
6581
|
+
onPrompt,
|
|
6582
|
+
disabled
|
|
6583
|
+
}) {
|
|
6584
|
+
const [index, setIndex] = React.useState(0);
|
|
6585
|
+
const [paused, setPaused] = React.useState(false);
|
|
6586
|
+
const count = prompts.length;
|
|
6587
|
+
const current = prompts[index % count] ?? prompts[0] ?? "";
|
|
6588
|
+
const go = React.useCallback(
|
|
6589
|
+
(delta) => {
|
|
6590
|
+
setIndex((i) => (i + delta + count) % count);
|
|
6591
|
+
},
|
|
6592
|
+
[count]
|
|
6593
|
+
);
|
|
6594
|
+
React.useEffect(() => {
|
|
6595
|
+
if (paused || disabled || count < 2) return;
|
|
6596
|
+
if (typeof window !== "undefined" && window.matchMedia?.("(prefers-reduced-motion: reduce)").matches) {
|
|
6597
|
+
return;
|
|
6598
|
+
}
|
|
6599
|
+
const timer = setInterval(() => setIndex((i) => (i + 1) % count), 4500);
|
|
6600
|
+
return () => clearInterval(timer);
|
|
6601
|
+
}, [paused, disabled, count]);
|
|
6602
|
+
if (count === 0) return null;
|
|
6603
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
6604
|
+
"div",
|
|
6605
|
+
{
|
|
6606
|
+
className: "flex min-w-0 items-center gap-1.5",
|
|
6607
|
+
onMouseEnter: () => setPaused(true),
|
|
6608
|
+
onMouseLeave: () => setPaused(false),
|
|
6609
|
+
onFocusCapture: () => setPaused(true),
|
|
6610
|
+
onBlurCapture: () => setPaused(false),
|
|
6611
|
+
children: [
|
|
6612
|
+
count > 1 ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
6613
|
+
"button",
|
|
6614
|
+
{
|
|
6615
|
+
type: "button",
|
|
6616
|
+
"aria-label": "Previous suggestion",
|
|
6617
|
+
onClick: () => go(-1),
|
|
6618
|
+
className: "hidden h-8 w-8 shrink-0 items-center justify-center rounded-full text-muted-foreground transition-colors hover:bg-accent hover:text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring sm:inline-flex",
|
|
6619
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronLeft, { className: "h-4 w-4" })
|
|
6620
|
+
}
|
|
6621
|
+
) : null,
|
|
6622
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
6623
|
+
"button",
|
|
6624
|
+
{
|
|
6625
|
+
"data-boff-explore": "chip",
|
|
6626
|
+
"data-chip-kind": "prompt",
|
|
6627
|
+
type: "button",
|
|
6628
|
+
disabled,
|
|
6629
|
+
onClick: () => onPrompt(current),
|
|
6630
|
+
className: "boff-explore-fade group flex min-w-0 flex-1 items-center gap-2 rounded-full border border-border bg-card px-4 py-2 text-left text-sm text-card-foreground shadow-sm transition-colors hover:border-primary/50 hover:bg-accent disabled:cursor-not-allowed disabled:opacity-50 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring",
|
|
6631
|
+
children: [
|
|
6632
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Sparkles, { className: "h-3.5 w-3.5 shrink-0 text-primary" }),
|
|
6633
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: current }),
|
|
6634
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowUp, { className: "ml-auto h-3.5 w-3.5 shrink-0 rotate-45 text-muted-foreground transition-colors group-hover:text-primary" })
|
|
6635
|
+
]
|
|
6636
|
+
},
|
|
6637
|
+
current
|
|
6638
|
+
),
|
|
6639
|
+
count > 1 ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
6640
|
+
"button",
|
|
6641
|
+
{
|
|
6642
|
+
type: "button",
|
|
6643
|
+
"aria-label": "Next suggestion",
|
|
6644
|
+
onClick: () => go(1),
|
|
6645
|
+
className: "inline-flex h-8 w-8 shrink-0 items-center justify-center rounded-full text-muted-foreground transition-colors hover:bg-accent hover:text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring",
|
|
6646
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { className: "h-4 w-4" })
|
|
6647
|
+
}
|
|
6648
|
+
) : null
|
|
6649
|
+
]
|
|
6650
|
+
}
|
|
6651
|
+
);
|
|
6652
|
+
}
|
|
6653
|
+
function ProductStrip({
|
|
6654
|
+
products,
|
|
6655
|
+
focusProduct,
|
|
6656
|
+
onFocus
|
|
6657
|
+
}) {
|
|
6658
|
+
const [expanded, setExpanded] = React.useState(false);
|
|
6659
|
+
const chipClass = (active) => cn(
|
|
6660
|
+
"shrink-0 rounded-full border px-3 py-1 text-xs font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring",
|
|
6661
|
+
active ? "border-primary bg-primary text-primary-foreground" : "border-border bg-card text-muted-foreground hover:bg-accent hover:text-accent-foreground"
|
|
6662
|
+
);
|
|
6663
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 items-center gap-2", children: [
|
|
6664
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
6665
|
+
"div",
|
|
6666
|
+
{
|
|
6667
|
+
className: cn(
|
|
6668
|
+
"boff-explore-strip flex min-w-0 flex-1 gap-2",
|
|
6669
|
+
expanded ? "flex-wrap" : "flex-nowrap overflow-x-auto"
|
|
6670
|
+
),
|
|
6671
|
+
children: [
|
|
6672
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6673
|
+
"button",
|
|
6674
|
+
{
|
|
6675
|
+
"data-boff-explore": "chip",
|
|
6676
|
+
"data-chip-kind": "product",
|
|
6677
|
+
"data-product": "all",
|
|
6678
|
+
type: "button",
|
|
6679
|
+
"aria-pressed": focusProduct === null,
|
|
6680
|
+
onClick: () => onFocus(null),
|
|
6681
|
+
className: chipClass(focusProduct === null),
|
|
6682
|
+
children: "All products"
|
|
6683
|
+
}
|
|
6684
|
+
),
|
|
6685
|
+
products.map((product) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
6686
|
+
"button",
|
|
6687
|
+
{
|
|
6688
|
+
"data-boff-explore": "chip",
|
|
6689
|
+
"data-chip-kind": "product",
|
|
6690
|
+
"data-product": product.slug,
|
|
6691
|
+
type: "button",
|
|
6692
|
+
"aria-pressed": focusProduct === product.slug,
|
|
6693
|
+
title: product.tagline ?? product.name,
|
|
6694
|
+
onClick: () => onFocus(focusProduct === product.slug ? null : product.slug),
|
|
6695
|
+
className: chipClass(focusProduct === product.slug),
|
|
6696
|
+
children: product.name
|
|
6697
|
+
},
|
|
6698
|
+
product.slug
|
|
6699
|
+
))
|
|
6700
|
+
]
|
|
6701
|
+
}
|
|
6702
|
+
),
|
|
6703
|
+
products.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
6704
|
+
"button",
|
|
6705
|
+
{
|
|
6706
|
+
type: "button",
|
|
6707
|
+
"data-boff-explore": "products-toggle",
|
|
6708
|
+
onClick: () => setExpanded((v) => !v),
|
|
6709
|
+
className: "shrink-0 whitespace-nowrap rounded-full px-2 py-1 text-xs font-medium text-primary underline-offset-4 hover:underline focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring",
|
|
6710
|
+
children: expanded ? "Show less" : `All ${products.length}`
|
|
6711
|
+
}
|
|
6712
|
+
) : null
|
|
6713
|
+
] });
|
|
6714
|
+
}
|
|
6715
|
+
function DisclaimerDialog({
|
|
6716
|
+
open,
|
|
6717
|
+
onClose,
|
|
6718
|
+
captchaOn
|
|
6719
|
+
}) {
|
|
6720
|
+
const closeRef = React.useRef(null);
|
|
6721
|
+
React.useEffect(() => {
|
|
6722
|
+
if (!open) return;
|
|
6723
|
+
const onKey = (event) => {
|
|
6724
|
+
if (event.key === "Escape") onClose();
|
|
6725
|
+
};
|
|
6726
|
+
document.addEventListener("keydown", onKey);
|
|
6727
|
+
closeRef.current?.focus();
|
|
6728
|
+
return () => document.removeEventListener("keydown", onKey);
|
|
6729
|
+
}, [open, onClose]);
|
|
6730
|
+
if (!open) return null;
|
|
6731
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
6732
|
+
"div",
|
|
6733
|
+
{
|
|
6734
|
+
"data-boff-explore": "disclaimer-dialog",
|
|
6735
|
+
role: "dialog",
|
|
6736
|
+
"aria-modal": "true",
|
|
6737
|
+
"aria-label": "How this assistant works",
|
|
6738
|
+
className: "fixed inset-0 z-50 flex items-end justify-center bg-foreground/40 p-4 backdrop-blur-sm sm:items-center",
|
|
6739
|
+
onClick: onClose,
|
|
6740
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
6741
|
+
"div",
|
|
6742
|
+
{
|
|
6743
|
+
className: "w-full max-w-md rounded-2xl border border-border bg-card p-5 shadow-xl",
|
|
6744
|
+
onClick: (event) => event.stopPropagation(),
|
|
6745
|
+
children: [
|
|
6746
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start gap-3", children: [
|
|
6747
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex h-8 w-8 shrink-0 items-center justify-center rounded-lg bg-primary/10 text-primary", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.TriangleAlert, { className: "h-4 w-4" }) }),
|
|
6748
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0", children: [
|
|
6749
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-semibold text-card-foreground", children: "How this assistant works" }),
|
|
6750
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-2 space-y-2 text-xs leading-relaxed text-muted-foreground", children: [
|
|
6751
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { children: "Answers are generated from our public documentation and can be imperfect \u2014 check anything important against the linked sources." }),
|
|
6752
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { children: "Conversations are saved in this browser so you can come back to them, and are also stored on our servers to help us improve these answers. Please don't share personal or confidential information." }),
|
|
6753
|
+
captchaOn ? /* @__PURE__ */ jsxRuntime.jsx("p", { children: "Protected by reCAPTCHA \u2014 the Google Privacy Policy and Terms of Service apply." }) : null
|
|
6754
|
+
] })
|
|
6755
|
+
] })
|
|
6756
|
+
] }),
|
|
6757
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-4 flex justify-end", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
6758
|
+
Button,
|
|
6759
|
+
{
|
|
6760
|
+
ref: closeRef,
|
|
6761
|
+
size: "sm",
|
|
6762
|
+
variant: "secondary",
|
|
6763
|
+
onClick: onClose,
|
|
6764
|
+
children: "Got it"
|
|
6765
|
+
}
|
|
6766
|
+
) })
|
|
6767
|
+
]
|
|
6768
|
+
}
|
|
6769
|
+
)
|
|
6770
|
+
}
|
|
6771
|
+
);
|
|
6772
|
+
}
|
|
6494
6773
|
function WelcomeState({
|
|
6495
6774
|
title,
|
|
6496
6775
|
body,
|
|
@@ -6501,21 +6780,19 @@ function WelcomeState({
|
|
|
6501
6780
|
onFocus,
|
|
6502
6781
|
disabled
|
|
6503
6782
|
}) {
|
|
6504
|
-
|
|
6505
|
-
const visibleProducts = showAllProducts ? products : products.slice(0, PRODUCT_CHIP_PREVIEW);
|
|
6506
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mx-auto w-full max-w-3xl px-4 py-10 sm:py-14", children: [
|
|
6783
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mx-auto w-full max-w-3xl px-4 py-8 sm:py-12", children: [
|
|
6507
6784
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-center", children: [
|
|
6508
6785
|
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "inline-flex items-center gap-1.5 rounded-full border border-border bg-muted px-3 py-1 text-xs font-medium text-muted-foreground", children: [
|
|
6509
6786
|
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Sparkles, { className: "h-3.5 w-3.5" }),
|
|
6510
6787
|
"AI answers, grounded in our documentation"
|
|
6511
6788
|
] }),
|
|
6512
|
-
/* @__PURE__ */ jsxRuntime.jsx("h1", { className: "mt-
|
|
6513
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "mx-auto mt-
|
|
6789
|
+
/* @__PURE__ */ jsxRuntime.jsx("h1", { className: "mt-4 text-balance break-words text-2xl font-bold tracking-tight sm:text-4xl", children: title }),
|
|
6790
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "mx-auto mt-2.5 max-w-2xl text-pretty text-sm leading-relaxed text-muted-foreground sm:text-lg", children: body })
|
|
6514
6791
|
] }),
|
|
6515
|
-
/* @__PURE__ */ jsxRuntime.jsx("ul", { className: "mt-
|
|
6792
|
+
/* @__PURE__ */ jsxRuntime.jsx("ul", { className: "mt-7 grid gap-2.5 sm:grid-cols-3", children: CAPABILITIES.map(({ icon: Icon, title: capTitle, body: capBody }) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
6516
6793
|
"li",
|
|
6517
6794
|
{
|
|
6518
|
-
className: "rounded-xl border border-border bg-card p-
|
|
6795
|
+
className: "rounded-xl border border-border/70 bg-card/60 p-3.5 text-left transition-colors hover:border-border",
|
|
6519
6796
|
children: [
|
|
6520
6797
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "mb-2.5 flex h-8 w-8 items-center justify-center rounded-lg bg-primary/10 text-primary", children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { className: "h-4 w-4" }) }),
|
|
6521
6798
|
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-semibold text-card-foreground", children: capTitle }),
|
|
@@ -6524,72 +6801,27 @@ function WelcomeState({
|
|
|
6524
6801
|
},
|
|
6525
6802
|
capTitle
|
|
6526
6803
|
)) }),
|
|
6527
|
-
prompts.length > 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-
|
|
6528
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "mb-2
|
|
6529
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6530
|
-
|
|
6804
|
+
prompts.length > 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-8", children: [
|
|
6805
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "mb-2 text-xs font-semibold uppercase tracking-wide text-muted-foreground", children: "Try asking" }),
|
|
6806
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6807
|
+
PromptCarousel,
|
|
6531
6808
|
{
|
|
6532
|
-
|
|
6533
|
-
|
|
6534
|
-
|
|
6535
|
-
|
|
6536
|
-
|
|
6537
|
-
className: "group inline-flex max-w-full items-center gap-1.5 rounded-full border border-border bg-card px-3.5 py-1.5 text-left text-sm text-card-foreground transition-colors hover:border-primary/40 hover:bg-accent disabled:cursor-not-allowed disabled:opacity-50 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring",
|
|
6538
|
-
children: [
|
|
6539
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: prompt }),
|
|
6540
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowUp, { className: "h-3 w-3 shrink-0 rotate-45 text-muted-foreground transition-colors group-hover:text-primary" })
|
|
6541
|
-
]
|
|
6542
|
-
},
|
|
6543
|
-
prompt
|
|
6544
|
-
)) })
|
|
6809
|
+
prompts,
|
|
6810
|
+
onPrompt,
|
|
6811
|
+
disabled
|
|
6812
|
+
}
|
|
6813
|
+
)
|
|
6545
6814
|
] }) : null,
|
|
6546
|
-
products.length > 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-
|
|
6547
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "mb-2
|
|
6548
|
-
/* @__PURE__ */ jsxRuntime.
|
|
6549
|
-
|
|
6550
|
-
|
|
6551
|
-
|
|
6552
|
-
|
|
6553
|
-
|
|
6554
|
-
|
|
6555
|
-
|
|
6556
|
-
"aria-pressed": focusProduct === null,
|
|
6557
|
-
onClick: () => onFocus(null),
|
|
6558
|
-
className: cn(
|
|
6559
|
-
"rounded-full border px-3 py-1 text-xs font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring",
|
|
6560
|
-
focusProduct === null ? "border-primary bg-primary text-primary-foreground" : "border-border bg-card text-muted-foreground hover:bg-accent hover:text-accent-foreground"
|
|
6561
|
-
),
|
|
6562
|
-
children: "All products"
|
|
6563
|
-
}
|
|
6564
|
-
),
|
|
6565
|
-
visibleProducts.map((product) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
6566
|
-
"button",
|
|
6567
|
-
{
|
|
6568
|
-
"data-boff-explore": "chip",
|
|
6569
|
-
"data-chip-kind": "product",
|
|
6570
|
-
"data-product": product.slug,
|
|
6571
|
-
type: "button",
|
|
6572
|
-
"aria-pressed": focusProduct === product.slug,
|
|
6573
|
-
title: product.tagline ?? product.name,
|
|
6574
|
-
onClick: () => onFocus(focusProduct === product.slug ? null : product.slug),
|
|
6575
|
-
className: cn(
|
|
6576
|
-
"rounded-full border px-3 py-1 text-xs font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring",
|
|
6577
|
-
focusProduct === product.slug ? "border-primary bg-primary text-primary-foreground" : "border-border bg-card text-muted-foreground hover:bg-accent hover:text-accent-foreground"
|
|
6578
|
-
),
|
|
6579
|
-
children: product.name
|
|
6580
|
-
},
|
|
6581
|
-
product.slug
|
|
6582
|
-
)),
|
|
6583
|
-
products.length > PRODUCT_CHIP_PREVIEW ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
6584
|
-
"button",
|
|
6585
|
-
{
|
|
6586
|
-
type: "button",
|
|
6587
|
-
onClick: () => setShowAllProducts((v) => !v),
|
|
6588
|
-
className: "rounded-full px-3 py-1 text-xs font-medium text-primary underline-offset-4 hover:underline focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring",
|
|
6589
|
-
children: showAllProducts ? "Show fewer" : `Show all ${products.length}`
|
|
6590
|
-
}
|
|
6591
|
-
) : null
|
|
6592
|
-
] })
|
|
6815
|
+
products.length > 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-6", children: [
|
|
6816
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "mb-2 text-xs font-semibold uppercase tracking-wide text-muted-foreground", children: "Focus on a product" }),
|
|
6817
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6818
|
+
ProductStrip,
|
|
6819
|
+
{
|
|
6820
|
+
products,
|
|
6821
|
+
focusProduct,
|
|
6822
|
+
onFocus
|
|
6823
|
+
}
|
|
6824
|
+
)
|
|
6593
6825
|
] }) : null
|
|
6594
6826
|
] });
|
|
6595
6827
|
}
|
|
@@ -6645,6 +6877,7 @@ function ExplorePage({
|
|
|
6645
6877
|
}
|
|
6646
6878
|
});
|
|
6647
6879
|
speechStopRef.current = speech.stop;
|
|
6880
|
+
const [disclaimerOpen, setDisclaimerOpen] = React.useState(false);
|
|
6648
6881
|
const scrollRef = React.useRef(null);
|
|
6649
6882
|
const latestAssistantRef = React.useRef(null);
|
|
6650
6883
|
const alignedForRef = React.useRef(null);
|
|
@@ -6737,7 +6970,7 @@ function ExplorePage({
|
|
|
6737
6970
|
"data-boff-explore": "page",
|
|
6738
6971
|
"data-phase": phase,
|
|
6739
6972
|
className: cn(
|
|
6740
|
-
"flex w-full flex-col bg-background text-foreground",
|
|
6973
|
+
"flex w-full min-w-0 flex-col overflow-x-hidden bg-background text-foreground",
|
|
6741
6974
|
heightMode === "auto" && "min-h-[70vh]",
|
|
6742
6975
|
className
|
|
6743
6976
|
),
|
|
@@ -6879,7 +7112,7 @@ function ExplorePage({
|
|
|
6879
7112
|
role: "log",
|
|
6880
7113
|
"aria-live": "polite",
|
|
6881
7114
|
"aria-label": "Explore conversation",
|
|
6882
|
-
className: "boff-explore-scroll min-h-0 flex-1 overflow-y-auto",
|
|
7115
|
+
className: "boff-explore-scroll min-h-0 min-w-0 flex-1 overflow-y-auto overflow-x-hidden",
|
|
6883
7116
|
children: showWelcome ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
6884
7117
|
WelcomeState,
|
|
6885
7118
|
{
|
|
@@ -6892,7 +7125,7 @@ function ExplorePage({
|
|
|
6892
7125
|
onFocus: setFocusProduct,
|
|
6893
7126
|
disabled: !canSend || busy
|
|
6894
7127
|
}
|
|
6895
|
-
) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mx-auto w-full max-w-3xl space-y-6 px-4 py-6", children: messages.map(
|
|
7128
|
+
) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mx-auto w-full min-w-0 max-w-3xl space-y-6 px-4 py-6", children: messages.map(
|
|
6896
7129
|
(message) => message.role === "USER" ? /* @__PURE__ */ jsxRuntime.jsx(UserBubble, { message }, message.id) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
6897
7130
|
AssistantBubble,
|
|
6898
7131
|
{
|
|
@@ -6906,7 +7139,15 @@ function ExplorePage({
|
|
|
6906
7139
|
) })
|
|
6907
7140
|
}
|
|
6908
7141
|
),
|
|
6909
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7142
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7143
|
+
DisclaimerDialog,
|
|
7144
|
+
{
|
|
7145
|
+
open: disclaimerOpen,
|
|
7146
|
+
onClose: () => setDisclaimerOpen(false),
|
|
7147
|
+
captchaOn
|
|
7148
|
+
}
|
|
7149
|
+
),
|
|
7150
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "border-t border-border bg-background/85 px-4 pb-[max(1rem,env(safe-area-inset-bottom))] pt-3 backdrop-blur-md", children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
6910
7151
|
"form",
|
|
6911
7152
|
{
|
|
6912
7153
|
"data-boff-explore": "composer",
|
|
@@ -6921,7 +7162,7 @@ function ExplorePage({
|
|
|
6921
7162
|
"div",
|
|
6922
7163
|
{
|
|
6923
7164
|
className: cn(
|
|
6924
|
-
"flex items-end gap-2 rounded-2xl border bg-card p-2 shadow-sm transition-
|
|
7165
|
+
"flex min-w-0 items-end gap-2 rounded-2xl border bg-card p-2 shadow-sm transition-all",
|
|
6925
7166
|
overLimit ? "border-destructive/60" : "border-border focus-within:border-primary/40 focus-within:ring-1 focus-within:ring-ring"
|
|
6926
7167
|
),
|
|
6927
7168
|
children: [
|
|
@@ -6942,7 +7183,7 @@ function ExplorePage({
|
|
|
6942
7183
|
},
|
|
6943
7184
|
"aria-label": "Ask a question",
|
|
6944
7185
|
placeholder: composerDisabled ? phase === "limited" ? "Message limit reached \u2014 please try again later" : "Explore is unavailable right now" : focusedProductName ? `Ask about ${focusedProductName}\u2026` : "Ask anything about our products\u2026",
|
|
6945
|
-
className: "max-h-[200px] min-h-[44px] flex-1 resize-none border-0 bg-transparent px-2 py-2.5 text-sm shadow-none focus-visible:ring-0 md:text-sm"
|
|
7186
|
+
className: "max-h-[200px] min-h-[44px] w-full min-w-0 flex-1 resize-none border-0 bg-transparent px-2 py-2.5 text-sm shadow-none focus-visible:ring-0 md:text-sm"
|
|
6946
7187
|
}
|
|
6947
7188
|
),
|
|
6948
7189
|
speech.supported ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -7033,48 +7274,19 @@ function ExplorePage({
|
|
|
7033
7274
|
}
|
|
7034
7275
|
)
|
|
7035
7276
|
] }),
|
|
7036
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
7037
|
-
"
|
|
7038
|
-
|
|
7039
|
-
"
|
|
7040
|
-
|
|
7041
|
-
|
|
7042
|
-
"
|
|
7043
|
-
|
|
7044
|
-
"
|
|
7045
|
-
|
|
7046
|
-
|
|
7047
|
-
|
|
7048
|
-
|
|
7049
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7050
|
-
"a",
|
|
7051
|
-
{
|
|
7052
|
-
href: "https://policies.google.com/privacy",
|
|
7053
|
-
target: "_blank",
|
|
7054
|
-
rel: "noopener noreferrer",
|
|
7055
|
-
className: "underline underline-offset-2 hover:text-foreground",
|
|
7056
|
-
children: "Privacy Policy"
|
|
7057
|
-
}
|
|
7058
|
-
),
|
|
7059
|
-
" ",
|
|
7060
|
-
"and",
|
|
7061
|
-
" ",
|
|
7062
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7063
|
-
"a",
|
|
7064
|
-
{
|
|
7065
|
-
href: "https://policies.google.com/terms",
|
|
7066
|
-
target: "_blank",
|
|
7067
|
-
rel: "noopener noreferrer",
|
|
7068
|
-
className: "underline underline-offset-2 hover:text-foreground",
|
|
7069
|
-
children: "Terms of Service"
|
|
7070
|
-
}
|
|
7071
|
-
),
|
|
7072
|
-
" ",
|
|
7073
|
-
"apply."
|
|
7074
|
-
] }) : null
|
|
7075
|
-
]
|
|
7076
|
-
}
|
|
7077
|
-
)
|
|
7277
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-2 flex flex-wrap items-center gap-x-3 gap-y-1 text-xs text-muted-foreground", children: [
|
|
7278
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "min-w-0 truncate", children: "Grounded in our docs \u2014 check anything important." }),
|
|
7279
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7280
|
+
"button",
|
|
7281
|
+
{
|
|
7282
|
+
type: "button",
|
|
7283
|
+
"data-boff-explore": "disclaimer",
|
|
7284
|
+
onClick: () => setDisclaimerOpen(true),
|
|
7285
|
+
className: "shrink-0 underline underline-offset-2 transition-colors hover:text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring",
|
|
7286
|
+
children: "Disclaimer"
|
|
7287
|
+
}
|
|
7288
|
+
)
|
|
7289
|
+
] })
|
|
7078
7290
|
]
|
|
7079
7291
|
}
|
|
7080
7292
|
) })
|