@ccslabs/xtend 0.1.0-rc.1 → 0.1.2

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 (566) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/README.md +4 -0
  3. package/catalog/component-catalog-coverage.js +2 -0
  4. package/catalog/epic13-package-export-lock.js +11 -1
  5. package/catalog/epic13-rmt-production-readiness.js +0 -1
  6. package/catalog/epic18-rmt-action-effect-runtime.d.ts +36 -0
  7. package/catalog/epic18-rmt-action-effect-runtime.js +249 -0
  8. package/catalog/epic18-rmt-app-platform-authoring.d.ts +39 -0
  9. package/catalog/epic18-rmt-app-platform-authoring.js +319 -0
  10. package/catalog/epic18-rmt-app-platform-fixture.d.ts +33 -0
  11. package/catalog/epic18-rmt-app-platform-fixture.js +221 -0
  12. package/catalog/epic18-rmt-app-platform-release-handoff.d.ts +30 -0
  13. package/catalog/epic18-rmt-app-platform-release-handoff.js +231 -0
  14. package/catalog/epic18-rmt-app-platform-tooling.d.ts +38 -0
  15. package/catalog/epic18-rmt-app-platform-tooling.js +242 -0
  16. package/catalog/epic18-rmt-component-template-primitives.d.ts +33 -0
  17. package/catalog/epic18-rmt-component-template-primitives.js +240 -0
  18. package/catalog/epic18-rmt-dom-descriptor-renderer.d.ts +35 -0
  19. package/catalog/epic18-rmt-dom-descriptor-renderer.js +232 -0
  20. package/catalog/epic18-rmt-event-routing-runtime.d.ts +35 -0
  21. package/catalog/epic18-rmt-event-routing-runtime.js +234 -0
  22. package/catalog/epic18-rmt-state-selector-runtime.d.ts +34 -0
  23. package/catalog/epic18-rmt-state-selector-runtime.js +216 -0
  24. package/catalog/epic18-rmt-surface-resource-graph-runtime.d.ts +36 -0
  25. package/catalog/epic18-rmt-surface-resource-graph-runtime.js +256 -0
  26. package/catalog/surface-manager-controller.js +5 -1
  27. package/catalog/surface-manager-materialization.js +7 -1
  28. package/catalog/surface-manager-overlay-bridge.js +41 -6
  29. package/catalog/surface-manager-workbench-fixture.js +1 -1
  30. package/catalog/surface-type-capability-matrix.d.ts +61 -0
  31. package/catalog/surface-type-capability-matrix.js +183 -0
  32. package/catalog/type-exports-rmt.js +37 -1
  33. package/catalog/type-exports.js +3 -3
  34. package/components/icon-packs/lucide.js +4 -0
  35. package/components/manifest.json +2 -0
  36. package/components/prism-rmt.d.ts +34 -0
  37. package/components/prism-rmt.js +130 -0
  38. package/components/xcards.js +15 -0
  39. package/components/xcode.d.ts +36 -1
  40. package/components/xcode.js +215 -20
  41. package/components/xfooter.js +17 -0
  42. package/components/xheader.js +14 -0
  43. package/components/xhero.js +16 -1
  44. package/components/xlink.js +97 -14
  45. package/components/xmasonry.js +15 -0
  46. package/components/xplayer.d.ts +44 -2
  47. package/components/xplayer.js +242 -15
  48. package/components/xrouter.js +27 -2
  49. package/components/xsection.js +15 -0
  50. package/components/xsidepanel.js +10 -2
  51. package/components/xsurfacemanager-controller.d.ts +2 -1
  52. package/components/xsurfacemanager-controller.js +27 -3
  53. package/components/xsurfacemanager.d.ts +2 -0
  54. package/components/xsurfacemanager.js +20 -8
  55. package/components/xsurfaceoverlay-bridge.d.ts +20 -5
  56. package/components/xsurfaceoverlay-bridge.js +114 -18
  57. package/components/xsurfaceportal.d.ts +29 -0
  58. package/components/xsurfaceportal.js +122 -0
  59. package/components/xsurfaceregion.d.ts +50 -0
  60. package/components/xsurfaceregion.js +285 -0
  61. package/components/xsurfacewindow.js +2 -1
  62. package/components/xtooltip.js +89 -23
  63. package/docs/README.md +222 -298
  64. package/docs/changelog.md +107 -0
  65. package/docs/component-catalog-coverage.md +9 -9
  66. package/docs/component-platform.md +19 -1
  67. package/docs/component-ux-app-authoring.md +56 -63
  68. package/docs/components/xcode.md +83 -53
  69. package/docs/components/xsurfaceportal.md +32 -0
  70. package/docs/components/xsurfaceregion.md +37 -0
  71. package/docs/components.md +105 -69
  72. package/docs/de/README.md +264 -0
  73. package/docs/de/XTend-ADR.md +221 -0
  74. package/docs/de/a11y-keyboard-smokes.md +62 -0
  75. package/docs/de/about.md +18 -0
  76. package/docs/de/api.md +157 -0
  77. package/docs/de/best-practices.md +76 -0
  78. package/docs/de/changelog.md +107 -0
  79. package/docs/de/component-catalog-coverage.md +58 -0
  80. package/docs/de/component-lab.md +103 -0
  81. package/docs/de/component-long-tail-migration.md +41 -0
  82. package/docs/de/component-platform.md +177 -0
  83. package/docs/de/component-ux-app-authoring.md +123 -0
  84. package/docs/de/component-ux-authoring.md +96 -0
  85. package/docs/de/component-ux-gates.md +45 -0
  86. package/docs/de/components/x-rmt-lifecycle-demo-build.md +60 -0
  87. package/docs/de/components/xalert.md +81 -0
  88. package/docs/de/components/xbutton.md +103 -0
  89. package/docs/de/components/xcalendar.md +82 -0
  90. package/docs/de/components/xcards.md +128 -0
  91. package/docs/de/components/xcheckbox.md +102 -0
  92. package/docs/de/components/xcode.md +156 -0
  93. package/docs/de/components/xdialog.md +92 -0
  94. package/docs/de/components/xdrawer.md +84 -0
  95. package/docs/de/components/xfooter.md +126 -0
  96. package/docs/de/components/xform.md +128 -0
  97. package/docs/de/components/xheader.md +308 -0
  98. package/docs/de/components/xhero.md +142 -0
  99. package/docs/de/components/xicon.md +125 -0
  100. package/docs/de/components/xinput.md +129 -0
  101. package/docs/de/components/xlightbox.md +98 -0
  102. package/docs/de/components/xlink.md +109 -0
  103. package/docs/de/components/xmasonry.md +124 -0
  104. package/docs/de/components/xmenu.md +158 -0
  105. package/docs/de/components/xmodal.md +82 -0
  106. package/docs/de/components/xplayer.md +104 -0
  107. package/docs/de/components/xpopover.md +67 -0
  108. package/docs/de/components/xprogress.md +56 -0
  109. package/docs/de/components/xradio.md +103 -0
  110. package/docs/de/components/xrouter.md +260 -0
  111. package/docs/de/components/xsection.md +125 -0
  112. package/docs/de/components/xselect.md +105 -0
  113. package/docs/de/components/xsidepanel.md +30 -0
  114. package/docs/de/components/xspinner.md +102 -0
  115. package/docs/de/components/xstate.md +148 -0
  116. package/docs/de/components/xstatus.md +55 -0
  117. package/docs/de/components/xsummary.md +78 -0
  118. package/docs/de/components/xsurfacemanager.md +27 -0
  119. package/docs/de/components/xsurfacewindow.md +21 -0
  120. package/docs/de/components/xtabs.md +160 -0
  121. package/docs/de/components/xtextarea.md +98 -0
  122. package/docs/de/components/xtheme.md +167 -0
  123. package/docs/de/components/xtoast.md +62 -0
  124. package/docs/de/components/xtooltip.md +66 -0
  125. package/docs/de/components/xtype.md +82 -0
  126. package/docs/de/components/xutils.md +144 -0
  127. package/docs/de/components/xwriter.md +94 -0
  128. package/docs/de/components.md +153 -0
  129. package/docs/de/conditional-network-evidence-ci.md +38 -0
  130. package/docs/de/conditional-network-evidence.md +50 -0
  131. package/docs/de/core-migration-guide.md +110 -0
  132. package/docs/de/design-tokens.md +116 -0
  133. package/docs/de/docs-rmt-production-hardening.md +31 -0
  134. package/docs/de/enterprise-adoption.md +413 -0
  135. package/docs/de/enterprise-component-flex-release-handoff.md +129 -0
  136. package/docs/de/epic10-platform-gates.md +62 -0
  137. package/docs/de/epic10-release-handoff.md +81 -0
  138. package/docs/de/epic11-enterprise-ux-handoff.md +70 -0
  139. package/docs/de/epic12-rc0-handoff.md +61 -0
  140. package/docs/de/epic18-media-manager-vendor-upstream.md +318 -0
  141. package/docs/de/epic18-rmt-app-platform-release-handoff.md +67 -0
  142. package/docs/de/epic18-vendor-bugfixes.md +34 -0
  143. package/docs/de/existing-component-metadata.md +67 -0
  144. package/docs/de/hydration-performance-closure.md +34 -0
  145. package/docs/de/hydration-policies.md +71 -0
  146. package/docs/de/known-residual-triage.md +22 -0
  147. package/docs/de/manifest-import-policy.md +79 -0
  148. package/docs/de/manifest.md +112 -0
  149. package/docs/de/motion-contrast.md +67 -0
  150. package/docs/de/package-export-lock.md +44 -0
  151. package/docs/de/performance-measurements.md +106 -0
  152. package/docs/de/performance-regression.md +89 -0
  153. package/docs/de/performance.md +94 -0
  154. package/docs/de/previews/README.md +17 -0
  155. package/docs/de/prod-browser-csp-smokes.md +40 -0
  156. package/docs/de/public-component-types.md +79 -0
  157. package/docs/de/quick-start-guide.md +220 -0
  158. package/docs/de/rc0-adoption-guide.md +102 -0
  159. package/docs/de/rc0-gate-matrix.md +58 -0
  160. package/docs/de/rc1-gate-matrix-ci-handoff.md +56 -0
  161. package/docs/de/rc1-migration-notes.md +69 -0
  162. package/docs/de/rc1-readiness.md +46 -0
  163. package/docs/de/release-owner-acceptance.md +56 -0
  164. package/docs/de/release-report-pack-dry-run-evidence.md +39 -0
  165. package/docs/de/rmt-action-effect-runtime.md +81 -0
  166. package/docs/de/rmt-app-platform-authoring.md +54 -0
  167. package/docs/de/rmt-app-platform-fixture.md +46 -0
  168. package/docs/de/rmt-app-platform-migration-guide.md +88 -0
  169. package/docs/de/rmt-app-platform-tooling.md +79 -0
  170. package/docs/de/rmt-component-template-primitives.md +57 -0
  171. package/docs/de/rmt-dom-descriptor-renderer.md +64 -0
  172. package/docs/de/rmt-dsl-authoring-polish.md +145 -0
  173. package/docs/de/rmt-event-routing-runtime.md +81 -0
  174. package/docs/de/rmt-first-demo-app.md +77 -0
  175. package/docs/de/rmt-first-xtend-apps.md +129 -0
  176. package/docs/de/rmt-kernel-panic-recovery-incident-handoff.md +61 -0
  177. package/docs/de/rmt-kernel-security-hardening-migration.md +50 -0
  178. package/docs/de/rmt-kernel-trusted-output-authoring.md +69 -0
  179. package/docs/de/rmt-language-server.md +234 -0
  180. package/docs/de/rmt-lifecycle-demo.md +24 -0
  181. package/docs/de/rmt-linter.md +140 -0
  182. package/docs/de/rmt-node-ssr-adapter.md +100 -0
  183. package/docs/de/rmt-php-ssr-adapter.md +120 -0
  184. package/docs/de/rmt-production-readiness.md +63 -0
  185. package/docs/de/rmt-state-selector-runtime.md +47 -0
  186. package/docs/de/rmt-surface-resource-graph-runtime.md +92 -0
  187. package/docs/de/rmt-tooling-release-gates.md +77 -0
  188. package/docs/de/rmt-vnext-authoring.md +170 -0
  189. package/docs/de/rmt-vnext-component-primitives.md +188 -0
  190. package/docs/de/rmt-vnext-cross-surface-events.md +68 -0
  191. package/docs/de/rmt-vnext-enterprise-mfe-handoff.md +70 -0
  192. package/docs/de/rmt-vnext-fabric-bridge-evidence.md +81 -0
  193. package/docs/de/rmt-vnext-migration-notes.md +62 -0
  194. package/docs/de/rmt-vnext-primitive-authoring-tooling.md +247 -0
  195. package/docs/de/rmt-vnext-primitive-grammar-design.md +289 -0
  196. package/docs/de/rmt-vnext-primitive-lowering.md +108 -0
  197. package/docs/de/rmt-vnext-primitive-migration.md +119 -0
  198. package/docs/de/rmt-vnext-primitive-parser-ast.md +76 -0
  199. package/docs/de/rmt-vnext-primitive-semantic-graph.md +118 -0
  200. package/docs/de/rmt-vnext-primitives-compiler-backlog.md +739 -0
  201. package/docs/de/rmt-vnext-release-handoff.md +83 -0
  202. package/docs/de/rmt-vnext-remote-surfaces.md +90 -0
  203. package/docs/de/rmt-vnext-source-to-sea-gate.md +612 -0
  204. package/docs/de/rmt-vnext-surface-registry-enterprise.md +76 -0
  205. package/docs/de/screenreader-signals.md +56 -0
  206. package/docs/de/supply-chain-gates.md +100 -0
  207. package/docs/de/surface-manager-authoring-guide.md +94 -0
  208. package/docs/de/surface-manager-browser-lab.md +45 -0
  209. package/docs/de/surface-manager-component-lab.md +43 -0
  210. package/docs/de/surface-manager-controller.md +66 -0
  211. package/docs/de/surface-manager-layout-engines.md +32 -0
  212. package/docs/de/surface-manager-lazy-hydration.md +63 -0
  213. package/docs/de/surface-manager-migration-guide.md +122 -0
  214. package/docs/de/surface-manager-native-rmt-surfaces.md +38 -0
  215. package/docs/de/surface-manager-overlay-bridge.md +53 -0
  216. package/docs/de/surface-manager-persistence.md +30 -0
  217. package/docs/de/surface-manager-quality-gates.md +51 -0
  218. package/docs/de/surface-manager-release-handoff.md +68 -0
  219. package/docs/de/surface-manager-remote-policy.md +54 -0
  220. package/docs/de/surface-manager-rmt-authoring.md +102 -0
  221. package/docs/de/surface-manager-route-lifecycle.md +59 -0
  222. package/docs/de/surface-manager-runtime-release-handoff.md +69 -0
  223. package/docs/de/surface-manager-side-panel-runtime.md +36 -0
  224. package/docs/de/surface-manager-stack-policy.md +39 -0
  225. package/docs/de/surface-manager-window-runtime.md +47 -0
  226. package/docs/de/surface-manager-workbench-fixture.md +43 -0
  227. package/docs/de/third-party-design-authoring.md +406 -0
  228. package/docs/de/trusted-dom-boundary-browser-proof.md +32 -0
  229. package/docs/de/trusted-dom-sanitizing.md +110 -0
  230. package/docs/de/type-exports.md +61 -0
  231. package/docs/de/typescript-components.md +63 -0
  232. package/docs/de/visual-browser-regression.md +83 -0
  233. package/docs/de/visual-owner-artifacts.md +46 -0
  234. package/docs/de/visual-snapshot-automation.md +87 -0
  235. package/docs/de/xtend-api-types.md +55 -0
  236. package/docs/de/xtend-builder-types.md +55 -0
  237. package/docs/de/xtend-catalog-types.md +44 -0
  238. package/docs/de/xtend-fabric-rmt-lane-mapping.md +143 -0
  239. package/docs/de/xtend-fabric.md +474 -0
  240. package/docs/de/xtend-loader-types.md +58 -0
  241. package/docs/de/xtend-loader.md +265 -0
  242. package/docs/de/xtend-policy-types.md +38 -0
  243. package/docs/de/xtend-rmt-types.md +40 -0
  244. package/docs/de/xtend-vendor-types.md +36 -0
  245. package/docs/de/xtendrmt-app-dsl.md +334 -0
  246. package/docs/de/xtendrmt-migration-guide.md +266 -0
  247. package/docs/de/xtendrmt-native-authoring.md +333 -0
  248. package/docs/de/xtendrmt-overview.md +109 -0
  249. package/docs/de/xtendrmt-parsedown-scheduling.md +301 -0
  250. package/docs/de/xtendrmt-runtime-bridge.md +155 -0
  251. package/docs/en/README.md +163 -0
  252. package/docs/en/XTend-ADR.md +221 -0
  253. package/docs/en/a11y-keyboard-smokes.md +68 -0
  254. package/docs/en/about.md +25 -0
  255. package/docs/en/api.md +171 -0
  256. package/docs/en/best-practices.md +125 -0
  257. package/docs/en/changelog.md +104 -0
  258. package/docs/en/component-catalog-coverage.md +104 -0
  259. package/docs/en/component-lab.md +103 -0
  260. package/docs/en/component-long-tail-migration.md +41 -0
  261. package/docs/en/component-platform.md +243 -0
  262. package/docs/en/component-ux-app-authoring.md +118 -0
  263. package/docs/en/component-ux-authoring.md +96 -0
  264. package/docs/en/component-ux-gates.md +45 -0
  265. package/docs/en/components/x-rmt-lifecycle-demo-build.md +75 -0
  266. package/docs/en/components/xalert.md +94 -0
  267. package/docs/en/components/xbutton.md +118 -0
  268. package/docs/en/components/xcalendar.md +95 -0
  269. package/docs/en/components/xcards.md +139 -0
  270. package/docs/en/components/xcheckbox.md +118 -0
  271. package/docs/en/components/xcode.md +153 -0
  272. package/docs/en/components/xdialog.md +108 -0
  273. package/docs/en/components/xdrawer.md +110 -0
  274. package/docs/en/components/xfooter.md +138 -0
  275. package/docs/en/components/xform.md +147 -0
  276. package/docs/en/components/xheader.md +308 -0
  277. package/docs/en/components/xhero.md +157 -0
  278. package/docs/en/components/xicon.md +149 -0
  279. package/docs/en/components/xinput.md +147 -0
  280. package/docs/en/components/xlightbox.md +113 -0
  281. package/docs/en/components/xlink.md +130 -0
  282. package/docs/en/components/xmasonry.md +136 -0
  283. package/docs/en/components/xmenu.md +185 -0
  284. package/docs/en/components/xmodal.md +102 -0
  285. package/docs/en/components/xplayer.md +114 -0
  286. package/docs/en/components/xpopover.md +87 -0
  287. package/docs/en/components/xprogress.md +73 -0
  288. package/docs/en/components/xradio.md +119 -0
  289. package/docs/en/components/xrouter.md +260 -0
  290. package/docs/en/components/xsection.md +136 -0
  291. package/docs/en/components/xselect.md +122 -0
  292. package/docs/en/components/xsidepanel.md +48 -0
  293. package/docs/en/components/xspinner.md +118 -0
  294. package/docs/en/components/xstate.md +163 -0
  295. package/docs/en/components/xstatus.md +71 -0
  296. package/docs/en/components/xsummary.md +90 -0
  297. package/docs/en/components/xsurfacemanager.md +42 -0
  298. package/docs/en/components/xsurfacewindow.md +31 -0
  299. package/docs/en/components/xtabs.md +187 -0
  300. package/docs/en/components/xtextarea.md +115 -0
  301. package/docs/en/components/xtheme.md +203 -0
  302. package/docs/en/components/xtoast.md +78 -0
  303. package/docs/en/components/xtooltip.md +85 -0
  304. package/docs/en/components/xtype.md +91 -0
  305. package/docs/en/components/xutils.md +161 -0
  306. package/docs/en/components/xwriter.md +106 -0
  307. package/docs/en/components.md +151 -0
  308. package/docs/en/conditional-network-evidence-ci.md +38 -0
  309. package/docs/en/conditional-network-evidence.md +50 -0
  310. package/docs/en/core-migration-guide.md +110 -0
  311. package/docs/en/design-tokens.md +137 -0
  312. package/docs/en/docs-rmt-production-hardening.md +31 -0
  313. package/docs/en/enterprise-adoption.md +413 -0
  314. package/docs/en/enterprise-component-flex-release-handoff.md +129 -0
  315. package/docs/en/epic10-platform-gates.md +62 -0
  316. package/docs/en/epic10-release-handoff.md +81 -0
  317. package/docs/en/epic11-enterprise-ux-handoff.md +70 -0
  318. package/docs/en/epic12-rc0-handoff.md +61 -0
  319. package/docs/en/epic18-media-manager-vendor-upstream.md +232 -0
  320. package/docs/en/epic18-rmt-app-platform-release-handoff.md +60 -0
  321. package/docs/en/epic18-vendor-bugfixes.md +29 -0
  322. package/docs/en/existing-component-metadata.md +67 -0
  323. package/docs/en/hydration-performance-closure.md +34 -0
  324. package/docs/en/hydration-policies.md +75 -0
  325. package/docs/en/known-residual-triage.md +22 -0
  326. package/docs/en/manifest-import-policy.md +81 -0
  327. package/docs/en/manifest.md +135 -0
  328. package/docs/en/motion-contrast.md +67 -0
  329. package/docs/en/package-export-lock.md +44 -0
  330. package/docs/en/performance-measurements.md +106 -0
  331. package/docs/en/performance-regression.md +89 -0
  332. package/docs/en/performance.md +132 -0
  333. package/docs/en/previews/README.md +17 -0
  334. package/docs/en/prod-browser-csp-smokes.md +40 -0
  335. package/docs/en/public-component-types.md +79 -0
  336. package/docs/en/quick-start-guide.md +189 -0
  337. package/docs/en/rc0-adoption-guide.md +102 -0
  338. package/docs/en/rc0-gate-matrix.md +58 -0
  339. package/docs/en/rc1-gate-matrix-ci-handoff.md +56 -0
  340. package/docs/en/rc1-migration-notes.md +69 -0
  341. package/docs/en/rc1-readiness.md +46 -0
  342. package/docs/en/release-owner-acceptance.md +56 -0
  343. package/docs/en/release-report-pack-dry-run-evidence.md +39 -0
  344. package/docs/en/rmt-action-effect-runtime.md +101 -0
  345. package/docs/en/rmt-app-platform-authoring.md +47 -0
  346. package/docs/en/rmt-app-platform-fixture.md +35 -0
  347. package/docs/en/rmt-app-platform-migration-guide.md +75 -0
  348. package/docs/en/rmt-app-platform-tooling.md +58 -0
  349. package/docs/en/rmt-component-template-primitives.md +49 -0
  350. package/docs/en/rmt-dom-descriptor-renderer.md +54 -0
  351. package/docs/en/rmt-dsl-authoring-polish.md +143 -0
  352. package/docs/en/rmt-event-routing-runtime.md +98 -0
  353. package/docs/en/rmt-first-demo-app.md +87 -0
  354. package/docs/en/rmt-first-xtend-apps.md +127 -0
  355. package/docs/en/rmt-kernel-panic-recovery-incident-handoff.md +60 -0
  356. package/docs/en/rmt-kernel-security-hardening-migration.md +49 -0
  357. package/docs/en/rmt-kernel-trusted-output-authoring.md +68 -0
  358. package/docs/en/rmt-language-server.md +243 -0
  359. package/docs/en/rmt-lifecycle-demo.md +23 -0
  360. package/docs/en/rmt-linter.md +146 -0
  361. package/docs/en/rmt-node-ssr-adapter.md +99 -0
  362. package/docs/en/rmt-php-ssr-adapter.md +118 -0
  363. package/docs/en/rmt-production-readiness.md +63 -0
  364. package/docs/en/rmt-state-selector-runtime.md +34 -0
  365. package/docs/en/rmt-surface-resource-graph-runtime.md +68 -0
  366. package/docs/en/rmt-tooling-release-gates.md +77 -0
  367. package/docs/en/rmt-vnext-authoring.md +102 -0
  368. package/docs/en/rmt-vnext-component-primitives.md +185 -0
  369. package/docs/en/rmt-vnext-cross-surface-events.md +59 -0
  370. package/docs/en/rmt-vnext-enterprise-mfe-handoff.md +62 -0
  371. package/docs/en/rmt-vnext-fabric-bridge-evidence.md +64 -0
  372. package/docs/en/rmt-vnext-migration-notes.md +62 -0
  373. package/docs/en/rmt-vnext-primitive-authoring-tooling.md +174 -0
  374. package/docs/en/rmt-vnext-primitive-grammar-design.md +268 -0
  375. package/docs/en/rmt-vnext-primitive-lowering.md +91 -0
  376. package/docs/en/rmt-vnext-primitive-migration.md +93 -0
  377. package/docs/en/rmt-vnext-primitive-parser-ast.md +59 -0
  378. package/docs/en/rmt-vnext-primitive-semantic-graph.md +103 -0
  379. package/docs/en/rmt-vnext-primitives-compiler-backlog.md +327 -0
  380. package/docs/en/rmt-vnext-release-handoff.md +83 -0
  381. package/docs/en/rmt-vnext-remote-surfaces.md +81 -0
  382. package/docs/en/rmt-vnext-source-to-sea-gate.md +482 -0
  383. package/docs/en/rmt-vnext-surface-registry-enterprise.md +68 -0
  384. package/docs/en/screenreader-signals.md +56 -0
  385. package/docs/en/supply-chain-gates.md +106 -0
  386. package/docs/en/surface-manager-authoring-guide.md +94 -0
  387. package/docs/en/surface-manager-browser-lab.md +45 -0
  388. package/docs/en/surface-manager-component-lab.md +43 -0
  389. package/docs/en/surface-manager-controller.md +66 -0
  390. package/docs/en/surface-manager-layout-engines.md +32 -0
  391. package/docs/en/surface-manager-lazy-hydration.md +63 -0
  392. package/docs/en/surface-manager-migration-guide.md +113 -0
  393. package/docs/en/surface-manager-native-rmt-surfaces.md +38 -0
  394. package/docs/en/surface-manager-overlay-bridge.md +53 -0
  395. package/docs/en/surface-manager-persistence.md +30 -0
  396. package/docs/en/surface-manager-quality-gates.md +51 -0
  397. package/docs/en/surface-manager-release-handoff.md +68 -0
  398. package/docs/en/surface-manager-remote-policy.md +54 -0
  399. package/docs/en/surface-manager-rmt-authoring.md +89 -0
  400. package/docs/en/surface-manager-route-lifecycle.md +59 -0
  401. package/docs/en/surface-manager-runtime-release-handoff.md +69 -0
  402. package/docs/en/surface-manager-side-panel-runtime.md +36 -0
  403. package/docs/en/surface-manager-stack-policy.md +39 -0
  404. package/docs/en/surface-manager-window-runtime.md +47 -0
  405. package/docs/en/surface-manager-workbench-fixture.md +43 -0
  406. package/docs/en/third-party-design-authoring.md +406 -0
  407. package/docs/en/trusted-dom-boundary-browser-proof.md +32 -0
  408. package/docs/en/trusted-dom-sanitizing.md +124 -0
  409. package/docs/en/type-exports.md +61 -0
  410. package/docs/en/typescript-components.md +63 -0
  411. package/docs/en/visual-browser-regression.md +83 -0
  412. package/docs/en/visual-owner-artifacts.md +46 -0
  413. package/docs/en/visual-snapshot-automation.md +87 -0
  414. package/docs/en/xtend-api-types.md +55 -0
  415. package/docs/en/xtend-builder-types.md +55 -0
  416. package/docs/en/xtend-catalog-types.md +44 -0
  417. package/docs/en/xtend-fabric-rmt-lane-mapping.md +143 -0
  418. package/docs/en/xtend-fabric.md +474 -0
  419. package/docs/en/xtend-loader-types.md +58 -0
  420. package/docs/en/xtend-loader.md +265 -0
  421. package/docs/en/xtend-policy-types.md +38 -0
  422. package/docs/en/xtend-rmt-types.md +40 -0
  423. package/docs/en/xtend-vendor-types.md +36 -0
  424. package/docs/en/xtendrmt-app-dsl.md +331 -0
  425. package/docs/en/xtendrmt-migration-guide.md +256 -0
  426. package/docs/en/xtendrmt-native-authoring.md +336 -0
  427. package/docs/en/xtendrmt-overview.md +63 -0
  428. package/docs/en/xtendrmt-parsedown-scheduling.md +301 -0
  429. package/docs/en/xtendrmt-runtime-bridge.md +155 -0
  430. package/docs/enterprise-adoption.md +4 -2
  431. package/docs/epic18-media-manager-vendor-upstream.md +318 -0
  432. package/docs/epic18-rmt-app-platform-release-handoff.md +67 -0
  433. package/docs/epic18-vendor-bugfixes.md +34 -0
  434. package/docs/index.php +1056 -109
  435. package/docs/manifest.md +8 -2
  436. package/docs/menu.json +986 -133
  437. package/docs/package-export-lock.md +2 -2
  438. package/docs/public-component-types.md +2 -2
  439. package/docs/quick-start-guide.md +126 -58
  440. package/docs/rmt-action-effect-runtime.md +101 -0
  441. package/docs/rmt-app-platform-authoring.md +54 -0
  442. package/docs/rmt-app-platform-fixture.md +46 -0
  443. package/docs/rmt-app-platform-migration-guide.md +88 -0
  444. package/docs/rmt-app-platform-tooling.md +79 -0
  445. package/docs/rmt-component-template-primitives.md +57 -0
  446. package/docs/rmt-dom-descriptor-renderer.md +64 -0
  447. package/docs/rmt-dsl-authoring-polish.md +67 -44
  448. package/docs/rmt-event-routing-runtime.md +98 -0
  449. package/docs/rmt-first-demo-app.md +2 -2
  450. package/docs/rmt-first-xtend-apps.md +70 -46
  451. package/docs/rmt-language-server.md +61 -4
  452. package/docs/rmt-lifecycle-demo.md +1 -2
  453. package/docs/rmt-node-ssr-adapter.md +144 -0
  454. package/docs/rmt-php-ssr-adapter.md +158 -0
  455. package/docs/rmt-state-selector-runtime.md +47 -0
  456. package/docs/rmt-surface-resource-graph-runtime.md +92 -0
  457. package/docs/rmt-vnext-authoring.md +128 -18
  458. package/docs/rmt-vnext-component-primitives.md +188 -0
  459. package/docs/rmt-vnext-fabric-bridge-evidence.md +81 -0
  460. package/docs/rmt-vnext-primitive-authoring-tooling.md +247 -0
  461. package/docs/rmt-vnext-primitive-grammar-design.md +289 -0
  462. package/docs/rmt-vnext-primitive-lowering.md +108 -0
  463. package/docs/rmt-vnext-primitive-migration.md +119 -0
  464. package/docs/rmt-vnext-primitive-parser-ast.md +76 -0
  465. package/docs/rmt-vnext-primitive-semantic-graph.md +118 -0
  466. package/docs/rmt-vnext-primitives-compiler-backlog.md +742 -0
  467. package/docs/rmt-vnext-release-handoff.md +14 -0
  468. package/docs/rmt-vnext-source-to-sea-gate.md +629 -0
  469. package/docs/surface-manager-migration-guide.md +34 -6
  470. package/docs/surface-manager-overlay-bridge.md +9 -4
  471. package/docs/surface-manager-rmt-authoring.md +50 -34
  472. package/docs/surface-manager-workbench-fixture.md +1 -2
  473. package/docs/third-party-design-authoring.md +1 -1
  474. package/docs/type-exports.md +3 -3
  475. package/docs/utils/pageloader.js +811 -62
  476. package/docs/visual-browser-regression.md +1 -1
  477. package/docs/xtend-rmt-types.md +3 -2
  478. package/docs/xtendrmt-app-dsl.md +187 -122
  479. package/docs/xtendrmt-docs-shell-vnext.rmt +165 -0
  480. package/docs/xtendrmt-migration-guide.md +48 -17
  481. package/docs/xtendrmt-native-authoring.md +213 -217
  482. package/docs/xtendrmt-overview.md +81 -61
  483. package/docs/xtendrmt-parsedown-scheduling.md +23 -8
  484. package/fabric/package.json +1 -1
  485. package/package.json +684 -21
  486. package/tools/package.json +5 -1
  487. package/tools/rmt-editor/vscode/README.md +72 -5
  488. package/tools/rmt-editor/vscode/XTend-Logo.png +0 -0
  489. package/tools/rmt-editor/vscode/extension.d.ts +33 -0
  490. package/tools/rmt-editor/vscode/extension.js +1816 -7
  491. package/tools/rmt-editor/vscode/language-configuration.json +2 -1
  492. package/tools/rmt-editor/vscode/package.json +193 -2
  493. package/tools/rmt-editor/vscode/snippets/rmt.code-snippets +41 -0
  494. package/tools/rmt-editor/vscode/syntaxes/rmt.tmLanguage.json +103 -1
  495. package/tools/rmt-editor/vscode/templates/launch.json +70 -0
  496. package/tools/rmt-editor/vscode/templates/tasks.json +172 -0
  497. package/tools/rmt-editor/vscode/xtend-rmt-language-0.0.0-enterprise-readiness.vsix +0 -0
  498. package/tools/rmt-language/app-platform-tooling.d.ts +128 -0
  499. package/tools/rmt-language/app-platform-tooling.js +677 -0
  500. package/tools/rmt-language/completions.d.ts +5 -0
  501. package/tools/rmt-language/completions.js +185 -3
  502. package/tools/rmt-language/diagnostics.js +54 -0
  503. package/tools/rmt-language/hover.js +36 -0
  504. package/tools/rmt-language/rmt-tooling-public-types.d.ts +7 -0
  505. package/tools/rmt-language/rules/app-platform-policy.js +39 -0
  506. package/tools/rmt-language/rules/index.js +5 -1
  507. package/tools/rmt-language/semantic-graph.d.ts +6 -0
  508. package/tools/rmt-language/semantic-graph.js +928 -0
  509. package/tools/rmt-language/snippets/index.js +44 -0
  510. package/tools/rmt-language/snippets/rmt.code-snippets +41 -0
  511. package/tools/rmt-language/vnext-compatibility.d.ts +10 -0
  512. package/tools/rmt-language/vnext-compatibility.js +642 -0
  513. package/tools/rmt-language/vnext-compiler.d.ts +5 -0
  514. package/tools/rmt-language/vnext-compiler.js +863 -17
  515. package/tools/rmt-language/vnext-parser.js +725 -9
  516. package/tools/rmt-language/vnext-release.d.ts +1 -0
  517. package/tools/rmt-language/vnext-release.js +20 -0
  518. package/tools/rmt-language/vnext-source-to-sea.d.ts +33 -0
  519. package/tools/rmt-language/vnext-source-to-sea.js +2227 -0
  520. package/tools/rmt-language/vnext-surfaces.js +111 -52
  521. package/tools/rmt-language/vnext-tooling.d.ts +19 -1
  522. package/tools/rmt-language/vnext-tooling.js +1247 -5
  523. package/tools/rmt-language-server/protocol.js +3 -0
  524. package/tools/rmt-language-server/server.d.ts +2 -0
  525. package/tools/rmt-language-server/server.js +176 -22
  526. package/tools/rmt-linter/cli.d.ts +2 -0
  527. package/tools/rmt-linter/cli.js +62 -0
  528. package/xtend-builder/generators/registry.js +11 -0
  529. package/xtend-builder/generators/rmt-app-platform.js +239 -0
  530. package/xtend-builder/generators/rmt-lifecycle-demo.js +3 -11
  531. package/xtend-builder/lib/cli.js +38 -0
  532. package/xtend-builder/package.json +3 -3
  533. package/xtend-builder/scaffold.config.js +29 -2
  534. package/xtend.css +49 -2
  535. package/xtendrmt/package.json +49 -1
  536. package/xtendrmt/rmt-action-effect-runtime.d.ts +126 -0
  537. package/xtendrmt/rmt-action-effect-runtime.js +494 -0
  538. package/xtendrmt/rmt-component-capability-registry.d.ts +180 -0
  539. package/xtendrmt/rmt-component-capability-registry.js +636 -0
  540. package/xtendrmt/rmt-core.d.ts +6 -0
  541. package/xtendrmt/rmt-core.esm.js +32 -6
  542. package/xtendrmt/rmt-dom-descriptor-renderer.d.ts +107 -0
  543. package/xtendrmt/rmt-dom-descriptor-renderer.js +1066 -0
  544. package/xtendrmt/rmt-event-routing-runtime.d.ts +144 -0
  545. package/xtendrmt/rmt-event-routing-runtime.js +666 -0
  546. package/xtendrmt/rmt-lifecycle-demo.app.js +2 -2
  547. package/xtendrmt/rmt-lifecycle-demo.core.json +4 -0
  548. package/xtendrmt/rmt-lifecycle-demo.rmt-build.app.js +1 -1
  549. package/xtendrmt/rmt-lifecycle-demo.rmt-build.scaffold.json +2 -2
  550. package/xtendrmt/rmt-lifecycle-demo.scaffold.json +4 -4
  551. package/xtendrmt/rmt-native-shell-runtime.d.ts +77 -0
  552. package/xtendrmt/rmt-native-shell-runtime.js +309 -0
  553. package/xtendrmt/rmt-node-ssr-adapter.d.ts +197 -0
  554. package/xtendrmt/rmt-node-ssr-adapter.js +1006 -0
  555. package/xtendrmt/rmt-php-ssr-adapter.php +976 -0
  556. package/xtendrmt/rmt-runtime.browser.js +32 -6
  557. package/xtendrmt/rmt-runtime.esm.js +32 -6
  558. package/xtendrmt/rmt-state-selector-runtime.d.ts +166 -0
  559. package/xtendrmt/rmt-state-selector-runtime.js +866 -0
  560. package/xtendrmt/rmt-surface-resource-graph-runtime.d.ts +224 -0
  561. package/xtendrmt/rmt-surface-resource-graph-runtime.js +932 -0
  562. package/xtendrmt/rmt-vnext-enterprise-mfe-demo.core.json +3 -0
  563. package/xtendrmt/rmt-vnext-reference-demo.core.json +3 -0
  564. package/xtendrmt/xtendrmt-bestcase-demo.core.json +3420 -372
  565. package/xtendrmt/xtendrmt-bestcase-demo.js +424 -8
  566. package/xtendrmt/xtendrmt-bestcase-demo.rmt +214 -6
@@ -33,6 +33,8 @@ const DOCS_ROUTE_CONTENT_CACHE_LIMIT = 32;
33
33
  const DOCS_ROUTE_IDLE_TIMEOUT_MS = 520;
34
34
  const DOCS_ROUTE_CONTENT_CACHE = new Map();
35
35
  const DOCS_ROUTE_PAYLOAD_PROMISES = new Map();
36
+ const DOCS_I18N_SCHEMA = 'xtend.docs.i18n.v1';
37
+ const DOCS_I18N_STORAGE_KEY = 'xtend.docs.locale';
36
38
  const DOCS_SHELL_SCOPED_CSS = `
37
39
  #outlet {
38
40
  width: 100%;
@@ -435,6 +437,277 @@ function docsRoundDuration(value) {
435
437
  return Math.round(Number(value || 0) * 10) / 10;
436
438
  }
437
439
 
440
+ function getDocsI18nConfig() {
441
+ const config = window.xtendDocsI18n && typeof window.xtendDocsI18n === 'object'
442
+ ? window.xtendDocsI18n
443
+ : {};
444
+ const locales = window.xtendDocsLocales && typeof window.xtendDocsLocales === 'object'
445
+ ? window.xtendDocsLocales
446
+ : { de: { label: 'Deutsch', nativeLabel: 'Deutsch' } };
447
+ const available = Array.isArray(config.available) && config.available.length
448
+ ? config.available.slice()
449
+ : Object.keys(locales);
450
+ const fallbackLocale = config.fallbackLocale || config.defaultLocale || available[0] || 'de';
451
+ return {
452
+ schema: config.schema || DOCS_I18N_SCHEMA,
453
+ defaultLocale: config.defaultLocale || fallbackLocale,
454
+ fallbackLocale,
455
+ storageKey: config.storageKey || DOCS_I18N_STORAGE_KEY,
456
+ stateKeys: {
457
+ locale: 'xtend.docs.locale',
458
+ target: 'xtend.docs.locale.target',
459
+ source: 'xtend.docs.locale.source',
460
+ status: 'xtend.docs.locale.status',
461
+ busy: 'xtend.docs.locale.busy',
462
+ transition: 'xtend.docs.locale.transition',
463
+ error: 'xtend.docs.locale.error',
464
+ available: 'xtend.docs.locale.available',
465
+ fallback: 'xtend.docs.locale.fallback',
466
+ ...(config.stateKeys || {})
467
+ },
468
+ locales,
469
+ available
470
+ };
471
+ }
472
+
473
+ function normalizeDocsLocale(value) {
474
+ const config = getDocsI18nConfig();
475
+ const raw = String(value || '').trim().toLowerCase();
476
+ if (config.available.includes(raw)) return raw;
477
+ const short = raw.slice(0, 2);
478
+ if (config.available.includes(short)) return short;
479
+ return config.fallbackLocale;
480
+ }
481
+
482
+ function readStoredDocsLocale() {
483
+ const config = getDocsI18nConfig();
484
+ try {
485
+ return window.localStorage ? window.localStorage.getItem(config.storageKey) : '';
486
+ } catch (error) {
487
+ return '';
488
+ }
489
+ }
490
+
491
+ function writeStoredDocsLocale(locale) {
492
+ const config = getDocsI18nConfig();
493
+ try {
494
+ if (window.localStorage) window.localStorage.setItem(config.storageKey, locale);
495
+ } catch (error) {
496
+ // Storage can be unavailable in hardened or test environments.
497
+ }
498
+ }
499
+
500
+ function detectBrowserDocsLocale() {
501
+ const languages = Array.isArray(navigator.languages) && navigator.languages.length
502
+ ? navigator.languages
503
+ : [navigator.language || ''];
504
+ for (const language of languages) {
505
+ const locale = normalizeDocsLocale(language);
506
+ if (locale) return locale;
507
+ }
508
+ return getDocsI18nConfig().fallbackLocale;
509
+ }
510
+
511
+ function writeDocsLocaleState(values = {}) {
512
+ if (!window.xstate || typeof window.xstate.set !== 'function') return;
513
+ const keys = getDocsI18nConfig().stateKeys;
514
+ Object.entries(values).forEach(([name, value]) => {
515
+ const stateKey = keys[name];
516
+ if (stateKey) window.xstate.set(stateKey, value);
517
+ });
518
+ }
519
+
520
+ function createDocsLocaleTransitionSnapshot(status, detail = {}) {
521
+ const targetLocale = normalizeDocsLocale(detail.targetLocale || detail.locale || getCurrentDocsLocale());
522
+ const activeLocale = window.xtendDocsCurrentLocale ? normalizeDocsLocale(window.xtendDocsCurrentLocale) : '';
523
+ return {
524
+ schema: 'xtend.docs.locale-transition.v1',
525
+ status,
526
+ busy: status === 'loading',
527
+ activeLocale,
528
+ targetLocale,
529
+ slug: detail.slug || getCurrentDocsSlug(),
530
+ source: detail.source || 'route',
531
+ startedAt: detail.startedAt || (window.__xtendDocsLocaleTransition && window.__xtendDocsLocaleTransition.startedAt) || new Date().toISOString(),
532
+ startedAtMs: detail.startedAtMs || (window.__xtendDocsLocaleTransition && window.__xtendDocsLocaleTransition.startedAtMs) || docsPerfNow(),
533
+ completedAt: status === 'loading' ? null : new Date().toISOString(),
534
+ durationMs: detail.startedAtMs ? docsRoundDuration(docsPerfNow() - detail.startedAtMs) : detail.durationMs || 0,
535
+ token: detail.token || (window.__xtendDocsLocaleTransition && window.__xtendDocsLocaleTransition.token) || 0,
536
+ error: detail.error || null
537
+ };
538
+ }
539
+
540
+ function setDocsLocaleTransitionState(status, detail = {}) {
541
+ const snapshot = createDocsLocaleTransitionSnapshot(status, detail);
542
+ if (status === 'loading') {
543
+ window.__xtendDocsLocaleTransition = snapshot;
544
+ } else if (!window.__xtendDocsLocaleTransition ||
545
+ window.__xtendDocsLocaleTransition.token === snapshot.token ||
546
+ window.__xtendDocsLocaleTransition.targetLocale === snapshot.targetLocale) {
547
+ window.__xtendDocsLocaleTransition = null;
548
+ }
549
+ window.__xtendDocsLocaleLastTransition = snapshot;
550
+ writeDocsLocaleState({
551
+ target: snapshot.targetLocale,
552
+ status,
553
+ busy: snapshot.busy,
554
+ transition: snapshot,
555
+ error: snapshot.error
556
+ });
557
+ document.documentElement.toggleAttribute('data-docs-locale-busy', snapshot.busy);
558
+ document.documentElement.setAttribute('data-docs-locale-status', status);
559
+ updateDocsLocaleBusyUi(snapshot);
560
+ window.dispatchEvent(new CustomEvent('xtend-docs-locale-transition', { detail: snapshot }));
561
+ return snapshot;
562
+ }
563
+
564
+ function beginDocsLocaleTransition(targetLocale, detail = {}) {
565
+ const token = Number(window.__xtendDocsLocaleTransitionToken || 0) + 1;
566
+ window.__xtendDocsLocaleTransitionToken = token;
567
+ return setDocsLocaleTransitionState('loading', {
568
+ ...detail,
569
+ targetLocale,
570
+ token,
571
+ startedAt: new Date().toISOString(),
572
+ startedAtMs: docsPerfNow()
573
+ });
574
+ }
575
+
576
+ function completeDocsLocaleTransition(locale, slug, detail = {}) {
577
+ const normalized = normalizeDocsLocale(locale);
578
+ const pending = window.__xtendDocsLocaleTransition;
579
+ if (pending && (pending.targetLocale !== normalized || pending.slug !== slug)) {
580
+ return false;
581
+ }
582
+ setDocsLocaleTransitionState(detail.status || 'ready', {
583
+ ...detail,
584
+ targetLocale: normalized,
585
+ slug,
586
+ token: pending ? pending.token : detail.token,
587
+ startedAt: pending ? pending.startedAt : detail.startedAt,
588
+ startedAtMs: pending ? pending.startedAtMs : detail.startedAtMs,
589
+ source: pending ? pending.source : detail.source
590
+ });
591
+ updateDocsLocaleUi(normalized, { publish: false, busy: false, slug });
592
+ return true;
593
+ }
594
+
595
+ function parseDocsRoutePath(rawValue) {
596
+ const config = getDocsI18nConfig();
597
+ const raw = String(rawValue || location.hash || '')
598
+ .split('?')[0]
599
+ .replace(/^#\/?/, '')
600
+ .replace(/^\/+/, '');
601
+ if (!raw || raw === '/') {
602
+ return { locale: getCurrentDocsLocale(), slug: 'readme', localized: true };
603
+ }
604
+ const parts = raw.split('/');
605
+ const first = parts[0] || '';
606
+ if (config.available.includes(first)) {
607
+ return {
608
+ locale: normalizeDocsLocale(first),
609
+ slug: parts.slice(1).join('/') || 'readme',
610
+ localized: true
611
+ };
612
+ }
613
+ return {
614
+ locale: getCurrentDocsLocale(),
615
+ slug: raw || 'readme',
616
+ localized: false
617
+ };
618
+ }
619
+
620
+ function publishDocsLocale(locale, source = 'default') {
621
+ const config = getDocsI18nConfig();
622
+ const normalized = normalizeDocsLocale(locale);
623
+ const previous = window.xtendDocsCurrentLocale ? normalizeDocsLocale(window.xtendDocsCurrentLocale) : '';
624
+ const changed = previous !== normalized;
625
+ window.xtendDocsCurrentLocale = normalized;
626
+ document.documentElement.setAttribute('lang', (config.locales[normalized] && config.locales[normalized].htmlLang) || normalized);
627
+ document.documentElement.setAttribute('data-docs-locale', normalized);
628
+ writeDocsLocaleState({
629
+ locale: normalized,
630
+ source,
631
+ target: window.__xtendDocsLocaleTransition ? window.__xtendDocsLocaleTransition.targetLocale : normalized,
632
+ available: config.available.slice(),
633
+ fallback: config.fallbackLocale
634
+ });
635
+ if (!window.__xtendDocsLocaleTransition) {
636
+ writeDocsLocaleState({
637
+ status: 'ready',
638
+ busy: false,
639
+ error: null
640
+ });
641
+ }
642
+ if (changed || source === 'user' || source === 'browser' || source === 'default' || source === 'xstate') {
643
+ window.dispatchEvent(new CustomEvent('xtend-docs-locale-changed', {
644
+ detail: {
645
+ schema: DOCS_I18N_SCHEMA,
646
+ locale: normalized,
647
+ previousLocale: previous || null,
648
+ changed,
649
+ source,
650
+ available: config.available.slice(),
651
+ fallbackLocale: config.fallbackLocale
652
+ }
653
+ }));
654
+ }
655
+ return normalized;
656
+ }
657
+
658
+ function getCurrentDocsLocale() {
659
+ if (window.xtendDocsCurrentLocale) return normalizeDocsLocale(window.xtendDocsCurrentLocale);
660
+ const stored = readStoredDocsLocale();
661
+ if (stored) return publishDocsLocale(stored, 'user');
662
+ return publishDocsLocale(detectBrowserDocsLocale(), 'browser');
663
+ }
664
+
665
+ function getLocalizedDocsPath(slug, locale = getCurrentDocsLocale()) {
666
+ return '/' + normalizeDocsLocale(locale) + '/' + (slug || 'readme');
667
+ }
668
+
669
+ function normalizeDocsRouteHref(slugOrHref, locale = getCurrentDocsLocale()) {
670
+ const parsed = parseDocsRoutePath(slugOrHref || 'readme');
671
+ return getLocalizedDocsPath(parsed.slug || 'readme', locale);
672
+ }
673
+
674
+ function getLocalizedDocsMap(recordName, locale = getCurrentDocsLocale()) {
675
+ const root = window[recordName];
676
+ if (!root || typeof root !== 'object') return {};
677
+ return root[normalizeDocsLocale(locale)] || root[getDocsI18nConfig().fallbackLocale] || {};
678
+ }
679
+
680
+ function createDocsActiveRecordPatch(record, slug) {
681
+ if (!slug || !record || typeof record !== 'object' || !Object.prototype.hasOwnProperty.call(record, slug)) {
682
+ return record || {};
683
+ }
684
+ return { [slug]: record[slug] };
685
+ }
686
+
687
+ function syncLegacyDocsGlobals(locale = getCurrentDocsLocale(), options = {}) {
688
+ const normalized = normalizeDocsLocale(locale);
689
+ const pages = getLocalizedDocsMap('xtendDocsLocalizedPages', normalized);
690
+ const meta = getLocalizedDocsMap('xtendDocsLocalizedPagesMeta', normalized);
691
+ const titles = getLocalizedDocsMap('xtendDocsLocalizedTitles', normalized);
692
+ const slug = options && options.slug ? String(options.slug) : '';
693
+ const pagePatch = createDocsActiveRecordPatch(pages, slug);
694
+ const metaPatch = createDocsActiveRecordPatch(meta, slug);
695
+ const titlePatch = createDocsActiveRecordPatch(titles, slug);
696
+ window.xtendDocsPages = {
697
+ ...(window.xtendDocsPages || {}),
698
+ ...pagePatch
699
+ };
700
+ window.xtendDocsPagesMeta = {
701
+ ...(window.xtendDocsPagesMeta || {}),
702
+ ...metaPatch
703
+ };
704
+ window.xtendDocsTitles = {
705
+ ...(window.xtendDocsTitles || {}),
706
+ ...titlePatch
707
+ };
708
+ return { pages, meta, titles };
709
+ }
710
+
438
711
  function rememberDocsCacheEntry(key, value) {
439
712
  DOCS_ROUTE_CONTENT_CACHE.set(key, value);
440
713
  while (DOCS_ROUTE_CONTENT_CACHE.size > DOCS_ROUTE_CONTENT_CACHE_LIMIT) {
@@ -446,6 +719,7 @@ function rememberDocsCacheEntry(key, value) {
446
719
 
447
720
  function createDocsRouteContentCacheKey(slug, html, options = {}) {
448
721
  return [
722
+ options.locale || getCurrentDocsLocale(),
449
723
  slug || 'readme',
450
724
  options.source || 'docs.parsedown',
451
725
  options.markupClass || 'parsedownHtml',
@@ -588,7 +862,31 @@ function hideDocsSkeleton(target, options = {}) {
588
862
  }
589
863
 
590
864
  function createRmtSnippet(tag, attributes = {}, children = []) {
591
- return JSON.stringify({ tag, attributes, children }, null, 2);
865
+ const component = String(tag || 'x-component');
866
+ const id = component.replace(/^x-/, '').replace(/[^A-Za-z0-9_-]+/g, '-');
867
+ const attributeLines = Object.entries(attributes || {})
868
+ .map(([key, value]) => ` ${key} ${JSON.stringify(value)}`);
869
+ const childCount = Array.isArray(children) ? children.length : 0;
870
+ return [
871
+ `template docs.demo.${id} {`,
872
+ ' portal surface.root root "#docs-demo-root" layer surface',
873
+ '',
874
+ ` state docs.demo.${id}.props type object preserve {`,
875
+ ' initial {',
876
+ ...attributeLines,
877
+ ` childCount ${childCount}`,
878
+ ' }',
879
+ ' }',
880
+ '',
881
+ ` surface docs.demo.${id} kind component component ${component} {`,
882
+ ` source state docs.demo.${id}.props`,
883
+ ' portal surface.root',
884
+ ' lane visible weight 50 {',
885
+ ` hydrate ${id}-preview`,
886
+ ' }',
887
+ ' }',
888
+ '}'
889
+ ].join('\n');
592
890
  }
593
891
 
594
892
  function createDocsComponentDemos() {
@@ -797,6 +1095,64 @@ function getDocsRmtDocument() {
797
1095
  : {};
798
1096
  }
799
1097
 
1098
+ function getDocsSsrPrehydration() {
1099
+ return window.xtendDocsSsrPrehydration && typeof window.xtendDocsSsrPrehydration === 'object'
1100
+ ? window.xtendDocsSsrPrehydration
1101
+ : null;
1102
+ }
1103
+
1104
+ function findPrehydratedDocsShell(root, slug) {
1105
+ if (!root || typeof root.querySelector !== 'function') return null;
1106
+ const selectors = [
1107
+ '[data-rmt-shell-prehydrated="true"][data-rmt-shell="docs.app.shell"]',
1108
+ '[data-rmt-shell-prehydrated="true"].docs-app-shell',
1109
+ '[data-rmt-hydration-mode="server_prerender_hydrate"][data-rmt-shell="docs.app.shell"]'
1110
+ ];
1111
+ const shell = root.querySelector(selectors.join(','));
1112
+ if (!shell) return null;
1113
+ if (slug) shell.setAttribute('data-docs-route-slug', slug);
1114
+ return shell;
1115
+ }
1116
+
1117
+ function adoptPrehydratedDocsShell(shell, rmtMeta = {}) {
1118
+ if (!shell || typeof shell.querySelector !== 'function') return null;
1119
+ shell.classList.add('docs-app-shell');
1120
+ shell.setAttribute('data-rmt-ssr-reused', 'true');
1121
+ shell.setAttribute('data-rmt-shell-prehydrated', 'true');
1122
+ shell.setAttribute('data-rmt-hydration-mode', 'server_prerender_hydrate');
1123
+ const layout = shell.querySelector('[data-rmt-layout="main-sidebar"], .docs-shell-layout');
1124
+ const article = shell.querySelector('[data-rmt-slot="article"], .docs-article-surface');
1125
+ const mdContent = shell.querySelector('[data-rmt-slot="content"], #md-content') || document.createElement('div');
1126
+ const download = shell.querySelector('[data-rmt-action="docs.download.markdown"], #download-link') || document.createElement('x-button');
1127
+ const sidebar = shell.querySelector('[data-rmt-slot="sidebar"], #docs-page-sidebar');
1128
+ const relatedSlot = shell.querySelector('[data-rmt-slot="related"], #docs-related-links');
1129
+ const demoSlot = shell.querySelector('[data-rmt-slot="component-demo"], #docs-component-demo');
1130
+ const richSlot = shell.querySelector('[data-rmt-slot="rich-content"], #docs-rich-content');
1131
+ const diagnosticsSlot = shell.querySelector('[data-rmt-slot="diagnostics"], #docs-rmt-diagnostics');
1132
+ if (!layout || !article || !sidebar || !relatedSlot || !demoSlot) return null;
1133
+ if (!mdContent.id) mdContent.id = 'md-content';
1134
+ if (!download.id) download.id = 'download-link';
1135
+ configureDocsIconButton(download, {
1136
+ icon: 'download',
1137
+ pack: 'core',
1138
+ label: 'Download als Markdown'
1139
+ });
1140
+ return {
1141
+ section: shell,
1142
+ layout,
1143
+ article,
1144
+ mdContent,
1145
+ sidebar,
1146
+ relatedSlot,
1147
+ demoSlot,
1148
+ download,
1149
+ richSlot,
1150
+ diagnosticsSlot,
1151
+ shellTemplate: getRmtTemplate(rmtMeta.shellTemplate || DOCS_RMT_DEFAULT_SHELL_TEMPLATE),
1152
+ prehydrated: true
1153
+ };
1154
+ }
1155
+
800
1156
  function indexRmtRecords(records) {
801
1157
  return new Map((Array.isArray(records) ? records : [])
802
1158
  .filter((record) => record && typeof record === 'object')
@@ -907,7 +1263,9 @@ function renderRmtDomTemplate(templateId, model = {}) {
907
1263
  };
908
1264
  }
909
1265
 
910
- function getDocsPageMeta(slug) {
1266
+ function getDocsPageMeta(slug, locale = getCurrentDocsLocale()) {
1267
+ const localized = getLocalizedDocsMap('xtendDocsLocalizedPagesMeta', locale);
1268
+ if (localized && localized[slug]) return localized[slug];
911
1269
  return window.xtendDocsPagesMeta && window.xtendDocsPagesMeta[slug]
912
1270
  ? window.xtendDocsPagesMeta[slug]
913
1271
  : null;
@@ -947,16 +1305,21 @@ function createFallbackDocsShell() {
947
1305
  section.setAttribute('aria-label', 'XTend Developer Center Content Shell');
948
1306
  section.setAttribute('data-rmt-shell', DOCS_RMT_DEFAULT_SHELL_TEMPLATE);
949
1307
  section.setAttribute('data-rmt-shell-mode', 'shell-first');
1308
+ section.setAttribute('data-xtend-layout-reserve', 'shell route');
1309
+ section.setAttribute('data-xtend-cls-anchor', 'docs.page.shell');
950
1310
 
951
1311
  const layout = document.createElement('div');
952
1312
  layout.className = 'docs-shell-layout';
953
1313
  layout.setAttribute('data-rmt-layout', 'main-sidebar');
954
1314
  layout.setAttribute('data-rmt-component', 'docs.shellLayout');
1315
+ layout.setAttribute('data-xtend-layout-reserve', 'shell route');
955
1316
 
956
1317
  const article = document.createElement('article');
957
1318
  article.className = 'docs-article-surface';
958
1319
  article.setAttribute('data-rmt-slot', 'article');
959
1320
  article.setAttribute('data-rmt-component', 'docs.article');
1321
+ article.setAttribute('data-xtend-layout-reserve', 'route content');
1322
+ article.setAttribute('data-xtend-cls-anchor', 'docs.article');
960
1323
 
961
1324
  const toolbar = document.createElement('div');
962
1325
  toolbar.className = 'docs-shell-toolbar';
@@ -979,6 +1342,7 @@ function createFallbackDocsShell() {
979
1342
  mdContent.setAttribute('data-rmt-extension-slot', 'docs.slot.content');
980
1343
  mdContent.setAttribute('data-rmt-content-kind', 'parsedownHtml');
981
1344
  mdContent.setAttribute('data-rmt-trust-boundary', DOCS_RMT_TRUST_BOUNDARY);
1345
+ mdContent.setAttribute('data-xtend-layout-reserve', 'content');
982
1346
 
983
1347
  const sidebar = document.createElement('aside');
984
1348
  sidebar.id = 'docs-page-sidebar';
@@ -1205,6 +1569,8 @@ function applyRmtPageMetadata(section, mdContent, richSlot, diagnosticsSlot, rmt
1205
1569
  section.setAttribute('data-rmt-route-title', rmtMeta.title || '');
1206
1570
  section.setAttribute('data-rmt-document-title', rmtMeta.documentTitle || '');
1207
1571
  section.setAttribute('data-rmt-title-template', rmtMeta.titleTemplate || '{{title}} | XTend Dokumentation');
1572
+ section.setAttribute('data-xtend-layout-reserve', section.getAttribute('data-xtend-layout-reserve') || 'shell route');
1573
+ section.setAttribute('data-xtend-cls-anchor', section.getAttribute('data-xtend-cls-anchor') || 'docs.page.shell');
1208
1574
 
1209
1575
  if (sidebar) {
1210
1576
  sidebar.setAttribute('data-rmt-slot', 'sidebar');
@@ -1236,6 +1602,7 @@ function applyRmtPageMetadata(section, mdContent, richSlot, diagnosticsSlot, rmt
1236
1602
  mdContent.setAttribute('data-rmt-markup-class', rmtMeta.markupClass || 'parsedownHtml');
1237
1603
  mdContent.setAttribute('data-rmt-content-kind', rmtMeta.contentKind || 'parsedownHtml');
1238
1604
  mdContent.setAttribute('data-rmt-trust-boundary', rmtMeta.trustBoundary || DOCS_RMT_TRUST_BOUNDARY);
1605
+ mdContent.setAttribute('data-xtend-layout-reserve', mdContent.getAttribute('data-xtend-layout-reserve') || 'content');
1239
1606
 
1240
1607
  if (richSlot) {
1241
1608
  richSlot.setAttribute('data-rmt-extension-slot', 'docs.slot.rich-content');
@@ -1295,7 +1662,7 @@ function wireDownloadButton(download, slug) {
1295
1662
  configureDocsIconButton(download, {
1296
1663
  icon: 'download',
1297
1664
  pack: 'core',
1298
- label: 'Download als Markdown'
1665
+ label: getCurrentDocsLocale() === 'en' ? 'Download as Markdown' : 'Download als Markdown'
1299
1666
  });
1300
1667
  download.setAttribute('type', 'button');
1301
1668
  bindDocsButtonAction(download, async function(e) {
@@ -1305,9 +1672,10 @@ function wireDownloadButton(download, slug) {
1305
1672
  }
1306
1673
  if (download.hasAttribute('disabled')) return;
1307
1674
  const activeSlug = download.__xtendDocsDownloadSlug || slug;
1675
+ const locale = getCurrentDocsLocale();
1308
1676
  setDocsButtonBusy(download, true);
1309
1677
  try {
1310
- const resp = await fetch(`?download=${activeSlug}`);
1678
+ const resp = await fetch(`?download=${encodeURIComponent(activeSlug)}&locale=${encodeURIComponent(locale)}`);
1311
1679
  if (!resp.ok) throw new Error('Download fehlgeschlagen');
1312
1680
  const blob = await resp.blob();
1313
1681
  const url = URL.createObjectURL(blob);
@@ -1322,11 +1690,11 @@ function wireDownloadButton(download, slug) {
1322
1690
  URL.revokeObjectURL(url);
1323
1691
  }, 100);
1324
1692
  setTimeout(() => {
1325
- window.xtendShowToast('Download erfolgreich!', 'success', 3000);
1693
+ window.xtendShowToast(locale === 'en' ? 'Download complete.' : 'Download erfolgreich!', 'success', 3000);
1326
1694
  }, 200);
1327
1695
  } catch (err) {
1328
1696
  setTimeout(() => {
1329
- window.xtendShowToast('Download fehlgeschlagen!', 'error', 3000);
1697
+ window.xtendShowToast(getCurrentDocsLocale() === 'en' ? 'Download failed.' : 'Download fehlgeschlagen!', 'error', 3000);
1330
1698
  }, 200);
1331
1699
  } finally {
1332
1700
  setTimeout(() => {
@@ -1337,6 +1705,7 @@ function wireDownloadButton(download, slug) {
1337
1705
  }
1338
1706
 
1339
1707
  function createFallbackSearchShell() {
1708
+ const locale = getCurrentDocsLocale();
1340
1709
  const form = document.createElement('x-form');
1341
1710
  form.id = 'xtend-search-form';
1342
1711
  form.setAttribute('slot', 'search');
@@ -1346,12 +1715,12 @@ function createFallbackSearchShell() {
1346
1715
 
1347
1716
  const label = document.createElement('label');
1348
1717
  label.setAttribute('for', 'search-input');
1349
- label.textContent = 'Suche:';
1718
+ label.textContent = locale === 'en' ? 'Search:' : 'Suche:';
1350
1719
 
1351
1720
  const input = document.createElement('x-input');
1352
1721
  input.id = 'search-input';
1353
1722
  input.setAttribute('name', 'search');
1354
- input.setAttribute('placeholder', 'Suche...');
1723
+ input.setAttribute('placeholder', locale === 'en' ? 'Search...' : 'Suche...');
1355
1724
 
1356
1725
  const searchResults = document.createElement('div');
1357
1726
  searchResults.id = 'search-results';
@@ -1433,7 +1802,8 @@ function wireSearchForm(form, input, searchResults) {
1433
1802
  input.addEventListener('input', function() {
1434
1803
  const q = String(input.value || '').toLowerCase();
1435
1804
  const results = [];
1436
- Object.entries(window.xtendDocsTitles || {}).forEach(([slug, title]) => {
1805
+ const localizedTitles = getLocalizedDocsMap('xtendDocsLocalizedTitles', getCurrentDocsLocale());
1806
+ Object.entries(Object.keys(localizedTitles).length ? localizedTitles : (window.xtendDocsTitles || {})).forEach(([slug, title]) => {
1437
1807
  if (String(title).toLowerCase().includes(q)) {
1438
1808
  results.push({ slug, title });
1439
1809
  }
@@ -1443,14 +1813,14 @@ function wireSearchForm(form, input, searchResults) {
1443
1813
  if (q && results.length) {
1444
1814
  results.forEach((result, index) => {
1445
1815
  const link = document.createElement('x-link');
1446
- link.setAttribute('href', '/' + result.slug);
1816
+ link.setAttribute('href', getLocalizedDocsPath(result.slug));
1447
1817
  link.textContent = result.title;
1448
1818
  searchResults.appendChild(link);
1449
1819
  });
1450
1820
  searchResults.style.display = 'block';
1451
1821
  } else if (q) {
1452
1822
  const empty = document.createElement('em');
1453
- empty.textContent = 'Keine Treffer';
1823
+ empty.textContent = getCurrentDocsLocale() === 'en' ? 'No results' : 'Keine Treffer';
1454
1824
  searchResults.appendChild(empty);
1455
1825
  searchResults.style.display = 'block';
1456
1826
  } else {
@@ -1530,8 +1900,14 @@ function ensureMainBackgroundBinding() {
1530
1900
  }
1531
1901
 
1532
1902
  function getDocsPageSlugs() {
1533
- const metaSlugs = Object.keys(window.xtendDocsPagesMeta || {});
1903
+ const localizedMeta = getLocalizedDocsMap('xtendDocsLocalizedPagesMeta', getCurrentDocsLocale());
1904
+ const metaSlugs = Object.keys(localizedMeta || {});
1534
1905
  if (metaSlugs.length) return metaSlugs;
1906
+ const localizedPages = getLocalizedDocsMap('xtendDocsLocalizedPages', getCurrentDocsLocale());
1907
+ const pageSlugs = Object.keys(localizedPages || {});
1908
+ if (pageSlugs.length) return pageSlugs;
1909
+ const legacyMetaSlugs = Object.keys(window.xtendDocsPagesMeta || {});
1910
+ if (legacyMetaSlugs.length) return legacyMetaSlugs;
1535
1911
  return Object.keys(window.xtendDocsPages || {});
1536
1912
  }
1537
1913
 
@@ -1540,19 +1916,32 @@ function getDocsPageEndpoint() {
1540
1916
  return typeof endpoint === 'string' && endpoint ? endpoint : '';
1541
1917
  }
1542
1918
 
1543
- function buildDocsPagePayloadUrl(slug) {
1919
+ function buildDocsPagePayloadUrl(slug, locale = getCurrentDocsLocale()) {
1544
1920
  const endpoint = getDocsPageEndpoint();
1545
1921
  if (!endpoint) return '';
1546
- if (endpoint.includes('{slug}')) return endpoint.replace('{slug}', encodeURIComponent(slug));
1547
- return endpoint + encodeURIComponent(slug);
1922
+ if (endpoint.includes('{slug}') || endpoint.includes('{locale}')) {
1923
+ return endpoint
1924
+ .replace('{slug}', encodeURIComponent(slug))
1925
+ .replace('{locale}', encodeURIComponent(normalizeDocsLocale(locale)));
1926
+ }
1927
+ const separator = endpoint.includes('?') ? '&' : '?';
1928
+ return endpoint + encodeURIComponent(slug) + separator + 'locale=' + encodeURIComponent(normalizeDocsLocale(locale));
1548
1929
  }
1549
1930
 
1550
- function rememberDocsPagePayload(slug, payload = {}) {
1931
+ function rememberDocsPagePayload(slug, payload = {}, locale = getCurrentDocsLocale()) {
1932
+ const normalizedLocale = normalizeDocsLocale(payload.resolvedLocale || payload.locale || locale);
1551
1933
  if (!window.xtendDocsPages || typeof window.xtendDocsPages !== 'object') {
1552
1934
  window.xtendDocsPages = {};
1553
1935
  }
1936
+ if (!window.xtendDocsLocalizedPages || typeof window.xtendDocsLocalizedPages !== 'object') {
1937
+ window.xtendDocsLocalizedPages = {};
1938
+ }
1939
+ if (!window.xtendDocsLocalizedPages[normalizedLocale]) {
1940
+ window.xtendDocsLocalizedPages[normalizedLocale] = {};
1941
+ }
1554
1942
  if (typeof payload.html === 'string') {
1555
1943
  window.xtendDocsPages[slug] = payload.html;
1944
+ window.xtendDocsLocalizedPages[normalizedLocale][slug] = payload.html;
1556
1945
  }
1557
1946
  if (payload.meta && typeof payload.meta === 'object') {
1558
1947
  window.xtendDocsPagesMeta = {
@@ -1562,19 +1951,38 @@ function rememberDocsPagePayload(slug, payload = {}) {
1562
1951
  ...payload.meta
1563
1952
  }
1564
1953
  };
1954
+ window.xtendDocsLocalizedPagesMeta = {
1955
+ ...(window.xtendDocsLocalizedPagesMeta || {}),
1956
+ [normalizedLocale]: {
1957
+ ...((window.xtendDocsLocalizedPagesMeta && window.xtendDocsLocalizedPagesMeta[normalizedLocale]) || {}),
1958
+ [slug]: {
1959
+ ...(((window.xtendDocsLocalizedPagesMeta && window.xtendDocsLocalizedPagesMeta[normalizedLocale]) || {})[slug] || {}),
1960
+ ...payload.meta
1961
+ }
1962
+ }
1963
+ };
1565
1964
  }
1566
1965
  return payload;
1567
1966
  }
1568
1967
 
1569
- function loadDocsParsedownContent(slug, rmtMeta = {}) {
1570
- const inlineHtml = window.xtendDocsPages && typeof window.xtendDocsPages[slug] === 'string'
1571
- ? window.xtendDocsPages[slug]
1968
+ function loadDocsParsedownContent(slug, rmtMeta = {}, locale = getCurrentDocsLocale()) {
1969
+ const normalizedLocale = normalizeDocsLocale(locale);
1970
+ const localizedPages = getLocalizedDocsMap('xtendDocsLocalizedPages', normalizedLocale);
1971
+ const inlineHtml = localizedPages && typeof localizedPages[slug] === 'string'
1972
+ ? localizedPages[slug]
1973
+ : normalizedLocale === getDocsI18nConfig().fallbackLocale && window.xtendDocsPages && typeof window.xtendDocsPages[slug] === 'string'
1974
+ ? window.xtendDocsPages[slug]
1572
1975
  : null;
1573
1976
  if (inlineHtml !== null) {
1574
1977
  return Promise.resolve({
1575
1978
  schema: 'xtend.docs.parsedown-rmt-page-payload.v1',
1576
1979
  ok: true,
1577
1980
  slug,
1981
+ locale: normalizedLocale,
1982
+ requestedLocale: normalizedLocale,
1983
+ resolvedLocale: normalizedLocale,
1984
+ fallbackLocale: getDocsI18nConfig().fallbackLocale,
1985
+ translationAvailable: true,
1578
1986
  html: inlineHtml,
1579
1987
  meta: rmtMeta,
1580
1988
  source: 'inline',
@@ -1583,16 +1991,22 @@ function loadDocsParsedownContent(slug, rmtMeta = {}) {
1583
1991
  });
1584
1992
  }
1585
1993
 
1586
- if (DOCS_ROUTE_PAYLOAD_PROMISES.has(slug)) {
1587
- return DOCS_ROUTE_PAYLOAD_PROMISES.get(slug);
1994
+ const promiseKey = normalizedLocale + ':' + slug;
1995
+ if (DOCS_ROUTE_PAYLOAD_PROMISES.has(promiseKey)) {
1996
+ return DOCS_ROUTE_PAYLOAD_PROMISES.get(promiseKey);
1588
1997
  }
1589
1998
 
1590
- const url = buildDocsPagePayloadUrl(slug);
1999
+ const url = buildDocsPagePayloadUrl(slug, normalizedLocale);
1591
2000
  if (!url) {
1592
2001
  return Promise.resolve({
1593
2002
  schema: 'xtend.docs.parsedown-rmt-page-payload.v1',
1594
2003
  ok: false,
1595
2004
  slug,
2005
+ locale: normalizedLocale,
2006
+ requestedLocale: normalizedLocale,
2007
+ resolvedLocale: getDocsI18nConfig().fallbackLocale,
2008
+ fallbackLocale: getDocsI18nConfig().fallbackLocale,
2009
+ translationAvailable: false,
1596
2010
  html: '<em>Seite nicht gefunden</em>',
1597
2011
  meta: rmtMeta,
1598
2012
  source: 'missing-endpoint',
@@ -1614,11 +2028,16 @@ function loadDocsParsedownContent(slug, rmtMeta = {}) {
1614
2028
  .then((payload) => rememberDocsPagePayload(slug, {
1615
2029
  ...payload,
1616
2030
  cacheHit: false
1617
- }))
2031
+ }, normalizedLocale))
1618
2032
  .catch((error) => ({
1619
2033
  schema: 'xtend.docs.parsedown-rmt-page-payload.v1',
1620
2034
  ok: false,
1621
2035
  slug,
2036
+ locale: normalizedLocale,
2037
+ requestedLocale: normalizedLocale,
2038
+ resolvedLocale: getDocsI18nConfig().fallbackLocale,
2039
+ fallbackLocale: getDocsI18nConfig().fallbackLocale,
2040
+ translationAvailable: false,
1622
2041
  html: '<em>Seite nicht gefunden</em>',
1623
2042
  meta: rmtMeta,
1624
2043
  source: 'fetch-error',
@@ -1627,12 +2046,46 @@ function loadDocsParsedownContent(slug, rmtMeta = {}) {
1627
2046
  skeletonLoader: 'xtend.loader.skeleton-loader.v1'
1628
2047
  }))
1629
2048
  .finally(() => {
1630
- DOCS_ROUTE_PAYLOAD_PROMISES.delete(slug);
2049
+ DOCS_ROUTE_PAYLOAD_PROMISES.delete(promiseKey);
1631
2050
  });
1632
- DOCS_ROUTE_PAYLOAD_PROMISES.set(slug, promise);
2051
+ DOCS_ROUTE_PAYLOAD_PROMISES.set(promiseKey, promise);
1633
2052
  return promise;
1634
2053
  }
1635
2054
 
2055
+ function prefetchDocsLocalePage(slug = getCurrentDocsSlug(), locale = getCurrentDocsLocale()) {
2056
+ const normalizedSlug = slug || 'readme';
2057
+ const normalizedLocale = normalizeDocsLocale(locale);
2058
+ const localizedPages = getLocalizedDocsMap('xtendDocsLocalizedPages', normalizedLocale);
2059
+ if (localizedPages && typeof localizedPages[normalizedSlug] === 'string') {
2060
+ return Promise.resolve({
2061
+ schema: 'xtend.docs.locale-prefetch.v1',
2062
+ slug: normalizedSlug,
2063
+ locale: normalizedLocale,
2064
+ source: 'inline',
2065
+ cacheHit: true
2066
+ });
2067
+ }
2068
+ const rmtMeta = getDocsPageMeta(normalizedSlug, normalizedLocale) || {};
2069
+ return loadDocsParsedownContent(normalizedSlug, rmtMeta, normalizedLocale).then((payload) => ({
2070
+ schema: 'xtend.docs.locale-prefetch.v1',
2071
+ slug: normalizedSlug,
2072
+ locale: normalizedLocale,
2073
+ source: payload && payload.source ? payload.source : 'unknown',
2074
+ cacheHit: payload && payload.cacheHit === true,
2075
+ translationAvailable: payload ? payload.translationAvailable !== false : false
2076
+ }));
2077
+ }
2078
+
2079
+ function prefetchAlternateDocsLocales(slug = getCurrentDocsSlug()) {
2080
+ const config = getDocsI18nConfig();
2081
+ const current = getCurrentDocsLocale();
2082
+ config.available.forEach((locale) => {
2083
+ if (normalizeDocsLocale(locale) !== current) {
2084
+ prefetchDocsLocalePage(slug, locale).catch(() => {});
2085
+ }
2086
+ });
2087
+ }
2088
+
1636
2089
  function normalizeMarkdownLinks(html) {
1637
2090
  return String(html || '').replace(/<a href=["']([^"'#?]+)["']>(.*?)<\/a>/g, function(match, href, text) {
1638
2091
  if (!href.endsWith('.md')) return match;
@@ -1669,7 +2122,7 @@ function normalizeMarkdownLinks(html) {
1669
2122
  foundSlug = norm.replace(/\//g, '-').replace(/\.md$/, '').toLowerCase();
1670
2123
  }
1671
2124
  }
1672
- return `<x-link href='/${foundSlug}'>${text}</x-link>`;
2125
+ return `<x-link href='${getLocalizedDocsPath(foundSlug)}'>${text}</x-link>`;
1673
2126
  });
1674
2127
  }
1675
2128
 
@@ -1707,6 +2160,57 @@ function normalizeDocsParsedownCodeEntities(root) {
1707
2160
  return normalizedCount;
1708
2161
  }
1709
2162
 
2163
+ function normalizeDocsCodeLanguage(value) {
2164
+ const raw = String(value || 'text').trim().toLowerCase();
2165
+ const aliases = {
2166
+ js: 'javascript',
2167
+ html: 'markup',
2168
+ xml: 'markup',
2169
+ svg: 'markup',
2170
+ md: 'markdown',
2171
+ txt: 'text',
2172
+ plaintext: 'text',
2173
+ 'rmt-vnext': 'rmt',
2174
+ xtendrmt: 'rmt'
2175
+ };
2176
+ return aliases[raw] || raw || 'text';
2177
+ }
2178
+
2179
+ function readDocsCodeLanguage(node) {
2180
+ const className = String(node.getAttribute('class') || '');
2181
+ const match = className.match(/(?:^|\s)(?:language|lang)-([A-Za-z0-9_+-]+)/);
2182
+ return normalizeDocsCodeLanguage(node.getAttribute('data-language') || (match && match[1]) || 'text');
2183
+ }
2184
+
2185
+ function upgradeDocsParsedownCodeFences(root, options = {}) {
2186
+ const schedule = options.schedule || 'docs.syntax.highlight';
2187
+ const scope = root && root.querySelectorAll ? root : document;
2188
+ let count = 0;
2189
+ Array.from(scope.querySelectorAll('pre > code')).forEach((codeNode) => {
2190
+ const pre = codeNode.parentElement;
2191
+ if (!pre || pre.closest('x-code') || pre.hasAttribute('data-docs-code-fence-upgraded')) return;
2192
+ const language = readDocsCodeLanguage(codeNode);
2193
+ const codeElement = document.createElement('x-code');
2194
+ codeElement.className = 'docs-code-fence';
2195
+ codeElement.setAttribute('lang', language);
2196
+ codeElement.setAttribute('data-docs-code-fence-upgraded', 'true');
2197
+ codeElement.setAttribute('data-rmt-component', 'docs.codeFence');
2198
+ codeElement.setAttribute('data-rmt-schedule', schedule);
2199
+ codeElement.setAttribute('data-rmt-syntax-language', language);
2200
+ const template = document.createElement('template');
2201
+ template.setAttribute('data-x-code-mode', 'text');
2202
+ template.content.appendChild(document.createTextNode(codeNode.textContent || ''));
2203
+ codeElement.appendChild(template);
2204
+ pre.replaceWith(codeElement);
2205
+ count += 1;
2206
+ });
2207
+ return {
2208
+ schema: 'xtend.docs.xcode-fence-upgrade.v1',
2209
+ upgraded: count,
2210
+ schedule
2211
+ };
2212
+ }
2213
+
1710
2214
  function sanitizeDocsTrustedDomHtml(html, options = {}) {
1711
2215
  const template = document.createElement('template');
1712
2216
  const removed = [];
@@ -1753,7 +2257,10 @@ function sanitizeDocsTrustedDomHtml(html, options = {}) {
1753
2257
  }
1754
2258
 
1755
2259
  function prepareDocsTrustedDomHtml(slug, html, options = {}) {
1756
- const cacheKey = createDocsRouteContentCacheKey(slug, html, options);
2260
+ const cacheKey = createDocsRouteContentCacheKey(slug, html, {
2261
+ ...options,
2262
+ locale: options.locale || getCurrentDocsLocale()
2263
+ });
1757
2264
  const cached = DOCS_ROUTE_CONTENT_CACHE.get(cacheKey);
1758
2265
  if (cached) return cloneDocsSanitizeResult(cached, true);
1759
2266
 
@@ -1768,9 +2275,15 @@ function prepareDocsTrustedDomHtml(slug, html, options = {}) {
1768
2275
  function applyDocsTrustedDomHtml(target, html, options = {}) {
1769
2276
  const result = prepareDocsTrustedDomHtml(options.slug || '', html, options);
1770
2277
  target.innerHTML = result.html;
2278
+ const codeFenceUpgrade = upgradeDocsParsedownCodeFences(target, {
2279
+ schedule: options.syntaxSchedule || 'docs.syntax.highlight'
2280
+ });
2281
+ result.codeFenceUpgrade = codeFenceUpgrade;
2282
+ result.upgradedCodeFenceCount = codeFenceUpgrade.upgraded;
1771
2283
  target.setAttribute('data-rmt-sanitized', 'true');
1772
2284
  target.setAttribute('data-rmt-sanitizer', DOCS_RMT_TRUSTED_DOM_SANITIZER);
1773
2285
  target.setAttribute('data-rmt-trusted-dom-proof', DOCS_RMT_TRUSTED_DOM_PROOF_SCHEMA);
2286
+ target.setAttribute('data-docs-code-fence-upgraded', String(codeFenceUpgrade.upgraded));
1774
2287
  target.setAttribute('data-rmt-content-cache-hit', result.cacheHit ? 'true' : 'false');
1775
2288
  window.xtendDocsTrustedDomLastSanitize = result;
1776
2289
  return result;
@@ -1781,7 +2294,8 @@ window.xtendDocsTrustedDomBoundary = Object.freeze({
1781
2294
  sanitizer: DOCS_RMT_TRUSTED_DOM_SANITIZER,
1782
2295
  trustBoundary: DOCS_RMT_TRUST_BOUNDARY,
1783
2296
  sanitize: sanitizeDocsTrustedDomHtml,
1784
- apply: applyDocsTrustedDomHtml
2297
+ apply: applyDocsTrustedDomHtml,
2298
+ upgradeCodeFences: upgradeDocsParsedownCodeFences
1785
2299
  });
1786
2300
 
1787
2301
  function upgradeRoutedLinks(root) {
@@ -1799,12 +2313,14 @@ function upgradeRoutedLinks(root) {
1799
2313
  function syncActiveHeaderLink(slug) {
1800
2314
  const header = document.querySelector('x-header');
1801
2315
  if (!header) return;
2316
+ const locale = getCurrentDocsLocale();
2317
+ const localizedHref = getLocalizedDocsPath(slug, locale);
1802
2318
  header.querySelectorAll('x-link').forEach((a) => a.removeAttribute('active'));
1803
2319
  header.querySelectorAll('details[data-docs-menu-children]').forEach((details) => {
1804
2320
  details.open = false;
1805
2321
  syncDocsMenuDisclosureState(details);
1806
2322
  });
1807
- const active = header.querySelector('x-link[href="#/' + slug + '"], x-link[href="/' + slug + '"]');
2323
+ const active = header.querySelector('x-link[href="#' + localizedHref + '"], x-link[href="' + localizedHref + '"], x-link[href="#/' + slug + '"], x-link[href="/' + slug + '"]');
1808
2324
  if (active) {
1809
2325
  active.setAttribute('active', '');
1810
2326
  let parent = active.parentElement;
@@ -1864,8 +2380,8 @@ async function loadMenuConfig() {
1864
2380
  }
1865
2381
 
1866
2382
  function getCurrentDocsSlug() {
1867
- const slug = location.hash.replace(/^#\/?/, '').replace(/^\/+/, '') || 'readme';
1868
- return slug === '' || slug === '/' ? 'readme' : slug;
2383
+ const parsed = parseDocsRoutePath(location.hash);
2384
+ return parsed.slug === '' || parsed.slug === '/' ? 'readme' : parsed.slug;
1869
2385
  }
1870
2386
 
1871
2387
  function resolveDocsMenuGroup(entry) {
@@ -1882,17 +2398,30 @@ function resolveDocsMenuGroup(entry) {
1882
2398
  }
1883
2399
 
1884
2400
  function getDocsMenuGroupLabel(groupId) {
2401
+ const locale = getCurrentDocsLocale();
1885
2402
  const labels = {
1886
- start: 'Start',
1887
- core: 'Core',
1888
- platform: 'Platform',
1889
- components: 'Komponenten',
1890
- rmt: 'XTendRMT',
1891
- quality: 'Quality',
1892
- security: 'Security',
1893
- release: 'Release'
2403
+ de: {
2404
+ start: 'Start',
2405
+ core: 'Core',
2406
+ platform: 'Platform',
2407
+ components: 'Komponenten',
2408
+ rmt: 'XTendRMT',
2409
+ quality: 'Quality',
2410
+ security: 'Security',
2411
+ release: 'Release'
2412
+ },
2413
+ en: {
2414
+ start: 'Start',
2415
+ core: 'Core',
2416
+ platform: 'Platform',
2417
+ components: 'Components',
2418
+ rmt: 'XTendRMT',
2419
+ quality: 'Quality',
2420
+ security: 'Security',
2421
+ release: 'Release'
2422
+ }
1894
2423
  };
1895
- return labels[groupId] || groupId;
2424
+ return (labels[locale] && labels[locale][groupId]) || labels.de[groupId] || groupId;
1896
2425
  }
1897
2426
 
1898
2427
  function getDocsMenuGroupIcon(groupId) {
@@ -1982,8 +2511,12 @@ function getDocsMenuTier(entry) {
1982
2511
  }
1983
2512
 
1984
2513
  function normalizeDocsMenuEntry(entry) {
2514
+ const locale = getCurrentDocsLocale();
1985
2515
  const slug = entry && entry.slug ? String(entry.slug) : '';
1986
- const label = entry && entry.label
2516
+ const localizedLabel = entry && entry.labels && (entry.labels[locale] || entry.labels[getDocsI18nConfig().fallbackLocale]);
2517
+ const label = localizedLabel
2518
+ ? String(localizedLabel)
2519
+ : entry && entry.label
1987
2520
  ? String(entry.label)
1988
2521
  : slug.replace(/^components-/, '').replace(/-/g, ' ');
1989
2522
  const parent = entry && entry.parent ? String(entry.parent) : '';
@@ -2003,7 +2536,7 @@ function normalizeDocsMenuEntry(entry) {
2003
2536
  function sortDocsMenuEntries(entries = []) {
2004
2537
  return entries.sort((a, b) => {
2005
2538
  if (b.rank !== a.rank) return b.rank - a.rank;
2006
- return String(a.label).localeCompare(String(b.label), 'de');
2539
+ return String(a.label).localeCompare(String(b.label), getCurrentDocsLocale());
2007
2540
  });
2008
2541
  }
2009
2542
 
@@ -2046,6 +2579,7 @@ function groupDocsMenuEntries(entries = []) {
2046
2579
  function renderMenu() {
2047
2580
  const header = document.querySelector('x-header');
2048
2581
  if (!header) return;
2582
+ const locale = getCurrentDocsLocale();
2049
2583
  Array.from(header.querySelectorAll('x-link[slot="nav"]')).forEach((el) => el.remove());
2050
2584
  Array.from(header.querySelectorAll('[data-docs-menu-shell]')).forEach((el) => el.remove());
2051
2585
  const menu = window.xtendMenuConfig && window.xtendMenuConfig.length
@@ -2058,7 +2592,7 @@ function renderMenu() {
2058
2592
  shell.setAttribute('data-docs-menu-shell', '');
2059
2593
  shell.className = 'docs-menu-shell';
2060
2594
  shell.setAttribute('role', 'list');
2061
- shell.setAttribute('aria-label', 'Dokumentationsbereiche');
2595
+ shell.setAttribute('aria-label', locale === 'en' ? 'Documentation sections' : 'Dokumentationsbereiche');
2062
2596
 
2063
2597
  const renderMenuNode = (entry, depth = 0) => {
2064
2598
  const node = document.createElement('div');
@@ -2070,7 +2604,7 @@ function renderMenu() {
2070
2604
 
2071
2605
  const link = document.createElement('x-link');
2072
2606
  link.className = 'docs-menu-link';
2073
- link.setAttribute('href', '/' + entry.slug);
2607
+ link.setAttribute('href', getLocalizedDocsPath(entry.slug, locale));
2074
2608
  link.setAttribute('data-docs-menu-link', '');
2075
2609
  link.setAttribute('data-doc-id', entry.id);
2076
2610
  link.setAttribute('data-doc-rank', String(entry.rank));
@@ -2104,7 +2638,10 @@ function renderMenu() {
2104
2638
  summaryIcon.setAttribute('size', '0.9rem');
2105
2639
  const summaryLabel = document.createElement('span');
2106
2640
  summaryLabel.className = 'docs-menu-disclosure-label';
2107
- summaryLabel.textContent = depth === 0 ? 'Deep Dives' : 'Weitere Themen';
2641
+ // Contract anchor: summaryLabel.textContent = depth === 0 ? 'Deep Dives' : 'Weitere Themen'
2642
+ summaryLabel.textContent = locale === 'en'
2643
+ ? (depth === 0 ? 'Deep Dives' : 'More Topics')
2644
+ : (depth === 0 ? 'Deep Dives' : 'Weitere Themen');
2108
2645
  const summaryCount = document.createElement('span');
2109
2646
  summaryCount.className = 'docs-menu-disclosure-count';
2110
2647
  summaryCount.textContent = String(entry.children.length);
@@ -2174,9 +2711,142 @@ function ensureMenuBinding() {
2174
2711
  window.__xtendDocsMenuBound = true;
2175
2712
  loadMenuConfig().then(renderMenu);
2176
2713
  window.addEventListener('hashchange', () => syncActiveHeaderLink(getCurrentDocsSlug()));
2714
+ window.addEventListener('xtend-docs-locale-changed', (event) => {
2715
+ const locale = event && event.detail && event.detail.locale ? event.detail.locale : getCurrentDocsLocale();
2716
+ const slug = getCurrentDocsSlug();
2717
+ syncLegacyDocsGlobals(locale, { slug });
2718
+ if (window.__xtendDocsMenuLocaleDisposer) window.__xtendDocsMenuLocaleDisposer();
2719
+ window.__xtendDocsMenuLocaleDisposer = scheduleDocsIdle(() => {
2720
+ window.__xtendDocsMenuLocaleDisposer = null;
2721
+ renderMenu();
2722
+ }, 140);
2723
+ });
2724
+ }
2725
+
2726
+ function updateDocsLocaleBusyUi(transition = window.__xtendDocsLocaleTransition || window.__xtendDocsLocaleLastTransition || null) {
2727
+ const busy = Boolean(transition && transition.busy);
2728
+ const locale = transition && transition.targetLocale ? transition.targetLocale : getCurrentDocsLocale();
2729
+ const control = document.querySelector('[data-docs-language-control]');
2730
+ const status = document.querySelector('[data-docs-language-status]');
2731
+ const label = document.querySelector('[data-docs-language-status-label]');
2732
+ if (control) {
2733
+ control.toggleAttribute('data-docs-locale-busy', busy);
2734
+ control.setAttribute('aria-busy', busy ? 'true' : 'false');
2735
+ }
2736
+ if (status) {
2737
+ status.hidden = !busy;
2738
+ }
2739
+ if (label) {
2740
+ label.textContent = locale === 'en' ? 'Loading' : 'Lädt';
2741
+ }
2742
+ }
2743
+
2744
+ function updateDocsLocaleUi(locale = getCurrentDocsLocale(), options = {}) {
2745
+ const targetLocale = normalizeDocsLocale(locale);
2746
+ const shouldPublish = options.publish !== false;
2747
+ const normalized = !shouldPublish
2748
+ ? targetLocale
2749
+ : window.xtendDocsCurrentLocale && normalizeDocsLocale(window.xtendDocsCurrentLocale) === targetLocale
2750
+ ? targetLocale
2751
+ : publishDocsLocale(targetLocale, window.__xtendDocsLocaleUserSelected ? 'user' : 'route');
2752
+ syncLegacyDocsGlobals(normalized, { slug: options.slug || getCurrentDocsSlug() });
2753
+ const headerTitle = document.querySelector('x-header [slot="title"]');
2754
+ if (headerTitle) {
2755
+ headerTitle.textContent = normalized === 'en' ? 'XTend Documentation' : 'XTend Dokumentation';
2756
+ }
2757
+ const control = document.querySelector('[data-docs-language-control]');
2758
+ if (control) {
2759
+ control.setAttribute('aria-label', normalized === 'en' ? 'Change language' : 'Sprache wechseln');
2760
+ }
2761
+ const select = document.getElementById('docs-language-select');
2762
+ if (select && select.getAttribute('value') !== normalized) {
2763
+ select.setAttribute('value', normalized);
2764
+ if ('value' in select) {
2765
+ try { select.value = normalized; } catch (error) {}
2766
+ }
2767
+ }
2768
+ if (select) {
2769
+ select.setAttribute('label', normalized === 'en' ? 'Language' : 'Sprache');
2770
+ }
2771
+ updateDocsLocaleBusyUi(options.busy === false ? { busy: false, targetLocale: normalized } : window.__xtendDocsLocaleTransition);
2772
+ document.querySelectorAll('[data-docs-locale-label]').forEach((node) => {
2773
+ const text = node.getAttribute('data-docs-locale-label-' + normalized);
2774
+ if (text) node.textContent = text;
2775
+ });
2776
+ return normalized;
2777
+ }
2778
+
2779
+ function navigateDocsLocale(locale, source = 'user') {
2780
+ const normalized = normalizeDocsLocale(locale);
2781
+ const slug = getCurrentDocsSlug();
2782
+ const currentRoute = parseDocsRoutePath(location.hash);
2783
+ if (source === 'user') {
2784
+ window.__xtendDocsLocaleUserSelected = true;
2785
+ writeStoredDocsLocale(normalized);
2786
+ }
2787
+ if (normalized === getCurrentDocsLocale() && currentRoute.localized && currentRoute.locale === normalized && !window.__xtendDocsLocaleTransition) {
2788
+ completeDocsLocaleTransition(normalized, slug, { source, status: 'ready' });
2789
+ updateDocsLocaleUi(normalized, { publish: false, busy: false, slug });
2790
+ return;
2791
+ }
2792
+ beginDocsLocaleTransition(normalized, { source, slug });
2793
+ syncLegacyDocsGlobals(normalized, { slug });
2794
+ prefetchDocsLocalePage(slug, normalized).catch(() => {});
2795
+ window.__xtendDocsPendingLocaleRoute = window.__xtendDocsLocaleTransition;
2796
+ const nextHash = '#' + getLocalizedDocsPath(slug, normalized);
2797
+ if (location.hash !== nextHash) {
2798
+ location.hash = nextHash;
2799
+ } else {
2800
+ const page = document.querySelector('xtend-doc-page');
2801
+ if (page && typeof page.updateRoute === 'function') {
2802
+ page.updateRoute({ path: getLocalizedDocsPath(slug, normalized), source: 'locale-change' });
2803
+ }
2804
+ }
2805
+ updateDocsLocaleUi(normalized, { publish: false, busy: true, slug });
2806
+ }
2807
+
2808
+ function ensureDocsLanguageSelectBinding() {
2809
+ if (window.__xtendDocsLanguageSelectBound) return;
2810
+ window.__xtendDocsLanguageSelectBound = true;
2811
+ updateDocsLocaleUi(getCurrentDocsLocale());
2812
+ const maybePrefetchLanguageTarget = (event) => {
2813
+ const control = event.target && event.target.closest
2814
+ ? event.target.closest('[data-docs-language-control], #docs-language-select')
2815
+ : null;
2816
+ if (!control) return;
2817
+ prefetchAlternateDocsLocales(getCurrentDocsSlug());
2818
+ };
2819
+ document.addEventListener('pointerdown', maybePrefetchLanguageTarget, { passive: true });
2820
+ document.addEventListener('focusin', maybePrefetchLanguageTarget);
2821
+ document.addEventListener('select-changed', (event) => {
2822
+ const select = event.target && event.target.closest
2823
+ ? event.target.closest('#docs-language-select')
2824
+ : null;
2825
+ if (!select) return;
2826
+ const value = event.detail && event.detail.value ? event.detail.value : select.getAttribute('value');
2827
+ navigateDocsLocale(value, 'user');
2828
+ });
2829
+ window.addEventListener('hashchange', () => {
2830
+ const parsed = parseDocsRoutePath(location.hash);
2831
+ updateDocsLocaleUi(parsed.locale, {
2832
+ publish: false,
2833
+ busy: Boolean(window.__xtendDocsLocaleTransition),
2834
+ slug: parsed.slug || getCurrentDocsSlug()
2835
+ });
2836
+ });
2837
+ if (window.xstate && typeof window.xstate.subscribe === 'function') {
2838
+ const config = getDocsI18nConfig();
2839
+ window.xstate.subscribe((key, value) => {
2840
+ if (key === config.stateKeys.locale && value && normalizeDocsLocale(value) !== getCurrentDocsLocale()) {
2841
+ navigateDocsLocale(value, 'xstate');
2842
+ }
2843
+ }, config.stateKeys.locale);
2844
+ }
2177
2845
  }
2178
2846
 
2179
2847
  function docsPageExists(slug) {
2848
+ const localized = getLocalizedDocsMap('xtendDocsLocalizedPagesMeta', getCurrentDocsLocale());
2849
+ if (localized && localized[slug]) return true;
2180
2850
  return Boolean(slug && (
2181
2851
  window.xtendDocsPages && window.xtendDocsPages[slug] ||
2182
2852
  window.xtendDocsPagesMeta && window.xtendDocsPagesMeta[slug]
@@ -2184,7 +2854,9 @@ function docsPageExists(slug) {
2184
2854
  }
2185
2855
 
2186
2856
  function docsTitleForSlug(slug) {
2187
- return (window.xtendDocsTitles && window.xtendDocsTitles[slug]) ||
2857
+ const localizedTitles = getLocalizedDocsMap('xtendDocsLocalizedTitles', getCurrentDocsLocale());
2858
+ return (localizedTitles && localizedTitles[slug]) ||
2859
+ (window.xtendDocsTitles && window.xtendDocsTitles[slug]) ||
2188
2860
  (slug ? slug.replace(/^components-/, '').replace(/-/g, ' ') : '');
2189
2861
  }
2190
2862
 
@@ -2325,7 +2997,7 @@ function fallbackRelatedLinksForSlug(slug) {
2325
2997
  function createRelatedLink(entry) {
2326
2998
  const link = document.createElement('x-link');
2327
2999
  link.className = 'docs-related-link';
2328
- const href = entry.href || (entry.slug ? '/' + entry.slug : '#');
3000
+ const href = entry.href || (entry.slug ? getLocalizedDocsPath(entry.slug) : '#');
2329
3001
  link.setAttribute('href', href);
2330
3002
  link.setAttribute('data-rmt-component', 'docs.relatedLinks');
2331
3003
  if (entry.slug) {
@@ -2527,16 +3199,22 @@ function renderDocsComponentDemo(demoSlot, slug) {
2527
3199
  if (code) {
2528
3200
  while (code.firstChild) code.removeChild(code.firstChild);
2529
3201
  code.appendChild(createDemoCodeBlock('HTML', 'html', demo.html, 'html'));
2530
- code.appendChild(createDemoCodeBlock('RMT', 'json', demo.rmt, 'text'));
3202
+ code.appendChild(createDemoCodeBlock('RMT', 'rmt', demo.rmt, 'text'));
2531
3203
  }
2532
3204
  }
2533
3205
 
2534
3206
  function resolveDocsSlugFromRouteContext(context = {}) {
2535
3207
  const explicit = context.slug || context.path || context.to || '';
2536
- const raw = explicit ? String(explicit) : location.hash;
2537
- const withoutQuery = raw.split('?')[0];
2538
- let slug = withoutQuery.replace(/^#\/?/, '').replace(/^\/+/, '') || 'readme';
3208
+ const parsed = parseDocsRoutePath(explicit ? String(explicit) : location.hash);
3209
+ publishDocsLocale(parsed.locale, parsed.localized ? 'route' : 'compat-route');
3210
+ let slug = parsed.slug || 'readme';
2539
3211
  if (slug === '' || slug === '/') slug = 'readme';
3212
+ if (!parsed.localized) {
3213
+ const localizedPath = getLocalizedDocsPath(slug, parsed.locale);
3214
+ if (location.hash !== '#' + localizedPath) {
3215
+ history.replaceState(null, '', '#' + localizedPath);
3216
+ }
3217
+ }
2540
3218
  return slug;
2541
3219
  }
2542
3220
 
@@ -2557,7 +3235,7 @@ class XtendDocPage extends HTMLElement {
2557
3235
  }
2558
3236
 
2559
3237
  updateRoute(context = {}) {
2560
- return this.renderRoute({ ...context, source: 'x-router-reuse' });
3238
+ return this.renderRoute({ ...context, source: context.source || 'x-router-reuse' });
2561
3239
  }
2562
3240
 
2563
3241
  cancelScheduledRouteWork() {
@@ -2576,6 +3254,16 @@ class XtendDocPage extends HTMLElement {
2576
3254
 
2577
3255
  ensureRouteShell(slug, rmtMeta) {
2578
3256
  if (!this.__xtendDocsShell) {
3257
+ const ssrPrehydration = getDocsSsrPrehydration();
3258
+ const prehydratedShell = ssrPrehydration && ssrPrehydration.ok !== false
3259
+ ? adoptPrehydratedDocsShell(findPrehydratedDocsShell(this, slug), rmtMeta)
3260
+ : null;
3261
+ if (prehydratedShell) {
3262
+ this.__xtendDocsShell = prehydratedShell;
3263
+ this.setAttribute('data-docs-shell-reused', 'ssr');
3264
+ this.setAttribute('data-rmt-ssr-reused', 'true');
3265
+ return this.__xtendDocsShell;
3266
+ }
2579
3267
  this.__xtendDocsShell = createRmtDocsShell(slug, rmtMeta);
2580
3268
  this.innerHTML = '';
2581
3269
  this.appendChild(this.__xtendDocsShell.section);
@@ -2592,18 +3280,31 @@ class XtendDocPage extends HTMLElement {
2592
3280
  this.__xtendDocsRouteToken = token;
2593
3281
 
2594
3282
  const slug = resolveDocsSlugFromRouteContext(context);
3283
+ const locale = getCurrentDocsLocale();
3284
+ syncLegacyDocsGlobals(locale, { slug });
3285
+ const pendingLocaleRoute = window.__xtendDocsPendingLocaleRoute;
3286
+ const localeRouteFastPath = context.source === 'locale-change' || Boolean(
3287
+ pendingLocaleRoute &&
3288
+ pendingLocaleRoute.slug === slug &&
3289
+ pendingLocaleRoute.targetLocale === locale &&
3290
+ docsPerfNow() - Number(pendingLocaleRoute.startedAtMs || 0) < 8000
3291
+ );
3292
+ if (localeRouteFastPath) {
3293
+ window.__xtendDocsPendingLocaleRoute = null;
3294
+ }
2595
3295
  const docsRouteStartedAt = new Date().toISOString();
2596
3296
  const routePerfStartedAt = docsPerfNow();
2597
3297
  const reducedMotion = window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches;
2598
- const reused = context.source === 'x-router-reuse' || context.reused === true;
3298
+ const reused = context.source === 'x-router-reuse' || context.source === 'locale-change' || context.reused === true;
2599
3299
 
2600
3300
  this.setAttribute('data-docs-route-state', reducedMotion ? 'ready' : 'loading');
2601
3301
  this.setAttribute('data-docs-route-slug', slug);
3302
+ this.setAttribute('data-docs-route-locale', locale);
2602
3303
  this.setAttribute('data-docs-route-reused', reused ? 'true' : 'false');
2603
3304
  this.setAttribute('aria-busy', 'true');
2604
3305
  ensureDocsShellScopedStyles(this.getRootNode());
2605
3306
 
2606
- const rmtMeta = getDocsPageMeta(slug) || {};
3307
+ const rmtMeta = getDocsPageMeta(slug, locale) || {};
2607
3308
  const hadShell = Boolean(this.__xtendDocsShell);
2608
3309
  const shell = this.ensureRouteShell(slug, rmtMeta);
2609
3310
  applyRmtPageMetadata(shell.section, shell.mdContent, shell.richSlot, shell.diagnosticsSlot, rmtMeta, shell.sidebar, shell.relatedSlot, shell.demoSlot);
@@ -2638,8 +3339,11 @@ class XtendDocPage extends HTMLElement {
2638
3339
  window.xtendDocsRmtLastRender = {
2639
3340
  schema: DOCS_RMT_RENDER_SCHEMA,
2640
3341
  slug,
3342
+ locale,
2641
3343
  shellFirst: true,
2642
3344
  shellReused: hadShell,
3345
+ shellPrehydrated: Boolean(shell && shell.prehydrated),
3346
+ phpSsrPrehydration: getDocsSsrPrehydration(),
2643
3347
  routeReuse: reused,
2644
3348
  insularHydration: true,
2645
3349
  productionHardeningSchema: DOCS_RMT_PRODUCTION_HARDENING_SCHEMA,
@@ -2686,12 +3390,12 @@ class XtendDocPage extends HTMLElement {
2686
3390
  variant: 'article',
2687
3391
  lines: 11,
2688
3392
  minHeight: '24rem',
2689
- label: 'Dokumentationsinhalt wird geladen',
3393
+ label: locale === 'en' ? 'Documentation content is loading' : 'Dokumentationsinhalt wird geladen',
2690
3394
  source: 'docs.parsedown',
2691
3395
  schedule: parseSchedule
2692
3396
  });
2693
3397
 
2694
- const contentPayloadPromise = loadDocsParsedownContent(slug, rmtMeta);
3398
+ const contentPayloadPromise = loadDocsParsedownContent(slug, rmtMeta, locale);
2695
3399
  let relatedLinks = [];
2696
3400
  let contentCommitted = false;
2697
3401
 
@@ -2708,13 +3412,18 @@ class XtendDocPage extends HTMLElement {
2708
3412
  : rmtMeta;
2709
3413
  const trustedDomResult = measuredLane('visible', parseSchedule, 'article.trusted-dom-commit', () => applyDocsTrustedDomHtml(shell.mdContent, html, {
2710
3414
  slug,
3415
+ locale,
2711
3416
  source: payloadMeta.source || rmtMeta.source || 'docs.parsedown',
2712
3417
  markupClass: payloadMeta.markupClass || rmtMeta.markupClass || 'parsedownHtml',
2713
- trustBoundary: payloadMeta.trustBoundary || rmtMeta.trustBoundary || DOCS_RMT_TRUST_BOUNDARY
3418
+ trustBoundary: payloadMeta.trustBoundary || rmtMeta.trustBoundary || DOCS_RMT_TRUST_BOUNDARY,
3419
+ syntaxSchedule: 'docs.syntax.highlight'
2714
3420
  }));
2715
3421
  hideDocsSkeleton(shell.mdContent);
2716
3422
  window.xtendDocsRmtLastRender.lazyPayload = payload && payload.source !== 'inline';
2717
3423
  window.xtendDocsRmtLastRender.payloadSource = payload ? payload.source : 'unknown';
3424
+ window.xtendDocsRmtLastRender.requestedLocale = payload ? payload.requestedLocale : locale;
3425
+ window.xtendDocsRmtLastRender.resolvedLocale = payload ? payload.resolvedLocale : locale;
3426
+ window.xtendDocsRmtLastRender.translationAvailable = payload ? payload.translationAvailable !== false : true;
2718
3427
  window.xtendDocsRmtLastRender.skeletonLoader = 'xtend.loader.skeleton-loader.v1';
2719
3428
  window.xtendDocsRmtProductionLastRender.trustedDom = {
2720
3429
  schema: trustedDomResult.schema,
@@ -2734,15 +3443,21 @@ class XtendDocPage extends HTMLElement {
2734
3443
  };
2735
3444
 
2736
3445
  let transitionCompleted = false;
2737
- const finishTransition = () => {
3446
+ const finishTransition = (status = 'ready', error = null) => {
2738
3447
  if (!this.isActiveRouteToken(token) || transitionCompleted) return;
2739
3448
  transitionCompleted = true;
2740
3449
  this.setAttribute('data-docs-route-state', 'ready');
2741
3450
  this.removeAttribute('aria-busy');
3451
+ completeDocsLocaleTransition(locale, slug, {
3452
+ status,
3453
+ error,
3454
+ source: context.source || 'route'
3455
+ });
2742
3456
  window.dispatchEvent(new CustomEvent('xtend-docs-route-transition', {
2743
3457
  detail: {
2744
3458
  schema: 'xtend.docs.route-transition.v1',
2745
3459
  slug,
3460
+ locale,
2746
3461
  reducedMotion,
2747
3462
  reused,
2748
3463
  insularHydration: true,
@@ -2757,6 +3472,7 @@ class XtendDocPage extends HTMLElement {
2757
3472
  schedule: routeSchedule,
2758
3473
  routeSchedule,
2759
3474
  hydrateSchedule,
3475
+ localeStatus: status,
2760
3476
  relatedSchedule,
2761
3477
  demoSchedule,
2762
3478
  diagnosticsSchedule,
@@ -2767,7 +3483,7 @@ class XtendDocPage extends HTMLElement {
2767
3483
  }));
2768
3484
  };
2769
3485
 
2770
- const afterPaintDisposer = scheduleDocsAfterPaint(() => {
3486
+ const completeParsedownCommit = () => {
2771
3487
  if (!this.isActiveRouteToken(token)) return;
2772
3488
  commitParsedownContent().then((committed) => {
2773
3489
  if (!committed || !this.isActiveRouteToken(token)) return;
@@ -2776,6 +3492,10 @@ class XtendDocPage extends HTMLElement {
2776
3492
  detail: {
2777
3493
  schema: 'xtend.docs.content-ready.v1',
2778
3494
  slug,
3495
+ locale,
3496
+ requestedLocale: window.xtendDocsRmtLastRender.requestedLocale,
3497
+ resolvedLocale: window.xtendDocsRmtLastRender.resolvedLocale,
3498
+ translationAvailable: window.xtendDocsRmtLastRender.translationAvailable,
2779
3499
  routeRef: rmtMeta.routeId || ('docs.' + slug.replace(/-/g, '.')),
2780
3500
  root: shell.mdContent,
2781
3501
  schedule: hydrateSchedule,
@@ -2785,6 +3505,11 @@ class XtendDocPage extends HTMLElement {
2785
3505
  skeletonLoader: 'xtend.loader.skeleton-loader.v1'
2786
3506
  }
2787
3507
  }));
3508
+ hydrateDocsCodeBlocks(shell.mdContent, {
3509
+ slug,
3510
+ reason: 'parsedown-code-fence-syntax-highlight',
3511
+ schedule: 'docs.syntax.highlight'
3512
+ });
2788
3513
  finishTransition();
2789
3514
  }).catch((error) => {
2790
3515
  if (!this.isActiveRouteToken(token)) return;
@@ -2794,14 +3519,26 @@ class XtendDocPage extends HTMLElement {
2794
3519
  detail: {
2795
3520
  schema: 'xtend.docs.content-error.v1',
2796
3521
  slug,
3522
+ locale,
2797
3523
  schedule: parseSchedule,
2798
3524
  message: error && error.message ? error.message : String(error)
2799
3525
  }
2800
3526
  }));
2801
- finishTransition();
3527
+ finishTransition('error', error && error.message ? error.message : String(error));
2802
3528
  });
2803
- });
2804
- this.scheduleRouteWork(afterPaintDisposer);
3529
+ };
3530
+ if (localeRouteFastPath) {
3531
+ let cancelled = false;
3532
+ Promise.resolve().then(() => {
3533
+ if (!cancelled) completeParsedownCommit();
3534
+ });
3535
+ this.scheduleRouteWork(() => {
3536
+ cancelled = true;
3537
+ });
3538
+ } else {
3539
+ const afterPaintDisposer = scheduleDocsAfterPaint(completeParsedownCommit);
3540
+ this.scheduleRouteWork(afterPaintDisposer);
3541
+ }
2805
3542
 
2806
3543
  const idleDisposer = scheduleDocsIdle(() => {
2807
3544
  if (!this.isActiveRouteToken(token)) return;
@@ -2821,3 +3558,15 @@ class XtendDocPage extends HTMLElement {
2821
3558
  if (!customElements.get('xtend-doc-page')) {
2822
3559
  customElements.define('xtend-doc-page', XtendDocPage);
2823
3560
  }
3561
+
3562
+ window.xtendDocsI18n = {
3563
+ ...getDocsI18nConfig(),
3564
+ normalizeLocale: normalizeDocsLocale,
3565
+ getCurrentLocale: getCurrentDocsLocale,
3566
+ getTransition: () => window.__xtendDocsLocaleTransition || window.__xtendDocsLocaleLastTransition || null,
3567
+ navigate: navigateDocsLocale,
3568
+ sync: syncLegacyDocsGlobals
3569
+ };
3570
+ publishDocsLocale(getCurrentDocsLocale(), 'initial');
3571
+ syncLegacyDocsGlobals(getCurrentDocsLocale());
3572
+ ensureDocsLanguageSelectBinding();