@burdenoff/website-sdk 2026.1031.3 → 2026.1101.2
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 +42 -8
- package/dist/analytics/index.js +19 -69
- package/dist/analytics/index.js.map +1 -1
- package/dist/analytics/index.mjs +3 -69
- package/dist/analytics/index.mjs.map +1 -1
- package/dist/avatar-live/index.js +1 -0
- package/dist/avatar-live/index.js.map +1 -1
- package/dist/avatar-live/index.mjs +1 -0
- package/dist/avatar-live/index.mjs.map +1 -1
- package/dist/avatar-live-view/index.js +10 -30
- package/dist/avatar-live-view/index.js.map +1 -1
- package/dist/avatar-live-view/index.mjs +4 -24
- package/dist/avatar-live-view/index.mjs.map +1 -1
- package/dist/chunk-23H4JUL4.js +41 -0
- package/dist/chunk-23H4JUL4.js.map +1 -0
- package/dist/chunk-34RX5P75.mjs +25 -0
- package/dist/chunk-34RX5P75.mjs.map +1 -0
- package/dist/chunk-3LFFY7AZ.js +184 -0
- package/dist/chunk-3LFFY7AZ.js.map +1 -0
- package/dist/chunk-3X26GE4S.js +2794 -0
- package/dist/chunk-3X26GE4S.js.map +1 -0
- package/dist/chunk-45GCA4GG.js +85 -0
- package/dist/chunk-45GCA4GG.js.map +1 -0
- package/dist/chunk-4SAGVLHN.js +876 -0
- package/dist/chunk-4SAGVLHN.js.map +1 -0
- package/dist/chunk-4U6YAII5.js +218 -0
- package/dist/chunk-4U6YAII5.js.map +1 -0
- package/dist/chunk-5GMTBOO6.js +21 -0
- package/dist/chunk-5GMTBOO6.js.map +1 -0
- package/dist/chunk-5JRJ57CL.mjs +329 -0
- package/dist/chunk-5JRJ57CL.mjs.map +1 -0
- package/dist/chunk-6C2DKIC7.js +4 -0
- package/dist/chunk-6C2DKIC7.js.map +1 -0
- package/dist/chunk-6IBFBWC5.mjs +17 -0
- package/dist/chunk-6IBFBWC5.mjs.map +1 -0
- package/dist/chunk-6KY2ZRVI.js +116 -0
- package/dist/chunk-6KY2ZRVI.js.map +1 -0
- package/dist/chunk-6VJT3SM4.mjs +182 -0
- package/dist/chunk-6VJT3SM4.mjs.map +1 -0
- package/dist/chunk-6YZUFMK2.mjs +40 -0
- package/dist/chunk-6YZUFMK2.mjs.map +1 -0
- package/dist/chunk-7A6R7CGG.js +47 -0
- package/dist/chunk-7A6R7CGG.js.map +1 -0
- package/dist/chunk-7PWL4V2R.js +4 -0
- package/dist/chunk-7PWL4V2R.js.map +1 -0
- package/dist/chunk-AA33WDYS.js +161 -0
- package/dist/chunk-AA33WDYS.js.map +1 -0
- package/dist/chunk-AHRGFXV2.js +525 -0
- package/dist/chunk-AHRGFXV2.js.map +1 -0
- package/dist/chunk-B63XLDZH.mjs +109 -0
- package/dist/chunk-B63XLDZH.mjs.map +1 -0
- package/dist/chunk-BX2USEWF.mjs +35 -0
- package/dist/chunk-BX2USEWF.mjs.map +1 -0
- package/dist/chunk-BYSZT35R.js +150 -0
- package/dist/chunk-BYSZT35R.js.map +1 -0
- package/dist/chunk-C6OJIHNO.js +12 -0
- package/dist/chunk-C6OJIHNO.js.map +1 -0
- package/dist/chunk-COOELBX7.mjs +63 -0
- package/dist/chunk-COOELBX7.mjs.map +1 -0
- package/dist/chunk-D2TW7MNC.mjs +2771 -0
- package/dist/chunk-D2TW7MNC.mjs.map +1 -0
- package/dist/chunk-D5KEZ6V6.mjs +3 -0
- package/dist/chunk-D5KEZ6V6.mjs.map +1 -0
- package/dist/chunk-E3GUGJMY.js +46 -0
- package/dist/chunk-E3GUGJMY.js.map +1 -0
- package/dist/chunk-EBZ2HGJ2.mjs +52 -0
- package/dist/chunk-EBZ2HGJ2.mjs.map +1 -0
- package/dist/chunk-EDLTUOIA.mjs +210 -0
- package/dist/chunk-EDLTUOIA.mjs.map +1 -0
- package/dist/chunk-EJQSOT4X.js +4 -0
- package/dist/chunk-EJQSOT4X.js.map +1 -0
- package/dist/chunk-EUPFS6MZ.mjs +2019 -0
- package/dist/chunk-EUPFS6MZ.mjs.map +1 -0
- package/dist/chunk-F3XWDC3B.js +77 -0
- package/dist/chunk-F3XWDC3B.js.map +1 -0
- package/dist/chunk-FFADMVIK.mjs +5127 -0
- package/dist/chunk-FFADMVIK.mjs.map +1 -0
- package/dist/chunk-FJWS7BKT.mjs +3 -0
- package/dist/chunk-FJWS7BKT.mjs.map +1 -0
- package/dist/chunk-FJZJDUOR.mjs +3 -0
- package/dist/chunk-FJZJDUOR.mjs.map +1 -0
- package/dist/chunk-GCFLCO2Z.mjs +145 -0
- package/dist/chunk-GCFLCO2Z.mjs.map +1 -0
- package/dist/chunk-GEXC4LRP.js +61 -0
- package/dist/chunk-GEXC4LRP.js.map +1 -0
- package/dist/chunk-GTRAXQGC.mjs +3 -0
- package/dist/chunk-GTRAXQGC.mjs.map +1 -0
- package/dist/chunk-IKOIRUKW.js +270 -0
- package/dist/chunk-IKOIRUKW.js.map +1 -0
- package/dist/chunk-IXTWOPRN.js +45 -0
- package/dist/chunk-IXTWOPRN.js.map +1 -0
- package/dist/chunk-JDXOXGOK.js +547 -0
- package/dist/chunk-JDXOXGOK.js.map +1 -0
- package/dist/chunk-JSLDWYV7.mjs +558 -0
- package/dist/chunk-JSLDWYV7.mjs.map +1 -0
- package/dist/chunk-JXLSTVBK.js +336 -0
- package/dist/chunk-JXLSTVBK.js.map +1 -0
- package/dist/chunk-KHYXK7FG.mjs +49 -0
- package/dist/chunk-KHYXK7FG.mjs.map +1 -0
- package/dist/chunk-KSMBOWQQ.js +2034 -0
- package/dist/chunk-KSMBOWQQ.js.map +1 -0
- package/dist/chunk-KU2PXHGB.mjs +83 -0
- package/dist/chunk-KU2PXHGB.mjs.map +1 -0
- package/dist/chunk-KZANIV3S.mjs +37 -0
- package/dist/chunk-KZANIV3S.mjs.map +1 -0
- package/dist/chunk-L4BP6YOB.js +20 -0
- package/dist/chunk-L4BP6YOB.js.map +1 -0
- package/dist/chunk-MRKA2OAF.mjs +75 -0
- package/dist/chunk-MRKA2OAF.mjs.map +1 -0
- package/dist/chunk-N5EC53MH.mjs +80 -0
- package/dist/chunk-N5EC53MH.mjs.map +1 -0
- package/dist/chunk-NZANQGDM.mjs +34 -0
- package/dist/chunk-NZANQGDM.mjs.map +1 -0
- package/dist/chunk-O4GS3XPZ.js +10 -0
- package/dist/chunk-O4GS3XPZ.js.map +1 -0
- package/dist/chunk-O76QDGRM.js +5154 -0
- package/dist/chunk-O76QDGRM.js.map +1 -0
- package/dist/chunk-OYEUNZJY.js +114 -0
- package/dist/chunk-OYEUNZJY.js.map +1 -0
- package/dist/chunk-PHXAGQNB.js +74 -0
- package/dist/chunk-PHXAGQNB.js.map +1 -0
- package/dist/chunk-PIHHPP7J.mjs +16 -0
- package/dist/chunk-PIHHPP7J.mjs.map +1 -0
- package/dist/chunk-PXRHVVOU.mjs +499 -0
- package/dist/chunk-PXRHVVOU.mjs.map +1 -0
- package/dist/chunk-QMA6U6AU.js +36 -0
- package/dist/chunk-QMA6U6AU.js.map +1 -0
- package/dist/chunk-R6J7IULF.js +44 -0
- package/dist/chunk-R6J7IULF.js.map +1 -0
- package/dist/chunk-R7G6TWIS.mjs +10 -0
- package/dist/chunk-R7G6TWIS.mjs.map +1 -0
- package/dist/chunk-RUMGFI6L.mjs +544 -0
- package/dist/chunk-RUMGFI6L.mjs.map +1 -0
- package/dist/chunk-S54JWSJF.js +565 -0
- package/dist/chunk-S54JWSJF.js.map +1 -0
- package/dist/chunk-SK5UGG6A.js +2041 -0
- package/dist/chunk-SK5UGG6A.js.map +1 -0
- package/dist/chunk-SKIYDKIS.mjs +70 -0
- package/dist/chunk-SKIYDKIS.mjs.map +1 -0
- package/dist/chunk-SZNS5IK6.mjs +322 -0
- package/dist/chunk-SZNS5IK6.mjs.map +1 -0
- package/dist/chunk-T7JIPZAC.js +66 -0
- package/dist/chunk-T7JIPZAC.js.map +1 -0
- package/dist/chunk-TGYQHO2E.mjs +864 -0
- package/dist/chunk-TGYQHO2E.mjs.map +1 -0
- package/dist/chunk-TT3MHN42.mjs +8 -0
- package/dist/chunk-TT3MHN42.mjs.map +1 -0
- package/dist/chunk-UM55U65W.mjs +268 -0
- package/dist/chunk-UM55U65W.mjs.map +1 -0
- package/dist/chunk-UQ2HALUD.js +72 -0
- package/dist/chunk-UQ2HALUD.js.map +1 -0
- package/dist/chunk-UXWT7G77.js +82 -0
- package/dist/chunk-UXWT7G77.js.map +1 -0
- package/dist/chunk-VNS5WDWO.mjs +7 -0
- package/dist/chunk-VNS5WDWO.mjs.map +1 -0
- package/dist/chunk-VRWZLGR7.js +4 -0
- package/dist/chunk-VRWZLGR7.js.map +1 -0
- package/dist/chunk-VZLDSNH4.mjs +22 -0
- package/dist/chunk-VZLDSNH4.mjs.map +1 -0
- package/dist/chunk-W6P3YETJ.js +92 -0
- package/dist/chunk-W6P3YETJ.js.map +1 -0
- package/dist/chunk-WPKFFQCR.mjs +90 -0
- package/dist/chunk-WPKFFQCR.mjs.map +1 -0
- package/dist/chunk-WTVTI5TO.mjs +22 -0
- package/dist/chunk-WTVTI5TO.mjs.map +1 -0
- package/dist/chunk-XJOBZ4RJ.js +44 -0
- package/dist/chunk-XJOBZ4RJ.js.map +1 -0
- package/dist/chunk-XP2JDNDU.js +325 -0
- package/dist/chunk-XP2JDNDU.js.map +1 -0
- package/dist/chunk-Y4V5CEWD.mjs +112 -0
- package/dist/chunk-Y4V5CEWD.mjs.map +1 -0
- package/dist/chunk-YERN2UWM.js +116 -0
- package/dist/chunk-YERN2UWM.js.map +1 -0
- package/dist/chunk-ZKJQWFAA.mjs +114 -0
- package/dist/chunk-ZKJQWFAA.mjs.map +1 -0
- package/dist/chunk-ZOON3S3Y.mjs +138 -0
- package/dist/chunk-ZOON3S3Y.mjs.map +1 -0
- package/dist/chunk-ZP6QRAYC.mjs +2024 -0
- package/dist/chunk-ZP6QRAYC.mjs.map +1 -0
- package/dist/chunk-ZSTFX7FV.js +9 -0
- package/dist/chunk-ZSTFX7FV.js.map +1 -0
- package/dist/client/index.js +23 -331
- package/dist/client/index.js.map +1 -1
- package/dist/client/index.mjs +3 -330
- package/dist/client/index.mjs.map +1 -1
- package/dist/comparison/index.js +28 -111
- package/dist/comparison/index.js.map +1 -1
- package/dist/comparison/index.mjs +2 -107
- package/dist/comparison/index.mjs.map +1 -1
- package/dist/components/contact.js +21 -931
- package/dist/components/contact.js.map +1 -1
- package/dist/components/contact.mjs +12 -909
- package/dist/components/contact.mjs.map +1 -1
- package/dist/components/electron-download.js +12 -124
- package/dist/components/electron-download.js.map +1 -1
- package/dist/components/electron-download.mjs +4 -106
- package/dist/components/electron-download.mjs.map +1 -1
- package/dist/components/explore-cta.js +8 -112
- package/dist/components/explore-cta.js.map +1 -1
- package/dist/components/explore-cta.mjs +3 -114
- package/dist/components/explore-cta.mjs.map +1 -1
- package/dist/components/explore.js +62 -7833
- package/dist/components/explore.js.map +1 -1
- package/dist/components/explore.mjs +13 -7800
- package/dist/components/explore.mjs.map +1 -1
- package/dist/components/launch-countdown.js +8 -83
- package/dist/components/launch-countdown.js.map +1 -1
- package/dist/components/launch-countdown.mjs +3 -85
- package/dist/components/launch-countdown.mjs.map +1 -1
- package/dist/components/newsletter.js +20 -993
- package/dist/components/newsletter.js.map +1 -1
- package/dist/components/newsletter.mjs +11 -971
- package/dist/components/newsletter.mjs.map +1 -1
- package/dist/components/partners.js +24 -1302
- package/dist/components/partners.js.map +1 -1
- package/dist/components/partners.mjs +15 -1276
- package/dist/components/partners.mjs.map +1 -1
- package/dist/components/pricing.js +49 -1249
- package/dist/components/pricing.js.map +1 -1
- package/dist/components/pricing.mjs +8 -1226
- package/dist/components/pricing.mjs.map +1 -1
- package/dist/components/problems-solved.js +8 -150
- package/dist/components/problems-solved.js.map +1 -1
- package/dist/components/problems-solved.mjs +4 -133
- package/dist/components/problems-solved.mjs.map +1 -1
- package/dist/components/resource-links.js +8 -304
- package/dist/components/resource-links.js.map +1 -1
- package/dist/components/resource-links.mjs +5 -308
- package/dist/components/resource-links.mjs.map +1 -1
- package/dist/components/social-links.js +8 -343
- package/dist/components/social-links.js.map +1 -1
- package/dist/components/social-links.mjs +5 -347
- package/dist/components/social-links.mjs.map +1 -1
- package/dist/components/unsubscribe.js +10 -627
- package/dist/components/unsubscribe.js.map +1 -1
- package/dist/components/unsubscribe.mjs +6 -611
- package/dist/components/unsubscribe.mjs.map +1 -1
- package/dist/components/waitlist.js +21 -1001
- package/dist/components/waitlist.js.map +1 -1
- package/dist/components/waitlist.mjs +12 -982
- package/dist/components/waitlist.mjs.map +1 -1
- package/dist/components/website-switcher.js +12 -175
- package/dist/components/website-switcher.js.map +1 -1
- package/dist/components/website-switcher.mjs +4 -157
- package/dist/components/website-switcher.mjs.map +1 -1
- package/dist/content/index.js +118 -3616
- package/dist/content/index.js.map +1 -1
- package/dist/content/index.mjs +12 -3567
- package/dist/content/index.mjs.map +1 -1
- package/dist/hooks/index.js +37 -2321
- package/dist/hooks/index.js.map +1 -1
- package/dist/hooks/index.mjs +6 -2318
- package/dist/hooks/index.mjs.map +1 -1
- package/dist/index.js +4145 -20599
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +3766 -20567
- package/dist/index.mjs.map +1 -1
- package/dist/product/index.js +20 -393
- package/dist/product/index.js.map +1 -1
- package/dist/product/index.mjs +5 -394
- package/dist/product/index.mjs.map +1 -1
- package/dist/seo/index.js +8 -76
- package/dist/seo/index.js.map +1 -1
- package/dist/seo/index.mjs +3 -78
- package/dist/seo/index.mjs.map +1 -1
- package/dist/store/index.js +51 -2650
- package/dist/store/index.js.map +1 -1
- package/dist/store/index.mjs +13 -2619
- package/dist/store/index.mjs.map +1 -1
- package/dist/utils/index.js +69 -134
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/index.mjs +5 -122
- package/dist/utils/index.mjs.map +1 -1
- package/package.json +2 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/ui/button.tsx"],"names":["cva","React","Slot","jsx","cn"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAOA,IAAM,cAAA,GAAiBA,0BAAA;AAAA,EACrB,uSAAA;AAAA,EACA;AAAA,IACE,QAAA,EAAU;AAAA,MACR,OAAA,EAAS;AAAA,QACP,OAAA,EACE,+DAAA;AAAA,QACF,WAAA,EACE,8EAAA;AAAA,QACF,OAAA,EACE,0FAAA;AAAA,QACF,SAAA,EACE,wEAAA;AAAA,QACF,KAAA,EAAO,8CAAA;AAAA,QACP,IAAA,EAAM;AAAA,OACR;AAAA,MACA,IAAA,EAAM;AAAA,QACJ,OAAA,EAAS,eAAA;AAAA,QACT,EAAA,EAAI,6BAAA;AAAA,QACJ,EAAA,EAAI,sBAAA;AAAA,QACJ,IAAA,EAAM;AAAA;AACR,KACF;AAAA,IACA,eAAA,EAAiB;AAAA,MACf,OAAA,EAAS,SAAA;AAAA,MACT,IAAA,EAAM;AAAA;AACR;AAEJ;AASA,IAAM,MAAA,GAAeC,gBAAA,CAAA,UAAA;AAAA,EACnB,CAAC,EAAE,SAAA,EAAW,OAAA,EAAS,IAAA,EAAM,UAAU,KAAA,EAAO,GAAG,KAAA,EAAM,EAAG,GAAA,KAAQ;AAChE,IAAA,MAAM,IAAA,GAAO,UAAUC,cAAA,GAAO,QAAA;AAC9B,IAAA,uBACEC,cAAA;AAAA,MAAC,IAAA;AAAA,MAAA;AAAA,QACC,SAAA,EAAWC,oBAAG,cAAA,CAAe,EAAE,SAAS,IAAA,EAAM,SAAA,EAAW,CAAC,CAAA;AAAA,QAC1D,GAAA;AAAA,QACC,GAAG;AAAA;AAAA,KACN;AAAA,EAEJ;AACF;AACA,MAAA,CAAO,WAAA,GAAc,QAAA","file":"chunk-UQ2HALUD.js","sourcesContent":["import * as React from \"react\";\n\nimport { Slot } from \"@radix-ui/react-slot\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\n\nimport { cn } from \"../utils/cn\";\n\nconst buttonVariants = cva(\n \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0\",\n {\n variants: {\n variant: {\n default:\n \"bg-primary text-primary-foreground shadow hover:bg-primary/90\",\n destructive:\n \"bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90\",\n outline:\n \"border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground\",\n secondary:\n \"bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80\",\n ghost: \"hover:bg-accent hover:text-accent-foreground\",\n link: \"text-primary underline-offset-4 hover:underline\",\n },\n size: {\n default: \"h-9 px-4 py-2\",\n sm: \"h-8 rounded-md px-3 text-xs\",\n lg: \"h-10 rounded-md px-8\",\n icon: \"h-9 w-9\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n },\n);\n\nexport interface ButtonProps\n extends\n React.ButtonHTMLAttributes<HTMLButtonElement>,\n VariantProps<typeof buttonVariants> {\n asChild?: boolean;\n}\n\nconst Button = React.forwardRef<HTMLButtonElement, ButtonProps>(\n ({ className, variant, size, asChild = false, ...props }, ref) => {\n const Comp = asChild ? Slot : \"button\";\n return (\n <Comp\n className={cn(buttonVariants({ variant, size, className }))}\n ref={ref}\n {...props}\n />\n );\n },\n);\nButton.displayName = \"Button\";\n\nexport { Button, buttonVariants };\n"]}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var reactHelmetAsync = require('react-helmet-async');
|
|
4
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
5
|
+
|
|
6
|
+
function canonicalFromLocation() {
|
|
7
|
+
if (typeof window === "undefined" || !window.location) return void 0;
|
|
8
|
+
const { origin, pathname } = window.location;
|
|
9
|
+
if (!origin || origin === "null") return void 0;
|
|
10
|
+
const path = pathname === "/" ? "/" : pathname.replace(/\/+$/, "");
|
|
11
|
+
return `${origin}${path}`;
|
|
12
|
+
}
|
|
13
|
+
function resolveImageUrl(image, base) {
|
|
14
|
+
if (!image || /^https?:\/\//i.test(image)) return image;
|
|
15
|
+
if (!base) return image;
|
|
16
|
+
try {
|
|
17
|
+
return new URL(image, base).toString();
|
|
18
|
+
} catch {
|
|
19
|
+
return image;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
function serializeJsonLd(data) {
|
|
23
|
+
return JSON.stringify(data).replace(/</g, "\\u003c").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
|
|
24
|
+
}
|
|
25
|
+
function PageHead({
|
|
26
|
+
title,
|
|
27
|
+
description,
|
|
28
|
+
productName,
|
|
29
|
+
keywords,
|
|
30
|
+
image,
|
|
31
|
+
url,
|
|
32
|
+
favicon,
|
|
33
|
+
robots = "index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1",
|
|
34
|
+
locale = "en_US",
|
|
35
|
+
twitterHandle,
|
|
36
|
+
themeColor = "#000000",
|
|
37
|
+
author,
|
|
38
|
+
structuredData,
|
|
39
|
+
additionalMeta
|
|
40
|
+
}) {
|
|
41
|
+
const fullTitle = productName && !title.includes(productName) ? `${title} | ${productName}` : title;
|
|
42
|
+
const resolvedUrl = url ?? canonicalFromLocation();
|
|
43
|
+
const fullImageUrl = resolveImageUrl(image, resolvedUrl);
|
|
44
|
+
const structuredDataItems = structuredData ? Array.isArray(structuredData) ? structuredData : [structuredData] : [];
|
|
45
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(reactHelmetAsync.Helmet, { children: [
|
|
46
|
+
/* @__PURE__ */ jsxRuntime.jsx("title", { children: fullTitle }),
|
|
47
|
+
/* @__PURE__ */ jsxRuntime.jsx("meta", { name: "title", content: fullTitle }),
|
|
48
|
+
description ? /* @__PURE__ */ jsxRuntime.jsx("meta", { name: "description", content: description }) : null,
|
|
49
|
+
keywords ? /* @__PURE__ */ jsxRuntime.jsx("meta", { name: "keywords", content: keywords }) : null,
|
|
50
|
+
author ? /* @__PURE__ */ jsxRuntime.jsx("meta", { name: "author", content: author }) : null,
|
|
51
|
+
/* @__PURE__ */ jsxRuntime.jsx("meta", { name: "robots", content: robots }),
|
|
52
|
+
resolvedUrl ? /* @__PURE__ */ jsxRuntime.jsx("link", { rel: "canonical", href: resolvedUrl }) : null,
|
|
53
|
+
favicon ? /* @__PURE__ */ jsxRuntime.jsx("link", { rel: "icon", href: favicon }) : null,
|
|
54
|
+
/* @__PURE__ */ jsxRuntime.jsx("meta", { property: "og:type", content: "website" }),
|
|
55
|
+
/* @__PURE__ */ jsxRuntime.jsx("meta", { property: "og:title", content: fullTitle }),
|
|
56
|
+
description ? /* @__PURE__ */ jsxRuntime.jsx("meta", { property: "og:description", content: description }) : null,
|
|
57
|
+
fullImageUrl ? /* @__PURE__ */ jsxRuntime.jsx("meta", { property: "og:image", content: fullImageUrl }) : null,
|
|
58
|
+
resolvedUrl ? /* @__PURE__ */ jsxRuntime.jsx("meta", { property: "og:url", content: resolvedUrl }) : null,
|
|
59
|
+
/* @__PURE__ */ jsxRuntime.jsx("meta", { property: "og:locale", content: locale }),
|
|
60
|
+
productName ? /* @__PURE__ */ jsxRuntime.jsx("meta", { property: "og:site_name", content: productName }) : null,
|
|
61
|
+
/* @__PURE__ */ jsxRuntime.jsx("meta", { name: "twitter:card", content: "summary_large_image" }),
|
|
62
|
+
/* @__PURE__ */ jsxRuntime.jsx("meta", { name: "twitter:title", content: fullTitle }),
|
|
63
|
+
description ? /* @__PURE__ */ jsxRuntime.jsx("meta", { name: "twitter:description", content: description }) : null,
|
|
64
|
+
fullImageUrl ? /* @__PURE__ */ jsxRuntime.jsx("meta", { name: "twitter:image", content: fullImageUrl }) : null,
|
|
65
|
+
twitterHandle ? /* @__PURE__ */ jsxRuntime.jsx("meta", { name: "twitter:creator", content: twitterHandle }) : null,
|
|
66
|
+
/* @__PURE__ */ jsxRuntime.jsx("meta", { name: "theme-color", content: themeColor }),
|
|
67
|
+
structuredDataItems.map((data, index) => /* @__PURE__ */ jsxRuntime.jsx("script", { type: "application/ld+json", children: serializeJsonLd(data) }, `ld-${index}`)),
|
|
68
|
+
additionalMeta?.map((meta, index) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
69
|
+
"meta",
|
|
70
|
+
{
|
|
71
|
+
...meta.name ? { name: meta.name } : {},
|
|
72
|
+
...meta.property ? { property: meta.property } : {},
|
|
73
|
+
content: meta.content
|
|
74
|
+
},
|
|
75
|
+
`meta-${index}`
|
|
76
|
+
))
|
|
77
|
+
] });
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
exports.PageHead = PageHead;
|
|
81
|
+
//# sourceMappingURL=chunk-UXWT7G77.js.map
|
|
82
|
+
//# sourceMappingURL=chunk-UXWT7G77.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/seo/page-head.tsx"],"names":["Helmet","jsx"],"mappings":"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","file":"chunk-UXWT7G77.js","sourcesContent":["/**\n * PageHead Component\n * Manages dynamic meta tags for SEO optimization on a per-page basis.\n * Supports JSON-LD structured data, Open Graph, Twitter Cards, favicons, and robots directives.\n *\n * @example\n * ```tsx\n * <PageHead\n * title=\"About Us\"\n * description=\"Learn about our mission and team\"\n * productName=\"MyProduct\"\n * keywords=\"about, team, mission\"\n * image=\"/og-about.png\"\n * url=\"https://myproduct.com/about\"\n * favicon=\"/favicon.ico\"\n * robots=\"index, follow\"\n * locale=\"en_US\"\n * twitterHandle=\"@burdenoff\"\n * themeColor=\"#1a1a2e\"\n * structuredData={{\n * \"@context\": \"https://schema.org\",\n * \"@type\": \"WebPage\",\n * name: \"About Us\",\n * }}\n * />\n * ```\n */\n\nimport { Helmet } from \"react-helmet-async\";\n\nexport interface PageHeadProps {\n /** Page title */\n title: string;\n /** Meta description */\n description?: string;\n /** Product/brand name (appended to title) */\n productName?: string;\n /** SEO keywords */\n keywords?: string;\n /** Open Graph image URL */\n image?: string;\n /** Page canonical URL */\n url?: string;\n /** Favicon URL */\n favicon?: string;\n /** Robots directive (e.g., \"index, follow\") */\n robots?: string;\n /** Open Graph locale (e.g., \"en_US\") */\n locale?: string;\n /** Twitter handle (e.g., \"@burdenoff\") */\n twitterHandle?: string;\n /** Theme color for mobile browsers */\n themeColor?: string;\n /**\n * Value for `<meta name=\"author\">`. Omitted by default.\n *\n * Each product site already declares its author in `index.html` as the\n * legal entity that publicly holds that product (BUR-SOP-029, \"Holder is\n * what you publish\"), and that entity differs between products. A default\n * here would add a second, conflicting author tag to every route, so the\n * tag is only rendered when a site passes the value explicitly.\n */\n author?: string;\n /** JSON-LD structured data objects */\n structuredData?: Record<string, unknown> | Array<Record<string, unknown>>;\n /** Additional meta tags */\n additionalMeta?: Array<{\n name?: string;\n property?: string;\n content: string;\n }>;\n}\n\n/**\n * Build a self-referencing canonical URL from the current location.\n *\n * Query strings and hashes are dropped (they never identify a distinct\n * canonical document here) and the trailing slash is normalised away for\n * everything but the site root. Returns `undefined` outside a DOM so the\n * component degrades to its previous behaviour under plain string rendering.\n */\nfunction canonicalFromLocation(): string | undefined {\n if (typeof window === \"undefined\" || !window.location) return undefined;\n const { origin, pathname } = window.location;\n if (!origin || origin === \"null\") return undefined;\n const path = pathname === \"/\" ? \"/\" : pathname.replace(/\\/+$/, \"\");\n return `${origin}${path}`;\n}\n\n/**\n * Absolutise an Open Graph image URL.\n *\n * Already-absolute URLs pass through. A root-relative path resolves against\n * the origin, and any other relative path against the page URL. Without a\n * resolvable base the original value is returned unchanged.\n */\nfunction resolveImageUrl(\n image: string | undefined,\n base: string | undefined,\n): string | undefined {\n if (!image || /^https?:\\/\\//i.test(image)) return image;\n if (!base) return image;\n try {\n return new URL(image, base).toString();\n } catch {\n return image;\n }\n}\n\n/**\n * JSON-LD as the body of a `<script>` element.\n *\n * `JSON.stringify` leaves `<` alone, and a script body ends at the first `</script` whatever\n * the quoting around it. The prerender serialises the live DOM with script text verbatim,\n * so a `</script><script>…` inside any string field (a caption, a title) would close the\n * JSON-LD block in the static HTML and run what follows. `\\u003c` is the same character to\n * every JSON parser; U+2028 / U+2029 are escaped for engines that still read them as line\n * breaks.\n */\nfunction serializeJsonLd(data: Record<string, unknown>): string {\n return JSON.stringify(data)\n .replace(/</g, \"\\\\u003c\")\n .replace(/\\u2028/g, \"\\\\u2028\")\n .replace(/\\u2029/g, \"\\\\u2029\");\n}\n\nexport function PageHead({\n title,\n description,\n productName,\n keywords,\n image,\n url,\n favicon,\n robots = \"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\",\n locale = \"en_US\",\n twitterHandle,\n themeColor = \"#000000\",\n author,\n structuredData,\n additionalMeta,\n}: PageHeadProps) {\n const fullTitle =\n productName && !title.includes(productName)\n ? `${title} | ${productName}`\n : title;\n\n // Self-referencing canonical by default.\n //\n // Without this, a route that renders PageHead but omits `url` emits no\n // canonical at all, so the static `<link rel=\"canonical\">` in index.html\n // survives and every such page declares itself a duplicate of the home\n // page — Google then drops /pricing, /privacy, /terms and friends from the\n // index. Deriving it from the current location keeps each page pointing at\n // itself; callers that genuinely need a cross-canonical still pass `url`.\n //\n // During prerender the DOM location already reflects the route being\n // rendered, so this resolves correctly ahead of hydration.\n const resolvedUrl = url ?? canonicalFromLocation();\n\n // Root-relative images (\"/og.png\") belong to the ORIGIN, not to the current\n // path — concatenating them onto the page URL yields /features/og.png and a\n // broken share card. Anything else is resolved relative to the page itself.\n const fullImageUrl = resolveImageUrl(image, resolvedUrl);\n\n // Normalize structured data to an array\n const structuredDataItems: Array<Record<string, unknown>> = structuredData\n ? Array.isArray(structuredData)\n ? structuredData\n : [structuredData]\n : [];\n\n // Every conditional below is a `? … : null` ternary, never `x && <el />`.\n // `&&` forwards the left operand when it is falsy, so an empty-string prop\n // (keywords is legitimately \"\" on generated answer pages) would reach Helmet\n // as a string child. react-helmet-async skips any falsy child, but its\n // maintained fork @dr.pogodin/react-helmet skips only null/undefined and\n // throws `\"string\" is not a valid <Helmet> descendant` — which crashes the\n // whole page at render time. `null` is skipped by both.\n return (\n <Helmet>\n {/* Primary Meta Tags */}\n <title>{fullTitle}</title>\n <meta name=\"title\" content={fullTitle} />\n {description ? <meta name=\"description\" content={description} /> : null}\n {keywords ? <meta name=\"keywords\" content={keywords} /> : null}\n {author ? <meta name=\"author\" content={author} /> : null}\n <meta name=\"robots\" content={robots} />\n\n {/* Canonical URL */}\n {resolvedUrl ? <link rel=\"canonical\" href={resolvedUrl} /> : null}\n\n {/* Favicon */}\n {favicon ? <link rel=\"icon\" href={favicon} /> : null}\n\n {/* Open Graph / Facebook */}\n <meta property=\"og:type\" content=\"website\" />\n <meta property=\"og:title\" content={fullTitle} />\n {description ? (\n <meta property=\"og:description\" content={description} />\n ) : null}\n {fullImageUrl ? (\n <meta property=\"og:image\" content={fullImageUrl} />\n ) : null}\n {resolvedUrl ? <meta property=\"og:url\" content={resolvedUrl} /> : null}\n <meta property=\"og:locale\" content={locale} />\n {productName ? (\n <meta property=\"og:site_name\" content={productName} />\n ) : null}\n\n {/* Twitter Card */}\n <meta name=\"twitter:card\" content=\"summary_large_image\" />\n <meta name=\"twitter:title\" content={fullTitle} />\n {description ? (\n <meta name=\"twitter:description\" content={description} />\n ) : null}\n {fullImageUrl ? (\n <meta name=\"twitter:image\" content={fullImageUrl} />\n ) : null}\n {twitterHandle ? (\n <meta name=\"twitter:creator\" content={twitterHandle} />\n ) : null}\n\n {/* Theme Color */}\n <meta name=\"theme-color\" content={themeColor} />\n\n {/* JSON-LD Structured Data */}\n {structuredDataItems.map((data, index) => (\n <script key={`ld-${index}`} type=\"application/ld+json\">\n {serializeJsonLd(data)}\n </script>\n ))}\n\n {/* Additional Meta Tags */}\n {additionalMeta?.map((meta, index) => (\n <meta\n key={`meta-${index}`}\n {...(meta.name ? { name: meta.name } : {})}\n {...(meta.property ? { property: meta.property } : {})}\n content={meta.content}\n />\n ))}\n </Helmet>\n );\n}\n"]}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
3
|
+
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
4
|
+
|
|
5
|
+
export { __publicField };
|
|
6
|
+
//# sourceMappingURL=chunk-VNS5WDWO.mjs.map
|
|
7
|
+
//# sourceMappingURL=chunk-VNS5WDWO.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"chunk-VNS5WDWO.mjs"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"chunk-VRWZLGR7.js"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { cn } from './chunk-R7G6TWIS.mjs';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import { jsx } from 'react/jsx-runtime';
|
|
4
|
+
|
|
5
|
+
var Textarea = React.forwardRef(({ className, ...props }, ref) => {
|
|
6
|
+
return /* @__PURE__ */ jsx(
|
|
7
|
+
"textarea",
|
|
8
|
+
{
|
|
9
|
+
className: cn(
|
|
10
|
+
"flex min-h-[60px] w-full rounded-md border border-input bg-transparent px-3 py-2 text-base shadow-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
|
|
11
|
+
className
|
|
12
|
+
),
|
|
13
|
+
ref,
|
|
14
|
+
...props
|
|
15
|
+
}
|
|
16
|
+
);
|
|
17
|
+
});
|
|
18
|
+
Textarea.displayName = "Textarea";
|
|
19
|
+
|
|
20
|
+
export { Textarea };
|
|
21
|
+
//# sourceMappingURL=chunk-VZLDSNH4.mjs.map
|
|
22
|
+
//# sourceMappingURL=chunk-VZLDSNH4.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/ui/textarea.tsx"],"names":[],"mappings":";;;;AAIA,IAAM,QAAA,GAAiB,iBAGrB,CAAC,EAAE,WAAW,GAAG,KAAA,IAAS,GAAA,KAAQ;AAClC,EAAA,uBACE,GAAA;AAAA,IAAC,UAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAW,EAAA;AAAA,QACT,2QAAA;AAAA,QACA;AAAA,OACF;AAAA,MACA,GAAA;AAAA,MACC,GAAG;AAAA;AAAA,GACN;AAEJ,CAAC;AACD,QAAA,CAAS,WAAA,GAAc,UAAA","file":"chunk-VZLDSNH4.mjs","sourcesContent":["import * as React from \"react\";\n\nimport { cn } from \"../utils/cn\";\n\nconst Textarea = React.forwardRef<\n HTMLTextAreaElement,\n React.ComponentProps<\"textarea\">\n>(({ className, ...props }, ref) => {\n return (\n <textarea\n className={cn(\n \"flex min-h-[60px] w-full rounded-md border border-input bg-transparent px-3 py-2 text-base shadow-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm\",\n className,\n )}\n ref={ref}\n {...props}\n />\n );\n});\nTextarea.displayName = \"Textarea\";\n\nexport { Textarea };\n"]}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunkUQ2HALUD_js = require('./chunk-UQ2HALUD.js');
|
|
4
|
+
var chunkC6OJIHNO_js = require('./chunk-C6OJIHNO.js');
|
|
5
|
+
var lucideReact = require('lucide-react');
|
|
6
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
7
|
+
|
|
8
|
+
function ProblemsSolvedSection({
|
|
9
|
+
eyebrow,
|
|
10
|
+
title,
|
|
11
|
+
subtitle,
|
|
12
|
+
problems,
|
|
13
|
+
storyBasePath = "/use-cases",
|
|
14
|
+
storyLabel = "See the story",
|
|
15
|
+
className,
|
|
16
|
+
children
|
|
17
|
+
}) {
|
|
18
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
19
|
+
"section",
|
|
20
|
+
{
|
|
21
|
+
className: chunkC6OJIHNO_js.cn(
|
|
22
|
+
"py-16 md:py-24 px-4 sm:px-6 lg:px-8 bg-muted/30",
|
|
23
|
+
className
|
|
24
|
+
),
|
|
25
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "max-w-7xl mx-auto", children: [
|
|
26
|
+
(eyebrow || title || subtitle) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "max-w-3xl mx-auto text-center mb-12 md:mb-16", children: [
|
|
27
|
+
eyebrow && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs font-mono uppercase tracking-widest text-primary mb-4", children: eyebrow }),
|
|
28
|
+
title && /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-3xl sm:text-4xl font-bold text-foreground mb-4", children: title }),
|
|
29
|
+
subtitle && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-lg text-muted-foreground", children: subtitle })
|
|
30
|
+
] }),
|
|
31
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6", children: problems.map((item, index) => {
|
|
32
|
+
const Icon = item.icon;
|
|
33
|
+
const storyHref = item.storySlug ? `${storyBasePath.replace(/\/$/, "")}/${item.storySlug}` : null;
|
|
34
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
35
|
+
"div",
|
|
36
|
+
{
|
|
37
|
+
className: chunkC6OJIHNO_js.cn(
|
|
38
|
+
"group relative flex flex-col rounded-2xl border border-border/40 bg-card p-6 transition-colors",
|
|
39
|
+
"hover:border-primary/30"
|
|
40
|
+
),
|
|
41
|
+
children: [
|
|
42
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
43
|
+
"div",
|
|
44
|
+
{
|
|
45
|
+
className: chunkC6OJIHNO_js.cn(
|
|
46
|
+
"mb-5 inline-flex h-12 w-12 items-center justify-center rounded-xl",
|
|
47
|
+
"bg-primary/10 text-primary"
|
|
48
|
+
),
|
|
49
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { className: "h-6 w-6", "aria-hidden": true })
|
|
50
|
+
}
|
|
51
|
+
),
|
|
52
|
+
/* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-lg font-semibold text-foreground mb-2", children: item.problem }),
|
|
53
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground leading-relaxed mb-4 flex-1", children: item.solution }),
|
|
54
|
+
storyHref && /* @__PURE__ */ jsxRuntime.jsx(
|
|
55
|
+
chunkUQ2HALUD_js.Button,
|
|
56
|
+
{
|
|
57
|
+
variant: "ghost",
|
|
58
|
+
className: "justify-start px-0 h-auto py-0 text-sm group/link",
|
|
59
|
+
asChild: true,
|
|
60
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
61
|
+
"a",
|
|
62
|
+
{
|
|
63
|
+
href: storyHref,
|
|
64
|
+
className: "inline-flex items-center gap-1 text-primary hover:underline",
|
|
65
|
+
children: [
|
|
66
|
+
storyLabel,
|
|
67
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
68
|
+
lucideReact.ArrowRight,
|
|
69
|
+
{
|
|
70
|
+
className: "h-3.5 w-3.5 transition-transform group-hover/link:translate-x-0.5",
|
|
71
|
+
"aria-hidden": "true"
|
|
72
|
+
}
|
|
73
|
+
)
|
|
74
|
+
]
|
|
75
|
+
}
|
|
76
|
+
)
|
|
77
|
+
}
|
|
78
|
+
)
|
|
79
|
+
]
|
|
80
|
+
},
|
|
81
|
+
`${item.problem}-${index}`
|
|
82
|
+
);
|
|
83
|
+
}) }),
|
|
84
|
+
children && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-12", children })
|
|
85
|
+
] })
|
|
86
|
+
}
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
exports.ProblemsSolvedSection = ProblemsSolvedSection;
|
|
91
|
+
//# sourceMappingURL=chunk-W6P3YETJ.js.map
|
|
92
|
+
//# sourceMappingURL=chunk-W6P3YETJ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/problems-solved.tsx"],"names":["jsx","cn","jsxs","Button","ArrowRight"],"mappings":"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","file":"chunk-W6P3YETJ.js","sourcesContent":["\"use client\";\n\n/**\n * ProblemsSolvedSection Component\n *\n * A creative, conversion-oriented section that pairs a problem with the\n * product's solution. Each card highlights the pain point, the fix, and an\n * optional link to a deeper use-case story.\n *\n * @example\n * ```tsx\n * import { ProblemsSolvedSection } from '@burdenoff/website-sdk'\n *\n * <ProblemsSolvedSection\n * eyebrow=\"Why teams switch\"\n * title=\"Stop fighting your tools\"\n * subtitle=\"We built VibeControls around the friction that actually slows engineering teams down.\"\n * problems={[...]}\n * />\n * ```\n */\n\nimport type { ComponentType, ReactNode } from \"react\";\n\nimport { ArrowRight } from \"lucide-react\";\n\nimport { Button } from \"../ui/button\";\nimport { cn } from \"../utils/cn\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface ProblemSolved {\n /** The pain point or before-state. */\n problem: string;\n /** How the product addresses the pain point. */\n solution: string;\n /** Lucide-style icon component. */\n icon: ComponentType<{ className?: string; \"aria-hidden\"?: boolean }>;\n /** Optional use-case story slug for linking to /use-cases/:slug. */\n storySlug?: string;\n}\n\nexport interface ProblemsSolvedSectionProps {\n /** Section eyebrow text. */\n eyebrow?: string;\n /** Section heading. */\n title?: string;\n /** Section subtitle. */\n subtitle?: string;\n /** Problem/solution pairs to render. */\n problems: ProblemSolved[];\n /** Base path for use-case story links. */\n storyBasePath?: string;\n /** Label for story links. */\n storyLabel?: string;\n /** Optional additional CSS class for the outer section. */\n className?: string;\n /** Optional child element rendered at the bottom of the section. */\n children?: ReactNode;\n}\n\n// ============================================================================\n// Component\n// ============================================================================\n\nexport function ProblemsSolvedSection({\n eyebrow,\n title,\n subtitle,\n problems,\n storyBasePath = \"/use-cases\",\n storyLabel = \"See the story\",\n className,\n children,\n}: ProblemsSolvedSectionProps) {\n return (\n <section\n className={cn(\n \"py-16 md:py-24 px-4 sm:px-6 lg:px-8 bg-muted/30\",\n className,\n )}\n >\n <div className=\"max-w-7xl mx-auto\">\n {(eyebrow || title || subtitle) && (\n <div className=\"max-w-3xl mx-auto text-center mb-12 md:mb-16\">\n {eyebrow && (\n <p className=\"text-xs font-mono uppercase tracking-widest text-primary mb-4\">\n {eyebrow}\n </p>\n )}\n {title && (\n <h2 className=\"text-3xl sm:text-4xl font-bold text-foreground mb-4\">\n {title}\n </h2>\n )}\n {subtitle && (\n <p className=\"text-lg text-muted-foreground\">{subtitle}</p>\n )}\n </div>\n )}\n\n <div className=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6\">\n {problems.map((item, index) => {\n const Icon = item.icon;\n const storyHref = item.storySlug\n ? `${storyBasePath.replace(/\\/$/, \"\")}/${item.storySlug}`\n : null;\n\n return (\n <div\n key={`${item.problem}-${index}`}\n className={cn(\n \"group relative flex flex-col rounded-2xl border border-border/40 bg-card p-6 transition-colors\",\n \"hover:border-primary/30\",\n )}\n >\n <div\n className={cn(\n \"mb-5 inline-flex h-12 w-12 items-center justify-center rounded-xl\",\n \"bg-primary/10 text-primary\",\n )}\n >\n <Icon className=\"h-6 w-6\" aria-hidden={true} />\n </div>\n\n <h3 className=\"text-lg font-semibold text-foreground mb-2\">\n {item.problem}\n </h3>\n\n <p className=\"text-sm text-muted-foreground leading-relaxed mb-4 flex-1\">\n {item.solution}\n </p>\n\n {storyHref && (\n <Button\n variant=\"ghost\"\n className=\"justify-start px-0 h-auto py-0 text-sm group/link\"\n asChild\n >\n <a\n href={storyHref}\n className=\"inline-flex items-center gap-1 text-primary hover:underline\"\n >\n {storyLabel}\n <ArrowRight\n className=\"h-3.5 w-3.5 transition-transform group-hover/link:translate-x-0.5\"\n aria-hidden=\"true\"\n />\n </a>\n </Button>\n )}\n </div>\n );\n })}\n </div>\n\n {children && <div className=\"mt-12\">{children}</div>}\n </div>\n </section>\n );\n}\n"]}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { Button } from './chunk-KHYXK7FG.mjs';
|
|
2
|
+
import { cn } from './chunk-R7G6TWIS.mjs';
|
|
3
|
+
import { ArrowRight } from 'lucide-react';
|
|
4
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
5
|
+
|
|
6
|
+
function ProblemsSolvedSection({
|
|
7
|
+
eyebrow,
|
|
8
|
+
title,
|
|
9
|
+
subtitle,
|
|
10
|
+
problems,
|
|
11
|
+
storyBasePath = "/use-cases",
|
|
12
|
+
storyLabel = "See the story",
|
|
13
|
+
className,
|
|
14
|
+
children
|
|
15
|
+
}) {
|
|
16
|
+
return /* @__PURE__ */ jsx(
|
|
17
|
+
"section",
|
|
18
|
+
{
|
|
19
|
+
className: cn(
|
|
20
|
+
"py-16 md:py-24 px-4 sm:px-6 lg:px-8 bg-muted/30",
|
|
21
|
+
className
|
|
22
|
+
),
|
|
23
|
+
children: /* @__PURE__ */ jsxs("div", { className: "max-w-7xl mx-auto", children: [
|
|
24
|
+
(eyebrow || title || subtitle) && /* @__PURE__ */ jsxs("div", { className: "max-w-3xl mx-auto text-center mb-12 md:mb-16", children: [
|
|
25
|
+
eyebrow && /* @__PURE__ */ jsx("p", { className: "text-xs font-mono uppercase tracking-widest text-primary mb-4", children: eyebrow }),
|
|
26
|
+
title && /* @__PURE__ */ jsx("h2", { className: "text-3xl sm:text-4xl font-bold text-foreground mb-4", children: title }),
|
|
27
|
+
subtitle && /* @__PURE__ */ jsx("p", { className: "text-lg text-muted-foreground", children: subtitle })
|
|
28
|
+
] }),
|
|
29
|
+
/* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6", children: problems.map((item, index) => {
|
|
30
|
+
const Icon = item.icon;
|
|
31
|
+
const storyHref = item.storySlug ? `${storyBasePath.replace(/\/$/, "")}/${item.storySlug}` : null;
|
|
32
|
+
return /* @__PURE__ */ jsxs(
|
|
33
|
+
"div",
|
|
34
|
+
{
|
|
35
|
+
className: cn(
|
|
36
|
+
"group relative flex flex-col rounded-2xl border border-border/40 bg-card p-6 transition-colors",
|
|
37
|
+
"hover:border-primary/30"
|
|
38
|
+
),
|
|
39
|
+
children: [
|
|
40
|
+
/* @__PURE__ */ jsx(
|
|
41
|
+
"div",
|
|
42
|
+
{
|
|
43
|
+
className: cn(
|
|
44
|
+
"mb-5 inline-flex h-12 w-12 items-center justify-center rounded-xl",
|
|
45
|
+
"bg-primary/10 text-primary"
|
|
46
|
+
),
|
|
47
|
+
children: /* @__PURE__ */ jsx(Icon, { className: "h-6 w-6", "aria-hidden": true })
|
|
48
|
+
}
|
|
49
|
+
),
|
|
50
|
+
/* @__PURE__ */ jsx("h3", { className: "text-lg font-semibold text-foreground mb-2", children: item.problem }),
|
|
51
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground leading-relaxed mb-4 flex-1", children: item.solution }),
|
|
52
|
+
storyHref && /* @__PURE__ */ jsx(
|
|
53
|
+
Button,
|
|
54
|
+
{
|
|
55
|
+
variant: "ghost",
|
|
56
|
+
className: "justify-start px-0 h-auto py-0 text-sm group/link",
|
|
57
|
+
asChild: true,
|
|
58
|
+
children: /* @__PURE__ */ jsxs(
|
|
59
|
+
"a",
|
|
60
|
+
{
|
|
61
|
+
href: storyHref,
|
|
62
|
+
className: "inline-flex items-center gap-1 text-primary hover:underline",
|
|
63
|
+
children: [
|
|
64
|
+
storyLabel,
|
|
65
|
+
/* @__PURE__ */ jsx(
|
|
66
|
+
ArrowRight,
|
|
67
|
+
{
|
|
68
|
+
className: "h-3.5 w-3.5 transition-transform group-hover/link:translate-x-0.5",
|
|
69
|
+
"aria-hidden": "true"
|
|
70
|
+
}
|
|
71
|
+
)
|
|
72
|
+
]
|
|
73
|
+
}
|
|
74
|
+
)
|
|
75
|
+
}
|
|
76
|
+
)
|
|
77
|
+
]
|
|
78
|
+
},
|
|
79
|
+
`${item.problem}-${index}`
|
|
80
|
+
);
|
|
81
|
+
}) }),
|
|
82
|
+
children && /* @__PURE__ */ jsx("div", { className: "mt-12", children })
|
|
83
|
+
] })
|
|
84
|
+
}
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export { ProblemsSolvedSection };
|
|
89
|
+
//# sourceMappingURL=chunk-WPKFFQCR.mjs.map
|
|
90
|
+
//# sourceMappingURL=chunk-WPKFFQCR.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/problems-solved.tsx"],"names":[],"mappings":"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","file":"chunk-WPKFFQCR.mjs","sourcesContent":["\"use client\";\n\n/**\n * ProblemsSolvedSection Component\n *\n * A creative, conversion-oriented section that pairs a problem with the\n * product's solution. Each card highlights the pain point, the fix, and an\n * optional link to a deeper use-case story.\n *\n * @example\n * ```tsx\n * import { ProblemsSolvedSection } from '@burdenoff/website-sdk'\n *\n * <ProblemsSolvedSection\n * eyebrow=\"Why teams switch\"\n * title=\"Stop fighting your tools\"\n * subtitle=\"We built VibeControls around the friction that actually slows engineering teams down.\"\n * problems={[...]}\n * />\n * ```\n */\n\nimport type { ComponentType, ReactNode } from \"react\";\n\nimport { ArrowRight } from \"lucide-react\";\n\nimport { Button } from \"../ui/button\";\nimport { cn } from \"../utils/cn\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface ProblemSolved {\n /** The pain point or before-state. */\n problem: string;\n /** How the product addresses the pain point. */\n solution: string;\n /** Lucide-style icon component. */\n icon: ComponentType<{ className?: string; \"aria-hidden\"?: boolean }>;\n /** Optional use-case story slug for linking to /use-cases/:slug. */\n storySlug?: string;\n}\n\nexport interface ProblemsSolvedSectionProps {\n /** Section eyebrow text. */\n eyebrow?: string;\n /** Section heading. */\n title?: string;\n /** Section subtitle. */\n subtitle?: string;\n /** Problem/solution pairs to render. */\n problems: ProblemSolved[];\n /** Base path for use-case story links. */\n storyBasePath?: string;\n /** Label for story links. */\n storyLabel?: string;\n /** Optional additional CSS class for the outer section. */\n className?: string;\n /** Optional child element rendered at the bottom of the section. */\n children?: ReactNode;\n}\n\n// ============================================================================\n// Component\n// ============================================================================\n\nexport function ProblemsSolvedSection({\n eyebrow,\n title,\n subtitle,\n problems,\n storyBasePath = \"/use-cases\",\n storyLabel = \"See the story\",\n className,\n children,\n}: ProblemsSolvedSectionProps) {\n return (\n <section\n className={cn(\n \"py-16 md:py-24 px-4 sm:px-6 lg:px-8 bg-muted/30\",\n className,\n )}\n >\n <div className=\"max-w-7xl mx-auto\">\n {(eyebrow || title || subtitle) && (\n <div className=\"max-w-3xl mx-auto text-center mb-12 md:mb-16\">\n {eyebrow && (\n <p className=\"text-xs font-mono uppercase tracking-widest text-primary mb-4\">\n {eyebrow}\n </p>\n )}\n {title && (\n <h2 className=\"text-3xl sm:text-4xl font-bold text-foreground mb-4\">\n {title}\n </h2>\n )}\n {subtitle && (\n <p className=\"text-lg text-muted-foreground\">{subtitle}</p>\n )}\n </div>\n )}\n\n <div className=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6\">\n {problems.map((item, index) => {\n const Icon = item.icon;\n const storyHref = item.storySlug\n ? `${storyBasePath.replace(/\\/$/, \"\")}/${item.storySlug}`\n : null;\n\n return (\n <div\n key={`${item.problem}-${index}`}\n className={cn(\n \"group relative flex flex-col rounded-2xl border border-border/40 bg-card p-6 transition-colors\",\n \"hover:border-primary/30\",\n )}\n >\n <div\n className={cn(\n \"mb-5 inline-flex h-12 w-12 items-center justify-center rounded-xl\",\n \"bg-primary/10 text-primary\",\n )}\n >\n <Icon className=\"h-6 w-6\" aria-hidden={true} />\n </div>\n\n <h3 className=\"text-lg font-semibold text-foreground mb-2\">\n {item.problem}\n </h3>\n\n <p className=\"text-sm text-muted-foreground leading-relaxed mb-4 flex-1\">\n {item.solution}\n </p>\n\n {storyHref && (\n <Button\n variant=\"ghost\"\n className=\"justify-start px-0 h-auto py-0 text-sm group/link\"\n asChild\n >\n <a\n href={storyHref}\n className=\"inline-flex items-center gap-1 text-primary hover:underline\"\n >\n {storyLabel}\n <ArrowRight\n className=\"h-3.5 w-3.5 transition-transform group-hover/link:translate-x-0.5\"\n aria-hidden=\"true\"\n />\n </a>\n </Button>\n )}\n </div>\n );\n })}\n </div>\n\n {children && <div className=\"mt-12\">{children}</div>}\n </div>\n </section>\n );\n}\n"]}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { cn } from './chunk-R7G6TWIS.mjs';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import * as LabelPrimitive from '@radix-ui/react-label';
|
|
4
|
+
import { cva } from 'class-variance-authority';
|
|
5
|
+
import { jsx } from 'react/jsx-runtime';
|
|
6
|
+
|
|
7
|
+
var labelVariants = cva(
|
|
8
|
+
"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
|
|
9
|
+
);
|
|
10
|
+
var Label = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
11
|
+
LabelPrimitive.Root,
|
|
12
|
+
{
|
|
13
|
+
ref,
|
|
14
|
+
className: cn(labelVariants(), className),
|
|
15
|
+
...props
|
|
16
|
+
}
|
|
17
|
+
));
|
|
18
|
+
Label.displayName = LabelPrimitive.Root.displayName;
|
|
19
|
+
|
|
20
|
+
export { Label };
|
|
21
|
+
//# sourceMappingURL=chunk-WTVTI5TO.mjs.map
|
|
22
|
+
//# sourceMappingURL=chunk-WTVTI5TO.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/ui/label.tsx"],"names":[],"mappings":";;;;;;AAOA,IAAM,aAAA,GAAgB,GAAA;AAAA,EACpB;AACF,CAAA;AAEA,IAAM,KAAA,GAAc,iBAIlB,CAAC,EAAE,WAAW,GAAG,KAAA,IAAS,GAAA,qBAC1B,GAAA;AAAA,EAAgB,cAAA,CAAA,IAAA;AAAA,EAAf;AAAA,IACC,GAAA;AAAA,IACA,SAAA,EAAW,EAAA,CAAG,aAAA,EAAc,EAAG,SAAS,CAAA;AAAA,IACvC,GAAG;AAAA;AACN,CACD;AACD,KAAA,CAAM,cAA6B,cAAA,CAAA,IAAA,CAAK,WAAA","file":"chunk-WTVTI5TO.mjs","sourcesContent":["import * as React from \"react\";\n\nimport * as LabelPrimitive from \"@radix-ui/react-label\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\n\nimport { cn } from \"../utils/cn\";\n\nconst labelVariants = cva(\n \"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70\",\n);\n\nconst Label = React.forwardRef<\n React.ElementRef<typeof LabelPrimitive.Root>,\n React.ComponentPropsWithoutRef<typeof LabelPrimitive.Root> &\n VariantProps<typeof labelVariants>\n>(({ className, ...props }, ref) => (\n <LabelPrimitive.Root\n ref={ref}\n className={cn(labelVariants(), className)}\n {...props}\n />\n));\nLabel.displayName = LabelPrimitive.Root.displayName;\n\nexport { Label };\n"]}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// src/analytics/events.ts
|
|
4
|
+
var MAX_PROPERTY_LENGTH = 64;
|
|
5
|
+
var EMAIL_LIKE = /[^\s@]+@[^\s@]+/;
|
|
6
|
+
function sanitizeWebsiteEventProperties(properties) {
|
|
7
|
+
const safe = {};
|
|
8
|
+
if (!properties) return safe;
|
|
9
|
+
for (const [key, value] of Object.entries(properties)) {
|
|
10
|
+
if (typeof value === "boolean") {
|
|
11
|
+
safe[key] = value;
|
|
12
|
+
} else if (typeof value === "number") {
|
|
13
|
+
if (Number.isFinite(value)) safe[key] = value;
|
|
14
|
+
} else if (typeof value === "string") {
|
|
15
|
+
const trimmed = value.trim();
|
|
16
|
+
if (trimmed.length > 0 && trimmed.length <= MAX_PROPERTY_LENGTH && !EMAIL_LIKE.test(trimmed)) {
|
|
17
|
+
safe[key] = trimmed;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return safe;
|
|
22
|
+
}
|
|
23
|
+
function trackWebsiteEvent(name, properties) {
|
|
24
|
+
if (typeof window === "undefined") return false;
|
|
25
|
+
try {
|
|
26
|
+
const rybbit = window.rybbit;
|
|
27
|
+
if (typeof rybbit?.event !== "function") return false;
|
|
28
|
+
const safe = sanitizeWebsiteEventProperties(properties);
|
|
29
|
+
if (Object.keys(safe).length > 0) {
|
|
30
|
+
rybbit.event(name, safe);
|
|
31
|
+
} else {
|
|
32
|
+
rybbit.event(name);
|
|
33
|
+
}
|
|
34
|
+
return true;
|
|
35
|
+
} catch {
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
exports.MAX_PROPERTY_LENGTH = MAX_PROPERTY_LENGTH;
|
|
41
|
+
exports.sanitizeWebsiteEventProperties = sanitizeWebsiteEventProperties;
|
|
42
|
+
exports.trackWebsiteEvent = trackWebsiteEvent;
|
|
43
|
+
//# sourceMappingURL=chunk-XJOBZ4RJ.js.map
|
|
44
|
+
//# sourceMappingURL=chunk-XJOBZ4RJ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/analytics/events.ts"],"names":[],"mappings":";;;AAqCO,IAAM,mBAAA,GAAsB;AAEnC,IAAM,UAAA,GAAa,iBAAA;AAKZ,SAAS,+BACd,UAAA,EACwB;AACxB,EAAA,MAAM,OAA+B,EAAC;AACtC,EAAA,IAAI,CAAC,YAAY,OAAO,IAAA;AACxB,EAAA,KAAA,MAAW,CAAC,GAAA,EAAK,KAAK,KAAK,MAAA,CAAO,OAAA,CAAQ,UAAU,CAAA,EAAG;AACrD,IAAA,IAAI,OAAO,UAAU,SAAA,EAAW;AAC9B,MAAA,IAAA,CAAK,GAAG,CAAA,GAAI,KAAA;AAAA,IACd,CAAA,MAAA,IAAW,OAAO,KAAA,KAAU,QAAA,EAAU;AACpC,MAAA,IAAI,OAAO,QAAA,CAAS,KAAK,CAAA,EAAG,IAAA,CAAK,GAAG,CAAA,GAAI,KAAA;AAAA,IAC1C,CAAA,MAAA,IAAW,OAAO,KAAA,KAAU,QAAA,EAAU;AACpC,MAAA,MAAM,OAAA,GAAU,MAAM,IAAA,EAAK;AAC3B,MAAA,IACE,OAAA,CAAQ,MAAA,GAAS,CAAA,IACjB,OAAA,CAAQ,MAAA,IAAU,uBAClB,CAAC,UAAA,CAAW,IAAA,CAAK,OAAO,CAAA,EACxB;AACA,QAAA,IAAA,CAAK,GAAG,CAAA,GAAI,OAAA;AAAA,MACd;AAAA,IACF;AAAA,EACF;AACA,EAAA,OAAO,IAAA;AACT;AAMO,SAAS,iBAAA,CACd,MACA,UAAA,EACS;AACT,EAAA,IAAI,OAAO,MAAA,KAAW,WAAA,EAAa,OAAO,KAAA;AAC1C,EAAA,IAAI;AACF,IAAA,MAAM,SAAS,MAAA,CAAO,MAAA;AACtB,IAAA,IAAI,OAAO,MAAA,EAAQ,KAAA,KAAU,UAAA,EAAY,OAAO,KAAA;AAChD,IAAA,MAAM,IAAA,GAAO,+BAA+B,UAAU,CAAA;AACtD,IAAA,IAAI,MAAA,CAAO,IAAA,CAAK,IAAI,CAAA,CAAE,SAAS,CAAA,EAAG;AAChC,MAAA,MAAA,CAAO,KAAA,CAAM,MAAM,IAAI,CAAA;AAAA,IACzB,CAAA,MAAO;AACL,MAAA,MAAA,CAAO,MAAM,IAAI,CAAA;AAAA,IACnB;AACA,IAAA,OAAO,IAAA;AAAA,EACT,CAAA,CAAA,MAAQ;AAEN,IAAA,OAAO,KAAA;AAAA,EACT;AACF","file":"chunk-XJOBZ4RJ.js","sourcesContent":["/**\n * Website analytics events (Rybbit custom events).\n *\n * Product websites load the Rybbit script, which records pageviews on its own.\n * Funnel facts that are not a pageview (for example a successful waitlist\n * signup) are sent through `trackWebsiteEvent`, which calls `window.rybbit.event`\n * when the script is present and does nothing otherwise.\n *\n * Privacy rules (BOFF-3167):\n * - Event names come from the closed `WebsiteEventName` union.\n * - Properties are short, low-cardinality strings, numbers or booleans. Strings\n * longer than `MAX_PROPERTY_LENGTH`, values that look like an email address,\n * and any other value type are dropped, so a caller cannot leak an email,\n * name or free text into the analytics provider by mistake.\n * - Tracking never throws: analytics must not break a signup.\n */\n\n/** Custom events product websites emit. */\nexport type WebsiteEventName = \"waitlist.signed_up\";\n\nexport type WebsiteEventPropertyValue = string | number | boolean;\n\nexport type WebsiteEventProperties = Record<string, WebsiteEventPropertyValue>;\n\ndeclare global {\n interface Window {\n /** Set by the Rybbit tracking script (https://app.rybbit.io/api/script.js). */\n rybbit?: {\n event?: (\n name: string,\n properties?: Record<string, WebsiteEventPropertyValue>,\n ) => void;\n };\n }\n}\n\n/** Longest string property value that is forwarded. */\nexport const MAX_PROPERTY_LENGTH = 64;\n\nconst EMAIL_LIKE = /[^\\s@]+@[^\\s@]+/;\n\n/**\n * Keeps only short, non-identifying primitive values. Exported for tests.\n */\nexport function sanitizeWebsiteEventProperties(\n properties: WebsiteEventProperties | undefined,\n): WebsiteEventProperties {\n const safe: WebsiteEventProperties = {};\n if (!properties) return safe;\n for (const [key, value] of Object.entries(properties)) {\n if (typeof value === \"boolean\") {\n safe[key] = value;\n } else if (typeof value === \"number\") {\n if (Number.isFinite(value)) safe[key] = value;\n } else if (typeof value === \"string\") {\n const trimmed = value.trim();\n if (\n trimmed.length > 0 &&\n trimmed.length <= MAX_PROPERTY_LENGTH &&\n !EMAIL_LIKE.test(trimmed)\n ) {\n safe[key] = trimmed;\n }\n }\n }\n return safe;\n}\n\n/**\n * Sends a custom event to Rybbit when the tracking script is loaded.\n * Returns true when the event was handed to Rybbit.\n */\nexport function trackWebsiteEvent(\n name: WebsiteEventName,\n properties?: WebsiteEventProperties,\n): boolean {\n if (typeof window === \"undefined\") return false;\n try {\n const rybbit = window.rybbit;\n if (typeof rybbit?.event !== \"function\") return false;\n const safe = sanitizeWebsiteEventProperties(properties);\n if (Object.keys(safe).length > 0) {\n rybbit.event(name, safe);\n } else {\n rybbit.event(name);\n }\n return true;\n } catch {\n // Analytics is best-effort and must never break the page.\n return false;\n }\n}\n"]}
|