@sonordev/site-kit 5.8.3 → 6.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 (537) hide show
  1. package/README.md +11 -11
  2. package/agent-manifest.json +17 -11
  3. package/dist/{AnalyticsProvider-IGOD64MY.mjs → AnalyticsProvider-6QVM2B6O.mjs} +6 -6
  4. package/dist/{AnalyticsProvider-IGOD64MY.mjs.map → AnalyticsProvider-6QVM2B6O.mjs.map} +1 -1
  5. package/dist/{AnalyticsProvider-DPXR6FSV.js → AnalyticsProvider-AZQXLRWN.js} +10 -10
  6. package/dist/{AnalyticsProvider-DPXR6FSV.js.map → AnalyticsProvider-AZQXLRWN.js.map} +1 -1
  7. package/dist/ArticleFaqSection-3KZ24MFS.js +13 -0
  8. package/dist/ArticleFaqSection-3KZ24MFS.js.map +1 -0
  9. package/dist/ArticleFaqSection-XZPXJVH4.mjs +11 -0
  10. package/dist/ArticleFaqSection-XZPXJVH4.mjs.map +1 -0
  11. package/dist/{BlogViewTracker-Q7Y4MN4B.mjs → ArticleViewTracker-AEWJMXQQ.mjs} +13 -13
  12. package/dist/ArticleViewTracker-AEWJMXQQ.mjs.map +1 -0
  13. package/dist/{BlogViewTracker-S3CSRBIZ.js → ArticleViewTracker-CFBTQ46B.js} +16 -16
  14. package/dist/ArticleViewTracker-CFBTQ46B.js.map +1 -0
  15. package/dist/ChatWidget-6626OPXO.mjs +15 -0
  16. package/dist/{ChatWidget-G3KOUDX5.mjs.map → ChatWidget-6626OPXO.mjs.map} +1 -1
  17. package/dist/ChatWidget-U24AYLXF.js +24 -0
  18. package/dist/{ChatWidget-76R7NOWD.js.map → ChatWidget-U24AYLXF.js.map} +1 -1
  19. package/dist/EngageWidget-TR47W2ZI.mjs +12 -0
  20. package/dist/{EngageWidget-UJ47PQFG.mjs.map → EngageWidget-TR47W2ZI.mjs.map} +1 -1
  21. package/dist/EngageWidget-XUTDFRF3.js +21 -0
  22. package/dist/{EngageWidget-HD4F2ZVE.js.map → EngageWidget-XUTDFRF3.js.map} +1 -1
  23. package/dist/{FileField-WNMEA3PK.mjs → FileField-DNNC5IPS.mjs} +5 -5
  24. package/dist/{FileField-WNMEA3PK.mjs.map → FileField-DNNC5IPS.mjs.map} +1 -1
  25. package/dist/{FileField-FV6WSZMX.js → FileField-R4RQG77G.js} +6 -6
  26. package/dist/{FileField-FV6WSZMX.js.map → FileField-R4RQG77G.js.map} +1 -1
  27. package/dist/{FormSpotlight-2VRQXEFI.js → FormSpotlight-7ILRAD3W.js} +9 -9
  28. package/dist/{FormSpotlight-2VRQXEFI.js.map → FormSpotlight-7ILRAD3W.js.map} +1 -1
  29. package/dist/{FormSpotlight-NGWEPGI4.mjs → FormSpotlight-MXY4I46H.mjs} +3 -3
  30. package/dist/{FormSpotlight-NGWEPGI4.mjs.map → FormSpotlight-MXY4I46H.mjs.map} +1 -1
  31. package/dist/{FormStage-Q3KQVFVW.js → FormStage-CVD3I3SE.js} +9 -9
  32. package/dist/{FormStage-Q3KQVFVW.js.map → FormStage-CVD3I3SE.js.map} +1 -1
  33. package/dist/{FormStage-7L4BBOLC.mjs → FormStage-FDJGRGEU.mjs} +3 -3
  34. package/dist/{FormStage-7L4BBOLC.mjs.map → FormStage-FDJGRGEU.mjs.map} +1 -1
  35. package/dist/ManagedForm-5675CLWS.mjs +16 -0
  36. package/dist/{ManagedForm-Z7QE4KYI.mjs.map → ManagedForm-5675CLWS.mjs.map} +1 -1
  37. package/dist/ManagedForm-KYIK54SL.js +25 -0
  38. package/dist/{ManagedForm-4ZGU4R3G.js.map → ManagedForm-KYIK54SL.js.map} +1 -1
  39. package/dist/{ManagedNewsletterForm-4TVO2VL4.mjs → ManagedNewsletterForm-DFLDGNQU.mjs} +11 -11
  40. package/dist/ManagedNewsletterForm-DFLDGNQU.mjs.map +1 -0
  41. package/dist/{ManagedNewsletterForm-22EPZB7Z.js → ManagedNewsletterForm-IH3MRJOD.js} +13 -13
  42. package/dist/ManagedNewsletterForm-IH3MRJOD.js.map +1 -0
  43. package/dist/{SignalCore-2N7UZGF3.js → SignalCore-6LYIZFXK.js} +11 -11
  44. package/dist/{SignalCore-2N7UZGF3.js.map → SignalCore-6LYIZFXK.js.map} +1 -1
  45. package/dist/{SignalCore-57OK3DHA.mjs → SignalCore-ZH3R6XD3.mjs} +5 -5
  46. package/dist/{SignalCore-57OK3DHA.mjs.map → SignalCore-ZH3R6XD3.mjs.map} +1 -1
  47. package/dist/SitemapSync-PKBXWVI6.mjs +9 -0
  48. package/dist/{SitemapSync-WIUEYOBS.mjs.map → SitemapSync-PKBXWVI6.mjs.map} +1 -1
  49. package/dist/SitemapSync-PZ76V5MX.js +18 -0
  50. package/dist/{SitemapSync-GF4OKN4Z.js.map → SitemapSync-PZ76V5MX.js.map} +1 -1
  51. package/dist/analytics/index.js +9 -9
  52. package/dist/analytics/index.mjs +4 -4
  53. package/dist/{blog-styles-7AKRUMV7.mjs → article-styles-DACUAOVT.mjs} +124 -124
  54. package/dist/article-styles-DACUAOVT.mjs.map +1 -0
  55. package/dist/{blog-styles-6EY3BS5Y.js → article-styles-JHHTNHOK.js} +125 -125
  56. package/dist/article-styles-JHHTNHOK.js.map +1 -0
  57. package/dist/article-tables-EWXG4LNP.js +17 -0
  58. package/dist/article-tables-EWXG4LNP.js.map +1 -0
  59. package/dist/article-tables-OGE52LNT.mjs +4 -0
  60. package/dist/article-tables-OGE52LNT.mjs.map +1 -0
  61. package/dist/{blog/BlogPost.d.ts → articles/Article.d.ts} +18 -16
  62. package/dist/articles/Article.d.ts.map +1 -0
  63. package/dist/{blog/BlogFAQ.d.ts → articles/ArticleFAQ.d.ts} +6 -6
  64. package/dist/articles/ArticleFAQ.d.ts.map +1 -0
  65. package/dist/articles/ArticleFaqSection.d.ts +3 -0
  66. package/dist/articles/ArticleFaqSection.d.ts.map +1 -0
  67. package/dist/{blog/BlogList.d.ts → articles/ArticleList.d.ts} +16 -16
  68. package/dist/articles/ArticleList.d.ts.map +1 -0
  69. package/dist/{blog/BlogViewTracker.d.ts → articles/ArticleViewTracker.d.ts} +4 -4
  70. package/dist/articles/ArticleViewTracker.d.ts.map +1 -0
  71. package/dist/{blog → articles}/AuthorCard.d.ts +3 -3
  72. package/dist/articles/AuthorCard.d.ts.map +1 -0
  73. package/dist/{blog → articles}/AuthorPage.d.ts +1 -1
  74. package/dist/articles/AuthorPage.d.ts.map +1 -0
  75. package/dist/{blog → articles}/ClusterLandingPage.d.ts +6 -6
  76. package/dist/articles/ClusterLandingPage.d.ts.map +1 -0
  77. package/dist/{blog → articles}/ClusterNavigation.d.ts +5 -5
  78. package/dist/articles/ClusterNavigation.d.ts.map +1 -0
  79. package/dist/{blog → articles}/ManagedNewsletterForm.d.ts +1 -1
  80. package/dist/articles/ManagedNewsletterForm.d.ts.map +1 -0
  81. package/dist/{blog → articles}/NewsletterShell.d.ts +1 -1
  82. package/dist/articles/NewsletterShell.d.ts.map +1 -0
  83. package/dist/{blog → articles}/NewsletterWidget.d.ts +4 -4
  84. package/dist/articles/NewsletterWidget.d.ts.map +1 -0
  85. package/dist/{blog/BlogLayout.d.ts → articles/PublicationLayout.d.ts} +18 -18
  86. package/dist/articles/PublicationLayout.d.ts.map +1 -0
  87. package/dist/{blog/BlogSidebar.d.ts → articles/PublicationSidebar.d.ts} +8 -8
  88. package/dist/articles/PublicationSidebar.d.ts.map +1 -0
  89. package/dist/{blog → articles}/RelatedPosts.d.ts +6 -6
  90. package/dist/articles/RelatedPosts.d.ts.map +1 -0
  91. package/dist/{blog → articles}/ServiceCallout.d.ts +4 -4
  92. package/dist/articles/ServiceCallout.d.ts.map +1 -0
  93. package/dist/{blog → articles}/TableOfContents.d.ts +1 -1
  94. package/dist/articles/TableOfContents.d.ts.map +1 -0
  95. package/dist/{blog/blog-styles.d.ts → articles/article-styles.d.ts} +5 -5
  96. package/dist/articles/article-styles.d.ts.map +1 -0
  97. package/dist/{blog/blog-tables.d.ts → articles/article-tables.d.ts} +4 -4
  98. package/dist/articles/article-tables.d.ts.map +1 -0
  99. package/dist/articles/artwork.d.ts +14 -0
  100. package/dist/articles/artwork.d.ts.map +1 -0
  101. package/dist/{blog → articles}/author-schema.d.ts +6 -5
  102. package/dist/articles/author-schema.d.ts.map +1 -0
  103. package/dist/{blog → articles}/author-social.d.ts +2 -2
  104. package/dist/articles/author-social.d.ts.map +1 -0
  105. package/dist/{blog → articles}/excerpt.d.ts +2 -2
  106. package/dist/articles/excerpt.d.ts.map +1 -0
  107. package/dist/{blog → articles}/index.d.ts +26 -31
  108. package/dist/articles/index.d.ts.map +1 -0
  109. package/dist/{blog → articles}/index.js +39 -73
  110. package/dist/articles/index.js.map +1 -0
  111. package/dist/{blog → articles}/index.mjs +16 -17
  112. package/dist/articles/index.mjs.map +1 -0
  113. package/dist/articles/news-sitemap.d.ts +47 -0
  114. package/dist/articles/news-sitemap.d.ts.map +1 -0
  115. package/dist/{blog/processBlogHtml.d.ts → articles/processArticleHtml.d.ts} +4 -4
  116. package/dist/articles/processArticleHtml.d.ts.map +1 -0
  117. package/dist/articles/public-reads.d.ts +27 -0
  118. package/dist/articles/public-reads.d.ts.map +1 -0
  119. package/dist/{blog → articles}/reading-time.d.ts +2 -2
  120. package/dist/articles/reading-time.d.ts.map +1 -0
  121. package/dist/{blog → articles}/routes.d.ts +16 -12
  122. package/dist/articles/routes.d.ts.map +1 -0
  123. package/dist/{blog → articles}/server-core.d.ts +94 -81
  124. package/dist/articles/server-core.d.ts.map +1 -0
  125. package/dist/articles/server-ui.d.ts +29 -0
  126. package/dist/articles/server-ui.d.ts.map +1 -0
  127. package/dist/{chunk-W2U5SLMY.js → articles/server-ui.js} +378 -499
  128. package/dist/articles/server-ui.js.map +1 -0
  129. package/dist/{chunk-MWKI6ZIS.mjs → articles/server-ui.mjs} +328 -474
  130. package/dist/articles/server-ui.mjs.map +1 -0
  131. package/dist/{blog → articles}/server.d.ts +94 -81
  132. package/dist/articles/server.d.ts.map +1 -0
  133. package/dist/articles/server.js +236 -0
  134. package/dist/articles/server.mjs +11 -0
  135. package/dist/{blog → articles}/types.d.ts +34 -34
  136. package/dist/articles/types.d.ts.map +1 -0
  137. package/dist/articles/widget-styles.d.ts +9 -0
  138. package/dist/articles/widget-styles.d.ts.map +1 -0
  139. package/dist/brand/extract-brand-profile.d.ts +1 -1
  140. package/dist/{chunk-PIEHBSCN.js → chunk-254IW4FC.js} +9 -9
  141. package/dist/{chunk-PIEHBSCN.js.map → chunk-254IW4FC.js.map} +1 -1
  142. package/dist/chunk-2KRAY5NC.mjs +6 -0
  143. package/dist/{chunk-5FETEH3Y.mjs.map → chunk-2KRAY5NC.mjs.map} +1 -1
  144. package/dist/{chunk-MQS6AF5K.mjs → chunk-2WEBUZNP.mjs} +3 -3
  145. package/dist/{chunk-MQS6AF5K.mjs.map → chunk-2WEBUZNP.mjs.map} +1 -1
  146. package/dist/{chunk-4C5CZJIN.mjs → chunk-2YSB4FIC.mjs} +4 -4
  147. package/dist/{chunk-4C5CZJIN.mjs.map → chunk-2YSB4FIC.mjs.map} +1 -1
  148. package/dist/{chunk-I7HOMMIK.js → chunk-3GHPFLEH.js} +15 -15
  149. package/dist/{chunk-I7HOMMIK.js.map → chunk-3GHPFLEH.js.map} +1 -1
  150. package/dist/{chunk-CY2RFEW6.js → chunk-3LCJJ6Y6.js} +3 -3
  151. package/dist/{chunk-CY2RFEW6.js.map → chunk-3LCJJ6Y6.js.map} +1 -1
  152. package/dist/{chunk-QOOLMSBY.mjs → chunk-3OCXVTN5.mjs} +3 -3
  153. package/dist/{chunk-QOOLMSBY.mjs.map → chunk-3OCXVTN5.mjs.map} +1 -1
  154. package/dist/{chunk-AJBOEV4I.mjs → chunk-3T2CVHFO.mjs} +3 -3
  155. package/dist/chunk-3T2CVHFO.mjs.map +1 -0
  156. package/dist/{chunk-NR7YZQRR.js → chunk-3U5SVB4W.js} +4 -4
  157. package/dist/{chunk-NR7YZQRR.js.map → chunk-3U5SVB4W.js.map} +1 -1
  158. package/dist/{chunk-I3ND4XYW.js → chunk-4BEGKFMN.js} +8 -8
  159. package/dist/{chunk-I3ND4XYW.js.map → chunk-4BEGKFMN.js.map} +1 -1
  160. package/dist/{chunk-YFX3Q56O.mjs → chunk-4KAMU5HD.mjs} +3 -3
  161. package/dist/chunk-4KAMU5HD.mjs.map +1 -0
  162. package/dist/{chunk-ZPLN537Q.mjs → chunk-4WCA2HM6.mjs} +2 -2
  163. package/dist/chunk-4WCA2HM6.mjs.map +1 -0
  164. package/dist/{chunk-6CCS2EGF.js → chunk-5DSUPTBU.js} +13 -13
  165. package/dist/{chunk-6CCS2EGF.js.map → chunk-5DSUPTBU.js.map} +1 -1
  166. package/dist/{chunk-GHECYDSZ.mjs → chunk-5F2FIM5A.mjs} +16 -15
  167. package/dist/chunk-5F2FIM5A.mjs.map +1 -0
  168. package/dist/{chunk-Y5QZPUL3.mjs → chunk-5YVQWLSQ.mjs} +5 -5
  169. package/dist/chunk-5YVQWLSQ.mjs.map +1 -0
  170. package/dist/chunk-6DCAMW62.mjs +55 -0
  171. package/dist/chunk-6DCAMW62.mjs.map +1 -0
  172. package/dist/{chunk-Q2NBD54V.js → chunk-7THQ4UW3.js} +2 -2
  173. package/dist/chunk-7THQ4UW3.js.map +1 -0
  174. package/dist/{chunk-LGOQ65JQ.mjs → chunk-7TKSRUQU.mjs} +7 -7
  175. package/dist/{chunk-LGOQ65JQ.mjs.map → chunk-7TKSRUQU.mjs.map} +1 -1
  176. package/dist/{chunk-4TLFZ6NR.mjs → chunk-AS2HUIDW.mjs} +3 -3
  177. package/dist/chunk-AS2HUIDW.mjs.map +1 -0
  178. package/dist/{chunk-YN7QHLWF.js → chunk-BBBJHYPH.js} +5 -5
  179. package/dist/chunk-BBBJHYPH.js.map +1 -0
  180. package/dist/{chunk-2TS4ALOA.js → chunk-BZG34WHF.js} +14 -14
  181. package/dist/{chunk-2TS4ALOA.js.map → chunk-BZG34WHF.js.map} +1 -1
  182. package/dist/{chunk-4LYW6PMU.mjs → chunk-C2CTLLIO.mjs} +3 -3
  183. package/dist/chunk-C2CTLLIO.mjs.map +1 -0
  184. package/dist/{chunk-O237KKCX.mjs → chunk-C5VITBN7.mjs} +5 -5
  185. package/dist/chunk-C5VITBN7.mjs.map +1 -0
  186. package/dist/{chunk-75A4KY4X.mjs → chunk-CFRJ2MK5.mjs} +2 -2
  187. package/dist/chunk-CFRJ2MK5.mjs.map +1 -0
  188. package/dist/{chunk-G2WC3CXW.js → chunk-CLO3K7PF.js} +2 -2
  189. package/dist/chunk-CLO3K7PF.js.map +1 -0
  190. package/dist/{chunk-SFC3OWSE.mjs → chunk-CSSNZGTU.mjs} +4 -4
  191. package/dist/{chunk-SFC3OWSE.mjs.map → chunk-CSSNZGTU.mjs.map} +1 -1
  192. package/dist/{chunk-7VZYP4K5.js → chunk-CZGGUPPQ.js} +15 -15
  193. package/dist/{chunk-7VZYP4K5.js.map → chunk-CZGGUPPQ.js.map} +1 -1
  194. package/dist/{chunk-FTB5LAD3.js → chunk-D47W5DE4.js} +4 -4
  195. package/dist/{chunk-FTB5LAD3.js.map → chunk-D47W5DE4.js.map} +1 -1
  196. package/dist/{chunk-AK6JZ3OE.mjs → chunk-EDLNMGQC.mjs} +3 -3
  197. package/dist/{chunk-DO6ATNLN.js.map → chunk-EDLNMGQC.mjs.map} +1 -1
  198. package/dist/chunk-EL74YDNX.js +8 -0
  199. package/dist/{chunk-7R6H3GQ4.js.map → chunk-EL74YDNX.js.map} +1 -1
  200. package/dist/{chunk-HX6ZG3PP.js → chunk-EMHSHAVW.js} +3 -3
  201. package/dist/chunk-EMHSHAVW.js.map +1 -0
  202. package/dist/{chunk-7TC3GRXQ.js → chunk-G6KQ3C3W.js} +25 -23
  203. package/dist/chunk-G6KQ3C3W.js.map +1 -0
  204. package/dist/{chunk-HEOLGDUX.mjs → chunk-GQ3SDRL6.mjs} +4 -4
  205. package/dist/{chunk-HEOLGDUX.mjs.map → chunk-GQ3SDRL6.mjs.map} +1 -1
  206. package/dist/{chunk-IIHIRHSW.js → chunk-HFCQGSD2.js} +18 -18
  207. package/dist/{chunk-IIHIRHSW.js.map → chunk-HFCQGSD2.js.map} +1 -1
  208. package/dist/{chunk-XZO5I4RS.mjs → chunk-HIZJD7TU.mjs} +3 -3
  209. package/dist/{chunk-XZO5I4RS.mjs.map → chunk-HIZJD7TU.mjs.map} +1 -1
  210. package/dist/{chunk-UQY5KC64.mjs → chunk-HOOVYWTO.mjs} +4 -4
  211. package/dist/{chunk-UQY5KC64.mjs.map → chunk-HOOVYWTO.mjs.map} +1 -1
  212. package/dist/{chunk-NBT4L2D7.js → chunk-HX5JPNMN.js} +8 -8
  213. package/dist/{chunk-NBT4L2D7.js.map → chunk-HX5JPNMN.js.map} +1 -1
  214. package/dist/chunk-HXHRS3PX.mjs +349 -0
  215. package/dist/chunk-HXHRS3PX.mjs.map +1 -0
  216. package/dist/{chunk-XBX2K3GA.js → chunk-IBJOGXQI.js} +4 -4
  217. package/dist/{chunk-XBX2K3GA.js.map → chunk-IBJOGXQI.js.map} +1 -1
  218. package/dist/{chunk-3OO5EDKD.mjs → chunk-JMNBU2RG.mjs} +9 -9
  219. package/dist/{chunk-3OO5EDKD.mjs.map → chunk-JMNBU2RG.mjs.map} +1 -1
  220. package/dist/{chunk-R7GHP3FY.js → chunk-JONWE26J.js} +3 -3
  221. package/dist/chunk-JONWE26J.js.map +1 -0
  222. package/dist/{chunk-PQYQHZWV.mjs → chunk-JSXLTZUP.mjs} +6 -6
  223. package/dist/{chunk-PQYQHZWV.mjs.map → chunk-JSXLTZUP.mjs.map} +1 -1
  224. package/dist/{chunk-FD72QL42.mjs → chunk-JXCMCASE.mjs} +3 -3
  225. package/dist/{chunk-FD72QL42.mjs.map → chunk-JXCMCASE.mjs.map} +1 -1
  226. package/dist/{chunk-TR3F3CLV.js → chunk-KA4NNWOK.js} +10 -10
  227. package/dist/{chunk-TR3F3CLV.js.map → chunk-KA4NNWOK.js.map} +1 -1
  228. package/dist/{chunk-K4TCEAUX.js → chunk-KR7ATPAN.js} +5 -5
  229. package/dist/chunk-KR7ATPAN.js.map +1 -0
  230. package/dist/{chunk-JLVCWC6A.mjs → chunk-KZVSB5WE.mjs} +2 -2
  231. package/dist/chunk-KZVSB5WE.mjs.map +1 -0
  232. package/dist/chunk-LWCAZDY2.js +355 -0
  233. package/dist/chunk-LWCAZDY2.js.map +1 -0
  234. package/dist/{chunk-5HFD36AN.js → chunk-MCG4BSRW.js} +5 -5
  235. package/dist/{chunk-5HFD36AN.js.map → chunk-MCG4BSRW.js.map} +1 -1
  236. package/dist/{chunk-S2Y7LVQ2.js → chunk-MIYGP34I.js} +14 -14
  237. package/dist/{chunk-S2Y7LVQ2.js.map → chunk-MIYGP34I.js.map} +1 -1
  238. package/dist/{chunk-PI3FHABB.js → chunk-MS2EE6LT.js} +10 -10
  239. package/dist/{chunk-PI3FHABB.js.map → chunk-MS2EE6LT.js.map} +1 -1
  240. package/dist/{chunk-QQQAW6WY.js → chunk-N6CB7MK7.js} +6 -6
  241. package/dist/{chunk-QQQAW6WY.js.map → chunk-N6CB7MK7.js.map} +1 -1
  242. package/dist/{chunk-LMEUYRRR.js → chunk-NAA5J2JM.js} +233 -120
  243. package/dist/chunk-NAA5J2JM.js.map +1 -0
  244. package/dist/{chunk-OE7CTIOU.mjs → chunk-NE6QGHFT.mjs} +4 -4
  245. package/dist/{chunk-OE7CTIOU.mjs.map → chunk-NE6QGHFT.mjs.map} +1 -1
  246. package/dist/{chunk-NCDF2RK4.mjs → chunk-NR52QHOD.mjs} +3 -3
  247. package/dist/{chunk-NCDF2RK4.mjs.map → chunk-NR52QHOD.mjs.map} +1 -1
  248. package/dist/{chunk-GQF6QAQS.js → chunk-OGNX6JT4.js} +5 -5
  249. package/dist/chunk-OGNX6JT4.js.map +1 -0
  250. package/dist/{chunk-FVW6FT6L.js → chunk-OSU4QA5M.js} +8 -8
  251. package/dist/{chunk-FVW6FT6L.js.map → chunk-OSU4QA5M.js.map} +1 -1
  252. package/dist/{chunk-UEUWC3PH.mjs → chunk-PJYTYM5G.mjs} +3 -3
  253. package/dist/{chunk-UEUWC3PH.mjs.map → chunk-PJYTYM5G.mjs.map} +1 -1
  254. package/dist/{chunk-DO6ATNLN.js → chunk-PRAHDLKT.js} +5 -5
  255. package/dist/chunk-PRAHDLKT.js.map +1 -0
  256. package/dist/{chunk-RFAAY3BW.mjs → chunk-QEM2F2DC.mjs} +3 -3
  257. package/dist/{chunk-RFAAY3BW.mjs.map → chunk-QEM2F2DC.mjs.map} +1 -1
  258. package/dist/{chunk-F3KA6V2Y.js → chunk-QOCLSJIU.js} +3 -3
  259. package/dist/{chunk-F3KA6V2Y.js.map → chunk-QOCLSJIU.js.map} +1 -1
  260. package/dist/{chunk-R5IPDAMM.mjs → chunk-QVBAAPNT.mjs} +3 -3
  261. package/dist/{chunk-R5IPDAMM.mjs.map → chunk-QVBAAPNT.mjs.map} +1 -1
  262. package/dist/{chunk-POJZA67T.mjs → chunk-RC4L4DV2.mjs} +4 -4
  263. package/dist/{chunk-POJZA67T.mjs.map → chunk-RC4L4DV2.mjs.map} +1 -1
  264. package/dist/{chunk-ZVI7MBVF.mjs → chunk-RDPI27TS.mjs} +12 -10
  265. package/dist/chunk-RDPI27TS.mjs.map +1 -0
  266. package/dist/{chunk-OEW2LFOV.js → chunk-RLUNEEGM.js} +4 -4
  267. package/dist/{chunk-OEW2LFOV.js.map → chunk-RLUNEEGM.js.map} +1 -1
  268. package/dist/{chunk-HBHS5VRN.mjs → chunk-RPCODOWG.mjs} +3 -3
  269. package/dist/{chunk-HBHS5VRN.mjs.map → chunk-RPCODOWG.mjs.map} +1 -1
  270. package/dist/{chunk-ROSYCNXG.mjs → chunk-RZGVNDO6.mjs} +4 -4
  271. package/dist/{chunk-ROSYCNXG.mjs.map → chunk-RZGVNDO6.mjs.map} +1 -1
  272. package/dist/{chunk-MYMZRHTC.js → chunk-SCRB5DZM.js} +8 -8
  273. package/dist/{chunk-MYMZRHTC.js.map → chunk-SCRB5DZM.js.map} +1 -1
  274. package/dist/{chunk-YQTE32QK.js → chunk-SG7CWD2R.js} +17 -16
  275. package/dist/chunk-SG7CWD2R.js.map +1 -0
  276. package/dist/{chunk-XEB77DQS.js → chunk-TBXWJJGT.js} +3 -3
  277. package/dist/chunk-TBXWJJGT.js.map +1 -0
  278. package/dist/{chunk-QXMWNIKL.mjs → chunk-TCCGP3FT.mjs} +3 -3
  279. package/dist/{chunk-QXMWNIKL.mjs.map → chunk-TCCGP3FT.mjs.map} +1 -1
  280. package/dist/{chunk-CZEIHFLW.js → chunk-TCZHRSWY.js} +4 -4
  281. package/dist/{chunk-CZEIHFLW.js.map → chunk-TCZHRSWY.js.map} +1 -1
  282. package/dist/{chunk-LB44BNJ2.js → chunk-TST2IKYO.js} +14 -14
  283. package/dist/{chunk-LB44BNJ2.js.map → chunk-TST2IKYO.js.map} +1 -1
  284. package/dist/{chunk-U2V542EO.mjs → chunk-UHYRVALN.mjs} +2 -2
  285. package/dist/{chunk-U2V542EO.mjs.map → chunk-UHYRVALN.mjs.map} +1 -1
  286. package/dist/{chunk-4L7OHRWB.mjs → chunk-UO6KTHBQ.mjs} +4 -4
  287. package/dist/{chunk-4L7OHRWB.mjs.map → chunk-UO6KTHBQ.mjs.map} +1 -1
  288. package/dist/{chunk-H5NBFNND.js → chunk-UZKXOZHR.js} +2 -2
  289. package/dist/chunk-UZKXOZHR.js.map +1 -0
  290. package/dist/{chunk-NMM27UOF.js → chunk-VINLIMAX.js} +3 -3
  291. package/dist/{chunk-NMM27UOF.js.map → chunk-VINLIMAX.js.map} +1 -1
  292. package/dist/{chunk-UHM3CCCC.js → chunk-WDEGGHTB.js} +12 -12
  293. package/dist/{chunk-UHM3CCCC.js.map → chunk-WDEGGHTB.js.map} +1 -1
  294. package/dist/{chunk-PIPERXI7.mjs → chunk-WV5YQL3W.mjs} +3 -3
  295. package/dist/{chunk-PIPERXI7.mjs.map → chunk-WV5YQL3W.mjs.map} +1 -1
  296. package/dist/{chunk-3EY5E35M.mjs → chunk-X3MY4PL7.mjs} +210 -107
  297. package/dist/chunk-X3MY4PL7.mjs.map +1 -0
  298. package/dist/{chunk-4NVMAYMQ.mjs → chunk-XKXZ4OW4.mjs} +4 -4
  299. package/dist/{chunk-4NVMAYMQ.mjs.map → chunk-XKXZ4OW4.mjs.map} +1 -1
  300. package/dist/{chunk-WINDP776.mjs → chunk-XSBKR3VF.mjs} +5 -5
  301. package/dist/{chunk-WINDP776.mjs.map → chunk-XSBKR3VF.mjs.map} +1 -1
  302. package/dist/{chunk-SEP5D4MI.js → chunk-Y2CP5J6Q.js} +2 -2
  303. package/dist/{chunk-SEP5D4MI.js.map → chunk-Y2CP5J6Q.js.map} +1 -1
  304. package/dist/{chunk-VVBMWV4O.js → chunk-YGDQVZEL.js} +7 -7
  305. package/dist/{chunk-VVBMWV4O.js.map → chunk-YGDQVZEL.js.map} +1 -1
  306. package/dist/{chunk-KV7XXLJV.mjs → chunk-YPGUV6BT.mjs} +3 -3
  307. package/dist/{chunk-KV7XXLJV.mjs.map → chunk-YPGUV6BT.mjs.map} +1 -1
  308. package/dist/chunk-YRCR7WY3.js +65 -0
  309. package/dist/chunk-YRCR7WY3.js.map +1 -0
  310. package/dist/{chunk-F2KW4OJF.mjs → chunk-YWLBQ3L5.mjs} +4 -4
  311. package/dist/{chunk-F2KW4OJF.mjs.map → chunk-YWLBQ3L5.mjs.map} +1 -1
  312. package/dist/{chunk-CNTDV7HM.js → chunk-YYEBFQGS.js} +4 -4
  313. package/dist/{chunk-CNTDV7HM.js.map → chunk-YYEBFQGS.js.map} +1 -1
  314. package/dist/chunk-ZL35JCDA.mjs +61 -0
  315. package/dist/chunk-ZL35JCDA.mjs.map +1 -0
  316. package/dist/chunk-ZR43XFUM.js +60 -0
  317. package/dist/chunk-ZR43XFUM.js.map +1 -0
  318. package/dist/{chunk-25F2EXOC.mjs → chunk-ZR4TYCQW.mjs} +3 -3
  319. package/dist/{chunk-25F2EXOC.mjs.map → chunk-ZR4TYCQW.mjs.map} +1 -1
  320. package/dist/cli/commands/setup.d.ts +2 -2
  321. package/dist/cli/commands/sync.d.ts +2 -2
  322. package/dist/cli/commands/sync.d.ts.map +1 -1
  323. package/dist/cli/index.js +76 -76
  324. package/dist/cli/index.mjs +29 -29
  325. package/dist/client/index.js +5 -5
  326. package/dist/client/index.mjs +4 -4
  327. package/dist/commerce/index.js +57 -57
  328. package/dist/commerce/index.mjs +5 -5
  329. package/dist/discover-LPN55L5B.js +21 -0
  330. package/dist/{discover-NGEPXZOD.js.map → discover-LPN55L5B.js.map} +1 -1
  331. package/dist/discover-QGA6QFSR.mjs +4 -0
  332. package/dist/{discover-CYXYKHZ2.mjs.map → discover-QGA6QFSR.mjs.map} +1 -1
  333. package/dist/engage/index.js +13 -13
  334. package/dist/engage/index.mjs +7 -7
  335. package/dist/fleet/contract.d.ts +1 -1
  336. package/dist/fleet/contract.js +12 -12
  337. package/dist/fleet/contract.mjs +1 -1
  338. package/dist/fleet/index.js +20 -20
  339. package/dist/fleet/index.mjs +5 -5
  340. package/dist/forms/index.js +16 -16
  341. package/dist/forms/index.mjs +9 -9
  342. package/dist/forms/server.js +10 -10
  343. package/dist/forms/server.mjs +8 -8
  344. package/dist/forms/static.js +7 -7
  345. package/dist/forms/static.mjs +6 -6
  346. package/dist/images/index.js +11 -11
  347. package/dist/images/index.mjs +4 -4
  348. package/dist/index.d.ts +2 -2
  349. package/dist/index.d.ts.map +1 -1
  350. package/dist/index.js +70 -70
  351. package/dist/index.mjs +12 -12
  352. package/dist/layout/client.js +10 -10
  353. package/dist/layout/client.mjs +9 -9
  354. package/dist/layout/index.js +12 -12
  355. package/dist/layout/index.mjs +10 -10
  356. package/dist/llms/SpeakableSchema.d.ts +1 -1
  357. package/dist/llms/SpeakableSchema.d.ts.map +1 -1
  358. package/dist/llms/client.js +15 -15
  359. package/dist/llms/client.mjs +1 -1
  360. package/dist/llms/generateLLMsTxt.d.ts.map +1 -1
  361. package/dist/llms/index.js +32 -31
  362. package/dist/llms/index.js.map +1 -1
  363. package/dist/llms/index.mjs +8 -7
  364. package/dist/llms/index.mjs.map +1 -1
  365. package/dist/llms/types.d.ts +7 -0
  366. package/dist/llms/types.d.ts.map +1 -1
  367. package/dist/maps/index.js +5 -5
  368. package/dist/maps/index.mjs +3 -3
  369. package/dist/og/index.js +7 -7
  370. package/dist/og/index.mjs +2 -2
  371. package/dist/og/route.d.ts +6 -6
  372. package/dist/og/route.js.map +1 -1
  373. package/dist/og/route.mjs.map +1 -1
  374. package/dist/og/wiring.d.ts +4 -4
  375. package/dist/og/wiring.d.ts.map +1 -1
  376. package/dist/proxy/index.js +5 -5
  377. package/dist/proxy/index.mjs +3 -3
  378. package/dist/redirects/index.js +10 -10
  379. package/dist/redirects/index.mjs +3 -3
  380. package/dist/redirects/not-found.js +7 -7
  381. package/dist/redirects/not-found.mjs +3 -3
  382. package/dist/robots/indexnow.d.ts +17 -0
  383. package/dist/robots/indexnow.d.ts.map +1 -0
  384. package/dist/robots/indexnow.js +39 -0
  385. package/dist/robots/indexnow.js.map +1 -0
  386. package/dist/robots/indexnow.mjs +34 -0
  387. package/dist/robots/indexnow.mjs.map +1 -0
  388. package/dist/search/contract.d.ts +1 -1
  389. package/dist/search/contract.js +3 -3
  390. package/dist/search/contract.mjs +1 -1
  391. package/dist/search/index.js +7 -7
  392. package/dist/search/index.mjs +5 -5
  393. package/dist/seo/client.js +6 -6
  394. package/dist/seo/client.mjs +5 -5
  395. package/dist/seo/index.js +47 -47
  396. package/dist/seo/index.js.map +1 -1
  397. package/dist/seo/index.mjs +12 -12
  398. package/dist/seo/index.mjs.map +1 -1
  399. package/dist/seo/register-sitemap-cli.js +12 -12
  400. package/dist/seo/register-sitemap-cli.mjs +5 -5
  401. package/dist/seo/server.js +21 -21
  402. package/dist/seo/server.mjs +5 -5
  403. package/dist/server/index.js +3 -3
  404. package/dist/server/index.mjs +2 -2
  405. package/dist/{server-api-A2EFCTZX.mjs → server-api-7F5P6CSH.mjs} +6 -6
  406. package/dist/{server-api-A2EFCTZX.mjs.map → server-api-7F5P6CSH.mjs.map} +1 -1
  407. package/dist/{server-api-IWTZ7C3O.js → server-api-OC5JNK6R.js} +24 -24
  408. package/dist/{server-api-IWTZ7C3O.js.map → server-api-OC5JNK6R.js.map} +1 -1
  409. package/dist/shared/build-entries.d.ts +9 -7
  410. package/dist/shared/build-entries.d.ts.map +1 -1
  411. package/dist/shared/version.d.ts +1 -1
  412. package/dist/signal/index.js +11 -11
  413. package/dist/signal/index.mjs +2 -2
  414. package/dist/sitemap/discover.d.ts +1 -1
  415. package/dist/sitemap/index.d.ts +7 -1
  416. package/dist/sitemap/index.d.ts.map +1 -1
  417. package/dist/sitemap/index.js +47 -30
  418. package/dist/sitemap/index.js.map +1 -1
  419. package/dist/sitemap/index.mjs +26 -9
  420. package/dist/sitemap/index.mjs.map +1 -1
  421. package/dist/sitemap/shared.d.ts +1 -1
  422. package/dist/sitemap/shared.d.ts.map +1 -1
  423. package/dist/sites/site-param.d.ts +2 -2
  424. package/dist/sync/index.js +17 -17
  425. package/dist/sync/index.mjs +4 -4
  426. package/dist/types.d.ts +1 -1
  427. package/dist/types.d.ts.map +1 -1
  428. package/dist/writeLLMsTxt-ATADOUVZ.js +20 -0
  429. package/dist/writeLLMsTxt-QJFXBHZF.mjs +11 -0
  430. package/package.json +20 -14
  431. package/dist/BlogPostFaqSection-P3GXVQPA.mjs +0 -11
  432. package/dist/BlogPostFaqSection-P3GXVQPA.mjs.map +0 -1
  433. package/dist/BlogPostFaqSection-YG5J4B4U.js +0 -13
  434. package/dist/BlogPostFaqSection-YG5J4B4U.js.map +0 -1
  435. package/dist/BlogViewTracker-Q7Y4MN4B.mjs.map +0 -1
  436. package/dist/BlogViewTracker-S3CSRBIZ.js.map +0 -1
  437. package/dist/ChatWidget-76R7NOWD.js +0 -24
  438. package/dist/ChatWidget-G3KOUDX5.mjs +0 -15
  439. package/dist/EngageWidget-HD4F2ZVE.js +0 -21
  440. package/dist/EngageWidget-UJ47PQFG.mjs +0 -12
  441. package/dist/ManagedForm-4ZGU4R3G.js +0 -25
  442. package/dist/ManagedForm-Z7QE4KYI.mjs +0 -16
  443. package/dist/ManagedNewsletterForm-22EPZB7Z.js.map +0 -1
  444. package/dist/ManagedNewsletterForm-4TVO2VL4.mjs.map +0 -1
  445. package/dist/SitemapSync-GF4OKN4Z.js +0 -18
  446. package/dist/SitemapSync-WIUEYOBS.mjs +0 -9
  447. package/dist/blog/AuthorCard.d.ts.map +0 -1
  448. package/dist/blog/AuthorPage.d.ts.map +0 -1
  449. package/dist/blog/BlogFAQ.d.ts.map +0 -1
  450. package/dist/blog/BlogLayout.d.ts.map +0 -1
  451. package/dist/blog/BlogList.d.ts.map +0 -1
  452. package/dist/blog/BlogPost.d.ts.map +0 -1
  453. package/dist/blog/BlogPostFaqSection.d.ts +0 -3
  454. package/dist/blog/BlogPostFaqSection.d.ts.map +0 -1
  455. package/dist/blog/BlogSidebar.d.ts.map +0 -1
  456. package/dist/blog/BlogViewTracker.d.ts.map +0 -1
  457. package/dist/blog/ClusterLandingPage.d.ts.map +0 -1
  458. package/dist/blog/ClusterNavigation.d.ts.map +0 -1
  459. package/dist/blog/ManagedNewsletterForm.d.ts.map +0 -1
  460. package/dist/blog/NewsletterShell.d.ts.map +0 -1
  461. package/dist/blog/NewsletterWidget.d.ts.map +0 -1
  462. package/dist/blog/RelatedPosts.d.ts.map +0 -1
  463. package/dist/blog/ServiceCallout.d.ts.map +0 -1
  464. package/dist/blog/TableOfContents.d.ts.map +0 -1
  465. package/dist/blog/artwork.d.ts +0 -14
  466. package/dist/blog/artwork.d.ts.map +0 -1
  467. package/dist/blog/author-schema.d.ts.map +0 -1
  468. package/dist/blog/author-social.d.ts.map +0 -1
  469. package/dist/blog/blog-styles.d.ts.map +0 -1
  470. package/dist/blog/blog-tables.d.ts.map +0 -1
  471. package/dist/blog/excerpt.d.ts.map +0 -1
  472. package/dist/blog/index.d.ts.map +0 -1
  473. package/dist/blog/index.js.map +0 -1
  474. package/dist/blog/index.mjs.map +0 -1
  475. package/dist/blog/processBlogHtml.d.ts.map +0 -1
  476. package/dist/blog/public-reads.d.ts +0 -27
  477. package/dist/blog/public-reads.d.ts.map +0 -1
  478. package/dist/blog/reading-time.d.ts.map +0 -1
  479. package/dist/blog/routes.d.ts.map +0 -1
  480. package/dist/blog/server-core.d.ts.map +0 -1
  481. package/dist/blog/server-ui.d.ts +0 -29
  482. package/dist/blog/server-ui.d.ts.map +0 -1
  483. package/dist/blog/server-ui.js +0 -267
  484. package/dist/blog/server-ui.js.map +0 -1
  485. package/dist/blog/server-ui.mjs +0 -203
  486. package/dist/blog/server-ui.mjs.map +0 -1
  487. package/dist/blog/server.d.ts.map +0 -1
  488. package/dist/blog/server.js +0 -207
  489. package/dist/blog/server.mjs +0 -10
  490. package/dist/blog/types.d.ts.map +0 -1
  491. package/dist/blog/widget-styles.d.ts +0 -9
  492. package/dist/blog/widget-styles.d.ts.map +0 -1
  493. package/dist/blog-styles-6EY3BS5Y.js.map +0 -1
  494. package/dist/blog-styles-7AKRUMV7.mjs.map +0 -1
  495. package/dist/blog-tables-DWDEWA3S.js +0 -17
  496. package/dist/blog-tables-DWDEWA3S.js.map +0 -1
  497. package/dist/blog-tables-QGIHOESZ.mjs +0 -4
  498. package/dist/blog-tables-QGIHOESZ.mjs.map +0 -1
  499. package/dist/chunk-3EY5E35M.mjs.map +0 -1
  500. package/dist/chunk-4LYW6PMU.mjs.map +0 -1
  501. package/dist/chunk-4TLFZ6NR.mjs.map +0 -1
  502. package/dist/chunk-5B4J3IBX.mjs +0 -164
  503. package/dist/chunk-5B4J3IBX.mjs.map +0 -1
  504. package/dist/chunk-5FETEH3Y.mjs +0 -6
  505. package/dist/chunk-75A4KY4X.mjs.map +0 -1
  506. package/dist/chunk-7R6H3GQ4.js +0 -8
  507. package/dist/chunk-7TC3GRXQ.js.map +0 -1
  508. package/dist/chunk-AJBOEV4I.mjs.map +0 -1
  509. package/dist/chunk-AK6JZ3OE.mjs.map +0 -1
  510. package/dist/chunk-FHPW7XVH.js +0 -175
  511. package/dist/chunk-FHPW7XVH.js.map +0 -1
  512. package/dist/chunk-G2WC3CXW.js.map +0 -1
  513. package/dist/chunk-GHECYDSZ.mjs.map +0 -1
  514. package/dist/chunk-GQF6QAQS.js.map +0 -1
  515. package/dist/chunk-H5NBFNND.js.map +0 -1
  516. package/dist/chunk-HX6ZG3PP.js.map +0 -1
  517. package/dist/chunk-JLVCWC6A.mjs.map +0 -1
  518. package/dist/chunk-K4TCEAUX.js.map +0 -1
  519. package/dist/chunk-LMEUYRRR.js.map +0 -1
  520. package/dist/chunk-MWKI6ZIS.mjs.map +0 -1
  521. package/dist/chunk-O237KKCX.mjs.map +0 -1
  522. package/dist/chunk-Q2NBD54V.js.map +0 -1
  523. package/dist/chunk-R7GHP3FY.js.map +0 -1
  524. package/dist/chunk-W2U5SLMY.js.map +0 -1
  525. package/dist/chunk-XEB77DQS.js.map +0 -1
  526. package/dist/chunk-Y5QZPUL3.mjs.map +0 -1
  527. package/dist/chunk-YFX3Q56O.mjs.map +0 -1
  528. package/dist/chunk-YN7QHLWF.js.map +0 -1
  529. package/dist/chunk-YQTE32QK.js.map +0 -1
  530. package/dist/chunk-ZPLN537Q.mjs.map +0 -1
  531. package/dist/chunk-ZVI7MBVF.mjs.map +0 -1
  532. package/dist/discover-CYXYKHZ2.mjs +0 -4
  533. package/dist/discover-NGEPXZOD.js +0 -21
  534. package/dist/writeLLMsTxt-CQ7A4AAL.js +0 -19
  535. package/dist/writeLLMsTxt-NX5MSPYX.mjs +0 -10
  536. /package/dist/{blog → articles}/server.js.map +0 -0
  537. /package/dist/{blog → articles}/server.mjs.map +0 -0
@@ -1,7 +1,7 @@
1
1
  'use client';
2
2
  'use strict';
3
3
 
4
- var chunkNMM27UOF_js = require('./chunk-NMM27UOF.js');
4
+ var chunkVINLIMAX_js = require('./chunk-VINLIMAX.js');
5
5
  var React = require('react');
6
6
  var jsxRuntime = require('react/jsx-runtime');
7
7
 
@@ -16,8 +16,8 @@ function SignalExperiment({
16
16
  trackImpression = true,
17
17
  children
18
18
  }) {
19
- const { assignment, variant, isControl } = chunkNMM27UOF_js.useSignalExperiment(experimentId);
20
- const trackEvent = chunkNMM27UOF_js.useSignalEvent();
19
+ const { assignment, variant, isControl } = chunkVINLIMAX_js.useSignalExperiment(experimentId);
20
+ const trackEvent = chunkVINLIMAX_js.useSignalEvent();
21
21
  React.useEffect(() => {
22
22
  if (trackImpression && variant) {
23
23
  trackEvent({
@@ -44,7 +44,7 @@ function SignalExperiment({
44
44
  return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: variants.control || null });
45
45
  }
46
46
  function useExperimentVariant(experimentId) {
47
- return chunkNMM27UOF_js.useSignalExperiment(experimentId);
47
+ return chunkVINLIMAX_js.useSignalExperiment(experimentId);
48
48
  }
49
49
  function ExperimentConversion({
50
50
  experimentId,
@@ -52,8 +52,8 @@ function ExperimentConversion({
52
52
  value,
53
53
  children
54
54
  }) {
55
- const trackEvent = chunkNMM27UOF_js.useSignalEvent();
56
- const { variant } = chunkNMM27UOF_js.useSignalExperiment(experimentId);
55
+ const trackEvent = chunkVINLIMAX_js.useSignalEvent();
56
+ const { variant } = chunkVINLIMAX_js.useSignalExperiment(experimentId);
57
57
  const handleInteraction = () => {
58
58
  trackEvent({
59
59
  event_type: "experiment",
@@ -79,5 +79,5 @@ function ExperimentConversion({
79
79
  exports.ExperimentConversion = ExperimentConversion;
80
80
  exports.SignalExperiment = SignalExperiment;
81
81
  exports.useExperimentVariant = useExperimentVariant;
82
- //# sourceMappingURL=chunk-MYMZRHTC.js.map
83
- //# sourceMappingURL=chunk-MYMZRHTC.js.map
82
+ //# sourceMappingURL=chunk-SCRB5DZM.js.map
83
+ //# sourceMappingURL=chunk-SCRB5DZM.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/signal/SignalExperiment.tsx"],"names":["useSignalExperiment","useSignalEvent","useEffect","jsx","Fragment","React"],"mappings":";;;;;;;;;;AAgDO,SAAS,gBAAA,CAAiB;AAAA,EAC/B,YAAA;AAAA,EACA,QAAA;AAAA,EACA,QAAA;AAAA,EACA,eAAA,GAAkB,IAAA;AAAA,EAClB;AACF,CAAA,EAA0B;AACxB,EAAA,MAAM,EAAE,UAAA,EAAY,OAAA,EAAS,SAAA,EAAU,GAAIA,qCAAoB,YAAY,CAAA;AAC3E,EAAA,MAAM,aAAaC,+BAAA,EAAe;AAGlC,EAAAC,eAAA,CAAU,MAAM;AACd,IAAA,IAAI,mBAAmB,OAAA,EAAS;AAC9B,MAAA,UAAA,CAAW;AAAA,QACT,UAAA,EAAY,YAAA;AAAA,QACZ,UAAA,EAAY,YAAA;AAAA,QACZ,UAAA,EAAY;AAAA,UACV,aAAA,EAAe,YAAA;AAAA,UACf,WAAA,EAAa;AAAA;AACf,OACD,CAAA;AAAA,IACH;AAAA,EACF,GAAG,CAAC,YAAA,EAAc,OAAA,EAAS,eAAA,EAAiB,UAAU,CAAC,CAAA;AAGvD,EAAA,IAAI,QAAA,EAAU;AACZ,IAAA,uBAAOC,cAAA,CAAAC,mBAAA,EAAA,EAAG,mBAAS,EAAE,OAAA,EAAS,WAAW,SAAA,EAAW,SAAA,EAAW,CAAA,EAAE,CAAA;AAAA,EACnE;AAGA,EAAA,MAAM,kBAAkB,OAAA,IAAW,SAAA;AACnC,EAAA,MAAM,OAAA,GAAU,SAAS,eAAe,CAAA;AAExC,EAAA,IAAI,YAAY,MAAA,EAAW;AACzB,IAAA,6DAAU,QAAA,EAAA,OAAA,EAAQ,CAAA;AAAA,EACpB;AAGA,EAAA,IAAI,QAAA,EAAU;AACZ,IAAA,6DAAU,QAAA,EAAA,QAAA,EAAS,CAAA;AAAA,EACrB;AAEA,EAAA,uBAAOD,cAAA,CAAAC,mBAAA,EAAA,EAAG,QAAA,EAAA,QAAA,CAAS,OAAA,IAAW,IAAA,EAAK,CAAA;AACrC;AAYO,SAAS,qBAAqB,YAAA,EAAsB;AACzD,EAAA,OAAOJ,qCAAoB,YAAY,CAAA;AACzC;AAoBO,SAAS,oBAAA,CAAqB;AAAA,EACnC,YAAA;AAAA,EACA,WAAA,GAAc,OAAA;AAAA,EACd,KAAA;AAAA,EACA;AACF,CAAA,EAKG;AACD,EAAA,MAAM,aAAaC,+BAAA,EAAe;AAClC,EAAA,MAAM,EAAE,OAAA,EAAQ,GAAID,oCAAA,CAAoB,YAAY,CAAA;AAEpD,EAAA,MAAM,oBAAoB,MAAM;AAC9B,IAAA,UAAA,CAAW;AAAA,MACT,UAAA,EAAY,YAAA;AAAA,MACZ,UAAA,EAAY,YAAA;AAAA,MACZ,UAAA,EAAY;AAAA,QACV,aAAA,EAAe,YAAA;AAAA,QACf,WAAA,EAAa,OAAA;AAAA,QACb,YAAA,EAAc,WAAA;AAAA,QACd;AAAA;AACF,KACD,CAAA;AAAA,EACH,CAAA;AAEA,EAAA,OAAOK,sBAAA,CAAM,aAAa,QAAA,EAAU;AAAA,IAClC,OAAA,EAAS,CAAC,CAAA,KAAwB;AAChC,MAAA,iBAAA,EAAkB;AAElB,MAAA,IAAK,QAAA,CAAS,MAAsD,OAAA,EAAS;AAC3E,QAAC,QAAA,CAAS,KAAA,CAAsD,OAAA,CAAS,CAAC,CAAA;AAAA,MAC5E;AAAA,IACF;AAAA,GACD,CAAA;AACH","file":"chunk-MYMZRHTC.js","sourcesContent":["/**\n * @sonordev/site-kit/signal - SignalExperiment\n * \n * A/B test component that renders different variants based on Signal assignment.\n * Uses Thompson Sampling (Bayesian bandit) for optimization.\n */\n\n'use client'\n\nimport React, { useMemo, useEffect } from 'react'\nimport { useSignalExperiment, useSignalEvent } from './SignalBridge'\n\ninterface SignalExperimentProps {\n /** Unique experiment ID */\n experimentId: string\n \n /** Variants to test - keys are variant names, values are React nodes */\n variants: Record<string, React.ReactNode>\n \n /** Fallback content if no assignment (defaults to 'control' variant) */\n fallback?: React.ReactNode\n \n /** Track impression automatically */\n trackImpression?: boolean\n \n /** Children function for more control */\n children?: (props: { variant: string; isControl: boolean }) => React.ReactNode\n}\n\n/**\n * Renders different content variants based on Signal's A/B assignment.\n * \n * @example\n * // Simple variant switching\n * <SignalExperiment experimentId=\"hero-cta\" variants={{\n * control: <Button>Get Started</Button>,\n * variant_a: <Button variant=\"primary\">Start Free Trial</Button>,\n * variant_b: <Button variant=\"secondary\">Book a Demo</Button>,\n * }} />\n * \n * @example\n * // With render prop for more control\n * <SignalExperiment experimentId=\"pricing-layout\">\n * {({ variant, isControl }) => (\n * <PricingSection layout={isControl ? 'cards' : 'table'} />\n * )}\n * </SignalExperiment>\n */\nexport function SignalExperiment({\n experimentId,\n variants,\n fallback,\n trackImpression = true,\n children,\n}: SignalExperimentProps) {\n const { assignment, variant, isControl } = useSignalExperiment(experimentId)\n const trackEvent = useSignalEvent()\n \n // Track impression when variant is rendered\n useEffect(() => {\n if (trackImpression && variant) {\n trackEvent({\n event_type: 'experiment',\n event_name: 'impression',\n event_data: {\n experiment_id: experimentId,\n variant_key: variant,\n },\n })\n }\n }, [experimentId, variant, trackImpression, trackEvent])\n \n // If using render prop\n if (children) {\n return <>{children({ variant: variant || 'control', isControl })}</>\n }\n \n // Determine what to render\n const selectedVariant = variant || 'control'\n const content = variants[selectedVariant]\n \n if (content !== undefined) {\n return <>{content}</>\n }\n \n // Fallback to provided fallback or control\n if (fallback) {\n return <>{fallback}</>\n }\n \n return <>{variants.control || null}</>\n}\n\n/**\n * Hook for conditional experiment logic\n * \n * @example\n * const { variant, isControl } = useExperimentVariant('pricing-test')\n * \n * return isControl \n * ? <OldPricing />\n * : <NewPricing showAnnual={variant === 'annual_first'} />\n */\nexport function useExperimentVariant(experimentId: string) {\n return useSignalExperiment(experimentId)\n}\n\n/**\n * Component for tracking experiment conversions\n * Wraps interactive elements to track when they convert\n * \n * @example\n * <SignalExperiment experimentId=\"signup-button\" variants={{\n * control: (\n * <ExperimentConversion experimentId=\"signup-button\" outcomeType=\"click\">\n * <Button>Sign Up</Button>\n * </ExperimentConversion>\n * ),\n * variant_a: (\n * <ExperimentConversion experimentId=\"signup-button\" outcomeType=\"click\">\n * <Button variant=\"large\">Join Now - It's Free!</Button>\n * </ExperimentConversion>\n * ),\n * }} />\n */\nexport function ExperimentConversion({\n experimentId,\n outcomeType = 'click',\n value,\n children,\n}: {\n experimentId: string\n outcomeType?: string\n value?: number\n children: React.ReactElement<{ onClick?: (e: React.MouseEvent) => void }>\n}) {\n const trackEvent = useSignalEvent()\n const { variant } = useSignalExperiment(experimentId)\n\n const handleInteraction = () => {\n trackEvent({\n event_type: 'experiment',\n event_name: 'conversion',\n event_data: {\n experiment_id: experimentId,\n variant_key: variant,\n outcome_type: outcomeType,\n value,\n },\n })\n }\n\n return React.cloneElement(children, {\n onClick: (e: React.MouseEvent) => {\n handleInteraction()\n // Call original onClick if exists\n if ((children.props as { onClick?: (e: React.MouseEvent) => void }).onClick) {\n (children.props as { onClick?: (e: React.MouseEvent) => void }).onClick!(e)\n }\n },\n })\n}\n"]}
1
+ {"version":3,"sources":["../src/signal/SignalExperiment.tsx"],"names":["useSignalExperiment","useSignalEvent","useEffect","jsx","Fragment","React"],"mappings":";;;;;;;;;;AAgDO,SAAS,gBAAA,CAAiB;AAAA,EAC/B,YAAA;AAAA,EACA,QAAA;AAAA,EACA,QAAA;AAAA,EACA,eAAA,GAAkB,IAAA;AAAA,EAClB;AACF,CAAA,EAA0B;AACxB,EAAA,MAAM,EAAE,UAAA,EAAY,OAAA,EAAS,SAAA,EAAU,GAAIA,qCAAoB,YAAY,CAAA;AAC3E,EAAA,MAAM,aAAaC,+BAAA,EAAe;AAGlC,EAAAC,eAAA,CAAU,MAAM;AACd,IAAA,IAAI,mBAAmB,OAAA,EAAS;AAC9B,MAAA,UAAA,CAAW;AAAA,QACT,UAAA,EAAY,YAAA;AAAA,QACZ,UAAA,EAAY,YAAA;AAAA,QACZ,UAAA,EAAY;AAAA,UACV,aAAA,EAAe,YAAA;AAAA,UACf,WAAA,EAAa;AAAA;AACf,OACD,CAAA;AAAA,IACH;AAAA,EACF,GAAG,CAAC,YAAA,EAAc,OAAA,EAAS,eAAA,EAAiB,UAAU,CAAC,CAAA;AAGvD,EAAA,IAAI,QAAA,EAAU;AACZ,IAAA,uBAAOC,cAAA,CAAAC,mBAAA,EAAA,EAAG,mBAAS,EAAE,OAAA,EAAS,WAAW,SAAA,EAAW,SAAA,EAAW,CAAA,EAAE,CAAA;AAAA,EACnE;AAGA,EAAA,MAAM,kBAAkB,OAAA,IAAW,SAAA;AACnC,EAAA,MAAM,OAAA,GAAU,SAAS,eAAe,CAAA;AAExC,EAAA,IAAI,YAAY,MAAA,EAAW;AACzB,IAAA,6DAAU,QAAA,EAAA,OAAA,EAAQ,CAAA;AAAA,EACpB;AAGA,EAAA,IAAI,QAAA,EAAU;AACZ,IAAA,6DAAU,QAAA,EAAA,QAAA,EAAS,CAAA;AAAA,EACrB;AAEA,EAAA,uBAAOD,cAAA,CAAAC,mBAAA,EAAA,EAAG,QAAA,EAAA,QAAA,CAAS,OAAA,IAAW,IAAA,EAAK,CAAA;AACrC;AAYO,SAAS,qBAAqB,YAAA,EAAsB;AACzD,EAAA,OAAOJ,qCAAoB,YAAY,CAAA;AACzC;AAoBO,SAAS,oBAAA,CAAqB;AAAA,EACnC,YAAA;AAAA,EACA,WAAA,GAAc,OAAA;AAAA,EACd,KAAA;AAAA,EACA;AACF,CAAA,EAKG;AACD,EAAA,MAAM,aAAaC,+BAAA,EAAe;AAClC,EAAA,MAAM,EAAE,OAAA,EAAQ,GAAID,oCAAA,CAAoB,YAAY,CAAA;AAEpD,EAAA,MAAM,oBAAoB,MAAM;AAC9B,IAAA,UAAA,CAAW;AAAA,MACT,UAAA,EAAY,YAAA;AAAA,MACZ,UAAA,EAAY,YAAA;AAAA,MACZ,UAAA,EAAY;AAAA,QACV,aAAA,EAAe,YAAA;AAAA,QACf,WAAA,EAAa,OAAA;AAAA,QACb,YAAA,EAAc,WAAA;AAAA,QACd;AAAA;AACF,KACD,CAAA;AAAA,EACH,CAAA;AAEA,EAAA,OAAOK,sBAAA,CAAM,aAAa,QAAA,EAAU;AAAA,IAClC,OAAA,EAAS,CAAC,CAAA,KAAwB;AAChC,MAAA,iBAAA,EAAkB;AAElB,MAAA,IAAK,QAAA,CAAS,MAAsD,OAAA,EAAS;AAC3E,QAAC,QAAA,CAAS,KAAA,CAAsD,OAAA,CAAS,CAAC,CAAA;AAAA,MAC5E;AAAA,IACF;AAAA,GACD,CAAA;AACH","file":"chunk-SCRB5DZM.js","sourcesContent":["/**\n * @sonordev/site-kit/signal - SignalExperiment\n * \n * A/B test component that renders different variants based on Signal assignment.\n * Uses Thompson Sampling (Bayesian bandit) for optimization.\n */\n\n'use client'\n\nimport React, { useMemo, useEffect } from 'react'\nimport { useSignalExperiment, useSignalEvent } from './SignalBridge'\n\ninterface SignalExperimentProps {\n /** Unique experiment ID */\n experimentId: string\n \n /** Variants to test - keys are variant names, values are React nodes */\n variants: Record<string, React.ReactNode>\n \n /** Fallback content if no assignment (defaults to 'control' variant) */\n fallback?: React.ReactNode\n \n /** Track impression automatically */\n trackImpression?: boolean\n \n /** Children function for more control */\n children?: (props: { variant: string; isControl: boolean }) => React.ReactNode\n}\n\n/**\n * Renders different content variants based on Signal's A/B assignment.\n * \n * @example\n * // Simple variant switching\n * <SignalExperiment experimentId=\"hero-cta\" variants={{\n * control: <Button>Get Started</Button>,\n * variant_a: <Button variant=\"primary\">Start Free Trial</Button>,\n * variant_b: <Button variant=\"secondary\">Book a Demo</Button>,\n * }} />\n * \n * @example\n * // With render prop for more control\n * <SignalExperiment experimentId=\"pricing-layout\">\n * {({ variant, isControl }) => (\n * <PricingSection layout={isControl ? 'cards' : 'table'} />\n * )}\n * </SignalExperiment>\n */\nexport function SignalExperiment({\n experimentId,\n variants,\n fallback,\n trackImpression = true,\n children,\n}: SignalExperimentProps) {\n const { assignment, variant, isControl } = useSignalExperiment(experimentId)\n const trackEvent = useSignalEvent()\n \n // Track impression when variant is rendered\n useEffect(() => {\n if (trackImpression && variant) {\n trackEvent({\n event_type: 'experiment',\n event_name: 'impression',\n event_data: {\n experiment_id: experimentId,\n variant_key: variant,\n },\n })\n }\n }, [experimentId, variant, trackImpression, trackEvent])\n \n // If using render prop\n if (children) {\n return <>{children({ variant: variant || 'control', isControl })}</>\n }\n \n // Determine what to render\n const selectedVariant = variant || 'control'\n const content = variants[selectedVariant]\n \n if (content !== undefined) {\n return <>{content}</>\n }\n \n // Fallback to provided fallback or control\n if (fallback) {\n return <>{fallback}</>\n }\n \n return <>{variants.control || null}</>\n}\n\n/**\n * Hook for conditional experiment logic\n * \n * @example\n * const { variant, isControl } = useExperimentVariant('pricing-test')\n * \n * return isControl \n * ? <OldPricing />\n * : <NewPricing showAnnual={variant === 'annual_first'} />\n */\nexport function useExperimentVariant(experimentId: string) {\n return useSignalExperiment(experimentId)\n}\n\n/**\n * Component for tracking experiment conversions\n * Wraps interactive elements to track when they convert\n * \n * @example\n * <SignalExperiment experimentId=\"signup-button\" variants={{\n * control: (\n * <ExperimentConversion experimentId=\"signup-button\" outcomeType=\"click\">\n * <Button>Sign Up</Button>\n * </ExperimentConversion>\n * ),\n * variant_a: (\n * <ExperimentConversion experimentId=\"signup-button\" outcomeType=\"click\">\n * <Button variant=\"large\">Join Now - It's Free!</Button>\n * </ExperimentConversion>\n * ),\n * }} />\n */\nexport function ExperimentConversion({\n experimentId,\n outcomeType = 'click',\n value,\n children,\n}: {\n experimentId: string\n outcomeType?: string\n value?: number\n children: React.ReactElement<{ onClick?: (e: React.MouseEvent) => void }>\n}) {\n const trackEvent = useSignalEvent()\n const { variant } = useSignalExperiment(experimentId)\n\n const handleInteraction = () => {\n trackEvent({\n event_type: 'experiment',\n event_name: 'conversion',\n event_data: {\n experiment_id: experimentId,\n variant_key: variant,\n outcome_type: outcomeType,\n value,\n },\n })\n }\n\n return React.cloneElement(children, {\n onClick: (e: React.MouseEvent) => {\n handleInteraction()\n // Call original onClick if exists\n if ((children.props as { onClick?: (e: React.MouseEvent) => void }).onClick) {\n (children.props as { onClick?: (e: React.MouseEvent) => void }).onClick!(e)\n }\n },\n })\n}\n"]}
@@ -1,7 +1,8 @@
1
1
  'use strict';
2
2
 
3
- // src/blog/blog-tables.ts
4
- var tableScrollClass = "sk-blog-table-scroll";
3
+ // src/articles/article-tables.ts
4
+ var tableScrollClass = "sk-article-table-scroll";
5
+ var legacyTableScrollClass = "sk-blog-table-scroll";
5
6
  var voidElements = /* @__PURE__ */ new Set([
6
7
  "area",
7
8
  "base",
@@ -27,7 +28,7 @@ function hasScrollClass(tag) {
27
28
  const pattern = /([^\s=/>]+)(?:\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s"'=<>`]+)))?/g;
28
29
  for (const attribute of attributes.matchAll(pattern)) {
29
30
  if (attribute[1].toLowerCase() !== "class") continue;
30
- return (attribute[2] ?? attribute[3] ?? attribute[4] ?? "").split(/\s+/).includes(tableScrollClass);
31
+ return (attribute[2] ?? attribute[3] ?? attribute[4] ?? "").split(/\s+/).some((name) => name === tableScrollClass || name === legacyTableScrollClass);
31
32
  }
32
33
  return false;
33
34
  }
@@ -43,7 +44,7 @@ function tableLabel(table, number) {
43
44
  const summary = labelText(caption || headers).slice(0, 180);
44
45
  return escapeLabel(`Table ${number}${summary ? `: ${summary}` : ""}`);
45
46
  }
46
- function wrapBlogTables(html) {
47
+ function wrapArticleTables(html) {
47
48
  const tags = htmlTags();
48
49
  const stack = [];
49
50
  const tables = [];
@@ -87,10 +88,10 @@ function wrapBlogTables(html) {
87
88
  }
88
89
  return output + html.slice(cursor);
89
90
  }
90
- var blogTableCss = (
91
+ var articleTableCss = (
91
92
  /* css */
92
93
  `
93
- .sk-blog-content .sk-blog-table-scroll {
94
+ .sk-article-content .sk-article-table-scroll {
94
95
  box-sizing: border-box;
95
96
  min-width: 0;
96
97
  max-width: 100%;
@@ -103,27 +104,27 @@ var blogTableCss = (
103
104
  scrollbar-color: var(--sk-primary, #2563eb) var(--sk-bg-elevated, #f8fafc);
104
105
  overscroll-behavior-x: contain;
105
106
  }
106
- .sk-blog-content .sk-blog-table-scroll:focus-visible {
107
+ .sk-article-content .sk-article-table-scroll:focus-visible {
107
108
  outline: 2px solid var(--sk-border-focus, var(--sk-primary, #2563eb));
108
109
  outline-offset: 3px;
109
110
  }
110
- .sk-blog-content .sk-blog-table-scroll::-webkit-scrollbar { height: 10px; }
111
- .sk-blog-content .sk-blog-table-scroll::-webkit-scrollbar-track {
111
+ .sk-article-content .sk-article-table-scroll::-webkit-scrollbar { height: 10px; }
112
+ .sk-article-content .sk-article-table-scroll::-webkit-scrollbar-track {
112
113
  background: var(--sk-bg-elevated, #f8fafc);
113
114
  border-radius: var(--sk-radius, 0.5rem);
114
115
  }
115
- .sk-blog-content .sk-blog-table-scroll::-webkit-scrollbar-thumb {
116
+ .sk-article-content .sk-article-table-scroll::-webkit-scrollbar-thumb {
116
117
  background: var(--sk-primary, #2563eb);
117
118
  background-clip: padding-box;
118
119
  border: 2px solid var(--sk-bg-elevated, #f8fafc);
119
120
  border-radius: var(--sk-radius, 0.5rem);
120
121
  }
121
- .sk-blog-content .sk-blog-table-scroll > table {
122
+ .sk-article-content .sk-article-table-scroll > table {
122
123
  display: table;
123
124
  margin: 0;
124
125
  overflow: visible;
125
126
  }
126
- .sk-blog-content .sk-blog-table-scroll caption {
127
+ .sk-article-content .sk-article-table-scroll caption {
127
128
  padding: 0.625rem 0.875rem;
128
129
  text-align: start;
129
130
  color: var(--sk-text-secondary, #475569);
@@ -131,7 +132,7 @@ var blogTableCss = (
131
132
  `.trim()
132
133
  );
133
134
 
134
- exports.blogTableCss = blogTableCss;
135
- exports.wrapBlogTables = wrapBlogTables;
136
- //# sourceMappingURL=chunk-YQTE32QK.js.map
137
- //# sourceMappingURL=chunk-YQTE32QK.js.map
135
+ exports.articleTableCss = articleTableCss;
136
+ exports.wrapArticleTables = wrapArticleTables;
137
+ //# sourceMappingURL=chunk-SG7CWD2R.js.map
138
+ //# sourceMappingURL=chunk-SG7CWD2R.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/articles/article-tables.ts"],"names":["frame"],"mappings":"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","file":"chunk-SG7CWD2R.js","sourcesContent":["/**\n * Server-rendered table scrolling. Keep the author's table markup intact so\n * captions, header associations, links and table semantics survive unchanged.\n */\n\nconst tableScrollClass = 'sk-article-table-scroll'\n/** The pre-6.0 name, still recognized in stored HTML so an already-wrapped table isn't wrapped twice. */\nconst legacyTableScrollClass = 'sk-blog-table-scroll'\nconst voidElements = new Set([\n 'area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input', 'link', 'meta',\n 'param', 'source', 'track', 'wbr',\n])\nconst preservedElements = new Set(['pre', 'code', 'script', 'style', 'textarea', 'xmp', 'template'])\n\n/** Match complete tags, including quoted `>` characters, without reserializing HTML. */\nfunction htmlTags(): RegExp {\n return /<!--[\\s\\S]*?(?:-->|$)|<\\/?[a-z][\\w:-]*(?=[\\s/>])(?:[^\"'<>]|\"[^\"]*\"|'[^']*')*>/gi\n}\n\nfunction hasScrollClass(tag: string): boolean {\n const attributes = tag.replace(/^<[\\w:-]+/, '').replace(/\\/?>$/, '')\n const pattern = /([^\\s=/>]+)(?:\\s*=\\s*(?:\"([^\"]*)\"|'([^']*)'|([^\\s\"'=<>`]+)))?/g\n for (const attribute of attributes.matchAll(pattern)) {\n if (attribute[1].toLowerCase() !== 'class') continue\n return (attribute[2] ?? attribute[3] ?? attribute[4] ?? '').split(/\\s+/).some((name) => name === tableScrollClass || name === legacyTableScrollClass)\n }\n return false\n}\n\nfunction labelText(html: string): string {\n // Preserve existing character references in the eventual attribute. Escaping\n // them a second time would announce \"amp\" instead of the author's text.\n return html\n .replace(/<!--[\\s\\S]*?(?:-->|$)/g, '')\n .replace(htmlTags(), ' ')\n .replace(/\\s+/g, ' ')\n .trim()\n}\n\nfunction escapeLabel(text: string): string {\n return text\n .replace(/&(?!(?:#\\d+|#x[\\da-f]+|[a-z][\\da-z]+);)/gi, '&amp;')\n .replace(/\"/g, '&quot;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n}\n\nfunction tableLabel(table: string, number: number): string {\n const caption = table.match(/<caption\\b(?:[^\"'<>]|\"[^\"]*\"|'[^']*')*>([\\s\\S]*?)<\\/caption\\s*>/i)?.[1]\n const headers = [...table.matchAll(/<th\\b(?:[^\"'<>]|\"[^\"]*\"|'[^']*')*>([\\s\\S]*?)<\\/th\\s*>/gi)]\n .slice(0, 4)\n .map((match) => labelText(match[1]))\n .filter(Boolean)\n .join(', ')\n const summary = labelText(caption || headers).slice(0, 180)\n return escapeLabel(`Table ${number}${summary ? `: ${summary}` : ''}`)\n}\n\ninterface ElementFrame {\n tag: string\n scrollRegion: boolean\n table?: { start: number; number: number }\n}\n\n/**\n * Single source of truth for default article table wrappers. Safe to call twice;\n * already wrapped tables and HTML examples are left alone. This is a layout\n * transform, not an HTML sanitizer: content still follows the host's trust policy.\n */\nexport function wrapArticleTables(html: string): string {\n const tags = htmlTags()\n const stack: ElementFrame[] = []\n const tables: Array<{ start: number; end: number; number: number }> = []\n let tableNumber = 0\n let token: RegExpExecArray | null\n\n while ((token = tags.exec(html))) {\n const tag = token[0]\n if (tag.startsWith('<!--')) continue\n const tagName = /^<\\/?([\\w:-]+)/.exec(tag)![1].toLowerCase()\n\n if (tag.startsWith('</')) {\n const index = stack.map((frame) => frame.tag).lastIndexOf(tagName)\n if (index < 0) continue\n const frame = stack[index]\n if (frame.table) tables.push({ ...frame.table, end: tags.lastIndex })\n stack.length = index\n continue\n }\n\n if (preservedElements.has(tagName)) {\n // Code examples and raw text can contain literal HTML. Skip to the end\n // without interpreting any of those tags as article content.\n const closingTag = new RegExp(`</${tagName}\\\\s*>`, 'gi')\n closingTag.lastIndex = tags.lastIndex\n if (!closingTag.exec(html)) break\n tags.lastIndex = closingTag.lastIndex\n continue\n }\n\n if (voidElements.has(tagName) || /\\/\\s*>$/.test(tag)) continue\n const frame: ElementFrame = { tag: tagName, scrollRegion: hasScrollClass(tag) }\n if (tagName === 'table' && !stack.some((ancestor) => ancestor.tag === 'table')) {\n tableNumber += 1\n if (!stack.some((ancestor) => ancestor.scrollRegion)) {\n frame.table = { start: token.index, number: tableNumber }\n }\n }\n stack.push(frame)\n }\n\n let output = ''\n let cursor = 0\n for (const { start, end, number } of tables) {\n const table = html.slice(start, end)\n output += `${html.slice(cursor, start)}<div class=\"${tableScrollClass}\" role=\"region\" tabindex=\"0\" aria-label=\"${tableLabel(table, number)}\">${table}</div>`\n cursor = end\n }\n return output + html.slice(cursor)\n}\n\n/** Native overflow only when content needs it; small tables retain their layout. */\nexport const articleTableCss = /* css */ `\n.sk-article-content .sk-article-table-scroll {\n box-sizing: border-box;\n min-width: 0;\n max-width: 100%;\n overflow-x: auto;\n margin: 1.5em 0;\n border: 1px solid var(--sk-surface-border, #e2e8f0);\n border-radius: var(--sk-radius, 0.5rem);\n background: var(--sk-bg-elevated, #f8fafc);\n scrollbar-width: thin;\n scrollbar-color: var(--sk-primary, #2563eb) var(--sk-bg-elevated, #f8fafc);\n overscroll-behavior-x: contain;\n}\n.sk-article-content .sk-article-table-scroll:focus-visible {\n outline: 2px solid var(--sk-border-focus, var(--sk-primary, #2563eb));\n outline-offset: 3px;\n}\n.sk-article-content .sk-article-table-scroll::-webkit-scrollbar { height: 10px; }\n.sk-article-content .sk-article-table-scroll::-webkit-scrollbar-track {\n background: var(--sk-bg-elevated, #f8fafc);\n border-radius: var(--sk-radius, 0.5rem);\n}\n.sk-article-content .sk-article-table-scroll::-webkit-scrollbar-thumb {\n background: var(--sk-primary, #2563eb);\n background-clip: padding-box;\n border: 2px solid var(--sk-bg-elevated, #f8fafc);\n border-radius: var(--sk-radius, 0.5rem);\n}\n.sk-article-content .sk-article-table-scroll > table {\n display: table;\n margin: 0;\n overflow: visible;\n}\n.sk-article-content .sk-article-table-scroll caption {\n padding: 0.625rem 0.875rem;\n text-align: start;\n color: var(--sk-text-secondary, #475569);\n}\n`.trim()\n"]}
@@ -50,7 +50,7 @@ function createSpeakableSchema(type, name, url, speakable, additionalProperties
50
50
  var DEFAULT_SPEAKABLE_SELECTORS = {
51
51
  /** Standard page elements */
52
52
  page: ["h1", 'meta[name="description"]', ".page-summary"],
53
- /** Article/blog post elements */
53
+ /** Article/article elements */
54
54
  article: ["h1", ".article-summary", ".article-intro", 'meta[name="description"]'],
55
55
  /** Service page elements */
56
56
  service: ["h1", ".service-overview", ".key-benefits", 'meta[name="description"]'],
@@ -464,5 +464,5 @@ exports.DEFAULT_SPEAKABLE_SELECTORS = DEFAULT_SPEAKABLE_SELECTORS;
464
464
  exports.SpeakableSchema = SpeakableSchema;
465
465
  exports.createSpeakableSchema = createSpeakableSchema;
466
466
  exports.getSpeakableSelectorsForPage = getSpeakableSelectorsForPage;
467
- //# sourceMappingURL=chunk-XEB77DQS.js.map
468
- //# sourceMappingURL=chunk-XEB77DQS.js.map
467
+ //# sourceMappingURL=chunk-TBXWJJGT.js.map
468
+ //# sourceMappingURL=chunk-TBXWJJGT.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/llms/SpeakableSchema.tsx","../src/llms/AEOComponents.tsx"],"names":["jsx","safeJsonLd","jsxs"],"mappings":"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","file":"chunk-TBXWJJGT.js","sourcesContent":["/**\n * @sonordev/site-kit/llms - Speakable Schema Generator\n * \n * Generates JSON-LD with SpeakableSpecification for voice assistant\n * and AI system content extraction.\n * \n * @see https://schema.org/speakable\n * @see https://developers.google.com/search/docs/appearance/structured-data/speakable\n */\n\nimport * as React from 'react'\nimport type { SpeakableSchemaProps, SpeakableConfig } from './types'\nimport { safeJsonLd } from '../seo/safeJsonLd'\n\n/**\n * Generate a WebPage or Article schema with speakable specification\n * \n * @example\n * ```tsx\n * // In a page component\n * <SpeakableSchema\n * type=\"Article\"\n * name=\"Family Law Services in Cincinnati\"\n * url=\"https://heinrichlaw.com/family-law\"\n * speakable={{\n * cssSelectors: ['.page-summary', '.key-points', 'h1']\n * }}\n * />\n * ```\n */\nexport function SpeakableSchema({\n type,\n name,\n url,\n speakable,\n additionalProperties = {},\n}: SpeakableSchemaProps): React.ReactElement {\n const schema = createSpeakableSchema(type, name, url, speakable, additionalProperties)\n \n return (\n <script\n type=\"application/ld+json\"\n dangerouslySetInnerHTML={{\n __html: safeJsonLd(schema),\n }}\n />\n )\n}\n\n/**\n * Create speakable schema object (for manual use or testing)\n */\nexport function createSpeakableSchema(\n type: 'Article' | 'WebPage',\n name: string,\n url: string,\n speakable: SpeakableConfig,\n additionalProperties: Record<string, unknown> = {}\n): Record<string, unknown> {\n const speakableSpec: Record<string, unknown> = {\n '@type': 'SpeakableSpecification',\n }\n\n // Prefer CSS selectors, fall back to XPath\n if (speakable.cssSelectors?.length) {\n speakableSpec.cssSelector = speakable.cssSelectors\n } else if (speakable.xPaths?.length) {\n speakableSpec.xpath = speakable.xPaths\n } else {\n // Default speakable selectors for common patterns\n speakableSpec.cssSelector = [\n 'h1',\n '[data-speakable]',\n '.page-summary',\n '.key-points',\n 'meta[name=\"description\"]'\n ]\n }\n\n return {\n '@context': 'https://schema.org',\n '@type': type,\n name,\n url,\n speakable: speakableSpec,\n ...additionalProperties,\n }\n}\n\n/**\n * Default speakable CSS selectors for common page elements\n */\nexport const DEFAULT_SPEAKABLE_SELECTORS = {\n /** Standard page elements */\n page: ['h1', 'meta[name=\"description\"]', '.page-summary'],\n /** Article/article elements */\n article: ['h1', '.article-summary', '.article-intro', 'meta[name=\"description\"]'],\n /** Service page elements */\n service: ['h1', '.service-overview', '.key-benefits', 'meta[name=\"description\"]'],\n /** FAQ page elements */\n faq: ['h1', '.faq-intro', '.faq-item'],\n /** Contact page elements */\n contact: ['h1', '.contact-intro', '.business-hours', '.contact-info'],\n}\n\n/**\n * Get recommended speakable selectors for a page type\n */\nexport function getSpeakableSelectorsForPage(\n pageType: 'page' | 'article' | 'service' | 'faq' | 'contact'\n): string[] {\n return DEFAULT_SPEAKABLE_SELECTORS[pageType] || DEFAULT_SPEAKABLE_SELECTORS.page\n}\n\nexport default SpeakableSchema\n","/**\n * @sonordev/site-kit/llms - AEO Components\n * \n * Answer Engine Optimization (AEO) components for structuring content\n * in a way that AI systems can easily extract and cite.\n * \n * These components create semantic HTML with proper structure for:\n * - Featured snippets\n * - AI-generated answers\n * - Voice assistant responses\n * - AI retrieval and citation (Sonor AI Visibility)\n */\n\nimport * as React from 'react'\nimport type { AEOBlockProps, AEOSummaryProps, AEODefinitionProps, AEOClaimProps } from './types'\n\n/**\n * AEOBlock - Generic content block optimized for AI extraction\n * \n * Wraps content with semantic HTML and Sonor data attributes.\n * Use for any content you want AI systems to prioritize.\n * \n * @example\n * ```tsx\n * <AEOBlock type=\"answer\" question=\"What is family law?\" speakable>\n * Family law is the area of legal practice that deals with family-related \n * matters such as divorce, child custody, adoption, and domestic relations.\n * </AEOBlock>\n * ```\n */\nexport function AEOBlock({\n id,\n type,\n question,\n speakable = true,\n entityId,\n children,\n className = '',\n}: AEOBlockProps): React.ReactElement {\n const blockId = id || `aeo-${type}-${Math.random().toString(36).slice(2, 8)}`\n \n const baseClasses = `aeo-block aeo-${type}`\n const combinedClasses = className ? `${baseClasses} ${className}` : baseClasses\n\n // Common data attributes for Sonor AI\n const sonorAttrs = {\n 'data-sonor-ai': type,\n 'data-sonor-block': 'true',\n ...(entityId && { 'data-sonor-entity': entityId }),\n }\n\n // Q&A format for answer type\n if (type === 'answer' && question) {\n return (\n <section \n id={blockId}\n className={combinedClasses}\n data-speakable={speakable ? 'true' : undefined}\n data-aeo-type={type}\n {...sonorAttrs}\n itemScope\n itemType=\"https://schema.org/Question\"\n >\n <h3 itemProp=\"name\" className=\"aeo-question\">\n {question}\n </h3>\n <div \n itemScope \n itemType=\"https://schema.org/Answer\" \n itemProp=\"acceptedAnswer\"\n className=\"aeo-answer\"\n >\n <div itemProp=\"text\">\n {children}\n </div>\n </div>\n </section>\n )\n }\n\n // Definition format\n if (type === 'definition') {\n return (\n <section \n id={blockId}\n className={combinedClasses}\n data-speakable={speakable ? 'true' : undefined}\n data-aeo-type={type}\n {...sonorAttrs}\n >\n {children}\n </section>\n )\n }\n\n // Steps format (numbered list)\n if (type === 'steps') {\n return (\n <section \n id={blockId}\n className={combinedClasses}\n data-speakable={speakable ? 'true' : undefined}\n data-aeo-type={type}\n {...sonorAttrs}\n itemScope\n itemType=\"https://schema.org/HowTo\"\n >\n {children}\n </section>\n )\n }\n\n // Default wrapper\n return (\n <section \n id={blockId}\n className={combinedClasses}\n data-speakable={speakable ? 'true' : undefined}\n data-aeo-type={type}\n {...sonorAttrs}\n >\n {children}\n </section>\n )\n}\n\n/**\n * AEOSummary - Key points summary for AI extraction\n * \n * Creates a scannable list of key points that AI can easily cite.\n * Perfect for \"at a glance\" or \"key takeaways\" sections.\n * \n * @example\n * ```tsx\n * <AEOSummary \n * title=\"Key Points\" \n * points={[\n * \"Family law covers divorce, custody, and adoption\",\n * \"Ohio is an equitable distribution state\",\n * \"Child custody decisions prioritize the child's best interests\"\n * ]} \n * />\n * ```\n */\nexport function AEOSummary({\n title = 'Key Points',\n points,\n speakable = true,\n entityId,\n className = '',\n}: AEOSummaryProps): React.ReactElement {\n const baseClasses = 'aeo-summary'\n const combinedClasses = className ? `${baseClasses} ${className}` : baseClasses\n\n return (\n <div \n className={combinedClasses}\n data-speakable={speakable ? 'true' : undefined}\n data-aeo-type=\"summary\"\n data-sonor-ai=\"summary\"\n data-sonor-block=\"true\"\n {...(entityId && { 'data-sonor-entity': entityId })}\n >\n {title && <h3 className=\"aeo-summary-title\">{title}</h3>}\n <ul className=\"aeo-summary-points\">\n {points.map((point, index) => (\n <li key={index} className=\"aeo-summary-point\">\n {point}\n </li>\n ))}\n </ul>\n </div>\n )\n}\n\n/**\n * AEODefinition - Term definition optimized for featured snippets\n * \n * Creates a clear definition format that works well for\n * \"What is X?\" queries in AI search results.\n * \n * @example\n * ```tsx\n * <AEODefinition \n * term=\"Equitable Distribution\" \n * definition=\"A legal principle used in Ohio divorce cases where marital \n * property is divided fairly, though not necessarily equally, between spouses.\"\n * />\n * ```\n */\nexport function AEODefinition({\n term,\n definition,\n speakable = true,\n entityId,\n source,\n className = '',\n}: AEODefinitionProps): React.ReactElement {\n const baseClasses = 'aeo-definition'\n const combinedClasses = className ? `${baseClasses} ${className}` : baseClasses\n\n return (\n <dl \n className={combinedClasses}\n data-speakable={speakable ? 'true' : undefined}\n data-aeo-type=\"definition\"\n data-sonor-ai=\"definition\"\n data-sonor-block=\"true\"\n {...(entityId && { 'data-sonor-entity': entityId })}\n {...(source && { 'data-sonor-source': source })}\n itemScope\n itemType=\"https://schema.org/DefinedTerm\"\n >\n <dt className=\"aeo-term\" itemProp=\"name\">\n <strong>{term}</strong>\n </dt>\n <dd className=\"aeo-definition-text\" itemProp=\"description\">\n {definition}\n </dd>\n </dl>\n )\n}\n\n/**\n * AEOSteps - How-to steps for featured snippets\n * \n * Creates numbered steps with HowTo schema markup.\n * \n * @example\n * ```tsx\n * <AEOSteps title=\"How to File for Divorce in Ohio\">\n * <AEOStep number={1} name=\"Gather Documents\">\n * Collect financial records, property deeds, and marriage certificate.\n * </AEOStep>\n * <AEOStep number={2} name=\"File Petition\">\n * Submit divorce petition to the county court.\n * </AEOStep>\n * </AEOSteps>\n * ```\n */\nexport function AEOSteps({\n title,\n children,\n speakable = true,\n entityId,\n className = '',\n}: {\n title: string\n children: React.ReactNode\n speakable?: boolean\n entityId?: string\n className?: string\n}): React.ReactElement {\n const baseClasses = 'aeo-steps'\n const combinedClasses = className ? `${baseClasses} ${className}` : baseClasses\n\n return (\n <section \n className={combinedClasses}\n data-speakable={speakable ? 'true' : undefined}\n data-aeo-type=\"steps\"\n data-sonor-ai=\"steps\"\n data-sonor-block=\"true\"\n {...(entityId && { 'data-sonor-entity': entityId })}\n itemScope\n itemType=\"https://schema.org/HowTo\"\n >\n <h3 className=\"aeo-steps-title\" itemProp=\"name\">{title}</h3>\n <ol className=\"aeo-steps-list\">\n {children}\n </ol>\n </section>\n )\n}\n\n/**\n * AEOStep - Individual step within AEOSteps\n */\nexport function AEOStep({\n number,\n name,\n children,\n}: {\n number: number\n name: string\n children: React.ReactNode\n}): React.ReactElement {\n return (\n <li \n className=\"aeo-step\"\n itemScope\n itemType=\"https://schema.org/HowToStep\"\n itemProp=\"step\"\n >\n <span className=\"aeo-step-number\" itemProp=\"position\">{number}</span>\n <strong className=\"aeo-step-name\" itemProp=\"name\">{name}</strong>\n <div className=\"aeo-step-content\" itemProp=\"text\">\n {children}\n </div>\n </li>\n )\n}\n\n/**\n * AEOComparison - Comparison table for AI extraction\n * \n * Creates a structured comparison that AI can understand and cite.\n * \n * @example\n * ```tsx\n * <AEOComparison \n * title=\"Divorce vs. Dissolution in Ohio\"\n * items={[\n * { aspect: 'Agreement', optionA: 'May be contested', optionB: 'Must be agreed upon' },\n * { aspect: 'Timeline', optionA: '6-12 months', optionB: '30-90 days' },\n * ]}\n * labelA=\"Divorce\"\n * labelB=\"Dissolution\"\n * />\n * ```\n */\nexport function AEOComparison({\n title,\n items,\n labelA,\n labelB,\n speakable = true,\n entityId,\n className = '',\n}: {\n title: string\n items: Array<{ aspect: string; optionA: string; optionB: string }>\n labelA: string\n labelB: string\n speakable?: boolean\n entityId?: string\n className?: string\n}): React.ReactElement {\n const baseClasses = 'aeo-comparison'\n const combinedClasses = className ? `${baseClasses} ${className}` : baseClasses\n\n return (\n <section \n className={combinedClasses}\n data-speakable={speakable ? 'true' : undefined}\n data-aeo-type=\"comparison\"\n data-sonor-ai=\"comparison\"\n data-sonor-block=\"true\"\n {...(entityId && { 'data-sonor-entity': entityId })}\n >\n <h3 className=\"aeo-comparison-title\">{title}</h3>\n <table className=\"aeo-comparison-table\">\n <thead>\n <tr>\n <th>Aspect</th>\n <th>{labelA}</th>\n <th>{labelB}</th>\n </tr>\n </thead>\n <tbody>\n {items.map((item, index) => (\n <tr key={index}>\n <td className=\"aeo-comparison-aspect\">{item.aspect}</td>\n <td className=\"aeo-comparison-a\">{item.optionA}</td>\n <td className=\"aeo-comparison-b\">{item.optionB}</td>\n </tr>\n ))}\n </tbody>\n </table>\n </section>\n )\n}\n\n/**\n * AEOClaim - AI-Verifiable Claim with Provenance\n * \n * Wraps factual claims with machine-readable source and confidence data.\n * LLMs prioritize verifiable facts with clear provenance.\n * \n * @example\n * ```tsx\n * <AEOClaim \n * source=\"KRS 281A.170\" \n * sourceUrl=\"https://apps.legislature.ky.gov/law/statutes/statute.aspx?id=6398\"\n * confidence={0.95}\n * claimType=\"statute\"\n * >\n * A CDL suspension is triggered at 26 MPH over the limit.\n * </AEOClaim>\n * ```\n */\nexport function AEOClaim({\n source,\n sourceUrl,\n confidence = 1.0,\n claimType = 'fact',\n retrievedAt,\n children,\n className = '',\n}: AEOClaimProps): React.ReactElement {\n const baseClasses = 'aeo-claim'\n const combinedClasses = className ? `${baseClasses} ${className}` : baseClasses\n\n return (\n <span \n className={combinedClasses}\n data-sonor-claim=\"true\"\n data-sonor-source={source}\n {...(sourceUrl && { 'data-sonor-source-url': sourceUrl })}\n data-sonor-confidence={confidence.toString()}\n data-sonor-claim-type={claimType}\n {...(retrievedAt && { 'data-sonor-retrieved': retrievedAt })}\n itemScope\n itemType=\"https://schema.org/Claim\"\n >\n <span itemProp=\"text\">{children}</span>\n {sourceUrl ? (\n <meta itemProp=\"citation\" content={sourceUrl} />\n ) : (\n <meta itemProp=\"citation\" content={source} />\n )}\n </span>\n )\n}\n\n/**\n * AEOEntity - Inline entity annotation\n * \n * Wraps entity mentions with machine-readable entity IDs for knowledge graph linking.\n * \n * @example\n * ```tsx\n * <AEOEntity entityId=\"person-123\" entityType=\"person\" name=\"Shannon Sexton\">\n * Attorney Shannon Sexton\n * </AEOEntity> handles CDL defense cases.\n * ```\n */\nexport function AEOEntity({\n entityId,\n entityType,\n name,\n url,\n children,\n className = '',\n}: {\n entityId: string\n entityType: 'organization' | 'person' | 'service' | 'product' | 'location' | 'concept' | 'credential'\n name: string\n url?: string\n children: React.ReactNode\n className?: string\n}): React.ReactElement {\n const baseClasses = 'aeo-entity'\n const combinedClasses = className ? `${baseClasses} aeo-entity-${entityType} ${className}` : `${baseClasses} aeo-entity-${entityType}`\n\n return (\n <span \n className={combinedClasses}\n data-sonor-entity={entityId}\n data-sonor-entity-type={entityType}\n data-sonor-entity-name={name}\n {...(url && { 'data-sonor-entity-url': url })}\n itemScope\n itemType={`https://schema.org/${entityType === 'organization' ? 'Organization' : entityType === 'person' ? 'Person' : entityType === 'location' ? 'Place' : 'Thing'}`}\n >\n <span itemProp=\"name\">{children}</span>\n {url && <link itemProp=\"url\" href={url} />}\n </span>\n )\n}\n\n// ============================================\n// Content Provenance Components\n// ============================================\n\n/**\n * AEOProvenanceList - Display sources/citations for content\n * \n * Shows a list of provenance sources with machine-readable attributes.\n * LLMs use this to verify claims and assess source quality.\n * \n * @example\n * ```tsx\n * <AEOProvenanceList \n * title=\"Sources\"\n * sources={[\n * { id: '1', source_type: 'legal_statute', title: 'KRS 281A.170', url: '...' },\n * { id: '2', source_type: 'news_article', title: 'CDL News', publisher: 'Transport Weekly' }\n * ]}\n * />\n * ```\n */\nexport function AEOProvenanceList({\n sources,\n title = 'Sources & References',\n className = '',\n}: {\n sources: Array<{\n id: string\n source_type: 'press_release' | 'news_article' | 'legal_statute' | 'research_paper' | 'official_document' | 'internal' | 'citation'\n title: string\n url?: string\n publisher?: string\n published_at?: string\n accessed_at?: string\n excerpt?: string\n confidence?: number\n identifier?: string\n }>\n title?: string\n className?: string\n}): React.ReactElement {\n const baseClasses = 'aeo-provenance-list'\n const combinedClasses = className ? `${baseClasses} ${className}` : baseClasses\n\n const getSchemaType = (sourceType: string): string => {\n switch (sourceType) {\n case 'legal_statute':\n return 'https://schema.org/Legislation'\n case 'research_paper':\n return 'https://schema.org/ScholarlyArticle'\n case 'news_article':\n return 'https://schema.org/NewsArticle'\n case 'press_release':\n return 'https://schema.org/NewsArticle'\n default:\n return 'https://schema.org/CreativeWork'\n }\n }\n\n return (\n <aside \n className={combinedClasses}\n data-sonor-provenance=\"list\"\n data-sonor-source-count={sources.length.toString()}\n itemScope\n itemType=\"https://schema.org/ItemList\"\n >\n <h4 className=\"aeo-provenance-title\" itemProp=\"name\">{title}</h4>\n <ol className=\"aeo-provenance-sources\">\n {sources.map((source, index) => (\n <li \n key={source.id}\n className=\"aeo-provenance-item\"\n data-sonor-source-id={source.id}\n data-sonor-source-type={source.source_type}\n {...(source.confidence && { 'data-sonor-confidence': source.confidence.toString() })}\n itemScope\n itemType={getSchemaType(source.source_type)}\n itemProp=\"itemListElement\"\n >\n <span className=\"aeo-provenance-number\">[{index + 1}]</span>\n {source.url ? (\n <a \n href={source.url} \n className=\"aeo-provenance-link\"\n itemProp=\"url\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n <span itemProp=\"name\">{source.title}</span>\n </a>\n ) : (\n <span itemProp=\"name\">{source.title}</span>\n )}\n {source.publisher && (\n <span className=\"aeo-provenance-publisher\" itemProp=\"publisher\">\n — {source.publisher}\n </span>\n )}\n {source.published_at && (\n <time \n className=\"aeo-provenance-date\" \n itemProp=\"datePublished\"\n dateTime={source.published_at}\n >\n ({new Date(source.published_at).toLocaleDateString()})\n </time>\n )}\n {source.identifier && (\n <span className=\"aeo-provenance-identifier\" data-sonor-identifier={source.identifier}>\n {source.identifier}\n </span>\n )}\n {source.excerpt && (\n <blockquote className=\"aeo-provenance-excerpt\" itemProp=\"description\">\n {source.excerpt}\n </blockquote>\n )}\n </li>\n ))}\n </ol>\n </aside>\n )\n}\n\n/**\n * AEOCitedContent - Content with inline citations linked to sources\n * \n * Wraps content that contains numbered citations [1], [2] etc., and links them\n * to a list of provenance sources for AI verification.\n * \n * @example\n * ```tsx\n * <AEOCitedContent \n * sources={[\n * { id: '1', source_type: 'legal_statute', title: 'KRS 281A.170' },\n * { id: '2', source_type: 'news_article', title: 'FMCSA Guidelines 2024' }\n * ]}\n * showSourcesList={true}\n * >\n * <p>Kentucky law requires CDL holders to report violations within 30 days [1]. \n * Federal guidelines add additional requirements [2].</p>\n * </AEOCitedContent>\n * ```\n */\nexport function AEOCitedContent({\n children,\n sources,\n showSourcesList = true,\n className = '',\n}: {\n children: React.ReactNode\n sources: Array<{\n id: string\n source_type: 'press_release' | 'news_article' | 'legal_statute' | 'research_paper' | 'official_document' | 'internal' | 'citation'\n title: string\n url?: string\n publisher?: string\n published_at?: string\n accessed_at?: string\n excerpt?: string\n confidence?: number\n identifier?: string\n }>\n showSourcesList?: boolean\n className?: string\n}): React.ReactElement {\n const baseClasses = 'aeo-cited-content'\n const combinedClasses = className ? `${baseClasses} ${className}` : baseClasses\n\n return (\n <section \n className={combinedClasses}\n data-sonor-ai=\"cited-content\"\n data-sonor-provenance=\"inline\"\n data-sonor-source-count={sources.length.toString()}\n >\n <div className=\"aeo-cited-body\">\n {children}\n </div>\n {showSourcesList && sources.length > 0 && (\n <AEOProvenanceList sources={sources} title=\"References\" />\n )}\n </section>\n )\n}\n\nexport default AEOBlock\n"]}
@@ -1,4 +1,4 @@
1
- import { getApiConfig } from './chunk-25F2EXOC.mjs';
1
+ import { getApiConfig } from './chunk-ZR4TYCQW.mjs';
2
2
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
3
3
 
4
4
  function HoneypotField({ name, value, onChange }) {
@@ -56,5 +56,5 @@ function NativeFallbackFields({ config, returnTo }) {
56
56
  }
57
57
 
58
58
  export { HoneypotField, NativeFallbackFields, nativeFormProps };
59
- //# sourceMappingURL=chunk-QXMWNIKL.mjs.map
60
- //# sourceMappingURL=chunk-QXMWNIKL.mjs.map
59
+ //# sourceMappingURL=chunk-TCCGP3FT.mjs.map
60
+ //# sourceMappingURL=chunk-TCCGP3FT.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/forms/HoneypotField.tsx","../src/forms/native-fallback.tsx"],"names":["jsx"],"mappings":";;;AAqCO,SAAS,aAAA,CAAc,EAAE,IAAA,EAAM,KAAA,EAAO,UAAS,EAAuB;AAC3E,EAAA,MAAM,WAAA,GAAc,OAAO,QAAA,KAAa,UAAA;AACxC,EAAA,uBACE,GAAA;AAAA,IAAC,OAAA;AAAA,IAAA;AAAA,MACC,IAAA,EAAK,MAAA;AAAA,MACL,IAAA;AAAA,MACA,QAAA,EAAU,EAAA;AAAA,MACV,YAAA,EAAa,cAAA;AAAA,MACb,aAAA,EAAY,MAAA;AAAA,MACZ,KAAA,EAAK,IAAA;AAAA,MACL,kBAAA,EAAiB,EAAA;AAAA,MAGjB,gBAAA,EAAe,EAAA;AAAA,MACf,eAAA,EAAc,MAAA;AAAA,MACd,gBAAA,EAAe,OAAA;AAAA,MACf,eAAA,EAAc,EAAA;AAAA,MACd,KAAA,EAAO;AAAA,QACL,QAAA,EAAU,UAAA;AAAA,QACV,IAAA,EAAM,KAAA;AAAA,QACN,KAAA,EAAO,CAAA;AAAA,QACP,MAAA,EAAQ,CAAA;AAAA,QACR,QAAA,EAAU,QAAA;AAAA,QACV,OAAA,EAAS,CAAA;AAAA,QACT,UAAA,EAAY,QAAA;AAAA,QACZ,aAAA,EAAe;AAAA,OACjB;AAAA,MACC,GAAI,WAAA,GACD;AAAA,QACE,OAAO,KAAA,IAAS,EAAA;AAAA,QAChB,QAAA,EAAU,CAAC,CAAA,KAA2C;AACpD,UAAA,QAAA,CAAU,CAAA,CAAE,OAAO,KAAK,CAAA;AACxB,UAAA,IAAI,CAAA,CAAE,OAAO,KAAA,EAAO;AAElB,YAAA,OAAA,CAAQ,KAAK,4BAA4B,CAAA;AAAA,UAC3C;AAAA,QACF;AAAA,OACF,GACA,EAAE,YAAA,EAAc,EAAA;AAAG;AAAA,GACzB;AAEJ;ACjDA,SAAS,eAAe,MAAA,EAAuD;AAC7E,EAAA,OAAO,CAAC,CAAC,MAAA,EAAQ,YAAA,IAAgB,CAAC,MAAA,CAAO,aAAA;AAC3C;AAGO,SAAS,gBACd,MAAA,EACsC;AACtC,EAAA,IAAI,CAAC,cAAA,CAAe,MAAM,CAAA,SAAU,EAAC;AACrC,EAAA,MAAM,EAAE,MAAA,EAAO,GAAI,YAAA,EAAa;AAChC,EAAA,OAAO,EAAE,MAAA,EAAQ,CAAA,EAAG,MAAM,CAAA,+BAAA,CAAA,EAAmC,QAAQ,MAAA,EAAO;AAC9E;AAaO,SAAS,oBAAA,CAAqB,EAAE,MAAA,EAAQ,QAAA,EAAS,EAA8B;AACpF,EAAA,IAAI,CAAC,cAAA,CAAe,MAAM,CAAA,EAAG,OAAO,IAAA;AACpC,EAAA,uBACE,IAAA,CAAA,QAAA,EAAA,EACE,QAAA,EAAA;AAAA,oBAAAA,GAAAA,CAAC,OAAA,EAAA,EAAM,IAAA,EAAK,QAAA,EAAS,IAAA,EAAK,aAAY,KAAA,EAAO,MAAA,CAAQ,YAAA,EAAc,QAAA,EAAQ,IAAA,EAAC,CAAA;AAAA,IAC3E,QAAA,mBAAWA,GAAAA,CAAC,OAAA,EAAA,EAAM,IAAA,EAAK,QAAA,EAAS,IAAA,EAAK,YAAA,EAAa,KAAA,EAAO,QAAA,EAAU,QAAA,EAAQ,IAAA,EAAC,CAAA,GAAK;AAAA,GAAA,EACpF,CAAA;AAEJ","file":"chunk-QXMWNIKL.mjs","sourcesContent":["/**\n * Single source of truth for the honeypot input — rendered by BOTH form\n * experiences (classic and stage) inside their <form>. The customRender path\n * deliberately gets none (documented limitation: custom renders lose the\n * honeypot, which is why alternate experiences must be render branches).\n *\n * Invariants (do not weaken any of these):\n * - `inert` blocks focus/interaction at the browser level, surviving hostile\n * site CSS that could defeat the inline styles.\n * - data-sk-honeypot gives site CSS a stable opt-OUT hook.\n * - Controlled input: bots filling via JS still fire React onChange, so the\n * value reaches submitForm's data payload.\n * - Name comes from config (`honeypot_field || DEFAULT_HONEYPOT_FIELD` from\n * the shared contract) — resolved by the caller, never forked here.\n * - The trap must be invisible to AUTOFILL as well as to people. A browser or\n * password manager filling a hidden input flags a real visitor as a bot, and\n * because the value is stripped server-side the mistake is undiagnosable\n * after the fact. `autocomplete=\"off\"` does not achieve this — it is the one\n * value Chrome deliberately ignores for contact/address autofill — so the\n * trap declares `new-password` (never offered saved contact data) plus the\n * documented per-manager opt-outs.\n */\n\nimport React from 'react'\n\nexport interface HoneypotFieldProps {\n name: string\n value?: string\n /**\n * Omit for STATIC mode — an uncontrolled trap a Server Component can render.\n * The trap's whole job is server-side (the value is read off the submission\n * and stripped), so it needs no client state to work; the controlled form is\n * only so the hydrated JSON path can read it back out of React state.\n */\n onChange?: (value: string) => void\n}\n\nexport function HoneypotField({ name, value, onChange }: HoneypotFieldProps) {\n const interactive = typeof onChange === 'function'\n return (\n <input\n type=\"text\"\n name={name}\n tabIndex={-1}\n autoComplete=\"new-password\"\n aria-hidden=\"true\"\n inert\n data-sk-honeypot=\"\"\n // Password-manager opt-outs: 1Password, LastPass, Dashlane, Bitwarden.\n // Each ignores its own attribute; none respects autocomplete alone.\n data-1p-ignore=\"\"\n data-lpignore=\"true\"\n data-form-type=\"other\"\n data-bwignore=\"\"\n style={{\n position: 'absolute',\n left: -9999,\n width: 1,\n height: 1,\n overflow: 'hidden',\n opacity: 0,\n visibility: 'hidden',\n pointerEvents: 'none',\n }}\n {...(interactive\n ? {\n value: value ?? '',\n onChange: (e: React.ChangeEvent<HTMLInputElement>) => {\n onChange!(e.target.value)\n if (e.target.value) {\n // Bot detected\n console.warn('[Forms] Honeypot triggered')\n }\n },\n }\n : { defaultValue: '' })}\n />\n )\n}\n","'use client'\n\n/**\n * No-JS native submission fallback — the floor under every managed form.\n *\n * The classic form is the SSR/no-JS surface (experiences are post-hydration\n * chunks), so it alone carries a real `action`/`method` pointing at\n * sonor-api's POST /api/public/forms/submit-native. With JS running, the\n * form's onSubmit preventDefault()s and the JSON path wins; without JS the\n * browser performs an ordinary form-encoded POST and the lead still lands.\n *\n * Auth rides in the hidden `_sk_token` field: a signed, single-purpose\n * credential minted by the api-key-authenticated forms/config endpoint\n * (`native_token` in the response). No token in the config (older API, or no\n * signing secret) means no fallback — the form keeps its historical behavior\n * rather than pointing at an endpoint that will reject it.\n *\n * Multi-step forms are excluded: step navigation is JS, and a native POST of\n * step-1 fields alone fails whole-form validation server-side. Single-step\n * forms are the overwhelming lead-capture case.\n *\n * Single source of truth for the gating — the form attrs and the hidden\n * fields must always agree, so both read the same predicate.\n */\n\nimport React from 'react'\nimport type { ManagedFormConfig } from './types'\nimport { getApiConfig } from './submitForm'\n\nfunction nativeEligible(config: ManagedFormConfig | null | undefined): boolean {\n return !!config?.native_token && !config.is_multi_step\n}\n\n/** `action`/`method` for the classic <form> — empty when ineligible. */\nexport function nativeFormProps(\n config: ManagedFormConfig | null | undefined,\n): { action?: string; method?: 'post' } {\n if (!nativeEligible(config)) return {}\n const { apiUrl } = getApiConfig()\n return { action: `${apiUrl}/api/public/forms/submit-native`, method: 'post' }\n}\n\nexport interface NativeFallbackFieldsProps {\n config: ManagedFormConfig | null | undefined\n /**\n * Absolute URL the native 303 should land on (usually the page hosting the\n * form). Optional — without it the server falls back to the Referer origin,\n * which loses the path but still returns the visitor to the right site.\n */\n returnTo?: string\n}\n\n/** Hidden control fields the native endpoint reads (`_sk_*` namespace). */\nexport function NativeFallbackFields({ config, returnTo }: NativeFallbackFieldsProps) {\n if (!nativeEligible(config)) return null\n return (\n <>\n <input type=\"hidden\" name=\"_sk_token\" value={config!.native_token} readOnly />\n {returnTo ? <input type=\"hidden\" name=\"_sk_return\" value={returnTo} readOnly /> : null}\n </>\n )\n}\n"]}
1
+ {"version":3,"sources":["../src/forms/HoneypotField.tsx","../src/forms/native-fallback.tsx"],"names":["jsx"],"mappings":";;;AAqCO,SAAS,aAAA,CAAc,EAAE,IAAA,EAAM,KAAA,EAAO,UAAS,EAAuB;AAC3E,EAAA,MAAM,WAAA,GAAc,OAAO,QAAA,KAAa,UAAA;AACxC,EAAA,uBACE,GAAA;AAAA,IAAC,OAAA;AAAA,IAAA;AAAA,MACC,IAAA,EAAK,MAAA;AAAA,MACL,IAAA;AAAA,MACA,QAAA,EAAU,EAAA;AAAA,MACV,YAAA,EAAa,cAAA;AAAA,MACb,aAAA,EAAY,MAAA;AAAA,MACZ,KAAA,EAAK,IAAA;AAAA,MACL,kBAAA,EAAiB,EAAA;AAAA,MAGjB,gBAAA,EAAe,EAAA;AAAA,MACf,eAAA,EAAc,MAAA;AAAA,MACd,gBAAA,EAAe,OAAA;AAAA,MACf,eAAA,EAAc,EAAA;AAAA,MACd,KAAA,EAAO;AAAA,QACL,QAAA,EAAU,UAAA;AAAA,QACV,IAAA,EAAM,KAAA;AAAA,QACN,KAAA,EAAO,CAAA;AAAA,QACP,MAAA,EAAQ,CAAA;AAAA,QACR,QAAA,EAAU,QAAA;AAAA,QACV,OAAA,EAAS,CAAA;AAAA,QACT,UAAA,EAAY,QAAA;AAAA,QACZ,aAAA,EAAe;AAAA,OACjB;AAAA,MACC,GAAI,WAAA,GACD;AAAA,QACE,OAAO,KAAA,IAAS,EAAA;AAAA,QAChB,QAAA,EAAU,CAAC,CAAA,KAA2C;AACpD,UAAA,QAAA,CAAU,CAAA,CAAE,OAAO,KAAK,CAAA;AACxB,UAAA,IAAI,CAAA,CAAE,OAAO,KAAA,EAAO;AAElB,YAAA,OAAA,CAAQ,KAAK,4BAA4B,CAAA;AAAA,UAC3C;AAAA,QACF;AAAA,OACF,GACA,EAAE,YAAA,EAAc,EAAA;AAAG;AAAA,GACzB;AAEJ;ACjDA,SAAS,eAAe,MAAA,EAAuD;AAC7E,EAAA,OAAO,CAAC,CAAC,MAAA,EAAQ,YAAA,IAAgB,CAAC,MAAA,CAAO,aAAA;AAC3C;AAGO,SAAS,gBACd,MAAA,EACsC;AACtC,EAAA,IAAI,CAAC,cAAA,CAAe,MAAM,CAAA,SAAU,EAAC;AACrC,EAAA,MAAM,EAAE,MAAA,EAAO,GAAI,YAAA,EAAa;AAChC,EAAA,OAAO,EAAE,MAAA,EAAQ,CAAA,EAAG,MAAM,CAAA,+BAAA,CAAA,EAAmC,QAAQ,MAAA,EAAO;AAC9E;AAaO,SAAS,oBAAA,CAAqB,EAAE,MAAA,EAAQ,QAAA,EAAS,EAA8B;AACpF,EAAA,IAAI,CAAC,cAAA,CAAe,MAAM,CAAA,EAAG,OAAO,IAAA;AACpC,EAAA,uBACE,IAAA,CAAA,QAAA,EAAA,EACE,QAAA,EAAA;AAAA,oBAAAA,GAAAA,CAAC,OAAA,EAAA,EAAM,IAAA,EAAK,QAAA,EAAS,IAAA,EAAK,aAAY,KAAA,EAAO,MAAA,CAAQ,YAAA,EAAc,QAAA,EAAQ,IAAA,EAAC,CAAA;AAAA,IAC3E,QAAA,mBAAWA,GAAAA,CAAC,OAAA,EAAA,EAAM,IAAA,EAAK,QAAA,EAAS,IAAA,EAAK,YAAA,EAAa,KAAA,EAAO,QAAA,EAAU,QAAA,EAAQ,IAAA,EAAC,CAAA,GAAK;AAAA,GAAA,EACpF,CAAA;AAEJ","file":"chunk-TCCGP3FT.mjs","sourcesContent":["/**\n * Single source of truth for the honeypot input — rendered by BOTH form\n * experiences (classic and stage) inside their <form>. The customRender path\n * deliberately gets none (documented limitation: custom renders lose the\n * honeypot, which is why alternate experiences must be render branches).\n *\n * Invariants (do not weaken any of these):\n * - `inert` blocks focus/interaction at the browser level, surviving hostile\n * site CSS that could defeat the inline styles.\n * - data-sk-honeypot gives site CSS a stable opt-OUT hook.\n * - Controlled input: bots filling via JS still fire React onChange, so the\n * value reaches submitForm's data payload.\n * - Name comes from config (`honeypot_field || DEFAULT_HONEYPOT_FIELD` from\n * the shared contract) — resolved by the caller, never forked here.\n * - The trap must be invisible to AUTOFILL as well as to people. A browser or\n * password manager filling a hidden input flags a real visitor as a bot, and\n * because the value is stripped server-side the mistake is undiagnosable\n * after the fact. `autocomplete=\"off\"` does not achieve this — it is the one\n * value Chrome deliberately ignores for contact/address autofill — so the\n * trap declares `new-password` (never offered saved contact data) plus the\n * documented per-manager opt-outs.\n */\n\nimport React from 'react'\n\nexport interface HoneypotFieldProps {\n name: string\n value?: string\n /**\n * Omit for STATIC mode — an uncontrolled trap a Server Component can render.\n * The trap's whole job is server-side (the value is read off the submission\n * and stripped), so it needs no client state to work; the controlled form is\n * only so the hydrated JSON path can read it back out of React state.\n */\n onChange?: (value: string) => void\n}\n\nexport function HoneypotField({ name, value, onChange }: HoneypotFieldProps) {\n const interactive = typeof onChange === 'function'\n return (\n <input\n type=\"text\"\n name={name}\n tabIndex={-1}\n autoComplete=\"new-password\"\n aria-hidden=\"true\"\n inert\n data-sk-honeypot=\"\"\n // Password-manager opt-outs: 1Password, LastPass, Dashlane, Bitwarden.\n // Each ignores its own attribute; none respects autocomplete alone.\n data-1p-ignore=\"\"\n data-lpignore=\"true\"\n data-form-type=\"other\"\n data-bwignore=\"\"\n style={{\n position: 'absolute',\n left: -9999,\n width: 1,\n height: 1,\n overflow: 'hidden',\n opacity: 0,\n visibility: 'hidden',\n pointerEvents: 'none',\n }}\n {...(interactive\n ? {\n value: value ?? '',\n onChange: (e: React.ChangeEvent<HTMLInputElement>) => {\n onChange!(e.target.value)\n if (e.target.value) {\n // Bot detected\n console.warn('[Forms] Honeypot triggered')\n }\n },\n }\n : { defaultValue: '' })}\n />\n )\n}\n","'use client'\n\n/**\n * No-JS native submission fallback — the floor under every managed form.\n *\n * The classic form is the SSR/no-JS surface (experiences are post-hydration\n * chunks), so it alone carries a real `action`/`method` pointing at\n * sonor-api's POST /api/public/forms/submit-native. With JS running, the\n * form's onSubmit preventDefault()s and the JSON path wins; without JS the\n * browser performs an ordinary form-encoded POST and the lead still lands.\n *\n * Auth rides in the hidden `_sk_token` field: a signed, single-purpose\n * credential minted by the api-key-authenticated forms/config endpoint\n * (`native_token` in the response). No token in the config (older API, or no\n * signing secret) means no fallback — the form keeps its historical behavior\n * rather than pointing at an endpoint that will reject it.\n *\n * Multi-step forms are excluded: step navigation is JS, and a native POST of\n * step-1 fields alone fails whole-form validation server-side. Single-step\n * forms are the overwhelming lead-capture case.\n *\n * Single source of truth for the gating — the form attrs and the hidden\n * fields must always agree, so both read the same predicate.\n */\n\nimport React from 'react'\nimport type { ManagedFormConfig } from './types'\nimport { getApiConfig } from './submitForm'\n\nfunction nativeEligible(config: ManagedFormConfig | null | undefined): boolean {\n return !!config?.native_token && !config.is_multi_step\n}\n\n/** `action`/`method` for the classic <form> — empty when ineligible. */\nexport function nativeFormProps(\n config: ManagedFormConfig | null | undefined,\n): { action?: string; method?: 'post' } {\n if (!nativeEligible(config)) return {}\n const { apiUrl } = getApiConfig()\n return { action: `${apiUrl}/api/public/forms/submit-native`, method: 'post' }\n}\n\nexport interface NativeFallbackFieldsProps {\n config: ManagedFormConfig | null | undefined\n /**\n * Absolute URL the native 303 should land on (usually the page hosting the\n * form). Optional — without it the server falls back to the Referer origin,\n * which loses the path but still returns the visitor to the right site.\n */\n returnTo?: string\n}\n\n/** Hidden control fields the native endpoint reads (`_sk_*` namespace). */\nexport function NativeFallbackFields({ config, returnTo }: NativeFallbackFieldsProps) {\n if (!nativeEligible(config)) return null\n return (\n <>\n <input type=\"hidden\" name=\"_sk_token\" value={config!.native_token} readOnly />\n {returnTo ? <input type=\"hidden\" name=\"_sk_return\" value={returnTo} readOnly /> : null}\n </>\n )\n}\n"]}
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var chunk7R6H3GQ4_js = require('./chunk-7R6H3GQ4.js');
3
+ var chunkEL74YDNX_js = require('./chunk-EL74YDNX.js');
4
4
 
5
5
  // src/shared/siteToken.ts
6
6
  var SITE_TOKEN_PREFIX = "st1.";
@@ -99,7 +99,7 @@ async function doRefresh() {
99
99
  method: "POST",
100
100
  headers: {
101
101
  "content-type": "application/json",
102
- "x-sitekit-version": chunk7R6H3GQ4_js.SITE_KIT_VERSION,
102
+ "x-sitekit-version": chunkEL74YDNX_js.SITE_KIT_VERSION,
103
103
  // Send the current token as x-api-key too, so the server's key-scoped
104
104
  // throttler buckets refreshes by token rather than by shared CDN IP.
105
105
  "x-api-key": current
@@ -154,5 +154,5 @@ exports.getFreshCredential = getFreshCredential;
154
154
  exports.isSiteToken = isSiteToken;
155
155
  exports.isTokenMode = isTokenMode;
156
156
  exports.refreshSiteToken = refreshSiteToken;
157
- //# sourceMappingURL=chunk-CZEIHFLW.js.map
158
- //# sourceMappingURL=chunk-CZEIHFLW.js.map
157
+ //# sourceMappingURL=chunk-TCZHRSWY.js.map
158
+ //# sourceMappingURL=chunk-TCZHRSWY.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/shared/siteToken.ts"],"names":["SITE_KIT_VERSION"],"mappings":"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","file":"chunk-CZEIHFLW.js","sourcesContent":["/**\n * @sonordev/site-kit shared — Client token manager\n *\n * SiteKitLayout (a server component) no longer ships the raw `sonor_` API key to\n * the browser. Instead it mints a short-lived, project-scoped token server-side\n * and injects THAT. This module is the browser-side lifecycle for that token:\n *\n * - holds the current token (seeded from the injected value)\n * - a static page's seed can be days old and already expired on first view, so\n * it transparently REFRESHES via the public endpoint before first use\n * - dedupes concurrent refreshes (one in-flight request, awaited by all)\n * - persists the freshest token in sessionStorage so navigations within a\n * session don't each re-refresh\n *\n * Everything here is a no-op passthrough when the injected credential is a raw\n * key (a 2.x kit, or the mint-failed fallback) — legacy behavior is unchanged.\n * Fully SSR-safe: on the server there is no refresh, just the seed.\n *\n * The token payload is NOT secret (only its HMAC is unforgeable), so decoding it\n * client-side to read `exp`/`pid` is fine and needs no crypto.\n */\nimport { SITE_KIT_VERSION } from './version'\n\nexport const SITE_TOKEN_PREFIX = 'st1.'\n\n/** Refresh this many ms before expiry, so a request never races the deadline. */\nconst REFRESH_SKEW_MS = 5 * 60_000\nconst REFRESH_TIMEOUT_MS = 6_000\nconst STORAGE_KEY = '__sonor_site_token__'\n\nexport function isSiteToken(credential?: string | null): boolean {\n return typeof credential === 'string' && credential.startsWith(SITE_TOKEN_PREFIX)\n}\n\ninterface DecodedClaims {\n pid?: string\n iat?: number\n exp?: number\n}\n\n/** Decode the (non-secret) token payload. Returns null if not a token / malformed. */\nexport function decodeSiteTokenClaims(token?: string | null): DecodedClaims | null {\n if (!isSiteToken(token)) return null\n const seg = (token as string).split('.')[1]\n if (!seg) return null\n try {\n // base64url → JSON. atob handles standard base64; restore url-safe chars.\n const b64 = seg.replace(/-/g, '+').replace(/_/g, '/')\n const json =\n typeof atob === 'function'\n ? atob(b64)\n : Buffer.from(seg, 'base64url').toString('utf8')\n const claims = JSON.parse(json)\n return typeof claims === 'object' && claims ? claims : null\n } catch {\n return null\n }\n}\n\n/**\n * Stable id for the auth circuit breaker. Tokens rotate, so keying the breaker\n * by the raw value would reset it every refresh — key by the project id encoded\n * in the token instead. Raw keys use a safe prefix.\n */\nexport function credentialBreakerId(credential?: string | null): string {\n if (!credential) return '(anonymous)'\n const claims = decodeSiteTokenClaims(credential)\n if (claims?.pid) return `pid:${claims.pid}`\n return credential.slice(0, 16)\n}\n\ninterface TokenState {\n /** The credential injected by the layout (token or raw key). */\n seed: string | undefined\n /** Whether we're in token mode (seed is a token). */\n isToken: boolean\n /** Base API URL for the refresh endpoint. */\n apiUrl: string\n /** The freshest known token (>= seed). Null in raw-key mode. */\n token: string | null\n /** In-flight refresh, deduped. */\n refreshing: Promise<string | null> | null\n}\n\nfunction initialTokenState(): TokenState {\n return {\n seed: undefined,\n isToken: false,\n apiUrl: 'https://api.sonor.io',\n token: null,\n refreshing: null,\n }\n}\n\n/**\n * Page-wide singleton, keyed on window. Bundlers can (and in the field, do)\n * inline more than one copy of this module into a page — e.g. an app importing\n * site-kit directly while a transpiled component library bundles its own copy.\n * Module-scoped state then splits into per-copy brains: one copy gets\n * configured and refreshes fine while the other keeps sending the stale\n * prerendered seed, 401s, and trips its breaker (\"sonor-auth-paused\" with a\n * working network). Sharing the state object on window gives every copy the\n * same token, the same deduped refresh, and the same breaker. On the server\n * (no window) each module instance keeps private state — there's no refresh\n * lifecycle there anyway.\n */\nconst TOKEN_STATE_KEY = '__SONOR_SITE_TOKEN_STATE__'\n\nconst state: TokenState = (() => {\n if (typeof window === 'undefined') return initialTokenState()\n const w = window as unknown as Record<string, TokenState | undefined>\n return (w[TOKEN_STATE_KEY] ??= initialTokenState())\n})()\n\nfunction readStoredToken(): string | null {\n if (typeof window === 'undefined') return null\n try {\n const raw = window.sessionStorage.getItem(STORAGE_KEY)\n if (!raw) return null\n const parsed = JSON.parse(raw)\n return typeof parsed?.token === 'string' ? parsed.token : null\n } catch {\n return null\n }\n}\n\nfunction storeToken(token: string): void {\n if (typeof window === 'undefined') return\n try {\n window.sessionStorage.setItem(STORAGE_KEY, JSON.stringify({ token }))\n } catch {\n /* private mode / disabled storage — memory-only is fine */\n }\n try {\n ;(window as any).__SITE_KIT_API_KEY__ = token\n } catch {\n /* ignore */\n }\n}\n\nfunction tokenExp(token: string | null): number {\n const claims = decodeSiteTokenClaims(token)\n return typeof claims?.exp === 'number' ? claims.exp * 1000 : 0\n}\n\n/**\n * Configure the manager from the layout-injected values. Adopts a fresher token\n * from sessionStorage if a prior page in this session already refreshed.\n */\nexport function configureSiteCredential(opts: {\n credential?: string\n apiUrl?: string\n}): void {\n state.seed = opts.credential\n state.isToken = isSiteToken(opts.credential)\n if (opts.apiUrl) state.apiUrl = opts.apiUrl.replace(/\\/+$/, '')\n\n if (!state.isToken) {\n state.token = null\n return\n }\n\n // configure runs on every render — never downgrade. Keep the freshest of the\n // injected seed, a token stored by an earlier page this session, and whatever\n // an in-flight/prior refresh already put in memory.\n const prior = state.token\n let best = opts.credential ?? null\n const stored = readStoredToken()\n if (stored && tokenExp(stored) > tokenExp(best)) best = stored\n if (prior && tokenExp(prior) > tokenExp(best)) best = prior\n state.token = best\n}\n\nfunction needsRefresh(): boolean {\n if (!state.isToken) return false\n if (!state.token) return true\n return Date.now() >= tokenExp(state.token) - REFRESH_SKEW_MS\n}\n\nasync function doRefresh(): Promise<string | null> {\n const current = state.token\n if (!current) return null\n try {\n const res = await fetch(`${state.apiUrl}/api/public/site-token/refresh`, {\n method: 'POST',\n headers: {\n 'content-type': 'application/json',\n 'x-sitekit-version': SITE_KIT_VERSION,\n // Send the current token as x-api-key too, so the server's key-scoped\n // throttler buckets refreshes by token rather than by shared CDN IP.\n 'x-api-key': current,\n },\n body: JSON.stringify({ token: current }),\n signal:\n typeof AbortSignal !== 'undefined' && AbortSignal.timeout\n ? AbortSignal.timeout(REFRESH_TIMEOUT_MS)\n : undefined,\n })\n if (!res.ok) return null\n const data = await res.json().catch(() => null)\n const next = data?.token\n if (typeof next === 'string' && isSiteToken(next)) {\n state.token = next\n storeToken(next)\n return next\n }\n return null\n } catch {\n return null\n }\n}\n\n/** Refresh now (deduped). Returns the new token, or null on failure. */\nexport function refreshSiteToken(): Promise<string | null> {\n if (!state.isToken) return Promise.resolve(null)\n if (state.refreshing) return state.refreshing\n state.refreshing = doRefresh().finally(() => {\n state.refreshing = null\n })\n return state.refreshing\n}\n\n/**\n * The credential to put on the next request. In token mode, refreshes a stale\n * seed first. In raw-key mode, returns the seed unchanged (legacy passthrough).\n */\nexport async function getFreshCredential(\n seed?: string,\n): Promise<string | undefined> {\n // Unconfigured but handed a token (a component received the prerendered seed\n // as a prop before any provider configured the manager): adopt it so the\n // refresh machinery works instead of replaying a possibly-expired seed.\n if (!state.isToken && isSiteToken(seed)) {\n configureSiteCredential({ credential: seed })\n }\n // A raw key (or nothing configured) — no token machinery.\n if (!state.isToken) return seed ?? state.seed\n if (needsRefresh()) {\n const refreshed = await refreshSiteToken()\n if (refreshed) return refreshed\n // Refresh failed — fall through to whatever we have; the request may 401 and\n // trip the breaker with friendly copy.\n }\n return state.token ?? seed ?? state.seed\n}\n\n/** Whether the given credential is being managed as a token. */\nexport function isTokenMode(): boolean {\n return state.isToken\n}\n\n/**\n * Best-known credential WITHOUT refreshing — for synchronous unload paths\n * (sonorBeacon) that can't await. In token mode returns the freshest token held;\n * in raw-key mode returns the seed.\n */\nexport function currentCredential(seed?: string): string | undefined {\n if (!state.isToken) return seed ?? state.seed\n return state.token ?? seed ?? state.seed\n}\n"]}
1
+ {"version":3,"sources":["../src/shared/siteToken.ts"],"names":["SITE_KIT_VERSION"],"mappings":"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","file":"chunk-TCZHRSWY.js","sourcesContent":["/**\n * @sonordev/site-kit shared — Client token manager\n *\n * SiteKitLayout (a server component) no longer ships the raw `sonor_` API key to\n * the browser. Instead it mints a short-lived, project-scoped token server-side\n * and injects THAT. This module is the browser-side lifecycle for that token:\n *\n * - holds the current token (seeded from the injected value)\n * - a static page's seed can be days old and already expired on first view, so\n * it transparently REFRESHES via the public endpoint before first use\n * - dedupes concurrent refreshes (one in-flight request, awaited by all)\n * - persists the freshest token in sessionStorage so navigations within a\n * session don't each re-refresh\n *\n * Everything here is a no-op passthrough when the injected credential is a raw\n * key (a 2.x kit, or the mint-failed fallback) — legacy behavior is unchanged.\n * Fully SSR-safe: on the server there is no refresh, just the seed.\n *\n * The token payload is NOT secret (only its HMAC is unforgeable), so decoding it\n * client-side to read `exp`/`pid` is fine and needs no crypto.\n */\nimport { SITE_KIT_VERSION } from './version'\n\nexport const SITE_TOKEN_PREFIX = 'st1.'\n\n/** Refresh this many ms before expiry, so a request never races the deadline. */\nconst REFRESH_SKEW_MS = 5 * 60_000\nconst REFRESH_TIMEOUT_MS = 6_000\nconst STORAGE_KEY = '__sonor_site_token__'\n\nexport function isSiteToken(credential?: string | null): boolean {\n return typeof credential === 'string' && credential.startsWith(SITE_TOKEN_PREFIX)\n}\n\ninterface DecodedClaims {\n pid?: string\n iat?: number\n exp?: number\n}\n\n/** Decode the (non-secret) token payload. Returns null if not a token / malformed. */\nexport function decodeSiteTokenClaims(token?: string | null): DecodedClaims | null {\n if (!isSiteToken(token)) return null\n const seg = (token as string).split('.')[1]\n if (!seg) return null\n try {\n // base64url → JSON. atob handles standard base64; restore url-safe chars.\n const b64 = seg.replace(/-/g, '+').replace(/_/g, '/')\n const json =\n typeof atob === 'function'\n ? atob(b64)\n : Buffer.from(seg, 'base64url').toString('utf8')\n const claims = JSON.parse(json)\n return typeof claims === 'object' && claims ? claims : null\n } catch {\n return null\n }\n}\n\n/**\n * Stable id for the auth circuit breaker. Tokens rotate, so keying the breaker\n * by the raw value would reset it every refresh — key by the project id encoded\n * in the token instead. Raw keys use a safe prefix.\n */\nexport function credentialBreakerId(credential?: string | null): string {\n if (!credential) return '(anonymous)'\n const claims = decodeSiteTokenClaims(credential)\n if (claims?.pid) return `pid:${claims.pid}`\n return credential.slice(0, 16)\n}\n\ninterface TokenState {\n /** The credential injected by the layout (token or raw key). */\n seed: string | undefined\n /** Whether we're in token mode (seed is a token). */\n isToken: boolean\n /** Base API URL for the refresh endpoint. */\n apiUrl: string\n /** The freshest known token (>= seed). Null in raw-key mode. */\n token: string | null\n /** In-flight refresh, deduped. */\n refreshing: Promise<string | null> | null\n}\n\nfunction initialTokenState(): TokenState {\n return {\n seed: undefined,\n isToken: false,\n apiUrl: 'https://api.sonor.io',\n token: null,\n refreshing: null,\n }\n}\n\n/**\n * Page-wide singleton, keyed on window. Bundlers can (and in the field, do)\n * inline more than one copy of this module into a page — e.g. an app importing\n * site-kit directly while a transpiled component library bundles its own copy.\n * Module-scoped state then splits into per-copy brains: one copy gets\n * configured and refreshes fine while the other keeps sending the stale\n * prerendered seed, 401s, and trips its breaker (\"sonor-auth-paused\" with a\n * working network). Sharing the state object on window gives every copy the\n * same token, the same deduped refresh, and the same breaker. On the server\n * (no window) each module instance keeps private state — there's no refresh\n * lifecycle there anyway.\n */\nconst TOKEN_STATE_KEY = '__SONOR_SITE_TOKEN_STATE__'\n\nconst state: TokenState = (() => {\n if (typeof window === 'undefined') return initialTokenState()\n const w = window as unknown as Record<string, TokenState | undefined>\n return (w[TOKEN_STATE_KEY] ??= initialTokenState())\n})()\n\nfunction readStoredToken(): string | null {\n if (typeof window === 'undefined') return null\n try {\n const raw = window.sessionStorage.getItem(STORAGE_KEY)\n if (!raw) return null\n const parsed = JSON.parse(raw)\n return typeof parsed?.token === 'string' ? parsed.token : null\n } catch {\n return null\n }\n}\n\nfunction storeToken(token: string): void {\n if (typeof window === 'undefined') return\n try {\n window.sessionStorage.setItem(STORAGE_KEY, JSON.stringify({ token }))\n } catch {\n /* private mode / disabled storage — memory-only is fine */\n }\n try {\n ;(window as any).__SITE_KIT_API_KEY__ = token\n } catch {\n /* ignore */\n }\n}\n\nfunction tokenExp(token: string | null): number {\n const claims = decodeSiteTokenClaims(token)\n return typeof claims?.exp === 'number' ? claims.exp * 1000 : 0\n}\n\n/**\n * Configure the manager from the layout-injected values. Adopts a fresher token\n * from sessionStorage if a prior page in this session already refreshed.\n */\nexport function configureSiteCredential(opts: {\n credential?: string\n apiUrl?: string\n}): void {\n state.seed = opts.credential\n state.isToken = isSiteToken(opts.credential)\n if (opts.apiUrl) state.apiUrl = opts.apiUrl.replace(/\\/+$/, '')\n\n if (!state.isToken) {\n state.token = null\n return\n }\n\n // configure runs on every render — never downgrade. Keep the freshest of the\n // injected seed, a token stored by an earlier page this session, and whatever\n // an in-flight/prior refresh already put in memory.\n const prior = state.token\n let best = opts.credential ?? null\n const stored = readStoredToken()\n if (stored && tokenExp(stored) > tokenExp(best)) best = stored\n if (prior && tokenExp(prior) > tokenExp(best)) best = prior\n state.token = best\n}\n\nfunction needsRefresh(): boolean {\n if (!state.isToken) return false\n if (!state.token) return true\n return Date.now() >= tokenExp(state.token) - REFRESH_SKEW_MS\n}\n\nasync function doRefresh(): Promise<string | null> {\n const current = state.token\n if (!current) return null\n try {\n const res = await fetch(`${state.apiUrl}/api/public/site-token/refresh`, {\n method: 'POST',\n headers: {\n 'content-type': 'application/json',\n 'x-sitekit-version': SITE_KIT_VERSION,\n // Send the current token as x-api-key too, so the server's key-scoped\n // throttler buckets refreshes by token rather than by shared CDN IP.\n 'x-api-key': current,\n },\n body: JSON.stringify({ token: current }),\n signal:\n typeof AbortSignal !== 'undefined' && AbortSignal.timeout\n ? AbortSignal.timeout(REFRESH_TIMEOUT_MS)\n : undefined,\n })\n if (!res.ok) return null\n const data = await res.json().catch(() => null)\n const next = data?.token\n if (typeof next === 'string' && isSiteToken(next)) {\n state.token = next\n storeToken(next)\n return next\n }\n return null\n } catch {\n return null\n }\n}\n\n/** Refresh now (deduped). Returns the new token, or null on failure. */\nexport function refreshSiteToken(): Promise<string | null> {\n if (!state.isToken) return Promise.resolve(null)\n if (state.refreshing) return state.refreshing\n state.refreshing = doRefresh().finally(() => {\n state.refreshing = null\n })\n return state.refreshing\n}\n\n/**\n * The credential to put on the next request. In token mode, refreshes a stale\n * seed first. In raw-key mode, returns the seed unchanged (legacy passthrough).\n */\nexport async function getFreshCredential(\n seed?: string,\n): Promise<string | undefined> {\n // Unconfigured but handed a token (a component received the prerendered seed\n // as a prop before any provider configured the manager): adopt it so the\n // refresh machinery works instead of replaying a possibly-expired seed.\n if (!state.isToken && isSiteToken(seed)) {\n configureSiteCredential({ credential: seed })\n }\n // A raw key (or nothing configured) — no token machinery.\n if (!state.isToken) return seed ?? state.seed\n if (needsRefresh()) {\n const refreshed = await refreshSiteToken()\n if (refreshed) return refreshed\n // Refresh failed — fall through to whatever we have; the request may 401 and\n // trip the breaker with friendly copy.\n }\n return state.token ?? seed ?? state.seed\n}\n\n/** Whether the given credential is being managed as a token. */\nexport function isTokenMode(): boolean {\n return state.isToken\n}\n\n/**\n * Best-known credential WITHOUT refreshing — for synchronous unload paths\n * (sonorBeacon) that can't await. In token mode returns the freshest token held;\n * in raw-key mode returns the seed.\n */\nexport function currentCredential(seed?: string): string | undefined {\n if (!state.isToken) return seed ?? state.seed\n return state.token ?? seed ?? state.seed\n}\n"]}
@@ -1,14 +1,14 @@
1
1
  'use strict';
2
2
 
3
- var chunkFVW6FT6L_js = require('./chunk-FVW6FT6L.js');
3
+ var chunkOSU4QA5M_js = require('./chunk-OSU4QA5M.js');
4
4
  var chunkCXAXZFFW_js = require('./chunk-CXAXZFFW.js');
5
- var chunkH5NBFNND_js = require('./chunk-H5NBFNND.js');
5
+ var chunkUZKXOZHR_js = require('./chunk-UZKXOZHR.js');
6
6
 
7
7
  // src/seo/getManagedMetadata.ts
8
8
  async function getManagedMetadata(options) {
9
9
  const { path, fallback = {}, overrides = {}, favicon: faviconMode = "metadata" } = options;
10
10
  const omitIcons = faviconMode === "component";
11
- const result = await chunkFVW6FT6L_js.getSEOPageData(path);
11
+ const result = await chunkOSU4QA5M_js.getSEOPageData(path);
12
12
  const pageData = result?.page;
13
13
  const projectData = result?.project;
14
14
  if (!pageData) {
@@ -37,12 +37,12 @@ async function getManagedMetadata(options) {
37
37
  };
38
38
  }
39
39
  if (!pageData.managed_title && !pageData.managed_meta_description && !pageData.managed_description) {
40
- chunkFVW6FT6L_js.ensureMetadata(path).catch(() => {
40
+ chunkOSU4QA5M_js.ensureMetadata(path).catch(() => {
41
41
  });
42
42
  }
43
43
  const identity = {
44
44
  brand: projectData?.brand ?? projectData?.title ?? null,
45
- hosts: [chunkH5NBFNND_js.resolveSiteHost(), pageData.site, projectData?.domain, projectData?.site_url]
45
+ hosts: [chunkUZKXOZHR_js.resolveSiteHost(), pageData.site, projectData?.domain, projectData?.site_url]
46
46
  };
47
47
  const rejected = {};
48
48
  const rawTitle = pageData.managed_title;
@@ -114,7 +114,7 @@ async function getManagedMetadata(options) {
114
114
  }
115
115
  async function getABVariant(options) {
116
116
  const { path, field, sessionId } = options;
117
- const test = await chunkFVW6FT6L_js.getABTest(path, field);
117
+ const test = await chunkOSU4QA5M_js.getABTest(path, field);
118
118
  if (!test) {
119
119
  return null;
120
120
  }
@@ -127,7 +127,7 @@ async function getABVariant(options) {
127
127
  } else {
128
128
  variant = Math.random() < test.traffic_split ? "a" : "b";
129
129
  }
130
- chunkFVW6FT6L_js.recordABImpression(test.id, variant, sessionId).catch(() => {
130
+ chunkOSU4QA5M_js.recordABImpression(test.id, variant, sessionId).catch(() => {
131
131
  });
132
132
  return {
133
133
  testId: test.id,
@@ -160,7 +160,7 @@ async function getManagedMetadataWithAB(options) {
160
160
  // src/seo/routing.ts
161
161
  async function getRedirect(options) {
162
162
  const { path } = options;
163
- const redirect = await chunkFVW6FT6L_js.getRedirectData(path);
163
+ const redirect = await chunkOSU4QA5M_js.getRedirectData(path);
164
164
  if (!redirect) {
165
165
  return null;
166
166
  }
@@ -202,7 +202,7 @@ function parseRobotsString(robots) {
202
202
  }
203
203
  async function getRobotsDirective(options) {
204
204
  const { path } = options;
205
- const robotsString = await chunkFVW6FT6L_js.getRobotsData(path);
205
+ const robotsString = await chunkOSU4QA5M_js.getRobotsData(path);
206
206
  if (!robotsString) {
207
207
  return { index: true, follow: true };
208
208
  }
@@ -210,7 +210,7 @@ async function getRobotsDirective(options) {
210
210
  }
211
211
  async function generateSitemap(options) {
212
212
  const { baseUrl, publishedOnly = true } = options;
213
- const pages = await chunkFVW6FT6L_js.getSitemapEntries({ publishedOnly });
213
+ const pages = await chunkOSU4QA5M_js.getSitemapEntries({ publishedOnly });
214
214
  const normalizedBase = baseUrl.endsWith("/") ? baseUrl.slice(0, -1) : baseUrl;
215
215
  return pages.map((page) => ({
216
216
  path: page.path,
@@ -221,11 +221,11 @@ async function generateSitemap(options) {
221
221
  }));
222
222
  }
223
223
  async function registerLocalSitemap(options) {
224
- const { registerSitemap } = await import('./server-api-IWTZ7C3O.js');
224
+ const { registerSitemap } = await import('./server-api-OC5JNK6R.js');
225
225
  let entries = options.entries || [];
226
226
  if (options.autoDiscover && entries.length === 0) {
227
227
  try {
228
- const { discoverNextJsRoutes, findAppDirForDiscovery } = await import('./discover-NGEPXZOD.js');
228
+ const { discoverNextJsRoutes, findAppDirForDiscovery } = await import('./discover-LPN55L5B.js');
229
229
  const appDir = findAppDirForDiscovery();
230
230
  if (appDir) {
231
231
  entries = discoverNextJsRoutes(appDir);
@@ -260,5 +260,5 @@ exports.getRedirect = getRedirect;
260
260
  exports.getRobotsDirective = getRobotsDirective;
261
261
  exports.isIndexable = isIndexable;
262
262
  exports.registerLocalSitemap = registerLocalSitemap;
263
- //# sourceMappingURL=chunk-LB44BNJ2.js.map
264
- //# sourceMappingURL=chunk-LB44BNJ2.js.map
263
+ //# sourceMappingURL=chunk-TST2IKYO.js.map
264
+ //# sourceMappingURL=chunk-TST2IKYO.js.map