@noirmd/previewer 1.2.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/NReditor.cjs +851 -895
- package/dist/NReditor.cjs.map +1 -1
- package/dist/NReditor.d.cts +1 -1
- package/dist/NReditor.d.ts +1 -1
- package/dist/NReditor.js +852 -896
- package/dist/NReditor.js.map +1 -1
- package/dist/admonition.css +55 -0
- package/dist/{markdown.css → base.css} +96 -126
- package/dist/blockquote.css +16 -0
- package/dist/button.css +32 -0
- package/dist/card.css +143 -0
- package/dist/codeblock.css +59 -0
- package/dist/core.cjs +9 -1
- package/dist/core.cjs.map +1 -1
- package/dist/core.js +9 -1
- package/dist/core.js.map +1 -1
- package/dist/details.css +45 -0
- package/dist/editor.css +56 -9
- package/dist/fonts/material-icons-round.woff2 +0 -0
- package/dist/index.cjs +852 -883
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +41 -70
- package/dist/index.d.ts +41 -70
- package/dist/index.js +851 -877
- package/dist/index.js.map +1 -1
- package/dist/list.css +18 -0
- package/dist/modal.css +82 -0
- package/dist/react.cjs +852 -886
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +44 -73
- package/dist/react.d.ts +44 -73
- package/dist/react.js +851 -880
- package/dist/react.js.map +1 -1
- package/dist/slide.css +21 -0
- package/dist/table.css +36 -0
- package/dist/toc.css +45 -0
- package/dist/vanilla.cjs +42 -28
- package/dist/vanilla.cjs.map +1 -1
- package/dist/vanilla.css +32 -677
- package/dist/vanilla.d.cts +8 -2
- package/dist/vanilla.d.ts +8 -2
- package/dist/vanilla.js +41 -28
- package/dist/vanilla.js.map +1 -1
- package/dist/variables.css +53 -0
- package/dist/vue.cjs +931 -1121
- package/dist/vue.cjs.map +1 -1
- package/dist/vue.d.cts +63 -214
- package/dist/vue.d.ts +63 -214
- package/dist/vue.js +930 -1120
- package/dist/vue.js.map +1 -1
- package/editor.css +56 -9
- package/package.json +5 -10
- 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
|
|
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
|
|
|
@@ -404,7 +404,7 @@ function scanTailwindCDN() {
|
|
|
404
404
|
}
|
|
405
405
|
|
|
406
406
|
// react/CustomMarkdownRenderer.tsx
|
|
407
|
-
var
|
|
407
|
+
var import_react3 = require("react");
|
|
408
408
|
|
|
409
409
|
// core/utils.ts
|
|
410
410
|
function parseCssString(cssText) {
|
|
@@ -450,9 +450,6 @@ function extractAttributes(text) {
|
|
|
450
450
|
return { text: cleanedText, classes: classList.join(" "), id };
|
|
451
451
|
}
|
|
452
452
|
var _scopeCounter = 0;
|
|
453
|
-
function resetScopeCounter() {
|
|
454
|
-
_scopeCounter = 0;
|
|
455
|
-
}
|
|
456
453
|
function generateScopeId() {
|
|
457
454
|
return `scope-${++_scopeCounter}`;
|
|
458
455
|
}
|
|
@@ -500,6 +497,7 @@ function parseMarkdown(markdown2) {
|
|
|
500
497
|
if (!markdown2) return [];
|
|
501
498
|
const lines = markdown2.replace(/\r\n/g, "\n").replace(/\r/g, "").split("\n");
|
|
502
499
|
const result = [];
|
|
500
|
+
const usedIds = /* @__PURE__ */ new Set();
|
|
503
501
|
let i = 0;
|
|
504
502
|
while (i < lines.length) {
|
|
505
503
|
const line = lines[i];
|
|
@@ -509,7 +507,14 @@ function parseMarkdown(markdown2) {
|
|
|
509
507
|
const level = match[1].length;
|
|
510
508
|
const rawText = match[2];
|
|
511
509
|
const { text: text2, classes: classes2, id: customId } = extractAttributes(rawText);
|
|
512
|
-
const
|
|
510
|
+
const baseId = customId || generateId(text2.replace(/->|<-/g, ""));
|
|
511
|
+
let id2 = baseId;
|
|
512
|
+
let n = 1;
|
|
513
|
+
while (usedIds.has(id2)) {
|
|
514
|
+
n++;
|
|
515
|
+
id2 = `${baseId}-${n}`;
|
|
516
|
+
}
|
|
517
|
+
usedIds.add(id2);
|
|
513
518
|
result.push({ type: "header", level, text: text2, id: id2, classes: classes2 || void 0 });
|
|
514
519
|
i++;
|
|
515
520
|
continue;
|
|
@@ -824,10 +829,7 @@ function splitSlots(rawContent) {
|
|
|
824
829
|
return slots;
|
|
825
830
|
}
|
|
826
831
|
|
|
827
|
-
//
|
|
828
|
-
var import_react3 = require("react");
|
|
829
|
-
|
|
830
|
-
// react/highlightSetup.ts
|
|
832
|
+
// vanilla/highlightSetup.ts
|
|
831
833
|
var import_core = __toESM(require("highlight.js/lib/core"), 1);
|
|
832
834
|
var import_javascript = __toESM(require("highlight.js/lib/languages/javascript"), 1);
|
|
833
835
|
var import_typescript = __toESM(require("highlight.js/lib/languages/typescript"), 1);
|
|
@@ -876,991 +878,947 @@ import_core.default.registerLanguage("java", import_java.default);
|
|
|
876
878
|
import_core.default.registerLanguage("csharp", import_csharp.default);
|
|
877
879
|
import_core.default.registerLanguage("cs", import_csharp.default);
|
|
878
880
|
import_core.default.registerLanguage("cpp", import_cpp.default);
|
|
879
|
-
import_core.default.registerLanguage("c", import_cpp.default);
|
|
880
881
|
import_core.default.registerLanguage("go", import_go.default);
|
|
881
882
|
import_core.default.registerLanguage("rust", import_rust.default);
|
|
882
|
-
import_core.default.registerLanguage("rs", import_rust.default);
|
|
883
883
|
import_core.default.registerLanguage("php", import_php.default);
|
|
884
884
|
import_core.default.registerLanguage("ruby", import_ruby.default);
|
|
885
|
-
import_core.default.registerLanguage("rb", import_ruby.default);
|
|
886
885
|
import_core.default.registerLanguage("swift", import_swift.default);
|
|
887
886
|
import_core.default.registerLanguage("kotlin", import_kotlin.default);
|
|
888
|
-
import_core.default.registerLanguage("kt", import_kotlin.default);
|
|
889
887
|
import_core.default.registerLanguage("dart", import_dart.default);
|
|
890
888
|
import_core.default.registerLanguage("yaml", import_yaml.default);
|
|
891
|
-
import_core.default.registerLanguage("yml", import_yaml.default);
|
|
892
889
|
import_core.default.registerLanguage("toml", import_ini.default);
|
|
893
|
-
import_core.default.registerLanguage("ini", import_ini.default);
|
|
894
890
|
import_core.default.registerLanguage("dockerfile", import_dockerfile.default);
|
|
895
|
-
import_core.default.registerLanguage("docker", import_dockerfile.default);
|
|
896
891
|
import_core.default.registerLanguage("diff", import_diff.default);
|
|
897
892
|
import_core.default.registerLanguage("shell", import_shell.default);
|
|
898
893
|
var highlightSetup_default = import_core.default;
|
|
899
894
|
|
|
900
|
-
//
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
895
|
+
// vanilla/components.ts
|
|
896
|
+
function createIcon(iconName, extraClasses) {
|
|
897
|
+
const span = document.createElement("span");
|
|
898
|
+
const cls = `nr-icon material-icons-round${extraClasses ? ` ${extraClasses}` : ""}`;
|
|
899
|
+
span.className = cls;
|
|
900
|
+
span.setAttribute("aria-hidden", "true");
|
|
906
901
|
const isCodepoint = /^[eE][0-9a-fA-F]{3,4}$/.test(iconName);
|
|
907
902
|
if (isCodepoint) {
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
className: baseClass,
|
|
912
|
-
dangerouslySetInnerHTML: { __html: `&#x${iconName};` },
|
|
913
|
-
"aria-hidden": "true"
|
|
914
|
-
}
|
|
915
|
-
);
|
|
903
|
+
span.innerHTML = `&#x${iconName};`;
|
|
904
|
+
} else {
|
|
905
|
+
span.textContent = iconName;
|
|
916
906
|
}
|
|
917
|
-
return
|
|
918
|
-
}
|
|
919
|
-
|
|
920
|
-
const
|
|
921
|
-
|
|
907
|
+
return span;
|
|
908
|
+
}
|
|
909
|
+
function createCodeBlock(code, language, title) {
|
|
910
|
+
const wrapper = document.createElement("div");
|
|
911
|
+
wrapper.className = "nr-codeblock";
|
|
922
912
|
const lang = language?.split(/[\s{]/)[0]?.trim() || "";
|
|
923
|
-
|
|
913
|
+
if (title) {
|
|
914
|
+
const header = document.createElement("div");
|
|
915
|
+
header.className = "nr-codeblock__header";
|
|
916
|
+
header.appendChild(createIcon("description"));
|
|
917
|
+
const titleSpan = document.createElement("span");
|
|
918
|
+
titleSpan.textContent = title;
|
|
919
|
+
header.appendChild(titleSpan);
|
|
920
|
+
wrapper.appendChild(header);
|
|
921
|
+
}
|
|
922
|
+
const pre = document.createElement("pre");
|
|
923
|
+
pre.className = "nr-codeblock__pre";
|
|
924
|
+
const codeEl = document.createElement("code");
|
|
925
|
+
codeEl.className = `language-${lang || "plaintext"}`;
|
|
924
926
|
try {
|
|
925
927
|
if (lang && highlightSetup_default.getLanguage(lang)) {
|
|
926
|
-
|
|
928
|
+
codeEl.innerHTML = highlightSetup_default.highlight(code, { language: lang }).value;
|
|
927
929
|
} else {
|
|
928
|
-
|
|
930
|
+
codeEl.innerHTML = highlightSetup_default.highlightAuto(code).value;
|
|
929
931
|
}
|
|
930
932
|
} catch {
|
|
931
|
-
|
|
933
|
+
codeEl.textContent = code;
|
|
932
934
|
}
|
|
933
|
-
|
|
935
|
+
pre.appendChild(codeEl);
|
|
936
|
+
wrapper.appendChild(pre);
|
|
937
|
+
const copyBtn = document.createElement("button");
|
|
938
|
+
copyBtn.className = "nr-codeblock__copy";
|
|
939
|
+
copyBtn.title = "Copy code";
|
|
940
|
+
const copyIcon = createIcon("content_copy");
|
|
941
|
+
copyIcon.style.fontSize = "1rem";
|
|
942
|
+
copyBtn.appendChild(copyIcon);
|
|
943
|
+
let timer = null;
|
|
944
|
+
copyBtn.addEventListener("click", () => {
|
|
934
945
|
navigator.clipboard.writeText(code);
|
|
935
|
-
|
|
936
|
-
if (
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
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 = {
|
|
946
|
+
copyIcon.textContent = "check";
|
|
947
|
+
if (timer) clearTimeout(timer);
|
|
948
|
+
timer = setTimeout(() => {
|
|
949
|
+
copyIcon.textContent = "content_copy";
|
|
950
|
+
}, 1800);
|
|
951
|
+
});
|
|
952
|
+
wrapper.appendChild(copyBtn);
|
|
953
|
+
return wrapper;
|
|
954
|
+
}
|
|
955
|
+
var DEFAULT_ADMONITION_ICONS = {
|
|
949
956
|
note: "info",
|
|
950
957
|
info: "lightbulb",
|
|
951
958
|
warning: "warning",
|
|
952
959
|
danger: "report",
|
|
953
|
-
greentext: "
|
|
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"
|
|
960
|
+
greentext: "subdirectory_arrow_right"
|
|
961
961
|
};
|
|
962
|
-
|
|
963
|
-
const
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "text-sm leading-relaxed opacity-90", children })
|
|
975
|
-
]
|
|
976
|
-
}
|
|
977
|
-
);
|
|
978
|
-
};
|
|
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;
|
|
1127
|
-
}
|
|
1128
|
-
if (lastIndex < text.length) {
|
|
1129
|
-
elements.push(text.slice(lastIndex));
|
|
962
|
+
function createAdmonition(type, title, icon) {
|
|
963
|
+
const el = document.createElement("div");
|
|
964
|
+
el.className = `nr-admonition nr-admonition--${type || "note"}`;
|
|
965
|
+
if (title) {
|
|
966
|
+
const header = document.createElement("h5");
|
|
967
|
+
header.className = "nr-admonition__title";
|
|
968
|
+
const iconToRender = icon || DEFAULT_ADMONITION_ICONS[type] || "info";
|
|
969
|
+
header.appendChild(createIcon(iconToRender, "nr-admonition__icon"));
|
|
970
|
+
const titleSpan = document.createElement("span");
|
|
971
|
+
titleSpan.textContent = title;
|
|
972
|
+
header.appendChild(titleSpan);
|
|
973
|
+
el.appendChild(header);
|
|
1130
974
|
}
|
|
1131
|
-
|
|
975
|
+
const body = document.createElement("div");
|
|
976
|
+
body.className = "nr-admonition__body";
|
|
977
|
+
el.appendChild(body);
|
|
978
|
+
return el;
|
|
1132
979
|
}
|
|
1133
|
-
function
|
|
980
|
+
function createDetails(title, icon, defaultOpen) {
|
|
981
|
+
const details = document.createElement("details");
|
|
982
|
+
details.className = "nr-details";
|
|
983
|
+
if (defaultOpen) details.open = true;
|
|
984
|
+
const summary = document.createElement("summary");
|
|
985
|
+
summary.className = "nr-details__summary";
|
|
986
|
+
const iconToRender = icon || "play_arrow";
|
|
987
|
+
const iconEl = createIcon(iconToRender, "nr-details__icon");
|
|
988
|
+
summary.appendChild(iconEl);
|
|
989
|
+
const titleSpan = document.createElement("span");
|
|
990
|
+
titleSpan.textContent = title || "Details";
|
|
991
|
+
summary.appendChild(titleSpan);
|
|
992
|
+
details.addEventListener("toggle", () => {
|
|
993
|
+
iconEl.classList.toggle("nr-details__icon--open", details.open);
|
|
994
|
+
});
|
|
995
|
+
details.appendChild(summary);
|
|
996
|
+
const body = document.createElement("div");
|
|
997
|
+
body.className = "nr-details__body";
|
|
998
|
+
details.appendChild(body);
|
|
999
|
+
return details;
|
|
1000
|
+
}
|
|
1001
|
+
function createModal(title) {
|
|
1002
|
+
const dialog = document.createElement("dialog");
|
|
1003
|
+
dialog.className = "nr-modal";
|
|
1004
|
+
dialog.addEventListener("click", (e) => {
|
|
1005
|
+
if (e.target === dialog) {
|
|
1006
|
+
dialog.close();
|
|
1007
|
+
}
|
|
1008
|
+
});
|
|
1009
|
+
const popup = document.createElement("div");
|
|
1010
|
+
popup.className = "nr-modal__popup";
|
|
1011
|
+
const header = document.createElement("div");
|
|
1012
|
+
header.className = "nr-modal__header";
|
|
1013
|
+
const titleEl = document.createElement("h2");
|
|
1014
|
+
titleEl.className = "nr-modal__title";
|
|
1015
|
+
titleEl.textContent = title;
|
|
1016
|
+
header.appendChild(titleEl);
|
|
1017
|
+
const closeBtn = document.createElement("button");
|
|
1018
|
+
closeBtn.className = "nr-modal__close";
|
|
1019
|
+
closeBtn.appendChild(createIcon("close"));
|
|
1020
|
+
closeBtn.addEventListener("click", () => dialog.close());
|
|
1021
|
+
header.appendChild(closeBtn);
|
|
1022
|
+
popup.appendChild(header);
|
|
1023
|
+
const body = document.createElement("div");
|
|
1024
|
+
body.className = "nr-modal__body";
|
|
1025
|
+
popup.appendChild(body);
|
|
1026
|
+
dialog.appendChild(popup);
|
|
1027
|
+
return dialog;
|
|
1028
|
+
}
|
|
1029
|
+
function createTable(content, renderInline2) {
|
|
1134
1030
|
const rows = content.split("\n").filter((r) => r.trim());
|
|
1135
|
-
if (rows.length < 2)
|
|
1031
|
+
if (rows.length < 2) {
|
|
1032
|
+
const p = document.createElement("p");
|
|
1033
|
+
p.textContent = content;
|
|
1034
|
+
return p;
|
|
1035
|
+
}
|
|
1136
1036
|
const parseRow = (row) => row.split("|").map((c) => c.trim()).filter(Boolean);
|
|
1137
1037
|
const headerCells = parseRow(rows[0]);
|
|
1138
1038
|
const bodyRows = rows.slice(2).map(parseRow);
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1039
|
+
const wrapper = document.createElement("div");
|
|
1040
|
+
wrapper.className = "nr-table-wrap";
|
|
1041
|
+
const table = document.createElement("table");
|
|
1042
|
+
table.className = "nr-table";
|
|
1043
|
+
const thead = document.createElement("thead");
|
|
1044
|
+
const tr = document.createElement("tr");
|
|
1045
|
+
for (const cell of headerCells) {
|
|
1046
|
+
const th = document.createElement("th");
|
|
1047
|
+
th.className = "nr-table__th";
|
|
1048
|
+
th.appendChild(renderInline2(cell));
|
|
1049
|
+
tr.appendChild(th);
|
|
1050
|
+
}
|
|
1051
|
+
thead.appendChild(tr);
|
|
1052
|
+
table.appendChild(thead);
|
|
1053
|
+
const tbody = document.createElement("tbody");
|
|
1054
|
+
for (const cells of bodyRows) {
|
|
1055
|
+
const tr2 = document.createElement("tr");
|
|
1056
|
+
for (const cell of cells) {
|
|
1057
|
+
const td = document.createElement("td");
|
|
1058
|
+
td.className = "nr-table__td";
|
|
1059
|
+
td.appendChild(renderInline2(cell));
|
|
1060
|
+
tr2.appendChild(td);
|
|
1061
|
+
}
|
|
1062
|
+
tbody.appendChild(tr2);
|
|
1063
|
+
}
|
|
1064
|
+
table.appendChild(tbody);
|
|
1065
|
+
wrapper.appendChild(table);
|
|
1066
|
+
return wrapper;
|
|
1143
1067
|
}
|
|
1144
|
-
function
|
|
1068
|
+
function createList(content, renderInline2) {
|
|
1145
1069
|
const lines = content.split("\n");
|
|
1146
1070
|
const items = [];
|
|
1147
1071
|
for (const line of lines) {
|
|
1148
1072
|
if (!line.trim()) continue;
|
|
1149
1073
|
const match = line.match(/^(\s*)([-*+]|\d+\.)\s+(.+)$/);
|
|
1150
1074
|
if (match) {
|
|
1151
|
-
items.push({
|
|
1152
|
-
indent: match[1].length,
|
|
1153
|
-
marker: match[2],
|
|
1154
|
-
text: match[3]
|
|
1155
|
-
});
|
|
1075
|
+
items.push({ indent: match[1].length, marker: match[2], text: match[3] });
|
|
1156
1076
|
}
|
|
1157
1077
|
}
|
|
1158
|
-
if (items.length === 0)
|
|
1078
|
+
if (items.length === 0) {
|
|
1079
|
+
const p = document.createElement("p");
|
|
1080
|
+
p.textContent = content;
|
|
1081
|
+
return p;
|
|
1082
|
+
}
|
|
1159
1083
|
const isOrdered = /^\d+\.$/.test(items[0].marker);
|
|
1160
|
-
const
|
|
1161
|
-
|
|
1084
|
+
const list = document.createElement(isOrdered ? "ol" : "ul");
|
|
1085
|
+
list.className = "nr-list";
|
|
1086
|
+
for (const item of items) {
|
|
1087
|
+
const li = document.createElement("li");
|
|
1088
|
+
li.className = "nr-list__item";
|
|
1089
|
+
li.appendChild(renderInline2(item.text));
|
|
1090
|
+
list.appendChild(li);
|
|
1091
|
+
}
|
|
1092
|
+
return list;
|
|
1162
1093
|
}
|
|
1163
|
-
function
|
|
1164
|
-
|
|
1094
|
+
function createTOC(headers, renderInline2) {
|
|
1095
|
+
const nav = document.createElement("nav");
|
|
1096
|
+
nav.className = "nr-toc";
|
|
1097
|
+
const title = document.createElement("div");
|
|
1098
|
+
title.className = "nr-toc__title";
|
|
1099
|
+
title.textContent = "Table of Contents";
|
|
1100
|
+
nav.appendChild(title);
|
|
1101
|
+
const ul = document.createElement("ul");
|
|
1102
|
+
ul.className = "nr-toc__list";
|
|
1103
|
+
for (const h of headers) {
|
|
1104
|
+
const li = document.createElement("li");
|
|
1105
|
+
li.className = `nr-toc__item nr-toc__item--h${h.level}`;
|
|
1106
|
+
const a = document.createElement("a");
|
|
1107
|
+
a.className = "nr-toc__link";
|
|
1108
|
+
a.href = `#${h.id}`;
|
|
1109
|
+
a.appendChild(renderInline2(h.text.replace(/->|<-/g, "").trim()));
|
|
1110
|
+
a.addEventListener("click", (e) => {
|
|
1111
|
+
e.preventDefault();
|
|
1112
|
+
const target = document.getElementById(h.id);
|
|
1113
|
+
if (target) target.scrollIntoView({ behavior: "smooth", block: "start" });
|
|
1114
|
+
});
|
|
1115
|
+
li.appendChild(a);
|
|
1116
|
+
ul.appendChild(li);
|
|
1117
|
+
}
|
|
1118
|
+
nav.appendChild(ul);
|
|
1119
|
+
return nav;
|
|
1120
|
+
}
|
|
1121
|
+
function createBlockquote(content, classes, renderInline2) {
|
|
1122
|
+
const el = document.createElement("blockquote");
|
|
1123
|
+
el.className = `nr-blockquote${classes ? ` ${classes}` : ""}`;
|
|
1124
|
+
el.appendChild(renderInline2(content));
|
|
1125
|
+
return el;
|
|
1165
1126
|
}
|
|
1166
1127
|
|
|
1167
|
-
//
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
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")
|
|
1128
|
+
// vanilla/inline.ts
|
|
1129
|
+
function renderInline(text) {
|
|
1130
|
+
const fragment = document.createDocumentFragment();
|
|
1131
|
+
if (!text) return fragment;
|
|
1132
|
+
const regex = /(\|\[[^\]]+\]\||\*\*\*.+?\*\*\*|\*\*.+?\*\*|_.+?_|~~.+?~~|`[^`]+?`|!~.+?~!|%[^%\s]+?%[\s\S]+?%%|!>.+?<!|==.+?==|\[[^\]]+?\]\([^)]+?\)|<[^>]+>)/g;
|
|
1133
|
+
let lastIndex = 0;
|
|
1134
|
+
let match;
|
|
1135
|
+
while ((match = regex.exec(text)) !== null) {
|
|
1136
|
+
if (match.index > lastIndex) {
|
|
1137
|
+
fragment.appendChild(document.createTextNode(text.slice(lastIndex, match.index)));
|
|
1183
1138
|
}
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1139
|
+
fragment.appendChild(parseInlinePart(match[0]));
|
|
1140
|
+
lastIndex = regex.lastIndex;
|
|
1141
|
+
}
|
|
1142
|
+
if (lastIndex < text.length) {
|
|
1143
|
+
fragment.appendChild(document.createTextNode(text.slice(lastIndex)));
|
|
1144
|
+
}
|
|
1145
|
+
return fragment;
|
|
1146
|
+
}
|
|
1147
|
+
function parseInlinePart(part) {
|
|
1148
|
+
let match;
|
|
1149
|
+
if (match = part.match(/^\|\[([^\]]+)\]\|$/)) {
|
|
1150
|
+
return createIcon(match[1]);
|
|
1151
|
+
}
|
|
1152
|
+
if (match = part.match(/^!~(.+?)~!$/)) {
|
|
1153
|
+
const content = match[1];
|
|
1154
|
+
const parts = content.split(";");
|
|
1155
|
+
let color = "currentColor";
|
|
1156
|
+
let decorationStyle = "solid";
|
|
1157
|
+
let type = "underline";
|
|
1158
|
+
let textIndex = 0;
|
|
1159
|
+
if (parts[textIndex]?.match(/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/) || ["red", "blue", "green", "purple", "orange", "yellow", "pink"].includes(parts[textIndex])) {
|
|
1160
|
+
color = parts[textIndex++];
|
|
1161
|
+
}
|
|
1162
|
+
if (["solid", "double", "dotted", "dashed", "wavy"].includes(parts[textIndex])) {
|
|
1163
|
+
decorationStyle = parts[textIndex++];
|
|
1164
|
+
}
|
|
1165
|
+
if (["underline", "line-through", "overline", "both"].includes(parts[textIndex])) {
|
|
1166
|
+
type = parts[textIndex] === "both" ? "underline line-through" : parts[textIndex++];
|
|
1167
|
+
}
|
|
1168
|
+
const innerText = parts.slice(textIndex).join(";");
|
|
1169
|
+
const span = document.createElement("span");
|
|
1170
|
+
span.className = "nr-underline";
|
|
1171
|
+
span.style.textDecoration = `${type} ${decorationStyle} ${color}`;
|
|
1172
|
+
span.style.textDecorationThickness = "auto";
|
|
1173
|
+
span.appendChild(renderInline(innerText));
|
|
1174
|
+
return span;
|
|
1175
|
+
}
|
|
1176
|
+
if (match = part.match(/%([^%\s]+?)%([\s\S]+?)%%/)) {
|
|
1177
|
+
const span = document.createElement("span");
|
|
1178
|
+
span.style.color = match[1];
|
|
1179
|
+
span.appendChild(renderInline(match[2]));
|
|
1180
|
+
return span;
|
|
1181
|
+
}
|
|
1182
|
+
if (match = part.match(/^!>([^<]+?)<!$/)) {
|
|
1183
|
+
const span = document.createElement("span");
|
|
1184
|
+
span.className = "nr-spoiler";
|
|
1185
|
+
span.appendChild(renderInline(match[1]));
|
|
1186
|
+
return span;
|
|
1187
|
+
}
|
|
1188
|
+
if (match = part.match(/^==(.+?)==$/)) {
|
|
1189
|
+
const mark = document.createElement("mark");
|
|
1190
|
+
mark.className = "nr-highlight";
|
|
1191
|
+
mark.appendChild(renderInline(match[1]));
|
|
1192
|
+
return mark;
|
|
1193
|
+
}
|
|
1194
|
+
if (match = part.match(/^\*\*\*(.+?)\*\*\*$/)) {
|
|
1195
|
+
const strong = document.createElement("strong");
|
|
1196
|
+
const em = document.createElement("em");
|
|
1197
|
+
em.appendChild(renderInline(match[1]));
|
|
1198
|
+
strong.appendChild(em);
|
|
1199
|
+
return strong;
|
|
1200
|
+
}
|
|
1201
|
+
if (match = part.match(/^\*\*(.+?)\*\*$/)) {
|
|
1202
|
+
const strong = document.createElement("strong");
|
|
1203
|
+
strong.appendChild(renderInline(match[1]));
|
|
1204
|
+
return strong;
|
|
1205
|
+
}
|
|
1206
|
+
if (match = part.match(/^_(.+?)_$/)) {
|
|
1207
|
+
const em = document.createElement("em");
|
|
1208
|
+
em.appendChild(renderInline(match[1]));
|
|
1209
|
+
return em;
|
|
1210
|
+
}
|
|
1211
|
+
if (match = part.match(/^~~(.+?)~~$/)) {
|
|
1212
|
+
const del = document.createElement("del");
|
|
1213
|
+
del.appendChild(renderInline(match[1]));
|
|
1214
|
+
return del;
|
|
1215
|
+
}
|
|
1216
|
+
if (match = part.match(/^`([^`]+)`$/)) {
|
|
1217
|
+
const code = document.createElement("code");
|
|
1218
|
+
code.className = "nr-inline-code";
|
|
1219
|
+
code.textContent = match[1];
|
|
1220
|
+
return code;
|
|
1221
|
+
}
|
|
1222
|
+
if (match = part.match(/^\[([^\]]+?)\]\(([^)]+?)\)$/)) {
|
|
1223
|
+
const a = document.createElement("a");
|
|
1224
|
+
a.className = "nr-link";
|
|
1225
|
+
a.href = match[2];
|
|
1226
|
+
a.target = "_blank";
|
|
1227
|
+
a.rel = "noopener noreferrer";
|
|
1228
|
+
a.appendChild(renderInline(match[1]));
|
|
1229
|
+
return a;
|
|
1230
|
+
}
|
|
1231
|
+
if (part.startsWith("<") && part.endsWith(">")) {
|
|
1232
|
+
const span = document.createElement("span");
|
|
1233
|
+
span.innerHTML = part;
|
|
1234
|
+
return span;
|
|
1235
|
+
}
|
|
1236
|
+
return document.createTextNode(part);
|
|
1237
|
+
}
|
|
1187
1238
|
|
|
1188
|
-
//
|
|
1189
|
-
var
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
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
|
-
] });
|
|
1239
|
+
// vanilla/directives/admonition.ts
|
|
1240
|
+
var admonitionDirective = ({ directiveType, props, renderSlot }) => {
|
|
1241
|
+
const el = createAdmonition(directiveType, props.title, props.icon);
|
|
1242
|
+
if (props.class) el.classList.add(...props.class.split(/\s+/).filter(Boolean));
|
|
1243
|
+
if (props.style) el.setAttribute("style", props.style);
|
|
1244
|
+
const body = el.querySelector(".nr-admonition__body");
|
|
1245
|
+
if (body) {
|
|
1246
|
+
body.appendChild(renderSlot("default"));
|
|
1247
|
+
}
|
|
1248
|
+
return el;
|
|
1271
1249
|
};
|
|
1272
|
-
var
|
|
1250
|
+
var admonition_default = admonitionDirective;
|
|
1273
1251
|
|
|
1274
|
-
//
|
|
1275
|
-
var
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
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
|
-
}
|
|
1252
|
+
// vanilla/directives/details.ts
|
|
1253
|
+
var detailsDirective = ({ props, renderSlot }) => {
|
|
1254
|
+
const el = createDetails(
|
|
1255
|
+
props.title || "Details",
|
|
1256
|
+
props.icon,
|
|
1257
|
+
props.defaultOpen === "true"
|
|
1290
1258
|
);
|
|
1259
|
+
if (props.class) el.classList.add(...props.class.split(/\s+/).filter(Boolean));
|
|
1260
|
+
if (props.style) el.setAttribute("style", props.style);
|
|
1261
|
+
const body = el.querySelector(".nr-details__body");
|
|
1262
|
+
if (body) {
|
|
1263
|
+
body.appendChild(renderSlot("default"));
|
|
1264
|
+
}
|
|
1265
|
+
return el;
|
|
1291
1266
|
};
|
|
1292
|
-
var
|
|
1267
|
+
var details_default = detailsDirective;
|
|
1293
1268
|
|
|
1294
|
-
//
|
|
1295
|
-
var
|
|
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}`;
|
|
1269
|
+
// vanilla/directives/modal.ts
|
|
1270
|
+
var modalDirective = ({ props, renderSlot }) => {
|
|
1304
1271
|
const label = props.label || props.title || "Open";
|
|
1305
1272
|
const modalTitle = props.title || "Modal";
|
|
1306
1273
|
const customClass = props.class || "";
|
|
1307
|
-
const
|
|
1308
|
-
|
|
1309
|
-
const
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
const
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
const
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
"
|
|
1319
|
-
}
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
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
|
-
] });
|
|
1274
|
+
const wrapper = document.createElement("div");
|
|
1275
|
+
wrapper.className = "nr-modal-trigger";
|
|
1276
|
+
const btn = document.createElement("button");
|
|
1277
|
+
btn.className = `nr-button nr-button--default`;
|
|
1278
|
+
if (customClass) btn.classList.add(...customClass.split(/\s+/).filter(Boolean));
|
|
1279
|
+
const icon = props.icon || "open_in_new";
|
|
1280
|
+
if (icon) btn.appendChild(createIcon(icon));
|
|
1281
|
+
btn.appendChild(document.createTextNode(label));
|
|
1282
|
+
const dialog = createModal(modalTitle);
|
|
1283
|
+
const body = dialog.querySelector(".nr-modal__body");
|
|
1284
|
+
if (body) {
|
|
1285
|
+
body.appendChild(renderSlot("default"));
|
|
1286
|
+
}
|
|
1287
|
+
btn.addEventListener("click", () => {
|
|
1288
|
+
if (!dialog.open) {
|
|
1289
|
+
document.body.appendChild(dialog);
|
|
1290
|
+
dialog.showModal();
|
|
1291
|
+
dialog.addEventListener("close", () => {
|
|
1292
|
+
dialog.remove();
|
|
1293
|
+
}, { once: true });
|
|
1294
|
+
}
|
|
1295
|
+
});
|
|
1296
|
+
wrapper.appendChild(btn);
|
|
1297
|
+
wrapper.appendChild(dialog);
|
|
1298
|
+
return wrapper;
|
|
1342
1299
|
};
|
|
1343
|
-
var
|
|
1300
|
+
var modal_default = modalDirective;
|
|
1344
1301
|
|
|
1345
|
-
//
|
|
1346
|
-
var
|
|
1347
|
-
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
1348
|
-
var ButtonDirective = ({
|
|
1349
|
-
props,
|
|
1350
|
-
renderSlot
|
|
1351
|
-
}) => {
|
|
1302
|
+
// vanilla/directives/button.ts
|
|
1303
|
+
var buttonDirective = ({ props, renderSlot }) => {
|
|
1352
1304
|
const url = props.url || props.href || "#";
|
|
1353
1305
|
const label = props.label;
|
|
1354
1306
|
const icon = props.icon || "near_me";
|
|
1355
1307
|
const target = props.target || "_blank";
|
|
1356
1308
|
const customClass = props.class || "";
|
|
1357
|
-
const
|
|
1358
|
-
|
|
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(" ");
|
|
1309
|
+
const wrapper = document.createElement("div");
|
|
1310
|
+
wrapper.className = "nr-button-wrap";
|
|
1371
1311
|
if (label) {
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
]
|
|
1383
|
-
}
|
|
1384
|
-
) });
|
|
1312
|
+
const a = document.createElement("a");
|
|
1313
|
+
a.href = url;
|
|
1314
|
+
a.target = target;
|
|
1315
|
+
a.rel = "noopener noreferrer";
|
|
1316
|
+
a.className = "nr-button nr-button--default";
|
|
1317
|
+
if (customClass) a.classList.add(...customClass.split(/\s+/).filter(Boolean));
|
|
1318
|
+
a.appendChild(createIcon(icon));
|
|
1319
|
+
a.appendChild(document.createTextNode(label));
|
|
1320
|
+
wrapper.appendChild(a);
|
|
1321
|
+
return wrapper;
|
|
1385
1322
|
}
|
|
1386
1323
|
const slotContent = renderSlot("default");
|
|
1387
|
-
const
|
|
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);
|
|
1324
|
+
const links = slotContent.querySelectorAll("a");
|
|
1401
1325
|
if (links.length > 0) {
|
|
1402
|
-
|
|
1403
|
-
(
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
)
|
|
1326
|
+
links.forEach((link) => {
|
|
1327
|
+
link.classList.add("nr-button", "nr-button--default");
|
|
1328
|
+
if (customClass) link.classList.add(...customClass.split(/\s+/).filter(Boolean));
|
|
1329
|
+
});
|
|
1330
|
+
wrapper.appendChild(slotContent);
|
|
1331
|
+
} else {
|
|
1332
|
+
const a = document.createElement("a");
|
|
1333
|
+
a.href = url;
|
|
1334
|
+
a.target = target;
|
|
1335
|
+
a.rel = "noopener noreferrer";
|
|
1336
|
+
a.className = "nr-button nr-button--default";
|
|
1337
|
+
if (customClass) a.classList.add(...customClass.split(/\s+/).filter(Boolean));
|
|
1338
|
+
a.appendChild(createIcon(icon));
|
|
1339
|
+
a.appendChild(slotContent);
|
|
1340
|
+
wrapper.appendChild(a);
|
|
1417
1341
|
}
|
|
1418
|
-
return
|
|
1419
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(IconRenderer, { iconName: icon }),
|
|
1420
|
-
slotContent
|
|
1421
|
-
] }) });
|
|
1342
|
+
return wrapper;
|
|
1422
1343
|
};
|
|
1423
|
-
var
|
|
1344
|
+
var button_default = buttonDirective;
|
|
1424
1345
|
|
|
1425
|
-
//
|
|
1426
|
-
var
|
|
1427
|
-
|
|
1346
|
+
// vanilla/directives/card.ts
|
|
1347
|
+
var cardDirective = ({
|
|
1348
|
+
directiveType,
|
|
1428
1349
|
props,
|
|
1429
|
-
|
|
1350
|
+
slots,
|
|
1351
|
+
renderSlot,
|
|
1352
|
+
options
|
|
1430
1353
|
}) => {
|
|
1431
|
-
const
|
|
1432
|
-
const
|
|
1433
|
-
const
|
|
1434
|
-
const
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1354
|
+
const { title, image, icon, url, target } = props;
|
|
1355
|
+
const customClass = props.class || "";
|
|
1356
|
+
const hasDescription = !!slots.description;
|
|
1357
|
+
const { isSingleCard } = options || {};
|
|
1358
|
+
const isModal = directiveType === "card-m";
|
|
1359
|
+
const isLink = directiveType === "card-b";
|
|
1360
|
+
const inlineStyles = props.style ? parseCssString(props.style) : {};
|
|
1361
|
+
const card = document.createElement("div");
|
|
1362
|
+
card.className = `nr-card${isModal || isLink ? " nr-card--interactive" : ""} ${customClass}`.trim();
|
|
1363
|
+
for (const [key, value] of Object.entries(inlineStyles)) {
|
|
1364
|
+
card.style.setProperty(key, String(value));
|
|
1365
|
+
}
|
|
1366
|
+
if (image) {
|
|
1367
|
+
const imgWrap = document.createElement("div");
|
|
1368
|
+
imgWrap.className = `nr-card__image${isSingleCard ? " nr-card__image--tall" : ""}`;
|
|
1369
|
+
const img = document.createElement("img");
|
|
1370
|
+
img.src = image;
|
|
1371
|
+
img.alt = title || "";
|
|
1372
|
+
img.className = "nr-card__img";
|
|
1373
|
+
imgWrap.appendChild(img);
|
|
1374
|
+
const gradient = document.createElement("div");
|
|
1375
|
+
gradient.className = "nr-card__gradient";
|
|
1376
|
+
imgWrap.appendChild(gradient);
|
|
1377
|
+
card.appendChild(imgWrap);
|
|
1378
|
+
}
|
|
1379
|
+
const body = document.createElement("div");
|
|
1380
|
+
body.className = `nr-card__body${image ? " nr-card__body--overlap" : ""}`;
|
|
1381
|
+
if (icon || title) {
|
|
1382
|
+
const header = document.createElement("div");
|
|
1383
|
+
header.className = "nr-card__header";
|
|
1384
|
+
if (icon) {
|
|
1385
|
+
const iconWrap = document.createElement("div");
|
|
1386
|
+
iconWrap.className = "nr-card__icon-wrap";
|
|
1387
|
+
iconWrap.appendChild(createIcon(icon));
|
|
1388
|
+
header.appendChild(iconWrap);
|
|
1389
|
+
}
|
|
1390
|
+
if (title) {
|
|
1391
|
+
const h3 = document.createElement("h3");
|
|
1392
|
+
h3.className = "nr-card__title";
|
|
1393
|
+
h3.textContent = title;
|
|
1394
|
+
header.appendChild(h3);
|
|
1395
|
+
}
|
|
1396
|
+
body.appendChild(header);
|
|
1397
|
+
}
|
|
1398
|
+
if (hasDescription) {
|
|
1399
|
+
const desc = document.createElement("div");
|
|
1400
|
+
desc.className = "nr-card__description";
|
|
1401
|
+
desc.appendChild(renderSlot("description"));
|
|
1402
|
+
body.appendChild(desc);
|
|
1403
|
+
}
|
|
1404
|
+
if (directiveType === "card") {
|
|
1405
|
+
const contentSlot = renderSlot("content") || renderSlot("default");
|
|
1406
|
+
if (contentSlot.childNodes.length > 0) {
|
|
1407
|
+
const contentDiv = document.createElement("div");
|
|
1408
|
+
contentDiv.className = "nr-card__content";
|
|
1409
|
+
contentDiv.appendChild(contentSlot);
|
|
1410
|
+
body.appendChild(contentDiv);
|
|
1411
|
+
}
|
|
1412
|
+
}
|
|
1413
|
+
if (isModal || isLink) {
|
|
1414
|
+
const action = document.createElement("div");
|
|
1415
|
+
action.className = "nr-card__action";
|
|
1416
|
+
if (isLink && url) {
|
|
1417
|
+
const a = document.createElement("a");
|
|
1418
|
+
a.href = url;
|
|
1419
|
+
a.target = target || "_blank";
|
|
1420
|
+
a.rel = "noopener noreferrer";
|
|
1421
|
+
a.className = "nr-card__action-link";
|
|
1422
|
+
a.appendChild(createIcon("open_in_new"));
|
|
1423
|
+
a.appendChild(document.createTextNode(" Link"));
|
|
1424
|
+
action.appendChild(a);
|
|
1425
|
+
} else if (isModal) {
|
|
1426
|
+
const modalBtn = document.createElement("div");
|
|
1427
|
+
modalBtn.className = "nr-card__action-link";
|
|
1428
|
+
modalBtn.appendChild(createIcon("arrow_forward"));
|
|
1429
|
+
modalBtn.appendChild(document.createTextNode(" Abrir"));
|
|
1430
|
+
action.appendChild(modalBtn);
|
|
1431
|
+
}
|
|
1432
|
+
body.appendChild(action);
|
|
1433
|
+
}
|
|
1434
|
+
card.appendChild(body);
|
|
1435
|
+
if (isModal) {
|
|
1436
|
+
const dialog = createModal(title || "Detalles");
|
|
1437
|
+
const modalBody = dialog.querySelector(".nr-modal__body");
|
|
1438
|
+
if (modalBody) {
|
|
1439
|
+
const contentSlot = renderSlot("content") || renderSlot("default");
|
|
1440
|
+
modalBody.appendChild(contentSlot);
|
|
1441
|
+
}
|
|
1442
|
+
card.addEventListener("click", () => {
|
|
1443
|
+
if (!dialog.open) {
|
|
1444
|
+
document.body.appendChild(dialog);
|
|
1445
|
+
dialog.showModal();
|
|
1446
|
+
dialog.addEventListener("close", () => dialog.remove(), { once: true });
|
|
1447
|
+
}
|
|
1448
|
+
});
|
|
1449
|
+
const frag = document.createDocumentFragment();
|
|
1450
|
+
frag.appendChild(card);
|
|
1451
|
+
frag.appendChild(dialog);
|
|
1452
|
+
return frag;
|
|
1453
|
+
}
|
|
1454
|
+
if (isLink && url) {
|
|
1455
|
+
card.addEventListener("click", () => window.open(url, target || "_blank"));
|
|
1456
|
+
}
|
|
1457
|
+
return card;
|
|
1458
|
+
};
|
|
1459
|
+
var card_default = cardDirective;
|
|
1460
|
+
|
|
1461
|
+
// vanilla/directives/wrapper.ts
|
|
1462
|
+
var wrapperDirective = ({ props, renderSlot }) => {
|
|
1463
|
+
const el = document.createElement("div");
|
|
1464
|
+
el.className = "nr-wrapper";
|
|
1465
|
+
if (props.class) el.classList.add(...props.class.split(/\s+/).filter(Boolean));
|
|
1466
|
+
if (props.id) el.id = props.id;
|
|
1467
|
+
if (props.style) {
|
|
1468
|
+
const styles = parseCssString(props.style);
|
|
1469
|
+
for (const [key, value] of Object.entries(styles)) {
|
|
1470
|
+
el.style.setProperty(key, String(value));
|
|
1471
|
+
}
|
|
1472
|
+
}
|
|
1438
1473
|
for (const [key, value] of Object.entries(props)) {
|
|
1439
1474
|
if (key.startsWith("data-")) {
|
|
1440
|
-
|
|
1475
|
+
el.setAttribute(key, value);
|
|
1441
1476
|
}
|
|
1442
1477
|
}
|
|
1443
|
-
|
|
1478
|
+
el.appendChild(renderSlot("default"));
|
|
1479
|
+
return el;
|
|
1444
1480
|
};
|
|
1445
|
-
var
|
|
1481
|
+
var wrapper_default = wrapperDirective;
|
|
1446
1482
|
|
|
1447
|
-
//
|
|
1448
|
-
var import_react7 = require("react");
|
|
1449
|
-
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
1483
|
+
// vanilla/directives/slide.ts
|
|
1450
1484
|
var slideCounter = 0;
|
|
1451
|
-
var
|
|
1485
|
+
var slideDirective = ({
|
|
1452
1486
|
props,
|
|
1453
|
-
|
|
1454
|
-
|
|
1487
|
+
slots,
|
|
1488
|
+
renderInline: renderInline2,
|
|
1489
|
+
renderMarkdown
|
|
1455
1490
|
}) => {
|
|
1456
1491
|
const rawContent = slots.default || "";
|
|
1457
1492
|
const lines = rawContent.split("\n").map((l) => l.trim()).filter(Boolean);
|
|
1458
|
-
|
|
1459
|
-
|
|
1493
|
+
if (lines.length === 0) {
|
|
1494
|
+
return document.createDocumentFragment();
|
|
1495
|
+
}
|
|
1460
1496
|
const interval = parseInt(props.interval || "3000", 10);
|
|
1461
1497
|
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
1498
|
const rawClass = props.class || "";
|
|
1482
1499
|
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
1500
|
const scopeClass = `sld-${++slideCounter}`;
|
|
1501
|
-
const
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1501
|
+
const container = document.createElement("div");
|
|
1502
|
+
container.className = "nr-slide";
|
|
1503
|
+
Object.assign(container.style, {
|
|
1504
|
+
position: "relative",
|
|
1505
|
+
overflow: "hidden",
|
|
1506
|
+
...inlineStyle
|
|
1507
|
+
});
|
|
1508
|
+
const track = document.createElement("div");
|
|
1509
|
+
track.className = "nr-slide__track";
|
|
1510
|
+
track.style.transition = `transform ${speed}ms cubic-bezier(0.16, 1, 0.3, 1)`;
|
|
1511
|
+
const slideEls = [];
|
|
1512
|
+
for (const line of lines) {
|
|
1513
|
+
const slideEl = document.createElement("div");
|
|
1514
|
+
slideEl.className = `nr-slide__item ${scopeClass} ${rawClass}`.trim();
|
|
1515
|
+
slideEl.style.display = "flex";
|
|
1516
|
+
slideEl.style.alignItems = "center";
|
|
1517
|
+
if (renderMarkdown) {
|
|
1518
|
+
const tokens = renderMarkdown(line);
|
|
1519
|
+
slideEl.appendChild(tokens);
|
|
1520
|
+
} else if (renderInline2) {
|
|
1521
|
+
slideEl.appendChild(renderInline2(line));
|
|
1522
|
+
}
|
|
1523
|
+
track.appendChild(slideEl);
|
|
1524
|
+
slideEls.push(slideEl);
|
|
1525
|
+
}
|
|
1526
|
+
container.appendChild(track);
|
|
1527
|
+
let current = 0;
|
|
1528
|
+
let maxH = 0;
|
|
1529
|
+
const measureAndSetHeight = () => {
|
|
1530
|
+
maxH = 0;
|
|
1531
|
+
for (const el of slideEls) {
|
|
1532
|
+
maxH = Math.max(maxH, el.offsetHeight);
|
|
1533
|
+
}
|
|
1534
|
+
if (maxH > 0) {
|
|
1535
|
+
container.style.height = `${maxH}px`;
|
|
1536
|
+
for (const el of slideEls) {
|
|
1537
|
+
el.style.height = `${maxH}px`;
|
|
1538
|
+
}
|
|
1534
1539
|
}
|
|
1535
|
-
|
|
1540
|
+
};
|
|
1541
|
+
requestAnimationFrame(() => {
|
|
1542
|
+
measureAndSetHeight();
|
|
1543
|
+
if (document.fonts?.ready) {
|
|
1544
|
+
document.fonts.ready.then(measureAndSetHeight);
|
|
1545
|
+
}
|
|
1546
|
+
});
|
|
1547
|
+
if (lines.length > 1) {
|
|
1548
|
+
setInterval(() => {
|
|
1549
|
+
current = (current + 1) % lines.length;
|
|
1550
|
+
track.style.transform = `translateY(${-current * maxH}px)`;
|
|
1551
|
+
}, interval);
|
|
1552
|
+
}
|
|
1553
|
+
return container;
|
|
1536
1554
|
};
|
|
1537
|
-
var
|
|
1555
|
+
var slide_default = slideDirective;
|
|
1538
1556
|
|
|
1539
|
-
//
|
|
1557
|
+
// vanilla/directives/index.ts
|
|
1540
1558
|
var directiveRegistry = {
|
|
1541
1559
|
// Admonitions
|
|
1542
|
-
note:
|
|
1543
|
-
info:
|
|
1544
|
-
warning:
|
|
1545
|
-
danger:
|
|
1546
|
-
greentext:
|
|
1560
|
+
note: admonition_default,
|
|
1561
|
+
info: admonition_default,
|
|
1562
|
+
warning: admonition_default,
|
|
1563
|
+
danger: admonition_default,
|
|
1564
|
+
greentext: admonition_default,
|
|
1547
1565
|
// Cards
|
|
1548
|
-
card:
|
|
1549
|
-
"card-m":
|
|
1550
|
-
"card-b":
|
|
1566
|
+
card: card_default,
|
|
1567
|
+
"card-m": card_default,
|
|
1568
|
+
"card-b": card_default,
|
|
1551
1569
|
// Interactive
|
|
1552
|
-
details:
|
|
1553
|
-
modal:
|
|
1554
|
-
button:
|
|
1570
|
+
details: details_default,
|
|
1571
|
+
modal: modal_default,
|
|
1572
|
+
button: button_default,
|
|
1555
1573
|
// Layout / generic wrappers
|
|
1556
|
-
div:
|
|
1557
|
-
style:
|
|
1558
|
-
custom:
|
|
1559
|
-
raw:
|
|
1574
|
+
div: wrapper_default,
|
|
1575
|
+
style: wrapper_default,
|
|
1576
|
+
custom: wrapper_default,
|
|
1577
|
+
raw: wrapper_default,
|
|
1560
1578
|
// Animation
|
|
1561
|
-
slide:
|
|
1579
|
+
slide: slide_default
|
|
1562
1580
|
};
|
|
1563
1581
|
var directives_default = directiveRegistry;
|
|
1564
1582
|
|
|
1565
|
-
//
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1583
|
+
// vanilla/renderer.ts
|
|
1584
|
+
function renderTokens(tokens) {
|
|
1585
|
+
const article = document.createElement("article");
|
|
1586
|
+
article.className = "nr-prose";
|
|
1587
|
+
const ctx = {
|
|
1588
|
+
parseMarkdown,
|
|
1589
|
+
renderElements: (tks) => renderTokensInner(tks, ctx),
|
|
1590
|
+
renderInline,
|
|
1591
|
+
renderMarkdown: (md) => renderTokensInner(parseMarkdown(md), ctx)
|
|
1592
|
+
};
|
|
1593
|
+
article.appendChild(processElements(tokens, ctx, tokens));
|
|
1594
|
+
return article;
|
|
1595
|
+
}
|
|
1596
|
+
function renderMarkdownString(markdown2) {
|
|
1597
|
+
const tokens = parseMarkdown(markdown2);
|
|
1598
|
+
return renderTokens(tokens);
|
|
1599
|
+
}
|
|
1600
|
+
function renderHtmlString(html) {
|
|
1601
|
+
let processedContent = html;
|
|
1602
|
+
processedContent = processedContent.replace(
|
|
1603
|
+
/<style(?:\s+[^>]*)?>([\s\S]*?)<\/style>/gi,
|
|
1604
|
+
(_match, cssContent) => {
|
|
1605
|
+
const styleEl = document.createElement("style");
|
|
1606
|
+
styleEl.setAttribute("data-nr-global", "");
|
|
1607
|
+
styleEl.textContent = cssContent;
|
|
1608
|
+
document.head.appendChild(styleEl);
|
|
1609
|
+
return "";
|
|
1610
|
+
}
|
|
1611
|
+
);
|
|
1612
|
+
const wrapper = document.createElement("div");
|
|
1613
|
+
wrapper.className = "nr-raw-html";
|
|
1614
|
+
wrapper.innerHTML = processedContent;
|
|
1615
|
+
const scripts = wrapper.querySelectorAll("script");
|
|
1616
|
+
scripts.forEach((oldScript) => {
|
|
1617
|
+
const newScript = document.createElement("script");
|
|
1618
|
+
Array.from(oldScript.attributes).forEach(
|
|
1619
|
+
(attr) => newScript.setAttribute(attr.name, attr.value)
|
|
1620
|
+
);
|
|
1621
|
+
newScript.textContent = oldScript.textContent;
|
|
1622
|
+
oldScript.parentNode?.replaceChild(newScript, oldScript);
|
|
1623
|
+
});
|
|
1624
|
+
return wrapper;
|
|
1625
|
+
}
|
|
1626
|
+
function renderTokensInner(tokens, ctx) {
|
|
1627
|
+
const container = document.createElement("div");
|
|
1628
|
+
container.appendChild(processElements(tokens, ctx, tokens));
|
|
1629
|
+
return container;
|
|
1630
|
+
}
|
|
1631
|
+
function processElements(elements, ctx, allElements) {
|
|
1632
|
+
const fragment = document.createDocumentFragment();
|
|
1633
|
+
let i = 0;
|
|
1634
|
+
while (i < elements.length) {
|
|
1635
|
+
const el = elements[i];
|
|
1636
|
+
if (el.type === "directive" && ["card", "card-m", "card-b"].includes(el.directiveType)) {
|
|
1637
|
+
const cards = [];
|
|
1638
|
+
while (i < elements.length && elements[i].type === "directive" && ["card", "card-m", "card-b"].includes(elements[i].directiveType)) {
|
|
1639
|
+
cards.push(elements[i]);
|
|
1640
|
+
i++;
|
|
1641
|
+
}
|
|
1642
|
+
if (cards.length === 1 || cards[0].props?.batch === "off") {
|
|
1643
|
+
for (const card of cards) {
|
|
1644
|
+
const rendered = renderElement(card, ctx, allElements);
|
|
1645
|
+
if (rendered) fragment.appendChild(rendered);
|
|
1646
|
+
}
|
|
1647
|
+
} else {
|
|
1648
|
+
const grid = document.createElement("div");
|
|
1649
|
+
grid.className = "nr-card-grid";
|
|
1650
|
+
for (const card of cards) {
|
|
1651
|
+
const rendered = renderElement(card, ctx, allElements);
|
|
1652
|
+
if (rendered) grid.appendChild(rendered);
|
|
1653
|
+
}
|
|
1654
|
+
fragment.appendChild(grid);
|
|
1655
|
+
}
|
|
1656
|
+
} else {
|
|
1657
|
+
const rendered = renderElement(el, ctx, allElements);
|
|
1658
|
+
if (rendered) fragment.appendChild(rendered);
|
|
1659
|
+
i++;
|
|
1660
|
+
}
|
|
1661
|
+
}
|
|
1662
|
+
return fragment;
|
|
1663
|
+
}
|
|
1664
|
+
function renderElement(element, ctx, allElements) {
|
|
1665
|
+
switch (element.type) {
|
|
1666
|
+
case "header": {
|
|
1667
|
+
const tag = `h${element.level}`;
|
|
1668
|
+
let text = element.text;
|
|
1669
|
+
const alignCenter = text.match(/^->\s*(.+?)\s*<-\s*$/);
|
|
1670
|
+
const alignRight = text.match(/^->\s*(.+?)\s*->\s*$/);
|
|
1671
|
+
if (alignCenter) text = alignCenter[1];
|
|
1672
|
+
else if (alignRight) text = alignRight[1];
|
|
1673
|
+
const h = document.createElement(tag);
|
|
1674
|
+
h.id = element.id;
|
|
1675
|
+
let cls = `md-h${element.level}`;
|
|
1676
|
+
if (alignCenter) cls += " text-center";
|
|
1677
|
+
if (alignRight) cls += " text-right";
|
|
1678
|
+
if (element.classes) cls += ` ${element.classes}`;
|
|
1679
|
+
h.className = cls;
|
|
1680
|
+
h.appendChild(renderInline(text));
|
|
1681
|
+
return h;
|
|
1682
|
+
}
|
|
1683
|
+
case "paragraph": {
|
|
1684
|
+
const p = document.createElement("p");
|
|
1685
|
+
let cls = "md-p";
|
|
1686
|
+
if (element.classes) cls += ` ${element.classes}`;
|
|
1687
|
+
if (element.align) cls += ` text-${element.align}`;
|
|
1688
|
+
p.className = cls;
|
|
1689
|
+
if (element.id) p.id = element.id;
|
|
1690
|
+
const lines = element.content.split("\n");
|
|
1691
|
+
for (let li = 0; li < lines.length; li++) {
|
|
1692
|
+
const line = lines[li];
|
|
1693
|
+
const hardBreakMatch = line.match(/^(.*?)(\s{2,})$/);
|
|
1694
|
+
if (hardBreakMatch) {
|
|
1695
|
+
p.appendChild(renderInline(hardBreakMatch[1]));
|
|
1696
|
+
p.appendChild(document.createElement("br"));
|
|
1697
|
+
} else {
|
|
1698
|
+
p.appendChild(renderInline(line));
|
|
1699
|
+
if (li < lines.length - 1) {
|
|
1700
|
+
p.appendChild(document.createTextNode(" "));
|
|
1701
|
+
}
|
|
1702
|
+
}
|
|
1703
|
+
}
|
|
1704
|
+
return p;
|
|
1705
|
+
}
|
|
1706
|
+
case "codeblock":
|
|
1707
|
+
return createCodeBlock(element.content, element.language, element.title);
|
|
1708
|
+
case "directive":
|
|
1709
|
+
return renderDirective(element, ctx, allElements);
|
|
1710
|
+
case "html": {
|
|
1711
|
+
const el = element;
|
|
1712
|
+
return renderHtmlString(el.content);
|
|
1713
|
+
}
|
|
1714
|
+
case "html-block": {
|
|
1715
|
+
const htmlBlock = element;
|
|
1716
|
+
const rawProps = parseHtmlAttrs(htmlBlock.attrs);
|
|
1717
|
+
const el = document.createElement(htmlBlock.tag);
|
|
1718
|
+
for (const [key, value] of Object.entries(rawProps)) {
|
|
1719
|
+
if (key === "style" && typeof value === "object") {
|
|
1720
|
+
for (const [prop, val] of Object.entries(value)) {
|
|
1721
|
+
el.style.setProperty(prop, String(val));
|
|
1722
|
+
}
|
|
1723
|
+
} else if (value === true) {
|
|
1724
|
+
el.setAttribute(key, "");
|
|
1725
|
+
} else {
|
|
1726
|
+
el.setAttribute(key, String(value));
|
|
1727
|
+
}
|
|
1728
|
+
}
|
|
1729
|
+
const childFrag = processElements(htmlBlock.children, ctx, allElements);
|
|
1730
|
+
el.appendChild(childFrag);
|
|
1731
|
+
return el;
|
|
1732
|
+
}
|
|
1733
|
+
case "image": {
|
|
1734
|
+
const img = document.createElement("img");
|
|
1735
|
+
img.src = element.src;
|
|
1736
|
+
img.alt = element.alt;
|
|
1737
|
+
img.className = "nr-image";
|
|
1738
|
+
if (element.style) {
|
|
1739
|
+
for (const [key, value] of Object.entries(element.style)) {
|
|
1740
|
+
img.style.setProperty(key, String(value));
|
|
1741
|
+
}
|
|
1742
|
+
}
|
|
1743
|
+
return img;
|
|
1744
|
+
}
|
|
1745
|
+
case "table":
|
|
1746
|
+
return createTable(element.content, renderInline);
|
|
1747
|
+
case "list":
|
|
1748
|
+
return createList(element.content, renderInline);
|
|
1749
|
+
case "blockquote":
|
|
1750
|
+
return createBlockquote(element.content, element.classes, renderInline);
|
|
1751
|
+
case "hr": {
|
|
1752
|
+
const hr = document.createElement("hr");
|
|
1753
|
+
hr.className = "nr-hr";
|
|
1754
|
+
return hr;
|
|
1755
|
+
}
|
|
1756
|
+
case "toc": {
|
|
1757
|
+
const headers = allElements.filter((e) => e.type === "header");
|
|
1758
|
+
return createTOC(headers.map((h) => ({ level: h.level, text: h.text, id: h.id })), renderInline);
|
|
1759
|
+
}
|
|
1760
|
+
default:
|
|
1761
|
+
return null;
|
|
1762
|
+
}
|
|
1763
|
+
}
|
|
1764
|
+
function renderDirective(element, ctx, allElements) {
|
|
1573
1765
|
const { directiveType, props, slots, scopeId } = element;
|
|
1574
|
-
const
|
|
1766
|
+
const renderer = directives_default[directiveType];
|
|
1575
1767
|
const renderSlot = (name) => {
|
|
1768
|
+
const frag = document.createDocumentFragment();
|
|
1576
1769
|
const slotContent = slots[name];
|
|
1577
|
-
if (!slotContent) return
|
|
1578
|
-
const
|
|
1579
|
-
|
|
1770
|
+
if (!slotContent) return frag;
|
|
1771
|
+
const tokens = ctx.parseMarkdown(slotContent);
|
|
1772
|
+
frag.appendChild(ctx.renderElements(tokens));
|
|
1773
|
+
return frag;
|
|
1580
1774
|
};
|
|
1581
1775
|
const directiveProps = {
|
|
1582
1776
|
directiveType,
|
|
1583
1777
|
props,
|
|
1584
1778
|
slots,
|
|
1585
1779
|
renderSlot,
|
|
1586
|
-
context,
|
|
1587
|
-
index,
|
|
1588
|
-
allElements
|
|
1780
|
+
context: ctx,
|
|
1781
|
+
index: 0,
|
|
1782
|
+
allElements,
|
|
1783
|
+
renderInline,
|
|
1784
|
+
renderMarkdown: ctx.renderMarkdown
|
|
1589
1785
|
};
|
|
1590
|
-
if (
|
|
1591
|
-
return
|
|
1786
|
+
if (renderer) {
|
|
1787
|
+
return renderer(directiveProps);
|
|
1592
1788
|
}
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
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;
|
|
1789
|
+
const fallback = document.createElement("div");
|
|
1790
|
+
fallback.className = "nr-unknown-directive";
|
|
1791
|
+
fallback.appendChild(renderSlot("default"));
|
|
1792
|
+
return fallback;
|
|
1793
|
+
}
|
|
1637
1794
|
|
|
1638
1795
|
// react/CustomMarkdownRenderer.tsx
|
|
1639
|
-
var
|
|
1640
|
-
var CustomMarkdownRenderer = ({ content
|
|
1641
|
-
const
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1796
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
1797
|
+
var CustomMarkdownRenderer = ({ content }) => {
|
|
1798
|
+
const containerRef = (0, import_react3.useRef)(null);
|
|
1799
|
+
(0, import_react3.useEffect)(() => {
|
|
1800
|
+
const container = containerRef.current;
|
|
1801
|
+
if (!container) return;
|
|
1802
|
+
container.replaceChildren();
|
|
1803
|
+
container.appendChild(renderMarkdownString(content));
|
|
1804
|
+
scanTailwindCDN();
|
|
1648
1805
|
const handleHashChange = () => {
|
|
1649
1806
|
const hash = window.location.hash;
|
|
1650
1807
|
if (hash) {
|
|
1651
1808
|
const parts = hash.split("#");
|
|
1652
|
-
|
|
1653
|
-
scrollToId(id);
|
|
1809
|
+
scrollToId(parts[parts.length - 1]);
|
|
1654
1810
|
}
|
|
1655
1811
|
};
|
|
1656
1812
|
handleHashChange();
|
|
1657
1813
|
window.addEventListener("hashchange", handleHashChange);
|
|
1658
1814
|
return () => window.removeEventListener("hashchange", handleHashChange);
|
|
1659
|
-
}, [
|
|
1660
|
-
|
|
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) });
|
|
1815
|
+
}, [content]);
|
|
1816
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { ref: containerRef });
|
|
1859
1817
|
};
|
|
1860
1818
|
var CustomMarkdownRenderer_default = CustomMarkdownRenderer;
|
|
1861
1819
|
|
|
1862
1820
|
// react/NReditor.tsx
|
|
1863
|
-
var
|
|
1821
|
+
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
1864
1822
|
var customSyntaxHighlighting = import_language2.HighlightStyle.define([
|
|
1865
1823
|
{ tag: import_highlight2.tags.heading, fontWeight: "bold", color: "var(--tc-heading, #e2e8f0)" },
|
|
1866
1824
|
{ tag: import_highlight2.tags.quote, color: "var(--tc-quote, #94a3b8)", fontStyle: "italic" },
|
|
@@ -2313,9 +2271,9 @@ var NReditor = ({
|
|
|
2313
2271
|
onGuide,
|
|
2314
2272
|
onConfig
|
|
2315
2273
|
}) => {
|
|
2316
|
-
const editorRef = (0,
|
|
2317
|
-
const [isAllFolded, setIsAllFolded] = (0,
|
|
2318
|
-
const [editorMode, setEditorMode] = (0,
|
|
2274
|
+
const editorRef = (0, import_react4.useRef)(null);
|
|
2275
|
+
const [isAllFolded, setIsAllFolded] = (0, import_react4.useState)(false);
|
|
2276
|
+
const [editorMode, setEditorMode] = (0, import_react4.useState)("split");
|
|
2319
2277
|
const debouncedContent = useDebounce(value, debounceMs);
|
|
2320
2278
|
useLazyTailwindCDN(tailwindCDN);
|
|
2321
2279
|
const handleToggleFold = () => {
|
|
@@ -2328,7 +2286,7 @@ var NReditor = ({
|
|
|
2328
2286
|
setIsAllFolded(true);
|
|
2329
2287
|
}
|
|
2330
2288
|
};
|
|
2331
|
-
const extensions =
|
|
2289
|
+
const extensions = import_react4.default.useMemo(
|
|
2332
2290
|
() => [
|
|
2333
2291
|
customStreamParserV2,
|
|
2334
2292
|
(0, import_view.lineNumbers)(),
|
|
@@ -2348,7 +2306,6 @@ var NReditor = ({
|
|
|
2348
2306
|
customEditorTheme,
|
|
2349
2307
|
(0, import_language2.syntaxHighlighting)(customSyntaxHighlighting),
|
|
2350
2308
|
import_view.EditorView.lineWrapping,
|
|
2351
|
-
(0, import_view.scrollPastEnd)(),
|
|
2352
2309
|
import_view.keymap.of([
|
|
2353
2310
|
{ key: "Ctrl-Shift-[", run: import_language2.foldAll },
|
|
2354
2311
|
{ key: "Ctrl-Shift-]", run: import_language2.unfoldAll }
|
|
@@ -2365,74 +2322,73 @@ var NReditor = ({
|
|
|
2365
2322
|
{ key: "split", icon: "vertical_split", label: "Split" },
|
|
2366
2323
|
{ key: "preview", icon: "visibility", label: "Preview" }
|
|
2367
2324
|
];
|
|
2368
|
-
return /* @__PURE__ */ (0,
|
|
2369
|
-
/* @__PURE__ */ (0,
|
|
2370
|
-
/* @__PURE__ */ (0,
|
|
2371
|
-
/* @__PURE__ */ (0,
|
|
2325
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: `nr-editor ${className || ""}`, children: [
|
|
2326
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "nr-editor-toolbar", children: [
|
|
2327
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "nr-editor-toolbar-left", children: [
|
|
2328
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
2372
2329
|
"button",
|
|
2373
2330
|
{
|
|
2374
2331
|
onClick: handleToggleFold,
|
|
2375
2332
|
className: "nr-toolbar-btn nr-toolbar-btn-fold",
|
|
2376
2333
|
title: isAllFolded ? "Expandir todo" : "Colapsar todo",
|
|
2377
2334
|
"aria-label": isAllFolded ? "Expandir todo" : "Colapsar todo",
|
|
2378
|
-
children: /* @__PURE__ */ (0,
|
|
2335
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "material-icons-round", children: isAllFolded ? "unfold_more" : "unfold_less" })
|
|
2379
2336
|
}
|
|
2380
2337
|
),
|
|
2381
|
-
/* @__PURE__ */ (0,
|
|
2382
|
-
/* @__PURE__ */ (0,
|
|
2338
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "nr-toolbar-divider" }),
|
|
2339
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "nr-toolbar-mode-group", children: modeButtons.map((btn) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
2383
2340
|
"button",
|
|
2384
2341
|
{
|
|
2385
2342
|
onClick: () => setEditorMode(btn.key),
|
|
2386
2343
|
className: `nr-toolbar-btn nr-toolbar-btn-mode ${editorMode === btn.key ? "nr-toolbar-btn-mode--active" : ""} ${btn.key === "split" ? "nr-toolbar-btn-split" : ""}`,
|
|
2387
2344
|
title: btn.label,
|
|
2388
2345
|
children: [
|
|
2389
|
-
/* @__PURE__ */ (0,
|
|
2390
|
-
/* @__PURE__ */ (0,
|
|
2346
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "material-icons-round", children: btn.icon }),
|
|
2347
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "nr-toolbar-label", children: btn.label })
|
|
2391
2348
|
]
|
|
2392
2349
|
},
|
|
2393
2350
|
btn.key
|
|
2394
2351
|
)) })
|
|
2395
2352
|
] }),
|
|
2396
|
-
/* @__PURE__ */ (0,
|
|
2397
|
-
onGuide && /* @__PURE__ */ (0,
|
|
2353
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "nr-editor-toolbar-right", children: [
|
|
2354
|
+
onGuide && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
2398
2355
|
"button",
|
|
2399
2356
|
{
|
|
2400
2357
|
onClick: onGuide,
|
|
2401
2358
|
className: "nr-toolbar-btn nr-toolbar-btn-sm nr-toolbar-btn-guide",
|
|
2402
2359
|
title: "Gu\xEDa de sintaxis",
|
|
2403
2360
|
children: [
|
|
2404
|
-
/* @__PURE__ */ (0,
|
|
2405
|
-
/* @__PURE__ */ (0,
|
|
2361
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "material-icons-round", children: "menu_book" }),
|
|
2362
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "nr-toolbar-label", children: "Gu\xEDa" })
|
|
2406
2363
|
]
|
|
2407
2364
|
}
|
|
2408
2365
|
),
|
|
2409
|
-
onGuide && onConfig && /* @__PURE__ */ (0,
|
|
2410
|
-
onConfig && /* @__PURE__ */ (0,
|
|
2366
|
+
onGuide && onConfig && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "nr-toolbar-divider" }),
|
|
2367
|
+
onConfig && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
2411
2368
|
"button",
|
|
2412
2369
|
{
|
|
2413
2370
|
onClick: onConfig,
|
|
2414
2371
|
className: "nr-toolbar-btn nr-toolbar-btn-sm nr-toolbar-btn-config",
|
|
2415
2372
|
title: "Configurar tema y metadata",
|
|
2416
2373
|
children: [
|
|
2417
|
-
/* @__PURE__ */ (0,
|
|
2418
|
-
/* @__PURE__ */ (0,
|
|
2374
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "material-icons-round", children: "tune" }),
|
|
2375
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "nr-toolbar-label", children: "Configurar" })
|
|
2419
2376
|
]
|
|
2420
2377
|
}
|
|
2421
2378
|
)
|
|
2422
2379
|
] })
|
|
2423
2380
|
] }),
|
|
2424
|
-
/* @__PURE__ */ (0,
|
|
2425
|
-
(editorMode === "editor" || editorMode === "split") && /* @__PURE__ */ (0,
|
|
2381
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "nr-editor-body", children: [
|
|
2382
|
+
(editorMode === "editor" || editorMode === "split") && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
2426
2383
|
"div",
|
|
2427
2384
|
{
|
|
2428
2385
|
className: `nr-editor-pane ${editorMode === "split" ? "nr-editor-pane--half" : ""}`,
|
|
2429
|
-
children: /* @__PURE__ */ (0,
|
|
2386
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
2430
2387
|
import_react_codemirror.default,
|
|
2431
2388
|
{
|
|
2432
2389
|
value,
|
|
2433
2390
|
onChange,
|
|
2434
|
-
|
|
2435
|
-
height: "100%",
|
|
2391
|
+
height: "auto",
|
|
2436
2392
|
onCreateEditor: (view) => {
|
|
2437
2393
|
editorRef.current = view;
|
|
2438
2394
|
},
|
|
@@ -2445,11 +2401,11 @@ var NReditor = ({
|
|
|
2445
2401
|
)
|
|
2446
2402
|
}
|
|
2447
2403
|
),
|
|
2448
|
-
(editorMode === "preview" || editorMode === "split") && /* @__PURE__ */ (0,
|
|
2404
|
+
(editorMode === "preview" || editorMode === "split") && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
2449
2405
|
"div",
|
|
2450
2406
|
{
|
|
2451
2407
|
className: `nr-editor-preview ${editorMode === "split" ? "nr-editor-preview--half" : ""}`,
|
|
2452
|
-
children: /* @__PURE__ */ (0,
|
|
2408
|
+
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
2409
|
}
|
|
2454
2410
|
)
|
|
2455
2411
|
] })
|