@contractspec/bundle.marketing 1.12.0 → 1.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (262) hide show
  1. package/.turbo/turbo-build.log +146 -175
  2. package/.turbo/turbo-prebuild.log +1 -0
  3. package/CHANGELOG.md +29 -0
  4. package/dist/browser/components/marketing/ChangelogPage.js +92 -0
  5. package/dist/browser/components/marketing/CofounderPage.js +581 -0
  6. package/dist/browser/components/marketing/ContactClient.js +1379 -0
  7. package/dist/browser/components/marketing/ContributePage.js +487 -0
  8. package/dist/browser/components/marketing/DesignPartnerPage.js +272 -0
  9. package/dist/browser/components/marketing/LandingPage.js +629 -0
  10. package/dist/browser/components/marketing/PricingClient.js +1972 -0
  11. package/dist/browser/components/marketing/ProductClientPage.js +563 -0
  12. package/dist/browser/components/marketing/index.js +4818 -0
  13. package/dist/browser/components/marketing/pricing-thinking-modal.js +258 -0
  14. package/dist/browser/components/marketing/sections/AudienceSection.js +90 -0
  15. package/dist/browser/components/marketing/sections/CorePositioningSection.js +72 -0
  16. package/dist/browser/components/marketing/sections/CtaSection.js +67 -0
  17. package/dist/browser/components/marketing/sections/DevelopersSection.js +50 -0
  18. package/dist/browser/components/marketing/sections/FearsSection.js +105 -0
  19. package/dist/browser/components/marketing/sections/HeroMarketingSection.js +93 -0
  20. package/dist/browser/components/marketing/sections/IconGridSection.js +63 -0
  21. package/dist/browser/components/marketing/sections/OutputsSection.js +116 -0
  22. package/dist/browser/components/marketing/sections/ProblemSection.js +103 -0
  23. package/dist/browser/components/marketing/sections/SolutionSection.js +103 -0
  24. package/dist/browser/components/marketing/sections/StepsSection.js +109 -0
  25. package/dist/browser/components/marketing/waitlist-section.js +1104 -0
  26. package/dist/browser/components/templates/TemplatesClientPage.js +5662 -0
  27. package/dist/browser/components/templates/TemplatesPage.js +177 -0
  28. package/dist/browser/components/templates/TemplatesPreviewModal.js +124 -0
  29. package/dist/browser/components/templates/index.js +5831 -0
  30. package/dist/browser/index.js +6485 -0
  31. package/dist/browser/libs/email/client.js +122 -0
  32. package/dist/browser/libs/email/contact.js +190 -0
  33. package/dist/browser/libs/email/newsletter.js +215 -0
  34. package/dist/browser/libs/email/types.js +2 -0
  35. package/dist/browser/libs/email/utils.js +16 -0
  36. package/dist/browser/libs/email/waitlist-application.js +295 -0
  37. package/dist/browser/libs/email/waitlist.js +225 -0
  38. package/dist/browser/libs/pricing-examples.js +26 -0
  39. package/dist/browser/registry/engine.js +5293 -0
  40. package/dist/browser/registry/factory.js +52 -0
  41. package/dist/browser/registry/index.js +5358 -0
  42. package/dist/browser/registry/registry-docs.js +343 -0
  43. package/dist/browser/registry/registry-landing.js +4937 -0
  44. package/dist/browser/registry/registry.js +5279 -0
  45. package/dist/browser/registry/types.js +0 -0
  46. package/dist/browser/registry/utils.js +5340 -0
  47. package/dist/components/marketing/ChangelogPage.d.ts +11 -17
  48. package/dist/components/marketing/ChangelogPage.d.ts.map +1 -1
  49. package/dist/components/marketing/ChangelogPage.js +84 -62
  50. package/dist/components/marketing/CofounderPage.d.ts +1 -6
  51. package/dist/components/marketing/CofounderPage.d.ts.map +1 -1
  52. package/dist/components/marketing/CofounderPage.js +544 -436
  53. package/dist/components/marketing/ContactClient.d.ts +1 -6
  54. package/dist/components/marketing/ContactClient.d.ts.map +1 -1
  55. package/dist/components/marketing/ContactClient.js +1371 -155
  56. package/dist/components/marketing/ContributePage.d.ts +3 -8
  57. package/dist/components/marketing/ContributePage.d.ts.map +1 -1
  58. package/dist/components/marketing/ContributePage.js +478 -358
  59. package/dist/components/marketing/DesignPartnerPage.d.ts +3 -8
  60. package/dist/components/marketing/DesignPartnerPage.d.ts.map +1 -1
  61. package/dist/components/marketing/DesignPartnerPage.js +263 -211
  62. package/dist/components/marketing/LandingPage.d.ts +1 -6
  63. package/dist/components/marketing/LandingPage.d.ts.map +1 -1
  64. package/dist/components/marketing/LandingPage.js +623 -37
  65. package/dist/components/marketing/PricingClient.d.ts +1 -6
  66. package/dist/components/marketing/PricingClient.d.ts.map +1 -1
  67. package/dist/components/marketing/PricingClient.js +1962 -516
  68. package/dist/components/marketing/ProductClientPage.d.ts +1 -6
  69. package/dist/components/marketing/ProductClientPage.d.ts.map +1 -1
  70. package/dist/components/marketing/ProductClientPage.js +556 -458
  71. package/dist/components/marketing/index.d.ts +11 -11
  72. package/dist/components/marketing/index.d.ts.map +1 -0
  73. package/dist/components/marketing/index.js +4813 -12
  74. package/dist/components/marketing/pricing-thinking-modal.d.ts +5 -13
  75. package/dist/components/marketing/pricing-thinking-modal.d.ts.map +1 -1
  76. package/dist/components/marketing/pricing-thinking-modal.js +248 -197
  77. package/dist/components/marketing/sections/AudienceSection.d.ts +1 -6
  78. package/dist/components/marketing/sections/AudienceSection.d.ts.map +1 -1
  79. package/dist/components/marketing/sections/AudienceSection.js +80 -63
  80. package/dist/components/marketing/sections/CorePositioningSection.d.ts +1 -6
  81. package/dist/components/marketing/sections/CorePositioningSection.d.ts.map +1 -1
  82. package/dist/components/marketing/sections/CorePositioningSection.js +62 -54
  83. package/dist/components/marketing/sections/CtaSection.d.ts +1 -6
  84. package/dist/components/marketing/sections/CtaSection.d.ts.map +1 -1
  85. package/dist/components/marketing/sections/CtaSection.js +58 -50
  86. package/dist/components/marketing/sections/DevelopersSection.d.ts +1 -6
  87. package/dist/components/marketing/sections/DevelopersSection.d.ts.map +1 -1
  88. package/dist/components/marketing/sections/DevelopersSection.js +40 -40
  89. package/dist/components/marketing/sections/FearsSection.d.ts +1 -6
  90. package/dist/components/marketing/sections/FearsSection.d.ts.map +1 -1
  91. package/dist/components/marketing/sections/FearsSection.js +96 -44
  92. package/dist/components/marketing/sections/HeroMarketingSection.d.ts +1 -6
  93. package/dist/components/marketing/sections/HeroMarketingSection.d.ts.map +1 -1
  94. package/dist/components/marketing/sections/HeroMarketingSection.js +82 -71
  95. package/dist/components/marketing/sections/IconGridSection.d.ts +25 -39
  96. package/dist/components/marketing/sections/IconGridSection.d.ts.map +1 -1
  97. package/dist/components/marketing/sections/IconGridSection.js +55 -41
  98. package/dist/components/marketing/sections/OutputsSection.d.ts +1 -6
  99. package/dist/components/marketing/sections/OutputsSection.d.ts.map +1 -1
  100. package/dist/components/marketing/sections/OutputsSection.js +107 -55
  101. package/dist/components/marketing/sections/ProblemSection.d.ts +1 -6
  102. package/dist/components/marketing/sections/ProblemSection.d.ts.map +1 -1
  103. package/dist/components/marketing/sections/ProblemSection.js +94 -42
  104. package/dist/components/marketing/sections/SolutionSection.d.ts +1 -6
  105. package/dist/components/marketing/sections/SolutionSection.d.ts.map +1 -1
  106. package/dist/components/marketing/sections/SolutionSection.js +94 -42
  107. package/dist/components/marketing/sections/StepsSection.d.ts +1 -6
  108. package/dist/components/marketing/sections/StepsSection.d.ts.map +1 -1
  109. package/dist/components/marketing/sections/StepsSection.js +100 -48
  110. package/dist/components/marketing/waitlist-section.d.ts +5 -12
  111. package/dist/components/marketing/waitlist-section.d.ts.map +1 -1
  112. package/dist/components/marketing/waitlist-section.js +1089 -568
  113. package/dist/components/templates/TemplatesClientPage.d.ts +1 -6
  114. package/dist/components/templates/TemplatesClientPage.d.ts.map +1 -1
  115. package/dist/components/templates/TemplatesClientPage.js +5649 -617
  116. package/dist/components/templates/TemplatesPage.d.ts +1 -6
  117. package/dist/components/templates/TemplatesPage.d.ts.map +1 -1
  118. package/dist/components/templates/TemplatesPage.js +163 -116
  119. package/dist/components/templates/TemplatesPreviewModal.d.ts +5 -12
  120. package/dist/components/templates/TemplatesPreviewModal.d.ts.map +1 -1
  121. package/dist/components/templates/TemplatesPreviewModal.js +113 -131
  122. package/dist/components/templates/index.d.ts +4 -4
  123. package/dist/components/templates/index.d.ts.map +1 -0
  124. package/dist/components/templates/index.js +5825 -4
  125. package/dist/index.d.ts +9 -29
  126. package/dist/index.d.ts.map +1 -0
  127. package/dist/index.js +6480 -28
  128. package/dist/libs/email/client.d.ts +9 -12
  129. package/dist/libs/email/client.d.ts.map +1 -1
  130. package/dist/libs/email/client.js +109 -105
  131. package/dist/libs/email/client.test.d.ts +2 -0
  132. package/dist/libs/email/client.test.d.ts.map +1 -0
  133. package/dist/libs/email/contact.d.ts +2 -6
  134. package/dist/libs/email/contact.d.ts.map +1 -1
  135. package/dist/libs/email/contact.js +155 -41
  136. package/dist/libs/email/newsletter.d.ts +2 -6
  137. package/dist/libs/email/newsletter.d.ts.map +1 -1
  138. package/dist/libs/email/newsletter.js +169 -54
  139. package/dist/libs/email/types.d.ts +48 -52
  140. package/dist/libs/email/types.d.ts.map +1 -1
  141. package/dist/libs/email/types.js +3 -1
  142. package/dist/libs/email/utils.d.ts +2 -5
  143. package/dist/libs/email/utils.d.ts.map +1 -1
  144. package/dist/libs/email/utils.js +10 -6
  145. package/dist/libs/email/waitlist-application.d.ts +2 -6
  146. package/dist/libs/email/waitlist-application.d.ts.map +1 -1
  147. package/dist/libs/email/waitlist-application.js +191 -71
  148. package/dist/libs/email/waitlist.d.ts +2 -6
  149. package/dist/libs/email/waitlist.d.ts.map +1 -1
  150. package/dist/libs/email/waitlist.js +171 -56
  151. package/dist/libs/pricing-examples.d.ts +13 -16
  152. package/dist/libs/pricing-examples.d.ts.map +1 -1
  153. package/dist/libs/pricing-examples.js +20 -20
  154. package/dist/node/components/marketing/ChangelogPage.js +87 -0
  155. package/dist/node/components/marketing/CofounderPage.js +576 -0
  156. package/dist/node/components/marketing/ContactClient.js +1374 -0
  157. package/dist/node/components/marketing/ContributePage.js +482 -0
  158. package/dist/node/components/marketing/DesignPartnerPage.js +267 -0
  159. package/dist/node/components/marketing/LandingPage.js +624 -0
  160. package/dist/node/components/marketing/PricingClient.js +1967 -0
  161. package/dist/node/components/marketing/ProductClientPage.js +558 -0
  162. package/dist/node/components/marketing/index.js +4813 -0
  163. package/dist/node/components/marketing/pricing-thinking-modal.js +253 -0
  164. package/dist/node/components/marketing/sections/AudienceSection.js +85 -0
  165. package/dist/node/components/marketing/sections/CorePositioningSection.js +67 -0
  166. package/dist/node/components/marketing/sections/CtaSection.js +62 -0
  167. package/dist/node/components/marketing/sections/DevelopersSection.js +45 -0
  168. package/dist/node/components/marketing/sections/FearsSection.js +100 -0
  169. package/dist/node/components/marketing/sections/HeroMarketingSection.js +88 -0
  170. package/dist/node/components/marketing/sections/IconGridSection.js +58 -0
  171. package/dist/node/components/marketing/sections/OutputsSection.js +111 -0
  172. package/dist/node/components/marketing/sections/ProblemSection.js +98 -0
  173. package/dist/node/components/marketing/sections/SolutionSection.js +98 -0
  174. package/dist/node/components/marketing/sections/StepsSection.js +104 -0
  175. package/dist/node/components/marketing/waitlist-section.js +1099 -0
  176. package/dist/node/components/templates/TemplatesClientPage.js +5657 -0
  177. package/dist/node/components/templates/TemplatesPage.js +172 -0
  178. package/dist/node/components/templates/TemplatesPreviewModal.js +119 -0
  179. package/dist/node/components/templates/index.js +5826 -0
  180. package/dist/node/index.js +6480 -0
  181. package/dist/node/libs/email/client.js +117 -0
  182. package/dist/node/libs/email/contact.js +185 -0
  183. package/dist/node/libs/email/newsletter.js +210 -0
  184. package/dist/node/libs/email/types.js +2 -0
  185. package/dist/node/libs/email/utils.js +11 -0
  186. package/dist/node/libs/email/waitlist-application.js +290 -0
  187. package/dist/node/libs/email/waitlist.js +220 -0
  188. package/dist/node/libs/pricing-examples.js +21 -0
  189. package/dist/node/registry/engine.js +5288 -0
  190. package/dist/node/registry/factory.js +47 -0
  191. package/dist/node/registry/index.js +5353 -0
  192. package/dist/node/registry/registry-docs.js +338 -0
  193. package/dist/node/registry/registry-landing.js +4932 -0
  194. package/dist/node/registry/registry.js +5274 -0
  195. package/dist/node/registry/types.js +0 -0
  196. package/dist/node/registry/utils.js +5335 -0
  197. package/dist/registry/engine.d.ts +4 -8
  198. package/dist/registry/engine.d.ts.map +1 -1
  199. package/dist/registry/engine.js +5287 -23
  200. package/dist/registry/factory.d.ts +30 -34
  201. package/dist/registry/factory.d.ts.map +1 -1
  202. package/dist/registry/factory.js +42 -56
  203. package/dist/registry/index.d.ts +8 -8
  204. package/dist/registry/index.d.ts.map +1 -0
  205. package/dist/registry/index.js +5353 -8
  206. package/dist/registry/registry-docs.d.ts +4 -8
  207. package/dist/registry/registry-docs.d.ts.map +1 -1
  208. package/dist/registry/registry-docs.js +242 -209
  209. package/dist/registry/registry-landing.d.ts +5 -9
  210. package/dist/registry/registry-landing.d.ts.map +1 -1
  211. package/dist/registry/registry-landing.js +4930 -93
  212. package/dist/registry/registry.d.ts +7 -11
  213. package/dist/registry/registry.d.ts.map +1 -1
  214. package/dist/registry/registry.js +5262 -49
  215. package/dist/registry/types.d.ts +6 -10
  216. package/dist/registry/types.d.ts.map +1 -1
  217. package/dist/registry/types.js +1 -0
  218. package/dist/registry/utils.d.ts +10 -14
  219. package/dist/registry/utils.d.ts.map +1 -1
  220. package/dist/registry/utils.js +5330 -49
  221. package/package.json +355 -73
  222. package/tsdown.config.js +1 -2
  223. package/.turbo/turbo-build$colon$types.log +0 -1
  224. package/.turbo/turbo-lint.log +0 -3
  225. package/dist/components/marketing/ChangelogPage.js.map +0 -1
  226. package/dist/components/marketing/CofounderPage.js.map +0 -1
  227. package/dist/components/marketing/ContactClient.js.map +0 -1
  228. package/dist/components/marketing/ContributePage.js.map +0 -1
  229. package/dist/components/marketing/DesignPartnerPage.js.map +0 -1
  230. package/dist/components/marketing/LandingPage.js.map +0 -1
  231. package/dist/components/marketing/PricingClient.js.map +0 -1
  232. package/dist/components/marketing/ProductClientPage.js.map +0 -1
  233. package/dist/components/marketing/pricing-thinking-modal.js.map +0 -1
  234. package/dist/components/marketing/sections/AudienceSection.js.map +0 -1
  235. package/dist/components/marketing/sections/CorePositioningSection.js.map +0 -1
  236. package/dist/components/marketing/sections/CtaSection.js.map +0 -1
  237. package/dist/components/marketing/sections/DevelopersSection.js.map +0 -1
  238. package/dist/components/marketing/sections/FearsSection.js.map +0 -1
  239. package/dist/components/marketing/sections/HeroMarketingSection.js.map +0 -1
  240. package/dist/components/marketing/sections/IconGridSection.js.map +0 -1
  241. package/dist/components/marketing/sections/OutputsSection.js.map +0 -1
  242. package/dist/components/marketing/sections/ProblemSection.js.map +0 -1
  243. package/dist/components/marketing/sections/SolutionSection.js.map +0 -1
  244. package/dist/components/marketing/sections/StepsSection.js.map +0 -1
  245. package/dist/components/marketing/waitlist-section.js.map +0 -1
  246. package/dist/components/templates/TemplatesClientPage.js.map +0 -1
  247. package/dist/components/templates/TemplatesPage.js.map +0 -1
  248. package/dist/components/templates/TemplatesPreviewModal.js.map +0 -1
  249. package/dist/libs/email/client.js.map +0 -1
  250. package/dist/libs/email/contact.js.map +0 -1
  251. package/dist/libs/email/newsletter.js.map +0 -1
  252. package/dist/libs/email/utils.js.map +0 -1
  253. package/dist/libs/email/waitlist-application.js.map +0 -1
  254. package/dist/libs/email/waitlist.js.map +0 -1
  255. package/dist/libs/pricing-examples.js.map +0 -1
  256. package/dist/registry/engine.js.map +0 -1
  257. package/dist/registry/factory.js.map +0 -1
  258. package/dist/registry/registry-docs.js.map +0 -1
  259. package/dist/registry/registry-landing.js.map +0 -1
  260. package/dist/registry/registry.js.map +0 -1
  261. package/dist/registry/utils.js.map +0 -1
  262. package/tsconfig.tsbuildinfo +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"client.js","names":[],"sources":["../../../src/libs/email/client.ts"],"sourcesContent":["import { createClient, Temv1alpha1 } from '@scaleway/sdk';\nimport type { Region } from '@scaleway/sdk-client';\nimport { Logger } from '@contractspec/lib.logger';\nimport type {\n EmailAddress,\n EmailConfigResult,\n EmailSendOutcome,\n EmailServiceConfig,\n SendEmailRequest,\n} from './types';\n\nconst DEFAULT_FROM: EmailAddress = {\n email: 'noreply@transactional.contractspec.io',\n name: 'ContractSpec',\n};\n\nconst DEFAULT_TEAM_INBOX: EmailAddress = {\n email: 'contact@contractspec.io',\n name: 'ContractSpec Team',\n};\n\nconst DEFAULT_REGION: Region = 'fr-par';\n\ntype EmailApi = Pick<Temv1alpha1.API, 'createEmail'>;\n\nlet cachedConfig: EmailServiceConfig | null = null;\nlet cachedClient: EmailApi | null = null;\nlet apiFactory: (client: ReturnType<typeof createClient>) => EmailApi = (\n client\n) => new Temv1alpha1.API(client);\n\nconst mapRegion = (value?: string | null): Region => {\n const normalized = value?.trim().toLowerCase();\n if (normalized === 'par' || normalized === 'fr-par') return 'fr-par';\n if (normalized === 'ams' || normalized === 'nl-ams') return 'nl-ams';\n if (normalized === 'waw' || normalized === 'pl-waw') return 'pl-waw';\n return DEFAULT_REGION;\n};\n\nexport const getEmailConfig = (): EmailConfigResult => {\n if (cachedConfig) {\n return { ok: true, config: cachedConfig };\n }\n\n const accessKey =\n process.env.SCALEWAY_ACCESS_KEY || process.env.SCALEWAY_ACCESS_KEY_QUEUE;\n const secretKey =\n process.env.SCALEWAY_SECRET_KEY || process.env.SCALEWAY_SECRET_KEY_QUEUE;\n const projectId = process.env.SCALEWAY_PROJECT_ID;\n\n if (!accessKey || !secretKey || !projectId) {\n return {\n ok: false,\n errorMessage:\n 'Email service is not configured. Please contact us directly at contact@contractspec.io.',\n };\n }\n\n const region = mapRegion(process.env.SCALEWAY_REGION);\n\n cachedConfig = {\n accessKey,\n secretKey,\n projectId,\n region,\n defaultZone: `${region}-1`,\n from: {\n email: process.env.SCALEWAY_EMAIL_FROM_EMAIL ?? DEFAULT_FROM.email,\n name: process.env.SCALEWAY_EMAIL_FROM_NAME ?? DEFAULT_FROM.name,\n },\n teamInbox: {\n email: process.env.SCALEWAY_EMAIL_TEAM_EMAIL ?? DEFAULT_TEAM_INBOX.email,\n name: process.env.SCALEWAY_EMAIL_TEAM_NAME ?? DEFAULT_TEAM_INBOX.name,\n },\n };\n\n return { ok: true, config: cachedConfig };\n};\n\nconst getTemClient = (config: EmailServiceConfig): EmailApi => {\n if (cachedClient) {\n return cachedClient;\n }\n\n const client = createClient({\n accessKey: config.accessKey,\n secretKey: config.secretKey,\n defaultProjectId: config.projectId,\n defaultRegion: config.region,\n defaultZone: config.defaultZone,\n });\n\n cachedClient = apiFactory(client);\n return cachedClient;\n};\n\nexport const sendEmail = async (\n config: EmailServiceConfig,\n request: SendEmailRequest\n): Promise<EmailSendOutcome> => {\n try {\n const client = getTemClient(config);\n\n await client.createEmail({\n region: config.region,\n projectId: config.projectId,\n from: config.from,\n to: request.to,\n subject: request.subject,\n text: request.text,\n html: request.html || request.text,\n additionalHeaders: request.replyTo\n ? [{ key: 'Reply-To', value: request.replyTo }]\n : undefined,\n });\n\n return { success: true };\n } catch (error) {\n new Logger().error('scaleway_tem_email_send_failed', {\n context: request.context ?? 'email',\n error: error instanceof Error ? error.message : error,\n });\n return {\n success: false,\n error,\n errorMessage: 'Failed to send email via Scaleway.',\n };\n }\n};\n\nexport const __internal = {\n resetCaches() {\n cachedClient = null;\n cachedConfig = null;\n apiFactory = (client: ReturnType<typeof createClient>) =>\n new Temv1alpha1.API(client);\n },\n setApiFactory(\n factory: (client: ReturnType<typeof createClient>) => EmailApi\n ) {\n apiFactory = factory;\n },\n setClient(client: EmailApi) {\n cachedClient = client;\n },\n};\n"],"mappings":";;;;AAWA,MAAM,eAA6B;CACjC,OAAO;CACP,MAAM;CACP;AAED,MAAM,qBAAmC;CACvC,OAAO;CACP,MAAM;CACP;AAED,MAAM,iBAAyB;AAI/B,IAAI,eAA0C;AAC9C,IAAI,eAAgC;AACpC,IAAI,cACF,WACG,IAAI,YAAY,IAAI,OAAO;AAEhC,MAAM,aAAa,UAAkC;CACnD,MAAM,aAAa,OAAO,MAAM,CAAC,aAAa;AAC9C,KAAI,eAAe,SAAS,eAAe,SAAU,QAAO;AAC5D,KAAI,eAAe,SAAS,eAAe,SAAU,QAAO;AAC5D,KAAI,eAAe,SAAS,eAAe,SAAU,QAAO;AAC5D,QAAO;;AAGT,MAAa,uBAA0C;AACrD,KAAI,aACF,QAAO;EAAE,IAAI;EAAM,QAAQ;EAAc;CAG3C,MAAM,YACJ,QAAQ,IAAI,uBAAuB,QAAQ,IAAI;CACjD,MAAM,YACJ,QAAQ,IAAI,uBAAuB,QAAQ,IAAI;CACjD,MAAM,YAAY,QAAQ,IAAI;AAE9B,KAAI,CAAC,aAAa,CAAC,aAAa,CAAC,UAC/B,QAAO;EACL,IAAI;EACJ,cACE;EACH;CAGH,MAAM,SAAS,UAAU,QAAQ,IAAI,gBAAgB;AAErD,gBAAe;EACb;EACA;EACA;EACA;EACA,aAAa,GAAG,OAAO;EACvB,MAAM;GACJ,OAAO,QAAQ,IAAI,6BAA6B,aAAa;GAC7D,MAAM,QAAQ,IAAI,4BAA4B,aAAa;GAC5D;EACD,WAAW;GACT,OAAO,QAAQ,IAAI,6BAA6B,mBAAmB;GACnE,MAAM,QAAQ,IAAI,4BAA4B,mBAAmB;GAClE;EACF;AAED,QAAO;EAAE,IAAI;EAAM,QAAQ;EAAc;;AAG3C,MAAM,gBAAgB,WAAyC;AAC7D,KAAI,aACF,QAAO;CAGT,MAAM,SAAS,aAAa;EAC1B,WAAW,OAAO;EAClB,WAAW,OAAO;EAClB,kBAAkB,OAAO;EACzB,eAAe,OAAO;EACtB,aAAa,OAAO;EACrB,CAAC;AAEF,gBAAe,WAAW,OAAO;AACjC,QAAO;;AAGT,MAAa,YAAY,OACvB,QACA,YAC8B;AAC9B,KAAI;AAGF,QAFe,aAAa,OAAO,CAEtB,YAAY;GACvB,QAAQ,OAAO;GACf,WAAW,OAAO;GAClB,MAAM,OAAO;GACb,IAAI,QAAQ;GACZ,SAAS,QAAQ;GACjB,MAAM,QAAQ;GACd,MAAM,QAAQ,QAAQ,QAAQ;GAC9B,mBAAmB,QAAQ,UACvB,CAAC;IAAE,KAAK;IAAY,OAAO,QAAQ;IAAS,CAAC,GAC7C;GACL,CAAC;AAEF,SAAO,EAAE,SAAS,MAAM;UACjB,OAAO;AACd,MAAI,QAAQ,CAAC,MAAM,kCAAkC;GACnD,SAAS,QAAQ,WAAW;GAC5B,OAAO,iBAAiB,QAAQ,MAAM,UAAU;GACjD,CAAC;AACF,SAAO;GACL,SAAS;GACT;GACA,cAAc;GACf;;;AAIL,MAAa,aAAa;CACxB,cAAc;AACZ,iBAAe;AACf,iBAAe;AACf,gBAAc,WACZ,IAAI,YAAY,IAAI,OAAO;;CAE/B,cACE,SACA;AACA,eAAa;;CAEf,UAAU,QAAkB;AAC1B,iBAAe;;CAElB"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"contact.js","names":[],"sources":["../../../src/libs/email/contact.ts"],"sourcesContent":["'use server';\n\nimport { getEmailConfig, sendEmail } from './client';\nimport { escapeHtml, formatMultilineHtml } from './utils';\nimport type { SubmitContactFormResult } from './types';\n\nconst CONTACT_MISSING_CONFIG =\n 'Email service is not configured. Please contact us directly at contact@contractspec.io.';\nconst CONTACT_SEND_ERROR =\n 'Failed to send message. Please contact us directly at contact@contractspec.io.';\n\nexport const submitContactForm = async (\n formData: FormData\n): Promise<SubmitContactFormResult> => {\n const name = (formData.get('name') ?? '').toString().trim();\n const email = (formData.get('email') ?? '').toString().trim();\n const message = (formData.get('message') ?? '').toString().trim();\n\n if (!email) {\n return {\n success: false,\n text: 'Please fill in all required fields.',\n };\n }\n\n const configResult = getEmailConfig();\n if (!configResult.ok || !configResult.config) {\n return {\n success: false,\n text: configResult.errorMessage ?? CONTACT_MISSING_CONFIG,\n };\n }\n\n const senderName = name || email;\n const emailContentText = `\nNew contact form submission from ${senderName}\n\nContact Information:\n- Name: ${name || 'Not provided'}\n- Email: ${email}\n\nMessage:\n${message || 'No message provided'}\n\n---\nSubmitted via ContractSpec contact form\n `.trim();\n\n const emailContentHtml = `\n <div style=\"font-family: sans-serif; max-width: 640px; margin: 0 auto;\">\n <h1 style=\"color: #8b5cf6; margin-bottom: 12px;\">New contact form submission</h1>\n <p style=\"margin: 0 0 12px;\">From ${escapeHtml(senderName)}</p>\n <h2 style=\"color: #8b5cf6; margin: 16px 0 8px;\">Contact Information</h2>\n <ul style=\"padding-left: 16px; line-height: 1.6; margin: 0 0 16px;\">\n <li>Name: ${escapeHtml(name || 'Not provided')}</li>\n <li>Email: ${escapeHtml(email)}</li>\n </ul>\n <h2 style=\"color: #8b5cf6; margin: 16px 0 8px;\">Message</h2>\n <div style=\"border: 1px solid #e5e7eb; border-radius: 8px; padding: 12px; background: #f9fafb; white-space: pre-wrap; line-height: 1.6;\">\n ${message ? formatMultilineHtml(message) : 'No message provided'}\n </div>\n <p style=\"color: #6b7280; font-size: 12px; margin-top: 20px;\">Submitted via ContractSpec contact form</p>\n </div>\n `;\n\n const sendResult = await sendEmail(configResult.config, {\n to: [configResult.config.teamInbox],\n subject: `New Contact Form Message from ${senderName}`,\n text: emailContentText,\n html: emailContentHtml,\n replyTo: email,\n context: 'contact-form',\n });\n\n if (!sendResult.success) {\n return { success: false, text: CONTACT_SEND_ERROR };\n }\n\n return { success: true, text: 'Message sent successfully!' };\n};\n"],"mappings":";;;;;;AAMA,MAAM,yBACJ;AACF,MAAM,qBACJ;AAEF,MAAa,oBAAoB,OAC/B,aACqC;CACrC,MAAM,QAAQ,SAAS,IAAI,OAAO,IAAI,IAAI,UAAU,CAAC,MAAM;CAC3D,MAAM,SAAS,SAAS,IAAI,QAAQ,IAAI,IAAI,UAAU,CAAC,MAAM;CAC7D,MAAM,WAAW,SAAS,IAAI,UAAU,IAAI,IAAI,UAAU,CAAC,MAAM;AAEjE,KAAI,CAAC,MACH,QAAO;EACL,SAAS;EACT,MAAM;EACP;CAGH,MAAM,eAAe,gBAAgB;AACrC,KAAI,CAAC,aAAa,MAAM,CAAC,aAAa,OACpC,QAAO;EACL,SAAS;EACT,MAAM,aAAa,gBAAgB;EACpC;CAGH,MAAM,aAAa,QAAQ;CAC3B,MAAM,mBAAmB;mCACQ,WAAW;;;UAGpC,QAAQ,eAAe;WACtB,MAAM;;;EAGf,WAAW,sBAAsB;;;;IAI/B,MAAM;CAER,MAAM,mBAAmB;;;0CAGe,WAAW,WAAW,CAAC;;;oBAG7C,WAAW,QAAQ,eAAe,CAAC;qBAClC,WAAW,MAAM,CAAC;;;;UAI7B,UAAU,oBAAoB,QAAQ,GAAG,sBAAsB;;;;;AAevE,KAAI,EATe,MAAM,UAAU,aAAa,QAAQ;EACtD,IAAI,CAAC,aAAa,OAAO,UAAU;EACnC,SAAS,iCAAiC;EAC1C,MAAM;EACN,MAAM;EACN,SAAS;EACT,SAAS;EACV,CAAC,EAEc,QACd,QAAO;EAAE,SAAS;EAAO,MAAM;EAAoB;AAGrD,QAAO;EAAE,SAAS;EAAM,MAAM;EAA8B"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"newsletter.js","names":[],"sources":["../../../src/libs/email/newsletter.ts"],"sourcesContent":["'use server';\n\nimport { getEmailConfig, sendEmail } from './client';\nimport { formatMultilineHtml } from './utils';\nimport type { SubmitNewsletterResult } from './types';\n\nconst NEWSLETTER_MISSING_CONFIG =\n 'Newsletter service is not configured. Please try again later.';\nconst NEWSLETTER_SEND_ERROR =\n 'Failed to subscribe. Please try again later or contact us directly.';\n\nexport const subscribeToNewsletter = async (\n formData: FormData\n): Promise<SubmitNewsletterResult> => {\n const email = (formData.get('email') ?? '').toString().trim();\n\n if (!email || !email.includes('@')) {\n return {\n success: false,\n text: 'Please enter a valid email address.',\n };\n }\n\n const configResult = getEmailConfig();\n if (!configResult.ok || !configResult.config) {\n return {\n success: false,\n text: configResult.errorMessage ?? NEWSLETTER_MISSING_CONFIG,\n };\n }\n\n const welcomeText = `\nWelcome to ContractSpec!\n\nThanks for subscribing to our newsletter. You'll receive updates on:\n\n• New integrations (Stripe, OpenAI, Qdrant, and more)\n• Product features and improvements\n• New templates and examples\n• Architecture insights and best practices\n• Documentation updates\n\nStay tuned for exciting updates!\n\n---\nContractSpec Team\nhttps://contractspec.io\n\nUnsubscribe: Reply to this email with \"unsubscribe\"\n `.trim();\n\n const welcomeHtml = `\n <div style=\"font-family: sans-serif; max-width: 640px; margin: 0 auto;\">\n <h1 style=\"color: #8b5cf6;\">Welcome to ContractSpec!</h1>\n <p>Thanks for subscribing to our newsletter. You'll receive updates on:</p>\n <ul style=\"line-height: 1.8;\">\n <li>New integrations (Stripe, OpenAI, Qdrant, and more)</li>\n <li>Product features and improvements</li>\n <li>New templates and examples</li>\n <li>Architecture insights and best practices</li>\n <li>Documentation updates</li>\n </ul>\n <p>Stay tuned for exciting updates!</p>\n <hr style=\"margin: 30px 0; border: none; border-top: 1px solid #e5e7eb;\" />\n <p style=\"color: #6b7280; font-size: 14px;\">\n ContractSpec Team<br />\n <a href=\"https://contractspec.io\" style=\"color: #8b5cf6;\">contractspec.io</a>\n </p>\n <p style=\"color: #9ca3af; font-size: 12px;\">\n To unsubscribe, reply to this email with \"unsubscribe\"\n </p>\n </div>\n `;\n\n const userSend = await sendEmail(configResult.config, {\n to: [{ email }],\n subject: 'Welcome to ContractSpec Newsletter',\n text: welcomeText,\n html: welcomeHtml,\n context: 'newsletter-welcome',\n });\n\n if (!userSend.success) {\n return { success: false, text: NEWSLETTER_SEND_ERROR };\n }\n\n const teamNotificationText = `New newsletter subscription from: ${email}`;\n const teamNotificationHtml = `\n <div style=\"font-family: sans-serif; max-width: 640px; margin: 0 auto;\">\n <p style=\"margin: 0 0 8px;\">New newsletter subscription</p>\n <p style=\"margin: 0;\"><strong>Email:</strong> ${formatMultilineHtml(email)}</p>\n </div>\n `;\n\n const teamSend = await sendEmail(configResult.config, {\n to: [configResult.config.teamInbox],\n subject: `New Newsletter Subscription: ${email}`,\n text: teamNotificationText,\n html: teamNotificationHtml,\n context: 'newsletter-team-notification',\n });\n\n if (!teamSend.success) {\n return { success: false, text: NEWSLETTER_SEND_ERROR };\n }\n\n return { success: true, text: 'Successfully subscribed!' };\n};\n"],"mappings":";;;;;;AAMA,MAAM,4BACJ;AACF,MAAM,wBACJ;AAEF,MAAa,wBAAwB,OACnC,aACoC;CACpC,MAAM,SAAS,SAAS,IAAI,QAAQ,IAAI,IAAI,UAAU,CAAC,MAAM;AAE7D,KAAI,CAAC,SAAS,CAAC,MAAM,SAAS,IAAI,CAChC,QAAO;EACL,SAAS;EACT,MAAM;EACP;CAGH,MAAM,eAAe,gBAAgB;AACrC,KAAI,CAAC,aAAa,MAAM,CAAC,aAAa,OACpC,QAAO;EACL,SAAS;EACT,MAAM,aAAa,gBAAgB;EACpC;CAGH,MAAM,cAAc;;;;;;;;;;;;;;;;;;IAkBlB,MAAM;AAiCR,KAAI,EARa,MAAM,UAAU,aAAa,QAAQ;EACpD,IAAI,CAAC,EAAE,OAAO,CAAC;EACf,SAAS;EACT,MAAM;EACN,MA3BkB;;;;;;;;;;;;;;;;;;;;;;EA4BlB,SAAS;EACV,CAAC,EAEY,QACZ,QAAO;EAAE,SAAS;EAAO,MAAM;EAAuB;CAGxD,MAAM,uBAAuB,qCAAqC;CAClE,MAAM,uBAAuB;;;sDAGuB,oBAAoB,MAAM,CAAC;;;AAY/E,KAAI,EARa,MAAM,UAAU,aAAa,QAAQ;EACpD,IAAI,CAAC,aAAa,OAAO,UAAU;EACnC,SAAS,gCAAgC;EACzC,MAAM;EACN,MAAM;EACN,SAAS;EACV,CAAC,EAEY,QACZ,QAAO;EAAE,SAAS;EAAO,MAAM;EAAuB;AAGxD,QAAO;EAAE,SAAS;EAAM,MAAM;EAA4B"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"utils.js","names":[],"sources":["../../../src/libs/email/utils.ts"],"sourcesContent":["export const escapeHtml = (value: string): string =>\n value\n .replaceAll('&', '&amp;')\n .replaceAll('<', '&lt;')\n .replaceAll('>', '&gt;');\n\nexport const formatMultilineHtml = (value: string): string =>\n escapeHtml(value).replaceAll('\\n', '<br />');\n"],"mappings":";AAAA,MAAa,cAAc,UACzB,MACG,WAAW,KAAK,QAAQ,CACxB,WAAW,KAAK,OAAO,CACvB,WAAW,KAAK,OAAO;AAE5B,MAAa,uBAAuB,UAClC,WAAW,MAAM,CAAC,WAAW,MAAM,SAAS"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"waitlist-application.js","names":[],"sources":["../../../src/libs/email/waitlist-application.ts"],"sourcesContent":["'use server';\n\nimport { getEmailConfig, sendEmail } from './client';\nimport { escapeHtml, formatMultilineHtml } from './utils';\nimport type { SubmitWaitlistApplicationResult } from './types';\n\nconst APPLICATION_MISSING_CONFIG =\n 'Waitlist application service is not configured. Please try again later.';\nconst APPLICATION_SEND_ERROR =\n 'Failed to submit application. Please try again later or contact us directly.';\n\nexport const submitWaitlistApplication = async (\n formData: FormData\n): Promise<SubmitWaitlistApplicationResult> => {\n const email = (formData.get('email') ?? '').toString().trim();\n const name = (formData.get('name') ?? '').toString().trim();\n const company = (formData.get('company') ?? '').toString().trim();\n const role = (formData.get('role') ?? '').toString().trim();\n const useCase = (formData.get('useCase') ?? '').toString().trim();\n const currentStack = (formData.get('currentStack') ?? '').toString().trim();\n const whatBuilding = (formData.get('whatBuilding') ?? '').toString().trim();\n const whatSolving = (formData.get('whatSolving') ?? '').toString().trim();\n const teamSize = (formData.get('teamSize') ?? '').toString().trim();\n const timeline = (formData.get('timeline') ?? '').toString().trim();\n\n const openToSessions = formData.get('openToSessions') === 'on';\n const okayWithCaseStudies = formData.get('okayWithCaseStudies') === 'on';\n\n if (!email || !email.includes('@')) {\n return {\n success: false,\n text: 'Please enter a valid email address.',\n };\n }\n\n if (!name || !whatBuilding || !whatSolving) {\n return {\n success: false,\n text: 'Please fill in all required fields.',\n };\n }\n\n const configResult = getEmailConfig();\n if (!configResult.ok || !configResult.config) {\n return {\n success: false,\n text: configResult.errorMessage ?? APPLICATION_MISSING_CONFIG,\n };\n }\n\n const applicantText = `\nYou're on the list.\n\nThanks for applying to the ContractSpec design partner program. We're slowly onboarding design partners in waves. If your use case is a good fit, we'll reach out personally.\n\nWhat happens next:\n• We review applications weekly\n• If selected, we'll reach out via email to schedule an intro call\n• During early access, you'll get hands-on support and influence over the roadmap\n\nIn the meantime:\n• Check out our docs: https://contractspec.io/docs\n• Book a demo call: https://contractspec.io/contact\n\nWe're excited about the possibility of working together!\n\n---\nContractSpec Team\nhttps://contractspec.io\n `.trim();\n\n const applicantHtml = `\n <div style=\"font-family: sans-serif; max-width: 640px; margin: 0 auto;\">\n <h1 style=\"color: #8b5cf6;\">You're on the list.</h1>\n <p>Thanks for applying to the ContractSpec design partner program. We're slowly onboarding design partners in waves. If your use case is a good fit, we'll reach out personally.</p>\n <h2 style=\"color: #8b5cf6; margin-top: 24px;\">What happens next:</h2>\n <ul style=\"line-height: 1.8;\">\n <li>We review applications weekly</li>\n <li>If selected, we'll reach out via email to schedule an intro call</li>\n <li>During early access, you'll get hands-on support and influence over the roadmap</li>\n </ul>\n <h2 style=\"color: #8b5cf6; margin-top: 24px;\">In the meantime:</h2>\n <ul style=\"line-height: 1.8;\">\n <li>Check out our <a href=\"https://contractspec.io/docs\" style=\"color: #8b5cf6;\">docs</a></li>\n <li>Book a demo call: <a href=\"https://contractspec.io/contact\" style=\"color: #8b5cf6;\">contractspec.io/contact</a></li>\n </ul>\n <p>We're excited about the possibility of working together!</p>\n <hr style=\"margin: 30px 0; border: none; border-top: 1px solid #e5e7eb;\" />\n <p style=\"color: #6b7280; font-size: 14px;\">\n ContractSpec Team<br />\n <a href=\"https://contractspec.io\" style=\"color: #8b5cf6;\">contractspec.io</a>\n </p>\n </div>\n `;\n\n const applicantSend = await sendEmail(configResult.config, {\n to: [{ email }],\n subject: \"You're on the ContractSpec design partner waitlist!\",\n text: applicantText,\n html: applicantHtml,\n context: 'waitlist-application-welcome',\n });\n\n if (!applicantSend.success) {\n return { success: false, text: APPLICATION_SEND_ERROR };\n }\n\n const preferencesText = `\nOpen to 1:1 product/design sessions: ${openToSessions ? 'Yes' : 'No'}\nOkay with anonymized case studies: ${okayWithCaseStudies ? 'Yes' : 'No'}\n `.trim();\n\n const teamEmailText = `\nNew Design Partner Waitlist Application\n\nContact Information:\n- Name: ${name}\n- Email: ${email}\n${company ? `- Company/Project: ${company}` : ''}\n${role ? `- Role: ${role}` : ''}\n\nApplication Details:\n- What are you building with AI today?\n${whatBuilding}\n\n- What do you hope ContractSpec will solve for you?\n${whatSolving}\n\n- Primary use case: ${useCase || 'Not specified'}\n- Current stack: ${currentStack || 'Not specified'}\n- Team Size: ${teamSize || 'Not specified'}\n- Timeline: ${timeline || 'Not specified'}\n\nPreferences:\n- Open to 1:1 product/design sessions: ${openToSessions ? 'Yes' : 'No'}\n- Okay with anonymized case studies: ${okayWithCaseStudies ? 'Yes' : 'No'}\n\n---\nSubmitted via ContractSpec waitlist application form\n `.trim();\n\n const teamEmailHtml = `\n <div style=\"font-family: sans-serif; max-width: 720px; margin: 0 auto;\">\n <h1 style=\"color: #8b5cf6;\">New Design Partner Waitlist Application</h1>\n <h2 style=\"color: #8b5cf6; margin: 16px 0 8px;\">Contact Information</h2>\n <ul style=\"padding-left: 16px; line-height: 1.6; margin: 0 0 16px;\">\n <li>Name: ${escapeHtml(name)}</li>\n <li>Email: ${escapeHtml(email)}</li>\n ${company ? `<li>Company/Project: ${escapeHtml(company)}</li>` : ''}\n ${role ? `<li>Role: ${escapeHtml(role)}</li>` : ''}\n </ul>\n <h2 style=\"color: #8b5cf6; margin: 16px 0 8px;\">Application Details</h2>\n <p style=\"margin: 0 0 8px; font-weight: 600;\">What are you building with AI today?</p>\n <div style=\"border: 1px solid #e5e7eb; border-radius: 8px; padding: 12px; background: #f9fafb; white-space: pre-wrap; line-height: 1.6;\">\n ${formatMultilineHtml(whatBuilding)}\n </div>\n <p style=\"margin: 16px 0 8px; font-weight: 600;\">What do you hope ContractSpec will solve for you?</p>\n <div style=\"border: 1px solid #e5e7eb; border-radius: 8px; padding: 12px; background: #f9fafb; white-space: pre-wrap; line-height: 1.6;\">\n ${formatMultilineHtml(whatSolving)}\n </div>\n <ul style=\"padding-left: 16px; line-height: 1.6; margin: 16px 0;\">\n <li>Primary use case: ${escapeHtml(useCase || 'Not specified')}</li>\n <li>Current stack: ${escapeHtml(currentStack || 'Not specified')}</li>\n <li>Team Size: ${escapeHtml(teamSize || 'Not specified')}</li>\n <li>Timeline: ${escapeHtml(timeline || 'Not specified')}</li>\n </ul>\n <h2 style=\"color: #8b5cf6; margin: 16px 0 8px;\">Preferences</h2>\n <div style=\"border: 1px solid #e5e7eb; border-radius: 8px; padding: 12px; background: #f9fafb; line-height: 1.6;\">\n ${formatMultilineHtml(preferencesText)}\n </div>\n <p style=\"color: #6b7280; font-size: 12px; margin-top: 20px;\">Submitted via ContractSpec waitlist application form</p>\n </div>\n `;\n\n const teamSend = await sendEmail(configResult.config, {\n to: [configResult.config.teamInbox],\n subject: `New Design Partner Application: ${name} (${email})`,\n text: teamEmailText,\n html: teamEmailHtml,\n replyTo: email,\n context: 'waitlist-application-team-notification',\n });\n\n if (!teamSend.success) {\n return { success: false, text: APPLICATION_SEND_ERROR };\n }\n\n return {\n success: true,\n text: 'Application submitted successfully!',\n };\n};\n"],"mappings":";;;;;;AAMA,MAAM,6BACJ;AACF,MAAM,yBACJ;AAEF,MAAa,4BAA4B,OACvC,aAC6C;CAC7C,MAAM,SAAS,SAAS,IAAI,QAAQ,IAAI,IAAI,UAAU,CAAC,MAAM;CAC7D,MAAM,QAAQ,SAAS,IAAI,OAAO,IAAI,IAAI,UAAU,CAAC,MAAM;CAC3D,MAAM,WAAW,SAAS,IAAI,UAAU,IAAI,IAAI,UAAU,CAAC,MAAM;CACjE,MAAM,QAAQ,SAAS,IAAI,OAAO,IAAI,IAAI,UAAU,CAAC,MAAM;CAC3D,MAAM,WAAW,SAAS,IAAI,UAAU,IAAI,IAAI,UAAU,CAAC,MAAM;CACjE,MAAM,gBAAgB,SAAS,IAAI,eAAe,IAAI,IAAI,UAAU,CAAC,MAAM;CAC3E,MAAM,gBAAgB,SAAS,IAAI,eAAe,IAAI,IAAI,UAAU,CAAC,MAAM;CAC3E,MAAM,eAAe,SAAS,IAAI,cAAc,IAAI,IAAI,UAAU,CAAC,MAAM;CACzE,MAAM,YAAY,SAAS,IAAI,WAAW,IAAI,IAAI,UAAU,CAAC,MAAM;CACnE,MAAM,YAAY,SAAS,IAAI,WAAW,IAAI,IAAI,UAAU,CAAC,MAAM;CAEnE,MAAM,iBAAiB,SAAS,IAAI,iBAAiB,KAAK;CAC1D,MAAM,sBAAsB,SAAS,IAAI,sBAAsB,KAAK;AAEpE,KAAI,CAAC,SAAS,CAAC,MAAM,SAAS,IAAI,CAChC,QAAO;EACL,SAAS;EACT,MAAM;EACP;AAGH,KAAI,CAAC,QAAQ,CAAC,gBAAgB,CAAC,YAC7B,QAAO;EACL,SAAS;EACT,MAAM;EACP;CAGH,MAAM,eAAe,gBAAgB;AACrC,KAAI,CAAC,aAAa,MAAM,CAAC,aAAa,OACpC,QAAO;EACL,SAAS;EACT,MAAM,aAAa,gBAAgB;EACpC;CAGH,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;IAmBpB,MAAM;AAkCR,KAAI,EARkB,MAAM,UAAU,aAAa,QAAQ;EACzD,IAAI,CAAC,EAAE,OAAO,CAAC;EACf,SAAS;EACT,MAAM;EACN,MA5BoB;;;;;;;;;;;;;;;;;;;;;;;EA6BpB,SAAS;EACV,CAAC,EAEiB,QACjB,QAAO;EAAE,SAAS;EAAO,MAAM;EAAwB;CAGzD,MAAM,kBAAkB;uCACa,iBAAiB,QAAQ,KAAK;qCAChC,sBAAsB,QAAQ,KAAK;IACpE,MAAM;CAER,MAAM,gBAAgB;;;;UAId,KAAK;WACJ,MAAM;EACf,UAAU,sBAAsB,YAAY,GAAG;EAC/C,OAAO,WAAW,SAAS,GAAG;;;;EAI9B,aAAa;;;EAGb,YAAY;;sBAEQ,WAAW,gBAAgB;mBAC9B,gBAAgB,gBAAgB;eACpC,YAAY,gBAAgB;cAC7B,YAAY,gBAAgB;;;yCAGD,iBAAiB,QAAQ,KAAK;uCAChC,sBAAsB,QAAQ,KAAK;;;;IAItE,MAAM;CAER,MAAM,gBAAgB;;;;;oBAKJ,WAAW,KAAK,CAAC;qBAChB,WAAW,MAAM,CAAC;UAC7B,UAAU,wBAAwB,WAAW,QAAQ,CAAC,SAAS,GAAG;UAClE,OAAO,aAAa,WAAW,KAAK,CAAC,SAAS,GAAG;;;;;UAKjD,oBAAoB,aAAa,CAAC;;;;UAIlC,oBAAoB,YAAY,CAAC;;;gCAGX,WAAW,WAAW,gBAAgB,CAAC;6BAC1C,WAAW,gBAAgB,gBAAgB,CAAC;yBAChD,WAAW,YAAY,gBAAgB,CAAC;wBACzC,WAAW,YAAY,gBAAgB,CAAC;;;;UAItD,oBAAoB,gBAAgB,CAAC;;;;;AAe7C,KAAI,EATa,MAAM,UAAU,aAAa,QAAQ;EACpD,IAAI,CAAC,aAAa,OAAO,UAAU;EACnC,SAAS,mCAAmC,KAAK,IAAI,MAAM;EAC3D,MAAM;EACN,MAAM;EACN,SAAS;EACT,SAAS;EACV,CAAC,EAEY,QACZ,QAAO;EAAE,SAAS;EAAO,MAAM;EAAwB;AAGzD,QAAO;EACL,SAAS;EACT,MAAM;EACP"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"waitlist.js","names":[],"sources":["../../../src/libs/email/waitlist.ts"],"sourcesContent":["'use server';\n\nimport { getEmailConfig, sendEmail } from './client';\nimport { formatMultilineHtml } from './utils';\nimport type { SubmitWaitlistResult } from './types';\n\nconst WAITLIST_MISSING_CONFIG =\n 'Waitlist service is not configured. Please try again later.';\nconst WAITLIST_SEND_ERROR =\n 'Failed to join waitlist. Please try again later or contact us directly.';\n\nexport const joinWaitlist = async (\n formData: FormData\n): Promise<SubmitWaitlistResult> => {\n const email = (formData.get('email') ?? '').toString().trim();\n\n if (!email || !email.includes('@')) {\n return {\n success: false,\n text: 'Please enter a valid email address.',\n };\n }\n\n const configResult = getEmailConfig();\n if (!configResult.ok || !configResult.config) {\n return {\n success: false,\n text: configResult.errorMessage ?? WAITLIST_MISSING_CONFIG,\n };\n }\n\n const waitlistText = `\nYou're on the waitlist!\n\nThanks for joining the ContractSpec waitlist. You're now in line for early access to:\n\n• Stabilize your AI-generated code with ContractSpec\n• Multi-surface consistency (API, DB, UI, events)\n• Safe regeneration without breaking changes\n• AI governance and contract enforcement\n\nWe'll notify you as soon as early access is available. In the meantime, you can:\n\n• Check out our docs: https://contractspec.io/docs\n• Follow our progress on GitHub\n• Book a demo call to see ContractSpec in action\n\nWe're excited to have you on board!\n\n---\nContractSpec Team\nhttps://contractspec.io\n\nTo remove yourself from the waitlist, reply to this email with \"remove\"\n `.trim();\n\n const waitlistHtml = `\n <div style=\"font-family: sans-serif; max-width: 640px; margin: 0 auto;\">\n <h1 style=\"color: #8b5cf6;\">You're on the waitlist!</h1>\n <p>Thanks for joining the ContractSpec waitlist. You're now in line for early access to:</p>\n <ul style=\"line-height: 1.8;\">\n <li>Stabilize your AI-generated code with ContractSpec</li>\n <li>Multi-surface consistency (API, DB, UI, events)</li>\n <li>Safe regeneration without breaking changes</li>\n <li>AI governance and contract enforcement</li>\n </ul>\n <p>We'll notify you as soon as early access is available. In the meantime, you can:</p>\n <ul style=\"line-height: 1.8;\">\n <li>Check out our <a href=\"https://contractspec.io/docs\" style=\"color: #8b5cf6;\">docs</a></li>\n <li>Follow our progress on GitHub</li>\n <li>Book a demo call to see ContractSpec in action</li>\n </ul>\n <p>We're excited to have you on board!</p>\n <hr style=\"margin: 30px 0; border: none; border-top: 1px solid #e5e7eb;\" />\n <p style=\"color: #6b7280; font-size: 14px;\">\n ContractSpec Team<br />\n <a href=\"https://contractspec.io\" style=\"color: #8b5cf6;\">contractspec.io</a>\n </p>\n <p style=\"color: #9ca3af; font-size: 12px;\">\n To remove yourself from the waitlist, reply to this email with \"remove\"\n </p>\n </div>\n `;\n\n const userSend = await sendEmail(configResult.config, {\n to: [{ email }],\n subject: \"You're on the ContractSpec waitlist!\",\n text: waitlistText,\n html: waitlistHtml,\n context: 'waitlist-welcome',\n });\n\n if (!userSend.success) {\n return { success: false, text: WAITLIST_SEND_ERROR };\n }\n\n const teamNotificationText = `New waitlist signup from: ${email}`;\n const teamNotificationHtml = `\n <div style=\"font-family: sans-serif; max-width: 640px; margin: 0 auto;\">\n <p style=\"margin: 0 0 8px;\">New waitlist signup</p>\n <p style=\"margin: 0;\"><strong>Email:</strong> ${formatMultilineHtml(email)}</p>\n </div>\n `;\n\n const teamSend = await sendEmail(configResult.config, {\n to: [configResult.config.teamInbox],\n subject: `New Waitlist Signup: ${email}`,\n text: teamNotificationText,\n html: teamNotificationHtml,\n context: 'waitlist-team-notification',\n });\n\n if (!teamSend.success) {\n return { success: false, text: WAITLIST_SEND_ERROR };\n }\n\n return { success: true, text: 'Successfully joined waitlist!' };\n};\n"],"mappings":";;;;;;AAMA,MAAM,0BACJ;AACF,MAAM,sBACJ;AAEF,MAAa,eAAe,OAC1B,aACkC;CAClC,MAAM,SAAS,SAAS,IAAI,QAAQ,IAAI,IAAI,UAAU,CAAC,MAAM;AAE7D,KAAI,CAAC,SAAS,CAAC,MAAM,SAAS,IAAI,CAChC,QAAO;EACL,SAAS;EACT,MAAM;EACP;CAGH,MAAM,eAAe,gBAAgB;AACrC,KAAI,CAAC,aAAa,MAAM,CAAC,aAAa,OACpC,QAAO;EACL,SAAS;EACT,MAAM,aAAa,gBAAgB;EACpC;CAGH,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;IAuBnB,MAAM;AAsCR,KAAI,EARa,MAAM,UAAU,aAAa,QAAQ;EACpD,IAAI,CAAC,EAAE,OAAO,CAAC;EACf,SAAS;EACT,MAAM;EACN,MAhCmB;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiCnB,SAAS;EACV,CAAC,EAEY,QACZ,QAAO;EAAE,SAAS;EAAO,MAAM;EAAqB;CAGtD,MAAM,uBAAuB,6BAA6B;CAC1D,MAAM,uBAAuB;;;sDAGuB,oBAAoB,MAAM,CAAC;;;AAY/E,KAAI,EARa,MAAM,UAAU,aAAa,QAAQ;EACpD,IAAI,CAAC,aAAa,OAAO,UAAU;EACnC,SAAS,wBAAwB;EACjC,MAAM;EACN,MAAM;EACN,SAAS;EACV,CAAC,EAEY,QACZ,QAAO;EAAE,SAAS;EAAO,MAAM;EAAqB;AAGtD,QAAO;EAAE,SAAS;EAAM,MAAM;EAAiC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"pricing-examples.js","names":[],"sources":["../../src/libs/pricing-examples.ts"],"sourcesContent":["/**\n * Tentative pricing example values for UI display.\n * These are examples only and subject to change based on learnings from design partners.\n */\n\nexport const PRICING_EXAMPLES = {\n free: {\n regenerationsPerMonth: 200,\n aiActionsPerMonth: 100,\n projects: 1,\n },\n builder: {\n regenerationsPerMonthHint: '1,000–2,000+',\n aiActionsPerMonthHint: '1,000+',\n },\n team: {\n description: 'Higher limits + cheaper per-regen at scale',\n },\n} as const;\n"],"mappings":";;;;;AAKA,MAAa,mBAAmB;CAC9B,MAAM;EACJ,uBAAuB;EACvB,mBAAmB;EACnB,UAAU;EACX;CACD,SAAS;EACP,2BAA2B;EAC3B,uBAAuB;EACxB;CACD,MAAM,EACJ,aAAa,8CACd;CACF"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"engine.js","names":[],"sources":["../../src/registry/engine.ts"],"sourcesContent":["import {\n createDefaultTransformEngine,\n registerBasicValidation,\n registerDefaultReactRenderer,\n registerReactToMarkdownRenderer,\n type TransformEngine,\n} from '@contractspec/lib.contracts/presentations';\nimport { componentMap } from './registry';\nimport type { ComponentMap } from './types';\n\n/**\n * Create and configure the TransformEngine for web-landing presentations.\n * Includes React and Markdown renderers with component map registration.\n */\nexport function createPresentationEngine(\n customComponentMap?: ComponentMap\n): TransformEngine {\n const engine = createDefaultTransformEngine();\n\n // Register React renderer\n registerDefaultReactRenderer(engine);\n\n // Register basic validation\n registerBasicValidation(engine);\n\n // Register React-to-markdown renderer with component map\n // This enables rendering React components to markdown for LLM consumption\n const mapToUse = customComponentMap ?? componentMap;\n registerReactToMarkdownRenderer(engine, mapToUse);\n\n return engine;\n}\n\n/**\n * Singleton engine instance for the app.\n * Use this for rendering presentations.\n */\nexport const presentationEngine = createPresentationEngine();\n"],"mappings":";;;;;;;;AAcA,SAAgB,yBACd,oBACiB;CACjB,MAAM,SAAS,8BAA8B;AAG7C,8BAA6B,OAAO;AAGpC,yBAAwB,OAAO;AAK/B,iCAAgC,QADf,sBAAsB,aACU;AAEjD,QAAO;;;;;;AAOT,MAAa,qBAAqB,0BAA0B"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"factory.js","names":[],"sources":["../../src/registry/factory.ts"],"sourcesContent":["import {\n type Owner,\n OwnersEnum,\n type Stability,\n StabilityEnum,\n type Tag,\n TagsEnum,\n} from '@contractspec/lib.contracts/ownership';\nimport type {\n PresentationSourceComponentReact,\n PresentationSpec,\n PresentationTarget,\n} from '@contractspec/lib.contracts/presentations';\n\n/**\n * Options for creating a React component presentation.\n */\nexport interface CreateComponentPresentationOptions {\n /** Fully-qualified spec key (e.g., \"web-landing.home\") */\n key: string;\n /** Component key resolved by host componentMap */\n componentKey: string;\n /** Short human-friendly summary */\n description: string;\n /** Business goal: why this exists */\n goal: string;\n /** Background, constraints, scope edges */\n context: string;\n /** Breaking changes => bump version @default '1.0.0' */\n version?: string;\n /** Lifecycle marker @default StabilityEnum.Stable */\n stability?: Stability;\n /** Owners for CODEOWNERS / on-call @default [OwnersEnum.PlatformCore] */\n owners?: Owner[];\n /** Search tags, grouping, docs navigation @default [] */\n tags?: Tag[];\n /** Render targets @default ['react', 'markdown'] */\n targets?: PresentationTarget[];\n}\n\n/**\n * Creates a PresentationSpec for a React component with all required metadata.\n *\n * @param opts - Configuration options for the presentation\n * @returns A fully-typed PresentationSpec\n */\nexport function createComponentPresentation(\n opts: CreateComponentPresentationOptions\n): PresentationSpec {\n const source: PresentationSourceComponentReact = {\n type: 'component',\n framework: 'react',\n componentKey: opts.componentKey,\n };\n\n return {\n meta: {\n key: opts.key,\n version: opts.version ?? '1.0.0',\n description: opts.description,\n goal: opts.goal,\n context: opts.context,\n stability: opts.stability ?? StabilityEnum.Stable,\n owners: opts.owners ?? [OwnersEnum.PlatformCore],\n tags: opts.tags ?? [],\n },\n source,\n targets: opts.targets ?? ['react', 'markdown'],\n };\n}\n\n/**\n * Helper to derive tags from a URL path.\n * Example: \"/docs/libraries/ai-agent\" -> [\"docs\", \"libraries\", \"ai-agent\"]\n */\nexport function tagsFromPath(path: string): Tag[] {\n return path\n .split('/')\n .filter((segment) => segment.length > 0)\n .map((segment) => segment as Tag);\n}\n\n/**\n * Default goal for documentation pages.\n */\nexport const DOCS_GOAL =\n 'Educate developers on ContractSpec usage and concepts';\n\n/**\n * Default context for documentation pages.\n */\nexport const DOCS_CONTEXT =\n 'Part of the ContractSpec documentation site, rendered on contractspec.io';\n\n/**\n * Default goal for marketing/landing pages.\n */\nexport const MARKETING_GOAL =\n 'Convert visitors into ContractSpec users and customers';\n\n/**\n * Default context for marketing pages.\n */\nexport const MARKETING_CONTEXT =\n 'Marketing content on contractspec.io, designed for conversion';\n\n/**\n * Default tags for documentation pages.\n */\nexport const DOCS_TAGS: Tag[] = [TagsEnum.Docs];\n"],"mappings":";;;;;;;;;AA8CA,SAAgB,4BACd,MACkB;CAClB,MAAM,SAA2C;EAC/C,MAAM;EACN,WAAW;EACX,cAAc,KAAK;EACpB;AAED,QAAO;EACL,MAAM;GACJ,KAAK,KAAK;GACV,SAAS,KAAK,WAAW;GACzB,aAAa,KAAK;GAClB,MAAM,KAAK;GACX,SAAS,KAAK;GACd,WAAW,KAAK,aAAa,cAAc;GAC3C,QAAQ,KAAK,UAAU,CAAC,WAAW,aAAa;GAChD,MAAM,KAAK,QAAQ,EAAE;GACtB;EACD;EACA,SAAS,KAAK,WAAW,CAAC,SAAS,WAAW;EAC/C;;;;;;AAOH,SAAgB,aAAa,MAAqB;AAChD,QAAO,KACJ,MAAM,IAAI,CACV,QAAQ,YAAY,QAAQ,SAAS,EAAE,CACvC,KAAK,YAAY,QAAe;;;;;AAMrC,MAAa,YACX;;;;AAKF,MAAa,eACX;;;;AAKF,MAAa,iBACX;;;;AAKF,MAAa,oBACX;;;;AAKF,MAAa,YAAmB,CAAC,SAAS,KAAK"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"registry-docs.js","names":[],"sources":["../../src/registry/registry-docs.ts"],"sourcesContent":["import { TagsEnum } from '@contractspec/lib.contracts/ownership';\nimport type { PresentationSpec } from '@contractspec/lib.contracts/presentations';\nimport {\n createComponentPresentation,\n DOCS_CONTEXT,\n DOCS_GOAL,\n tagsFromPath,\n} from './factory';\nimport type { ComponentMap } from './types';\n\n// Import doc page components from local marketing bundle\n// Note: Imports are relative to src/registry (../components/docs/...)\n\n// Advanced\nimport { AdvancedMCPPage } from '@contractspec/bundle.library/components/docs/advanced/AdvancedMCPPage';\nimport { AdvancedOverlayEditorPage } from '@contractspec/bundle.library/components/docs/advanced/AdvancedOverlayEditorPage';\nimport { AdvancedRenderersPage } from '@contractspec/bundle.library/components/docs/advanced/AdvancedRenderersPage';\nimport { AdvancedSpecExperimentsPage } from '@contractspec/bundle.library/components/docs/advanced/AdvancedSpecExperimentsPage';\nimport { AdvancedTelemetryPage } from '@contractspec/bundle.library/components/docs/advanced/AdvancedTelemetryPage';\nimport { AdvancedWorkflowMonitoringPage } from '@contractspec/bundle.library/components/docs/advanced/AdvancedWorkflowMonitoringPage';\n\n// Architecture\nimport { ArchitectureAppConfigPage } from '@contractspec/bundle.library/components/docs/architecture/ArchitectureAppConfigPage';\nimport { ArchitectureIntegrationBindingPage } from '@contractspec/bundle.library/components/docs/architecture/ArchitectureIntegrationBindingPage';\nimport { ArchitectureKnowledgeBindingPage } from '@contractspec/bundle.library/components/docs/architecture/ArchitectureKnowledgeBindingPage';\nimport { ArchitectureMultiTenancyPage } from '@contractspec/bundle.library/components/docs/architecture/ArchitectureMultiTenancyPage';\nimport { ArchitectureOverviewPage } from '@contractspec/bundle.library/components/docs/architecture/ArchitectureOverviewPage';\n\n// Comparison\nimport { ComparisonAutomationPlatformsPage } from '@contractspec/bundle.library/components/docs/comparison/ComparisonAutomationPlatformsPage';\nimport { ComparisonEnterprisePlatformsPage } from '@contractspec/bundle.library/components/docs/comparison/ComparisonEnterprisePlatformsPage';\nimport { ComparisonInternalToolBuildersPage } from '@contractspec/bundle.library/components/docs/comparison/ComparisonInternalToolBuildersPage';\nimport { ComparisonOverviewPage } from '@contractspec/bundle.library/components/docs/comparison/ComparisonOverviewPage';\nimport { ComparisonWindmillPage } from '@contractspec/bundle.library/components/docs/comparison/ComparisonWindmillPage';\nimport { ComparisonWorkflowEnginesPage } from '@contractspec/bundle.library/components/docs/comparison/ComparisonWorkflowEnginesPage';\n\n// Getting Started\nimport { CLIPage } from '@contractspec/bundle.library/components/docs/getting-started/CLIPage';\nimport { DataViewTutorialPage } from '@contractspec/bundle.library/components/docs/getting-started/DataViewTutorialPage';\nimport { HelloWorldPage } from '@contractspec/bundle.library/components/docs/getting-started/HelloWorldPage';\nimport { InstallationPage } from '@contractspec/bundle.library/components/docs/getting-started/InstallationPage';\nimport { StartHerePage } from '@contractspec/bundle.library/components/docs/getting-started/StartHerePage';\nimport { TroubleshootingPage } from '@contractspec/bundle.library/components/docs/getting-started/TroubleshootingPage';\nimport { CompatibilityPage } from '@contractspec/bundle.library/components/docs/getting-started/CompatibilityPage';\n\n// Integrations\nimport { IntegrationsCircuitBreakersPage } from '@contractspec/bundle.library/components/docs/integrations/IntegrationsCircuitBreakersPage';\nimport { IntegrationsElevenLabsPage } from '@contractspec/bundle.library/components/docs/integrations/IntegrationsElevenLabsPage';\nimport { IntegrationsGmailPage } from '@contractspec/bundle.library/components/docs/integrations/IntegrationsGmailPage';\nimport { IntegrationsGoogleCalendarPage } from '@contractspec/bundle.library/components/docs/integrations/IntegrationsGoogleCalendarPage';\nimport { IntegrationsOpenAIPage } from '@contractspec/bundle.library/components/docs/integrations/IntegrationsOpenAIPage';\nimport { IntegrationsOverviewPage } from '@contractspec/bundle.library/components/docs/integrations/IntegrationsOverviewPage';\nimport { IntegrationsPostmarkPage } from '@contractspec/bundle.library/components/docs/integrations/IntegrationsPostmarkPage';\nimport { IntegrationsPowensPage } from '@contractspec/bundle.library/components/docs/integrations/IntegrationsPowensPage';\nimport { IntegrationsQdrantPage } from '@contractspec/bundle.library/components/docs/integrations/IntegrationsQdrantPage';\nimport { IntegrationsResendPage } from '@contractspec/bundle.library/components/docs/integrations/IntegrationsResendPage';\nimport { IntegrationsS3Page } from '@contractspec/bundle.library/components/docs/integrations/IntegrationsS3Page';\nimport { IntegrationsSpecModelPage } from '@contractspec/bundle.library/components/docs/integrations/IntegrationsSpecModelPage';\nimport { IntegrationsStripePage } from '@contractspec/bundle.library/components/docs/integrations/IntegrationsStripePage';\nimport { IntegrationsTwilioPage } from '@contractspec/bundle.library/components/docs/integrations/IntegrationsTwilioPage';\n\n// Knowledge\nimport { KnowledgeCategoriesPage } from '@contractspec/bundle.library/components/docs/knowledge/KnowledgeCategoriesPage';\nimport { KnowledgeExamplesPage } from '@contractspec/bundle.library/components/docs/knowledge/KnowledgeExamplesPage';\nimport { KnowledgeOverviewPage } from '@contractspec/bundle.library/components/docs/knowledge/KnowledgeOverviewPage';\nimport { KnowledgeSourcesPage } from '@contractspec/bundle.library/components/docs/knowledge/KnowledgeSourcesPage';\nimport { KnowledgeSpacesPage } from '@contractspec/bundle.library/components/docs/knowledge/KnowledgeSpacesPage';\n\n// Libraries\nimport { LibrariesAccessibilityPage } from '@contractspec/bundle.library/components/docs/libraries/LibrariesAccessibilityPage';\nimport { LibrariesAiAgentPage } from '@contractspec/bundle.library/components/docs/libraries/LibrariesAiAgentPage';\nimport { LibrariesAnalyticsPage } from '@contractspec/bundle.library/components/docs/libraries/LibrariesAnalyticsPage';\nimport { LibrariesContentGenPage } from '@contractspec/bundle.library/components/docs/libraries/LibrariesContentGenPage';\nimport { LibrariesContractsPage } from '@contractspec/bundle.library/components/docs/libraries/LibrariesContractsPage';\nimport { LibrariesCostTrackingPage } from '@contractspec/bundle.library/components/docs/libraries/LibrariesCostTrackingPage';\nimport { LibrariesDataBackendPage } from '@contractspec/bundle.library/components/docs/libraries/LibrariesDataBackendPage';\nimport { LibrariesDataViewsPage } from '@contractspec/bundle.library/components/docs/libraries/LibrariesDataViewsPage';\nimport { LibrariesDesignSystemPage } from '@contractspec/bundle.library/components/docs/libraries/LibrariesDesignSystemPage';\nimport { LibrariesEvolutionPage } from '@contractspec/bundle.library/components/docs/libraries/LibrariesEvolutionPage';\nimport { LibrariesGraphQLPage } from '@contractspec/bundle.library/components/docs/libraries/LibrariesGraphQLPage';\nimport { LibrariesGrowthPage } from '@contractspec/bundle.library/components/docs/libraries/LibrariesGrowthPage';\nimport { LibrariesMultiTenancyPage } from '@contractspec/bundle.library/components/docs/libraries/LibrariesMultiTenancyPage';\nimport { LibrariesObservabilityPage } from '@contractspec/bundle.library/components/docs/libraries/LibrariesObservabilityPage';\nimport { LibrariesOverlayEnginePage } from '@contractspec/bundle.library/components/docs/libraries/LibrariesOverlayEnginePage';\nimport { LibrariesOverviewPage } from '@contractspec/bundle.library/components/docs/libraries/LibrariesOverviewPage';\nimport { LibrariesPersonalizationPage } from '@contractspec/bundle.library/components/docs/libraries/LibrariesPersonalizationPage';\nimport { LibrariesProgressiveDeliveryPage } from '@contractspec/bundle.library/components/docs/libraries/LibrariesProgressiveDeliveryPage';\nimport { LibrariesResiliencePage } from '@contractspec/bundle.library/components/docs/libraries/LibrariesResiliencePage';\nimport { LibrariesRuntimePage } from '@contractspec/bundle.library/components/docs/libraries/LibrariesRuntimePage';\nimport { LibrariesSchemaPage } from '@contractspec/bundle.library/components/docs/libraries/LibrariesSchemaPage';\nimport { LibrariesSLOPage } from '@contractspec/bundle.library/components/docs/libraries/LibrariesSLOPage';\nimport { LibrariesSupportBotPage } from '@contractspec/bundle.library/components/docs/libraries/LibrariesSupportBotPage';\nimport { LibrariesTestingPage } from '@contractspec/bundle.library/components/docs/libraries/LibrariesTestingPage';\nimport { LibrariesUIKitPage } from '@contractspec/bundle.library/components/docs/libraries/LibrariesUIKitPage';\nimport { LibrariesWorkflowComposerPage } from '@contractspec/bundle.library/components/docs/libraries/LibrariesWorkflowComposerPage';\nimport { LibrariesWorkflowsPage } from '@contractspec/bundle.library/components/docs/libraries/LibrariesWorkflowsPage';\n\n// Manifesto\nimport { ManifestoPage } from '@contractspec/bundle.library/components/docs/manifesto/ManifestoPage';\n\n// Ops\nimport { OpsAutoEvolutionPage } from '@contractspec/bundle.library/components/docs/ops/AutoEvolutionOpsPage';\nimport { OpsDistributedTracingPage } from '@contractspec/bundle.library/components/docs/ops/DistributedTracingOpsPage';\n\n// Safety\nimport { SafetyAuditingPage } from '@contractspec/bundle.library/components/docs/safety/SafetyAuditingPage';\nimport { SafetyMigrationsPage } from '@contractspec/bundle.library/components/docs/safety/SafetyMigrationsPage';\nimport { SafetyOverviewPage } from '@contractspec/bundle.library/components/docs/safety/SafetyOverviewPage';\nimport { SafetyPDPPage } from '@contractspec/bundle.library/components/docs/safety/SafetyPDPPage';\nimport { SafetySigningPage } from '@contractspec/bundle.library/components/docs/safety/SafetySigningPage';\nimport { SafetyTenantIsolationPage } from '@contractspec/bundle.library/components/docs/safety/SafetyTenantIsolationPage';\n\n// Specs\nimport { SpecsCapabilitiesPage } from '@contractspec/bundle.library/components/docs/specs/SpecsCapabilitiesPage';\nimport { SpecsDataViewsPage } from '@contractspec/bundle.library/components/docs/specs/SpecsDataViewsPage';\nimport { SpecsOverlaysPage } from '@contractspec/bundle.library/components/docs/specs/SpecsOverlaysPage';\nimport { SpecsOverviewPage } from '@contractspec/bundle.library/components/docs/specs/SpecsOverviewPage';\nimport { SpecsPolicyPage } from '@contractspec/bundle.library/components/docs/specs/SpecsPolicyPage';\nimport { SpecsWorkflowsPage } from '@contractspec/bundle.library/components/docs/specs/SpecsWorkflowsPage';\n\n// Studio\nimport { StudioBYOKPage } from '@contractspec/bundle.library/components/docs/studio/StudioBYOKPage';\nimport { StudioDeploymentsPage } from '@contractspec/bundle.library/components/docs/studio/StudioDeploymentsPage';\nimport { StudioGettingStartedPage } from '@contractspec/bundle.library/components/docs/studio/StudioGettingStartedPage';\nimport { StudioIntegrationsPage } from '@contractspec/bundle.library/components/docs/studio/StudioIntegrationsPage';\nimport { StudioOverviewPage } from '@contractspec/bundle.library/components/docs/studio/StudioOverviewPage';\nimport { StudioVisualBuilderPage } from '@contractspec/bundle.library/components/docs/studio/StudioVisualBuilderPage';\n\n// Docs Index\nimport { DocsIndexPage } from '@contractspec/bundle.library/components/docs/DocsIndexPage';\n\n/**\n * Component map for documentation page React rendering.\n */\nexport const docsComponentMap: ComponentMap = {\n DocsIndexPage,\n // Getting Started\n InstallationPage,\n StartHerePage,\n TroubleshootingPage,\n CompatibilityPage,\n HelloWorldPage,\n CLIPage,\n DataViewTutorialPage,\n // Specs\n SpecsOverviewPage,\n SpecsCapabilitiesPage,\n SpecsDataViewsPage,\n SpecsWorkflowsPage,\n SpecsPolicyPage,\n SpecsOverlaysPage,\n // Libraries\n LibrariesOverviewPage,\n LibrariesContractsPage,\n LibrariesAiAgentPage,\n LibrariesAnalyticsPage,\n LibrariesAccessibilityPage,\n LibrariesContentGenPage,\n LibrariesCostTrackingPage,\n LibrariesDataBackendPage,\n LibrariesDataViewsPage,\n LibrariesDesignSystemPage,\n LibrariesEvolutionPage,\n LibrariesGraphQLPage,\n LibrariesGrowthPage,\n LibrariesMultiTenancyPage,\n LibrariesObservabilityPage,\n LibrariesOverlayEnginePage,\n LibrariesPersonalizationPage,\n LibrariesProgressiveDeliveryPage,\n LibrariesResiliencePage,\n LibrariesRuntimePage,\n LibrariesSchemaPage,\n LibrariesSLOPage,\n LibrariesSupportBotPage,\n LibrariesTestingPage,\n LibrariesUIKitPage,\n LibrariesWorkflowsPage,\n LibrariesWorkflowComposerPage,\n // Architecture\n ArchitectureOverviewPage,\n ArchitectureAppConfigPage,\n ArchitectureMultiTenancyPage,\n ArchitectureIntegrationBindingPage,\n ArchitectureKnowledgeBindingPage,\n // Advanced\n AdvancedRenderersPage,\n AdvancedMCPPage,\n AdvancedTelemetryPage,\n AdvancedWorkflowMonitoringPage,\n AdvancedOverlayEditorPage,\n AdvancedSpecExperimentsPage,\n // Safety\n SafetyOverviewPage,\n SafetySigningPage,\n SafetyAuditingPage,\n SafetyMigrationsPage,\n SafetyPDPPage,\n SafetyTenantIsolationPage,\n // Integrations\n IntegrationsOverviewPage,\n IntegrationsCircuitBreakersPage,\n IntegrationsElevenLabsPage,\n IntegrationsGmailPage,\n IntegrationsGoogleCalendarPage,\n IntegrationsOpenAIPage,\n IntegrationsPostmarkPage,\n IntegrationsPowensPage,\n IntegrationsQdrantPage,\n IntegrationsResendPage,\n IntegrationsS3Page,\n IntegrationsSpecModelPage,\n IntegrationsStripePage,\n IntegrationsTwilioPage,\n // Knowledge\n KnowledgeOverviewPage,\n KnowledgeCategoriesPage,\n KnowledgeExamplesPage,\n KnowledgeSourcesPage,\n KnowledgeSpacesPage,\n // Comparison\n ComparisonOverviewPage,\n ComparisonAutomationPlatformsPage,\n ComparisonEnterprisePlatformsPage,\n ComparisonInternalToolBuildersPage,\n ComparisonWorkflowEnginesPage,\n ComparisonWindmillPage,\n // Ops\n OpsAutoEvolutionPage,\n OpsDistributedTracingPage,\n // Manifesto\n ManifestoPage,\n // Studio docs\n StudioOverviewPage,\n StudioGettingStartedPage,\n StudioVisualBuilderPage,\n StudioIntegrationsPage,\n StudioDeploymentsPage,\n StudioBYOKPage,\n};\n\n/** Helper to create a docs presentation entry */\nfunction docsEntry(\n route: string,\n key: string,\n componentKey: string,\n description: string\n): [string, PresentationSpec] {\n return [\n route,\n createComponentPresentation({\n key,\n componentKey,\n description,\n goal: DOCS_GOAL,\n context: DOCS_CONTEXT,\n tags: [TagsEnum.Docs, ...tagsFromPath(route)],\n }),\n ];\n}\n\n/**\n * Presentation specs for documentation pages.\n */\nexport const docsPresentations: [string, PresentationSpec][] = [\n // Docs index\n docsEntry(\n '/docs',\n 'web-landing.docs.index',\n 'DocsIndexPage',\n 'ContractSpec documentation index page'\n ),\n\n // Getting Started\n docsEntry(\n '/docs/getting-started/start-here',\n 'web-landing.docs.start-here',\n 'StartHerePage',\n 'ContractSpec start here onboarding guide'\n ),\n docsEntry(\n '/docs/getting-started/troubleshooting',\n 'web-landing.docs.troubleshooting',\n 'TroubleshootingPage',\n 'ContractSpec getting started troubleshooting'\n ),\n docsEntry(\n '/docs/getting-started/compatibility',\n 'web-landing.docs.compatibility',\n 'CompatibilityPage',\n 'ContractSpec compatibility and requirements'\n ),\n docsEntry(\n '/docs/getting-started/installation',\n 'web-landing.docs.installation',\n 'InstallationPage',\n 'ContractSpec installation guide'\n ),\n docsEntry(\n '/docs/getting-started/hello-world',\n 'web-landing.docs.hello-world',\n 'HelloWorldPage',\n 'ContractSpec hello world tutorial'\n ),\n docsEntry(\n '/docs/getting-started/cli',\n 'web-landing.docs.cli',\n 'CLIPage',\n 'ContractSpec CLI reference guide'\n ),\n docsEntry(\n '/docs/getting-started/dataviews',\n 'web-landing.docs.dataviews-tutorial',\n 'DataViewTutorialPage',\n 'ContractSpec DataView tutorial'\n ),\n\n // Specs\n docsEntry(\n '/docs/specs',\n 'web-landing.docs.specs.overview',\n 'SpecsOverviewPage',\n 'ContractSpec specifications overview'\n ),\n docsEntry(\n '/docs/specs/capabilities',\n 'web-landing.docs.specs.capabilities',\n 'SpecsCapabilitiesPage',\n 'ContractSpec capabilities'\n ),\n docsEntry(\n '/docs/specs/dataviews',\n 'web-landing.docs.specs.dataviews',\n 'SpecsDataViewsPage',\n 'ContractSpec DataViews specification'\n ),\n docsEntry(\n '/docs/specs/workflows',\n 'web-landing.docs.specs.workflows',\n 'SpecsWorkflowsPage',\n 'ContractSpec workflows specification'\n ),\n docsEntry(\n '/docs/specs/policy',\n 'web-landing.docs.specs.policy',\n 'SpecsPolicyPage',\n 'ContractSpec policy specification'\n ),\n docsEntry(\n '/docs/specs/overlays',\n 'web-landing.docs.specs.overlays',\n 'SpecsOverlaysPage',\n 'ContractSpec overlays specification'\n ),\n\n // Libraries\n docsEntry(\n '/docs/libraries',\n 'web-landing.docs.libraries.overview',\n 'LibrariesOverviewPage',\n 'ContractSpec libraries overview'\n ),\n docsEntry(\n '/docs/libraries/contracts',\n 'web-landing.docs.libraries.contracts',\n 'LibrariesContractsPage',\n 'ContractSpec contracts library'\n ),\n docsEntry(\n '/docs/libraries/ai-agent',\n 'web-landing.docs.libraries.ai-agent',\n 'LibrariesAiAgentPage',\n 'ContractSpec AI agent library'\n ),\n docsEntry(\n '/docs/libraries/analytics',\n 'web-landing.docs.libraries.analytics',\n 'LibrariesAnalyticsPage',\n 'ContractSpec analytics library'\n ),\n docsEntry(\n '/docs/libraries/accessibility',\n 'web-landing.docs.libraries.accessibility',\n 'LibrariesAccessibilityPage',\n 'ContractSpec accessibility library'\n ),\n docsEntry(\n '/docs/libraries/content-gen',\n 'web-landing.docs.libraries.content-gen',\n 'LibrariesContentGenPage',\n 'ContractSpec content generation library'\n ),\n docsEntry(\n '/docs/libraries/cost-tracking',\n 'web-landing.docs.libraries.cost-tracking',\n 'LibrariesCostTrackingPage',\n 'ContractSpec cost tracking library'\n ),\n docsEntry(\n '/docs/libraries/data-backend',\n 'web-landing.docs.libraries.data-backend',\n 'LibrariesDataBackendPage',\n 'ContractSpec data backend library'\n ),\n docsEntry(\n '/docs/libraries/data-views',\n 'web-landing.docs.libraries.data-views',\n 'LibrariesDataViewsPage',\n 'ContractSpec data views library'\n ),\n docsEntry(\n '/docs/libraries/design-system',\n 'web-landing.docs.libraries.design-system',\n 'LibrariesDesignSystemPage',\n 'ContractSpec design system library'\n ),\n docsEntry(\n '/docs/libraries/evolution',\n 'web-landing.docs.libraries.evolution',\n 'LibrariesEvolutionPage',\n 'ContractSpec evolution library'\n ),\n docsEntry(\n '/docs/libraries/graphql',\n 'web-landing.docs.libraries.graphql',\n 'LibrariesGraphQLPage',\n 'ContractSpec GraphQL library'\n ),\n docsEntry(\n '/docs/libraries/growth',\n 'web-landing.docs.libraries.growth',\n 'LibrariesGrowthPage',\n 'ContractSpec growth library'\n ),\n docsEntry(\n '/docs/libraries/multi-tenancy',\n 'web-landing.docs.libraries.multi-tenancy',\n 'LibrariesMultiTenancyPage',\n 'ContractSpec multi-tenancy library'\n ),\n docsEntry(\n '/docs/libraries/observability',\n 'web-landing.docs.libraries.observability',\n 'LibrariesObservabilityPage',\n 'ContractSpec observability library'\n ),\n docsEntry(\n '/docs/libraries/overlay-engine',\n 'web-landing.docs.libraries.overlay-engine',\n 'LibrariesOverlayEnginePage',\n 'ContractSpec overlay engine library'\n ),\n docsEntry(\n '/docs/libraries/personalization',\n 'web-landing.docs.libraries.personalization',\n 'LibrariesPersonalizationPage',\n 'ContractSpec personalization library'\n ),\n docsEntry(\n '/docs/libraries/progressive-delivery',\n 'web-landing.docs.libraries.progressive-delivery',\n 'LibrariesProgressiveDeliveryPage',\n 'ContractSpec progressive delivery library'\n ),\n docsEntry(\n '/docs/libraries/resilience',\n 'web-landing.docs.libraries.resilience',\n 'LibrariesResiliencePage',\n 'ContractSpec resilience library'\n ),\n docsEntry(\n '/docs/libraries/runtime',\n 'web-landing.docs.libraries.runtime',\n 'LibrariesRuntimePage',\n 'ContractSpec runtime library'\n ),\n docsEntry(\n '/docs/libraries/schema',\n 'web-landing.docs.libraries.schema',\n 'LibrariesSchemaPage',\n 'ContractSpec schema library'\n ),\n docsEntry(\n '/docs/libraries/slo',\n 'web-landing.docs.libraries.slo',\n 'LibrariesSLOPage',\n 'ContractSpec SLO library'\n ),\n docsEntry(\n '/docs/libraries/support-bot',\n 'web-landing.docs.libraries.support-bot',\n 'LibrariesSupportBotPage',\n 'ContractSpec support bot library'\n ),\n docsEntry(\n '/docs/libraries/testing',\n 'web-landing.docs.libraries.testing',\n 'LibrariesTestingPage',\n 'ContractSpec testing library'\n ),\n docsEntry(\n '/docs/libraries/ui-kit',\n 'web-landing.docs.libraries.ui-kit',\n 'LibrariesUIKitPage',\n 'ContractSpec UI kit library'\n ),\n docsEntry(\n '/docs/libraries/workflows',\n 'web-landing.docs.libraries.workflows',\n 'LibrariesWorkflowsPage',\n 'ContractSpec workflows library'\n ),\n docsEntry(\n '/docs/libraries/workflow-composer',\n 'web-landing.docs.libraries.workflow-composer',\n 'LibrariesWorkflowComposerPage',\n 'ContractSpec workflow composer library'\n ),\n\n // Architecture\n docsEntry(\n '/docs/architecture',\n 'web-landing.docs.architecture.overview',\n 'ArchitectureOverviewPage',\n 'ContractSpec architecture overview'\n ),\n docsEntry(\n '/docs/architecture/app-config',\n 'web-landing.docs.architecture.app-config',\n 'ArchitectureAppConfigPage',\n 'ContractSpec app configuration'\n ),\n docsEntry(\n '/docs/architecture/multi-tenancy',\n 'web-landing.docs.architecture.multi-tenancy',\n 'ArchitectureMultiTenancyPage',\n 'ContractSpec multi-tenancy architecture'\n ),\n docsEntry(\n '/docs/architecture/integration-binding',\n 'web-landing.docs.architecture.integration-binding',\n 'ArchitectureIntegrationBindingPage',\n 'ContractSpec integration binding'\n ),\n docsEntry(\n '/docs/architecture/knowledge-binding',\n 'web-landing.docs.architecture.knowledge-binding',\n 'ArchitectureKnowledgeBindingPage',\n 'ContractSpec knowledge binding'\n ),\n\n // Advanced\n docsEntry(\n '/docs/advanced/renderers',\n 'web-landing.docs.advanced.renderers',\n 'AdvancedRenderersPage',\n 'ContractSpec renderers documentation'\n ),\n docsEntry(\n '/docs/advanced/mcp',\n 'web-landing.docs.advanced.mcp',\n 'AdvancedMCPPage',\n 'ContractSpec MCP documentation'\n ),\n docsEntry(\n '/docs/advanced/telemetry',\n 'web-landing.docs.advanced.telemetry',\n 'AdvancedTelemetryPage',\n 'ContractSpec telemetry documentation'\n ),\n docsEntry(\n '/docs/advanced/workflow-monitoring',\n 'web-landing.docs.advanced.workflow-monitoring',\n 'AdvancedWorkflowMonitoringPage',\n 'ContractSpec workflow monitoring'\n ),\n docsEntry(\n '/docs/advanced/overlay-editor',\n 'web-landing.docs.advanced.overlay-editor',\n 'AdvancedOverlayEditorPage',\n 'ContractSpec overlay editor'\n ),\n docsEntry(\n '/docs/advanced/spec-experiments',\n 'web-landing.docs.advanced.spec-experiments',\n 'AdvancedSpecExperimentsPage',\n 'ContractSpec spec experiments'\n ),\n\n // Safety\n docsEntry(\n '/docs/safety',\n 'web-landing.docs.safety.overview',\n 'SafetyOverviewPage',\n 'ContractSpec safety overview'\n ),\n docsEntry(\n '/docs/safety/signing',\n 'web-landing.docs.safety.signing',\n 'SafetySigningPage',\n 'ContractSpec signing and attestation'\n ),\n docsEntry(\n '/docs/safety/auditing',\n 'web-landing.docs.safety.auditing',\n 'SafetyAuditingPage',\n 'ContractSpec auditing documentation'\n ),\n docsEntry(\n '/docs/safety/migrations',\n 'web-landing.docs.safety.migrations',\n 'SafetyMigrationsPage',\n 'ContractSpec migrations documentation'\n ),\n docsEntry(\n '/docs/safety/pdp',\n 'web-landing.docs.safety.pdp',\n 'SafetyPDPPage',\n 'ContractSpec Policy Decision Point'\n ),\n docsEntry(\n '/docs/safety/tenant-isolation',\n 'web-landing.docs.safety.tenant-isolation',\n 'SafetyTenantIsolationPage',\n 'ContractSpec tenant isolation'\n ),\n\n // Integrations\n docsEntry(\n '/docs/integrations',\n 'web-landing.docs.integrations.overview',\n 'IntegrationsOverviewPage',\n 'ContractSpec integrations overview'\n ),\n docsEntry(\n '/docs/integrations/circuit-breakers',\n 'web-landing.docs.integrations.circuit-breakers',\n 'IntegrationsCircuitBreakersPage',\n 'ContractSpec circuit breakers'\n ),\n docsEntry(\n '/docs/integrations/elevenlabs',\n 'web-landing.docs.integrations.elevenlabs',\n 'IntegrationsElevenLabsPage',\n 'ContractSpec ElevenLabs integration'\n ),\n docsEntry(\n '/docs/integrations/gmail',\n 'web-landing.docs.integrations.gmail',\n 'IntegrationsGmailPage',\n 'ContractSpec Gmail integration'\n ),\n docsEntry(\n '/docs/integrations/google-calendar',\n 'web-landing.docs.integrations.google-calendar',\n 'IntegrationsGoogleCalendarPage',\n 'ContractSpec Google Calendar'\n ),\n docsEntry(\n '/docs/integrations/openai',\n 'web-landing.docs.integrations.openai',\n 'IntegrationsOpenAIPage',\n 'ContractSpec OpenAI integration'\n ),\n docsEntry(\n '/docs/integrations/postmark',\n 'web-landing.docs.integrations.postmark',\n 'IntegrationsPostmarkPage',\n 'ContractSpec Postmark integration'\n ),\n docsEntry(\n '/docs/integrations/powens',\n 'web-landing.docs.integrations.powens',\n 'IntegrationsPowensPage',\n 'ContractSpec Powens integration'\n ),\n docsEntry(\n '/docs/integrations/qdrant',\n 'web-landing.docs.integrations.qdrant',\n 'IntegrationsQdrantPage',\n 'ContractSpec Qdrant integration'\n ),\n docsEntry(\n '/docs/integrations/resend',\n 'web-landing.docs.integrations.resend',\n 'IntegrationsResendPage',\n 'ContractSpec Resend integration'\n ),\n docsEntry(\n '/docs/integrations/s3',\n 'web-landing.docs.integrations.s3',\n 'IntegrationsS3Page',\n 'ContractSpec S3 integration'\n ),\n docsEntry(\n '/docs/integrations/spec-model',\n 'web-landing.docs.integrations.spec-model',\n 'IntegrationsSpecModelPage',\n 'ContractSpec spec model integration'\n ),\n docsEntry(\n '/docs/integrations/stripe',\n 'web-landing.docs.integrations.stripe',\n 'IntegrationsStripePage',\n 'ContractSpec Stripe integration'\n ),\n docsEntry(\n '/docs/integrations/twilio',\n 'web-landing.docs.integrations.twilio',\n 'IntegrationsTwilioPage',\n 'ContractSpec Twilio integration'\n ),\n\n // Knowledge\n docsEntry(\n '/docs/knowledge',\n 'web-landing.docs.knowledge.overview',\n 'KnowledgeOverviewPage',\n 'ContractSpec knowledge overview'\n ),\n docsEntry(\n '/docs/knowledge/categories',\n 'web-landing.docs.knowledge.categories',\n 'KnowledgeCategoriesPage',\n 'ContractSpec knowledge categories'\n ),\n docsEntry(\n '/docs/knowledge/examples',\n 'web-landing.docs.knowledge.examples',\n 'KnowledgeExamplesPage',\n 'ContractSpec knowledge examples'\n ),\n docsEntry(\n '/docs/knowledge/sources',\n 'web-landing.docs.knowledge.sources',\n 'KnowledgeSourcesPage',\n 'ContractSpec knowledge sources'\n ),\n docsEntry(\n '/docs/knowledge/spaces',\n 'web-landing.docs.knowledge.spaces',\n 'KnowledgeSpacesPage',\n 'ContractSpec knowledge spaces'\n ),\n\n // Comparison\n docsEntry(\n '/docs/comparison',\n 'web-landing.docs.comparison.overview',\n 'ComparisonOverviewPage',\n 'ContractSpec comparison overview'\n ),\n docsEntry(\n '/docs/comparison/automation-platforms',\n 'web-landing.docs.comparison.automation-platforms',\n 'ComparisonAutomationPlatformsPage',\n 'Comparison with automation platforms'\n ),\n docsEntry(\n '/docs/comparison/enterprise-platforms',\n 'web-landing.docs.comparison.enterprise-platforms',\n 'ComparisonEnterprisePlatformsPage',\n 'Comparison with enterprise platforms'\n ),\n docsEntry(\n '/docs/comparison/internal-tool-builders',\n 'web-landing.docs.comparison.internal-tool-builders',\n 'ComparisonInternalToolBuildersPage',\n 'Comparison with internal tool builders'\n ),\n docsEntry(\n '/docs/comparison/workflow-engines',\n 'web-landing.docs.comparison.workflow-engines',\n 'ComparisonWorkflowEnginesPage',\n 'Comparison with workflow engines'\n ),\n docsEntry(\n '/docs/comparison/windmill',\n 'web-landing.docs.comparison.windmill',\n 'ComparisonWindmillPage',\n 'Comparison with Windmill'\n ),\n\n // Ops\n docsEntry(\n '/docs/ops/auto-evolution',\n 'web-landing.docs.ops.auto-evolution',\n 'OpsAutoEvolutionPage',\n 'ContractSpec auto-evolution operations'\n ),\n docsEntry(\n '/docs/ops/distributed-tracing',\n 'web-landing.docs.ops.distributed-tracing',\n 'OpsDistributedTracingPage',\n 'ContractSpec distributed tracing'\n ),\n\n // Manifesto\n docsEntry(\n '/docs/manifesto',\n 'web-landing.docs.manifesto',\n 'ManifestoPage',\n 'ContractSpec manifesto'\n ),\n\n // Studio docs\n docsEntry(\n '/docs/studio',\n 'web-landing.docs.studio.overview',\n 'StudioOverviewPage',\n 'ContractSpec Studio overview'\n ),\n docsEntry(\n '/docs/studio/getting-started',\n 'web-landing.docs.studio.getting-started',\n 'StudioGettingStartedPage',\n 'ContractSpec Studio getting started'\n ),\n docsEntry(\n '/docs/studio/visual-builder',\n 'web-landing.docs.studio.visual-builder',\n 'StudioVisualBuilderPage',\n 'ContractSpec Studio visual builder'\n ),\n docsEntry(\n '/docs/studio/integrations',\n 'web-landing.docs.studio.integrations',\n 'StudioIntegrationsPage',\n 'ContractSpec Studio integrations'\n ),\n docsEntry(\n '/docs/studio/deployments',\n 'web-landing.docs.studio.deployments',\n 'StudioDeploymentsPage',\n 'ContractSpec Studio deployments'\n ),\n docsEntry(\n '/docs/studio/byok',\n 'web-landing.docs.studio.byok',\n 'StudioBYOKPage',\n 'ContractSpec Studio BYOK'\n ),\n];\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsIA,MAAa,mBAAiC;CAC5C;CAEA;CACA;CACA;CACA;CACA;CACA;CACA;CAEA;CACA;CACA;CACA;CACA;CACA;CAEA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CAEA;CACA;CACA;CACA;CACA;CAEA;CACA;CACA;CACA;CACA;CACA;CAEA;CACA;CACA;CACA;CACA;CACA;CAEA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CAEA;CACA;CACA;CACA;CACA;CAEA;CACA;CACA;CACA;CACA;CACA;CAEA;CACA;CAEA;CAEA;CACA;CACA;CACA;CACA;CACA;CACD;;AAGD,SAAS,UACP,OACA,KACA,cACA,aAC4B;AAC5B,QAAO,CACL,OACA,4BAA4B;EAC1B;EACA;EACA;EACA,MAAM;EACN,SAAS;EACT,MAAM,CAAC,SAAS,MAAM,GAAG,aAAa,MAAM,CAAC;EAC9C,CAAC,CACH;;;;;AAMH,MAAa,oBAAkD;CAE7D,UACE,SACA,0BACA,iBACA,wCACD;CAGD,UACE,oCACA,+BACA,iBACA,2CACD;CACD,UACE,yCACA,oCACA,uBACA,+CACD;CACD,UACE,uCACA,kCACA,qBACA,8CACD;CACD,UACE,sCACA,iCACA,oBACA,kCACD;CACD,UACE,qCACA,gCACA,kBACA,oCACD;CACD,UACE,6BACA,wBACA,WACA,mCACD;CACD,UACE,mCACA,uCACA,wBACA,iCACD;CAGD,UACE,eACA,mCACA,qBACA,uCACD;CACD,UACE,4BACA,uCACA,yBACA,4BACD;CACD,UACE,yBACA,oCACA,sBACA,uCACD;CACD,UACE,yBACA,oCACA,sBACA,uCACD;CACD,UACE,sBACA,iCACA,mBACA,oCACD;CACD,UACE,wBACA,mCACA,qBACA,sCACD;CAGD,UACE,mBACA,uCACA,yBACA,kCACD;CACD,UACE,6BACA,wCACA,0BACA,iCACD;CACD,UACE,4BACA,uCACA,wBACA,gCACD;CACD,UACE,6BACA,wCACA,0BACA,iCACD;CACD,UACE,iCACA,4CACA,8BACA,qCACD;CACD,UACE,+BACA,0CACA,2BACA,0CACD;CACD,UACE,iCACA,4CACA,6BACA,qCACD;CACD,UACE,gCACA,2CACA,4BACA,oCACD;CACD,UACE,8BACA,yCACA,0BACA,kCACD;CACD,UACE,iCACA,4CACA,6BACA,qCACD;CACD,UACE,6BACA,wCACA,0BACA,iCACD;CACD,UACE,2BACA,sCACA,wBACA,+BACD;CACD,UACE,0BACA,qCACA,uBACA,8BACD;CACD,UACE,iCACA,4CACA,6BACA,qCACD;CACD,UACE,iCACA,4CACA,8BACA,qCACD;CACD,UACE,kCACA,6CACA,8BACA,sCACD;CACD,UACE,mCACA,8CACA,gCACA,uCACD;CACD,UACE,wCACA,mDACA,oCACA,4CACD;CACD,UACE,8BACA,yCACA,2BACA,kCACD;CACD,UACE,2BACA,sCACA,wBACA,+BACD;CACD,UACE,0BACA,qCACA,uBACA,8BACD;CACD,UACE,uBACA,kCACA,oBACA,2BACD;CACD,UACE,+BACA,0CACA,2BACA,mCACD;CACD,UACE,2BACA,sCACA,wBACA,+BACD;CACD,UACE,0BACA,qCACA,sBACA,8BACD;CACD,UACE,6BACA,wCACA,0BACA,iCACD;CACD,UACE,qCACA,gDACA,iCACA,yCACD;CAGD,UACE,sBACA,0CACA,4BACA,qCACD;CACD,UACE,iCACA,4CACA,6BACA,iCACD;CACD,UACE,oCACA,+CACA,gCACA,0CACD;CACD,UACE,0CACA,qDACA,sCACA,mCACD;CACD,UACE,wCACA,mDACA,oCACA,iCACD;CAGD,UACE,4BACA,uCACA,yBACA,uCACD;CACD,UACE,sBACA,iCACA,mBACA,iCACD;CACD,UACE,4BACA,uCACA,yBACA,uCACD;CACD,UACE,sCACA,iDACA,kCACA,mCACD;CACD,UACE,iCACA,4CACA,6BACA,8BACD;CACD,UACE,mCACA,8CACA,+BACA,gCACD;CAGD,UACE,gBACA,oCACA,sBACA,+BACD;CACD,UACE,wBACA,mCACA,qBACA,uCACD;CACD,UACE,yBACA,oCACA,sBACA,sCACD;CACD,UACE,2BACA,sCACA,wBACA,wCACD;CACD,UACE,oBACA,+BACA,iBACA,qCACD;CACD,UACE,iCACA,4CACA,6BACA,gCACD;CAGD,UACE,sBACA,0CACA,4BACA,qCACD;CACD,UACE,uCACA,kDACA,mCACA,gCACD;CACD,UACE,iCACA,4CACA,8BACA,sCACD;CACD,UACE,4BACA,uCACA,yBACA,iCACD;CACD,UACE,sCACA,iDACA,kCACA,+BACD;CACD,UACE,6BACA,wCACA,0BACA,kCACD;CACD,UACE,+BACA,0CACA,4BACA,oCACD;CACD,UACE,6BACA,wCACA,0BACA,kCACD;CACD,UACE,6BACA,wCACA,0BACA,kCACD;CACD,UACE,6BACA,wCACA,0BACA,kCACD;CACD,UACE,yBACA,oCACA,sBACA,8BACD;CACD,UACE,iCACA,4CACA,6BACA,sCACD;CACD,UACE,6BACA,wCACA,0BACA,kCACD;CACD,UACE,6BACA,wCACA,0BACA,kCACD;CAGD,UACE,mBACA,uCACA,yBACA,kCACD;CACD,UACE,8BACA,yCACA,2BACA,oCACD;CACD,UACE,4BACA,uCACA,yBACA,kCACD;CACD,UACE,2BACA,sCACA,wBACA,iCACD;CACD,UACE,0BACA,qCACA,uBACA,gCACD;CAGD,UACE,oBACA,wCACA,0BACA,mCACD;CACD,UACE,yCACA,oDACA,qCACA,uCACD;CACD,UACE,yCACA,oDACA,qCACA,uCACD;CACD,UACE,2CACA,sDACA,sCACA,yCACD;CACD,UACE,qCACA,gDACA,iCACA,mCACD;CACD,UACE,6BACA,wCACA,0BACA,2BACD;CAGD,UACE,4BACA,uCACA,wBACA,yCACD;CACD,UACE,iCACA,4CACA,6BACA,mCACD;CAGD,UACE,mBACA,8BACA,iBACA,yBACD;CAGD,UACE,gBACA,oCACA,sBACA,+BACD;CACD,UACE,gCACA,2CACA,4BACA,sCACD;CACD,UACE,+BACA,0CACA,2BACA,qCACD;CACD,UACE,6BACA,wCACA,0BACA,mCACD;CACD,UACE,4BACA,uCACA,yBACA,kCACD;CACD,UACE,qBACA,gCACA,kBACA,2BACD;CACF"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"registry-landing.js","names":[],"sources":["../../src/registry/registry-landing.ts"],"sourcesContent":["import { TagsEnum } from '@contractspec/lib.contracts/ownership';\nimport type { PresentationSpec } from '@contractspec/lib.contracts/presentations';\nimport {\n createComponentPresentation,\n MARKETING_CONTEXT,\n MARKETING_GOAL,\n} from './factory';\nimport type { ComponentMap } from './types';\n\n// Import page components - Root/Marketing pages\nimport {\n ChangelogPage,\n ContactClient,\n LandingPage,\n PricingClient,\n ProductClientPage,\n} from '../components/marketing';\n\n/**\n * Component map for landing/marketing page React rendering.\n */\nexport const landingComponentMap: ComponentMap = {\n LandingPage,\n PricingPage: PricingClient,\n ProductPage: ProductClientPage,\n ContactPage: ContactClient,\n ChangelogPage,\n};\n\n/**\n * Presentation specs for landing/marketing pages.\n */\nexport const landingPresentations: [string, PresentationSpec][] = [\n [\n '/',\n createComponentPresentation({\n key: 'web-landing.home',\n componentKey: 'LandingPage',\n description:\n 'ContractSpec landing page - Stabilize your AI-generated code',\n goal: MARKETING_GOAL,\n context: MARKETING_CONTEXT,\n tags: ['landing', 'home'],\n }),\n ],\n [\n '/pricing',\n createComponentPresentation({\n key: 'web-landing.pricing',\n componentKey: 'PricingPage',\n description: 'ContractSpec pricing information',\n goal: 'Help visitors understand pricing and choose a plan',\n context: MARKETING_CONTEXT,\n tags: ['pricing', 'plans'],\n }),\n ],\n [\n '/product',\n createComponentPresentation({\n key: 'web-landing.product',\n componentKey: 'ProductPage',\n description: 'ContractSpec product overview',\n goal: 'Explain product features and benefits',\n context: MARKETING_CONTEXT,\n tags: ['product', 'features'],\n }),\n ],\n [\n '/contact',\n createComponentPresentation({\n key: 'web-landing.contact',\n componentKey: 'ContactPage',\n description: 'Contact ContractSpec team',\n goal: 'Enable visitors to reach the ContractSpec team',\n context: MARKETING_CONTEXT,\n tags: ['contact', 'support'],\n }),\n ],\n [\n '/changelog',\n createComponentPresentation({\n key: 'web-landing.changelog',\n componentKey: 'ChangelogPage',\n description: 'ContractSpec changelog and release notes',\n goal: 'Keep users informed about changes and updates',\n context: MARKETING_CONTEXT,\n tags: ['changelog', 'releases'],\n }),\n ],\n];\n\n/**\n * Presentation specs for learning journey pages.\n */\nexport const learningPresentations: [string, PresentationSpec][] = [\n [\n '/learning',\n createComponentPresentation({\n key: 'web-landing.learning.tracks',\n componentKey: 'LearningTrackList',\n description: 'Learning tracks list',\n goal: 'Guide users through ContractSpec learning paths',\n context: 'Part of the onboarding and education experience',\n tags: [TagsEnum.Guide, 'learning', 'onboarding'],\n }),\n ],\n [\n '/learning/:trackId',\n createComponentPresentation({\n key: 'web-landing.learning.track-detail',\n componentKey: 'LearningTrackDetail',\n description: 'Learning track detail view',\n goal: 'Show progress and content for a specific learning track',\n context: 'Part of the onboarding and education experience',\n tags: [TagsEnum.Guide, 'learning', 'onboarding'],\n }),\n ],\n];\n"],"mappings":";;;;;;;;;;;;;AAqBA,MAAa,sBAAoC;CAC/C;CACA,aAAa;CACb,aAAa;CACb,aAAa;CACb;CACD;;;;AAKD,MAAa,uBAAqD;CAChE,CACE,KACA,4BAA4B;EAC1B,KAAK;EACL,cAAc;EACd,aACE;EACF,MAAM;EACN,SAAS;EACT,MAAM,CAAC,WAAW,OAAO;EAC1B,CAAC,CACH;CACD,CACE,YACA,4BAA4B;EAC1B,KAAK;EACL,cAAc;EACd,aAAa;EACb,MAAM;EACN,SAAS;EACT,MAAM,CAAC,WAAW,QAAQ;EAC3B,CAAC,CACH;CACD,CACE,YACA,4BAA4B;EAC1B,KAAK;EACL,cAAc;EACd,aAAa;EACb,MAAM;EACN,SAAS;EACT,MAAM,CAAC,WAAW,WAAW;EAC9B,CAAC,CACH;CACD,CACE,YACA,4BAA4B;EAC1B,KAAK;EACL,cAAc;EACd,aAAa;EACb,MAAM;EACN,SAAS;EACT,MAAM,CAAC,WAAW,UAAU;EAC7B,CAAC,CACH;CACD,CACE,cACA,4BAA4B;EAC1B,KAAK;EACL,cAAc;EACd,aAAa;EACb,MAAM;EACN,SAAS;EACT,MAAM,CAAC,aAAa,WAAW;EAChC,CAAC,CACH;CACF;;;;AAKD,MAAa,wBAAsD,CACjE,CACE,aACA,4BAA4B;CAC1B,KAAK;CACL,cAAc;CACd,aAAa;CACb,MAAM;CACN,SAAS;CACT,MAAM;EAAC,SAAS;EAAO;EAAY;EAAa;CACjD,CAAC,CACH,EACD,CACE,sBACA,4BAA4B;CAC1B,KAAK;CACL,cAAc;CACd,aAAa;CACb,MAAM;CACN,SAAS;CACT,MAAM;EAAC,SAAS;EAAO;EAAY;EAAa;CACjD,CAAC,CACH,CACF"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"registry.js","names":[],"sources":["../../src/registry/registry.ts"],"sourcesContent":["import {\n docBlocksToPresentationRoutes,\n type DocPresentationRoute,\n listRegisteredDocBlocks,\n metaDocs,\n techContractsDocs,\n} from '@contractspec/lib.contracts/docs';\nimport type { PresentationSpec } from '@contractspec/lib.contracts/presentations';\nimport { opsDocBlocks } from '@contractspec/bundle.library/components/docs/ops/ops.docs';\nimport { productDocs } from '@contractspec/bundle.library/components/docs/product/product.docblocks';\nimport { techContractsDocBlocks } from '@contractspec/bundle.library/components/docs/tech/contracts/tech-docs.docblocks';\nimport type { ComponentMap } from './types';\n\n// Import sub-registries\nimport { docsComponentMap, docsPresentations } from './registry-docs';\nimport {\n landingComponentMap,\n landingPresentations,\n learningPresentations,\n} from './registry-landing';\n\n/**\n * Merged component map for React rendering.\n * Maps componentKey to actual React components.\n */\nexport const componentMap: ComponentMap = {\n ...landingComponentMap,\n ...docsComponentMap,\n};\n\n/**\n * Presentation registry for all static pages.\n * Maps route paths to PresentationSpec definitions.\n */\nexport const presentationRegistry = new Map<string, PresentationSpec>([\n ...landingPresentations,\n ...learningPresentations,\n ...docsPresentations,\n]);\n\n// Add docBlocks-based presentations\nconst docRoutes: DocPresentationRoute[] = docBlocksToPresentationRoutes(\n [\n ...opsDocBlocks,\n ...productDocs,\n ...techContractsDocBlocks,\n ...techContractsDocs,\n ...metaDocs,\n ...listRegisteredDocBlocks(),\n ],\n {\n namespace: 'web-landing.docs',\n routePrefix: '/docs',\n }\n);\n\nfor (const { route, descriptor } of docRoutes) {\n presentationRegistry.set(route, descriptor);\n}\n\n/**\n * Get presentation descriptor for a given route.\n * Returns undefined if no presentation exists for the route.\n */\nexport function getPresentationForRoute(\n route: string\n): PresentationSpec | undefined {\n // Normalize route (remove trailing slash, handle root)\n const normalizedRoute = route === '/' ? '/' : route.replace(/\\/$/, '');\n return presentationRegistry.get(normalizedRoute);\n}\n\n/**\n * Check if a route has a presentation descriptor.\n */\nexport function hasPresentation(route: string): boolean {\n return getPresentationForRoute(route) !== undefined;\n}\n\n/**\n * Get all registered routes with presentations.\n */\nexport function getAllPresentationRoutes(): string[] {\n return Array.from(presentationRegistry.keys());\n}\n"],"mappings":";;;;;;;;;;;;AAyBA,MAAa,eAA6B;CACxC,GAAG;CACH,GAAG;CACJ;;;;;AAMD,MAAa,uBAAuB,IAAI,IAA8B;CACpE,GAAG;CACH,GAAG;CACH,GAAG;CACJ,CAAC;AAGF,MAAM,YAAoC,8BACxC;CACE,GAAG;CACH,GAAG;CACH,GAAG;CACH,GAAG;CACH,GAAG;CACH,GAAG,yBAAyB;CAC7B,EACD;CACE,WAAW;CACX,aAAa;CACd,CACF;AAED,KAAK,MAAM,EAAE,OAAO,gBAAgB,UAClC,sBAAqB,IAAI,OAAO,WAAW;;;;;AAO7C,SAAgB,wBACd,OAC8B;CAE9B,MAAM,kBAAkB,UAAU,MAAM,MAAM,MAAM,QAAQ,OAAO,GAAG;AACtE,QAAO,qBAAqB,IAAI,gBAAgB;;;;;AAMlD,SAAgB,gBAAgB,OAAwB;AACtD,QAAO,wBAAwB,MAAM,KAAK;;;;;AAM5C,SAAgB,2BAAqC;AACnD,QAAO,MAAM,KAAK,qBAAqB,MAAM,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"utils.js","names":[],"sources":["../../src/registry/utils.ts"],"sourcesContent":["import { renderFeaturePresentation } from '@contractspec/lib.contracts/client/react/feature-render';\nimport type { PresentationSpec } from '@contractspec/lib.contracts/presentations';\nimport type React from 'react';\nimport { presentationEngine } from './engine';\nimport { componentMap } from './registry';\nimport type { ComponentMap } from './types';\n\n/**\n * Render a presentation descriptor to markdown.\n * Returns the markdown content as a string.\n */\nexport async function renderPresentationToMarkdown(\n descriptor: PresentationSpec\n): Promise<string> {\n const result = await presentationEngine.render<{\n mimeType: string;\n body: string;\n }>('markdown', descriptor);\n\n return result.body;\n}\n\n/**\n * Render a presentation descriptor to React element.\n * Returns the React element or null if component not found.\n */\nexport async function renderPresentationToReact(\n descriptor: PresentationSpec,\n customComponentMap?: ComponentMap\n): Promise<React.ReactElement | null> {\n const map = customComponentMap ?? componentMap;\n const element = await renderFeaturePresentation(\n presentationEngine,\n 'react',\n descriptor,\n {\n componentMap: map,\n }\n );\n\n if (element && typeof element === 'object' && 'type' in element) {\n return element as React.ReactElement;\n }\n\n return null;\n}\n\n/**\n * Get markdown URL for a given route.\n * Uses llms. subdomain and .md extension.\n */\nexport function getMarkdownUrl(route: string, baseUrl?: string): string {\n const base = baseUrl ?? 'https://contractspec.io/mdx';\n const llmsBase = base.replace('contractspec.io', 'llms.contractspec.io');\n\n // Normalize route\n const normalizedRoute = route === '/' ? '/' : route.replace(/\\/$/, '');\n return `${llmsBase}${normalizedRoute}`;\n\n // Add .md extension if not root\n // const path = normalizedRoute === '/' ? '/index.md' : `${normalizedRoute}.md`;\n // return `${llmsBase}${path}`;\n}\n\n/**\n * Get AI chat URLs for various providers.\n */\nexport interface AIChatProvider {\n name: string;\n getUrl: (url: string) => string;\n}\n\nexport const aiChatProviders: AIChatProvider[] = [\n {\n name: 'ChatGPT',\n getUrl: (url: string) =>\n `https://chatgpt.com/?q=${encodeURIComponent(url)}`,\n },\n {\n name: 'Claude',\n getUrl: (url: string) =>\n `https://claude.ai/new?url=${encodeURIComponent(url)}`,\n },\n {\n name: 'Grok',\n getUrl: (url: string) =>\n `https://x.com/i/grok?url=${encodeURIComponent(url)}`,\n },\n {\n name: 'Mistral',\n getUrl: (url: string) =>\n `https://mistral.ai/chat?url=${encodeURIComponent(url)}`,\n },\n {\n name: 'Perplexity',\n getUrl: (url: string) =>\n `https://www.perplexity.ai/?q=${encodeURIComponent(url)}`,\n },\n];\n"],"mappings":";;;;;;;;;AAWA,eAAsB,6BACpB,YACiB;AAMjB,SALe,MAAM,mBAAmB,OAGrC,YAAY,WAAW,EAEZ;;;;;;AAOhB,eAAsB,0BACpB,YACA,oBACoC;CAEpC,MAAM,UAAU,MAAM,0BACpB,oBACA,SACA,YACA,EACE,cANQ,sBAAsB,cAO/B,CACF;AAED,KAAI,WAAW,OAAO,YAAY,YAAY,UAAU,QACtD,QAAO;AAGT,QAAO;;;;;;AAOT,SAAgB,eAAe,OAAe,SAA0B;AAMtE,QAAO,IALM,WAAW,+BACF,QAAQ,mBAAmB,uBAAuB,GAGhD,UAAU,MAAM,MAAM,MAAM,QAAQ,OAAO,GAAG;;AAgBxE,MAAa,kBAAoC;CAC/C;EACE,MAAM;EACN,SAAS,QACP,0BAA0B,mBAAmB,IAAI;EACpD;CACD;EACE,MAAM;EACN,SAAS,QACP,6BAA6B,mBAAmB,IAAI;EACvD;CACD;EACE,MAAM;EACN,SAAS,QACP,4BAA4B,mBAAmB,IAAI;EACtD;CACD;EACE,MAAM;EACN,SAAS,QACP,+BAA+B,mBAAmB,IAAI;EACzD;CACD;EACE,MAAM;EACN,SAAS,QACP,gCAAgC,mBAAmB,IAAI;EAC1D;CACF"}