@sonordev/site-kit 7.3.0 → 8.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (239) hide show
  1. package/AGENTS.md +40 -12
  2. package/CHANGELOG.md +73 -0
  3. package/README.md +44 -18
  4. package/agent-manifest.json +111 -56
  5. package/dist/AnalyticsProvider-LYFDQRRJ.js +13 -0
  6. package/dist/{ArticleViewTracker-GFOAXFV7.js → ArticleViewTracker-HG7IIRJY.js} +6 -5
  7. package/dist/{BlocksPopup-AHDU34TL.js → BlocksPopup-GFX3GZIK.js} +6 -5
  8. package/dist/{ChatWidget-FHBAHFZX.js → ChatWidget-DVS7MLBN.js} +8 -5
  9. package/dist/{FileField-J5W5MIAZ.js → FileField-DVN7NUBI.js} +5 -5
  10. package/dist/{FormSpotlight-PE5YZBFZ.js → FormSpotlight-W4SXKKO6.js} +3 -3
  11. package/dist/{FormStage-OOPQC27J.js → FormStage-JTEE5MZD.js} +3 -3
  12. package/dist/ManagedForm-ZAUHIHGP.js +19 -0
  13. package/dist/{ManagedNewsletterForm-TC5542ZG.js → ManagedNewsletterForm-DQIB5Z4Y.js} +9 -6
  14. package/dist/{SignalCore-2YP5FCAS.js → SignalCore-W5PYYMGX.js} +7 -7
  15. package/dist/SiteChat-MY2GATWC.js +6 -0
  16. package/dist/SiteDesignReporter-ICZWEGCY.js +12 -0
  17. package/dist/SitePopups-TGULLAER.js +13 -0
  18. package/dist/SitemapSync-AN2OBJE6.js +9 -0
  19. package/dist/_client/booking-widget.js +6 -5
  20. package/dist/_client/testimonial-section.d.ts +1 -1
  21. package/dist/_client/testimonial-section.js +4 -2
  22. package/dist/affiliates/index.js +6 -6
  23. package/dist/analytics/index.js +73 -7
  24. package/dist/articles/index.js +2 -2
  25. package/dist/articles/server-ui.js +3 -3
  26. package/dist/articles/server.js +2 -2
  27. package/dist/brand.css +1 -1
  28. package/dist/chat/index.d.ts +1 -1
  29. package/dist/chat/index.js +39 -8
  30. package/dist/chunk-3G7YABRA.js +25 -0
  31. package/dist/{chunk-CGWUXUYZ.js → chunk-3RDJKIYO.js} +2 -2
  32. package/dist/{chunk-J4FSB4OG.js → chunk-3YKQLC7J.js} +5 -2
  33. package/dist/{chunk-BEBR4OJD.js → chunk-56VDS2RP.js} +2 -2
  34. package/dist/chunk-5ROTTMBL.js +19 -0
  35. package/dist/{chunk-56KNHB4U.js → chunk-5S2XDG5O.js} +1 -1
  36. package/dist/chunk-5TM3WPCI.js +7 -0
  37. package/dist/{chunk-BR4ZKUHH.js → chunk-6CJGZFOU.js} +18 -2
  38. package/dist/{chunk-RYVDGXC2.js → chunk-6KU7STM3.js} +3 -1
  39. package/dist/{chunk-XLSQTTUE.js → chunk-6QFINXLH.js} +3 -3
  40. package/dist/{chunk-CYUFBKJQ.js → chunk-6ZXJ3SXR.js} +1 -1
  41. package/dist/{chunk-NI2XNEMR.js → chunk-7YEEOIWI.js} +1 -1
  42. package/dist/{chunk-DNPNYWVL.js → chunk-BQ2CXKTQ.js} +5 -20
  43. package/dist/{chunk-X6F6SO4S.js → chunk-C7TLGL3R.js} +21 -1
  44. package/dist/{chunk-43OCZ3JA.js → chunk-CAH4Y4PY.js} +4 -2
  45. package/dist/chunk-CAT235HY.js +13 -0
  46. package/dist/{chunk-PXKIGZ2F.js → chunk-EATJPSTS.js} +1 -1
  47. package/dist/{chunk-O5RGXTWU.js → chunk-GNSXOTIK.js} +6 -4
  48. package/dist/{chunk-UPRSH6Q4.js → chunk-ICAVVF6D.js} +3 -3
  49. package/dist/{chunk-2ECWEUHP.js → chunk-IJQ767JS.js} +3 -5
  50. package/dist/{chunk-MKMD2HJW.js → chunk-J65N34YM.js} +3 -3
  51. package/dist/{chunk-6U3VLV2C.js → chunk-JIH32RH2.js} +4 -4
  52. package/dist/{chunk-T4DLETKR.js → chunk-K22OLAPC.js} +2 -2
  53. package/dist/{chunk-I2YX3HVD.js → chunk-KRBBH64S.js} +3 -3
  54. package/dist/{chunk-VF4F5WXZ.js → chunk-LBIQ5LTC.js} +1 -1
  55. package/dist/{chunk-WGIDC6QP.js → chunk-LKH44GI3.js} +5 -5
  56. package/dist/{chunk-ZTLMPUO6.js → chunk-LNSF6BJC.js} +1 -1
  57. package/dist/{chunk-WDQB4OXY.js → chunk-M62U7TJF.js} +1 -1
  58. package/dist/{chunk-EDYHROQ7.js → chunk-NFRJTOTB.js} +3 -3
  59. package/dist/chunk-OD2ULW5Z.js +57 -0
  60. package/dist/{chunk-Y6LP36UW.js → chunk-OE3NXEOF.js} +2 -2
  61. package/dist/{chunk-L7U23XI2.js → chunk-OGK7OL3T.js} +5 -4
  62. package/dist/{chunk-RDPW4D33.js → chunk-PD7K54EQ.js} +2 -2
  63. package/dist/{chunk-MVR4FY5R.js → chunk-PIX7FAMX.js} +2 -2
  64. package/dist/{chunk-2AD3CDRR.js → chunk-ROAOI6GG.js} +10 -10
  65. package/dist/{chunk-YJLS6JBI.js → chunk-S7SSYGUJ.js} +6 -5
  66. package/dist/{chunk-ZKHI4E2B.js → chunk-SBPAXWLF.js} +1 -1
  67. package/dist/{chunk-ZHS2XFLV.js → chunk-TOSZGJEQ.js} +1 -1
  68. package/dist/{chunk-4NTBQNHA.js → chunk-TYAVHRWH.js} +80 -81
  69. package/dist/{chunk-Z65DHMTW.js → chunk-TZ5RTANX.js} +3 -3
  70. package/dist/{chunk-VX5CMNMM.js → chunk-UAYAJPEP.js} +7 -1
  71. package/dist/{chunk-4YTYGG2C.js → chunk-URJN75ZG.js} +29 -16
  72. package/dist/{chunk-EPT6FJUY.js → chunk-UUWUAMUC.js} +13 -16
  73. package/dist/{chunk-PKGN32AU.js → chunk-XPTJRVL2.js} +1 -1
  74. package/dist/{chunk-662ILEZ6.js → chunk-Y35BWW2C.js} +3 -7
  75. package/dist/{chunk-MRQ2U4LZ.js → chunk-ZHNQFNO3.js} +2 -2
  76. package/dist/chunk-ZKADJNR2.js +52 -0
  77. package/dist/{chunk-WGG6GTKW.js → chunk-ZLFGXKLG.js} +1 -1
  78. package/dist/client/index.js +6 -5
  79. package/dist/contracts/entries.d.ts +1 -1
  80. package/dist/contracts/sentences.d.ts +46 -0
  81. package/dist/contracts/site-cache.d.ts +2 -0
  82. package/dist/cta-bar/index.js +1 -1
  83. package/dist/fleet/index.js +6 -5
  84. package/dist/forms/field-autocomplete.d.ts +16 -8
  85. package/dist/forms/index.d.ts +5 -0
  86. package/dist/forms/index.js +17 -17
  87. package/dist/forms/server.js +7 -7
  88. package/dist/forms/static.js +2 -2
  89. package/dist/forms/submitForm.d.ts +5 -0
  90. package/dist/images/index.js +4 -4
  91. package/dist/index.d.ts +3 -7
  92. package/dist/index.js +1 -1
  93. package/dist/layout/SiteKitLayout.d.ts +2 -1
  94. package/dist/layout/client.js +11 -9
  95. package/dist/layout/index.js +14 -12
  96. package/dist/llms/index.js +8 -7
  97. package/dist/maps/index.js +6 -6
  98. package/dist/mcp/sonor.d.ts +47 -3
  99. package/dist/mcp/sonor.js +31 -21
  100. package/dist/proxy/index.d.ts +3 -3
  101. package/dist/proxy/index.js +1 -1
  102. package/dist/reputation/TestimonialSection.d.ts +1 -1
  103. package/dist/reputation/VisualReviewCard.d.ts +6 -0
  104. package/dist/reputation/index.d.ts +2 -1
  105. package/dist/reputation/index.js +5 -2
  106. package/dist/reputation/review-photo.d.ts +2 -0
  107. package/dist/reputation/server.d.ts +3 -2
  108. package/dist/reputation/server.js +4 -1
  109. package/dist/reputation/types.d.ts +22 -0
  110. package/dist/revalidate/index.js +3 -3
  111. package/dist/robots/indexnow.js +2 -2
  112. package/dist/runtime/index.d.ts +32 -0
  113. package/dist/runtime/index.js +7 -0
  114. package/dist/seo/api.d.ts +0 -4
  115. package/dist/seo/client.js +6 -5
  116. package/dist/seo/getManagedMetadata.d.ts +24 -0
  117. package/dist/seo/index.d.ts +2 -3
  118. package/dist/seo/index.js +14 -132
  119. package/dist/seo/indexnow.js +2 -2
  120. package/dist/seo/llms.js +8 -7
  121. package/dist/seo/register-sitemap-cli.js +2 -2
  122. package/dist/seo/server-api.d.ts +0 -6
  123. package/dist/seo/server.d.ts +1 -1
  124. package/dist/seo/server.js +4 -4
  125. package/dist/seo/sitemap.js +5 -4
  126. package/dist/seo/types.d.ts +9 -30
  127. package/dist/server/index.d.ts +8 -1
  128. package/dist/server/index.js +5 -4
  129. package/dist/server/mint-site-token.d.ts +1 -13
  130. package/dist/server/server-fetch.d.ts +19 -0
  131. package/dist/server-api-EGOKC7Q3.js +9 -0
  132. package/dist/shared/build-entries.d.ts +21 -9
  133. package/dist/shared/clientApiConfig.d.ts +56 -0
  134. package/dist/shared/fresh-fetch.d.ts +9 -3
  135. package/dist/shared/identity-reader.d.ts +26 -0
  136. package/dist/shared/identity-storage.d.ts +30 -0
  137. package/dist/shared/identity.d.ts +13 -13
  138. package/dist/shared/import-specifiers.d.ts +26 -0
  139. package/dist/shared/sonorFetch.d.ts +4 -3
  140. package/dist/shared/version.d.ts +1 -1
  141. package/dist/signal/index.js +2 -2
  142. package/dist/sitemap/index.js +5 -4
  143. package/dist/slots/index.js +3 -3
  144. package/dist/sync/index.js +6 -5
  145. package/dist/types.d.ts +0 -1
  146. package/dist/website/cta-bar.js +1 -1
  147. package/dist/website/images.js +4 -4
  148. package/dist/website/index.js +7 -6
  149. package/dist/website/popups.js +10 -7
  150. package/dist/website/slots.js +3 -3
  151. package/dist/{writeLLMsTxt-2NQVDGYI.js → writeLLMsTxt-UZGN6IBU.js} +4 -3
  152. package/docs/MIGRATING-TO-7.md +5 -2
  153. package/docs/MIGRATING-TO-8.md +183 -0
  154. package/docs.json +4 -8
  155. package/package.json +15 -44
  156. package/skills/site-kit/SKILL.md +41 -11
  157. package/src/analytics/README.md +14 -14
  158. package/src/chat/README.md +7 -7
  159. package/src/forms/README.md +61 -6
  160. package/src/mcp/README.md +61 -20
  161. package/src/proxy/README.md +5 -4
  162. package/src/reputation/README.md +25 -0
  163. package/src/revalidate/README.md +2 -2
  164. package/src/runtime/README.md +51 -0
  165. package/src/seo/README.md +24 -8
  166. package/src/sync/README.md +2 -2
  167. package/src/website/README.md +3 -2
  168. package/dist/AnalyticsProvider-DJQA66AG.js +0 -11
  169. package/dist/ManagedForm-JRZAJ7SZ.js +0 -16
  170. package/dist/SiteChat-EGEZJJVV.js +0 -5
  171. package/dist/SiteDesignReporter-YEEWJKWN.js +0 -11
  172. package/dist/SitePopups-LQBIXIFV.js +0 -10
  173. package/dist/SitemapSync-LSZ2EYOF.js +0 -8
  174. package/dist/chunk-24QZEO3Q.js +0 -41
  175. package/dist/chunk-BU66S5B7.js +0 -1
  176. package/dist/chunk-G3NHWMP5.js +0 -233
  177. package/dist/chunk-HODO5BX5.js +0 -28
  178. package/dist/chunk-L3AQCDCY.js +0 -386
  179. package/dist/chunk-P5GB6NEO.js +0 -66
  180. package/dist/chunk-SWKE6FWH.js +0 -47
  181. package/dist/cms/CmsPage.d.ts +0 -17
  182. package/dist/cms/CmsPreview.d.ts +0 -37
  183. package/dist/cms/CmsSection.d.ts +0 -8
  184. package/dist/cms/PortableTextRenderer.d.ts +0 -7
  185. package/dist/cms/index.d.ts +0 -37
  186. package/dist/cms/index.js +0 -5
  187. package/dist/cms/sanity-image.d.ts +0 -47
  188. package/dist/cms/sections/CtaSection.d.ts +0 -3
  189. package/dist/cms/sections/CustomSection.d.ts +0 -7
  190. package/dist/cms/sections/FaqSection.d.ts +0 -3
  191. package/dist/cms/sections/FormSection.d.ts +0 -8
  192. package/dist/cms/sections/GallerySection.d.ts +0 -3
  193. package/dist/cms/sections/HeroSection.d.ts +0 -3
  194. package/dist/cms/sections/RichTextSection.d.ts +0 -3
  195. package/dist/cms/sections/TestimonialsSection.d.ts +0 -3
  196. package/dist/cms/sections/index.d.ts +0 -8
  197. package/dist/cms/server-api.d.ts +0 -49
  198. package/dist/cms/server.d.ts +0 -1
  199. package/dist/cms/server.js +0 -5
  200. package/dist/cms/types.d.ts +0 -104
  201. package/dist/commerce/CalendarView.d.ts +0 -43
  202. package/dist/commerce/CheckoutForm.d.ts +0 -11
  203. package/dist/commerce/EventCalendar.d.ts +0 -26
  204. package/dist/commerce/EventCheckout.d.ts +0 -42
  205. package/dist/commerce/EventEmbed.d.ts +0 -11
  206. package/dist/commerce/EventModal.d.ts +0 -43
  207. package/dist/commerce/EventTile.d.ts +0 -10
  208. package/dist/commerce/EventsAgenda.d.ts +0 -38
  209. package/dist/commerce/EventsWidget.d.ts +0 -84
  210. package/dist/commerce/OfferingCard.d.ts +0 -9
  211. package/dist/commerce/OfferingList.d.ts +0 -9
  212. package/dist/commerce/ProductDetail.d.ts +0 -38
  213. package/dist/commerce/ProductEmbed.d.ts +0 -11
  214. package/dist/commerce/ProductGrid.d.ts +0 -41
  215. package/dist/commerce/ProductPage.d.ts +0 -39
  216. package/dist/commerce/RegistrationForm.d.ts +0 -9
  217. package/dist/commerce/SizeChart.d.ts +0 -8
  218. package/dist/commerce/UpcomingEvents.d.ts +0 -9
  219. package/dist/commerce/api.d.ts +0 -179
  220. package/dist/commerce/events-extras.d.ts +0 -60
  221. package/dist/commerce/index.d.ts +0 -33
  222. package/dist/commerce/index.js +0 -8022
  223. package/dist/commerce/server.d.ts +0 -161
  224. package/dist/commerce/server.js +0 -2
  225. package/dist/commerce/types.d.ts +0 -340
  226. package/dist/commerce/useEventModal.d.ts +0 -20
  227. package/dist/commerce/utils.d.ts +0 -17
  228. package/dist/engage/EngageWidget.d.ts +0 -21
  229. package/dist/engage/index.d.ts +0 -14
  230. package/dist/engage/index.js +0 -45
  231. package/dist/engage/types.d.ts +0 -33
  232. package/dist/seo/ManagedContent.d.ts +0 -14
  233. package/dist/server-api-BVCBLJKL.js +0 -9
  234. package/dist/website/cms/server.d.ts +0 -2
  235. package/dist/website/cms/server.js +0 -5
  236. package/dist/website/cms-server.d.ts +0 -2
  237. package/dist/website/cms.d.ts +0 -2
  238. package/dist/website/cms.js +0 -5
  239. package/src/commerce/README.md +0 -109
@@ -0,0 +1,7 @@
1
+ // src/shared/identity-storage.ts
2
+ var VISITOR_ID_KEY = "_sk_vid";
3
+ var SESSION_ID_KEY = "_sk_sid";
4
+ var SESSION_TIME_KEY = "_sk_stime";
5
+ var memoryIdentity = { visitorId: "", sessionId: "" };
6
+
7
+ export { SESSION_ID_KEY, SESSION_TIME_KEY, VISITOR_ID_KEY, memoryIdentity };
@@ -1,5 +1,6 @@
1
1
  'use client';
2
- import { fetchReviews } from './chunk-EDYHROQ7.js';
2
+ import { reviewPhotoUrl } from './chunk-CAT235HY.js';
3
+ import { fetchReviews } from './chunk-NFRJTOTB.js';
3
4
  import { useState, useEffect, useCallback } from 'react';
4
5
  import { jsxs, jsx } from 'react/jsx-runtime';
5
6
 
@@ -9,6 +10,7 @@ function TestimonialSection({
9
10
  autoplay = true,
10
11
  autoplayInterval = 5e3,
11
12
  showRating = true,
13
+ showPhoto = true,
12
14
  maxReviews,
13
15
  featuredOnly = false,
14
16
  service,
@@ -19,6 +21,7 @@ function TestimonialSection({
19
21
  const [isLoading, setIsLoading] = useState(true);
20
22
  const [direction, setDirection] = useState("next");
21
23
  useEffect(() => {
24
+ let active = true;
22
25
  async function loadReviews() {
23
26
  setIsLoading(true);
24
27
  const data = await fetchReviews({
@@ -26,10 +29,15 @@ function TestimonialSection({
26
29
  limit: maxReviews,
27
30
  featured: featuredOnly
28
31
  });
32
+ if (!active) return;
29
33
  setReviews(data);
34
+ setCurrentIndex(0);
30
35
  setIsLoading(false);
31
36
  }
32
37
  loadReviews();
38
+ return () => {
39
+ active = false;
40
+ };
33
41
  }, [service, maxReviews, featuredOnly]);
34
42
  useEffect(() => {
35
43
  if (!autoplay || reviews.length <= 1) return;
@@ -58,6 +66,7 @@ function TestimonialSection({
58
66
  return null;
59
67
  }
60
68
  const currentReview = reviews[currentIndex];
69
+ const photoUrl = showPhoto ? reviewPhotoUrl(currentReview.photo?.url) : void 0;
61
70
  return /* @__PURE__ */ jsxs("section", { className: `testimonial-section ${className}`, "data-site-kit-testimonials": true, children: [
62
71
  /* @__PURE__ */ jsx("style", { children: `
63
72
  .testimonial-section {
@@ -69,6 +78,9 @@ function TestimonialSection({
69
78
  position: relative;
70
79
  overflow: hidden;
71
80
  }
81
+ .sk-testimonial-photo { margin:0 auto 1.5rem;max-width:42rem;overflow:hidden;border-radius:var(--sk-radius-lg,.75rem);background:var(--sk-surface); }
82
+ .sk-testimonial-photo img { display:block;width:100%;aspect-ratio:4/3;object-fit:cover; }
83
+ .sk-testimonial-photo figcaption { padding:.75rem 1rem;color:var(--sk-text-secondary);font-size:.875rem;line-height:1.5;overflow-wrap:anywhere; }
72
84
 
73
85
  .testimonial-slide {
74
86
  animation: ${direction === "next" ? "slideInRight" : "slideInLeft"} 0.6s cubic-bezier(0.4, 0, 0.2, 1);
@@ -175,8 +187,12 @@ function TestimonialSection({
175
187
  title && /* @__PURE__ */ jsx("h2", { className: "testimonial-title", children: title }),
176
188
  subtitle && /* @__PURE__ */ jsx("p", { className: "testimonial-subtitle", children: subtitle }),
177
189
  /* @__PURE__ */ jsx("div", { className: "testimonial-content", children: /* @__PURE__ */ jsxs("div", { className: "testimonial-slide", children: [
190
+ photoUrl && /* @__PURE__ */ jsxs("figure", { className: "sk-testimonial-photo", children: [
191
+ /* @__PURE__ */ jsx("img", { src: photoUrl, alt: currentReview.photo?.altText || `Photo accompanying ${currentReview.name}'s review`, loading: "lazy", decoding: "async" }),
192
+ currentReview.photo?.caption && /* @__PURE__ */ jsx("figcaption", { children: currentReview.photo.caption })
193
+ ] }),
178
194
  /* @__PURE__ */ jsx("div", { className: "testimonial-quote-icon", children: "\u201C" }),
179
- showRating && /* @__PURE__ */ jsx("div", { className: "testimonial-stars", children: [...Array(5)].map((_, i) => /* @__PURE__ */ jsx(
195
+ showRating && /* @__PURE__ */ jsx("div", { className: "testimonial-stars", role: "img", "aria-label": `${currentReview.rating} out of 5 stars`, children: [...Array(5)].map((_, i) => /* @__PURE__ */ jsx(
180
196
  "span",
181
197
  {
182
198
  className: `star ${i < currentReview.rating ? "star-filled" : "star-empty"}`,
@@ -10,7 +10,9 @@ var SITE_CACHE_TAGS = {
10
10
  /** Article categories and tags. */
11
11
  taxonomy: "editorial-taxonomy",
12
12
  /** Portfolio items (agency-site-kit). */
13
- portfolio: "portfolio"
13
+ portfolio: "portfolio",
14
+ /** Products, services, events and membership plans (commerce-kit). */
15
+ commerce: "commerce"
14
16
  };
15
17
  function isSiteRevalidatePong(body) {
16
18
  return typeof body === "object" && body !== null && body.ok === true && body.ping === true;
@@ -1,6 +1,6 @@
1
- import { FormEnhancer } from './chunk-MVR4FY5R.js';
2
- import { StaticForm } from './chunk-ZTLMPUO6.js';
3
- import { serverApiFetch } from './chunk-X6F6SO4S.js';
1
+ import { FormEnhancer } from './chunk-PIX7FAMX.js';
2
+ import { StaticForm } from './chunk-LNSF6BJC.js';
3
+ import { serverApiFetch } from './chunk-C7TLGL3R.js';
4
4
  import { jsx } from 'react/jsx-runtime';
5
5
 
6
6
  async function ServerForm({
@@ -54,7 +54,7 @@ function useSignal() {
54
54
  return useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
55
55
  }
56
56
  var LazySignalCore = dynamic(
57
- () => import('./SignalCore-2YP5FCAS.js').then((m) => ({ default: m.SignalCore })),
57
+ () => import('./SignalCore-W5PYYMGX.js').then((m) => ({ default: m.SignalCore })),
58
58
  { ssr: false }
59
59
  );
60
60
  function SignalBridge({
@@ -1,5 +1,5 @@
1
1
  import { secretsMatch, readCappedBody } from './chunk-XTRZGXB2.js';
2
- import { SITE_KIT_VERSION } from './chunk-56KNHB4U.js';
2
+ import { SITE_KIT_VERSION } from './chunk-5S2XDG5O.js';
3
3
 
4
4
  // src/llms/revalidate.ts
5
5
  function createLlmsRevalidateHandler(secret, options) {
@@ -1,6 +1,7 @@
1
- import { resolveFetch } from './chunk-VX5CMNMM.js';
1
+ import { trackedFreshFetch } from './chunk-UAYAJPEP.js';
2
+ import { isNextControlFlow } from './chunk-C7TLGL3R.js';
2
3
  import { monotonicMs } from './chunk-MH2DSGC6.js';
3
- import { SITE_KIT_VERSION } from './chunk-56KNHB4U.js';
4
+ import { SITE_KIT_VERSION } from './chunk-5S2XDG5O.js';
4
5
  import 'server-only';
5
6
 
6
7
  var MINT_PATH = "/api/public/site-token";
@@ -37,15 +38,6 @@ function failClosed(reason, rawKey, now) {
37
38
  `site-kit: could not mint a site token (${reason}). Refusing to publish the raw SONOR_API_KEY in page HTML, so this build fails instead. Check that the mint endpoint is reachable and the key is valid, then rebuild. To ship anyway \u2014 which publishes the project secret in public HTML \u2014 set SONOR_SITE_TOKEN_FALLBACK=raw.`
38
39
  );
39
40
  }
40
- function isFrameworkSignal(err) {
41
- if (!err || typeof err !== "object") return false;
42
- const e = err;
43
- if (e.digest === "DYNAMIC_SERVER_USAGE") return true;
44
- if (e.code === "NEXT_STATIC_GEN_BAILOUT") return true;
45
- if (typeof e.digest === "string" && e.digest.startsWith("NEXT_")) return true;
46
- if (e.$$typeof === /* @__PURE__ */ Symbol.for("react.postpone")) return true;
47
- return false;
48
- }
49
41
  async function resolveClientCredential(rawKey, apiUrl) {
50
42
  if (!rawKey) return "";
51
43
  if (rawKey.startsWith(SITE_TOKEN_PREFIX)) return rawKey;
@@ -67,24 +59,17 @@ async function mintWithRetry(rawKey, apiUrl) {
67
59
  for (let attempt = 0; attempt < MINT_MAX_ATTEMPTS; attempt++) {
68
60
  let res = null;
69
61
  try {
70
- const { fn: fetchFn, unpatched } = resolveFetch();
71
- res = await fetchFn(`${base}${MINT_PATH}`, {
62
+ res = await trackedFreshFetch(`${base}${MINT_PATH}`, {
72
63
  method: "POST",
73
64
  headers: {
74
65
  "content-type": "application/json",
75
66
  "x-api-key": rawKey,
76
67
  "x-sitekit-version": SITE_KIT_VERSION
77
68
  },
78
- // Only meaningful on the fallback path, where a future Next stopped
79
- // exposing `_nextOriginalFetch` and we're back on the patched fetch.
80
- // `revalidate: false` is the one setting that neither bails out of static
81
- // generation nor downgrades the route to ISR; a Data Cache entry is the
82
- // lesser evil versus shipping the raw key again.
83
- ...unpatched ? {} : { next: { revalidate: false } },
84
69
  signal: typeof AbortSignal !== "undefined" && AbortSignal.timeout ? AbortSignal.timeout(MINT_TIMEOUT_MS) : void 0
85
70
  });
86
71
  } catch (err) {
87
- if (isFrameworkSignal(err)) throw err;
72
+ if (isNextControlFlow(err)) throw err;
88
73
  lastReason = err instanceof Error ? err.message : "network error";
89
74
  if (attempt < MINT_MAX_ATTEMPTS - 1) {
90
75
  await sleep(retryDelayMs(null, attempt));
@@ -37,6 +37,25 @@ function attemptSignal(budgetMs, callerSignal) {
37
37
  function sleep(ms) {
38
38
  return new Promise((resolve) => setTimeout(resolve, ms));
39
39
  }
40
+ var NEXT_CONTROL_DIGESTS = /* @__PURE__ */ new Set([
41
+ "DYNAMIC_SERVER_USAGE",
42
+ "BAILOUT_TO_CLIENT_SIDE_RENDERING",
43
+ "HANGING_PROMISE_REJECTION"
44
+ ]);
45
+ var REACT_POSTPONE = /* @__PURE__ */ Symbol.for("react.postpone");
46
+ function isNextControlFlow(error) {
47
+ for (let current = error, depth = 0; current && typeof current === "object" && depth < 5; depth++) {
48
+ const { digest, code, message } = current;
49
+ if (typeof digest === "string" && (NEXT_CONTROL_DIGESTS.has(digest) || digest.startsWith("NEXT_"))) return true;
50
+ if (code === "NEXT_STATIC_GEN_BAILOUT") return true;
51
+ if (current.$$typeof === REACT_POSTPONE) return true;
52
+ if (typeof message === "string" && message.includes("needs to bail out of prerendering at this point because it used") && message.includes("ppr-caught-error")) {
53
+ return true;
54
+ }
55
+ current = current.cause;
56
+ }
57
+ return false;
58
+ }
40
59
  async function serverApiFetch(path, options = {}) {
41
60
  const {
42
61
  method = "GET",
@@ -116,6 +135,7 @@ async function serverApiFetch(path, options = {}) {
116
135
  }
117
136
  return await response.json();
118
137
  } catch (error) {
138
+ if (isNextControlFlow(error)) throw error;
119
139
  if (retry && attempt < attempts && monotonicMs() < deadline) {
120
140
  await sleep(
121
141
  Math.min(200 * attempt * attempt + retryJitter() * 150, Math.max(0, deadline - monotonicMs()))
@@ -132,4 +152,4 @@ async function serverApiFetch(path, options = {}) {
132
152
  return null;
133
153
  }
134
154
 
135
- export { requireServerApiConfig, resolveApiOrigin, resolveServerApiConfig, serverApiFetch };
155
+ export { isNextControlFlow, requireServerApiConfig, resolveApiOrigin, resolveServerApiConfig, serverApiFetch };
@@ -1,4 +1,5 @@
1
1
  import { FRAME_READY_MESSAGE } from './chunk-EKBEOXTH.js';
2
+ import { readPublishedApiConfig, DEFAULT_SONOR_API_URL } from './chunk-3G7YABRA.js';
2
3
 
3
4
  // src/shared/frame.ts
4
5
  function isFramed() {
@@ -48,8 +49,9 @@ function announceFrameReady() {
48
49
  var announcedSuppression = false;
49
50
  function resolveAnalyticsTarget(options = {}) {
50
51
  const config = typeof window === "undefined" ? void 0 : window;
51
- const apiUrl = options.apiUrl || config?.__SITE_KIT_API_URL__ || "https://api.sonor.io";
52
- const apiKey = options.apiKey || config?.__SITE_KIT_API_KEY__;
52
+ const published = readPublishedApiConfig();
53
+ const apiUrl = options.apiUrl || published.apiUrl || DEFAULT_SONOR_API_URL;
54
+ const apiKey = options.apiKey || published.apiKey;
53
55
  if (!apiKey) return null;
54
56
  const hostname = (config?.location?.hostname || "").toLowerCase().replace(/\.+$/, "");
55
57
  const local = hostname === "localhost" || hostname.endsWith(".localhost") || hostname === "127.0.0.1" || hostname === "[::1]" || hostname === "::1" || hostname === "0.0.0.0";
@@ -0,0 +1,13 @@
1
+ // src/reputation/review-photo.ts
2
+ function reviewPhotoUrl(value) {
3
+ if (typeof value !== "string" || value.length > 2048) return void 0;
4
+ try {
5
+ const url = new URL(value);
6
+ if (url.protocol !== "https:" || url.username || url.password) return void 0;
7
+ return url.href;
8
+ } catch {
9
+ return void 0;
10
+ }
11
+ }
12
+
13
+ export { reviewPhotoUrl };
@@ -1,4 +1,4 @@
1
- import { serverApiFetch } from './chunk-X6F6SO4S.js';
1
+ import { serverApiFetch } from './chunk-C7TLGL3R.js';
2
2
 
3
3
  // src/robots/indexnow.ts
4
4
  var INDEXNOW_KEY_PATH = "/indexnow.txt";
@@ -2,9 +2,10 @@
2
2
  import { VISUAL_VIEWPORT_GAP_PROPERTY } from './chunk-6T6CQVNL.js';
3
3
  import { GlassStyles } from './chunk-JE4A5S4F.js';
4
4
  import { DEFAULT_WIDGET_Z_INDEX } from './chunk-27FISYK4.js';
5
- import { useForm } from './chunk-EPT6FJUY.js';
5
+ import { useForm } from './chunk-UUWUAMUC.js';
6
6
  import { parseColor, relativeLuminance, DARK_LUMINANCE, contrastRatio } from './chunk-S22FSH7C.js';
7
- import { sonorFetch } from './chunk-BEBR4OJD.js';
7
+ import { readPublishedApiConfig } from './chunk-3G7YABRA.js';
8
+ import { sonorFetch } from './chunk-56VDS2RP.js';
8
9
  import { useState, useEffect, useRef, useLayoutEffect, useCallback, Fragment as Fragment$1 } from 'react';
9
10
  import { lexer } from 'marked';
10
11
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
@@ -556,8 +557,9 @@ function getApiConfig() {
556
557
  const isDev = typeof process !== "undefined" && process.env?.NODE_ENV === "development";
557
558
  const defaultApiUrl = isDev && process.env?.SONOR_API_URL ? process.env.SONOR_API_URL : "https://api.sonor.io";
558
559
  const defaultSignalUrl = isDev && (process.env?.SONOR_SIGNAL_URL || process.env?.NEXT_PUBLIC_SIGNAL_API_URL) ? process.env.SONOR_SIGNAL_URL || process.env.NEXT_PUBLIC_SIGNAL_API_URL : "https://signal.sonor.io";
559
- const apiUrl = typeof window !== "undefined" ? window.__SITE_KIT_API_URL__ || defaultApiUrl : defaultApiUrl;
560
- const apiKey = typeof window !== "undefined" ? window.__SITE_KIT_API_KEY__ : void 0;
560
+ const published = readPublishedApiConfig();
561
+ const apiUrl = published.apiUrl || defaultApiUrl;
562
+ const apiKey = published.apiKey;
561
563
  const signalUrl = typeof window !== "undefined" ? window.__SITE_KIT_SIGNAL_URL__ || defaultSignalUrl : defaultSignalUrl;
562
564
  return { apiUrl, apiKey, signalUrl };
563
565
  }
@@ -1,9 +1,9 @@
1
1
  'use client';
2
2
  import { sanitizeFleetVersion, buildFleetHeartbeatPayload } from './chunk-ZTZQPYP6.js';
3
3
  import { useDeferredActivation } from './chunk-YC7ELZS3.js';
4
- import { resolveAnalyticsTarget } from './chunk-43OCZ3JA.js';
5
- import { sonorFetch } from './chunk-BEBR4OJD.js';
6
- import { SITE_KIT_VERSION } from './chunk-56KNHB4U.js';
4
+ import { resolveAnalyticsTarget } from './chunk-CAH4Y4PY.js';
5
+ import { sonorFetch } from './chunk-56VDS2RP.js';
6
+ import { SITE_KIT_VERSION } from './chunk-5S2XDG5O.js';
7
7
  import { useRef, useEffect } from 'react';
8
8
 
9
9
  // src/fleet/heartbeat.ts
@@ -1,11 +1,9 @@
1
- import { sonorFetch } from './chunk-BEBR4OJD.js';
1
+ import { getClientApiConfig } from './chunk-3G7YABRA.js';
2
+ import { sonorFetch } from './chunk-56VDS2RP.js';
2
3
 
3
4
  // src/sync/api.ts
4
- var DEFAULT_API_URL = "https://api.sonor.io";
5
5
  function getApiConfig() {
6
- const apiUrl = typeof window !== "undefined" ? window.__SITE_KIT_API_URL__ || DEFAULT_API_URL : DEFAULT_API_URL;
7
- const apiKey = typeof window !== "undefined" ? window.__SITE_KIT_API_KEY__ : void 0;
8
- return { apiUrl, apiKey };
6
+ return getClientApiConfig();
9
7
  }
10
8
  function buildHeaders(isPost = false) {
11
9
  const headers = {};
@@ -1,9 +1,9 @@
1
1
  'use client';
2
2
  import { registerAnalyticsDispatcher } from './chunk-LCDVPAMR.js';
3
- import { getOrCreateVisitorId, getOrCreateSessionId } from './chunk-24QZEO3Q.js';
3
+ import { getOrCreateVisitorId, getOrCreateSessionId } from './chunk-ZKADJNR2.js';
4
4
  import { onPageLeave } from './chunk-L2V5PUFN.js';
5
- import { resolveAnalyticsTarget } from './chunk-43OCZ3JA.js';
6
- import { sonorFetch, sonorBeacon } from './chunk-BEBR4OJD.js';
5
+ import { resolveAnalyticsTarget } from './chunk-CAH4Y4PY.js';
6
+ import { sonorFetch, sonorBeacon } from './chunk-56VDS2RP.js';
7
7
  import { createContext, useRef, useEffect, useState, useMemo, useCallback, useContext } from 'react';
8
8
  import { usePathname } from 'next/navigation';
9
9
  import { jsxs, jsx } from 'react/jsx-runtime';
@@ -1,12 +1,12 @@
1
- import { freshFetch } from './chunk-VX5CMNMM.js';
1
+ import { freshFetch } from './chunk-UAYAJPEP.js';
2
2
  import { LLM_GEO_CONTRACT_VERSION } from './chunk-NZ4RXN3G.js';
3
3
  import { withSiteParam } from './chunk-MJP63SSS.js';
4
+ import { getClientApiConfig } from './chunk-3G7YABRA.js';
4
5
  import { cache } from 'react';
5
6
 
6
7
  function getApiConfig() {
7
- const apiUrl = typeof window !== "undefined" && window.__SITE_KIT_API_URL__ || process.env.SONOR_API_URL || "https://api.sonor.io";
8
- const apiKey = typeof window !== "undefined" && window.__SITE_KIT_API_KEY__ || process.env.SONOR_API_KEY || "";
9
- return { apiUrl, apiKey };
8
+ const { apiUrl, apiKey } = getClientApiConfig({ serverKey: true });
9
+ return { apiUrl, apiKey: apiKey ?? "" };
10
10
  }
11
11
  async function apiGet(endpoint, options) {
12
12
  const { apiUrl, apiKey } = getApiConfig();
@@ -1,7 +1,7 @@
1
1
  'use client';
2
2
  import { locToPath, isMalformedSitemapPath, inferPageType } from './chunk-YVKRYQRG.js';
3
- import { resolveAnalyticsTarget } from './chunk-43OCZ3JA.js';
4
- import { sonorFetch } from './chunk-BEBR4OJD.js';
3
+ import { resolveAnalyticsTarget } from './chunk-CAH4Y4PY.js';
4
+ import { sonorFetch } from './chunk-56VDS2RP.js';
5
5
  import { useRef, useEffect } from 'react';
6
6
 
7
7
  var SYNC_STAMP_KEY = "_sk_sitemap_synced_at";
@@ -1,8 +1,8 @@
1
1
  import { toHexColor, normalizeDesignTokens, designTokensHash } from './chunk-IHG36STL.js';
2
2
  import { contrastRatio, parseColor, relativeLuminance } from './chunk-S22FSH7C.js';
3
- import { resolveAnalyticsTarget } from './chunk-43OCZ3JA.js';
4
- import { sonorFetch } from './chunk-BEBR4OJD.js';
5
- import { SITE_KIT_VERSION } from './chunk-56KNHB4U.js';
3
+ import { resolveAnalyticsTarget } from './chunk-CAH4Y4PY.js';
4
+ import { sonorFetch } from './chunk-56VDS2RP.js';
5
+ import { SITE_KIT_VERSION } from './chunk-5S2XDG5O.js';
6
6
 
7
7
  // src/website/design.ts
8
8
  var SITE_DESIGN_PATH = "/api/public/site/design";
@@ -1,5 +1,5 @@
1
1
  import { resolveSiteHost } from './chunk-FESKKJAS.js';
2
- import { configureSiteCredential, currentCredential } from './chunk-WGG6GTKW.js';
2
+ import { configureSiteCredential, currentCredential } from './chunk-ZLFGXKLG.js';
3
3
 
4
4
  // src/shared/publishCredential.ts
5
5
  function publishSiteCredential({
@@ -1,10 +1,10 @@
1
1
  'use client';
2
- import { countStageViews, countStageQuestions, useFieldControls } from './chunk-ZKHI4E2B.js';
3
- import { HoneypotField } from './chunk-DXO6SBMD.js';
4
- import { DelightStyles, FormMomentum, FormField } from './chunk-4NTBQNHA.js';
5
- import { useFormLoadedAt, useFormTracking, submitForm, useRecaptchaWarmup, useForm } from './chunk-EPT6FJUY.js';
2
+ import { countStageViews, countStageQuestions, useFieldControls } from './chunk-SBPAXWLF.js';
3
+ import { useFormLoadedAt, useFormTracking, submitForm, useRecaptchaWarmup, useForm } from './chunk-UUWUAMUC.js';
6
4
  import { readAgentSubmit, formToolAttributes } from './chunk-Q6E4OPGG.js';
7
5
  import { isFieldVisible, validateField, isFieldComplete, isDisplayOnly, unseenControlValues } from './chunk-C2FZBUSS.js';
6
+ import { HoneypotField } from './chunk-DXO6SBMD.js';
7
+ import { DelightStyles, FormMomentum, FormField } from './chunk-TYAVHRWH.js';
8
8
  import { DEFAULT_FORM_SUCCESS_MESSAGE } from './chunk-5SQK3D53.js';
9
9
  import { DEFAULT_HONEYPOT_FIELD } from './chunk-NJCTQH2P.js';
10
10
  import { useState, useRef, useMemo, useEffect, useCallback } from 'react';
@@ -63,7 +63,7 @@ function FormClient({
63
63
  return;
64
64
  }
65
65
  let cancelled = false;
66
- const load = resolvedExperience === "stage" ? import('./FormStage-OOPQC27J.js').then((m) => m.FormStage) : import('./FormSpotlight-PE5YZBFZ.js').then((m) => m.FormSpotlight);
66
+ const load = resolvedExperience === "stage" ? import('./FormStage-JTEE5MZD.js').then((m) => m.FormStage) : import('./FormSpotlight-W4SXKKO6.js').then((m) => m.FormSpotlight);
67
67
  load.then((Component) => {
68
68
  if (!cancelled) setExperience(() => Component);
69
69
  }).catch((err) => {
@@ -1,5 +1,5 @@
1
1
  import { HoneypotField } from './chunk-DXO6SBMD.js';
2
- import { FormField } from './chunk-4NTBQNHA.js';
2
+ import { FormField } from './chunk-TYAVHRWH.js';
3
3
  import { normalizeFormConfig } from './chunk-5SQK3D53.js';
4
4
  import { DEFAULT_HONEYPOT_FIELD } from './chunk-NJCTQH2P.js';
5
5
  import { jsxs, jsx } from 'react/jsx-runtime';
@@ -1,4 +1,4 @@
1
- import { generateLLMsTxt, generateLLMsFullTxt, appendAgentAccessSection } from './chunk-Z65DHMTW.js';
1
+ import { generateLLMsTxt, generateLLMsFullTxt, appendAgentAccessSection } from './chunk-TZ5RTANX.js';
2
2
  import { createHash } from 'crypto';
3
3
  import { existsSync, readFileSync } from 'fs';
4
4
  import { join } from 'path';
@@ -1,12 +1,12 @@
1
1
  import { monotonicMs } from './chunk-MH2DSGC6.js';
2
+ import { getClientApiConfig } from './chunk-3G7YABRA.js';
2
3
 
3
4
  // src/reputation/api.ts
4
5
  var reviewsCache = /* @__PURE__ */ new Map();
5
6
  var CACHE_TTL = 6e4;
6
7
  function getApiConfig() {
7
- const apiUrl = typeof window !== "undefined" ? window.__SITE_KIT_API_URL__ || "https://api.sonor.io" : process.env.SONOR_API_URL || "https://api.sonor.io";
8
- const apiKey = typeof window !== "undefined" ? window.__SITE_KIT_API_KEY__ || "" : process.env.SONOR_API_KEY || "";
9
- return { apiUrl, apiKey };
8
+ const { apiUrl, apiKey } = getClientApiConfig({ serverKey: true });
9
+ return { apiUrl, apiKey: apiKey ?? "" };
10
10
  }
11
11
  async function fetchWithRetry(url, headers, retries = 2) {
12
12
  for (let attempt = 0; attempt <= retries; attempt++) {
@@ -0,0 +1,57 @@
1
+ import { reviewPhotoUrl } from './chunk-CAT235HY.js';
2
+ import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
3
+
4
+ var styles = `
5
+ .sk-visual-review-gallery{font-family:var(--sk-font,inherit);color:var(--sk-text-primary);padding-block:2rem}
6
+ .sk-visual-review-gallery-header{margin-block-end:1.5rem}.sk-visual-review-gallery-header h2{margin:0 0 .5rem}.sk-visual-review-gallery-header p{margin:0;color:var(--sk-text-secondary)}
7
+ .sk-visual-review-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,19rem),1fr));gap:1.5rem;align-items:start}
8
+ .sk-visual-review{min-width:0;overflow:hidden;border:1px solid var(--sk-surface-border);border-radius:var(--sk-radius-lg,.75rem);background:var(--sk-bg);color:var(--sk-text-primary);font-family:var(--sk-font,inherit)}
9
+ .sk-visual-review-photo{margin:0;background:var(--sk-surface)}.sk-visual-review-photo img{display:block;aspect-ratio:4/3;width:100%;object-fit:cover}
10
+ .sk-visual-review-photo figcaption{padding:.75rem 1rem;color:var(--sk-text-secondary);font-size:.875rem;line-height:1.5;overflow-wrap:anywhere}
11
+ .sk-visual-review-body{position:relative;padding:1.5rem;border-block-start:3px solid var(--sk-primary)}
12
+ .sk-visual-review-stars{display:flex;gap:.2rem;margin-block-end:1rem;color:var(--sk-primary)}.sk-visual-review-star-empty{opacity:.25}
13
+ .sk-visual-review blockquote{margin:0;font-size:1.125rem;line-height:1.7;white-space:pre-line;overflow-wrap:anywhere}
14
+ .sk-visual-review-author{display:flex;align-items:center;gap:.75rem;margin-block-start:1.25rem}.sk-visual-review-avatar{width:2.75rem;height:2.75rem;border-radius:50%;object-fit:cover;flex:none}
15
+ .sk-visual-review-name{font-weight:600;overflow-wrap:anywhere}.sk-visual-review-role{margin-block-start:.2rem;font-size:.875rem;color:var(--sk-text-secondary);overflow-wrap:anywhere}
16
+ `;
17
+ function CardContent({ review, showRating = true, className = "" }) {
18
+ const photoUrl = reviewPhotoUrl(review.photo?.url);
19
+ const avatarUrl = reviewPhotoUrl(review.image);
20
+ const rating = Number.isFinite(review.rating) ? Math.max(0, Math.min(5, review.rating)) : 0;
21
+ return /* @__PURE__ */ jsxs("article", { className: `sk-visual-review ${className}`, "data-site-kit-visual-review": review.id, children: [
22
+ photoUrl && /* @__PURE__ */ jsxs("figure", { className: "sk-visual-review-photo", children: [
23
+ /* @__PURE__ */ jsx("img", { src: photoUrl, alt: review.photo?.altText || `Photo accompanying ${review.name}'s review`, loading: "lazy", decoding: "async" }),
24
+ review.photo?.caption && /* @__PURE__ */ jsx("figcaption", { children: review.photo.caption })
25
+ ] }),
26
+ /* @__PURE__ */ jsxs("div", { className: "sk-visual-review-body", children: [
27
+ showRating && /* @__PURE__ */ jsx("div", { className: "sk-visual-review-stars", role: "img", "aria-label": `${rating} out of 5 stars`, children: [1, 2, 3, 4, 5].map((star) => /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: star > rating ? "sk-visual-review-star-empty" : void 0, children: "\u2605" }, star)) }),
28
+ /* @__PURE__ */ jsx("blockquote", { children: review.quote }),
29
+ /* @__PURE__ */ jsxs("div", { className: "sk-visual-review-author", children: [
30
+ avatarUrl && /* @__PURE__ */ jsx("img", { className: "sk-visual-review-avatar", src: avatarUrl, alt: "", loading: "lazy", decoding: "async" }),
31
+ /* @__PURE__ */ jsxs("div", { children: [
32
+ /* @__PURE__ */ jsx("div", { className: "sk-visual-review-name", children: review.name }),
33
+ review.role && /* @__PURE__ */ jsx("div", { className: "sk-visual-review-role", children: review.role })
34
+ ] })
35
+ ] })
36
+ ] })
37
+ ] });
38
+ }
39
+ function VisualReviewCard(props) {
40
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
41
+ /* @__PURE__ */ jsx("style", { children: styles }),
42
+ /* @__PURE__ */ jsx(CardContent, { ...props })
43
+ ] });
44
+ }
45
+ function VisualReviewGallery({ reviews, title, subtitle, showRating = true, className = "" }) {
46
+ if (!reviews.length) return null;
47
+ return /* @__PURE__ */ jsxs("section", { className: `sk-visual-review-gallery ${className}`, "data-site-kit-visual-reviews": true, children: [
48
+ /* @__PURE__ */ jsx("style", { children: styles }),
49
+ (title || subtitle) && /* @__PURE__ */ jsxs("header", { className: "sk-visual-review-gallery-header", children: [
50
+ title && /* @__PURE__ */ jsx("h2", { children: title }),
51
+ subtitle && /* @__PURE__ */ jsx("p", { children: subtitle })
52
+ ] }),
53
+ /* @__PURE__ */ jsx("div", { className: "sk-visual-review-grid", children: reviews.map((review) => /* @__PURE__ */ jsx(CardContent, { review, showRating }, review.id)) })
54
+ ] });
55
+ }
56
+
57
+ export { VisualReviewCard, VisualReviewGallery };
@@ -1,6 +1,6 @@
1
+ import { writeLLMsTxtToPublic } from './chunk-TZ5RTANX.js';
1
2
  import { getSiteConfig } from './chunk-Z22QVHT4.js';
2
- import { writeLLMsTxtToPublic } from './chunk-Z65DHMTW.js';
3
- import { buildFetch } from './chunk-VX5CMNMM.js';
3
+ import { buildFetch } from './chunk-UAYAJPEP.js';
4
4
  import { findAppDirForDiscovery } from './chunk-ZEGVKVD5.js';
5
5
  import { stripEmbeddedDomain, locToPath, inferPageType, isMalformedSitemapPath, resolveTrailingSlash, stripTrailingSlash, llmsWriteTimeoutMs, applyTrailingSlash } from './chunk-YVKRYQRG.js';
6
6
  import { postRegisterSitemap } from './chunk-DIKNRN34.js';
@@ -1,5 +1,6 @@
1
1
  'use client';
2
- import { detectTimezone, releaseSlotHold, fetchBookingTypeDetails, fetchBookingTypes, fetchAvailability, createSlotHold, createBooking, formatDuration, formatDate, formatTime, prepareMeeting } from './chunk-2ECWEUHP.js';
2
+ import { detectTimezone, releaseSlotHold, fetchBookingTypeDetails, fetchBookingTypes, fetchAvailability, createSlotHold, createBooking, formatDuration, formatDate, formatTime, prepareMeeting } from './chunk-IJQ767JS.js';
3
+ import { readPublishedApiConfig, DEFAULT_SONOR_API_URL } from './chunk-3G7YABRA.js';
3
4
  import { useState, useRef, useMemo, useCallback, useEffect, useId } from 'react';
4
5
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
5
6
 
@@ -125,7 +126,6 @@ function bookingRecoveryFromError(error) {
125
126
  if (/time reservation expired|invalid slot hold|meeting details changed/i.test(message)) return "hold";
126
127
  return null;
127
128
  }
128
- var DEFAULT_API_URL = "https://api.sonor.io";
129
129
  var DAYS = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
130
130
  var MONTHS = [
131
131
  "January",
@@ -217,8 +217,9 @@ function BookingWidget({
217
217
  autoSelectFirstDay = true,
218
218
  styles = {}
219
219
  }) {
220
- const apiKey = propApiKey || (typeof window !== "undefined" ? window.__SITE_KIT_API_KEY__ : void 0);
221
- const apiUrl = propApiUrl || (typeof window !== "undefined" ? window.__SITE_KIT_API_URL__ : void 0) || DEFAULT_API_URL;
220
+ const published = readPublishedApiConfig();
221
+ const apiKey = propApiKey || published.apiKey;
222
+ const apiUrl = propApiUrl || published.apiUrl || DEFAULT_SONOR_API_URL;
222
223
  const [step, setStep] = useState(bookingTypeSlug ? "datetime" : "type");
223
224
  const [loading, setLoading] = useState(false);
224
225
  const [slotsLoading, setSlotsLoading] = useState(false);
@@ -1,13 +1,13 @@
1
1
  'use client';
2
2
  import { DEFAULT_WIDGET_Z_INDEX } from './chunk-27FISYK4.js';
3
- import { resolveAnalyticsTarget } from './chunk-43OCZ3JA.js';
3
+ import { resolveAnalyticsTarget } from './chunk-CAH4Y4PY.js';
4
4
  import { useState, useEffect } from 'react';
5
5
  import ReactDOM from 'react-dom';
6
6
  import dynamic from 'next/dynamic';
7
7
  import { jsx } from 'react/jsx-runtime';
8
8
 
9
9
  var LazyChatWidget = dynamic(
10
- () => import('./ChatWidget-FHBAHFZX.js').then((m) => ({ default: m.ChatWidget })),
10
+ () => import('./ChatWidget-DVS7MLBN.js').then((m) => ({ default: m.ChatWidget })),
11
11
  { ssr: false }
12
12
  );
13
13
  function SiteChat(props) {
@@ -1,12 +1,12 @@
1
1
  'use client';
2
- import { useDeferredActivation } from './chunk-YC7ELZS3.js';
3
2
  import { shellValuesToCarry } from './chunk-C2FZBUSS.js';
3
+ import { useDeferredActivation } from './chunk-YC7ELZS3.js';
4
4
  import { normalizeFormConfig } from './chunk-5SQK3D53.js';
5
5
  import { DEFAULT_HONEYPOT_FIELD } from './chunk-NJCTQH2P.js';
6
6
  import React, { useRef, useEffect, useState, useMemo, useCallback } from 'react';
7
7
  import { jsx, jsxs } from 'react/jsx-runtime';
8
8
 
9
- var loadInteractiveForm = () => import('./ManagedForm-JRZAJ7SZ.js').then((m) => m.ManagedForm);
9
+ var loadInteractiveForm = () => import('./ManagedForm-ZAUHIHGP.js').then((m) => m.ManagedForm);
10
10
  var REPLAY_WAIT_MS = 8e3;
11
11
  function FormEnhancer({
12
12
  formId,
@@ -1,12 +1,12 @@
1
1
  'use client';
2
2
  import { SITE_EDIT_PARAM } from './chunk-6G43IRWR.js';
3
- import { publishSiteCredential } from './chunk-VF4F5WXZ.js';
4
- import { FleetHeartbeat } from './chunk-UPRSH6Q4.js';
5
- import { SignalBridge } from './chunk-CYUFBKJQ.js';
3
+ import { publishSiteCredential } from './chunk-LBIQ5LTC.js';
4
+ import { FleetHeartbeat } from './chunk-ICAVVF6D.js';
6
5
  import { useDeferredActivation } from './chunk-YC7ELZS3.js';
7
6
  import { resolveSiteHost } from './chunk-FESKKJAS.js';
8
- import { getOrCreateVisitorId, getOrCreateSessionId } from './chunk-24QZEO3Q.js';
9
- import { announceFrameReady, isCrossOriginFrame } from './chunk-43OCZ3JA.js';
7
+ import { getOrCreateVisitorId, getOrCreateSessionId } from './chunk-ZKADJNR2.js';
8
+ import { announceFrameReady, isCrossOriginFrame } from './chunk-CAH4Y4PY.js';
9
+ import { SignalBridge } from './chunk-6ZXJ3SXR.js';
10
10
  import React, { useState, useRef, useCallback, useEffect, Suspense } from 'react';
11
11
  import dynamic from 'next/dynamic';
12
12
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
@@ -33,23 +33,23 @@ function startEditBridge() {
33
33
  };
34
34
  }
35
35
  var LazyAnalyticsProvider = dynamic(
36
- () => import('./AnalyticsProvider-DJQA66AG.js').then((m) => ({ default: m.AnalyticsProvider })),
36
+ () => import('./AnalyticsProvider-LYFDQRRJ.js').then((m) => ({ default: m.AnalyticsProvider })),
37
37
  { ssr: false }
38
38
  );
39
39
  var LazySiteChat = dynamic(
40
- () => import('./SiteChat-EGEZJJVV.js').then((m) => ({ default: m.SiteChat })),
40
+ () => import('./SiteChat-MY2GATWC.js').then((m) => ({ default: m.SiteChat })),
41
41
  { ssr: false }
42
42
  );
43
43
  var LazySitePopups = dynamic(
44
- () => import('./SitePopups-LQBIXIFV.js').then((m) => ({ default: m.SitePopups })),
44
+ () => import('./SitePopups-TGULLAER.js').then((m) => ({ default: m.SitePopups })),
45
45
  { ssr: false }
46
46
  );
47
47
  var LazySiteDesignReporter = dynamic(
48
- () => import('./SiteDesignReporter-YEEWJKWN.js').then((m) => ({ default: m.SiteDesignReporter })),
48
+ () => import('./SiteDesignReporter-ICZWEGCY.js').then((m) => ({ default: m.SiteDesignReporter })),
49
49
  { ssr: false }
50
50
  );
51
51
  var LazySitemapSync = dynamic(
52
- () => import('./SitemapSync-LSZ2EYOF.js').then((m) => ({ default: m.SitemapSync })),
52
+ () => import('./SitemapSync-AN2OBJE6.js').then((m) => ({ default: m.SitemapSync })),
53
53
  { ssr: false }
54
54
  );
55
55
  function SiteKitClientProviders({