@noirmd/previewer 1.2.0 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/dist/NReditor.cjs +928 -895
  2. package/dist/NReditor.cjs.map +1 -1
  3. package/dist/NReditor.d.cts +1 -1
  4. package/dist/NReditor.d.ts +1 -1
  5. package/dist/NReditor.js +929 -896
  6. package/dist/NReditor.js.map +1 -1
  7. package/dist/admonition.css +55 -0
  8. package/dist/{markdown.css → base.css} +96 -126
  9. package/dist/blockquote.css +16 -0
  10. package/dist/button.css +32 -0
  11. package/dist/card.css +143 -0
  12. package/dist/codeblock.css +59 -0
  13. package/dist/core.cjs +9 -1
  14. package/dist/core.cjs.map +1 -1
  15. package/dist/core.js +9 -1
  16. package/dist/core.js.map +1 -1
  17. package/dist/details.css +45 -0
  18. package/dist/editor.css +56 -9
  19. package/dist/fonts/material-icons-round.woff2 +0 -0
  20. package/dist/index.cjs +929 -882
  21. package/dist/index.cjs.map +1 -1
  22. package/dist/index.d.cts +41 -70
  23. package/dist/index.d.ts +41 -70
  24. package/dist/index.js +928 -876
  25. package/dist/index.js.map +1 -1
  26. package/dist/list.css +18 -0
  27. package/dist/modal.css +82 -0
  28. package/dist/react.cjs +929 -885
  29. package/dist/react.cjs.map +1 -1
  30. package/dist/react.d.cts +44 -73
  31. package/dist/react.d.ts +44 -73
  32. package/dist/react.js +928 -879
  33. package/dist/react.js.map +1 -1
  34. package/dist/slide.css +21 -0
  35. package/dist/table.css +36 -0
  36. package/dist/toc.css +45 -0
  37. package/dist/vanilla.cjs +123 -31
  38. package/dist/vanilla.cjs.map +1 -1
  39. package/dist/vanilla.css +32 -677
  40. package/dist/vanilla.d.cts +24 -2
  41. package/dist/vanilla.d.ts +24 -2
  42. package/dist/vanilla.js +119 -31
  43. package/dist/vanilla.js.map +1 -1
  44. package/dist/variables.css +90 -0
  45. package/dist/vue.cjs +1007 -1120
  46. package/dist/vue.cjs.map +1 -1
  47. package/dist/vue.d.cts +63 -214
  48. package/dist/vue.d.ts +63 -214
  49. package/dist/vue.js +1006 -1119
  50. package/dist/vue.js.map +1 -1
  51. package/editor.css +56 -9
  52. package/package.json +5 -10
  53. package/markdown.css +0 -344
package/dist/NReditor.cjs CHANGED
@@ -33,7 +33,7 @@ __export(NReditor_exports, {
33
33
  default: () => NReditor_default
34
34
  });
35
35
  module.exports = __toCommonJS(NReditor_exports);
36
- var import_react11 = __toESM(require("react"), 1);
36
+ var import_react4 = __toESM(require("react"), 1);
37
37
  var import_react_codemirror = __toESM(require("@uiw/react-codemirror"), 1);
38
38
  var import_view = require("@codemirror/view");
39
39
 
@@ -349,6 +349,75 @@ function useDebounce(value, delay) {
349
349
 
350
350
  // react/useTailwindCDN.ts
351
351
  var import_react2 = require("react");
352
+
353
+ // vanilla/tailwindTheme.ts
354
+ var THEME_STYLE_ID = "nr-tailwind-theme";
355
+ var NR_THEME_CSS = `
356
+ @theme {
357
+ --color-primary: var(--color-accent-primary, oklch(var(--p, 55% 0.3 240) / 1));
358
+ --color-primary-content: #ffffff;
359
+ --color-secondary: oklch(var(--s, 55% 0.25 200) / 1);
360
+ --color-secondary-content: #ffffff;
361
+ --color-accent: var(--color-accent-primary, oklch(var(--a, 65% 0.25 160) / 1));
362
+ --color-accent-content: #ffffff;
363
+ --color-neutral: oklch(var(--n, 50% 0.05 240) / 1);
364
+ --color-neutral-content: var(--color-text-primary, oklch(var(--nc, 92% 0.02 240) / 1));
365
+ --color-base-100: var(--color-background-primary, oklch(var(--b1, 15% 0.01 260) / 1));
366
+ --color-base-200: var(--color-background-secondary-solid, oklch(var(--b2, 20% 0.02 260) / 1));
367
+ --color-base-300: var(--color-border, oklch(var(--b3, 25% 0.03 260) / 1));
368
+ --color-base-content: var(--color-text-primary, oklch(var(--bc, 92% 0.02 260) / 1));
369
+ --color-info: oklch(var(--in, 70% 0.2 220) / 1);
370
+ --color-info-content: #ffffff;
371
+ --color-success: oklch(var(--su, 65% 0.25 140) / 1);
372
+ --color-success-content: #ffffff;
373
+ --color-warning: oklch(var(--wa, 80% 0.25 80) / 1);
374
+ --color-warning-content: #1f2937;
375
+ --color-error: oklch(var(--er, 65% 0.3 30) / 1);
376
+ --color-error-content: #ffffff;
377
+ }
378
+ `;
379
+ function getVar(root, name) {
380
+ return getComputedStyle(root).getPropertyValue(name).trim();
381
+ }
382
+ function stylesheetHasTheme() {
383
+ for (const sheet of Array.from(document.styleSheets)) {
384
+ let rules = null;
385
+ try {
386
+ rules = sheet.cssRules;
387
+ } catch {
388
+ continue;
389
+ }
390
+ if (!rules) continue;
391
+ for (const rule of Array.from(rules)) {
392
+ const css2 = rule.cssText || "";
393
+ if (css2.includes("@theme") || css2.includes('@plugin "daisyui"')) return true;
394
+ }
395
+ }
396
+ return false;
397
+ }
398
+ function hasHostTheme() {
399
+ if (typeof window === "undefined" || typeof document === "undefined") return true;
400
+ if (getVar(document.documentElement, "--color-primary")) return true;
401
+ if (getVar(document.documentElement, "--color-base-100")) return true;
402
+ if (document.body && (getVar(document.body, "--color-primary") || getVar(document.body, "--color-base-100"))) return true;
403
+ return stylesheetHasTheme();
404
+ }
405
+ function injectNRTailwindTheme() {
406
+ if (typeof document === "undefined") return;
407
+ if (document.getElementById(THEME_STYLE_ID)) return;
408
+ if (hasHostTheme()) return;
409
+ const style = document.createElement("style");
410
+ style.id = THEME_STYLE_ID;
411
+ style.setAttribute("type", "text/tailwindcss");
412
+ style.textContent = NR_THEME_CSS;
413
+ document.head.appendChild(style);
414
+ }
415
+ function removeNRTailwindTheme() {
416
+ if (typeof document === "undefined") return;
417
+ document.getElementById(THEME_STYLE_ID)?.remove();
418
+ }
419
+
420
+ // react/useTailwindCDN.ts
352
421
  var CDN_URL = "https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4";
353
422
  var SCRIPT_ID = "tailwind-cdn-v4-runtime";
354
423
  var CONFIG_ID = "tailwind-cdn-v4-config";
@@ -368,6 +437,7 @@ function useLazyTailwindCDN(enabled) {
368
437
  if ((window.__twCDNRefs ?? 0) <= 0) {
369
438
  document.getElementById(SCRIPT_ID)?.remove();
370
439
  document.getElementById(CONFIG_ID)?.remove();
440
+ removeNRTailwindTheme();
371
441
  window.__twCDNRefs = 0;
372
442
  loadedRef.current = false;
373
443
  }
@@ -380,6 +450,7 @@ function useLazyTailwindCDN(enabled) {
380
450
  configScript.textContent = TAILWIND_CDN_CONFIG;
381
451
  document.head.appendChild(configScript);
382
452
  }
453
+ injectNRTailwindTheme();
383
454
  if (!document.getElementById(SCRIPT_ID)) {
384
455
  const script = document.createElement("script");
385
456
  script.id = SCRIPT_ID;
@@ -392,6 +463,7 @@ function useLazyTailwindCDN(enabled) {
392
463
  if ((window.__twCDNRefs ?? 0) <= 0) {
393
464
  document.getElementById(SCRIPT_ID)?.remove();
394
465
  document.getElementById(CONFIG_ID)?.remove();
466
+ removeNRTailwindTheme();
395
467
  window.__twCDNRefs = 0;
396
468
  loadedRef.current = false;
397
469
  }
@@ -404,7 +476,7 @@ function scanTailwindCDN() {
404
476
  }
405
477
 
406
478
  // react/CustomMarkdownRenderer.tsx
407
- var import_react10 = __toESM(require("react"), 1);
479
+ var import_react3 = require("react");
408
480
 
409
481
  // core/utils.ts
410
482
  function parseCssString(cssText) {
@@ -450,9 +522,6 @@ function extractAttributes(text) {
450
522
  return { text: cleanedText, classes: classList.join(" "), id };
451
523
  }
452
524
  var _scopeCounter = 0;
453
- function resetScopeCounter() {
454
- _scopeCounter = 0;
455
- }
456
525
  function generateScopeId() {
457
526
  return `scope-${++_scopeCounter}`;
458
527
  }
@@ -500,6 +569,7 @@ function parseMarkdown(markdown2) {
500
569
  if (!markdown2) return [];
501
570
  const lines = markdown2.replace(/\r\n/g, "\n").replace(/\r/g, "").split("\n");
502
571
  const result = [];
572
+ const usedIds = /* @__PURE__ */ new Set();
503
573
  let i = 0;
504
574
  while (i < lines.length) {
505
575
  const line = lines[i];
@@ -509,7 +579,14 @@ function parseMarkdown(markdown2) {
509
579
  const level = match[1].length;
510
580
  const rawText = match[2];
511
581
  const { text: text2, classes: classes2, id: customId } = extractAttributes(rawText);
512
- const id2 = customId || generateId(text2.replace(/->|<-/g, ""));
582
+ const baseId = customId || generateId(text2.replace(/->|<-/g, ""));
583
+ let id2 = baseId;
584
+ let n = 1;
585
+ while (usedIds.has(id2)) {
586
+ n++;
587
+ id2 = `${baseId}-${n}`;
588
+ }
589
+ usedIds.add(id2);
513
590
  result.push({ type: "header", level, text: text2, id: id2, classes: classes2 || void 0 });
514
591
  i++;
515
592
  continue;
@@ -824,10 +901,7 @@ function splitSlots(rawContent) {
824
901
  return slots;
825
902
  }
826
903
 
827
- // react/ui-components.tsx
828
- var import_react3 = require("react");
829
-
830
- // react/highlightSetup.ts
904
+ // vanilla/highlightSetup.ts
831
905
  var import_core = __toESM(require("highlight.js/lib/core"), 1);
832
906
  var import_javascript = __toESM(require("highlight.js/lib/languages/javascript"), 1);
833
907
  var import_typescript = __toESM(require("highlight.js/lib/languages/typescript"), 1);
@@ -876,991 +950,952 @@ import_core.default.registerLanguage("java", import_java.default);
876
950
  import_core.default.registerLanguage("csharp", import_csharp.default);
877
951
  import_core.default.registerLanguage("cs", import_csharp.default);
878
952
  import_core.default.registerLanguage("cpp", import_cpp.default);
879
- import_core.default.registerLanguage("c", import_cpp.default);
880
953
  import_core.default.registerLanguage("go", import_go.default);
881
954
  import_core.default.registerLanguage("rust", import_rust.default);
882
- import_core.default.registerLanguage("rs", import_rust.default);
883
955
  import_core.default.registerLanguage("php", import_php.default);
884
956
  import_core.default.registerLanguage("ruby", import_ruby.default);
885
- import_core.default.registerLanguage("rb", import_ruby.default);
886
957
  import_core.default.registerLanguage("swift", import_swift.default);
887
958
  import_core.default.registerLanguage("kotlin", import_kotlin.default);
888
- import_core.default.registerLanguage("kt", import_kotlin.default);
889
959
  import_core.default.registerLanguage("dart", import_dart.default);
890
960
  import_core.default.registerLanguage("yaml", import_yaml.default);
891
- import_core.default.registerLanguage("yml", import_yaml.default);
892
961
  import_core.default.registerLanguage("toml", import_ini.default);
893
- import_core.default.registerLanguage("ini", import_ini.default);
894
962
  import_core.default.registerLanguage("dockerfile", import_dockerfile.default);
895
- import_core.default.registerLanguage("docker", import_dockerfile.default);
896
963
  import_core.default.registerLanguage("diff", import_diff.default);
897
964
  import_core.default.registerLanguage("shell", import_shell.default);
898
965
  var highlightSetup_default = import_core.default;
899
966
 
900
- // react/ui-components.tsx
901
- var import_dialog = require("@base-ui/react/dialog");
902
- var import_jsx_runtime = require("react/jsx-runtime");
903
- var IconRenderer = ({ iconName, extraClasses = "" }) => {
904
- if (!iconName) return null;
905
- const baseClass = `material-symbols-rounded !text-[1em] leading-none align-top ${extraClasses}`;
967
+ // vanilla/components.ts
968
+ function createIcon(iconName, extraClasses) {
969
+ const span = document.createElement("span");
970
+ const cls = `nr-icon material-icons-round${extraClasses ? ` ${extraClasses}` : ""}`;
971
+ span.className = cls;
972
+ span.setAttribute("aria-hidden", "true");
906
973
  const isCodepoint = /^[eE][0-9a-fA-F]{3,4}$/.test(iconName);
907
974
  if (isCodepoint) {
908
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
909
- "span",
910
- {
911
- className: baseClass,
912
- dangerouslySetInnerHTML: { __html: `&#x${iconName};` },
913
- "aria-hidden": "true"
914
- }
915
- );
975
+ span.innerHTML = `&#x${iconName};`;
976
+ } else {
977
+ span.textContent = iconName;
916
978
  }
917
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: baseClass, "aria-hidden": "true", children: iconName });
918
- };
919
- var CodeBlock = ({ code, language, title }) => {
920
- const [copied, setCopied] = (0, import_react3.useState)(false);
921
- const timerRef = (0, import_react3.useRef)(null);
979
+ return span;
980
+ }
981
+ function createCodeBlock(code, language, title) {
982
+ const wrapper = document.createElement("div");
983
+ wrapper.className = "nr-codeblock";
922
984
  const lang = language?.split(/[\s{]/)[0]?.trim() || "";
923
- let html;
985
+ if (title) {
986
+ const header = document.createElement("div");
987
+ header.className = "nr-codeblock__header";
988
+ header.appendChild(createIcon("description"));
989
+ const titleSpan = document.createElement("span");
990
+ titleSpan.textContent = title;
991
+ header.appendChild(titleSpan);
992
+ wrapper.appendChild(header);
993
+ }
994
+ const pre = document.createElement("pre");
995
+ pre.className = "nr-codeblock__pre";
996
+ const codeEl = document.createElement("code");
997
+ codeEl.className = `language-${lang || "plaintext"}`;
924
998
  try {
925
999
  if (lang && highlightSetup_default.getLanguage(lang)) {
926
- html = highlightSetup_default.highlight(code, { language: lang }).value;
1000
+ codeEl.innerHTML = highlightSetup_default.highlight(code, { language: lang }).value;
927
1001
  } else {
928
- html = highlightSetup_default.highlightAuto(code).value;
1002
+ codeEl.innerHTML = highlightSetup_default.highlightAuto(code).value;
929
1003
  }
930
1004
  } catch {
931
- html = "";
1005
+ codeEl.textContent = code;
932
1006
  }
933
- const handleCopy = () => {
1007
+ pre.appendChild(codeEl);
1008
+ wrapper.appendChild(pre);
1009
+ const copyBtn = document.createElement("button");
1010
+ copyBtn.className = "nr-codeblock__copy";
1011
+ copyBtn.title = "Copy code";
1012
+ const copyIcon = createIcon("content_copy");
1013
+ copyIcon.style.fontSize = "1rem";
1014
+ copyBtn.appendChild(copyIcon);
1015
+ let timer = null;
1016
+ copyBtn.addEventListener("click", () => {
934
1017
  navigator.clipboard.writeText(code);
935
- setCopied(true);
936
- if (timerRef.current) clearTimeout(timerRef.current);
937
- timerRef.current = setTimeout(() => setCopied(false), 1800);
938
- };
939
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "not-prose my-4 rounded-2xl border border-border overflow-hidden bg-background-secondary-solid/5", children: [
940
- title && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-center gap-2 px-4 py-2 border-b border-border bg-background-secondary-solid/10 text-xs sm:text-sm font-mono text-text-secondary", children: [
941
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "material-symbols-rounded text-base", children: "description" }),
942
- title
943
- ] }),
944
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "overflow-auto [&_pre]:m-0 [&_pre]:p-4 [&_pre]:text-xs sm:[&_pre]:text-sm", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("pre", { className: "m-0", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("code", { className: `language-${lang || "plaintext"}`, dangerouslySetInnerHTML: { __html: html } }) }) }),
945
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { className: "absolute top-2 right-2 p-1.5 rounded-lg bg-background-secondary-solid/20 hover:bg-background-secondary-solid/40 transition-colors cursor-pointer border-none text-text-secondary hover:text-text-primary", onClick: handleCopy, title: "Copy code", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "material-symbols-rounded", style: { fontSize: "1rem" }, children: copied ? "check" : "content_copy" }) })
946
- ] });
947
- };
948
- var defaultIcons = {
1018
+ copyIcon.textContent = "check";
1019
+ if (timer) clearTimeout(timer);
1020
+ timer = setTimeout(() => {
1021
+ copyIcon.textContent = "content_copy";
1022
+ }, 1800);
1023
+ });
1024
+ wrapper.appendChild(copyBtn);
1025
+ return wrapper;
1026
+ }
1027
+ var DEFAULT_ADMONITION_ICONS = {
949
1028
  note: "info",
950
1029
  info: "lightbulb",
951
1030
  warning: "warning",
952
1031
  danger: "report",
953
- greentext: "subdirectory_play_arrow"
954
- };
955
- var typeClasses = {
956
- note: "border-info/20 bg-info/5 text-info",
957
- info: "border-info/30 bg-info/10 text-info",
958
- warning: "border-amber-500/30 bg-amber-500/10 text-amber-500",
959
- danger: "border-danger/30 bg-danger/10 text-danger",
960
- greentext: "border-success/30 bg-success/10 text-success"
961
- };
962
- var Admonition = ({ type, title, icon, className = "", style, children }) => {
963
- const iconToRender = icon || defaultIcons[type] || "info";
964
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
965
- "div",
966
- {
967
- className: `not-prose rounded-2xl mb-6 border shadow-xs p-4 ${typeClasses[type] || typeClasses.note} ${className}`,
968
- style,
969
- children: [
970
- title && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("h5", { className: "font-bold text-base mb-2 m-0 flex items-center gap-2", children: [
971
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(IconRenderer, { iconName: iconToRender, extraClasses: "shrink-0" }),
972
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: title })
973
- ] }),
974
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "text-sm leading-relaxed opacity-90", children })
975
- ]
976
- }
977
- );
1032
+ greentext: "subdirectory_arrow_right"
978
1033
  };
979
- var Details = ({
980
- title,
981
- icon,
982
- defaultOpen = false,
983
- className = "",
984
- style,
985
- children
986
- }) => {
987
- const [isOpen, setIsOpen] = (0, import_react3.useState)(defaultOpen);
988
- const iconToRender = icon || "play_arrow";
989
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
990
- "details",
991
- {
992
- className: `not-prose rounded-2xl border border-border mb-4 bg-background-primary/5 ${className}`,
993
- open: isOpen,
994
- style,
995
- children: [
996
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
997
- "summary",
998
- {
999
- className: "cursor-pointer p-4 font-bold flex items-center gap-2 list-none [&::-webkit-details-marker]:hidden hover:text-accent-primary transition-colors",
1000
- onClick: (e) => {
1001
- e.preventDefault();
1002
- setIsOpen((prev) => !prev);
1003
- },
1004
- children: [
1005
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1006
- IconRenderer,
1007
- {
1008
- iconName: iconToRender,
1009
- extraClasses: `transition-transform ${isOpen ? "rotate-90" : ""}`
1010
- }
1011
- ),
1012
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: title })
1013
- ]
1014
- }
1015
- ),
1016
- isOpen && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "px-4 pb-4 border-t border-border pt-3 text-sm leading-relaxed opacity-90 overflow-hidden min-w-0", children })
1017
- ]
1018
- }
1019
- );
1020
- };
1021
- var Modal = ({ title, isOpen, onClose, children }) => {
1022
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dialog.Dialog.Root, { open: isOpen, onOpenChange: (open) => {
1023
- if (!open) onClose();
1024
- }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_dialog.Dialog.Portal, { children: [
1025
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dialog.Dialog.Backdrop, { className: "fixed inset-0 z-[9999] bg-black/60" }),
1026
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dialog.Dialog.Viewport, { className: "fixed inset-0 z-[9999] flex items-center justify-center p-4", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_dialog.Dialog.Popup, { className: "bg-background-primary border border-border shadow-2xl rounded-3xl w-full max-w-3xl max-h-[85vh] flex flex-col overflow-hidden", children: [
1027
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex justify-between items-center p-4 border-b border-border bg-background-secondary-solid/20", children: [
1028
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dialog.Dialog.Title, { className: "text-lg font-bold !m-0", children: title }),
1029
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dialog.Dialog.Close, { className: "w-8 h-8 rounded-full hover:bg-white/10 flex items-center justify-center transition-colors cursor-pointer border-none bg-transparent", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "material-symbols-rounded text-base", children: "close" }) })
1030
- ] }),
1031
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "p-6 overflow-auto min-h-0 text-text-primary [&_h1:first-child]:mt-0 [&_h2:first-child]:mt-0 [&_h3:first-child]:mt-0 [&_h4:first-child]:mt-0 [&_h5:first-child]:mt-0 [&_h6:first-child]:mt-0", children })
1032
- ] }) })
1033
- ] }) });
1034
- };
1035
-
1036
- // react/renderers.tsx
1037
- var import_jsx_runtime2 = require("react/jsx-runtime");
1038
- function renderInline(text) {
1039
- if (!text) return text;
1040
- const parsePart = (part, key) => {
1041
- let match2;
1042
- if (match2 = part.match(/^\|\[([^\]]+)\]\|$/)) {
1043
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(IconRenderer, { iconName: match2[1] }, key);
1044
- }
1045
- if (match2 = part.match(/^!~(.+?)~!$/)) {
1046
- const content = match2[1];
1047
- const parts = content.split(";");
1048
- let color = "currentColor";
1049
- let decorationStyle = "solid";
1050
- let type = "underline";
1051
- let textIndex = 0;
1052
- if (parts[textIndex]?.match(/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/) || ["red", "blue", "green", "purple", "orange", "yellow", "pink"].includes(parts[textIndex])) {
1053
- color = parts[textIndex++];
1054
- }
1055
- if (["solid", "double", "dotted", "dashed", "wavy"].includes(parts[textIndex])) {
1056
- decorationStyle = parts[textIndex++];
1057
- }
1058
- if (["underline", "line-through", "overline", "both"].includes(parts[textIndex])) {
1059
- type = parts[textIndex] === "both" ? "underline line-through" : parts[textIndex++];
1060
- }
1061
- const innerText = parts.slice(textIndex).join(";");
1062
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1063
- "span",
1064
- {
1065
- style: {
1066
- textDecoration: `${type} ${decorationStyle} ${color}`,
1067
- textDecorationThickness: "auto"
1068
- },
1069
- children: renderInline(innerText)
1070
- },
1071
- key
1072
- );
1073
- }
1074
- if (match2 = part.match(/%([^%\s]+?)%([\s\S]+?)%%/)) {
1075
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { color: match2[1] }, children: renderInline(match2[2]) }, key);
1076
- }
1077
- if (match2 = part.match(/^!>([^<]+?)<!$/)) {
1078
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "bg-text-primary text-bg-primary px-1 rounded hover:bg-transparent transition-colors cursor-pointer", children: renderInline(match2[1]) }, key);
1079
- }
1080
- if (match2 = part.match(/^==(.+?)==$/)) {
1081
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("mark", { className: "bg-yellow-500/20 text-inherit px-0.5 rounded", children: renderInline(match2[1]) }, key);
1082
- }
1083
- if (match2 = part.match(/^\*\*\*(.+?)\*\*\*$/)) {
1084
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("strong", { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("em", { children: renderInline(match2[1]) }) }, key);
1085
- }
1086
- if (match2 = part.match(/^\*\*(.+?)\*\*$/)) {
1087
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("strong", { children: renderInline(match2[1]) }, key);
1088
- }
1089
- if (match2 = part.match(/^_(.+?)_$/)) {
1090
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("em", { children: renderInline(match2[1]) }, key);
1091
- }
1092
- if (match2 = part.match(/^~~(.+?)~~$/)) {
1093
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("del", { children: renderInline(match2[1]) }, key);
1094
- }
1095
- if (match2 = part.match(/^`([^`]+)`$/)) {
1096
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("code", { className: "text-[0.875em] font-mono bg-background-secondary/50 px-1.5 py-0.5 rounded text-text-primary", children: match2[1] }, key);
1097
- }
1098
- if (match2 = part.match(/^\[([^\]]+?)\]\(([^)]+?)\)$/)) {
1099
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1100
- "a",
1101
- {
1102
- href: match2[2],
1103
- className: "text-accent-primary underline decoration-accent-primary/40 hover:decoration-accent-primary transition-colors",
1104
- target: "_blank",
1105
- rel: "noopener noreferrer",
1106
- children: renderInline(match2[1])
1107
- },
1108
- key
1109
- );
1110
- }
1111
- if (part.startsWith("<") && part.endsWith(">")) {
1112
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { dangerouslySetInnerHTML: { __html: part } }, key);
1113
- }
1114
- return part;
1115
- };
1116
- const regex = /(\|\[[^\]]+\]\||\*\*\*.+?\*\*\*|\*\*.+?\*\*|_.+?_|~~.+?~~|`[^`]+?`|!~.+?~!|%[^%\s]+?%[\s\S]+?%%|!>.+?<!|==.+?==|\[[^\]]+?\]\([^)]+?\)|<[^>]+>)/g;
1117
- const elements = [];
1118
- let lastIndex = 0;
1119
- let match;
1120
- let keyCounter = 0;
1121
- while ((match = regex.exec(text)) !== null) {
1122
- if (match.index > lastIndex) {
1123
- elements.push(text.slice(lastIndex, match.index));
1124
- }
1125
- elements.push(parsePart(match[0], `inline-${keyCounter++}`));
1126
- lastIndex = regex.lastIndex;
1034
+ function createAdmonition(type, title, icon) {
1035
+ const el = document.createElement("div");
1036
+ el.className = `nr-admonition nr-admonition--${type || "note"}`;
1037
+ if (title) {
1038
+ const header = document.createElement("h5");
1039
+ header.className = "nr-admonition__title";
1040
+ const iconToRender = icon || DEFAULT_ADMONITION_ICONS[type] || "info";
1041
+ header.appendChild(createIcon(iconToRender, "nr-admonition__icon"));
1042
+ const titleSpan = document.createElement("span");
1043
+ titleSpan.textContent = title;
1044
+ header.appendChild(titleSpan);
1045
+ el.appendChild(header);
1127
1046
  }
1128
- if (lastIndex < text.length) {
1129
- elements.push(text.slice(lastIndex));
1130
- }
1131
- return elements;
1047
+ const body = document.createElement("div");
1048
+ body.className = "nr-admonition__body";
1049
+ el.appendChild(body);
1050
+ return el;
1132
1051
  }
1133
- function renderTable(content) {
1052
+ function createDetails(title, icon, defaultOpen) {
1053
+ const details = document.createElement("details");
1054
+ details.className = "nr-details";
1055
+ if (defaultOpen) details.open = true;
1056
+ const summary = document.createElement("summary");
1057
+ summary.className = "nr-details__summary";
1058
+ const iconToRender = icon || "play_arrow";
1059
+ const iconEl = createIcon(iconToRender, "nr-details__icon");
1060
+ summary.appendChild(iconEl);
1061
+ const titleSpan = document.createElement("span");
1062
+ titleSpan.textContent = title || "Details";
1063
+ summary.appendChild(titleSpan);
1064
+ details.addEventListener("toggle", () => {
1065
+ iconEl.classList.toggle("nr-details__icon--open", details.open);
1066
+ });
1067
+ details.appendChild(summary);
1068
+ const body = document.createElement("div");
1069
+ body.className = "nr-details__body";
1070
+ details.appendChild(body);
1071
+ return details;
1072
+ }
1073
+ function createModal(title) {
1074
+ const dialog = document.createElement("dialog");
1075
+ dialog.className = "nr-modal";
1076
+ dialog.addEventListener("click", (e) => {
1077
+ if (e.target === dialog) {
1078
+ dialog.close();
1079
+ }
1080
+ });
1081
+ const popup = document.createElement("div");
1082
+ popup.className = "nr-modal__popup";
1083
+ const header = document.createElement("div");
1084
+ header.className = "nr-modal__header";
1085
+ const titleEl = document.createElement("h2");
1086
+ titleEl.className = "nr-modal__title";
1087
+ titleEl.textContent = title;
1088
+ header.appendChild(titleEl);
1089
+ const closeBtn = document.createElement("button");
1090
+ closeBtn.className = "nr-modal__close";
1091
+ closeBtn.appendChild(createIcon("close"));
1092
+ closeBtn.addEventListener("click", () => dialog.close());
1093
+ header.appendChild(closeBtn);
1094
+ popup.appendChild(header);
1095
+ const body = document.createElement("div");
1096
+ body.className = "nr-modal__body";
1097
+ popup.appendChild(body);
1098
+ dialog.appendChild(popup);
1099
+ return dialog;
1100
+ }
1101
+ function createTable(content, renderInline2) {
1134
1102
  const rows = content.split("\n").filter((r) => r.trim());
1135
- if (rows.length < 2) return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { children: content });
1103
+ if (rows.length < 2) {
1104
+ const p = document.createElement("p");
1105
+ p.textContent = content;
1106
+ return p;
1107
+ }
1136
1108
  const parseRow = (row) => row.split("|").map((c) => c.trim()).filter(Boolean);
1137
1109
  const headerCells = parseRow(rows[0]);
1138
1110
  const bodyRows = rows.slice(2).map(parseRow);
1139
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "overflow-x-auto", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("table", { className: "w-full text-sm sm:text-base border-collapse my-4", children: [
1140
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("tr", { children: headerCells.map((cell, ci) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("th", { className: "border border-border px-3 py-2 bg-background-secondary-solid/10 text-left font-bold", children: renderInline(cell) }, ci)) }) }),
1141
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("tbody", { children: bodyRows.map((cells, ri) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("tr", { children: cells.map((cell, ci) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("td", { className: "border border-border px-3 py-2", children: renderInline(cell) }, ci)) }, ri)) })
1142
- ] }) });
1111
+ const wrapper = document.createElement("div");
1112
+ wrapper.className = "nr-table-wrap";
1113
+ const table = document.createElement("table");
1114
+ table.className = "nr-table";
1115
+ const thead = document.createElement("thead");
1116
+ const tr = document.createElement("tr");
1117
+ for (const cell of headerCells) {
1118
+ const th = document.createElement("th");
1119
+ th.className = "nr-table__th";
1120
+ th.appendChild(renderInline2(cell));
1121
+ tr.appendChild(th);
1122
+ }
1123
+ thead.appendChild(tr);
1124
+ table.appendChild(thead);
1125
+ const tbody = document.createElement("tbody");
1126
+ for (const cells of bodyRows) {
1127
+ const tr2 = document.createElement("tr");
1128
+ for (const cell of cells) {
1129
+ const td = document.createElement("td");
1130
+ td.className = "nr-table__td";
1131
+ td.appendChild(renderInline2(cell));
1132
+ tr2.appendChild(td);
1133
+ }
1134
+ tbody.appendChild(tr2);
1135
+ }
1136
+ table.appendChild(tbody);
1137
+ wrapper.appendChild(table);
1138
+ return wrapper;
1143
1139
  }
1144
- function renderList(content) {
1140
+ function createList(content, renderInline2) {
1145
1141
  const lines = content.split("\n");
1146
1142
  const items = [];
1147
1143
  for (const line of lines) {
1148
1144
  if (!line.trim()) continue;
1149
1145
  const match = line.match(/^(\s*)([-*+]|\d+\.)\s+(.+)$/);
1150
1146
  if (match) {
1151
- items.push({
1152
- indent: match[1].length,
1153
- marker: match[2],
1154
- text: match[3]
1155
- });
1147
+ items.push({ indent: match[1].length, marker: match[2], text: match[3] });
1156
1148
  }
1157
1149
  }
1158
- if (items.length === 0) return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { children: content });
1150
+ if (items.length === 0) {
1151
+ const p = document.createElement("p");
1152
+ p.textContent = content;
1153
+ return p;
1154
+ }
1159
1155
  const isOrdered = /^\d+\.$/.test(items[0].marker);
1160
- const Tag = isOrdered ? "ol" : "ul";
1161
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Tag, { className: `${isOrdered ? "list-decimal" : "list-disc"} pl-6 my-3 space-y-1 text-sm sm:text-base`, children: items.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("li", { className: "leading-relaxed", children: renderInline(item.text) }, index)) });
1156
+ const list = document.createElement(isOrdered ? "ol" : "ul");
1157
+ list.className = "nr-list";
1158
+ for (const item of items) {
1159
+ const li = document.createElement("li");
1160
+ li.className = "nr-list__item";
1161
+ li.appendChild(renderInline2(item.text));
1162
+ list.appendChild(li);
1163
+ }
1164
+ return list;
1162
1165
  }
1163
- function extractHeaders(elements) {
1164
- return elements.filter((el) => el.type === "header");
1166
+ function createTOC(headers, renderInline2) {
1167
+ const nav = document.createElement("nav");
1168
+ nav.className = "nr-toc";
1169
+ const title = document.createElement("div");
1170
+ title.className = "nr-toc__title";
1171
+ title.textContent = "Table of Contents";
1172
+ nav.appendChild(title);
1173
+ const ul = document.createElement("ul");
1174
+ ul.className = "nr-toc__list";
1175
+ for (const h of headers) {
1176
+ const li = document.createElement("li");
1177
+ li.className = `nr-toc__item nr-toc__item--h${h.level}`;
1178
+ const a = document.createElement("a");
1179
+ a.className = "nr-toc__link";
1180
+ a.href = `#${h.id}`;
1181
+ a.appendChild(renderInline2(h.text.replace(/->|<-/g, "").trim()));
1182
+ a.addEventListener("click", (e) => {
1183
+ e.preventDefault();
1184
+ const target = document.getElementById(h.id);
1185
+ if (target) target.scrollIntoView({ behavior: "smooth", block: "start" });
1186
+ });
1187
+ li.appendChild(a);
1188
+ ul.appendChild(li);
1189
+ }
1190
+ nav.appendChild(ul);
1191
+ return nav;
1192
+ }
1193
+ function createBlockquote(content, classes, renderInline2) {
1194
+ const el = document.createElement("blockquote");
1195
+ el.className = `nr-blockquote${classes ? ` ${classes}` : ""}`;
1196
+ el.appendChild(renderInline2(content));
1197
+ return el;
1165
1198
  }
1166
1199
 
1167
- // react/directives/AdmonitionDirective.tsx
1168
- var import_jsx_runtime3 = require("react/jsx-runtime");
1169
- var AdmonitionDirective = ({
1170
- directiveType,
1171
- props,
1172
- renderSlot
1173
- }) => {
1174
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1175
- Admonition,
1176
- {
1177
- type: directiveType,
1178
- title: props.title,
1179
- icon: props.icon,
1180
- className: props.class,
1181
- style: props.style ? parseCssString(props.style) : void 0,
1182
- children: renderSlot("default")
1200
+ // vanilla/inline.ts
1201
+ function renderInline(text) {
1202
+ const fragment = document.createDocumentFragment();
1203
+ if (!text) return fragment;
1204
+ const regex = /(\|\[[^\]]+\]\||\*\*\*.+?\*\*\*|\*\*.+?\*\*|_.+?_|~~.+?~~|`[^`]+?`|!~.+?~!|%[^%\s]+?%[\s\S]+?%%|!>.+?<!|==.+?==|\[[^\]]+?\]\([^)]+?\)|<[^>]+>)/g;
1205
+ let lastIndex = 0;
1206
+ let match;
1207
+ while ((match = regex.exec(text)) !== null) {
1208
+ if (match.index > lastIndex) {
1209
+ fragment.appendChild(document.createTextNode(text.slice(lastIndex, match.index)));
1183
1210
  }
1184
- );
1185
- };
1186
- var AdmonitionDirective_default = AdmonitionDirective;
1211
+ fragment.appendChild(parseInlinePart(match[0]));
1212
+ lastIndex = regex.lastIndex;
1213
+ }
1214
+ if (lastIndex < text.length) {
1215
+ fragment.appendChild(document.createTextNode(text.slice(lastIndex)));
1216
+ }
1217
+ return fragment;
1218
+ }
1219
+ function parseInlinePart(part) {
1220
+ let match;
1221
+ if (match = part.match(/^\|\[([^\]]+)\]\|$/)) {
1222
+ return createIcon(match[1]);
1223
+ }
1224
+ if (match = part.match(/^!~(.+?)~!$/)) {
1225
+ const content = match[1];
1226
+ const parts = content.split(";");
1227
+ let color = "currentColor";
1228
+ let decorationStyle = "solid";
1229
+ let type = "underline";
1230
+ let textIndex = 0;
1231
+ if (parts[textIndex]?.match(/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/) || ["red", "blue", "green", "purple", "orange", "yellow", "pink"].includes(parts[textIndex])) {
1232
+ color = parts[textIndex++];
1233
+ }
1234
+ if (["solid", "double", "dotted", "dashed", "wavy"].includes(parts[textIndex])) {
1235
+ decorationStyle = parts[textIndex++];
1236
+ }
1237
+ if (["underline", "line-through", "overline", "both"].includes(parts[textIndex])) {
1238
+ type = parts[textIndex] === "both" ? "underline line-through" : parts[textIndex++];
1239
+ }
1240
+ const innerText = parts.slice(textIndex).join(";");
1241
+ const span = document.createElement("span");
1242
+ span.className = "nr-underline";
1243
+ span.style.textDecoration = `${type} ${decorationStyle} ${color}`;
1244
+ span.style.textDecorationThickness = "auto";
1245
+ span.appendChild(renderInline(innerText));
1246
+ return span;
1247
+ }
1248
+ if (match = part.match(/%([^%\s]+?)%([\s\S]+?)%%/)) {
1249
+ const span = document.createElement("span");
1250
+ span.style.color = match[1];
1251
+ span.appendChild(renderInline(match[2]));
1252
+ return span;
1253
+ }
1254
+ if (match = part.match(/^!>([^<]+?)<!$/)) {
1255
+ const span = document.createElement("span");
1256
+ span.className = "nr-spoiler";
1257
+ span.appendChild(renderInline(match[1]));
1258
+ return span;
1259
+ }
1260
+ if (match = part.match(/^==(.+?)==$/)) {
1261
+ const mark = document.createElement("mark");
1262
+ mark.className = "nr-highlight";
1263
+ mark.appendChild(renderInline(match[1]));
1264
+ return mark;
1265
+ }
1266
+ if (match = part.match(/^\*\*\*(.+?)\*\*\*$/)) {
1267
+ const strong = document.createElement("strong");
1268
+ const em = document.createElement("em");
1269
+ em.appendChild(renderInline(match[1]));
1270
+ strong.appendChild(em);
1271
+ return strong;
1272
+ }
1273
+ if (match = part.match(/^\*\*(.+?)\*\*$/)) {
1274
+ const strong = document.createElement("strong");
1275
+ strong.appendChild(renderInline(match[1]));
1276
+ return strong;
1277
+ }
1278
+ if (match = part.match(/^_(.+?)_$/)) {
1279
+ const em = document.createElement("em");
1280
+ em.appendChild(renderInline(match[1]));
1281
+ return em;
1282
+ }
1283
+ if (match = part.match(/^~~(.+?)~~$/)) {
1284
+ const del = document.createElement("del");
1285
+ del.appendChild(renderInline(match[1]));
1286
+ return del;
1287
+ }
1288
+ if (match = part.match(/^`([^`]+)`$/)) {
1289
+ const code = document.createElement("code");
1290
+ code.className = "nr-inline-code";
1291
+ code.textContent = match[1];
1292
+ return code;
1293
+ }
1294
+ if (match = part.match(/^\[([^\]]+?)\]\(([^)]+?)\)$/)) {
1295
+ const a = document.createElement("a");
1296
+ a.className = "nr-link";
1297
+ a.href = match[2];
1298
+ a.target = "_blank";
1299
+ a.rel = "noopener noreferrer";
1300
+ a.appendChild(renderInline(match[1]));
1301
+ return a;
1302
+ }
1303
+ if (part.startsWith("<") && part.endsWith(">")) {
1304
+ const span = document.createElement("span");
1305
+ span.innerHTML = part;
1306
+ return span;
1307
+ }
1308
+ return document.createTextNode(part);
1309
+ }
1187
1310
 
1188
- // react/directives/CardDirective.tsx
1189
- var import_react4 = __toESM(require("react"), 1);
1190
- var import_jsx_runtime4 = require("react/jsx-runtime");
1191
- var CardDirective = ({
1192
- directiveType,
1193
- props,
1194
- slots,
1195
- renderSlot,
1196
- context,
1197
- options = {}
1198
- }) => {
1199
- const stableId = (0, import_react4.useId)();
1200
- const { title, image, icon, class: customClass, url, target } = props;
1201
- const hasDescription = !!slots.description;
1202
- const { isSingleCard } = options;
1203
- const isModal = directiveType === "card-m";
1204
- const isLink = directiveType === "card-b";
1205
- const modalId = `modal-card-${props.id || stableId}`;
1206
- const wrapperClass = customClass || "";
1207
- const inlineStyles = props.style ? parseCssString(props.style) : {};
1208
- const description = hasDescription ? renderSlot("description") : null;
1209
- const content = renderSlot("content") || renderSlot("default");
1210
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react4.default.Fragment, { children: [
1211
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
1212
- "div",
1213
- {
1214
- className: `flex flex-col h-full rounded-3xl transition-all relative overflow-hidden group border min-w-[18rem] w-[18rem] max-w-[20rem] ${isModal || isLink ? "cursor-pointer !border-accent-primary/10 hover:border-accent-primary/50" : "border-border"} ${wrapperClass}`,
1215
- style: inlineStyles,
1216
- onClick: isModal ? (e) => {
1217
- e.preventDefault();
1218
- e.stopPropagation();
1219
- context.setModals((prev) => ({ ...prev, [modalId]: true }));
1220
- } : isLink && url ? () => window.open(url, "_blank") : void 0,
1221
- role: isModal ? "button" : void 0,
1222
- tabIndex: isModal ? 0 : void 0,
1223
- onKeyDown: isModal ? (e) => {
1224
- if (e.key === "Enter" || e.key === " ") context.setModals((prev) => ({ ...prev, [modalId]: true }));
1225
- } : void 0,
1226
- children: [
1227
- image && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: `w-full ${isSingleCard ? "h-[240px]" : "h-[160px]"} overflow-hidden relative transition-all duration-500`, children: [
1228
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("img", { src: image, alt: title || "", className: "w-full h-full object-cover !m-0" }),
1229
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "absolute inset-0 bg-gradient-to-t from-background-primary/40 to-transparent" })
1230
- ] }),
1231
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: `flex flex-col flex-1 bg-background-primary/80 rounded-t-xl p-6 relative ${image ? "-mt-10" : ""} border-t border-white/5 shadow-2xl`, children: [
1232
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "flex items-center gap-3 mb-3", children: [
1233
- icon && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "w-10 h-10 text-[1.6em] rounded-xl bg-accent-primary/20 flex items-center justify-center shrink-0 text-accent-primary", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(IconRenderer, { iconName: icon }) }),
1234
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("h3", { className: "text-base font-black tracking-tight leading-tight !m-0", children: title })
1235
- ] }),
1236
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "flex-1 flex flex-col gap-2", children: [
1237
- description && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "text-sm opacity-80 leading-relaxed font-medium", children: description }),
1238
- directiveType === "card" && content && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "mt-2", children: content })
1239
- ] }),
1240
- (isModal || isLink) && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "mt-6 flex justify-end", children: isLink && url ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
1241
- "a",
1242
- {
1243
- href: url,
1244
- target: "_blank",
1245
- rel: "noopener noreferrer",
1246
- className: "bg-accent-primary/20 hover:bg-accent-primary/30 px-4 py-2 rounded-xl flex items-center gap-1.5 text-[10px] font-black uppercase tracking-widest opacity-50 group-hover:opacity-100 group-hover:text-accent-primary transition-all no-underline",
1247
- onClick: (e) => e.stopPropagation(),
1248
- children: [
1249
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(IconRenderer, { iconName: "open_in_new" }),
1250
- " Link"
1251
- ]
1252
- }
1253
- ) : isModal ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "bg-accent-primary/20 hover:bg-accent-primary/30 px-4 py-2 cursor-pointer rounded-xl flex items-center gap-1.5 text-[10px] font-black uppercase tracking-widest opacity-50 group-hover:opacity-100 group-hover:text-accent-primary transition-all", children: [
1254
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(IconRenderer, { iconName: "arrow_forward" }),
1255
- " Abrir"
1256
- ] }) : null })
1257
- ] })
1258
- ]
1259
- }
1260
- ),
1261
- isModal && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1262
- Modal,
1263
- {
1264
- title: title || "Detalles",
1265
- isOpen: !!context.modals[modalId],
1266
- onClose: () => context.setModals((prev) => ({ ...prev, [modalId]: false })),
1267
- children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "prose prose-sm max-w-none", children: content })
1268
- }
1269
- )
1270
- ] });
1311
+ // vanilla/directives/admonition.ts
1312
+ var admonitionDirective = ({ directiveType, props, renderSlot }) => {
1313
+ const el = createAdmonition(directiveType, props.title, props.icon);
1314
+ if (props.class) el.classList.add(...props.class.split(/\s+/).filter(Boolean));
1315
+ if (props.style) el.setAttribute("style", props.style);
1316
+ const body = el.querySelector(".nr-admonition__body");
1317
+ if (body) {
1318
+ body.appendChild(renderSlot("default"));
1319
+ }
1320
+ return el;
1271
1321
  };
1272
- var CardDirective_default = CardDirective;
1322
+ var admonition_default = admonitionDirective;
1273
1323
 
1274
- // react/directives/DetailsDirective.tsx
1275
- var import_jsx_runtime5 = require("react/jsx-runtime");
1276
- var DetailsDirective = ({
1277
- props,
1278
- renderSlot
1279
- }) => {
1280
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1281
- Details,
1282
- {
1283
- title: props.title || "Details",
1284
- icon: props.icon,
1285
- defaultOpen: props.defaultOpen === "true",
1286
- className: props.class,
1287
- style: props.style ? parseCssString(props.style) : void 0,
1288
- children: renderSlot("default")
1289
- }
1324
+ // vanilla/directives/details.ts
1325
+ var detailsDirective = ({ props, renderSlot }) => {
1326
+ const el = createDetails(
1327
+ props.title || "Details",
1328
+ props.icon,
1329
+ props.defaultOpen === "true"
1290
1330
  );
1331
+ if (props.class) el.classList.add(...props.class.split(/\s+/).filter(Boolean));
1332
+ if (props.style) el.setAttribute("style", props.style);
1333
+ const body = el.querySelector(".nr-details__body");
1334
+ if (body) {
1335
+ body.appendChild(renderSlot("default"));
1336
+ }
1337
+ return el;
1291
1338
  };
1292
- var DetailsDirective_default = DetailsDirective;
1339
+ var details_default = detailsDirective;
1293
1340
 
1294
- // react/directives/ModalDirective.tsx
1295
- var import_react5 = require("react");
1296
- var import_jsx_runtime6 = require("react/jsx-runtime");
1297
- var ModalDirective = ({
1298
- props,
1299
- renderSlot,
1300
- context
1301
- }) => {
1302
- const stableId = (0, import_react5.useId)();
1303
- const modalId = `modal-${props.id || stableId}`;
1341
+ // vanilla/directives/modal.ts
1342
+ var modalDirective = ({ props, renderSlot }) => {
1304
1343
  const label = props.label || props.title || "Open";
1305
1344
  const modalTitle = props.title || "Modal";
1306
1345
  const customClass = props.class || "";
1307
- const hasSizeClass = /\btext-(xs|sm|base|lg|xl|[2-9]xl)\b/.test(customClass);
1308
- const sizeClass = hasSizeClass ? "" : "text-sm";
1309
- const hasDisplayClass = /\b(flex|inline-flex|block|inline-block|grid|inline-grid|hidden)\b/.test(customClass);
1310
- const displayClass = hasDisplayClass ? "" : "inline-flex";
1311
- const isInlineFlex = /\binline-flex\b/.test(customClass);
1312
- const marginClass = isInlineFlex ? "my-1 mx-1" : "my-4";
1313
- const btnBase = `${displayClass} items-center w-fit ${marginClass} ${sizeClass} px-4 py-2 rounded-xl font-bold no-underline gap-2 transition-all hover:scale-105 active:scale-95 border border-border bg-background-primary/5 hover:bg-background-primary/10 text-text-primary hover:text-text-primary`.replace(/\s+/g, " ");
1314
- const btnClass = `${btnBase} ${customClass}`.trim();
1315
- const positionMap = {
1316
- "#left": "text-left",
1317
- "#center": "text-center",
1318
- "#right": "text-right"
1319
- };
1320
- const wrapperClass = customClass.split(/\s+/).map((c) => positionMap[c] || c).join(" ");
1321
- const handleOpen = () => {
1322
- context.setModals((prev) => ({ ...prev, [modalId]: true }));
1323
- };
1324
- const handleClose = () => {
1325
- context.setModals((prev) => ({ ...prev, [modalId]: false }));
1326
- };
1327
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: `not-prose ${wrapperClass}`.trim(), children: [
1328
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("button", { className: btnClass, onClick: handleOpen, children: [
1329
- props.icon && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(IconRenderer, { iconName: props.icon }),
1330
- label
1331
- ] }),
1332
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1333
- Modal,
1334
- {
1335
- title: modalTitle,
1336
- isOpen: !!context.modals[modalId],
1337
- onClose: handleClose,
1338
- children: renderSlot("default")
1339
- }
1340
- )
1341
- ] });
1346
+ const wrapper = document.createElement("div");
1347
+ wrapper.className = "nr-modal-trigger";
1348
+ const btn = document.createElement("button");
1349
+ btn.className = `nr-button nr-button--default`;
1350
+ if (customClass) btn.classList.add(...customClass.split(/\s+/).filter(Boolean));
1351
+ const icon = props.icon || "open_in_new";
1352
+ if (icon) btn.appendChild(createIcon(icon));
1353
+ btn.appendChild(document.createTextNode(label));
1354
+ const dialog = createModal(modalTitle);
1355
+ const body = dialog.querySelector(".nr-modal__body");
1356
+ if (body) {
1357
+ const prose = document.createElement("div");
1358
+ prose.className = "nr-prose";
1359
+ prose.appendChild(renderSlot("default"));
1360
+ body.appendChild(prose);
1361
+ }
1362
+ btn.addEventListener("click", () => {
1363
+ if (!dialog.open) {
1364
+ document.body.appendChild(dialog);
1365
+ dialog.showModal();
1366
+ dialog.addEventListener("close", () => {
1367
+ dialog.remove();
1368
+ }, { once: true });
1369
+ }
1370
+ });
1371
+ wrapper.appendChild(btn);
1372
+ wrapper.appendChild(dialog);
1373
+ return wrapper;
1342
1374
  };
1343
- var ModalDirective_default = ModalDirective;
1375
+ var modal_default = modalDirective;
1344
1376
 
1345
- // react/directives/ButtonDirective.tsx
1346
- var import_react6 = __toESM(require("react"), 1);
1347
- var import_jsx_runtime7 = require("react/jsx-runtime");
1348
- var ButtonDirective = ({
1349
- props,
1350
- renderSlot
1351
- }) => {
1377
+ // vanilla/directives/button.ts
1378
+ var buttonDirective = ({ props, renderSlot }) => {
1352
1379
  const url = props.url || props.href || "#";
1353
1380
  const label = props.label;
1354
1381
  const icon = props.icon || "near_me";
1355
1382
  const target = props.target || "_blank";
1356
1383
  const customClass = props.class || "";
1357
- const hasSizeClass = /\btext-(xs|sm|base|lg|xl|[2-9]xl)\b/.test(customClass);
1358
- const sizeClass = hasSizeClass ? "" : "text-sm";
1359
- const hasDisplayClass = /\b(flex|inline-flex|block|inline-block|grid|inline-grid|hidden)\b/.test(customClass);
1360
- const displayClass = hasDisplayClass ? "" : "inline-flex";
1361
- const isInline = !customClass || !/\b(flex|block|grid)\b/.test(customClass) || /\binline-flex\b/.test(customClass);
1362
- const marginClass = isInline ? "my-1 mx-1" : "my-4";
1363
- const btnBase = `${displayClass} items-center w-fit ${marginClass} ${sizeClass} px-4 py-2 rounded-xl font-bold no-underline gap-2 transition-all hover:scale-105 active:scale-95 border border-border bg-background-primary/5 hover:bg-background-primary/10 text-text-primary hover:text-text-primary`.replace(/\s+/g, " ");
1364
- const btnClass = `${btnBase} ${customClass}`.trim();
1365
- const positionMap = {
1366
- "#left": "flex justify-start",
1367
- "#center": "flex justify-center",
1368
- "#right": "flex justify-end"
1369
- };
1370
- const wrapperClass = customClass.split(/\s+/).map((c) => positionMap[c] || c).join(" ");
1384
+ const wrapper = document.createElement("div");
1385
+ wrapper.className = "nr-button-wrap";
1371
1386
  if (label) {
1372
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: `not-prose ${wrapperClass}`.trim(), children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
1373
- "a",
1374
- {
1375
- href: url,
1376
- target,
1377
- rel: "noopener noreferrer",
1378
- className: btnClass,
1379
- children: [
1380
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(IconRenderer, { iconName: icon }),
1381
- label
1382
- ]
1383
- }
1384
- ) });
1387
+ const a = document.createElement("a");
1388
+ a.href = url;
1389
+ a.target = target;
1390
+ a.rel = "noopener noreferrer";
1391
+ a.className = "nr-button nr-button--default";
1392
+ if (customClass) a.classList.add(...customClass.split(/\s+/).filter(Boolean));
1393
+ a.appendChild(createIcon(icon));
1394
+ a.appendChild(document.createTextNode(label));
1395
+ wrapper.appendChild(a);
1396
+ return wrapper;
1385
1397
  }
1386
1398
  const slotContent = renderSlot("default");
1387
- const findLinks = (element) => {
1388
- if (!element) return [];
1389
- if (import_react6.default.isValidElement(element) && element.type === "a") {
1390
- return [element];
1391
- }
1392
- if (Array.isArray(element)) {
1393
- return element.flatMap(findLinks);
1394
- }
1395
- if (import_react6.default.isValidElement(element) && element.props.children) {
1396
- return findLinks(element.props.children);
1397
- }
1398
- return [];
1399
- };
1400
- const links = findLinks(slotContent);
1399
+ const links = slotContent.querySelectorAll("a");
1401
1400
  if (links.length > 0) {
1402
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: `not-prose ${wrapperClass}`.trim(), children: links.map(
1403
- (link, index) => import_react6.default.cloneElement(
1404
- link,
1405
- {
1406
- key: index,
1407
- className: `${link.props.className || ""} ${btnClass}`.trim(),
1408
- target,
1409
- rel: "noopener noreferrer"
1410
- },
1411
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
1412
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(IconRenderer, { iconName: icon }),
1413
- link.props.children
1414
- ] })
1415
- )
1416
- ) });
1401
+ links.forEach((link) => {
1402
+ link.classList.add("nr-button", "nr-button--default");
1403
+ if (customClass) link.classList.add(...customClass.split(/\s+/).filter(Boolean));
1404
+ });
1405
+ wrapper.appendChild(slotContent);
1406
+ } else {
1407
+ const a = document.createElement("a");
1408
+ a.href = url;
1409
+ a.target = target;
1410
+ a.rel = "noopener noreferrer";
1411
+ a.className = "nr-button nr-button--default";
1412
+ if (customClass) a.classList.add(...customClass.split(/\s+/).filter(Boolean));
1413
+ a.appendChild(createIcon(icon));
1414
+ a.appendChild(slotContent);
1415
+ wrapper.appendChild(a);
1417
1416
  }
1418
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: `not-prose ${wrapperClass}`.trim(), children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("a", { href: url, target, rel: "noopener noreferrer", className: btnClass, children: [
1419
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(IconRenderer, { iconName: icon }),
1420
- slotContent
1421
- ] }) });
1417
+ return wrapper;
1422
1418
  };
1423
- var ButtonDirective_default = ButtonDirective;
1419
+ var button_default = buttonDirective;
1424
1420
 
1425
- // react/directives/WrapperDirective.tsx
1426
- var import_jsx_runtime8 = require("react/jsx-runtime");
1427
- var WrapperDirective = ({
1421
+ // vanilla/directives/card.ts
1422
+ var cardDirective = ({
1423
+ directiveType,
1428
1424
  props,
1429
- renderSlot
1425
+ slots,
1426
+ renderSlot,
1427
+ options
1430
1428
  }) => {
1431
- const className = props.class || "";
1432
- const id = props.id || "";
1433
- const inlineStyle = props.style ? parseCssString(props.style) : {};
1434
- const wrapperProps = {};
1435
- if (className) wrapperProps.className = className;
1436
- if (id) wrapperProps.id = id;
1437
- if (Object.keys(inlineStyle).length > 0) wrapperProps.style = inlineStyle;
1429
+ const { title, image, icon, url, target } = props;
1430
+ const customClass = props.class || "";
1431
+ const hasDescription = !!slots.description;
1432
+ const { isSingleCard } = options || {};
1433
+ const isModal = directiveType === "card-m";
1434
+ const isLink = directiveType === "card-b";
1435
+ const inlineStyles = props.style ? parseCssString(props.style) : {};
1436
+ const card = document.createElement("div");
1437
+ card.className = `nr-card${isModal || isLink ? " nr-card--interactive" : ""} ${customClass}`.trim();
1438
+ for (const [key, value] of Object.entries(inlineStyles)) {
1439
+ card.style.setProperty(key, String(value));
1440
+ }
1441
+ if (image) {
1442
+ const imgWrap = document.createElement("div");
1443
+ imgWrap.className = `nr-card__image${isSingleCard ? " nr-card__image--tall" : ""}`;
1444
+ const img = document.createElement("img");
1445
+ img.src = image;
1446
+ img.alt = title || "";
1447
+ img.className = "nr-card__img";
1448
+ imgWrap.appendChild(img);
1449
+ const gradient = document.createElement("div");
1450
+ gradient.className = "nr-card__gradient";
1451
+ imgWrap.appendChild(gradient);
1452
+ card.appendChild(imgWrap);
1453
+ }
1454
+ const body = document.createElement("div");
1455
+ body.className = `nr-card__body${image ? " nr-card__body--overlap" : ""}`;
1456
+ if (icon || title) {
1457
+ const header = document.createElement("div");
1458
+ header.className = "nr-card__header";
1459
+ if (icon) {
1460
+ const iconWrap = document.createElement("div");
1461
+ iconWrap.className = "nr-card__icon-wrap";
1462
+ iconWrap.appendChild(createIcon(icon));
1463
+ header.appendChild(iconWrap);
1464
+ }
1465
+ if (title) {
1466
+ const h3 = document.createElement("h3");
1467
+ h3.className = "nr-card__title";
1468
+ h3.textContent = title;
1469
+ header.appendChild(h3);
1470
+ }
1471
+ body.appendChild(header);
1472
+ }
1473
+ if (hasDescription) {
1474
+ const desc = document.createElement("div");
1475
+ desc.className = "nr-card__description";
1476
+ desc.appendChild(renderSlot("description"));
1477
+ body.appendChild(desc);
1478
+ }
1479
+ if (directiveType === "card") {
1480
+ const contentSlot = renderSlot("content") || renderSlot("default");
1481
+ if (contentSlot.childNodes.length > 0) {
1482
+ const contentDiv = document.createElement("div");
1483
+ contentDiv.className = "nr-card__content";
1484
+ contentDiv.appendChild(contentSlot);
1485
+ body.appendChild(contentDiv);
1486
+ }
1487
+ }
1488
+ if (isModal || isLink) {
1489
+ const action = document.createElement("div");
1490
+ action.className = "nr-card__action";
1491
+ if (isLink && url) {
1492
+ const a = document.createElement("a");
1493
+ a.href = url;
1494
+ a.target = target || "_blank";
1495
+ a.rel = "noopener noreferrer";
1496
+ a.className = "nr-card__action-link";
1497
+ a.appendChild(createIcon("open_in_new"));
1498
+ a.appendChild(document.createTextNode(" Link"));
1499
+ action.appendChild(a);
1500
+ } else if (isModal) {
1501
+ const modalBtn = document.createElement("div");
1502
+ modalBtn.className = "nr-card__action-link";
1503
+ modalBtn.appendChild(createIcon("arrow_forward"));
1504
+ modalBtn.appendChild(document.createTextNode(" Abrir"));
1505
+ action.appendChild(modalBtn);
1506
+ }
1507
+ body.appendChild(action);
1508
+ }
1509
+ card.appendChild(body);
1510
+ if (isModal) {
1511
+ const dialog = createModal(title || "Detalles");
1512
+ const modalBody = dialog.querySelector(".nr-modal__body");
1513
+ if (modalBody) {
1514
+ const prose = document.createElement("div");
1515
+ prose.className = "nr-prose";
1516
+ prose.appendChild(renderSlot("content") || renderSlot("default"));
1517
+ modalBody.appendChild(prose);
1518
+ }
1519
+ card.addEventListener("click", () => {
1520
+ if (!dialog.open) {
1521
+ document.body.appendChild(dialog);
1522
+ dialog.showModal();
1523
+ dialog.addEventListener("close", () => dialog.remove(), { once: true });
1524
+ }
1525
+ });
1526
+ const frag = document.createDocumentFragment();
1527
+ frag.appendChild(card);
1528
+ frag.appendChild(dialog);
1529
+ return frag;
1530
+ }
1531
+ if (isLink && url) {
1532
+ card.addEventListener("click", () => window.open(url, target || "_blank"));
1533
+ }
1534
+ return card;
1535
+ };
1536
+ var card_default = cardDirective;
1537
+
1538
+ // vanilla/directives/wrapper.ts
1539
+ var wrapperDirective = ({ props, renderSlot }) => {
1540
+ const el = document.createElement("div");
1541
+ el.className = "nr-wrapper";
1542
+ if (props.class) el.classList.add(...props.class.split(/\s+/).filter(Boolean));
1543
+ if (props.id) el.id = props.id;
1544
+ if (props.style) {
1545
+ const styles = parseCssString(props.style);
1546
+ for (const [key, value] of Object.entries(styles)) {
1547
+ el.style.setProperty(key, String(value));
1548
+ }
1549
+ }
1438
1550
  for (const [key, value] of Object.entries(props)) {
1439
1551
  if (key.startsWith("data-")) {
1440
- wrapperProps[key] = value;
1552
+ el.setAttribute(key, value);
1441
1553
  }
1442
1554
  }
1443
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { ...wrapperProps, children: renderSlot("default") });
1555
+ el.appendChild(renderSlot("default"));
1556
+ return el;
1444
1557
  };
1445
- var WrapperDirective_default = WrapperDirective;
1558
+ var wrapper_default = wrapperDirective;
1446
1559
 
1447
- // react/directives/SlideDirective.tsx
1448
- var import_react7 = require("react");
1449
- var import_jsx_runtime9 = require("react/jsx-runtime");
1560
+ // vanilla/directives/slide.ts
1450
1561
  var slideCounter = 0;
1451
- var SlideDirective = ({
1562
+ var slideDirective = ({
1452
1563
  props,
1453
- context,
1454
- slots
1564
+ slots,
1565
+ renderInline: renderInline2,
1566
+ renderMarkdown
1455
1567
  }) => {
1456
1568
  const rawContent = slots.default || "";
1457
1569
  const lines = rawContent.split("\n").map((l) => l.trim()).filter(Boolean);
1458
- const elements = lines.map((line) => context.parseMarkdown(line));
1459
- const [current, setCurrent] = (0, import_react7.useState)(0);
1570
+ if (lines.length === 0) {
1571
+ return document.createDocumentFragment();
1572
+ }
1460
1573
  const interval = parseInt(props.interval || "3000", 10);
1461
1574
  const speed = parseInt(props.speed || "500", 10);
1462
- const elRefs = (0, import_react7.useRef)([]);
1463
- const [maxH, setMaxH] = (0, import_react7.useState)(0);
1464
- (0, import_react7.useLayoutEffect)(() => {
1465
- let h = 0;
1466
- elRefs.current.forEach((el) => {
1467
- if (el) h = Math.max(h, el.offsetHeight);
1468
- });
1469
- if (h > 0) setMaxH(h);
1470
- }, [elements]);
1471
- const cycle = (0, import_react7.useCallback)(() => {
1472
- if (elements.length <= 1) return;
1473
- setCurrent((prev) => (prev + 1) % elements.length);
1474
- }, [elements.length]);
1475
- (0, import_react7.useEffect)(() => {
1476
- if (elements.length <= 1) return;
1477
- const id = setInterval(cycle, interval);
1478
- return () => clearInterval(id);
1479
- }, [cycle, interval, elements.length]);
1480
- if (elements.length === 0) return null;
1481
1575
  const rawClass = props.class || "";
1482
1576
  const inlineStyle = props.style ? parseCssString(props.style) : {};
1483
- const textSizeMap = {
1484
- "text-xs": "0.75rem",
1485
- "text-sm": "0.875rem",
1486
- "text-base": "1rem",
1487
- "text-lg": "1.125rem",
1488
- "text-xl": "1.25rem",
1489
- "text-2xl": "1.5rem",
1490
- "text-3xl": "1.875rem",
1491
- "text-4xl": "2.25rem",
1492
- "text-5xl": "3rem",
1493
- "text-6xl": "3.75rem",
1494
- "text-7xl": "4.5rem",
1495
- "text-8xl": "6rem",
1496
- "text-9xl": "8rem"
1497
- };
1498
- const textSizeMatch = rawClass.match(/\btext-(xs|sm|base|lg|xl|[2-9]xl)\b/);
1499
- const forcedFontSize = textSizeMatch ? textSizeMap[textSizeMatch[0]] : null;
1500
1577
  const scopeClass = `sld-${++slideCounter}`;
1501
- const className = textSizeMatch ? rawClass.replace(textSizeMatch[0], "").replace(/\s+/g, " ").trim() : rawClass;
1502
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
1503
- "div",
1504
- {
1505
- className: "not-prose",
1506
- style: { height: maxH || "auto", position: "relative", overflow: "hidden", ...inlineStyle },
1507
- children: [
1508
- forcedFontSize && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("style", { children: `.${scopeClass} * { font-size: ${forcedFontSize} !important; line-height: normal !important; }` }),
1509
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1510
- "div",
1511
- {
1512
- style: {
1513
- position: "absolute",
1514
- left: 0,
1515
- right: 0,
1516
- top: 0,
1517
- transition: `transform ${speed}ms cubic-bezier(0.16, 1, 0.3, 1)`,
1518
- transform: `translateY(${-current * maxH}px)`
1519
- },
1520
- children: elements.map((tokens, i) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1521
- "div",
1522
- {
1523
- ref: (el) => {
1524
- elRefs.current[i] = el;
1525
- },
1526
- style: maxH ? { height: maxH, display: "flex", alignItems: "center", overflow: "hidden" } : { display: "flex", alignItems: "center" },
1527
- children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: `${scopeClass} ${className}`, style: { width: "100%" }, children: context.processAndRenderElements(tokens) })
1528
- },
1529
- i
1530
- ))
1531
- }
1532
- )
1533
- ]
1578
+ const container = document.createElement("div");
1579
+ container.className = "nr-slide";
1580
+ Object.assign(container.style, {
1581
+ position: "relative",
1582
+ overflow: "hidden",
1583
+ ...inlineStyle
1584
+ });
1585
+ const track = document.createElement("div");
1586
+ track.className = "nr-slide__track";
1587
+ track.style.transition = `transform ${speed}ms cubic-bezier(0.16, 1, 0.3, 1)`;
1588
+ const slideEls = [];
1589
+ for (const line of lines) {
1590
+ const slideEl = document.createElement("div");
1591
+ slideEl.className = `nr-slide__item ${scopeClass} ${rawClass}`.trim();
1592
+ slideEl.style.display = "flex";
1593
+ slideEl.style.alignItems = "center";
1594
+ if (renderMarkdown) {
1595
+ const tokens = renderMarkdown(line);
1596
+ slideEl.appendChild(tokens);
1597
+ } else if (renderInline2) {
1598
+ slideEl.appendChild(renderInline2(line));
1599
+ }
1600
+ track.appendChild(slideEl);
1601
+ slideEls.push(slideEl);
1602
+ }
1603
+ container.appendChild(track);
1604
+ let current = 0;
1605
+ let maxH = 0;
1606
+ const measureAndSetHeight = () => {
1607
+ maxH = 0;
1608
+ for (const el of slideEls) {
1609
+ maxH = Math.max(maxH, el.offsetHeight);
1610
+ }
1611
+ if (maxH > 0) {
1612
+ container.style.height = `${maxH}px`;
1613
+ for (const el of slideEls) {
1614
+ el.style.height = `${maxH}px`;
1615
+ }
1534
1616
  }
1535
- );
1617
+ };
1618
+ requestAnimationFrame(() => {
1619
+ measureAndSetHeight();
1620
+ if (document.fonts?.ready) {
1621
+ document.fonts.ready.then(measureAndSetHeight);
1622
+ }
1623
+ });
1624
+ if (lines.length > 1) {
1625
+ setInterval(() => {
1626
+ current = (current + 1) % lines.length;
1627
+ track.style.transform = `translateY(${-current * maxH}px)`;
1628
+ }, interval);
1629
+ }
1630
+ return container;
1536
1631
  };
1537
- var SlideDirective_default = SlideDirective;
1632
+ var slide_default = slideDirective;
1538
1633
 
1539
- // react/directives/index.ts
1634
+ // vanilla/directives/index.ts
1540
1635
  var directiveRegistry = {
1541
1636
  // Admonitions
1542
- note: AdmonitionDirective_default,
1543
- info: AdmonitionDirective_default,
1544
- warning: AdmonitionDirective_default,
1545
- danger: AdmonitionDirective_default,
1546
- greentext: AdmonitionDirective_default,
1637
+ note: admonition_default,
1638
+ info: admonition_default,
1639
+ warning: admonition_default,
1640
+ danger: admonition_default,
1641
+ greentext: admonition_default,
1547
1642
  // Cards
1548
- card: CardDirective_default,
1549
- "card-m": CardDirective_default,
1550
- "card-b": CardDirective_default,
1643
+ card: card_default,
1644
+ "card-m": card_default,
1645
+ "card-b": card_default,
1551
1646
  // Interactive
1552
- details: DetailsDirective_default,
1553
- modal: ModalDirective_default,
1554
- button: ButtonDirective_default,
1647
+ details: details_default,
1648
+ modal: modal_default,
1649
+ button: button_default,
1555
1650
  // Layout / generic wrappers
1556
- div: WrapperDirective_default,
1557
- style: WrapperDirective_default,
1558
- custom: WrapperDirective_default,
1559
- raw: WrapperDirective_default,
1651
+ div: wrapper_default,
1652
+ style: wrapper_default,
1653
+ custom: wrapper_default,
1654
+ raw: wrapper_default,
1560
1655
  // Animation
1561
- slide: SlideDirective_default
1656
+ slide: slide_default
1562
1657
  };
1563
1658
  var directives_default = directiveRegistry;
1564
1659
 
1565
- // react/DirectiveRenderer.tsx
1566
- var import_jsx_runtime10 = require("react/jsx-runtime");
1567
- var DirectiveRenderer = ({
1568
- element,
1569
- context,
1570
- index,
1571
- allElements
1572
- }) => {
1660
+ // vanilla/renderer.ts
1661
+ function renderTokens(tokens) {
1662
+ const article = document.createElement("article");
1663
+ article.className = "nr-prose";
1664
+ const ctx = {
1665
+ parseMarkdown,
1666
+ renderElements: (tks) => renderTokensInner(tks, ctx),
1667
+ renderInline,
1668
+ renderMarkdown: (md) => renderTokensInner(parseMarkdown(md), ctx)
1669
+ };
1670
+ article.appendChild(processElements(tokens, ctx, tokens));
1671
+ return article;
1672
+ }
1673
+ function renderMarkdownString(markdown2) {
1674
+ const tokens = parseMarkdown(markdown2);
1675
+ return renderTokens(tokens);
1676
+ }
1677
+ function renderHtmlString(html) {
1678
+ let processedContent = html;
1679
+ processedContent = processedContent.replace(
1680
+ /<style(?:\s+[^>]*)?>([\s\S]*?)<\/style>/gi,
1681
+ (_match, cssContent) => {
1682
+ const styleEl = document.createElement("style");
1683
+ styleEl.setAttribute("data-nr-global", "");
1684
+ styleEl.textContent = cssContent;
1685
+ document.head.appendChild(styleEl);
1686
+ return "";
1687
+ }
1688
+ );
1689
+ const wrapper = document.createElement("div");
1690
+ wrapper.className = "nr-raw-html";
1691
+ wrapper.innerHTML = processedContent;
1692
+ const scripts = wrapper.querySelectorAll("script");
1693
+ scripts.forEach((oldScript) => {
1694
+ const newScript = document.createElement("script");
1695
+ Array.from(oldScript.attributes).forEach(
1696
+ (attr) => newScript.setAttribute(attr.name, attr.value)
1697
+ );
1698
+ newScript.textContent = oldScript.textContent;
1699
+ oldScript.parentNode?.replaceChild(newScript, oldScript);
1700
+ });
1701
+ return wrapper;
1702
+ }
1703
+ function renderTokensInner(tokens, ctx) {
1704
+ const container = document.createElement("div");
1705
+ container.appendChild(processElements(tokens, ctx, tokens));
1706
+ return container;
1707
+ }
1708
+ function processElements(elements, ctx, allElements) {
1709
+ const fragment = document.createDocumentFragment();
1710
+ let i = 0;
1711
+ while (i < elements.length) {
1712
+ const el = elements[i];
1713
+ if (el.type === "directive" && ["card", "card-m", "card-b"].includes(el.directiveType)) {
1714
+ const cards = [];
1715
+ while (i < elements.length && elements[i].type === "directive" && ["card", "card-m", "card-b"].includes(elements[i].directiveType)) {
1716
+ cards.push(elements[i]);
1717
+ i++;
1718
+ }
1719
+ if (cards.length === 1 || cards[0].props?.batch === "off") {
1720
+ for (const card of cards) {
1721
+ const rendered = renderElement(card, ctx, allElements);
1722
+ if (rendered) fragment.appendChild(rendered);
1723
+ }
1724
+ } else {
1725
+ const grid = document.createElement("div");
1726
+ grid.className = "nr-card-grid";
1727
+ for (const card of cards) {
1728
+ const rendered = renderElement(card, ctx, allElements);
1729
+ if (rendered) grid.appendChild(rendered);
1730
+ }
1731
+ fragment.appendChild(grid);
1732
+ }
1733
+ } else {
1734
+ const rendered = renderElement(el, ctx, allElements);
1735
+ if (rendered) fragment.appendChild(rendered);
1736
+ i++;
1737
+ }
1738
+ }
1739
+ return fragment;
1740
+ }
1741
+ function renderElement(element, ctx, allElements) {
1742
+ switch (element.type) {
1743
+ case "header": {
1744
+ const tag = `h${element.level}`;
1745
+ let text = element.text;
1746
+ const alignCenter = text.match(/^->\s*(.+?)\s*<-\s*$/);
1747
+ const alignRight = text.match(/^->\s*(.+?)\s*->\s*$/);
1748
+ if (alignCenter) text = alignCenter[1];
1749
+ else if (alignRight) text = alignRight[1];
1750
+ const h = document.createElement(tag);
1751
+ h.id = element.id;
1752
+ let cls = `md-h${element.level}`;
1753
+ if (alignCenter) cls += " text-center";
1754
+ if (alignRight) cls += " text-right";
1755
+ if (element.classes) cls += ` ${element.classes}`;
1756
+ h.className = cls;
1757
+ h.appendChild(renderInline(text));
1758
+ return h;
1759
+ }
1760
+ case "paragraph": {
1761
+ const p = document.createElement("p");
1762
+ let cls = "md-p";
1763
+ if (element.classes) cls += ` ${element.classes}`;
1764
+ if (element.align) cls += ` text-${element.align}`;
1765
+ p.className = cls;
1766
+ if (element.id) p.id = element.id;
1767
+ const lines = element.content.split("\n");
1768
+ for (let li = 0; li < lines.length; li++) {
1769
+ const line = lines[li];
1770
+ const hardBreakMatch = line.match(/^(.*?)(\s{2,})$/);
1771
+ if (hardBreakMatch) {
1772
+ p.appendChild(renderInline(hardBreakMatch[1]));
1773
+ p.appendChild(document.createElement("br"));
1774
+ } else {
1775
+ p.appendChild(renderInline(line));
1776
+ if (li < lines.length - 1) {
1777
+ p.appendChild(document.createTextNode(" "));
1778
+ }
1779
+ }
1780
+ }
1781
+ return p;
1782
+ }
1783
+ case "codeblock":
1784
+ return createCodeBlock(element.content, element.language, element.title);
1785
+ case "directive":
1786
+ return renderDirective(element, ctx, allElements);
1787
+ case "html": {
1788
+ const el = element;
1789
+ return renderHtmlString(el.content);
1790
+ }
1791
+ case "html-block": {
1792
+ const htmlBlock = element;
1793
+ const rawProps = parseHtmlAttrs(htmlBlock.attrs);
1794
+ const el = document.createElement(htmlBlock.tag);
1795
+ for (const [key, value] of Object.entries(rawProps)) {
1796
+ if (key === "style" && typeof value === "object") {
1797
+ for (const [prop, val] of Object.entries(value)) {
1798
+ el.style.setProperty(prop, String(val));
1799
+ }
1800
+ } else if (value === true) {
1801
+ el.setAttribute(key, "");
1802
+ } else {
1803
+ el.setAttribute(key, String(value));
1804
+ }
1805
+ }
1806
+ const childFrag = processElements(htmlBlock.children, ctx, allElements);
1807
+ el.appendChild(childFrag);
1808
+ return el;
1809
+ }
1810
+ case "image": {
1811
+ const img = document.createElement("img");
1812
+ img.src = element.src;
1813
+ img.alt = element.alt;
1814
+ img.className = "nr-image";
1815
+ if (element.style) {
1816
+ for (const [key, value] of Object.entries(element.style)) {
1817
+ img.style.setProperty(key, String(value));
1818
+ }
1819
+ }
1820
+ return img;
1821
+ }
1822
+ case "table":
1823
+ return createTable(element.content, renderInline);
1824
+ case "list":
1825
+ return createList(element.content, renderInline);
1826
+ case "blockquote":
1827
+ return createBlockquote(element.content, element.classes, renderInline);
1828
+ case "hr": {
1829
+ const hr = document.createElement("hr");
1830
+ hr.className = "nr-hr";
1831
+ return hr;
1832
+ }
1833
+ case "toc": {
1834
+ const headers = allElements.filter((e) => e.type === "header");
1835
+ return createTOC(headers.map((h) => ({ level: h.level, text: h.text, id: h.id })), renderInline);
1836
+ }
1837
+ default:
1838
+ return null;
1839
+ }
1840
+ }
1841
+ function renderDirective(element, ctx, allElements) {
1573
1842
  const { directiveType, props, slots, scopeId } = element;
1574
- const Component = directives_default[directiveType];
1843
+ const renderer = directives_default[directiveType];
1575
1844
  const renderSlot = (name) => {
1845
+ const frag = document.createDocumentFragment();
1576
1846
  const slotContent = slots[name];
1577
- if (!slotContent) return null;
1578
- const parsed = context.parseMarkdown(slotContent);
1579
- return context.processAndRenderElements(parsed);
1847
+ if (!slotContent) return frag;
1848
+ const tokens = ctx.parseMarkdown(slotContent);
1849
+ frag.appendChild(ctx.renderElements(tokens));
1850
+ return frag;
1580
1851
  };
1581
1852
  const directiveProps = {
1582
1853
  directiveType,
1583
1854
  props,
1584
1855
  slots,
1585
1856
  renderSlot,
1586
- context,
1587
- index,
1588
- allElements
1857
+ context: ctx,
1858
+ index: 0,
1859
+ allElements,
1860
+ renderInline,
1861
+ renderMarkdown: ctx.renderMarkdown
1589
1862
  };
1590
- if (Component) {
1591
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Component, { ...directiveProps }, index);
1863
+ if (renderer) {
1864
+ return renderer(directiveProps);
1592
1865
  }
1593
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: `my-4 p-4 rounded-2xl border border-border bg-background-primary/5`, children: renderSlot("default") }, index);
1594
- };
1595
- var DirectiveRenderer_default = DirectiveRenderer;
1596
-
1597
- // react/RawHtmlRenderer.tsx
1598
- var import_react8 = require("react");
1599
- var import_jsx_runtime11 = require("react/jsx-runtime");
1600
- var RawHtmlRenderer = ({
1601
- content,
1602
- globalStyles,
1603
- wrapperClassName
1604
- }) => {
1605
- const containerRef = (0, import_react8.useRef)(null);
1606
- (0, import_react8.useEffect)(() => {
1607
- if (!containerRef.current) return;
1608
- const scripts = containerRef.current.querySelectorAll("script");
1609
- scripts.forEach((oldScript) => {
1610
- const newScript = document.createElement("script");
1611
- Array.from(oldScript.attributes).forEach(
1612
- (attr) => newScript.setAttribute(attr.name, attr.value)
1613
- );
1614
- newScript.textContent = oldScript.textContent;
1615
- oldScript.parentNode?.replaceChild(newScript, oldScript);
1616
- });
1617
- scanTailwindCDN();
1618
- }, [content]);
1619
- (0, import_react8.useEffect)(() => {
1620
- if (!globalStyles) return;
1621
- const styleEl = document.createElement("style");
1622
- styleEl.setAttribute("data-global", "");
1623
- styleEl.textContent = globalStyles;
1624
- document.head.appendChild(styleEl);
1625
- return () => {
1626
- if (styleEl.parentNode) document.head.removeChild(styleEl);
1627
- };
1628
- }, [globalStyles]);
1629
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: wrapperClassName, ref: containerRef, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { dangerouslySetInnerHTML: { __html: content } }) });
1630
- };
1631
- var RawHtmlRenderer_default = RawHtmlRenderer;
1632
-
1633
- // react/context.tsx
1634
- var import_react9 = require("react");
1635
- var RenderCtx = (0, import_react9.createContext)(null);
1636
- var RenderContextProvider = RenderCtx.Provider;
1866
+ const fallback = document.createElement("div");
1867
+ fallback.className = "nr-unknown-directive";
1868
+ fallback.appendChild(renderSlot("default"));
1869
+ return fallback;
1870
+ }
1637
1871
 
1638
1872
  // react/CustomMarkdownRenderer.tsx
1639
- var import_jsx_runtime12 = require("react/jsx-runtime");
1640
- var CustomMarkdownRenderer = ({ content: initialContent }) => {
1641
- const [modals, setModals] = (0, import_react10.useState)({});
1642
- const baseId = (0, import_react10.useId)().replace(/:/g, "");
1643
- const articleClass = `scope-${baseId}`;
1644
- const contextRef = (0, import_react10.useRef)(null);
1645
- resetScopeCounter();
1646
- const allElements = (0, import_react10.useMemo)(() => parseMarkdown(initialContent), [initialContent]);
1647
- (0, import_react10.useEffect)(() => {
1873
+ var import_jsx_runtime = require("react/jsx-runtime");
1874
+ var CustomMarkdownRenderer = ({ content }) => {
1875
+ const containerRef = (0, import_react3.useRef)(null);
1876
+ (0, import_react3.useEffect)(() => {
1877
+ const container = containerRef.current;
1878
+ if (!container) return;
1879
+ container.replaceChildren();
1880
+ container.appendChild(renderMarkdownString(content));
1881
+ scanTailwindCDN();
1648
1882
  const handleHashChange = () => {
1649
1883
  const hash = window.location.hash;
1650
1884
  if (hash) {
1651
1885
  const parts = hash.split("#");
1652
- const id = parts[parts.length - 1];
1653
- scrollToId(id);
1886
+ scrollToId(parts[parts.length - 1]);
1654
1887
  }
1655
1888
  };
1656
1889
  handleHashChange();
1657
1890
  window.addEventListener("hashchange", handleHashChange);
1658
1891
  return () => window.removeEventListener("hashchange", handleHashChange);
1659
- }, [initialContent]);
1660
- const renderElement = (0, import_react10.useCallback)(
1661
- (element, index, _depth = 0) => {
1662
- switch (element.type) {
1663
- case "header": {
1664
- const HeaderTag = `h${element.level}`;
1665
- let text = element.text;
1666
- const alignCenter = text.match(/^->\s*(.+?)\s*<-\s*$/);
1667
- const alignRight = text.match(/^->\s*(.+?)\s*->\s*$/);
1668
- if (alignCenter) {
1669
- text = alignCenter[1];
1670
- } else if (alignRight) {
1671
- text = alignRight[1];
1672
- }
1673
- const userClasses = element.classes || "";
1674
- let headerClasses = `md-h${element.level}`;
1675
- if (alignCenter) headerClasses += " text-center";
1676
- if (alignRight) headerClasses += " text-right";
1677
- if (userClasses) headerClasses += ` ${userClasses}`;
1678
- return import_react10.default.createElement(
1679
- HeaderTag,
1680
- { key: index, id: element.id, className: headerClasses },
1681
- renderInline(text)
1682
- );
1683
- }
1684
- case "paragraph": {
1685
- const lines = element.content.split("\n");
1686
- const processedContent = lines.map((line, lineIndex) => {
1687
- const hardBreakMatch = line.match(/^(.*?)(\s{2,})$/);
1688
- if (hardBreakMatch) {
1689
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_react10.default.Fragment, { children: [
1690
- renderInline(hardBreakMatch[1]),
1691
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("br", {})
1692
- ] }, lineIndex);
1693
- }
1694
- const isLastLine = lineIndex === lines.length - 1;
1695
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_react10.default.Fragment, { children: [
1696
- renderInline(line),
1697
- !isLastLine && " "
1698
- ] }, lineIndex);
1699
- });
1700
- const pUserClasses = element.classes || "";
1701
- let pClasses = "md-p";
1702
- if (pUserClasses) pClasses += ` ${pUserClasses}`;
1703
- if (element.align) pClasses += ` text-${element.align}`;
1704
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { id: element.id, className: pClasses, children: processedContent }, index);
1705
- }
1706
- case "codeblock":
1707
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1708
- CodeBlock,
1709
- {
1710
- code: element.content,
1711
- language: element.language,
1712
- title: element.title
1713
- },
1714
- index
1715
- );
1716
- case "directive":
1717
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1718
- DirectiveRenderer_default,
1719
- {
1720
- element,
1721
- context: contextRef.current,
1722
- index,
1723
- allElements
1724
- },
1725
- index
1726
- );
1727
- case "html": {
1728
- let processedContent = element.content;
1729
- let globalStyles = "";
1730
- processedContent = processedContent.replace(
1731
- /<style(?:\s+[^>]*)?>([\s\S]*?)<\/style>/gi,
1732
- (_match, cssContent) => {
1733
- globalStyles += cssContent + "\n";
1734
- return "";
1735
- }
1736
- );
1737
- const wrapperClassName = "w-full my-4";
1738
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1739
- RawHtmlRenderer_default,
1740
- {
1741
- content: processedContent,
1742
- globalStyles: globalStyles || void 0,
1743
- wrapperClassName
1744
- },
1745
- index
1746
- );
1747
- }
1748
- case "html-block": {
1749
- const htmlBlock = element;
1750
- const rawProps = parseHtmlAttrs(htmlBlock.attrs);
1751
- const props = {};
1752
- for (const [key, value] of Object.entries(rawProps)) {
1753
- if (key === "class") props["className"] = value;
1754
- else if (key === "for") props["htmlFor"] = value;
1755
- else if (key === "tabindex") props["tabIndex"] = value;
1756
- else props[key] = value;
1757
- }
1758
- return import_react10.default.createElement(
1759
- htmlBlock.tag,
1760
- { key: index, ...props },
1761
- ...processAndRenderElements(htmlBlock.children, _depth + 1)
1762
- );
1763
- }
1764
- case "image":
1765
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1766
- "img",
1767
- {
1768
- alt: element.alt,
1769
- src: element.src,
1770
- style: element.style,
1771
- className: "max-w-full h-auto"
1772
- },
1773
- index
1774
- );
1775
- case "table":
1776
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { children: renderTable(element.content) }, index);
1777
- case "list":
1778
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { children: renderList(element.content) }, index);
1779
- case "blockquote":
1780
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("blockquote", { className: `border-l-4 border-accent-primary/30 pl-4 italic text-text-secondary my-4 text-sm sm:text-base${element.classes ? ` ${element.classes}` : ""}`, children: renderInline(element.content) }, index);
1781
- case "hr":
1782
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("hr", { className: "my-8 border-border" }, index);
1783
- case "toc":
1784
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { children: generateToc(allElements) }, index);
1785
- default:
1786
- return null;
1787
- }
1788
- },
1789
- [allElements]
1790
- );
1791
- const processAndRenderElements = (0, import_react10.useCallback)(
1792
- (elements, depth = 0) => {
1793
- const result = [];
1794
- let i = 0;
1795
- while (i < elements.length) {
1796
- const el = elements[i];
1797
- if (el.type === "directive" && ["card", "card-m", "card-b"].includes(el.directiveType)) {
1798
- const cards = [];
1799
- while (i < elements.length && elements[i].type === "directive" && ["card", "card-m", "card-b"].includes(elements[i].directiveType)) {
1800
- cards.push(elements[i]);
1801
- i++;
1802
- }
1803
- if (cards.length === 1 || cards[0].props?.batch === "off") {
1804
- for (let c = 0; c < cards.length; c++) {
1805
- result.push(renderElement(cards[c], result.length, depth));
1806
- }
1807
- } else {
1808
- const firstCardClass = cards[0].props?.["class"] || "";
1809
- const justifyClasses = firstCardClass.match(/\bjustify-\S+/g) || [];
1810
- const wrapperJustify = justifyClasses.length > 0 ? justifyClasses.join(" ") : "";
1811
- result.push(
1812
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: `not-prose flex flex-wrap gap-6 my-6 ${wrapperJustify}`, children: cards.map((card, ci) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react10.default.Fragment, { children: renderElement(card, ci, depth) }, ci)) }, `card-grid-${result.length}`)
1813
- );
1814
- }
1815
- } else {
1816
- result.push(renderElement(el, result.length, depth));
1817
- i++;
1818
- }
1819
- }
1820
- return result;
1821
- },
1822
- [renderElement]
1823
- );
1824
- const generateToc = (elements) => {
1825
- const headers = extractHeaders(elements);
1826
- if (headers.length === 0) return null;
1827
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("nav", { className: "not-prose my-6 p-4 rounded-2xl border border-border bg-background-primary/5", children: [
1828
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "text-base font-bold mb-3", children: "Table of Contents" }),
1829
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("ul", { className: "space-y-1 list-none p-0 m-0", children: headers.map((h, i) => {
1830
- if (h.type !== "header") return null;
1831
- const indentClass = h.level <= 2 ? "pl-0" : h.level === 3 ? "pl-4" : h.level === 4 ? "pl-8" : "pl-12";
1832
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("li", { className: `${indentClass} text-sm sm:text-base`, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1833
- "a",
1834
- {
1835
- href: `#${h.id}`,
1836
- className: "text-accent-primary hover:text-accent-primary/80 no-underline hover:underline transition-colors",
1837
- onClick: (e) => {
1838
- e.preventDefault();
1839
- scrollToId(h.id);
1840
- },
1841
- children: renderInline(h.text.replace(/->|<-/g, "").trim())
1842
- }
1843
- ) }, i);
1844
- }) })
1845
- ] });
1846
- };
1847
- const contextForDirectives = {
1848
- modals,
1849
- setModals,
1850
- articleClass,
1851
- allElements,
1852
- parseMarkdown,
1853
- renderElement,
1854
- renderInline,
1855
- processAndRenderElements
1856
- };
1857
- contextRef.current = contextForDirectives;
1858
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(RenderContextProvider, { value: contextForDirectives, children: processAndRenderElements(allElements) });
1892
+ }, [content]);
1893
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { ref: containerRef });
1859
1894
  };
1860
1895
  var CustomMarkdownRenderer_default = CustomMarkdownRenderer;
1861
1896
 
1862
1897
  // react/NReditor.tsx
1863
- var import_jsx_runtime13 = require("react/jsx-runtime");
1898
+ var import_jsx_runtime2 = require("react/jsx-runtime");
1864
1899
  var customSyntaxHighlighting = import_language2.HighlightStyle.define([
1865
1900
  { tag: import_highlight2.tags.heading, fontWeight: "bold", color: "var(--tc-heading, #e2e8f0)" },
1866
1901
  { tag: import_highlight2.tags.quote, color: "var(--tc-quote, #94a3b8)", fontStyle: "italic" },
@@ -2313,9 +2348,9 @@ var NReditor = ({
2313
2348
  onGuide,
2314
2349
  onConfig
2315
2350
  }) => {
2316
- const editorRef = (0, import_react11.useRef)(null);
2317
- const [isAllFolded, setIsAllFolded] = (0, import_react11.useState)(false);
2318
- const [editorMode, setEditorMode] = (0, import_react11.useState)("editor");
2351
+ const editorRef = (0, import_react4.useRef)(null);
2352
+ const [isAllFolded, setIsAllFolded] = (0, import_react4.useState)(false);
2353
+ const [editorMode, setEditorMode] = (0, import_react4.useState)("split");
2319
2354
  const debouncedContent = useDebounce(value, debounceMs);
2320
2355
  useLazyTailwindCDN(tailwindCDN);
2321
2356
  const handleToggleFold = () => {
@@ -2328,7 +2363,7 @@ var NReditor = ({
2328
2363
  setIsAllFolded(true);
2329
2364
  }
2330
2365
  };
2331
- const extensions = import_react11.default.useMemo(
2366
+ const extensions = import_react4.default.useMemo(
2332
2367
  () => [
2333
2368
  customStreamParserV2,
2334
2369
  (0, import_view.lineNumbers)(),
@@ -2348,7 +2383,6 @@ var NReditor = ({
2348
2383
  customEditorTheme,
2349
2384
  (0, import_language2.syntaxHighlighting)(customSyntaxHighlighting),
2350
2385
  import_view.EditorView.lineWrapping,
2351
- (0, import_view.scrollPastEnd)(),
2352
2386
  import_view.keymap.of([
2353
2387
  { key: "Ctrl-Shift-[", run: import_language2.foldAll },
2354
2388
  { key: "Ctrl-Shift-]", run: import_language2.unfoldAll }
@@ -2365,74 +2399,73 @@ var NReditor = ({
2365
2399
  { key: "split", icon: "vertical_split", label: "Split" },
2366
2400
  { key: "preview", icon: "visibility", label: "Preview" }
2367
2401
  ];
2368
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: `nr-editor ${className || ""}`, children: [
2369
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "nr-editor-toolbar", children: [
2370
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "nr-editor-toolbar-left", children: [
2371
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2402
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: `nr-editor ${className || ""}`, children: [
2403
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "nr-editor-toolbar", children: [
2404
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "nr-editor-toolbar-left", children: [
2405
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
2372
2406
  "button",
2373
2407
  {
2374
2408
  onClick: handleToggleFold,
2375
2409
  className: "nr-toolbar-btn nr-toolbar-btn-fold",
2376
2410
  title: isAllFolded ? "Expandir todo" : "Colapsar todo",
2377
2411
  "aria-label": isAllFolded ? "Expandir todo" : "Colapsar todo",
2378
- children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "material-symbols-rounded", children: isAllFolded ? "unfold_more" : "unfold_less" })
2412
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "material-icons-round", children: isAllFolded ? "unfold_more" : "unfold_less" })
2379
2413
  }
2380
2414
  ),
2381
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "nr-toolbar-divider" }),
2382
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "nr-toolbar-mode-group", children: modeButtons.map((btn) => /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
2415
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "nr-toolbar-divider" }),
2416
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "nr-toolbar-mode-group", children: modeButtons.map((btn) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
2383
2417
  "button",
2384
2418
  {
2385
2419
  onClick: () => setEditorMode(btn.key),
2386
2420
  className: `nr-toolbar-btn nr-toolbar-btn-mode ${editorMode === btn.key ? "nr-toolbar-btn-mode--active" : ""} ${btn.key === "split" ? "nr-toolbar-btn-split" : ""}`,
2387
2421
  title: btn.label,
2388
2422
  children: [
2389
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "material-symbols-rounded", children: btn.icon }),
2390
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "nr-toolbar-label", children: btn.label })
2423
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "material-icons-round", children: btn.icon }),
2424
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "nr-toolbar-label", children: btn.label })
2391
2425
  ]
2392
2426
  },
2393
2427
  btn.key
2394
2428
  )) })
2395
2429
  ] }),
2396
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "nr-editor-toolbar-right", children: [
2397
- onGuide && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
2430
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "nr-editor-toolbar-right", children: [
2431
+ onGuide && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
2398
2432
  "button",
2399
2433
  {
2400
2434
  onClick: onGuide,
2401
2435
  className: "nr-toolbar-btn nr-toolbar-btn-sm nr-toolbar-btn-guide",
2402
2436
  title: "Gu\xEDa de sintaxis",
2403
2437
  children: [
2404
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "material-symbols-rounded", children: "menu_book" }),
2405
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "nr-toolbar-label", children: "Gu\xEDa" })
2438
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "material-icons-round", children: "menu_book" }),
2439
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "nr-toolbar-label", children: "Gu\xEDa" })
2406
2440
  ]
2407
2441
  }
2408
2442
  ),
2409
- onGuide && onConfig && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "nr-toolbar-divider" }),
2410
- onConfig && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
2443
+ onGuide && onConfig && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "nr-toolbar-divider" }),
2444
+ onConfig && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
2411
2445
  "button",
2412
2446
  {
2413
2447
  onClick: onConfig,
2414
2448
  className: "nr-toolbar-btn nr-toolbar-btn-sm nr-toolbar-btn-config",
2415
2449
  title: "Configurar tema y metadata",
2416
2450
  children: [
2417
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "material-symbols-rounded", children: "tune" }),
2418
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "nr-toolbar-label", children: "Configurar" })
2451
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "material-icons-round", children: "tune" }),
2452
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "nr-toolbar-label", children: "Configurar" })
2419
2453
  ]
2420
2454
  }
2421
2455
  )
2422
2456
  ] })
2423
2457
  ] }),
2424
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "nr-editor-body", children: [
2425
- (editorMode === "editor" || editorMode === "split") && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2458
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "nr-editor-body", children: [
2459
+ (editorMode === "editor" || editorMode === "split") && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
2426
2460
  "div",
2427
2461
  {
2428
2462
  className: `nr-editor-pane ${editorMode === "split" ? "nr-editor-pane--half" : ""}`,
2429
- children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2463
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
2430
2464
  import_react_codemirror.default,
2431
2465
  {
2432
2466
  value,
2433
2467
  onChange,
2434
- className: "flex-1 min-h-0 min-w-0",
2435
- height: "100%",
2468
+ height: "auto",
2436
2469
  onCreateEditor: (view) => {
2437
2470
  editorRef.current = view;
2438
2471
  },
@@ -2445,11 +2478,11 @@ var NReditor = ({
2445
2478
  )
2446
2479
  }
2447
2480
  ),
2448
- (editorMode === "preview" || editorMode === "split") && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2481
+ (editorMode === "preview" || editorMode === "split") && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
2449
2482
  "div",
2450
2483
  {
2451
2484
  className: `nr-editor-preview ${editorMode === "split" ? "nr-editor-preview--half" : ""}`,
2452
- children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "nr-editor-prose", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "nr-prose", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(CustomMarkdownRenderer_default, { content: debouncedContent }) }) })
2485
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "nr-editor-prose", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "nr-prose", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(CustomMarkdownRenderer_default, { content: debouncedContent }) }) })
2453
2486
  }
2454
2487
  )
2455
2488
  ] })