meno-core 1.0.51 → 1.0.53

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 (137) hide show
  1. package/build-astro.ts +183 -13
  2. package/build-next.ts +1361 -0
  3. package/build-static.ts +7 -5
  4. package/dist/bin/cli.js +2 -2
  5. package/dist/build-static.js +6 -6
  6. package/dist/chunks/{chunk-HNLUO36W.js → chunk-GZHGVVW3.js} +2 -2
  7. package/dist/chunks/chunk-GZHGVVW3.js.map +7 -0
  8. package/dist/chunks/{chunk-LPVETICS.js → chunk-H3GJ4H2U.js} +185 -1
  9. package/dist/chunks/chunk-H3GJ4H2U.js.map +7 -0
  10. package/dist/chunks/{chunk-DM54NPEC.js → chunk-IGYR22T6.js} +89 -271
  11. package/dist/chunks/chunk-IGYR22T6.js.map +7 -0
  12. package/dist/chunks/{chunk-3KJ6SJZC.js → chunk-JGP5A3Y5.js} +12 -11
  13. package/dist/chunks/chunk-JGP5A3Y5.js.map +7 -0
  14. package/dist/chunks/{chunk-7NIC4I3V.js → chunk-JGWFTO6P.js} +167 -21
  15. package/dist/chunks/chunk-JGWFTO6P.js.map +7 -0
  16. package/dist/chunks/{chunk-EDQSMAMP.js → chunk-O3NAGJP4.js} +85 -4
  17. package/dist/chunks/chunk-O3NAGJP4.js.map +7 -0
  18. package/dist/chunks/{chunk-H4JSCDNW.js → chunk-QB2LNO4W.js} +24 -1
  19. package/dist/chunks/chunk-QB2LNO4W.js.map +7 -0
  20. package/dist/chunks/{chunk-V7CD7V7W.js → chunk-R6XHAFBF.js} +561 -112
  21. package/dist/chunks/chunk-R6XHAFBF.js.map +7 -0
  22. package/dist/chunks/{chunk-J23ZX5AP.js → chunk-X754AHS5.js} +277 -1
  23. package/dist/chunks/chunk-X754AHS5.js.map +7 -0
  24. package/dist/chunks/{chunk-2QK6U5UK.js → chunk-YBLHKYFF.js} +12 -2
  25. package/dist/chunks/chunk-YBLHKYFF.js.map +7 -0
  26. package/dist/chunks/{constants-GWBAD66U.js → constants-STK2YBIW.js} +2 -2
  27. package/dist/entries/server-router.js +7 -7
  28. package/dist/lib/client/index.js +354 -59
  29. package/dist/lib/client/index.js.map +4 -4
  30. package/dist/lib/server/index.js +1458 -190
  31. package/dist/lib/server/index.js.map +4 -4
  32. package/dist/lib/shared/index.js +202 -34
  33. package/dist/lib/shared/index.js.map +4 -4
  34. package/dist/lib/test-utils/index.js +1 -1
  35. package/entries/client-router.tsx +5 -165
  36. package/lib/client/ErrorBoundary.test.tsx +27 -25
  37. package/lib/client/ErrorBoundary.tsx +34 -19
  38. package/lib/client/core/ComponentBuilder.ts +19 -2
  39. package/lib/client/core/builders/embedBuilder.ts +8 -4
  40. package/lib/client/core/builders/listBuilder.ts +23 -4
  41. package/lib/client/fontFamiliesService.test.ts +76 -0
  42. package/lib/client/fontFamiliesService.ts +69 -0
  43. package/lib/client/hmrCssReload.ts +160 -0
  44. package/lib/client/hooks/useColorVariables.ts +2 -0
  45. package/lib/client/index.ts +4 -0
  46. package/lib/client/meno-filter/ui.ts +2 -0
  47. package/lib/client/routing/RouteLoader.test.ts +2 -2
  48. package/lib/client/routing/RouteLoader.ts +8 -2
  49. package/lib/client/routing/Router.tsx +81 -15
  50. package/lib/client/scripts/ScriptExecutor.test.ts +143 -0
  51. package/lib/client/scripts/ScriptExecutor.ts +56 -2
  52. package/lib/client/styles/StyleInjector.ts +20 -5
  53. package/lib/client/styles/UtilityClassCollector.ts +7 -1
  54. package/lib/client/styles/cspNonce.test.ts +67 -0
  55. package/lib/client/styles/cspNonce.ts +63 -0
  56. package/lib/client/templateEngine.test.ts +80 -0
  57. package/lib/client/templateEngine.ts +5 -0
  58. package/lib/server/astro/cmsPageEmitter.ts +35 -5
  59. package/lib/server/astro/componentEmitter.ts +61 -5
  60. package/lib/server/astro/nodeToAstro.ts +149 -11
  61. package/lib/server/astro/normalizeOrphanTemplateProps.test.ts +264 -0
  62. package/lib/server/astro/normalizeOrphanTemplateProps.ts +184 -0
  63. package/lib/server/createServer.ts +11 -0
  64. package/lib/server/draftPageStore.ts +49 -0
  65. package/lib/server/fileWatcher.ts +62 -2
  66. package/lib/server/index.ts +13 -1
  67. package/lib/server/providers/fileSystemPageProvider.ts +8 -0
  68. package/lib/server/routes/api/components.ts +9 -4
  69. package/lib/server/routes/api/core-routes.ts +2 -2
  70. package/lib/server/routes/api/pages.ts +14 -22
  71. package/lib/server/routes/api/shared.ts +56 -0
  72. package/lib/server/routes/index.ts +90 -0
  73. package/lib/server/routes/pages.ts +13 -6
  74. package/lib/server/services/componentService.test.ts +199 -2
  75. package/lib/server/services/componentService.ts +354 -49
  76. package/lib/server/services/fileWatcherService.ts +4 -24
  77. package/lib/server/services/pageService.test.ts +23 -0
  78. package/lib/server/services/pageService.ts +124 -6
  79. package/lib/server/ssr/attributeBuilder.ts +8 -2
  80. package/lib/server/ssr/buildErrorOverlay.ts +1 -1
  81. package/lib/server/ssr/errorOverlay.test.ts +21 -2
  82. package/lib/server/ssr/errorOverlay.ts +38 -11
  83. package/lib/server/ssr/htmlGenerator.test.ts +53 -13
  84. package/lib/server/ssr/htmlGenerator.ts +71 -27
  85. package/lib/server/ssr/liveReloadIntegration.test.ts +123 -2
  86. package/lib/server/ssr/metaTagGenerator.ts +19 -1
  87. package/lib/server/ssr/ssrRenderer.test.ts +67 -0
  88. package/lib/server/ssr/ssrRenderer.ts +94 -9
  89. package/lib/server/ssrRenderer.test.ts +70 -0
  90. package/lib/server/websocketManager.ts +0 -1
  91. package/lib/shared/componentRefs.ts +45 -0
  92. package/lib/shared/constants.ts +8 -0
  93. package/lib/shared/cssGeneration.ts +2 -0
  94. package/lib/shared/cssProperties.ts +184 -0
  95. package/lib/shared/expressionEvaluator.ts +54 -0
  96. package/lib/shared/fontCss.ts +101 -0
  97. package/lib/shared/fontLoader.ts +8 -86
  98. package/lib/shared/friendlyError.test.ts +87 -0
  99. package/lib/shared/friendlyError.ts +121 -0
  100. package/lib/shared/hrefRefs.test.ts +130 -0
  101. package/lib/shared/hrefRefs.ts +100 -0
  102. package/lib/shared/index.ts +52 -0
  103. package/lib/shared/inlineSvgStyleRules.test.ts +108 -0
  104. package/lib/shared/inlineSvgStyleRules.ts +134 -0
  105. package/lib/shared/interfaces/contentProvider.ts +13 -0
  106. package/lib/shared/itemTemplateUtils.test.ts +14 -0
  107. package/lib/shared/itemTemplateUtils.ts +4 -1
  108. package/lib/shared/registry/NodeTypeDefinition.ts +1 -1
  109. package/lib/shared/registry/nodeTypes/LinkNodeType.ts +1 -1
  110. package/lib/shared/slugTranslator.test.ts +24 -0
  111. package/lib/shared/slugTranslator.ts +24 -0
  112. package/lib/shared/styleNodeUtils.ts +4 -1
  113. package/lib/shared/tree/PathBuilder.test.ts +128 -1
  114. package/lib/shared/tree/PathBuilder.ts +83 -31
  115. package/lib/shared/types/comment.ts +99 -0
  116. package/lib/shared/types/index.ts +12 -0
  117. package/lib/shared/types/rendering.ts +8 -0
  118. package/lib/shared/utilityClassConfig.ts +4 -2
  119. package/lib/shared/utilityClassMapper.test.ts +24 -0
  120. package/lib/shared/validation/commentValidators.ts +69 -0
  121. package/lib/shared/validation/index.ts +1 -0
  122. package/lib/shared/viewportUnits.integration.test.ts +42 -0
  123. package/lib/shared/viewportUnits.test.ts +103 -0
  124. package/lib/shared/viewportUnits.ts +63 -0
  125. package/lib/test-utils/dom-setup.ts +6 -0
  126. package/package.json +1 -1
  127. package/dist/chunks/chunk-2QK6U5UK.js.map +0 -7
  128. package/dist/chunks/chunk-3KJ6SJZC.js.map +0 -7
  129. package/dist/chunks/chunk-7NIC4I3V.js.map +0 -7
  130. package/dist/chunks/chunk-DM54NPEC.js.map +0 -7
  131. package/dist/chunks/chunk-EDQSMAMP.js.map +0 -7
  132. package/dist/chunks/chunk-H4JSCDNW.js.map +0 -7
  133. package/dist/chunks/chunk-HNLUO36W.js.map +0 -7
  134. package/dist/chunks/chunk-J23ZX5AP.js.map +0 -7
  135. package/dist/chunks/chunk-LPVETICS.js.map +0 -7
  136. package/dist/chunks/chunk-V7CD7V7W.js.map +0 -7
  137. /package/dist/chunks/{constants-GWBAD66U.js.map → constants-STK2YBIW.js.map} +0 -0
@@ -14,19 +14,29 @@ import {
14
14
  } from "./chunk-WQFG7PAH.js";
15
15
  import {
16
16
  CMS_DRAFT_SUFFIX,
17
+ buildSlugIndex,
18
+ collectComponentLibraries,
19
+ filterLibrariesByContext,
20
+ fontFaceCss,
21
+ fontPreloadLinks,
22
+ generateLibraryTags,
23
+ getLocaleLinks,
17
24
  isReservedDraftFilename,
18
25
  isSafePathSegment,
19
26
  isValidIdentifier,
20
- resolvePaletteColor
21
- } from "./chunk-J23ZX5AP.js";
27
+ mergeLibraries,
28
+ resolvePaletteColor,
29
+ translatePath
30
+ } from "./chunk-X754AHS5.js";
22
31
  import {
23
32
  extractAttributesFromNode,
33
+ inlineSvgStyleRules,
24
34
  isHtmlMapping,
25
35
  mergeNodeStyles,
26
36
  processStructure,
27
37
  resolveHtmlMapping,
28
38
  skipEmptyTemplateAttributes
29
- } from "./chunk-EDQSMAMP.js";
39
+ } from "./chunk-O3NAGJP4.js";
30
40
  import {
31
41
  DEFAULT_PREFETCH_CONFIG,
32
42
  SSRRegistry,
@@ -62,11 +72,13 @@ import {
62
72
  resolvePropsFromDefinition,
63
73
  resolveTemplateRawValue,
64
74
  responsiveStylesToClasses,
75
+ rewriteViewportUnits,
65
76
  singularize,
77
+ toFriendlyError,
66
78
  validateCMSDraftItem,
67
79
  validateCMSItem,
68
80
  validateComponentDefinition
69
- } from "./chunk-7NIC4I3V.js";
81
+ } from "./chunk-JGWFTO6P.js";
70
82
  import {
71
83
  DEFAULT_BREAKPOINTS,
72
84
  DEFAULT_FLUID_RANGE,
@@ -91,7 +103,7 @@ import {
91
103
  NODE_TYPE,
92
104
  RAW_HTML_PREFIX,
93
105
  init_constants
94
- } from "./chunk-2QK6U5UK.js";
106
+ } from "./chunk-YBLHKYFF.js";
95
107
  import {
96
108
  __require
97
109
  } from "./chunk-KSBZ2L7C.js";
@@ -1323,57 +1335,11 @@ async function loadProjectConfig() {
1323
1335
  function getProjectConfig() {
1324
1336
  return cachedConfig || { fonts: [] };
1325
1337
  }
1326
- function getFontFormat(path2) {
1327
- if (path2.endsWith(".woff2")) return "woff2";
1328
- if (path2.endsWith(".woff")) return "woff";
1329
- if (path2.endsWith(".ttf")) return "truetype";
1330
- if (path2.endsWith(".otf")) return "opentype";
1331
- return "truetype";
1332
- }
1333
- function extractFamilyName(path2) {
1334
- const filename = path2.split("/").pop() || "Font";
1335
- const name = filename.replace(/\.(ttf|woff2?|otf)$/i, "");
1336
- return name.split("-").map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join(" ");
1337
- }
1338
1338
  function generateFontCSS() {
1339
- const config = getProjectConfig();
1340
- const fonts = config.fonts || [];
1341
- return fonts.filter((font) => font.path || font.src).map((font) => {
1342
- const fontPath = font.path || font.src;
1343
- const format = getFontFormat(fontPath);
1344
- const family = font.family || extractFamilyName(fontPath);
1345
- const weight = font.weight ?? 400;
1346
- const weightMax = font.weightMax;
1347
- const style = font.style ?? "normal";
1348
- const fontDisplay = font.fontDisplay;
1349
- const fontWeight = weightMax != null ? `${weight} ${weightMax}` : weight;
1350
- const unicodeRange = font.unicodeRange;
1351
- return `@font-face {
1352
- font-family: '${family}';
1353
- src: url('${fontPath}') format('${format}');
1354
- font-weight: ${fontWeight};
1355
- font-style: ${style};${fontDisplay ? `
1356
- font-display: ${fontDisplay};` : ""}${unicodeRange ? `
1357
- unicode-range: ${unicodeRange};` : ""}
1358
- }`;
1359
- }).join("\n\n");
1360
- }
1361
- function getFontMimeType(path2) {
1362
- if (path2.endsWith(".woff2")) return "font/woff2";
1363
- if (path2.endsWith(".woff")) return "font/woff";
1364
- if (path2.endsWith(".ttf")) return "font/ttf";
1365
- if (path2.endsWith(".otf")) return "font/otf";
1366
- return "font/ttf";
1339
+ return fontFaceCss(getProjectConfig().fonts || []);
1367
1340
  }
1368
1341
  function generateFontPreloadTags() {
1369
- const config = getProjectConfig();
1370
- const fonts = config.fonts || [];
1371
- if (fonts.length === 0) return "";
1372
- return fonts.filter((font) => font.path || font.src).map((font) => {
1373
- const fontPath = font.path || font.src;
1374
- const mimeType = getFontMimeType(fontPath);
1375
- return `<link rel="preload" href="${fontPath}" as="font" type="${mimeType}" crossorigin>`;
1376
- }).join("\n ");
1342
+ return fontPreloadLinks(getProjectConfig().fonts || []);
1377
1343
  }
1378
1344
 
1379
1345
  // lib/server/cssGenerator.ts
@@ -1553,80 +1519,17 @@ function styleToString(style) {
1553
1519
  const declarations = [];
1554
1520
  for (const [key, value] of Object.entries(style)) {
1555
1521
  if (value === null || value === void 0) continue;
1522
+ const rewritten = rewriteViewportUnits(String(value));
1556
1523
  if (key.startsWith("--")) {
1557
- declarations.push(`${key}: ${escapeHtml(String(value))}`);
1524
+ declarations.push(`${key}: ${escapeHtml(rewritten)}`);
1558
1525
  } else {
1559
1526
  const cssProperty = key.replace(/([A-Z])/g, "-$1").toLowerCase();
1560
- declarations.push(`${cssProperty}: ${escapeHtml(String(value))}`);
1527
+ declarations.push(`${cssProperty}: ${escapeHtml(rewritten)}`);
1561
1528
  }
1562
1529
  }
1563
1530
  return declarations.length > 0 ? declarations.join("; ") : "";
1564
1531
  }
1565
1532
 
1566
- // lib/shared/slugTranslator.ts
1567
- function buildSlugIndex(mappings) {
1568
- const index = /* @__PURE__ */ new Map();
1569
- for (const mapping of mappings) {
1570
- for (const [locale, slug] of Object.entries(mapping.slugs)) {
1571
- const key = `${locale}:${slug}`;
1572
- index.set(key, {
1573
- pageId: mapping.pageId,
1574
- slugs: mapping.slugs
1575
- });
1576
- }
1577
- }
1578
- return index;
1579
- }
1580
- function findPageBySlug(slug, locale, index) {
1581
- const key = `${locale}:${slug}`;
1582
- return index.get(key);
1583
- }
1584
- function translatePath(currentPath, targetLocale, currentLocale, defaultLocale, index) {
1585
- let slug = currentPath;
1586
- if (slug.startsWith("/")) {
1587
- slug = slug.substring(1);
1588
- }
1589
- if (currentLocale !== defaultLocale) {
1590
- if (slug.startsWith(`${currentLocale}/`)) {
1591
- slug = slug.substring(currentLocale.length + 1);
1592
- } else if (slug === currentLocale) {
1593
- slug = "";
1594
- }
1595
- }
1596
- if (slug === "" || slug === "/") {
1597
- slug = "";
1598
- }
1599
- let entry = findPageBySlug(slug, currentLocale, index);
1600
- if (!entry && currentLocale !== defaultLocale) {
1601
- entry = findPageBySlug(slug, defaultLocale, index);
1602
- }
1603
- if (!entry) {
1604
- if (targetLocale === defaultLocale) {
1605
- return slug === "" ? "/" : `/${slug}`;
1606
- }
1607
- return slug === "" ? `/${targetLocale}` : `/${targetLocale}/${slug}`;
1608
- }
1609
- const targetSlug = entry.slugs[targetLocale] ?? entry.slugs[defaultLocale] ?? slug;
1610
- if (targetLocale === defaultLocale) {
1611
- return targetSlug === "" ? "/" : `/${targetSlug}`;
1612
- }
1613
- return targetSlug === "" ? `/${targetLocale}` : `/${targetLocale}/${targetSlug}`;
1614
- }
1615
- function getLocaleLinks(currentPath, currentLocale, i18nConfig, index) {
1616
- return i18nConfig.locales.map((localeConfig) => ({
1617
- locale: localeConfig.code,
1618
- langTag: localeConfig.langTag,
1619
- name: localeConfig.name,
1620
- nativeName: localeConfig.nativeName,
1621
- path: translatePath(currentPath, localeConfig.code, currentLocale, i18nConfig.defaultLocale, index),
1622
- isCurrent: localeConfig.code === currentLocale
1623
- }));
1624
- }
1625
- function resolveSlugToPageId(slug, locale, index) {
1626
- const entry = findPageBySlug(slug, locale, index);
1627
- return entry?.pageId;
1628
- }
1629
-
1630
1533
  // lib/server/ssr/metaTagGenerator.ts
1631
1534
  function extractPageMeta(pageData) {
1632
1535
  const meta = {};
@@ -1641,6 +1544,17 @@ function extractPageMeta(pageData) {
1641
1544
  }
1642
1545
  return meta;
1643
1546
  }
1547
+ function normalizeOgImageUrl(value, baseUrl) {
1548
+ if (!value) return value;
1549
+ let out = value;
1550
+ if (/^\/images\/[^?#]+\.(webp|avif)(\?|#|$)/i.test(out)) {
1551
+ out = out.replace(/\.(webp|avif)(?=\?|#|$)/i, ".jpg");
1552
+ }
1553
+ if (baseUrl && out.startsWith("/")) {
1554
+ out = `${baseUrl.replace(/\/$/, "")}${out}`;
1555
+ }
1556
+ return out;
1557
+ }
1644
1558
  function generateMetaTags(meta, url = "", locale = "en", config = DEFAULT_I18N_CONFIG, options) {
1645
1559
  const tags = [];
1646
1560
  const resolve = (value) => {
@@ -1670,7 +1584,8 @@ function generateMetaTags(meta, url = "", locale = "en", config = DEFAULT_I18N_C
1670
1584
  tags.push(`<meta property="og:description" content="${escapeHtml(ogDescription)}" />`);
1671
1585
  }
1672
1586
  if (ogImage) {
1673
- tags.push(`<meta property="og:image" content="${escapeHtml(ogImage)}" />`);
1587
+ const normalizedOgImage = normalizeOgImageUrl(ogImage, options?.baseUrl);
1588
+ tags.push(`<meta property="og:image" content="${escapeHtml(normalizedOgImage)}" />`);
1674
1589
  }
1675
1590
  if (ogType) {
1676
1591
  tags.push(`<meta property="og:type" content="${escapeHtml(ogType)}" />`);
@@ -2300,6 +2215,13 @@ async function renderNestedListPlaceholder(node, ctx) {
2300
2215
  const configJson = escapeHtml(JSON.stringify(config));
2301
2216
  return `<div data-cms-list-nested="true" data-collection="${escapeHtml(sourceStr)}" data-cms-config="${configJson}"${editorAttrs(ctx, { isCMSListContainer: true })}><template data-nested-template>${templateContent}</template></div>`;
2302
2217
  }
2218
+ function renderNodeFallback(ctx, error, label) {
2219
+ console.error(`\u274C SSR render error in ${label}:`, error);
2220
+ if (!ctx.injectEditorAttrs) return "";
2221
+ const friendly = toFriendlyError(error);
2222
+ const text = `${friendly.title} \u2014 ${friendly.friendlyMessage}`;
2223
+ return `<div data-meno-render-error style="margin:8px 0;padding:12px 14px;border:1px dashed #e0a3a3;border-radius:6px;background:#fdf3f3;color:#9a3b3b;font:13px/1.5 -apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;">\u26A0\uFE0F ${escapeHtml(text)}</div>`;
2224
+ }
2303
2225
  async function processList(node, ctx) {
2304
2226
  const nodeType = node.type;
2305
2227
  const isLegacyCMSList = nodeType === "cms-list";
@@ -2334,6 +2256,7 @@ async function processList(node, ctx) {
2334
2256
  items = [];
2335
2257
  }
2336
2258
  }
2259
+ if (!Array.isArray(items)) items = [];
2337
2260
  if (node.offset && sourceType === "prop") {
2338
2261
  items = items.slice(node.offset);
2339
2262
  }
@@ -2500,7 +2423,7 @@ function registerInteractiveStyles(ctx, elementClass, interactiveStyles) {
2500
2423
  }
2501
2424
  function buildCssVariableStyleAttr(cssVariables) {
2502
2425
  if (Object.keys(cssVariables).length === 0) return "";
2503
- const styleString = Object.entries(cssVariables).map(([k, v]) => `${k}: ${v}`).join("; ");
2426
+ const styleString = Object.entries(cssVariables).map(([k, v]) => `${k}: ${rewriteViewportUnits(v)}`).join("; ");
2504
2427
  return ` style="${escapeHtml(styleString)}"`;
2505
2428
  }
2506
2429
  function arraysEqual(a, b) {
@@ -2526,6 +2449,9 @@ function editorAttrs(ctx, opts = {}) {
2526
2449
  async function renderNode(node, ctx) {
2527
2450
  const { breakpoints, viewportWidth, locale, i18nConfig, slugMappings, pagePath } = ctx;
2528
2451
  if (node === null || node === void 0) return "";
2452
+ if (typeof node === "object" && !Array.isArray(node) && node._code === true) {
2453
+ return "";
2454
+ }
2529
2455
  if (typeof node === "string" || typeof node === "number") {
2530
2456
  let text = String(node);
2531
2457
  if (ctx.templateMode) {
@@ -2581,7 +2507,11 @@ async function renderNode(node, ctx) {
2581
2507
  return "";
2582
2508
  }
2583
2509
  if (isListNode(node)) {
2584
- return await processList(node, ctx);
2510
+ try {
2511
+ return await processList(node, ctx);
2512
+ } catch (error) {
2513
+ return renderNodeFallback(ctx, error, "list");
2514
+ }
2585
2515
  }
2586
2516
  const nodeType = "type" in node ? node.type : void 0;
2587
2517
  const nodeStyle = "style" in node ? node.style : void 0;
@@ -2610,11 +2540,12 @@ async function renderNode(node, ctx) {
2610
2540
  }
2611
2541
  }
2612
2542
  const purify = getDOMPurify();
2613
- const sanitizedHtml = purify ? purify.sanitize(htmlContent, {
2614
- ALLOWED_TAGS: ["svg", "path", "circle", "rect", "line", "polyline", "polygon", "g", "text", "tspan", "image", "defs", "use", "linearGradient", "radialGradient", "stop", "clipPath", "mask", "pattern", "marker", "symbol", "a", "div", "span", "p", "br", "button", "img", "iframe", "video", "audio", "source", "canvas", "b", "i", "u", "strong", "em", "sub", "sup", "mark", "s", "small", "del", "ins", "q", "abbr", "code", "pre", "blockquote", "ul", "ol", "li", "h1", "h2", "h3", "h4", "h5", "h6", "style", "animate", "animateTransform", "animateMotion", "set"],
2615
- ALLOWED_ATTR: ["class", "id", "style", "width", "height", "viewBox", "xmlns", "fill", "stroke", "stroke-width", "stroke-linecap", "stroke-linejoin", "stroke-dasharray", "stroke-dashoffset", "d", "cx", "cy", "r", "x", "y", "x1", "y1", "x2", "y2", "points", "href", "src", "alt", "target", "rel", "data-*", "aria-*", "transform", "opacity", "fill-opacity", "stroke-opacity", "font-size", "font-family", "text-anchor", "dominant-baseline", "offset", "stop-color", "stop-opacity", "frameborder", "allowfullscreen", "allow", "title", "attributeName", "values", "dur", "begin", "end", "repeatCount", "repeatDur", "keyTimes", "keySplines", "calcMode", "from", "to", "by", "additive", "accumulate", "type", "rotate", "keyPoints", "path"],
2543
+ const purifiedHtml = purify ? purify.sanitize(htmlContent, {
2544
+ ALLOWED_TAGS: ["svg", "path", "circle", "rect", "line", "polyline", "polygon", "g", "text", "tspan", "image", "defs", "use", "linearGradient", "radialGradient", "stop", "clipPath", "mask", "pattern", "marker", "symbol", "a", "div", "span", "p", "br", "button", "img", "iframe", "video", "audio", "source", "canvas", "b", "i", "u", "strong", "em", "sub", "sup", "mark", "s", "small", "del", "ins", "q", "abbr", "code", "pre", "blockquote", "ul", "ol", "li", "h1", "h2", "h3", "h4", "h5", "h6", "style", "animate", "animateTransform", "animateMotion", "set", "filter", "feGaussianBlur", "feOffset", "feMerge", "feMergeNode", "feColorMatrix", "feComposite", "feFlood", "feMorphology", "feBlend", "feDropShadow", "feTurbulence", "feDisplacementMap", "foreignObject"],
2545
+ ALLOWED_ATTR: ["class", "id", "style", "width", "height", "viewBox", "xmlns", "xmlns:xlink", "xlink:href", "fill", "stroke", "stroke-width", "stroke-linecap", "stroke-linejoin", "stroke-dasharray", "stroke-dashoffset", "d", "cx", "cy", "r", "x", "y", "x1", "y1", "x2", "y2", "points", "href", "src", "alt", "target", "rel", "data-*", "aria-*", "transform", "opacity", "fill-opacity", "fill-rule", "clip-rule", "clip-path", "clipPathUnits", "mask", "mask-type", "maskUnits", "maskContentUnits", "patternUnits", "patternContentUnits", "patternTransform", "gradientUnits", "gradientTransform", "spreadMethod", "preserveAspectRatio", "marker-start", "marker-mid", "marker-end", "markerUnits", "markerWidth", "markerHeight", "refX", "refY", "orient", "paint-order", "vector-effect", "filter", "filterUnits", "primitiveUnits", "in", "in2", "result", "stdDeviation", "flood-color", "flood-opacity", "stroke-opacity", "font-size", "font-family", "font-weight", "font-style", "text-anchor", "dominant-baseline", "offset", "stop-color", "stop-opacity", "frameborder", "allowfullscreen", "allow", "title", "attributeName", "values", "dur", "begin", "end", "repeatCount", "repeatDur", "keyTimes", "keySplines", "calcMode", "from", "to", "by", "additive", "accumulate", "type", "rotate", "keyPoints", "path"],
2616
2546
  KEEP_CONTENT: true
2617
2547
  }) : htmlContent;
2548
+ const sanitizedHtml = inlineSvgStyleRules(purifiedHtml);
2618
2549
  const optimizedHtml = ctx.imageMetadataMap ? rewriteRichTextImages(sanitizedHtml, ctx.imageMetadataMap, ctx.imageFormat) : sanitizedHtml;
2619
2550
  const nodeAttributes2 = resolveI18nAttrs(extractAttributesFromNode(node), locale, i18nConfig);
2620
2551
  const classNames = ["oem"];
@@ -2818,7 +2749,17 @@ async function renderComponent(componentName, propsWithStyleAndAttrs, children,
2818
2749
  const markedChildren = children ? markAsSlotContent(children) : void 0;
2819
2750
  const processedStructure = processStructure(
2820
2751
  structuredComponentDef.structure,
2821
- { props: resolvedProps, componentDef: structuredComponentDef, itemContext: ctx.templateContext },
2752
+ {
2753
+ props: resolvedProps,
2754
+ componentDef: structuredComponentDef,
2755
+ itemContext: ctx.templateContext,
2756
+ // Host (outer) component's resolved props — used as fallback scope
2757
+ // for `{{x}}` templates the child's interface doesn't declare. At
2758
+ // this point `ctx.componentResolvedProps` still belongs to the
2759
+ // outer component; it's only swapped to `resolvedProps` below when
2760
+ // we recurse via `renderNode`.
2761
+ parentProps: ctx.componentResolvedProps
2762
+ },
2822
2763
  void 0,
2823
2764
  markedChildren,
2824
2765
  true
@@ -2882,6 +2823,16 @@ async function renderComponent(componentName, propsWithStyleAndAttrs, children,
2882
2823
  existingPropsMap[componentName] = propsForJS;
2883
2824
  processedRoot.attributes["data-props"] = JSON.stringify(existingPropsMap);
2884
2825
  }
2826
+ if (componentName && (isHtmlNode(rootNode) || isLinkNode(rootNode))) {
2827
+ if (!rootNode.attributes) rootNode.attributes = {};
2828
+ if (!ctx.componentInstanceCounter) {
2829
+ ctx.componentInstanceCounter = /* @__PURE__ */ new Map();
2830
+ }
2831
+ const instanceIndex = ctx.componentInstanceCounter.get(componentName) ?? 0;
2832
+ ctx.componentInstanceCounter.set(componentName, instanceIndex + 1);
2833
+ rootNode.attributes["data-meno-component"] = componentName;
2834
+ rootNode.attributes["data-meno-component-instance"] = String(instanceIndex);
2835
+ }
2885
2836
  }
2886
2837
  return await renderNode(processedStructure, {
2887
2838
  ...ctx,
@@ -2892,8 +2843,7 @@ async function renderComponent(componentName, propsWithStyleAndAttrs, children,
2892
2843
  componentResolvedProps: resolvedProps
2893
2844
  });
2894
2845
  } catch (error) {
2895
- console.error(`\u274C SSR Error rendering component ${componentName}:`, error);
2896
- return "";
2846
+ return renderNodeFallback(ctx, error, `component ${componentName}`);
2897
2847
  }
2898
2848
  }
2899
2849
  async function renderLinkNode(propsWithStyleAndAttrs, children, ctx) {
@@ -3145,6 +3095,9 @@ async function renderPageSSR(pageData, globalComponents = {}, pagePath = "/", ba
3145
3095
  if (typeof meta.ogDescription === "string") {
3146
3096
  meta = { ...meta, ogDescription: processCMSTemplate(meta.ogDescription, cmsContext.cms, effectiveLocale, config) };
3147
3097
  }
3098
+ if (typeof meta.ogImage === "string") {
3099
+ meta = { ...meta, ogImage: processCMSTemplate(meta.ogImage, cmsContext.cms, effectiveLocale, config) };
3100
+ }
3148
3101
  }
3149
3102
  const pageComponents = pageData?.components || {};
3150
3103
  const { html: contentHTML, interactiveStylesMap, preloadImages, neededCollections, ssrFallbackCollector, processedRawHtmlCollector } = rootNode ? await buildComponentHTML(rootNode, globalComponents, pageComponents, effectiveLocale, config, slugMappings, pagePath, cmsContext, cmsService, isProductionBuild, injectEditorAttrs) : { html: "", interactiveStylesMap: /* @__PURE__ */ new Map(), preloadImages: [], neededCollections: /* @__PURE__ */ new Set(), ssrFallbackCollector: /* @__PURE__ */ new Map(), processedRawHtmlCollector: /* @__PURE__ */ new Map() };
@@ -3337,134 +3290,6 @@ function generateAllInlineDataScripts(collections) {
3337
3290
  return scripts.join("\n ");
3338
3291
  }
3339
3292
 
3340
- // lib/shared/libraryLoader.ts
3341
- function escapeAttr2(str) {
3342
- return str.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
3343
- }
3344
- function mergeLibraries(global, page) {
3345
- if (!page) {
3346
- return global;
3347
- }
3348
- if (page.mode === "replace") {
3349
- return {
3350
- js: page.js || [],
3351
- css: page.css || []
3352
- };
3353
- }
3354
- return {
3355
- js: [...global.js || [], ...page.js || []],
3356
- css: [...global.css || [], ...page.css || []]
3357
- };
3358
- }
3359
- function generateScriptTag(lib) {
3360
- const attrs = [`src="${escapeAttr2(lib.url)}"`];
3361
- if (lib.type === "module") {
3362
- attrs.push('type="module"');
3363
- } else {
3364
- const mode = lib.mode || "defer";
3365
- attrs.push(mode);
3366
- }
3367
- return `<script ${attrs.join(" ")}></script>`;
3368
- }
3369
- function generateInlineStyleTag(content, media) {
3370
- const attrs = media ? ` media="${escapeAttr2(media)}"` : "";
3371
- return `<style${attrs}>${content}</style>`;
3372
- }
3373
- function generateStylesheetTag(lib) {
3374
- const attrs = [
3375
- 'rel="stylesheet"',
3376
- `href="${escapeAttr2(lib.url)}"`
3377
- ];
3378
- if (lib.media) {
3379
- attrs.push(`media="${escapeAttr2(lib.media)}"`);
3380
- }
3381
- return `<link ${attrs.join(" ")}>`;
3382
- }
3383
- function generateLibraryTags(libs, inlineContents) {
3384
- const headCSS = [];
3385
- const headJS = [];
3386
- const bodyEndJS = [];
3387
- for (const css of libs.css || []) {
3388
- const inlineContent = inlineContents?.get(css.url);
3389
- if (inlineContent !== void 0) {
3390
- headCSS.push(generateInlineStyleTag(inlineContent, css.media));
3391
- } else {
3392
- headCSS.push(generateStylesheetTag(css));
3393
- }
3394
- }
3395
- for (const js of libs.js || []) {
3396
- const tag = generateScriptTag(js);
3397
- if (js.position === "head") {
3398
- headJS.push(tag);
3399
- } else {
3400
- bodyEndJS.push(tag);
3401
- }
3402
- }
3403
- return {
3404
- headCSS: headCSS.join("\n "),
3405
- headJS: headJS.join("\n "),
3406
- bodyEndJS: bodyEndJS.join("\n ")
3407
- };
3408
- }
3409
- function collectComponentLibraries(globalComponents = {}, pageComponents = {}) {
3410
- const seenJS = /* @__PURE__ */ new Set();
3411
- const seenCSS = /* @__PURE__ */ new Set();
3412
- const jsLibs = [];
3413
- const cssLibs = [];
3414
- const collect = (components) => {
3415
- for (const component of Object.values(components)) {
3416
- const libs = component?.component?.libraries;
3417
- if (!libs) continue;
3418
- for (const js of libs.js || []) {
3419
- if (!seenJS.has(js.url)) {
3420
- seenJS.add(js.url);
3421
- jsLibs.push(js);
3422
- }
3423
- }
3424
- for (const css of libs.css || []) {
3425
- if (!seenCSS.has(css.url)) {
3426
- seenCSS.add(css.url);
3427
- cssLibs.push(css);
3428
- }
3429
- }
3430
- }
3431
- };
3432
- collect(globalComponents);
3433
- collect(pageComponents);
3434
- return { js: jsLibs, css: cssLibs };
3435
- }
3436
- function extractLibraryOrigins(libs) {
3437
- const scriptOrigins = /* @__PURE__ */ new Set();
3438
- const styleOrigins = /* @__PURE__ */ new Set();
3439
- for (const js of libs.js || []) {
3440
- const origin = safeOrigin(js.url);
3441
- if (origin) scriptOrigins.add(origin);
3442
- }
3443
- for (const css of libs.css || []) {
3444
- const origin = safeOrigin(css.url);
3445
- if (origin) styleOrigins.add(origin);
3446
- }
3447
- return { scriptOrigins, styleOrigins };
3448
- }
3449
- function filterLibrariesByContext(libs, context) {
3450
- if (context === "preview") return libs;
3451
- const key = context === "editor" ? "disableEditor" : "disableBuild";
3452
- return {
3453
- js: libs.js,
3454
- css: (libs.css || []).filter((css) => !css[key])
3455
- };
3456
- }
3457
- function safeOrigin(url) {
3458
- if (!url || url.startsWith("/") || url.startsWith("./") || url.startsWith("../")) {
3459
- return null;
3460
- }
3461
- try {
3462
- return new URL(url).origin;
3463
- } catch {
3464
- return null;
3465
- }
3466
- }
3467
-
3468
3293
  // lib/server/ssr/htmlGenerator.ts
3469
3294
  function generateImagePreloadTags(preloadImages) {
3470
3295
  if (preloadImages.length === 0) return "";
@@ -3546,7 +3371,7 @@ async function generateSSRHTML(pageDataOrOptions, globalComponents = {}, pagePat
3546
3371
  await configService.load();
3547
3372
  const globalLibraries = configService.getLibraries() || { js: [], css: [] };
3548
3373
  const globalCustomCode = configService.getCustomCode();
3549
- const menoBadgeHtml = configService.getShowMenoBadge() ? `<style>.meno-badge{position:fixed;bottom:12px;left:12px;z-index:9999;background:#000;color:#fff;padding:4px 10px;border-radius:6px;font-size:12px;font-family:system-ui,sans-serif;text-decoration:none;opacity:0.8;transition:opacity 0.2s}.meno-badge:hover,.meno-badge:focus{opacity:1}</style><a class="meno-badge" href="https://meno.so" target="_blank" rel="noopener">Made in Meno</a>` : "";
3374
+ const menoBadgeHtml = configService.getShowMenoBadge() ? `<style${nonceAttr}>.meno-badge{position:fixed;bottom:12px;left:12px;z-index:9999;background:#000;color:#fff;padding:4px 10px;border-radius:6px;font-size:12px;font-family:system-ui,sans-serif;text-decoration:none;opacity:0.8;transition:opacity 0.2s}.meno-badge:hover,.meno-badge:focus{opacity:1}</style><a class="meno-badge" href="https://meno.so" target="_blank" rel="noopener">Made in Meno</a>` : "";
3550
3375
  const mergedCustomCode = {
3551
3376
  head: [globalCustomCode.head, pageCustomCode?.head].filter(Boolean).join("\n"),
3552
3377
  bodyStart: [globalCustomCode.bodyStart, pageCustomCode?.bodyStart].filter(Boolean).join("\n"),
@@ -3678,7 +3503,8 @@ picture {
3678
3503
  utilityCSS,
3679
3504
  interactiveCSS
3680
3505
  ].filter(Boolean).join("\n");
3681
- const finalCSS = useBundled ? minifyCSS(combinedCSS) : combinedCSS;
3506
+ const cssWithStableViewport = rewriteViewportUnits(combinedCSS);
3507
+ const finalCSS = useBundled ? minifyCSS(cssWithStableViewport) : cssWithStableViewport;
3682
3508
  const prefetchConfig = await loadPrefetchConfig();
3683
3509
  const menoConfig = prefetchConfig.enabled ? { prefetch: prefetchConfig } : {};
3684
3510
  const hasConfig = Object.keys(menoConfig).length > 0;
@@ -3700,7 +3526,7 @@ picture {
3700
3526
  const scriptPreloadTag = extScriptPath ? `<link rel="preload" href="${extScriptPath}" as="script">` : "";
3701
3527
  const imagePreloadTags = generateImagePreloadTags(rendered.preloadImages);
3702
3528
  const wsUrl = serverPort ? `'ws://localhost:${serverPort}/hmr'` : `location.origin.replace('http','ws')+'/hmr'`;
3703
- const liveReloadScript = injectLiveReload ? `<script${nonceAttr}>(function(){var ws,timer,gen=0,lastSrvRoot=null;function strip(s){return s?s.replace(/[?&]_r=\\d+/,''):''}function classList(el){return (el.getAttribute('class')||'').split(/\\s+/).filter(Boolean)}function syncEl(cur,srv,old){var cc=classList(cur),sc=classList(srv),oc=old?new Set(classList(old)):new Set();var rt=cc.filter(function(c){return !oc.has(c)});var seen=new Set(),fin=[];sc.concat(rt).forEach(function(c){if(!seen.has(c)){seen.add(c);fin.push(c)}});var fs=fin.join(' ');if((cur.getAttribute('class')||'')!==fs){if(fs)cur.setAttribute('class',fs);else cur.removeAttribute('class')}for(var i=0;i<srv.attributes.length;i++){var a=srv.attributes[i];if(a.name==='class')continue;if(cur.getAttribute(a.name)!==a.value)cur.setAttribute(a.name,a.value)}if(old){for(var i=0;i<old.attributes.length;i++){var a=old.attributes[i];if(a.name==='class')continue;if(!srv.hasAttribute(a.name)&&cur.hasAttribute(a.name))cur.removeAttribute(a.name)}}}function syncText(cur,srv){var cc=cur.childNodes,sc=srv.childNodes;for(var i=0;i<sc.length;i++){var s=sc[i],c=cc[i];if(s.nodeType===3&&c&&c.nodeType===3){if(c.textContent!==s.textContent)c.textContent=s.textContent}}}function smartUpdate(curR,srvR,oldR){var ce=curR.querySelectorAll('[data-element-path]'),se=srvR.querySelectorAll('[data-element-path]');if(ce.length!==se.length){if(curR.innerHTML!==srvR.innerHTML)curR.innerHTML=srvR.innerHTML;return}var sbp={};for(var i=0;i<se.length;i++)sbp[se[i].getAttribute('data-element-path')]=se[i];var obp={};if(oldR){var oe=oldR.querySelectorAll('[data-element-path]');for(var i=0;i<oe.length;i++)obp[oe[i].getAttribute('data-element-path')]=oe[i]}for(var i=0;i<ce.length;i++){var c=ce[i],p=c.getAttribute('data-element-path'),s=sbp[p];if(!s){if(curR.innerHTML!==srvR.innerHTML)curR.innerHTML=srvR.innerHTML;return}syncEl(c,s,obp[p]);syncText(c,s)}syncText(curR,srvR)}function connect(){ws=new WebSocket(${wsUrl});ws.onmessage=function(e){var d=JSON.parse(e.data);if(d.type==='hmr:libraries-update'){location.reload()}else if(d.type==='hmr:update'||d.type==='hmr:cms-update'||d.type==='hmr:colors-update'||d.type==='hmr:variables-update')hotReload()};ws.onclose=function(){clearTimeout(timer);timer=setTimeout(connect,1000)}}function hotReload(){var g=++gen;var sx=window.scrollX,sy=window.scrollY;fetch(location.href,{cache:'no-store'}).then(function(r){return r.text()}).then(function(html){if(g!==gen)return;var p=new DOMParser();var d=p.parseFromString(html,'text/html');var or=document.getElementById('root'),nr=d.getElementById('root');if(or&&nr)smartUpdate(or,nr,lastSrvRoot);if(nr)lastSrvRoot=nr.cloneNode(true);var os=document.getElementById('meno-styles'),ns=d.getElementById('meno-styles');if(os&&ns&&os.textContent!==ns.textContent)os.parentNode.replaceChild(ns.cloneNode(true),os);var nh=d.documentElement;if(nh){var nl=nh.getAttribute('lang')||'en',nt=nh.getAttribute('theme')||'light';if(document.documentElement.getAttribute('lang')!==nl)document.documentElement.setAttribute('lang',nl);if(document.documentElement.getAttribute('theme')!==nt)document.documentElement.setAttribute('theme',nt)}var ocms=document.querySelectorAll('script[id^="meno-cms-"]'),ncms=d.querySelectorAll('script[id^="meno-cms-"]');var ock=JSON.stringify(Array.prototype.map.call(ocms,function(s){return [s.id,s.textContent]}));var nck=JSON.stringify(Array.prototype.map.call(ncms,function(s){return [s.id,s.textContent]}));if(ock!==nck){ocms.forEach(function(s){s.remove()});ncms.forEach(function(s){var c=document.createElement('script');c.type=s.type;c.id=s.id;c.textContent=s.textContent;document.head.appendChild(c)})}window.__menoHotReload=true;var olib=document.querySelectorAll('body > script[src^="/libraries/"]'),nlib=d.querySelectorAll('body > script[src^="/libraries/"]');var olk=JSON.stringify(Array.prototype.map.call(olib,function(s){return strip(s.getAttribute('src'))}).sort());var nlk=JSON.stringify(Array.prototype.map.call(nlib,function(s){return strip(s.getAttribute('src'))}).sort());if(olk!==nlk){olib.forEach(function(o){o.remove()});nlib.forEach(function(n){var src=n.getAttribute('src');var ls=document.createElement('script');ls.src=src+(src.indexOf('?')>-1?'&':'?')+'_r='+Date.now();document.body.appendChild(ls)})}var oscr=document.querySelector('script[src^="/_scripts/"]'),nscr=d.querySelector('script[src^="/_scripts/"]');var oss=oscr?strip(oscr.getAttribute('src')):'',nss=nscr?strip(nscr.getAttribute('src')):'';if(oss===nss){window.scrollTo(sx,sy)}else{if(oscr)oscr.remove();if(nscr){var src=nscr.getAttribute('src');var s=document.createElement('script');s.src=src+(src.indexOf('?')>-1?'&':'?')+'_r='+Date.now();s.onload=function(){document.dispatchEvent(new Event('DOMContentLoaded'));window.scrollTo(sx,sy)};s.onerror=function(){window.scrollTo(sx,sy)};document.body.appendChild(s)}else{document.dispatchEvent(new Event('DOMContentLoaded'));window.scrollTo(sx,sy)}}}).catch(function(){location.reload()})}var iR=document.getElementById('root');if(iR)lastSrvRoot=iR.cloneNode(true);connect()})()</script>` : "";
3529
+ const liveReloadScript = injectLiveReload ? `<script${nonceAttr}>(function(){var ws,timer,gen=0,lastSrvRoot=null,dn=document.querySelector('meta[name="csp-nonce"]'),docNonce=dn?dn.getAttribute('content'):'';function strip(s){return s?s.replace(/[?&]_r=\\d+/,''):''}function classList(el){return (el.getAttribute('class')||'').split(/\\s+/).filter(Boolean)}function syncEl(cur,srv,old){var cc=classList(cur),sc=classList(srv),oc=old?new Set(classList(old)):new Set();var rt=cc.filter(function(c){return !oc.has(c)});var seen=new Set(),fin=[];sc.concat(rt).forEach(function(c){if(!seen.has(c)){seen.add(c);fin.push(c)}});var fs=fin.join(' ');if((cur.getAttribute('class')||'')!==fs){if(fs)cur.setAttribute('class',fs);else cur.removeAttribute('class')}for(var i=0;i<srv.attributes.length;i++){var a=srv.attributes[i];if(a.name==='class')continue;var ov=old?old.getAttribute(a.name):null;if(a.value!==ov){if(cur.getAttribute(a.name)!==a.value)cur.setAttribute(a.name,a.value)}}if(old){for(var i=0;i<old.attributes.length;i++){var a=old.attributes[i];if(a.name==='class')continue;if(!srv.hasAttribute(a.name)&&cur.hasAttribute(a.name))cur.removeAttribute(a.name)}}}function syncText(cur,srv){var cc=cur.childNodes,sc=srv.childNodes;for(var i=0;i<sc.length;i++){var s=sc[i],c=cc[i];if(s.nodeType===3&&c&&c.nodeType===3){if(c.textContent!==s.textContent)c.textContent=s.textContent}}}function ek(el){var p=el.getAttribute('data-element-path'),ci=el.getAttribute('data-cms-item-index');return ci?p+'|'+ci:p}function structKey(root){var e=root.querySelectorAll('[data-element-path]'),k=[];for(var i=0;i<e.length;i++)k.push(ek(e[i]));return k.sort().join('~')}function softSync(curR,srvR,oldR){var ce=curR.querySelectorAll('[data-element-path]');var sbp={},se=srvR.querySelectorAll('[data-element-path]');for(var i=0;i<se.length;i++)sbp[ek(se[i])]=se[i];var obp={};if(oldR){var oe=oldR.querySelectorAll('[data-element-path]');for(var i=0;i<oe.length;i++)obp[ek(oe[i])]=oe[i]}for(var i=0;i<ce.length;i++){var c=ce[i],p=ek(c),s=sbp[p];if(!s)continue;syncEl(c,s,obp[p]);syncText(c,s)}syncText(curR,srvR)}function connect(){ws=new WebSocket(${wsUrl});ws.onmessage=function(e){var d=JSON.parse(e.data);if(d.type==='hmr:libraries-update'){location.reload()}else if(d.type==='hmr:update'||d.type==='hmr:cms-update'||d.type==='hmr:colors-update'||d.type==='hmr:variables-update')hotReload()};ws.onclose=function(){clearTimeout(timer);timer=setTimeout(connect,1000)}}function hotReload(){var g=++gen;var sx=window.scrollX,sy=window.scrollY;fetch(location.href,{cache:'no-store'}).then(function(r){return r.text()}).then(function(html){if(g!==gen)return;var p=new DOMParser();var d=p.parseFromString(html,'text/html');var or=document.getElementById('root'),nr=d.getElementById('root');var oscr=document.querySelector('script[src^="/_scripts/"]'),nscr=d.querySelector('script[src^="/_scripts/"]');var oss=oscr?strip(oscr.getAttribute('src')):'',nss=nscr?strip(nscr.getAttribute('src')):'';var hardReset=(oss!==nss)||!lastSrvRoot||!or||!nr||structKey(lastSrvRoot)!==structKey(nr);if(or&&nr){if(hardReset){if(or.innerHTML!==nr.innerHTML)or.innerHTML=nr.innerHTML}else{softSync(or,nr,lastSrvRoot)}}if(nr)lastSrvRoot=nr.cloneNode(true);var os=document.getElementById('meno-styles'),ns=d.getElementById('meno-styles');if(os&&ns&&os.textContent!==ns.textContent)os.textContent=ns.textContent;var nh=d.documentElement;if(nh){var nl=nh.getAttribute('lang')||'en',nt=nh.getAttribute('theme')||'light';if(document.documentElement.getAttribute('lang')!==nl)document.documentElement.setAttribute('lang',nl);if(document.documentElement.getAttribute('theme')!==nt)document.documentElement.setAttribute('theme',nt)}var ocms=document.querySelectorAll('script[id^="meno-cms-"]'),ncms=d.querySelectorAll('script[id^="meno-cms-"]');var ock=JSON.stringify(Array.prototype.map.call(ocms,function(s){return [s.id,s.textContent]}));var nck=JSON.stringify(Array.prototype.map.call(ncms,function(s){return [s.id,s.textContent]}));if(ock!==nck){ocms.forEach(function(s){s.remove()});ncms.forEach(function(s){var c=document.createElement('script');c.type=s.type;c.id=s.id;if(docNonce)c.nonce=docNonce;c.textContent=s.textContent;document.head.appendChild(c)})}window.__menoHotReload=true;var olib=document.querySelectorAll('body > script[src^="/libraries/"]'),nlib=d.querySelectorAll('body > script[src^="/libraries/"]');var olk=JSON.stringify(Array.prototype.map.call(olib,function(s){return strip(s.getAttribute('src'))}).sort());var nlk=JSON.stringify(Array.prototype.map.call(nlib,function(s){return strip(s.getAttribute('src'))}).sort());if(olk!==nlk){olib.forEach(function(o){o.remove()});nlib.forEach(function(n){var src=n.getAttribute('src');var ls=document.createElement('script');ls.src=src+(src.indexOf('?')>-1?'&':'?')+'_r='+Date.now();document.body.appendChild(ls)})}if(!hardReset){window.scrollTo(sx,sy)}else{if(oscr)oscr.remove();if(nscr){var src=nscr.getAttribute('src');var s=document.createElement('script');s.src=src+(src.indexOf('?')>-1?'&':'?')+'_r='+Date.now();s.onload=function(){document.dispatchEvent(new Event('DOMContentLoaded'));window.scrollTo(sx,sy)};s.onerror=function(){window.scrollTo(sx,sy)};document.body.appendChild(s)}else{document.dispatchEvent(new Event('DOMContentLoaded'));window.scrollTo(sx,sy)}}}).catch(function(){location.reload()})}var iR=document.getElementById('root');if(iR)lastSrvRoot=iR.cloneNode(true);connect()})()</script>` : "";
3704
3530
  const scrollHandlerScript = injectLiveReload ? `<script${nonceAttr}>(function(){window.addEventListener('message',function(e){if(e.data.type==='GET_SCROLL_POSITION'){window.parent.postMessage({type:'SCROLL_POSITION_RESPONSE',scrollX:window.scrollX,scrollY:window.scrollY},'*')}else if(e.data.type==='SET_SCROLL_POSITION'){window.scrollTo(e.data.scrollX,e.data.scrollY)}})})()</script>` : "";
3705
3531
  const styleContent = useBundled ? finalCSS : `
3706
3532
  ${combinedCSS.split("\n").join("\n ")}
@@ -3710,8 +3536,9 @@ picture {
3710
3536
  <head>
3711
3537
  <meta charset="UTF-8">
3712
3538
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
3713
- ${iconTags ? iconTags + "\n " : ""}${scriptPreloadTag ? scriptPreloadTag + "\n " : ""}${imagePreloadTags ? imagePreloadTags + "\n " : ""}${fontPreloadTags ? fontPreloadTags + "\n " : ""}${libraryTags.headCSS ? libraryTags.headCSS + "\n " : ""}${libraryTags.headJS ? libraryTags.headJS + "\n " : ""}${rendered.meta}
3714
- ${configInlineScript}${cmsInlineScript}${clientDataScripts}<style id="meno-styles">${styleContent}</style>${mergedCustomCode.head ? "\n " + mergedCustomCode.head : ""}
3539
+ ${cspNonce ? `<meta name="csp-nonce" content="${cspNonce}">
3540
+ ` : ""}${iconTags ? iconTags + "\n " : ""}${scriptPreloadTag ? scriptPreloadTag + "\n " : ""}${imagePreloadTags ? imagePreloadTags + "\n " : ""}${fontPreloadTags ? fontPreloadTags + "\n " : ""}${libraryTags.headCSS ? libraryTags.headCSS + "\n " : ""}${libraryTags.headJS ? libraryTags.headJS + "\n " : ""}${rendered.meta}
3541
+ ${configInlineScript}${cmsInlineScript}${clientDataScripts}<style id="meno-styles"${nonceAttr}>${styleContent}</style>${mergedCustomCode.head ? "\n " + mergedCustomCode.head : ""}
3715
3542
  </head>
3716
3543
  <body>${mergedCustomCode.bodyStart ? "\n " + mergedCustomCode.bodyStart : ""}
3717
3544
  <div id="root">
@@ -6336,10 +6163,6 @@ export {
6336
6163
  generateFontPreloadTags,
6337
6164
  generateThemeColorVariablesCSS,
6338
6165
  generateVariablesCSS,
6339
- buildSlugIndex,
6340
- translatePath,
6341
- getLocaleLinks,
6342
- resolveSlugToPageId,
6343
6166
  escapeHtml,
6344
6167
  buildAttributes,
6345
6168
  styleToString,
@@ -6362,13 +6185,8 @@ export {
6362
6185
  menoFilterScript,
6363
6186
  needsMenoFilter,
6364
6187
  prepareClientData,
6365
- mergeLibraries,
6366
- generateLibraryTags,
6367
- collectComponentLibraries,
6368
- extractLibraryOrigins,
6369
- filterLibrariesByContext,
6370
6188
  generateSSRHTML,
6371
6189
  FileSystemCMSProvider,
6372
6190
  migrateTemplatesDirectory
6373
6191
  };
6374
- //# sourceMappingURL=chunk-DM54NPEC.js.map
6192
+ //# sourceMappingURL=chunk-IGYR22T6.js.map