@burdenoff/website-sdk 2026.830.1 → 2026.921.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/README.md +112 -1
- package/dist/components/contact.js +4 -1
- package/dist/components/contact.js.map +1 -1
- package/dist/components/contact.mjs +4 -1
- package/dist/components/contact.mjs.map +1 -1
- package/dist/components/explore.d.mts +14 -1
- package/dist/components/explore.d.ts +14 -1
- package/dist/components/explore.js +154 -15
- package/dist/components/explore.js.map +1 -1
- package/dist/components/explore.mjs +154 -17
- package/dist/components/explore.mjs.map +1 -1
- package/dist/components/newsletter.js +4 -1
- package/dist/components/newsletter.js.map +1 -1
- package/dist/components/newsletter.mjs +4 -1
- package/dist/components/newsletter.mjs.map +1 -1
- package/dist/components/partners.js +23 -13
- package/dist/components/partners.js.map +1 -1
- package/dist/components/partners.mjs +23 -13
- package/dist/components/partners.mjs.map +1 -1
- package/dist/components/pricing.js +4 -1
- package/dist/components/pricing.js.map +1 -1
- package/dist/components/pricing.mjs +4 -1
- package/dist/components/pricing.mjs.map +1 -1
- package/dist/components/unsubscribe.js +4 -1
- package/dist/components/unsubscribe.js.map +1 -1
- package/dist/components/unsubscribe.mjs +4 -1
- package/dist/components/unsubscribe.mjs.map +1 -1
- package/dist/components/waitlist.js +4 -1
- package/dist/components/waitlist.js.map +1 -1
- package/dist/components/waitlist.mjs +4 -1
- package/dist/components/waitlist.mjs.map +1 -1
- package/dist/content/index.js +23 -13
- package/dist/content/index.js.map +1 -1
- package/dist/content/index.mjs +23 -13
- package/dist/content/index.mjs.map +1 -1
- package/dist/{use-explore-chat-B8xKGid5.d.mts → explore-types-CLw19R76.d.mts} +1 -143
- package/dist/{use-explore-chat-B8xKGid5.d.ts → explore-types-CLw19R76.d.ts} +1 -143
- package/dist/hooks/index.d.mts +2 -1
- package/dist/hooks/index.d.ts +2 -1
- package/dist/hooks/index.js +4 -1
- package/dist/hooks/index.js.map +1 -1
- package/dist/hooks/index.mjs +4 -1
- package/dist/hooks/index.mjs.map +1 -1
- package/dist/index.d.mts +141 -2
- package/dist/index.d.ts +141 -2
- package/dist/index.js +1489 -179
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1485 -182
- package/dist/index.mjs.map +1 -1
- package/dist/seo/index.js +4 -1
- package/dist/seo/index.js.map +1 -1
- package/dist/seo/index.mjs +4 -1
- package/dist/seo/index.mjs.map +1 -1
- package/dist/store/index.js +23 -13
- package/dist/store/index.js.map +1 -1
- package/dist/store/index.mjs +23 -13
- package/dist/store/index.mjs.map +1 -1
- package/dist/use-explore-chat-CvW-kyIm.d.mts +145 -0
- package/dist/use-explore-chat-DdGBimiz.d.ts +145 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -507,6 +507,9 @@ function resolveImageUrl(image, base) {
|
|
|
507
507
|
return image;
|
|
508
508
|
}
|
|
509
509
|
}
|
|
510
|
+
function serializeJsonLd(data) {
|
|
511
|
+
return JSON.stringify(data).replace(/</g, "\\u003c").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
|
|
512
|
+
}
|
|
510
513
|
function PageHead({
|
|
511
514
|
title,
|
|
512
515
|
description,
|
|
@@ -548,7 +551,7 @@ function PageHead({
|
|
|
548
551
|
fullImageUrl && /* @__PURE__ */ jsxRuntime.jsx("meta", { name: "twitter:image", content: fullImageUrl }),
|
|
549
552
|
twitterHandle && /* @__PURE__ */ jsxRuntime.jsx("meta", { name: "twitter:creator", content: twitterHandle }),
|
|
550
553
|
/* @__PURE__ */ jsxRuntime.jsx("meta", { name: "theme-color", content: themeColor }),
|
|
551
|
-
structuredDataItems.map((data, index) => /* @__PURE__ */ jsxRuntime.jsx("script", { type: "application/ld+json", children:
|
|
554
|
+
structuredDataItems.map((data, index) => /* @__PURE__ */ jsxRuntime.jsx("script", { type: "application/ld+json", children: serializeJsonLd(data) }, `ld-${index}`)),
|
|
552
555
|
additionalMeta?.map((meta, index) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
553
556
|
"meta",
|
|
554
557
|
{
|
|
@@ -1108,19 +1111,26 @@ function ContactPage({
|
|
|
1108
1111
|
] }) })
|
|
1109
1112
|
] });
|
|
1110
1113
|
}
|
|
1114
|
+
function MarkdownLink({
|
|
1115
|
+
href,
|
|
1116
|
+
children,
|
|
1117
|
+
// react-markdown passes the hast node to every override; it is not a DOM attribute.
|
|
1118
|
+
node: _node,
|
|
1119
|
+
...props
|
|
1120
|
+
}) {
|
|
1121
|
+
const isExternal = typeof href === "string" && (href.startsWith("http://") || href.startsWith("https://"));
|
|
1122
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1123
|
+
"a",
|
|
1124
|
+
{
|
|
1125
|
+
href,
|
|
1126
|
+
...props,
|
|
1127
|
+
...isExternal ? { target: "_blank", rel: "noopener noreferrer" } : { rel: "noopener noreferrer" },
|
|
1128
|
+
children
|
|
1129
|
+
}
|
|
1130
|
+
);
|
|
1131
|
+
}
|
|
1111
1132
|
var defaultComponents = {
|
|
1112
|
-
a:
|
|
1113
|
-
const isExternal = typeof href === "string" && (href.startsWith("http://") || href.startsWith("https://"));
|
|
1114
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1115
|
-
"a",
|
|
1116
|
-
{
|
|
1117
|
-
href,
|
|
1118
|
-
...props,
|
|
1119
|
-
...isExternal ? { target: "_blank", rel: "noopener noreferrer" } : { rel: "noopener noreferrer" },
|
|
1120
|
-
children
|
|
1121
|
-
}
|
|
1122
|
-
);
|
|
1123
|
-
}
|
|
1133
|
+
a: MarkdownLink
|
|
1124
1134
|
};
|
|
1125
1135
|
function Markdown({
|
|
1126
1136
|
children,
|
|
@@ -4766,171 +4776,1343 @@ function ElectronDownloadLink({
|
|
|
4766
4776
|
);
|
|
4767
4777
|
}
|
|
4768
4778
|
|
|
4769
|
-
// src/components/
|
|
4770
|
-
var
|
|
4771
|
-
var
|
|
4772
|
-
|
|
4773
|
-
|
|
4779
|
+
// src/components/concepts-types.ts
|
|
4780
|
+
var CONCEPT_ILLUSTRATION_NOTICE = "These images are illustrations of the concept, not screenshots of the actual product.";
|
|
4781
|
+
var CONCEPTS_PATH = "/concepts";
|
|
4782
|
+
var CONCEPT_PATH_PREFIX = "/concept";
|
|
4783
|
+
function conceptPath(slug) {
|
|
4784
|
+
return `${CONCEPT_PATH_PREFIX}/${encodeURIComponent(slug)}`;
|
|
4785
|
+
}
|
|
4786
|
+
function getConceptBySlug(concepts, slug) {
|
|
4787
|
+
if (!slug) return void 0;
|
|
4788
|
+
const wanted = slug.trim().toLowerCase();
|
|
4789
|
+
if (!wanted) return void 0;
|
|
4790
|
+
return concepts.find((concept) => concept.slug === wanted);
|
|
4791
|
+
}
|
|
4792
|
+
var NAV_BUTTON = "inline-flex h-11 w-11 items-center justify-center rounded-full border border-border bg-card text-foreground shadow-md transition-colors hover:bg-muted focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring";
|
|
4793
|
+
function ConceptLightbox({
|
|
4794
|
+
images,
|
|
4795
|
+
index,
|
|
4796
|
+
conceptTitle,
|
|
4797
|
+
onIndexChange,
|
|
4798
|
+
onClose
|
|
4799
|
+
}) {
|
|
4800
|
+
const dialogRef = React.useRef(null);
|
|
4801
|
+
const closeRef = React.useRef(null);
|
|
4802
|
+
const nativeModalRef = React.useRef(false);
|
|
4803
|
+
const titleId = React.useId();
|
|
4804
|
+
const count = images.length;
|
|
4805
|
+
const position = count > 0 ? (index % count + count) % count : 0;
|
|
4806
|
+
const image = images[position];
|
|
4807
|
+
React.useEffect(() => {
|
|
4808
|
+
const dialog = dialogRef.current;
|
|
4809
|
+
if (!dialog) return;
|
|
4810
|
+
if (typeof dialog.showModal === "function") {
|
|
4811
|
+
if (!dialog.open) dialog.showModal();
|
|
4812
|
+
nativeModalRef.current = true;
|
|
4813
|
+
} else {
|
|
4814
|
+
dialog.setAttribute("open", "");
|
|
4815
|
+
nativeModalRef.current = false;
|
|
4816
|
+
}
|
|
4817
|
+
closeRef.current?.focus();
|
|
4818
|
+
return () => {
|
|
4819
|
+
if (dialog.open && typeof dialog.close === "function") dialog.close();
|
|
4820
|
+
};
|
|
4821
|
+
}, []);
|
|
4822
|
+
const go = React.useCallback(
|
|
4823
|
+
(delta) => {
|
|
4824
|
+
if (count < 2) return;
|
|
4825
|
+
onIndexChange((position + delta + count) % count);
|
|
4826
|
+
},
|
|
4827
|
+
[count, onIndexChange, position]
|
|
4828
|
+
);
|
|
4829
|
+
const handleClose = React.useCallback(
|
|
4830
|
+
(event) => {
|
|
4831
|
+
if (event.currentTarget.open) return;
|
|
4832
|
+
onClose();
|
|
4833
|
+
},
|
|
4834
|
+
[onClose]
|
|
4835
|
+
);
|
|
4836
|
+
const handleKeyDown = React.useCallback(
|
|
4837
|
+
(event) => {
|
|
4838
|
+
if (event.key === "ArrowRight") {
|
|
4839
|
+
event.preventDefault();
|
|
4840
|
+
go(1);
|
|
4841
|
+
} else if (event.key === "ArrowLeft") {
|
|
4842
|
+
event.preventDefault();
|
|
4843
|
+
go(-1);
|
|
4844
|
+
} else if (event.key === "Escape" && !nativeModalRef.current) {
|
|
4845
|
+
event.preventDefault();
|
|
4846
|
+
onClose();
|
|
4847
|
+
}
|
|
4848
|
+
},
|
|
4849
|
+
[go, onClose]
|
|
4850
|
+
);
|
|
4851
|
+
const handleStageClick = React.useCallback(
|
|
4852
|
+
(event) => {
|
|
4853
|
+
if (event.target === event.currentTarget) onClose();
|
|
4854
|
+
},
|
|
4855
|
+
[onClose]
|
|
4856
|
+
);
|
|
4857
|
+
if (!image) return null;
|
|
4858
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4859
|
+
"dialog",
|
|
4860
|
+
{
|
|
4861
|
+
ref: dialogRef,
|
|
4862
|
+
"data-concepts": "lightbox",
|
|
4863
|
+
"aria-labelledby": titleId,
|
|
4864
|
+
onClose: handleClose,
|
|
4865
|
+
onKeyDown: handleKeyDown,
|
|
4866
|
+
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",
|
|
4867
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-h-full flex-col", children: [
|
|
4868
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start justify-between gap-4 border-b border-border px-4 py-3 sm:px-6", children: [
|
|
4869
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0", children: [
|
|
4870
|
+
/* @__PURE__ */ jsxRuntime.jsxs("p", { className: "truncate text-xs font-medium uppercase tracking-wide text-muted-foreground", children: [
|
|
4871
|
+
conceptTitle,
|
|
4872
|
+
count > 1 ? ` \xB7 ${position + 1} / ${count}` : null
|
|
4873
|
+
] }),
|
|
4874
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4875
|
+
"h2",
|
|
4876
|
+
{
|
|
4877
|
+
id: titleId,
|
|
4878
|
+
className: "truncate text-base font-semibold text-foreground sm:text-lg",
|
|
4879
|
+
children: image.title
|
|
4880
|
+
}
|
|
4881
|
+
)
|
|
4882
|
+
] }),
|
|
4883
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4884
|
+
"button",
|
|
4885
|
+
{
|
|
4886
|
+
ref: closeRef,
|
|
4887
|
+
type: "button",
|
|
4888
|
+
onClick: onClose,
|
|
4889
|
+
"aria-label": "Close",
|
|
4890
|
+
"data-concepts": "lightbox-close",
|
|
4891
|
+
className: "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",
|
|
4892
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { "aria-hidden": "true", className: "h-5 w-5" })
|
|
4893
|
+
}
|
|
4894
|
+
)
|
|
4895
|
+
] }),
|
|
4896
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
4897
|
+
"div",
|
|
4898
|
+
{
|
|
4899
|
+
className: "relative flex flex-1 items-center justify-center px-4 py-4 sm:px-20",
|
|
4900
|
+
onClick: handleStageClick,
|
|
4901
|
+
children: [
|
|
4902
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4903
|
+
"img",
|
|
4904
|
+
{
|
|
4905
|
+
src: image.src,
|
|
4906
|
+
alt: image.alt,
|
|
4907
|
+
width: image.width,
|
|
4908
|
+
height: image.height,
|
|
4909
|
+
decoding: "async",
|
|
4910
|
+
className: "h-auto max-h-[calc(100vh-14rem)] w-auto max-w-full rounded-lg border border-border bg-muted object-contain shadow-lg"
|
|
4911
|
+
},
|
|
4912
|
+
image.key
|
|
4913
|
+
),
|
|
4914
|
+
count > 1 ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
4915
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4916
|
+
"button",
|
|
4917
|
+
{
|
|
4918
|
+
type: "button",
|
|
4919
|
+
onClick: () => go(-1),
|
|
4920
|
+
"aria-label": "Previous illustration",
|
|
4921
|
+
"data-concepts": "lightbox-prev",
|
|
4922
|
+
className: `absolute left-2 top-1/2 -translate-y-1/2 sm:left-4 ${NAV_BUTTON}`,
|
|
4923
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronLeft, { "aria-hidden": "true", className: "h-5 w-5" })
|
|
4924
|
+
}
|
|
4925
|
+
),
|
|
4926
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4927
|
+
"button",
|
|
4928
|
+
{
|
|
4929
|
+
type: "button",
|
|
4930
|
+
onClick: () => go(1),
|
|
4931
|
+
"aria-label": "Next illustration",
|
|
4932
|
+
"data-concepts": "lightbox-next",
|
|
4933
|
+
className: `absolute right-2 top-1/2 -translate-y-1/2 sm:right-4 ${NAV_BUTTON}`,
|
|
4934
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { "aria-hidden": "true", className: "h-5 w-5" })
|
|
4935
|
+
}
|
|
4936
|
+
)
|
|
4937
|
+
] }) : null
|
|
4938
|
+
]
|
|
4939
|
+
}
|
|
4940
|
+
),
|
|
4941
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "border-t border-border px-4 py-3 sm:px-6", children: [
|
|
4942
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm leading-relaxed text-foreground", children: image.caption }),
|
|
4943
|
+
/* @__PURE__ */ jsxRuntime.jsxs("p", { className: "mt-1.5 flex items-start gap-1.5 text-xs leading-relaxed text-muted-foreground", children: [
|
|
4944
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Info, { "aria-hidden": "true", className: "mt-0.5 h-3.5 w-3.5 shrink-0" }),
|
|
4945
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: CONCEPT_ILLUSTRATION_NOTICE })
|
|
4946
|
+
] })
|
|
4947
|
+
] })
|
|
4948
|
+
] })
|
|
4949
|
+
}
|
|
4950
|
+
);
|
|
4774
4951
|
}
|
|
4775
|
-
var
|
|
4776
|
-
|
|
4777
|
-
|
|
4778
|
-
|
|
4779
|
-
|
|
4780
|
-
|
|
4781
|
-
|
|
4782
|
-
|
|
4783
|
-
|
|
4784
|
-
|
|
4785
|
-
|
|
4786
|
-
|
|
4787
|
-
|
|
4788
|
-
|
|
4789
|
-
|
|
4790
|
-
|
|
4791
|
-
|
|
4792
|
-
|
|
4793
|
-
|
|
4794
|
-
|
|
4795
|
-
|
|
4796
|
-
|
|
4797
|
-
|
|
4798
|
-
|
|
4799
|
-
|
|
4800
|
-
|
|
4801
|
-
|
|
4802
|
-
|
|
4803
|
-
|
|
4804
|
-
|
|
4805
|
-
|
|
4806
|
-
|
|
4807
|
-
|
|
4808
|
-
|
|
4809
|
-
|
|
4810
|
-
|
|
4811
|
-
|
|
4812
|
-
|
|
4813
|
-
|
|
4814
|
-
|
|
4815
|
-
"
|
|
4816
|
-
|
|
4817
|
-
|
|
4818
|
-
|
|
4819
|
-
|
|
4820
|
-
|
|
4821
|
-
|
|
4822
|
-
]
|
|
4823
|
-
}
|
|
4824
|
-
|
|
4825
|
-
|
|
4826
|
-
|
|
4827
|
-
|
|
4828
|
-
|
|
4829
|
-
|
|
4830
|
-
|
|
4831
|
-
|
|
4832
|
-
|
|
4833
|
-
|
|
4834
|
-
|
|
4835
|
-
|
|
4836
|
-
|
|
4837
|
-
|
|
4838
|
-
|
|
4839
|
-
|
|
4840
|
-
|
|
4841
|
-
|
|
4842
|
-
|
|
4843
|
-
|
|
4844
|
-
|
|
4845
|
-
|
|
4846
|
-
|
|
4847
|
-
|
|
4848
|
-
|
|
4849
|
-
|
|
4850
|
-
|
|
4851
|
-
|
|
4852
|
-
|
|
4853
|
-
|
|
4854
|
-
|
|
4855
|
-
|
|
4856
|
-
|
|
4857
|
-
|
|
4858
|
-
|
|
4859
|
-
|
|
4860
|
-
|
|
4861
|
-
|
|
4862
|
-
|
|
4863
|
-
|
|
4864
|
-
|
|
4865
|
-
|
|
4866
|
-
|
|
4867
|
-
|
|
4868
|
-
|
|
4869
|
-
|
|
4870
|
-
|
|
4871
|
-
|
|
4872
|
-
|
|
4873
|
-
|
|
4874
|
-
|
|
4875
|
-
|
|
4876
|
-
|
|
4877
|
-
|
|
4878
|
-
|
|
4879
|
-
|
|
4880
|
-
|
|
4881
|
-
|
|
4882
|
-
|
|
4883
|
-
|
|
4884
|
-
|
|
4885
|
-
|
|
4886
|
-
|
|
4887
|
-
|
|
4888
|
-
|
|
4889
|
-
|
|
4890
|
-
|
|
4891
|
-
|
|
4892
|
-
|
|
4893
|
-
|
|
4894
|
-
|
|
4895
|
-
|
|
4896
|
-
|
|
4897
|
-
|
|
4898
|
-
|
|
4899
|
-
|
|
4900
|
-
|
|
4901
|
-
|
|
4902
|
-
|
|
4903
|
-
|
|
4904
|
-
|
|
4905
|
-
|
|
4906
|
-
|
|
4907
|
-
"
|
|
4908
|
-
|
|
4909
|
-
|
|
4910
|
-
|
|
4911
|
-
|
|
4912
|
-
|
|
4913
|
-
|
|
4914
|
-
|
|
4915
|
-
|
|
4916
|
-
|
|
4917
|
-
}
|
|
4918
|
-
|
|
4919
|
-
|
|
4920
|
-
|
|
4921
|
-
|
|
4922
|
-
|
|
4923
|
-
|
|
4924
|
-
|
|
4925
|
-
|
|
4926
|
-
|
|
4927
|
-
|
|
4928
|
-
|
|
4929
|
-
|
|
4930
|
-
|
|
4931
|
-
|
|
4932
|
-
|
|
4933
|
-
|
|
4952
|
+
var META_DESCRIPTION_LIMIT = 160;
|
|
4953
|
+
var RELATED_LIMIT = 4;
|
|
4954
|
+
var HERO_FETCH_PRIORITY = Number.parseInt(React.version, 10) >= 19 ? { fetchPriority: "high" } : { fetchpriority: "high" };
|
|
4955
|
+
function normaliseSiteUrl(siteUrl) {
|
|
4956
|
+
return siteUrl.trim().replace(/\/+$/, "");
|
|
4957
|
+
}
|
|
4958
|
+
function absoluteUrl(base, path) {
|
|
4959
|
+
if (/^https?:\/\//i.test(path)) return path;
|
|
4960
|
+
return `${base}${path.startsWith("/") ? path : `/${path}`}`;
|
|
4961
|
+
}
|
|
4962
|
+
function sortByOrder(concepts) {
|
|
4963
|
+
return [...concepts].sort(
|
|
4964
|
+
(a, b) => a.order - b.order || a.slug.localeCompare(b.slug)
|
|
4965
|
+
);
|
|
4966
|
+
}
|
|
4967
|
+
function plural(count, singular, pluralForm) {
|
|
4968
|
+
return `${count} ${count === 1 ? singular : pluralForm}`;
|
|
4969
|
+
}
|
|
4970
|
+
function illustrationCount(count) {
|
|
4971
|
+
return plural(count, "illustration", "illustrations");
|
|
4972
|
+
}
|
|
4973
|
+
function listSentence(items) {
|
|
4974
|
+
if (items.length <= 1) return items.join("");
|
|
4975
|
+
return `${items.slice(0, -1).join(", ")} and ${items[items.length - 1]}`;
|
|
4976
|
+
}
|
|
4977
|
+
function clampText(text, limit) {
|
|
4978
|
+
if (text.length <= limit) return text;
|
|
4979
|
+
const cut = text.slice(0, limit - 1);
|
|
4980
|
+
const lastSpace = cut.lastIndexOf(" ");
|
|
4981
|
+
return `${(lastSpace > 0 ? cut.slice(0, lastSpace) : cut).replace(/[\s,;:—–-]+$/, "")}\u2026`;
|
|
4982
|
+
}
|
|
4983
|
+
function defaultLandingDescription(productName, conceptTotal, imageTotal, categoryNames) {
|
|
4984
|
+
if (conceptTotal === 0) {
|
|
4985
|
+
return clampText(
|
|
4986
|
+
`Concepts of how ${productName} works, each a feature or flow explained with illustrations.`,
|
|
4987
|
+
META_DESCRIPTION_LIMIT
|
|
4988
|
+
);
|
|
4989
|
+
}
|
|
4990
|
+
const head = `Explore ${plural(conceptTotal, `${productName} concept`, `${productName} concepts`)} with ${illustrationCount(imageTotal)}`;
|
|
4991
|
+
for (let take = Math.min(categoryNames.length, 4); take >= 1; take -= 1) {
|
|
4992
|
+
const more = categoryNames.length > take ? " and more" : "";
|
|
4993
|
+
const text = `${head} across ${listSentence(categoryNames.slice(0, take))}${more}.`;
|
|
4994
|
+
if (text.length <= META_DESCRIPTION_LIMIT) return text;
|
|
4995
|
+
}
|
|
4996
|
+
return clampText(`${head} of how the product works.`, META_DESCRIPTION_LIMIT);
|
|
4997
|
+
}
|
|
4998
|
+
function slugifyAnchor(value) {
|
|
4999
|
+
return value.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
5000
|
+
}
|
|
5001
|
+
function groupByCategory(ordered, categories) {
|
|
5002
|
+
const byName = /* @__PURE__ */ new Map();
|
|
5003
|
+
for (const concept of ordered) {
|
|
5004
|
+
const list = byName.get(concept.category);
|
|
5005
|
+
if (list) list.push(concept);
|
|
5006
|
+
else byName.set(concept.category, [concept]);
|
|
5007
|
+
}
|
|
5008
|
+
const described = [];
|
|
5009
|
+
for (const category of categories ?? []) {
|
|
5010
|
+
const list = byName.get(category.name);
|
|
5011
|
+
if (!list) continue;
|
|
5012
|
+
described.push({
|
|
5013
|
+
name: category.name,
|
|
5014
|
+
description: category.description,
|
|
5015
|
+
concepts: list
|
|
5016
|
+
});
|
|
5017
|
+
byName.delete(category.name);
|
|
5018
|
+
}
|
|
5019
|
+
for (const [name, list] of byName) {
|
|
5020
|
+
described.push({ name, description: "", concepts: list });
|
|
5021
|
+
}
|
|
5022
|
+
const used = /* @__PURE__ */ new Set();
|
|
5023
|
+
return described.map((group) => {
|
|
5024
|
+
const base = `concepts-${slugifyAnchor(group.name) || "category"}`;
|
|
5025
|
+
let anchor = base;
|
|
5026
|
+
for (let n = 2; used.has(anchor); n += 1) anchor = `${base}-${n}`;
|
|
5027
|
+
used.add(anchor);
|
|
5028
|
+
return { ...group, anchor };
|
|
5029
|
+
});
|
|
5030
|
+
}
|
|
5031
|
+
function searchTokens(query) {
|
|
5032
|
+
return query.toLowerCase().split(/\s+/).filter(Boolean);
|
|
5033
|
+
}
|
|
5034
|
+
function matchesSearch(concept, tokens) {
|
|
5035
|
+
if (tokens.length === 0) return true;
|
|
5036
|
+
const haystack = [
|
|
5037
|
+
concept.title,
|
|
5038
|
+
concept.tagline,
|
|
5039
|
+
concept.category,
|
|
5040
|
+
...concept.keywords
|
|
5041
|
+
].join(" ").toLowerCase();
|
|
5042
|
+
return tokens.every((token) => haystack.includes(token));
|
|
5043
|
+
}
|
|
5044
|
+
function isPortrait(width, height) {
|
|
5045
|
+
return height > width;
|
|
5046
|
+
}
|
|
5047
|
+
function copyKey(index, text) {
|
|
5048
|
+
return `${index}-${text}`;
|
|
5049
|
+
}
|
|
5050
|
+
function DefaultConceptLink({
|
|
5051
|
+
href,
|
|
5052
|
+
className,
|
|
5053
|
+
children,
|
|
5054
|
+
"aria-label": ariaLabel
|
|
5055
|
+
}) {
|
|
5056
|
+
return /* @__PURE__ */ jsxRuntime.jsx("a", { href, className, "aria-label": ariaLabel, children });
|
|
5057
|
+
}
|
|
5058
|
+
function IllustrationNotice({ className }) {
|
|
5059
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5060
|
+
"div",
|
|
5061
|
+
{
|
|
5062
|
+
role: "note",
|
|
5063
|
+
"data-concepts": "notice",
|
|
5064
|
+
"data-concepts-notice": "",
|
|
5065
|
+
className: cn(
|
|
5066
|
+
"flex items-start gap-3 rounded-xl border border-primary/30 bg-primary/10 px-4 py-3 text-sm leading-relaxed text-foreground",
|
|
5067
|
+
className
|
|
5068
|
+
),
|
|
5069
|
+
children: [
|
|
5070
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5071
|
+
lucideReact.Info,
|
|
5072
|
+
{
|
|
5073
|
+
"aria-hidden": "true",
|
|
5074
|
+
className: "mt-0.5 h-4 w-4 shrink-0 text-primary"
|
|
5075
|
+
}
|
|
5076
|
+
),
|
|
5077
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { children: CONCEPT_ILLUSTRATION_NOTICE })
|
|
5078
|
+
]
|
|
5079
|
+
}
|
|
5080
|
+
);
|
|
5081
|
+
}
|
|
5082
|
+
function IllustrationBadge({ className }) {
|
|
5083
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
5084
|
+
"span",
|
|
5085
|
+
{
|
|
5086
|
+
"aria-hidden": "true",
|
|
5087
|
+
className: cn(
|
|
5088
|
+
"pointer-events-none absolute left-2 top-2 inline-flex items-center rounded-full border border-border bg-background/90 px-2 py-0.5 text-[11px] font-semibold uppercase tracking-wide text-foreground shadow-sm",
|
|
5089
|
+
className
|
|
5090
|
+
),
|
|
5091
|
+
children: "Illustration"
|
|
5092
|
+
}
|
|
5093
|
+
);
|
|
5094
|
+
}
|
|
5095
|
+
function ConceptCard({
|
|
5096
|
+
concept,
|
|
5097
|
+
Link
|
|
5098
|
+
}) {
|
|
5099
|
+
const image = concept.images[0];
|
|
5100
|
+
const portrait = image ? isPortrait(image.thumbWidth, image.thumbHeight) : false;
|
|
5101
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5102
|
+
Link,
|
|
5103
|
+
{
|
|
5104
|
+
href: conceptPath(concept.slug),
|
|
5105
|
+
className: "group flex h-full flex-col overflow-hidden rounded-2xl border border-border bg-card text-card-foreground shadow-sm transition hover:-translate-y-0.5 hover:border-primary/40 hover:shadow-md focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring motion-reduce:transform-none motion-reduce:transition-none",
|
|
5106
|
+
children: [
|
|
5107
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative aspect-[16/10] overflow-hidden border-b border-border bg-muted", children: [
|
|
5108
|
+
image ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
5109
|
+
"img",
|
|
5110
|
+
{
|
|
5111
|
+
src: image.thumb,
|
|
5112
|
+
alt: "",
|
|
5113
|
+
width: image.thumbWidth,
|
|
5114
|
+
height: image.thumbHeight,
|
|
5115
|
+
loading: "lazy",
|
|
5116
|
+
decoding: "async",
|
|
5117
|
+
className: cn(
|
|
5118
|
+
"h-full w-full",
|
|
5119
|
+
portrait ? "object-contain p-3" : "object-cover object-top"
|
|
5120
|
+
)
|
|
5121
|
+
}
|
|
5122
|
+
) : null,
|
|
5123
|
+
/* @__PURE__ */ jsxRuntime.jsx(IllustrationBadge, {})
|
|
5124
|
+
] }),
|
|
5125
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-1 flex-col gap-2 p-4", children: [
|
|
5126
|
+
/* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-base font-semibold leading-snug text-card-foreground transition-colors group-hover:text-primary", children: concept.title }),
|
|
5127
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "line-clamp-3 text-sm leading-relaxed text-muted-foreground", children: concept.tagline }),
|
|
5128
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "mt-auto inline-flex items-center gap-1.5 pt-1 text-xs font-medium text-muted-foreground", children: [
|
|
5129
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.ImageIcon, { "aria-hidden": "true", className: "h-3.5 w-3.5" }),
|
|
5130
|
+
illustrationCount(concept.images.length)
|
|
5131
|
+
] })
|
|
5132
|
+
] })
|
|
5133
|
+
]
|
|
5134
|
+
}
|
|
5135
|
+
);
|
|
5136
|
+
}
|
|
5137
|
+
function FilterChip({
|
|
5138
|
+
label,
|
|
5139
|
+
count,
|
|
5140
|
+
active,
|
|
5141
|
+
category,
|
|
5142
|
+
onSelect
|
|
5143
|
+
}) {
|
|
5144
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5145
|
+
"button",
|
|
5146
|
+
{
|
|
5147
|
+
type: "button",
|
|
5148
|
+
"aria-pressed": active,
|
|
5149
|
+
"data-category": category,
|
|
5150
|
+
onClick: onSelect,
|
|
5151
|
+
className: cn(
|
|
5152
|
+
"inline-flex items-center gap-2 rounded-full border px-3 py-1.5 text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
5153
|
+
active ? "border-primary bg-primary text-primary-foreground" : "border-border bg-card text-foreground hover:border-primary/40 hover:bg-muted"
|
|
5154
|
+
),
|
|
5155
|
+
children: [
|
|
5156
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: label }),
|
|
5157
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5158
|
+
"span",
|
|
5159
|
+
{
|
|
5160
|
+
className: cn(
|
|
5161
|
+
"rounded-full px-1.5 text-xs tabular-nums",
|
|
5162
|
+
active ? "bg-primary-foreground/20 text-primary-foreground" : "bg-muted text-muted-foreground"
|
|
5163
|
+
),
|
|
5164
|
+
children: count
|
|
5165
|
+
}
|
|
5166
|
+
)
|
|
5167
|
+
]
|
|
5168
|
+
}
|
|
5169
|
+
);
|
|
5170
|
+
}
|
|
5171
|
+
function ConceptsPage({
|
|
5172
|
+
productName,
|
|
5173
|
+
siteUrl,
|
|
5174
|
+
concepts,
|
|
5175
|
+
categories,
|
|
5176
|
+
cta,
|
|
5177
|
+
linkComponent,
|
|
5178
|
+
title,
|
|
5179
|
+
description,
|
|
5180
|
+
className
|
|
5181
|
+
}) {
|
|
5182
|
+
const Link = linkComponent ?? DefaultConceptLink;
|
|
5183
|
+
const base = normaliseSiteUrl(siteUrl);
|
|
5184
|
+
const searchId = React.useId();
|
|
5185
|
+
const ordered = React.useMemo(() => sortByOrder(concepts), [concepts]);
|
|
5186
|
+
const groups = React.useMemo(
|
|
5187
|
+
() => groupByCategory(ordered, categories),
|
|
5188
|
+
[ordered, categories]
|
|
5189
|
+
);
|
|
5190
|
+
const imageTotal = React.useMemo(
|
|
5191
|
+
() => ordered.reduce((sum, concept) => sum + concept.images.length, 0),
|
|
5192
|
+
[ordered]
|
|
5193
|
+
);
|
|
5194
|
+
const [query, setQuery] = React.useState("");
|
|
5195
|
+
const [activeCategory, setActiveCategory] = React.useState(null);
|
|
5196
|
+
const hasConcepts = ordered.length > 0;
|
|
5197
|
+
const tokens = React.useMemo(() => searchTokens(query), [query]);
|
|
5198
|
+
const searched = React.useMemo(
|
|
5199
|
+
() => ordered.filter((concept) => matchesSearch(concept, tokens)),
|
|
5200
|
+
[ordered, tokens]
|
|
5201
|
+
);
|
|
5202
|
+
const countsByCategory = React.useMemo(() => {
|
|
5203
|
+
const counts = /* @__PURE__ */ new Map();
|
|
5204
|
+
for (const concept of searched) {
|
|
5205
|
+
counts.set(concept.category, (counts.get(concept.category) ?? 0) + 1);
|
|
5206
|
+
}
|
|
5207
|
+
return counts;
|
|
5208
|
+
}, [searched]);
|
|
5209
|
+
const visibleGroups = React.useMemo(() => {
|
|
5210
|
+
const visible = new Set(
|
|
5211
|
+
searched.filter(
|
|
5212
|
+
(concept) => activeCategory === null || concept.category === activeCategory
|
|
5213
|
+
)
|
|
5214
|
+
);
|
|
5215
|
+
return groups.map((group) => ({
|
|
5216
|
+
...group,
|
|
5217
|
+
concepts: group.concepts.filter((concept) => visible.has(concept))
|
|
5218
|
+
})).filter((group) => group.concepts.length > 0);
|
|
5219
|
+
}, [groups, searched, activeCategory]);
|
|
5220
|
+
const visibleTotal = visibleGroups.reduce(
|
|
5221
|
+
(sum, group) => sum + group.concepts.length,
|
|
5222
|
+
0
|
|
5223
|
+
);
|
|
5224
|
+
const filtering = tokens.length > 0 || activeCategory !== null;
|
|
5225
|
+
const clearFilters = React.useCallback(() => {
|
|
5226
|
+
setQuery("");
|
|
5227
|
+
setActiveCategory(null);
|
|
5228
|
+
}, []);
|
|
5229
|
+
const heading = title ?? `${productName} concepts`;
|
|
5230
|
+
const metaDescription = description ?? defaultLandingDescription(
|
|
5231
|
+
productName,
|
|
5232
|
+
ordered.length,
|
|
5233
|
+
imageTotal,
|
|
5234
|
+
groups.map((group) => group.name)
|
|
5235
|
+
);
|
|
5236
|
+
const lead = description ?? `A guided tour of ${productName}, one concept at a time. Each concept groups the illustrations of a feature or flow and explains what it does, how it works and who it is for.`;
|
|
5237
|
+
const canonical = `${base}${CONCEPTS_PATH}`;
|
|
5238
|
+
const firstImage = ordered.find((concept) => concept.images[0])?.images[0];
|
|
5239
|
+
const structuredData = React.useMemo(
|
|
5240
|
+
() => [
|
|
5241
|
+
{
|
|
5242
|
+
"@context": "https://schema.org",
|
|
5243
|
+
"@type": "CollectionPage",
|
|
5244
|
+
name: heading,
|
|
5245
|
+
description: metaDescription,
|
|
5246
|
+
url: canonical,
|
|
5247
|
+
isPartOf: { "@type": "WebSite", name: productName, url: `${base}/` },
|
|
5248
|
+
mainEntity: {
|
|
5249
|
+
"@type": "ItemList",
|
|
5250
|
+
numberOfItems: ordered.length,
|
|
5251
|
+
itemListElement: ordered.map((concept, index) => {
|
|
5252
|
+
const image = concept.images[0];
|
|
5253
|
+
return {
|
|
5254
|
+
"@type": "ListItem",
|
|
5255
|
+
position: index + 1,
|
|
5256
|
+
url: absoluteUrl(base, conceptPath(concept.slug)),
|
|
5257
|
+
name: concept.title,
|
|
5258
|
+
...image ? { image: absoluteUrl(base, image.src) } : {}
|
|
5259
|
+
};
|
|
5260
|
+
})
|
|
5261
|
+
}
|
|
5262
|
+
},
|
|
5263
|
+
{
|
|
5264
|
+
"@context": "https://schema.org",
|
|
5265
|
+
"@type": "BreadcrumbList",
|
|
5266
|
+
itemListElement: [
|
|
5267
|
+
{ "@type": "ListItem", position: 1, name: "Home", item: `${base}/` },
|
|
5268
|
+
{
|
|
5269
|
+
"@type": "ListItem",
|
|
5270
|
+
position: 2,
|
|
5271
|
+
name: "Concepts",
|
|
5272
|
+
item: canonical
|
|
5273
|
+
}
|
|
5274
|
+
]
|
|
5275
|
+
}
|
|
5276
|
+
],
|
|
5277
|
+
[base, canonical, heading, metaDescription, ordered, productName]
|
|
5278
|
+
);
|
|
5279
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5280
|
+
"div",
|
|
5281
|
+
{
|
|
5282
|
+
"data-concepts": "landing",
|
|
5283
|
+
className: cn("bg-background text-foreground", className),
|
|
5284
|
+
children: [
|
|
5285
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5286
|
+
PageHead,
|
|
5287
|
+
{
|
|
5288
|
+
title: "Concepts",
|
|
5289
|
+
description: metaDescription,
|
|
5290
|
+
productName,
|
|
5291
|
+
keywords: [
|
|
5292
|
+
`${productName} concepts`,
|
|
5293
|
+
`${productName} illustrations`,
|
|
5294
|
+
...groups.map((group) => group.name)
|
|
5295
|
+
].join(", "),
|
|
5296
|
+
image: firstImage ? absoluteUrl(base, firstImage.src) : void 0,
|
|
5297
|
+
url: canonical,
|
|
5298
|
+
structuredData
|
|
5299
|
+
}
|
|
5300
|
+
),
|
|
5301
|
+
/* @__PURE__ */ jsxRuntime.jsx("section", { className: "border-b border-border bg-muted/30", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mx-auto max-w-6xl px-4 py-14 sm:px-6 sm:py-20 lg:px-8", children: [
|
|
5302
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs font-semibold uppercase tracking-[0.2em] text-primary", children: "Concepts" }),
|
|
5303
|
+
/* @__PURE__ */ jsxRuntime.jsx("h1", { className: "mt-3 max-w-3xl text-4xl font-bold tracking-tight text-foreground sm:text-5xl", children: heading }),
|
|
5304
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-4 max-w-2xl text-lg leading-relaxed text-muted-foreground", children: lead }),
|
|
5305
|
+
hasConcepts ? /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "mt-6 flex flex-wrap gap-x-6 gap-y-2 text-sm text-muted-foreground", children: [
|
|
5306
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
5307
|
+
/* @__PURE__ */ jsxRuntime.jsx("strong", { className: "text-lg font-semibold text-foreground", children: ordered.length }),
|
|
5308
|
+
" ",
|
|
5309
|
+
ordered.length === 1 ? "concept" : "concepts"
|
|
5310
|
+
] }),
|
|
5311
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
5312
|
+
/* @__PURE__ */ jsxRuntime.jsx("strong", { className: "text-lg font-semibold text-foreground", children: imageTotal }),
|
|
5313
|
+
" ",
|
|
5314
|
+
imageTotal === 1 ? "illustration" : "illustrations"
|
|
5315
|
+
] })
|
|
5316
|
+
] }) : null,
|
|
5317
|
+
/* @__PURE__ */ jsxRuntime.jsx(IllustrationNotice, { className: "mt-6 max-w-2xl" }),
|
|
5318
|
+
cta ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-8 flex flex-wrap gap-3", children: cta }) : null
|
|
5319
|
+
] }) }),
|
|
5320
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mx-auto max-w-6xl px-4 pb-20 sm:px-6 lg:px-8", children: hasConcepts ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
5321
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
5322
|
+
"div",
|
|
5323
|
+
{
|
|
5324
|
+
role: "search",
|
|
5325
|
+
"data-concepts": "filter",
|
|
5326
|
+
className: "flex flex-col gap-4 py-8",
|
|
5327
|
+
children: [
|
|
5328
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative w-full max-w-md", children: [
|
|
5329
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5330
|
+
lucideReact.Search,
|
|
5331
|
+
{
|
|
5332
|
+
"aria-hidden": "true",
|
|
5333
|
+
className: "pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground"
|
|
5334
|
+
}
|
|
5335
|
+
),
|
|
5336
|
+
/* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: searchId, className: "sr-only", children: "Search concepts" }),
|
|
5337
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5338
|
+
"input",
|
|
5339
|
+
{
|
|
5340
|
+
id: searchId,
|
|
5341
|
+
type: "search",
|
|
5342
|
+
value: query,
|
|
5343
|
+
onChange: (event) => setQuery(event.target.value),
|
|
5344
|
+
placeholder: "Search concepts",
|
|
5345
|
+
autoComplete: "off",
|
|
5346
|
+
className: "h-10 w-full rounded-lg border border-border bg-background pl-9 pr-3 text-sm text-foreground shadow-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
|
|
5347
|
+
}
|
|
5348
|
+
)
|
|
5349
|
+
] }),
|
|
5350
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
5351
|
+
"div",
|
|
5352
|
+
{
|
|
5353
|
+
role: "group",
|
|
5354
|
+
"aria-label": "Filter by category",
|
|
5355
|
+
className: "flex flex-wrap gap-2",
|
|
5356
|
+
children: [
|
|
5357
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5358
|
+
FilterChip,
|
|
5359
|
+
{
|
|
5360
|
+
label: "All",
|
|
5361
|
+
category: "all",
|
|
5362
|
+
count: searched.length,
|
|
5363
|
+
active: activeCategory === null,
|
|
5364
|
+
onSelect: () => setActiveCategory(null)
|
|
5365
|
+
}
|
|
5366
|
+
),
|
|
5367
|
+
groups.map((group) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
5368
|
+
FilterChip,
|
|
5369
|
+
{
|
|
5370
|
+
label: group.name,
|
|
5371
|
+
category: group.name,
|
|
5372
|
+
count: countsByCategory.get(group.name) ?? 0,
|
|
5373
|
+
active: activeCategory === group.name,
|
|
5374
|
+
onSelect: () => setActiveCategory(
|
|
5375
|
+
(current) => current === group.name ? null : group.name
|
|
5376
|
+
)
|
|
5377
|
+
},
|
|
5378
|
+
group.anchor
|
|
5379
|
+
))
|
|
5380
|
+
]
|
|
5381
|
+
}
|
|
5382
|
+
),
|
|
5383
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
5384
|
+
"p",
|
|
5385
|
+
{
|
|
5386
|
+
"aria-live": "polite",
|
|
5387
|
+
className: filtering ? "text-sm text-muted-foreground" : "sr-only",
|
|
5388
|
+
children: [
|
|
5389
|
+
"Showing ",
|
|
5390
|
+
visibleTotal,
|
|
5391
|
+
" of ",
|
|
5392
|
+
ordered.length,
|
|
5393
|
+
" ",
|
|
5394
|
+
ordered.length === 1 ? "concept" : "concepts"
|
|
5395
|
+
]
|
|
5396
|
+
}
|
|
5397
|
+
)
|
|
5398
|
+
]
|
|
5399
|
+
}
|
|
5400
|
+
),
|
|
5401
|
+
visibleTotal === 0 ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5402
|
+
"div",
|
|
5403
|
+
{
|
|
5404
|
+
"data-concepts": "empty",
|
|
5405
|
+
className: "rounded-2xl border border-dashed border-border bg-muted/30 px-6 py-14 text-center",
|
|
5406
|
+
children: [
|
|
5407
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5408
|
+
lucideReact.Search,
|
|
5409
|
+
{
|
|
5410
|
+
"aria-hidden": "true",
|
|
5411
|
+
className: "mx-auto h-8 w-8 text-muted-foreground"
|
|
5412
|
+
}
|
|
5413
|
+
),
|
|
5414
|
+
/* @__PURE__ */ jsxRuntime.jsx("h2", { className: "mt-4 text-lg font-semibold text-foreground", children: "No concepts match your filters" }),
|
|
5415
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-2 text-sm text-muted-foreground", children: "Try a different search, or show every category." }),
|
|
5416
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5417
|
+
"button",
|
|
5418
|
+
{
|
|
5419
|
+
type: "button",
|
|
5420
|
+
onClick: clearFilters,
|
|
5421
|
+
className: "mt-6 inline-flex items-center rounded-full border border-border bg-card px-4 py-2 text-sm font-medium text-foreground transition-colors hover:bg-muted focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
5422
|
+
children: "Clear filters"
|
|
5423
|
+
}
|
|
5424
|
+
)
|
|
5425
|
+
]
|
|
5426
|
+
}
|
|
5427
|
+
) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-14", children: visibleGroups.map((group) => /* @__PURE__ */ jsxRuntime.jsxs("section", { "aria-labelledby": group.anchor, children: [
|
|
5428
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "max-w-3xl", children: [
|
|
5429
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5430
|
+
"h2",
|
|
5431
|
+
{
|
|
5432
|
+
id: group.anchor,
|
|
5433
|
+
className: "scroll-mt-24 text-2xl font-semibold tracking-tight text-foreground",
|
|
5434
|
+
children: group.name
|
|
5435
|
+
}
|
|
5436
|
+
),
|
|
5437
|
+
group.description ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-2 leading-relaxed text-muted-foreground", children: group.description }) : null
|
|
5438
|
+
] }),
|
|
5439
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5440
|
+
"ul",
|
|
5441
|
+
{
|
|
5442
|
+
role: "list",
|
|
5443
|
+
className: "mt-6 grid grid-cols-1 gap-5 sm:grid-cols-2 lg:grid-cols-3",
|
|
5444
|
+
children: group.concepts.map((concept) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
5445
|
+
"li",
|
|
5446
|
+
{
|
|
5447
|
+
"data-concepts": "card",
|
|
5448
|
+
"data-slug": concept.slug,
|
|
5449
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(ConceptCard, { concept, Link })
|
|
5450
|
+
},
|
|
5451
|
+
concept.slug
|
|
5452
|
+
))
|
|
5453
|
+
}
|
|
5454
|
+
)
|
|
5455
|
+
] }, group.anchor)) })
|
|
5456
|
+
] }) : (
|
|
5457
|
+
// Nothing published yet: no filter bar with an "All 0" chip, and no empty state
|
|
5458
|
+
// that blames filters the visitor never set.
|
|
5459
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
5460
|
+
"div",
|
|
5461
|
+
{
|
|
5462
|
+
"data-concepts": "none",
|
|
5463
|
+
className: "mt-10 rounded-2xl border border-dashed border-border bg-muted/30 px-6 py-14 text-center",
|
|
5464
|
+
children: [
|
|
5465
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5466
|
+
lucideReact.ImageIcon,
|
|
5467
|
+
{
|
|
5468
|
+
"aria-hidden": "true",
|
|
5469
|
+
className: "mx-auto h-8 w-8 text-muted-foreground"
|
|
5470
|
+
}
|
|
5471
|
+
),
|
|
5472
|
+
/* @__PURE__ */ jsxRuntime.jsx("h2", { className: "mt-4 text-lg font-semibold text-foreground", children: "No concepts published yet" }),
|
|
5473
|
+
/* @__PURE__ */ jsxRuntime.jsxs("p", { className: "mt-2 text-sm text-muted-foreground", children: [
|
|
5474
|
+
productName,
|
|
5475
|
+
" concepts will appear here as they are published."
|
|
5476
|
+
] })
|
|
5477
|
+
]
|
|
5478
|
+
}
|
|
5479
|
+
)
|
|
5480
|
+
) })
|
|
5481
|
+
]
|
|
5482
|
+
}
|
|
5483
|
+
);
|
|
5484
|
+
}
|
|
5485
|
+
var SECTION_HEADING = "scroll-mt-24 text-2xl font-semibold tracking-tight text-foreground";
|
|
5486
|
+
var CHIP = "inline-flex items-center rounded-full border border-border bg-muted/50 px-3 py-1 text-sm text-foreground";
|
|
5487
|
+
function IllustrationFigure({
|
|
5488
|
+
image,
|
|
5489
|
+
onOpen
|
|
5490
|
+
}) {
|
|
5491
|
+
const portrait = isPortrait(image.width, image.height);
|
|
5492
|
+
return (
|
|
5493
|
+
// The block the llms extractor reads: title, image line, caption, description — in
|
|
5494
|
+
// that order and with nothing in between. The description sits outside <figure>
|
|
5495
|
+
// because a <figcaption> must be the figure's first or last child.
|
|
5496
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4", children: [
|
|
5497
|
+
/* @__PURE__ */ jsxRuntime.jsxs("figure", { id: `illustration-${image.key}`, className: "scroll-mt-24", children: [
|
|
5498
|
+
/* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-lg font-semibold text-foreground", children: image.title }),
|
|
5499
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
5500
|
+
"button",
|
|
5501
|
+
{
|
|
5502
|
+
type: "button",
|
|
5503
|
+
onClick: (event) => onOpen(event.currentTarget),
|
|
5504
|
+
"data-concepts": "illustration",
|
|
5505
|
+
className: cn(
|
|
5506
|
+
"group relative mt-3 block w-full overflow-hidden rounded-2xl border border-border shadow-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
5507
|
+
portrait ? "bg-muted p-4 sm:p-6" : "bg-muted"
|
|
5508
|
+
),
|
|
5509
|
+
children: [
|
|
5510
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5511
|
+
"img",
|
|
5512
|
+
{
|
|
5513
|
+
"data-llms-image": "",
|
|
5514
|
+
src: image.src,
|
|
5515
|
+
alt: image.alt,
|
|
5516
|
+
width: image.width,
|
|
5517
|
+
height: image.height,
|
|
5518
|
+
loading: "lazy",
|
|
5519
|
+
decoding: "async",
|
|
5520
|
+
className: "mx-auto block h-auto max-h-[80vh] w-auto max-w-full"
|
|
5521
|
+
}
|
|
5522
|
+
),
|
|
5523
|
+
/* @__PURE__ */ jsxRuntime.jsx(IllustrationBadge, { className: "left-3 top-3" }),
|
|
5524
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5525
|
+
"span",
|
|
5526
|
+
{
|
|
5527
|
+
"aria-hidden": "true",
|
|
5528
|
+
className: "absolute bottom-3 right-3 inline-flex h-8 w-8 items-center justify-center rounded-full border border-border bg-background/90 text-foreground shadow-sm transition-opacity group-hover:opacity-100 sm:opacity-80",
|
|
5529
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Maximize2, { className: "h-4 w-4" })
|
|
5530
|
+
}
|
|
5531
|
+
),
|
|
5532
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Enlarge illustration" })
|
|
5533
|
+
]
|
|
5534
|
+
}
|
|
5535
|
+
),
|
|
5536
|
+
/* @__PURE__ */ jsxRuntime.jsx("figcaption", { className: "mt-3 text-sm font-medium text-foreground", children: image.caption })
|
|
5537
|
+
] }),
|
|
5538
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "leading-relaxed text-muted-foreground", children: image.description })
|
|
5539
|
+
] })
|
|
5540
|
+
);
|
|
5541
|
+
}
|
|
5542
|
+
function ConceptDetailPage(props) {
|
|
5543
|
+
return /* @__PURE__ */ jsxRuntime.jsx(ConceptDetail, { ...props }, props.concept.slug);
|
|
5544
|
+
}
|
|
5545
|
+
function ConceptDetail({
|
|
5546
|
+
productName,
|
|
5547
|
+
siteUrl,
|
|
5548
|
+
concept,
|
|
5549
|
+
concepts,
|
|
5550
|
+
categories,
|
|
5551
|
+
cta,
|
|
5552
|
+
linkComponent,
|
|
5553
|
+
className
|
|
5554
|
+
}) {
|
|
5555
|
+
const Link = linkComponent ?? DefaultConceptLink;
|
|
5556
|
+
const base = normaliseSiteUrl(siteUrl);
|
|
5557
|
+
const headingId = React.useId();
|
|
5558
|
+
const ordered = React.useMemo(() => sortByOrder(concepts), [concepts]);
|
|
5559
|
+
const position = ordered.findIndex((item) => item.slug === concept.slug);
|
|
5560
|
+
const previous = position > 0 ? ordered[position - 1] : void 0;
|
|
5561
|
+
const next = position >= 0 && position < ordered.length - 1 ? ordered[position + 1] : void 0;
|
|
5562
|
+
const related = React.useMemo(() => {
|
|
5563
|
+
const bySlug = new Map(ordered.map((item) => [item.slug, item]));
|
|
5564
|
+
const curated = [...new Set(concept.related)].map((slug) => bySlug.get(slug)).filter(
|
|
5565
|
+
(item) => item !== void 0 && item.slug !== concept.slug
|
|
5566
|
+
);
|
|
5567
|
+
const list = curated.length > 0 ? curated : ordered.filter(
|
|
5568
|
+
(item) => item.category === concept.category && item.slug !== concept.slug
|
|
5569
|
+
);
|
|
5570
|
+
return list.slice(0, RELATED_LIMIT);
|
|
5571
|
+
}, [concept, ordered]);
|
|
5572
|
+
const relatedIsCurated = concept.related.some(
|
|
5573
|
+
(slug) => related.some((item) => item.slug === slug)
|
|
5574
|
+
);
|
|
5575
|
+
const categoryDescription = categories?.find(
|
|
5576
|
+
(category) => category.name === concept.category
|
|
5577
|
+
)?.description;
|
|
5578
|
+
const [lightboxIndex, setLightboxIndex] = React.useState(null);
|
|
5579
|
+
const triggerRef = React.useRef(null);
|
|
5580
|
+
const openLightbox = React.useCallback((index, trigger) => {
|
|
5581
|
+
triggerRef.current = trigger;
|
|
5582
|
+
setLightboxIndex(index);
|
|
5583
|
+
}, []);
|
|
5584
|
+
const closeLightbox = React.useCallback(() => setLightboxIndex(null), []);
|
|
5585
|
+
React.useEffect(() => {
|
|
5586
|
+
if (lightboxIndex !== null) return;
|
|
5587
|
+
const trigger = triggerRef.current;
|
|
5588
|
+
if (!trigger) return;
|
|
5589
|
+
triggerRef.current = null;
|
|
5590
|
+
if (trigger.isConnected) trigger.focus();
|
|
5591
|
+
}, [lightboxIndex]);
|
|
5592
|
+
const canonical = absoluteUrl(base, conceptPath(concept.slug));
|
|
5593
|
+
const hero = concept.images[0];
|
|
5594
|
+
const imageTotal = concept.images.length;
|
|
5595
|
+
const structuredData = React.useMemo(
|
|
5596
|
+
() => [
|
|
5597
|
+
{
|
|
5598
|
+
"@context": "https://schema.org",
|
|
5599
|
+
"@type": "ImageGallery",
|
|
5600
|
+
name: concept.title,
|
|
5601
|
+
description: concept.metaDescription,
|
|
5602
|
+
url: canonical,
|
|
5603
|
+
keywords: concept.keywords.join(", "),
|
|
5604
|
+
about: { "@type": "Thing", name: productName },
|
|
5605
|
+
image: concept.images.map((image) => ({
|
|
5606
|
+
"@type": "ImageObject",
|
|
5607
|
+
contentUrl: absoluteUrl(base, image.src),
|
|
5608
|
+
thumbnailUrl: absoluteUrl(base, image.thumb),
|
|
5609
|
+
name: image.title,
|
|
5610
|
+
caption: image.caption,
|
|
5611
|
+
description: image.description,
|
|
5612
|
+
width: image.width,
|
|
5613
|
+
height: image.height
|
|
5614
|
+
}))
|
|
5615
|
+
},
|
|
5616
|
+
{
|
|
5617
|
+
"@context": "https://schema.org",
|
|
5618
|
+
"@type": "BreadcrumbList",
|
|
5619
|
+
itemListElement: [
|
|
5620
|
+
{ "@type": "ListItem", position: 1, name: "Home", item: `${base}/` },
|
|
5621
|
+
{
|
|
5622
|
+
"@type": "ListItem",
|
|
5623
|
+
position: 2,
|
|
5624
|
+
name: "Concepts",
|
|
5625
|
+
item: `${base}${CONCEPTS_PATH}`
|
|
5626
|
+
},
|
|
5627
|
+
{
|
|
5628
|
+
"@type": "ListItem",
|
|
5629
|
+
position: 3,
|
|
5630
|
+
name: concept.title,
|
|
5631
|
+
item: canonical
|
|
5632
|
+
}
|
|
5633
|
+
]
|
|
5634
|
+
}
|
|
5635
|
+
],
|
|
5636
|
+
[base, canonical, concept, productName]
|
|
5637
|
+
);
|
|
5638
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5639
|
+
"article",
|
|
5640
|
+
{
|
|
5641
|
+
"data-concepts": "detail",
|
|
5642
|
+
"data-slug": concept.slug,
|
|
5643
|
+
"aria-labelledby": headingId,
|
|
5644
|
+
className: cn("bg-background text-foreground", className),
|
|
5645
|
+
children: [
|
|
5646
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5647
|
+
PageHead,
|
|
5648
|
+
{
|
|
5649
|
+
title: `${concept.title} \u2014 Concept`,
|
|
5650
|
+
description: concept.metaDescription,
|
|
5651
|
+
productName,
|
|
5652
|
+
keywords: concept.keywords.join(", "),
|
|
5653
|
+
image: hero ? absoluteUrl(base, hero.src) : void 0,
|
|
5654
|
+
url: canonical,
|
|
5655
|
+
structuredData
|
|
5656
|
+
}
|
|
5657
|
+
),
|
|
5658
|
+
/* @__PURE__ */ jsxRuntime.jsx("header", { className: "border-b border-border bg-muted/30", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mx-auto max-w-6xl px-4 pb-10 pt-8 sm:px-6 lg:px-8", children: [
|
|
5659
|
+
/* @__PURE__ */ jsxRuntime.jsx("nav", { "aria-label": "Breadcrumb", children: /* @__PURE__ */ jsxRuntime.jsxs("ol", { className: "flex flex-wrap items-center gap-1.5 text-sm text-muted-foreground", children: [
|
|
5660
|
+
/* @__PURE__ */ jsxRuntime.jsxs("li", { className: "inline-flex items-center gap-1.5", children: [
|
|
5661
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5662
|
+
Link,
|
|
5663
|
+
{
|
|
5664
|
+
href: "/",
|
|
5665
|
+
className: "rounded hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
5666
|
+
children: "Home"
|
|
5667
|
+
}
|
|
5668
|
+
),
|
|
5669
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { "aria-hidden": "true", className: "h-3.5 w-3.5" })
|
|
5670
|
+
] }),
|
|
5671
|
+
/* @__PURE__ */ jsxRuntime.jsxs("li", { className: "inline-flex items-center gap-1.5", children: [
|
|
5672
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5673
|
+
Link,
|
|
5674
|
+
{
|
|
5675
|
+
href: CONCEPTS_PATH,
|
|
5676
|
+
className: "rounded hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
5677
|
+
children: "Concepts"
|
|
5678
|
+
}
|
|
5679
|
+
),
|
|
5680
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { "aria-hidden": "true", className: "h-3.5 w-3.5" })
|
|
5681
|
+
] }),
|
|
5682
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5683
|
+
"li",
|
|
5684
|
+
{
|
|
5685
|
+
"aria-current": "page",
|
|
5686
|
+
className: "min-w-0 truncate text-foreground",
|
|
5687
|
+
children: concept.title
|
|
5688
|
+
}
|
|
5689
|
+
)
|
|
5690
|
+
] }) }),
|
|
5691
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-6 flex flex-wrap items-center gap-2", children: [
|
|
5692
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5693
|
+
"span",
|
|
5694
|
+
{
|
|
5695
|
+
"data-concepts": "category",
|
|
5696
|
+
title: categoryDescription,
|
|
5697
|
+
className: "inline-flex items-center rounded-full border border-primary/30 bg-primary/10 px-3 py-1 text-xs font-semibold text-primary",
|
|
5698
|
+
children: concept.category
|
|
5699
|
+
}
|
|
5700
|
+
),
|
|
5701
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "inline-flex items-center gap-1.5 rounded-full border border-border bg-background px-3 py-1 text-xs font-medium text-muted-foreground", children: [
|
|
5702
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.ImageIcon, { "aria-hidden": "true", className: "h-3.5 w-3.5" }),
|
|
5703
|
+
illustrationCount(imageTotal)
|
|
5704
|
+
] })
|
|
5705
|
+
] }),
|
|
5706
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5707
|
+
"h1",
|
|
5708
|
+
{
|
|
5709
|
+
id: headingId,
|
|
5710
|
+
className: "mt-4 max-w-4xl text-3xl font-bold tracking-tight text-foreground sm:text-4xl lg:text-5xl",
|
|
5711
|
+
children: concept.title
|
|
5712
|
+
}
|
|
5713
|
+
),
|
|
5714
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-4 max-w-3xl text-lg leading-relaxed text-muted-foreground", children: concept.tagline }),
|
|
5715
|
+
/* @__PURE__ */ jsxRuntime.jsx(IllustrationNotice, { className: "mt-6 max-w-3xl" })
|
|
5716
|
+
] }) }),
|
|
5717
|
+
hero ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mx-auto max-w-6xl px-4 pt-10 sm:px-6 lg:px-8", children: /* @__PURE__ */ jsxRuntime.jsx("figure", { "data-concepts": "hero", children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5718
|
+
"button",
|
|
5719
|
+
{
|
|
5720
|
+
type: "button",
|
|
5721
|
+
onClick: (event) => openLightbox(0, event.currentTarget),
|
|
5722
|
+
className: cn(
|
|
5723
|
+
"group relative block w-full overflow-hidden rounded-2xl border border-border bg-muted shadow-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
5724
|
+
isPortrait(hero.width, hero.height) && "p-4 sm:p-6"
|
|
5725
|
+
),
|
|
5726
|
+
children: [
|
|
5727
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5728
|
+
"img",
|
|
5729
|
+
{
|
|
5730
|
+
src: hero.src,
|
|
5731
|
+
alt: hero.alt,
|
|
5732
|
+
width: hero.width,
|
|
5733
|
+
height: hero.height,
|
|
5734
|
+
loading: "eager",
|
|
5735
|
+
...HERO_FETCH_PRIORITY,
|
|
5736
|
+
className: "mx-auto block h-auto max-h-[75vh] w-auto max-w-full"
|
|
5737
|
+
}
|
|
5738
|
+
),
|
|
5739
|
+
/* @__PURE__ */ jsxRuntime.jsx(IllustrationBadge, { className: "left-3 top-3" }),
|
|
5740
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
5741
|
+
"span",
|
|
5742
|
+
{
|
|
5743
|
+
"aria-hidden": "true",
|
|
5744
|
+
className: "absolute bottom-3 right-3 inline-flex items-center gap-1.5 rounded-full border border-border bg-background/90 px-3 py-1 text-xs font-medium text-foreground shadow-sm",
|
|
5745
|
+
children: [
|
|
5746
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Maximize2, { className: "h-3.5 w-3.5" }),
|
|
5747
|
+
"Enlarge"
|
|
5748
|
+
]
|
|
5749
|
+
}
|
|
5750
|
+
),
|
|
5751
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Enlarge illustration" })
|
|
5752
|
+
]
|
|
5753
|
+
}
|
|
5754
|
+
) }) }) : null,
|
|
5755
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mx-auto max-w-6xl px-4 py-14 sm:px-6 lg:px-8", children: [
|
|
5756
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "max-w-3xl space-y-12", children: [
|
|
5757
|
+
concept.overview.length > 0 ? /* @__PURE__ */ jsxRuntime.jsxs("section", { "aria-labelledby": `${headingId}-overview`, children: [
|
|
5758
|
+
/* @__PURE__ */ jsxRuntime.jsx("h2", { id: `${headingId}-overview`, className: SECTION_HEADING, children: "Overview" }),
|
|
5759
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-4 space-y-4 text-base leading-relaxed text-foreground", children: concept.overview.map((paragraph, index) => /* @__PURE__ */ jsxRuntime.jsx("p", { children: paragraph }, copyKey(index, paragraph))) })
|
|
5760
|
+
] }) : null,
|
|
5761
|
+
concept.highlights.length > 0 ? /* @__PURE__ */ jsxRuntime.jsxs("section", { "aria-labelledby": `${headingId}-highlights`, children: [
|
|
5762
|
+
/* @__PURE__ */ jsxRuntime.jsx("h2", { id: `${headingId}-highlights`, className: SECTION_HEADING, children: "What this concept shows" }),
|
|
5763
|
+
/* @__PURE__ */ jsxRuntime.jsx("ul", { role: "list", className: "mt-4 space-y-3", children: concept.highlights.map((highlight, index) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5764
|
+
"li",
|
|
5765
|
+
{
|
|
5766
|
+
className: "flex items-start gap-3 leading-relaxed text-foreground",
|
|
5767
|
+
children: [
|
|
5768
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5769
|
+
"span",
|
|
5770
|
+
{
|
|
5771
|
+
"aria-hidden": "true",
|
|
5772
|
+
className: "mt-0.5 inline-flex h-5 w-5 shrink-0 items-center justify-center rounded-full bg-primary/10 text-primary",
|
|
5773
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: "h-3.5 w-3.5" })
|
|
5774
|
+
}
|
|
5775
|
+
),
|
|
5776
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: highlight })
|
|
5777
|
+
]
|
|
5778
|
+
},
|
|
5779
|
+
copyKey(index, highlight)
|
|
5780
|
+
)) })
|
|
5781
|
+
] }) : null,
|
|
5782
|
+
concept.workflow.length > 0 ? /* @__PURE__ */ jsxRuntime.jsxs("section", { "aria-labelledby": `${headingId}-workflow`, children: [
|
|
5783
|
+
/* @__PURE__ */ jsxRuntime.jsx("h2", { id: `${headingId}-workflow`, className: SECTION_HEADING, children: "How it works" }),
|
|
5784
|
+
/* @__PURE__ */ jsxRuntime.jsx("ol", { role: "list", className: "mt-4 space-y-4", children: concept.workflow.map((step, index) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5785
|
+
"li",
|
|
5786
|
+
{
|
|
5787
|
+
className: "flex items-start gap-4",
|
|
5788
|
+
children: [
|
|
5789
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5790
|
+
"span",
|
|
5791
|
+
{
|
|
5792
|
+
"aria-hidden": "true",
|
|
5793
|
+
className: "inline-flex h-7 w-7 shrink-0 items-center justify-center rounded-full border border-border bg-card text-sm font-semibold tabular-nums text-foreground",
|
|
5794
|
+
children: index + 1
|
|
5795
|
+
}
|
|
5796
|
+
),
|
|
5797
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pt-0.5 leading-relaxed text-foreground", children: step })
|
|
5798
|
+
]
|
|
5799
|
+
},
|
|
5800
|
+
copyKey(index, step)
|
|
5801
|
+
)) })
|
|
5802
|
+
] }) : null,
|
|
5803
|
+
concept.audience.length > 0 ? /* @__PURE__ */ jsxRuntime.jsxs("section", { "aria-labelledby": `${headingId}-audience`, children: [
|
|
5804
|
+
/* @__PURE__ */ jsxRuntime.jsx("h2", { id: `${headingId}-audience`, className: SECTION_HEADING, children: "Who it's for" }),
|
|
5805
|
+
/* @__PURE__ */ jsxRuntime.jsx("ul", { role: "list", className: "mt-4 flex flex-wrap gap-2", children: concept.audience.map((who, index) => /* @__PURE__ */ jsxRuntime.jsx("li", { className: CHIP, children: who }, copyKey(index, who))) })
|
|
5806
|
+
] }) : null
|
|
5807
|
+
] }),
|
|
5808
|
+
imageTotal > 0 ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5809
|
+
"section",
|
|
5810
|
+
{
|
|
5811
|
+
"aria-labelledby": `${headingId}-illustrations`,
|
|
5812
|
+
className: "mt-16",
|
|
5813
|
+
children: [
|
|
5814
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "max-w-3xl", children: [
|
|
5815
|
+
/* @__PURE__ */ jsxRuntime.jsx("h2", { id: `${headingId}-illustrations`, className: SECTION_HEADING, children: "Illustrations" }),
|
|
5816
|
+
/* @__PURE__ */ jsxRuntime.jsxs("p", { className: "mt-2 text-muted-foreground", children: [
|
|
5817
|
+
illustrationCount(imageTotal),
|
|
5818
|
+
" of this concept. Select one to view it full size."
|
|
5819
|
+
] })
|
|
5820
|
+
] }),
|
|
5821
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-8 space-y-14", children: concept.images.map((image, index) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
5822
|
+
IllustrationFigure,
|
|
5823
|
+
{
|
|
5824
|
+
image,
|
|
5825
|
+
onOpen: (trigger) => openLightbox(index, trigger)
|
|
5826
|
+
},
|
|
5827
|
+
image.key
|
|
5828
|
+
)) })
|
|
5829
|
+
]
|
|
5830
|
+
}
|
|
5831
|
+
) : null,
|
|
5832
|
+
concept.keywords.length > 0 ? /* @__PURE__ */ jsxRuntime.jsxs("section", { "aria-labelledby": `${headingId}-topics`, className: "mt-16", children: [
|
|
5833
|
+
/* @__PURE__ */ jsxRuntime.jsx("h2", { id: `${headingId}-topics`, className: SECTION_HEADING, children: "Topics" }),
|
|
5834
|
+
/* @__PURE__ */ jsxRuntime.jsx("ul", { role: "list", className: "mt-4 flex flex-wrap gap-2", children: concept.keywords.map((keyword, index) => /* @__PURE__ */ jsxRuntime.jsx("li", { className: CHIP, children: keyword }, copyKey(index, keyword))) })
|
|
5835
|
+
] }) : null,
|
|
5836
|
+
related.length > 0 ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5837
|
+
"section",
|
|
5838
|
+
{
|
|
5839
|
+
"aria-labelledby": `${headingId}-related`,
|
|
5840
|
+
"data-concepts": "related",
|
|
5841
|
+
className: "mt-16",
|
|
5842
|
+
children: [
|
|
5843
|
+
/* @__PURE__ */ jsxRuntime.jsx("h2", { id: `${headingId}-related`, className: SECTION_HEADING, children: relatedIsCurated ? "Related concepts" : `More in ${concept.category}` }),
|
|
5844
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5845
|
+
"ul",
|
|
5846
|
+
{
|
|
5847
|
+
role: "list",
|
|
5848
|
+
className: cn(
|
|
5849
|
+
"mt-6 grid grid-cols-1 gap-5 sm:grid-cols-2",
|
|
5850
|
+
related.length >= 4 ? "lg:grid-cols-4" : "lg:grid-cols-3"
|
|
5851
|
+
),
|
|
5852
|
+
children: related.map((item) => /* @__PURE__ */ jsxRuntime.jsx("li", { "data-concepts": "card", "data-slug": item.slug, children: /* @__PURE__ */ jsxRuntime.jsx(ConceptCard, { concept: item, Link }) }, item.slug))
|
|
5853
|
+
}
|
|
5854
|
+
)
|
|
5855
|
+
]
|
|
5856
|
+
}
|
|
5857
|
+
) : null,
|
|
5858
|
+
previous || next ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5859
|
+
"nav",
|
|
5860
|
+
{
|
|
5861
|
+
"aria-label": "Previous and next concepts",
|
|
5862
|
+
"data-concepts": "pager",
|
|
5863
|
+
className: "mt-16 grid gap-4 sm:grid-cols-2",
|
|
5864
|
+
children: [
|
|
5865
|
+
previous ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5866
|
+
Link,
|
|
5867
|
+
{
|
|
5868
|
+
href: conceptPath(previous.slug),
|
|
5869
|
+
className: "group flex items-center gap-3 rounded-2xl border border-border bg-card p-4 text-card-foreground transition-colors hover:border-primary/40 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
5870
|
+
children: [
|
|
5871
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5872
|
+
lucideReact.ArrowLeft,
|
|
5873
|
+
{
|
|
5874
|
+
"aria-hidden": "true",
|
|
5875
|
+
className: "h-5 w-5 shrink-0 text-muted-foreground transition-colors group-hover:text-primary"
|
|
5876
|
+
}
|
|
5877
|
+
),
|
|
5878
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "min-w-0", children: [
|
|
5879
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "block text-xs font-medium uppercase tracking-wide text-muted-foreground", children: "Previous concept" }),
|
|
5880
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "block truncate font-semibold", children: previous.title })
|
|
5881
|
+
] })
|
|
5882
|
+
]
|
|
5883
|
+
}
|
|
5884
|
+
) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "hidden sm:block" }),
|
|
5885
|
+
next ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5886
|
+
Link,
|
|
5887
|
+
{
|
|
5888
|
+
href: conceptPath(next.slug),
|
|
5889
|
+
className: "group flex items-center justify-end gap-3 rounded-2xl border border-border bg-card p-4 text-right text-card-foreground transition-colors hover:border-primary/40 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
5890
|
+
children: [
|
|
5891
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "min-w-0", children: [
|
|
5892
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "block text-xs font-medium uppercase tracking-wide text-muted-foreground", children: "Next concept" }),
|
|
5893
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "block truncate font-semibold", children: next.title })
|
|
5894
|
+
] }),
|
|
5895
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5896
|
+
lucideReact.ArrowRight,
|
|
5897
|
+
{
|
|
5898
|
+
"aria-hidden": "true",
|
|
5899
|
+
className: "h-5 w-5 shrink-0 text-muted-foreground transition-colors group-hover:text-primary"
|
|
5900
|
+
}
|
|
5901
|
+
)
|
|
5902
|
+
]
|
|
5903
|
+
}
|
|
5904
|
+
) : null
|
|
5905
|
+
]
|
|
5906
|
+
}
|
|
5907
|
+
) : null,
|
|
5908
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-10", children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5909
|
+
Link,
|
|
5910
|
+
{
|
|
5911
|
+
href: CONCEPTS_PATH,
|
|
5912
|
+
className: "inline-flex items-center gap-2 rounded text-sm font-medium text-primary hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
5913
|
+
children: [
|
|
5914
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowLeft, { "aria-hidden": "true", className: "h-4 w-4" }),
|
|
5915
|
+
"All ",
|
|
5916
|
+
productName,
|
|
5917
|
+
" concepts"
|
|
5918
|
+
]
|
|
5919
|
+
}
|
|
5920
|
+
) })
|
|
5921
|
+
] }),
|
|
5922
|
+
cta ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
5923
|
+
"section",
|
|
5924
|
+
{
|
|
5925
|
+
"data-concepts": "cta",
|
|
5926
|
+
className: "border-t border-border bg-muted/30",
|
|
5927
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mx-auto flex max-w-6xl flex-wrap items-center gap-4 px-4 py-12 sm:px-6 lg:px-8", children: cta })
|
|
5928
|
+
}
|
|
5929
|
+
) : null,
|
|
5930
|
+
lightboxIndex !== null ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
5931
|
+
ConceptLightbox,
|
|
5932
|
+
{
|
|
5933
|
+
images: concept.images,
|
|
5934
|
+
index: lightboxIndex,
|
|
5935
|
+
conceptTitle: concept.title,
|
|
5936
|
+
onIndexChange: setLightboxIndex,
|
|
5937
|
+
onClose: closeLightbox
|
|
5938
|
+
}
|
|
5939
|
+
) : null
|
|
5940
|
+
]
|
|
5941
|
+
}
|
|
5942
|
+
);
|
|
5943
|
+
}
|
|
5944
|
+
|
|
5945
|
+
// src/components/explore-i18n.ts
|
|
5946
|
+
var EXPLORE_LOCALES = ["en", "zh", "hi", "es", "ar", "ta"];
|
|
5947
|
+
var RTL_LOCALES = /* @__PURE__ */ new Set(["ar"]);
|
|
5948
|
+
function isRtlLocale(locale) {
|
|
5949
|
+
return RTL_LOCALES.has(locale);
|
|
5950
|
+
}
|
|
5951
|
+
var EN = {
|
|
5952
|
+
badge: "AI answers, grounded in our documentation",
|
|
5953
|
+
welcomeTitle: "Ask anything about our products",
|
|
5954
|
+
welcomeBody: "Describe what you are trying to do and I will point you at the product, the page and the next step.",
|
|
5955
|
+
tryAsking: "Try asking",
|
|
5956
|
+
focusProduct: "Focus on a product",
|
|
5957
|
+
allProducts: "All products",
|
|
5958
|
+
showAll: "All",
|
|
5959
|
+
showLess: "Show less",
|
|
5960
|
+
sources: "Sources",
|
|
5961
|
+
nextYouCouldAsk: "Next you could ask",
|
|
5962
|
+
placeholder: "Ask anything about our products\u2026",
|
|
5963
|
+
placeholderProduct: "Ask about {product}\u2026",
|
|
5964
|
+
send: "Send",
|
|
5965
|
+
stop: "Stop",
|
|
5966
|
+
newChat: "New chat",
|
|
5967
|
+
history: "History",
|
|
5968
|
+
clearHistory: "Clear history",
|
|
5969
|
+
share: "Share",
|
|
5970
|
+
copied: "Copied",
|
|
5971
|
+
copying: "Copying\u2026",
|
|
5972
|
+
shareUnavailable: "Unavailable",
|
|
5973
|
+
disclaimer: "Disclaimer",
|
|
5974
|
+
disclaimerShort: "Grounded in our docs \u2014 check anything important.",
|
|
5975
|
+
dictate: "Dictate your question",
|
|
5976
|
+
stopDictating: "Stop dictating",
|
|
5977
|
+
attach: "Attach files",
|
|
5978
|
+
attachHint: "Up to {{max}} files, {{size}} MB each",
|
|
5979
|
+
removeAttachment: "Remove {{name}}",
|
|
5980
|
+
attachmentNameOnly: "name and type only",
|
|
5981
|
+
attachmentTooLarge: "{{name}} is larger than {{size}} MB and was not attached.",
|
|
5982
|
+
attachmentTooMany: "Only {{max}} files can be attached, so {{name}} was skipped.",
|
|
5983
|
+
noAnswer: "I couldn't find this in our documentation, so the answer below is not grounded in a source. Try rephrasing, or",
|
|
5984
|
+
answerDidNotArrive: "That answer didn't come through. Try asking again.",
|
|
5985
|
+
askHuman: "ask a human",
|
|
5986
|
+
prevSuggestion: "Previous suggestion",
|
|
5987
|
+
nextSuggestion: "Next suggestion",
|
|
5988
|
+
conceptIllustration: "Concept illustration",
|
|
5989
|
+
opensInNewTab: "opens in a new tab",
|
|
5990
|
+
capabilities: [
|
|
5991
|
+
"Grounded in our own docs",
|
|
5992
|
+
"Compare across the ecosystem",
|
|
5993
|
+
"Straight to the right page"
|
|
5994
|
+
],
|
|
5995
|
+
prompts: [
|
|
5996
|
+
"What does this product actually do?",
|
|
5997
|
+
"Which product fits my team?",
|
|
5998
|
+
"How do I get started, step by step?",
|
|
5999
|
+
"How much does it cost?"
|
|
6000
|
+
]
|
|
6001
|
+
};
|
|
6002
|
+
var ZH = {
|
|
6003
|
+
badge: "\u57FA\u4E8E\u6211\u4EEC\u6587\u6863\u7684 AI \u56DE\u7B54",
|
|
6004
|
+
welcomeTitle: "\u5173\u4E8E\u6211\u4EEC\u7684\u4EA7\u54C1\uFF0C\u968F\u4FBF\u95EE",
|
|
6005
|
+
welcomeBody: "\u63CF\u8FF0\u4F60\u60F3\u505A\u7684\u4E8B\uFF0C\u6211\u4F1A\u4E3A\u4F60\u6307\u51FA\u5BF9\u5E94\u7684\u4EA7\u54C1\u3001\u9875\u9762\u548C\u4E0B\u4E00\u6B65\u3002",
|
|
6006
|
+
tryAsking: "\u8BD5\u7740\u95EE",
|
|
6007
|
+
focusProduct: "\u805A\u7126\u67D0\u4E2A\u4EA7\u54C1",
|
|
6008
|
+
allProducts: "\u5168\u90E8\u4EA7\u54C1",
|
|
6009
|
+
showAll: "\u5168\u90E8",
|
|
6010
|
+
showLess: "\u6536\u8D77",
|
|
6011
|
+
sources: "\u6765\u6E90",
|
|
6012
|
+
nextYouCouldAsk: "\u4F60\u8FD8\u53EF\u4EE5\u95EE",
|
|
6013
|
+
placeholder: "\u5173\u4E8E\u6211\u4EEC\u7684\u4EA7\u54C1\uFF0C\u968F\u4FBF\u95EE\u2026",
|
|
6014
|
+
placeholderProduct: "\u8BE2\u95EE\u5173\u4E8E {product} \u7684\u95EE\u9898\u2026",
|
|
6015
|
+
send: "\u53D1\u9001",
|
|
6016
|
+
stop: "\u505C\u6B62",
|
|
6017
|
+
newChat: "\u65B0\u5BF9\u8BDD",
|
|
6018
|
+
history: "\u5386\u53F2",
|
|
6019
|
+
clearHistory: "\u6E05\u9664\u5386\u53F2",
|
|
6020
|
+
share: "\u5206\u4EAB",
|
|
6021
|
+
copied: "\u5DF2\u590D\u5236",
|
|
6022
|
+
copying: "\u590D\u5236\u4E2D\u2026",
|
|
6023
|
+
shareUnavailable: "\u4E0D\u53EF\u7528",
|
|
6024
|
+
disclaimer: "\u514D\u8D23\u58F0\u660E",
|
|
6025
|
+
disclaimerShort: "\u5185\u5BB9\u57FA\u4E8E\u6211\u4EEC\u7684\u6587\u6863\uFF0C\u91CD\u8981\u4FE1\u606F\u8BF7\u81EA\u884C\u6838\u5BF9\u3002",
|
|
6026
|
+
dictate: "\u8BED\u97F3\u8F93\u5165",
|
|
6027
|
+
stopDictating: "\u505C\u6B62\u8BED\u97F3\u8F93\u5165",
|
|
6028
|
+
attach: "\u6DFB\u52A0\u6587\u4EF6",
|
|
6029
|
+
attachHint: "\u6700\u591A {{max}} \u4E2A\u6587\u4EF6\uFF0C\u6BCF\u4E2A\u4E0D\u8D85\u8FC7 {{size}} MB",
|
|
6030
|
+
removeAttachment: "\u79FB\u9664 {{name}}",
|
|
6031
|
+
attachmentNameOnly: "\u4EC5\u6587\u4EF6\u540D\u548C\u7C7B\u578B",
|
|
6032
|
+
attachmentTooLarge: "{{name}} \u8D85\u8FC7 {{size}} MB\uFF0C\u672A\u80FD\u6DFB\u52A0\u3002",
|
|
6033
|
+
attachmentTooMany: "\u6700\u591A\u53EA\u80FD\u6DFB\u52A0 {{max}} \u4E2A\u6587\u4EF6\uFF0C\u5DF2\u8DF3\u8FC7 {{name}}\u3002",
|
|
6034
|
+
noAnswer: "\u6211\u5728\u6587\u6863\u4E2D\u6CA1\u6709\u627E\u5230\u76F8\u5173\u5185\u5BB9\uFF0C\u4E0B\u9762\u7684\u56DE\u7B54\u6CA1\u6709\u6765\u6E90\u652F\u6301\u3002\u8BF7\u6362\u4E2A\u8BF4\u6CD5\uFF0C\u6216",
|
|
6035
|
+
answerDidNotArrive: "\u8FD9\u6761\u56DE\u7B54\u6CA1\u6709\u8FD4\u56DE\u3002\u8BF7\u518D\u95EE\u4E00\u6B21\u3002",
|
|
6036
|
+
askHuman: "\u8054\u7CFB\u6211\u4EEC",
|
|
6037
|
+
prevSuggestion: "\u4E0A\u4E00\u4E2A\u5EFA\u8BAE",
|
|
6038
|
+
nextSuggestion: "\u4E0B\u4E00\u4E2A\u5EFA\u8BAE",
|
|
6039
|
+
conceptIllustration: "\u6982\u5FF5\u793A\u610F\u56FE",
|
|
6040
|
+
opensInNewTab: "\u5728\u65B0\u6807\u7B7E\u9875\u4E2D\u6253\u5F00",
|
|
6041
|
+
capabilities: ["\u57FA\u4E8E\u6211\u4EEC\u81EA\u5DF1\u7684\u6587\u6863", "\u8DE8\u4EA7\u54C1\u5BF9\u6BD4", "\u76F4\u8FBE\u6B63\u786E\u7684\u9875\u9762"],
|
|
6042
|
+
prompts: [
|
|
6043
|
+
"\u8FD9\u4E2A\u4EA7\u54C1\u5230\u5E95\u80FD\u505A\u4EC0\u4E48\uFF1F",
|
|
6044
|
+
"\u54EA\u4E2A\u4EA7\u54C1\u9002\u5408\u6211\u7684\u56E2\u961F\uFF1F",
|
|
6045
|
+
"\u5982\u4F55\u4E00\u6B65\u6B65\u5F00\u59CB\u4F7F\u7528\uFF1F",
|
|
6046
|
+
"\u4EF7\u683C\u662F\u591A\u5C11\uFF1F"
|
|
6047
|
+
]
|
|
6048
|
+
};
|
|
6049
|
+
var HI = {
|
|
6050
|
+
badge: "\u0939\u092E\u093E\u0930\u0947 \u0926\u0938\u094D\u0924\u093E\u0935\u0947\u091C\u093C\u094B\u0902 \u092A\u0930 \u0906\u0927\u093E\u0930\u093F\u0924 AI \u0909\u0924\u094D\u0924\u0930",
|
|
6051
|
+
welcomeTitle: "\u0939\u092E\u093E\u0930\u0947 \u0909\u0924\u094D\u092A\u093E\u0926\u094B\u0902 \u0915\u0947 \u092C\u093E\u0930\u0947 \u092E\u0947\u0902 \u0915\u0941\u091B \u092D\u0940 \u092A\u0942\u091B\u0947\u0902",
|
|
6052
|
+
welcomeBody: "\u092C\u0924\u093E\u0907\u090F \u0906\u092A \u0915\u094D\u092F\u093E \u0915\u0930\u0928\u093E \u091A\u093E\u0939\u0924\u0947 \u0939\u0948\u0902, \u0914\u0930 \u092E\u0948\u0902 \u0906\u092A\u0915\u094B \u0938\u0939\u0940 \u0909\u0924\u094D\u092A\u093E\u0926, \u092A\u0947\u091C \u0914\u0930 \u0905\u0917\u0932\u093E \u0915\u0926\u092E \u092C\u0924\u093E\u090A\u0901\u0917\u093E\u0964",
|
|
6053
|
+
tryAsking: "\u092F\u0939 \u092A\u0942\u091B\u0915\u0930 \u0926\u0947\u0916\u0947\u0902",
|
|
6054
|
+
focusProduct: "\u0915\u093F\u0938\u0940 \u0909\u0924\u094D\u092A\u093E\u0926 \u092A\u0930 \u0927\u094D\u092F\u093E\u0928 \u0926\u0947\u0902",
|
|
6055
|
+
allProducts: "\u0938\u092D\u0940 \u0909\u0924\u094D\u092A\u093E\u0926",
|
|
6056
|
+
showAll: "\u0938\u092D\u0940",
|
|
6057
|
+
showLess: "\u0915\u092E \u0926\u093F\u0916\u093E\u090F\u0901",
|
|
6058
|
+
sources: "\u0938\u094D\u0930\u094B\u0924",
|
|
6059
|
+
nextYouCouldAsk: "\u0906\u0917\u0947 \u0906\u092A \u092A\u0942\u091B \u0938\u0915\u0924\u0947 \u0939\u0948\u0902",
|
|
6060
|
+
placeholder: "\u0939\u092E\u093E\u0930\u0947 \u0909\u0924\u094D\u092A\u093E\u0926\u094B\u0902 \u0915\u0947 \u092C\u093E\u0930\u0947 \u092E\u0947\u0902 \u0915\u0941\u091B \u092D\u0940 \u092A\u0942\u091B\u0947\u0902\u2026",
|
|
6061
|
+
placeholderProduct: "{product} \u0915\u0947 \u092C\u093E\u0930\u0947 \u092E\u0947\u0902 \u092A\u0942\u091B\u0947\u0902\u2026",
|
|
6062
|
+
send: "\u092D\u0947\u091C\u0947\u0902",
|
|
6063
|
+
stop: "\u0930\u094B\u0915\u0947\u0902",
|
|
6064
|
+
newChat: "\u0928\u0908 \u092C\u093E\u0924\u091A\u0940\u0924",
|
|
6065
|
+
history: "\u0907\u0924\u093F\u0939\u093E\u0938",
|
|
6066
|
+
clearHistory: "\u0907\u0924\u093F\u0939\u093E\u0938 \u092E\u093F\u091F\u093E\u090F\u0901",
|
|
6067
|
+
share: "\u0938\u093E\u091D\u093E \u0915\u0930\u0947\u0902",
|
|
6068
|
+
copied: "\u0915\u0949\u092A\u0940 \u0939\u094B \u0917\u092F\u093E",
|
|
6069
|
+
copying: "\u0915\u0949\u092A\u0940 \u0939\u094B \u0930\u0939\u093E \u0939\u0948\u2026",
|
|
6070
|
+
shareUnavailable: "\u0909\u092A\u0932\u092C\u094D\u0927 \u0928\u0939\u0940\u0902",
|
|
6071
|
+
disclaimer: "\u0905\u0938\u094D\u0935\u0940\u0915\u0930\u0923",
|
|
6072
|
+
disclaimerShort: "\u092F\u0939 \u0939\u092E\u093E\u0930\u0947 \u0926\u0938\u094D\u0924\u093E\u0935\u0947\u091C\u093C\u094B\u0902 \u092A\u0930 \u0906\u0927\u093E\u0930\u093F\u0924 \u0939\u0948 \u2014 \u092E\u0939\u0924\u094D\u0935\u092A\u0942\u0930\u094D\u0923 \u092C\u093E\u0924\u0947\u0902 \u091C\u093C\u0930\u0942\u0930 \u091C\u093E\u0901\u091A \u0932\u0947\u0902\u0964",
|
|
6073
|
+
dictate: "\u092C\u094B\u0932\u0915\u0930 \u092A\u0942\u091B\u0947\u0902",
|
|
6074
|
+
stopDictating: "\u092C\u094B\u0932\u0928\u093E \u092C\u0902\u0926 \u0915\u0930\u0947\u0902",
|
|
6075
|
+
attach: "\u092B\u093C\u093E\u0907\u0932\u0947\u0902 \u091C\u094B\u0921\u093C\u0947\u0902",
|
|
6076
|
+
attachHint: "\u0905\u0927\u093F\u0915\u0924\u092E {{max}} \u092B\u093C\u093E\u0907\u0932\u0947\u0902, \u092A\u094D\u0930\u0924\u094D\u092F\u0947\u0915 {{size}} MB \u0924\u0915",
|
|
6077
|
+
removeAttachment: "{{name}} \u0939\u091F\u093E\u090F\u0901",
|
|
6078
|
+
attachmentNameOnly: "\u0915\u0947\u0935\u0932 \u0928\u093E\u092E \u0914\u0930 \u092A\u094D\u0930\u0915\u093E\u0930",
|
|
6079
|
+
attachmentTooLarge: "{{name}} {{size}} MB \u0938\u0947 \u092C\u0921\u093C\u0940 \u0939\u0948, \u0907\u0938\u0932\u093F\u090F \u091C\u094B\u0921\u093C\u0940 \u0928\u0939\u0940\u0902 \u0917\u0908\u0964",
|
|
6080
|
+
attachmentTooMany: "\u0915\u0947\u0935\u0932 {{max}} \u092B\u093C\u093E\u0907\u0932\u0947\u0902 \u091C\u094B\u0921\u093C\u0940 \u091C\u093E \u0938\u0915\u0924\u0940 \u0939\u0948\u0902, \u0907\u0938\u0932\u093F\u090F {{name}} \u091B\u094B\u0921\u093C \u0926\u0940 \u0917\u0908\u0964",
|
|
6081
|
+
noAnswer: "\u092F\u0939 \u092E\u0941\u091D\u0947 \u0939\u092E\u093E\u0930\u0947 \u0926\u0938\u094D\u0924\u093E\u0935\u0947\u091C\u093C\u094B\u0902 \u092E\u0947\u0902 \u0928\u0939\u0940\u0902 \u092E\u093F\u0932\u093E, \u0907\u0938\u0932\u093F\u090F \u0928\u0940\u091A\u0947 \u0926\u093F\u092F\u093E \u0909\u0924\u094D\u0924\u0930 \u0915\u093F\u0938\u0940 \u0938\u094D\u0930\u094B\u0924 \u092A\u0930 \u0906\u0927\u093E\u0930\u093F\u0924 \u0928\u0939\u0940\u0902 \u0939\u0948\u0964 \u0926\u0942\u0938\u0930\u0947 \u0936\u092C\u094D\u0926\u094B\u0902 \u092E\u0947\u0902 \u092A\u0942\u091B\u0947\u0902, \u092F\u093E",
|
|
6082
|
+
answerDidNotArrive: "\u0935\u0939 \u0909\u0924\u094D\u0924\u0930 \u0928\u0939\u0940\u0902 \u0906 \u0938\u0915\u093E\u0964 \u0915\u0943\u092A\u092F\u093E \u0926\u094B\u092C\u093E\u0930\u093E \u092A\u0942\u091B\u0947\u0902\u0964",
|
|
6083
|
+
askHuman: "\u0939\u092E\u0938\u0947 \u0938\u0902\u092A\u0930\u094D\u0915 \u0915\u0930\u0947\u0902",
|
|
6084
|
+
prevSuggestion: "\u092A\u093F\u091B\u0932\u093E \u0938\u0941\u091D\u093E\u0935",
|
|
6085
|
+
nextSuggestion: "\u0905\u0917\u0932\u093E \u0938\u0941\u091D\u093E\u0935",
|
|
6086
|
+
conceptIllustration: "\u0905\u0935\u0927\u093E\u0930\u0923\u093E \u091A\u093F\u0924\u094D\u0930\u0923",
|
|
6087
|
+
opensInNewTab: "\u0928\u090F \u091F\u0948\u092C \u092E\u0947\u0902 \u0916\u0941\u0932\u0924\u093E \u0939\u0948",
|
|
6088
|
+
capabilities: [
|
|
6089
|
+
"\u0939\u092E\u093E\u0930\u0947 \u0905\u092A\u0928\u0947 \u0926\u0938\u094D\u0924\u093E\u0935\u0947\u091C\u093C\u094B\u0902 \u092A\u0930 \u0906\u0927\u093E\u0930\u093F\u0924",
|
|
6090
|
+
"\u0938\u092D\u0940 \u0909\u0924\u094D\u092A\u093E\u0926\u094B\u0902 \u0915\u0940 \u0924\u0941\u0932\u0928\u093E \u0915\u0930\u0947\u0902",
|
|
6091
|
+
"\u0938\u0940\u0927\u0947 \u0938\u0939\u0940 \u092A\u0947\u091C \u092A\u0930"
|
|
6092
|
+
],
|
|
6093
|
+
prompts: [
|
|
6094
|
+
"\u092F\u0939 \u0909\u0924\u094D\u092A\u093E\u0926 \u0905\u0938\u0932 \u092E\u0947\u0902 \u0915\u094D\u092F\u093E \u0915\u0930\u0924\u093E \u0939\u0948?",
|
|
6095
|
+
"\u092E\u0947\u0930\u0940 \u091F\u0940\u092E \u0915\u0947 \u0932\u093F\u090F \u0915\u094C\u0928 \u0938\u093E \u0909\u0924\u094D\u092A\u093E\u0926 \u0938\u0939\u0940 \u0939\u0948?",
|
|
6096
|
+
"\u0936\u0941\u0930\u0941\u0906\u0924 \u0915\u0948\u0938\u0947 \u0915\u0930\u0947\u0902, \u091A\u0930\u0923 \u0926\u0930 \u091A\u0930\u0923?",
|
|
6097
|
+
"\u0907\u0938\u0915\u0940 \u0915\u0940\u092E\u0924 \u0915\u093F\u0924\u0928\u0940 \u0939\u0948?"
|
|
6098
|
+
]
|
|
6099
|
+
};
|
|
6100
|
+
var ES = {
|
|
6101
|
+
badge: "Respuestas de IA basadas en nuestra documentaci\xF3n",
|
|
6102
|
+
welcomeTitle: "Pregunta lo que quieras sobre nuestros productos",
|
|
6103
|
+
welcomeBody: "Cu\xE9ntame qu\xE9 necesitas hacer y te indicar\xE9 el producto, la p\xE1gina y el siguiente paso.",
|
|
6104
|
+
tryAsking: "Prueba a preguntar",
|
|
6105
|
+
focusProduct: "Centrarse en un producto",
|
|
6106
|
+
allProducts: "Todos los productos",
|
|
6107
|
+
showAll: "Todos",
|
|
6108
|
+
showLess: "Ver menos",
|
|
6109
|
+
sources: "Fuentes",
|
|
6110
|
+
nextYouCouldAsk: "Tambi\xE9n puedes preguntar",
|
|
6111
|
+
placeholder: "Pregunta lo que quieras sobre nuestros productos\u2026",
|
|
6112
|
+
placeholderProduct: "Pregunta sobre {product}\u2026",
|
|
6113
|
+
send: "Enviar",
|
|
6114
|
+
stop: "Detener",
|
|
6115
|
+
newChat: "Nueva conversaci\xF3n",
|
|
4934
6116
|
history: "Historial",
|
|
4935
6117
|
clearHistory: "Borrar historial",
|
|
4936
6118
|
share: "Compartir",
|
|
@@ -4952,6 +6134,8 @@ var ES = {
|
|
|
4952
6134
|
askHuman: "habla con una persona",
|
|
4953
6135
|
prevSuggestion: "Sugerencia anterior",
|
|
4954
6136
|
nextSuggestion: "Sugerencia siguiente",
|
|
6137
|
+
conceptIllustration: "Ilustraci\xF3n del concepto",
|
|
6138
|
+
opensInNewTab: "se abre en una pesta\xF1a nueva",
|
|
4955
6139
|
capabilities: [
|
|
4956
6140
|
"Basado en nuestra documentaci\xF3n",
|
|
4957
6141
|
"Compara todo el ecosistema",
|
|
@@ -5001,6 +6185,8 @@ var AR = {
|
|
|
5001
6185
|
askHuman: "\u062A\u062D\u062F\u0651\u062B \u0625\u0644\u0649 \u0634\u062E\u0635",
|
|
5002
6186
|
prevSuggestion: "\u0627\u0644\u0627\u0642\u062A\u0631\u0627\u062D \u0627\u0644\u0633\u0627\u0628\u0642",
|
|
5003
6187
|
nextSuggestion: "\u0627\u0644\u0627\u0642\u062A\u0631\u0627\u062D \u0627\u0644\u062A\u0627\u0644\u064A",
|
|
6188
|
+
conceptIllustration: "\u0631\u0633\u0645 \u062A\u0648\u0636\u064A\u062D\u064A \u0644\u0644\u0645\u0641\u0647\u0648\u0645",
|
|
6189
|
+
opensInNewTab: "\u064A\u064F\u0641\u062A\u062D \u0641\u064A \u0639\u0644\u0627\u0645\u0629 \u062A\u0628\u0648\u064A\u0628 \u062C\u062F\u064A\u062F\u0629",
|
|
5004
6190
|
capabilities: [
|
|
5005
6191
|
"\u0645\u0628\u0646\u064A \u0639\u0644\u0649 \u0648\u062B\u0627\u0626\u0642\u0646\u0627",
|
|
5006
6192
|
"\u0642\u0627\u0631\u0646 \u0639\u0628\u0631 \u0627\u0644\u0645\u0646\u0638\u0648\u0645\u0629",
|
|
@@ -5050,6 +6236,8 @@ var TA = {
|
|
|
5050
6236
|
askHuman: "\u0B8E\u0B99\u0BCD\u0B95\u0BB3\u0BC8\u0BA4\u0BCD \u0BA4\u0BCA\u0B9F\u0BB0\u0BCD\u0BAA\u0BC1 \u0B95\u0BCA\u0BB3\u0BCD\u0BB3\u0BC1\u0B99\u0BCD\u0B95\u0BB3\u0BCD",
|
|
5051
6237
|
prevSuggestion: "\u0BAE\u0BC1\u0BA8\u0BCD\u0BA4\u0BC8\u0BAF \u0BAA\u0BB0\u0BBF\u0BA8\u0BCD\u0BA4\u0BC1\u0BB0\u0BC8",
|
|
5052
6238
|
nextSuggestion: "\u0B85\u0B9F\u0BC1\u0BA4\u0BCD\u0BA4 \u0BAA\u0BB0\u0BBF\u0BA8\u0BCD\u0BA4\u0BC1\u0BB0\u0BC8",
|
|
6239
|
+
conceptIllustration: "\u0B95\u0BB0\u0BC1\u0BA4\u0BCD\u0BA4\u0BC1 \u0BB5\u0BBF\u0BB3\u0B95\u0BCD\u0B95\u0BAA\u0BCD\u0BAA\u0B9F\u0BAE\u0BCD",
|
|
6240
|
+
opensInNewTab: "\u0BAA\u0BC1\u0BA4\u0BBF\u0BAF \u0BA4\u0BBE\u0BB5\u0BB2\u0BBF\u0BB2\u0BCD \u0BA4\u0BBF\u0BB1\u0B95\u0BCD\u0B95\u0BC1\u0BAE\u0BCD",
|
|
5053
6241
|
capabilities: [
|
|
5054
6242
|
"\u0B8E\u0B99\u0BCD\u0B95\u0BB3\u0BCD \u0B9A\u0BCA\u0BA8\u0BCD\u0BA4 \u0B86\u0BB5\u0BA3\u0B99\u0BCD\u0B95\u0BB3\u0BBF\u0BA9\u0BCD \u0B85\u0B9F\u0BBF\u0BAA\u0BCD\u0BAA\u0B9F\u0BC8\u0BAF\u0BBF\u0BB2\u0BCD",
|
|
5055
6243
|
"\u0BA4\u0BAF\u0BBE\u0BB0\u0BBF\u0BAA\u0BCD\u0BAA\u0BC1\u0B95\u0BB3\u0BC8 \u0B92\u0BAA\u0BCD\u0BAA\u0BBF\u0B9F\u0BC1\u0B99\u0BCD\u0B95\u0BB3\u0BCD",
|
|
@@ -5408,10 +6596,13 @@ var ECOSYSTEM_PRODUCTS = [
|
|
|
5408
6596
|
name: "VibeControls",
|
|
5409
6597
|
websiteUrl: "https://vibecontrols.com"
|
|
5410
6598
|
},
|
|
6599
|
+
// FluidGrids ships on www.fluidgrids.ai — fluidgrids.com only redirects there. The explore
|
|
6600
|
+
// catalog and the site's own sitemap use this origin, and so must the fallback catalog
|
|
6601
|
+
// built from this list, or /explore rejects FluidGrids concept images until it loads.
|
|
5411
6602
|
{
|
|
5412
6603
|
slug: "fluidgrids",
|
|
5413
6604
|
name: "FluidGrids",
|
|
5414
|
-
websiteUrl: "https://fluidgrids.
|
|
6605
|
+
websiteUrl: "https://www.fluidgrids.ai"
|
|
5415
6606
|
},
|
|
5416
6607
|
// Botlit ships on botlit.ai — botlit.com does not resolve.
|
|
5417
6608
|
{ slug: "botlit", name: "Botlit", websiteUrl: "https://www.botlit.ai" },
|
|
@@ -7048,6 +8239,93 @@ function logoUrlOf(url) {
|
|
|
7048
8239
|
return null;
|
|
7049
8240
|
}
|
|
7050
8241
|
}
|
|
8242
|
+
function inlineImageOrigins(products) {
|
|
8243
|
+
const origins = /* @__PURE__ */ new Set();
|
|
8244
|
+
for (const product of products) {
|
|
8245
|
+
let url;
|
|
8246
|
+
try {
|
|
8247
|
+
url = new URL(product.website);
|
|
8248
|
+
} catch {
|
|
8249
|
+
continue;
|
|
8250
|
+
}
|
|
8251
|
+
if (url.protocol !== "https:") continue;
|
|
8252
|
+
const apex = url.hostname.replace(/^www\./, "");
|
|
8253
|
+
const port = url.port ? `:${url.port}` : "";
|
|
8254
|
+
origins.add(`https://${apex}${port}`);
|
|
8255
|
+
origins.add(`https://www.${apex}${port}`);
|
|
8256
|
+
}
|
|
8257
|
+
return origins;
|
|
8258
|
+
}
|
|
8259
|
+
function isInlineImageAllowed(src, origins) {
|
|
8260
|
+
if (typeof src !== "string" || src === "") return false;
|
|
8261
|
+
let url;
|
|
8262
|
+
try {
|
|
8263
|
+
url = new URL(src);
|
|
8264
|
+
} catch {
|
|
8265
|
+
return false;
|
|
8266
|
+
}
|
|
8267
|
+
if (url.protocol !== "https:" || url.username || url.password) return false;
|
|
8268
|
+
return origins.has(url.origin);
|
|
8269
|
+
}
|
|
8270
|
+
var InlineImageScopeContext = React.createContext(null);
|
|
8271
|
+
var InsideLinkContext = React.createContext(false);
|
|
8272
|
+
function AnswerLink(props) {
|
|
8273
|
+
return /* @__PURE__ */ jsxRuntime.jsx(InsideLinkContext.Provider, { value: true, children: /* @__PURE__ */ jsxRuntime.jsx(MarkdownLink, { ...props }) });
|
|
8274
|
+
}
|
|
8275
|
+
var INLINE_IMAGE_FRAME = "relative inline-block max-w-full overflow-hidden rounded-xl border border-border bg-muted align-top shadow-sm";
|
|
8276
|
+
function InlineConceptImage({ src, alt }) {
|
|
8277
|
+
const scope = React.useContext(InlineImageScopeContext);
|
|
8278
|
+
const insideLink = React.useContext(InsideLinkContext);
|
|
8279
|
+
if (!scope || !scope.enabled || !isInlineImageAllowed(src, scope.origins) || scope.failed.has(src)) {
|
|
8280
|
+
return null;
|
|
8281
|
+
}
|
|
8282
|
+
const { strings: T, onFailed } = scope;
|
|
8283
|
+
const picture = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
8284
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
8285
|
+
"img",
|
|
8286
|
+
{
|
|
8287
|
+
src,
|
|
8288
|
+
alt: alt ?? "",
|
|
8289
|
+
loading: "lazy",
|
|
8290
|
+
decoding: "async",
|
|
8291
|
+
onError: () => onFailed(src),
|
|
8292
|
+
className: "block h-auto max-h-80 w-auto max-w-full object-contain"
|
|
8293
|
+
}
|
|
8294
|
+
),
|
|
8295
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
8296
|
+
"span",
|
|
8297
|
+
{
|
|
8298
|
+
"aria-hidden": "true",
|
|
8299
|
+
className: "pointer-events-none absolute left-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",
|
|
8300
|
+
children: T.conceptIllustration
|
|
8301
|
+
}
|
|
8302
|
+
)
|
|
8303
|
+
] });
|
|
8304
|
+
return /* @__PURE__ */ jsxRuntime.jsx("span", { "data-boff-explore": "inline-image", className: "my-3 block", children: insideLink ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: INLINE_IMAGE_FRAME, children: picture }) : /* @__PURE__ */ jsxRuntime.jsxs(
|
|
8305
|
+
"a",
|
|
8306
|
+
{
|
|
8307
|
+
href: src,
|
|
8308
|
+
target: "_blank",
|
|
8309
|
+
rel: "noopener noreferrer",
|
|
8310
|
+
className: cn(
|
|
8311
|
+
INLINE_IMAGE_FRAME,
|
|
8312
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
|
|
8313
|
+
),
|
|
8314
|
+
children: [
|
|
8315
|
+
picture,
|
|
8316
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "sr-only", children: [
|
|
8317
|
+
"(",
|
|
8318
|
+
T.opensInNewTab,
|
|
8319
|
+
")"
|
|
8320
|
+
] })
|
|
8321
|
+
]
|
|
8322
|
+
}
|
|
8323
|
+
) });
|
|
8324
|
+
}
|
|
8325
|
+
var ANSWER_MARKDOWN_COMPONENTS = {
|
|
8326
|
+
a: AnswerLink,
|
|
8327
|
+
img: InlineConceptImage
|
|
8328
|
+
};
|
|
7051
8329
|
function ReferenceCard({
|
|
7052
8330
|
reference,
|
|
7053
8331
|
onFollow
|
|
@@ -7230,6 +8508,7 @@ function AssistantBubble({
|
|
|
7230
8508
|
strings: T,
|
|
7231
8509
|
message,
|
|
7232
8510
|
activity,
|
|
8511
|
+
imageOrigins,
|
|
7233
8512
|
onNavigate,
|
|
7234
8513
|
anchorRef,
|
|
7235
8514
|
onFollow,
|
|
@@ -7238,6 +8517,25 @@ function AssistantBubble({
|
|
|
7238
8517
|
const streaming = message.status === "PENDING" || message.status === "RUNNING";
|
|
7239
8518
|
const body = message.content || message.partialContent || "";
|
|
7240
8519
|
const failed = message.status === "FAILED";
|
|
8520
|
+
const completed = message.status === "COMPLETED";
|
|
8521
|
+
const [failedImages, setFailedImages] = React.useState(
|
|
8522
|
+
() => /* @__PURE__ */ new Set()
|
|
8523
|
+
);
|
|
8524
|
+
const markImageFailed = React.useCallback((src) => {
|
|
8525
|
+
setFailedImages(
|
|
8526
|
+
(current) => current.has(src) ? current : new Set(current).add(src)
|
|
8527
|
+
);
|
|
8528
|
+
}, []);
|
|
8529
|
+
const imageScope = React.useMemo(
|
|
8530
|
+
() => ({
|
|
8531
|
+
strings: T,
|
|
8532
|
+
enabled: completed,
|
|
8533
|
+
origins: imageOrigins,
|
|
8534
|
+
failed: failedImages,
|
|
8535
|
+
onFailed: markImageFailed
|
|
8536
|
+
}),
|
|
8537
|
+
[T, completed, imageOrigins, failedImages, markImageFailed]
|
|
8538
|
+
);
|
|
7241
8539
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
7242
8540
|
"div",
|
|
7243
8541
|
{
|
|
@@ -7284,7 +8582,7 @@ function AssistantBubble({
|
|
|
7284
8582
|
}
|
|
7285
8583
|
) : null,
|
|
7286
8584
|
body ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-2xl rounded-tl-md border border-border bg-card px-4 py-3 shadow-sm", children: [
|
|
7287
|
-
/* @__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 }) }),
|
|
8585
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "boff-prose boff-prose-sm boff-explore-body min-w-0 text-card-foreground", children: /* @__PURE__ */ jsxRuntime.jsx(InlineImageScopeContext.Provider, { value: imageScope, children: /* @__PURE__ */ jsxRuntime.jsx(Markdown, { components: ANSWER_MARKDOWN_COMPONENTS, children: body }) }) }),
|
|
7288
8586
|
streaming ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "boff-explore-caret", "aria-hidden": "true" }) : null
|
|
7289
8587
|
] }) : null,
|
|
7290
8588
|
streaming ? /* @__PURE__ */ jsxRuntime.jsx(ThinkingIndicator, { activity }) : null,
|
|
@@ -7783,6 +9081,10 @@ function ExplorePage({
|
|
|
7783
9081
|
() => catalog.products.find((p) => p.slug === focusProduct)?.name ?? null,
|
|
7784
9082
|
[catalog.products, focusProduct]
|
|
7785
9083
|
);
|
|
9084
|
+
const imageOrigins = React.useMemo(
|
|
9085
|
+
() => inlineImageOrigins(catalog.products),
|
|
9086
|
+
[catalog.products]
|
|
9087
|
+
);
|
|
7786
9088
|
React.useEffect(() => {
|
|
7787
9089
|
const el = textareaRef.current;
|
|
7788
9090
|
if (!el) return;
|
|
@@ -8113,6 +9415,7 @@ function ExplorePage({
|
|
|
8113
9415
|
strings: T,
|
|
8114
9416
|
message,
|
|
8115
9417
|
activity,
|
|
9418
|
+
imageOrigins,
|
|
8116
9419
|
onNavigate,
|
|
8117
9420
|
anchorRef: message.id === latestAssistantId ? latestAssistantRef : void 0,
|
|
8118
9421
|
onFollow: (kind, url) => recordClick(message.id, kind, url),
|
|
@@ -13068,11 +14371,16 @@ function StoreProductDetailPage({
|
|
|
13068
14371
|
exports.BlogListPage = BlogListPage;
|
|
13069
14372
|
exports.BlogPostPage = BlogPostPage;
|
|
13070
14373
|
exports.Button = Button;
|
|
14374
|
+
exports.CONCEPTS_PATH = CONCEPTS_PATH;
|
|
14375
|
+
exports.CONCEPT_ILLUSTRATION_NOTICE = CONCEPT_ILLUSTRATION_NOTICE;
|
|
14376
|
+
exports.CONCEPT_PATH_PREFIX = CONCEPT_PATH_PREFIX;
|
|
13071
14377
|
exports.CareersApplyForm = CareersApplyForm;
|
|
13072
14378
|
exports.CareersSubmissionForm = CareersSubmissionForm;
|
|
13073
14379
|
exports.CaseStudiesListPage = CaseStudiesListPage;
|
|
13074
14380
|
exports.CaseStudyPage = CaseStudyPage;
|
|
13075
14381
|
exports.ChangelogPage = ChangelogPage;
|
|
14382
|
+
exports.ConceptDetailPage = ConceptDetailPage;
|
|
14383
|
+
exports.ConceptsPage = ConceptsPage;
|
|
13076
14384
|
exports.ContactPage = ContactPage;
|
|
13077
14385
|
exports.ContentRenderer = ContentRenderer;
|
|
13078
14386
|
exports.ContractsPage = ContractsPage;
|
|
@@ -13121,12 +14429,14 @@ exports.WebsiteSwitcher = WebsiteSwitcher;
|
|
|
13121
14429
|
exports.buttonVariants = buttonVariants;
|
|
13122
14430
|
exports.classifyExploreError = classifyExploreError;
|
|
13123
14431
|
exports.cn = cn;
|
|
14432
|
+
exports.conceptPath = conceptPath;
|
|
13124
14433
|
exports.detectElectronPlatform = detectElectronPlatform;
|
|
13125
14434
|
exports.fetchPublicJobPosting = fetchPublicJobPosting;
|
|
13126
14435
|
exports.fetchPublicJobPostings = fetchPublicJobPostings;
|
|
13127
14436
|
exports.fetchPublicJobPostingsForSubmission = fetchPublicJobPostingsForSubmission;
|
|
13128
14437
|
exports.formatDownloads = formatDownloads;
|
|
13129
14438
|
exports.formatPrice = formatPrice2;
|
|
14439
|
+
exports.getConceptBySlug = getConceptBySlug;
|
|
13130
14440
|
exports.getRecaptchaV3Token = getRecaptchaV3Token;
|
|
13131
14441
|
exports.isValidUrl = isValidUrl;
|
|
13132
14442
|
exports.loadRecaptchaV3 = loadRecaptchaV3;
|