@sonordev/site-kit 5.7.0 → 5.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (752) hide show
  1. package/README.md +3 -3
  2. package/agent-manifest.json +14 -2
  3. package/dist/AnalyticsProvider-ERNSZ4DH.mjs +12 -0
  4. package/dist/{AnalyticsProvider-EWF7JN2X.mjs.map → AnalyticsProvider-ERNSZ4DH.mjs.map} +1 -1
  5. package/dist/AnalyticsProvider-HE6V5UJD.js +33 -0
  6. package/dist/{AnalyticsProvider-GJFG7YXA.js.map → AnalyticsProvider-HE6V5UJD.js.map} +1 -1
  7. package/dist/{BlogViewTracker-CKYG6MYU.mjs → BlogViewTracker-2NQ5LBVR.mjs} +13 -10
  8. package/dist/BlogViewTracker-2NQ5LBVR.mjs.map +1 -0
  9. package/dist/{BlogViewTracker-2D3IJPJK.js → BlogViewTracker-4OGWSC2Q.js} +14 -11
  10. package/dist/BlogViewTracker-4OGWSC2Q.js.map +1 -0
  11. package/dist/ChatWidget-67CHHONZ.js +24 -0
  12. package/dist/{ChatWidget-AWP6GBVW.js.map → ChatWidget-67CHHONZ.js.map} +1 -1
  13. package/dist/ChatWidget-T4RICLLT.mjs +15 -0
  14. package/dist/{ChatWidget-Z5QXDZP3.mjs.map → ChatWidget-T4RICLLT.mjs.map} +1 -1
  15. package/dist/EngageWidget-TDW2ZI3Q.js +21 -0
  16. package/dist/{EngageWidget-VT4DYXVO.js.map → EngageWidget-TDW2ZI3Q.js.map} +1 -1
  17. package/dist/EngageWidget-WXEQTV4X.mjs +12 -0
  18. package/dist/{EngageWidget-BKEY5TPO.mjs.map → EngageWidget-WXEQTV4X.mjs.map} +1 -1
  19. package/dist/{FileField-62ZWZMQK.js → FileField-DEVOXJSO.js} +6 -6
  20. package/dist/{FileField-62ZWZMQK.js.map → FileField-DEVOXJSO.js.map} +1 -1
  21. package/dist/{FileField-JJN5QKDL.mjs → FileField-Y5YM365S.mjs} +5 -5
  22. package/dist/{FileField-JJN5QKDL.mjs.map → FileField-Y5YM365S.mjs.map} +1 -1
  23. package/dist/{FormSpotlight-URS4XRS7.js → FormSpotlight-4Q5FM3YS.js} +25 -21
  24. package/dist/FormSpotlight-4Q5FM3YS.js.map +1 -0
  25. package/dist/{FormSpotlight-OTFB6QM5.mjs → FormSpotlight-T3ASGUYB.mjs} +11 -7
  26. package/dist/FormSpotlight-T3ASGUYB.mjs.map +1 -0
  27. package/dist/{FormStage-FVKMIV73.js → FormStage-PSAIPZBS.js} +20 -15
  28. package/dist/FormStage-PSAIPZBS.js.map +1 -0
  29. package/dist/{FormStage-VPGOCMAV.mjs → FormStage-U5V4MI5Q.mjs} +9 -4
  30. package/dist/FormStage-U5V4MI5Q.mjs.map +1 -0
  31. package/dist/ManagedForm-EAZOMNSL.mjs +16 -0
  32. package/dist/{ManagedForm-CXVDJMHN.mjs.map → ManagedForm-EAZOMNSL.mjs.map} +1 -1
  33. package/dist/ManagedForm-R6DJXU34.js +25 -0
  34. package/dist/{ManagedForm-FGNTDGED.js.map → ManagedForm-R6DJXU34.js.map} +1 -1
  35. package/dist/{ManagedNewsletterForm-SQYB4BZU.mjs → ManagedNewsletterForm-5RY3TWPQ.mjs} +9 -7
  36. package/dist/ManagedNewsletterForm-5RY3TWPQ.mjs.map +1 -0
  37. package/dist/{ManagedNewsletterForm-3O5L44AZ.js → ManagedNewsletterForm-VX6GMZXJ.js} +10 -8
  38. package/dist/ManagedNewsletterForm-VX6GMZXJ.js.map +1 -0
  39. package/dist/{SignalCore-RFBOBNLQ.js → SignalCore-MWHF2WG4.js} +14 -20
  40. package/dist/SignalCore-MWHF2WG4.js.map +1 -0
  41. package/dist/{SignalCore-M2PKKIGH.mjs → SignalCore-ZT6EQGV3.mjs} +8 -14
  42. package/dist/SignalCore-ZT6EQGV3.mjs.map +1 -0
  43. package/dist/SitemapSync-OG4TQLDB.mjs +9 -0
  44. package/dist/{SitemapSync-4OVMIIGC.mjs.map → SitemapSync-OG4TQLDB.mjs.map} +1 -1
  45. package/dist/SitemapSync-Z62BGZMV.js +18 -0
  46. package/dist/{SitemapSync-RK3SQ4M2.js.map → SitemapSync-Z62BGZMV.js.map} +1 -1
  47. package/dist/analytics/AnalyticsProvider.d.ts.map +1 -1
  48. package/dist/analytics/index.js +10 -9
  49. package/dist/analytics/index.mjs +5 -4
  50. package/dist/api-D745LGGU.mjs +0 -1
  51. package/dist/api-XR5APCH3.js +0 -1
  52. package/dist/blog/BlogLayout.d.ts +3 -1
  53. package/dist/blog/BlogLayout.d.ts.map +1 -1
  54. package/dist/blog/BlogList.d.ts +7 -1
  55. package/dist/blog/BlogList.d.ts.map +1 -1
  56. package/dist/blog/BlogPost.d.ts +20 -1
  57. package/dist/blog/BlogPost.d.ts.map +1 -1
  58. package/dist/blog/BlogSidebar.d.ts +3 -1
  59. package/dist/blog/BlogSidebar.d.ts.map +1 -1
  60. package/dist/blog/BlogViewTracker.d.ts +8 -2
  61. package/dist/blog/BlogViewTracker.d.ts.map +1 -1
  62. package/dist/blog/ClusterLandingPage.d.ts +3 -1
  63. package/dist/blog/ClusterLandingPage.d.ts.map +1 -1
  64. package/dist/blog/ClusterNavigation.d.ts +5 -2
  65. package/dist/blog/ClusterNavigation.d.ts.map +1 -1
  66. package/dist/blog/RelatedPosts.d.ts +3 -1
  67. package/dist/blog/RelatedPosts.d.ts.map +1 -1
  68. package/dist/blog/index.d.ts +1 -1
  69. package/dist/blog/index.d.ts.map +1 -1
  70. package/dist/blog/index.js +40 -31
  71. package/dist/blog/index.js.map +1 -1
  72. package/dist/blog/index.mjs +11 -6
  73. package/dist/blog/index.mjs.map +1 -1
  74. package/dist/blog/processBlogHtml.d.ts +19 -2
  75. package/dist/blog/processBlogHtml.d.ts.map +1 -1
  76. package/dist/blog/public-reads.d.ts +27 -0
  77. package/dist/blog/public-reads.d.ts.map +1 -0
  78. package/dist/blog/server-core.d.ts +76 -10
  79. package/dist/blog/server-core.d.ts.map +1 -1
  80. package/dist/blog/server-ui.js +29 -23
  81. package/dist/blog/server-ui.js.map +1 -1
  82. package/dist/blog/server-ui.mjs +12 -6
  83. package/dist/blog/server-ui.mjs.map +1 -1
  84. package/dist/blog/server.d.ts +76 -10
  85. package/dist/blog/server.d.ts.map +1 -1
  86. package/dist/blog/server.js +54 -47
  87. package/dist/blog/server.mjs +5 -2
  88. package/dist/brand/extract-brand-profile.d.ts +36 -2
  89. package/dist/brand/extract-brand-profile.d.ts.map +1 -1
  90. package/dist/{chunk-MW2M6O7A.mjs → chunk-26EKSVXM.mjs} +4 -4
  91. package/dist/{chunk-MW2M6O7A.mjs.map → chunk-26EKSVXM.mjs.map} +1 -1
  92. package/dist/{chunk-D553G64G.js → chunk-2HPQTRUB.js} +13 -13
  93. package/dist/{chunk-D553G64G.js.map → chunk-2HPQTRUB.js.map} +1 -1
  94. package/dist/{chunk-BFJOZ3MU.mjs → chunk-3EY5E35M.mjs} +36 -71
  95. package/dist/chunk-3EY5E35M.mjs.map +1 -0
  96. package/dist/{chunk-BUJWXSYZ.mjs → chunk-3TQUARVN.mjs} +4 -4
  97. package/dist/{chunk-BUJWXSYZ.mjs.map → chunk-3TQUARVN.mjs.map} +1 -1
  98. package/dist/{chunk-OYOO2OO5.js → chunk-3VRWKKTD.js} +10 -10
  99. package/dist/{chunk-OYOO2OO5.js.map → chunk-3VRWKKTD.js.map} +1 -1
  100. package/dist/{chunk-BFM5PEFV.js → chunk-43I7U5AI.js} +56 -177
  101. package/dist/chunk-43I7U5AI.js.map +1 -0
  102. package/dist/{chunk-ILNCUSXW.mjs → chunk-4L7OHRWB.mjs} +12 -9
  103. package/dist/chunk-4L7OHRWB.mjs.map +1 -0
  104. package/dist/chunk-4LYW6PMU.mjs +72 -0
  105. package/dist/chunk-4LYW6PMU.mjs.map +1 -0
  106. package/dist/chunk-4TLFZ6NR.mjs +16 -0
  107. package/dist/chunk-4TLFZ6NR.mjs.map +1 -0
  108. package/dist/{chunk-JQ7M6CVL.mjs → chunk-4VSDMNQU.mjs} +3 -3
  109. package/dist/{chunk-JQ7M6CVL.mjs.map → chunk-4VSDMNQU.mjs.map} +1 -1
  110. package/dist/{chunk-4B4S56WJ.mjs → chunk-5B4J3IBX.mjs} +75 -21
  111. package/dist/chunk-5B4J3IBX.mjs.map +1 -0
  112. package/dist/{chunk-M5GY2AI3.mjs → chunk-5K6B4LWV.mjs} +4 -10
  113. package/dist/chunk-5K6B4LWV.mjs.map +1 -0
  114. package/dist/chunk-5SANRSX3.mjs +17 -0
  115. package/dist/chunk-5SANRSX3.mjs.map +1 -0
  116. package/dist/chunk-5XFFUP6D.js +100 -0
  117. package/dist/chunk-5XFFUP6D.js.map +1 -0
  118. package/dist/chunk-5YA6SI4Z.mjs +0 -1
  119. package/dist/{chunk-TDJKGN5Q.mjs → chunk-62Y4W4LR.mjs} +216 -103
  120. package/dist/chunk-62Y4W4LR.mjs.map +1 -0
  121. package/dist/{chunk-3CLP35TT.mjs → chunk-6S3JE66D.mjs} +62 -97
  122. package/dist/chunk-6S3JE66D.mjs.map +1 -0
  123. package/dist/{chunk-4A5V73SR.mjs → chunk-6WEZWYRU.mjs} +9 -9
  124. package/dist/{chunk-4A5V73SR.mjs.map → chunk-6WEZWYRU.mjs.map} +1 -1
  125. package/dist/{chunk-JTF4DFUF.mjs → chunk-7AEVA667.mjs} +4 -4
  126. package/dist/{chunk-JTF4DFUF.mjs.map → chunk-7AEVA667.mjs.map} +1 -1
  127. package/dist/{chunk-H65OX263.js → chunk-7DV7Y7BZ.js} +15 -15
  128. package/dist/{chunk-H65OX263.js.map → chunk-7DV7Y7BZ.js.map} +1 -1
  129. package/dist/{chunk-7ZX6TO6C.mjs → chunk-7H4HB4UZ.mjs} +50 -26
  130. package/dist/chunk-7H4HB4UZ.mjs.map +1 -0
  131. package/dist/{chunk-FO4KGPGF.js → chunk-7TC3GRXQ.js} +73 -38
  132. package/dist/chunk-7TC3GRXQ.js.map +1 -0
  133. package/dist/{chunk-UQ5YULFU.mjs → chunk-AUHUEIBB.mjs} +4 -4
  134. package/dist/{chunk-UQ5YULFU.mjs.map → chunk-AUHUEIBB.mjs.map} +1 -1
  135. package/dist/{chunk-BQGEVMIR.mjs → chunk-AWF73RU2.mjs} +5 -5
  136. package/dist/{chunk-BQGEVMIR.mjs.map → chunk-AWF73RU2.mjs.map} +1 -1
  137. package/dist/{chunk-ELQ4SRRR.js → chunk-BHBW2SZF.js} +15 -15
  138. package/dist/{chunk-ELQ4SRRR.js.map → chunk-BHBW2SZF.js.map} +1 -1
  139. package/dist/{chunk-RNAGCAIB.js → chunk-BIGXEYKT.js} +7 -7
  140. package/dist/{chunk-RNAGCAIB.js.map → chunk-BIGXEYKT.js.map} +1 -1
  141. package/dist/chunk-BQP6JIE2.mjs +28 -0
  142. package/dist/chunk-BQP6JIE2.mjs.map +1 -0
  143. package/dist/{chunk-VFGEY6FJ.js → chunk-BY35X57A.js} +223 -110
  144. package/dist/chunk-BY35X57A.js.map +1 -0
  145. package/dist/{chunk-3YQILJKJ.js → chunk-CGCUHIAR.js} +60 -35
  146. package/dist/chunk-CGCUHIAR.js.map +1 -0
  147. package/dist/chunk-CUNZAD46.js +53 -0
  148. package/dist/chunk-CUNZAD46.js.map +1 -0
  149. package/dist/{chunk-FEWWGEQF.js → chunk-CWUYI6LI.js} +4 -4
  150. package/dist/{chunk-FEWWGEQF.js.map → chunk-CWUYI6LI.js.map} +1 -1
  151. package/dist/chunk-CXAXZFFW.js +157 -0
  152. package/dist/chunk-CXAXZFFW.js.map +1 -0
  153. package/dist/{chunk-H4OBGC43.mjs → chunk-DA7IANFG.mjs} +14 -3
  154. package/dist/chunk-DA7IANFG.mjs.map +1 -0
  155. package/dist/{chunk-57AFHENV.mjs → chunk-EHAUNF4V.mjs} +3 -3
  156. package/dist/{chunk-57AFHENV.mjs.map → chunk-EHAUNF4V.mjs.map} +1 -1
  157. package/dist/{chunk-2N27LCZH.js → chunk-FEKPEI2G.js} +9 -9
  158. package/dist/{chunk-2N27LCZH.js.map → chunk-FEKPEI2G.js.map} +1 -1
  159. package/dist/{chunk-LC7AM4J5.js → chunk-FHPW7XVH.js} +77 -20
  160. package/dist/chunk-FHPW7XVH.js.map +1 -0
  161. package/dist/{chunk-JNRHTZL4.js → chunk-FVW6FT6L.js} +73 -29
  162. package/dist/chunk-FVW6FT6L.js.map +1 -0
  163. package/dist/{chunk-YKUEFRZI.js → chunk-FWW4K6QP.js} +14 -14
  164. package/dist/{chunk-YKUEFRZI.js.map → chunk-FWW4K6QP.js.map} +1 -1
  165. package/dist/{chunk-JNAXDFC4.mjs → chunk-GF4LV5LX.mjs} +38 -156
  166. package/dist/chunk-GF4LV5LX.mjs.map +1 -0
  167. package/dist/{chunk-C563AHZZ.mjs → chunk-GKFTJ5AF.mjs} +3 -3
  168. package/dist/{chunk-C563AHZZ.mjs.map → chunk-GKFTJ5AF.mjs.map} +1 -1
  169. package/dist/{chunk-OZ3FU4BT.js → chunk-H5NBFNND.js} +2 -2
  170. package/dist/chunk-H5NBFNND.js.map +1 -0
  171. package/dist/chunk-HCN3IKMW.mjs +106 -0
  172. package/dist/chunk-HCN3IKMW.mjs.map +1 -0
  173. package/dist/{chunk-6FC5Q4KU.mjs → chunk-HOJ4J4X2.mjs} +30 -12
  174. package/dist/chunk-HOJ4J4X2.mjs.map +1 -0
  175. package/dist/{chunk-H6YVT3BL.js → chunk-I3ND4XYW.js} +12 -9
  176. package/dist/chunk-I3ND4XYW.js.map +1 -0
  177. package/dist/chunk-I7AZC5ZQ.js +0 -1
  178. package/dist/{chunk-V5THCFPG.mjs → chunk-JFJ7NHS3.mjs} +4 -4
  179. package/dist/{chunk-V5THCFPG.mjs.map → chunk-JFJ7NHS3.mjs.map} +1 -1
  180. package/dist/{chunk-KXGD4E7G.js → chunk-JI4EUPHB.js} +7 -7
  181. package/dist/{chunk-KXGD4E7G.js.map → chunk-JI4EUPHB.js.map} +1 -1
  182. package/dist/{chunk-GZJE23Y5.mjs → chunk-JLVCWC6A.mjs} +2 -2
  183. package/dist/chunk-JLVCWC6A.mjs.map +1 -0
  184. package/dist/chunk-JOYMIGR2.mjs +0 -1
  185. package/dist/chunk-JS75ORH7.js +0 -1
  186. package/dist/{chunk-Q7347KP6.mjs → chunk-JX5SM2MX.mjs} +6 -12
  187. package/dist/chunk-JX5SM2MX.mjs.map +1 -0
  188. package/dist/chunk-K4TCEAUX.js +52 -0
  189. package/dist/chunk-K4TCEAUX.js.map +1 -0
  190. package/dist/chunk-KV7XXLJV.mjs +30 -0
  191. package/dist/chunk-KV7XXLJV.mjs.map +1 -0
  192. package/dist/{chunk-JTCQJKJE.js → chunk-LIAISQUE.js} +76 -111
  193. package/dist/chunk-LIAISQUE.js.map +1 -0
  194. package/dist/{chunk-CPY74A4F.js → chunk-LMEUYRRR.js} +72 -106
  195. package/dist/chunk-LMEUYRRR.js.map +1 -0
  196. package/dist/{chunk-4WBTM6YE.js → chunk-LOEP76MQ.js} +4 -4
  197. package/dist/{chunk-4WBTM6YE.js.map → chunk-LOEP76MQ.js.map} +1 -1
  198. package/dist/chunk-LVGSOW2F.js +32 -0
  199. package/dist/chunk-LVGSOW2F.js.map +1 -0
  200. package/dist/{chunk-DOB37PV4.js → chunk-M45AL7EA.js} +37 -19
  201. package/dist/chunk-M45AL7EA.js.map +1 -0
  202. package/dist/{chunk-RCSTDJUH.js → chunk-M4UVFUFR.js} +8 -13
  203. package/dist/chunk-M4UVFUFR.js.map +1 -0
  204. package/dist/{chunk-R2SXXFXZ.mjs → chunk-MI2SRBCR.mjs} +3 -3
  205. package/dist/{chunk-R2SXXFXZ.mjs.map → chunk-MI2SRBCR.mjs.map} +1 -1
  206. package/dist/chunk-MLVHVKFT.mjs +148 -0
  207. package/dist/chunk-MLVHVKFT.mjs.map +1 -0
  208. package/dist/{chunk-L7ACQ6PC.js → chunk-MOAYT3KN.js} +4 -4
  209. package/dist/{chunk-L7ACQ6PC.js.map → chunk-MOAYT3KN.js.map} +1 -1
  210. package/dist/chunk-NG2TTI7D.js +8 -0
  211. package/dist/{chunk-5TXXTYXL.js.map → chunk-NG2TTI7D.js.map} +1 -1
  212. package/dist/{chunk-C4PZ2R3B.js → chunk-NLDN6PYM.js} +10 -10
  213. package/dist/{chunk-C4PZ2R3B.js.map → chunk-NLDN6PYM.js.map} +1 -1
  214. package/dist/chunk-NN2YE5WT.js +0 -1
  215. package/dist/chunk-NNZDWY3L.mjs +0 -1
  216. package/dist/chunk-NRBITVDK.js +114 -0
  217. package/dist/chunk-NRBITVDK.js.map +1 -0
  218. package/dist/{chunk-TSZIACRC.js → chunk-OBKYF4TP.js} +6 -12
  219. package/dist/chunk-OBKYF4TP.js.map +1 -0
  220. package/dist/{chunk-TP7H6BSK.mjs → chunk-OE7CTIOU.mjs} +73 -30
  221. package/dist/chunk-OE7CTIOU.mjs.map +1 -0
  222. package/dist/chunk-OESGRWI4.mjs +6 -0
  223. package/dist/{chunk-QRBPT6Z6.mjs.map → chunk-OESGRWI4.mjs.map} +1 -1
  224. package/dist/{chunk-UJ6CHZAI.mjs → chunk-OEW2LFOV.js} +169 -25
  225. package/dist/chunk-OEW2LFOV.js.map +1 -0
  226. package/dist/chunk-P4Y75QSU.js +19 -0
  227. package/dist/chunk-P4Y75QSU.js.map +1 -0
  228. package/dist/{chunk-47XQWV4S.mjs → chunk-PQVQAX67.mjs} +3 -3
  229. package/dist/{chunk-47XQWV4S.mjs.map → chunk-PQVQAX67.mjs.map} +1 -1
  230. package/dist/chunk-QRHVMTHF.mjs +94 -0
  231. package/dist/chunk-QRHVMTHF.mjs.map +1 -0
  232. package/dist/{chunk-FBDHKYNF.mjs → chunk-R4B3DFF4.mjs} +3 -3
  233. package/dist/{chunk-FBDHKYNF.mjs.map → chunk-R4B3DFF4.mjs.map} +1 -1
  234. package/dist/chunk-R7GHP3FY.js +81 -0
  235. package/dist/chunk-R7GHP3FY.js.map +1 -0
  236. package/dist/{chunk-4UVM7E2W.js → chunk-S5VL7AWW.js} +3 -3
  237. package/dist/{chunk-4UVM7E2W.js.map → chunk-S5VL7AWW.js.map} +1 -1
  238. package/dist/{chunk-P4TB4ROG.js → chunk-SEP5D4MI.js} +8 -2
  239. package/dist/chunk-SEP5D4MI.js.map +1 -0
  240. package/dist/{chunk-L4V6TKMJ.mjs → chunk-U2V542EO.mjs} +7 -3
  241. package/dist/chunk-U2V542EO.mjs.map +1 -0
  242. package/dist/{chunk-HBN4A2N4.mjs → chunk-U6H5ZY3B.mjs} +3 -3
  243. package/dist/{chunk-HBN4A2N4.mjs.map → chunk-U6H5ZY3B.mjs.map} +1 -1
  244. package/dist/{chunk-H7274TKR.mjs → chunk-VJV7WUR2.mjs} +12 -4
  245. package/dist/chunk-VJV7WUR2.mjs.map +1 -0
  246. package/dist/{chunk-F3AKYZOH.js → chunk-WED6ZDVS.js} +6 -13
  247. package/dist/chunk-WED6ZDVS.js.map +1 -0
  248. package/dist/{chunk-5B4FABFK.js → chunk-WS7MH3GD.js} +14 -2
  249. package/dist/chunk-WS7MH3GD.js.map +1 -0
  250. package/dist/{chunk-XLPU3TEE.mjs → chunk-X22BGNVL.mjs} +4 -4
  251. package/dist/{chunk-XLPU3TEE.mjs.map → chunk-X22BGNVL.mjs.map} +1 -1
  252. package/dist/{chunk-IPV2TUAT.js → chunk-XA2GJFVM.js} +12 -4
  253. package/dist/chunk-XA2GJFVM.js.map +1 -0
  254. package/dist/chunk-XBX2K3GA.js +33 -0
  255. package/dist/chunk-XBX2K3GA.js.map +1 -0
  256. package/dist/{chunk-ABZGEHTC.mjs → chunk-XSAHJ2BB.mjs} +3 -3
  257. package/dist/{chunk-ABZGEHTC.mjs.map → chunk-XSAHJ2BB.mjs.map} +1 -1
  258. package/dist/{chunk-6CJP7BFM.js → chunk-XZO5I4RS.mjs} +147 -20
  259. package/dist/chunk-XZO5I4RS.mjs.map +1 -0
  260. package/dist/chunk-Y5QZPUL3.mjs +47 -0
  261. package/dist/chunk-Y5QZPUL3.mjs.map +1 -0
  262. package/dist/{chunk-NOU3JQJK.js → chunk-Y6Z2W45H.js} +8 -8
  263. package/dist/{chunk-NOU3JQJK.js.map → chunk-Y6Z2W45H.js.map} +1 -1
  264. package/dist/{chunk-YYDZ2TYR.js → chunk-YCFYQN2Q.js} +3 -3
  265. package/dist/{chunk-YYDZ2TYR.js.map → chunk-YCFYQN2Q.js.map} +1 -1
  266. package/dist/chunk-YN7QHLWF.js +19 -0
  267. package/dist/chunk-YN7QHLWF.js.map +1 -0
  268. package/dist/{chunk-O2VJZOR2.mjs → chunk-YRNDASQY.mjs} +6 -11
  269. package/dist/chunk-YRNDASQY.mjs.map +1 -0
  270. package/dist/chunk-YU7QZ3PP.mjs +45 -0
  271. package/dist/chunk-YU7QZ3PP.mjs.map +1 -0
  272. package/dist/{chunk-3S5JN6KL.js → chunk-ZV6HIQRQ.js} +6 -6
  273. package/dist/{chunk-3S5JN6KL.js.map → chunk-ZV6HIQRQ.js.map} +1 -1
  274. package/dist/{chunk-RVRN5U7W.mjs → chunk-ZVI7MBVF.mjs} +73 -38
  275. package/dist/chunk-ZVI7MBVF.mjs.map +1 -0
  276. package/dist/cli/agent/checks.d.ts +15 -1
  277. package/dist/cli/agent/checks.d.ts.map +1 -1
  278. package/dist/cli/commands/doctor.d.ts.map +1 -1
  279. package/dist/cli/commands/og.d.ts +26 -8
  280. package/dist/cli/commands/og.d.ts.map +1 -1
  281. package/dist/cli/index.js +683 -323
  282. package/dist/cli/index.mjs +604 -244
  283. package/dist/client/index.js +6 -6
  284. package/dist/client/index.mjs +5 -5
  285. package/dist/commerce/CheckoutForm.d.ts.map +1 -1
  286. package/dist/commerce/ProductDetail.d.ts.map +1 -1
  287. package/dist/commerce/api.d.ts +14 -0
  288. package/dist/commerce/api.d.ts.map +1 -1
  289. package/dist/commerce/index.d.ts +1 -1
  290. package/dist/commerce/index.d.ts.map +1 -1
  291. package/dist/commerce/index.js +61 -56
  292. package/dist/commerce/index.mjs +6 -5
  293. package/dist/config/index.js +3 -3
  294. package/dist/config/index.mjs +1 -1
  295. package/dist/discover-CYXYKHZ2.mjs +4 -0
  296. package/dist/{discover-FGTKWOL3.mjs.map → discover-CYXYKHZ2.mjs.map} +1 -1
  297. package/dist/discover-NGEPXZOD.js +21 -0
  298. package/dist/{discover-NJZPWTDL.js.map → discover-NGEPXZOD.js.map} +1 -1
  299. package/dist/engage/index.js +12 -10
  300. package/dist/engage/index.js.map +1 -1
  301. package/dist/engage/index.mjs +9 -7
  302. package/dist/engage/index.mjs.map +1 -1
  303. package/dist/fleet/index.js +8 -8
  304. package/dist/fleet/index.mjs +4 -4
  305. package/dist/forms/FormClient.d.ts.map +1 -1
  306. package/dist/forms/FormField.d.ts +7 -1
  307. package/dist/forms/FormField.d.ts.map +1 -1
  308. package/dist/forms/FormSpotlight.d.ts +1 -1
  309. package/dist/forms/FormSpotlight.d.ts.map +1 -1
  310. package/dist/forms/FormStage.d.ts +1 -1
  311. package/dist/forms/FormStage.d.ts.map +1 -1
  312. package/dist/forms/experience-plan.d.ts +0 -1
  313. package/dist/forms/experience-plan.d.ts.map +1 -1
  314. package/dist/forms/field-interactions.d.ts +63 -0
  315. package/dist/forms/field-interactions.d.ts.map +1 -0
  316. package/dist/forms/field-rules.d.ts +41 -0
  317. package/dist/forms/field-rules.d.ts.map +1 -0
  318. package/dist/forms/index.js +25 -23
  319. package/dist/forms/index.js.map +1 -1
  320. package/dist/forms/index.mjs +13 -11
  321. package/dist/forms/index.mjs.map +1 -1
  322. package/dist/forms/server.js +11 -11
  323. package/dist/forms/server.mjs +9 -9
  324. package/dist/forms/static.js +8 -8
  325. package/dist/forms/static.mjs +7 -7
  326. package/dist/forms/tracking-session.d.ts +48 -3
  327. package/dist/forms/tracking-session.d.ts.map +1 -1
  328. package/dist/forms/types.d.ts +11 -0
  329. package/dist/forms/types.d.ts.map +1 -1
  330. package/dist/forms/useForm.d.ts +8 -0
  331. package/dist/forms/useForm.d.ts.map +1 -1
  332. package/dist/forms/useFormTracking.d.ts +29 -4
  333. package/dist/forms/useFormTracking.d.ts.map +1 -1
  334. package/dist/images/index.js +11 -11
  335. package/dist/images/index.mjs +4 -4
  336. package/dist/index.js +72 -68
  337. package/dist/index.js.map +1 -1
  338. package/dist/index.mjs +14 -10
  339. package/dist/index.mjs.map +1 -1
  340. package/dist/layout/client.js +10 -10
  341. package/dist/layout/client.mjs +9 -9
  342. package/dist/layout/index.js +13 -12
  343. package/dist/layout/index.js.map +1 -1
  344. package/dist/layout/index.mjs +11 -10
  345. package/dist/layout/index.mjs.map +1 -1
  346. package/dist/lib-6HOOMENJ.js +0 -1
  347. package/dist/lib-BGAWCSUH.js +0 -1
  348. package/dist/lib-R7IQ4ZHE.mjs +0 -1
  349. package/dist/lib-RSDMEKDQ.mjs +0 -1
  350. package/dist/llms/aiRobots.d.ts +20 -4
  351. package/dist/llms/aiRobots.d.ts.map +1 -1
  352. package/dist/llms/api.d.ts +8 -3
  353. package/dist/llms/api.d.ts.map +1 -1
  354. package/dist/llms/discovery-headers.d.ts +24 -0
  355. package/dist/llms/discovery-headers.d.ts.map +1 -1
  356. package/dist/llms/generateLLMsTxt.d.ts.map +1 -1
  357. package/dist/llms/index.d.ts +2 -2
  358. package/dist/llms/index.d.ts.map +1 -1
  359. package/dist/llms/index.js +45 -96
  360. package/dist/llms/index.js.map +1 -1
  361. package/dist/llms/index.mjs +11 -81
  362. package/dist/llms/index.mjs.map +1 -1
  363. package/dist/llms/links.d.ts +26 -0
  364. package/dist/llms/links.d.ts.map +1 -0
  365. package/dist/llms/types.d.ts +15 -0
  366. package/dist/llms/types.d.ts.map +1 -1
  367. package/dist/llms/wiring.d.ts +22 -0
  368. package/dist/llms/wiring.d.ts.map +1 -1
  369. package/dist/llms/writeLLMsTxt.d.ts +9 -0
  370. package/dist/llms/writeLLMsTxt.d.ts.map +1 -1
  371. package/dist/maps/index.js +5 -5
  372. package/dist/maps/index.mjs +3 -3
  373. package/dist/motion/gsap.d.ts +54 -0
  374. package/dist/motion/gsap.d.ts.map +1 -1
  375. package/dist/motion/gsap.js +34 -4
  376. package/dist/motion/gsap.js.map +1 -1
  377. package/dist/motion/gsap.mjs +33 -5
  378. package/dist/motion/gsap.mjs.map +1 -1
  379. package/dist/og/config.d.ts +6 -0
  380. package/dist/og/config.d.ts.map +1 -1
  381. package/dist/og/contrast.d.ts +33 -0
  382. package/dist/og/contrast.d.ts.map +1 -0
  383. package/dist/og/index.d.ts +2 -0
  384. package/dist/og/index.d.ts.map +1 -1
  385. package/dist/og/index.js +26 -8
  386. package/dist/og/index.mjs +3 -1
  387. package/dist/og/pages.d.ts +101 -0
  388. package/dist/og/pages.d.ts.map +1 -1
  389. package/dist/og/route-copy.d.ts +34 -0
  390. package/dist/og/route-copy.d.ts.map +1 -0
  391. package/dist/og/route-fit.d.ts +77 -0
  392. package/dist/og/route-fit.d.ts.map +1 -0
  393. package/dist/og/route.d.ts +80 -20
  394. package/dist/og/route.d.ts.map +1 -1
  395. package/dist/og/route.js +195 -25
  396. package/dist/og/route.js.map +1 -1
  397. package/dist/og/route.mjs +193 -26
  398. package/dist/og/route.mjs.map +1 -1
  399. package/dist/og/template.d.ts.map +1 -1
  400. package/dist/og/wiring.d.ts +43 -3
  401. package/dist/og/wiring.d.ts.map +1 -1
  402. package/dist/proxy/index.d.ts.map +1 -1
  403. package/dist/proxy/index.js +15 -10
  404. package/dist/proxy/index.js.map +1 -1
  405. package/dist/proxy/index.mjs +12 -7
  406. package/dist/proxy/index.mjs.map +1 -1
  407. package/dist/redirects/index.d.ts +24 -0
  408. package/dist/redirects/index.d.ts.map +1 -1
  409. package/dist/redirects/index.js +11 -8
  410. package/dist/redirects/index.mjs +4 -1
  411. package/dist/redirects/not-found.js +8 -5
  412. package/dist/redirects/not-found.js.map +1 -1
  413. package/dist/redirects/not-found.mjs +4 -1
  414. package/dist/redirects/not-found.mjs.map +1 -1
  415. package/dist/robots/index.d.ts +2 -0
  416. package/dist/robots/index.d.ts.map +1 -1
  417. package/dist/robots/index.js +23 -3
  418. package/dist/robots/index.js.map +1 -1
  419. package/dist/robots/index.mjs +2 -2
  420. package/dist/robots/index.mjs.map +1 -1
  421. package/dist/search/index.js +4 -4
  422. package/dist/search/index.mjs +3 -3
  423. package/dist/seo/ManagedContent.d.ts +4 -2
  424. package/dist/seo/ManagedContent.d.ts.map +1 -1
  425. package/dist/seo/ManagedFAQ.d.ts.map +1 -1
  426. package/dist/seo/ManagedInternalLinks.d.ts.map +1 -1
  427. package/dist/seo/ManagedSchema.d.ts.map +1 -1
  428. package/dist/seo/client.js +6 -6
  429. package/dist/seo/client.mjs +5 -5
  430. package/dist/seo/getManagedMetadata.d.ts.map +1 -1
  431. package/dist/seo/index.js +59 -49
  432. package/dist/seo/index.js.map +1 -1
  433. package/dist/seo/index.mjs +29 -19
  434. package/dist/seo/index.mjs.map +1 -1
  435. package/dist/seo/register-sitemap-cli-impl.d.ts +32 -0
  436. package/dist/seo/register-sitemap-cli-impl.d.ts.map +1 -1
  437. package/dist/seo/register-sitemap-cli.d.ts +7 -0
  438. package/dist/seo/register-sitemap-cli.d.ts.map +1 -1
  439. package/dist/seo/register-sitemap-cli.js +273 -57
  440. package/dist/seo/register-sitemap-cli.mjs +269 -53
  441. package/dist/seo/register-sitemap-request.d.ts +36 -0
  442. package/dist/seo/register-sitemap-request.d.ts.map +1 -0
  443. package/dist/seo/routing.d.ts +2 -0
  444. package/dist/seo/routing.d.ts.map +1 -1
  445. package/dist/seo/schema-filter.d.ts +43 -0
  446. package/dist/seo/schema-filter.d.ts.map +1 -0
  447. package/dist/seo/server-api.d.ts +15 -2
  448. package/dist/seo/server-api.d.ts.map +1 -1
  449. package/dist/seo/server.js +23 -18
  450. package/dist/seo/server.mjs +7 -2
  451. package/dist/seo/types.d.ts +30 -0
  452. package/dist/seo/types.d.ts.map +1 -1
  453. package/dist/seo-meta/contract.d.ts +60 -0
  454. package/dist/seo-meta/contract.d.ts.map +1 -0
  455. package/dist/seo-meta/contract.js +41 -0
  456. package/dist/seo-meta/contract.js.map +1 -0
  457. package/dist/seo-meta/contract.mjs +4 -0
  458. package/dist/seo-meta/contract.mjs.map +1 -0
  459. package/dist/server/index.js +4 -3
  460. package/dist/server/index.mjs +3 -2
  461. package/dist/server/mint-site-token.d.ts +2 -32
  462. package/dist/server/mint-site-token.d.ts.map +1 -1
  463. package/dist/{server-api-RG3ZL3DV.mjs → server-api-A2EFCTZX.mjs} +7 -3
  464. package/dist/{server-api-RG3ZL3DV.mjs.map → server-api-A2EFCTZX.mjs.map} +1 -1
  465. package/dist/{server-api-RYJQAUGO.js → server-api-IWTZ7C3O.js} +25 -21
  466. package/dist/{server-api-RYJQAUGO.js.map → server-api-IWTZ7C3O.js.map} +1 -1
  467. package/dist/shared/build-entries.d.ts +2 -0
  468. package/dist/shared/build-entries.d.ts.map +1 -1
  469. package/dist/shared/fresh-fetch.d.ts +64 -0
  470. package/dist/shared/fresh-fetch.d.ts.map +1 -0
  471. package/dist/shared/next-files.d.ts +7 -0
  472. package/dist/shared/next-files.d.ts.map +1 -1
  473. package/dist/shared/page-leave.d.ts +27 -0
  474. package/dist/shared/page-leave.d.ts.map +1 -0
  475. package/dist/shared/source-graph.d.ts +63 -0
  476. package/dist/shared/source-graph.d.ts.map +1 -0
  477. package/dist/shared/version.d.ts +1 -1
  478. package/dist/signal/SignalCore.d.ts.map +1 -1
  479. package/dist/signal/index.js +11 -11
  480. package/dist/signal/index.mjs +2 -2
  481. package/dist/sitemap/index.d.ts +19 -4
  482. package/dist/sitemap/index.d.ts.map +1 -1
  483. package/dist/sitemap/index.js +53 -43
  484. package/dist/sitemap/index.js.map +1 -1
  485. package/dist/sitemap/index.mjs +37 -27
  486. package/dist/sitemap/index.mjs.map +1 -1
  487. package/dist/sitemap/shared.d.ts +65 -0
  488. package/dist/sitemap/shared.d.ts.map +1 -1
  489. package/dist/sites/resolve.d.ts.map +1 -1
  490. package/dist/sites/site-param.d.ts +16 -0
  491. package/dist/sites/site-param.d.ts.map +1 -0
  492. package/dist/sync/index.js +17 -17
  493. package/dist/sync/index.mjs +4 -4
  494. package/dist/writeLLMsTxt-CQ7A4AAL.js +19 -0
  495. package/dist/writeLLMsTxt-NX5MSPYX.mjs +10 -0
  496. package/package.json +9 -4
  497. package/dist/AnalyticsProvider-EWF7JN2X.mjs +0 -11
  498. package/dist/AnalyticsProvider-GJFG7YXA.js +0 -32
  499. package/dist/BlogViewTracker-2D3IJPJK.js.map +0 -1
  500. package/dist/BlogViewTracker-CKYG6MYU.mjs.map +0 -1
  501. package/dist/ChatWidget-AWP6GBVW.js +0 -22
  502. package/dist/ChatWidget-Z5QXDZP3.mjs +0 -13
  503. package/dist/EngageWidget-BKEY5TPO.mjs +0 -12
  504. package/dist/EngageWidget-VT4DYXVO.js +0 -21
  505. package/dist/FormSpotlight-OTFB6QM5.mjs.map +0 -1
  506. package/dist/FormSpotlight-URS4XRS7.js.map +0 -1
  507. package/dist/FormStage-FVKMIV73.js.map +0 -1
  508. package/dist/FormStage-VPGOCMAV.mjs.map +0 -1
  509. package/dist/ManagedForm-CXVDJMHN.mjs +0 -14
  510. package/dist/ManagedForm-FGNTDGED.js +0 -23
  511. package/dist/ManagedNewsletterForm-3O5L44AZ.js.map +0 -1
  512. package/dist/ManagedNewsletterForm-SQYB4BZU.mjs.map +0 -1
  513. package/dist/SignalCore-M2PKKIGH.mjs.map +0 -1
  514. package/dist/SignalCore-RFBOBNLQ.js.map +0 -1
  515. package/dist/SitemapSync-4OVMIIGC.mjs +0 -9
  516. package/dist/SitemapSync-RK3SQ4M2.js +0 -18
  517. package/dist/analytics/send-gate.test.d.ts +0 -20
  518. package/dist/analytics/send-gate.test.d.ts.map +0 -1
  519. package/dist/api-D745LGGU.mjs.map +0 -1
  520. package/dist/api-XR5APCH3.js.map +0 -1
  521. package/dist/blog/artwork-components.test.d.ts +0 -2
  522. package/dist/blog/artwork-components.test.d.ts.map +0 -1
  523. package/dist/blog/artwork.test.d.ts +0 -2
  524. package/dist/blog/artwork.test.d.ts.map +0 -1
  525. package/dist/blog/author-social.test.d.ts +0 -2
  526. package/dist/blog/author-social.test.d.ts.map +0 -1
  527. package/dist/blog/blog-tables.test.d.ts +0 -2
  528. package/dist/blog/blog-tables.test.d.ts.map +0 -1
  529. package/dist/blog/blog-view-tracker.test.d.ts +0 -2
  530. package/dist/blog/blog-view-tracker.test.d.ts.map +0 -1
  531. package/dist/blog/category-metadata.test.d.ts +0 -2
  532. package/dist/blog/category-metadata.test.d.ts.map +0 -1
  533. package/dist/blog/metadata-images.test.d.ts +0 -2
  534. package/dist/blog/metadata-images.test.d.ts.map +0 -1
  535. package/dist/blog/newsletter-widget.test.d.ts +0 -2
  536. package/dist/blog/newsletter-widget.test.d.ts.map +0 -1
  537. package/dist/blog/publication-render.test.d.ts +0 -2
  538. package/dist/blog/publication-render.test.d.ts.map +0 -1
  539. package/dist/blog/publication-routes.test.d.ts +0 -2
  540. package/dist/blog/publication-routes.test.d.ts.map +0 -1
  541. package/dist/blog/reading-time.test.d.ts +0 -2
  542. package/dist/blog/reading-time.test.d.ts.map +0 -1
  543. package/dist/blog/sanitize-excerpt.test.d.ts +0 -2
  544. package/dist/blog/sanitize-excerpt.test.d.ts.map +0 -1
  545. package/dist/blog/server-core-contract.test.d.ts +0 -2
  546. package/dist/blog/server-core-contract.test.d.ts.map +0 -1
  547. package/dist/blog/static-params.test.d.ts +0 -2
  548. package/dist/blog/static-params.test.d.ts.map +0 -1
  549. package/dist/blog/tag-links.test.d.ts +0 -2
  550. package/dist/blog/tag-links.test.d.ts.map +0 -1
  551. package/dist/blog/types-wire-shape.test.d.ts +0 -2
  552. package/dist/blog/types-wire-shape.test.d.ts.map +0 -1
  553. package/dist/brand/status-contrast.test.d.ts +0 -2
  554. package/dist/brand/status-contrast.test.d.ts.map +0 -1
  555. package/dist/chunk-3CLP35TT.mjs.map +0 -1
  556. package/dist/chunk-3UC6JETG.js +0 -32
  557. package/dist/chunk-3UC6JETG.js.map +0 -1
  558. package/dist/chunk-3YQILJKJ.js.map +0 -1
  559. package/dist/chunk-4B4S56WJ.mjs.map +0 -1
  560. package/dist/chunk-5B4FABFK.js.map +0 -1
  561. package/dist/chunk-5TXXTYXL.js +0 -8
  562. package/dist/chunk-5YA6SI4Z.mjs.map +0 -1
  563. package/dist/chunk-6CJP7BFM.js.map +0 -1
  564. package/dist/chunk-6FC5Q4KU.mjs.map +0 -1
  565. package/dist/chunk-7ZX6TO6C.mjs.map +0 -1
  566. package/dist/chunk-AWK57R5S.mjs +0 -29
  567. package/dist/chunk-AWK57R5S.mjs.map +0 -1
  568. package/dist/chunk-BFJOZ3MU.mjs.map +0 -1
  569. package/dist/chunk-BFM5PEFV.js.map +0 -1
  570. package/dist/chunk-CPY74A4F.js.map +0 -1
  571. package/dist/chunk-DOB37PV4.js.map +0 -1
  572. package/dist/chunk-F3AKYZOH.js.map +0 -1
  573. package/dist/chunk-FO4KGPGF.js.map +0 -1
  574. package/dist/chunk-GZJE23Y5.mjs.map +0 -1
  575. package/dist/chunk-H4OBGC43.mjs.map +0 -1
  576. package/dist/chunk-H6YVT3BL.js.map +0 -1
  577. package/dist/chunk-H7274TKR.mjs.map +0 -1
  578. package/dist/chunk-I7AZC5ZQ.js.map +0 -1
  579. package/dist/chunk-ILNCUSXW.mjs.map +0 -1
  580. package/dist/chunk-IPV2TUAT.js.map +0 -1
  581. package/dist/chunk-JEOKDUPQ.js +0 -45
  582. package/dist/chunk-JEOKDUPQ.js.map +0 -1
  583. package/dist/chunk-JNAXDFC4.mjs.map +0 -1
  584. package/dist/chunk-JNRHTZL4.js.map +0 -1
  585. package/dist/chunk-JOYMIGR2.mjs.map +0 -1
  586. package/dist/chunk-JS75ORH7.js.map +0 -1
  587. package/dist/chunk-JTCQJKJE.js.map +0 -1
  588. package/dist/chunk-L4V6TKMJ.mjs.map +0 -1
  589. package/dist/chunk-LC7AM4J5.js.map +0 -1
  590. package/dist/chunk-M5GY2AI3.mjs.map +0 -1
  591. package/dist/chunk-NN2YE5WT.js.map +0 -1
  592. package/dist/chunk-NNZDWY3L.mjs.map +0 -1
  593. package/dist/chunk-O2VJZOR2.mjs.map +0 -1
  594. package/dist/chunk-OZ3FU4BT.js.map +0 -1
  595. package/dist/chunk-P4TB4ROG.js.map +0 -1
  596. package/dist/chunk-Q7347KP6.mjs.map +0 -1
  597. package/dist/chunk-QJU6HBSK.mjs +0 -39
  598. package/dist/chunk-QJU6HBSK.mjs.map +0 -1
  599. package/dist/chunk-QRBPT6Z6.mjs +0 -6
  600. package/dist/chunk-RCSTDJUH.js.map +0 -1
  601. package/dist/chunk-RVRN5U7W.mjs.map +0 -1
  602. package/dist/chunk-TDJKGN5Q.mjs.map +0 -1
  603. package/dist/chunk-TP7H6BSK.mjs.map +0 -1
  604. package/dist/chunk-TSZIACRC.js.map +0 -1
  605. package/dist/chunk-UJ6CHZAI.mjs.map +0 -1
  606. package/dist/chunk-VFGEY6FJ.js.map +0 -1
  607. package/dist/cli/agent/envelope.test.d.ts +0 -2
  608. package/dist/cli/agent/envelope.test.d.ts.map +0 -1
  609. package/dist/cli/agent/ssr-bailout.test.d.ts +0 -2
  610. package/dist/cli/agent/ssr-bailout.test.d.ts.map +0 -1
  611. package/dist/cli/codemod/diff.test.d.ts +0 -2
  612. package/dist/cli/codemod/diff.test.d.ts.map +0 -1
  613. package/dist/cli/codemod/transforms.test.d.ts +0 -2
  614. package/dist/cli/codemod/transforms.test.d.ts.map +0 -1
  615. package/dist/cli/commands/config-regression.test.d.ts +0 -2
  616. package/dist/cli/commands/config-regression.test.d.ts.map +0 -1
  617. package/dist/cli/commands/geo.test.d.ts +0 -2
  618. package/dist/cli/commands/geo.test.d.ts.map +0 -1
  619. package/dist/cli/commands/og.test.d.ts +0 -2
  620. package/dist/cli/commands/og.test.d.ts.map +0 -1
  621. package/dist/cli/config.test.d.ts +0 -2
  622. package/dist/cli/config.test.d.ts.map +0 -1
  623. package/dist/cli/generators/index.test.d.ts +0 -2
  624. package/dist/cli/generators/index.test.d.ts.map +0 -1
  625. package/dist/cli/index.js.map +0 -1
  626. package/dist/cli/index.mjs.map +0 -1
  627. package/dist/cli/state.test.d.ts +0 -2
  628. package/dist/cli/state.test.d.ts.map +0 -1
  629. package/dist/commerce/events-extras.test.d.ts +0 -2
  630. package/dist/commerce/events-extras.test.d.ts.map +0 -1
  631. package/dist/commerce/server-result.test.d.ts +0 -2
  632. package/dist/commerce/server-result.test.d.ts.map +0 -1
  633. package/dist/discover-FGTKWOL3.mjs +0 -4
  634. package/dist/discover-NJZPWTDL.js +0 -21
  635. package/dist/engage/chat-launcher.test.d.ts +0 -2
  636. package/dist/engage/chat-launcher.test.d.ts.map +0 -1
  637. package/dist/engage/dependency-contract.test.d.ts +0 -2
  638. package/dist/engage/dependency-contract.test.d.ts.map +0 -1
  639. package/dist/engage/launcher-placement.test.d.ts +0 -2
  640. package/dist/engage/launcher-placement.test.d.ts.map +0 -1
  641. package/dist/fleet/contract.test.d.ts +0 -2
  642. package/dist/fleet/contract.test.d.ts.map +0 -1
  643. package/dist/fleet/heartbeat.test.d.ts +0 -2
  644. package/dist/fleet/heartbeat.test.d.ts.map +0 -1
  645. package/dist/forms/contract.test.d.ts +0 -2
  646. package/dist/forms/contract.test.d.ts.map +0 -1
  647. package/dist/forms/ga4-identity.test.d.ts +0 -2
  648. package/dist/forms/ga4-identity.test.d.ts.map +0 -1
  649. package/dist/forms/native-fallback.test.d.ts +0 -2
  650. package/dist/forms/native-fallback.test.d.ts.map +0 -1
  651. package/dist/forms/stage.test.d.ts +0 -2
  652. package/dist/forms/stage.test.d.ts.map +0 -1
  653. package/dist/forms/static-form.test.d.ts +0 -2
  654. package/dist/forms/static-form.test.d.ts.map +0 -1
  655. package/dist/forms/tracking-session.test.d.ts +0 -22
  656. package/dist/forms/tracking-session.test.d.ts.map +0 -1
  657. package/dist/landing/contract.test.d.ts +0 -2
  658. package/dist/landing/contract.test.d.ts.map +0 -1
  659. package/dist/landing/server-entry.test.d.ts +0 -2
  660. package/dist/landing/server-entry.test.d.ts.map +0 -1
  661. package/dist/lib-6HOOMENJ.js.map +0 -1
  662. package/dist/lib-BGAWCSUH.js.map +0 -1
  663. package/dist/lib-R7IQ4ZHE.mjs.map +0 -1
  664. package/dist/lib-RSDMEKDQ.mjs.map +0 -1
  665. package/dist/llms/aiRobots.test.d.ts +0 -2
  666. package/dist/llms/aiRobots.test.d.ts.map +0 -1
  667. package/dist/llms/contract.test.d.ts +0 -2
  668. package/dist/llms/contract.test.d.ts.map +0 -1
  669. package/dist/llms/discovery-headers.test.d.ts +0 -2
  670. package/dist/llms/discovery-headers.test.d.ts.map +0 -1
  671. package/dist/llms/generateLLMsTxt.test.d.ts +0 -2
  672. package/dist/llms/generateLLMsTxt.test.d.ts.map +0 -1
  673. package/dist/llms/handlers.test.d.ts +0 -2
  674. package/dist/llms/handlers.test.d.ts.map +0 -1
  675. package/dist/llms/humanize-industry.test.d.ts +0 -2
  676. package/dist/llms/humanize-industry.test.d.ts.map +0 -1
  677. package/dist/llms/sourcedFacts.test.d.ts +0 -2
  678. package/dist/llms/sourcedFacts.test.d.ts.map +0 -1
  679. package/dist/llms/wiring.test.d.ts +0 -2
  680. package/dist/llms/wiring.test.d.ts.map +0 -1
  681. package/dist/llms/writeLLMsTxt.test.d.ts +0 -2
  682. package/dist/llms/writeLLMsTxt.test.d.ts.map +0 -1
  683. package/dist/mcp/protocol.test.d.ts +0 -2
  684. package/dist/mcp/protocol.test.d.ts.map +0 -1
  685. package/dist/motion/motion.test.d.ts +0 -16
  686. package/dist/motion/motion.test.d.ts.map +0 -1
  687. package/dist/og/pages.test.d.ts +0 -2
  688. package/dist/og/pages.test.d.ts.map +0 -1
  689. package/dist/og/template.test.d.ts +0 -2
  690. package/dist/og/template.test.d.ts.map +0 -1
  691. package/dist/og/wiring.test.d.ts +0 -2
  692. package/dist/og/wiring.test.d.ts.map +0 -1
  693. package/dist/portfolio/contract.test.d.ts +0 -2
  694. package/dist/portfolio/contract.test.d.ts.map +0 -1
  695. package/dist/proxy/securityHeaders.test.d.ts +0 -2
  696. package/dist/proxy/securityHeaders.test.d.ts.map +0 -1
  697. package/dist/proxy/segment.test.d.ts +0 -2
  698. package/dist/proxy/segment.test.d.ts.map +0 -1
  699. package/dist/robots/index.test.d.ts +0 -2
  700. package/dist/robots/index.test.d.ts.map +0 -1
  701. package/dist/seo/register-sitemap-cli-impl.test.d.ts +0 -2
  702. package/dist/seo/register-sitemap-cli-impl.test.d.ts.map +0 -1
  703. package/dist/seo/register-sitemap-cli.js.map +0 -1
  704. package/dist/seo/register-sitemap-cli.mjs.map +0 -1
  705. package/dist/seo-pages/contract.test.d.ts +0 -2
  706. package/dist/seo-pages/contract.test.d.ts.map +0 -1
  707. package/dist/server/mint-site-token.test.d.ts +0 -2
  708. package/dist/server/mint-site-token.test.d.ts.map +0 -1
  709. package/dist/server/server-fetch.test.d.ts +0 -2
  710. package/dist/server/server-fetch.test.d.ts.map +0 -1
  711. package/dist/shared/client-entry-boundary.test.d.ts +0 -2
  712. package/dist/shared/client-entry-boundary.test.d.ts.map +0 -1
  713. package/dist/shared/next-files.test.d.ts +0 -2
  714. package/dist/shared/next-files.test.d.ts.map +0 -1
  715. package/dist/shared/no-cjs-require.test.d.ts +0 -2
  716. package/dist/shared/no-cjs-require.test.d.ts.map +0 -1
  717. package/dist/shared/publishCredential.test.d.ts +0 -2
  718. package/dist/shared/publishCredential.test.d.ts.map +0 -1
  719. package/dist/shared/raw-browser-api-guard.test.d.ts +0 -15
  720. package/dist/shared/raw-browser-api-guard.test.d.ts.map +0 -1
  721. package/dist/shared/siteToken.test.d.ts +0 -2
  722. package/dist/shared/siteToken.test.d.ts.map +0 -1
  723. package/dist/shared/sonorFetch.test.d.ts +0 -2
  724. package/dist/shared/sonorFetch.test.d.ts.map +0 -1
  725. package/dist/shared/uuid.test.d.ts +0 -2
  726. package/dist/shared/uuid.test.d.ts.map +0 -1
  727. package/dist/shared/version.test.d.ts +0 -2
  728. package/dist/shared/version.test.d.ts.map +0 -1
  729. package/dist/shared/visual-viewport-gap.test.d.ts +0 -2
  730. package/dist/shared/visual-viewport-gap.test.d.ts.map +0 -1
  731. package/dist/sitemap/discover.test.d.ts +0 -2
  732. package/dist/sitemap/discover.test.d.ts.map +0 -1
  733. package/dist/sitemap/shared.test.d.ts +0 -2
  734. package/dist/sitemap/shared.test.d.ts.map +0 -1
  735. package/dist/sitemap/site-scope.test.d.ts +0 -2
  736. package/dist/sitemap/site-scope.test.d.ts.map +0 -1
  737. package/dist/sites/contract.test.d.ts +0 -2
  738. package/dist/sites/contract.test.d.ts.map +0 -1
  739. package/dist/slots/ManagedSlot.test.d.ts +0 -2
  740. package/dist/slots/ManagedSlot.test.d.ts.map +0 -1
  741. package/dist/slots/contract.test.d.ts +0 -2
  742. package/dist/slots/contract.test.d.ts.map +0 -1
  743. package/dist/slots/revalidate.test.d.ts +0 -2
  744. package/dist/slots/revalidate.test.d.ts.map +0 -1
  745. package/dist/slots/server-api.test.d.ts +0 -2
  746. package/dist/slots/server-api.test.d.ts.map +0 -1
  747. package/dist/sync/add-to-calendar.test.d.ts +0 -2
  748. package/dist/sync/add-to-calendar.test.d.ts.map +0 -1
  749. package/dist/sync/api-errors.test.d.ts +0 -2
  750. package/dist/sync/api-errors.test.d.ts.map +0 -1
  751. package/dist/sync/booking-flow.test.d.ts +0 -2
  752. package/dist/sync/booking-flow.test.d.ts.map +0 -1
@@ -0,0 +1,81 @@
1
+ 'use strict';
2
+
3
+ // src/sitemap/shared.ts
4
+ function inferPageType(urlPath) {
5
+ if (urlPath === "/" || urlPath === "") return "homepage";
6
+ if (/^\/services(\/|$)/i.test(urlPath)) return "service";
7
+ if (/^\/compare(\/|$)/i.test(urlPath)) return "comparison";
8
+ if (/^\/(insights|blog)(\/|$)/i.test(urlPath)) return "blog";
9
+ if (/^\/industries(\/|$)/i.test(urlPath)) return "industry";
10
+ if (/^\/work(\/|$)/i.test(urlPath)) return "portfolio";
11
+ if (/^\/faq(\/|$)/i.test(urlPath)) return "faq";
12
+ if (/^\/pricing(\/|$)/i.test(urlPath)) return "pricing";
13
+ return "page";
14
+ }
15
+ function stripTrailingSlash(path) {
16
+ if (path !== "/" && path.endsWith("/")) {
17
+ return path.slice(0, -1);
18
+ }
19
+ return path;
20
+ }
21
+ function applyTrailingSlash(path, trailingSlash) {
22
+ const cut = path.search(/[?#]/);
23
+ const pathname = cut === -1 ? path : path.slice(0, cut);
24
+ const suffix = cut === -1 ? "" : path.slice(cut);
25
+ return shapePathname(pathname, trailingSlash) + suffix;
26
+ }
27
+ function shapePathname(pathname, trailingSlash) {
28
+ if (pathname === "" || pathname === "/") return pathname;
29
+ if (/^\/\.well-known(\/|$)/.test(pathname)) return pathname;
30
+ const bare = stripTrailingSlash(pathname);
31
+ if (!trailingSlash) return bare;
32
+ const lastSegment = bare.slice(bare.lastIndexOf("/") + 1);
33
+ return lastSegment.includes(".") ? bare : `${bare}/`;
34
+ }
35
+ function nextTrailingSlash() {
36
+ let value;
37
+ try {
38
+ value = process.env.__NEXT_TRAILING_SLASH;
39
+ } catch {
40
+ return void 0;
41
+ }
42
+ if (value === true || value === "true") return true;
43
+ if (value === false || value === "false") return false;
44
+ return void 0;
45
+ }
46
+ function resolveTrailingSlash(explicit) {
47
+ return explicit ?? nextTrailingSlash() ?? false;
48
+ }
49
+ function locToPath(loc) {
50
+ let path;
51
+ try {
52
+ path = new URL(loc).pathname;
53
+ } catch {
54
+ path = loc.startsWith("/") ? loc : `/${loc}`;
55
+ }
56
+ return stripTrailingSlash(path);
57
+ }
58
+ var EMBEDDED_DOMAIN_PREFIX = /^\/{1,2}[a-z0-9.-]+\.[a-z]{2,}(\/|$)/i;
59
+ var EMBEDDED_DOMAIN_ANYWHERE = /\/\/[a-z0-9.-]+\.[a-z]{2,}/i;
60
+ function stripEmbeddedDomain(path) {
61
+ return path.replace(EMBEDDED_DOMAIN_PREFIX, "/");
62
+ }
63
+ function isMalformedSitemapPath(path) {
64
+ return path.includes("://") || EMBEDDED_DOMAIN_ANYWHERE.test(path);
65
+ }
66
+ var LLMS_WRITE_ROUTE_BUDGET_MS = 5e4;
67
+ function llmsWriteTimeoutMs(configured, routeStartedAt, now = Date.now()) {
68
+ if (configured != null) return configured;
69
+ return LLMS_WRITE_ROUTE_BUDGET_MS - (now - routeStartedAt);
70
+ }
71
+
72
+ exports.applyTrailingSlash = applyTrailingSlash;
73
+ exports.inferPageType = inferPageType;
74
+ exports.isMalformedSitemapPath = isMalformedSitemapPath;
75
+ exports.llmsWriteTimeoutMs = llmsWriteTimeoutMs;
76
+ exports.locToPath = locToPath;
77
+ exports.resolveTrailingSlash = resolveTrailingSlash;
78
+ exports.stripEmbeddedDomain = stripEmbeddedDomain;
79
+ exports.stripTrailingSlash = stripTrailingSlash;
80
+ //# sourceMappingURL=chunk-R7GHP3FY.js.map
81
+ //# sourceMappingURL=chunk-R7GHP3FY.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/sitemap/shared.ts"],"names":[],"mappings":";;;AAyCO,SAAS,cAAc,OAAA,EAA2B;AACvD,EAAA,IAAI,OAAA,KAAY,GAAA,IAAO,OAAA,KAAY,EAAA,EAAI,OAAO,UAAA;AAC9C,EAAA,IAAI,oBAAA,CAAqB,IAAA,CAAK,OAAO,CAAA,EAAG,OAAO,SAAA;AAC/C,EAAA,IAAI,mBAAA,CAAoB,IAAA,CAAK,OAAO,CAAA,EAAG,OAAO,YAAA;AAC9C,EAAA,IAAI,2BAAA,CAA4B,IAAA,CAAK,OAAO,CAAA,EAAG,OAAO,MAAA;AACtD,EAAA,IAAI,sBAAA,CAAuB,IAAA,CAAK,OAAO,CAAA,EAAG,OAAO,UAAA;AACjD,EAAA,IAAI,gBAAA,CAAiB,IAAA,CAAK,OAAO,CAAA,EAAG,OAAO,WAAA;AAC3C,EAAA,IAAI,eAAA,CAAgB,IAAA,CAAK,OAAO,CAAA,EAAG,OAAO,KAAA;AAC1C,EAAA,IAAI,mBAAA,CAAoB,IAAA,CAAK,OAAO,CAAA,EAAG,OAAO,SAAA;AAC9C,EAAA,OAAO,MAAA;AACT;AAMO,SAAS,mBAAmB,IAAA,EAAsB;AACvD,EAAA,IAAI,IAAA,KAAS,GAAA,IAAO,IAAA,CAAK,QAAA,CAAS,GAAG,CAAA,EAAG;AACtC,IAAA,OAAO,IAAA,CAAK,KAAA,CAAM,CAAA,EAAG,EAAE,CAAA;AAAA,EACzB;AACA,EAAA,OAAO,IAAA;AACT;AAuBO,SAAS,kBAAA,CAAmB,MAAc,aAAA,EAAgC;AAC/E,EAAA,MAAM,GAAA,GAAM,IAAA,CAAK,MAAA,CAAO,MAAM,CAAA;AAC9B,EAAA,MAAM,WAAW,GAAA,KAAQ,EAAA,GAAK,OAAO,IAAA,CAAK,KAAA,CAAM,GAAG,GAAG,CAAA;AACtD,EAAA,MAAM,SAAS,GAAA,KAAQ,EAAA,GAAK,EAAA,GAAK,IAAA,CAAK,MAAM,GAAG,CAAA;AAC/C,EAAA,OAAO,aAAA,CAAc,QAAA,EAAU,aAAa,CAAA,GAAI,MAAA;AAClD;AAEA,SAAS,aAAA,CAAc,UAAkB,aAAA,EAAgC;AACvE,EAAA,IAAI,QAAA,KAAa,EAAA,IAAM,QAAA,KAAa,GAAA,EAAK,OAAO,QAAA;AAChD,EAAA,IAAI,uBAAA,CAAwB,IAAA,CAAK,QAAQ,CAAA,EAAG,OAAO,QAAA;AACnD,EAAA,MAAM,IAAA,GAAO,mBAAmB,QAAQ,CAAA;AACxC,EAAA,IAAI,CAAC,eAAe,OAAO,IAAA;AAC3B,EAAA,MAAM,cAAc,IAAA,CAAK,KAAA,CAAM,KAAK,WAAA,CAAY,GAAG,IAAI,CAAC,CAAA;AACxD,EAAA,OAAO,YAAY,QAAA,CAAS,GAAG,CAAA,GAAI,IAAA,GAAO,GAAG,IAAI,CAAA,CAAA,CAAA;AACnD;AAiBO,SAAS,iBAAA,GAAyC;AACvD,EAAA,IAAI,KAAA;AACJ,EAAA,IAAI;AACF,IAAA,KAAA,GAAQ,QAAQ,GAAA,CAAI,qBAAA;AAAA,EACtB,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,MAAA;AAAA,EACT;AACA,EAAA,IAAI,KAAA,KAAU,IAAA,IAAQ,KAAA,KAAU,MAAA,EAAQ,OAAO,IAAA;AAC/C,EAAA,IAAI,KAAA,KAAU,KAAA,IAAS,KAAA,KAAU,OAAA,EAAS,OAAO,KAAA;AACjD,EAAA,OAAO,MAAA;AACT;AAGO,SAAS,qBAAqB,QAAA,EAA6B;AAChE,EAAA,OAAO,QAAA,IAAY,mBAAkB,IAAK,KAAA;AAC5C;AAUO,SAAS,UAAU,GAAA,EAAqB;AAC7C,EAAA,IAAI,IAAA;AACJ,EAAA,IAAI;AACF,IAAA,IAAA,GAAO,IAAI,GAAA,CAAI,GAAG,CAAA,CAAE,QAAA;AAAA,EACtB,CAAA,CAAA,MAAQ;AACN,IAAA,IAAA,GAAO,IAAI,UAAA,CAAW,GAAG,CAAA,GAAI,GAAA,GAAM,IAAI,GAAG,CAAA,CAAA;AAAA,EAC5C;AACA,EAAA,OAAO,mBAAmB,IAAI,CAAA;AAChC;AAMA,IAAM,sBAAA,GAAyB,uCAAA;AAG/B,IAAM,wBAAA,GAA2B,6BAAA;AAO1B,SAAS,oBAAoB,IAAA,EAAsB;AACxD,EAAA,OAAO,IAAA,CAAK,OAAA,CAAQ,sBAAA,EAAwB,GAAG,CAAA;AACjD;AAMO,SAAS,uBAAuB,IAAA,EAAuB;AAC5D,EAAA,OAAO,KAAK,QAAA,CAAS,KAAK,CAAA,IAAK,wBAAA,CAAyB,KAAK,IAAI,CAAA;AACnE;AAeO,IAAM,0BAAA,GAA6B,GAAA;AAOnC,SAAS,mBACd,UAAA,EACA,cAAA,EACA,GAAA,GAAc,IAAA,CAAK,KAAI,EACf;AACR,EAAA,IAAI,UAAA,IAAc,MAAM,OAAO,UAAA;AAC/B,EAAA,OAAO,8BAA8B,GAAA,GAAM,cAAA,CAAA;AAC7C","file":"chunk-R7GHP3FY.js","sourcesContent":["/**\n * @sonordev/site-kit — shared sitemap page classification + path normalization\n *\n * Single source of truth for two bits of logic that used to be copy-pasted in\n * three places (createSitemap in `sitemap/index.ts`, the runtime `SitemapSync`\n * component, and the `sonor-register-sitemap` CLI):\n *\n * 1. inferPageType — path → Signal page-type hint\n * 2. path normalization — turning a sitemap `<loc>` / entry URL into a clean,\n * site-relative path, and rejecting/repairing malformed embedded-domain paths\n *\n * It also owns the outbound direction, `applyTrailingSlash`: the shape of a\n * path in a URL the kit emits, which follows the site's Next `trailingSlash`.\n * Normalized paths (the dedupe/sync key) never carry the slash. Emitted URLs\n * carry it when the site does.\n *\n * The copies had already drifted (one treated `''` as the homepage, the others\n * didn't; one stripped embedded domains, another only rejected them). Keeping\n * one implementation is the CLAUDE.md \"consolidate duplicated logic\" rule.\n *\n * Pure string logic only — NO Node built-ins, NO React — so this file is safe to\n * import from the browser `SitemapSync` client component AND from the Node CLI.\n */\n\n/** Signal page-type hint attached to each sitemap entry. */\nexport type PageType =\n | 'homepage'\n | 'service'\n | 'comparison'\n | 'blog'\n | 'industry'\n | 'portfolio'\n | 'faq'\n | 'pricing'\n | 'page'\n\n/**\n * Infer a page type from a URL path, to give Signal context about what each\n * page covers. Accepts both `'/'` and `''` as the homepage (callers pass either\n * depending on how they normalized the path).\n */\nexport function inferPageType(urlPath: string): PageType {\n if (urlPath === '/' || urlPath === '') return 'homepage'\n if (/^\\/services(\\/|$)/i.test(urlPath)) return 'service'\n if (/^\\/compare(\\/|$)/i.test(urlPath)) return 'comparison'\n if (/^\\/(insights|blog)(\\/|$)/i.test(urlPath)) return 'blog'\n if (/^\\/industries(\\/|$)/i.test(urlPath)) return 'industry'\n if (/^\\/work(\\/|$)/i.test(urlPath)) return 'portfolio'\n if (/^\\/faq(\\/|$)/i.test(urlPath)) return 'faq'\n if (/^\\/pricing(\\/|$)/i.test(urlPath)) return 'pricing'\n return 'page'\n}\n\n/**\n * Strip a trailing slash from a path, preserving the `'/'` root. Used so that\n * `/about` and `/about/` are treated as the same page everywhere.\n */\nexport function stripTrailingSlash(path: string): string {\n if (path !== '/' && path.endsWith('/')) {\n return path.slice(0, -1)\n }\n return path\n}\n\n/**\n * Shape a site path the way the site's own Next config serves it.\n *\n * Single source of truth for Next's `trailingSlash` URL shape, used by\n * createSitemap (`<loc>`), the llms.txt link rewrite and ClusterNavigation.\n * With `trailingSlash: true`, Next 308-redirects `/about` to `/about/`. Every\n * URL the kit emits for a page has to carry the slash already, or crawlers\n * get a redirect instead of the page and the sitemap disagrees with the\n * canonicals. That's what happened on the five MDG property sites\n * (2026-09-15).\n *\n * Mirrors the redirects Next adds in `lib/load-custom-routes`:\n * - `/` stays `/`.\n * - A last segment with a `.` is a file (`/llms.txt`, `/feed.xml`) and never\n * gets a slash.\n * - `/.well-known/*` is left exactly as written. Next exempts it from both\n * redirects.\n * - `trailingSlash: false` strips the slash, which is Next's default.\n *\n * A `?query` or `#hash` is kept and the rule applies to the path before it.\n */\nexport function applyTrailingSlash(path: string, trailingSlash: boolean): string {\n const cut = path.search(/[?#]/)\n const pathname = cut === -1 ? path : path.slice(0, cut)\n const suffix = cut === -1 ? '' : path.slice(cut)\n return shapePathname(pathname, trailingSlash) + suffix\n}\n\nfunction shapePathname(pathname: string, trailingSlash: boolean): string {\n if (pathname === '' || pathname === '/') return pathname\n if (/^\\/\\.well-known(\\/|$)/.test(pathname)) return pathname\n const bare = stripTrailingSlash(pathname)\n if (!trailingSlash) return bare\n const lastSegment = bare.slice(bare.lastIndexOf('/') + 1)\n return lastSegment.includes('.') ? bare : `${bare}/`\n}\n\n/**\n * The site's `next.config` `trailingSlash`, or undefined when not running inside\n * a Next bundle.\n *\n * Next inlines `process.env.__NEXT_TRAILING_SLASH` at compile time (its\n * `define-env`) into every module it bundles, node_modules included, for\n * server, edge and client alike. The kit reads the site's config this way\n * with no file I/O. Keep the expression spelled exactly like this: the\n * bundler matches the literal member expression, so destructuring\n * `process.env` or indexing it with a variable gets no substitution.\n *\n * Returns undefined in plain Node, like a postbuild script, or when a site\n * lists the kit in `serverExternalPackages`. Pass `trailingSlash` explicitly\n * there.\n */\nexport function nextTrailingSlash(): boolean | undefined {\n let value: unknown\n try {\n value = process.env.__NEXT_TRAILING_SLASH\n } catch {\n return undefined // no `process` in this runtime and no Next substitution\n }\n if (value === true || value === 'true') return true\n if (value === false || value === 'false') return false\n return undefined\n}\n\n/** An explicit `trailingSlash` option, else the site's Next config, else Next's default (false). */\nexport function resolveTrailingSlash(explicit?: boolean): boolean {\n return explicit ?? nextTrailingSlash() ?? false\n}\n\n/**\n * Turn a sitemap `<loc>` value (a full URL) or an already-relative path into a\n * clean, site-relative path. Falls back gracefully when the value isn't a\n * parseable absolute URL, and always strips the trailing slash.\n *\n * `https://example.com/about/` → `/about`\n * `about` → `/about`\n */\nexport function locToPath(loc: string): string {\n let path: string\n try {\n path = new URL(loc).pathname\n } catch {\n path = loc.startsWith('/') ? loc : `/${loc}`\n }\n return stripTrailingSlash(path)\n}\n\n/**\n * Matches a leading embedded domain in a malformed path, e.g. a crawler or bad\n * generator producing `//example.com/services` instead of `/services`.\n */\nconst EMBEDDED_DOMAIN_PREFIX = /^\\/{1,2}[a-z0-9.-]+\\.[a-z]{2,}(\\/|$)/i\n\n/** Matches an embedded protocol or domain anywhere in a path (unrepairable). */\nconst EMBEDDED_DOMAIN_ANYWHERE = /\\/\\/[a-z0-9.-]+\\.[a-z]{2,}/i\n\n/**\n * Repair a path whose leading segment is actually a domain\n * (`//example.com/x` → `/x`). Only touches the leading embedded domain; a path\n * that's malformed deeper in is left for `isMalformedSitemapPath` to reject.\n */\nexport function stripEmbeddedDomain(path: string): string {\n return path.replace(EMBEDDED_DOMAIN_PREFIX, '/')\n}\n\n/**\n * True when a path still contains an embedded protocol or domain after\n * normalization — such a \"path\" isn't a real page path and must not be synced.\n */\nexport function isMalformedSitemapPath(path: string): boolean {\n return path.includes('://') || EMBEDDED_DOMAIN_ANYWHERE.test(path)\n}\n\n/**\n * How much of the sitemap route's time the build-time llms.txt write may use.\n *\n * Next gives a prerendered route 60s (`staticPageGenerationTimeout`), then\n * retries it and fails the build. Sonor generates llms.txt through an LLM call\n * that takes roughly 27-60s, so the write can't reliably fit, and it runs\n * after the Portal sync has already spent part of the budget. Until 2026-09 a\n * one-year Data Cache entry hid this: the call ran live only on a site's first\n * build, and every later build replayed the stored response (a stale file).\n * With reads fresh (shared/fresh-fetch.ts), the write gets whatever is left of\n * this share of the budget. When Sonor answers in time, llms.txt refreshes;\n * when it doesn't, the existing file keeps serving and the build still passes.\n */\nexport const LLMS_WRITE_ROUTE_BUDGET_MS = 50_000\n\n/**\n * Timeout for the in-route llms.txt write: an explicit `llmsWriteTimeoutMs`\n * wins; otherwise what's left of LLMS_WRITE_ROUTE_BUDGET_MS since the route\n * started. Zero or less means skip the write.\n */\nexport function llmsWriteTimeoutMs(\n configured: number | undefined,\n routeStartedAt: number,\n now: number = Date.now(),\n): number {\n if (configured != null) return configured\n return LLMS_WRITE_ROUTE_BUDGET_MS - (now - routeStartedAt)\n}\n"]}
@@ -10,7 +10,7 @@ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
10
10
  var React__default = /*#__PURE__*/_interopDefault(React);
11
11
 
12
12
  var InteractiveForm = React.lazy(
13
- () => import('./ManagedForm-FGNTDGED.js').then((m) => ({ default: m.ManagedForm }))
13
+ () => import('./ManagedForm-R6DJXU34.js').then((m) => ({ default: m.ManagedForm }))
14
14
  );
15
15
  function FormEnhancer({
16
16
  formId,
@@ -106,5 +106,5 @@ function EnterStyles() {
106
106
  }
107
107
 
108
108
  exports.FormEnhancer = FormEnhancer;
109
- //# sourceMappingURL=chunk-4UVM7E2W.js.map
110
- //# sourceMappingURL=chunk-4UVM7E2W.js.map
109
+ //# sourceMappingURL=chunk-S5VL7AWW.js.map
110
+ //# sourceMappingURL=chunk-S5VL7AWW.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/forms/FormEnhancer.tsx"],"names":["lazy","useDeferredActivation","useState","jsxs","jsx","Suspense","React","useRef","useEffect"],"mappings":"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","file":"chunk-4UVM7E2W.js","sourcesContent":["'use client'\n\n/**\n * FormEnhancer — the only client code a managed form needs up front.\n *\n * Renders the server-rendered shell (<StaticForm>, passed as `children`) until\n * an idle/first-interaction gate fires, then lazy-imports the interactive form\n * and swaps it in. Everything expensive — validation, conditional logic,\n * spotlight/stage, celebration, momentum — lives behind that dynamic import,\n * so a page ships this boundary and nothing else in its initial chunk set.\n *\n * The shell is a REAL form the whole time (native action + signed token), so\n * the progression is:\n *\n * no JS at all -> shell, submits natively. Works.\n * JS, pre-idle -> shell, submits natively. Works.\n * JS, post-idle -> enhanced form, submits over JSON. Works, with delight.\n * chunk 404s -> shell stays. Works. (Never left blank.)\n *\n * That last line is the invariant to protect: the shell is only removed once\n * the enhancement has actually rendered. Do not \"hide the shell then load\" —\n * a CDN hiccup would leave a visitor staring at an empty box where the form\n * used to be.\n *\n * ── Entrance animation ──────────────────────────────────────────────────\n *\n * Above-the-fold forms upgrade while the visitor is looking at them, so the\n * swap must not pop. The wrapper carries `data-sk-form-mount=\"shell\"` and\n * flips to `\"enhanced\"`, and the enhanced form gets `data-sk-enter` for one\n * frame, so a site can style the transition entirely in CSS:\n *\n * [data-sk-form-mount] { transition: opacity .35s ease }\n * [data-sk-form-mount=\"shell\"] { opacity: .6 }\n *\n * Defaults ship as CSS variables rather than hard-coded values:\n *\n * --sk-form-enter-duration (default 320ms)\n * --sk-form-enter-easing (default cubic-bezier(.22,1,.36,1))\n * --sk-form-enter-distance (default 6px)\n *\n * `enter=\"none\"` opts out entirely; `enter=\"custom\"` emits the data\n * attributes but no site-kit styles, leaving the animation to the site.\n * Every default is collapsed by prefers-reduced-motion.\n */\n\nimport React, { lazy, Suspense, useEffect, useRef, useState } from 'react'\nimport { useDeferredActivation } from '../shared/defer'\nimport type { FormExperience, FormSubmission } from './types'\n\n/** The heavy half. Nothing else in this module may import it statically. */\nconst InteractiveForm = lazy(() =>\n import('./ManagedForm').then((m) => ({ default: m.ManagedForm })),\n)\n\nexport type FormEnterAnimation = 'fade' | 'none' | 'custom'\n\nexport interface FormEnhancerProps {\n formId: string\n /** Server-fetched raw config — hands the enhancement its fields instantly. */\n initialConfig?: Record<string, unknown> | null\n className?: string\n nativeReturnTo?: string\n experience?: FormExperience\n /** Pre-fill field values by slug. See ManagedForm.defaultValues. */\n defaultValues?: Record<string, unknown>\n onSuccess?: (submission: FormSubmission) => void\n onError?: (error: Error) => void\n /**\n * How the enhanced form arrives. 'fade' (default) crossfades and lifts it\n * into place; 'none' swaps instantly; 'custom' emits the data attributes\n * and no styles so the site owns the animation.\n */\n enter?: FormEnterAnimation\n /**\n * Set false to enhance immediately instead of waiting for idle. Only worth\n * it for a form that is the entire point of the page AND above the fold.\n */\n defer?: boolean\n /** The server-rendered <StaticForm>. Shown until the enhancement mounts. */\n children: React.ReactNode\n}\n\nexport function FormEnhancer({\n formId,\n initialConfig,\n className,\n nativeReturnTo,\n experience,\n defaultValues,\n onSuccess,\n onError,\n enter = 'fade',\n defer = true,\n children,\n}: FormEnhancerProps) {\n const ready = useDeferredActivation(defer)\n // Flipped only after the enhancement has actually committed to the DOM, so\n // the shell never disappears ahead of its replacement.\n const [enhanced, setEnhanced] = useState(false)\n\n return (\n <div\n data-sk-form-mount={enhanced ? 'enhanced' : 'shell'}\n data-sk-part=\"form-mount\"\n style={enter === 'fade' ? FADE_HOST : undefined}\n >\n {enter === 'fade' && <EnterStyles />}\n {ready ? (\n <Suspense fallback={children}>\n <Enhanced onMount={() => setEnhanced(true)} fallback={children}>\n <InteractiveForm\n formId={formId}\n initialConfig={initialConfig}\n className={className}\n nativeReturnTo={nativeReturnTo}\n experience={experience}\n defaultValues={defaultValues}\n onSuccess={onSuccess}\n onError={onError}\n />\n </Enhanced>\n </Suspense>\n ) : (\n children\n )}\n </div>\n )\n}\n\n/**\n * Reports the moment the enhancement is on screen, and keeps the shell\n * rendered if it throws. An error boundary is the difference between \"the\n * fancy version failed\" and \"there is no form on this page\".\n */\nclass Enhanced extends React.Component<\n { onMount: () => void; fallback: React.ReactNode; children: React.ReactNode },\n { failed: boolean }\n> {\n state = { failed: false }\n\n static getDerivedStateFromError() {\n return { failed: true }\n }\n\n componentDidCatch(err: unknown) {\n console.error('[Forms] Enhancement failed; keeping the native form:', err)\n }\n\n componentDidMount() {\n if (!this.state.failed) this.props.onMount()\n }\n\n render() {\n if (this.state.failed) return this.props.fallback\n return <FrameTag>{this.props.children}</FrameTag>\n }\n}\n\n/** Adds data-sk-enter for one frame so a CSS transition has something to run. */\nfunction FrameTag({ children }: { children: React.ReactNode }) {\n const ref = useRef<HTMLDivElement>(null)\n useEffect(() => {\n const el = ref.current\n if (!el) return\n el.setAttribute('data-sk-enter', '')\n const id = requestAnimationFrame(() => el.removeAttribute('data-sk-enter'))\n return () => cancelAnimationFrame(id)\n }, [])\n return (\n <div ref={ref} style={{ display: 'contents' }}>\n {children}\n </div>\n )\n}\n\nconst FADE_HOST: React.CSSProperties = {\n transition:\n 'opacity var(--sk-form-enter-duration, 320ms) var(--sk-form-enter-easing, cubic-bezier(.22,1,.36,1))',\n}\n\n/**\n * Scoped to [data-sk-part=\"form-mount\"] so it can never touch a site's own\n * markup. Emitted once per form; identical text dedupes in every browser's\n * style cache and gzips to nothing.\n */\nfunction EnterStyles() {\n return (\n <style\n // biome-ignore lint/security/noDangerouslySetInnerHtml: static string, no interpolation\n dangerouslySetInnerHTML={{\n __html: `\n[data-sk-part=\"form-mount\"][data-sk-form-mount=\"shell\"]{opacity:.55}\n[data-sk-part=\"form-mount\"][data-sk-form-mount=\"enhanced\"]{opacity:1}\n[data-sk-part=\"form-mount\"] [data-sk-enter]{opacity:0;transform:translateY(var(--sk-form-enter-distance,6px))}\n[data-sk-part=\"form-mount\"] [data-sk-enter] *{transition:none!important}\n@media (prefers-reduced-motion: reduce){\n[data-sk-part=\"form-mount\"]{transition:none!important}\n[data-sk-part=\"form-mount\"][data-sk-form-mount=\"shell\"]{opacity:1}\n[data-sk-part=\"form-mount\"] [data-sk-enter]{opacity:1;transform:none}\n}`,\n }}\n />\n )\n}\n"]}
1
+ {"version":3,"sources":["../src/forms/FormEnhancer.tsx"],"names":["lazy","useDeferredActivation","useState","jsxs","jsx","Suspense","React","useRef","useEffect"],"mappings":"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","file":"chunk-S5VL7AWW.js","sourcesContent":["'use client'\n\n/**\n * FormEnhancer — the only client code a managed form needs up front.\n *\n * Renders the server-rendered shell (<StaticForm>, passed as `children`) until\n * an idle/first-interaction gate fires, then lazy-imports the interactive form\n * and swaps it in. Everything expensive — validation, conditional logic,\n * spotlight/stage, celebration, momentum — lives behind that dynamic import,\n * so a page ships this boundary and nothing else in its initial chunk set.\n *\n * The shell is a REAL form the whole time (native action + signed token), so\n * the progression is:\n *\n * no JS at all -> shell, submits natively. Works.\n * JS, pre-idle -> shell, submits natively. Works.\n * JS, post-idle -> enhanced form, submits over JSON. Works, with delight.\n * chunk 404s -> shell stays. Works. (Never left blank.)\n *\n * That last line is the invariant to protect: the shell is only removed once\n * the enhancement has actually rendered. Do not \"hide the shell then load\" —\n * a CDN hiccup would leave a visitor staring at an empty box where the form\n * used to be.\n *\n * ── Entrance animation ──────────────────────────────────────────────────\n *\n * Above-the-fold forms upgrade while the visitor is looking at them, so the\n * swap must not pop. The wrapper carries `data-sk-form-mount=\"shell\"` and\n * flips to `\"enhanced\"`, and the enhanced form gets `data-sk-enter` for one\n * frame, so a site can style the transition entirely in CSS:\n *\n * [data-sk-form-mount] { transition: opacity .35s ease }\n * [data-sk-form-mount=\"shell\"] { opacity: .6 }\n *\n * Defaults ship as CSS variables rather than hard-coded values:\n *\n * --sk-form-enter-duration (default 320ms)\n * --sk-form-enter-easing (default cubic-bezier(.22,1,.36,1))\n * --sk-form-enter-distance (default 6px)\n *\n * `enter=\"none\"` opts out entirely; `enter=\"custom\"` emits the data\n * attributes but no site-kit styles, leaving the animation to the site.\n * Every default is collapsed by prefers-reduced-motion.\n */\n\nimport React, { lazy, Suspense, useEffect, useRef, useState } from 'react'\nimport { useDeferredActivation } from '../shared/defer'\nimport type { FormExperience, FormSubmission } from './types'\n\n/** The heavy half. Nothing else in this module may import it statically. */\nconst InteractiveForm = lazy(() =>\n import('./ManagedForm').then((m) => ({ default: m.ManagedForm })),\n)\n\nexport type FormEnterAnimation = 'fade' | 'none' | 'custom'\n\nexport interface FormEnhancerProps {\n formId: string\n /** Server-fetched raw config — hands the enhancement its fields instantly. */\n initialConfig?: Record<string, unknown> | null\n className?: string\n nativeReturnTo?: string\n experience?: FormExperience\n /** Pre-fill field values by slug. See ManagedForm.defaultValues. */\n defaultValues?: Record<string, unknown>\n onSuccess?: (submission: FormSubmission) => void\n onError?: (error: Error) => void\n /**\n * How the enhanced form arrives. 'fade' (default) crossfades and lifts it\n * into place; 'none' swaps instantly; 'custom' emits the data attributes\n * and no styles so the site owns the animation.\n */\n enter?: FormEnterAnimation\n /**\n * Set false to enhance immediately instead of waiting for idle. Only worth\n * it for a form that is the entire point of the page AND above the fold.\n */\n defer?: boolean\n /** The server-rendered <StaticForm>. Shown until the enhancement mounts. */\n children: React.ReactNode\n}\n\nexport function FormEnhancer({\n formId,\n initialConfig,\n className,\n nativeReturnTo,\n experience,\n defaultValues,\n onSuccess,\n onError,\n enter = 'fade',\n defer = true,\n children,\n}: FormEnhancerProps) {\n const ready = useDeferredActivation(defer)\n // Flipped only after the enhancement has actually committed to the DOM, so\n // the shell never disappears ahead of its replacement.\n const [enhanced, setEnhanced] = useState(false)\n\n return (\n <div\n data-sk-form-mount={enhanced ? 'enhanced' : 'shell'}\n data-sk-part=\"form-mount\"\n style={enter === 'fade' ? FADE_HOST : undefined}\n >\n {enter === 'fade' && <EnterStyles />}\n {ready ? (\n <Suspense fallback={children}>\n <Enhanced onMount={() => setEnhanced(true)} fallback={children}>\n <InteractiveForm\n formId={formId}\n initialConfig={initialConfig}\n className={className}\n nativeReturnTo={nativeReturnTo}\n experience={experience}\n defaultValues={defaultValues}\n onSuccess={onSuccess}\n onError={onError}\n />\n </Enhanced>\n </Suspense>\n ) : (\n children\n )}\n </div>\n )\n}\n\n/**\n * Reports the moment the enhancement is on screen, and keeps the shell\n * rendered if it throws. An error boundary is the difference between \"the\n * fancy version failed\" and \"there is no form on this page\".\n */\nclass Enhanced extends React.Component<\n { onMount: () => void; fallback: React.ReactNode; children: React.ReactNode },\n { failed: boolean }\n> {\n state = { failed: false }\n\n static getDerivedStateFromError() {\n return { failed: true }\n }\n\n componentDidCatch(err: unknown) {\n console.error('[Forms] Enhancement failed; keeping the native form:', err)\n }\n\n componentDidMount() {\n if (!this.state.failed) this.props.onMount()\n }\n\n render() {\n if (this.state.failed) return this.props.fallback\n return <FrameTag>{this.props.children}</FrameTag>\n }\n}\n\n/** Adds data-sk-enter for one frame so a CSS transition has something to run. */\nfunction FrameTag({ children }: { children: React.ReactNode }) {\n const ref = useRef<HTMLDivElement>(null)\n useEffect(() => {\n const el = ref.current\n if (!el) return\n el.setAttribute('data-sk-enter', '')\n const id = requestAnimationFrame(() => el.removeAttribute('data-sk-enter'))\n return () => cancelAnimationFrame(id)\n }, [])\n return (\n <div ref={ref} style={{ display: 'contents' }}>\n {children}\n </div>\n )\n}\n\nconst FADE_HOST: React.CSSProperties = {\n transition:\n 'opacity var(--sk-form-enter-duration, 320ms) var(--sk-form-enter-easing, cubic-bezier(.22,1,.36,1))',\n}\n\n/**\n * Scoped to [data-sk-part=\"form-mount\"] so it can never touch a site's own\n * markup. Emitted once per form; identical text dedupes in every browser's\n * style cache and gzips to nothing.\n */\nfunction EnterStyles() {\n return (\n <style\n // biome-ignore lint/security/noDangerouslySetInnerHtml: static string, no interpolation\n dangerouslySetInnerHTML={{\n __html: `\n[data-sk-part=\"form-mount\"][data-sk-form-mount=\"shell\"]{opacity:.55}\n[data-sk-part=\"form-mount\"][data-sk-form-mount=\"enhanced\"]{opacity:1}\n[data-sk-part=\"form-mount\"] [data-sk-enter]{opacity:0;transform:translateY(var(--sk-form-enter-distance,6px))}\n[data-sk-part=\"form-mount\"] [data-sk-enter] *{transition:none!important}\n@media (prefers-reduced-motion: reduce){\n[data-sk-part=\"form-mount\"]{transition:none!important}\n[data-sk-part=\"form-mount\"][data-sk-form-mount=\"shell\"]{opacity:1}\n[data-sk-part=\"form-mount\"] [data-sk-enter]{opacity:1;transform:none}\n}`,\n }}\n />\n )\n}\n"]}
@@ -13,6 +13,7 @@ var NEXT_APP_DIRS = ["app", path__default.default.join("src", "app")];
13
13
  var NEXT_SOURCE_EXTENSIONS = ["tsx", "ts", "jsx", "js"];
14
14
  var NEXT_PROXY_FILES = ["proxy.ts", "proxy.js", "src/proxy.ts", "src/proxy.js"];
15
15
  var NEXT_MIDDLEWARE_FILES = ["middleware.ts", "middleware.js", "src/middleware.ts", "src/middleware.js"];
16
+ var NEXT_CONFIG_FILES = ["next.config.js", "next.config.mjs", "next.config.ts", "next.config.mts"];
16
17
  function safeExists(p) {
17
18
  try {
18
19
  return fs2__default.default.existsSync(p);
@@ -37,6 +38,9 @@ function findRootLayout(cwd) {
37
38
  }
38
39
  return null;
39
40
  }
41
+ function findNextConfig(cwd) {
42
+ return NEXT_CONFIG_FILES.find((rel) => safeExists(path__default.default.join(cwd, rel))) ?? null;
43
+ }
40
44
  function findProxyFiles(cwd) {
41
45
  return [...NEXT_PROXY_FILES, ...NEXT_MIDDLEWARE_FILES].filter((rel) => safeExists(path__default.default.join(cwd, rel)));
42
46
  }
@@ -99,12 +103,14 @@ function discoverNextJsRoutes(appDir, basePath = "") {
99
103
  exports.NEXT_APP_DIRS = NEXT_APP_DIRS;
100
104
  exports.NEXT_MIDDLEWARE_FILES = NEXT_MIDDLEWARE_FILES;
101
105
  exports.NEXT_PROXY_FILES = NEXT_PROXY_FILES;
106
+ exports.NEXT_SOURCE_EXTENSIONS = NEXT_SOURCE_EXTENSIONS;
102
107
  exports.discoverNextJsRoutes = discoverNextJsRoutes;
103
108
  exports.findAppDirForDiscovery = findAppDirForDiscovery;
104
109
  exports.findConventionFile = findConventionFile;
110
+ exports.findNextConfig = findNextConfig;
105
111
  exports.findProxyFiles = findProxyFiles;
106
112
  exports.findRootLayout = findRootLayout;
107
113
  exports.findSitemapRoute = findSitemapRoute;
108
114
  exports.hasPageFile = hasPageFile;
109
- //# sourceMappingURL=chunk-P4TB4ROG.js.map
110
- //# sourceMappingURL=chunk-P4TB4ROG.js.map
115
+ //# sourceMappingURL=chunk-SEP5D4MI.js.map
116
+ //# sourceMappingURL=chunk-SEP5D4MI.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/shared/next-files.ts","../src/sitemap/discover.ts"],"names":["path","fs"],"mappings":"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","file":"chunk-SEP5D4MI.js","sourcesContent":["/**\n * @sonordev/site-kit — where a Next.js project keeps its convention files.\n *\n * SINGLE SOURCE OF TRUTH for \"find the root layout / a page / the proxy\". Each\n * CLI check used to carry its own candidate list, and the lists drifted: the OG\n * wiring rule only looked for `app/layout.tsx`, so `doctor` told a site whose\n * root layout is `app/layout.jsx` (heinrich-law-nextjs, 2026-09-14) that it had\n * no layout at all. `geo` knew about `.jsx` but not `src/app`, and none of them\n * knew about `proxy.ts`. Route every lookup through here; never re-fork a list.\n *\n * Node-only (fs/path): never import from browser or client code.\n */\n\nimport fs from 'fs'\nimport path from 'path'\n\n/** App-directory candidates, in Next's resolution order (`app/` wins over `src/app/`). */\nexport const NEXT_APP_DIRS = ['app', path.join('src', 'app')]\n\n/**\n * Extensions Next resolves for convention files (`layout`, `page`, `route`,\n * `opengraph-image`) under the default `pageExtensions`.\n */\nexport const NEXT_SOURCE_EXTENSIONS = ['tsx', 'ts', 'jsx', 'js']\n\n/**\n * Next 16 Proxy files. The proxy lives at the project root, or in `src/` when\n * the app directory does, beside `src/app`.\n */\nexport const NEXT_PROXY_FILES = ['proxy.ts', 'proxy.js', 'src/proxy.ts', 'src/proxy.js']\n\n/** The pre-16 name for the same file. Still builds; deprecated. */\nexport const NEXT_MIDDLEWARE_FILES = ['middleware.ts', 'middleware.js', 'src/middleware.ts', 'src/middleware.js']\n\n/**\n * next.config candidates in Next's own resolution order (`CONFIG_FILES` in\n * next/dist/shared/lib/constants). Next reads the first one present.\n */\nexport const NEXT_CONFIG_FILES = ['next.config.js', 'next.config.mjs', 'next.config.ts', 'next.config.mts']\n\nfunction safeExists(p: string): boolean {\n try {\n return fs.existsSync(p)\n } catch {\n return false\n }\n}\n\n/** `dir/<basename>.<ext>` for the first extension that exists, or null. */\nexport function findConventionFile(dir: string, basename: string): string | null {\n for (const ext of NEXT_SOURCE_EXTENSIONS) {\n const file = path.join(dir, `${basename}.${ext}`)\n if (safeExists(file)) return file\n }\n return null\n}\n\n/** True when `dir` holds a `page.{tsx,ts,jsx,js}`. */\nexport function hasPageFile(dir: string): boolean {\n return findConventionFile(dir, 'page') !== null\n}\n\n/** Absolute path of the root layout (`app/layout.*`, then `src/app/layout.*`), or null. */\nexport function findRootLayout(cwd: string): string | null {\n for (const rel of NEXT_APP_DIRS) {\n const found = findConventionFile(path.join(cwd, rel), 'layout')\n if (found) return found\n }\n return null\n}\n\n/** Project-relative path of the next.config Next will read, or null. */\nexport function findNextConfig(cwd: string): string | null {\n return NEXT_CONFIG_FILES.find(rel => safeExists(path.join(cwd, rel))) ?? null\n}\n\n/** Project-relative paths of every proxy and middleware file present, proxy first. */\nexport function findProxyFiles(cwd: string): string[] {\n return [...NEXT_PROXY_FILES, ...NEXT_MIDDLEWARE_FILES].filter(rel => safeExists(path.join(cwd, rel)))\n}\n","/**\n * @sonordev/site-kit — Node-only filesystem discovery for the sitemap CLI\n *\n * Single source of truth for the build-time filesystem scan used by\n * `registerLocalSitemap` (both the standalone CLI impl and the server routing\n * helper used to keep their own byte-drifting copies of `discoverNextJsRoutes`).\n *\n * Plus `findSitemapRoute` — the guard that makes `--auto-discover` safe to leave\n * in any site's `postbuild`.\n *\n * IMPORTANT — why a filesystem scan must never drive a `full-replace`:\n * a scan of `app/` can only see STATIC route segments. It structurally cannot\n * enumerate the params of a dynamic route (`/work/[slug]`, `/blog/[cat]/[id]`),\n * and it ignores the app's sitemap `exclude` config. So the route set it\n * produces is always a strict, incomplete SUBSET of the real page set. Feeding\n * that incomplete set to a `full-replace` sync tells the API to DELETE every\n * page that isn't in it — i.e. every dynamic page, plus anything the app\n * intentionally excluded. When a site also has an `app/sitemap.{ts,js}` (which\n * `createSitemap` syncs as an authoritative full-replace), the two syncs delete\n * and recreate each other's rows on every build (the sitemap-oscillation bug),\n * destroying managed metadata, Signal optimizations, LLM schemas, and GSC\n * history on real pages. Hence: auto-discover is additive by default, and skips\n * entirely when a sitemap route already exists.\n *\n * Node built-ins (`fs`/`path`) only — never import this from browser/client code.\n */\n\nimport fs from 'fs'\nimport path from 'path'\n// App-dir order and page extensions are shared with the OG/doctor/geo checks.\nimport { NEXT_APP_DIRS as APP_DIR_CANDIDATES, hasPageFile } from '../shared/next-files'\n\n/** Extensions a Next.js `sitemap` route file can use. */\nconst SITEMAP_ROUTE_EXTENSIONS = ['ts', 'tsx', 'js', 'jsx', 'mjs']\n\n/**\n * Return the app directory (absolute path) that exists under `cwd`, or null.\n * Prefers `app/`, then `src/app/`.\n */\nexport function findAppDirForDiscovery(cwd: string = process.cwd()): string | null {\n for (const candidate of APP_DIR_CANDIDATES) {\n const abs = path.join(cwd, candidate)\n if (fs.existsSync(abs)) return abs\n }\n return null\n}\n\n/**\n * Detect a Next.js `sitemap` route file (`app/sitemap.{ts,tsx,js,jsx,mjs}` or\n * `src/app/sitemap.*`). Returns the project-relative path if found, else null.\n *\n * Presence of this file means the framework already emits `/sitemap.xml` — the\n * authoritative page set — and site-kit's runtime `SitemapSync` syncs that real\n * sitemap (dynamic routes and all) additively. In that world an `--auto-discover`\n * filesystem scan is both inferior and dangerous (see the module header), so the\n * CLI skips.\n */\nexport function findSitemapRoute(cwd: string = process.cwd()): string | null {\n for (const dir of APP_DIR_CANDIDATES) {\n for (const ext of SITEMAP_ROUTE_EXTENSIONS) {\n const rel = path.join(dir, `sitemap.${ext}`)\n if (fs.existsSync(path.join(cwd, rel))) return rel\n }\n }\n return null\n}\n\n/**\n * Recursively discover STATIC Next.js routes from an app directory.\n *\n * Intentionally skips dynamic segments (`[slug]`) — they can't be enumerated\n * from disk — which is exactly why the result is incomplete and must only ever\n * drive an additive sync. Route groups `(marketing)` are folded out of the URL.\n */\nexport function discoverNextJsRoutes(\n appDir: string,\n basePath: string = '',\n): Array<{ path: string; priority: number }> {\n const entries: Array<{ path: string; priority: number }> = []\n\n const items = fs.readdirSync(appDir, { withFileTypes: true })\n\n for (const item of items) {\n if (item.name.startsWith('_') || item.name.startsWith('.')) continue\n if (item.name === 'api') continue\n if (item.name === 'node_modules') continue\n\n const itemPath = path.join(appDir, item.name)\n\n if (item.isDirectory()) {\n const hasPage = hasPageFile(itemPath)\n\n const isRouteGroup = item.name.startsWith('(') && item.name.endsWith(')')\n const isDynamic = item.name.startsWith('[') && item.name.endsWith(']')\n\n let routePath = basePath\n if (!isRouteGroup && !isDynamic) {\n routePath = `${basePath}/${item.name}`\n }\n\n if (hasPage && !isDynamic) {\n const priority = routePath === '' ? 1.0 : 0.8\n entries.push({ path: routePath || '/', priority })\n }\n\n if (!isDynamic) {\n const subEntries = discoverNextJsRoutes(\n itemPath,\n isRouteGroup ? basePath : routePath,\n )\n entries.push(...subEntries)\n }\n }\n }\n\n if (basePath === '') {\n if (hasPageFile(appDir)) {\n entries.unshift({ path: '/', priority: 1.0 })\n }\n }\n\n return entries\n}\n"]}
@@ -6,6 +6,7 @@ var NEXT_APP_DIRS = ["app", path.join("src", "app")];
6
6
  var NEXT_SOURCE_EXTENSIONS = ["tsx", "ts", "jsx", "js"];
7
7
  var NEXT_PROXY_FILES = ["proxy.ts", "proxy.js", "src/proxy.ts", "src/proxy.js"];
8
8
  var NEXT_MIDDLEWARE_FILES = ["middleware.ts", "middleware.js", "src/middleware.ts", "src/middleware.js"];
9
+ var NEXT_CONFIG_FILES = ["next.config.js", "next.config.mjs", "next.config.ts", "next.config.mts"];
9
10
  function safeExists(p) {
10
11
  try {
11
12
  return fs2.existsSync(p);
@@ -30,6 +31,9 @@ function findRootLayout(cwd) {
30
31
  }
31
32
  return null;
32
33
  }
34
+ function findNextConfig(cwd) {
35
+ return NEXT_CONFIG_FILES.find((rel) => safeExists(path.join(cwd, rel))) ?? null;
36
+ }
33
37
  function findProxyFiles(cwd) {
34
38
  return [...NEXT_PROXY_FILES, ...NEXT_MIDDLEWARE_FILES].filter((rel) => safeExists(path.join(cwd, rel)));
35
39
  }
@@ -89,6 +93,6 @@ function discoverNextJsRoutes(appDir, basePath = "") {
89
93
  return entries;
90
94
  }
91
95
 
92
- export { NEXT_APP_DIRS, NEXT_MIDDLEWARE_FILES, NEXT_PROXY_FILES, discoverNextJsRoutes, findAppDirForDiscovery, findConventionFile, findProxyFiles, findRootLayout, findSitemapRoute, hasPageFile };
93
- //# sourceMappingURL=chunk-L4V6TKMJ.mjs.map
94
- //# sourceMappingURL=chunk-L4V6TKMJ.mjs.map
96
+ export { NEXT_APP_DIRS, NEXT_MIDDLEWARE_FILES, NEXT_PROXY_FILES, NEXT_SOURCE_EXTENSIONS, discoverNextJsRoutes, findAppDirForDiscovery, findConventionFile, findNextConfig, findProxyFiles, findRootLayout, findSitemapRoute, hasPageFile };
97
+ //# sourceMappingURL=chunk-U2V542EO.mjs.map
98
+ //# sourceMappingURL=chunk-U2V542EO.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/shared/next-files.ts","../src/sitemap/discover.ts"],"names":["fs","path"],"mappings":"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","file":"chunk-U2V542EO.mjs","sourcesContent":["/**\n * @sonordev/site-kit — where a Next.js project keeps its convention files.\n *\n * SINGLE SOURCE OF TRUTH for \"find the root layout / a page / the proxy\". Each\n * CLI check used to carry its own candidate list, and the lists drifted: the OG\n * wiring rule only looked for `app/layout.tsx`, so `doctor` told a site whose\n * root layout is `app/layout.jsx` (heinrich-law-nextjs, 2026-09-14) that it had\n * no layout at all. `geo` knew about `.jsx` but not `src/app`, and none of them\n * knew about `proxy.ts`. Route every lookup through here; never re-fork a list.\n *\n * Node-only (fs/path): never import from browser or client code.\n */\n\nimport fs from 'fs'\nimport path from 'path'\n\n/** App-directory candidates, in Next's resolution order (`app/` wins over `src/app/`). */\nexport const NEXT_APP_DIRS = ['app', path.join('src', 'app')]\n\n/**\n * Extensions Next resolves for convention files (`layout`, `page`, `route`,\n * `opengraph-image`) under the default `pageExtensions`.\n */\nexport const NEXT_SOURCE_EXTENSIONS = ['tsx', 'ts', 'jsx', 'js']\n\n/**\n * Next 16 Proxy files. The proxy lives at the project root, or in `src/` when\n * the app directory does, beside `src/app`.\n */\nexport const NEXT_PROXY_FILES = ['proxy.ts', 'proxy.js', 'src/proxy.ts', 'src/proxy.js']\n\n/** The pre-16 name for the same file. Still builds; deprecated. */\nexport const NEXT_MIDDLEWARE_FILES = ['middleware.ts', 'middleware.js', 'src/middleware.ts', 'src/middleware.js']\n\n/**\n * next.config candidates in Next's own resolution order (`CONFIG_FILES` in\n * next/dist/shared/lib/constants). Next reads the first one present.\n */\nexport const NEXT_CONFIG_FILES = ['next.config.js', 'next.config.mjs', 'next.config.ts', 'next.config.mts']\n\nfunction safeExists(p: string): boolean {\n try {\n return fs.existsSync(p)\n } catch {\n return false\n }\n}\n\n/** `dir/<basename>.<ext>` for the first extension that exists, or null. */\nexport function findConventionFile(dir: string, basename: string): string | null {\n for (const ext of NEXT_SOURCE_EXTENSIONS) {\n const file = path.join(dir, `${basename}.${ext}`)\n if (safeExists(file)) return file\n }\n return null\n}\n\n/** True when `dir` holds a `page.{tsx,ts,jsx,js}`. */\nexport function hasPageFile(dir: string): boolean {\n return findConventionFile(dir, 'page') !== null\n}\n\n/** Absolute path of the root layout (`app/layout.*`, then `src/app/layout.*`), or null. */\nexport function findRootLayout(cwd: string): string | null {\n for (const rel of NEXT_APP_DIRS) {\n const found = findConventionFile(path.join(cwd, rel), 'layout')\n if (found) return found\n }\n return null\n}\n\n/** Project-relative path of the next.config Next will read, or null. */\nexport function findNextConfig(cwd: string): string | null {\n return NEXT_CONFIG_FILES.find(rel => safeExists(path.join(cwd, rel))) ?? null\n}\n\n/** Project-relative paths of every proxy and middleware file present, proxy first. */\nexport function findProxyFiles(cwd: string): string[] {\n return [...NEXT_PROXY_FILES, ...NEXT_MIDDLEWARE_FILES].filter(rel => safeExists(path.join(cwd, rel)))\n}\n","/**\n * @sonordev/site-kit — Node-only filesystem discovery for the sitemap CLI\n *\n * Single source of truth for the build-time filesystem scan used by\n * `registerLocalSitemap` (both the standalone CLI impl and the server routing\n * helper used to keep their own byte-drifting copies of `discoverNextJsRoutes`).\n *\n * Plus `findSitemapRoute` — the guard that makes `--auto-discover` safe to leave\n * in any site's `postbuild`.\n *\n * IMPORTANT — why a filesystem scan must never drive a `full-replace`:\n * a scan of `app/` can only see STATIC route segments. It structurally cannot\n * enumerate the params of a dynamic route (`/work/[slug]`, `/blog/[cat]/[id]`),\n * and it ignores the app's sitemap `exclude` config. So the route set it\n * produces is always a strict, incomplete SUBSET of the real page set. Feeding\n * that incomplete set to a `full-replace` sync tells the API to DELETE every\n * page that isn't in it — i.e. every dynamic page, plus anything the app\n * intentionally excluded. When a site also has an `app/sitemap.{ts,js}` (which\n * `createSitemap` syncs as an authoritative full-replace), the two syncs delete\n * and recreate each other's rows on every build (the sitemap-oscillation bug),\n * destroying managed metadata, Signal optimizations, LLM schemas, and GSC\n * history on real pages. Hence: auto-discover is additive by default, and skips\n * entirely when a sitemap route already exists.\n *\n * Node built-ins (`fs`/`path`) only — never import this from browser/client code.\n */\n\nimport fs from 'fs'\nimport path from 'path'\n// App-dir order and page extensions are shared with the OG/doctor/geo checks.\nimport { NEXT_APP_DIRS as APP_DIR_CANDIDATES, hasPageFile } from '../shared/next-files'\n\n/** Extensions a Next.js `sitemap` route file can use. */\nconst SITEMAP_ROUTE_EXTENSIONS = ['ts', 'tsx', 'js', 'jsx', 'mjs']\n\n/**\n * Return the app directory (absolute path) that exists under `cwd`, or null.\n * Prefers `app/`, then `src/app/`.\n */\nexport function findAppDirForDiscovery(cwd: string = process.cwd()): string | null {\n for (const candidate of APP_DIR_CANDIDATES) {\n const abs = path.join(cwd, candidate)\n if (fs.existsSync(abs)) return abs\n }\n return null\n}\n\n/**\n * Detect a Next.js `sitemap` route file (`app/sitemap.{ts,tsx,js,jsx,mjs}` or\n * `src/app/sitemap.*`). Returns the project-relative path if found, else null.\n *\n * Presence of this file means the framework already emits `/sitemap.xml` — the\n * authoritative page set — and site-kit's runtime `SitemapSync` syncs that real\n * sitemap (dynamic routes and all) additively. In that world an `--auto-discover`\n * filesystem scan is both inferior and dangerous (see the module header), so the\n * CLI skips.\n */\nexport function findSitemapRoute(cwd: string = process.cwd()): string | null {\n for (const dir of APP_DIR_CANDIDATES) {\n for (const ext of SITEMAP_ROUTE_EXTENSIONS) {\n const rel = path.join(dir, `sitemap.${ext}`)\n if (fs.existsSync(path.join(cwd, rel))) return rel\n }\n }\n return null\n}\n\n/**\n * Recursively discover STATIC Next.js routes from an app directory.\n *\n * Intentionally skips dynamic segments (`[slug]`) — they can't be enumerated\n * from disk — which is exactly why the result is incomplete and must only ever\n * drive an additive sync. Route groups `(marketing)` are folded out of the URL.\n */\nexport function discoverNextJsRoutes(\n appDir: string,\n basePath: string = '',\n): Array<{ path: string; priority: number }> {\n const entries: Array<{ path: string; priority: number }> = []\n\n const items = fs.readdirSync(appDir, { withFileTypes: true })\n\n for (const item of items) {\n if (item.name.startsWith('_') || item.name.startsWith('.')) continue\n if (item.name === 'api') continue\n if (item.name === 'node_modules') continue\n\n const itemPath = path.join(appDir, item.name)\n\n if (item.isDirectory()) {\n const hasPage = hasPageFile(itemPath)\n\n const isRouteGroup = item.name.startsWith('(') && item.name.endsWith(')')\n const isDynamic = item.name.startsWith('[') && item.name.endsWith(']')\n\n let routePath = basePath\n if (!isRouteGroup && !isDynamic) {\n routePath = `${basePath}/${item.name}`\n }\n\n if (hasPage && !isDynamic) {\n const priority = routePath === '' ? 1.0 : 0.8\n entries.push({ path: routePath || '/', priority })\n }\n\n if (!isDynamic) {\n const subEntries = discoverNextJsRoutes(\n itemPath,\n isRouteGroup ? basePath : routePath,\n )\n entries.push(...subEntries)\n }\n }\n }\n\n if (basePath === '') {\n if (hasPageFile(appDir)) {\n entries.unshift({ path: '/', priority: 1.0 })\n }\n }\n\n return entries\n}\n"]}
@@ -1,5 +1,5 @@
1
1
  import { DEFAULT_HONEYPOT_FIELD } from './chunk-TMVKRQGJ.mjs';
2
- import { sonorFetch } from './chunk-XLPU3TEE.mjs';
2
+ import { sonorFetch } from './chunk-X22BGNVL.mjs';
3
3
 
4
4
  // src/forms/defaultSuccessMessage.ts
5
5
  var DEFAULT_FORM_SUCCESS_MESSAGE = "Thank you for your submission! We will be in touch soon.";
@@ -215,5 +215,5 @@ async function submitForm({
215
215
  }
216
216
 
217
217
  export { DEFAULT_FORM_SUCCESS_MESSAGE, getApiConfig, normalizeFormConfig, submitForm };
218
- //# sourceMappingURL=chunk-HBN4A2N4.mjs.map
219
- //# sourceMappingURL=chunk-HBN4A2N4.mjs.map
218
+ //# sourceMappingURL=chunk-U6H5ZY3B.mjs.map
219
+ //# sourceMappingURL=chunk-U6H5ZY3B.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/forms/defaultSuccessMessage.ts","../src/forms/normalize-config.ts","../src/forms/recaptcha.ts","../src/forms/ga4-identity.ts","../src/forms/submitForm.ts"],"names":[],"mappings":"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","file":"chunk-HBN4A2N4.mjs","sourcesContent":["/** Shown when the API omits or returns an empty `success_message`. */\nexport const DEFAULT_FORM_SUCCESS_MESSAGE =\n 'Thank you for your submission! We will be in touch soon.'\n","/**\n * Shared form-config normalizer — the ONE place a raw\n * /api/public/forms/config payload becomes a ManagedFormConfig.\n *\n * Deliberately has no `'use client'` directive and no hooks, so it is usable\n * from a Server Component (StaticForm) as well as from useForm's client\n * fetch. Both the server shell and the hydrated enhancement must agree on\n * field order, step count and success copy or the swap visibly jumps, so\n * there must never be a second copy of this.\n */\n\nimport type { ManagedFormConfig } from './types'\nimport { DEFAULT_FORM_SUCCESS_MESSAGE } from './defaultSuccessMessage'\n\n/**\n * Normalize a raw /api/public/forms/config payload into ManagedFormConfig.\n * Single source of truth — used for both the client fetch and server-provided\n * `initialForm`, so the two paths can never drift.\n */\nexport function normalizeFormConfig(data: any): ManagedFormConfig {\n if (data.steps) {\n data.steps.sort((a: any, b: any) => (a.step_number || 0) - (b.step_number || 0))\n }\n if (data.fields) {\n data.fields.sort((a: any, b: any) => (a.sort_order || 0) - (b.sort_order || 0))\n }\n\n const total_steps = data.steps?.length || 1\n const is_multi_step = total_steps > 1\n\n const apiSuccess =\n typeof data.success_message === 'string' ? data.success_message.trim() : ''\n const success_message =\n apiSuccess ||\n (typeof (data as { successMessage?: string }).successMessage === 'string'\n ? String((data as { successMessage?: string }).successMessage).trim()\n : '') ||\n DEFAULT_FORM_SUCCESS_MESSAGE\n\n return {\n ...data,\n success_message,\n total_steps,\n is_multi_step,\n }\n}\n","/**\n * reCAPTCHA Enterprise - Client-side token generation for site-kit forms\n *\n * Site key is read from:\n * - window.__SITE_KIT_RECAPTCHA_SITE_KEY__ (set by SiteKitLayout)\n * - process.env.NEXT_PUBLIC_RECAPTCHA_SITE_KEY (when bundled in Next.js app)\n */\n\nfunction getSiteKey(explicitSiteKey?: string): string | undefined {\n if (typeof window === 'undefined') return undefined\n if (explicitSiteKey) return explicitSiteKey\n const win = window as any\n return win.__SITE_KIT_RECAPTCHA_SITE_KEY__ ?? process.env.NEXT_PUBLIC_RECAPTCHA_SITE_KEY\n}\n\n/** Max time to wait for reCAPTCHA Enterprise to become usable before giving up. */\nconst RECAPTCHA_LOAD_TIMEOUT_MS = 10000\n\nfunction loadScript(siteKey: string): Promise<any> {\n return new Promise((resolve) => {\n if (typeof window === 'undefined') {\n resolve(null)\n return\n }\n const win = window as any\n if (win.grecaptcha?.enterprise) {\n resolve(win.grecaptcha)\n return\n }\n\n // Never hang the form: if the script is blocked (ad-blocker), stalls, or\n // never initializes `grecaptcha.enterprise`, resolve null after a timeout.\n // The caller treats a null result as \"no token\" rather than waiting forever.\n let settled = false\n const finish = (value: any) => {\n if (settled) return\n settled = true\n resolve(value)\n }\n const giveUp = setTimeout(() => finish(null), RECAPTCHA_LOAD_TIMEOUT_MS)\n\n const waitForReady = () => {\n if (settled) return\n if (win.grecaptcha?.enterprise) {\n clearTimeout(giveUp)\n finish(win.grecaptcha)\n return\n }\n setTimeout(waitForReady, 50)\n }\n\n const existing = document.querySelector('script[src*=\"recaptcha/enterprise\"]')\n if (existing) {\n waitForReady()\n return\n }\n\n const script = document.createElement('script')\n script.src = `https://www.google.com/recaptcha/enterprise.js?render=${siteKey}`\n script.async = true\n script.onload = () => waitForReady()\n script.onerror = () => {\n clearTimeout(giveUp)\n finish(null)\n }\n document.head.appendChild(script)\n })\n}\n\n/**\n * Get a reCAPTCHA Enterprise token for form submission.\n * Returns null if not configured or in SSR.\n */\nexport async function getRecaptchaToken(explicitSiteKey?: string): Promise<string | null> {\n const siteKey = getSiteKey(explicitSiteKey)\n if (!siteKey || typeof window === 'undefined') return null\n try {\n const grecaptcha = await loadScript(siteKey)\n if (!grecaptcha?.enterprise?.execute) return null\n // loadScript only waits for grecaptcha.enterprise to EXIST — execute()\n // before enterprise.ready() rejects while the widget initializes (cold\n // page load = every first-visit submitter). A swallowed rejection here\n // means no token, and a requireRecaptcha project hard-rejects the lead.\n await new Promise<void>((resolve) => grecaptcha.enterprise.ready(resolve))\n const token = await grecaptcha.enterprise.execute(siteKey, { action: 'submit' })\n return token || null\n } catch (err) {\n // One retry after a beat — first-execute flakes persist on slow devices\n // even post-ready, and a dropped token is a dropped lead.\n try {\n await new Promise((resolve) => setTimeout(resolve, 800))\n const win = window as any\n const token = await win.grecaptcha.enterprise.execute(siteKey, { action: 'submit' })\n return token || null\n } catch (retryErr) {\n console.warn('[site-kit reCAPTCHA]', retryErr)\n return null\n }\n }\n}\n","/**\n * Reads the visitor's GA4 identity out of their own first-party cookies so a\n * lead conversion can be reported SERVER-side.\n *\n * Why the server has to do the reporting: Sonor's form-submit endpoint answers\n * with a byte-identical success payload whether it accepted a submission or\n * quarantined it as spam (deliberately — a bot must never learn it was\n * caught). So the browser cannot tell a real lead from a filtered one, and a\n * site firing its own ad conversion bills both. The accept/reject verdict only\n * exists on the server, so the conversion has to be sent from there — and to\n * send it, the server needs the GA4 identity that only the browser can see.\n *\n * Nothing here is a new identifier: these are cookies Google's own tag already\n * set on this visitor. We read them, we never write them.\n */\n\nexport interface Ga4Identity {\n /** GA4 client id, from `_ga`. Without it a server-sent event has no identity. */\n gaClientId?: string\n /**\n * GA4 session ids keyed by container id (the measurement id minus `G-`), from\n * the `_ga_<CONTAINER>` cookies.\n *\n * A map rather than one value because a page may carry more than one GA4\n * property, and picking the wrong one would silently attach the lead to the\n * wrong session — the sender knows which measurement id it is configured for,\n * this side does not.\n */\n gaSessions?: Record<string, string>\n}\n\nfunction readCookie(jar: string, name: string): string | undefined {\n const escaped = name.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')\n const match = jar.match(new RegExp(`(?:^|;\\\\s*)${escaped}=([^;]*)`))\n return match ? decodeURIComponent(match[1]) : undefined\n}\n\nexport function readGa4Identity(): Ga4Identity {\n if (typeof document === 'undefined') return {}\n const jar = document.cookie || ''\n if (!jar) return {}\n\n const identity: Ga4Identity = {}\n\n // `_ga` is `GA1.<depth>.<id1>.<id2>`; the client id is the last two parts\n // joined. Reading the raw cookie rather than the trailing two segments\n // blindly keeps it correct when the depth prefix varies by domain scope.\n const ga = readCookie(jar, '_ga')\n if (ga) {\n const parts = ga.split('.')\n if (parts.length >= 4) {\n const clientId = `${parts[parts.length - 2]}.${parts[parts.length - 1]}`\n if (/^\\d+\\.\\d+$/.test(clientId)) identity.gaClientId = clientId\n }\n }\n\n // `_ga_<CONTAINER>` is `GS<v>.<depth>.<session_id>.<session_number>....`\n const sessions: Record<string, string> = {}\n for (const raw of jar.split(';')) {\n const cookie = raw.trim()\n const eq = cookie.indexOf('=')\n if (eq < 0) continue\n const name = cookie.slice(0, eq)\n const container = /^_ga_([A-Z0-9]+)$/i.exec(name)?.[1]\n if (!container) continue\n const parts = decodeURIComponent(cookie.slice(eq + 1)).split('.')\n if (parts.length >= 3 && /^\\d+$/.test(parts[2])) sessions[container] = parts[2]\n }\n if (Object.keys(sessions).length > 0) identity.gaSessions = sessions\n\n return identity\n}\n","/**\n * @sonordev/site-kit/forms - Shared submission logic\n *\n * Single source of truth for sending a managed form to the Sonor API. Both\n * <ManagedForm> (via FormClient) and the headless useForm() hook submit through\n * here, so the request shape, retry behaviour, reCAPTCHA handling, and error\n * parsing can never drift between the two paths.\n */\n\nimport { sonorFetch } from '../shared/sonorFetch'\nimport { getRecaptchaToken } from './recaptcha'\nimport { DEFAULT_HONEYPOT_FIELD } from './contract'\nimport { readGa4Identity } from './ga4-identity'\nimport type { ManagedFormConfig } from './types'\n\n// The honeypot trap-field name lives once in the shared forms contract\n// (single source of truth for site-kit's client + sonor-api's intake).\n// Re-exported so existing importers of this path keep resolving it.\nexport { DEFAULT_HONEYPOT_FIELD }\n\nexport function getApiConfig(): { apiUrl: string; apiKey: string | undefined } {\n // Server branch must honor the same env override SiteKitLayout feeds into\n // __SITE_KIT_API_URL__, or SSR-rendered absolute URLs (the native form\n // action) would point at prod from a staging site.\n const apiUrl =\n typeof window !== 'undefined'\n ? (window as any).__SITE_KIT_API_URL__ || 'https://api.sonor.io'\n : process.env.SONOR_API_URL || process.env.NEXT_PUBLIC_SONOR_API_URL || 'https://api.sonor.io'\n const apiKey =\n typeof window !== 'undefined' ? (window as any).__SITE_KIT_API_KEY__ : undefined\n return { apiUrl, apiKey }\n}\n\nfunction getUTMParams(): Record<string, string | null> {\n if (typeof window === 'undefined') return {}\n const params = new URLSearchParams(window.location.search)\n const out: Record<string, string | null> = {}\n for (const key of ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content']) {\n out[key] = params.get(key)\n }\n return out\n}\n\nexport interface SubmitFormArgs {\n config: ManagedFormConfig\n /**\n * Field values to submit. The caller must pass VISIBLE values only —\n * conditionally-hidden fields should be excluded so stale values are not sent.\n */\n values: Record<string, unknown>\n /** Honeypot input value (empty string for the headless hook, which has no honeypot UI). */\n honeypotValue: string\n /** Timestamp (ms) the form was first rendered — a weak anti-bot timing signal. */\n formLoadedAt: number\n}\n\n/**\n * Submit a managed form. Throws on failure (network, timeout, or a non-2xx\n * response) with a human-readable message; resolves with the parsed API\n * response on success.\n */\nexport async function submitForm({\n config,\n values,\n honeypotValue,\n formLoadedAt,\n}: SubmitFormArgs): Promise<unknown> {\n const { apiUrl, apiKey } = getApiConfig()\n if (!apiKey) {\n throw new Error('API key is required. Set SONOR_API_KEY in your environment.')\n }\n\n // reCAPTCHA token is fetched right before the POST so it cannot expire.\n const recaptchaToken = config.recaptcha_enabled\n ? await getRecaptchaToken(config.recaptcha_site_key)\n : null\n if (config.recaptcha_enabled && !recaptchaToken) {\n throw new Error('Verification could not be completed. Please try again.')\n }\n\n const honeypotFieldName = config.honeypot_field || DEFAULT_HONEYPOT_FIELD\n const utm = getUTMParams()\n // The visitor's existing GA4 cookies, so Sonor can report an accepted lead\n // as a conversion server-side. Nothing is written or created here — see\n // ga4-identity.ts for why the server, not this browser, has to do it.\n const ga4 = readGa4Identity()\n\n const payload = {\n formId: config.id,\n form_id: config.id,\n data: {\n ...values,\n ...(config.honeypot_enabled ? { [honeypotFieldName]: honeypotValue } : {}),\n },\n metadata: {\n pageUrl: typeof window !== 'undefined' ? window.location.href : null,\n referrer: typeof document !== 'undefined' ? document.referrer || null : null,\n userAgent: typeof navigator !== 'undefined' ? navigator.userAgent : null,\n sessionId:\n typeof sessionStorage !== 'undefined' ? sessionStorage.getItem('_sk_sid') : null,\n // Anonymous visitor id (_sk_vid) — the same id Analytics/Signal stamp on\n // page views, so the Sonor side can bind this lead to its browsing session\n // (page -> lead attribution). Sent on every submission; null pre-hydration.\n visitorId:\n typeof localStorage !== 'undefined' ? localStorage.getItem('_sk_vid') : null,\n recaptchaToken: recaptchaToken || undefined,\n utmSource: utm.utm_source,\n utmMedium: utm.utm_medium,\n utmCampaign: utm.utm_campaign,\n utmTerm: utm.utm_term,\n utmContent: utm.utm_content,\n ...ga4,\n // Sub-site host — preserved on form_submissions for lead attribution\n // across multi-site projects. Resolved by SiteKitClientProviders.\n site:\n typeof window !== 'undefined'\n ? (window as { __SITE_KIT_SITE__?: string }).__SITE_KIT_SITE__ ||\n window.location.host\n : undefined,\n _formLoadedAt: formLoadedAt,\n },\n }\n\n const response = await sonorFetch(\n `${apiUrl}/api/public/forms/submit`,\n {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${apiKey}`,\n },\n body: JSON.stringify(payload),\n },\n { retries: 2, timeoutMs: 20000 },\n )\n\n const data = await response.json().catch(() => null)\n\n if (!response.ok) {\n const msg = (\n data?.message ??\n data?.error ??\n (response.statusText || `HTTP ${response.status}`)\n )\n .toString()\n .trim()\n throw new Error(\n msg ? `Failed to submit form: ${msg}` : `Failed to submit form (${response.status})`,\n )\n }\n\n return data\n}\n"]}
1
+ {"version":3,"sources":["../src/forms/defaultSuccessMessage.ts","../src/forms/normalize-config.ts","../src/forms/recaptcha.ts","../src/forms/ga4-identity.ts","../src/forms/submitForm.ts"],"names":[],"mappings":"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","file":"chunk-U6H5ZY3B.mjs","sourcesContent":["/** Shown when the API omits or returns an empty `success_message`. */\nexport const DEFAULT_FORM_SUCCESS_MESSAGE =\n 'Thank you for your submission! We will be in touch soon.'\n","/**\n * Shared form-config normalizer — the ONE place a raw\n * /api/public/forms/config payload becomes a ManagedFormConfig.\n *\n * Deliberately has no `'use client'` directive and no hooks, so it is usable\n * from a Server Component (StaticForm) as well as from useForm's client\n * fetch. Both the server shell and the hydrated enhancement must agree on\n * field order, step count and success copy or the swap visibly jumps, so\n * there must never be a second copy of this.\n */\n\nimport type { ManagedFormConfig } from './types'\nimport { DEFAULT_FORM_SUCCESS_MESSAGE } from './defaultSuccessMessage'\n\n/**\n * Normalize a raw /api/public/forms/config payload into ManagedFormConfig.\n * Single source of truth — used for both the client fetch and server-provided\n * `initialForm`, so the two paths can never drift.\n */\nexport function normalizeFormConfig(data: any): ManagedFormConfig {\n if (data.steps) {\n data.steps.sort((a: any, b: any) => (a.step_number || 0) - (b.step_number || 0))\n }\n if (data.fields) {\n data.fields.sort((a: any, b: any) => (a.sort_order || 0) - (b.sort_order || 0))\n }\n\n const total_steps = data.steps?.length || 1\n const is_multi_step = total_steps > 1\n\n const apiSuccess =\n typeof data.success_message === 'string' ? data.success_message.trim() : ''\n const success_message =\n apiSuccess ||\n (typeof (data as { successMessage?: string }).successMessage === 'string'\n ? String((data as { successMessage?: string }).successMessage).trim()\n : '') ||\n DEFAULT_FORM_SUCCESS_MESSAGE\n\n return {\n ...data,\n success_message,\n total_steps,\n is_multi_step,\n }\n}\n","/**\n * reCAPTCHA Enterprise - Client-side token generation for site-kit forms\n *\n * Site key is read from:\n * - window.__SITE_KIT_RECAPTCHA_SITE_KEY__ (set by SiteKitLayout)\n * - process.env.NEXT_PUBLIC_RECAPTCHA_SITE_KEY (when bundled in Next.js app)\n */\n\nfunction getSiteKey(explicitSiteKey?: string): string | undefined {\n if (typeof window === 'undefined') return undefined\n if (explicitSiteKey) return explicitSiteKey\n const win = window as any\n return win.__SITE_KIT_RECAPTCHA_SITE_KEY__ ?? process.env.NEXT_PUBLIC_RECAPTCHA_SITE_KEY\n}\n\n/** Max time to wait for reCAPTCHA Enterprise to become usable before giving up. */\nconst RECAPTCHA_LOAD_TIMEOUT_MS = 10000\n\nfunction loadScript(siteKey: string): Promise<any> {\n return new Promise((resolve) => {\n if (typeof window === 'undefined') {\n resolve(null)\n return\n }\n const win = window as any\n if (win.grecaptcha?.enterprise) {\n resolve(win.grecaptcha)\n return\n }\n\n // Never hang the form: if the script is blocked (ad-blocker), stalls, or\n // never initializes `grecaptcha.enterprise`, resolve null after a timeout.\n // The caller treats a null result as \"no token\" rather than waiting forever.\n let settled = false\n const finish = (value: any) => {\n if (settled) return\n settled = true\n resolve(value)\n }\n const giveUp = setTimeout(() => finish(null), RECAPTCHA_LOAD_TIMEOUT_MS)\n\n const waitForReady = () => {\n if (settled) return\n if (win.grecaptcha?.enterprise) {\n clearTimeout(giveUp)\n finish(win.grecaptcha)\n return\n }\n setTimeout(waitForReady, 50)\n }\n\n const existing = document.querySelector('script[src*=\"recaptcha/enterprise\"]')\n if (existing) {\n waitForReady()\n return\n }\n\n const script = document.createElement('script')\n script.src = `https://www.google.com/recaptcha/enterprise.js?render=${siteKey}`\n script.async = true\n script.onload = () => waitForReady()\n script.onerror = () => {\n clearTimeout(giveUp)\n finish(null)\n }\n document.head.appendChild(script)\n })\n}\n\n/**\n * Get a reCAPTCHA Enterprise token for form submission.\n * Returns null if not configured or in SSR.\n */\nexport async function getRecaptchaToken(explicitSiteKey?: string): Promise<string | null> {\n const siteKey = getSiteKey(explicitSiteKey)\n if (!siteKey || typeof window === 'undefined') return null\n try {\n const grecaptcha = await loadScript(siteKey)\n if (!grecaptcha?.enterprise?.execute) return null\n // loadScript only waits for grecaptcha.enterprise to EXIST — execute()\n // before enterprise.ready() rejects while the widget initializes (cold\n // page load = every first-visit submitter). A swallowed rejection here\n // means no token, and a requireRecaptcha project hard-rejects the lead.\n await new Promise<void>((resolve) => grecaptcha.enterprise.ready(resolve))\n const token = await grecaptcha.enterprise.execute(siteKey, { action: 'submit' })\n return token || null\n } catch (err) {\n // One retry after a beat — first-execute flakes persist on slow devices\n // even post-ready, and a dropped token is a dropped lead.\n try {\n await new Promise((resolve) => setTimeout(resolve, 800))\n const win = window as any\n const token = await win.grecaptcha.enterprise.execute(siteKey, { action: 'submit' })\n return token || null\n } catch (retryErr) {\n console.warn('[site-kit reCAPTCHA]', retryErr)\n return null\n }\n }\n}\n","/**\n * Reads the visitor's GA4 identity out of their own first-party cookies so a\n * lead conversion can be reported SERVER-side.\n *\n * Why the server has to do the reporting: Sonor's form-submit endpoint answers\n * with a byte-identical success payload whether it accepted a submission or\n * quarantined it as spam (deliberately — a bot must never learn it was\n * caught). So the browser cannot tell a real lead from a filtered one, and a\n * site firing its own ad conversion bills both. The accept/reject verdict only\n * exists on the server, so the conversion has to be sent from there — and to\n * send it, the server needs the GA4 identity that only the browser can see.\n *\n * Nothing here is a new identifier: these are cookies Google's own tag already\n * set on this visitor. We read them, we never write them.\n */\n\nexport interface Ga4Identity {\n /** GA4 client id, from `_ga`. Without it a server-sent event has no identity. */\n gaClientId?: string\n /**\n * GA4 session ids keyed by container id (the measurement id minus `G-`), from\n * the `_ga_<CONTAINER>` cookies.\n *\n * A map rather than one value because a page may carry more than one GA4\n * property, and picking the wrong one would silently attach the lead to the\n * wrong session — the sender knows which measurement id it is configured for,\n * this side does not.\n */\n gaSessions?: Record<string, string>\n}\n\nfunction readCookie(jar: string, name: string): string | undefined {\n const escaped = name.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')\n const match = jar.match(new RegExp(`(?:^|;\\\\s*)${escaped}=([^;]*)`))\n return match ? decodeURIComponent(match[1]) : undefined\n}\n\nexport function readGa4Identity(): Ga4Identity {\n if (typeof document === 'undefined') return {}\n const jar = document.cookie || ''\n if (!jar) return {}\n\n const identity: Ga4Identity = {}\n\n // `_ga` is `GA1.<depth>.<id1>.<id2>`; the client id is the last two parts\n // joined. Reading the raw cookie rather than the trailing two segments\n // blindly keeps it correct when the depth prefix varies by domain scope.\n const ga = readCookie(jar, '_ga')\n if (ga) {\n const parts = ga.split('.')\n if (parts.length >= 4) {\n const clientId = `${parts[parts.length - 2]}.${parts[parts.length - 1]}`\n if (/^\\d+\\.\\d+$/.test(clientId)) identity.gaClientId = clientId\n }\n }\n\n // `_ga_<CONTAINER>` is `GS<v>.<depth>.<session_id>.<session_number>....`\n const sessions: Record<string, string> = {}\n for (const raw of jar.split(';')) {\n const cookie = raw.trim()\n const eq = cookie.indexOf('=')\n if (eq < 0) continue\n const name = cookie.slice(0, eq)\n const container = /^_ga_([A-Z0-9]+)$/i.exec(name)?.[1]\n if (!container) continue\n const parts = decodeURIComponent(cookie.slice(eq + 1)).split('.')\n if (parts.length >= 3 && /^\\d+$/.test(parts[2])) sessions[container] = parts[2]\n }\n if (Object.keys(sessions).length > 0) identity.gaSessions = sessions\n\n return identity\n}\n","/**\n * @sonordev/site-kit/forms - Shared submission logic\n *\n * Single source of truth for sending a managed form to the Sonor API. Both\n * <ManagedForm> (via FormClient) and the headless useForm() hook submit through\n * here, so the request shape, retry behaviour, reCAPTCHA handling, and error\n * parsing can never drift between the two paths.\n */\n\nimport { sonorFetch } from '../shared/sonorFetch'\nimport { getRecaptchaToken } from './recaptcha'\nimport { DEFAULT_HONEYPOT_FIELD } from './contract'\nimport { readGa4Identity } from './ga4-identity'\nimport type { ManagedFormConfig } from './types'\n\n// The honeypot trap-field name lives once in the shared forms contract\n// (single source of truth for site-kit's client + sonor-api's intake).\n// Re-exported so existing importers of this path keep resolving it.\nexport { DEFAULT_HONEYPOT_FIELD }\n\nexport function getApiConfig(): { apiUrl: string; apiKey: string | undefined } {\n // Server branch must honor the same env override SiteKitLayout feeds into\n // __SITE_KIT_API_URL__, or SSR-rendered absolute URLs (the native form\n // action) would point at prod from a staging site.\n const apiUrl =\n typeof window !== 'undefined'\n ? (window as any).__SITE_KIT_API_URL__ || 'https://api.sonor.io'\n : process.env.SONOR_API_URL || process.env.NEXT_PUBLIC_SONOR_API_URL || 'https://api.sonor.io'\n const apiKey =\n typeof window !== 'undefined' ? (window as any).__SITE_KIT_API_KEY__ : undefined\n return { apiUrl, apiKey }\n}\n\nfunction getUTMParams(): Record<string, string | null> {\n if (typeof window === 'undefined') return {}\n const params = new URLSearchParams(window.location.search)\n const out: Record<string, string | null> = {}\n for (const key of ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content']) {\n out[key] = params.get(key)\n }\n return out\n}\n\nexport interface SubmitFormArgs {\n config: ManagedFormConfig\n /**\n * Field values to submit. The caller must pass VISIBLE values only —\n * conditionally-hidden fields should be excluded so stale values are not sent.\n */\n values: Record<string, unknown>\n /** Honeypot input value (empty string for the headless hook, which has no honeypot UI). */\n honeypotValue: string\n /** Timestamp (ms) the form was first rendered — a weak anti-bot timing signal. */\n formLoadedAt: number\n}\n\n/**\n * Submit a managed form. Throws on failure (network, timeout, or a non-2xx\n * response) with a human-readable message; resolves with the parsed API\n * response on success.\n */\nexport async function submitForm({\n config,\n values,\n honeypotValue,\n formLoadedAt,\n}: SubmitFormArgs): Promise<unknown> {\n const { apiUrl, apiKey } = getApiConfig()\n if (!apiKey) {\n throw new Error('API key is required. Set SONOR_API_KEY in your environment.')\n }\n\n // reCAPTCHA token is fetched right before the POST so it cannot expire.\n const recaptchaToken = config.recaptcha_enabled\n ? await getRecaptchaToken(config.recaptcha_site_key)\n : null\n if (config.recaptcha_enabled && !recaptchaToken) {\n throw new Error('Verification could not be completed. Please try again.')\n }\n\n const honeypotFieldName = config.honeypot_field || DEFAULT_HONEYPOT_FIELD\n const utm = getUTMParams()\n // The visitor's existing GA4 cookies, so Sonor can report an accepted lead\n // as a conversion server-side. Nothing is written or created here — see\n // ga4-identity.ts for why the server, not this browser, has to do it.\n const ga4 = readGa4Identity()\n\n const payload = {\n formId: config.id,\n form_id: config.id,\n data: {\n ...values,\n ...(config.honeypot_enabled ? { [honeypotFieldName]: honeypotValue } : {}),\n },\n metadata: {\n pageUrl: typeof window !== 'undefined' ? window.location.href : null,\n referrer: typeof document !== 'undefined' ? document.referrer || null : null,\n userAgent: typeof navigator !== 'undefined' ? navigator.userAgent : null,\n sessionId:\n typeof sessionStorage !== 'undefined' ? sessionStorage.getItem('_sk_sid') : null,\n // Anonymous visitor id (_sk_vid) — the same id Analytics/Signal stamp on\n // page views, so the Sonor side can bind this lead to its browsing session\n // (page -> lead attribution). Sent on every submission; null pre-hydration.\n visitorId:\n typeof localStorage !== 'undefined' ? localStorage.getItem('_sk_vid') : null,\n recaptchaToken: recaptchaToken || undefined,\n utmSource: utm.utm_source,\n utmMedium: utm.utm_medium,\n utmCampaign: utm.utm_campaign,\n utmTerm: utm.utm_term,\n utmContent: utm.utm_content,\n ...ga4,\n // Sub-site host — preserved on form_submissions for lead attribution\n // across multi-site projects. Resolved by SiteKitClientProviders.\n site:\n typeof window !== 'undefined'\n ? (window as { __SITE_KIT_SITE__?: string }).__SITE_KIT_SITE__ ||\n window.location.host\n : undefined,\n _formLoadedAt: formLoadedAt,\n },\n }\n\n const response = await sonorFetch(\n `${apiUrl}/api/public/forms/submit`,\n {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${apiKey}`,\n },\n body: JSON.stringify(payload),\n },\n { retries: 2, timeoutMs: 20000 },\n )\n\n const data = await response.json().catch(() => null)\n\n if (!response.ok) {\n const msg = (\n data?.message ??\n data?.error ??\n (response.statusText || `HTTP ${response.status}`)\n )\n .toString()\n .trim()\n throw new Error(\n msg ? `Failed to submit form: ${msg}` : `Failed to submit form (${response.status})`,\n )\n }\n\n return data\n}\n"]}
@@ -226,7 +226,7 @@ function normalizeOptions(options) {
226
226
  }
227
227
  return [];
228
228
  }
229
- function FormField({ field, value, error, onChange, classPrefix = "sk-form", showValid, controls }) {
229
+ function FormField({ field, value, error, onChange, onFocus, onBlur, classPrefix = "sk-form", showValid, controls }) {
230
230
  const interactive = typeof onChange === "function";
231
231
  const emit = (v) => onChange?.(v);
232
232
  const bind = (v) => interactive ? { value: v, onChange: (e) => emit(e.target.value) } : { defaultValue: v || void 0 };
@@ -279,7 +279,15 @@ function FormField({ field, value, error, onChange, classPrefix = "sk-form", sho
279
279
  }
280
280
  const hideLabel = !!field.hide_label;
281
281
  const effectivePlaceholder = hideLabel ? field.label : field.placeholder;
282
- return /* @__PURE__ */ jsxs("div", { className: `${classPrefix}__field ${classPrefix}__field--${field.field_type}`, children: [
282
+ const focusProps = interactive && (onFocus || onBlur) ? {
283
+ onFocus: (e) => {
284
+ if (!e.currentTarget.contains(e.relatedTarget)) onFocus?.();
285
+ },
286
+ onBlur: (e) => {
287
+ if (!e.currentTarget.contains(e.relatedTarget)) onBlur?.();
288
+ }
289
+ } : {};
290
+ return /* @__PURE__ */ jsxs("div", { className: `${classPrefix}__field ${classPrefix}__field--${field.field_type}`, ...focusProps, children: [
283
291
  /* @__PURE__ */ jsxs("label", { htmlFor: inputId, className: `${classPrefix}__label`, style: { ...labelStyle, ...hideLabel ? { position: "absolute", width: 1, height: 1, padding: 0, margin: -1, overflow: "hidden", clip: "rect(0,0,0,0)", whiteSpace: "nowrap", border: 0 } : {} }, children: [
284
292
  field.label,
285
293
  field.is_required && /* @__PURE__ */ jsx("span", { style: { color: "var(--sk-error, #dc2626)" }, children: " *" })
@@ -525,5 +533,5 @@ function FormField({ field, value, error, onChange, classPrefix = "sk-form", sho
525
533
  }
526
534
 
527
535
  export { DelightStyles, FormField, FormMomentum };
528
- //# sourceMappingURL=chunk-H7274TKR.mjs.map
529
- //# sourceMappingURL=chunk-H7274TKR.mjs.map
536
+ //# sourceMappingURL=chunk-VJV7WUR2.mjs.map
537
+ //# sourceMappingURL=chunk-VJV7WUR2.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/forms/delight.tsx","../src/forms/FormField.tsx"],"names":["jsx","jsxs"],"mappings":"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","file":"chunk-VJV7WUR2.mjs","sourcesContent":["'use client'\n\n/**\n * Form delight primitives — the interaction layer that makes filling a form\n * feel like progress instead of paperwork. Forms capture the lead; this is\n * conversion surface, not decoration.\n *\n * The bar: AAA-game onboarding. Nothing on screen is inert — the focused\n * field is lit, completing a field LOCKS IN, progress reads like a meter you\n * want to fill, and when the last requirement clears the submit button wakes\n * up. The arc: aura -> lock-in tick -> bar surges -> READY -> press start ->\n * celebration.\n *\n * - FieldValidTick: a check that draws itself the moment a field becomes\n * valid (touched + non-empty + no error), with a ripple ring. The field\n * wrap also flashes a one-shot lock-in ring via [data-sk-valid].\n * - FormMomentum: a fields-completed meter (not steps) — endowed progress;\n * people finish bars they've started. Live sheen, advance flash, leading-\n * edge spark, \"N of M\" label that flips to READY and charges the bar.\n * - [data-sk-ready] (set by FormClient when every required field validates\n * on the final step) wakes the submit button: pop, then breathing glow.\n *\n * Same construction rules as FormCelebration: zero deps, one deduped style\n * tag, data-sk-part on everything, --sk-primary theming, reduced-motion\n * collapses animation to instant states.\n *\n * Contrast guarantee: forms routinely live in sections painted with the\n * brand color itself, where pure --sk-primary chrome is invisible (found\n * live: fill rgb(173,29,37) on section rgb(173,29,37)). Everything here\n * mixes toward currentColor — the section's text color must contrast with\n * the section background, so the mix guarantees the chrome does too.\n */\n\nimport React from 'react'\n\nconst STYLE_ID = 'sk-delight-css'\n\nconst CSS = `\n/* Every frame must carry the centering translateY: the animation fills both\n directions, so a keyframe transform of scale() alone REPLACES the rule's\n translateY(-50%) and drops the tick half its height below center. */\n@keyframes sk-tick-in {\n 0% { transform: translateY(-50%) scale(.3); opacity: 0 }\n 70% { transform: translateY(-50%) scale(1.15) }\n 100% { transform: translateY(-50%) scale(1); opacity: 1 }\n}\n@keyframes sk-tick-draw { to { stroke-dashoffset: 0 } }\n@keyframes sk-tick-ring { 0% { transform: scale(.5); opacity: .7 } 100% { transform: scale(2.2); opacity: 0 } }\n@keyframes sk-lock-in { 0% { opacity: .85; transform: scale(.985) } 100% { opacity: 0; transform: scale(1.012) } }\n@keyframes sk-momentum-sheen { 0% { transform: translateX(-120%) } 100% { transform: translateX(360%) } }\n@keyframes sk-momentum-flash { 0% { opacity: .55 } 100% { opacity: 0 } }\n@keyframes sk-spark-pulse {\n 0%, 100% { box-shadow: 0 0 4px 1px color-mix(in srgb, var(--sk-primary, #2563eb) 60%, currentColor) }\n 50% { box-shadow: 0 0 11px 2px color-mix(in srgb, var(--sk-primary, #2563eb) 60%, currentColor) }\n}\n@keyframes sk-fill-charge {\n 0%, 100% { box-shadow: 0 0 5px 0 color-mix(in srgb, var(--sk-primary, #2563eb) 55%, currentColor) }\n 50% { box-shadow: 0 0 13px 2px color-mix(in srgb, var(--sk-primary, #2563eb) 55%, currentColor) }\n}\n@keyframes sk-label-pop { 0% { transform: scale(.8) } 60% { transform: scale(1.15) } 100% { transform: scale(1) } }\n@keyframes sk-btn-wake { 0% { transform: scale(1) } 40% { transform: scale(1.04) } 100% { transform: scale(1) } }\n@keyframes sk-btn-breathe {\n 0%, 100% { filter: drop-shadow(0 0 0 transparent) }\n 50% { filter: drop-shadow(0 0 9px color-mix(in srgb, var(--sk-primary, #2563eb) 60%, currentColor)) }\n}\n@keyframes sk-submit-pulse { 0%, 100% { opacity: 1 } 50% { opacity: .6 } }\n\n/* ---- Field: aura, lift, lock-in, tick ---- */\n/* Flex, not the default inline formatting context: an <input> is inline-block,\n so the wrapper would be a few px taller than the input (baseline descender\n gap) and the absolutely-centered tick would sit visibly low. */\n[data-sk-part=\"field-input-wrap\"] { display: flex; align-items: center; transition: transform .18s ease; }\n[data-sk-part=\"field-input-wrap\"]:focus-within { transform: translateY(-2px); }\n/* Focus aura — the active field is the lit one. Glow-only pseudo (its own\n box is transparent), so it never occludes the input. */\n[data-sk-part=\"field-input-wrap\"]::before {\n content: ''; position: absolute; inset: -3px;\n border-radius: calc(var(--sk-input-radius, 6px) + 3px);\n box-shadow: 0 0 16px color-mix(in srgb, var(--sk-primary, #2563eb) 55%, currentColor);\n opacity: 0; transition: opacity .25s ease; pointer-events: none;\n}\n[data-sk-part=\"field-input-wrap\"]:focus-within::before { opacity: .5; }\n/* One-shot lock-in ring when the field validates ([data-sk-valid] appears). */\n[data-sk-part=\"field-input-wrap\"]::after {\n content: ''; position: absolute; inset: 0;\n border-radius: var(--sk-input-radius, 6px);\n border: 2px solid color-mix(in srgb, var(--sk-primary, #2563eb) 72%, currentColor);\n opacity: 0; pointer-events: none;\n}\n[data-sk-part=\"field-input-wrap\"][data-sk-valid=\"true\"]::after { animation: sk-lock-in .55s ease-out both; }\n.sk-tick {\n position: absolute; right: 10px; top: 50%; transform: translateY(-50%);\n width: 20px; height: 20px; border-radius: 50%;\n background: color-mix(in srgb, var(--sk-primary, #2563eb) 72%, currentColor);\n display: flex; align-items: center; justify-content: center;\n animation: sk-tick-in .28s cubic-bezier(.22,1.4,.36,1) both;\n pointer-events: none;\n}\n.sk-tick::after {\n content: ''; position: absolute; inset: 0; border-radius: 50%;\n border: 2px solid color-mix(in srgb, var(--sk-primary, #2563eb) 72%, currentColor);\n animation: sk-tick-ring .55s ease-out .06s both;\n}\n.sk-tick path { stroke-dasharray: 14; stroke-dashoffset: 14; animation: sk-tick-draw .22s ease-out .12s forwards; }\n\n/* ---- Momentum meter ---- */\n.sk-momentum { display: flex; align-items: center; gap: 10px; margin: 0 0 16px; }\n.sk-momentum-track {\n flex: 1; position: relative; height: 8px; border-radius: 999px;\n background: color-mix(in srgb, currentColor 14%, transparent);\n}\n.sk-momentum-fill {\n position: relative; overflow: hidden;\n height: 100%; border-radius: 999px;\n background: color-mix(in srgb, var(--sk-primary, #2563eb) 72%, currentColor);\n transition: width .45s cubic-bezier(.22,1,.36,1);\n}\n/* Continuous sheen sweep — the bar reads as live, not static chrome. */\n.sk-momentum-fill::after {\n content: ''; position: absolute; top: 0; bottom: 0; left: 0; width: 45%;\n background: linear-gradient(105deg, transparent, rgba(255,255,255,.4), transparent);\n animation: sk-momentum-sheen 2.6s ease-in-out infinite;\n}\n/* One-shot white flash on each advance (keyed remount restarts it). */\n.sk-momentum-flash {\n position: absolute; inset: 0; border-radius: 999px;\n background: #fff; opacity: 0;\n animation: sk-momentum-flash .5s ease-out;\n}\n/* Leading-edge spark rides the fill tip. */\n.sk-momentum-spark {\n position: absolute; top: 50%; width: 10px; height: 10px; margin-top: -5px;\n border-radius: 50%;\n background: color-mix(in srgb, var(--sk-primary, #2563eb) 55%, currentColor);\n animation: sk-spark-pulse 1.6s ease-in-out infinite;\n transition: left .45s cubic-bezier(.22,1,.36,1);\n pointer-events: none;\n}\n.sk-momentum[data-sk-momentum=\"0\"] .sk-momentum-spark { opacity: 0; }\n.sk-momentum-label {\n font-size: 11px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase;\n opacity: .75; font-variant-numeric: tabular-nums; white-space: nowrap;\n}\n/* Charged state: every requirement met — bar glows, sheen accelerates,\n label flips to READY in brand. */\n.sk-momentum[data-sk-complete=\"true\"] .sk-momentum-fill { animation: sk-fill-charge 1.8s ease-in-out infinite; }\n.sk-momentum[data-sk-complete=\"true\"] .sk-momentum-fill::after { animation-duration: 1.4s; }\n.sk-momentum[data-sk-complete=\"true\"] .sk-momentum-label {\n opacity: 1;\n color: color-mix(in srgb, var(--sk-primary, #2563eb) 60%, currentColor);\n animation: sk-label-pop .4s cubic-bezier(.22,1.4,.36,1);\n}\n\n/* ---- DatePicker: the calendar morphs out of its tile and morphs back in\n on selection (container-transform), and the picked date stamps in. ---- */\n@keyframes sk-cal-out { 0% { opacity: 0; transform: scale(.92) translateY(-8px) } 100% { opacity: 1; transform: scale(1) translateY(0) } }\n@keyframes sk-cal-in { 0% { opacity: 1; transform: scale(1) translateY(0) } 100% { opacity: 0; transform: scale(.94) translateY(-6px) } }\n@keyframes sk-cal-stamp { 0% { transform: scale(.9) } 60% { transform: scale(1.06) } 100% { transform: scale(1) } }\n.sk-datepicker__pop { transform-origin: top center; animation: sk-cal-out .28s cubic-bezier(.22,1.4,.36,1) both; }\n.sk-datepicker__pop[data-sk-closing=\"true\"] { animation: sk-cal-in .18s ease-in both; }\n.sk-datepicker__value--stamp { display: inline-block; animation: sk-cal-stamp .3s cubic-bezier(.22,1.4,.36,1); }\n\n/* ---- Submit: wake on ready, pulse while submitting ---- */\n.sk-form__btn--submit { transition: transform .12s ease; }\n.sk-form__btn--submit:active { transform: scale(.97); }\n[data-sk-ready=\"true\"] .sk-form__btn--submit {\n animation: sk-btn-wake .5s cubic-bezier(.22,1.4,.36,1),\n sk-btn-breathe 2.4s ease-in-out .5s infinite;\n}\n[data-sk-state=\"submitting\"] .sk-form__btn--submit { animation: sk-submit-pulse 1.1s ease-in-out infinite; }\n[data-sk-state=\"submitting\"] .sk-momentum-fill::after { animation-duration: .8s; }\n\n@media (prefers-reduced-motion: reduce) {\n .sk-datepicker__pop { animation: none }\n .sk-datepicker__pop[data-sk-closing=\"true\"] { animation: none }\n .sk-datepicker__value--stamp { animation: none }\n .sk-tick { animation: none }\n .sk-tick::after { animation: none; opacity: 0 }\n .sk-tick path { animation: none; stroke-dashoffset: 0 }\n [data-sk-part=\"field-input-wrap\"] { transition: none }\n [data-sk-part=\"field-input-wrap\"]:focus-within { transform: none }\n [data-sk-part=\"field-input-wrap\"]::before { transition: none }\n [data-sk-part=\"field-input-wrap\"][data-sk-valid=\"true\"]::after { animation: none }\n .sk-momentum-fill { transition: none }\n .sk-momentum-fill::after { animation: none; opacity: 0 }\n .sk-momentum-flash { animation: none }\n .sk-momentum-spark { animation: none; transition: none }\n .sk-momentum[data-sk-complete=\"true\"] .sk-momentum-fill { animation: none }\n .sk-momentum[data-sk-complete=\"true\"] .sk-momentum-label { animation: none }\n .sk-form__btn--submit { transition: none }\n [data-sk-ready=\"true\"] .sk-form__btn--submit { animation: none }\n [data-sk-state=\"submitting\"] .sk-form__btn--submit { animation: none }\n}\n`\n\nexport function DelightStyles() {\n return <style id={STYLE_ID} dangerouslySetInnerHTML={{ __html: CSS }} />\n}\n\n/** Draw-in check shown inside a field wrapper once the value validates. */\nexport function FieldValidTick() {\n return (\n <span className=\"sk-tick\" data-sk-part=\"field-valid-tick\" aria-hidden=\"true\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 16 16\" fill=\"none\">\n <path\n d=\"M3.5 8.5l3 3 6-6.5\"\n stroke=\"var(--sk-form-success-check, #fff)\"\n strokeWidth=\"2.4\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n </span>\n )\n}\n\nexport interface FormMomentumProps {\n /** Completed required+visible fields. */\n done: number\n /** Total required+visible fields. */\n total: number\n}\n\n/**\n * Fields-completed meter. Hidden when there is nothing to measure (0-1\n * required fields) — a bar that fills in one keystroke reads as noise.\n */\nexport function FormMomentum({ done, total }: FormMomentumProps) {\n if (total < 2) return null\n const pct = Math.round((Math.min(done, total) / total) * 100)\n const ready = done >= total\n return (\n <div\n className=\"sk-momentum\"\n data-sk-part=\"momentum\"\n data-sk-momentum={pct}\n data-sk-complete={ready ? 'true' : undefined}\n role=\"progressbar\"\n aria-valuenow={done}\n aria-valuemin={0}\n aria-valuemax={total}\n aria-label=\"Form progress\"\n >\n <div className=\"sk-momentum-track\" data-sk-part=\"momentum-track\">\n <div className=\"sk-momentum-fill\" data-sk-part=\"momentum-fill\" style={{ width: `${pct}%` }}>\n {/* keyed by pct: remounts on every advance, replaying the flash */}\n <span key={pct} className=\"sk-momentum-flash\" data-sk-part=\"momentum-flash\" aria-hidden=\"true\" />\n </div>\n <span\n className=\"sk-momentum-spark\"\n data-sk-part=\"momentum-spark\"\n style={{ left: `calc(${pct}% - 5px)` }}\n aria-hidden=\"true\"\n />\n </div>\n <span className=\"sk-momentum-label\" data-sk-part=\"momentum-label\" aria-hidden=\"true\">\n {ready ? 'Ready' : `${done} of ${total}`}\n </span>\n </div>\n )\n}\n","/**\n * @sonordev/site-kit/forms - Form Field Component\n *\n * Renders individual form fields based on type.\n *\n * Styling Options:\n * 1. Use CSS variables to customize the default styles\n * 2. Use the `className` prop on ManagedForm for scoped styles\n * 3. Use the custom render function for complete control\n *\n * CSS Variables (set these in your stylesheet or import brand.css):\n * --sk-input-bg: #ffffff\n * --sk-input-text: #111827 (pairs with --sk-input-bg; falls back to\n * --sk-text-primary, so a themed site is covered)\n * --sk-input-border: #d1d5db\n * --sk-input-border-w: 1px\n * --sk-input-border-focus: #2563eb\n * --sk-input-border-error: #dc2626\n * --sk-input-radius: 0.375rem\n * --sk-input-padding: 10px 12px\n * --sk-label-color: inherit\n * --sk-label-weight: 500\n * --sk-error: #dc2626\n * --sk-text-tertiary: #6b7280\n * --sk-font-size: 16px\n */\n\nimport React from 'react'\nimport { FieldValidTick } from './delight'\nimport type { FormField as FormFieldType } from './types'\n\ninterface FormFieldProps {\n /** Render the valid-state tick (touched + validated). Text-like fields only. */\n showValid?: boolean\n field: FormFieldType\n value?: unknown\n error?: string\n /**\n * Omit to render STATIC mode: uncontrolled native controls with\n * `defaultValue`, no React state, no event handlers. That is what lets a\n * Server Component render a complete, submittable form with zero client\n * JavaScript (see StaticForm.tsx). Pass a handler for the usual controlled\n * behaviour once the enhancement hydrates.\n *\n * The two modes MUST emit the same element/class structure — the\n * enhancement replaces the shell in place, and a mismatch shows up as a\n * visible jump. field-parity.test.tsx pins this.\n */\n onChange?: (value: unknown) => void\n /**\n * Focus entered / left this field, for form analytics (`field_interactions`).\n * Interactive mode only; static mode renders no handlers of any kind.\n */\n onFocus?: () => void\n onBlur?: () => void\n /** Optional class name prefix for custom styling */\n classPrefix?: string\n /**\n * Client-only controls, injected by FormClient. DatePicker and FileField\n * carry hooks; importing them here would pull them into this module's chunk\n * and the build would stamp the whole thing `'use client'`, so a Server\n * Component rendering one text input would ship the date picker too.\n * Injection keeps this file hook-free and therefore server-renderable.\n * Absent = static mode falls back to the native control.\n */\n controls?: {\n Date?: React.ComponentType<any>\n File?: React.ComponentType<any>\n }\n}\n\n/**\n * Normalize options from various DB formats into [{value, label}]\n * Handles:\n * - [{value, label}] → pass through\n * - {choices: [\"A\", \"B\"]} → [{value: \"A\", label: \"A\"}, ...]\n * - [\"A\", \"B\"] → [{value: \"A\", label: \"A\"}, ...]\n */\nfunction normalizeOptions(options: unknown): { value: string; label: string }[] {\n if (!options) return []\n if (Array.isArray(options)) {\n return options.map((opt) => {\n if (typeof opt === 'string') return { value: opt, label: opt }\n if (typeof opt === 'object' && opt !== null && 'value' in opt && 'label' in opt) return opt as { value: string; label: string }\n if (typeof opt === 'object' && opt !== null && 'label' in opt) return { value: (opt as any).label, label: (opt as any).label }\n return { value: String(opt), label: String(opt) }\n })\n }\n if (typeof options === 'object' && options !== null) {\n const obj = options as Record<string, unknown>\n if (Array.isArray(obj.choices)) return normalizeOptions(obj.choices)\n if (Array.isArray(obj.items)) return normalizeOptions(obj.items)\n if (Array.isArray(obj.options)) return normalizeOptions(obj.options)\n }\n return []\n}\n\nexport function FormField({ field, value, error, onChange, onFocus, onBlur, classPrefix = 'sk-form' , showValid, controls }: FormFieldProps) {\n // Static mode: no handler, so render native uncontrolled controls. The\n // browser owns the value and a native form POST still carries it.\n const interactive = typeof onChange === 'function'\n const emit = (v: unknown) => onChange?.(v)\n /** value/onChange when interactive, defaultValue when static. */\n const bind = (v: string) =>\n interactive\n ? { value: v, onChange: (e: any) => emit(e.target.value) }\n : { defaultValue: v || undefined }\n // Stable id from field (no hooks - avoids \"Rendered fewer hooks than expected\" with early returns)\n const inputId = `sk-${(field as { id?: string }).id || field.slug}`\n // Normalize options once\n const options = normalizeOptions(field.options)\n // Use CSS variables with inline style fallbacks\n const baseInputStyle: React.CSSProperties = {\n width: '100%',\n padding: 'var(--sk-input-padding, 10px 12px)',\n fontSize: 'var(--sk-font-size, 16px)',\n border: error\n ? 'var(--sk-input-border-w, 1px) solid var(--sk-input-border-error, #dc2626)'\n : 'var(--sk-input-border-w, 1px) solid var(--sk-input-border, #d1d5db)',\n borderRadius: 'var(--sk-input-radius, 6px)',\n backgroundColor: 'var(--sk-input-bg, #ffffff)',\n // fg and bg MUST come from the same source. Inlining bg but letting color\n // cascade from the section produced cream-on-white on brand-colored panels\n // (found live). Default pairs with the white bg; theme both via vars.\n //\n // The fallback chain matters, and it is the reason this was broken on\n // upforgelabs.com: a dark site that set --sk-input-bg and --sk-text-primary\n // but never heard of --sk-input-text landed on #111827 over its own dark\n // field, 1.03:1, an input you cannot read your own typing in. Falling\n // through --sk-text-primary first means theming the page's text is enough.\n color: 'var(--sk-input-text, var(--sk-text-primary, #111827))',\n outline: 'none',\n fontFamily: 'inherit',\n }\n \n const labelStyle: React.CSSProperties = {\n display: 'block',\n marginBottom: 6,\n fontWeight: 'var(--sk-label-weight, 500)' as any,\n color: 'var(--sk-label-color, inherit)',\n }\n \n const errorStyle: React.CSSProperties = {\n color: 'var(--sk-error, #dc2626)',\n fontSize: 14,\n marginTop: 4,\n }\n \n const helpStyle: React.CSSProperties = {\n color: 'var(--sk-text-tertiary, #6b7280)',\n fontSize: 14,\n marginTop: 4,\n }\n \n // Heading / Section Header (display only)\n if (field.field_type === 'heading' || field.field_type === 'section_header') {\n return <h3 className={`${classPrefix}__heading`} style={{ margin: '16px 0 8px', fontWeight: 600, fontSize: 18 }}>{field.label}</h3>\n }\n \n // Paragraph (display only)\n if (field.field_type === 'paragraph') {\n return <p className={`${classPrefix}__paragraph`} style={{ color: 'var(--sk-text-tertiary, #6b7280)', margin: '8px 0' }}>{field.help_text || field.label}</p>\n }\n \n // Hidden field\n if (field.field_type === 'hidden') {\n return interactive\n ? <input type=\"hidden\" name={field.slug} value={String(value || '')} readOnly />\n : <input type=\"hidden\" name={field.slug} defaultValue={String(value || '')} />\n }\n\n const hideLabel = !!(field as { hide_label?: boolean }).hide_label\n const effectivePlaceholder = hideLabel ? field.label : field.placeholder\n\n // Focus reporting sits on the wrapper, so every control inside (radios, the\n // date picker, the file button) reports as this one field. Moves between\n // controls inside the same field are not a new visit to it.\n const focusProps = interactive && (onFocus || onBlur)\n ? {\n onFocus: (e: React.FocusEvent<HTMLDivElement>) => {\n if (!e.currentTarget.contains(e.relatedTarget as Node | null)) onFocus?.()\n },\n onBlur: (e: React.FocusEvent<HTMLDivElement>) => {\n if (!e.currentTarget.contains(e.relatedTarget as Node | null)) onBlur?.()\n },\n }\n : {}\n\n return (\n <div className={`${classPrefix}__field ${classPrefix}__field--${field.field_type}`} {...focusProps}>\n <label htmlFor={inputId} className={`${classPrefix}__label`} style={{ ...labelStyle, ...(hideLabel ? { position: 'absolute', width: 1, height: 1, padding: 0, margin: -1, overflow: 'hidden', clip: 'rect(0,0,0,0)', whiteSpace: 'nowrap', border: 0 } : {}) }}>\n {field.label}\n {field.is_required && <span style={{ color: 'var(--sk-error, #dc2626)' }}> *</span>}\n </label>\n \n {/* Text, Email, Phone/Tel, Number — relative wrapper hosts the valid tick */}\n {['text', 'email', 'phone', 'tel', 'number'].includes(field.field_type) && (\n <div style={{ position: 'relative' }} data-sk-part=\"field-input-wrap\" data-sk-valid={showValid ? 'true' : undefined}>\n <input\n id={inputId}\n className={`${classPrefix}__input`}\n type={field.field_type === 'phone' || field.field_type === 'tel' ? 'tel' : field.field_type}\n name={field.slug}\n {...bind(String(value || ''))}\n placeholder={effectivePlaceholder}\n required={field.is_required}\n style={baseInputStyle}\n />\n {showValid && <FieldValidTick />}\n </div>\n )}\n \n {/* Textarea */}\n {field.field_type === 'textarea' && (\n <textarea\n id={inputId}\n className={`${classPrefix}__textarea`}\n name={field.slug}\n {...bind(String(value || ''))}\n placeholder={effectivePlaceholder}\n required={field.is_required}\n rows={4}\n style={{ ...baseInputStyle, resize: 'vertical' }}\n />\n )}\n \n {/* Select */}\n {field.field_type === 'select' && (\n <select\n id={inputId}\n className={`${classPrefix}__select`}\n name={field.slug}\n {...bind(String(value || ''))}\n required={field.is_required}\n style={baseInputStyle}\n >\n <option value=\"\">{effectivePlaceholder || 'Select an option'}</option>\n {options.map((option) => (\n <option key={option.value} value={option.value}>\n {option.label}\n </option>\n ))}\n </select>\n )}\n \n {/* Multi-select */}\n {field.field_type === 'multi-select' && (\n <select\n id={inputId}\n className={`${classPrefix}__select ${classPrefix}__select--multi`}\n name={field.slug}\n {...(interactive\n ? {\n value: Array.isArray(value) ? (value as string[]) : [],\n onChange: (e: any) =>\n emit(Array.from(e.target.selectedOptions, (opt: any) => opt.value)),\n }\n : { defaultValue: Array.isArray(value) ? (value as string[]) : [] })}\n required={field.is_required}\n multiple\n style={{ ...baseInputStyle, height: 120 }}\n >\n {options.map((option) => (\n <option key={option.value} value={option.value}>\n {option.label}\n </option>\n ))}\n </select>\n )}\n \n {/* Radio */}\n {field.field_type === 'radio' && (\n <div className={`${classPrefix}__radio-group`} style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>\n {options.map((option) => (\n <label key={option.value} className={`${classPrefix}__radio-option`} style={{ display: 'flex', alignItems: 'center', gap: 8 }}>\n <input\n type=\"radio\"\n name={field.slug}\n value={option.value}\n {...(interactive\n ? { checked: value === option.value, onChange: () => emit(option.value) }\n : { defaultChecked: value === option.value })}\n required={field.is_required}\n />\n {option.label}\n </label>\n ))}\n </div>\n )}\n \n {/* Checkbox (single) */}\n {field.field_type === 'checkbox' && options.length === 0 && (\n <label className={`${classPrefix}__checkbox`} style={{ display: 'flex', alignItems: 'center', gap: 8 }}>\n <input\n type=\"checkbox\"\n name={field.slug}\n {...(interactive\n ? { checked: !!value, onChange: (e: any) => emit(e.target.checked) }\n : { defaultChecked: !!value })}\n required={field.is_required}\n />\n {field.help_text || field.label}\n </label>\n )}\n \n {/* Checkbox (multiple options) */}\n {field.field_type === 'checkbox' && options.length > 0 && (\n <div className={`${classPrefix}__checkbox-group`} style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>\n {options.map((option) => {\n const selectedValues = Array.isArray(value) ? value : []\n const isChecked = selectedValues.includes(option.value)\n \n return (\n <label key={option.value} className={`${classPrefix}__checkbox-option`} style={{ display: 'flex', alignItems: 'center', gap: 8 }}>\n <input\n type=\"checkbox\"\n name={field.slug}\n value={option.value}\n {...(interactive\n ? {\n checked: isChecked,\n onChange: () =>\n emit(\n isChecked\n ? selectedValues.filter((v) => v !== option.value)\n : [...selectedValues, option.value],\n ),\n }\n : { defaultChecked: isChecked })}\n />\n {option.label}\n </label>\n )\n })}\n </div>\n )}\n \n {/* Date - Custom calendar picker */}\n {field.field_type === 'date' && (\n interactive && controls?.Date ? (\n <controls.Date\n id={inputId}\n name={field.slug}\n value={String(value || '')}\n onChange={emit}\n required={field.is_required}\n placeholder={field.placeholder || 'Select a date'}\n className={`${classPrefix}__input ${classPrefix}__input--date`}\n />\n ) : (\n // Static: the browser's own date control. Same name and class, so\n // the swap to DatePicker on enhancement is in place.\n <input\n id={inputId}\n className={`${classPrefix}__input ${classPrefix}__input--date`}\n type=\"date\"\n name={field.slug}\n defaultValue={String(value || '') || undefined}\n required={field.is_required}\n style={baseInputStyle}\n />\n )\n )}\n \n {/* Time */}\n {field.field_type === 'time' && (\n <input\n id={inputId}\n className={`${classPrefix}__input ${classPrefix}__input--time`}\n type=\"time\"\n name={field.slug}\n {...bind(String(value || ''))}\n required={field.is_required}\n style={baseInputStyle}\n />\n )}\n \n {/* DateTime */}\n {field.field_type === 'datetime' && (\n <input\n id={inputId}\n className={`${classPrefix}__input ${classPrefix}__input--datetime`}\n type=\"datetime-local\"\n name={field.slug}\n {...bind(String(value || ''))}\n required={field.is_required}\n style={baseInputStyle}\n />\n )}\n \n {/* File */}\n {field.field_type === 'file' && (\n interactive && controls?.File ? (\n <controls.File\n field={field}\n inputId={inputId}\n classPrefix={classPrefix}\n baseInputStyle={baseInputStyle}\n onChange={emit}\n />\n ) : (\n // Static: a real file input so the field is visible and labelled,\n // but the Sonor upload only happens once enhanced. Forms with a file\n // field are excluded from native POST for exactly this reason\n // (see nativeEligible in native-fallback.tsx).\n <input\n id={inputId}\n className={`${classPrefix}__input ${classPrefix}__input--file`}\n type=\"file\"\n name={field.slug}\n required={field.is_required}\n style={baseInputStyle}\n />\n )\n )}\n \n {/* Rating */}\n {field.field_type === 'rating' && (\n <div className={`${classPrefix}__rating`} style={{ display: 'flex', gap: 4 }} role={interactive ? undefined : 'radiogroup'} aria-label={interactive ? undefined : field.label}>\n {!interactive && [1, 2, 3, 4, 5].map((star) => (\n // Static: a real radio group. Submits natively, and is reachable\n // by keyboard and screen readers without any script.\n <label key={`s${star}`} className={`${classPrefix}__rating-star`} style={{ fontSize: 24, cursor: 'pointer', color: (value as number) >= star ? 'var(--sk-rating-active, #fbbf24)' : 'var(--sk-rating-inactive, #d1d5db)' }}>\n <input\n type=\"radio\"\n name={field.slug}\n value={star}\n defaultChecked={(value as number) === star}\n required={field.is_required && star === 1}\n style={{ position: 'absolute', width: 1, height: 1, opacity: 0 }}\n />\n <span aria-label={`${star} star${star > 1 ? 's' : ''}`}>★</span>\n </label>\n ))}\n {interactive && [1, 2, 3, 4, 5].map((star) => (\n <button\n key={star}\n type=\"button\"\n onClick={() => emit(star)}\n className={`${classPrefix}__rating-star`}\n style={{\n background: 'none',\n border: 'none',\n fontSize: 24,\n cursor: 'pointer',\n color: (value as number) >= star ? 'var(--sk-rating-active, #fbbf24)' : 'var(--sk-rating-inactive, #d1d5db)',\n }}\n >\n ★\n </button>\n ))}\n </div>\n )}\n \n {/* Slider */}\n {field.field_type === 'slider' && (\n <div className={`${classPrefix}__slider`}>\n <input\n id={inputId}\n type=\"range\"\n name={field.slug}\n {...(interactive\n ? { value: Number(value || 50), onChange: (e: any) => emit(Number(e.target.value)) }\n : { defaultValue: Number(value || 50) })}\n min={field.validation?.min || 0}\n max={field.validation?.max || 100}\n style={{ width: '100%' }}\n />\n <div className={`${classPrefix}__slider-value`} style={{ textAlign: 'center', marginTop: 4 }}>{String(value || 50)}</div>\n </div>\n )}\n \n {/* Error message */}\n {error && <p className={`${classPrefix}__error`} style={errorStyle}>{error}</p>}\n \n {/* Help text */}\n {field.help_text && !error && field.field_type !== 'checkbox' && (\n <p className={`${classPrefix}__help`} style={helpStyle}>{field.help_text}</p>\n )}\n </div>\n )\n}\n"]}