@floegence/floe-webapp-core 0.86.74 → 0.86.76
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/components/chat/blocks/MermaidBlock.d.ts +4 -0
- package/dist/components/chat/blocks/MermaidBlock.js +23 -198
- package/dist/components/chat/hooks/useMermaid.d.ts +3 -2
- package/dist/components/chat/hooks/useMermaid.js +48 -45
- package/dist/components/chat/markdown/fence.d.ts +2 -0
- package/dist/components/chat/markdown/fence.js +14 -0
- package/dist/diagrams/Diagram.d.ts +30 -0
- package/dist/diagrams/Diagram.js +233 -0
- package/dist/diagrams/render.d.ts +27 -0
- package/dist/diagrams/render.js +107 -0
- package/dist/diagrams.css +31 -0
- package/dist/diagrams.d.ts +4 -0
- package/dist/diagrams.js +9 -0
- package/dist/floe-webapp-core.css +1 -0
- package/dist/markdown.d.ts +1 -0
- package/dist/markdown.js +9 -7
- package/package.json +23 -6
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { type Component } from 'solid-js';
|
|
2
|
+
import { type DiagramLabels } from '../../../diagrams/Diagram';
|
|
3
|
+
import '../../../styles/diagrams.css';
|
|
2
4
|
export interface MermaidBlockProps {
|
|
3
5
|
content: string;
|
|
4
6
|
class?: string;
|
|
7
|
+
labels?: DiagramLabels;
|
|
5
8
|
}
|
|
9
|
+
/** Existing public component, now backed by the shared diagram surface. */
|
|
6
10
|
export declare const MermaidBlock: Component<MermaidBlockProps>;
|
|
@@ -1,200 +1,25 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
4
|
-
import { renderMermaid as
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
y: 0
|
|
24
|
-
}), d(!1));
|
|
25
|
-
};
|
|
26
|
-
O(() => {
|
|
27
|
-
const e = ++S, t = T.content;
|
|
28
|
-
if (!t) {
|
|
29
|
-
X(null), b(!1);
|
|
30
|
-
return;
|
|
31
|
-
}
|
|
32
|
-
b(!0), Y(null), pe(() => {
|
|
33
|
-
me(t).then((n) => {
|
|
34
|
-
e === S && (X(n), b(!1));
|
|
35
|
-
}).catch((n) => {
|
|
36
|
-
e === S && (Y(n.message || "Failed to render diagram"), b(!1));
|
|
37
|
-
});
|
|
38
|
-
});
|
|
39
|
-
});
|
|
40
|
-
const te = () => {
|
|
41
|
-
C(1), v({
|
|
42
|
-
x: 0,
|
|
43
|
-
y: 0
|
|
44
|
-
}), F(!0);
|
|
45
|
-
}, E = () => {
|
|
46
|
-
F(!1);
|
|
47
|
-
}, L = () => {
|
|
48
|
-
M(r() + Z);
|
|
49
|
-
}, z = () => {
|
|
50
|
-
M(r() - Z);
|
|
51
|
-
}, N = () => {
|
|
52
|
-
C(1), v({
|
|
53
|
-
x: 0,
|
|
54
|
-
y: 0
|
|
55
|
-
}), d(!1);
|
|
56
|
-
}, ne = (e) => {
|
|
57
|
-
e.preventDefault(), e.deltaY < 0 ? L() : z();
|
|
58
|
-
}, ie = (e) => {
|
|
59
|
-
if (e.pointerType === "mouse" && e.button !== 0) return;
|
|
60
|
-
e.preventDefault();
|
|
61
|
-
const t = e.currentTarget;
|
|
62
|
-
i.set(e.pointerId, {
|
|
63
|
-
x: e.clientX,
|
|
64
|
-
y: e.clientY
|
|
65
|
-
});
|
|
66
|
-
try {
|
|
67
|
-
t.setPointerCapture(e.pointerId);
|
|
68
|
-
} catch {
|
|
69
|
-
}
|
|
70
|
-
if (i.size === 1) {
|
|
71
|
-
c = {
|
|
72
|
-
x: e.clientX,
|
|
73
|
-
y: e.clientY
|
|
74
|
-
}, s = {
|
|
75
|
-
...y()
|
|
76
|
-
}, d(r() > 1);
|
|
77
|
-
return;
|
|
78
|
-
}
|
|
79
|
-
if (i.size === 2) {
|
|
80
|
-
const [n, l] = Array.from(i.values());
|
|
81
|
-
f = Math.hypot(n.x - l.x, n.y - l.y), x = r(), c = null, s = null, d(!1);
|
|
82
|
-
}
|
|
83
|
-
}, re = (e) => {
|
|
84
|
-
if (i.has(e.pointerId)) {
|
|
85
|
-
if (i.set(e.pointerId, {
|
|
86
|
-
x: e.clientX,
|
|
87
|
-
y: e.clientY
|
|
88
|
-
}), i.size === 2) {
|
|
89
|
-
const [t, n] = Array.from(i.values()), l = Math.hypot(t.x - n.x, t.y - n.y);
|
|
90
|
-
f > 0 && M(x * (l / f));
|
|
91
|
-
return;
|
|
92
|
-
}
|
|
93
|
-
if (!(i.size !== 1 || r() <= 1) && (d(!0), (!c || !s) && (c = {
|
|
94
|
-
x: e.clientX,
|
|
95
|
-
y: e.clientY
|
|
96
|
-
}, s = {
|
|
97
|
-
...y()
|
|
98
|
-
}), I = {
|
|
99
|
-
x: s.x + (e.clientX - c.x),
|
|
100
|
-
y: s.y + (e.clientY - c.y)
|
|
101
|
-
}, p === null)) {
|
|
102
|
-
if (typeof requestAnimationFrame > "u") {
|
|
103
|
-
v(I);
|
|
104
|
-
return;
|
|
105
|
-
}
|
|
106
|
-
p = requestAnimationFrame(() => {
|
|
107
|
-
p = null, !(i.size !== 1 || r() <= 1) && v(I);
|
|
108
|
-
});
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
}, q = (e) => {
|
|
112
|
-
i.delete(e.pointerId);
|
|
113
|
-
try {
|
|
114
|
-
e.currentTarget.releasePointerCapture(e.pointerId);
|
|
115
|
-
} catch {
|
|
116
|
-
}
|
|
117
|
-
if (i.size === 0) {
|
|
118
|
-
d(!1), c = null, s = null, f = 0, x = r();
|
|
119
|
-
return;
|
|
120
|
-
}
|
|
121
|
-
if (i.size === 1) {
|
|
122
|
-
const t = Array.from(i.values())[0];
|
|
123
|
-
c = {
|
|
124
|
-
x: t.x,
|
|
125
|
-
y: t.y
|
|
126
|
-
}, s = {
|
|
127
|
-
...y()
|
|
128
|
-
}, d(r() > 1), f = 0, x = r();
|
|
129
|
-
return;
|
|
130
|
-
}
|
|
131
|
-
if (i.size === 2) {
|
|
132
|
-
const [t, n] = Array.from(i.values());
|
|
133
|
-
f = Math.hypot(t.x - n.x, t.y - n.y), x = r(), c = null, s = null, d(!1);
|
|
134
|
-
}
|
|
135
|
-
};
|
|
136
|
-
return R(() => {
|
|
137
|
-
p !== null && typeof cancelAnimationFrame < "u" && (cancelAnimationFrame(p), p = null), i.clear();
|
|
138
|
-
}), O(() => {
|
|
139
|
-
if (!w()) return;
|
|
140
|
-
const e = (t) => {
|
|
141
|
-
t.key === "Escape" ? E() : t.key === "+" || t.key === "=" ? L() : t.key === "-" ? z() : t.key === "0" && N();
|
|
142
|
-
};
|
|
143
|
-
document.addEventListener("keydown", e), R(() => document.removeEventListener("keydown", e));
|
|
144
|
-
}), O(() => {
|
|
145
|
-
if (!w()) return;
|
|
146
|
-
const e = he({
|
|
147
|
-
overflow: "hidden"
|
|
148
|
-
});
|
|
149
|
-
R(e);
|
|
150
|
-
}), [(() => {
|
|
151
|
-
var e = fe();
|
|
152
|
-
return a(e, (() => {
|
|
153
|
-
var t = k(() => !!j());
|
|
154
|
-
return () => t() && (() => {
|
|
155
|
-
var n = ve(), l = n.firstChild;
|
|
156
|
-
return a(n, u(Ie, {}), l), n;
|
|
157
|
-
})();
|
|
158
|
-
})(), null), a(e, (() => {
|
|
159
|
-
var t = k(() => !!_());
|
|
160
|
-
return () => t() && (() => {
|
|
161
|
-
var n = xe(), l = n.firstChild;
|
|
162
|
-
return a(n, u(Me, {}), l), a(l, _), n;
|
|
163
|
-
})();
|
|
164
|
-
})(), null), a(e, (() => {
|
|
165
|
-
var t = k(() => !!($() && !_()));
|
|
166
|
-
return () => t() && (() => {
|
|
167
|
-
var n = $e();
|
|
168
|
-
return n.$$click = te, D(() => n.innerHTML = $()), n;
|
|
169
|
-
})();
|
|
170
|
-
})(), null), D(() => ae(e, ue("chat-mermaid-block", T.class))), e;
|
|
171
|
-
})(), u(de, {
|
|
172
|
-
get when() {
|
|
173
|
-
return k(() => !!w())() && $();
|
|
174
|
-
},
|
|
175
|
-
get children() {
|
|
176
|
-
return u(ce, {
|
|
177
|
-
get children() {
|
|
178
|
-
return [(() => {
|
|
179
|
-
var e = ge();
|
|
180
|
-
return e.$$click = E, e;
|
|
181
|
-
})(), (() => {
|
|
182
|
-
var e = ye(), t = e.firstChild, n = t.firstChild, l = n.nextSibling, le = l.firstChild, A = l.nextSibling, P = A.nextSibling, oe = P.nextSibling, H = oe.nextSibling, g = t.nextSibling, B = g.firstChild;
|
|
183
|
-
return n.$$click = z, a(n, u(ze, {})), a(l, () => Math.round(r() * 100), le), A.$$click = L, a(A, u(Le, {})), P.$$click = N, a(P, u(Ae, {})), H.$$click = E, a(H, u(Ee, {})), g.addEventListener("pointercancel", q), g.$$pointerup = q, g.$$pointermove = re, g.$$pointerdown = ie, g.addEventListener("wheel", ne), D((m) => {
|
|
184
|
-
var K = `translate(${y().x}px, ${y().y}px) scale(${r()})`, U = r() > 1 ? G() ? "grabbing" : "grab" : "default", V = $();
|
|
185
|
-
return K !== m.e && W(B, "transform", m.e = K), U !== m.t && W(B, "cursor", m.t = U), V !== m.a && (B.innerHTML = m.a = V), m;
|
|
186
|
-
}, {
|
|
187
|
-
e: void 0,
|
|
188
|
-
t: void 0,
|
|
189
|
-
a: void 0
|
|
190
|
-
}), e;
|
|
191
|
-
})()];
|
|
192
|
-
}
|
|
193
|
-
});
|
|
194
|
-
}
|
|
195
|
-
})];
|
|
196
|
-
}, Ie = () => be(), Me = () => ke(), Ee = () => _e(), Le = () => we(), ze = () => Ce(), Ae = () => Se();
|
|
197
|
-
se(["click", "pointerdown", "pointermove", "pointerup"]);
|
|
1
|
+
import { createComponent as a } from "solid-js/web";
|
|
2
|
+
import "solid-js";
|
|
3
|
+
import { Diagram as m, diagramLabelsEnUS as n } from "../../../diagrams/Diagram.js";
|
|
4
|
+
import { renderMermaid as o } from "../hooks/useMermaid.js";
|
|
5
|
+
/* empty css */
|
|
6
|
+
const i = (e, r) => o(e, "default", r).then((t) => ({
|
|
7
|
+
svg: t,
|
|
8
|
+
width: 0,
|
|
9
|
+
height: 0,
|
|
10
|
+
type: "mermaid"
|
|
11
|
+
})), u = (e) => a(m, {
|
|
12
|
+
get source() {
|
|
13
|
+
return e.content;
|
|
14
|
+
},
|
|
15
|
+
get class() {
|
|
16
|
+
return e.class;
|
|
17
|
+
},
|
|
18
|
+
get labels() {
|
|
19
|
+
return e.labels ?? n;
|
|
20
|
+
},
|
|
21
|
+
render: i
|
|
22
|
+
});
|
|
198
23
|
export {
|
|
199
|
-
|
|
24
|
+
u as MermaidBlock
|
|
200
25
|
};
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
import { type DiagramRenderOptions } from '../../../diagrams/render';
|
|
1
2
|
/**
|
|
2
3
|
* Configure the Mermaid worker.
|
|
3
4
|
* Call this during app initialization to enable worker mode.
|
|
4
5
|
*/
|
|
5
6
|
export declare function configureMermaidWorker(worker: Worker): Promise<void>;
|
|
6
7
|
/**
|
|
7
|
-
* Configure
|
|
8
|
+
* Configure an explicit host Mermaid renderer.
|
|
8
9
|
* If you don't use a worker, pass a Mermaid instance directly.
|
|
9
10
|
*/
|
|
10
11
|
export declare function configureSyncMermaid(mermaid: {
|
|
@@ -12,7 +13,7 @@ export declare function configureSyncMermaid(mermaid: {
|
|
|
12
13
|
svg: string;
|
|
13
14
|
}>;
|
|
14
15
|
}): void;
|
|
15
|
-
export declare function renderMermaid(content: string, theme?: string): Promise<string>;
|
|
16
|
+
export declare function renderMermaid(content: string, theme?: string, options?: DiagramRenderOptions): Promise<string>;
|
|
16
17
|
export declare function useMermaid(): {
|
|
17
18
|
render: (content: string, theme?: string) => Promise<string>;
|
|
18
19
|
isLoading: import("solid-js").Accessor<boolean>;
|
|
@@ -1,76 +1,79 @@
|
|
|
1
1
|
import { secureRandomUUID as w } from "../../../utils/secureRandom.js";
|
|
2
|
-
import { createSignal as
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
2
|
+
import { createSignal as y } from "solid-js";
|
|
3
|
+
import { sanitizeDiagramSvg as m, renderDiagram as k } from "../../../diagrams/render.js";
|
|
4
|
+
let a = null, f = !1, d = null;
|
|
5
|
+
const c = /* @__PURE__ */ new Map();
|
|
6
|
+
let l = null, p = 0;
|
|
7
|
+
function D(r) {
|
|
8
|
+
return a = r, d = new Promise((o) => {
|
|
8
9
|
a.onmessage = (e) => {
|
|
9
10
|
if ("type" in e.data && e.data.type === "ready") {
|
|
10
11
|
f = !0, o();
|
|
11
12
|
return;
|
|
12
13
|
}
|
|
13
|
-
const { id:
|
|
14
|
-
|
|
14
|
+
const { id: s, svg: n, error: t } = e.data, i = c.get(s);
|
|
15
|
+
i && (c.delete(s), t ? i.reject(new Error(t)) : i.resolve(n));
|
|
15
16
|
}, a.onerror = (e) => {
|
|
16
17
|
console.error("Mermaid worker error:", e);
|
|
17
18
|
};
|
|
18
|
-
}),
|
|
19
|
+
}), d;
|
|
19
20
|
}
|
|
20
|
-
function
|
|
21
|
-
|
|
21
|
+
function R(r) {
|
|
22
|
+
l = r;
|
|
22
23
|
}
|
|
23
|
-
async function
|
|
24
|
-
return a ? f ? !0 :
|
|
24
|
+
async function M() {
|
|
25
|
+
return a ? f ? !0 : d ? (await d, !0) : !1 : !1;
|
|
25
26
|
}
|
|
26
|
-
async function
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
const m = w();
|
|
32
|
-
l.set(m, {
|
|
27
|
+
async function v(r, o = "default", e = {}) {
|
|
28
|
+
if (await M() && a)
|
|
29
|
+
return new Promise((n, t) => {
|
|
30
|
+
const i = w();
|
|
31
|
+
c.set(i, {
|
|
33
32
|
resolve: (g) => {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
33
|
+
try {
|
|
34
|
+
n(m(g, e.document));
|
|
35
|
+
} catch (u) {
|
|
36
|
+
t(u instanceof Error ? u : new Error(String(u)));
|
|
37
37
|
}
|
|
38
|
-
s.set(e, g), t(g);
|
|
39
38
|
},
|
|
40
|
-
reject:
|
|
41
|
-
}), a.postMessage({ id:
|
|
39
|
+
reject: t
|
|
40
|
+
}), a.postMessage({ id: i, content: r, theme: o });
|
|
42
41
|
});
|
|
43
|
-
if (
|
|
42
|
+
if (l)
|
|
44
43
|
try {
|
|
45
|
-
const
|
|
46
|
-
return
|
|
47
|
-
} catch (
|
|
48
|
-
const
|
|
49
|
-
throw new Error(
|
|
44
|
+
const n = `mermaid-sync-${p++}`, { svg: t } = await l.render(n, r);
|
|
45
|
+
return m(t, e.document);
|
|
46
|
+
} catch (n) {
|
|
47
|
+
const t = n instanceof Error ? n.message : "Failed to render diagram";
|
|
48
|
+
throw new Error(t);
|
|
50
49
|
}
|
|
51
|
-
|
|
50
|
+
return (await k(r, e)).svg;
|
|
52
51
|
}
|
|
53
|
-
function
|
|
54
|
-
const [
|
|
52
|
+
function S() {
|
|
53
|
+
const [r, o] = y(!1);
|
|
55
54
|
return {
|
|
56
|
-
render: async (
|
|
55
|
+
render: async (s, n) => {
|
|
57
56
|
o(!0);
|
|
58
57
|
try {
|
|
59
|
-
return await
|
|
58
|
+
return await v(s, n);
|
|
60
59
|
} finally {
|
|
61
60
|
o(!1);
|
|
62
61
|
}
|
|
63
62
|
},
|
|
64
|
-
isLoading:
|
|
63
|
+
isLoading: r
|
|
65
64
|
};
|
|
66
65
|
}
|
|
67
|
-
function
|
|
68
|
-
|
|
66
|
+
function I() {
|
|
67
|
+
if (a) {
|
|
68
|
+
a.terminate(), a = null, f = !1, d = null;
|
|
69
|
+
for (const r of c.values()) r.reject(new Error("Diagram worker terminated."));
|
|
70
|
+
c.clear();
|
|
71
|
+
}
|
|
69
72
|
}
|
|
70
73
|
export {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
74
|
+
D as configureMermaidWorker,
|
|
75
|
+
R as configureSyncMermaid,
|
|
76
|
+
v as renderMermaid,
|
|
77
|
+
I as terminateMermaidWorker,
|
|
78
|
+
S as useMermaid
|
|
76
79
|
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
function r(s) {
|
|
2
|
+
const e = s.replace(/\r\n?/g, `
|
|
3
|
+
`).split(`
|
|
4
|
+
`), t = e[0]?.match(/^[ ]{0,3}(\x60{3,}|~{3,})/);
|
|
5
|
+
if (!t) return !1;
|
|
6
|
+
const c = t[1];
|
|
7
|
+
return e.slice(1).some((o) => {
|
|
8
|
+
const n = o.match(/^[ ]{0,3}(\x60+|~+)[ \t]*$/)?.[1];
|
|
9
|
+
return !!n && n[0] === c[0] && n.length >= c.length;
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
export {
|
|
13
|
+
r as isClosedMarkdownFence
|
|
14
|
+
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { type Component } from 'solid-js';
|
|
2
|
+
import { type DiagramRenderOptions, type DiagramRenderResult } from './render';
|
|
3
|
+
export interface DiagramLabels {
|
|
4
|
+
diagram: string;
|
|
5
|
+
loading: string;
|
|
6
|
+
unavailable: string;
|
|
7
|
+
retry: string;
|
|
8
|
+
source: string;
|
|
9
|
+
preview: string;
|
|
10
|
+
copy: string;
|
|
11
|
+
copied: string;
|
|
12
|
+
copyFailed: string;
|
|
13
|
+
expand: string;
|
|
14
|
+
close: string;
|
|
15
|
+
zoomIn: string;
|
|
16
|
+
zoomOut: string;
|
|
17
|
+
fit: string;
|
|
18
|
+
}
|
|
19
|
+
export declare const diagramLabelsEnUS: DiagramLabels;
|
|
20
|
+
export interface DiagramProps {
|
|
21
|
+
source: string;
|
|
22
|
+
labels: DiagramLabels;
|
|
23
|
+
class?: string;
|
|
24
|
+
onCopy?: (source: string) => Promise<void>;
|
|
25
|
+
onOpenLink?: (href: string) => void | Promise<void>;
|
|
26
|
+
/** Explicit renderer injection for existing hosts; never an error fallback. */
|
|
27
|
+
render?: (source: string, options: DiagramRenderOptions) => Promise<DiagramRenderResult>;
|
|
28
|
+
}
|
|
29
|
+
/** Shared diagram controls. The host owns source identity, localization and navigation. */
|
|
30
|
+
export declare const Diagram: Component<DiagramProps>;
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
import { insert as c, createComponent as v, memo as V, mergeProps as H, effect as N, setAttribute as D, className as K, template as S, use as J, setStyleProperty as U, delegateEvents as Q } from "solid-js/web";
|
|
2
|
+
import { createSignal as m, onCleanup as Z, Show as O, createMemo as X, createEffect as j, onMount as Y, on as p } from "solid-js";
|
|
3
|
+
import { Dialog as ee } from "../components/ui/Dialog.js";
|
|
4
|
+
import { StableText as B } from "../components/ui/StableText.js";
|
|
5
|
+
import { renderDiagram as te, sanitizeDiagramSvg as ne } from "./render.js";
|
|
6
|
+
var oe = /* @__PURE__ */ S("<div class=floe-diagram-status role=status>"), re = /* @__PURE__ */ S("<div class=floe-diagram-error role=alert><strong></strong><pre></pre><pre><code>"), ie = /* @__PURE__ */ S("<div class=floe-diagram-viewport data-floe-workbench-text-selection-surface=true><div class=floe-diagram-svg>"), ae = /* @__PURE__ */ S("<button type=button>"), le = /* @__PURE__ */ S("<pre class=floe-diagram-source data-floe-workbench-text-selection-surface=true><code>"), se = /* @__PURE__ */ S("<div class=floe-diagram><div class=floe-diagram-toolbar><button type=button>−</button><button type=button></button><button type=button>+"), ce = /* @__PURE__ */ S("<section><div class=floe-diagram-toolbar><button type=button></button><button type=button></button><span class=floe-diagram-feedback role=status></span><button type=button>⤢</button></div><div>");
|
|
7
|
+
const ve = {
|
|
8
|
+
diagram: "Diagram",
|
|
9
|
+
loading: "Rendering diagram…",
|
|
10
|
+
unavailable: "Diagram unavailable",
|
|
11
|
+
retry: "Retry",
|
|
12
|
+
source: "Source",
|
|
13
|
+
preview: "Preview",
|
|
14
|
+
copy: "Copy source",
|
|
15
|
+
copied: "Copied",
|
|
16
|
+
copyFailed: "Could not copy",
|
|
17
|
+
expand: "Expand diagram",
|
|
18
|
+
close: "Close",
|
|
19
|
+
zoomIn: "Zoom in",
|
|
20
|
+
zoomOut: "Zoom out",
|
|
21
|
+
fit: "Fit"
|
|
22
|
+
}, G = (e) => {
|
|
23
|
+
let s;
|
|
24
|
+
const [A, R] = m(!1), [T, I] = m(0), [b, P] = m(0), [x, $] = m("loading"), [W, w] = m(""), L = X(() => e.source);
|
|
25
|
+
j(() => e.onStatus?.(x())), Y(() => {
|
|
26
|
+
const l = new ResizeObserver((o) => {
|
|
27
|
+
const a = Math.round(o[0]?.contentRect.width ?? s.clientWidth);
|
|
28
|
+
a > 0 && I(a);
|
|
29
|
+
});
|
|
30
|
+
l.observe(s);
|
|
31
|
+
const i = new IntersectionObserver((o) => {
|
|
32
|
+
o.some((a) => a.isIntersecting) && (R(!0), i.disconnect());
|
|
33
|
+
}, {
|
|
34
|
+
rootMargin: "200px"
|
|
35
|
+
});
|
|
36
|
+
i.observe(s);
|
|
37
|
+
const g = s.ownerDocument.fonts, t = () => P((o) => o + 1);
|
|
38
|
+
g?.addEventListener("loadingdone", t), Z(() => {
|
|
39
|
+
l.disconnect(), i.disconnect(), g?.removeEventListener("loadingdone", t);
|
|
40
|
+
});
|
|
41
|
+
}), j(p([L, T, A, b, () => e.revision], ([l, i, g]) => {
|
|
42
|
+
if (!g || !i) return;
|
|
43
|
+
const t = new AbortController(), o = s.ownerDocument, a = getComputedStyle(s);
|
|
44
|
+
$("loading"), w("");
|
|
45
|
+
const u = (d) => {
|
|
46
|
+
if (t.signal.aborted || !s.isConnected) return;
|
|
47
|
+
const h = o.getSelection();
|
|
48
|
+
for (let C = 0; h && C < h.rangeCount; C++)
|
|
49
|
+
if (h.getRangeAt(C).intersectsNode(s)) {
|
|
50
|
+
const n = () => {
|
|
51
|
+
o.removeEventListener("selectionchange", n), u(d);
|
|
52
|
+
};
|
|
53
|
+
o.addEventListener("selectionchange", n, {
|
|
54
|
+
once: !0,
|
|
55
|
+
signal: t.signal
|
|
56
|
+
});
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
const f = o.createElement("template");
|
|
60
|
+
f.innerHTML = ne(d.svg, o);
|
|
61
|
+
const M = f.content.querySelector("svg");
|
|
62
|
+
M && e.expanded && (M.style.maxWidth = "none"), s.replaceChildren(f.content), $("ready");
|
|
63
|
+
};
|
|
64
|
+
(e.render ?? te)(l, {
|
|
65
|
+
signal: t.signal,
|
|
66
|
+
maxWidth: i,
|
|
67
|
+
document: o,
|
|
68
|
+
fontFamily: a.fontFamily,
|
|
69
|
+
fontFamilyMono: a.getPropertyValue("--font-mono").trim() || "monospace",
|
|
70
|
+
fontSize: parseFloat(a.fontSize) || 16,
|
|
71
|
+
links: !!e.onOpenLink
|
|
72
|
+
}).then(u).catch((d) => {
|
|
73
|
+
t.signal.aborted || (s.replaceChildren(), w(d instanceof Error ? d.message : String(d)), $("error"));
|
|
74
|
+
}), Z(() => t.abort());
|
|
75
|
+
}));
|
|
76
|
+
const z = (l) => {
|
|
77
|
+
const i = l.target instanceof Element ? l.target.closest("a") : null;
|
|
78
|
+
if (!i) return;
|
|
79
|
+
l.preventDefault();
|
|
80
|
+
const g = i.getAttribute("href");
|
|
81
|
+
!g || !/^(?:https?:\/\/|mailto:)/i.test(g) || !e.onOpenLink || Promise.resolve(e.onOpenLink(g)).catch(() => {
|
|
82
|
+
w(e.labels.unavailable), $("error");
|
|
83
|
+
});
|
|
84
|
+
};
|
|
85
|
+
return (() => {
|
|
86
|
+
var l = ie(), i = l.firstChild;
|
|
87
|
+
i.$$click = z;
|
|
88
|
+
var g = s;
|
|
89
|
+
return typeof g == "function" ? J(g, i) : s = i, c(l, v(O, {
|
|
90
|
+
get when() {
|
|
91
|
+
return x() === "loading";
|
|
92
|
+
},
|
|
93
|
+
get children() {
|
|
94
|
+
var t = oe();
|
|
95
|
+
return c(t, () => e.labels.loading), t;
|
|
96
|
+
}
|
|
97
|
+
}), null), c(l, v(O, {
|
|
98
|
+
get when() {
|
|
99
|
+
return x() === "error";
|
|
100
|
+
},
|
|
101
|
+
get children() {
|
|
102
|
+
var t = re(), o = t.firstChild, a = o.nextSibling, u = a.nextSibling, d = u.firstChild;
|
|
103
|
+
return c(o, () => e.labels.unavailable), c(a, W), c(d, () => e.source), t;
|
|
104
|
+
}
|
|
105
|
+
}), null), N((t) => {
|
|
106
|
+
var o = e.expanded ? "true" : void 0, a = e.expanded ? "auto" : "hidden", u = !!e.expanded, d = x() === "loading", h = e.scale ?? 1;
|
|
107
|
+
return o !== t.e && D(l, "data-floe-local-interaction-surface", t.e = o), a !== t.t && U(l, "overflow", t.t = a), u !== t.a && i.classList.toggle("floe-diagram-zoomed", t.a = u), d !== t.o && D(i, "aria-busy", t.o = d), h !== t.i && U(i, "--floe-diagram-scale", t.i = h), t;
|
|
108
|
+
}, {
|
|
109
|
+
e: void 0,
|
|
110
|
+
t: void 0,
|
|
111
|
+
a: void 0,
|
|
112
|
+
o: void 0,
|
|
113
|
+
i: void 0
|
|
114
|
+
}), l;
|
|
115
|
+
})();
|
|
116
|
+
}, be = (e) => {
|
|
117
|
+
const [s, A] = m(!1), [R, T] = m(!1), [I, b] = m(1), [P, x] = m(0), [$, W] = m("loading"), [w, L] = m("idle");
|
|
118
|
+
let z, l = !1, i;
|
|
119
|
+
Z(() => {
|
|
120
|
+
l = !0, clearTimeout(z);
|
|
121
|
+
});
|
|
122
|
+
const g = async () => {
|
|
123
|
+
try {
|
|
124
|
+
await (e.onCopy ? e.onCopy(e.source) : navigator.clipboard.writeText(e.source)), l || L("copied");
|
|
125
|
+
} catch {
|
|
126
|
+
l || L("error");
|
|
127
|
+
}
|
|
128
|
+
l || (clearTimeout(z), z = setTimeout(() => L("idle"), 1600));
|
|
129
|
+
}, t = (o) => {
|
|
130
|
+
const a = typeof document < "u" ? document.activeElement : null, u = a instanceof Element && !!a.closest('[role="dialog"]');
|
|
131
|
+
T(o), !o && u && i?.isConnected && i.focus({
|
|
132
|
+
preventScroll: !0
|
|
133
|
+
});
|
|
134
|
+
};
|
|
135
|
+
return (() => {
|
|
136
|
+
var o = ce(), a = o.firstChild, u = a.firstChild, d = u.nextSibling, h = d.nextSibling, f = h.nextSibling, M = a.nextSibling;
|
|
137
|
+
u.$$click = () => A((n) => !n), c(u, v(B, {
|
|
138
|
+
get reserve() {
|
|
139
|
+
return [e.labels.source, e.labels.preview];
|
|
140
|
+
},
|
|
141
|
+
get children() {
|
|
142
|
+
return V(() => !!s())() ? e.labels.preview : e.labels.source;
|
|
143
|
+
}
|
|
144
|
+
})), d.$$click = () => {
|
|
145
|
+
g();
|
|
146
|
+
}, c(d, () => e.labels.copy), c(h, v(B, {
|
|
147
|
+
get reserve() {
|
|
148
|
+
return [e.labels.copied, e.labels.copyFailed];
|
|
149
|
+
},
|
|
150
|
+
get children() {
|
|
151
|
+
return V(() => w() === "copied")() ? e.labels.copied : V(() => w() === "error")() ? e.labels.copyFailed : "";
|
|
152
|
+
}
|
|
153
|
+
})), c(a, v(O, {
|
|
154
|
+
get when() {
|
|
155
|
+
return $() === "error";
|
|
156
|
+
},
|
|
157
|
+
get children() {
|
|
158
|
+
var n = ae();
|
|
159
|
+
return n.$$click = () => x((y) => y + 1), c(n, () => e.labels.retry), n;
|
|
160
|
+
}
|
|
161
|
+
}), f), f.$$click = () => {
|
|
162
|
+
b(1), T(!0);
|
|
163
|
+
};
|
|
164
|
+
var C = i;
|
|
165
|
+
return typeof C == "function" ? J(C, f) : i = f, c(M, v(G, H(e, {
|
|
166
|
+
get revision() {
|
|
167
|
+
return P();
|
|
168
|
+
},
|
|
169
|
+
onStatus: W
|
|
170
|
+
}))), c(o, v(O, {
|
|
171
|
+
get when() {
|
|
172
|
+
return s();
|
|
173
|
+
},
|
|
174
|
+
get children() {
|
|
175
|
+
var n = le(), y = n.firstChild;
|
|
176
|
+
return c(y, () => e.source), n;
|
|
177
|
+
}
|
|
178
|
+
}), null), c(o, v(ee, {
|
|
179
|
+
get open() {
|
|
180
|
+
return R();
|
|
181
|
+
},
|
|
182
|
+
onOpenChange: t,
|
|
183
|
+
get title() {
|
|
184
|
+
return e.labels.diagram;
|
|
185
|
+
},
|
|
186
|
+
get closeLabel() {
|
|
187
|
+
return e.labels.close;
|
|
188
|
+
},
|
|
189
|
+
class: "floe-diagram-dialog",
|
|
190
|
+
get children() {
|
|
191
|
+
var n = se(), y = n.firstChild, k = y.firstChild, _ = k.nextSibling, F = _.nextSibling;
|
|
192
|
+
return n.$$keydown = (r) => {
|
|
193
|
+
r.target instanceof Element && r.target.closest("button,input,textarea") || ((r.key === "+" || r.key === "=") && (r.preventDefault(), b((E) => Math.min(4, E + 0.25))), r.key === "-" && (r.preventDefault(), b((E) => Math.max(0.5, E - 0.25))), r.key === "0" && (r.preventDefault(), b(1)));
|
|
194
|
+
}, k.$$click = () => b((r) => Math.max(0.5, r - 0.25)), _.$$click = () => b(1), c(_, () => e.labels.fit), F.$$click = () => b((r) => Math.min(4, r + 0.25)), c(n, v(O, {
|
|
195
|
+
get when() {
|
|
196
|
+
return R();
|
|
197
|
+
},
|
|
198
|
+
get children() {
|
|
199
|
+
return v(G, H(e, {
|
|
200
|
+
expanded: !0,
|
|
201
|
+
get scale() {
|
|
202
|
+
return I();
|
|
203
|
+
},
|
|
204
|
+
get revision() {
|
|
205
|
+
return P();
|
|
206
|
+
}
|
|
207
|
+
}));
|
|
208
|
+
}
|
|
209
|
+
}), null), N((r) => {
|
|
210
|
+
var E = e.labels.zoomOut, q = e.labels.zoomIn;
|
|
211
|
+
return E !== r.e && D(k, "aria-label", r.e = E), q !== r.t && D(F, "aria-label", r.t = q), r;
|
|
212
|
+
}, {
|
|
213
|
+
e: void 0,
|
|
214
|
+
t: void 0
|
|
215
|
+
}), n;
|
|
216
|
+
}
|
|
217
|
+
}), null), N((n) => {
|
|
218
|
+
var y = "floe-diagram " + (e.class ?? ""), k = s(), _ = $() !== "ready", F = e.labels.expand, r = s();
|
|
219
|
+
return y !== n.e && K(o, n.e = y), k !== n.t && D(u, "aria-pressed", n.t = k), _ !== n.a && (f.disabled = n.a = _), F !== n.o && D(f, "aria-label", n.o = F), r !== n.i && (M.hidden = n.i = r), n;
|
|
220
|
+
}, {
|
|
221
|
+
e: void 0,
|
|
222
|
+
t: void 0,
|
|
223
|
+
a: void 0,
|
|
224
|
+
o: void 0,
|
|
225
|
+
i: void 0
|
|
226
|
+
}), o;
|
|
227
|
+
})();
|
|
228
|
+
};
|
|
229
|
+
Q(["click", "keydown"]);
|
|
230
|
+
export {
|
|
231
|
+
be as Diagram,
|
|
232
|
+
ve as diagramLabelsEnUS
|
|
233
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export type DiagramErrorCode = 'syntax' | 'semantic' | 'limit' | 'unsupported-diagram' | 'unavailable';
|
|
2
|
+
export declare class DiagramError extends Error {
|
|
3
|
+
readonly code: DiagramErrorCode;
|
|
4
|
+
readonly line: number;
|
|
5
|
+
readonly column: number;
|
|
6
|
+
constructor(code: DiagramErrorCode, message: string, line?: number, column?: number);
|
|
7
|
+
}
|
|
8
|
+
export interface DiagramRenderOptions {
|
|
9
|
+
signal?: AbortSignal;
|
|
10
|
+
/** The owner supplies actual local CSS width, never transformed screen width. */
|
|
11
|
+
maxWidth?: number;
|
|
12
|
+
fontFamily?: string;
|
|
13
|
+
fontFamilyMono?: string;
|
|
14
|
+
fontSize?: number;
|
|
15
|
+
document?: Document;
|
|
16
|
+
/** Links remain inert unless the host explicitly owns navigation. */
|
|
17
|
+
links?: boolean;
|
|
18
|
+
}
|
|
19
|
+
export interface DiagramRenderResult {
|
|
20
|
+
svg: string;
|
|
21
|
+
width: number;
|
|
22
|
+
height: number;
|
|
23
|
+
type: string;
|
|
24
|
+
}
|
|
25
|
+
export declare function sanitizeDiagramSvg(svg: string, doc?: Document): string;
|
|
26
|
+
/** One lazy renderer for all Mermaid syntax surfaces. Never retries another engine. */
|
|
27
|
+
export declare function renderDiagram(source: string, options?: DiagramRenderOptions): Promise<DiagramRenderResult>;
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import d from "../node_modules/.pnpm/dompurify@3.4.17/node_modules/dompurify/dist/purify.es.js";
|
|
2
|
+
import { secureRandomUUID as y } from "../utils/secureRandom.js";
|
|
3
|
+
class c extends Error {
|
|
4
|
+
constructor(t, l, n = 0, e = 0) {
|
|
5
|
+
super(l), this.code = t, this.line = n, this.column = e, this.name = "DiagramError";
|
|
6
|
+
}
|
|
7
|
+
code;
|
|
8
|
+
line;
|
|
9
|
+
column;
|
|
10
|
+
}
|
|
11
|
+
let p = Promise.resolve(), f = 0;
|
|
12
|
+
const u = (o) => {
|
|
13
|
+
if (o?.aborted) throw new DOMException("Aborted", "AbortError");
|
|
14
|
+
};
|
|
15
|
+
function S(o, t = document) {
|
|
16
|
+
const l = t.defaultView?.DOMParser ?? DOMParser, n = new l().parseFromString(o, "image/svg+xml"), e = [];
|
|
17
|
+
for (const r of Array.from(n.querySelectorAll("foreignObject"))) {
|
|
18
|
+
const i = r.querySelector("math");
|
|
19
|
+
if (!i) {
|
|
20
|
+
r.remove();
|
|
21
|
+
continue;
|
|
22
|
+
}
|
|
23
|
+
const h = t.createElement("template");
|
|
24
|
+
h.innerHTML = d.sanitize(i.outerHTML, { USE_PROFILES: { mathMl: !0 }, FORBID_TAGS: ["annotation-xml"], FORBID_ATTR: ["href", "style"] });
|
|
25
|
+
const g = h.content.querySelector("math");
|
|
26
|
+
if (!g) {
|
|
27
|
+
r.remove();
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
r.replaceChildren(), r.setAttribute("data-floe-formula", String(e.length)), e.push(g);
|
|
31
|
+
}
|
|
32
|
+
const m = d.sanitize(new XMLSerializer().serializeToString(n.documentElement), {
|
|
33
|
+
USE_PROFILES: { svg: !0, svgFilters: !0, mathMl: !0 },
|
|
34
|
+
ADD_TAGS: ["foreignObject"],
|
|
35
|
+
ADD_ATTR: ["role"],
|
|
36
|
+
FORBID_TAGS: ["script", "style", "image", "iframe", "object", "embed", "animate", "set"]
|
|
37
|
+
}), a = new l().parseFromString(m, "image/svg+xml"), s = a.documentElement;
|
|
38
|
+
if (s.localName !== "svg" || a.querySelector("parsererror")) throw new c("unavailable", "Invalid diagram SVG.");
|
|
39
|
+
for (const r of [s, ...Array.from(s.querySelectorAll("*"))])
|
|
40
|
+
for (const i of Array.from(r.attributes))
|
|
41
|
+
/^on/i.test(i.name) && r.removeAttribute(i.name), i.localName === "href" && !/^(?:#|https?:\/\/|mailto:)/i.test(i.value.trim()) && r.removeAttribute(i.name), /url\s*\(/i.test(i.value) && !/^url\(#[\w-]+\)$/.test(i.value.trim()) && r.removeAttribute(i.name);
|
|
42
|
+
for (const r of Array.from(s.querySelectorAll("foreignObject"))) {
|
|
43
|
+
const i = e[Number(r.getAttribute("data-floe-formula"))];
|
|
44
|
+
r.removeAttribute("data-floe-formula"), i ? r.append(a.importNode(i, !0)) : r.remove();
|
|
45
|
+
}
|
|
46
|
+
return new XMLSerializer().serializeToString(s);
|
|
47
|
+
}
|
|
48
|
+
async function w(o, t, l) {
|
|
49
|
+
if (!o.includes("$$")) return { dispose() {
|
|
50
|
+
} };
|
|
51
|
+
const { default: n } = await import("katex"), e = t.createElement("span");
|
|
52
|
+
return e.style.cssText = "position:fixed;left:-99999px;top:0;visibility:hidden;display:inline-block;white-space:nowrap;", e.style.fontSize = l + "px", t.body.append(e), {
|
|
53
|
+
dispose: () => e.remove(),
|
|
54
|
+
math(m, a) {
|
|
55
|
+
e.style.fontSize = a + "px", e.innerHTML = d.sanitize(n.renderToString(m, { output: "mathml", throwOnError: !0, trust: !1, strict: "error" }), { USE_PROFILES: { html: !0, mathMl: !0 } });
|
|
56
|
+
const s = e.querySelector("math");
|
|
57
|
+
if (!s) throw new c("semantic", "The diagram formula could not be typeset.");
|
|
58
|
+
const { width: r, height: i } = s.getBoundingClientRect();
|
|
59
|
+
return { html: s.outerHTML, width: r, height: i };
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
function A(o, t = {}) {
|
|
64
|
+
if (o.length > 5e4 || f >= 128) return Promise.reject(new c("limit", "Diagram rendering limit exceeded."));
|
|
65
|
+
f++;
|
|
66
|
+
const l = p.then(async () => {
|
|
67
|
+
await new Promise((a) => setTimeout(a, 0)), u(t.signal);
|
|
68
|
+
const n = t.document ?? document, { renderAsync: e } = await import("pele/lazy");
|
|
69
|
+
u(t.signal);
|
|
70
|
+
const m = await w(o, n, t.fontSize ?? 16);
|
|
71
|
+
try {
|
|
72
|
+
u(t.signal);
|
|
73
|
+
const a = await e(o, {
|
|
74
|
+
idPrefix: "floe-diagram-" + y(),
|
|
75
|
+
autoDirection: !1,
|
|
76
|
+
maxWidth: t.maxWidth,
|
|
77
|
+
fontFamily: t.fontFamily ?? "Inter, system-ui, sans-serif",
|
|
78
|
+
fontFamilyMono: t.fontFamilyMono ?? "monospace",
|
|
79
|
+
fontSize: t.fontSize ?? 16,
|
|
80
|
+
links: t.links === !0,
|
|
81
|
+
images: !1,
|
|
82
|
+
linkSchemes: ["https", "http", "mailto"],
|
|
83
|
+
linkRel: "noopener noreferrer",
|
|
84
|
+
limit: 5e4,
|
|
85
|
+
maxEdges: 500,
|
|
86
|
+
outputLimit: 4e6,
|
|
87
|
+
math: m.math
|
|
88
|
+
});
|
|
89
|
+
return u(t.signal), { svg: S(a.svg, n), width: a.width, height: a.height, type: a.type };
|
|
90
|
+
} finally {
|
|
91
|
+
m.dispose();
|
|
92
|
+
}
|
|
93
|
+
}).catch((n) => {
|
|
94
|
+
if (n instanceof c || n instanceof DOMException && n.name === "AbortError") throw n;
|
|
95
|
+
const e = n;
|
|
96
|
+
throw new c(e.code ?? "unavailable", e.message ?? "Diagram rendering failed.", e.line, e.column);
|
|
97
|
+
});
|
|
98
|
+
return p = l.catch(() => {
|
|
99
|
+
}).finally(() => {
|
|
100
|
+
f--;
|
|
101
|
+
}), l;
|
|
102
|
+
}
|
|
103
|
+
export {
|
|
104
|
+
c as DiagramError,
|
|
105
|
+
A as renderDiagram,
|
|
106
|
+
S as sanitizeDiagramSvg
|
|
107
|
+
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
.floe-diagram {
|
|
2
|
+
--pele-bg: var(--background); --pele-fg: var(--foreground);
|
|
3
|
+
--pele-muted: var(--muted-foreground); --pele-line: var(--muted-foreground);
|
|
4
|
+
--pele-surface: var(--card); --pele-surface-alt: var(--muted);
|
|
5
|
+
--pele-border: var(--border); --pele-accent: var(--primary);
|
|
6
|
+
--pele-font: var(--font-sans, Inter, system-ui, sans-serif);
|
|
7
|
+
--pele-font-mono: var(--font-mono, monospace);
|
|
8
|
+
--pele-fg-on-light: #171717; --pele-fg-on-dark: #fafafa;
|
|
9
|
+
min-width: 0; background:var(--background); color: var(--foreground); font: 14px/1.5 var(--pele-font);
|
|
10
|
+
border: 1px solid var(--border); border-radius: .5rem; overflow: hidden;
|
|
11
|
+
}
|
|
12
|
+
.floe-diagram-toolbar { display:flex; flex-wrap:wrap; align-items:center; gap:.25rem; padding:.375rem; border-bottom:1px solid var(--border); }
|
|
13
|
+
.floe-diagram-toolbar button { font:inherit; white-space:nowrap; border:0; border-radius:.25rem; padding:.25rem .5rem; background:transparent; color:inherit; cursor:pointer; }
|
|
14
|
+
.floe-diagram-toolbar button:hover,.floe-diagram-toolbar button[aria-pressed=true] { background:var(--accent); }
|
|
15
|
+
.floe-diagram-toolbar button:focus-visible { outline:2px solid var(--ring); outline-offset:-2px; }
|
|
16
|
+
.floe-diagram-feedback { flex:1; min-width:0; font-size:.85em; }
|
|
17
|
+
.floe-diagram-viewport { position:relative; box-sizing:border-box; padding:.75rem; min-width:0; height:clamp(12rem,36vw,24rem); max-height:65vh; }
|
|
18
|
+
.floe-diagram-svg { min-height:2rem; width:100%; }
|
|
19
|
+
.floe-diagram-svg > svg { display:block; max-width:100%; height:auto; margin:auto; }
|
|
20
|
+
.floe-diagram-source { box-sizing:border-box; height:clamp(12rem,36vw,24rem); max-height:65vh; overflow:auto; }
|
|
21
|
+
.floe-diagram-source,.floe-diagram-error pre { white-space:pre-wrap; overflow-wrap:anywhere; margin:0; padding:.75rem; font:12px/1.6 var(--pele-font-mono); }
|
|
22
|
+
.floe-diagram-status,.floe-diagram-error { position:absolute; inset:0; box-sizing:border-box; padding:.75rem; overflow:auto; background:var(--background); }
|
|
23
|
+
.floe-diagram-status { display:grid; place-items:center; }
|
|
24
|
+
.floe-diagram-error { color:var(--error,var(--foreground)); }
|
|
25
|
+
.floe-diagram-dialog { width:min(94vw,1100px); max-width:94vw; }
|
|
26
|
+
@media (forced-colors:active) { .floe-diagram { --pele-fg:CanvasText; --pele-line:CanvasText; --pele-bg:Canvas; --pele-surface:Canvas; --pele-surface-alt:Canvas; --pele-border:CanvasText; --pele-accent:Highlight; } }
|
|
27
|
+
|
|
28
|
+
.floe-diagram-zoomed > svg { width:calc(100% * var(--floe-diagram-scale,1)); max-width:none; }
|
|
29
|
+
.floe-diagram-toolbar button:disabled { opacity:.5; cursor:default; }
|
|
30
|
+
|
|
31
|
+
.floe-diagram-svg:not(.floe-diagram-zoomed) > svg { max-height:min(60vh,calc(clamp(12rem,36vw,24rem) - 1.5rem)); }
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { Diagram, diagramLabelsEnUS } from './diagrams/Diagram';
|
|
2
|
+
export type { DiagramProps, DiagramLabels } from './diagrams/Diagram';
|
|
3
|
+
export { renderDiagram, sanitizeDiagramSvg, DiagramError } from './diagrams/render';
|
|
4
|
+
export type { DiagramRenderOptions, DiagramRenderResult, DiagramErrorCode } from './diagrams/render';
|
package/dist/diagrams.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Diagram as i, diagramLabelsEnUS as m } from "./diagrams/Diagram.js";
|
|
2
|
+
import { DiagramError as g, renderDiagram as o, sanitizeDiagramSvg as D } from "./diagrams/render.js";
|
|
3
|
+
export {
|
|
4
|
+
i as Diagram,
|
|
5
|
+
g as DiagramError,
|
|
6
|
+
m as diagramLabelsEnUS,
|
|
7
|
+
o as renderDiagram,
|
|
8
|
+
D as sanitizeDiagramSvg
|
|
9
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.floe-diagram{--pele-bg: var(--background);--pele-fg: var(--foreground);--pele-muted: var(--muted-foreground);--pele-line: var(--muted-foreground);--pele-surface: var(--card);--pele-surface-alt: var(--muted);--pele-border: var(--border);--pele-accent: var(--primary);--pele-font: var(--font-sans, Inter, system-ui, sans-serif);--pele-font-mono: var(--font-mono, monospace);--pele-fg-on-light: #171717;--pele-fg-on-dark: #fafafa;min-width:0;background:var(--background);color:var(--foreground);font:14px/1.5 var(--pele-font);border:1px solid var(--border);border-radius:.5rem;overflow:hidden}.floe-diagram-toolbar{display:flex;flex-wrap:wrap;align-items:center;gap:.25rem;padding:.375rem;border-bottom:1px solid var(--border)}.floe-diagram-toolbar button{font:inherit;white-space:nowrap;border:0;border-radius:.25rem;padding:.25rem .5rem;background:transparent;color:inherit;cursor:pointer}.floe-diagram-toolbar button:hover,.floe-diagram-toolbar button[aria-pressed=true]{background:var(--accent)}.floe-diagram-toolbar button:focus-visible{outline:2px solid var(--ring);outline-offset:-2px}.floe-diagram-feedback{flex:1;min-width:0;font-size:.85em}.floe-diagram-viewport{position:relative;box-sizing:border-box;padding:.75rem;min-width:0;height:clamp(12rem,36vw,24rem);max-height:65vh}.floe-diagram-svg{min-height:2rem;width:100%}.floe-diagram-svg>svg{display:block;max-width:100%;height:auto;margin:auto}.floe-diagram-source{box-sizing:border-box;height:clamp(12rem,36vw,24rem);max-height:65vh;overflow:auto}.floe-diagram-source,.floe-diagram-error pre{white-space:pre-wrap;overflow-wrap:anywhere;margin:0;padding:.75rem;font:12px/1.6 var(--pele-font-mono)}.floe-diagram-status,.floe-diagram-error{position:absolute;inset:0;box-sizing:border-box;padding:.75rem;overflow:auto;background:var(--background)}.floe-diagram-status{display:grid;place-items:center}.floe-diagram-error{color:var(--error,var(--foreground))}.floe-diagram-dialog{width:min(94vw,1100px);max-width:94vw}@media(forced-colors:active){.floe-diagram{--pele-fg:CanvasText;--pele-line:CanvasText;--pele-bg:Canvas;--pele-surface:Canvas;--pele-surface-alt:Canvas;--pele-border:CanvasText;--pele-accent:Highlight}}.floe-diagram-zoomed>svg{width:calc(100% * var(--floe-diagram-scale,1));max-width:none}.floe-diagram-toolbar button:disabled{opacity:.5;cursor:default}.floe-diagram-svg:not(.floe-diagram-zoomed)>svg{max-height:min(60vh,calc(clamp(12rem,36vw,24rem) - 1.5rem))}
|
package/dist/markdown.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { createMarkdownParser } from './components/chat/markdown/parser';
|
|
2
|
+
export { isClosedMarkdownFence } from './components/chat/markdown/fence';
|
|
2
3
|
export { createIncrementalMarkdownParser } from './components/chat/markdown/incremental';
|
|
3
4
|
export { createMarkdownSessionWorker } from './components/chat/markdown/createSessionWorker';
|
|
4
5
|
export { createMarkdownSessionHandler, createMarkdownWorkerClient } from './components/chat/markdown/workerSession';
|
package/dist/markdown.js
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { createMarkdownParser as o } from "./components/chat/markdown/parser.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
2
|
+
import { isClosedMarkdownFence as n } from "./components/chat/markdown/fence.js";
|
|
3
|
+
import { createIncrementalMarkdownParser as d } from "./components/chat/markdown/incremental.js";
|
|
4
|
+
import { createMarkdownSessionWorker as s } from "./components/chat/markdown/createSessionWorker.js";
|
|
5
|
+
import { createMarkdownSessionHandler as m, createMarkdownWorkerClient as w } from "./components/chat/markdown/workerSession.js";
|
|
5
6
|
export {
|
|
6
|
-
|
|
7
|
+
d as createIncrementalMarkdownParser,
|
|
7
8
|
o as createMarkdownParser,
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
m as createMarkdownSessionHandler,
|
|
10
|
+
s as createMarkdownSessionWorker,
|
|
11
|
+
w as createMarkdownWorkerClient,
|
|
12
|
+
n as isClosedMarkdownFence
|
|
11
13
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@floegence/floe-webapp-core",
|
|
3
|
-
"version": "0.86.
|
|
3
|
+
"version": "0.86.76",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -155,7 +155,12 @@
|
|
|
155
155
|
"./pptx": {
|
|
156
156
|
"types": "./dist/pptx.d.ts",
|
|
157
157
|
"import": "./dist/pptx.js"
|
|
158
|
-
}
|
|
158
|
+
},
|
|
159
|
+
"./diagrams": {
|
|
160
|
+
"types": "./dist/diagrams.d.ts",
|
|
161
|
+
"import": "./dist/diagrams.js"
|
|
162
|
+
},
|
|
163
|
+
"./diagrams.css": "./dist/diagrams.css"
|
|
159
164
|
},
|
|
160
165
|
"files": [
|
|
161
166
|
"dist",
|
|
@@ -174,7 +179,9 @@
|
|
|
174
179
|
"clean": "rm -rf dist *.tsbuildinfo"
|
|
175
180
|
},
|
|
176
181
|
"peerDependencies": {
|
|
177
|
-
"solid-js": "^1.9.17"
|
|
182
|
+
"solid-js": "^1.9.17",
|
|
183
|
+
"pele": "1.13.0",
|
|
184
|
+
"katex": "0.18.10"
|
|
178
185
|
},
|
|
179
186
|
"dependencies": {
|
|
180
187
|
"clsx": "^2.1.1",
|
|
@@ -184,7 +191,6 @@
|
|
|
184
191
|
"libavoid-js": "0.5.0-beta.5",
|
|
185
192
|
"marked": "^17.0.6",
|
|
186
193
|
"marked-cjk-friendly": "0.1.2",
|
|
187
|
-
"mermaid": "^11.17.2",
|
|
188
194
|
"monaco-editor": "^0.57.0",
|
|
189
195
|
"pdfjs-dist": "6.3.289",
|
|
190
196
|
"shiki": "^3.23.0",
|
|
@@ -192,12 +198,23 @@
|
|
|
192
198
|
"tailwind-merge": "^3.7.0"
|
|
193
199
|
},
|
|
194
200
|
"devDependencies": {
|
|
201
|
+
"@aiden0z/pptx-renderer": "1.3.0",
|
|
195
202
|
"@tailwindcss/vite": "^4.3.3",
|
|
203
|
+
"@types/katex": "0.16.8",
|
|
204
|
+
"katex": "0.18.10",
|
|
205
|
+
"pele": "1.13.0",
|
|
196
206
|
"solid-js": "^1.9.17",
|
|
197
207
|
"tailwindcss": "^4.3.3",
|
|
198
208
|
"typescript": "^5.9.3",
|
|
199
209
|
"vite": "^7.3.6",
|
|
200
|
-
"vite-plugin-solid": "^2.11.14"
|
|
201
|
-
|
|
210
|
+
"vite-plugin-solid": "^2.11.14"
|
|
211
|
+
},
|
|
212
|
+
"peerDependenciesMeta": {
|
|
213
|
+
"pele": {
|
|
214
|
+
"optional": true
|
|
215
|
+
},
|
|
216
|
+
"katex": {
|
|
217
|
+
"optional": true
|
|
218
|
+
}
|
|
202
219
|
}
|
|
203
220
|
}
|