emdash 0.39.1 → 0.40.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 (1649) hide show
  1. package/dist/action-token-DYwe4Pk0.mjs +26 -0
  2. package/dist/action-token-DYwe4Pk0.mjs.map +1 -0
  3. package/dist/activation-LOkDM5WT.mjs +382 -0
  4. package/dist/activation-LOkDM5WT.mjs.map +1 -0
  5. package/dist/adapters-B64LbYcB.d.mts +171 -0
  6. package/dist/adapters-B64LbYcB.d.mts.map +1 -0
  7. package/dist/allowed-origins-CHB8oZNM.mjs +116 -0
  8. package/dist/allowed-origins-CHB8oZNM.mjs.map +1 -0
  9. package/dist/api/route-utils.d.mts +4 -4
  10. package/dist/api/route-utils.mjs +49 -40
  11. package/dist/api/route-utils.mjs.map +1 -1
  12. package/dist/api/schemas/index.d.mts +2 -2
  13. package/dist/api/schemas/index.mjs +11 -7
  14. package/dist/api-cFFZpyS0.mjs +4718 -0
  15. package/dist/api-cFFZpyS0.mjs.map +1 -0
  16. package/dist/api-tokens-CE1ECIg0.mjs +3 -0
  17. package/dist/api-tokens-s4i4aUp_.mjs +166 -0
  18. package/dist/api-tokens-s4i4aUp_.mjs.map +1 -0
  19. package/dist/apply-CoT603H3.mjs +1163 -0
  20. package/dist/apply-CoT603H3.mjs.map +1 -0
  21. package/dist/approvals-CqMfNxak.mjs +460 -0
  22. package/dist/approvals-CqMfNxak.mjs.map +1 -0
  23. package/dist/artifact-fetch-DZMOGZ3-.mjs +818 -0
  24. package/dist/artifact-fetch-DZMOGZ3-.mjs.map +1 -0
  25. package/dist/astro/index.d.mts +14 -14
  26. package/dist/astro/index.mjs +62 -12
  27. package/dist/astro/index.mjs.map +1 -1
  28. package/dist/astro/middleware/auth.d.mts +14 -12
  29. package/dist/astro/middleware/auth.d.mts.map +1 -1
  30. package/dist/astro/middleware/auth.mjs +26 -11
  31. package/dist/astro/middleware/auth.mjs.map +1 -1
  32. package/dist/astro/middleware/media-usage-write-fence.d.mts +9 -1
  33. package/dist/astro/middleware/media-usage-write-fence.d.mts.map +1 -1
  34. package/dist/astro/middleware/media-usage-write-fence.mjs +95 -13
  35. package/dist/astro/middleware/media-usage-write-fence.mjs.map +1 -1
  36. package/dist/astro/middleware/redirect.mjs +8 -8
  37. package/dist/astro/middleware/request-context.d.mts.map +1 -1
  38. package/dist/astro/middleware/request-context.mjs +145 -47
  39. package/dist/astro/middleware/request-context.mjs.map +1 -1
  40. package/dist/astro/middleware/setup.mjs +1 -1
  41. package/dist/astro/middleware.d.mts +12 -12
  42. package/dist/astro/middleware.d.mts.map +1 -1
  43. package/dist/astro/middleware.mjs +129 -123
  44. package/dist/astro/middleware.mjs.map +1 -1
  45. package/dist/astro/routes/api/admin/allowed-domains/_domain_.mjs +14 -8
  46. package/dist/astro/routes/api/admin/allowed-domains/_domain_.mjs.map +1 -1
  47. package/dist/astro/routes/api/admin/allowed-domains/index.mjs +14 -8
  48. package/dist/astro/routes/api/admin/allowed-domains/index.mjs.map +1 -1
  49. package/dist/astro/routes/api/admin/api-tokens/_id_.mjs +5 -3
  50. package/dist/astro/routes/api/admin/api-tokens/_id_.mjs.map +1 -1
  51. package/dist/astro/routes/api/admin/api-tokens/index.mjs +6 -4
  52. package/dist/astro/routes/api/admin/api-tokens/index.mjs.map +1 -1
  53. package/dist/astro/routes/api/admin/byline-fields/_slug_/usage.mjs +6 -4
  54. package/dist/astro/routes/api/admin/byline-fields/_slug_/usage.mjs.map +1 -1
  55. package/dist/astro/routes/api/admin/byline-fields/_slug_.mjs +17 -11
  56. package/dist/astro/routes/api/admin/byline-fields/_slug_.mjs.map +1 -1
  57. package/dist/astro/routes/api/admin/byline-fields/index.mjs +17 -11
  58. package/dist/astro/routes/api/admin/byline-fields/index.mjs.map +1 -1
  59. package/dist/astro/routes/api/admin/byline-fields/reorder.mjs +17 -11
  60. package/dist/astro/routes/api/admin/byline-fields/reorder.mjs.map +1 -1
  61. package/dist/astro/routes/api/admin/bylines/_id_/index.mjs +25 -19
  62. package/dist/astro/routes/api/admin/bylines/_id_/index.mjs.map +1 -1
  63. package/dist/astro/routes/api/admin/bylines/_id_/translations.mjs +25 -19
  64. package/dist/astro/routes/api/admin/bylines/_id_/translations.mjs.map +1 -1
  65. package/dist/astro/routes/api/admin/bylines/index.mjs +25 -19
  66. package/dist/astro/routes/api/admin/bylines/index.mjs.map +1 -1
  67. package/dist/astro/routes/api/admin/comments/_id_/status.mjs +19 -13
  68. package/dist/astro/routes/api/admin/comments/_id_/status.mjs.map +1 -1
  69. package/dist/astro/routes/api/admin/comments/_id_.mjs +7 -5
  70. package/dist/astro/routes/api/admin/comments/_id_.mjs.map +1 -1
  71. package/dist/astro/routes/api/admin/comments/bulk.mjs +18 -12
  72. package/dist/astro/routes/api/admin/comments/bulk.mjs.map +1 -1
  73. package/dist/astro/routes/api/admin/comments/counts.mjs +7 -5
  74. package/dist/astro/routes/api/admin/comments/counts.mjs.map +1 -1
  75. package/dist/astro/routes/api/admin/comments/index.mjs +18 -12
  76. package/dist/astro/routes/api/admin/comments/index.mjs.map +1 -1
  77. package/dist/astro/routes/api/admin/hooks/exclusive/_hookName_.mjs +6 -4
  78. package/dist/astro/routes/api/admin/hooks/exclusive/_hookName_.mjs.map +1 -1
  79. package/dist/astro/routes/api/admin/hooks/exclusive/index.d.mts.map +1 -1
  80. package/dist/astro/routes/api/admin/hooks/exclusive/index.mjs +5 -6
  81. package/dist/astro/routes/api/admin/hooks/exclusive/index.mjs.map +1 -1
  82. package/dist/astro/routes/api/admin/media-usage/activation.mjs +21 -15
  83. package/dist/astro/routes/api/admin/media-usage/activation.mjs.map +1 -1
  84. package/dist/astro/routes/api/admin/media-usage/collection-deletions/index.mjs +23 -17
  85. package/dist/astro/routes/api/admin/media-usage/collection-deletions/index.mjs.map +1 -1
  86. package/dist/astro/routes/api/admin/media-usage/collection-deletions/retry.mjs +23 -17
  87. package/dist/astro/routes/api/admin/media-usage/collection-deletions/retry.mjs.map +1 -1
  88. package/dist/astro/routes/api/admin/media-usage/progress.mjs +26 -15
  89. package/dist/astro/routes/api/admin/media-usage/progress.mjs.map +1 -1
  90. package/dist/astro/routes/api/admin/media-usage/repair.mjs +32 -19
  91. package/dist/astro/routes/api/admin/media-usage/repair.mjs.map +1 -1
  92. package/dist/astro/routes/api/admin/media-usage/work/index.mjs +23 -17
  93. package/dist/astro/routes/api/admin/media-usage/work/index.mjs.map +1 -1
  94. package/dist/astro/routes/api/admin/media-usage/work/retry.mjs +23 -17
  95. package/dist/astro/routes/api/admin/media-usage/work/retry.mjs.map +1 -1
  96. package/dist/astro/routes/api/admin/oauth-clients/_id_.mjs +5 -3
  97. package/dist/astro/routes/api/admin/oauth-clients/_id_.mjs.map +1 -1
  98. package/dist/astro/routes/api/admin/oauth-clients/index.mjs +5 -3
  99. package/dist/astro/routes/api/admin/oauth-clients/index.mjs.map +1 -1
  100. package/dist/astro/routes/api/admin/plugins/_id_/disable.d.mts.map +1 -1
  101. package/dist/astro/routes/api/admin/plugins/_id_/disable.mjs +10 -8
  102. package/dist/astro/routes/api/admin/plugins/_id_/disable.mjs.map +1 -1
  103. package/dist/astro/routes/api/admin/plugins/_id_/enable.d.mts.map +1 -1
  104. package/dist/astro/routes/api/admin/plugins/_id_/enable.mjs +10 -8
  105. package/dist/astro/routes/api/admin/plugins/_id_/enable.mjs.map +1 -1
  106. package/dist/astro/routes/api/admin/plugins/_id_/index.mjs +72 -62
  107. package/dist/astro/routes/api/admin/plugins/_id_/index.mjs.map +1 -1
  108. package/dist/astro/routes/api/admin/plugins/_id_/mcp.mjs +6 -4
  109. package/dist/astro/routes/api/admin/plugins/_id_/mcp.mjs.map +1 -1
  110. package/dist/astro/routes/api/admin/plugins/_id_/settings.mjs +71 -61
  111. package/dist/astro/routes/api/admin/plugins/_id_/settings.mjs.map +1 -1
  112. package/dist/astro/routes/api/admin/plugins/_id_/uninstall.d.mts.map +1 -1
  113. package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs +74 -64
  114. package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs.map +1 -1
  115. package/dist/astro/routes/api/admin/plugins/_id_/update.d.mts.map +1 -1
  116. package/dist/astro/routes/api/admin/plugins/_id_/update.mjs +84 -74
  117. package/dist/astro/routes/api/admin/plugins/_id_/update.mjs.map +1 -1
  118. package/dist/astro/routes/api/admin/plugins/index.mjs +72 -62
  119. package/dist/astro/routes/api/admin/plugins/index.mjs.map +1 -1
  120. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/icon.mjs +4 -2
  121. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/icon.mjs.map +1 -1
  122. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/index.mjs +71 -61
  123. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/index.mjs.map +1 -1
  124. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.d.mts.map +1 -1
  125. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.mjs +83 -73
  126. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.mjs.map +1 -1
  127. package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs +71 -61
  128. package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs.map +1 -1
  129. package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.d.mts.map +1 -1
  130. package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.mjs +74 -64
  131. package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.mjs.map +1 -1
  132. package/dist/astro/routes/api/admin/plugins/registry/_id_/update.mjs +85 -75
  133. package/dist/astro/routes/api/admin/plugins/registry/_id_/update.mjs.map +1 -1
  134. package/dist/astro/routes/api/admin/plugins/registry/artifact.mjs +8 -6
  135. package/dist/astro/routes/api/admin/plugins/registry/artifact.mjs.map +1 -1
  136. package/dist/astro/routes/api/admin/plugins/registry/install.mjs +76 -66
  137. package/dist/astro/routes/api/admin/plugins/registry/install.mjs.map +1 -1
  138. package/dist/astro/routes/api/admin/plugins/registry/publisher-handle.d.mts +8 -0
  139. package/dist/astro/routes/api/admin/plugins/registry/publisher-handle.d.mts.map +1 -0
  140. package/dist/astro/routes/api/admin/plugins/registry/publisher-handle.mjs +221 -0
  141. package/dist/astro/routes/api/admin/plugins/registry/publisher-handle.mjs.map +1 -0
  142. package/dist/astro/routes/api/admin/plugins/registry/verify.mjs +72 -62
  143. package/dist/astro/routes/api/admin/plugins/registry/verify.mjs.map +1 -1
  144. package/dist/astro/routes/api/admin/plugins/updates.mjs +71 -61
  145. package/dist/astro/routes/api/admin/plugins/updates.mjs.map +1 -1
  146. package/dist/astro/routes/api/admin/scheduled-policy-rejections/_collection_/_id_.mjs +6 -4
  147. package/dist/astro/routes/api/admin/scheduled-policy-rejections/_collection_/_id_.mjs.map +1 -1
  148. package/dist/astro/routes/api/admin/themes/marketplace/_id_/index.mjs +71 -61
  149. package/dist/astro/routes/api/admin/themes/marketplace/_id_/index.mjs.map +1 -1
  150. package/dist/astro/routes/api/admin/themes/marketplace/_id_/thumbnail.mjs +4 -2
  151. package/dist/astro/routes/api/admin/themes/marketplace/_id_/thumbnail.mjs.map +1 -1
  152. package/dist/astro/routes/api/admin/themes/marketplace/index.mjs +71 -61
  153. package/dist/astro/routes/api/admin/themes/marketplace/index.mjs.map +1 -1
  154. package/dist/astro/routes/api/admin/transfer/_...path_.d.mts +12 -0
  155. package/dist/astro/routes/api/admin/transfer/_...path_.d.mts.map +1 -0
  156. package/dist/astro/routes/api/admin/transfer/_...path_.mjs +144 -0
  157. package/dist/astro/routes/api/admin/transfer/_...path_.mjs.map +1 -0
  158. package/dist/astro/routes/api/admin/transfer/approvals/_id_/approve.d.mts +8 -0
  159. package/dist/astro/routes/api/admin/transfer/approvals/_id_/approve.d.mts.map +1 -0
  160. package/dist/astro/routes/api/admin/transfer/approvals/_id_/approve.mjs +68 -0
  161. package/dist/astro/routes/api/admin/transfer/approvals/_id_/approve.mjs.map +1 -0
  162. package/dist/astro/routes/api/admin/transfer/approvals/_id_/deny.d.mts +8 -0
  163. package/dist/astro/routes/api/admin/transfer/approvals/_id_/deny.d.mts.map +1 -0
  164. package/dist/astro/routes/api/admin/transfer/approvals/_id_/deny.mjs +68 -0
  165. package/dist/astro/routes/api/admin/transfer/approvals/_id_/deny.mjs.map +1 -0
  166. package/dist/astro/routes/api/admin/transfer/approvals/index.d.mts +8 -0
  167. package/dist/astro/routes/api/admin/transfer/approvals/index.d.mts.map +1 -0
  168. package/dist/astro/routes/api/admin/transfer/approvals/index.mjs +67 -0
  169. package/dist/astro/routes/api/admin/transfer/approvals/index.mjs.map +1 -0
  170. package/dist/astro/routes/api/admin/transfer/capabilities.d.mts +8 -0
  171. package/dist/astro/routes/api/admin/transfer/capabilities.d.mts.map +1 -0
  172. package/dist/astro/routes/api/admin/transfer/capabilities.mjs +70 -0
  173. package/dist/astro/routes/api/admin/transfer/capabilities.mjs.map +1 -0
  174. package/dist/astro/routes/api/admin/transfer/exports/_id_/advance.d.mts +8 -0
  175. package/dist/astro/routes/api/admin/transfer/exports/_id_/advance.d.mts.map +1 -0
  176. package/dist/astro/routes/api/admin/transfer/exports/_id_/advance.mjs +67 -0
  177. package/dist/astro/routes/api/admin/transfer/exports/_id_/advance.mjs.map +1 -0
  178. package/dist/astro/routes/api/admin/transfer/exports/_id_/archive.d.mts +8 -0
  179. package/dist/astro/routes/api/admin/transfer/exports/_id_/archive.d.mts.map +1 -0
  180. package/dist/astro/routes/api/admin/transfer/exports/_id_/archive.mjs +70 -0
  181. package/dist/astro/routes/api/admin/transfer/exports/_id_/archive.mjs.map +1 -0
  182. package/dist/astro/routes/api/admin/transfer/exports/_id_/files/_...path_.d.mts +8 -0
  183. package/dist/astro/routes/api/admin/transfer/exports/_id_/files/_...path_.d.mts.map +1 -0
  184. package/dist/astro/routes/api/admin/transfer/exports/_id_/files/_...path_.mjs +69 -0
  185. package/dist/astro/routes/api/admin/transfer/exports/_id_/files/_...path_.mjs.map +1 -0
  186. package/dist/astro/routes/api/admin/transfer/exports/_id_/index.d.mts +8 -0
  187. package/dist/astro/routes/api/admin/transfer/exports/_id_/index.d.mts.map +1 -0
  188. package/dist/astro/routes/api/admin/transfer/exports/_id_/index.mjs +66 -0
  189. package/dist/astro/routes/api/admin/transfer/exports/_id_/index.mjs.map +1 -0
  190. package/dist/astro/routes/api/admin/transfer/exports/_id_/manifest.d.mts +8 -0
  191. package/dist/astro/routes/api/admin/transfer/exports/_id_/manifest.d.mts.map +1 -0
  192. package/dist/astro/routes/api/admin/transfer/exports/_id_/manifest.mjs +69 -0
  193. package/dist/astro/routes/api/admin/transfer/exports/_id_/manifest.mjs.map +1 -0
  194. package/dist/astro/routes/api/admin/transfer/exports/index.d.mts +9 -0
  195. package/dist/astro/routes/api/admin/transfer/exports/index.d.mts.map +1 -0
  196. package/dist/astro/routes/api/admin/transfer/exports/index.mjs +91 -0
  197. package/dist/astro/routes/api/admin/transfer/exports/index.mjs.map +1 -0
  198. package/dist/astro/routes/api/admin/transfer/imports/_id_/abandon.d.mts +8 -0
  199. package/dist/astro/routes/api/admin/transfer/imports/_id_/abandon.d.mts.map +1 -0
  200. package/dist/astro/routes/api/admin/transfer/imports/_id_/abandon.mjs +66 -0
  201. package/dist/astro/routes/api/admin/transfer/imports/_id_/abandon.mjs.map +1 -0
  202. package/dist/astro/routes/api/admin/transfer/imports/_id_/advance.d.mts +8 -0
  203. package/dist/astro/routes/api/admin/transfer/imports/_id_/advance.d.mts.map +1 -0
  204. package/dist/astro/routes/api/admin/transfer/imports/_id_/advance.mjs +70 -0
  205. package/dist/astro/routes/api/admin/transfer/imports/_id_/advance.mjs.map +1 -0
  206. package/dist/astro/routes/api/admin/transfer/imports/_id_/analyze.d.mts +8 -0
  207. package/dist/astro/routes/api/admin/transfer/imports/_id_/analyze.d.mts.map +1 -0
  208. package/dist/astro/routes/api/admin/transfer/imports/_id_/analyze.mjs +78 -0
  209. package/dist/astro/routes/api/admin/transfer/imports/_id_/analyze.mjs.map +1 -0
  210. package/dist/astro/routes/api/admin/transfer/imports/_id_/cancel.d.mts +8 -0
  211. package/dist/astro/routes/api/admin/transfer/imports/_id_/cancel.d.mts.map +1 -0
  212. package/dist/astro/routes/api/admin/transfer/imports/_id_/cancel.mjs +66 -0
  213. package/dist/astro/routes/api/admin/transfer/imports/_id_/cancel.mjs.map +1 -0
  214. package/dist/astro/routes/api/admin/transfer/imports/_id_/execute.d.mts +8 -0
  215. package/dist/astro/routes/api/admin/transfer/imports/_id_/execute.d.mts.map +1 -0
  216. package/dist/astro/routes/api/admin/transfer/imports/_id_/execute.mjs +77 -0
  217. package/dist/astro/routes/api/admin/transfer/imports/_id_/execute.mjs.map +1 -0
  218. package/dist/astro/routes/api/admin/transfer/imports/_id_/files/_...path_.d.mts +8 -0
  219. package/dist/astro/routes/api/admin/transfer/imports/_id_/files/_...path_.d.mts.map +1 -0
  220. package/dist/astro/routes/api/admin/transfer/imports/_id_/files/_...path_.mjs +77 -0
  221. package/dist/astro/routes/api/admin/transfer/imports/_id_/files/_...path_.mjs.map +1 -0
  222. package/dist/astro/routes/api/admin/transfer/imports/_id_/index.d.mts +8 -0
  223. package/dist/astro/routes/api/admin/transfer/imports/_id_/index.d.mts.map +1 -0
  224. package/dist/astro/routes/api/admin/transfer/imports/_id_/index.mjs +66 -0
  225. package/dist/astro/routes/api/admin/transfer/imports/_id_/index.mjs.map +1 -0
  226. package/dist/astro/routes/api/admin/transfer/imports/_id_/missing.d.mts +8 -0
  227. package/dist/astro/routes/api/admin/transfer/imports/_id_/missing.d.mts.map +1 -0
  228. package/dist/astro/routes/api/admin/transfer/imports/_id_/missing.mjs +70 -0
  229. package/dist/astro/routes/api/admin/transfer/imports/_id_/missing.mjs.map +1 -0
  230. package/dist/astro/routes/api/admin/transfer/imports/_id_/plan.d.mts +8 -0
  231. package/dist/astro/routes/api/admin/transfer/imports/_id_/plan.d.mts.map +1 -0
  232. package/dist/astro/routes/api/admin/transfer/imports/_id_/plan.mjs +67 -0
  233. package/dist/astro/routes/api/admin/transfer/imports/_id_/plan.mjs.map +1 -0
  234. package/dist/astro/routes/api/admin/transfer/imports/_id_/receipt.d.mts +8 -0
  235. package/dist/astro/routes/api/admin/transfer/imports/_id_/receipt.d.mts.map +1 -0
  236. package/dist/astro/routes/api/admin/transfer/imports/_id_/receipt.mjs +66 -0
  237. package/dist/astro/routes/api/admin/transfer/imports/_id_/receipt.mjs.map +1 -0
  238. package/dist/astro/routes/api/admin/transfer/imports/index.d.mts +9 -0
  239. package/dist/astro/routes/api/admin/transfer/imports/index.d.mts.map +1 -0
  240. package/dist/astro/routes/api/admin/transfer/imports/index.mjs +99 -0
  241. package/dist/astro/routes/api/admin/transfer/imports/index.mjs.map +1 -0
  242. package/dist/astro/routes/api/admin/users/_id_/disable.mjs +3 -1
  243. package/dist/astro/routes/api/admin/users/_id_/disable.mjs.map +1 -1
  244. package/dist/astro/routes/api/admin/users/_id_/enable.mjs +3 -1
  245. package/dist/astro/routes/api/admin/users/_id_/enable.mjs.map +1 -1
  246. package/dist/astro/routes/api/admin/users/_id_/index.mjs +14 -8
  247. package/dist/astro/routes/api/admin/users/_id_/index.mjs.map +1 -1
  248. package/dist/astro/routes/api/admin/users/_id_/send-recovery.d.mts.map +1 -1
  249. package/dist/astro/routes/api/admin/users/_id_/send-recovery.mjs +16 -6
  250. package/dist/astro/routes/api/admin/users/_id_/send-recovery.mjs.map +1 -1
  251. package/dist/astro/routes/api/admin/users/index.mjs +14 -8
  252. package/dist/astro/routes/api/admin/users/index.mjs.map +1 -1
  253. package/dist/astro/routes/api/auth/dev-bypass.mjs +5 -3
  254. package/dist/astro/routes/api/auth/dev-bypass.mjs.map +1 -1
  255. package/dist/astro/routes/api/auth/invite/accept.mjs +3 -1
  256. package/dist/astro/routes/api/auth/invite/accept.mjs.map +1 -1
  257. package/dist/astro/routes/api/auth/invite/complete.mjs +19 -13
  258. package/dist/astro/routes/api/auth/invite/complete.mjs.map +1 -1
  259. package/dist/astro/routes/api/auth/invite/index.d.mts.map +1 -1
  260. package/dist/astro/routes/api/auth/invite/index.mjs +24 -12
  261. package/dist/astro/routes/api/auth/invite/index.mjs.map +1 -1
  262. package/dist/astro/routes/api/auth/invite/register-options.mjs +18 -12
  263. package/dist/astro/routes/api/auth/invite/register-options.mjs.map +1 -1
  264. package/dist/astro/routes/api/auth/logout.mjs +4 -2
  265. package/dist/astro/routes/api/auth/logout.mjs.map +1 -1
  266. package/dist/astro/routes/api/auth/magic-link/send.d.mts.map +1 -1
  267. package/dist/astro/routes/api/auth/magic-link/send.mjs +29 -15
  268. package/dist/astro/routes/api/auth/magic-link/send.mjs.map +1 -1
  269. package/dist/astro/routes/api/auth/magic-link/verify.d.mts +2 -1
  270. package/dist/astro/routes/api/auth/magic-link/verify.d.mts.map +1 -1
  271. package/dist/astro/routes/api/auth/magic-link/verify.mjs +37 -17
  272. package/dist/astro/routes/api/auth/magic-link/verify.mjs.map +1 -1
  273. package/dist/astro/routes/api/auth/me.mjs +15 -9
  274. package/dist/astro/routes/api/auth/me.mjs.map +1 -1
  275. package/dist/astro/routes/api/auth/mode.mjs +4 -2
  276. package/dist/astro/routes/api/auth/mode.mjs.map +1 -1
  277. package/dist/astro/routes/api/auth/oauth/_provider_/callback.mjs +4 -4
  278. package/dist/astro/routes/api/auth/oauth/_provider_.mjs +2 -2
  279. package/dist/astro/routes/api/auth/passkey/_id_.mjs +14 -8
  280. package/dist/astro/routes/api/auth/passkey/_id_.mjs.map +1 -1
  281. package/dist/astro/routes/api/auth/passkey/index.mjs +3 -1
  282. package/dist/astro/routes/api/auth/passkey/index.mjs.map +1 -1
  283. package/dist/astro/routes/api/auth/passkey/options.d.mts.map +1 -1
  284. package/dist/astro/routes/api/auth/passkey/options.mjs +21 -24
  285. package/dist/astro/routes/api/auth/passkey/options.mjs.map +1 -1
  286. package/dist/astro/routes/api/auth/passkey/register/options.mjs +18 -12
  287. package/dist/astro/routes/api/auth/passkey/register/options.mjs.map +1 -1
  288. package/dist/astro/routes/api/auth/passkey/register/verify.mjs +19 -13
  289. package/dist/astro/routes/api/auth/passkey/register/verify.mjs.map +1 -1
  290. package/dist/astro/routes/api/auth/passkey/verify.mjs +19 -13
  291. package/dist/astro/routes/api/auth/passkey/verify.mjs.map +1 -1
  292. package/dist/astro/routes/api/auth/signup/complete.mjs +19 -13
  293. package/dist/astro/routes/api/auth/signup/complete.mjs.map +1 -1
  294. package/dist/astro/routes/api/auth/signup/request.mjs +18 -12
  295. package/dist/astro/routes/api/auth/signup/request.mjs.map +1 -1
  296. package/dist/astro/routes/api/auth/signup/verify.mjs +3 -1
  297. package/dist/astro/routes/api/auth/signup/verify.mjs.map +1 -1
  298. package/dist/astro/routes/api/comments/_collection_/_contentId_/index.mjs +14 -11
  299. package/dist/astro/routes/api/comments/_collection_/_contentId_/index.mjs.map +1 -1
  300. package/dist/astro/routes/api/comments/_collection_/_contentId_/reactions.mjs +21 -15
  301. package/dist/astro/routes/api/comments/_collection_/_contentId_/reactions.mjs.map +1 -1
  302. package/dist/astro/routes/api/content/_collection_/_id_/compare.mjs +4 -2
  303. package/dist/astro/routes/api/content/_collection_/_id_/compare.mjs.map +1 -1
  304. package/dist/astro/routes/api/content/_collection_/_id_/discard-draft.mjs +18 -13
  305. package/dist/astro/routes/api/content/_collection_/_id_/discard-draft.mjs.map +1 -1
  306. package/dist/astro/routes/api/content/_collection_/_id_/duplicate.mjs +4 -3
  307. package/dist/astro/routes/api/content/_collection_/_id_/duplicate.mjs.map +1 -1
  308. package/dist/astro/routes/api/content/_collection_/_id_/lock.mjs +18 -13
  309. package/dist/astro/routes/api/content/_collection_/_id_/lock.mjs.map +1 -1
  310. package/dist/astro/routes/api/content/_collection_/_id_/permanent.mjs +4 -2
  311. package/dist/astro/routes/api/content/_collection_/_id_/permanent.mjs.map +1 -1
  312. package/dist/astro/routes/api/content/_collection_/_id_/plugin-extensions/_pluginId_/_kind_/_extensionId_.mjs +10 -8
  313. package/dist/astro/routes/api/content/_collection_/_id_/plugin-extensions/_pluginId_/_kind_/_extensionId_.mjs.map +1 -1
  314. package/dist/astro/routes/api/content/_collection_/_id_/preview-url.d.mts.map +1 -1
  315. package/dist/astro/routes/api/content/_collection_/_id_/preview-url.mjs +68 -16
  316. package/dist/astro/routes/api/content/_collection_/_id_/preview-url.mjs.map +1 -1
  317. package/dist/astro/routes/api/content/_collection_/_id_/publish.mjs +18 -13
  318. package/dist/astro/routes/api/content/_collection_/_id_/publish.mjs.map +1 -1
  319. package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/children.mjs +31 -22
  320. package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/children.mjs.map +1 -1
  321. package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/parents.mjs +31 -22
  322. package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/parents.mjs.map +1 -1
  323. package/dist/astro/routes/api/content/_collection_/_id_/restore.mjs +4 -3
  324. package/dist/astro/routes/api/content/_collection_/_id_/restore.mjs.map +1 -1
  325. package/dist/astro/routes/api/content/_collection_/_id_/revisions.mjs +4 -2
  326. package/dist/astro/routes/api/content/_collection_/_id_/revisions.mjs.map +1 -1
  327. package/dist/astro/routes/api/content/_collection_/_id_/schedule.mjs +18 -13
  328. package/dist/astro/routes/api/content/_collection_/_id_/schedule.mjs.map +1 -1
  329. package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.d.mts.map +1 -1
  330. package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.mjs +38 -19
  331. package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.mjs.map +1 -1
  332. package/dist/astro/routes/api/content/_collection_/_id_/translations.mjs +4 -2
  333. package/dist/astro/routes/api/content/_collection_/_id_/translations.mjs.map +1 -1
  334. package/dist/astro/routes/api/content/_collection_/_id_/unpublish.mjs +18 -13
  335. package/dist/astro/routes/api/content/_collection_/_id_/unpublish.mjs.map +1 -1
  336. package/dist/astro/routes/api/content/_collection_/_id_.mjs +18 -13
  337. package/dist/astro/routes/api/content/_collection_/_id_.mjs.map +1 -1
  338. package/dist/astro/routes/api/content/_collection_/authors.mjs +4 -2
  339. package/dist/astro/routes/api/content/_collection_/authors.mjs.map +1 -1
  340. package/dist/astro/routes/api/content/_collection_/index.mjs +15 -10
  341. package/dist/astro/routes/api/content/_collection_/index.mjs.map +1 -1
  342. package/dist/astro/routes/api/content/_collection_/trash.mjs +15 -9
  343. package/dist/astro/routes/api/content/_collection_/trash.mjs.map +1 -1
  344. package/dist/astro/routes/api/dashboard.mjs +11 -9
  345. package/dist/astro/routes/api/dashboard.mjs.map +1 -1
  346. package/dist/astro/routes/api/dev/emails.mjs +4 -2
  347. package/dist/astro/routes/api/dev/emails.mjs.map +1 -1
  348. package/dist/astro/routes/api/health.mjs +5 -3
  349. package/dist/astro/routes/api/health.mjs.map +1 -1
  350. package/dist/astro/routes/api/import/probe.d.mts +3 -3
  351. package/dist/astro/routes/api/import/probe.mjs +27 -21
  352. package/dist/astro/routes/api/import/probe.mjs.map +1 -1
  353. package/dist/astro/routes/api/import/wordpress/analyze.mjs +5 -3
  354. package/dist/astro/routes/api/import/wordpress/analyze.mjs.map +1 -1
  355. package/dist/astro/routes/api/import/wordpress/execute.d.mts +13 -13
  356. package/dist/astro/routes/api/import/wordpress/execute.mjs +18 -16
  357. package/dist/astro/routes/api/import/wordpress/execute.mjs.map +1 -1
  358. package/dist/astro/routes/api/import/wordpress/media.d.mts +12 -12
  359. package/dist/astro/routes/api/import/wordpress/media.mjs +19 -13
  360. package/dist/astro/routes/api/import/wordpress/media.mjs.map +1 -1
  361. package/dist/astro/routes/api/import/wordpress/prepare.mjs +18 -12
  362. package/dist/astro/routes/api/import/wordpress/prepare.mjs.map +1 -1
  363. package/dist/astro/routes/api/import/wordpress/rewrite-url-helpers.d.mts +5 -1
  364. package/dist/astro/routes/api/import/wordpress/rewrite-url-helpers.d.mts.map +1 -1
  365. package/dist/astro/routes/api/import/wordpress/rewrite-url-helpers.mjs +4 -2
  366. package/dist/astro/routes/api/import/wordpress/rewrite-url-helpers.mjs.map +1 -1
  367. package/dist/astro/routes/api/import/wordpress/rewrite-urls.d.mts +13 -13
  368. package/dist/astro/routes/api/import/wordpress/rewrite-urls.mjs +29 -15
  369. package/dist/astro/routes/api/import/wordpress/rewrite-urls.mjs.map +1 -1
  370. package/dist/astro/routes/api/import/wordpress-plugin/analyze.d.mts +1 -1
  371. package/dist/astro/routes/api/import/wordpress-plugin/analyze.mjs +27 -21
  372. package/dist/astro/routes/api/import/wordpress-plugin/analyze.mjs.map +1 -1
  373. package/dist/astro/routes/api/import/wordpress-plugin/execute.d.mts +13 -13
  374. package/dist/astro/routes/api/import/wordpress-plugin/execute.mjs +38 -32
  375. package/dist/astro/routes/api/import/wordpress-plugin/execute.mjs.map +1 -1
  376. package/dist/astro/routes/api/manifest.mjs +6 -4
  377. package/dist/astro/routes/api/manifest.mjs.map +1 -1
  378. package/dist/astro/routes/api/mcp.d.mts.map +1 -1
  379. package/dist/astro/routes/api/mcp.mjs +717 -67
  380. package/dist/astro/routes/api/mcp.mjs.map +1 -1
  381. package/dist/astro/routes/api/media/_id_/confirm.mjs +19 -13
  382. package/dist/astro/routes/api/media/_id_/confirm.mjs.map +1 -1
  383. package/dist/astro/routes/api/media/_id_/replace.mjs +16 -10
  384. package/dist/astro/routes/api/media/_id_/replace.mjs.map +1 -1
  385. package/dist/astro/routes/api/media/_id_/upload.mjs +8 -6
  386. package/dist/astro/routes/api/media/_id_/upload.mjs.map +1 -1
  387. package/dist/astro/routes/api/media/_id_/usage.mjs +34 -21
  388. package/dist/astro/routes/api/media/_id_/usage.mjs.map +1 -1
  389. package/dist/astro/routes/api/media/_id_.d.mts.map +1 -1
  390. package/dist/astro/routes/api/media/_id_.mjs +37 -26
  391. package/dist/astro/routes/api/media/_id_.mjs.map +1 -1
  392. package/dist/astro/routes/api/media/asset/_id_/_filename_.mjs +5 -3
  393. package/dist/astro/routes/api/media/asset/_id_/_filename_.mjs.map +1 -1
  394. package/dist/astro/routes/api/media/file/_...key_.d.mts.map +1 -1
  395. package/dist/astro/routes/api/media/file/_...key_.mjs +31 -2
  396. package/dist/astro/routes/api/media/file/_...key_.mjs.map +1 -1
  397. package/dist/astro/routes/api/media/folders/_id_.mjs +16 -10
  398. package/dist/astro/routes/api/media/folders/_id_.mjs.map +1 -1
  399. package/dist/astro/routes/api/media/folders/index.mjs +16 -10
  400. package/dist/astro/routes/api/media/folders/index.mjs.map +1 -1
  401. package/dist/astro/routes/api/media/providers/_providerId_/_itemId_.mjs +4 -2
  402. package/dist/astro/routes/api/media/providers/_providerId_/_itemId_.mjs.map +1 -1
  403. package/dist/astro/routes/api/media/providers/_providerId_/index.mjs +4 -2
  404. package/dist/astro/routes/api/media/providers/_providerId_/index.mjs.map +1 -1
  405. package/dist/astro/routes/api/media/providers/index.mjs +4 -2
  406. package/dist/astro/routes/api/media/providers/index.mjs.map +1 -1
  407. package/dist/astro/routes/api/media/upload-url.mjs +18 -12
  408. package/dist/astro/routes/api/media/upload-url.mjs.map +1 -1
  409. package/dist/astro/routes/api/media.mjs +36 -24
  410. package/dist/astro/routes/api/media.mjs.map +1 -1
  411. package/dist/astro/routes/api/menus/_name_/items/_id_.mjs +18 -12
  412. package/dist/astro/routes/api/menus/_name_/items/_id_.mjs.map +1 -1
  413. package/dist/astro/routes/api/menus/_name_/items.mjs +18 -12
  414. package/dist/astro/routes/api/menus/_name_/items.mjs.map +1 -1
  415. package/dist/astro/routes/api/menus/_name_/reorder.mjs +18 -12
  416. package/dist/astro/routes/api/menus/_name_/reorder.mjs.map +1 -1
  417. package/dist/astro/routes/api/menus/_name_/translations.mjs +18 -12
  418. package/dist/astro/routes/api/menus/_name_/translations.mjs.map +1 -1
  419. package/dist/astro/routes/api/menus/_name_.mjs +18 -12
  420. package/dist/astro/routes/api/menus/_name_.mjs.map +1 -1
  421. package/dist/astro/routes/api/menus/index.mjs +18 -12
  422. package/dist/astro/routes/api/menus/index.mjs.map +1 -1
  423. package/dist/astro/routes/api/oauth/authorize.d.mts.map +1 -1
  424. package/dist/astro/routes/api/oauth/authorize.mjs +9 -6
  425. package/dist/astro/routes/api/oauth/authorize.mjs.map +1 -1
  426. package/dist/astro/routes/api/oauth/device/authorize.mjs +7 -5
  427. package/dist/astro/routes/api/oauth/device/authorize.mjs.map +1 -1
  428. package/dist/astro/routes/api/oauth/device/code.mjs +10 -8
  429. package/dist/astro/routes/api/oauth/device/code.mjs.map +1 -1
  430. package/dist/astro/routes/api/oauth/device/token.mjs +9 -7
  431. package/dist/astro/routes/api/oauth/device/token.mjs.map +1 -1
  432. package/dist/astro/routes/api/oauth/register.mjs +4 -2
  433. package/dist/astro/routes/api/oauth/register.mjs.map +1 -1
  434. package/dist/astro/routes/api/oauth/token/refresh.mjs +7 -5
  435. package/dist/astro/routes/api/oauth/token/refresh.mjs.map +1 -1
  436. package/dist/astro/routes/api/oauth/token/revoke.mjs +7 -5
  437. package/dist/astro/routes/api/oauth/token/revoke.mjs.map +1 -1
  438. package/dist/astro/routes/api/oauth/token.mjs +7 -5
  439. package/dist/astro/routes/api/oauth/token.mjs.map +1 -1
  440. package/dist/astro/routes/api/openapi.json.mjs +497 -12
  441. package/dist/astro/routes/api/openapi.json.mjs.map +1 -1
  442. package/dist/astro/routes/api/plugins/_pluginId_/_...path_.mjs +10 -8
  443. package/dist/astro/routes/api/plugins/_pluginId_/_...path_.mjs.map +1 -1
  444. package/dist/astro/routes/api/redirects/404s/index.mjs +21 -15
  445. package/dist/astro/routes/api/redirects/404s/index.mjs.map +1 -1
  446. package/dist/astro/routes/api/redirects/404s/summary.mjs +21 -15
  447. package/dist/astro/routes/api/redirects/404s/summary.mjs.map +1 -1
  448. package/dist/astro/routes/api/redirects/_id_.mjs +21 -15
  449. package/dist/astro/routes/api/redirects/_id_.mjs.map +1 -1
  450. package/dist/astro/routes/api/redirects/index.mjs +21 -15
  451. package/dist/astro/routes/api/redirects/index.mjs.map +1 -1
  452. package/dist/astro/routes/api/relations/_id_/index.mjs +31 -22
  453. package/dist/astro/routes/api/relations/_id_/index.mjs.map +1 -1
  454. package/dist/astro/routes/api/relations/_id_/translations.mjs +21 -16
  455. package/dist/astro/routes/api/relations/_id_/translations.mjs.map +1 -1
  456. package/dist/astro/routes/api/relations/index.mjs +31 -22
  457. package/dist/astro/routes/api/relations/index.mjs.map +1 -1
  458. package/dist/astro/routes/api/revisions/_revisionId_/index.mjs +4 -2
  459. package/dist/astro/routes/api/revisions/_revisionId_/index.mjs.map +1 -1
  460. package/dist/astro/routes/api/revisions/_revisionId_/restore.mjs +4 -3
  461. package/dist/astro/routes/api/revisions/_revisionId_/restore.mjs.map +1 -1
  462. package/dist/astro/routes/api/schema/block-types/_slug_/index.d.mts +9 -0
  463. package/dist/astro/routes/api/schema/block-types/_slug_/index.d.mts.map +1 -0
  464. package/dist/astro/routes/api/schema/block-types/_slug_/index.mjs +102 -0
  465. package/dist/astro/routes/api/schema/block-types/_slug_/index.mjs.map +1 -0
  466. package/dist/astro/routes/api/schema/block-types/_slug_/versions/_version_/activate.d.mts +8 -0
  467. package/dist/astro/routes/api/schema/block-types/_slug_/versions/_version_/activate.d.mts.map +1 -0
  468. package/dist/astro/routes/api/schema/block-types/_slug_/versions/_version_/activate.mjs +96 -0
  469. package/dist/astro/routes/api/schema/block-types/_slug_/versions/_version_/activate.mjs.map +1 -0
  470. package/dist/astro/routes/api/schema/block-types/index.d.mts +9 -0
  471. package/dist/astro/routes/api/schema/block-types/index.d.mts.map +1 -0
  472. package/dist/astro/routes/api/schema/block-types/index.mjs +102 -0
  473. package/dist/astro/routes/api/schema/block-types/index.mjs.map +1 -0
  474. package/dist/astro/routes/api/schema/collections/_slug_/fields/_fieldSlug_.mjs +71 -61
  475. package/dist/astro/routes/api/schema/collections/_slug_/fields/_fieldSlug_.mjs.map +1 -1
  476. package/dist/astro/routes/api/schema/collections/_slug_/fields/index.mjs +71 -61
  477. package/dist/astro/routes/api/schema/collections/_slug_/fields/index.mjs.map +1 -1
  478. package/dist/astro/routes/api/schema/collections/_slug_/fields/reorder.mjs +71 -61
  479. package/dist/astro/routes/api/schema/collections/_slug_/fields/reorder.mjs.map +1 -1
  480. package/dist/astro/routes/api/schema/collections/_slug_/index.mjs +71 -61
  481. package/dist/astro/routes/api/schema/collections/_slug_/index.mjs.map +1 -1
  482. package/dist/astro/routes/api/schema/collections/index.mjs +71 -61
  483. package/dist/astro/routes/api/schema/collections/index.mjs.map +1 -1
  484. package/dist/astro/routes/api/schema/collections/reorder.mjs +71 -61
  485. package/dist/astro/routes/api/schema/collections/reorder.mjs.map +1 -1
  486. package/dist/astro/routes/api/schema/index.mjs +17 -14
  487. package/dist/astro/routes/api/schema/index.mjs.map +1 -1
  488. package/dist/astro/routes/api/schema/orphans/_slug_.mjs +71 -61
  489. package/dist/astro/routes/api/schema/orphans/_slug_.mjs.map +1 -1
  490. package/dist/astro/routes/api/schema/orphans/index.mjs +71 -61
  491. package/dist/astro/routes/api/schema/orphans/index.mjs.map +1 -1
  492. package/dist/astro/routes/api/search/enable.mjs +20 -14
  493. package/dist/astro/routes/api/search/enable.mjs.map +1 -1
  494. package/dist/astro/routes/api/search/index.mjs +19 -13
  495. package/dist/astro/routes/api/search/index.mjs.map +1 -1
  496. package/dist/astro/routes/api/search/rebuild.mjs +20 -14
  497. package/dist/astro/routes/api/search/rebuild.mjs.map +1 -1
  498. package/dist/astro/routes/api/search/stats.mjs +10 -8
  499. package/dist/astro/routes/api/search/stats.mjs.map +1 -1
  500. package/dist/astro/routes/api/search/suggest.mjs +19 -13
  501. package/dist/astro/routes/api/search/suggest.mjs.map +1 -1
  502. package/dist/astro/routes/api/sections/_slug_.mjs +19 -13
  503. package/dist/astro/routes/api/sections/_slug_.mjs.map +1 -1
  504. package/dist/astro/routes/api/sections/index.mjs +19 -13
  505. package/dist/astro/routes/api/sections/index.mjs.map +1 -1
  506. package/dist/astro/routes/api/settings/backups/archives/_name_.mjs +8 -7
  507. package/dist/astro/routes/api/settings/backups/archives/_name_.mjs.map +1 -1
  508. package/dist/astro/routes/api/settings/backups/archives/index.mjs +8 -6
  509. package/dist/astro/routes/api/settings/backups/archives/index.mjs.map +1 -1
  510. package/dist/astro/routes/api/settings/backups/export.mjs +8 -7
  511. package/dist/astro/routes/api/settings/backups/export.mjs.map +1 -1
  512. package/dist/astro/routes/api/settings/backups/index.mjs +9 -8
  513. package/dist/astro/routes/api/settings/backups/index.mjs.map +1 -1
  514. package/dist/astro/routes/api/settings/email.mjs +6 -4
  515. package/dist/astro/routes/api/settings/email.mjs.map +1 -1
  516. package/dist/astro/routes/api/settings.mjs +25 -19
  517. package/dist/astro/routes/api/settings.mjs.map +1 -1
  518. package/dist/astro/routes/api/setup/admin-verify.mjs +20 -14
  519. package/dist/astro/routes/api/setup/admin-verify.mjs.map +1 -1
  520. package/dist/astro/routes/api/setup/admin.mjs +19 -13
  521. package/dist/astro/routes/api/setup/admin.mjs.map +1 -1
  522. package/dist/astro/routes/api/setup/dev-bypass.mjs +43 -37
  523. package/dist/astro/routes/api/setup/dev-bypass.mjs.map +1 -1
  524. package/dist/astro/routes/api/setup/dev-reset.mjs +4 -2
  525. package/dist/astro/routes/api/setup/dev-reset.mjs.map +1 -1
  526. package/dist/astro/routes/api/setup/index.mjs +48 -38
  527. package/dist/astro/routes/api/setup/index.mjs.map +1 -1
  528. package/dist/astro/routes/api/setup/status.mjs +5 -3
  529. package/dist/astro/routes/api/setup/status.mjs.map +1 -1
  530. package/dist/astro/routes/api/snapshot.mjs +10 -8
  531. package/dist/astro/routes/api/snapshot.mjs.map +1 -1
  532. package/dist/astro/routes/api/taxonomies/_name_/reorder.mjs +25 -19
  533. package/dist/astro/routes/api/taxonomies/_name_/reorder.mjs.map +1 -1
  534. package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_/translations.mjs +25 -19
  535. package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_/translations.mjs.map +1 -1
  536. package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.mjs +25 -19
  537. package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.mjs.map +1 -1
  538. package/dist/astro/routes/api/taxonomies/_name_/terms/index.mjs +25 -19
  539. package/dist/astro/routes/api/taxonomies/_name_/terms/index.mjs.map +1 -1
  540. package/dist/astro/routes/api/taxonomies/_name_/translations.mjs +24 -18
  541. package/dist/astro/routes/api/taxonomies/_name_/translations.mjs.map +1 -1
  542. package/dist/astro/routes/api/taxonomies/_name_.mjs +25 -19
  543. package/dist/astro/routes/api/taxonomies/_name_.mjs.map +1 -1
  544. package/dist/astro/routes/api/taxonomies/bulk-tag.d.mts +8 -0
  545. package/dist/astro/routes/api/taxonomies/bulk-tag.d.mts.map +1 -0
  546. package/dist/astro/routes/api/taxonomies/bulk-tag.mjs +295 -0
  547. package/dist/astro/routes/api/taxonomies/bulk-tag.mjs.map +1 -0
  548. package/dist/astro/routes/api/taxonomies/index.mjs +25 -19
  549. package/dist/astro/routes/api/taxonomies/index.mjs.map +1 -1
  550. package/dist/astro/routes/api/themes/preview.mjs +7 -5
  551. package/dist/astro/routes/api/themes/preview.mjs.map +1 -1
  552. package/dist/astro/routes/api/typegen.d.mts.map +1 -1
  553. package/dist/astro/routes/api/typegen.mjs +12 -9
  554. package/dist/astro/routes/api/typegen.mjs.map +1 -1
  555. package/dist/astro/routes/api/visual-editing/action-token.mjs +7 -5
  556. package/dist/astro/routes/api/visual-editing/action-token.mjs.map +1 -1
  557. package/dist/astro/routes/api/visual-editing/content/_collection_/_id_/publish.mjs +22 -16
  558. package/dist/astro/routes/api/visual-editing/content/_collection_/_id_/publish.mjs.map +1 -1
  559. package/dist/astro/routes/api/visual-editing/toolbar-labels.mjs +3 -1
  560. package/dist/astro/routes/api/visual-editing/toolbar-labels.mjs.map +1 -1
  561. package/dist/astro/routes/api/well-known/auth.mjs +2 -2
  562. package/dist/astro/routes/api/well-known/oauth-authorization-server.mjs +2 -2
  563. package/dist/astro/routes/api/well-known/oauth-protected-resource.mjs +2 -2
  564. package/dist/astro/routes/api/widget-areas/_name_/reorder.mjs +16 -10
  565. package/dist/astro/routes/api/widget-areas/_name_/reorder.mjs.map +1 -1
  566. package/dist/astro/routes/api/widget-areas/_name_/widgets/_id_.mjs +20 -14
  567. package/dist/astro/routes/api/widget-areas/_name_/widgets/_id_.mjs.map +1 -1
  568. package/dist/astro/routes/api/widget-areas/_name_/widgets.mjs +20 -14
  569. package/dist/astro/routes/api/widget-areas/_name_/widgets.mjs.map +1 -1
  570. package/dist/astro/routes/api/widget-areas/_name_.mjs +10 -8
  571. package/dist/astro/routes/api/widget-areas/_name_.mjs.map +1 -1
  572. package/dist/astro/routes/api/widget-areas/index.mjs +20 -14
  573. package/dist/astro/routes/api/widget-areas/index.mjs.map +1 -1
  574. package/dist/astro/routes/api/widget-components.mjs +4 -2
  575. package/dist/astro/routes/api/widget-components.mjs.map +1 -1
  576. package/dist/astro/routes/robots.txt.mjs +10 -10
  577. package/dist/astro/routes/sitemap-_collection_.xml.mjs +13 -13
  578. package/dist/astro/routes/sitemap.xml.mjs +11 -11
  579. package/dist/astro/types.d.mts +21 -17
  580. package/dist/astro/types.d.mts.map +1 -1
  581. package/dist/audit-RfCugiSB.mjs +127 -0
  582. package/dist/audit-RfCugiSB.mjs.map +1 -0
  583. package/dist/auth/providers/github.d.mts +1 -1
  584. package/dist/auth/providers/google.d.mts +1 -1
  585. package/dist/authoritative-records-CoJvBXAD.mjs +5172 -0
  586. package/dist/authoritative-records-CoJvBXAD.mjs.map +1 -0
  587. package/dist/authorize-seCifOMJ.mjs +49 -0
  588. package/dist/authorize-seCifOMJ.mjs.map +1 -0
  589. package/dist/backup-CBu0LrXf.mjs +246 -0
  590. package/dist/backup-CBu0LrXf.mjs.map +1 -0
  591. package/dist/block-type-registry-DUI_3KxT.mjs +6709 -0
  592. package/dist/block-type-registry-DUI_3KxT.mjs.map +1 -0
  593. package/dist/block-types-BmZmLmAD.mjs +132 -0
  594. package/dist/block-types-BmZmLmAD.mjs.map +1 -0
  595. package/dist/block-values-C_VIPr5t.mjs +175 -0
  596. package/dist/block-values-C_VIPr5t.mjs.map +1 -0
  597. package/dist/byline-DYmkXqvo.mjs +909 -0
  598. package/dist/byline-DYmkXqvo.mjs.map +1 -0
  599. package/dist/byline-fields-D28AT-Fh.mjs +123 -0
  600. package/dist/byline-fields-D28AT-Fh.mjs.map +1 -0
  601. package/dist/byline-registry-gnKscbQX.mjs +406 -0
  602. package/dist/byline-registry-gnKscbQX.mjs.map +1 -0
  603. package/dist/bylines-BPwJqoYH.mjs +232 -0
  604. package/dist/bylines-BPwJqoYH.mjs.map +1 -0
  605. package/dist/bylines-ukLaYpVZ.mjs +214 -0
  606. package/dist/bylines-ukLaYpVZ.mjs.map +1 -0
  607. package/dist/cache-m7UEkRFV.mjs +108 -0
  608. package/dist/cache-m7UEkRFV.mjs.map +1 -0
  609. package/dist/canonical-YhEQezjg.mjs +174 -0
  610. package/dist/canonical-YhEQezjg.mjs.map +1 -0
  611. package/dist/capture-triggers-kJyl_yyM.mjs +362 -0
  612. package/dist/capture-triggers-kJyl_yyM.mjs.map +1 -0
  613. package/dist/challenge-store-ppU6Uv13.mjs +51 -0
  614. package/dist/challenge-store-ppU6Uv13.mjs.map +1 -0
  615. package/dist/checksum-B2IINIlN.mjs +162 -0
  616. package/dist/checksum-B2IINIlN.mjs.map +1 -0
  617. package/dist/chrome-tags-DApCQSIk.mjs +24 -0
  618. package/dist/chrome-tags-DApCQSIk.mjs.map +1 -0
  619. package/dist/chunks-Dms7Uxbt.mjs +25 -0
  620. package/dist/chunks-Dms7Uxbt.mjs.map +1 -0
  621. package/dist/cli/index.mjs +1471 -56
  622. package/dist/cli/index.mjs.map +1 -1
  623. package/dist/client/cf-access.d.mts +1 -1
  624. package/dist/client/index.d.mts +1050 -4
  625. package/dist/client/index.d.mts.map +1 -1
  626. package/dist/client/index.mjs +193 -11
  627. package/dist/client/index.mjs.map +1 -1
  628. package/dist/collection-deletion-BIm28mo3.mjs +436 -0
  629. package/dist/collection-deletion-BIm28mo3.mjs.map +1 -0
  630. package/dist/collection-deletion-processor-Br6rxs3u.mjs +217 -0
  631. package/dist/collection-deletion-processor-Br6rxs3u.mjs.map +1 -0
  632. package/dist/collection-slugs-cache-CjGk__zp.mjs +85 -0
  633. package/dist/collection-slugs-cache-CjGk__zp.mjs.map +1 -0
  634. package/dist/comment-CrBl22OF.mjs +313 -0
  635. package/dist/comment-CrBl22OF.mjs.map +1 -0
  636. package/dist/comment-reaction-JEQ2Fpd8.mjs +85 -0
  637. package/dist/comment-reaction-JEQ2Fpd8.mjs.map +1 -0
  638. package/dist/comments-2ah9du9y.mjs +195 -0
  639. package/dist/comments-2ah9du9y.mjs.map +1 -0
  640. package/dist/comments-fHZ8ON9O.mjs +99 -0
  641. package/dist/comments-fHZ8ON9O.mjs.map +1 -0
  642. package/dist/components-CXbq7CSM.mjs +108 -0
  643. package/dist/components-CXbq7CSM.mjs.map +1 -0
  644. package/dist/config-5ii2haYu.d.mts +6528 -0
  645. package/dist/config-5ii2haYu.d.mts.map +1 -0
  646. package/dist/config-CvmjJcVw.mjs +73 -0
  647. package/dist/config-CvmjJcVw.mjs.map +1 -0
  648. package/dist/config-IhybvkIQ.mjs +242 -0
  649. package/dist/config-IhybvkIQ.mjs.map +1 -0
  650. package/dist/config-Py43JK9r.d.mts +39 -0
  651. package/dist/config-Py43JK9r.d.mts.map +1 -0
  652. package/dist/content-DFaIEDj9.mjs +2281 -0
  653. package/dist/content-DFaIEDj9.mjs.map +1 -0
  654. package/dist/content-list-query-Dra4Dalc.d.mts +26 -0
  655. package/dist/content-list-query-Dra4Dalc.d.mts.map +1 -0
  656. package/dist/content-policy-DFNw91-d.mjs +46 -0
  657. package/dist/content-policy-DFNw91-d.mjs.map +1 -0
  658. package/dist/content-repair-Q8IUrpLL.mjs +442 -0
  659. package/dist/content-repair-Q8IUrpLL.mjs.map +1 -0
  660. package/dist/context-BeGccdUX.mjs +1921 -0
  661. package/dist/context-BeGccdUX.mjs.map +1 -0
  662. package/dist/cron-7DCJwPXq.mjs +284 -0
  663. package/dist/cron-7DCJwPXq.mjs.map +1 -0
  664. package/dist/dashboard-DjrB-xxZ.mjs +151 -0
  665. package/dist/dashboard-DjrB-xxZ.mjs.map +1 -0
  666. package/dist/db/index.d.mts +3 -3
  667. package/dist/db/index.mjs +3 -3
  668. package/dist/db/libsql-migrations.d.mts +1 -1
  669. package/dist/db/libsql-migrations.mjs +6 -6
  670. package/dist/db/libsql.d.mts +1 -1
  671. package/dist/db/postgres-migrations.d.mts +1 -1
  672. package/dist/db/postgres-migrations.mjs +6 -6
  673. package/dist/db/postgres.d.mts +1 -1
  674. package/dist/db/sqlite-migrations.d.mts +1 -1
  675. package/dist/db/sqlite-migrations.mjs +6 -6
  676. package/dist/db/sqlite.d.mts +1 -1
  677. package/dist/db/sqlite.mjs +2 -2
  678. package/dist/db/sqlite.mjs.map +1 -1
  679. package/dist/default-DQ6vsviu.mjs +81 -0
  680. package/dist/default-DQ6vsviu.mjs.map +1 -0
  681. package/dist/deferred-tasks-BPxXUB4x.d.mts +9 -0
  682. package/dist/deferred-tasks-BPxXUB4x.d.mts.map +1 -0
  683. package/dist/device-flow-CRd6DXmW.mjs +466 -0
  684. package/dist/device-flow-CRd6DXmW.mjs.map +1 -0
  685. package/dist/dialect-helpers-7_IqPdh9.mjs +307 -0
  686. package/dist/dialect-helpers-7_IqPdh9.mjs.map +1 -0
  687. package/dist/digest-BarSh-pN.mjs +194 -0
  688. package/dist/digest-BarSh-pN.mjs.map +1 -0
  689. package/dist/direct-executor-BmuFJJZV.mjs +104 -0
  690. package/dist/direct-executor-BmuFJJZV.mjs.map +1 -0
  691. package/dist/dist-BNwANFJR.mjs +810 -0
  692. package/dist/dist-BNwANFJR.mjs.map +1 -0
  693. package/dist/email-console-bJn3ctqA.mjs +50 -0
  694. package/dist/email-console-bJn3ctqA.mjs.map +1 -0
  695. package/dist/email-locale-CN6WAMx0.mjs +25 -0
  696. package/dist/email-locale-CN6WAMx0.mjs.map +1 -0
  697. package/dist/emdash-runtime-DAjghyEG.mjs +4186 -0
  698. package/dist/emdash-runtime-DAjghyEG.mjs.map +1 -0
  699. package/dist/enrich-Dl3kZ-lP.mjs +194 -0
  700. package/dist/enrich-Dl3kZ-lP.mjs.map +1 -0
  701. package/dist/entry-lock-BJYdBfXb.mjs +1097 -0
  702. package/dist/entry-lock-BJYdBfXb.mjs.map +1 -0
  703. package/dist/entry-lock-DHQOxN7R.mjs +163 -0
  704. package/dist/entry-lock-DHQOxN7R.mjs.map +1 -0
  705. package/dist/entry-lock-DVhCt49A.d.mts +4368 -0
  706. package/dist/entry-lock-DVhCt49A.d.mts.map +1 -0
  707. package/dist/entry-locks-D0foLdjQ.mjs +167 -0
  708. package/dist/entry-locks-D0foLdjQ.mjs.map +1 -0
  709. package/dist/error-CfvOHP0M.mjs +90 -0
  710. package/dist/error-CfvOHP0M.mjs.map +1 -0
  711. package/dist/errors-BF0_LFhW.mjs +460 -0
  712. package/dist/errors-BF0_LFhW.mjs.map +1 -0
  713. package/dist/errors-DgE1zJGG.mjs +120 -0
  714. package/dist/errors-DgE1zJGG.mjs.map +1 -0
  715. package/dist/escape-CuaZhZvL.mjs +9 -0
  716. package/dist/escape-CuaZhZvL.mjs.map +1 -0
  717. package/dist/fence-CMDXJYc_.mjs +162 -0
  718. package/dist/fence-CMDXJYc_.mjs.map +1 -0
  719. package/dist/field-defs-cache-HIgBbqZZ.mjs +77 -0
  720. package/dist/field-defs-cache-HIgBbqZZ.mjs.map +1 -0
  721. package/dist/fts-manager-S-K0laoS.mjs +443 -0
  722. package/dist/fts-manager-S-K0laoS.mjs.map +1 -0
  723. package/dist/gc-DjKY0Ay1.mjs +75 -0
  724. package/dist/gc-DjKY0Ay1.mjs.map +1 -0
  725. package/dist/hash-SDAW6zC-.mjs +37 -0
  726. package/dist/hash-SDAW6zC-.mjs.map +1 -0
  727. package/dist/hook-result-B5bXDgS2.d.mts +31 -0
  728. package/dist/hook-result-B5bXDgS2.d.mts.map +1 -0
  729. package/dist/hreflang-D5uNnsGJ.d.mts +50 -0
  730. package/dist/hreflang-D5uNnsGJ.d.mts.map +1 -0
  731. package/dist/hreflang-DMFBL2eb.mjs +105 -0
  732. package/dist/hreflang-DMFBL2eb.mjs.map +1 -0
  733. package/dist/http-route-dispatch-BitqzwMy.mjs +339 -0
  734. package/dist/http-route-dispatch-BitqzwMy.mjs.map +1 -0
  735. package/dist/identity-IyNWwXr6.mjs +35 -0
  736. package/dist/identity-IyNWwXr6.mjs.map +1 -0
  737. package/dist/import-C3JZplWq.mjs +2020 -0
  738. package/dist/import-C3JZplWq.mjs.map +1 -0
  739. package/dist/index-D-hdtLe8.d.mts +623 -0
  740. package/dist/index-D-hdtLe8.d.mts.map +1 -0
  741. package/dist/index.d.mts +24 -24
  742. package/dist/index.mjs +105 -93
  743. package/dist/install-finalization-DfM1fj5x.mjs +58 -0
  744. package/dist/install-finalization-DfM1fj5x.mjs.map +1 -0
  745. package/dist/keys-yxLm5l35.mjs +61 -0
  746. package/dist/keys-yxLm5l35.mjs.map +1 -0
  747. package/dist/kinds-CRu_T5T5.mjs +961 -0
  748. package/dist/kinds-CRu_T5T5.mjs.map +1 -0
  749. package/dist/lifecycle-BzeGPeQ-.mjs +25 -0
  750. package/dist/lifecycle-BzeGPeQ-.mjs.map +1 -0
  751. package/dist/load-XgJiE6_3.mjs +28 -0
  752. package/dist/load-XgJiE6_3.mjs.map +1 -0
  753. package/dist/loader-BzqeR1ZN.mjs +1086 -0
  754. package/dist/loader-BzqeR1ZN.mjs.map +1 -0
  755. package/dist/loops-BQSzv5Zn.mjs +203 -0
  756. package/dist/loops-BQSzv5Zn.mjs.map +1 -0
  757. package/dist/manifest-builder-B8zR-73J.mjs +189 -0
  758. package/dist/manifest-builder-B8zR-73J.mjs.map +1 -0
  759. package/dist/manifest-schema-CY3zng_M.mjs +492 -0
  760. package/dist/manifest-schema-CY3zng_M.mjs.map +1 -0
  761. package/dist/media/image-endpoint.mjs +1 -1
  762. package/dist/media/index.d.mts +1 -1
  763. package/dist/media/index.mjs +3 -3
  764. package/dist/media/local-runtime.d.mts +14 -14
  765. package/dist/media/local-runtime.d.mts.map +1 -1
  766. package/dist/media/local-runtime.mjs +15 -16
  767. package/dist/media/local-runtime.mjs.map +1 -1
  768. package/dist/media-Pu1L6xir.mjs +408 -0
  769. package/dist/media-Pu1L6xir.mjs.map +1 -0
  770. package/dist/media-Qp5S3eH3.mjs +355 -0
  771. package/dist/media-Qp5S3eH3.mjs.map +1 -0
  772. package/dist/media-allowlist-BSoa9Vvm.mjs +44 -0
  773. package/dist/media-allowlist-BSoa9Vvm.mjs.map +1 -0
  774. package/dist/media-folders-BE0oo2eX.mjs +210 -0
  775. package/dist/media-folders-BE0oo2eX.mjs.map +1 -0
  776. package/dist/media-h7tOiDLj.mjs +221 -0
  777. package/dist/media-h7tOiDLj.mjs.map +1 -0
  778. package/dist/media-url-jArBpzIG.mjs +43 -0
  779. package/dist/media-url-jArBpzIG.mjs.map +1 -0
  780. package/dist/media-usage-My-Vi-ex.mjs +1629 -0
  781. package/dist/media-usage-My-Vi-ex.mjs.map +1 -0
  782. package/dist/media-usage-activation-HKp7zk7W.mjs +78 -0
  783. package/dist/media-usage-activation-HKp7zk7W.mjs.map +1 -0
  784. package/dist/media-usage-work-C2OZLCAd.mjs +586 -0
  785. package/dist/media-usage-work-C2OZLCAd.mjs.map +1 -0
  786. package/dist/media-usage-work-DwUNbgvS.mjs +152 -0
  787. package/dist/media-usage-work-DwUNbgvS.mjs.map +1 -0
  788. package/dist/menus-BM7BPLOb.mjs +139 -0
  789. package/dist/menus-BM7BPLOb.mjs.map +1 -0
  790. package/dist/menus-ITeAbcIF.mjs +753 -0
  791. package/dist/menus-ITeAbcIF.mjs.map +1 -0
  792. package/dist/menus-TsSGmSR4.mjs +3608 -0
  793. package/dist/menus-TsSGmSR4.mjs.map +1 -0
  794. package/dist/migrations/index.d.mts +1 -1
  795. package/dist/migrations/index.mjs +5 -5
  796. package/dist/mime-ChLqYwDk.mjs +36 -0
  797. package/dist/mime-ChLqYwDk.mjs.map +1 -0
  798. package/dist/mode-CCuKXUci.mjs +23 -0
  799. package/dist/mode-CCuKXUci.mjs.map +1 -0
  800. package/dist/node-sqlite-compat-CONMsl-x.mjs +46 -0
  801. package/dist/node-sqlite-compat-CONMsl-x.mjs.map +1 -0
  802. package/dist/normalize-CO2P8-iE.mjs +191 -0
  803. package/dist/normalize-CO2P8-iE.mjs.map +1 -0
  804. package/dist/oauth-authorization-DlMIL5_h.mjs +274 -0
  805. package/dist/oauth-authorization-DlMIL5_h.mjs.map +1 -0
  806. package/dist/oauth-clients-Djq9r_KP.mjs +266 -0
  807. package/dist/oauth-clients-Djq9r_KP.mjs.map +1 -0
  808. package/dist/oauth-state-store-BbjnZXNC.mjs +50 -0
  809. package/dist/oauth-state-store-BbjnZXNC.mjs.map +1 -0
  810. package/dist/oauth-user-lookup-vue9a64A.mjs +26 -0
  811. package/dist/oauth-user-lookup-vue9a64A.mjs.map +1 -0
  812. package/dist/object-cache/memory.d.mts +1 -1
  813. package/dist/object-cache-CqWNY5uP.mjs +582 -0
  814. package/dist/object-cache-CqWNY5uP.mjs.map +1 -0
  815. package/dist/options-DhrI7eMv.mjs +208 -0
  816. package/dist/options-DhrI7eMv.mjs.map +1 -0
  817. package/dist/options-SQCHQCPH.d.mts +81 -0
  818. package/dist/options-SQCHQCPH.d.mts.map +1 -0
  819. package/dist/page/index.d.mts +2 -2
  820. package/dist/page/index.mjs +9 -9
  821. package/dist/parse-CVgO-Qai.d.mts +168 -0
  822. package/dist/parse-CVgO-Qai.d.mts.map +1 -0
  823. package/dist/parse-DY6OD1j_.mjs +81 -0
  824. package/dist/parse-DY6OD1j_.mjs.map +1 -0
  825. package/dist/passkey-config-X_H8128a.mjs +46 -0
  826. package/dist/passkey-config-X_H8128a.mjs.map +1 -0
  827. package/dist/paths-JxokKIbr.mjs +77 -0
  828. package/dist/paths-JxokKIbr.mjs.map +1 -0
  829. package/dist/patterns-BhAvqO0S.mjs +145 -0
  830. package/dist/patterns-BhAvqO0S.mjs.map +1 -0
  831. package/dist/placeholder-MSEd8gty.d.mts +306 -0
  832. package/dist/placeholder-MSEd8gty.d.mts.map +1 -0
  833. package/dist/plan-xjcWrAah.mjs +135 -0
  834. package/dist/plan-xjcWrAah.mjs.map +1 -0
  835. package/dist/plugin-test-runtime.d.mts +38 -15
  836. package/dist/plugin-test-runtime.d.mts.map +1 -1
  837. package/dist/plugin-test-runtime.mjs +112 -100
  838. package/dist/plugin-types.d.mts +2 -2
  839. package/dist/plugin-utils.d.mts +12 -12
  840. package/dist/plugins/adapt-sandbox-entry.d.mts +12 -12
  841. package/dist/plugins/adapt-sandbox-entry.mjs +3 -3
  842. package/dist/plugins/host.d.mts +5 -5
  843. package/dist/plugins/host.mjs +45 -37
  844. package/dist/plugins-DUXUt8B9.mjs +277 -0
  845. package/dist/plugins-DUXUt8B9.mjs.map +1 -0
  846. package/dist/policy-CUvwAARc.mjs +45 -0
  847. package/dist/policy-CUvwAARc.mjs.map +1 -0
  848. package/dist/portable-text-5O_ZGUjB.mjs +307 -0
  849. package/dist/portable-text-5O_ZGUjB.mjs.map +1 -0
  850. package/dist/preview-CIUcPYr6.mjs +107 -0
  851. package/dist/preview-CIUcPYr6.mjs.map +1 -0
  852. package/dist/protocol-B97DZaFr.d.mts +61 -0
  853. package/dist/protocol-B97DZaFr.d.mts.map +1 -0
  854. package/dist/public-submission-BFBUrqst.mjs +250 -0
  855. package/dist/public-submission-BFBUrqst.mjs.map +1 -0
  856. package/dist/public-url-Bn7U0D7-.mjs +101 -0
  857. package/dist/public-url-Bn7U0D7-.mjs.map +1 -0
  858. package/dist/query-B48peoRT.mjs +890 -0
  859. package/dist/query-B48peoRT.mjs.map +1 -0
  860. package/dist/query-C4IH0uhR.mjs +41 -0
  861. package/dist/query-C4IH0uhR.mjs.map +1 -0
  862. package/dist/rate-limit-BZ6nybgc.mjs +120 -0
  863. package/dist/rate-limit-BZ6nybgc.mjs.map +1 -0
  864. package/dist/receipt-B4wJj5Jq.mjs +43 -0
  865. package/dist/receipt-B4wJj5Jq.mjs.map +1 -0
  866. package/dist/redirect-Cd1E7VUt.mjs +17 -0
  867. package/dist/redirect-Cd1E7VUt.mjs.map +1 -0
  868. package/dist/redirect-iJf5fltD.mjs +415 -0
  869. package/dist/redirect-iJf5fltD.mjs.map +1 -0
  870. package/dist/redirects-CYu1u1aK.mjs +446 -0
  871. package/dist/redirects-CYu1u1aK.mjs.map +1 -0
  872. package/dist/redirects-Cv9apQKj.mjs +148 -0
  873. package/dist/redirects-Cv9apQKj.mjs.map +1 -0
  874. package/dist/registry/testing.mjs +3 -3
  875. package/dist/relation-M4NUCb0b.mjs +334 -0
  876. package/dist/relation-M4NUCb0b.mjs.map +1 -0
  877. package/dist/relations-CCif47Oq.mjs +403 -0
  878. package/dist/relations-CCif47Oq.mjs.map +1 -0
  879. package/dist/relations-CK9CYUyr.mjs +310 -0
  880. package/dist/relations-CK9CYUyr.mjs.map +1 -0
  881. package/dist/request-cache-DzLYKm_x.mjs +104 -0
  882. package/dist/request-cache-DzLYKm_x.mjs.map +1 -0
  883. package/dist/request-context.d.mts +1 -1
  884. package/dist/request-meta-sZXt3sRo.mjs +141 -0
  885. package/dist/request-meta-sZXt3sRo.mjs.map +1 -0
  886. package/dist/resolve-2WbQsCvT.mjs +199 -0
  887. package/dist/resolve-2WbQsCvT.mjs.map +1 -0
  888. package/dist/route-wire--1hLuACz.mjs +197 -0
  889. package/dist/route-wire--1hLuACz.mjs.map +1 -0
  890. package/dist/routes-CUsM40Cc.mjs +272 -0
  891. package/dist/routes-CUsM40Cc.mjs.map +1 -0
  892. package/dist/runner-1y4J9fJB.mjs +5742 -0
  893. package/dist/runner-1y4J9fJB.mjs.map +1 -0
  894. package/dist/runner-D5_LzKXI.d.mts +68 -0
  895. package/dist/runner-D5_LzKXI.d.mts.map +1 -0
  896. package/dist/runtime.d.mts +13 -13
  897. package/dist/runtime.mjs +4 -4
  898. package/dist/schema-BABiRdsH.mjs +13 -0
  899. package/dist/schema-BABiRdsH.mjs.map +1 -0
  900. package/dist/schema-Du3MzCG0.mjs +446 -0
  901. package/dist/schema-Du3MzCG0.mjs.map +1 -0
  902. package/dist/scopes-Dbk-ElhT.mjs +34 -0
  903. package/dist/scopes-Dbk-ElhT.mjs.map +1 -0
  904. package/dist/search-Bt1PL1jf.mjs +448 -0
  905. package/dist/search-Bt1PL1jf.mjs.map +1 -0
  906. package/dist/secrets-CIi0nFiR.mjs +341 -0
  907. package/dist/secrets-CIi0nFiR.mjs.map +1 -0
  908. package/dist/sections-Ddptx_o9.mjs +346 -0
  909. package/dist/sections-Ddptx_o9.mjs.map +1 -0
  910. package/dist/seed/index.d.mts +2 -2
  911. package/dist/seed/index.mjs +35 -30
  912. package/dist/seo/index.d.mts +3 -3
  913. package/dist/seo/index.mjs +25 -21
  914. package/dist/seo/index.mjs.map +1 -1
  915. package/dist/seo-CZT2oLtT.mjs +114 -0
  916. package/dist/seo-CZT2oLtT.mjs.map +1 -0
  917. package/dist/seo-D5w3-Azy.mjs +133 -0
  918. package/dist/seo-D5w3-Azy.mjs.map +1 -0
  919. package/dist/service-DuykXPyW.mjs +150 -0
  920. package/dist/service-DuykXPyW.mjs.map +1 -0
  921. package/dist/session-user-BhaVp8w0.mjs +51 -0
  922. package/dist/session-user-BhaVp8w0.mjs.map +1 -0
  923. package/dist/settings-2xNYr90o.mjs +51 -0
  924. package/dist/settings-2xNYr90o.mjs.map +1 -0
  925. package/dist/settings-CgjRWGW9.mjs +439 -0
  926. package/dist/settings-CgjRWGW9.mjs.map +1 -0
  927. package/dist/settings-DYidIB26.mjs +61 -0
  928. package/dist/settings-DYidIB26.mjs.map +1 -0
  929. package/dist/setup-complete-bOogcHWG.mjs +26 -0
  930. package/dist/setup-complete-bOogcHWG.mjs.map +1 -0
  931. package/dist/setup-nonce-0EGuKM4s.mjs +25 -0
  932. package/dist/setup-nonce-0EGuKM4s.mjs.map +1 -0
  933. package/dist/site-settings-DOgRUoFX.mjs +50 -0
  934. package/dist/site-settings-DOgRUoFX.mjs.map +1 -0
  935. package/dist/site-url-BU_bbxwj.mjs +16 -0
  936. package/dist/site-url-BU_bbxwj.mjs.map +1 -0
  937. package/dist/snapshot-CugwUqKQ.mjs +237 -0
  938. package/dist/snapshot-CugwUqKQ.mjs.map +1 -0
  939. package/dist/ssrf-CJUnJymJ.mjs +406 -0
  940. package/dist/ssrf-CJUnJymJ.mjs.map +1 -0
  941. package/dist/stage-DgrBz_du.mjs +662 -0
  942. package/dist/stage-DgrBz_du.mjs.map +1 -0
  943. package/dist/state-DDiPySSG.mjs +153 -0
  944. package/dist/state-DDiPySSG.mjs.map +1 -0
  945. package/dist/status-DZKIG4a9.mjs +30 -0
  946. package/dist/status-DZKIG4a9.mjs.map +1 -0
  947. package/dist/storage/local.d.mts +1 -1
  948. package/dist/storage/local.mjs +1 -1
  949. package/dist/storage/s3.d.mts +1 -1
  950. package/dist/storage/s3.mjs +1 -1
  951. package/dist/storage-query-Bdv7A62k.d.mts +1576 -0
  952. package/dist/storage-query-Bdv7A62k.d.mts.map +1 -0
  953. package/dist/tar-_1AgTYFu.mjs +449 -0
  954. package/dist/tar-_1AgTYFu.mjs.map +1 -0
  955. package/dist/target-_7pn2Gbg.mjs +27 -0
  956. package/dist/target-_7pn2Gbg.mjs.map +1 -0
  957. package/dist/taxonomies-C1IwNe8Q.mjs +697 -0
  958. package/dist/taxonomies-C1IwNe8Q.mjs.map +1 -0
  959. package/dist/taxonomies-C_XMoRcX.mjs +939 -0
  960. package/dist/taxonomies-C_XMoRcX.mjs.map +1 -0
  961. package/dist/taxonomy-C3Fu1YeH.mjs +525 -0
  962. package/dist/taxonomy-C3Fu1YeH.mjs.map +1 -0
  963. package/dist/tokens-u78jETkX.mjs +171 -0
  964. package/dist/tokens-u78jETkX.mjs.map +1 -0
  965. package/dist/transfer-BhUCrgDc.mjs +8675 -0
  966. package/dist/transfer-BhUCrgDc.mjs.map +1 -0
  967. package/dist/transfer-DIGvR9Af.mjs +166 -0
  968. package/dist/transfer-DIGvR9Af.mjs.map +1 -0
  969. package/dist/transfer-download-Pml7RMio.mjs +33 -0
  970. package/dist/transfer-download-Pml7RMio.mjs.map +1 -0
  971. package/dist/transformations-9gfpwY65.mjs +196 -0
  972. package/dist/transformations-9gfpwY65.mjs.map +1 -0
  973. package/dist/transport-BIfH7_hx.d.mts +42 -0
  974. package/dist/transport-BIfH7_hx.d.mts.map +1 -0
  975. package/dist/transport-DKWIq53q.mjs +136 -0
  976. package/dist/transport-DKWIq53q.mjs.map +1 -0
  977. package/dist/trusted-proxy-tKiVtyTD.mjs +51 -0
  978. package/dist/trusted-proxy-tKiVtyTD.mjs.map +1 -0
  979. package/dist/turnstile-DpsoyOfg.mjs +53 -0
  980. package/dist/turnstile-DpsoyOfg.mjs.map +1 -0
  981. package/dist/types-B4sUC2p1.d.mts +198 -0
  982. package/dist/types-B4sUC2p1.d.mts.map +1 -0
  983. package/dist/types-B7Lmsh1E.d.mts +887 -0
  984. package/dist/types-B7Lmsh1E.d.mts.map +1 -0
  985. package/dist/types-BZakh7Ym.mjs +22 -0
  986. package/dist/types-BZakh7Ym.mjs.map +1 -0
  987. package/dist/types-B_CppEmv.d.mts +264 -0
  988. package/dist/types-B_CppEmv.d.mts.map +1 -0
  989. package/dist/types-BcrBrE6-.mjs +159 -0
  990. package/dist/types-BcrBrE6-.mjs.map +1 -0
  991. package/dist/types-CAZgq9fO.d.mts +124 -0
  992. package/dist/types-CAZgq9fO.d.mts.map +1 -0
  993. package/dist/types-Cd-O03VG.d.mts +363 -0
  994. package/dist/types-Cd-O03VG.d.mts.map +1 -0
  995. package/dist/types-Cr-Kg-3D.d.mts +1641 -0
  996. package/dist/types-Cr-Kg-3D.d.mts.map +1 -0
  997. package/dist/types-D2fvWd1i.d.mts +359 -0
  998. package/dist/types-D2fvWd1i.d.mts.map +1 -0
  999. package/dist/types-D7HUsguf.mjs +77 -0
  1000. package/dist/types-D7HUsguf.mjs.map +1 -0
  1001. package/dist/types-DA1Te3Oy.d.mts +198 -0
  1002. package/dist/types-DA1Te3Oy.d.mts.map +1 -0
  1003. package/dist/types-DhV6Q5bP.mjs +18 -0
  1004. package/dist/types-DhV6Q5bP.mjs.map +1 -0
  1005. package/dist/types-DnnVSl6Y.d.mts +85 -0
  1006. package/dist/types-DnnVSl6Y.d.mts.map +1 -0
  1007. package/dist/types-VT4-BugW.mjs +16 -0
  1008. package/dist/types-VT4-BugW.mjs.map +1 -0
  1009. package/dist/upload-attempts-B68ZGNu9.mjs +32 -0
  1010. package/dist/upload-attempts-B68ZGNu9.mjs.map +1 -0
  1011. package/dist/url-pattern-CCeZMGOh.mjs +33 -0
  1012. package/dist/url-pattern-CCeZMGOh.mjs.map +1 -0
  1013. package/dist/user-DDSL-sGw.mjs +171 -0
  1014. package/dist/user-DDSL-sGw.mjs.map +1 -0
  1015. package/dist/utils-DdhmO9w9.mjs +439 -0
  1016. package/dist/utils-DdhmO9w9.mjs.map +1 -0
  1017. package/dist/validate-CHosPEhs.mjs +453 -0
  1018. package/dist/validate-CHosPEhs.mjs.map +1 -0
  1019. package/dist/validate-CM79QXYE.d.mts +432 -0
  1020. package/dist/validate-CM79QXYE.d.mts.map +1 -0
  1021. package/dist/validation-BFecQczG.mjs +218 -0
  1022. package/dist/validation-BFecQczG.mjs.map +1 -0
  1023. package/dist/version-BRZXVifl.mjs +9 -0
  1024. package/dist/version-BRZXVifl.mjs.map +1 -0
  1025. package/dist/version-DUQDHgrf.mjs +7 -0
  1026. package/dist/version-DUQDHgrf.mjs.map +1 -0
  1027. package/dist/widgets-WdV72brA.mjs +126 -0
  1028. package/dist/widgets-WdV72brA.mjs.map +1 -0
  1029. package/dist/wxr-taxonomies-BHTdqkmZ.d.mts +34 -0
  1030. package/dist/wxr-taxonomies-BHTdqkmZ.d.mts.map +1 -0
  1031. package/dist/wxr-taxonomies-DP6ESgMN.mjs +372 -0
  1032. package/dist/wxr-taxonomies-DP6ESgMN.mjs.map +1 -0
  1033. package/dist/zod-generator-D6uE4WiS.mjs +389 -0
  1034. package/dist/zod-generator-D6uE4WiS.mjs.map +1 -0
  1035. package/package.json +6 -5
  1036. package/src/api/authorize.ts +17 -0
  1037. package/src/api/email-locale.ts +24 -0
  1038. package/src/api/errors.ts +16 -0
  1039. package/src/api/handlers/api-tokens.ts +18 -3
  1040. package/src/api/handlers/block-types.ts +129 -0
  1041. package/src/api/handlers/bulk-tag.ts +309 -0
  1042. package/src/api/handlers/comments.ts +0 -28
  1043. package/src/api/handlers/index.ts +10 -0
  1044. package/src/api/handlers/manifest.ts +8 -1
  1045. package/src/api/handlers/marketplace.ts +22 -16
  1046. package/src/api/handlers/media-usage.ts +31 -12
  1047. package/src/api/handlers/media.ts +19 -14
  1048. package/src/api/handlers/schema.ts +33 -8
  1049. package/src/api/handlers/settings.ts +2 -2
  1050. package/src/api/handlers/snapshot.ts +4 -0
  1051. package/src/api/handlers/taxonomies.ts +132 -83
  1052. package/src/api/handlers/transfer.ts +1347 -0
  1053. package/src/api/handlers/validate-media-fields.ts +124 -12
  1054. package/src/api/media-usage-write-fence.ts +5 -26
  1055. package/src/api/openapi/document.ts +614 -5
  1056. package/src/api/schemas/auth.ts +7 -1
  1057. package/src/api/schemas/common.ts +5 -0
  1058. package/src/api/schemas/content.ts +20 -1
  1059. package/src/api/schemas/media-usage.ts +11 -0
  1060. package/src/api/schemas/menus.ts +1 -1
  1061. package/src/api/schemas/schema.ts +117 -0
  1062. package/src/api/schemas/settings.ts +3 -3
  1063. package/src/api/schemas/taxonomies.ts +18 -0
  1064. package/src/api/schemas/transfer.ts +249 -0
  1065. package/src/api/transfer-download.ts +36 -0
  1066. package/src/api/types.ts +3 -0
  1067. package/src/astro/integration/routes.ts +31 -0
  1068. package/src/astro/integration/vite-config.ts +26 -0
  1069. package/src/astro/middleware/auth.ts +30 -7
  1070. package/src/astro/middleware/media-usage-write-fence.ts +106 -11
  1071. package/src/astro/middleware/request-context.ts +16 -2
  1072. package/src/astro/middleware.ts +38 -18
  1073. package/src/astro/routes/admin.astro +3 -1
  1074. package/src/astro/routes/api/admin/hooks/exclusive/index.ts +1 -5
  1075. package/src/astro/routes/api/admin/plugins/[id]/disable.ts +4 -3
  1076. package/src/astro/routes/api/admin/plugins/[id]/enable.ts +4 -3
  1077. package/src/astro/routes/api/admin/plugins/[id]/uninstall.ts +4 -3
  1078. package/src/astro/routes/api/admin/plugins/[id]/update.ts +4 -3
  1079. package/src/astro/routes/api/admin/plugins/marketplace/[id]/install.ts +4 -3
  1080. package/src/astro/routes/api/admin/plugins/registry/[id]/uninstall.ts +4 -3
  1081. package/src/astro/routes/api/admin/plugins/registry/[id]/update.ts +3 -3
  1082. package/src/astro/routes/api/admin/plugins/registry/install.ts +3 -3
  1083. package/src/astro/routes/api/admin/plugins/registry/publisher-handle.ts +59 -0
  1084. package/src/astro/routes/api/admin/transfer/[...path].ts +143 -0
  1085. package/src/astro/routes/api/admin/transfer/approvals/[id]/approve.ts +35 -0
  1086. package/src/astro/routes/api/admin/transfer/approvals/[id]/deny.ts +35 -0
  1087. package/src/astro/routes/api/admin/transfer/approvals/index.ts +33 -0
  1088. package/src/astro/routes/api/admin/transfer/capabilities.ts +36 -0
  1089. package/src/astro/routes/api/admin/transfer/exports/[id]/advance.ts +34 -0
  1090. package/src/astro/routes/api/admin/transfer/exports/[id]/archive.ts +35 -0
  1091. package/src/astro/routes/api/admin/transfer/exports/[id]/files/[...path].ts +40 -0
  1092. package/src/astro/routes/api/admin/transfer/exports/[id]/index.ts +25 -0
  1093. package/src/astro/routes/api/admin/transfer/exports/[id]/manifest.ts +38 -0
  1094. package/src/astro/routes/api/admin/transfer/exports/index.ts +64 -0
  1095. package/src/astro/routes/api/admin/transfer/imports/[id]/abandon.ts +28 -0
  1096. package/src/astro/routes/api/admin/transfer/imports/[id]/advance.ts +37 -0
  1097. package/src/astro/routes/api/admin/transfer/imports/[id]/analyze.ts +51 -0
  1098. package/src/astro/routes/api/admin/transfer/imports/[id]/cancel.ts +27 -0
  1099. package/src/astro/routes/api/admin/transfer/imports/[id]/execute.ts +48 -0
  1100. package/src/astro/routes/api/admin/transfer/imports/[id]/files/[...path].ts +54 -0
  1101. package/src/astro/routes/api/admin/transfer/imports/[id]/index.ts +25 -0
  1102. package/src/astro/routes/api/admin/transfer/imports/[id]/missing.ts +34 -0
  1103. package/src/astro/routes/api/admin/transfer/imports/[id]/plan.ts +29 -0
  1104. package/src/astro/routes/api/admin/transfer/imports/[id]/receipt.ts +25 -0
  1105. package/src/astro/routes/api/admin/transfer/imports/index.ts +85 -0
  1106. package/src/astro/routes/api/admin/users/[id]/send-recovery.ts +9 -1
  1107. package/src/astro/routes/api/auth/invite/index.ts +15 -1
  1108. package/src/astro/routes/api/auth/magic-link/send.ts +9 -1
  1109. package/src/astro/routes/api/auth/magic-link/verify.ts +37 -39
  1110. package/src/astro/routes/api/auth/passkey/options.ts +2 -21
  1111. package/src/astro/routes/api/content/[collection]/[id]/preview-url.ts +64 -13
  1112. package/src/astro/routes/api/content/[collection]/[id]/terms/[taxonomy].ts +16 -1
  1113. package/src/astro/routes/api/import/wordpress/rewrite-url-helpers.ts +11 -4
  1114. package/src/astro/routes/api/mcp.ts +1 -0
  1115. package/src/astro/routes/api/media/[id].ts +5 -15
  1116. package/src/astro/routes/api/media/file/[...key].ts +30 -5
  1117. package/src/astro/routes/api/oauth/authorize.ts +4 -0
  1118. package/src/astro/routes/api/schema/block-types/[slug]/index.ts +29 -0
  1119. package/src/astro/routes/api/schema/block-types/[slug]/versions/[version]/activate.ts +31 -0
  1120. package/src/astro/routes/api/schema/block-types/index.ts +29 -0
  1121. package/src/astro/routes/api/taxonomies/bulk-tag.ts +29 -0
  1122. package/src/astro/routes/api/typegen.ts +8 -4
  1123. package/src/astro/types.ts +4 -0
  1124. package/src/auth/api-tokens.ts +1 -0
  1125. package/src/auth/rate-limit.ts +2 -1
  1126. package/src/auth/scopes.ts +11 -0
  1127. package/src/cleanup.ts +14 -0
  1128. package/src/cli/client-factory.ts +6 -1
  1129. package/src/cli/commands/export-seed.ts +41 -15
  1130. package/src/cli/commands/seed.ts +6 -2
  1131. package/src/cli/commands/site.ts +556 -0
  1132. package/src/cli/index.ts +2 -0
  1133. package/src/cli/site/archive.ts +273 -0
  1134. package/src/cli/site/export.ts +311 -0
  1135. package/src/cli/site/import.ts +815 -0
  1136. package/src/cli/site/shared.ts +241 -0
  1137. package/src/client/index.ts +414 -11
  1138. package/src/client/portable-text.ts +41 -0
  1139. package/src/comments/public-submission.ts +19 -11
  1140. package/src/components/Blocks.astro +46 -0
  1141. package/src/components/Gallery.astro +2 -1
  1142. package/src/components/Image.astro +51 -6
  1143. package/src/components/InlinePortableTextEditor.tsx +28 -18
  1144. package/src/components/blocks.ts +44 -0
  1145. package/src/components/index.ts +14 -4
  1146. package/src/content/converters/gallery.ts +54 -16
  1147. package/src/content/converters/image-link.ts +27 -0
  1148. package/src/content/converters/index.ts +1 -0
  1149. package/src/content/converters/portable-text-to-prosemirror.ts +10 -7
  1150. package/src/content/converters/prosemirror-to-portable-text.ts +14 -0
  1151. package/src/content/converters/types.ts +17 -0
  1152. package/src/database/content-datetime.ts +19 -2
  1153. package/src/database/migrations/035_bounded_404_log.ts +28 -39
  1154. package/src/database/migrations/083_block_types.ts +58 -0
  1155. package/src/database/migrations/084_site_transfer.ts +264 -0
  1156. package/src/database/migrations/085_taxonomy_def_groups.ts +155 -0
  1157. package/src/database/migrations/runner.ts +6 -0
  1158. package/src/database/repositories/audit.ts +10 -1
  1159. package/src/database/repositories/byline.ts +4 -1
  1160. package/src/database/repositories/content.ts +83 -11
  1161. package/src/database/repositories/media-usage.ts +43 -13
  1162. package/src/database/repositories/media.ts +32 -1
  1163. package/src/database/repositories/options.ts +12 -0
  1164. package/src/database/repositories/revision.ts +6 -3
  1165. package/src/database/repositories/taxonomy-def.ts +126 -0
  1166. package/src/database/repositories/taxonomy.ts +65 -26
  1167. package/src/database/types.ts +133 -1
  1168. package/src/db/sqlite.ts +1 -1
  1169. package/src/emdash-runtime.ts +287 -51
  1170. package/src/import/utils.ts +8 -1
  1171. package/src/import/wxr-taxonomies.ts +11 -67
  1172. package/src/index.ts +26 -1
  1173. package/src/loader.ts +9 -5
  1174. package/src/mcp/server.ts +521 -29
  1175. package/src/mcp/transfer.ts +569 -0
  1176. package/src/media/local-runtime.ts +5 -18
  1177. package/src/media/upload-attempts.ts +5 -0
  1178. package/src/media/url.ts +15 -0
  1179. package/src/media/usage/content-fields.ts +69 -5
  1180. package/src/media/usage/content-refresh.ts +13 -66
  1181. package/src/media/usage/content-repair.ts +10 -2
  1182. package/src/media/usage/extractor.ts +74 -3
  1183. package/src/media/usage/projection-fingerprint.ts +14 -0
  1184. package/src/media/usage/schema-invalidation.ts +72 -0
  1185. package/src/media/usage/site-settings.ts +52 -0
  1186. package/src/media/usage/types.ts +2 -0
  1187. package/src/object-cache/index.ts +69 -4
  1188. package/src/plugin-test-runtime.ts +1 -0
  1189. package/src/plugins/context.ts +104 -56
  1190. package/src/plugins/cron.ts +6 -4
  1191. package/src/plugins/define-plugin.ts +11 -1
  1192. package/src/plugins/email-console.ts +2 -0
  1193. package/src/plugins/email.ts +16 -0
  1194. package/src/plugins/hooks.ts +33 -9
  1195. package/src/plugins/manifest-schema.ts +1 -0
  1196. package/src/plugins/route-error.ts +57 -0
  1197. package/src/plugins/routes.ts +5 -60
  1198. package/src/plugins/sandbox/types.ts +22 -2
  1199. package/src/plugins/types.ts +4 -0
  1200. package/src/registry/artifact-fetch.ts +17 -4
  1201. package/src/registry/publisher-handle.ts +273 -0
  1202. package/src/schema/block-type-contract.ts +478 -0
  1203. package/src/schema/block-type-registry.ts +689 -0
  1204. package/src/schema/block-types.ts +110 -0
  1205. package/src/schema/block-values.ts +293 -0
  1206. package/src/schema/byline-registry.ts +1 -1
  1207. package/src/schema/index.ts +28 -0
  1208. package/src/schema/registry.ts +462 -12
  1209. package/src/schema/types.ts +12 -1
  1210. package/src/schema/zod-generator.ts +92 -9
  1211. package/src/search/fts-manager.ts +40 -0
  1212. package/src/seed/apply.ts +173 -49
  1213. package/src/seed/types.ts +23 -3
  1214. package/src/seed/validate.ts +131 -7
  1215. package/src/settings/index.ts +32 -9
  1216. package/src/settings/types.ts +15 -0
  1217. package/src/taxonomies/index.ts +72 -83
  1218. package/src/transfer/analyze/index.ts +45 -0
  1219. package/src/transfer/analyze/issues.ts +55 -0
  1220. package/src/transfer/analyze/plan.ts +327 -0
  1221. package/src/transfer/analyze/read.ts +134 -0
  1222. package/src/transfer/analyze/step.ts +551 -0
  1223. package/src/transfer/analyze/target.ts +269 -0
  1224. package/src/transfer/analyze/unique-keys.ts +228 -0
  1225. package/src/transfer/analyze/validate.ts +1412 -0
  1226. package/src/transfer/analyze/values.ts +227 -0
  1227. package/src/transfer/analyze/write-rules.ts +196 -0
  1228. package/src/transfer/audit.ts +38 -0
  1229. package/src/transfer/auth.ts +25 -0
  1230. package/src/transfer/container/tar.ts +242 -0
  1231. package/src/transfer/domain.ts +248 -0
  1232. package/src/transfer/errors.ts +134 -0
  1233. package/src/transfer/export/exporter.ts +1067 -0
  1234. package/src/transfer/export/fence.ts +84 -0
  1235. package/src/transfer/export/media.ts +165 -0
  1236. package/src/transfer/export/readers.ts +1164 -0
  1237. package/src/transfer/export/verify.ts +677 -0
  1238. package/src/transfer/fence.ts +193 -0
  1239. package/src/transfer/format/canonical.ts +151 -0
  1240. package/src/transfer/format/column-codec.ts +275 -0
  1241. package/src/transfer/format/columns.ts +707 -0
  1242. package/src/transfer/format/digest.ts +287 -0
  1243. package/src/transfer/format/features.ts +91 -0
  1244. package/src/transfer/format/issues.ts +39 -0
  1245. package/src/transfer/format/kinds.ts +936 -0
  1246. package/src/transfer/format/limits.ts +87 -0
  1247. package/src/transfer/format/manifest.ts +297 -0
  1248. package/src/transfer/format/media-refs.ts +716 -0
  1249. package/src/transfer/format/paths.ts +73 -0
  1250. package/src/transfer/format/plan.ts +162 -0
  1251. package/src/transfer/format/receipt.ts +43 -0
  1252. package/src/transfer/format/records.ts +127 -0
  1253. package/src/transfer/format/settings.ts +94 -0
  1254. package/src/transfer/format/transformations.ts +260 -0
  1255. package/src/transfer/format/version.ts +9 -0
  1256. package/src/transfer/gc.ts +103 -0
  1257. package/src/transfer/import/advance.ts +522 -0
  1258. package/src/transfer/import/context.ts +281 -0
  1259. package/src/transfer/import/entries.ts +186 -0
  1260. package/src/transfer/import/ids.ts +40 -0
  1261. package/src/transfer/import/index.ts +15 -0
  1262. package/src/transfer/import/media.ts +141 -0
  1263. package/src/transfer/import/rebuild.ts +300 -0
  1264. package/src/transfer/import/rows.ts +114 -0
  1265. package/src/transfer/import/scaffold.ts +221 -0
  1266. package/src/transfer/import/sql.ts +134 -0
  1267. package/src/transfer/import/stages.ts +329 -0
  1268. package/src/transfer/import/writers.ts +370 -0
  1269. package/src/transfer/index.ts +472 -0
  1270. package/src/transfer/ops/approvals.ts +359 -0
  1271. package/src/transfer/ops/budget.ts +82 -0
  1272. package/src/transfer/ops/collation.ts +21 -0
  1273. package/src/transfer/ops/identity-map.ts +142 -0
  1274. package/src/transfer/ops/media-blobs.ts +135 -0
  1275. package/src/transfer/ops/operations.ts +842 -0
  1276. package/src/transfer/ops/package-index.ts +159 -0
  1277. package/src/transfer/ops/staged-files.ts +231 -0
  1278. package/src/transfer/ops/states.ts +265 -0
  1279. package/src/transfer/ops/time.ts +54 -0
  1280. package/src/transfer/schema-importer.ts +34 -0
  1281. package/src/transfer/site-id.ts +30 -0
  1282. package/src/transfer/staging/assembler.ts +217 -0
  1283. package/src/transfer/staging/keys.ts +94 -0
  1284. package/src/transfer/staging/package.ts +229 -0
  1285. package/src/transfer/staging/stage.ts +231 -0
  1286. package/src/ui.ts +19 -0
  1287. package/src/visual-editing/toolbar.ts +125 -37
  1288. package/dist/action-token-On1sot_c.mjs +0 -26
  1289. package/dist/action-token-On1sot_c.mjs.map +0 -1
  1290. package/dist/activation-CaMfdBt1.mjs +0 -382
  1291. package/dist/activation-CaMfdBt1.mjs.map +0 -1
  1292. package/dist/adapters-Cq10K4_c.d.mts +0 -171
  1293. package/dist/adapters-Cq10K4_c.d.mts.map +0 -1
  1294. package/dist/allowed-origins-1Sa-2wZK.mjs +0 -116
  1295. package/dist/allowed-origins-1Sa-2wZK.mjs.map +0 -1
  1296. package/dist/api-BB5BoQbN.mjs +0 -4831
  1297. package/dist/api-BB5BoQbN.mjs.map +0 -1
  1298. package/dist/api-tokens-BIXItFKV.mjs +0 -163
  1299. package/dist/api-tokens-BIXItFKV.mjs.map +0 -1
  1300. package/dist/api-tokens-DS1VzN7_.mjs +0 -3
  1301. package/dist/apply-CsKm_5S5.mjs +0 -1005
  1302. package/dist/apply-CsKm_5S5.mjs.map +0 -1
  1303. package/dist/artifact-fetch-COiMhVgk.mjs +0 -813
  1304. package/dist/artifact-fetch-COiMhVgk.mjs.map +0 -1
  1305. package/dist/authoritative-records-DbqshfKD.mjs +0 -5172
  1306. package/dist/authoritative-records-DbqshfKD.mjs.map +0 -1
  1307. package/dist/authorize-BXpfMpp0.mjs +0 -40
  1308. package/dist/authorize-BXpfMpp0.mjs.map +0 -1
  1309. package/dist/backup-B4tByjBb.mjs +0 -246
  1310. package/dist/backup-B4tByjBb.mjs.map +0 -1
  1311. package/dist/byline-C8ndlnP0.mjs +0 -906
  1312. package/dist/byline-C8ndlnP0.mjs.map +0 -1
  1313. package/dist/byline-fields-CsrdvaLV.mjs +0 -123
  1314. package/dist/byline-fields-CsrdvaLV.mjs.map +0 -1
  1315. package/dist/byline-registry-D6lWzXk6.mjs +0 -406
  1316. package/dist/byline-registry-D6lWzXk6.mjs.map +0 -1
  1317. package/dist/bylines-CHP44GkL.mjs +0 -232
  1318. package/dist/bylines-CHP44GkL.mjs.map +0 -1
  1319. package/dist/bylines-DxjM4Usz.mjs +0 -214
  1320. package/dist/bylines-DxjM4Usz.mjs.map +0 -1
  1321. package/dist/cache-BByLKGPu.mjs +0 -108
  1322. package/dist/cache-BByLKGPu.mjs.map +0 -1
  1323. package/dist/capture-triggers-gxQxnxrJ.mjs +0 -362
  1324. package/dist/capture-triggers-gxQxnxrJ.mjs.map +0 -1
  1325. package/dist/challenge-store-CkRdSdd8.mjs +0 -51
  1326. package/dist/challenge-store-CkRdSdd8.mjs.map +0 -1
  1327. package/dist/checksum-Bsi2D9M1.mjs +0 -162
  1328. package/dist/checksum-Bsi2D9M1.mjs.map +0 -1
  1329. package/dist/chrome-tags-D7LGB91U.mjs +0 -24
  1330. package/dist/chrome-tags-D7LGB91U.mjs.map +0 -1
  1331. package/dist/chunks-DUK-cWXi.mjs +0 -25
  1332. package/dist/chunks-DUK-cWXi.mjs.map +0 -1
  1333. package/dist/collection-deletion-C-yQB9fq.mjs +0 -436
  1334. package/dist/collection-deletion-C-yQB9fq.mjs.map +0 -1
  1335. package/dist/collection-slugs-cache-D9auiKmI.mjs +0 -85
  1336. package/dist/collection-slugs-cache-D9auiKmI.mjs.map +0 -1
  1337. package/dist/comment-DcT8qdPK.mjs +0 -313
  1338. package/dist/comment-DcT8qdPK.mjs.map +0 -1
  1339. package/dist/comment-reaction-B6KHCLYK.mjs +0 -85
  1340. package/dist/comment-reaction-B6KHCLYK.mjs.map +0 -1
  1341. package/dist/comments-B67VRNGw.mjs +0 -204
  1342. package/dist/comments-B67VRNGw.mjs.map +0 -1
  1343. package/dist/comments-BVzzt6x5.mjs +0 -99
  1344. package/dist/comments-BVzzt6x5.mjs.map +0 -1
  1345. package/dist/components-DIl9Qzh6.mjs +0 -108
  1346. package/dist/components-DIl9Qzh6.mjs.map +0 -1
  1347. package/dist/config-B2acLeC5.mjs +0 -242
  1348. package/dist/config-B2acLeC5.mjs.map +0 -1
  1349. package/dist/config-CGVeT8Hc.mjs +0 -73
  1350. package/dist/config-CGVeT8Hc.mjs.map +0 -1
  1351. package/dist/config-Cw1Xz_Br.d.mts +0 -6387
  1352. package/dist/config-Cw1Xz_Br.d.mts.map +0 -1
  1353. package/dist/config-D3HhLON3.d.mts +0 -39
  1354. package/dist/config-D3HhLON3.d.mts.map +0 -1
  1355. package/dist/content-C0Hl3ktM.mjs +0 -2216
  1356. package/dist/content-C0Hl3ktM.mjs.map +0 -1
  1357. package/dist/content-list-query-CbPdzsna.d.mts +0 -26
  1358. package/dist/content-list-query-CbPdzsna.d.mts.map +0 -1
  1359. package/dist/content-policy-CM4skrNi.mjs +0 -46
  1360. package/dist/content-policy-CM4skrNi.mjs.map +0 -1
  1361. package/dist/content-refresh-iRBhQHr5.mjs +0 -3599
  1362. package/dist/content-refresh-iRBhQHr5.mjs.map +0 -1
  1363. package/dist/content-repair-8uHRIJkd.mjs +0 -440
  1364. package/dist/content-repair-8uHRIJkd.mjs.map +0 -1
  1365. package/dist/context-DJP3aNeR.mjs +0 -1835
  1366. package/dist/context-DJP3aNeR.mjs.map +0 -1
  1367. package/dist/cron-BcR3RN4K.mjs +0 -282
  1368. package/dist/cron-BcR3RN4K.mjs.map +0 -1
  1369. package/dist/dashboard-B0s6QKgi.mjs +0 -151
  1370. package/dist/dashboard-B0s6QKgi.mjs.map +0 -1
  1371. package/dist/default-BtlxWgh9.mjs +0 -81
  1372. package/dist/default-BtlxWgh9.mjs.map +0 -1
  1373. package/dist/deferred-tasks-Ba9fphlE.d.mts +0 -9
  1374. package/dist/deferred-tasks-Ba9fphlE.d.mts.map +0 -1
  1375. package/dist/device-flow-3E5l0fpH.mjs +0 -466
  1376. package/dist/device-flow-3E5l0fpH.mjs.map +0 -1
  1377. package/dist/dialect-helpers-CtYdsX4W.mjs +0 -307
  1378. package/dist/dialect-helpers-CtYdsX4W.mjs.map +0 -1
  1379. package/dist/direct-executor-CDr1quOq.mjs +0 -104
  1380. package/dist/direct-executor-CDr1quOq.mjs.map +0 -1
  1381. package/dist/dist-2hDLsLeq.mjs +0 -810
  1382. package/dist/dist-2hDLsLeq.mjs.map +0 -1
  1383. package/dist/email-console-gc-E3Eqj.mjs +0 -50
  1384. package/dist/email-console-gc-E3Eqj.mjs.map +0 -1
  1385. package/dist/emdash-runtime-CxxL05Z0.mjs +0 -4041
  1386. package/dist/emdash-runtime-CxxL05Z0.mjs.map +0 -1
  1387. package/dist/enrich-C2Mk0lwE.mjs +0 -194
  1388. package/dist/enrich-C2Mk0lwE.mjs.map +0 -1
  1389. package/dist/entry-lock-CwWdnFyR.mjs +0 -1520
  1390. package/dist/entry-lock-CwWdnFyR.mjs.map +0 -1
  1391. package/dist/entry-lock-D9rnj2Lu.mjs +0 -163
  1392. package/dist/entry-lock-D9rnj2Lu.mjs.map +0 -1
  1393. package/dist/entry-lock-DqkvBC6L.d.mts +0 -3503
  1394. package/dist/entry-lock-DqkvBC6L.d.mts.map +0 -1
  1395. package/dist/entry-locks-CO_KaoU5.mjs +0 -167
  1396. package/dist/entry-locks-CO_KaoU5.mjs.map +0 -1
  1397. package/dist/error-CCTCskie.mjs +0 -90
  1398. package/dist/error-CCTCskie.mjs.map +0 -1
  1399. package/dist/errors-W3PA8HqB.mjs +0 -447
  1400. package/dist/errors-W3PA8HqB.mjs.map +0 -1
  1401. package/dist/escape-DN4Qmjsl.mjs +0 -9
  1402. package/dist/escape-DN4Qmjsl.mjs.map +0 -1
  1403. package/dist/field-defs-cache-Db0pJgqn.mjs +0 -77
  1404. package/dist/field-defs-cache-Db0pJgqn.mjs.map +0 -1
  1405. package/dist/fts-manager-CjX0e5BR.mjs +0 -413
  1406. package/dist/fts-manager-CjX0e5BR.mjs.map +0 -1
  1407. package/dist/hash-CLVFzWvx.mjs +0 -37
  1408. package/dist/hash-CLVFzWvx.mjs.map +0 -1
  1409. package/dist/hook-result-KY1jq21o.d.mts +0 -31
  1410. package/dist/hook-result-KY1jq21o.d.mts.map +0 -1
  1411. package/dist/hreflang-BgS2FqhH.d.mts +0 -50
  1412. package/dist/hreflang-BgS2FqhH.d.mts.map +0 -1
  1413. package/dist/hreflang-DOQeTXpg.mjs +0 -105
  1414. package/dist/hreflang-DOQeTXpg.mjs.map +0 -1
  1415. package/dist/http-route-dispatch-MCVKiQCl.mjs +0 -339
  1416. package/dist/http-route-dispatch-MCVKiQCl.mjs.map +0 -1
  1417. package/dist/identity-vFbpuwfY.mjs +0 -35
  1418. package/dist/identity-vFbpuwfY.mjs.map +0 -1
  1419. package/dist/import-got6I69S.mjs +0 -2020
  1420. package/dist/import-got6I69S.mjs.map +0 -1
  1421. package/dist/index-CDwKDkTq.d.mts +0 -623
  1422. package/dist/index-CDwKDkTq.d.mts.map +0 -1
  1423. package/dist/install-finalization-5Os-QZ-2.mjs +0 -58
  1424. package/dist/install-finalization-5Os-QZ-2.mjs.map +0 -1
  1425. package/dist/lifecycle-7e-Lt_kX.mjs +0 -25
  1426. package/dist/lifecycle-7e-Lt_kX.mjs.map +0 -1
  1427. package/dist/load-C56XiwbV.mjs +0 -28
  1428. package/dist/load-C56XiwbV.mjs.map +0 -1
  1429. package/dist/loader-xhNQiT9T.mjs +0 -1004
  1430. package/dist/loader-xhNQiT9T.mjs.map +0 -1
  1431. package/dist/manifest-builder-Bz3nxVET.mjs +0 -189
  1432. package/dist/manifest-builder-Bz3nxVET.mjs.map +0 -1
  1433. package/dist/manifest-schema-Bkh8SeHd.mjs +0 -491
  1434. package/dist/manifest-schema-Bkh8SeHd.mjs.map +0 -1
  1435. package/dist/media-TBlKCwo7.mjs +0 -334
  1436. package/dist/media-TBlKCwo7.mjs.map +0 -1
  1437. package/dist/media-allowlist-s60eAIf6.mjs +0 -44
  1438. package/dist/media-allowlist-s60eAIf6.mjs.map +0 -1
  1439. package/dist/media-folders-ClIRLUQv.mjs +0 -210
  1440. package/dist/media-folders-ClIRLUQv.mjs.map +0 -1
  1441. package/dist/media-url-DY_ijO3B.mjs +0 -43
  1442. package/dist/media-url-DY_ijO3B.mjs.map +0 -1
  1443. package/dist/media-usage-Bd9rFPKN.mjs +0 -1833
  1444. package/dist/media-usage-Bd9rFPKN.mjs.map +0 -1
  1445. package/dist/media-usage-activation-CAhmb14O.mjs +0 -78
  1446. package/dist/media-usage-activation-CAhmb14O.mjs.map +0 -1
  1447. package/dist/media-usage-work-BPlRMOJv.mjs +0 -152
  1448. package/dist/media-usage-work-BPlRMOJv.mjs.map +0 -1
  1449. package/dist/media-usage-work-Cu5DqewW.mjs +0 -586
  1450. package/dist/media-usage-work-Cu5DqewW.mjs.map +0 -1
  1451. package/dist/media-usage-write-fence-DW5oHT7q.mjs +0 -42
  1452. package/dist/media-usage-write-fence-DW5oHT7q.mjs.map +0 -1
  1453. package/dist/menus-BUQdvXep.mjs +0 -3732
  1454. package/dist/menus-BUQdvXep.mjs.map +0 -1
  1455. package/dist/menus-DgSUodmF.mjs +0 -753
  1456. package/dist/menus-DgSUodmF.mjs.map +0 -1
  1457. package/dist/mime-CCYRC4r1.mjs +0 -36
  1458. package/dist/mime-CCYRC4r1.mjs.map +0 -1
  1459. package/dist/mode-CkmOhFqj.mjs +0 -23
  1460. package/dist/mode-CkmOhFqj.mjs.map +0 -1
  1461. package/dist/node-sqlite-compat-vpVaILnb.mjs +0 -46
  1462. package/dist/node-sqlite-compat-vpVaILnb.mjs.map +0 -1
  1463. package/dist/normalize-dChXQjwS.mjs +0 -191
  1464. package/dist/normalize-dChXQjwS.mjs.map +0 -1
  1465. package/dist/oauth-authorization-DZ-R-hmx.mjs +0 -274
  1466. package/dist/oauth-authorization-DZ-R-hmx.mjs.map +0 -1
  1467. package/dist/oauth-clients-BMPA8vjl.mjs +0 -266
  1468. package/dist/oauth-clients-BMPA8vjl.mjs.map +0 -1
  1469. package/dist/oauth-state-store-0gIdb48-.mjs +0 -50
  1470. package/dist/oauth-state-store-0gIdb48-.mjs.map +0 -1
  1471. package/dist/oauth-user-lookup-ChVW4UWu.mjs +0 -26
  1472. package/dist/oauth-user-lookup-ChVW4UWu.mjs.map +0 -1
  1473. package/dist/object-cache-DlSVbn5Y.mjs +0 -534
  1474. package/dist/object-cache-DlSVbn5Y.mjs.map +0 -1
  1475. package/dist/options-D5WcorD5.mjs +0 -200
  1476. package/dist/options-D5WcorD5.mjs.map +0 -1
  1477. package/dist/options-DAknChnw.d.mts +0 -77
  1478. package/dist/options-DAknChnw.d.mts.map +0 -1
  1479. package/dist/parse-Cr379Av9.mjs +0 -81
  1480. package/dist/parse-Cr379Av9.mjs.map +0 -1
  1481. package/dist/parse-tj9XLNO_.d.mts +0 -165
  1482. package/dist/parse-tj9XLNO_.d.mts.map +0 -1
  1483. package/dist/passkey-config-BD-wMaCf.mjs +0 -46
  1484. package/dist/passkey-config-BD-wMaCf.mjs.map +0 -1
  1485. package/dist/patterns-Do3iqi7N.mjs +0 -145
  1486. package/dist/patterns-Do3iqi7N.mjs.map +0 -1
  1487. package/dist/placeholder-CubPFn_L.d.mts +0 -306
  1488. package/dist/placeholder-CubPFn_L.d.mts.map +0 -1
  1489. package/dist/plugins-DHurtdXQ.mjs +0 -277
  1490. package/dist/plugins-DHurtdXQ.mjs.map +0 -1
  1491. package/dist/policy-pL9QLKZm.mjs +0 -45
  1492. package/dist/policy-pL9QLKZm.mjs.map +0 -1
  1493. package/dist/portable-text-oAwodbPS.mjs +0 -286
  1494. package/dist/portable-text-oAwodbPS.mjs.map +0 -1
  1495. package/dist/preview-Cup2bj8c.mjs +0 -107
  1496. package/dist/preview-Cup2bj8c.mjs.map +0 -1
  1497. package/dist/protocol-C1CNiKX4.d.mts +0 -61
  1498. package/dist/protocol-C1CNiKX4.d.mts.map +0 -1
  1499. package/dist/public-submission-Cs-pFMQK.mjs +0 -245
  1500. package/dist/public-submission-Cs-pFMQK.mjs.map +0 -1
  1501. package/dist/public-url-BWVHsfQv.mjs +0 -101
  1502. package/dist/public-url-BWVHsfQv.mjs.map +0 -1
  1503. package/dist/query-CxnFU6sz.mjs +0 -890
  1504. package/dist/query-CxnFU6sz.mjs.map +0 -1
  1505. package/dist/query-sgHYEgBW.mjs +0 -41
  1506. package/dist/query-sgHYEgBW.mjs.map +0 -1
  1507. package/dist/rate-limit-CqJn-w4h.mjs +0 -120
  1508. package/dist/rate-limit-CqJn-w4h.mjs.map +0 -1
  1509. package/dist/redirect-BrChFPIu.mjs +0 -17
  1510. package/dist/redirect-BrChFPIu.mjs.map +0 -1
  1511. package/dist/redirect-D2Yo-b6S.mjs +0 -415
  1512. package/dist/redirect-D2Yo-b6S.mjs.map +0 -1
  1513. package/dist/redirects-BCiTaIQ-.mjs +0 -146
  1514. package/dist/redirects-BCiTaIQ-.mjs.map +0 -1
  1515. package/dist/redirects-CAoL3r26.mjs +0 -644
  1516. package/dist/redirects-CAoL3r26.mjs.map +0 -1
  1517. package/dist/registry-xKzE-_m5.mjs +0 -1222
  1518. package/dist/registry-xKzE-_m5.mjs.map +0 -1
  1519. package/dist/relation-ClsWcYg2.mjs +0 -334
  1520. package/dist/relation-ClsWcYg2.mjs.map +0 -1
  1521. package/dist/relations-B4w-G5U9.mjs +0 -309
  1522. package/dist/relations-B4w-G5U9.mjs.map +0 -1
  1523. package/dist/relations-C3Td_mct.mjs +0 -403
  1524. package/dist/relations-C3Td_mct.mjs.map +0 -1
  1525. package/dist/request-cache-DaMhSQdx.mjs +0 -104
  1526. package/dist/request-cache-DaMhSQdx.mjs.map +0 -1
  1527. package/dist/request-meta-C8yl_sIs.mjs +0 -141
  1528. package/dist/request-meta-C8yl_sIs.mjs.map +0 -1
  1529. package/dist/resolve-BJIS8wKr.mjs +0 -199
  1530. package/dist/resolve-BJIS8wKr.mjs.map +0 -1
  1531. package/dist/route-wire-D66L2oaZ.mjs +0 -197
  1532. package/dist/route-wire-D66L2oaZ.mjs.map +0 -1
  1533. package/dist/routes-CWzxcZpn.mjs +0 -321
  1534. package/dist/routes-CWzxcZpn.mjs.map +0 -1
  1535. package/dist/runner-3gfxRsJG.d.mts +0 -68
  1536. package/dist/runner-3gfxRsJG.d.mts.map +0 -1
  1537. package/dist/runner-CIltKk4i.mjs +0 -5502
  1538. package/dist/runner-CIltKk4i.mjs.map +0 -1
  1539. package/dist/schema-DQIE9Htn.mjs +0 -420
  1540. package/dist/schema-DQIE9Htn.mjs.map +0 -1
  1541. package/dist/schema-ILPFMPW3.mjs +0 -9
  1542. package/dist/schema-ILPFMPW3.mjs.map +0 -1
  1543. package/dist/scopes-Bn8_rCSt.mjs +0 -27
  1544. package/dist/scopes-Bn8_rCSt.mjs.map +0 -1
  1545. package/dist/search-D6muneha.mjs +0 -448
  1546. package/dist/search-D6muneha.mjs.map +0 -1
  1547. package/dist/secrets-DNgVgz_e.mjs +0 -341
  1548. package/dist/secrets-DNgVgz_e.mjs.map +0 -1
  1549. package/dist/sections-BPCEGYWd.mjs +0 -346
  1550. package/dist/sections-BPCEGYWd.mjs.map +0 -1
  1551. package/dist/seo-BtU70b7l.mjs +0 -114
  1552. package/dist/seo-BtU70b7l.mjs.map +0 -1
  1553. package/dist/seo-rCk6pDwT.mjs +0 -133
  1554. package/dist/seo-rCk6pDwT.mjs.map +0 -1
  1555. package/dist/service-Bpy5iTX0.mjs +0 -150
  1556. package/dist/service-Bpy5iTX0.mjs.map +0 -1
  1557. package/dist/session-user-BQeS2Mrb.mjs +0 -51
  1558. package/dist/session-user-BQeS2Mrb.mjs.map +0 -1
  1559. package/dist/settings-CsoLiwpL.mjs +0 -420
  1560. package/dist/settings-CsoLiwpL.mjs.map +0 -1
  1561. package/dist/settings-DCnWtfSZ.mjs +0 -51
  1562. package/dist/settings-DCnWtfSZ.mjs.map +0 -1
  1563. package/dist/setup-complete-BrZaXpVV.mjs +0 -26
  1564. package/dist/setup-complete-BrZaXpVV.mjs.map +0 -1
  1565. package/dist/setup-nonce-Cb9-884O.mjs +0 -25
  1566. package/dist/setup-nonce-Cb9-884O.mjs.map +0 -1
  1567. package/dist/site-url-DjhYCaep.mjs +0 -16
  1568. package/dist/site-url-DjhYCaep.mjs.map +0 -1
  1569. package/dist/snapshot-C32Xuv3o.mjs +0 -233
  1570. package/dist/snapshot-C32Xuv3o.mjs.map +0 -1
  1571. package/dist/ssrf-Co1GGFZz.mjs +0 -406
  1572. package/dist/ssrf-Co1GGFZz.mjs.map +0 -1
  1573. package/dist/state-C7gCoiHr.mjs +0 -153
  1574. package/dist/state-C7gCoiHr.mjs.map +0 -1
  1575. package/dist/status-DLoBmcDz.mjs +0 -30
  1576. package/dist/status-DLoBmcDz.mjs.map +0 -1
  1577. package/dist/storage-query-CPctdMKX.d.mts +0 -1519
  1578. package/dist/storage-query-CPctdMKX.d.mts.map +0 -1
  1579. package/dist/target-CUKlGrXb.mjs +0 -27
  1580. package/dist/target-CUKlGrXb.mjs.map +0 -1
  1581. package/dist/taxonomies-Bs5dJVDJ.mjs +0 -899
  1582. package/dist/taxonomies-Bs5dJVDJ.mjs.map +0 -1
  1583. package/dist/taxonomies-DjGU22ur.mjs +0 -707
  1584. package/dist/taxonomies-DjGU22ur.mjs.map +0 -1
  1585. package/dist/taxonomy-c1Q8PMFF.mjs +0 -508
  1586. package/dist/taxonomy-c1Q8PMFF.mjs.map +0 -1
  1587. package/dist/tokens-Ns02GAma.mjs +0 -171
  1588. package/dist/tokens-Ns02GAma.mjs.map +0 -1
  1589. package/dist/transport-B8P1xsqk.mjs +0 -136
  1590. package/dist/transport-B8P1xsqk.mjs.map +0 -1
  1591. package/dist/transport-BLHZZcD_.d.mts +0 -42
  1592. package/dist/transport-BLHZZcD_.d.mts.map +0 -1
  1593. package/dist/trusted-proxy-Cg7SuD15.mjs +0 -51
  1594. package/dist/trusted-proxy-Cg7SuD15.mjs.map +0 -1
  1595. package/dist/turnstile-DWCSh_Qc.mjs +0 -53
  1596. package/dist/turnstile-DWCSh_Qc.mjs.map +0 -1
  1597. package/dist/types-B3RkqvDW.mjs +0 -156
  1598. package/dist/types-B3RkqvDW.mjs.map +0 -1
  1599. package/dist/types-BtuppOTV.mjs +0 -16
  1600. package/dist/types-BtuppOTV.mjs.map +0 -1
  1601. package/dist/types-CCR3ivXE.d.mts +0 -363
  1602. package/dist/types-CCR3ivXE.d.mts.map +0 -1
  1603. package/dist/types-CSHgU_-_.mjs +0 -18
  1604. package/dist/types-CSHgU_-_.mjs.map +0 -1
  1605. package/dist/types-CbwqGOXm.d.mts +0 -766
  1606. package/dist/types-CbwqGOXm.d.mts.map +0 -1
  1607. package/dist/types-D4RGIc2I.d.mts +0 -198
  1608. package/dist/types-D4RGIc2I.d.mts.map +0 -1
  1609. package/dist/types-DEHidMEk.d.mts +0 -1637
  1610. package/dist/types-DEHidMEk.d.mts.map +0 -1
  1611. package/dist/types-DQeU2SR7.d.mts +0 -279
  1612. package/dist/types-DQeU2SR7.d.mts.map +0 -1
  1613. package/dist/types-DxQWoQLA.d.mts +0 -264
  1614. package/dist/types-DxQWoQLA.d.mts.map +0 -1
  1615. package/dist/types-FBBnGZ2Y.d.mts +0 -198
  1616. package/dist/types-FBBnGZ2Y.d.mts.map +0 -1
  1617. package/dist/types-ZCnlropY.mjs +0 -69
  1618. package/dist/types-ZCnlropY.mjs.map +0 -1
  1619. package/dist/types-_Qtyawiy.d.mts +0 -124
  1620. package/dist/types-_Qtyawiy.d.mts.map +0 -1
  1621. package/dist/types-gC6FAoa_.d.mts +0 -75
  1622. package/dist/types-gC6FAoa_.d.mts.map +0 -1
  1623. package/dist/types-k--LneIF.mjs +0 -22
  1624. package/dist/types-k--LneIF.mjs.map +0 -1
  1625. package/dist/upload-attempts-2xdnoKGe.mjs +0 -27
  1626. package/dist/upload-attempts-2xdnoKGe.mjs.map +0 -1
  1627. package/dist/url-pattern-3m3reMzr.mjs +0 -33
  1628. package/dist/url-pattern-3m3reMzr.mjs.map +0 -1
  1629. package/dist/user-2R1gceFl.mjs +0 -171
  1630. package/dist/user-2R1gceFl.mjs.map +0 -1
  1631. package/dist/utils-CC2oNGV8.mjs +0 -435
  1632. package/dist/utils-CC2oNGV8.mjs.map +0 -1
  1633. package/dist/validate-CaFSi_Wa.mjs +0 -384
  1634. package/dist/validate-CaFSi_Wa.mjs.map +0 -1
  1635. package/dist/validate-CyQ7I3xF.d.mts +0 -410
  1636. package/dist/validate-CyQ7I3xF.d.mts.map +0 -1
  1637. package/dist/validation-nsX2uixg.mjs +0 -216
  1638. package/dist/validation-nsX2uixg.mjs.map +0 -1
  1639. package/dist/version-DGh4SL8e.mjs +0 -7
  1640. package/dist/version-DGh4SL8e.mjs.map +0 -1
  1641. package/dist/widgets-B7ued6f5.mjs +0 -126
  1642. package/dist/widgets-B7ued6f5.mjs.map +0 -1
  1643. package/dist/wxr-taxonomies-BtH3jYSg.mjs +0 -406
  1644. package/dist/wxr-taxonomies-BtH3jYSg.mjs.map +0 -1
  1645. package/dist/wxr-taxonomies-DU2ZSiGc.d.mts +0 -34
  1646. package/dist/wxr-taxonomies-DU2ZSiGc.d.mts.map +0 -1
  1647. package/dist/zod-generator-DuBjYyrI.mjs +0 -329
  1648. package/dist/zod-generator-DuBjYyrI.mjs.map +0 -1
  1649. /package/dist/{ssrf-BRpTDMV6.mjs → ssrf-DpBH7aOt.mjs} +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"request-context.mjs","names":[],"sources":["../../../src/visual-editing/toolbar-bootstrap.ts","../../../src/visual-editing/toolbar.ts","../../../src/astro/middleware/request-context.ts"],"sourcesContent":["/**\n * EmDash Toolbar Bootstrap (toolbar: \"client\")\n *\n * A tiny script injected into every public HTML response when the client\n * toolbar mode is enabled. It is identical for every visitor, so the HTML\n * stays fully cacheable by shared caches (Workers Cache, Cache Everything,\n * Fastly, Varnish, …).\n *\n * Behavior: if this browser has logged into the admin (non-secret\n * localStorage flag set by the admin SPA), render a small \"Edit\" pill.\n * Clicking it verifies the session server-side and reloads the page with the\n * `_edit` query param — that URL is always rendered fresh with the full\n * server-side toolbar. Logged-out browsers pay one localStorage read and\n * nothing else.\n */\n\n/**\n * Non-secret localStorage flag set by the admin SPA when an editor session\n * exists in this browser. It only means \"a session may exist\" — the click\n * handler verifies the real session before entering edit mode. The literal\n * is duplicated in `@emdash-cms/admin` (Shell/Header), which cannot import\n * from core.\n */\nexport const EDITOR_FLAG_KEY = \"emdash-editor\";\n\n/**\n * localStorage flag set when the user dismisses the toolbar in this browser.\n * Cleared the next time an editor opens the admin. Also duplicated in\n * `@emdash-cms/admin`.\n */\nexport const TOOLBAR_DISMISSED_KEY = \"emdash-toolbar-dismissed\";\n\n/** Localized bootstrap labels written by the admin SPA for this browser. */\nexport const TOOLBAR_LABELS_KEY = \"emdash-toolbar-labels\";\n\n/**\n * Query param that requests a fresh (never cached) editor render. Presence is\n * verified server-side: non-editors are redirected to the canonical URL.\n */\nexport const EDIT_PARAM = \"_edit\";\n\nexport function renderToolbarBootstrap(): string {\n\treturn `\n<!-- EmDash Toolbar Bootstrap -->\n<script>\n(function mountToolbar() {\n var flag, dismissed, labelsRaw;\n var labels = null;\n try {\n flag = localStorage.getItem(\"${EDITOR_FLAG_KEY}\");\n dismissed = localStorage.getItem(\"${TOOLBAR_DISMISSED_KEY}\");\n labelsRaw = localStorage.getItem(\"${TOOLBAR_LABELS_KEY}\");\n } catch (e) {\n return;\n }\n if (!flag || dismissed) return;\n if (labelsRaw) {\n try {\n var storedLabels = JSON.parse(labelsRaw);\n if (storedLabels && typeof storedLabels.editMode === \"string\" && typeof storedLabels.hideToolbar === \"string\") {\n labels = storedLabels;\n }\n } catch (e) {}\n }\n if (!labels) {\n fetch(\"/_emdash/api/visual-editing/toolbar-labels\", { credentials: \"same-origin\" })\n .then(function(response) { return response.ok ? response.json() : null; })\n .then(function(body) {\n var fetched = body && body.data;\n if (!fetched || typeof fetched.editMode !== \"string\" || typeof fetched.hideToolbar !== \"string\") return;\n try { localStorage.setItem(\"${TOOLBAR_LABELS_KEY}\", JSON.stringify(fetched)); } catch (e) { return; }\n mountToolbar();\n })\n .catch(function() {});\n return;\n }\n // The server toolbar is present on _edit / edit-mode / preview renders.\n if (document.getElementById(\"emdash-toolbar\")) return;\n\n var root = document.createElement(\"div\");\n root.id = \"emdash-toolbar-bootstrap\";\n root.style.cssText = \"position:fixed;bottom:16px;left:50%;transform:translateX(-50%);z-index:999999;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;font-size:13px;line-height:1;-webkit-font-smoothing:antialiased;\";\n\n var inner = document.createElement(\"div\");\n inner.style.cssText = \"display:flex;align-items:center;gap:10px;padding:8px 16px;background:#1a1a1a;color:#e0e0e0;border-radius:999px;box-shadow:0 4px 24px rgba(0,0,0,0.3),0 0 0 1px rgba(255,255,255,0.08);white-space:nowrap;user-select:none;\";\n\n var logo = document.createElement(\"span\");\n logo.textContent = \"EmDash\";\n logo.style.cssText = \"font-weight:600;font-size:12px;letter-spacing:0.02em;color:#fff;opacity:0.7;\";\n\n var divider = document.createElement(\"span\");\n divider.style.cssText = \"width:1px;height:16px;background:rgba(255,255,255,0.15);\";\n\n var editBtn = document.createElement(\"button\");\n editBtn.textContent = labels.editMode;\n editBtn.style.cssText = \"padding:4px 12px;background:#3b82f6;color:#fff;border:none;border-radius:999px;font-size:12px;font-weight:600;cursor:pointer;font-family:inherit;\";\n\n var closeBtn = document.createElement(\"button\");\n closeBtn.textContent = \"\\\\u00d7\";\n closeBtn.title = labels.hideToolbar;\n closeBtn.setAttribute(\"aria-label\", labels.hideToolbar);\n closeBtn.style.cssText = \"background:none;border:none;color:#666;cursor:pointer;font-size:16px;padding:0 2px;line-height:1;font-family:inherit;\";\n\n editBtn.addEventListener(\"click\", function() {\n editBtn.disabled = true;\n fetch(\"/_emdash/api/auth/me\", {\n credentials: \"same-origin\",\n headers: { \"X-EmDash-Request\": \"1\" }\n })\n .then(function(r) { return r.ok ? r.json() : null; })\n .then(function(body) {\n var user = body && body.data;\n if (user && user.role >= 30) {\n var u = new URL(location.href);\n u.searchParams.set(\"${EDIT_PARAM}\", \"1\");\n location.href = u.toString();\n } else if (user) {\n // Logged in but not an editor — the flag is stale for this browser.\n try { localStorage.removeItem(\"${EDITOR_FLAG_KEY}\"); } catch (e) {}\n root.remove();\n } else {\n // No session — go to the admin login page.\n location.href = \"/_emdash/admin/login\";\n }\n })\n .catch(function() {\n editBtn.disabled = false;\n });\n });\n\n closeBtn.addEventListener(\"click\", function() {\n try { localStorage.setItem(\"${TOOLBAR_DISMISSED_KEY}\", \"1\"); } catch (e) {}\n root.remove();\n });\n\n inner.appendChild(logo);\n inner.appendChild(divider);\n inner.appendChild(editBtn);\n inner.appendChild(closeBtn);\n root.appendChild(inner);\n document.body.appendChild(root);\n})();\n</script>\n`;\n}\n","import { escapeHtml } from \"../api/escape.js\";\nimport { VISUAL_ACTION_TOKEN_INVALID } from \"./action-token.js\";\n\n/**\n * EmDash Visual Editing Toolbar\n *\n * A floating pill injected via middleware for authenticated editors.\n * Renders as a plain HTML string with inline styles and a <script> tag.\n * No dependencies — works on any page with a </body> tag.\n */\n\ninterface ToolbarConfig {\n\teditMode: boolean;\n\tisPreview: boolean;\n\tactionToken?: string;\n\tlabels: ToolbarLabels;\n}\n\nexport interface ToolbarLabels {\n\tpublish: string;\n\tpublishing: string;\n\tsessionExpired: string;\n\trefreshPage: string;\n\tpublishFailed: string;\n\teditMode: string;\n\topenInAdmin: string;\n\thideToolbar: string;\n}\n\nconst SCRIPT_LINE_SEPARATOR_RE = /\\u2028/g;\nconst SCRIPT_PARAGRAPH_SEPARATOR_RE = /\\u2029/g;\n\nfunction inlineScriptJson(value: unknown): string {\n\treturn JSON.stringify(value)\n\t\t.replaceAll(\"<\", \"\\\\u003c\")\n\t\t.replace(SCRIPT_LINE_SEPARATOR_RE, \"\\\\u2028\")\n\t\t.replace(SCRIPT_PARAGRAPH_SEPARATOR_RE, \"\\\\u2029\");\n}\n\nexport function renderToolbar(config: ToolbarConfig): string {\n\tconst { editMode, isPreview, actionToken = \"\", labels } = config;\n\tconst recoveryBadge = `<span class=\"emdash-tb-badge emdash-tb-badge--error\">${escapeHtml(labels.sessionExpired)}</span>`;\n\n\treturn `\n<!-- EmDash Visual Editing Toolbar -->\n<div id=\"emdash-toolbar\" data-edit-mode=\"${editMode}\" data-preview=\"${isPreview}\">\n <div class=\"emdash-tb-inner\">\n <span class=\"emdash-tb-logo\">EmDash</span>\n\n <div class=\"emdash-tb-divider\"></div>\n\n <label class=\"emdash-tb-toggle\" title=\"${escapeHtml(labels.editMode)}\">\n <input type=\"checkbox\" id=\"emdash-edit-toggle\" ${editMode ? \"checked\" : \"\"} />\n <span class=\"emdash-tb-toggle-track\">\n <span class=\"emdash-tb-toggle-thumb\"></span>\n </span>\n <span class=\"emdash-tb-toggle-label\">${escapeHtml(labels.editMode)}</span>\n </label>\n\n <span class=\"emdash-tb-status\" id=\"emdash-tb-status\"></span>\n\n <span class=\"emdash-tb-save-status\" id=\"emdash-tb-save-status\"></span>\n\n <a class=\"emdash-tb-admin\" id=\"emdash-tb-admin\" href=\"#\" target=\"emdash-admin\" style=\"display:none\" title=\"${escapeHtml(labels.openInAdmin)}\">\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6\"/><polyline points=\"15 3 21 3 21 9\"/><line x1=\"10\" y1=\"14\" x2=\"21\" y2=\"3\"/></svg>\n </a>\n\n <button class=\"emdash-tb-publish\" id=\"emdash-tb-publish\" style=\"display:none\">${escapeHtml(labels.publish)}</button>\n\n <button class=\"emdash-tb-dismiss\" id=\"emdash-tb-dismiss\" title=\"${escapeHtml(labels.hideToolbar)}\" aria-label=\"${escapeHtml(labels.hideToolbar)}\">&times;</button>\n </div>\n</div>\n\n<style>\n #emdash-toolbar {\n position: fixed;\n bottom: 16px;\n left: 50%;\n transform: translateX(-50%);\n z-index: 999999;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n font-size: 13px;\n line-height: 1;\n -webkit-font-smoothing: antialiased;\n }\n\n .emdash-tb-inner {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 8px 16px;\n background: #1a1a1a;\n color: #e0e0e0;\n border-radius: 999px;\n box-shadow: 0 4px 24px rgba(0,0,0,0.3), 0 0 0 1px rgba(255,255,255,0.08);\n white-space: nowrap;\n user-select: none;\n }\n\n .emdash-tb-logo {\n font-weight: 600;\n font-size: 12px;\n letter-spacing: 0.02em;\n color: #fff;\n opacity: 0.7;\n }\n\n .emdash-tb-divider {\n width: 1px;\n height: 16px;\n background: rgba(255,255,255,0.15);\n }\n\n /* Toggle switch */\n .emdash-tb-toggle {\n display: flex;\n align-items: center;\n gap: 6px;\n cursor: pointer;\n }\n\n .emdash-tb-toggle input {\n position: absolute;\n opacity: 0;\n width: 0;\n height: 0;\n }\n\n .emdash-tb-toggle-track {\n position: relative;\n width: 32px;\n height: 18px;\n background: #444;\n border-radius: 9px;\n transition: background 0.2s;\n }\n\n .emdash-tb-toggle input:checked + .emdash-tb-toggle-track {\n background: #3b82f6;\n }\n\n .emdash-tb-toggle-thumb {\n position: absolute;\n top: 2px;\n left: 2px;\n width: 14px;\n height: 14px;\n background: #fff;\n border-radius: 50%;\n transition: transform 0.2s;\n }\n\n .emdash-tb-toggle input:checked + .emdash-tb-toggle-track .emdash-tb-toggle-thumb {\n transform: translateX(14px);\n }\n\n .emdash-tb-toggle-label {\n font-size: 12px;\n color: #aaa;\n }\n\n .emdash-tb-toggle input:checked ~ .emdash-tb-toggle-label {\n color: #fff;\n }\n\n /* Status area — flex for multiple badges */\n .emdash-tb-status {\n display: inline-flex;\n gap: 6px;\n align-items: center;\n }\n\n /* Badges */\n .emdash-tb-badge {\n display: inline-flex;\n align-items: center;\n padding: 3px 8px;\n border-radius: 999px;\n font-size: 11px;\n font-weight: 600;\n letter-spacing: 0.02em;\n text-transform: uppercase;\n }\n\n .emdash-tb-badge--preview {\n background: rgba(139,92,246,0.2);\n color: #a78bfa;\n }\n\n .emdash-tb-badge--draft {\n background: rgba(245,158,11,0.2);\n color: #fbbf24;\n }\n\n .emdash-tb-badge--published {\n background: rgba(34,197,94,0.2);\n color: #4ade80;\n }\n\n .emdash-tb-badge--pending {\n background: rgba(59,130,246,0.2);\n color: #60a5fa;\n }\n\n .emdash-tb-badge--unsaved {\n background: rgba(245,158,11,0.2);\n color: #fbbf24;\n }\n\n .emdash-tb-badge--saving {\n background: rgba(148,163,184,0.2);\n color: #94a3b8;\n }\n\n .emdash-tb-badge--saved {\n background: rgba(34,197,94,0.2);\n color: #4ade80;\n transition: opacity 0.3s;\n }\n\n .emdash-tb-badge--error {\n background: rgba(239,68,68,0.2);\n color: #f87171;\n }\n\n /* Admin link */\n .emdash-tb-admin {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n color: #888;\n text-decoration: none;\n padding: 2px;\n border-radius: 4px;\n transition: color 0.15s;\n }\n\n .emdash-tb-admin:hover {\n color: #fff;\n }\n\n /* Publish button */\n .emdash-tb-publish {\n padding: 4px 12px;\n background: #3b82f6;\n color: #fff;\n border: none;\n border-radius: 999px;\n font-size: 12px;\n font-weight: 600;\n cursor: pointer;\n transition: background 0.15s;\n font-family: inherit;\n }\n\n .emdash-tb-publish:hover {\n background: #2563eb;\n }\n\n .emdash-tb-publish:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n\n /* Dismiss button */\n .emdash-tb-dismiss {\n background: none;\n border: none;\n color: #666;\n cursor: pointer;\n font-size: 16px;\n line-height: 1;\n padding: 0 2px;\n font-family: inherit;\n transition: color 0.15s;\n }\n\n .emdash-tb-dismiss:hover {\n color: #fff;\n }\n\n /* Edit mode: editable hover styles — uses :has() to check toolbar state */\n body:has(#emdash-toolbar[data-edit-mode=\"true\"]) [data-emdash-ref] {\n transition: box-shadow 0.15s, background-color 0.15s;\n }\n\n body:has(#emdash-toolbar[data-edit-mode=\"true\"]) [data-emdash-ref]:hover {\n box-shadow: 0 0 0 2px rgba(59,130,246,0.5);\n border-radius: 4px;\n background-color: rgba(59,130,246,0.04);\n cursor: text;\n }\n\n /* Active editing state — override hover pencil cursor */\n [data-emdash-editing] {\n box-shadow: 0 0 0 2px #3b82f6 !important;\n border-radius: 4px !important;\n background-color: rgba(59,130,246,0.04) !important;\n cursor: text !important;\n }\n\n /* Suppress browser focus ring on contenteditable and tiptap editor */\n [data-emdash-editing]:focus,\n [data-emdash-ref] .tiptap:focus,\n [data-emdash-ref] .ProseMirror:focus {\n outline: none !important;\n }\n\n /* Image editor popover */\n .emdash-img-popover {\n position: fixed;\n z-index: 1000000;\n background: #1a1a1a;\n border-radius: 12px;\n box-shadow: 0 8px 32px rgba(0,0,0,0.4), 0 0 0 1px rgba(255,255,255,0.08);\n color: #e0e0e0;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n font-size: 13px;\n width: 320px;\n overflow: hidden;\n animation: emdash-img-fadein 0.15s ease-out;\n }\n\n @keyframes emdash-img-fadein {\n from { opacity: 0; transform: translateY(4px); }\n to { opacity: 1; transform: translateY(0); }\n }\n\n .emdash-img-popover-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 10px 12px;\n border-bottom: 1px solid rgba(255,255,255,0.08);\n }\n\n .emdash-img-popover-title {\n font-weight: 600;\n font-size: 12px;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n color: #999;\n }\n\n .emdash-img-popover-close {\n background: none;\n border: none;\n color: #666;\n cursor: pointer;\n padding: 2px;\n line-height: 1;\n font-size: 16px;\n border-radius: 4px;\n transition: color 0.15s;\n }\n\n .emdash-img-popover-close:hover {\n color: #fff;\n }\n\n .emdash-img-popover-body {\n padding: 12px;\n display: flex;\n flex-direction: column;\n gap: 10px;\n }\n\n .emdash-img-preview {\n width: 100%;\n max-height: 160px;\n object-fit: contain;\n border-radius: 6px;\n background: #111;\n }\n\n .emdash-img-empty {\n display: flex;\n align-items: center;\n justify-content: center;\n height: 80px;\n border: 2px dashed rgba(255,255,255,0.15);\n border-radius: 6px;\n color: #666;\n font-size: 12px;\n }\n\n .emdash-img-field {\n display: flex;\n flex-direction: column;\n gap: 4px;\n }\n\n .emdash-img-field label {\n font-size: 11px;\n font-weight: 600;\n color: #888;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n }\n\n .emdash-img-field input[type=\"text\"] {\n background: #111;\n border: 1px solid rgba(255,255,255,0.12);\n border-radius: 6px;\n color: #e0e0e0;\n padding: 6px 8px;\n font-size: 13px;\n font-family: inherit;\n outline: none;\n transition: border-color 0.15s;\n }\n\n .emdash-img-field input[type=\"text\"]:focus {\n border-color: #3b82f6;\n }\n\n .emdash-img-actions {\n display: flex;\n gap: 6px;\n }\n\n .emdash-img-btn {\n flex: 1;\n padding: 6px 10px;\n border: 1px solid rgba(255,255,255,0.12);\n border-radius: 6px;\n background: #222;\n color: #e0e0e0;\n font-size: 12px;\n font-family: inherit;\n cursor: pointer;\n transition: background 0.15s, border-color 0.15s;\n text-align: center;\n white-space: nowrap;\n }\n\n .emdash-img-btn:hover {\n background: #333;\n border-color: rgba(255,255,255,0.2);\n }\n\n .emdash-img-btn--primary {\n background: #3b82f6;\n border-color: #3b82f6;\n color: #fff;\n }\n\n .emdash-img-btn--primary:hover {\n background: #2563eb;\n border-color: #2563eb;\n }\n\n .emdash-img-btn--danger {\n color: #f87171;\n border-color: rgba(248,113,113,0.3);\n }\n\n .emdash-img-btn--danger:hover {\n background: rgba(248,113,113,0.1);\n border-color: rgba(248,113,113,0.5);\n }\n\n /* Media browser within the popover */\n .emdash-img-browser {\n border-top: 1px solid rgba(255,255,255,0.08);\n padding: 12px;\n }\n\n .emdash-img-browser-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 8px;\n }\n\n .emdash-img-browser-title {\n font-size: 12px;\n font-weight: 600;\n color: #999;\n }\n\n .emdash-img-browser-back {\n background: none;\n border: none;\n color: #3b82f6;\n cursor: pointer;\n font-size: 12px;\n font-family: inherit;\n padding: 2px 4px;\n }\n\n .emdash-img-browser-back:hover {\n text-decoration: underline;\n }\n\n .emdash-img-grid {\n display: grid;\n grid-template-columns: repeat(3, 1fr);\n gap: 6px;\n max-height: 240px;\n overflow-y: auto;\n }\n\n .emdash-img-grid-item {\n aspect-ratio: 1;\n border-radius: 4px;\n overflow: hidden;\n cursor: pointer;\n border: 2px solid transparent;\n transition: border-color 0.15s;\n background: #111;\n }\n\n .emdash-img-grid-item:hover {\n border-color: rgba(59,130,246,0.5);\n }\n\n .emdash-img-grid-item--selected {\n border-color: #3b82f6;\n }\n\n .emdash-img-grid-item img {\n width: 100%;\n height: 100%;\n object-fit: cover;\n }\n\n .emdash-img-loading {\n display: flex;\n align-items: center;\n justify-content: center;\n height: 80px;\n color: #666;\n font-size: 12px;\n }\n\n .emdash-img-drop {\n border: 2px dashed #3b82f6;\n background: rgba(59,130,246,0.05);\n }\n\n .emdash-img-uploading {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 0;\n color: #999;\n font-size: 12px;\n }\n\n .emdash-img-popover-backdrop {\n position: fixed;\n inset: 0;\n z-index: 999999;\n }\n</style>\n\n<script>\n(function() {\n var toolbar = document.getElementById(\"emdash-toolbar\");\n var toggle = document.getElementById(\"emdash-edit-toggle\");\n var statusEl = document.getElementById(\"emdash-tb-status\");\n var saveStatusEl = document.getElementById(\"emdash-tb-save-status\");\n var publishBtn = document.getElementById(\"emdash-tb-publish\");\n if (!toolbar || !toggle || !statusEl || !publishBtn || !saveStatusEl) return;\n\n // Dismissed in this browser (localStorage flag, cleared on the next admin\n // visit). Remove the toolbar entirely instead of rendering it.\n try {\n if (localStorage.getItem(\"emdash-toolbar-dismissed\")) {\n toolbar.remove();\n return;\n }\n } catch (e) {\n // localStorage unavailable — render normally\n }\n\n var isEditMode = toolbar.getAttribute(\"data-edit-mode\") === \"true\";\n var visualActionToken = ${inlineScriptJson(actionToken)};\n var visualActionTokenErrorCode = ${inlineScriptJson(VISUAL_ACTION_TOKEN_INVALID)};\n var toolbarLabels = ${inlineScriptJson(labels)};\n var visualActionRefreshTimer = null;\n\n function showVisualActionRecovery() {\n if (visualActionRefreshTimer !== null) clearTimeout(visualActionRefreshTimer);\n visualActionRefreshTimer = null;\n statusEl.innerHTML = ${inlineScriptJson(recoveryBadge)};\n publishBtn.disabled = true;\n publishBtn.textContent = toolbarLabels.refreshPage;\n }\n\n function showPublishError(message) {\n statusEl.textContent = message || toolbarLabels.publishFailed;\n publishBtn.disabled = false;\n publishBtn.textContent = toolbarLabels.publish;\n }\n\n function scheduleVisualActionTokenRefresh(delay) {\n if (visualActionRefreshTimer !== null) clearTimeout(visualActionRefreshTimer);\n visualActionRefreshTimer = setTimeout(function() {\n visualActionRefreshTimer = null;\n refreshVisualActionToken();\n }, delay);\n }\n\n function refreshVisualActionToken() {\n return ecFetch(\"/_emdash/api/visual-editing/action-token\", {\n method: \"POST\",\n credentials: \"same-origin\",\n headers: { \"X-EmDash-Visual-Action\": visualActionToken },\n })\n .then(function(res) {\n if (res.status === 401 || res.status === 403) {\n showVisualActionRecovery();\n return null;\n }\n if (!res.ok) throw new Error(\"Visual action token renewal failed\");\n return res.json();\n })\n .then(function(body) {\n if (!body) return;\n if (!body.data || !body.data.token) throw new Error(\"Visual action token renewal returned no token\");\n visualActionToken = body.data.token;\n scheduleVisualActionTokenRefresh(240000);\n })\n .catch(function(error) {\n console.error(\"Visual action token renewal failed:\", error);\n scheduleVisualActionTokenRefresh(30000);\n });\n }\n\n if (visualActionToken) scheduleVisualActionTokenRefresh(240000);\n\n var dismissBtn = document.getElementById(\"emdash-tb-dismiss\");\n if (dismissBtn) {\n dismissBtn.addEventListener(\"click\", function() {\n try { localStorage.setItem(\"emdash-toolbar-dismissed\", \"1\"); } catch (e) {}\n // Dismissing while edit mode is on would strand the user in edit mode\n // with no UI to leave it — clear the cookie too.\n if (isEditMode) {\n document.cookie = \"emdash-edit-mode=;path=/;expires=Thu, 01 Jan 1970 00:00:00 GMT\";\n toolbar.remove();\n location.replace(location.href);\n return;\n }\n toolbar.remove();\n });\n }\n\n // CSRF-protected fetch — adds X-EmDash-Request header to all API calls\n function ecFetch(url, init) {\n init = init || {};\n init.headers = Object.assign({ \"X-EmDash-Request\": \"1\" }, init.headers || {});\n return fetch(url, init);\n }\n\n // --- Save status tracking ---\n var saveState = \"idle\"; // idle | unsaved | saving | saved | error\n var saveHideTimer = null;\n var pendingSavePromise = null;\n\n function setSaveState(state) {\n saveState = state;\n clearTimeout(saveHideTimer);\n\n switch (state) {\n case \"unsaved\":\n saveStatusEl.innerHTML = '<span class=\"emdash-tb-badge emdash-tb-badge--unsaved\">Unsaved</span>';\n break;\n case \"saving\":\n saveStatusEl.innerHTML = '<span class=\"emdash-tb-badge emdash-tb-badge--saving\">Saving\\u2026</span>';\n break;\n case \"saved\":\n saveStatusEl.innerHTML = '<span class=\"emdash-tb-badge emdash-tb-badge--saved\">Saved</span>';\n saveHideTimer = setTimeout(function() {\n saveStatusEl.innerHTML = \"\";\n saveState = \"idle\";\n }, 2000);\n break;\n case \"error\":\n saveStatusEl.innerHTML = '<span class=\"emdash-tb-badge emdash-tb-badge--error\">Save failed</span>';\n saveHideTimer = setTimeout(function() {\n saveStatusEl.innerHTML = \"\";\n saveState = \"idle\";\n }, 3000);\n break;\n default:\n saveStatusEl.innerHTML = \"\";\n }\n }\n\n // Listen for save events from inline editors (e.g. PT editor)\n document.addEventListener(\"emdash:save\", function(e) {\n var detail = e.detail || {};\n if (detail.state) {\n setSaveState(detail.state);\n }\n });\n\n document.addEventListener(\"emdash:content-changed\", function(e) {\n var detail = e.detail || {};\n if (detail.collection && detail.id) {\n showUnpublishedChanges(detail.collection, detail.id);\n }\n });\n\n // --- Entry status ---\n var entryRef = null;\n\n function updateStatus() {\n if (!isEditMode) {\n statusEl.innerHTML = \"\";\n publishBtn.style.display = \"none\";\n return;\n }\n\n var first = document.querySelector(\"[data-emdash-ref]\");\n if (!first) {\n statusEl.innerHTML = \"\";\n publishBtn.style.display = \"none\";\n return;\n }\n\n try {\n var ref = JSON.parse(first.getAttribute(\"data-emdash-ref\"));\n entryRef = ref;\n if (!ref.status) return;\n\n // Show admin link\n var adminLink = document.getElementById(\"emdash-tb-admin\");\n if (adminLink) {\n adminLink.href = \"/_emdash/admin/content/\" + encodeURIComponent(ref.collection) + \"/\" + encodeURIComponent(ref.id);\n adminLink.style.display = \"\";\n }\n\n if (ref.status === \"draft\") {\n statusEl.innerHTML = '<span class=\"emdash-tb-badge emdash-tb-badge--draft\">Draft</span>';\n publishBtn.style.display = \"\";\n publishBtn.onclick = function() { publish(ref.collection, ref.id); };\n } else if (ref.status === \"published\" && ref.hasDraft) {\n statusEl.innerHTML = '<span class=\"emdash-tb-badge emdash-tb-badge--pending\">Unpublished changes</span>';\n publishBtn.style.display = \"\";\n publishBtn.onclick = function() { publish(ref.collection, ref.id); };\n } else if (ref.status === \"published\") {\n statusEl.innerHTML = '<span class=\"emdash-tb-badge emdash-tb-badge--published\">Published</span>';\n publishBtn.style.display = \"none\";\n }\n } catch (e) {\n // ignore parse errors\n }\n }\n\n // Publish action\n function publish(collection, id) {\n if (pendingSavePromise) {\n pendingSavePromise.then(function() { publish(collection, id); });\n return;\n }\n\n publishBtn.disabled = true;\n publishBtn.textContent = toolbarLabels.publishing;\n\n ecFetch(\"/_emdash/api/visual-editing/content/\" + encodeURIComponent(collection) + \"/\" + encodeURIComponent(id) + \"/publish\", {\n method: \"POST\",\n credentials: \"same-origin\",\n headers: { \"X-EmDash-Visual-Action\": visualActionToken },\n })\n .then(function(res) {\n if (res.ok) {\n if (document.startViewTransition) {\n document.startViewTransition(function() { location.reload(); });\n } else {\n location.reload();\n }\n } else {\n if (res.status === 401) {\n showVisualActionRecovery();\n return;\n }\n return res.json().catch(function() { return null; }).then(function(body) {\n if (body && body.error && body.error.code === visualActionTokenErrorCode) {\n showVisualActionRecovery();\n return;\n }\n showPublishError(body && body.error && body.error.message);\n console.error(\"Publish failed:\", res.status);\n });\n }\n })\n .catch(function(err) {\n publishBtn.disabled = false;\n publishBtn.textContent = toolbarLabels.publish;\n console.error(\"Publish failed:\", err);\n });\n }\n\n // Edit mode toggle\n toggle.addEventListener(\"change\", function() {\n if (toggle.checked) {\n document.cookie = \"emdash-edit-mode=true;path=/;samesite=lax\";\n } else {\n document.cookie = \"emdash-edit-mode=;path=/;expires=Thu, 01 Jan 1970 00:00:00 GMT\";\n }\n\n if (document.startViewTransition) {\n document.startViewTransition(function() { location.replace(location.href); });\n } else {\n location.replace(location.href);\n }\n });\n\n // --- Inline editing ---\n\n // Cached manifest (fetched once on first edit click)\n var manifestCache = null;\n var manifestPromise = null;\n\n function fetchManifest() {\n if (manifestCache) return Promise.resolve(manifestCache);\n if (manifestPromise) return manifestPromise;\n manifestPromise = ecFetch(\"/_emdash/api/manifest\", { credentials: \"same-origin\" })\n .then(function(r) { return r.json(); })\n .then(function(m) {\n // The manifest endpoint wraps the payload in a { success, data } envelope (ApiResponse shape).\n // Unwrap it so getFieldKind can read manifest.collections directly.\n manifestCache = m && m.data ? m.data : m;\n return manifestCache;\n });\n return manifestPromise;\n }\n\n function getFieldKind(manifest, collection, field) {\n var col = manifest.collections && manifest.collections[collection];\n if (!col || !col.fields) return null;\n var f = col.fields[field];\n return f ? f.kind : null;\n }\n\n // Load manifest early so the first click can resolve field kinds without racing the event.\n if (isEditMode) {\n fetchManifest();\n }\n\n // Save a single field value\n function saveField(collection, id, field, value) {\n setSaveState(\"saving\");\n return ecFetch(\"/_emdash/api/content/\" + encodeURIComponent(collection) + \"/\" + encodeURIComponent(id), {\n method: \"PUT\",\n credentials: \"same-origin\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ data: { [field]: value } }),\n })\n .then(function(res) {\n if (res.ok) {\n setSaveState(\"saved\");\n // A save creates/updates a draft — show unpublished changes\n showUnpublishedChanges(collection, id);\n } else {\n setSaveState(\"error\");\n console.error(\"Save failed:\", res.status);\n }\n })\n .catch(function(err) {\n setSaveState(\"error\");\n console.error(\"Save failed:\", err);\n });\n }\n\n function showUnpublishedChanges(collection, id) {\n statusEl.innerHTML = '<span class=\"emdash-tb-badge emdash-tb-badge--pending\">Unpublished changes</span>';\n publishBtn.style.display = \"\";\n publishBtn.disabled = false;\n publishBtn.textContent = \"Publish\";\n publishBtn.onclick = function() { publish(collection, id); };\n }\n\n // Plain text inline editing (contenteditable)\n var currentlyEditing = null;\n\n function startTextEdit(element, annotation) {\n if (currentlyEditing === element) return;\n if (currentlyEditing) endCurrentEdit();\n\n currentlyEditing = element;\n var originalText = element.textContent || \"\";\n\n element.setAttribute(\"data-emdash-editing\", \"\");\n element.contentEditable = \"plaintext-only\";\n element.focus();\n\n // Select all text\n var range = document.createRange();\n range.selectNodeContents(element);\n var sel = window.getSelection();\n sel.removeAllRanges();\n sel.addRange(range);\n\n // Track dirty state via input events\n function handleInput() {\n var current = (element.textContent || \"\").trim();\n if (current !== originalText.trim()) {\n setSaveState(\"unsaved\");\n } else {\n setSaveState(\"idle\");\n }\n }\n\n function handleBlur() {\n element.removeEventListener(\"blur\", handleBlur);\n element.removeEventListener(\"keydown\", handleKeydown);\n element.removeEventListener(\"input\", handleInput);\n element.contentEditable = \"false\";\n element.removeAttribute(\"data-emdash-editing\");\n currentlyEditing = null;\n\n var newValue = (element.textContent || \"\").trim();\n if (newValue !== originalText.trim()) {\n pendingSavePromise = saveField(annotation.collection, annotation.id, annotation.field, newValue).then(function() {\n pendingSavePromise = null;\n }, function() {\n pendingSavePromise = null;\n });\n } else {\n setSaveState(\"idle\");\n }\n }\n\n function handleKeydown(e) {\n if (e.key === \"Enter\" && !e.shiftKey) {\n e.preventDefault();\n element.blur();\n }\n if (e.key === \"Escape\") {\n element.textContent = originalText;\n setSaveState(\"idle\");\n element.blur();\n }\n }\n\n element.addEventListener(\"input\", handleInput);\n element.addEventListener(\"blur\", handleBlur);\n element.addEventListener(\"keydown\", handleKeydown);\n }\n\n function endCurrentEdit() {\n if (currentlyEditing) {\n currentlyEditing.blur();\n }\n }\n\n // Fallback: open admin\n function openAdmin(annotation) {\n var url = \"/_emdash/admin/content/\" + encodeURIComponent(annotation.collection) + \"/\" + encodeURIComponent(annotation.id);\n if (annotation.field) {\n url += \"?field=\" + encodeURIComponent(annotation.field);\n }\n window.open(url, \"emdash-admin\");\n }\n\n // --- Inline image editing ---\n var activeImagePopover = null;\n\n function closeImagePopover() {\n if (activeImagePopover) {\n activeImagePopover.backdrop.remove();\n activeImagePopover.popover.remove();\n if (activeImagePopover.escapeHandler) {\n document.removeEventListener(\"keydown\", activeImagePopover.escapeHandler);\n }\n activeImagePopover = null;\n }\n }\n\n function startImageEdit(element, annotation) {\n closeImagePopover();\n\n // Find the current image value by fetching the entry\n var collection = annotation.collection;\n var id = annotation.id;\n var field = annotation.field;\n\n // Find img element inside the annotated container (or the element itself if it's an img)\n var imgEl = element.tagName === \"IMG\" ? element : element.querySelector(\"img\");\n\n // Fetch current field value from the content API\n ecFetch(\"/_emdash/api/content/\" + encodeURIComponent(collection) + \"/\" + encodeURIComponent(id), {\n credentials: \"same-origin\"\n })\n .then(function(r) { return r.json(); })\n .then(function(entry) {\n var currentValue = entry.data && entry.data[field];\n showImagePopover(element, imgEl, annotation, currentValue);\n })\n .catch(function() {\n // If fetch fails, still show popover with what we can infer from DOM\n showImagePopover(element, imgEl, annotation, null);\n });\n }\n\n function showImagePopover(element, imgEl, annotation, currentValue) {\n closeImagePopover();\n\n var collection = annotation.collection;\n var id = annotation.id;\n var field = annotation.field;\n\n // Position near the element\n var rect = element.getBoundingClientRect();\n var viewportH = window.innerHeight;\n var viewportW = window.innerWidth;\n\n // Create backdrop for click-outside-to-close\n var backdrop = document.createElement(\"div\");\n backdrop.className = \"emdash-img-popover-backdrop\";\n backdrop.addEventListener(\"click\", function(e) {\n if (e.target === backdrop) closeImagePopover();\n });\n\n // Create popover\n var popover = document.createElement(\"div\");\n popover.className = \"emdash-img-popover\";\n\n var currentSrc = currentValue ? (currentValue.previewUrl || currentValue.src) : (imgEl ? imgEl.src : null);\n var currentAlt = currentValue ? (currentValue.alt || \"\") : (imgEl ? (imgEl.alt || \"\") : \"\");\n\n // Build popover HTML\n var html = '';\n html += '<div class=\"emdash-img-popover-header\">';\n html += ' <span class=\"emdash-img-popover-title\">Image</span>';\n html += ' <button class=\"emdash-img-popover-close\" data-action=\"close\">&times;</button>';\n html += '</div>';\n html += '<div class=\"emdash-img-popover-body\" id=\"emdash-img-main\">';\n\n if (currentSrc) {\n html += '<img class=\"emdash-img-preview\" src=\"' + escapeAttr(currentSrc) + '\" alt=\"\" />';\n } else {\n html += '<div class=\"emdash-img-empty\">No image selected</div>';\n }\n\n html += '<div class=\"emdash-img-field\">';\n html += ' <label for=\"emdash-img-alt\">Alt text</label>';\n html += ' <input type=\"text\" id=\"emdash-img-alt\" value=\"' + escapeAttr(currentAlt) + '\" placeholder=\"Describe the image\" />';\n html += '</div>';\n\n html += '<div class=\"emdash-img-actions\">';\n html += ' <button class=\"emdash-img-btn emdash-img-btn--primary\" data-action=\"browse\">Replace</button>';\n html += ' <label class=\"emdash-img-btn\" style=\"cursor:pointer\">';\n html += ' Upload';\n html += ' <input type=\"file\" accept=\"image/*\" id=\"emdash-img-upload\" style=\"display:none\" />';\n html += ' </label>';\n if (currentSrc) {\n html += ' <button class=\"emdash-img-btn emdash-img-btn--danger\" data-action=\"remove\">Remove</button>';\n }\n html += '</div>';\n html += '</div>';\n\n popover.innerHTML = html;\n\n backdrop.appendChild(popover);\n document.body.appendChild(backdrop);\n\n // Position the popover\n positionPopover(popover, rect, viewportW, viewportH);\n\n // Escape key handler\n function handleEscape(e) {\n if (e.key === \"Escape\") {\n closeImagePopover();\n document.removeEventListener(\"keydown\", handleEscape);\n }\n }\n document.addEventListener(\"keydown\", handleEscape);\n\n activeImagePopover = {\n backdrop: backdrop,\n popover: popover,\n annotation: annotation,\n currentValue: currentValue,\n element: element,\n imgEl: imgEl,\n escapeHandler: handleEscape\n };\n\n // Event handlers\n popover.querySelector('[data-action=\"close\"]').addEventListener(\"click\", closeImagePopover);\n\n popover.querySelector('[data-action=\"browse\"]').addEventListener(\"click\", function() {\n showMediaBrowser(popover, annotation, currentValue, element, imgEl);\n });\n\n var uploadInput = popover.querySelector(\"#emdash-img-upload\");\n uploadInput.addEventListener(\"change\", function(e) {\n var file = e.target.files && e.target.files[0];\n if (file) handleImageUpload(file, popover, annotation, element, imgEl);\n });\n\n var removeBtn = popover.querySelector('[data-action=\"remove\"]');\n if (removeBtn) {\n removeBtn.addEventListener(\"click\", function() {\n saveField(collection, id, field, null).then(function() {\n if (imgEl) {\n imgEl.style.display = \"none\";\n }\n closeImagePopover();\n });\n });\n }\n\n // Save alt text on change (debounced)\n var altInput = popover.querySelector(\"#emdash-img-alt\");\n var altTimer = null;\n altInput.addEventListener(\"input\", function() {\n clearTimeout(altTimer);\n altTimer = setTimeout(function() {\n var newAlt = altInput.value;\n if (currentValue) {\n var updated = Object.assign({}, currentValue, { alt: newAlt });\n saveField(collection, id, field, updated);\n if (imgEl) imgEl.alt = newAlt;\n }\n }, 500);\n });\n\n // Handle drag and drop on the popover body\n var body = popover.querySelector(\".emdash-img-popover-body\");\n body.addEventListener(\"dragover\", function(e) {\n e.preventDefault();\n body.classList.add(\"emdash-img-drop\");\n });\n body.addEventListener(\"dragleave\", function() {\n body.classList.remove(\"emdash-img-drop\");\n });\n body.addEventListener(\"drop\", function(e) {\n e.preventDefault();\n body.classList.remove(\"emdash-img-drop\");\n var file = e.dataTransfer && e.dataTransfer.files && e.dataTransfer.files[0];\n if (file && file.type.startsWith(\"image/\")) {\n handleImageUpload(file, popover, annotation, element, imgEl);\n }\n });\n }\n\n function positionPopover(popover, targetRect, viewportW, viewportH) {\n var popoverW = 320;\n var gap = 8;\n\n // Try to place to the right of the element\n var left = targetRect.right + gap;\n var top = targetRect.top;\n\n // If it overflows right, place to the left\n if (left + popoverW > viewportW - 16) {\n left = targetRect.left - popoverW - gap;\n }\n // If it still overflows (narrow viewport), center below\n if (left < 16) {\n left = Math.max(16, (viewportW - popoverW) / 2);\n top = targetRect.bottom + gap;\n }\n // Clamp vertically\n if (top + 400 > viewportH - 80) { // 80 for toolbar\n top = Math.max(16, viewportH - 480);\n }\n if (top < 16) top = 16;\n\n popover.style.left = left + \"px\";\n popover.style.top = top + \"px\";\n }\n\n function escapeAttr(str) {\n return String(str || \"\").replace(/&/g, \"&amp;\").replace(/\"/g, \"&quot;\").replace(/</g, \"&lt;\").replace(/>/g, \"&gt;\");\n }\n\n function showMediaBrowser(popover, annotation, currentValue, element, imgEl) {\n var mainBody = popover.querySelector(\"#emdash-img-main\");\n if (mainBody) mainBody.style.display = \"none\";\n\n // Remove existing browser if any\n var existing = popover.querySelector(\".emdash-img-browser\");\n if (existing) existing.remove();\n\n var browser = document.createElement(\"div\");\n browser.className = \"emdash-img-browser\";\n\n browser.innerHTML = '<div class=\"emdash-img-browser-header\">' +\n '<span class=\"emdash-img-browser-title\">Media Library</span>' +\n '<button class=\"emdash-img-browser-back\">Back</button>' +\n '</div>' +\n '<div class=\"emdash-img-loading\">Loading\\u2026</div>';\n\n popover.appendChild(browser);\n\n browser.querySelector(\".emdash-img-browser-back\").addEventListener(\"click\", function() {\n browser.remove();\n if (mainBody) mainBody.style.display = \"\";\n });\n\n // Fetch media\n ecFetch(\"/_emdash/api/media?mimeType=image/&limit=30\", { credentials: \"same-origin\" })\n .then(function(r) { return r.json(); })\n .then(function(data) {\n var items = data.items || [];\n var loadingEl = browser.querySelector(\".emdash-img-loading\");\n if (loadingEl) loadingEl.remove();\n\n if (items.length === 0) {\n var empty = document.createElement(\"div\");\n empty.className = \"emdash-img-loading\";\n empty.textContent = \"No images found\";\n browser.appendChild(empty);\n return;\n }\n\n var grid = document.createElement(\"div\");\n grid.className = \"emdash-img-grid\";\n\n items.forEach(function(item) {\n var thumb = document.createElement(\"div\");\n thumb.className = \"emdash-img-grid-item\";\n if (currentValue && currentValue.id === item.id) {\n thumb.classList.add(\"emdash-img-grid-item--selected\");\n }\n var thumbUrl = item.url || item.previewUrl || (\"/_emdash/api/media/file/\" + item.storageKey);\n thumb.innerHTML = '<img src=\"' + escapeAttr(thumbUrl) + '\" alt=\"' + escapeAttr(item.alt || item.filename || \"\") + '\" loading=\"lazy\" />';\n\n thumb.addEventListener(\"click\", function() {\n selectMediaItem(item, annotation, element, imgEl);\n });\n\n grid.appendChild(thumb);\n });\n\n browser.appendChild(grid);\n })\n .catch(function(err) {\n var loadingEl = browser.querySelector(\".emdash-img-loading\");\n if (loadingEl) loadingEl.textContent = \"Failed to load media\";\n console.error(\"Media fetch error:\", err);\n });\n }\n\n function selectMediaItem(item, annotation, element, imgEl) {\n var collection = annotation.collection;\n var id = annotation.id;\n var field = annotation.field;\n\n var isLocal = !item.provider || item.provider === \"local\";\n var itemUrl = item.url || item.previewUrl || (\"/_emdash/api/media/file/\" + item.storageKey);\n\n var newValue = {\n id: item.id,\n provider: item.provider || \"local\",\n src: isLocal ? itemUrl : undefined,\n previewUrl: isLocal ? undefined : itemUrl,\n alt: item.alt || \"\",\n width: item.width,\n height: item.height,\n meta: item.meta\n };\n\n // Clean undefined fields\n Object.keys(newValue).forEach(function(k) {\n if (newValue[k] === undefined) delete newValue[k];\n });\n\n saveField(collection, id, field, newValue).then(function() {\n // Update the image in the DOM\n if (imgEl) {\n imgEl.src = itemUrl;\n imgEl.alt = item.alt || \"\";\n imgEl.style.display = \"\";\n }\n closeImagePopover();\n });\n }\n\n function handleImageUpload(file, popover, annotation, element, imgEl) {\n var collection = annotation.collection;\n var id = annotation.id;\n var field = annotation.field;\n\n // Show uploading state\n var mainBody = popover.querySelector(\"#emdash-img-main\");\n var browserEl = popover.querySelector(\".emdash-img-browser\");\n if (browserEl) browserEl.remove();\n if (mainBody) {\n mainBody.innerHTML = '<div class=\"emdash-img-uploading\">' +\n '<span>Uploading ' + escapeAttr(file.name) + '\\u2026</span>' +\n '</div>';\n mainBody.style.display = \"\";\n }\n\n // Detect dimensions before upload\n var dimPromise = new Promise(function(resolve) {\n if (!file.type.startsWith(\"image/\")) return resolve({});\n var img = new Image();\n img.onload = function() {\n resolve({ width: img.naturalWidth, height: img.naturalHeight });\n URL.revokeObjectURL(img.src);\n };\n img.onerror = function() {\n resolve({});\n URL.revokeObjectURL(img.src);\n };\n img.src = URL.createObjectURL(file);\n });\n\n dimPromise.then(function(dims) {\n // Generate a thumbnail for large images to avoid OOM in server-side\n // blurhash generation on memory-constrained runtimes (Workers).\n // Thumbnail fits within a 64x64 box (scale by max dimension) so that\n // extreme aspect ratios don't explode into a huge canvas client-side.\n var thumbPromise;\n if (dims.width && dims.height && dims.width * dims.height * 4 > 32 * 1024 * 1024) {\n thumbPromise = new Promise(function(resolve) {\n try {\n var maxDim = Math.max(dims.width, dims.height);\n var scale = Math.min(1, 64 / maxDim);\n var thumbW = Math.max(1, Math.round(dims.width * scale));\n var thumbH = Math.max(1, Math.round(dims.height * scale));\n var canvas = document.createElement(\"canvas\");\n canvas.width = thumbW;\n canvas.height = thumbH;\n var ctx = canvas.getContext(\"2d\");\n if (ctx) {\n var img = new Image();\n img.onload = function() {\n try {\n ctx.drawImage(img, 0, 0, thumbW, thumbH);\n canvas.toBlob(function(blob) {\n URL.revokeObjectURL(img.src);\n resolve(blob);\n }, \"image/png\");\n } catch (e) {\n URL.revokeObjectURL(img.src);\n resolve(null);\n }\n };\n img.onerror = function() {\n URL.revokeObjectURL(img.src);\n resolve(null);\n };\n img.src = URL.createObjectURL(file);\n } else {\n resolve(null);\n }\n } catch (e) {\n resolve(null);\n }\n });\n } else {\n thumbPromise = Promise.resolve(null);\n }\n\n return thumbPromise.then(function(thumbnail) {\n var formData = new FormData();\n formData.append(\"file\", file);\n if (dims.width) formData.append(\"width\", String(dims.width));\n if (dims.height) formData.append(\"height\", String(dims.height));\n if (thumbnail) formData.append(\"thumbnail\", thumbnail, \"thumb.png\");\n\n return ecFetch(\"/_emdash/api/media\", {\n method: \"POST\",\n credentials: \"same-origin\",\n body: formData\n });\n });\n })\n .then(function(r) { return r.json(); })\n .then(function(data) {\n if (!data.item) throw new Error(\"Upload failed\");\n var item = data.item;\n selectMediaItem(item, annotation, element, imgEl);\n })\n .catch(function(err) {\n console.error(\"Upload error:\", err);\n setSaveState(\"error\");\n closeImagePopover();\n });\n }\n\n // Click handler for edit mode\n if (isEditMode) {\n document.addEventListener(\"click\", function(e) {\n var target = e.target;\n\n // Don't intercept clicks on elements currently being edited\n if (target.hasAttribute && target.hasAttribute(\"data-emdash-editing\")) return;\n\n // Walk up to find annotated element\n while (target && target !== document.body) {\n if (target.hasAttribute && target.hasAttribute(\"data-emdash-editing\")) return;\n\n var ref = target.getAttribute && target.getAttribute(\"data-emdash-ref\");\n if (ref) {\n try {\n var annotation = JSON.parse(ref);\n\n // Entry-level annotation (no field) — keep walking for a field-level ancestor\n if (!annotation.field) {\n target = target.parentElement;\n continue;\n }\n\n function dispatchInline(kind) {\n closeImagePopover();\n // Portable Text is edited in-page by InlinePortableTextEditor — do not open admin\n if (kind === \"portableText\") {\n return;\n }\n e.preventDefault();\n e.stopPropagation();\n if (kind === \"string\" || kind === \"text\") {\n startTextEdit(target, annotation);\n } else if (kind === \"image\") {\n startImageEdit(target, annotation);\n } else {\n openAdmin(annotation);\n }\n }\n\n if (manifestCache) {\n dispatchInline(getFieldKind(manifestCache, annotation.collection, annotation.field));\n } else {\n fetchManifest().then(function(manifest) {\n dispatchInline(getFieldKind(manifest, annotation.collection, annotation.field));\n });\n }\n } catch (err) {\n console.error(\"Failed to parse emdash ref:\", err);\n }\n return;\n }\n target = target.parentElement;\n }\n }, true);\n }\n\n updateStatus();\n})();\n</script>\n`;\n}\n","/**\n * EmDash Request Context Middleware\n *\n * Sets up AsyncLocalStorage-based request context for query functions.\n * Skips ALS entirely for logged-out users with no CMS signals (fast path).\n *\n * Handles:\n * - Preview tokens: _preview query param with signed HMAC token\n * - Edit mode: emdash-edit-mode cookie (for visual editing)\n * - Toolbar injection: floating pill for authenticated editors\n * - Client toolbar mode (`toolbar: \"client\"`): cache-identical HTML with a\n * client-side bootstrap pill and an `_edit` query param for fresh editor\n * renders; the backend verifies the `_edit` param and redirects non-editors\n */\n\nimport { loadVisualEditingToolbarLabels } from \"@emdash-cms/admin/locales/server\";\nimport type { APIContext } from \"astro\";\nimport { defineMiddleware } from \"astro:middleware\";\n// @ts-ignore - virtual module\nimport virtualConfig from \"virtual:emdash/config\";\n\nimport { resolveSecretsCached } from \"#config/secrets.js\";\n\nimport { verifyPreviewToken, parseContentId } from \"../../preview/tokens.js\";\nimport { getRequestContext, runWithContext } from \"../../request-context.js\";\nimport { generateVisualEditingActionToken } from \"../../visual-editing/action-token.js\";\nimport { EDIT_PARAM, renderToolbarBootstrap } from \"../../visual-editing/toolbar-bootstrap.js\";\nimport { renderToolbar } from \"../../visual-editing/toolbar.js\";\n\ntype ToolbarMode = \"server\" | \"client\" | false;\n\nconst toolbarMode: ToolbarMode = virtualConfig?.toolbar ?? \"server\";\n\n/**\n * Astro's route-cache handle. Astro defines `context.cache` only on requests\n * that went through its cache handler, so it is `undefined` on some renders,\n * such as the 404 page for a URL that matches no route.\n */\ntype RouteCache = APIContext[\"cache\"] | undefined;\n\nasync function renderEditorToolbar(\n\tcontext: APIContext,\n\tconfig: { editMode: boolean; isPreview: boolean },\n): Promise<string> {\n\tconst labels = await loadVisualEditingToolbarLabels(context.request);\n\tconst { emdash, user } = context.locals;\n\tif (!emdash?.db || !user) return renderToolbar({ ...config, labels });\n\tconst { previewSecret } = await resolveSecretsCached(emdash.db);\n\tconst actionToken = await generateVisualEditingActionToken(previewSecret, user.id);\n\treturn renderToolbar({ ...config, actionToken, labels });\n}\n\n/**\n * Opt the current request out of Astro's route cache (e.g. Workers Cache on\n * Cloudflare). `Cache-Control` headers do NOT cover this: the adapter derives\n * the shared-cache TTL from the route-cache options (on Cloudflare via\n * `Cloudflare-CDN-Cache-Control`), so session-specific responses must\n * explicitly disable it or they get stored in the shared cache and served to\n * anonymous visitors without ever invoking the middleware again. With no cache\n * provider configured, or no cache handle on the request, this is a no-op.\n */\nfunction optOutOfRouteCache(cache: RouteCache): void {\n\tcache?.set(false);\n}\n\n/**\n * Inject HTML before `</body>` if the response is an HTML page with a body\n * end tag. Does not touch cache headers — callers decide whether the result\n * is still shareable. `injected` tells the caller whether anything changed.\n */\nasync function injectBeforeBodyEnd(\n\tresponse: Response,\n\thtmlToInject: string,\n): Promise<{ response: Response; injected: boolean }> {\n\tconst contentType = response.headers.get(\"content-type\");\n\tif (!contentType?.includes(\"text/html\")) return { response, injected: false };\n\n\tconst html = await response.text();\n\tif (!html.includes(\"</body>\")) {\n\t\t// Body already consumed — rebuild the response unchanged.\n\t\treturn { response: new Response(html, response), injected: false };\n\t}\n\n\tconst injected = html.replace(\"</body>\", `${htmlToInject}</body>`);\n\treturn {\n\t\tresponse: new Response(injected, {\n\t\t\tstatus: response.status,\n\t\t\theaders: response.headers,\n\t\t}),\n\t\tinjected: true,\n\t};\n}\n\n/**\n * Inject toolbar HTML into a response if it's an HTML page.\n * Returns the original response if not HTML.\n */\nasync function injectToolbar(\n\tresponse: Response,\n\ttoolbarHtml: string,\n\trouteCache: RouteCache,\n): Promise<Response> {\n\tconst result = await injectBeforeBodyEnd(response, toolbarHtml);\n\tif (result.injected) {\n\t\t// Toolbar-injected HTML is session-specific (its presence reveals an\n\t\t// active editor session); it must never be stored in a shared CDN cache\n\t\t// and served to anonymous visitors. `Cache-Control` covers\n\t\t// browsers/downstream proxies; the\n\t\t// route-cache opt-out covers the shared edge cache, which ignores\n\t\t// `Cache-Control`.\n\t\tresult.response.headers.set(\"Cache-Control\", \"private, no-store\");\n\t\toptOutOfRouteCache(routeCache);\n\t}\n\treturn result.response;\n}\n\n/**\n * Inject the client-toolbar bootstrap script. Identical for every visitor, so\n * cache headers and route-cache options are left untouched and the response\n * stays fully shareable.\n */\nasync function injectBootstrap(response: Response): Promise<Response> {\n\tconst result = await injectBeforeBodyEnd(response, renderToolbarBootstrap());\n\treturn result.response;\n}\n\n/**\n * Redirect an `_edit` URL to its canonical form (same URL without the param).\n * Applied when the requester is not an authenticated editor, so a shared\n * `?_edit` link degrades gracefully for everyone else.\n */\nfunction redirectToCanonical(url: URL): Response {\n\tconst canonical = new URL(url);\n\tcanonical.searchParams.delete(EDIT_PARAM);\n\treturn new Response(null, {\n\t\tstatus: 302,\n\t\theaders: {\n\t\t\tLocation: canonical.pathname + canonical.search + canonical.hash,\n\t\t\t// Header-following caches (Fastly, Varnish, browsers) must not store\n\t\t\t// the redirect — a cached 302 would bounce editors back to the\n\t\t\t// canonical URL. The route-cache opt-out at the call site covers the\n\t\t\t// Workers Cache, which ignores Cache-Control.\n\t\t\t\"Cache-Control\": \"private, no-store\",\n\t\t},\n\t});\n}\n\nexport const onRequest = defineMiddleware(async (context, next) => {\n\tconst { cookies, url } = context;\n\n\t// Skip /_emdash routes (admin has its own UI, no rendering context needed)\n\tif (url.pathname.startsWith(\"/_emdash\")) {\n\t\treturn next();\n\t}\n\n\t// Check for authenticated editor (role >= 30)\n\tconst { user } = context.locals;\n\tconst isEditor = !!user && user.role >= 30;\n\n\t// Playground mode: the playground middleware (from @emdash-cms/cloudflare) stashes\n\t// the per-session DO database on locals.__playgroundDb. We set it via ALS here\n\t// (same module instance as the loader) so getDb() picks it up correctly.\n\t//\n\t// `dbIsIsolated: true` tells schema-derived caches (manifest, taxonomy defs,\n\t// byline/term existence probes) to bypass module-scope memoization — each\n\t// playground session is its own database with its own schema, so a cached\n\t// value from another session would be wrong.\n\tconst playgroundDb = context.locals.__playgroundDb;\n\tif (playgroundDb) {\n\t\t// Check if playground user has toggled edit mode on\n\t\tconst hasEditCookie = cookies.get(\"emdash-edit-mode\")?.value === \"true\";\n\t\treturn runWithContext({ editMode: hasEditCookie, db: playgroundDb, dbIsIsolated: true }, () =>\n\t\t\tnext(),\n\t\t);\n\t}\n\n\t// Fast path: check for CMS signals before doing any work\n\tconst hasEditCookie = cookies.get(\"emdash-edit-mode\")?.value === \"true\";\n\tconst hasPreviewToken = url.searchParams.has(\"_preview\");\n\t// `_edit` requests a fresh (never cached) editor render; only meaningful in\n\t// client toolbar mode where public HTML is otherwise identical for everyone.\n\tconst hasEditParam = toolbarMode === \"client\" && url.searchParams.has(EDIT_PARAM);\n\n\tif (hasEditParam) {\n\t\t// `_edit` URLs are their own cache key. Never store them in the route\n\t\t// cache — a cached anonymous redirect would bounce editors back to the\n\t\t// canonical URL, and a cached editor render must never be shared.\n\t\toptOutOfRouteCache(context.cache);\n\n\t\t// A non-editor (anonymous, logged-out, or insufficient role) opening an\n\t\t// `_edit` URL is sent to the canonical URL — shared `?_edit` links\n\t\t// degrade gracefully and never prime a cache entry with page content.\n\t\tif (!isEditor) {\n\t\t\treturn redirectToCanonical(url);\n\t\t}\n\t}\n\n\t// No CMS signals and not an editor → skip everything (zero overhead in\n\t// server mode; client mode injects the identical-for-everyone bootstrap)\n\tif (!hasEditCookie && !hasPreviewToken && !isEditor) {\n\t\tif (toolbarMode === \"client\") {\n\t\t\treturn injectBootstrap(await next());\n\t\t}\n\t\treturn next();\n\t}\n\n\t// Determine edit mode: cookie AND authenticated editor\n\tconst editMode = hasEditCookie && isEditor;\n\n\t// Read locale from Astro's i18n routing\n\t// eslint-disable-next-line typescript/no-unsafe-type-assertion -- Astro context includes currentLocale when i18n is configured\n\tconst locale = (context as { currentLocale?: string }).currentLocale;\n\n\tconst routeCache = context.cache;\n\n\t// Verify preview token if present.\n\t// The preview secret is resolved via `resolveSecretsCached`: env wins,\n\t// otherwise a DB-stored value is read (or generated on first need).\n\t// `emdash.db` is set by the runtime middleware which runs first; the\n\t// only path where it's missing is a runtime-init failure.\n\tlet preview: { collection: string; id: string } | undefined;\n\tif (hasPreviewToken) {\n\t\tconst db = context.locals.emdash?.db;\n\t\tif (db) {\n\t\t\tconst { previewSecret } = await resolveSecretsCached(db);\n\t\t\tconst result = await verifyPreviewToken({ url, secret: previewSecret });\n\t\t\tif (result.valid) {\n\t\t\t\tconst { collection, id } = parseContentId(result.payload.cid);\n\t\t\t\tpreview = { collection, id };\n\t\t\t}\n\t\t} else {\n\t\t\tconsole.warn(\n\t\t\t\t\"[emdash] Preview token present but EmDash runtime not initialized; preview disabled.\",\n\t\t\t);\n\t\t}\n\t}\n\n\t// If we have CMS signals, wrap in ALS context\n\tconst needsContext = hasEditCookie || hasPreviewToken;\n\n\tif (needsContext) {\n\t\t// Merge with any outer ALS context (e.g. the per-request D1 session db\n\t\t// set by the runtime middleware). `storage.run()` replaces the store\n\t\t// wholesale, so without the spread the outer `db` would be lost and\n\t\t// loaders would fall back to the singleton non-session dialect.\n\t\tconst parent = getRequestContext();\n\t\treturn runWithContext({ ...parent, editMode, preview, locale }, async () => {\n\t\t\tlet response = await next();\n\n\t\t\t// Preview responses must not be cached -- draft content could leak past token expiry.\n\t\t\t// Clone the response before modifying headers — the original may be immutable.\n\t\t\t// `Cache-Control` only governs browsers/downstream proxies; the shared\n\t\t\t// edge cache follows the route-cache options, so opt out of those too —\n\t\t\t// otherwise the draft response is stored in the shared cache and served\n\t\t\t// on cache hits without token verification until TTL/purge. Opt out for\n\t\t\t// any request carrying a `_preview` param (valid or not): those URLs are\n\t\t\t// per-token, so cached copies are useless at best and drafts at worst.\n\t\t\tif (hasPreviewToken) {\n\t\t\t\toptOutOfRouteCache(routeCache);\n\t\t\t}\n\t\t\tif (preview) {\n\t\t\t\tresponse = new Response(response.body, response);\n\t\t\t\tresponse.headers.set(\"Cache-Control\", \"private, no-store\");\n\t\t\t}\n\n\t\t\t// Inject toolbar for authenticated editors. Preview and edit-mode\n\t\t\t// responses are session-specific (`private, no-store` + route-cache\n\t\t\t// opt-out) in every toolbar mode, so the server toolbar is safe to\n\t\t\t// inject here even in client mode.\n\t\t\tif (isEditor && toolbarMode !== false) {\n\t\t\t\tconst toolbarHtml = await renderEditorToolbar(context, {\n\t\t\t\t\teditMode,\n\t\t\t\t\tisPreview: !!preview,\n\t\t\t\t});\n\t\t\t\treturn injectToolbar(response, toolbarHtml, routeCache);\n\t\t\t}\n\n\t\t\t// Stale edit cookie without a session (client mode): still serve the\n\t\t\t// shareable bootstrap variant.\n\t\t\tif (toolbarMode === \"client\" && !isEditor && !preview) {\n\t\t\t\treturn injectBootstrap(response);\n\t\t\t}\n\n\t\t\treturn response;\n\t\t});\n\t}\n\n\t// Editor without preview/edit-mode signals.\n\tif (isEditor) {\n\t\tif (toolbarMode === false) {\n\t\t\treturn next();\n\t\t}\n\n\t\t// Client mode: without the `_edit` param the response must stay\n\t\t// byte-identical to the anonymous variant (plus the same bootstrap\n\t\t// script), so shared caches serve one entry for everyone. The bootstrap\n\t\t// pill is the editor's entry point into the fresh `_edit` render.\n\t\tif (toolbarMode === \"client\" && !hasEditParam) {\n\t\t\treturn injectBootstrap(await next());\n\t\t}\n\n\t\t// Server mode, or an `_edit` request in client mode: inject the full\n\t\t// toolbar (response becomes `private, no-store` and route-cache\n\t\t// opted out).\n\t\tconst response = await next();\n\t\tconst toolbarHtml = await renderEditorToolbar(context, {\n\t\t\teditMode: false,\n\t\t\tisPreview: false,\n\t\t});\n\t\treturn injectToolbar(response, toolbarHtml, routeCache);\n\t}\n\n\treturn next();\n});\n\nexport default onRequest;\n"],"mappings":"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"}
1
+ {"version":3,"file":"request-context.mjs","names":[],"sources":["../../../src/visual-editing/toolbar-bootstrap.ts","../../../src/visual-editing/toolbar.ts","../../../src/astro/middleware/request-context.ts"],"sourcesContent":["/**\n * EmDash Toolbar Bootstrap (toolbar: \"client\")\n *\n * A tiny script injected into every public HTML response when the client\n * toolbar mode is enabled. It is identical for every visitor, so the HTML\n * stays fully cacheable by shared caches (Workers Cache, Cache Everything,\n * Fastly, Varnish, …).\n *\n * Behavior: if this browser has logged into the admin (non-secret\n * localStorage flag set by the admin SPA), render a small \"Edit\" pill.\n * Clicking it verifies the session server-side and reloads the page with the\n * `_edit` query param — that URL is always rendered fresh with the full\n * server-side toolbar. Logged-out browsers pay one localStorage read and\n * nothing else.\n */\n\n/**\n * Non-secret localStorage flag set by the admin SPA when an editor session\n * exists in this browser. It only means \"a session may exist\" — the click\n * handler verifies the real session before entering edit mode. The literal\n * is duplicated in `@emdash-cms/admin` (Shell/Header), which cannot import\n * from core.\n */\nexport const EDITOR_FLAG_KEY = \"emdash-editor\";\n\n/**\n * localStorage flag set when the user dismisses the toolbar in this browser.\n * Cleared the next time an editor opens the admin. Also duplicated in\n * `@emdash-cms/admin`.\n */\nexport const TOOLBAR_DISMISSED_KEY = \"emdash-toolbar-dismissed\";\n\n/** Localized bootstrap labels written by the admin SPA for this browser. */\nexport const TOOLBAR_LABELS_KEY = \"emdash-toolbar-labels\";\n\n/**\n * Query param that requests a fresh (never cached) editor render. Presence is\n * verified server-side: non-editors are redirected to the canonical URL.\n */\nexport const EDIT_PARAM = \"_edit\";\n\nexport function renderToolbarBootstrap(): string {\n\treturn `\n<!-- EmDash Toolbar Bootstrap -->\n<script>\n(function mountToolbar() {\n var flag, dismissed, labelsRaw;\n var labels = null;\n try {\n flag = localStorage.getItem(\"${EDITOR_FLAG_KEY}\");\n dismissed = localStorage.getItem(\"${TOOLBAR_DISMISSED_KEY}\");\n labelsRaw = localStorage.getItem(\"${TOOLBAR_LABELS_KEY}\");\n } catch (e) {\n return;\n }\n if (!flag || dismissed) return;\n if (labelsRaw) {\n try {\n var storedLabels = JSON.parse(labelsRaw);\n if (storedLabels && typeof storedLabels.editMode === \"string\" && typeof storedLabels.hideToolbar === \"string\") {\n labels = storedLabels;\n }\n } catch (e) {}\n }\n if (!labels) {\n fetch(\"/_emdash/api/visual-editing/toolbar-labels\", { credentials: \"same-origin\" })\n .then(function(response) { return response.ok ? response.json() : null; })\n .then(function(body) {\n var fetched = body && body.data;\n if (!fetched || typeof fetched.editMode !== \"string\" || typeof fetched.hideToolbar !== \"string\") return;\n try { localStorage.setItem(\"${TOOLBAR_LABELS_KEY}\", JSON.stringify(fetched)); } catch (e) { return; }\n mountToolbar();\n })\n .catch(function() {});\n return;\n }\n // The server toolbar is present on _edit / edit-mode / preview renders.\n if (document.getElementById(\"emdash-toolbar\")) return;\n\n var root = document.createElement(\"div\");\n root.id = \"emdash-toolbar-bootstrap\";\n root.style.cssText = \"position:fixed;bottom:16px;left:50%;transform:translateX(-50%);z-index:999999;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;font-size:13px;line-height:1;-webkit-font-smoothing:antialiased;\";\n\n var inner = document.createElement(\"div\");\n inner.style.cssText = \"display:flex;align-items:center;gap:10px;padding:8px 16px;background:#1a1a1a;color:#e0e0e0;border-radius:999px;box-shadow:0 4px 24px rgba(0,0,0,0.3),0 0 0 1px rgba(255,255,255,0.08);white-space:nowrap;user-select:none;\";\n\n var logo = document.createElement(\"span\");\n logo.textContent = \"EmDash\";\n logo.style.cssText = \"font-weight:600;font-size:12px;letter-spacing:0.02em;color:#fff;opacity:0.7;\";\n\n var divider = document.createElement(\"span\");\n divider.style.cssText = \"width:1px;height:16px;background:rgba(255,255,255,0.15);\";\n\n var editBtn = document.createElement(\"button\");\n editBtn.textContent = labels.editMode;\n editBtn.style.cssText = \"padding:4px 12px;background:#3b82f6;color:#fff;border:none;border-radius:999px;font-size:12px;font-weight:600;cursor:pointer;font-family:inherit;\";\n\n var closeBtn = document.createElement(\"button\");\n closeBtn.textContent = \"\\\\u00d7\";\n closeBtn.title = labels.hideToolbar;\n closeBtn.setAttribute(\"aria-label\", labels.hideToolbar);\n closeBtn.style.cssText = \"background:none;border:none;color:#666;cursor:pointer;font-size:16px;padding:0 2px;line-height:1;font-family:inherit;\";\n\n editBtn.addEventListener(\"click\", function() {\n editBtn.disabled = true;\n fetch(\"/_emdash/api/auth/me\", {\n credentials: \"same-origin\",\n headers: { \"X-EmDash-Request\": \"1\" }\n })\n .then(function(r) { return r.ok ? r.json() : null; })\n .then(function(body) {\n var user = body && body.data;\n if (user && user.role >= 30) {\n var u = new URL(location.href);\n u.searchParams.set(\"${EDIT_PARAM}\", \"1\");\n location.href = u.toString();\n } else if (user) {\n // Logged in but not an editor — the flag is stale for this browser.\n try { localStorage.removeItem(\"${EDITOR_FLAG_KEY}\"); } catch (e) {}\n root.remove();\n } else {\n // No session — go to the admin login page.\n location.href = \"/_emdash/admin/login\";\n }\n })\n .catch(function() {\n editBtn.disabled = false;\n });\n });\n\n closeBtn.addEventListener(\"click\", function() {\n try { localStorage.setItem(\"${TOOLBAR_DISMISSED_KEY}\", \"1\"); } catch (e) {}\n root.remove();\n });\n\n inner.appendChild(logo);\n inner.appendChild(divider);\n inner.appendChild(editBtn);\n inner.appendChild(closeBtn);\n root.appendChild(inner);\n document.body.appendChild(root);\n})();\n</script>\n`;\n}\n","import { escapeHtml } from \"../api/escape.js\";\nimport { VISUAL_ACTION_TOKEN_INVALID } from \"./action-token.js\";\n\n/**\n * EmDash Visual Editing Toolbar\n *\n * A floating pill injected via middleware for authenticated editors.\n * Renders as a plain HTML string with inline styles and a <script> tag.\n * No dependencies — works on any page with a </body> tag.\n */\n\ninterface ToolbarConfig {\n\teditMode: boolean;\n\tisPreview: boolean;\n\tactionToken?: string;\n\tlabels: ToolbarLabels;\n\t/** Hide the pill but keep inline editing, for pages that show their own bar. */\n\thidden?: boolean;\n}\n\nexport interface ToolbarLabels {\n\tpublish: string;\n\tpublishing: string;\n\tsessionExpired: string;\n\trefreshPage: string;\n\tpublishFailed: string;\n\teditMode: string;\n\topenInAdmin: string;\n\thideToolbar: string;\n}\n\nconst SCRIPT_LINE_SEPARATOR_RE = /\\u2028/g;\nconst SCRIPT_PARAGRAPH_SEPARATOR_RE = /\\u2029/g;\n\nfunction inlineScriptJson(value: unknown): string {\n\treturn JSON.stringify(value)\n\t\t.replaceAll(\"<\", \"\\\\u003c\")\n\t\t.replace(SCRIPT_LINE_SEPARATOR_RE, \"\\\\u2028\")\n\t\t.replace(SCRIPT_PARAGRAPH_SEPARATOR_RE, \"\\\\u2029\");\n}\n\nexport function renderToolbar(config: ToolbarConfig): string {\n\tconst { editMode, isPreview, actionToken = \"\", labels, hidden = false } = config;\n\tconst recoveryBadge = `<span class=\"emdash-tb-badge emdash-tb-badge--error\">${escapeHtml(labels.sessionExpired)}</span>`;\n\n\treturn `\n<!-- EmDash Visual Editing Toolbar -->\n<div id=\"emdash-toolbar\" data-edit-mode=\"${editMode}\" data-preview=\"${isPreview}\"${hidden ? \" hidden\" : \"\"}>\n <div class=\"emdash-tb-inner\">\n <span class=\"emdash-tb-logo\">EmDash</span>\n\n <div class=\"emdash-tb-divider\"></div>\n\n <label class=\"emdash-tb-toggle\" title=\"${escapeHtml(labels.editMode)}\">\n <input type=\"checkbox\" id=\"emdash-edit-toggle\" ${editMode ? \"checked\" : \"\"} />\n <span class=\"emdash-tb-toggle-track\">\n <span class=\"emdash-tb-toggle-thumb\"></span>\n </span>\n <span class=\"emdash-tb-toggle-label\">${escapeHtml(labels.editMode)}</span>\n </label>\n\n <span class=\"emdash-tb-status\" id=\"emdash-tb-status\"></span>\n\n <span class=\"emdash-tb-save-status\" id=\"emdash-tb-save-status\"></span>\n\n <a class=\"emdash-tb-admin\" id=\"emdash-tb-admin\" href=\"#\" target=\"emdash-admin\" style=\"display:none\" title=\"${escapeHtml(labels.openInAdmin)}\">\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6\"/><polyline points=\"15 3 21 3 21 9\"/><line x1=\"10\" y1=\"14\" x2=\"21\" y2=\"3\"/></svg>\n </a>\n\n <button class=\"emdash-tb-publish\" id=\"emdash-tb-publish\" style=\"display:none\">${escapeHtml(labels.publish)}</button>\n\n <button class=\"emdash-tb-dismiss\" id=\"emdash-tb-dismiss\" title=\"${escapeHtml(labels.hideToolbar)}\" aria-label=\"${escapeHtml(labels.hideToolbar)}\">&times;</button>\n </div>\n</div>\n\n<style>\n #emdash-toolbar {\n position: fixed;\n bottom: 16px;\n left: 50%;\n transform: translateX(-50%);\n z-index: 999999;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n font-size: 13px;\n line-height: 1;\n -webkit-font-smoothing: antialiased;\n }\n\n .emdash-tb-inner {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 8px 16px;\n background: #1a1a1a;\n color: #e0e0e0;\n border-radius: 999px;\n box-shadow: 0 4px 24px rgba(0,0,0,0.3), 0 0 0 1px rgba(255,255,255,0.08);\n white-space: nowrap;\n user-select: none;\n }\n\n .emdash-tb-logo {\n font-weight: 600;\n font-size: 12px;\n letter-spacing: 0.02em;\n color: #fff;\n opacity: 0.7;\n }\n\n .emdash-tb-divider {\n width: 1px;\n height: 16px;\n background: rgba(255,255,255,0.15);\n }\n\n /* Toggle switch */\n .emdash-tb-toggle {\n display: flex;\n align-items: center;\n gap: 6px;\n cursor: pointer;\n }\n\n .emdash-tb-toggle input {\n position: absolute;\n opacity: 0;\n width: 0;\n height: 0;\n }\n\n .emdash-tb-toggle-track {\n position: relative;\n width: 32px;\n height: 18px;\n background: #444;\n border-radius: 9px;\n transition: background 0.2s;\n }\n\n .emdash-tb-toggle input:checked + .emdash-tb-toggle-track {\n background: #3b82f6;\n }\n\n .emdash-tb-toggle-thumb {\n position: absolute;\n top: 2px;\n left: 2px;\n width: 14px;\n height: 14px;\n background: #fff;\n border-radius: 50%;\n transition: transform 0.2s;\n }\n\n .emdash-tb-toggle input:checked + .emdash-tb-toggle-track .emdash-tb-toggle-thumb {\n transform: translateX(14px);\n }\n\n .emdash-tb-toggle-label {\n font-size: 12px;\n color: #aaa;\n }\n\n .emdash-tb-toggle input:checked ~ .emdash-tb-toggle-label {\n color: #fff;\n }\n\n /* Status area — flex for multiple badges */\n .emdash-tb-status {\n display: inline-flex;\n gap: 6px;\n align-items: center;\n }\n\n /* Badges */\n .emdash-tb-badge {\n display: inline-flex;\n align-items: center;\n padding: 3px 8px;\n border-radius: 999px;\n font-size: 11px;\n font-weight: 600;\n letter-spacing: 0.02em;\n text-transform: uppercase;\n }\n\n .emdash-tb-badge--preview {\n background: rgba(139,92,246,0.2);\n color: #a78bfa;\n }\n\n .emdash-tb-badge--draft {\n background: rgba(245,158,11,0.2);\n color: #fbbf24;\n }\n\n .emdash-tb-badge--published {\n background: rgba(34,197,94,0.2);\n color: #4ade80;\n }\n\n .emdash-tb-badge--pending {\n background: rgba(59,130,246,0.2);\n color: #60a5fa;\n }\n\n .emdash-tb-badge--unsaved {\n background: rgba(245,158,11,0.2);\n color: #fbbf24;\n }\n\n .emdash-tb-badge--saving {\n background: rgba(148,163,184,0.2);\n color: #94a3b8;\n }\n\n .emdash-tb-badge--saved {\n background: rgba(34,197,94,0.2);\n color: #4ade80;\n transition: opacity 0.3s;\n }\n\n .emdash-tb-badge--error {\n background: rgba(239,68,68,0.2);\n color: #f87171;\n }\n\n /* Admin link */\n .emdash-tb-admin {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n color: #888;\n text-decoration: none;\n padding: 2px;\n border-radius: 4px;\n transition: color 0.15s;\n }\n\n .emdash-tb-admin:hover {\n color: #fff;\n }\n\n /* Publish button */\n .emdash-tb-publish {\n padding: 4px 12px;\n background: #3b82f6;\n color: #fff;\n border: none;\n border-radius: 999px;\n font-size: 12px;\n font-weight: 600;\n cursor: pointer;\n transition: background 0.15s;\n font-family: inherit;\n }\n\n .emdash-tb-publish:hover {\n background: #2563eb;\n }\n\n .emdash-tb-publish:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n\n /* Dismiss button */\n .emdash-tb-dismiss {\n background: none;\n border: none;\n color: #666;\n cursor: pointer;\n font-size: 16px;\n line-height: 1;\n padding: 0 2px;\n font-family: inherit;\n transition: color 0.15s;\n }\n\n .emdash-tb-dismiss:hover {\n color: #fff;\n }\n\n /* Edit mode: editable hover styles — uses :has() to check toolbar state */\n body:has(#emdash-toolbar[data-edit-mode=\"true\"]) [data-emdash-ref] {\n transition: box-shadow 0.15s, background-color 0.15s;\n }\n\n body:has(#emdash-toolbar[data-edit-mode=\"true\"]) [data-emdash-ref]:hover {\n box-shadow: 0 0 0 2px rgba(59,130,246,0.5);\n border-radius: 4px;\n background-color: rgba(59,130,246,0.04);\n cursor: text;\n }\n\n /* Active editing state — override hover pencil cursor */\n [data-emdash-editing] {\n box-shadow: 0 0 0 2px #3b82f6 !important;\n border-radius: 4px !important;\n background-color: rgba(59,130,246,0.04) !important;\n cursor: text !important;\n }\n\n /* Suppress browser focus ring on contenteditable and tiptap editor */\n [data-emdash-editing]:focus,\n [data-emdash-ref] .tiptap:focus,\n [data-emdash-ref] .ProseMirror:focus {\n outline: none !important;\n }\n\n /* Image editor popover */\n .emdash-img-popover {\n position: fixed;\n z-index: 1000000;\n background: #1a1a1a;\n border-radius: 12px;\n box-shadow: 0 8px 32px rgba(0,0,0,0.4), 0 0 0 1px rgba(255,255,255,0.08);\n color: #e0e0e0;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n font-size: 13px;\n width: 320px;\n overflow: hidden;\n animation: emdash-img-fadein 0.15s ease-out;\n }\n\n @keyframes emdash-img-fadein {\n from { opacity: 0; transform: translateY(4px); }\n to { opacity: 1; transform: translateY(0); }\n }\n\n .emdash-img-popover-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 10px 12px;\n border-bottom: 1px solid rgba(255,255,255,0.08);\n }\n\n .emdash-img-popover-title {\n font-weight: 600;\n font-size: 12px;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n color: #999;\n }\n\n .emdash-img-popover-close {\n background: none;\n border: none;\n color: #666;\n cursor: pointer;\n padding: 2px;\n line-height: 1;\n font-size: 16px;\n border-radius: 4px;\n transition: color 0.15s;\n }\n\n .emdash-img-popover-close:hover {\n color: #fff;\n }\n\n .emdash-img-popover-body {\n padding: 12px;\n display: flex;\n flex-direction: column;\n gap: 10px;\n }\n\n .emdash-img-preview {\n width: 100%;\n max-height: 160px;\n object-fit: contain;\n border-radius: 6px;\n background: #111;\n }\n\n .emdash-img-empty {\n display: flex;\n align-items: center;\n justify-content: center;\n height: 80px;\n border: 2px dashed rgba(255,255,255,0.15);\n border-radius: 6px;\n color: #666;\n font-size: 12px;\n }\n\n .emdash-img-field {\n display: flex;\n flex-direction: column;\n gap: 4px;\n }\n\n .emdash-img-field label {\n font-size: 11px;\n font-weight: 600;\n color: #888;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n }\n\n .emdash-img-field input[type=\"text\"] {\n background: #111;\n border: 1px solid rgba(255,255,255,0.12);\n border-radius: 6px;\n color: #e0e0e0;\n padding: 6px 8px;\n font-size: 13px;\n font-family: inherit;\n outline: none;\n transition: border-color 0.15s;\n }\n\n .emdash-img-field input[type=\"text\"]:focus {\n border-color: #3b82f6;\n }\n\n .emdash-img-actions {\n display: flex;\n gap: 6px;\n }\n\n .emdash-img-btn {\n flex: 1;\n padding: 6px 10px;\n border: 1px solid rgba(255,255,255,0.12);\n border-radius: 6px;\n background: #222;\n color: #e0e0e0;\n font-size: 12px;\n font-family: inherit;\n cursor: pointer;\n transition: background 0.15s, border-color 0.15s;\n text-align: center;\n white-space: nowrap;\n }\n\n .emdash-img-btn:hover {\n background: #333;\n border-color: rgba(255,255,255,0.2);\n }\n\n .emdash-img-btn--primary {\n background: #3b82f6;\n border-color: #3b82f6;\n color: #fff;\n }\n\n .emdash-img-btn--primary:hover {\n background: #2563eb;\n border-color: #2563eb;\n }\n\n .emdash-img-btn--danger {\n color: #f87171;\n border-color: rgba(248,113,113,0.3);\n }\n\n .emdash-img-btn--danger:hover {\n background: rgba(248,113,113,0.1);\n border-color: rgba(248,113,113,0.5);\n }\n\n /* Media browser within the popover */\n .emdash-img-browser {\n border-top: 1px solid rgba(255,255,255,0.08);\n padding: 12px;\n }\n\n .emdash-img-browser-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 8px;\n }\n\n .emdash-img-browser-title {\n font-size: 12px;\n font-weight: 600;\n color: #999;\n }\n\n .emdash-img-browser-back {\n background: none;\n border: none;\n color: #3b82f6;\n cursor: pointer;\n font-size: 12px;\n font-family: inherit;\n padding: 2px 4px;\n }\n\n .emdash-img-browser-back:hover {\n text-decoration: underline;\n }\n\n .emdash-img-grid {\n display: grid;\n grid-template-columns: repeat(3, 1fr);\n gap: 6px;\n max-height: 240px;\n overflow-y: auto;\n }\n\n .emdash-img-grid-item {\n aspect-ratio: 1;\n border-radius: 4px;\n overflow: hidden;\n cursor: pointer;\n border: 2px solid transparent;\n transition: border-color 0.15s;\n background: #111;\n }\n\n .emdash-img-grid-item:hover {\n border-color: rgba(59,130,246,0.5);\n }\n\n .emdash-img-grid-item--selected {\n border-color: #3b82f6;\n }\n\n .emdash-img-grid-item img {\n width: 100%;\n height: 100%;\n object-fit: cover;\n }\n\n .emdash-img-loading {\n display: flex;\n align-items: center;\n justify-content: center;\n height: 80px;\n color: #666;\n font-size: 12px;\n }\n\n .emdash-img-drop {\n border: 2px dashed #3b82f6;\n background: rgba(59,130,246,0.05);\n }\n\n .emdash-img-uploading {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 0;\n color: #999;\n font-size: 12px;\n }\n\n .emdash-img-popover-backdrop {\n position: fixed;\n inset: 0;\n z-index: 999999;\n }\n</style>\n\n<script>\n(function() {\n var toolbar = document.getElementById(\"emdash-toolbar\");\n var toggle = document.getElementById(\"emdash-edit-toggle\");\n var statusEl = document.getElementById(\"emdash-tb-status\");\n var saveStatusEl = document.getElementById(\"emdash-tb-save-status\");\n var publishBtn = document.getElementById(\"emdash-tb-publish\");\n if (!toolbar || !toggle || !statusEl || !publishBtn || !saveStatusEl) return;\n\n // Dismissed in this browser (localStorage flag, cleared on the next admin\n // visit). Remove the toolbar entirely instead of rendering it.\n try {\n if (localStorage.getItem(\"emdash-toolbar-dismissed\")) {\n toolbar.remove();\n return;\n }\n } catch (e) {\n // localStorage unavailable — render normally\n }\n\n var isEditMode = toolbar.getAttribute(\"data-edit-mode\") === \"true\";\n var visualActionToken = ${inlineScriptJson(actionToken)};\n var visualActionTokenErrorCode = ${inlineScriptJson(VISUAL_ACTION_TOKEN_INVALID)};\n var toolbarLabels = ${inlineScriptJson(labels)};\n var visualActionRefreshTimer = null;\n\n function showVisualActionRecovery() {\n if (visualActionRefreshTimer !== null) clearTimeout(visualActionRefreshTimer);\n visualActionRefreshTimer = null;\n statusEl.innerHTML = ${inlineScriptJson(recoveryBadge)};\n publishBtn.disabled = true;\n publishBtn.textContent = toolbarLabels.refreshPage;\n }\n\n function showPublishError(message) {\n statusEl.textContent = message || toolbarLabels.publishFailed;\n publishBtn.disabled = false;\n publishBtn.textContent = toolbarLabels.publish;\n }\n\n function scheduleVisualActionTokenRefresh(delay) {\n if (visualActionRefreshTimer !== null) clearTimeout(visualActionRefreshTimer);\n visualActionRefreshTimer = setTimeout(function() {\n visualActionRefreshTimer = null;\n refreshVisualActionToken();\n }, delay);\n }\n\n function refreshVisualActionToken() {\n return ecFetch(\"/_emdash/api/visual-editing/action-token\", {\n method: \"POST\",\n credentials: \"same-origin\",\n headers: { \"X-EmDash-Visual-Action\": visualActionToken },\n })\n .then(function(res) {\n if (res.status === 401 || res.status === 403) {\n showVisualActionRecovery();\n return null;\n }\n if (!res.ok) throw new Error(\"Visual action token renewal failed\");\n return res.json();\n })\n .then(function(body) {\n if (!body) return;\n if (!body.data || !body.data.token) throw new Error(\"Visual action token renewal returned no token\");\n visualActionToken = body.data.token;\n scheduleVisualActionTokenRefresh(240000);\n })\n .catch(function(error) {\n console.error(\"Visual action token renewal failed:\", error);\n scheduleVisualActionTokenRefresh(30000);\n });\n }\n\n if (visualActionToken) scheduleVisualActionTokenRefresh(240000);\n\n var dismissBtn = document.getElementById(\"emdash-tb-dismiss\");\n if (dismissBtn) {\n dismissBtn.addEventListener(\"click\", function() {\n try { localStorage.setItem(\"emdash-toolbar-dismissed\", \"1\"); } catch (e) {}\n // Dismissing while edit mode is on would strand the user in edit mode\n // with no UI to leave it — clear the cookie too.\n if (isEditMode) {\n document.cookie = \"emdash-edit-mode=;path=/;expires=Thu, 01 Jan 1970 00:00:00 GMT\";\n toolbar.remove();\n location.replace(location.href);\n return;\n }\n toolbar.remove();\n });\n }\n\n // CSRF-protected fetch — adds X-EmDash-Request header to all API calls\n function ecFetch(url, init) {\n init = init || {};\n init.headers = Object.assign({ \"X-EmDash-Request\": \"1\" }, init.headers || {});\n return fetch(url, init);\n }\n\n // --- Save status tracking ---\n var saveState = \"idle\"; // idle | unsaved | saving | saved | error\n var saveHideTimer = null;\n var pendingSavePromise = null;\n\n function setSaveState(state) {\n saveState = state;\n clearTimeout(saveHideTimer);\n\n switch (state) {\n case \"unsaved\":\n saveStatusEl.innerHTML = '<span class=\"emdash-tb-badge emdash-tb-badge--unsaved\">Unsaved</span>';\n break;\n case \"saving\":\n saveStatusEl.innerHTML = '<span class=\"emdash-tb-badge emdash-tb-badge--saving\">Saving\\u2026</span>';\n break;\n case \"saved\":\n saveStatusEl.innerHTML = '<span class=\"emdash-tb-badge emdash-tb-badge--saved\">Saved</span>';\n saveHideTimer = setTimeout(function() {\n saveStatusEl.innerHTML = \"\";\n saveState = \"idle\";\n }, 2000);\n break;\n case \"error\":\n saveStatusEl.innerHTML = '<span class=\"emdash-tb-badge emdash-tb-badge--error\">Save failed</span>';\n saveHideTimer = setTimeout(function() {\n saveStatusEl.innerHTML = \"\";\n saveState = \"idle\";\n }, 3000);\n break;\n default:\n saveStatusEl.innerHTML = \"\";\n }\n }\n\n // Listen for save events from inline editors (e.g. PT editor)\n document.addEventListener(\"emdash:save\", function(e) {\n var detail = e.detail || {};\n if (detail.state) {\n setSaveState(detail.state);\n }\n });\n\n document.addEventListener(\"emdash:content-changed\", function(e) {\n var detail = e.detail || {};\n if (detail.collection && detail.id) {\n showUnpublishedChanges(detail.collection, detail.id);\n }\n });\n\n // --- Entry status ---\n var entryRef = null;\n\n function updateStatus() {\n if (!isEditMode) {\n statusEl.innerHTML = \"\";\n publishBtn.style.display = \"none\";\n return;\n }\n\n var first = document.querySelector(\"[data-emdash-ref]\");\n if (!first) {\n statusEl.innerHTML = \"\";\n publishBtn.style.display = \"none\";\n return;\n }\n\n try {\n var ref = JSON.parse(first.getAttribute(\"data-emdash-ref\"));\n entryRef = ref;\n if (!ref.status) return;\n\n // Show admin link\n var adminLink = document.getElementById(\"emdash-tb-admin\");\n if (adminLink) {\n adminLink.href = \"/_emdash/admin/content/\" + encodeURIComponent(ref.collection) + \"/\" + encodeURIComponent(ref.id);\n adminLink.style.display = \"\";\n }\n\n if (ref.status === \"draft\") {\n statusEl.innerHTML = '<span class=\"emdash-tb-badge emdash-tb-badge--draft\">Draft</span>';\n publishBtn.style.display = \"\";\n publishBtn.onclick = function() { publish(ref.collection, ref.id); };\n } else if (ref.status === \"published\" && ref.hasDraft) {\n statusEl.innerHTML = '<span class=\"emdash-tb-badge emdash-tb-badge--pending\">Unpublished changes</span>';\n publishBtn.style.display = \"\";\n publishBtn.onclick = function() { publish(ref.collection, ref.id); };\n } else if (ref.status === \"published\") {\n statusEl.innerHTML = '<span class=\"emdash-tb-badge emdash-tb-badge--published\">Published</span>';\n publishBtn.style.display = \"none\";\n }\n } catch (e) {\n // ignore parse errors\n }\n }\n\n // Publish action\n function publish(collection, id) {\n if (pendingSavePromise) {\n pendingSavePromise.then(function() { publish(collection, id); });\n return;\n }\n\n publishBtn.disabled = true;\n publishBtn.textContent = toolbarLabels.publishing;\n\n ecFetch(\"/_emdash/api/visual-editing/content/\" + encodeURIComponent(collection) + \"/\" + encodeURIComponent(id) + \"/publish\", {\n method: \"POST\",\n credentials: \"same-origin\",\n headers: { \"X-EmDash-Visual-Action\": visualActionToken },\n })\n .then(function(res) {\n if (res.ok) {\n if (document.startViewTransition) {\n document.startViewTransition(function() { location.reload(); });\n } else {\n location.reload();\n }\n } else {\n if (res.status === 401) {\n showVisualActionRecovery();\n return;\n }\n return res.json().catch(function() { return null; }).then(function(body) {\n if (body && body.error && body.error.code === visualActionTokenErrorCode) {\n showVisualActionRecovery();\n return;\n }\n showPublishError(body && body.error && body.error.message);\n console.error(\"Publish failed:\", res.status);\n });\n }\n })\n .catch(function(err) {\n publishBtn.disabled = false;\n publishBtn.textContent = toolbarLabels.publish;\n console.error(\"Publish failed:\", err);\n });\n }\n\n // Edit mode toggle\n toggle.addEventListener(\"change\", function() {\n if (toggle.checked) {\n document.cookie = \"emdash-edit-mode=true;path=/;samesite=lax\";\n } else {\n document.cookie = \"emdash-edit-mode=;path=/;expires=Thu, 01 Jan 1970 00:00:00 GMT\";\n }\n\n if (document.startViewTransition) {\n document.startViewTransition(function() { location.replace(location.href); });\n } else {\n location.replace(location.href);\n }\n });\n\n // --- Inline editing ---\n\n // Cached manifest (fetched once on first edit click)\n var manifestCache = null;\n var manifestPromise = null;\n\n function fetchManifest() {\n if (manifestCache) return Promise.resolve(manifestCache);\n if (manifestPromise) return manifestPromise;\n manifestPromise = ecFetch(\"/_emdash/api/manifest\", { credentials: \"same-origin\" })\n .then(function(r) { return r.json(); })\n .then(function(m) {\n // The manifest endpoint wraps the payload in a { success, data } envelope (ApiResponse shape).\n // Unwrap it so getFieldKind can read manifest.collections directly.\n manifestCache = m && m.data ? m.data : m;\n return manifestCache;\n });\n return manifestPromise;\n }\n\n function getFieldKind(manifest, collection, field) {\n var col = manifest.collections && manifest.collections[collection];\n if (!col || !col.fields) return null;\n var f = col.fields[field];\n return f ? f.kind : null;\n }\n\n // Load manifest early so the first click can resolve field kinds without racing the event.\n if (isEditMode) {\n fetchManifest();\n }\n\n // Save a single field value. Never rejects: resolves to whether the save\n // succeeded, after the save badge already shows the outcome.\n function saveField(collection, id, field, value) {\n setSaveState(\"saving\");\n return ecFetch(\"/_emdash/api/content/\" + encodeURIComponent(collection) + \"/\" + encodeURIComponent(id), {\n method: \"PUT\",\n credentials: \"same-origin\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ data: { [field]: value } }),\n })\n .then(function(res) {\n if (res.ok) {\n setSaveState(\"saved\");\n // A save creates/updates a draft — show unpublished changes\n showUnpublishedChanges(collection, id);\n return true;\n }\n setSaveState(\"error\");\n console.error(\"Save failed:\", res.status);\n return false;\n })\n .catch(function(err) {\n setSaveState(\"error\");\n console.error(\"Save failed:\", err);\n return false;\n });\n }\n\n function showUnpublishedChanges(collection, id) {\n statusEl.innerHTML = '<span class=\"emdash-tb-badge emdash-tb-badge--pending\">Unpublished changes</span>';\n publishBtn.style.display = \"\";\n publishBtn.disabled = false;\n publishBtn.textContent = \"Publish\";\n publishBtn.onclick = function() { publish(collection, id); };\n }\n\n // Plain text inline editing (contenteditable)\n var currentlyEditing = null;\n\n // Browsers add line breaks while editing as <br> or <div> elements (Shift+Enter,\n // pasted lines), which textContent drops.\n function editableText(element) {\n var text = \"\";\n (function walk(node) {\n for (var child = node.firstChild; child; child = child.nextSibling) {\n if (child.nodeType === Node.TEXT_NODE) {\n text += child.data;\n } else if (child.nodeName === \"BR\") {\n text += \"\\\\n\";\n } else {\n if (child.nodeName === \"DIV\" && text && text.slice(-1) !== \"\\\\n\") text += \"\\\\n\";\n walk(child);\n }\n }\n })(element);\n return text;\n }\n\n function startTextEdit(element, annotation, multiline) {\n if (currentlyEditing === element) return;\n if (currentlyEditing) endCurrentEdit();\n\n // Line breaks only belong in multi-line fields.\n function readText() {\n return multiline ? editableText(element) : element.textContent || \"\";\n }\n\n currentlyEditing = element;\n var originalText = readText();\n\n element.setAttribute(\"data-emdash-editing\", \"\");\n element.contentEditable = \"plaintext-only\";\n element.focus();\n\n // Select all text\n var range = document.createRange();\n range.selectNodeContents(element);\n var sel = window.getSelection();\n sel.removeAllRanges();\n sel.addRange(range);\n\n // Track dirty state via input events\n function handleInput() {\n var current = readText().trim();\n if (current !== originalText.trim()) {\n setSaveState(\"unsaved\");\n } else {\n setSaveState(\"idle\");\n }\n }\n\n function handleBlur() {\n element.removeEventListener(\"blur\", handleBlur);\n element.removeEventListener(\"keydown\", handleKeydown);\n element.removeEventListener(\"input\", handleInput);\n element.contentEditable = \"false\";\n element.removeAttribute(\"data-emdash-editing\");\n currentlyEditing = null;\n\n var newValue = readText().trim();\n if (newValue !== originalText.trim()) {\n pendingSavePromise = saveField(annotation.collection, annotation.id, annotation.field, newValue).then(function() {\n pendingSavePromise = null;\n }, function() {\n pendingSavePromise = null;\n });\n } else {\n setSaveState(\"idle\");\n }\n }\n\n function handleKeydown(e) {\n if (e.key === \"Enter\" && !e.shiftKey) {\n e.preventDefault();\n element.blur();\n }\n if (e.key === \"Escape\") {\n element.textContent = originalText;\n setSaveState(\"idle\");\n element.blur();\n }\n }\n\n element.addEventListener(\"input\", handleInput);\n element.addEventListener(\"blur\", handleBlur);\n element.addEventListener(\"keydown\", handleKeydown);\n }\n\n function endCurrentEdit() {\n if (currentlyEditing) {\n currentlyEditing.blur();\n }\n }\n\n // Text fields are often rendered transformed (Markdown to HTML, truncated\n // excerpts). Saving the page text over the stored value would lose content,\n // so they are edited in place only when the page shows the stored text.\n function startTextEditIfShownAsStored(element, annotation) {\n // Rendered markup means the text was transformed. Open the admin before the\n // lookup, while the click still lets popup blockers allow window.open().\n if (element.children.length > 0) {\n openAdmin(annotation);\n return;\n }\n ecFetch(\"/_emdash/api/content/\" + encodeURIComponent(annotation.collection) + \"/\" + encodeURIComponent(annotation.id), {\n credentials: \"same-origin\"\n })\n .then(function(r) { return r.json(); })\n .then(function(body) {\n var item = body && body.data && body.data.item;\n var stored = item && item.data ? item.data[annotation.field] : null;\n if (typeof stored === \"string\" && stored.trim() === (element.textContent || \"\").trim()) {\n startTextEdit(element, annotation, true);\n } else {\n openAdmin(annotation);\n }\n })\n .catch(function() {\n openAdmin(annotation);\n });\n }\n\n // Fallback: open admin\n function openAdmin(annotation) {\n var url = \"/_emdash/admin/content/\" + encodeURIComponent(annotation.collection) + \"/\" + encodeURIComponent(annotation.id);\n if (annotation.field) {\n url += \"?field=\" + encodeURIComponent(annotation.field);\n }\n window.open(url, \"emdash-admin\");\n }\n\n // --- Inline image editing ---\n var activeImagePopover = null;\n\n function closeImagePopover() {\n if (activeImagePopover) {\n activeImagePopover.backdrop.remove();\n activeImagePopover.popover.remove();\n if (activeImagePopover.escapeHandler) {\n document.removeEventListener(\"keydown\", activeImagePopover.escapeHandler);\n }\n activeImagePopover = null;\n }\n }\n\n function startImageEdit(element, annotation) {\n closeImagePopover();\n\n // Find the current image value by fetching the entry\n var collection = annotation.collection;\n var id = annotation.id;\n var field = annotation.field;\n\n // Find img element inside the annotated container (or the element itself if it's an img)\n var imgEl = element.tagName === \"IMG\" ? element : element.querySelector(\"img\");\n\n // Fetch current field value from the content API\n ecFetch(\"/_emdash/api/content/\" + encodeURIComponent(collection) + \"/\" + encodeURIComponent(id), {\n credentials: \"same-origin\"\n })\n .then(function(r) { return r.json(); })\n .then(function(body) {\n if (!body || !body.success) throw new Error(\"Failed to load entry\");\n showImagePopover(element, imgEl, annotation, body.data.item.data[field]);\n })\n .catch(function() {\n // If fetch fails, still show popover with what we can infer from DOM\n showImagePopover(element, imgEl, annotation, null);\n });\n }\n\n function showImagePopover(element, imgEl, annotation, currentValue) {\n closeImagePopover();\n\n var collection = annotation.collection;\n var id = annotation.id;\n var field = annotation.field;\n\n // Position near the element\n var rect = element.getBoundingClientRect();\n var viewportH = window.innerHeight;\n var viewportW = window.innerWidth;\n\n // Create backdrop for click-outside-to-close\n var backdrop = document.createElement(\"div\");\n backdrop.className = \"emdash-img-popover-backdrop\";\n backdrop.addEventListener(\"click\", function(e) {\n if (e.target === backdrop) closeImagePopover();\n });\n\n // Create popover\n var popover = document.createElement(\"div\");\n popover.className = \"emdash-img-popover\";\n\n // Local images are stored without a URL (the site builds it at render\n // time), so preview what the page shows when the value carries none.\n var currentSrc = (currentValue && (currentValue.previewUrl || currentValue.src)) || (imgEl ? imgEl.src : null);\n var currentAlt = currentValue ? (currentValue.alt || \"\") : (imgEl ? (imgEl.alt || \"\") : \"\");\n\n // Build popover HTML\n var html = '';\n html += '<div class=\"emdash-img-popover-header\">';\n html += ' <span class=\"emdash-img-popover-title\">Image</span>';\n html += ' <button class=\"emdash-img-popover-close\" data-action=\"close\">&times;</button>';\n html += '</div>';\n html += '<div class=\"emdash-img-popover-body\" id=\"emdash-img-main\">';\n\n if (currentSrc) {\n html += '<img class=\"emdash-img-preview\" src=\"' + escapeAttr(currentSrc) + '\" alt=\"\" />';\n } else {\n html += '<div class=\"emdash-img-empty\">No image selected</div>';\n }\n\n html += '<div class=\"emdash-img-field\">';\n html += ' <label for=\"emdash-img-alt\">Alt text</label>';\n html += ' <input type=\"text\" id=\"emdash-img-alt\" value=\"' + escapeAttr(currentAlt) + '\" placeholder=\"Describe the image\" />';\n html += '</div>';\n\n html += '<div class=\"emdash-img-actions\">';\n html += ' <button class=\"emdash-img-btn emdash-img-btn--primary\" data-action=\"browse\">Replace</button>';\n html += ' <label class=\"emdash-img-btn\" style=\"cursor:pointer\">';\n html += ' Upload';\n html += ' <input type=\"file\" accept=\"image/*\" id=\"emdash-img-upload\" style=\"display:none\" />';\n html += ' </label>';\n if (currentSrc) {\n html += ' <button class=\"emdash-img-btn emdash-img-btn--danger\" data-action=\"remove\">Remove</button>';\n }\n html += '</div>';\n html += '</div>';\n\n popover.innerHTML = html;\n\n backdrop.appendChild(popover);\n document.body.appendChild(backdrop);\n\n // Position the popover\n positionPopover(popover, rect, viewportW, viewportH);\n\n // Escape key handler\n function handleEscape(e) {\n if (e.key === \"Escape\") {\n closeImagePopover();\n document.removeEventListener(\"keydown\", handleEscape);\n }\n }\n document.addEventListener(\"keydown\", handleEscape);\n\n activeImagePopover = {\n backdrop: backdrop,\n popover: popover,\n annotation: annotation,\n currentValue: currentValue,\n element: element,\n imgEl: imgEl,\n escapeHandler: handleEscape\n };\n\n // Event handlers\n popover.querySelector('[data-action=\"close\"]').addEventListener(\"click\", closeImagePopover);\n\n popover.querySelector('[data-action=\"browse\"]').addEventListener(\"click\", function() {\n showMediaBrowser(popover, annotation, currentValue, element, imgEl);\n });\n\n var uploadInput = popover.querySelector(\"#emdash-img-upload\");\n uploadInput.addEventListener(\"change\", function(e) {\n var file = e.target.files && e.target.files[0];\n if (file) handleImageUpload(file, popover, annotation, currentValue, element, imgEl);\n });\n\n var removeBtn = popover.querySelector('[data-action=\"remove\"]');\n if (removeBtn) {\n removeBtn.addEventListener(\"click\", function() {\n saveField(collection, id, field, null).then(function(saved) {\n if (saved && imgEl) {\n imgEl.style.display = \"none\";\n }\n closeImagePopover();\n });\n });\n }\n\n // Save alt text on change (debounced)\n var altInput = popover.querySelector(\"#emdash-img-alt\");\n var altTimer = null;\n altInput.addEventListener(\"input\", function() {\n clearTimeout(altTimer);\n altTimer = setTimeout(function() {\n var newAlt = altInput.value;\n if (currentValue) {\n var updated = Object.assign({}, currentValue, { alt: newAlt });\n saveField(collection, id, field, updated).then(function(saved) {\n if (saved && imgEl) imgEl.alt = newAlt;\n });\n }\n }, 500);\n });\n\n // Handle drag and drop on the popover body\n var body = popover.querySelector(\".emdash-img-popover-body\");\n body.addEventListener(\"dragover\", function(e) {\n e.preventDefault();\n body.classList.add(\"emdash-img-drop\");\n });\n body.addEventListener(\"dragleave\", function() {\n body.classList.remove(\"emdash-img-drop\");\n });\n body.addEventListener(\"drop\", function(e) {\n e.preventDefault();\n body.classList.remove(\"emdash-img-drop\");\n var file = e.dataTransfer && e.dataTransfer.files && e.dataTransfer.files[0];\n if (file && file.type.startsWith(\"image/\")) {\n handleImageUpload(file, popover, annotation, currentValue, element, imgEl);\n }\n });\n }\n\n function positionPopover(popover, targetRect, viewportW, viewportH) {\n var popoverW = 320;\n var gap = 8;\n\n // Try to place to the right of the element\n var left = targetRect.right + gap;\n var top = targetRect.top;\n\n // If it overflows right, place to the left\n if (left + popoverW > viewportW - 16) {\n left = targetRect.left - popoverW - gap;\n }\n // If it still overflows (narrow viewport), center below\n if (left < 16) {\n left = Math.max(16, (viewportW - popoverW) / 2);\n top = targetRect.bottom + gap;\n }\n // Clamp vertically\n if (top + 400 > viewportH - 80) { // 80 for toolbar\n top = Math.max(16, viewportH - 480);\n }\n if (top < 16) top = 16;\n\n popover.style.left = left + \"px\";\n popover.style.top = top + \"px\";\n }\n\n function escapeAttr(str) {\n return String(str || \"\").replace(/&/g, \"&amp;\").replace(/\"/g, \"&quot;\").replace(/</g, \"&lt;\").replace(/>/g, \"&gt;\");\n }\n\n function showMediaBrowser(popover, annotation, currentValue, element, imgEl) {\n var mainBody = popover.querySelector(\"#emdash-img-main\");\n if (mainBody) mainBody.style.display = \"none\";\n\n // Remove existing browser if any\n var existing = popover.querySelector(\".emdash-img-browser\");\n if (existing) existing.remove();\n\n var browser = document.createElement(\"div\");\n browser.className = \"emdash-img-browser\";\n\n browser.innerHTML = '<div class=\"emdash-img-browser-header\">' +\n '<span class=\"emdash-img-browser-title\">Media Library</span>' +\n '<button class=\"emdash-img-browser-back\">Back</button>' +\n '</div>' +\n '<div class=\"emdash-img-loading\">Loading\\u2026</div>';\n\n popover.appendChild(browser);\n\n browser.querySelector(\".emdash-img-browser-back\").addEventListener(\"click\", function() {\n browser.remove();\n if (mainBody) mainBody.style.display = \"\";\n });\n\n // Fetch media\n ecFetch(\"/_emdash/api/media?mimeType=image/&limit=30\", { credentials: \"same-origin\" })\n .then(function(r) { return r.json(); })\n .then(function(body) {\n if (!body || !body.success) throw new Error((body && body.error && body.error.message) || \"Failed to load media\");\n var items = body.data.items || [];\n var loadingEl = browser.querySelector(\".emdash-img-loading\");\n if (loadingEl) loadingEl.remove();\n\n if (items.length === 0) {\n var empty = document.createElement(\"div\");\n empty.className = \"emdash-img-loading\";\n empty.textContent = \"No images found\";\n browser.appendChild(empty);\n return;\n }\n\n var grid = document.createElement(\"div\");\n grid.className = \"emdash-img-grid\";\n\n items.forEach(function(item) {\n var thumb = document.createElement(\"div\");\n thumb.className = \"emdash-img-grid-item\";\n if (currentValue && currentValue.id === item.id) {\n thumb.classList.add(\"emdash-img-grid-item--selected\");\n }\n var thumbUrl = item.url || item.previewUrl || (\"/_emdash/api/media/file/\" + item.storageKey);\n thumb.innerHTML = '<img src=\"' + escapeAttr(thumbUrl) + '\" alt=\"' + escapeAttr(item.alt || item.filename || \"\") + '\" loading=\"lazy\" />';\n\n thumb.addEventListener(\"click\", function() {\n selectMediaItem(item, annotation, currentValue, element, imgEl);\n });\n\n grid.appendChild(thumb);\n });\n\n browser.appendChild(grid);\n })\n .catch(function(err) {\n var loadingEl = browser.querySelector(\".emdash-img-loading\");\n if (loadingEl) loadingEl.textContent = \"Failed to load media\";\n console.error(\"Media fetch error:\", err);\n });\n }\n\n function selectMediaItem(item, annotation, currentValue, element, imgEl) {\n var collection = annotation.collection;\n var id = annotation.id;\n var field = annotation.field;\n\n var isLocal = !item.provider || item.provider === \"local\";\n var itemUrl = item.url || item.previewUrl || (\"/_emdash/api/media/file/\" + item.storageKey);\n\n var newValue = {\n id: item.id,\n provider: item.provider || \"local\",\n src: isLocal ? itemUrl : undefined,\n previewUrl: isLocal ? undefined : itemUrl,\n alt: item.alt || \"\",\n width: item.width,\n height: item.height,\n focalX: item.focalX == null ? undefined : item.focalX,\n focalY: item.focalY == null ? undefined : item.focalY,\n meta: item.meta,\n // The save replaces the whole field, so a dark variant not sent is deleted.\n darkVariant: currentValue ? currentValue.darkVariant : undefined\n };\n\n // Clean undefined fields\n Object.keys(newValue).forEach(function(k) {\n if (newValue[k] === undefined) delete newValue[k];\n });\n\n saveField(collection, id, field, newValue).then(function(saved) {\n // Update the image in the DOM\n if (saved && imgEl) {\n replacePageImageSource(imgEl, itemUrl);\n imgEl.alt = item.alt || \"\";\n imgEl.style.display = \"\";\n }\n closeImagePopover();\n });\n }\n\n // The rendered srcset/sizes (and any <picture> sources) still describe the\n // previous media and take precedence over src, so they have to go. The next\n // server render restores responsive variants for the new image.\n function replacePageImageSource(img, url) {\n var picture = img.parentElement;\n if (picture && picture.tagName === \"PICTURE\") {\n Array.prototype.forEach.call(picture.querySelectorAll(\"source\"), function(source) {\n source.removeAttribute(\"srcset\");\n source.removeAttribute(\"sizes\");\n });\n }\n img.removeAttribute(\"srcset\");\n img.removeAttribute(\"sizes\");\n img.src = url;\n }\n\n function handleImageUpload(file, popover, annotation, currentValue, element, imgEl) {\n var collection = annotation.collection;\n var id = annotation.id;\n var field = annotation.field;\n\n // Show uploading state\n var mainBody = popover.querySelector(\"#emdash-img-main\");\n var browserEl = popover.querySelector(\".emdash-img-browser\");\n if (browserEl) browserEl.remove();\n if (mainBody) {\n mainBody.innerHTML = '<div class=\"emdash-img-uploading\">' +\n '<span>Uploading ' + escapeAttr(file.name) + '\\u2026</span>' +\n '</div>';\n mainBody.style.display = \"\";\n }\n\n // Detect dimensions before upload\n var dimPromise = new Promise(function(resolve) {\n if (!file.type.startsWith(\"image/\")) return resolve({});\n var img = new Image();\n img.onload = function() {\n resolve({ width: img.naturalWidth, height: img.naturalHeight });\n URL.revokeObjectURL(img.src);\n };\n img.onerror = function() {\n resolve({});\n URL.revokeObjectURL(img.src);\n };\n img.src = URL.createObjectURL(file);\n });\n\n dimPromise.then(function(dims) {\n // Generate a thumbnail for large images to avoid OOM in server-side\n // blurhash generation on memory-constrained runtimes (Workers).\n // Thumbnail fits within a 64x64 box (scale by max dimension) so that\n // extreme aspect ratios don't explode into a huge canvas client-side.\n var thumbPromise;\n if (dims.width && dims.height && dims.width * dims.height * 4 > 32 * 1024 * 1024) {\n thumbPromise = new Promise(function(resolve) {\n try {\n var maxDim = Math.max(dims.width, dims.height);\n var scale = Math.min(1, 64 / maxDim);\n var thumbW = Math.max(1, Math.round(dims.width * scale));\n var thumbH = Math.max(1, Math.round(dims.height * scale));\n var canvas = document.createElement(\"canvas\");\n canvas.width = thumbW;\n canvas.height = thumbH;\n var ctx = canvas.getContext(\"2d\");\n if (ctx) {\n var img = new Image();\n img.onload = function() {\n try {\n ctx.drawImage(img, 0, 0, thumbW, thumbH);\n canvas.toBlob(function(blob) {\n URL.revokeObjectURL(img.src);\n resolve(blob);\n }, \"image/png\");\n } catch (e) {\n URL.revokeObjectURL(img.src);\n resolve(null);\n }\n };\n img.onerror = function() {\n URL.revokeObjectURL(img.src);\n resolve(null);\n };\n img.src = URL.createObjectURL(file);\n } else {\n resolve(null);\n }\n } catch (e) {\n resolve(null);\n }\n });\n } else {\n thumbPromise = Promise.resolve(null);\n }\n\n return thumbPromise.then(function(thumbnail) {\n var formData = new FormData();\n formData.append(\"file\", file);\n if (dims.width) formData.append(\"width\", String(dims.width));\n if (dims.height) formData.append(\"height\", String(dims.height));\n if (thumbnail) formData.append(\"thumbnail\", thumbnail, \"thumb.png\");\n\n return ecFetch(\"/_emdash/api/media\", {\n method: \"POST\",\n credentials: \"same-origin\",\n body: formData\n });\n });\n })\n .then(function(r) { return r.json(); })\n .then(function(body) {\n var item = body && body.success && body.data && body.data.item;\n if (!item) throw new Error((body && body.error && body.error.message) || \"Upload failed\");\n selectMediaItem(item, annotation, currentValue, element, imgEl);\n })\n .catch(function(err) {\n console.error(\"Upload error:\", err);\n setSaveState(\"error\");\n closeImagePopover();\n });\n }\n\n // Click handler for edit mode\n if (isEditMode) {\n document.addEventListener(\"click\", function(e) {\n var target = e.target;\n\n // Clicks inside the field being edited only move the caret; cancel them so\n // a link wrapping the field isn't followed.\n if (target.closest && target.closest(\"[data-emdash-editing]\")) {\n e.preventDefault();\n return;\n }\n\n // Walk up to find annotated element\n while (target && target !== document.body) {\n var ref = target.getAttribute && target.getAttribute(\"data-emdash-ref\");\n if (ref) {\n try {\n var annotation = JSON.parse(ref);\n\n // Entry-level annotation (no field) — keep walking for a field-level ancestor\n if (!annotation.field) {\n target = target.parentElement;\n continue;\n }\n\n function dispatchInline(kind) {\n closeImagePopover();\n // Portable Text is edited in-page by InlinePortableTextEditor — do not open admin\n if (kind === \"portableText\") {\n return;\n }\n e.preventDefault();\n e.stopPropagation();\n if (kind === \"string\" || kind === \"text\") {\n startTextEdit(target, annotation);\n } else if (kind === \"richText\") {\n startTextEditIfShownAsStored(target, annotation);\n } else if (kind === \"image\") {\n startImageEdit(target, annotation);\n } else {\n openAdmin(annotation);\n }\n }\n\n if (manifestCache) {\n dispatchInline(getFieldKind(manifestCache, annotation.collection, annotation.field));\n } else {\n // The click can only be cancelled now, so a link wrapping the field\n // isn't followed while the manifest loads.\n e.preventDefault();\n fetchManifest().then(function(manifest) {\n dispatchInline(getFieldKind(manifest, annotation.collection, annotation.field));\n });\n }\n } catch (err) {\n console.error(\"Failed to parse emdash ref:\", err);\n }\n return;\n }\n target = target.parentElement;\n }\n }, true);\n }\n\n updateStatus();\n})();\n</script>\n`;\n}\n","/**\n * EmDash Request Context Middleware\n *\n * Sets up AsyncLocalStorage-based request context for query functions.\n * Skips ALS entirely for logged-out users with no CMS signals (fast path).\n *\n * Handles:\n * - Preview tokens: _preview query param with signed HMAC token\n * - Edit mode: emdash-edit-mode cookie (for visual editing)\n * - Toolbar injection: floating pill for authenticated editors\n * - Client toolbar mode (`toolbar: \"client\"`): cache-identical HTML with a\n * client-side bootstrap pill and an `_edit` query param for fresh editor\n * renders; the backend verifies the `_edit` param and redirects non-editors\n */\n\nimport { loadVisualEditingToolbarLabels } from \"@emdash-cms/admin/locales/server\";\nimport type { APIContext } from \"astro\";\nimport { defineMiddleware } from \"astro:middleware\";\n// @ts-ignore - virtual module\nimport virtualConfig from \"virtual:emdash/config\";\n\nimport { resolveSecretsCached } from \"#config/secrets.js\";\n\nimport { verifyPreviewToken, parseContentId } from \"../../preview/tokens.js\";\nimport { getRequestContext, runWithContext } from \"../../request-context.js\";\nimport { generateVisualEditingActionToken } from \"../../visual-editing/action-token.js\";\nimport { EDIT_PARAM, renderToolbarBootstrap } from \"../../visual-editing/toolbar-bootstrap.js\";\nimport { renderToolbar } from \"../../visual-editing/toolbar.js\";\n\ntype ToolbarMode = \"server\" | \"client\" | false;\n\nconst toolbarMode: ToolbarMode = virtualConfig?.toolbar ?? \"server\";\n\n/**\n * Astro's route-cache handle. Astro defines `context.cache` only on requests\n * that went through its cache handler, so it is `undefined` on some renders,\n * such as the 404 page for a URL that matches no route.\n */\ntype RouteCache = APIContext[\"cache\"] | undefined;\n\nasync function renderEditorToolbar(\n\tcontext: APIContext,\n\tconfig: { editMode: boolean; isPreview: boolean },\n): Promise<string> {\n\tconst labels = await loadVisualEditingToolbarLabels(context.request);\n\tconst { emdash, user } = context.locals;\n\tif (!emdash?.db || !user) return renderToolbar({ ...config, labels });\n\tconst { previewSecret } = await resolveSecretsCached(emdash.db);\n\tconst actionToken = await generateVisualEditingActionToken(previewSecret, user.id);\n\treturn renderToolbar({ ...config, actionToken, labels });\n}\n\n/**\n * Opt the current request out of Astro's route cache (e.g. Workers Cache on\n * Cloudflare). `Cache-Control` headers do NOT cover this: the adapter derives\n * the shared-cache TTL from the route-cache options (on Cloudflare via\n * `Cloudflare-CDN-Cache-Control`), so session-specific responses must\n * explicitly disable it or they get stored in the shared cache and served to\n * anonymous visitors without ever invoking the middleware again. With no cache\n * provider configured, or no cache handle on the request, this is a no-op.\n */\nfunction optOutOfRouteCache(cache: RouteCache): void {\n\tcache?.set(false);\n}\n\n/**\n * Inject HTML before `</body>` if the response is an HTML page with a body\n * end tag. Does not touch cache headers — callers decide whether the result\n * is still shareable. `injected` tells the caller whether anything changed.\n */\nasync function injectBeforeBodyEnd(\n\tresponse: Response,\n\thtmlToInject: string,\n): Promise<{ response: Response; injected: boolean }> {\n\tconst contentType = response.headers.get(\"content-type\");\n\tif (!contentType?.includes(\"text/html\")) return { response, injected: false };\n\n\tconst html = await response.text();\n\tif (!html.includes(\"</body>\")) {\n\t\t// Body already consumed — rebuild the response unchanged.\n\t\treturn { response: new Response(html, response), injected: false };\n\t}\n\n\tconst injected = html.replace(\"</body>\", `${htmlToInject}</body>`);\n\treturn {\n\t\tresponse: new Response(injected, {\n\t\t\tstatus: response.status,\n\t\t\theaders: response.headers,\n\t\t}),\n\t\tinjected: true,\n\t};\n}\n\n/**\n * Inject toolbar HTML into a response if it's an HTML page.\n * Returns the original response if not HTML.\n */\nasync function injectToolbar(\n\tresponse: Response,\n\ttoolbarHtml: string,\n\trouteCache: RouteCache,\n): Promise<Response> {\n\tconst result = await injectBeforeBodyEnd(response, toolbarHtml);\n\tif (result.injected) {\n\t\t// Toolbar-injected HTML is session-specific (its presence reveals an\n\t\t// active editor session); it must never be stored in a shared CDN cache\n\t\t// and served to anonymous visitors. `Cache-Control` covers\n\t\t// browsers/downstream proxies; the\n\t\t// route-cache opt-out covers the shared edge cache, which ignores\n\t\t// `Cache-Control`.\n\t\tresult.response.headers.set(\"Cache-Control\", \"private, no-store\");\n\t\toptOutOfRouteCache(routeCache);\n\t}\n\treturn result.response;\n}\n\n/**\n * Inject the client-toolbar bootstrap script. Identical for every visitor, so\n * cache headers and route-cache options are left untouched and the response\n * stays fully shareable.\n */\nasync function injectBootstrap(response: Response): Promise<Response> {\n\tconst result = await injectBeforeBodyEnd(response, renderToolbarBootstrap());\n\treturn result.response;\n}\n\n/**\n * Redirect an `_edit` URL to its canonical form (same URL without the param).\n * Applied when the requester is not an authenticated editor, so a shared\n * `?_edit` link degrades gracefully for everyone else.\n */\nfunction redirectToCanonical(url: URL): Response {\n\tconst canonical = new URL(url);\n\tcanonical.searchParams.delete(EDIT_PARAM);\n\treturn new Response(null, {\n\t\tstatus: 302,\n\t\theaders: {\n\t\t\tLocation: canonical.pathname + canonical.search + canonical.hash,\n\t\t\t// Header-following caches (Fastly, Varnish, browsers) must not store\n\t\t\t// the redirect — a cached 302 would bounce editors back to the\n\t\t\t// canonical URL. The route-cache opt-out at the call site covers the\n\t\t\t// Workers Cache, which ignores Cache-Control.\n\t\t\t\"Cache-Control\": \"private, no-store\",\n\t\t},\n\t});\n}\n\nexport const onRequest = defineMiddleware(async (context, next) => {\n\tconst { cookies, url } = context;\n\n\t// Skip /_emdash routes (admin has its own UI, no rendering context needed)\n\tif (url.pathname.startsWith(\"/_emdash\")) {\n\t\treturn next();\n\t}\n\n\t// Check for authenticated editor (role >= 30)\n\tconst { user } = context.locals;\n\tconst isEditor = !!user && user.role >= 30;\n\n\t// Playground mode: the playground middleware (from @emdash-cms/cloudflare) stashes\n\t// the per-session DO database on locals.__playgroundDb. We set it via ALS here\n\t// (same module instance as the loader) so getDb() picks it up correctly.\n\t//\n\t// `dbIsIsolated: true` tells schema-derived caches (manifest, taxonomy defs,\n\t// byline/term existence probes) to bypass module-scope memoization — each\n\t// playground session is its own database with its own schema, so a cached\n\t// value from another session would be wrong.\n\tconst playgroundDb = context.locals.__playgroundDb;\n\tif (playgroundDb) {\n\t\t// Check if playground user has toggled edit mode on\n\t\tconst hasEditCookie = cookies.get(\"emdash-edit-mode\")?.value === \"true\";\n\t\treturn runWithContext(\n\t\t\t{ editMode: hasEditCookie, db: playgroundDb, dbIsIsolated: true },\n\t\t\tasync () => {\n\t\t\t\tconst response = await next();\n\t\t\t\tif (!hasEditCookie || toolbarMode === false) return response;\n\t\t\t\t// The Playground shows its own bar, so the editor toolbar is hidden and\n\t\t\t\t// only provides inline editing.\n\t\t\t\tconst labels = await loadVisualEditingToolbarLabels(context.request);\n\t\t\t\tconst toolbarHtml = renderToolbar({\n\t\t\t\t\teditMode: true,\n\t\t\t\t\tisPreview: false,\n\t\t\t\t\tlabels,\n\t\t\t\t\thidden: true,\n\t\t\t\t});\n\t\t\t\treturn injectToolbar(response, toolbarHtml, context.cache);\n\t\t\t},\n\t\t);\n\t}\n\n\t// Fast path: check for CMS signals before doing any work\n\tconst hasEditCookie = cookies.get(\"emdash-edit-mode\")?.value === \"true\";\n\tconst hasPreviewToken = url.searchParams.has(\"_preview\");\n\t// `_edit` requests a fresh (never cached) editor render; only meaningful in\n\t// client toolbar mode where public HTML is otherwise identical for everyone.\n\tconst hasEditParam = toolbarMode === \"client\" && url.searchParams.has(EDIT_PARAM);\n\n\tif (hasEditParam) {\n\t\t// `_edit` URLs are their own cache key. Never store them in the route\n\t\t// cache — a cached anonymous redirect would bounce editors back to the\n\t\t// canonical URL, and a cached editor render must never be shared.\n\t\toptOutOfRouteCache(context.cache);\n\n\t\t// A non-editor (anonymous, logged-out, or insufficient role) opening an\n\t\t// `_edit` URL is sent to the canonical URL — shared `?_edit` links\n\t\t// degrade gracefully and never prime a cache entry with page content.\n\t\tif (!isEditor) {\n\t\t\treturn redirectToCanonical(url);\n\t\t}\n\t}\n\n\t// No CMS signals and not an editor → skip everything (zero overhead in\n\t// server mode; client mode injects the identical-for-everyone bootstrap)\n\tif (!hasEditCookie && !hasPreviewToken && !isEditor) {\n\t\tif (toolbarMode === \"client\") {\n\t\t\treturn injectBootstrap(await next());\n\t\t}\n\t\treturn next();\n\t}\n\n\t// Determine edit mode: cookie AND authenticated editor\n\tconst editMode = hasEditCookie && isEditor;\n\n\t// Read locale from Astro's i18n routing\n\t// eslint-disable-next-line typescript/no-unsafe-type-assertion -- Astro context includes currentLocale when i18n is configured\n\tconst locale = (context as { currentLocale?: string }).currentLocale;\n\n\tconst routeCache = context.cache;\n\n\t// Verify preview token if present.\n\t// The preview secret is resolved via `resolveSecretsCached`: env wins,\n\t// otherwise a DB-stored value is read (or generated on first need).\n\t// `emdash.db` is set by the runtime middleware which runs first; the\n\t// only path where it's missing is a runtime-init failure.\n\tlet preview: { collection: string; id: string } | undefined;\n\tif (hasPreviewToken) {\n\t\tconst db = context.locals.emdash?.db;\n\t\tif (db) {\n\t\t\tconst { previewSecret } = await resolveSecretsCached(db);\n\t\t\tconst result = await verifyPreviewToken({ url, secret: previewSecret });\n\t\t\tif (result.valid) {\n\t\t\t\tconst { collection, id } = parseContentId(result.payload.cid);\n\t\t\t\tpreview = { collection, id };\n\t\t\t}\n\t\t} else {\n\t\t\tconsole.warn(\n\t\t\t\t\"[emdash] Preview token present but EmDash runtime not initialized; preview disabled.\",\n\t\t\t);\n\t\t}\n\t}\n\n\t// If we have CMS signals, wrap in ALS context\n\tconst needsContext = hasEditCookie || hasPreviewToken;\n\n\tif (needsContext) {\n\t\t// Merge with any outer ALS context (e.g. the per-request D1 session db\n\t\t// set by the runtime middleware). `storage.run()` replaces the store\n\t\t// wholesale, so without the spread the outer `db` would be lost and\n\t\t// loaders would fall back to the singleton non-session dialect.\n\t\tconst parent = getRequestContext();\n\t\treturn runWithContext({ ...parent, editMode, preview, locale }, async () => {\n\t\t\tlet response = await next();\n\n\t\t\t// Preview responses must not be cached -- draft content could leak past token expiry.\n\t\t\t// Clone the response before modifying headers — the original may be immutable.\n\t\t\t// `Cache-Control` only governs browsers/downstream proxies; the shared\n\t\t\t// edge cache follows the route-cache options, so opt out of those too —\n\t\t\t// otherwise the draft response is stored in the shared cache and served\n\t\t\t// on cache hits without token verification until TTL/purge. Opt out for\n\t\t\t// any request carrying a `_preview` param (valid or not): those URLs are\n\t\t\t// per-token, so cached copies are useless at best and drafts at worst.\n\t\t\tif (hasPreviewToken) {\n\t\t\t\toptOutOfRouteCache(routeCache);\n\t\t\t}\n\t\t\tif (preview) {\n\t\t\t\tresponse = new Response(response.body, response);\n\t\t\t\tresponse.headers.set(\"Cache-Control\", \"private, no-store\");\n\t\t\t}\n\n\t\t\t// Inject toolbar for authenticated editors. Preview and edit-mode\n\t\t\t// responses are session-specific (`private, no-store` + route-cache\n\t\t\t// opt-out) in every toolbar mode, so the server toolbar is safe to\n\t\t\t// inject here even in client mode.\n\t\t\tif (isEditor && toolbarMode !== false) {\n\t\t\t\tconst toolbarHtml = await renderEditorToolbar(context, {\n\t\t\t\t\teditMode,\n\t\t\t\t\tisPreview: !!preview,\n\t\t\t\t});\n\t\t\t\treturn injectToolbar(response, toolbarHtml, routeCache);\n\t\t\t}\n\n\t\t\t// Stale edit cookie without a session (client mode): still serve the\n\t\t\t// shareable bootstrap variant.\n\t\t\tif (toolbarMode === \"client\" && !isEditor && !preview) {\n\t\t\t\treturn injectBootstrap(response);\n\t\t\t}\n\n\t\t\treturn response;\n\t\t});\n\t}\n\n\t// Editor without preview/edit-mode signals.\n\tif (isEditor) {\n\t\tif (toolbarMode === false) {\n\t\t\treturn next();\n\t\t}\n\n\t\t// Client mode: without the `_edit` param the response must stay\n\t\t// byte-identical to the anonymous variant (plus the same bootstrap\n\t\t// script), so shared caches serve one entry for everyone. The bootstrap\n\t\t// pill is the editor's entry point into the fresh `_edit` render.\n\t\tif (toolbarMode === \"client\" && !hasEditParam) {\n\t\t\treturn injectBootstrap(await next());\n\t\t}\n\n\t\t// Server mode, or an `_edit` request in client mode: inject the full\n\t\t// toolbar (response becomes `private, no-store` and route-cache\n\t\t// opted out).\n\t\tconst response = await next();\n\t\tconst toolbarHtml = await renderEditorToolbar(context, {\n\t\t\teditMode: false,\n\t\t\tisPreview: false,\n\t\t});\n\t\treturn injectToolbar(response, toolbarHtml, routeCache);\n\t}\n\n\treturn next();\n});\n\nexport default onRequest;\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { t as getAuthMode } from "../../mode-CkmOhFqj.mjs";
1
+ import { t as getAuthMode } from "../../mode-CCuKXUci.mjs";
2
2
  import { defineMiddleware } from "astro:middleware";
3
3
 
4
4
  //#region src/astro/middleware/setup.ts
@@ -1,15 +1,15 @@
1
- import "../parse-tj9XLNO_.mjs";
2
- import "../types-CbwqGOXm.mjs";
3
- import "../types-DEHidMEk.mjs";
4
- import "../options-DAknChnw.mjs";
5
- import "../entry-lock-DqkvBC6L.mjs";
6
- import { cr as EmDashRuntime, gr as PluginContentCacheInvalidator, pr as PublishedRef } from "../config-Cw1Xz_Br.mjs";
7
- import "../runner-3gfxRsJG.mjs";
8
- import "../storage-query-CPctdMKX.mjs";
9
- import "../index-CDwKDkTq.mjs";
10
- import "../types-CCR3ivXE.mjs";
11
- import "../hreflang-BgS2FqhH.mjs";
12
- import "../validate-CyQ7I3xF.mjs";
1
+ import "../parse-CVgO-Qai.mjs";
2
+ import "../types-B7Lmsh1E.mjs";
3
+ import "../types-Cr-Kg-3D.mjs";
4
+ import "../options-SQCHQCPH.mjs";
5
+ import "../entry-lock-DVhCt49A.mjs";
6
+ import { cr as EmDashRuntime, gr as PluginContentCacheInvalidator, pr as PublishedRef } from "../config-5ii2haYu.mjs";
7
+ import "../runner-D5_LzKXI.mjs";
8
+ import "../storage-query-Bdv7A62k.mjs";
9
+ import "../index-D-hdtLe8.mjs";
10
+ import "../types-Cd-O03VG.mjs";
11
+ import "../hreflang-D5uNnsGJ.mjs";
12
+ import "../validate-CM79QXYE.mjs";
13
13
  import * as astro from "astro";
14
14
 
15
15
  //#region src/astro/middleware.d.ts
@@ -1 +1 @@
1
- {"version":3,"file":"middleware.d.mts","names":[],"sources":["../../src/astro/middleware.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;AAySA;;;;;;;;;iBAAsB,iBAAA,CACrB,OAAA;EACC,WAAA,IAAe,IAAA,EAAM,YAAA,OAAmB,OAAA;EACxC,sBAAA,GAAyB,6BAAA;AAAA,IAExB,OAAA;EAAU,SAAA,EAAW,YAAA;AAAA;;;;;;;;AAyCxB;;;;;;;;;;;;;;;;;;;;;;AAyRA;;;;;;iBAzRsB,iBAAA,GAAA,CACrB,GAAA,GAAM,OAAA,EAAS,aAAA,KAAkB,CAAA,GAAI,OAAA,CAAQ,CAAA,IAC3C,OAAA,CAAQ,CAAA;AAAA,cAuRE,SAAA,EAmeX,KAAA,CAneoB,iBAAA"}
1
+ {"version":3,"file":"middleware.d.mts","names":[],"sources":["../../src/astro/middleware.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;AAySA;;;;;;;;;iBAAsB,iBAAA,CACrB,OAAA;EACC,WAAA,IAAe,IAAA,EAAM,YAAA,OAAmB,OAAA;EACxC,sBAAA,GAAyB,6BAAA;AAAA,IAExB,OAAA;EAAU,SAAA,EAAW,YAAA;AAAA;;;;;;;;AAyCxB;;;;;;;;;;;;;;;;;;;;;;AAuSA;;;;;;iBAvSsB,iBAAA,GAAA,CACrB,GAAA,GAAM,OAAA,EAAS,aAAA,KAAkB,CAAA,GAAI,OAAA,CAAQ,CAAA,IAC3C,OAAA,CAAQ,CAAA;AAAA,cAqSE,SAAA,EAyeX,KAAA,CAzeoB,iBAAA"}