@leelaa/vitepress-plugin-extended
Version:
VitePress 增强插件集合,提供多种高级功能和组件
632 lines (627 loc) • 31.6 kB
JavaScript
import { defineComponent, useCssVars, ref, watch, nextTick, onMounted, onUnmounted, createElementBlock, openBlock, normalizeClass, createCommentVNode, createElementVNode, Fragment, renderList, createTextVNode, toDisplayString, withDirectives, vShow } from 'vue';
import * as d3 from 'd3';
import { d as downloadFunc } from './utils-B3XjiJac.js';
import { s as styleInject } from './style-inject.es-tgCJW-Cu.js';
const _hoisted_1 = { class: "toolbar" };
const _hoisted_2 = { class: "toolbar-left" };
const _hoisted_3 = ["onClick"];
const _hoisted_4 = {
key: 0,
class: "icon",
viewBox: "0 0 24 24",
fill: "currentColor"
};
const _hoisted_5 = {
key: 1,
class: "icon",
viewBox: "0 0 24 24",
fill: "currentColor"
};
const _hoisted_6 = { class: "toolbar-right" };
const _hoisted_7 = { class: "control-group" };
const _hoisted_8 = ["title"];
const _hoisted_9 = {
key: 0,
class: "icon",
viewBox: "0 0 24 24",
fill: "currentColor"
};
const _hoisted_10 = {
key: 1,
class: "icon",
viewBox: "0 0 24 24",
fill: "currentColor"
};
const _hoisted_11 = {
key: 1,
class: "control-group"
};
const _hoisted_12 = ["title"];
const _hoisted_13 = {
key: 0,
class: "icon",
viewBox: "0 0 24 24",
fill: "currentColor"
};
const _hoisted_14 = {
key: 1,
class: "icon",
viewBox: "0 0 24 24",
fill: "currentColor"
};
const _hoisted_15 = { class: "content-area" };
const _hoisted_16 = { class: "code-panel" };
const _hoisted_17 = { class: "code-viewer" };
const _hoisted_18 = { class: "code-content" };
const _hoisted_19 = { class: "preview-panel" };
const _hoisted_20 = {
key: 0,
class: "loading-overlay"
};
const _hoisted_21 = {
key: 1,
class: "empty-state"
};
var script = /* @__PURE__ */ defineComponent({
__name: "index",
props: {
content: { type: String, required: false, default: "" },
height: { type: String, required: false, default: "600px" },
theme: { type: String, required: false, default: "light" }
},
setup(__props) {
useCssVars((_ctx) => ({
"5fd93944-height": _ctx.height
}));
const props = __props;
const activeTab = ref("preview");
const markdownContent = ref(props.content);
const markmapContainer = ref();
const isLoading = ref(false);
const isFullscreen = ref(false);
const isDragging = ref(false);
const dragStart = ref({ x: 0, y: 0 });
const currentTransform = ref({ x: 0, y: 0, scale: 1 });
let svg = null;
let zoomBehavior = null;
const tabs = [
{ key: "preview", label: "\u9884\u89C8" },
{ key: "code", label: "\u4EE3\u7801" }
];
const parseMarkdown = (content) => {
const lines = content.split("\n").filter((line) => line.trim());
const root = { name: "Root", children: [], level: 0 };
const stack = [root];
lines.forEach((line) => {
const match = line.match(/^(#+)\s*(.+)$/);
if (match) {
const level = match[1].length;
const text = match[2].trim();
const node = { name: text, children: [], level };
while (stack.length > 1 && stack[stack.length - 1].level >= level) {
stack.pop();
}
stack[stack.length - 1].children.push(node);
stack.push(node);
} else if (line.trim().startsWith("-")) {
const text = line.trim().substring(1).trim();
const node = {
name: text,
children: [],
level: stack[stack.length - 1].level + 1
};
stack[stack.length - 1].children.push(node);
}
});
return root.children[0] || { name: "\u7A7A\u767D\u601D\u7EF4\u5BFC\u56FE", children: [] };
};
const renderMindmap = () => {
if (!markmapContainer.value || !markdownContent.value.trim()) return;
isLoading.value = true;
try {
const container = markmapContainer.value;
container.innerHTML = "";
const width = container.clientWidth;
const height = container.clientHeight;
const treeData = parseMarkdown(markdownContent.value);
svg = d3.select(container).append("svg").attr("width", width).attr("height", height);
const g = svg.append("g");
zoomBehavior = d3.zoom().scaleExtent([0.1, 3]).filter((event) => {
return event.type !== "wheel";
}).on("zoom", (event) => {
if (!isNaN(event.transform.x) && !isNaN(event.transform.y) && !isNaN(event.transform.k)) {
g.attr("transform", event.transform);
currentTransform.value = {
x: event.transform.x,
y: event.transform.y,
scale: event.transform.k
};
}
});
svg.call(zoomBehavior);
const tree = d3.tree().size([height - 100, width - 200]);
const hierarchy = d3.hierarchy(treeData);
const treeWithPosition = tree(hierarchy);
const colors = [
"#3B82F6",
"#EF4444",
"#10B981",
"#F59E0B",
"#8B5CF6",
"#EC4899"
];
g.selectAll(".link").data(treeWithPosition.links()).enter().append("path").attr("class", "link").attr(
"d",
d3.linkHorizontal().x((d) => d.y + 100).y((d) => d.x + 50)
).style("fill", "none").style("stroke", "#94a3b8").style("stroke-width", 2);
const nodes = g.selectAll(".node").data(treeWithPosition.descendants()).enter().append("g").attr("class", "node").attr("transform", (d) => `translate(${d.y + 100},${d.x + 50})`).style("cursor", "pointer");
nodes.append("circle").attr("r", 8).style("fill", (d) => colors[d.depth % colors.length]).style("stroke", "#fff").style("stroke-width", 2);
nodes.append("text").attr("dx", (d) => d.children ? -15 : 15).attr("dy", 5).attr("text-anchor", (d) => d.children ? "end" : "start").text((d) => d.data.name).style("font-size", "14px").style("font-family", "Inter, sans-serif").style("fill", "#374151");
nodes.on("mouseenter", function() {
d3.select(this).select("circle").transition().duration(200).attr("r", 12);
}).on("mouseleave", function() {
d3.select(this).select("circle").transition().duration(200).attr("r", 8);
});
const bounds = g.node()?.getBBox();
if (bounds) {
const scale = Math.min(width / bounds.width, height / bounds.height) * 0.8;
const translateX = (width - bounds.width * scale) / 2 - bounds.x * scale;
const translateY = (height - bounds.height * scale) / 2 - bounds.y * scale;
svg.call(
zoomBehavior.transform,
d3.zoomIdentity.translate(translateX, translateY).scale(scale)
);
}
} catch (error) {
console.error("Error rendering mindmap:", error);
} finally {
isLoading.value = false;
}
};
const zoomIn = () => {
if (svg && zoomBehavior) {
svg.transition().call(zoomBehavior.scaleBy, 1.2);
}
};
const zoomOut = () => {
if (svg && zoomBehavior) {
svg.transition().call(zoomBehavior.scaleBy, 0.8);
}
};
const resetView = () => {
if (svg && zoomBehavior) {
svg.transition().call(zoomBehavior.transform, d3.zoomIdentity);
}
currentTransform.value = { x: 0, y: 0, scale: 1 };
};
const downloadSVG = () => {
if (!markmapContainer.value) return;
const svgElement = markmapContainer.value.querySelector("svg");
if (!svgElement) return;
const serializer = new XMLSerializer();
const svgString = serializer.serializeToString(svgElement);
const blob = new Blob([svgString], { type: "image/svg+xml" });
downloadFunc(URL.createObjectURL(blob), "mindmap.svg");
};
const downloadMarkdown = () => {
const blob = new Blob([markdownContent.value], { type: "text/markdown" });
downloadFunc(URL.createObjectURL(blob), "mindmap.md");
};
const copyCode = async () => {
try {
await navigator.clipboard.writeText(markdownContent.value);
} catch (err) {
console.error("\u590D\u5236\u5931\u8D25:", err);
}
};
const toggleFullscreen = () => {
isFullscreen.value = !isFullscreen.value;
nextTick(() => {
setTimeout(() => {
if (activeTab.value === "preview") {
renderMindmap();
}
}, 100);
});
};
const exitFullscreen = () => {
isFullscreen.value = false;
nextTick(() => {
setTimeout(() => {
if (activeTab.value === "preview") {
renderMindmap();
}
}, 100);
});
};
const handleMouseDown = (e) => {
if (e.button === 0) {
isDragging.value = true;
dragStart.value = { x: e.clientX, y: e.clientY };
e.preventDefault();
}
};
const handleMouseMove = (e) => {
if (isDragging.value && svg && zoomBehavior) {
const deltaX = e.clientX - dragStart.value.x;
const deltaY = e.clientY - dragStart.value.y;
const currentTransformValue = d3.zoomTransform(svg.node());
const newTransform = currentTransformValue.translate(
deltaX / currentTransformValue.k,
deltaY / currentTransformValue.k
);
svg.call(zoomBehavior.transform, newTransform);
dragStart.value = { x: e.clientX, y: e.clientY };
}
};
const handleMouseUp = () => {
isDragging.value = false;
};
const handleResize = () => {
if (activeTab.value === "preview") {
nextTick(() => {
setTimeout(() => {
renderMindmap();
}, 100);
});
}
};
watch(activeTab, (newTab) => {
if (newTab === "preview") {
nextTick(() => {
renderMindmap();
});
}
});
onMounted(() => {
renderMindmap();
window.addEventListener("resize", handleResize);
});
onUnmounted(() => {
window.removeEventListener("resize", handleResize);
});
return (_ctx, _cache) => {
return openBlock(), createElementBlock(
"div",
{
class: normalizeClass(["markmap-container", { fullscreen: isFullscreen.value }])
},
[
createCommentVNode(" Header Toolbar "),
createElementVNode("div", _hoisted_1, [
createElementVNode("div", _hoisted_2, [
(openBlock(), createElementBlock(
Fragment,
null,
renderList(tabs, (tab) => {
return createElementVNode("button", {
key: tab.key,
onClick: ($event) => activeTab.value = tab.key,
class: normalizeClass(["tab-button", { active: activeTab.value === tab.key }])
}, [
tab.key === "preview" ? (openBlock(), createElementBlock("svg", _hoisted_4, [..._cache[0] || (_cache[0] = [
createElementVNode(
"path",
{ d: "M12 4.5C7 4.5 2.73 7.61 1 12c1.73 4.39 6 7.5 11 7.5s9.27-3.11 11-7.5c-1.73-4.39-6-7.5-11-7.5zM12 17c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5zm0-8c-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3-1.34-3-3-3z" },
null,
-1
/* HOISTED */
)
])])) : createCommentVNode("v-if", true),
tab.key === "code" ? (openBlock(), createElementBlock("svg", _hoisted_5, [..._cache[1] || (_cache[1] = [
createElementVNode(
"path",
{ d: "M9.4 16.6L4.8 12l4.6-4.6L8 6l-6 6 6 6 1.4-1.4zm5.2 0L19.2 12l-4.6-4.6L16 6l6 6-6 6-1.4-1.4z" },
null,
-1
/* HOISTED */
)
])])) : createCommentVNode("v-if", true),
createTextVNode(
" " + toDisplayString(tab.label),
1
/* TEXT */
)
], 10, _hoisted_3);
}),
64
/* STABLE_FRAGMENT */
))
]),
createElementVNode("div", _hoisted_6, [
createCommentVNode(" \u9884\u89C8\u6A21\u5F0F\u7684\u5DE5\u5177\u680F "),
activeTab.value === "preview" ? (openBlock(), createElementBlock(
Fragment,
{ key: 0 },
[
createElementVNode("div", { class: "control-group" }, [
createElementVNode("button", {
onClick: zoomIn,
class: "control-button",
title: "\u653E\u5927"
}, _cache[2] || (_cache[2] = [
createElementVNode(
"svg",
{
class: "icon",
viewBox: "0 0 24 24",
fill: "currentColor"
},
[
createElementVNode("path", { d: "M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z" }),
createElementVNode("path", { d: "M12 10h-2v2H9v-2H7V9h2V7h1v2h2v1z" })
],
-1
/* HOISTED */
)
])),
createElementVNode("button", {
onClick: zoomOut,
class: "control-button",
title: "\u7F29\u5C0F"
}, _cache[3] || (_cache[3] = [
createElementVNode(
"svg",
{
class: "icon",
viewBox: "0 0 24 24",
fill: "currentColor"
},
[
createElementVNode("path", { d: "M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z" }),
createElementVNode("path", { d: "M7 9h5v1H7z" })
],
-1
/* HOISTED */
)
])),
createElementVNode("button", {
onClick: resetView,
class: "control-button",
title: "\u91CD\u7F6E\u89C6\u56FE"
}, _cache[4] || (_cache[4] = [
createElementVNode(
"svg",
{
class: "icon",
viewBox: "0 0 24 24",
fill: "currentColor"
},
[
createElementVNode("path", { d: "M17.65 6.35C16.2 4.9 14.21 4 12 4c-4.42 0-7.99 3.58-7.99 8s3.57 8 7.99 8c3.73 0 6.84-2.55 7.73-6h-2.08c-.82 2.33-3.04 4-5.65 4-3.31 0-6-2.69-6-6s2.69-6 6-6c1.66 0 3.14.69 4.22 1.78L13 11h7V4l-2.35 2.35z" })
],
-1
/* HOISTED */
)
]))
]),
createElementVNode("div", _hoisted_7, [
createElementVNode("button", {
onClick: downloadSVG,
class: "control-button",
title: "\u4E0B\u8F7DSVG"
}, _cache[5] || (_cache[5] = [
createElementVNode(
"svg",
{
class: "icon",
viewBox: "0 0 24 24",
fill: "currentColor"
},
[
createElementVNode("path", { d: "M19 9h-4V3H9v6H5l7 7 7-7zM5 18v2h14v-2H5z" })
],
-1
/* HOISTED */
)
])),
createElementVNode("button", {
onClick: toggleFullscreen,
class: "control-button",
title: isFullscreen.value ? "\u9000\u51FA\u5168\u5C4F" : "\u5168\u5C4F"
}, [
!isFullscreen.value ? (openBlock(), createElementBlock("svg", _hoisted_9, _cache[6] || (_cache[6] = [
createElementVNode(
"path",
{ d: "M7 14H5v5h5v-2H7v-3zm-2-4h2V7h3V5H5v5zm12 7h-3v2h5v-5h-2v3zM14 5v2h3v3h2V5h-5z" },
null,
-1
/* HOISTED */
)
]))) : (openBlock(), createElementBlock("svg", _hoisted_10, _cache[7] || (_cache[7] = [
createElementVNode(
"path",
{ d: "M5 16h3v3h2v-5H5v2zm3-8H5v2h5V5H8v3zm6 11h2v-3h3v-2h-5v5zm2-11V5h-2v5h5V8h-3z" },
null,
-1
/* HOISTED */
)
])))
], 8, _hoisted_8)
])
],
64
/* STABLE_FRAGMENT */
)) : createCommentVNode("v-if", true),
createCommentVNode(" \u4EE3\u7801\u6A21\u5F0F\u7684\u5DE5\u5177\u680F "),
activeTab.value === "code" ? (openBlock(), createElementBlock("div", _hoisted_11, [
createElementVNode("button", {
onClick: copyCode,
class: "control-button",
title: "\u590D\u5236\u4EE3\u7801"
}, _cache[8] || (_cache[8] = [
createElementVNode(
"svg",
{
class: "icon",
viewBox: "0 0 24 24",
fill: "currentColor"
},
[
createElementVNode("path", { d: "M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z" })
],
-1
/* HOISTED */
)
])),
createElementVNode("button", {
onClick: downloadMarkdown,
class: "control-button",
title: "\u4E0B\u8F7DMarkdown"
}, _cache[9] || (_cache[9] = [
createElementVNode(
"svg",
{
class: "icon",
viewBox: "0 0 24 24",
fill: "currentColor"
},
[
createElementVNode("path", { d: "M19 9h-4V3H9v6H5l7 7 7-7zM5 18v2h14v-2H5z" })
],
-1
/* HOISTED */
)
])),
createElementVNode("button", {
onClick: toggleFullscreen,
class: "control-button",
title: isFullscreen.value ? "\u9000\u51FA\u5168\u5C4F" : "\u5168\u5C4F"
}, [
!isFullscreen.value ? (openBlock(), createElementBlock("svg", _hoisted_13, _cache[10] || (_cache[10] = [
createElementVNode(
"path",
{ d: "M7 14H5v5h5v-2H7v-3zm-2-4h2V7h3V5H5v5zm12 7h-3v2h5v-5h-2v3zM14 5v2h3v3h2V5h-5z" },
null,
-1
/* HOISTED */
)
]))) : (openBlock(), createElementBlock("svg", _hoisted_14, _cache[11] || (_cache[11] = [
createElementVNode(
"path",
{ d: "M5 16h3v3h2v-5H5v2zm3-8H5v2h5V5H8v3zm6 11h2v-3h3v-2h-5v5zm2-11V5h-2v5h5V8h-3z" },
null,
-1
/* HOISTED */
)
])))
], 8, _hoisted_12)
])) : createCommentVNode("v-if", true)
])
]),
createCommentVNode(" Content Area "),
createElementVNode("div", _hoisted_15, [
createCommentVNode(" Code Editor "),
withDirectives(createElementVNode(
"div",
_hoisted_16,
[
createElementVNode("div", _hoisted_17, [
createElementVNode(
"pre",
_hoisted_18,
toDisplayString(markdownContent.value),
1
/* TEXT */
)
])
],
512
/* NEED_PATCH */
), [
[vShow, activeTab.value === "code"]
]),
createCommentVNode(" MarkMap Preview "),
withDirectives(createElementVNode(
"div",
_hoisted_19,
[
createElementVNode(
"div",
{
ref_key: "markmapContainer",
ref: markmapContainer,
class: "markmap-svg-container",
onMousedown: handleMouseDown,
onMousemove: handleMouseMove,
onMouseup: handleMouseUp,
onMouseleave: handleMouseUp
},
null,
544
/* NEED_HYDRATION, NEED_PATCH */
),
createCommentVNode(" Loading State "),
isLoading.value ? (openBlock(), createElementBlock("div", _hoisted_20, _cache[12] || (_cache[12] = [
createElementVNode(
"div",
{ class: "loading-spinner" },
null,
-1
/* HOISTED */
),
createElementVNode(
"p",
null,
"\u6B63\u5728\u6E32\u67D3\u601D\u7EF4\u5BFC\u56FE...",
-1
/* HOISTED */
)
]))) : createCommentVNode("v-if", true),
createCommentVNode(" Empty State "),
!markdownContent.value.trim() && !isLoading.value ? (openBlock(), createElementBlock("div", _hoisted_21, _cache[13] || (_cache[13] = [
createElementVNode(
"div",
{ class: "empty-icon" },
"\u{1F5FA}\uFE0F",
-1
/* HOISTED */
),
createElementVNode(
"h3",
null,
"\u5F00\u59CB\u521B\u5EFA\u4F60\u7684\u601D\u7EF4\u5BFC\u56FE",
-1
/* HOISTED */
),
createElementVNode(
"p",
null,
"\u5207\u6362\u5230\u4EE3\u7801\u6A21\u5F0F\u67E5\u770BMarkdown\u6E90\u7801",
-1
/* HOISTED */
)
]))) : createCommentVNode("v-if", true)
],
512
/* NEED_PATCH */
), [
[vShow, activeTab.value === "preview"]
])
]),
createCommentVNode(" Fullscreen Overlay (when in fullscreen mode) "),
isFullscreen.value ? (openBlock(), createElementBlock("div", {
key: 0,
class: "fullscreen-overlay",
onClick: exitFullscreen
}, _cache[14] || (_cache[14] = [
createElementVNode(
"div",
{ class: "fullscreen-close-hint" },
"\u70B9\u51FB\u4EFB\u610F\u4F4D\u7F6E\u6216\u6309 ESC \u9000\u51FA\u5168\u5C4F",
-1
/* HOISTED */
)
]))) : createCommentVNode("v-if", true)
],
2
/* CLASS */
);
};
}
});
var css_248z = "\n.dark .content-area[data-v-5fd93944] {\r\n background: #99999980 !important;\n}\n.dark .code-viewer[data-v-5fd93944] {\r\n background: #99999980 !important;\n}\n.dark .control-button[data-v-5fd93944]:hover {\r\n background: #cccccc80 !important;\n}\n.dark .toolbar[data-v-5fd93944] {\r\n background: #1d1d1d !important;\n}\n.dark .control-group[data-v-5fd93944]{\r\n background-color: #000 !important;\n}\n.dark .toolbar .tab-button.active[data-v-5fd93944]{\r\n background-color: #dbeafe80 !important;\n}\n.dark .toolbar .tab-button[data-v-5fd93944]:hover{\r\n background-color: #9299a380 !important;\r\n color: white;\n}\n.markmap-container[data-v-5fd93944] {\r\n background: white;\r\n border-radius: 8px;\r\n box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1),\r\n 0 4px 6px -2px rgba(0, 0, 0, 0.05);\r\n border: 1px solid #e5e7eb;\r\n overflow: hidden;\r\n height: var(--5fd93944-height);\r\n transition: all 0.3s ease;\r\n position: relative;\n}\n.markmap-container.fullscreen[data-v-5fd93944] {\r\n position: fixed;\r\n top: 0;\r\n left: 0;\r\n right: 0;\r\n bottom: 0;\r\n z-index: 1000;\r\n border-radius: 0;\r\n height: 100vh !important;\r\n margin: 0;\r\n padding: 0;\n}\n.markmap-container.fullscreen .content-area[data-v-5fd93944] {\r\n background: white;\r\n height: calc(100vh - 60px);\r\n margin: 0;\r\n padding: 0;\n}\n.fullscreen-overlay[data-v-5fd93944] {\r\n position: absolute;\r\n top: 0;\r\n left: 0;\r\n right: 0;\r\n bottom: 0;\r\n background: rgba(0, 0, 0, 0.8);\r\n z-index: -1;\r\n cursor: pointer;\n}\n.fullscreen-close-hint[data-v-5fd93944] {\r\n position: absolute;\r\n top: 10px;\r\n right: 20px;\r\n color: white;\r\n font-size: 14px;\r\n padding: 8px 12px;\r\n background: rgba(0, 0, 0, 0.6);\r\n border-radius: 4px;\r\n z-index: 1001;\n}\n.toolbar[data-v-5fd93944] {\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n padding: 12px 16px;\r\n background: #f9fafb;\r\n border-bottom: 1px solid #e5e7eb;\r\n height: 60px;\n}\n.toolbar-left[data-v-5fd93944] {\r\n display: flex;\r\n gap: 4px;\n}\n.toolbar-right[data-v-5fd93944] {\r\n display: flex;\r\n align-items: center;\r\n gap: 12px;\n}\n.tab-button[data-v-5fd93944] {\r\n display: flex;\r\n align-items: center;\r\n gap: 8px;\r\n padding: 8px 16px;\r\n border-radius: 6px;\r\n font-size: 14px;\r\n font-weight: 500;\r\n transition: all 0.2s;\r\n color: #6b7280;\r\n background: transparent;\r\n border: none;\r\n cursor: pointer;\n}\n.tab-button[data-v-5fd93944]:hover {\r\n color: #374151;\r\n background: white;\n}\n.tab-button.active[data-v-5fd93944] {\r\n background: #dbeafe;\r\n color: #1d4ed8;\r\n box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);\n}\n.control-group[data-v-5fd93944] {\r\n display: flex;\r\n align-items: center;\r\n background: white;\r\n border-radius: 6px;\r\n box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);\r\n border: 1px solid #e5e7eb;\n}\n.control-button[data-v-5fd93944] {\r\n padding: 8px;\r\n background: transparent;\r\n border: none;\r\n color: #6b7280;\r\n cursor: pointer;\r\n transition: all 0.2s;\r\n border-right: 1px solid #e5e7eb;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\n}\n.control-button[data-v-5fd93944]:last-child {\r\n border-right: none;\n}\n.control-button[data-v-5fd93944]:first-child {\r\n border-top-left-radius: 6px;\r\n border-bottom-left-radius: 6px;\n}\n.control-button[data-v-5fd93944]:last-child {\r\n border-top-right-radius: 6px;\r\n border-bottom-right-radius: 6px;\n}\n.control-button[data-v-5fd93944]:hover {\r\n background: #f9fafb;\r\n color: #374151;\n}\n.icon[data-v-5fd93944] {\r\n width: 16px;\r\n height: 16px;\n}\n.content-area[data-v-5fd93944] {\r\n flex: 1;\r\n position: relative;\r\n height: calc(100% - 60px);\n}\n.code-panel[data-v-5fd93944] {\r\n height: 100%;\r\n overflow: hidden;\n}\n.code-viewer[data-v-5fd93944] {\r\n height: 100%;\r\n overflow: auto;\r\n background: #f9fafb;\n}\n.code-content[data-v-5fd93944] {\r\n width: 100%;\r\n height: 100%;\r\n margin: 0;\r\n padding: 16px;\r\n font-family: \"Fira Code\", \"Monaco\", \"Consolas\", monospace;\r\n font-size: 14px;\r\n color: #374151;\r\n line-height: 1.6;\r\n white-space: pre-wrap;\r\n background: transparent;\r\n border: none;\r\n outline: none;\n}\n.preview-panel[data-v-5fd93944] {\r\n height: 100%;\r\n position: relative;\n}\n.markmap-svg-container[data-v-5fd93944] {\r\n width: 100%;\r\n height: 100%;\r\n cursor: grab;\n}\n.markmap-svg-container[data-v-5fd93944]:active {\r\n cursor: grabbing;\n}\n.loading-overlay[data-v-5fd93944] {\r\n position: absolute;\r\n top: 0;\r\n left: 0;\r\n right: 0;\r\n bottom: 0;\r\n display: flex;\r\n flex-direction: column;\r\n align-items: center;\r\n justify-content: center;\r\n background: rgba(255, 255, 255, 0.8);\n}\n.loading-spinner[data-v-5fd93944] {\r\n width: 32px;\r\n height: 32px;\r\n border: 4px solid #dbeafe;\r\n border-top: 4px solid #2563eb;\r\n border-radius: 50%;\r\n animation: spin-5fd93944 1s linear infinite;\r\n margin-bottom: 16px;\n}\n.empty-state[data-v-5fd93944] {\r\n position: absolute;\r\n top: 0;\r\n left: 0;\r\n right: 0;\r\n bottom: 0;\r\n display: flex;\r\n flex-direction: column;\r\n align-items: center;\r\n justify-content: center;\r\n color: #6b7280;\n}\n.empty-icon[data-v-5fd93944] {\r\n font-size: 48px;\r\n margin-bottom: 16px;\n}\n.empty-state h3[data-v-5fd93944] {\r\n font-size: 18px;\r\n font-weight: 600;\r\n margin-bottom: 8px;\r\n color: #374151;\n}\n.empty-state p[data-v-5fd93944] {\r\n font-size: 14px;\n}\n@keyframes spin-5fd93944 {\nto {\r\n transform: rotate(360deg);\n}\n}\r\n\r\n/* Custom scrollbar for code viewer */\n.code-viewer[data-v-5fd93944]::-webkit-scrollbar {\r\n width: 8px;\r\n height: 8px;\n}\n.code-viewer[data-v-5fd93944]::-webkit-scrollbar-track {\r\n background: #f1f1f1;\r\n border-radius: 4px;\n}\n.code-viewer[data-v-5fd93944]::-webkit-scrollbar-thumb {\r\n background: #c1c1c1;\r\n border-radius: 4px;\n}\n.code-viewer[data-v-5fd93944]::-webkit-scrollbar-thumb:hover {\r\n background: #a1a1a1;\n}\r\n\r\n/* Responsive adjustments */\n@media (max-width: 768px) {\n.toolbar[data-v-5fd93944] {\r\n flex-direction: column;\r\n gap: 12px;\r\n padding: 16px;\r\n height: auto;\n}\n.toolbar-left[data-v-5fd93944],\r\n .toolbar-right[data-v-5fd93944] {\r\n width: 100%;\r\n justify-content: center;\n}\n.tab-button[data-v-5fd93944] {\r\n flex: 1;\r\n justify-content: center;\n}\n}\r\n\r\n/* Print styles */\n@media print {\n.toolbar[data-v-5fd93944] {\r\n display: none;\n}\n.markmap-container[data-v-5fd93944] {\r\n box-shadow: none;\r\n border: none;\n}\n}\r\n";
styleInject(css_248z);
script.__scopeId = "data-v-5fd93944";
script.__file = "packages/MarkMap/index.vue";
export { script as default };