@frontmcp/ui 0.12.2 → 1.0.0-beta.2
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/README.md +279 -72
- package/bridge/adapters/claude.adapter.d.ts.map +1 -1
- package/bridge/adapters/gemini.adapter.d.ts.map +1 -1
- package/bridge/index.js +2 -36
- package/components/Alert/Alert.d.ts +11 -0
- package/components/Alert/Alert.d.ts.map +1 -0
- package/components/Alert/index.d.ts +4 -0
- package/components/Alert/index.d.ts.map +1 -0
- package/components/Alert/index.js +61 -0
- package/components/Avatar/Avatar.d.ts +10 -0
- package/components/Avatar/Avatar.d.ts.map +1 -0
- package/components/Avatar/index.d.ts +4 -0
- package/components/Avatar/index.d.ts.map +1 -0
- package/components/Avatar/index.js +43 -0
- package/components/Badge/Badge.d.ts +13 -0
- package/components/Badge/Badge.d.ts.map +1 -0
- package/components/Badge/index.d.ts +4 -0
- package/components/Badge/index.d.ts.map +1 -0
- package/{render → components/Badge}/index.js +54 -42
- package/components/Button/Button.d.ts +16 -0
- package/components/Button/Button.d.ts.map +1 -0
- package/components/Button/index.d.ts +4 -0
- package/components/Button/index.d.ts.map +1 -0
- package/components/Button/index.js +91 -0
- package/components/Card/Card.d.ts +25 -0
- package/components/Card/Card.d.ts.map +1 -0
- package/components/Card/index.d.ts +4 -0
- package/components/Card/index.d.ts.map +1 -0
- package/components/Card/index.js +110 -0
- package/components/List/List.d.ts +15 -0
- package/components/List/List.d.ts.map +1 -0
- package/components/List/index.d.ts +4 -0
- package/components/List/index.d.ts.map +1 -0
- package/components/List/index.js +58 -0
- package/components/Loader/Loader.d.ts +28 -0
- package/components/Loader/Loader.d.ts.map +1 -0
- package/components/Loader/LoaderContext.d.ts +20 -0
- package/components/Loader/LoaderContext.d.ts.map +1 -0
- package/components/Loader/index.d.ts +6 -0
- package/components/Loader/index.d.ts.map +1 -0
- package/components/Loader/index.js +174 -0
- package/components/Modal/Modal.d.ts +22 -0
- package/components/Modal/Modal.d.ts.map +1 -0
- package/components/Modal/index.d.ts +4 -0
- package/components/Modal/index.d.ts.map +1 -0
- package/components/Modal/index.js +80 -0
- package/components/Select/Select.d.ts +21 -0
- package/components/Select/Select.d.ts.map +1 -0
- package/components/Select/index.d.ts +4 -0
- package/components/Select/index.d.ts.map +1 -0
- package/components/Select/index.js +78 -0
- package/components/Table/Table.d.ts +15 -0
- package/components/Table/Table.d.ts.map +1 -0
- package/components/Table/index.d.ts +4 -0
- package/components/Table/index.d.ts.map +1 -0
- package/components/Table/index.js +70 -0
- package/components/TextField/TextField.d.ts +19 -0
- package/components/TextField/TextField.d.ts.map +1 -0
- package/components/TextField/index.d.ts +4 -0
- package/components/TextField/index.d.ts.map +1 -0
- package/components/TextField/index.js +77 -0
- package/components/index.d.ts +22 -28
- package/components/index.d.ts.map +1 -1
- package/components/index.js +523 -2521
- package/esm/bridge/index.mjs +2 -6
- package/esm/components/Alert/index.mjs +28 -0
- package/esm/components/Avatar/index.mjs +10 -0
- package/esm/components/Badge/index.mjs +56 -0
- package/esm/components/Button/index.mjs +58 -0
- package/esm/components/Card/index.mjs +77 -0
- package/esm/components/List/index.mjs +25 -0
- package/esm/components/Loader/index.mjs +141 -0
- package/esm/components/Modal/index.mjs +47 -0
- package/esm/components/Select/index.mjs +45 -0
- package/esm/components/Table/index.mjs +37 -0
- package/esm/components/TextField/index.mjs +44 -0
- package/esm/components/index.mjs +513 -2415
- package/esm/index.mjs +62 -4652
- package/esm/package.json +372 -16
- package/esm/react/index.mjs +2 -285
- package/esm/renderer/charts/index.mjs +336 -0
- package/esm/renderer/common/index.mjs +135 -0
- package/esm/renderer/csv/index.mjs +193 -0
- package/esm/renderer/flow/index.mjs +259 -0
- package/esm/renderer/html/index.mjs +99 -0
- package/esm/renderer/image/index.mjs +125 -0
- package/esm/renderer/index.mjs +2173 -0
- package/esm/renderer/maps/index.mjs +217 -0
- package/esm/renderer/math/index.mjs +229 -0
- package/esm/renderer/mdx/index.mjs +261 -0
- package/esm/renderer/media/index.mjs +235 -0
- package/esm/renderer/mermaid/index.mjs +220 -0
- package/esm/renderer/pdf/index.mjs +229 -0
- package/esm/renderer/react/index.mjs +230 -0
- package/esm/runtime/index.mjs +194 -0
- package/esm/theme/index.mjs +93 -0
- package/index.d.ts +10 -18
- package/index.d.ts.map +1 -1
- package/index.js +63 -4806
- package/package.json +372 -16
- package/react/index.d.ts +8 -54
- package/react/index.d.ts.map +1 -1
- package/react/index.js +2 -295
- package/renderer/auto-detect.d.ts +39 -0
- package/renderer/auto-detect.d.ts.map +1 -0
- package/renderer/charts/index.d.ts +22 -0
- package/renderer/charts/index.d.ts.map +1 -0
- package/renderer/charts/index.js +367 -0
- package/renderer/common/index.d.ts +5 -0
- package/renderer/common/index.d.ts.map +1 -0
- package/renderer/common/index.js +158 -0
- package/renderer/common/inject-stylesheet.d.ts +9 -0
- package/renderer/common/inject-stylesheet.d.ts.map +1 -0
- package/renderer/common/lazy-import.d.ts +85 -0
- package/renderer/common/lazy-import.d.ts.map +1 -0
- package/renderer/common/use-lazy-module.d.ts +13 -0
- package/renderer/common/use-lazy-module.d.ts.map +1 -0
- package/renderer/common/use-renderer-theme.d.ts +35 -0
- package/renderer/common/use-renderer-theme.d.ts.map +1 -0
- package/renderer/csv/index.d.ts +12 -0
- package/renderer/csv/index.d.ts.map +1 -0
- package/renderer/csv/index.js +224 -0
- package/renderer/flow/index.d.ts +40 -0
- package/renderer/flow/index.d.ts.map +1 -0
- package/renderer/flow/index.js +290 -0
- package/renderer/html/index.d.ts +12 -0
- package/renderer/html/index.d.ts.map +1 -0
- package/renderer/html/index.js +130 -0
- package/renderer/image/index.d.ts +11 -0
- package/renderer/image/index.d.ts.map +1 -0
- package/renderer/image/index.js +156 -0
- package/renderer/index.d.ts +32 -0
- package/renderer/index.d.ts.map +1 -0
- package/renderer/index.js +2206 -0
- package/renderer/maps/index.d.ts +27 -0
- package/renderer/maps/index.d.ts.map +1 -0
- package/renderer/maps/index.js +248 -0
- package/renderer/math/index.d.ts +11 -0
- package/renderer/math/index.d.ts.map +1 -0
- package/renderer/math/index.js +260 -0
- package/renderer/mdx/index.d.ts +10 -0
- package/renderer/mdx/index.d.ts.map +1 -0
- package/renderer/mdx/index.js +292 -0
- package/renderer/media/index.d.ts +20 -0
- package/renderer/media/index.d.ts.map +1 -0
- package/renderer/media/index.js +266 -0
- package/renderer/mermaid/index.d.ts +11 -0
- package/renderer/mermaid/index.d.ts.map +1 -0
- package/renderer/mermaid/index.js +251 -0
- package/renderer/pdf/index.d.ts +10 -0
- package/renderer/pdf/index.d.ts.map +1 -0
- package/renderer/pdf/index.js +260 -0
- package/renderer/react/index.d.ts +45 -0
- package/renderer/react/index.d.ts.map +1 -0
- package/renderer/react/index.js +261 -0
- package/renderer/types.d.ts +24 -0
- package/renderer/types.d.ts.map +1 -0
- package/runtime/babel-runtime.d.ts +70 -0
- package/runtime/babel-runtime.d.ts.map +1 -0
- package/runtime/content-detector.d.ts +43 -0
- package/runtime/content-detector.d.ts.map +1 -0
- package/runtime/index.d.ts +10 -0
- package/runtime/index.d.ts.map +1 -0
- package/runtime/index.js +217 -0
- package/theme/FrontMcpThemeProvider.d.ts +4 -0
- package/theme/FrontMcpThemeProvider.d.ts.map +1 -0
- package/theme/create-theme.d.ts +9 -0
- package/theme/create-theme.d.ts.map +1 -0
- package/theme/index.d.ts +5 -0
- package/theme/index.d.ts.map +1 -0
- package/theme/index.js +126 -0
- package/theme/types.d.ts +28 -0
- package/theme/types.d.ts.map +1 -0
- package/theme/use-theme.d.ts +3 -0
- package/theme/use-theme.d.ts.map +1 -0
- package/bundler/browser-components.d.ts +0 -42
- package/bundler/browser-components.d.ts.map +0 -1
- package/bundler/bundler.d.ts +0 -282
- package/bundler/bundler.d.ts.map +0 -1
- package/bundler/index.d.ts +0 -43
- package/bundler/index.d.ts.map +0 -1
- package/bundler/index.js +0 -3168
- package/bundler/types.d.ts +0 -883
- package/bundler/types.d.ts.map +0 -1
- package/components/alert.d.ts +0 -83
- package/components/alert.d.ts.map +0 -1
- package/components/alert.schema.d.ts +0 -98
- package/components/alert.schema.d.ts.map +0 -1
- package/components/avatar.d.ts +0 -77
- package/components/avatar.d.ts.map +0 -1
- package/components/avatar.schema.d.ts +0 -170
- package/components/avatar.schema.d.ts.map +0 -1
- package/components/badge.d.ts +0 -78
- package/components/badge.d.ts.map +0 -1
- package/components/badge.schema.d.ts +0 -91
- package/components/badge.schema.d.ts.map +0 -1
- package/components/button.d.ts +0 -100
- package/components/button.d.ts.map +0 -1
- package/components/button.schema.d.ts +0 -120
- package/components/button.schema.d.ts.map +0 -1
- package/components/card.d.ts +0 -76
- package/components/card.d.ts.map +0 -1
- package/components/card.schema.d.ts +0 -93
- package/components/card.schema.d.ts.map +0 -1
- package/components/form.d.ts +0 -227
- package/components/form.d.ts.map +0 -1
- package/components/form.schema.d.ts +0 -365
- package/components/form.schema.d.ts.map +0 -1
- package/components/list.d.ts +0 -121
- package/components/list.d.ts.map +0 -1
- package/components/list.schema.d.ts +0 -129
- package/components/list.schema.d.ts.map +0 -1
- package/components/modal.d.ts +0 -100
- package/components/modal.d.ts.map +0 -1
- package/components/modal.schema.d.ts +0 -151
- package/components/modal.schema.d.ts.map +0 -1
- package/components/table.d.ts +0 -91
- package/components/table.d.ts.map +0 -1
- package/components/table.schema.d.ts +0 -123
- package/components/table.schema.d.ts.map +0 -1
- package/esm/bundler/index.mjs +0 -3136
- package/esm/layouts/index.mjs +0 -409
- package/esm/render/index.mjs +0 -45
- package/esm/renderers/index.mjs +0 -621
- package/esm/universal/index.mjs +0 -1946
- package/esm/web-components/index.mjs +0 -2023
- package/layouts/base.d.ts +0 -86
- package/layouts/base.d.ts.map +0 -1
- package/layouts/index.d.ts +0 -8
- package/layouts/index.d.ts.map +0 -1
- package/layouts/index.js +0 -437
- package/layouts/presets.d.ts +0 -134
- package/layouts/presets.d.ts.map +0 -1
- package/react/Alert.d.ts +0 -101
- package/react/Alert.d.ts.map +0 -1
- package/react/Badge.d.ts +0 -100
- package/react/Badge.d.ts.map +0 -1
- package/react/Button.d.ts +0 -108
- package/react/Button.d.ts.map +0 -1
- package/react/Card.d.ts +0 -103
- package/react/Card.d.ts.map +0 -1
- package/react/types.d.ts +0 -105
- package/react/types.d.ts.map +0 -1
- package/render/index.d.ts +0 -8
- package/render/index.d.ts.map +0 -1
- package/render/prerender.d.ts +0 -57
- package/render/prerender.d.ts.map +0 -1
- package/renderers/index.d.ts +0 -26
- package/renderers/index.d.ts.map +0 -1
- package/renderers/index.js +0 -666
- package/renderers/mdx.renderer.d.ts +0 -99
- package/renderers/mdx.renderer.d.ts.map +0 -1
- package/renderers/react.adapter.d.ts +0 -70
- package/renderers/react.adapter.d.ts.map +0 -1
- package/renderers/react.renderer.d.ts +0 -105
- package/renderers/react.renderer.d.ts.map +0 -1
- package/renderers/transpiler.d.ts +0 -49
- package/renderers/transpiler.d.ts.map +0 -1
- package/universal/UniversalApp.d.ts +0 -108
- package/universal/UniversalApp.d.ts.map +0 -1
- package/universal/cached-runtime.d.ts +0 -139
- package/universal/cached-runtime.d.ts.map +0 -1
- package/universal/context.d.ts +0 -122
- package/universal/context.d.ts.map +0 -1
- package/universal/index.d.ts +0 -57
- package/universal/index.d.ts.map +0 -1
- package/universal/index.js +0 -2032
- package/universal/renderers/html.renderer.d.ts +0 -36
- package/universal/renderers/html.renderer.d.ts.map +0 -1
- package/universal/renderers/index.d.ts +0 -112
- package/universal/renderers/index.d.ts.map +0 -1
- package/universal/renderers/markdown.renderer.d.ts +0 -33
- package/universal/renderers/markdown.renderer.d.ts.map +0 -1
- package/universal/renderers/mdx.renderer.d.ts +0 -38
- package/universal/renderers/mdx.renderer.d.ts.map +0 -1
- package/universal/renderers/react.renderer.d.ts +0 -46
- package/universal/renderers/react.renderer.d.ts.map +0 -1
- package/universal/runtime-builder.d.ts +0 -33
- package/universal/runtime-builder.d.ts.map +0 -1
- package/universal/store.d.ts +0 -135
- package/universal/store.d.ts.map +0 -1
- package/universal/types.d.ts +0 -199
- package/universal/types.d.ts.map +0 -1
- package/web-components/core/attribute-parser.d.ts +0 -82
- package/web-components/core/attribute-parser.d.ts.map +0 -1
- package/web-components/core/base-element.d.ts +0 -197
- package/web-components/core/base-element.d.ts.map +0 -1
- package/web-components/core/index.d.ts +0 -9
- package/web-components/core/index.d.ts.map +0 -1
- package/web-components/elements/fmcp-alert.d.ts +0 -46
- package/web-components/elements/fmcp-alert.d.ts.map +0 -1
- package/web-components/elements/fmcp-badge.d.ts +0 -47
- package/web-components/elements/fmcp-badge.d.ts.map +0 -1
- package/web-components/elements/fmcp-button.d.ts +0 -117
- package/web-components/elements/fmcp-button.d.ts.map +0 -1
- package/web-components/elements/fmcp-card.d.ts +0 -53
- package/web-components/elements/fmcp-card.d.ts.map +0 -1
- package/web-components/elements/fmcp-input.d.ts +0 -96
- package/web-components/elements/fmcp-input.d.ts.map +0 -1
- package/web-components/elements/fmcp-select.d.ts +0 -100
- package/web-components/elements/fmcp-select.d.ts.map +0 -1
- package/web-components/elements/index.d.ts +0 -13
- package/web-components/elements/index.d.ts.map +0 -1
- package/web-components/index.d.ts +0 -49
- package/web-components/index.d.ts.map +0 -1
- package/web-components/index.js +0 -2058
- package/web-components/register.d.ts +0 -57
- package/web-components/register.d.ts.map +0 -1
- package/web-components/types.d.ts +0 -122
- package/web-components/types.d.ts.map +0 -1
|
@@ -0,0 +1,2206 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// libs/ui/src/renderer/index.ts
|
|
31
|
+
var renderer_exports = {};
|
|
32
|
+
__export(renderer_exports, {
|
|
33
|
+
AudioRenderer: () => AudioRenderer,
|
|
34
|
+
ChartsRenderer: () => ChartsRenderer,
|
|
35
|
+
ContentView: () => ContentView,
|
|
36
|
+
CsvRenderer: () => CsvRenderer,
|
|
37
|
+
ESM_SH_BASE: () => ESM_SH_BASE,
|
|
38
|
+
FlowRenderer: () => FlowRenderer,
|
|
39
|
+
HtmlRenderer: () => HtmlRenderer,
|
|
40
|
+
ImageRenderer: () => ImageRenderer,
|
|
41
|
+
MapsRenderer: () => MapsRenderer,
|
|
42
|
+
MathRenderer: () => MathRenderer,
|
|
43
|
+
MdxRenderer: () => MdxRenderer,
|
|
44
|
+
MermaidRenderer: () => MermaidRenderer,
|
|
45
|
+
PdfRenderer: () => PdfRenderer,
|
|
46
|
+
ReactJsxRenderer: () => ReactJsxRenderer,
|
|
47
|
+
VideoRenderer: () => VideoRenderer,
|
|
48
|
+
audioRenderer: () => audioRenderer,
|
|
49
|
+
chartsRenderer: () => chartsRenderer,
|
|
50
|
+
clearRegistry: () => clearRegistry,
|
|
51
|
+
createLazyImport: () => createLazyImport,
|
|
52
|
+
csvRenderer: () => csvRenderer,
|
|
53
|
+
detectContentType: () => detectContentType2,
|
|
54
|
+
esmShUrl: () => esmShUrl,
|
|
55
|
+
extractThemeValues: () => extractThemeValues,
|
|
56
|
+
flowRenderer: () => flowRenderer,
|
|
57
|
+
getRegisteredRenderers: () => getRegisteredRenderers,
|
|
58
|
+
getRenderer: () => getRenderer,
|
|
59
|
+
htmlRenderer: () => htmlRenderer,
|
|
60
|
+
imageRenderer: () => imageRenderer,
|
|
61
|
+
injectStylesheet: () => injectStylesheet,
|
|
62
|
+
isAudio: () => isAudio,
|
|
63
|
+
isChart: () => isChart,
|
|
64
|
+
isFlow: () => isFlow,
|
|
65
|
+
isImage: () => isImage,
|
|
66
|
+
isMap: () => isMap,
|
|
67
|
+
isMath: () => isMath,
|
|
68
|
+
isMedia: () => isMedia,
|
|
69
|
+
isMermaid: () => isMermaid,
|
|
70
|
+
isReactJsx: () => isReactJsx,
|
|
71
|
+
isVideo: () => isVideo,
|
|
72
|
+
mapsRenderer: () => mapsRenderer,
|
|
73
|
+
mathRenderer: () => mathRenderer,
|
|
74
|
+
mdxRenderer: () => mdxRenderer,
|
|
75
|
+
mermaidRenderer: () => mermaidRenderer,
|
|
76
|
+
pdfRenderer: () => pdfRenderer,
|
|
77
|
+
reactJsxRenderer: () => reactJsxRenderer,
|
|
78
|
+
registerAllRenderers: () => registerAllRenderers,
|
|
79
|
+
registerRenderer: () => registerRenderer,
|
|
80
|
+
renderContent: () => renderContent,
|
|
81
|
+
runtimeImportWithFallback: () => runtimeImportWithFallback,
|
|
82
|
+
useLazyModule: () => useLazyModule,
|
|
83
|
+
useRendererTheme: () => useRendererTheme,
|
|
84
|
+
videoRenderer: () => videoRenderer
|
|
85
|
+
});
|
|
86
|
+
module.exports = __toCommonJS(renderer_exports);
|
|
87
|
+
|
|
88
|
+
// libs/ui/src/renderer/auto-detect.ts
|
|
89
|
+
var import_react = __toESM(require("react"));
|
|
90
|
+
|
|
91
|
+
// libs/ui/src/runtime/content-detector.ts
|
|
92
|
+
var JSX_PATTERNS = [
|
|
93
|
+
// JSX-specific syntax: self-closing tags with capitalized names
|
|
94
|
+
/<[A-Z][a-zA-Z0-9]*[\s/>]/,
|
|
95
|
+
// JSX expressions: {someVar} or {() => ...}
|
|
96
|
+
/\{[a-zA-Z_$][\w$.]*\}/,
|
|
97
|
+
// React hooks: useState, useEffect, etc.
|
|
98
|
+
/\buse[A-Z]\w+\s*\(/,
|
|
99
|
+
// Arrow function components or function declarations: const Foo = / function Foo(
|
|
100
|
+
/(?:const|let|var|function)\s+[A-Z]\w*\s*[=(]/,
|
|
101
|
+
// Import from react
|
|
102
|
+
/import\s[^\n]{1,200}from\s+['"]react['"]/,
|
|
103
|
+
// JSX pragma or import
|
|
104
|
+
/\/\*\*?\s*@jsx\b/,
|
|
105
|
+
// export default function/const (component pattern)
|
|
106
|
+
/export\s+default\s+function\s+[A-Z]/
|
|
107
|
+
];
|
|
108
|
+
var MDX_PATTERNS = [
|
|
109
|
+
// MDX frontmatter
|
|
110
|
+
/^---\s*\n/,
|
|
111
|
+
// Markdown headings
|
|
112
|
+
/^#{1,6}\s+\S/m,
|
|
113
|
+
// MDX import statements followed by markdown
|
|
114
|
+
/^import\s[^\n]*\n+#/m,
|
|
115
|
+
// MDX export default (layout pattern)
|
|
116
|
+
/^export\s+default\s+/m,
|
|
117
|
+
// Markdown bullet lists
|
|
118
|
+
/^\s*[-*+]\s+\S/m,
|
|
119
|
+
// Markdown links
|
|
120
|
+
/\[[^\]]+\]\([^)]+\)/,
|
|
121
|
+
// Markdown code blocks
|
|
122
|
+
/^```\w*/m,
|
|
123
|
+
// Markdown emphasis
|
|
124
|
+
/(?:\*\*|__)(?:(?!\*\*|__).)+(?:\*\*|__)/
|
|
125
|
+
];
|
|
126
|
+
var CHART_TYPE_RE = /"type"\s*:\s*"(?:bar|line|area|pie|scatter|radar|composed)"/;
|
|
127
|
+
var MERMAID_PATTERN = /^\s*(?:graph|sequenceDiagram|classDiagram|stateDiagram|flowchart|erDiagram|gantt|pie|journey|gitGraph)\b/;
|
|
128
|
+
function looksLikeChart(s) {
|
|
129
|
+
return s.charCodeAt(0) === 123 && CHART_TYPE_RE.test(s) && s.includes('"data"');
|
|
130
|
+
}
|
|
131
|
+
function looksLikeFlow(s) {
|
|
132
|
+
return s.charCodeAt(0) === 123 && s.includes('"nodes"') && s.includes('"edges"');
|
|
133
|
+
}
|
|
134
|
+
var MATH_PATTERNS = [
|
|
135
|
+
/\$\$(?:[^$]|\$(?!\$))+\$\$/s,
|
|
136
|
+
/\$[^$\n]+?\$/,
|
|
137
|
+
/\\\[(?:[^\\]|\\.)*\\\]/s,
|
|
138
|
+
/\\\((?:[^\\]|\\.)*\\\)/s,
|
|
139
|
+
/\\begin\{(?:equation|align|gather|matrix|pmatrix|bmatrix|cases)\}/
|
|
140
|
+
];
|
|
141
|
+
var GEOJSON_TYPE_RE = /"type"\s*:\s*"(?:FeatureCollection|Feature|Point|LineString|Polygon|MultiPoint|MultiLineString|MultiPolygon|GeometryCollection)"/;
|
|
142
|
+
function looksLikeMap(s) {
|
|
143
|
+
return s.charCodeAt(0) === 123 && GEOJSON_TYPE_RE.test(s);
|
|
144
|
+
}
|
|
145
|
+
var IMAGE_PATTERNS = [
|
|
146
|
+
/^data:image\/(?:png|jpeg|jpg|gif|webp|svg\+xml)[;,]/,
|
|
147
|
+
/^https?:\/\/[^?#\s]+\.(?:png|jpe?g|gif|webp|svg|avif|ico)(?:\?[^#\s]*)?$/i
|
|
148
|
+
];
|
|
149
|
+
var VIDEO_PATTERNS = [
|
|
150
|
+
/^https?:\/\/[^?#\s]+\.(?:mp4|webm|ogg|mov)(?:\?[^#\s]*)?$/i,
|
|
151
|
+
/^https?:\/\/(?:www\.)?(?:youtube\.com|youtu\.be|vimeo\.com)\//i,
|
|
152
|
+
/^data:video\//
|
|
153
|
+
];
|
|
154
|
+
var AUDIO_PATTERNS = [
|
|
155
|
+
/^https?:\/\/[^?#\s]+\.(?:mp3|wav|ogg|aac|flac|m4a)(?:\?[^#\s]*)?$/i,
|
|
156
|
+
/^https?:\/\/(?:www\.)?soundcloud\.com\//i,
|
|
157
|
+
/^data:audio\//
|
|
158
|
+
];
|
|
159
|
+
function detectContentType(content) {
|
|
160
|
+
if (!content || typeof content !== "string") {
|
|
161
|
+
return "html";
|
|
162
|
+
}
|
|
163
|
+
const trimmed = content.trim();
|
|
164
|
+
if (looksLikeChart(trimmed)) return "chart";
|
|
165
|
+
if (looksLikeFlow(trimmed)) return "flow";
|
|
166
|
+
if (looksLikeMap(trimmed)) return "map";
|
|
167
|
+
if (MERMAID_PATTERN.test(trimmed)) return "mermaid";
|
|
168
|
+
if (MATH_PATTERNS.some((p) => p.test(trimmed))) return "math";
|
|
169
|
+
if (IMAGE_PATTERNS.some((p) => p.test(trimmed))) return "image";
|
|
170
|
+
if (VIDEO_PATTERNS.some((p) => p.test(trimmed))) return "video";
|
|
171
|
+
if (AUDIO_PATTERNS.some((p) => p.test(trimmed))) return "audio";
|
|
172
|
+
const jsxScore = countMatches(trimmed, JSX_PATTERNS);
|
|
173
|
+
const mdxScore = countMatches(trimmed, MDX_PATTERNS);
|
|
174
|
+
if (jsxScore > 0 && jsxScore >= mdxScore) {
|
|
175
|
+
return "jsx";
|
|
176
|
+
}
|
|
177
|
+
if (mdxScore >= 2) {
|
|
178
|
+
return "mdx";
|
|
179
|
+
}
|
|
180
|
+
if (mdxScore === 1 && /^import\s+/m.test(trimmed)) {
|
|
181
|
+
return "mdx";
|
|
182
|
+
}
|
|
183
|
+
return "html";
|
|
184
|
+
}
|
|
185
|
+
function countMatches(content, patterns) {
|
|
186
|
+
let count = 0;
|
|
187
|
+
for (const pattern of patterns) {
|
|
188
|
+
if (pattern.test(content)) {
|
|
189
|
+
count++;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
return count;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// libs/ui/src/renderer/auto-detect.ts
|
|
196
|
+
var PDF_HEADER = "%PDF-";
|
|
197
|
+
var BASE64_PDF_PREFIX = "JVBER";
|
|
198
|
+
function isPdf(content) {
|
|
199
|
+
if (content.startsWith(PDF_HEADER)) return true;
|
|
200
|
+
const trimmed = content.trim();
|
|
201
|
+
return trimmed.startsWith(BASE64_PDF_PREFIX) || /^data:application\/pdf[;,]/.test(trimmed);
|
|
202
|
+
}
|
|
203
|
+
function isCsv(content) {
|
|
204
|
+
const lines = content.trim().split("\n").slice(0, 5);
|
|
205
|
+
if (lines.length < 2) return false;
|
|
206
|
+
for (const delim of [",", " ", ";"]) {
|
|
207
|
+
const counts = lines.map((line) => line.split(delim).length);
|
|
208
|
+
if (counts[0] > 1 && counts.every((c) => c === counts[0])) return true;
|
|
209
|
+
}
|
|
210
|
+
return false;
|
|
211
|
+
}
|
|
212
|
+
function detectContentType2(content) {
|
|
213
|
+
if (isPdf(content)) return "pdf";
|
|
214
|
+
if (isCsv(content)) return "csv";
|
|
215
|
+
return detectContentType(content);
|
|
216
|
+
}
|
|
217
|
+
var rendererRegistry = [];
|
|
218
|
+
var rendererByType = /* @__PURE__ */ new Map();
|
|
219
|
+
function sortRegistry() {
|
|
220
|
+
rendererRegistry.sort((a, b) => (b.priority ?? 0) - (a.priority ?? 0));
|
|
221
|
+
}
|
|
222
|
+
function registerRenderer(renderer) {
|
|
223
|
+
if (rendererByType.has(renderer.type)) {
|
|
224
|
+
const idx = rendererRegistry.findIndex((r) => r.type === renderer.type);
|
|
225
|
+
if (idx !== -1) rendererRegistry.splice(idx, 1);
|
|
226
|
+
}
|
|
227
|
+
rendererRegistry.push(renderer);
|
|
228
|
+
rendererByType.set(renderer.type, renderer);
|
|
229
|
+
sortRegistry();
|
|
230
|
+
}
|
|
231
|
+
function clearRegistry() {
|
|
232
|
+
rendererRegistry.length = 0;
|
|
233
|
+
rendererByType.clear();
|
|
234
|
+
}
|
|
235
|
+
function getRenderer(type) {
|
|
236
|
+
return rendererByType.get(type);
|
|
237
|
+
}
|
|
238
|
+
function getRegisteredRenderers() {
|
|
239
|
+
return rendererRegistry;
|
|
240
|
+
}
|
|
241
|
+
function renderContent(content, options) {
|
|
242
|
+
const type = detectContentType2(content);
|
|
243
|
+
for (const renderer of rendererRegistry) {
|
|
244
|
+
if (renderer.canHandle(content)) {
|
|
245
|
+
return renderer.render(content, options);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
const exact = rendererByType.get(type);
|
|
249
|
+
if (exact) {
|
|
250
|
+
return exact.render(content, options);
|
|
251
|
+
}
|
|
252
|
+
throw new Error(`No renderer found for content type: ${type}`);
|
|
253
|
+
}
|
|
254
|
+
function ContentView({ content, options, fallback }) {
|
|
255
|
+
return import_react.default.createElement(
|
|
256
|
+
import_react.Suspense,
|
|
257
|
+
{ fallback: fallback ?? import_react.default.createElement("div", { className: "fmcp-content-loading" }, "Loading...") },
|
|
258
|
+
import_react.default.createElement(ContentViewInner, { content, options })
|
|
259
|
+
);
|
|
260
|
+
}
|
|
261
|
+
function ContentViewInner({ content, options }) {
|
|
262
|
+
return renderContent(content, options);
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
// libs/ui/src/renderer/common/use-renderer-theme.ts
|
|
266
|
+
var import_react2 = require("react");
|
|
267
|
+
var import_styles = require("@mui/material/styles");
|
|
268
|
+
function extractThemeValues(theme) {
|
|
269
|
+
const palette = theme.palette;
|
|
270
|
+
return {
|
|
271
|
+
mode: palette.mode,
|
|
272
|
+
primary: palette.primary.main,
|
|
273
|
+
secondary: palette.secondary.main,
|
|
274
|
+
error: palette.error.main,
|
|
275
|
+
warning: palette.warning.main,
|
|
276
|
+
success: palette.success.main,
|
|
277
|
+
info: palette.info.main,
|
|
278
|
+
background: palette.background.default,
|
|
279
|
+
paper: palette.background.paper,
|
|
280
|
+
textPrimary: palette.text.primary,
|
|
281
|
+
textSecondary: palette.text.secondary,
|
|
282
|
+
divider: palette.divider,
|
|
283
|
+
fontFamily: theme.typography.fontFamily ?? "sans-serif",
|
|
284
|
+
monoFontFamily: theme.typography["monoFontFamily"] ?? '"SF Mono", "Fira Code", "Fira Mono", "Roboto Mono", monospace',
|
|
285
|
+
fontSize: theme.typography.fontSize ?? 14,
|
|
286
|
+
borderRadius: typeof theme.shape.borderRadius === "number" ? theme.shape.borderRadius : 4,
|
|
287
|
+
seriesColors: [
|
|
288
|
+
palette.primary.main,
|
|
289
|
+
palette.secondary.main,
|
|
290
|
+
palette.error.main,
|
|
291
|
+
palette.warning.main,
|
|
292
|
+
palette.success.main,
|
|
293
|
+
palette.info.main
|
|
294
|
+
]
|
|
295
|
+
};
|
|
296
|
+
}
|
|
297
|
+
function useRendererTheme() {
|
|
298
|
+
const theme = (0, import_styles.useTheme)();
|
|
299
|
+
return (0, import_react2.useMemo)(() => extractThemeValues(theme), [theme]);
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
// libs/ui/src/renderer/common/inject-stylesheet.ts
|
|
303
|
+
function injectStylesheet(href, id) {
|
|
304
|
+
if (typeof document === "undefined") return;
|
|
305
|
+
if (document.getElementById(id)) return;
|
|
306
|
+
const link = document.createElement("link");
|
|
307
|
+
link.id = id;
|
|
308
|
+
link.rel = "stylesheet";
|
|
309
|
+
link.href = href;
|
|
310
|
+
link.crossOrigin = "anonymous";
|
|
311
|
+
document.head.appendChild(link);
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
// libs/ui/src/renderer/common/lazy-import.ts
|
|
315
|
+
var ESM_SH_BASE = "https://esm.sh/";
|
|
316
|
+
function esmShUrl(pkg, options) {
|
|
317
|
+
let url = `${ESM_SH_BASE}${pkg}`;
|
|
318
|
+
if (options?.external?.length) {
|
|
319
|
+
url += `?external=${options.external.join(",")}`;
|
|
320
|
+
}
|
|
321
|
+
return url;
|
|
322
|
+
}
|
|
323
|
+
function runtimeImport(specifier) {
|
|
324
|
+
const dynamicImport = new Function("s", "return import(s)");
|
|
325
|
+
return dynamicImport(specifier);
|
|
326
|
+
}
|
|
327
|
+
async function runtimeImportWithFallback(bareSpecifier, fallbackUrl) {
|
|
328
|
+
try {
|
|
329
|
+
return await runtimeImport(bareSpecifier);
|
|
330
|
+
} catch {
|
|
331
|
+
return runtimeImport(fallbackUrl);
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
function createLazyImport(moduleId, importer) {
|
|
335
|
+
let state = { status: "idle" };
|
|
336
|
+
const doImport = importer ?? (async () => {
|
|
337
|
+
const mod = await runtimeImport(moduleId);
|
|
338
|
+
return mod["default"] ?? mod;
|
|
339
|
+
});
|
|
340
|
+
return {
|
|
341
|
+
load() {
|
|
342
|
+
if (state.status === "loaded") return Promise.resolve(state.module);
|
|
343
|
+
if (state.status === "loading") return state.promise;
|
|
344
|
+
if (state.status === "error") {
|
|
345
|
+
state = { status: "idle" };
|
|
346
|
+
}
|
|
347
|
+
const promise = doImport().then(
|
|
348
|
+
(mod) => {
|
|
349
|
+
state = { status: "loaded", module: mod };
|
|
350
|
+
return mod;
|
|
351
|
+
},
|
|
352
|
+
(err) => {
|
|
353
|
+
const error = err instanceof Error ? err : new Error(`Failed to load module "${moduleId}": ${String(err)}`);
|
|
354
|
+
state = { status: "error", error };
|
|
355
|
+
throw error;
|
|
356
|
+
}
|
|
357
|
+
);
|
|
358
|
+
state = { status: "loading", promise };
|
|
359
|
+
return promise;
|
|
360
|
+
},
|
|
361
|
+
get() {
|
|
362
|
+
return state.status === "loaded" ? state.module : void 0;
|
|
363
|
+
},
|
|
364
|
+
getState() {
|
|
365
|
+
return state;
|
|
366
|
+
},
|
|
367
|
+
reset() {
|
|
368
|
+
state = { status: "idle" };
|
|
369
|
+
}
|
|
370
|
+
};
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
// libs/ui/src/renderer/common/use-lazy-module.ts
|
|
374
|
+
var import_react3 = require("react");
|
|
375
|
+
function useLazyModule(lazy) {
|
|
376
|
+
const [, forceUpdate] = (0, import_react3.useState)(0);
|
|
377
|
+
(0, import_react3.useEffect)(() => {
|
|
378
|
+
if (lazy.getState().status === "loaded") {
|
|
379
|
+
forceUpdate((n) => n + 1);
|
|
380
|
+
return;
|
|
381
|
+
}
|
|
382
|
+
lazy.load().then(
|
|
383
|
+
() => forceUpdate((n) => n + 1),
|
|
384
|
+
() => forceUpdate((n) => n + 1)
|
|
385
|
+
);
|
|
386
|
+
}, [lazy]);
|
|
387
|
+
return lazy.get();
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
// libs/ui/src/renderer/mdx/index.ts
|
|
391
|
+
var import_react4 = __toESM(require("react"));
|
|
392
|
+
var import_Box = __toESM(require("@mui/material/Box"));
|
|
393
|
+
var import_Typography = __toESM(require("@mui/material/Typography"));
|
|
394
|
+
var import_Link = __toESM(require("@mui/material/Link"));
|
|
395
|
+
var import_Table = __toESM(require("@mui/material/Table"));
|
|
396
|
+
var import_TableBody = __toESM(require("@mui/material/TableBody"));
|
|
397
|
+
var import_TableCell = __toESM(require("@mui/material/TableCell"));
|
|
398
|
+
var import_TableHead = __toESM(require("@mui/material/TableHead"));
|
|
399
|
+
var import_TableRow = __toESM(require("@mui/material/TableRow"));
|
|
400
|
+
var import_styles2 = require("@mui/material/styles");
|
|
401
|
+
var lazyReactMarkdown = createLazyImport(
|
|
402
|
+
"react-markdown",
|
|
403
|
+
async () => {
|
|
404
|
+
const mod = await runtimeImportWithFallback(
|
|
405
|
+
"react-markdown",
|
|
406
|
+
esmShUrl("react-markdown@9", { external: ["react", "react-dom"] })
|
|
407
|
+
);
|
|
408
|
+
return mod;
|
|
409
|
+
}
|
|
410
|
+
);
|
|
411
|
+
var lazyRemarkGfm = createLazyImport("remark-gfm", async () => {
|
|
412
|
+
const mod = await runtimeImportWithFallback("remark-gfm", esmShUrl("remark-gfm@4"));
|
|
413
|
+
return mod;
|
|
414
|
+
});
|
|
415
|
+
var lazyRehypeHighlight = createLazyImport("rehype-highlight", async () => {
|
|
416
|
+
const mod = await runtimeImportWithFallback("rehype-highlight", esmShUrl("rehype-highlight@7"));
|
|
417
|
+
return mod;
|
|
418
|
+
});
|
|
419
|
+
var lazyRehypeRaw = createLazyImport("rehype-raw", async () => {
|
|
420
|
+
const mod = await runtimeImportWithFallback("rehype-raw", esmShUrl("rehype-raw@7"));
|
|
421
|
+
return mod;
|
|
422
|
+
});
|
|
423
|
+
var MarkdownRoot = (0, import_styles2.styled)(import_Box.default, {
|
|
424
|
+
name: "FrontMcpMarkdown",
|
|
425
|
+
slot: "Root"
|
|
426
|
+
})(() => ({
|
|
427
|
+
lineHeight: 1.7,
|
|
428
|
+
"& > *:first-of-type": { marginTop: 0 },
|
|
429
|
+
"& > *:last-child": { marginBottom: 0 },
|
|
430
|
+
"& img": { maxWidth: "100%", height: "auto" }
|
|
431
|
+
}));
|
|
432
|
+
var CodeBlock = (0, import_styles2.styled)("pre", {
|
|
433
|
+
name: "FrontMcpMarkdown",
|
|
434
|
+
slot: "Code"
|
|
435
|
+
})(({ theme }) => {
|
|
436
|
+
const monoFont = String(
|
|
437
|
+
theme.typography["monoFontFamily"] ?? '"SF Mono", "Fira Code", "Roboto Mono", monospace'
|
|
438
|
+
);
|
|
439
|
+
return {
|
|
440
|
+
backgroundColor: theme.palette.mode === "dark" ? theme.palette.grey[900] : theme.palette.grey[100],
|
|
441
|
+
padding: theme.spacing(2),
|
|
442
|
+
borderRadius: Number(theme.shape.borderRadius),
|
|
443
|
+
overflow: "auto",
|
|
444
|
+
fontFamily: monoFont,
|
|
445
|
+
fontSize: "0.875rem",
|
|
446
|
+
"& code": {
|
|
447
|
+
backgroundColor: "transparent",
|
|
448
|
+
padding: 0,
|
|
449
|
+
fontSize: "inherit",
|
|
450
|
+
fontFamily: "inherit"
|
|
451
|
+
}
|
|
452
|
+
};
|
|
453
|
+
});
|
|
454
|
+
var InlineCode = (0, import_styles2.styled)("code")(({ theme }) => {
|
|
455
|
+
const monoFont = String(
|
|
456
|
+
theme.typography["monoFontFamily"] ?? '"SF Mono", "Fira Code", "Roboto Mono", monospace'
|
|
457
|
+
);
|
|
458
|
+
return {
|
|
459
|
+
backgroundColor: theme.palette.mode === "dark" ? theme.palette.grey[800] : theme.palette.grey[200],
|
|
460
|
+
padding: "2px 6px",
|
|
461
|
+
borderRadius: Number(theme.shape.borderRadius) / 2,
|
|
462
|
+
fontFamily: monoFont,
|
|
463
|
+
fontSize: "0.85em"
|
|
464
|
+
};
|
|
465
|
+
});
|
|
466
|
+
var Blockquote = (0, import_styles2.styled)("blockquote", {
|
|
467
|
+
name: "FrontMcpMarkdown",
|
|
468
|
+
slot: "Blockquote"
|
|
469
|
+
})(({ theme }) => ({
|
|
470
|
+
borderLeft: `4px solid ${theme.palette.primary.main}`,
|
|
471
|
+
margin: theme.spacing(2, 0),
|
|
472
|
+
padding: theme.spacing(1, 2),
|
|
473
|
+
color: theme.palette.text.secondary,
|
|
474
|
+
"& > p": { margin: 0 }
|
|
475
|
+
}));
|
|
476
|
+
function createMuiComponents() {
|
|
477
|
+
return {
|
|
478
|
+
h1: (props) => import_react4.default.createElement(import_Typography.default, { ...props, variant: "h4", gutterBottom: true }),
|
|
479
|
+
h2: (props) => import_react4.default.createElement(import_Typography.default, { ...props, variant: "h5", gutterBottom: true }),
|
|
480
|
+
h3: (props) => import_react4.default.createElement(import_Typography.default, { ...props, variant: "h6", gutterBottom: true }),
|
|
481
|
+
h4: (props) => import_react4.default.createElement(import_Typography.default, { ...props, variant: "subtitle1", gutterBottom: true, fontWeight: 600 }),
|
|
482
|
+
h5: (props) => import_react4.default.createElement(import_Typography.default, { ...props, variant: "subtitle2", gutterBottom: true }),
|
|
483
|
+
h6: (props) => import_react4.default.createElement(import_Typography.default, { ...props, variant: "subtitle2", gutterBottom: true }),
|
|
484
|
+
p: (props) => import_react4.default.createElement(import_Typography.default, { ...props, variant: "body1", paragraph: true }),
|
|
485
|
+
a: (props) => import_react4.default.createElement(import_Link.default, { ...props, target: "_blank", rel: "noopener noreferrer" }),
|
|
486
|
+
blockquote: (props) => import_react4.default.createElement(Blockquote, props),
|
|
487
|
+
pre: (props) => import_react4.default.createElement(CodeBlock, props),
|
|
488
|
+
code: ({ inline, className, children, ...rest }) => {
|
|
489
|
+
if (inline) return import_react4.default.createElement(InlineCode, rest, children);
|
|
490
|
+
return import_react4.default.createElement("code", { className, ...rest }, children);
|
|
491
|
+
},
|
|
492
|
+
table: (props) => import_react4.default.createElement(import_Table.default, { ...props, size: "small" }),
|
|
493
|
+
thead: (props) => import_react4.default.createElement(import_TableHead.default, props),
|
|
494
|
+
tbody: (props) => import_react4.default.createElement(import_TableBody.default, props),
|
|
495
|
+
tr: (props) => import_react4.default.createElement(import_TableRow.default, { ...props, hover: true }),
|
|
496
|
+
th: (props) => import_react4.default.createElement(import_TableCell.default, { ...props, sx: { fontWeight: 600 } }),
|
|
497
|
+
td: (props) => import_react4.default.createElement(import_TableCell.default, props)
|
|
498
|
+
};
|
|
499
|
+
}
|
|
500
|
+
function MarkdownView({ content, className }) {
|
|
501
|
+
const components = (0, import_react4.useMemo)(() => createMuiComponents(), []);
|
|
502
|
+
const ReactMarkdownMod = useLazyModule(lazyReactMarkdown);
|
|
503
|
+
const remarkGfmMod = lazyRemarkGfm.get();
|
|
504
|
+
const rehypeHighlightMod = lazyRehypeHighlight.get();
|
|
505
|
+
const rehypeRawMod = lazyRehypeRaw.get();
|
|
506
|
+
if (ReactMarkdownMod) {
|
|
507
|
+
const ReactMarkdown = ReactMarkdownMod.default;
|
|
508
|
+
const remarkPlugins = [];
|
|
509
|
+
const rehypePlugins = [];
|
|
510
|
+
if (remarkGfmMod) remarkPlugins.push(remarkGfmMod.default);
|
|
511
|
+
if (rehypeHighlightMod) rehypePlugins.push(rehypeHighlightMod.default);
|
|
512
|
+
if (rehypeRawMod) rehypePlugins.push(rehypeRawMod.default);
|
|
513
|
+
return import_react4.default.createElement(
|
|
514
|
+
MarkdownRoot,
|
|
515
|
+
{ className },
|
|
516
|
+
import_react4.default.createElement(ReactMarkdown, {
|
|
517
|
+
children: content,
|
|
518
|
+
remarkPlugins,
|
|
519
|
+
rehypePlugins,
|
|
520
|
+
components
|
|
521
|
+
})
|
|
522
|
+
);
|
|
523
|
+
}
|
|
524
|
+
return import_react4.default.createElement(MarkdownRoot, { className }, ...renderFallback(content));
|
|
525
|
+
}
|
|
526
|
+
function renderFallback(content) {
|
|
527
|
+
const lines = content.split("\n");
|
|
528
|
+
const elements = [];
|
|
529
|
+
for (let i = 0; i < lines.length; i++) {
|
|
530
|
+
const line = lines[i];
|
|
531
|
+
if (line.startsWith("# ")) {
|
|
532
|
+
elements.push(import_react4.default.createElement(import_Typography.default, { key: i, variant: "h4", gutterBottom: true }, line.slice(2)));
|
|
533
|
+
} else if (line.startsWith("## ")) {
|
|
534
|
+
elements.push(import_react4.default.createElement(import_Typography.default, { key: i, variant: "h5", gutterBottom: true }, line.slice(3)));
|
|
535
|
+
} else if (line.startsWith("### ")) {
|
|
536
|
+
elements.push(import_react4.default.createElement(import_Typography.default, { key: i, variant: "h6", gutterBottom: true }, line.slice(4)));
|
|
537
|
+
} else if (line.startsWith("- ") || line.startsWith("* ")) {
|
|
538
|
+
elements.push(import_react4.default.createElement("li", { key: i }, line.slice(2)));
|
|
539
|
+
} else if (line.startsWith("**") && line.endsWith("**")) {
|
|
540
|
+
elements.push(import_react4.default.createElement(import_Typography.default, { key: i, variant: "body1", fontWeight: 700 }, line.slice(2, -2)));
|
|
541
|
+
} else if (line.trim()) {
|
|
542
|
+
elements.push(import_react4.default.createElement(import_Typography.default, { key: i, variant: "body1", paragraph: true }, line));
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
return elements;
|
|
546
|
+
}
|
|
547
|
+
lazyReactMarkdown.load().catch(() => {
|
|
548
|
+
});
|
|
549
|
+
lazyRemarkGfm.load().catch(() => {
|
|
550
|
+
});
|
|
551
|
+
lazyRehypeHighlight.load().catch(() => {
|
|
552
|
+
});
|
|
553
|
+
lazyRehypeRaw.load().catch(() => {
|
|
554
|
+
});
|
|
555
|
+
var MdxRenderer = class {
|
|
556
|
+
type = "mdx";
|
|
557
|
+
priority = 5;
|
|
558
|
+
canHandle(content) {
|
|
559
|
+
return /^---\s*\n/.test(content) || /import\s+/.test(content) || /<[A-Z]/.test(content) || /^#{1,6}\s+\S/m.test(content) || /^\s*[-*+]\s+\S/m.test(content);
|
|
560
|
+
}
|
|
561
|
+
render(content, options) {
|
|
562
|
+
return import_react4.default.createElement(MarkdownView, {
|
|
563
|
+
content,
|
|
564
|
+
className: options?.className ?? "fmcp-mdx-content"
|
|
565
|
+
});
|
|
566
|
+
}
|
|
567
|
+
};
|
|
568
|
+
var mdxRenderer = new MdxRenderer();
|
|
569
|
+
|
|
570
|
+
// libs/ui/src/renderer/html/index.ts
|
|
571
|
+
var import_react5 = __toESM(require("react"));
|
|
572
|
+
var import_Box2 = __toESM(require("@mui/material/Box"));
|
|
573
|
+
var import_styles3 = require("@mui/material/styles");
|
|
574
|
+
var HtmlRoot = (0, import_styles3.styled)(import_Box2.default, {
|
|
575
|
+
name: "FrontMcpHtml",
|
|
576
|
+
slot: "Root"
|
|
577
|
+
})(({ theme }) => ({
|
|
578
|
+
"& a": { color: theme.palette.primary.main },
|
|
579
|
+
"& table": { borderCollapse: "collapse", width: "100%" },
|
|
580
|
+
"& th, & td": { border: `1px solid ${theme.palette.divider}`, padding: theme.spacing(1) },
|
|
581
|
+
"& pre": {
|
|
582
|
+
backgroundColor: theme.palette.mode === "dark" ? theme.palette.grey[900] : theme.palette.grey[100],
|
|
583
|
+
padding: theme.spacing(1.5),
|
|
584
|
+
borderRadius: theme.shape.borderRadius,
|
|
585
|
+
overflow: "auto"
|
|
586
|
+
}
|
|
587
|
+
}));
|
|
588
|
+
var purifyModule = null;
|
|
589
|
+
var purifyPromise = null;
|
|
590
|
+
function loadDOMPurify() {
|
|
591
|
+
if (purifyModule) return Promise.resolve(purifyModule);
|
|
592
|
+
if (purifyPromise) return purifyPromise;
|
|
593
|
+
purifyPromise = runtimeImportWithFallback("dompurify", esmShUrl("dompurify@3")).then((mod) => {
|
|
594
|
+
purifyModule = mod;
|
|
595
|
+
return purifyModule;
|
|
596
|
+
}).catch(() => {
|
|
597
|
+
purifyModule = null;
|
|
598
|
+
purifyPromise = null;
|
|
599
|
+
return null;
|
|
600
|
+
});
|
|
601
|
+
return purifyPromise;
|
|
602
|
+
}
|
|
603
|
+
function escapeHtml(html) {
|
|
604
|
+
return html.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
605
|
+
}
|
|
606
|
+
function sanitizeSync(html) {
|
|
607
|
+
if (!purifyModule) return escapeHtml(html);
|
|
608
|
+
const sanitize = purifyModule.default?.sanitize ?? purifyModule.sanitize;
|
|
609
|
+
return sanitize ? sanitize(html) : escapeHtml(html);
|
|
610
|
+
}
|
|
611
|
+
loadDOMPurify();
|
|
612
|
+
function HtmlView({ html, className }) {
|
|
613
|
+
const [purifyReady, setPurifyReady] = (0, import_react5.useState)(!!purifyModule);
|
|
614
|
+
(0, import_react5.useEffect)(() => {
|
|
615
|
+
if (!purifyModule) {
|
|
616
|
+
loadDOMPurify().then((mod) => {
|
|
617
|
+
if (mod) setPurifyReady(true);
|
|
618
|
+
});
|
|
619
|
+
}
|
|
620
|
+
}, []);
|
|
621
|
+
const sanitized = (0, import_react5.useMemo)(() => sanitizeSync(html), [html, purifyReady]);
|
|
622
|
+
return import_react5.default.createElement(HtmlRoot, {
|
|
623
|
+
className,
|
|
624
|
+
dangerouslySetInnerHTML: { __html: sanitized }
|
|
625
|
+
});
|
|
626
|
+
}
|
|
627
|
+
var HtmlRenderer = class {
|
|
628
|
+
type = "html";
|
|
629
|
+
priority = 0;
|
|
630
|
+
canHandle(content) {
|
|
631
|
+
return /^\s*</.test(content) && /<\/\w+>/.test(content);
|
|
632
|
+
}
|
|
633
|
+
render(content, options) {
|
|
634
|
+
return import_react5.default.createElement(HtmlView, {
|
|
635
|
+
html: content,
|
|
636
|
+
className: options?.className ?? "fmcp-html-content"
|
|
637
|
+
});
|
|
638
|
+
}
|
|
639
|
+
};
|
|
640
|
+
var htmlRenderer = new HtmlRenderer();
|
|
641
|
+
|
|
642
|
+
// libs/ui/src/renderer/react/index.ts
|
|
643
|
+
var import_react6 = __toESM(require("react"));
|
|
644
|
+
var import_Box3 = __toESM(require("@mui/material/Box"));
|
|
645
|
+
var import_Alert = __toESM(require("@mui/material/Alert"));
|
|
646
|
+
|
|
647
|
+
// libs/ui/src/runtime/babel-runtime.ts
|
|
648
|
+
var BABEL_STANDALONE_CDN = "https://esm.sh/@babel/standalone@7";
|
|
649
|
+
var BABEL_STANDALONE_FALLBACK_CDN = "https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/7.26.10/babel.min.js";
|
|
650
|
+
var babelState = { status: "idle" };
|
|
651
|
+
async function loadBabel() {
|
|
652
|
+
if (babelState.status === "loaded") {
|
|
653
|
+
return babelState.babel;
|
|
654
|
+
}
|
|
655
|
+
if (babelState.status === "loading") {
|
|
656
|
+
return babelState.promise;
|
|
657
|
+
}
|
|
658
|
+
if (babelState.status === "error") {
|
|
659
|
+
throw babelState.error;
|
|
660
|
+
}
|
|
661
|
+
const promise = doLoadBabel();
|
|
662
|
+
babelState = { status: "loading", promise };
|
|
663
|
+
try {
|
|
664
|
+
const babel = await promise;
|
|
665
|
+
babelState = { status: "loaded", babel };
|
|
666
|
+
return babel;
|
|
667
|
+
} catch (error) {
|
|
668
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
669
|
+
babelState = { status: "error", error: err };
|
|
670
|
+
throw err;
|
|
671
|
+
}
|
|
672
|
+
}
|
|
673
|
+
async function doLoadBabel() {
|
|
674
|
+
const globalBabel = globalThis["Babel"];
|
|
675
|
+
if (globalBabel && typeof globalBabel.transform === "function") {
|
|
676
|
+
return globalBabel;
|
|
677
|
+
}
|
|
678
|
+
try {
|
|
679
|
+
const module2 = await import(
|
|
680
|
+
/* @vite-ignore */
|
|
681
|
+
/* webpackIgnore: true */
|
|
682
|
+
BABEL_STANDALONE_CDN
|
|
683
|
+
);
|
|
684
|
+
if (module2 && typeof module2.transform === "function") {
|
|
685
|
+
return module2;
|
|
686
|
+
}
|
|
687
|
+
if (module2.default && typeof module2.default.transform === "function") {
|
|
688
|
+
return module2.default;
|
|
689
|
+
}
|
|
690
|
+
} catch {
|
|
691
|
+
}
|
|
692
|
+
return new Promise((resolve, reject) => {
|
|
693
|
+
if (typeof document === "undefined") {
|
|
694
|
+
reject(new Error("Babel Standalone requires a browser environment"));
|
|
695
|
+
return;
|
|
696
|
+
}
|
|
697
|
+
const script = document.createElement("script");
|
|
698
|
+
script.src = BABEL_STANDALONE_FALLBACK_CDN;
|
|
699
|
+
script.crossOrigin = "anonymous";
|
|
700
|
+
script.onload = () => {
|
|
701
|
+
const babel = globalThis["Babel"];
|
|
702
|
+
if (babel && typeof babel.transform === "function") {
|
|
703
|
+
resolve(babel);
|
|
704
|
+
} else {
|
|
705
|
+
reject(new Error("Babel Standalone loaded but transform function not found"));
|
|
706
|
+
}
|
|
707
|
+
};
|
|
708
|
+
script.onerror = () => {
|
|
709
|
+
reject(new Error(`Failed to load Babel Standalone from ${BABEL_STANDALONE_FALLBACK_CDN}`));
|
|
710
|
+
};
|
|
711
|
+
document.head.appendChild(script);
|
|
712
|
+
});
|
|
713
|
+
}
|
|
714
|
+
async function transpileJsx(source, filename = "component.jsx") {
|
|
715
|
+
const babel = await loadBabel();
|
|
716
|
+
const result = babel.transform(source, {
|
|
717
|
+
presets: ["react"],
|
|
718
|
+
filename
|
|
719
|
+
});
|
|
720
|
+
return result.code;
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
// libs/ui/src/renderer/react/index.ts
|
|
724
|
+
function isReactJsx(content) {
|
|
725
|
+
if (/^#{1,6}\s+\S/m.test(content)) return false;
|
|
726
|
+
return /(?:function|const|class)\s+\w+/.test(content) && /(?:return|=>)[\s(]*</.test(content);
|
|
727
|
+
}
|
|
728
|
+
function parseImports(source) {
|
|
729
|
+
const results = [];
|
|
730
|
+
const defaultRe = /^import\s+(\w+)\s+from\s+['"]([^'"]+)['"][\s;]*$/gm;
|
|
731
|
+
let m;
|
|
732
|
+
while ((m = defaultRe.exec(source)) !== null) {
|
|
733
|
+
results.push({ line: m[0], localName: m[1], specifier: m[2], named: false });
|
|
734
|
+
}
|
|
735
|
+
const namedRe = /^import\s+\{([^}]+)\}\s+from\s+['"]([^'"]+)['"][\s;]*$/gm;
|
|
736
|
+
while ((m = namedRe.exec(source)) !== null) {
|
|
737
|
+
const names = m[1].split(",").map((n) => n.trim()).filter(Boolean);
|
|
738
|
+
for (const name of names) {
|
|
739
|
+
results.push({ line: m[0], localName: name, specifier: m[2], named: true });
|
|
740
|
+
}
|
|
741
|
+
}
|
|
742
|
+
return results;
|
|
743
|
+
}
|
|
744
|
+
function stripImports(source) {
|
|
745
|
+
return source.replace(/^import\s+\w+\s+from\s+['"][^'"]+['"][\s;]*$/gm, "").replace(/^import\s+\{[^}]+\}\s+from\s+['"][^'"]+['"][\s;]*$/gm, "");
|
|
746
|
+
}
|
|
747
|
+
function rewriteExportDefault(source) {
|
|
748
|
+
let result = source.replace(/^export\s+default\s+(function|class)\b/gm, "var __default__ = $1");
|
|
749
|
+
result = result.replace(/^export\s+default\s+(\([^)]*\)\s*=>)/gm, "var __default__ = $1");
|
|
750
|
+
result = result.replace(/^export\s+default\s+(\w+)\s*;?\s*$/gm, "var __default__ = $1;");
|
|
751
|
+
return result;
|
|
752
|
+
}
|
|
753
|
+
function isReactSpecifier(specifier) {
|
|
754
|
+
return specifier === "react" || /^https?:\/\/esm\.sh\/react(?:@[\d.]+)?$/.test(specifier);
|
|
755
|
+
}
|
|
756
|
+
async function resolveModules(imports) {
|
|
757
|
+
const modules = {};
|
|
758
|
+
const specifierMap = /* @__PURE__ */ new Map();
|
|
759
|
+
for (const imp of imports) {
|
|
760
|
+
const existing = specifierMap.get(imp.specifier) ?? [];
|
|
761
|
+
existing.push(imp);
|
|
762
|
+
specifierMap.set(imp.specifier, existing);
|
|
763
|
+
}
|
|
764
|
+
for (const [specifier, specImports] of specifierMap) {
|
|
765
|
+
let mod;
|
|
766
|
+
if (isReactSpecifier(specifier)) {
|
|
767
|
+
mod = import_react6.default;
|
|
768
|
+
} else {
|
|
769
|
+
mod = await runtimeImport(specifier);
|
|
770
|
+
}
|
|
771
|
+
for (const imp of specImports) {
|
|
772
|
+
if (imp.named) {
|
|
773
|
+
modules[imp.localName] = mod[imp.localName] ?? mod["default"]?.[imp.localName];
|
|
774
|
+
} else {
|
|
775
|
+
modules[imp.localName] = mod["default"] ?? mod;
|
|
776
|
+
}
|
|
777
|
+
}
|
|
778
|
+
}
|
|
779
|
+
return modules;
|
|
780
|
+
}
|
|
781
|
+
function ReactJsxView({ source, className }) {
|
|
782
|
+
const [Component, setComponent] = (0, import_react6.useState)(null);
|
|
783
|
+
const [error, setError] = (0, import_react6.useState)(null);
|
|
784
|
+
const [loading, setLoading] = (0, import_react6.useState)(true);
|
|
785
|
+
(0, import_react6.useEffect)(() => {
|
|
786
|
+
let cancelled = false;
|
|
787
|
+
async function transpileAndRender() {
|
|
788
|
+
try {
|
|
789
|
+
const imports = parseImports(source);
|
|
790
|
+
const modules = await resolveModules(imports);
|
|
791
|
+
let code = stripImports(source);
|
|
792
|
+
code = rewriteExportDefault(code);
|
|
793
|
+
code = await transpileJsx(code, "component.jsx");
|
|
794
|
+
code += "\nreturn __default__;";
|
|
795
|
+
const argNames = Object.keys(modules);
|
|
796
|
+
const argValues = argNames.map((n) => modules[n]);
|
|
797
|
+
const factory = new Function(...argNames, code);
|
|
798
|
+
const Comp = factory(...argValues);
|
|
799
|
+
if (!cancelled) {
|
|
800
|
+
setComponent(() => Comp);
|
|
801
|
+
setError(null);
|
|
802
|
+
setLoading(false);
|
|
803
|
+
}
|
|
804
|
+
} catch (err) {
|
|
805
|
+
if (!cancelled) {
|
|
806
|
+
setError(err instanceof Error ? err.message : String(err));
|
|
807
|
+
setComponent(null);
|
|
808
|
+
setLoading(false);
|
|
809
|
+
}
|
|
810
|
+
}
|
|
811
|
+
}
|
|
812
|
+
setLoading(true);
|
|
813
|
+
setError(null);
|
|
814
|
+
setComponent(null);
|
|
815
|
+
transpileAndRender();
|
|
816
|
+
return () => {
|
|
817
|
+
cancelled = true;
|
|
818
|
+
};
|
|
819
|
+
}, [source]);
|
|
820
|
+
if (loading) {
|
|
821
|
+
return import_react6.default.createElement(import_Box3.default, { className, sx: { p: 2, color: "text.secondary" } }, "Transpiling JSX...");
|
|
822
|
+
}
|
|
823
|
+
if (error) {
|
|
824
|
+
return import_react6.default.createElement(
|
|
825
|
+
import_Box3.default,
|
|
826
|
+
{ className },
|
|
827
|
+
import_react6.default.createElement(import_Alert.default, { severity: "error", sx: { mb: 1 } }, `JSX render error: ${error}`),
|
|
828
|
+
import_react6.default.createElement(
|
|
829
|
+
"pre",
|
|
830
|
+
{ style: { fontFamily: "monospace", whiteSpace: "pre-wrap", fontSize: "0.85em" } },
|
|
831
|
+
source
|
|
832
|
+
)
|
|
833
|
+
);
|
|
834
|
+
}
|
|
835
|
+
if (!Component) {
|
|
836
|
+
return import_react6.default.createElement(
|
|
837
|
+
import_Box3.default,
|
|
838
|
+
{ className },
|
|
839
|
+
import_react6.default.createElement(import_Alert.default, { severity: "warning" }, "No component exported. Use `export default MyComponent`.")
|
|
840
|
+
);
|
|
841
|
+
}
|
|
842
|
+
return import_react6.default.createElement(import_Box3.default, { className }, import_react6.default.createElement(Component, {}));
|
|
843
|
+
}
|
|
844
|
+
var ReactJsxRenderer = class {
|
|
845
|
+
type = "jsx";
|
|
846
|
+
priority = 10;
|
|
847
|
+
canHandle(content) {
|
|
848
|
+
return isReactJsx(content);
|
|
849
|
+
}
|
|
850
|
+
render(content, options) {
|
|
851
|
+
return import_react6.default.createElement(ReactJsxView, {
|
|
852
|
+
source: content,
|
|
853
|
+
className: options?.className ?? "fmcp-jsx-content"
|
|
854
|
+
});
|
|
855
|
+
}
|
|
856
|
+
};
|
|
857
|
+
var reactJsxRenderer = new ReactJsxRenderer();
|
|
858
|
+
|
|
859
|
+
// libs/ui/src/renderer/pdf/index.ts
|
|
860
|
+
var import_react7 = __toESM(require("react"));
|
|
861
|
+
var import_Box4 = __toESM(require("@mui/material/Box"));
|
|
862
|
+
var import_IconButton = __toESM(require("@mui/material/IconButton"));
|
|
863
|
+
var import_Typography2 = __toESM(require("@mui/material/Typography"));
|
|
864
|
+
var import_TextField = __toESM(require("@mui/material/TextField"));
|
|
865
|
+
var import_styles4 = require("@mui/material/styles");
|
|
866
|
+
var lazyReactPdf = createLazyImport("react-pdf", async () => {
|
|
867
|
+
const mod = await runtimeImportWithFallback(
|
|
868
|
+
"react-pdf",
|
|
869
|
+
esmShUrl("react-pdf@9", { external: ["react", "react-dom"] })
|
|
870
|
+
);
|
|
871
|
+
const pdfjs = mod["pdfjs"];
|
|
872
|
+
if (pdfjs?.GlobalWorkerOptions) {
|
|
873
|
+
pdfjs.GlobalWorkerOptions.workerSrc = `${ESM_SH_BASE}pdfjs-dist@${pdfjs.version ?? "4"}/build/pdf.worker.min.mjs?raw`;
|
|
874
|
+
}
|
|
875
|
+
return mod;
|
|
876
|
+
});
|
|
877
|
+
function toDataUri(content) {
|
|
878
|
+
if (content.startsWith("data:")) return content;
|
|
879
|
+
if (content.startsWith("%PDF-")) {
|
|
880
|
+
const base64 = typeof btoa === "function" ? btoa(content) : Buffer.from(content).toString("base64");
|
|
881
|
+
return `data:application/pdf;base64,${base64}`;
|
|
882
|
+
}
|
|
883
|
+
return `data:application/pdf;base64,${content}`;
|
|
884
|
+
}
|
|
885
|
+
var PdfRoot = (0, import_styles4.styled)(import_Box4.default, {
|
|
886
|
+
name: "FrontMcpPdf",
|
|
887
|
+
slot: "Root"
|
|
888
|
+
})(({ theme }) => ({
|
|
889
|
+
width: "100%",
|
|
890
|
+
borderRadius: theme.shape.borderRadius,
|
|
891
|
+
overflow: "hidden",
|
|
892
|
+
border: `1px solid ${theme.palette.divider}`
|
|
893
|
+
}));
|
|
894
|
+
var Toolbar = (0, import_styles4.styled)(import_Box4.default, {
|
|
895
|
+
name: "FrontMcpPdf",
|
|
896
|
+
slot: "Toolbar"
|
|
897
|
+
})(({ theme }) => ({
|
|
898
|
+
display: "flex",
|
|
899
|
+
alignItems: "center",
|
|
900
|
+
gap: theme.spacing(1),
|
|
901
|
+
padding: theme.spacing(1, 2),
|
|
902
|
+
borderBottom: `1px solid ${theme.palette.divider}`,
|
|
903
|
+
backgroundColor: theme.palette.mode === "dark" ? theme.palette.grey[900] : theme.palette.grey[50]
|
|
904
|
+
}));
|
|
905
|
+
var PageContainer = (0, import_styles4.styled)(import_Box4.default, {
|
|
906
|
+
name: "FrontMcpPdf",
|
|
907
|
+
slot: "PageContainer"
|
|
908
|
+
})({
|
|
909
|
+
display: "flex",
|
|
910
|
+
justifyContent: "center",
|
|
911
|
+
overflow: "auto",
|
|
912
|
+
maxHeight: 700
|
|
913
|
+
});
|
|
914
|
+
function PdfView({ content, className, title }) {
|
|
915
|
+
const [numPages, setNumPages] = (0, import_react7.useState)(0);
|
|
916
|
+
const [pageNumber, setPageNumber] = (0, import_react7.useState)(1);
|
|
917
|
+
const [scale, setScale] = (0, import_react7.useState)(1);
|
|
918
|
+
const reactPdf = useLazyModule(lazyReactPdf);
|
|
919
|
+
const dataUri = (0, import_react7.useMemo)(() => toDataUri(content), [content]);
|
|
920
|
+
const onDocumentLoadSuccess = (0, import_react7.useCallback)(({ numPages: n }) => {
|
|
921
|
+
setNumPages(n);
|
|
922
|
+
}, []);
|
|
923
|
+
const goToPrev = (0, import_react7.useCallback)(() => setPageNumber((p) => Math.max(1, p - 1)), []);
|
|
924
|
+
const goToNext = (0, import_react7.useCallback)(() => setPageNumber((p) => Math.min(numPages, p + 1)), []);
|
|
925
|
+
const zoomIn = (0, import_react7.useCallback)(() => setScale((s) => Math.min(3, s + 0.25)), []);
|
|
926
|
+
const zoomOut = (0, import_react7.useCallback)(() => setScale((s) => Math.max(0.25, s - 0.25)), []);
|
|
927
|
+
if (!reactPdf) {
|
|
928
|
+
return import_react7.default.createElement("iframe", {
|
|
929
|
+
className: className ?? "fmcp-pdf-content",
|
|
930
|
+
src: dataUri,
|
|
931
|
+
style: { width: "100%", height: "600px", border: "none" },
|
|
932
|
+
title: title ?? "PDF Document"
|
|
933
|
+
});
|
|
934
|
+
}
|
|
935
|
+
const { Document, Page } = reactPdf;
|
|
936
|
+
return import_react7.default.createElement(
|
|
937
|
+
PdfRoot,
|
|
938
|
+
{ className },
|
|
939
|
+
import_react7.default.createElement(
|
|
940
|
+
Toolbar,
|
|
941
|
+
null,
|
|
942
|
+
import_react7.default.createElement(
|
|
943
|
+
import_IconButton.default,
|
|
944
|
+
{ size: "small", onClick: goToPrev, disabled: pageNumber <= 1, "aria-label": "Previous page" },
|
|
945
|
+
"\u25C0"
|
|
946
|
+
),
|
|
947
|
+
import_react7.default.createElement(
|
|
948
|
+
import_Typography2.default,
|
|
949
|
+
{ variant: "body2", sx: { minWidth: 80, textAlign: "center" } },
|
|
950
|
+
`${pageNumber} / ${numPages || "..."}`
|
|
951
|
+
),
|
|
952
|
+
import_react7.default.createElement(
|
|
953
|
+
import_IconButton.default,
|
|
954
|
+
{ size: "small", onClick: goToNext, disabled: pageNumber >= numPages, "aria-label": "Next page" },
|
|
955
|
+
"\u25B6"
|
|
956
|
+
),
|
|
957
|
+
import_react7.default.createElement(import_Box4.default, { sx: { flex: 1 } }),
|
|
958
|
+
import_react7.default.createElement(import_IconButton.default, { size: "small", onClick: zoomOut, "aria-label": "Zoom out" }, "\u2212"),
|
|
959
|
+
import_react7.default.createElement(
|
|
960
|
+
import_Typography2.default,
|
|
961
|
+
{ variant: "body2", sx: { minWidth: 50, textAlign: "center" } },
|
|
962
|
+
`${Math.round(scale * 100)}%`
|
|
963
|
+
),
|
|
964
|
+
import_react7.default.createElement(import_IconButton.default, { size: "small", onClick: zoomIn, "aria-label": "Zoom in" }, "+"),
|
|
965
|
+
import_react7.default.createElement(import_Box4.default, { sx: { flex: 1 } }),
|
|
966
|
+
import_react7.default.createElement(import_TextField.default, {
|
|
967
|
+
size: "small",
|
|
968
|
+
type: "number",
|
|
969
|
+
value: pageNumber,
|
|
970
|
+
onChange: (e) => {
|
|
971
|
+
const n = parseInt(e.target.value, 10);
|
|
972
|
+
if (n >= 1 && n <= numPages) setPageNumber(n);
|
|
973
|
+
},
|
|
974
|
+
sx: { width: 70 },
|
|
975
|
+
slotProps: { htmlInput: { min: 1, max: numPages, "aria-label": "Go to page" } }
|
|
976
|
+
})
|
|
977
|
+
),
|
|
978
|
+
import_react7.default.createElement(
|
|
979
|
+
PageContainer,
|
|
980
|
+
null,
|
|
981
|
+
import_react7.default.createElement(
|
|
982
|
+
Document,
|
|
983
|
+
{ file: dataUri, onLoadSuccess: onDocumentLoadSuccess },
|
|
984
|
+
import_react7.default.createElement(Page, { pageNumber, scale, renderTextLayer: false, renderAnnotationLayer: false })
|
|
985
|
+
)
|
|
986
|
+
)
|
|
987
|
+
);
|
|
988
|
+
}
|
|
989
|
+
lazyReactPdf.load().catch(() => {
|
|
990
|
+
});
|
|
991
|
+
var PdfRenderer = class {
|
|
992
|
+
type = "pdf";
|
|
993
|
+
priority = 90;
|
|
994
|
+
canHandle(content) {
|
|
995
|
+
return content.startsWith("%PDF-") || content.trim().startsWith("JVBER") || /^data:application\/pdf[;,]/.test(content.trim());
|
|
996
|
+
}
|
|
997
|
+
render(content, options) {
|
|
998
|
+
return import_react7.default.createElement(PdfView, {
|
|
999
|
+
content,
|
|
1000
|
+
className: options?.className ?? "fmcp-pdf-content",
|
|
1001
|
+
title: options?.toolName ?? "PDF Document"
|
|
1002
|
+
});
|
|
1003
|
+
}
|
|
1004
|
+
};
|
|
1005
|
+
var pdfRenderer = new PdfRenderer();
|
|
1006
|
+
|
|
1007
|
+
// libs/ui/src/renderer/csv/index.ts
|
|
1008
|
+
var import_react8 = __toESM(require("react"));
|
|
1009
|
+
var import_Box5 = __toESM(require("@mui/material/Box"));
|
|
1010
|
+
var import_Table2 = __toESM(require("@mui/material/Table"));
|
|
1011
|
+
var import_TableBody2 = __toESM(require("@mui/material/TableBody"));
|
|
1012
|
+
var import_TableCell2 = __toESM(require("@mui/material/TableCell"));
|
|
1013
|
+
var import_TableContainer = __toESM(require("@mui/material/TableContainer"));
|
|
1014
|
+
var import_TableHead2 = __toESM(require("@mui/material/TableHead"));
|
|
1015
|
+
var import_TableRow2 = __toESM(require("@mui/material/TableRow"));
|
|
1016
|
+
var import_TablePagination = __toESM(require("@mui/material/TablePagination"));
|
|
1017
|
+
var import_TableSortLabel = __toESM(require("@mui/material/TableSortLabel"));
|
|
1018
|
+
var import_TextField2 = __toESM(require("@mui/material/TextField"));
|
|
1019
|
+
var import_styles5 = require("@mui/material/styles");
|
|
1020
|
+
function detectDelimiter(content) {
|
|
1021
|
+
const firstLine = content.split("\n")[0];
|
|
1022
|
+
const commas = (firstLine.match(/,/g) ?? []).length;
|
|
1023
|
+
const tabs = (firstLine.match(/\t/g) ?? []).length;
|
|
1024
|
+
const semicolons = (firstLine.match(/;/g) ?? []).length;
|
|
1025
|
+
if (tabs > commas && tabs > semicolons) return " ";
|
|
1026
|
+
if (semicolons > commas) return ";";
|
|
1027
|
+
return ",";
|
|
1028
|
+
}
|
|
1029
|
+
function parseCsv(content, delimiter) {
|
|
1030
|
+
return content.trim().split("\n").map((line) => line.split(delimiter).map((cell) => cell.trim()));
|
|
1031
|
+
}
|
|
1032
|
+
var CsvRoot = (0, import_styles5.styled)(import_Box5.default, {
|
|
1033
|
+
name: "FrontMcpCsvTable",
|
|
1034
|
+
slot: "Root"
|
|
1035
|
+
})({
|
|
1036
|
+
width: "100%"
|
|
1037
|
+
});
|
|
1038
|
+
var StyledHeaderCell = (0, import_styles5.styled)(import_TableCell2.default, {
|
|
1039
|
+
name: "FrontMcpCsvTable",
|
|
1040
|
+
slot: "Header"
|
|
1041
|
+
})(({ theme }) => ({
|
|
1042
|
+
fontWeight: 600,
|
|
1043
|
+
backgroundColor: theme.palette.mode === "dark" ? theme.palette.grey[900] : theme.palette.grey[50],
|
|
1044
|
+
whiteSpace: "nowrap"
|
|
1045
|
+
}));
|
|
1046
|
+
var FilterToolbar = (0, import_styles5.styled)(import_Box5.default, {
|
|
1047
|
+
name: "FrontMcpCsvTable",
|
|
1048
|
+
slot: "Toolbar"
|
|
1049
|
+
})(({ theme }) => ({
|
|
1050
|
+
padding: theme.spacing(1, 2),
|
|
1051
|
+
display: "flex",
|
|
1052
|
+
gap: theme.spacing(1)
|
|
1053
|
+
}));
|
|
1054
|
+
function CsvTableView({ content, className, pageSize = 25 }) {
|
|
1055
|
+
const delimiter = (0, import_react8.useMemo)(() => detectDelimiter(content), [content]);
|
|
1056
|
+
const allRows = (0, import_react8.useMemo)(() => parseCsv(content, delimiter), [content, delimiter]);
|
|
1057
|
+
const headers = allRows[0] ?? [];
|
|
1058
|
+
const dataRows = (0, import_react8.useMemo)(() => allRows.slice(1), [allRows]);
|
|
1059
|
+
const [page, setPage] = (0, import_react8.useState)(0);
|
|
1060
|
+
const [rowsPerPage, setRowsPerPage] = (0, import_react8.useState)(pageSize);
|
|
1061
|
+
const [sortCol, setSortCol] = (0, import_react8.useState)(null);
|
|
1062
|
+
const [sortDir, setSortDir] = (0, import_react8.useState)("asc");
|
|
1063
|
+
const [filter, setFilter] = (0, import_react8.useState)("");
|
|
1064
|
+
const filteredRows = (0, import_react8.useMemo)(() => {
|
|
1065
|
+
if (!filter) return dataRows;
|
|
1066
|
+
const lower = filter.toLowerCase();
|
|
1067
|
+
return dataRows.filter((row) => row.some((cell) => cell.toLowerCase().includes(lower)));
|
|
1068
|
+
}, [dataRows, filter]);
|
|
1069
|
+
const sortedRows = (0, import_react8.useMemo)(() => {
|
|
1070
|
+
if (sortCol === null) return filteredRows;
|
|
1071
|
+
const sorted = [...filteredRows];
|
|
1072
|
+
sorted.sort((a, b) => {
|
|
1073
|
+
const va = a[sortCol] ?? "";
|
|
1074
|
+
const vb = b[sortCol] ?? "";
|
|
1075
|
+
const numA = Number(va);
|
|
1076
|
+
const numB = Number(vb);
|
|
1077
|
+
if (!isNaN(numA) && !isNaN(numB)) {
|
|
1078
|
+
return sortDir === "asc" ? numA - numB : numB - numA;
|
|
1079
|
+
}
|
|
1080
|
+
return sortDir === "asc" ? va.localeCompare(vb) : vb.localeCompare(va);
|
|
1081
|
+
});
|
|
1082
|
+
return sorted;
|
|
1083
|
+
}, [filteredRows, sortCol, sortDir]);
|
|
1084
|
+
const pageRows = (0, import_react8.useMemo)(
|
|
1085
|
+
() => sortedRows.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage),
|
|
1086
|
+
[sortedRows, page, rowsPerPage]
|
|
1087
|
+
);
|
|
1088
|
+
const handleSort = (0, import_react8.useCallback)((colIndex) => {
|
|
1089
|
+
setSortCol((prev) => {
|
|
1090
|
+
if (prev === colIndex) {
|
|
1091
|
+
setSortDir((d) => d === "asc" ? "desc" : "asc");
|
|
1092
|
+
return colIndex;
|
|
1093
|
+
}
|
|
1094
|
+
setSortDir("asc");
|
|
1095
|
+
return colIndex;
|
|
1096
|
+
});
|
|
1097
|
+
}, []);
|
|
1098
|
+
const handleChangePage = (0, import_react8.useCallback)((_, newPage) => setPage(newPage), []);
|
|
1099
|
+
const handleChangeRowsPerPage = (0, import_react8.useCallback)((e) => {
|
|
1100
|
+
setRowsPerPage(parseInt(e.target.value, 10));
|
|
1101
|
+
setPage(0);
|
|
1102
|
+
}, []);
|
|
1103
|
+
return import_react8.default.createElement(
|
|
1104
|
+
CsvRoot,
|
|
1105
|
+
{ className },
|
|
1106
|
+
import_react8.default.createElement(
|
|
1107
|
+
FilterToolbar,
|
|
1108
|
+
null,
|
|
1109
|
+
import_react8.default.createElement(import_TextField2.default, {
|
|
1110
|
+
size: "small",
|
|
1111
|
+
placeholder: "Filter rows...",
|
|
1112
|
+
value: filter,
|
|
1113
|
+
onChange: (e) => {
|
|
1114
|
+
setFilter(e.target.value);
|
|
1115
|
+
setPage(0);
|
|
1116
|
+
},
|
|
1117
|
+
sx: { minWidth: 200 }
|
|
1118
|
+
})
|
|
1119
|
+
),
|
|
1120
|
+
import_react8.default.createElement(
|
|
1121
|
+
import_TableContainer.default,
|
|
1122
|
+
{ sx: { border: 1, borderColor: "divider", borderRadius: 1 } },
|
|
1123
|
+
import_react8.default.createElement(
|
|
1124
|
+
import_Table2.default,
|
|
1125
|
+
{ size: "small", stickyHeader: true },
|
|
1126
|
+
import_react8.default.createElement(
|
|
1127
|
+
import_TableHead2.default,
|
|
1128
|
+
null,
|
|
1129
|
+
import_react8.default.createElement(
|
|
1130
|
+
import_TableRow2.default,
|
|
1131
|
+
null,
|
|
1132
|
+
headers.map(
|
|
1133
|
+
(header, i) => import_react8.default.createElement(
|
|
1134
|
+
StyledHeaderCell,
|
|
1135
|
+
{ key: i },
|
|
1136
|
+
import_react8.default.createElement(
|
|
1137
|
+
import_TableSortLabel.default,
|
|
1138
|
+
{
|
|
1139
|
+
active: sortCol === i,
|
|
1140
|
+
direction: sortCol === i ? sortDir : "asc",
|
|
1141
|
+
onClick: () => handleSort(i)
|
|
1142
|
+
},
|
|
1143
|
+
header
|
|
1144
|
+
)
|
|
1145
|
+
)
|
|
1146
|
+
)
|
|
1147
|
+
)
|
|
1148
|
+
),
|
|
1149
|
+
import_react8.default.createElement(
|
|
1150
|
+
import_TableBody2.default,
|
|
1151
|
+
null,
|
|
1152
|
+
pageRows.map(
|
|
1153
|
+
(row, ri) => import_react8.default.createElement(
|
|
1154
|
+
import_TableRow2.default,
|
|
1155
|
+
{ key: ri, hover: true },
|
|
1156
|
+
row.map((cell, ci) => import_react8.default.createElement(import_TableCell2.default, { key: ci }, cell))
|
|
1157
|
+
)
|
|
1158
|
+
)
|
|
1159
|
+
)
|
|
1160
|
+
)
|
|
1161
|
+
),
|
|
1162
|
+
sortedRows.length > rowsPerPage && import_react8.default.createElement(import_TablePagination.default, {
|
|
1163
|
+
count: sortedRows.length,
|
|
1164
|
+
page,
|
|
1165
|
+
rowsPerPage,
|
|
1166
|
+
onPageChange: handleChangePage,
|
|
1167
|
+
onRowsPerPageChange: handleChangeRowsPerPage,
|
|
1168
|
+
rowsPerPageOptions: [10, 25, 50, 100]
|
|
1169
|
+
})
|
|
1170
|
+
);
|
|
1171
|
+
}
|
|
1172
|
+
var CsvRenderer = class {
|
|
1173
|
+
type = "csv";
|
|
1174
|
+
priority = 10;
|
|
1175
|
+
canHandle(content) {
|
|
1176
|
+
const lines = content.trim().split("\n").slice(0, 5);
|
|
1177
|
+
if (lines.length < 2) return false;
|
|
1178
|
+
for (const delim of [",", " ", ";"]) {
|
|
1179
|
+
const counts = lines.map((line) => line.split(delim).length);
|
|
1180
|
+
if (counts[0] > 1 && counts.every((c) => c === counts[0])) return true;
|
|
1181
|
+
}
|
|
1182
|
+
return false;
|
|
1183
|
+
}
|
|
1184
|
+
render(content, options) {
|
|
1185
|
+
const pageSize = options?.rendererOptions?.["pageSize"];
|
|
1186
|
+
return import_react8.default.createElement(CsvTableView, {
|
|
1187
|
+
content,
|
|
1188
|
+
className: options?.className ?? "fmcp-csv-table",
|
|
1189
|
+
pageSize
|
|
1190
|
+
});
|
|
1191
|
+
}
|
|
1192
|
+
};
|
|
1193
|
+
var csvRenderer = new CsvRenderer();
|
|
1194
|
+
|
|
1195
|
+
// libs/ui/src/renderer/image/index.ts
|
|
1196
|
+
var import_react9 = __toESM(require("react"));
|
|
1197
|
+
var import_Box6 = __toESM(require("@mui/material/Box"));
|
|
1198
|
+
var import_Skeleton = __toESM(require("@mui/material/Skeleton"));
|
|
1199
|
+
var import_Alert2 = __toESM(require("@mui/material/Alert"));
|
|
1200
|
+
var import_Typography3 = __toESM(require("@mui/material/Typography"));
|
|
1201
|
+
var import_styles6 = require("@mui/material/styles");
|
|
1202
|
+
var IMAGE_DATA_URI = /^data:image\/(?:png|jpeg|jpg|gif|webp|svg\+xml|avif)[;,]/;
|
|
1203
|
+
var IMAGE_URL = /^https?:\/\/[^?#\s]+\.(?:png|jpe?g|gif|webp|svg|avif|ico)(?:\?[^#\s]*)?$/i;
|
|
1204
|
+
var IMAGE_SERVICE_URL = /^https?:\/\/(?:picsum\.photos|images\.unsplash\.com|i\.imgur\.com|placekitten\.com|via\.placeholder\.com)\//i;
|
|
1205
|
+
function isImage(content) {
|
|
1206
|
+
const trimmed = content.trim();
|
|
1207
|
+
return IMAGE_DATA_URI.test(trimmed) || IMAGE_URL.test(trimmed) || IMAGE_SERVICE_URL.test(trimmed);
|
|
1208
|
+
}
|
|
1209
|
+
var ImageRoot = (0, import_styles6.styled)(import_Box6.default, {
|
|
1210
|
+
name: "FrontMcpImage",
|
|
1211
|
+
slot: "Root"
|
|
1212
|
+
})({
|
|
1213
|
+
display: "inline-block",
|
|
1214
|
+
position: "relative",
|
|
1215
|
+
maxWidth: "100%"
|
|
1216
|
+
});
|
|
1217
|
+
var StyledImage = (0, import_styles6.styled)("img", {
|
|
1218
|
+
name: "FrontMcpImage",
|
|
1219
|
+
slot: "Image"
|
|
1220
|
+
})({
|
|
1221
|
+
maxWidth: "100%",
|
|
1222
|
+
height: "auto",
|
|
1223
|
+
display: "block",
|
|
1224
|
+
cursor: "pointer",
|
|
1225
|
+
borderRadius: "inherit"
|
|
1226
|
+
});
|
|
1227
|
+
var LightboxBackdrop = (0, import_styles6.styled)(import_Box6.default, {
|
|
1228
|
+
name: "FrontMcpImage",
|
|
1229
|
+
slot: "Lightbox"
|
|
1230
|
+
})({
|
|
1231
|
+
display: "flex",
|
|
1232
|
+
alignItems: "center",
|
|
1233
|
+
justifyContent: "center",
|
|
1234
|
+
padding: 16
|
|
1235
|
+
});
|
|
1236
|
+
var LightboxImage = (0, import_styles6.styled)("img")({
|
|
1237
|
+
maxWidth: "90vw",
|
|
1238
|
+
maxHeight: "90vh",
|
|
1239
|
+
objectFit: "contain",
|
|
1240
|
+
borderRadius: 8
|
|
1241
|
+
});
|
|
1242
|
+
function LightboxOverlay({ src, alt, onClose }) {
|
|
1243
|
+
return import_react9.default.createElement(
|
|
1244
|
+
LightboxBackdrop,
|
|
1245
|
+
{
|
|
1246
|
+
onClick: onClose,
|
|
1247
|
+
sx: {
|
|
1248
|
+
position: "fixed",
|
|
1249
|
+
inset: 0,
|
|
1250
|
+
zIndex: 1300,
|
|
1251
|
+
bgcolor: "rgba(0,0,0,0.8)"
|
|
1252
|
+
}
|
|
1253
|
+
},
|
|
1254
|
+
import_react9.default.createElement(LightboxImage, { src, alt })
|
|
1255
|
+
);
|
|
1256
|
+
}
|
|
1257
|
+
function ImageView({ src, alt, caption, className }) {
|
|
1258
|
+
const [loaded, setLoaded] = (0, import_react9.useState)(false);
|
|
1259
|
+
const [error, setError] = (0, import_react9.useState)(false);
|
|
1260
|
+
const [lightboxOpen, setLightboxOpen] = (0, import_react9.useState)(false);
|
|
1261
|
+
(0, import_react9.useEffect)(() => {
|
|
1262
|
+
setLoaded(false);
|
|
1263
|
+
setError(false);
|
|
1264
|
+
setLightboxOpen(false);
|
|
1265
|
+
}, [src]);
|
|
1266
|
+
const handleLoad = (0, import_react9.useCallback)(() => setLoaded(true), []);
|
|
1267
|
+
const handleError = (0, import_react9.useCallback)(() => {
|
|
1268
|
+
setLoaded(true);
|
|
1269
|
+
setError(true);
|
|
1270
|
+
}, []);
|
|
1271
|
+
if (error) {
|
|
1272
|
+
return import_react9.default.createElement(import_Alert2.default, { severity: "error" }, `Failed to load image: ${src}`);
|
|
1273
|
+
}
|
|
1274
|
+
return import_react9.default.createElement(
|
|
1275
|
+
ImageRoot,
|
|
1276
|
+
{ className },
|
|
1277
|
+
!loaded && import_react9.default.createElement(import_Skeleton.default, { variant: "rectangular", width: 400, height: 300 }),
|
|
1278
|
+
import_react9.default.createElement(StyledImage, {
|
|
1279
|
+
src,
|
|
1280
|
+
alt: alt ?? "Image",
|
|
1281
|
+
onLoad: handleLoad,
|
|
1282
|
+
onError: handleError,
|
|
1283
|
+
onClick: () => setLightboxOpen(true),
|
|
1284
|
+
style: loaded ? void 0 : { display: "none" }
|
|
1285
|
+
}),
|
|
1286
|
+
caption && import_react9.default.createElement(
|
|
1287
|
+
import_Typography3.default,
|
|
1288
|
+
{ variant: "caption", color: "text.secondary", sx: { mt: 0.5, display: "block", textAlign: "center" } },
|
|
1289
|
+
caption
|
|
1290
|
+
),
|
|
1291
|
+
lightboxOpen && import_react9.default.createElement(LightboxOverlay, {
|
|
1292
|
+
src,
|
|
1293
|
+
alt: alt ?? "Image",
|
|
1294
|
+
onClose: () => setLightboxOpen(false)
|
|
1295
|
+
})
|
|
1296
|
+
);
|
|
1297
|
+
}
|
|
1298
|
+
var ImageRenderer = class {
|
|
1299
|
+
type = "image";
|
|
1300
|
+
priority = 30;
|
|
1301
|
+
canHandle(content) {
|
|
1302
|
+
return isImage(content);
|
|
1303
|
+
}
|
|
1304
|
+
render(content, options) {
|
|
1305
|
+
const caption = options?.rendererOptions?.["caption"];
|
|
1306
|
+
return import_react9.default.createElement(ImageView, {
|
|
1307
|
+
src: content.trim(),
|
|
1308
|
+
alt: options?.toolName ?? "Image",
|
|
1309
|
+
caption,
|
|
1310
|
+
className: options?.className ?? "fmcp-image-content"
|
|
1311
|
+
});
|
|
1312
|
+
}
|
|
1313
|
+
};
|
|
1314
|
+
var imageRenderer = new ImageRenderer();
|
|
1315
|
+
|
|
1316
|
+
// libs/ui/src/renderer/charts/index.ts
|
|
1317
|
+
var import_react10 = __toESM(require("react"));
|
|
1318
|
+
var import_Box7 = __toESM(require("@mui/material/Box"));
|
|
1319
|
+
var import_Alert3 = __toESM(require("@mui/material/Alert"));
|
|
1320
|
+
var import_Typography4 = __toESM(require("@mui/material/Typography"));
|
|
1321
|
+
var import_styles7 = require("@mui/material/styles");
|
|
1322
|
+
var CHART_TYPE_RE2 = /"type"\s*:\s*"(?:bar|line|area|pie|scatter|radar|composed)"/;
|
|
1323
|
+
function isChart(content) {
|
|
1324
|
+
const trimmed = content.trim();
|
|
1325
|
+
if (trimmed.charCodeAt(0) !== 123) return false;
|
|
1326
|
+
return CHART_TYPE_RE2.test(trimmed) && trimmed.includes('"data"');
|
|
1327
|
+
}
|
|
1328
|
+
var lazyRecharts = createLazyImport("recharts", async () => {
|
|
1329
|
+
const mod = await runtimeImportWithFallback("recharts", esmShUrl("recharts@2", { external: ["react", "react-dom"] }));
|
|
1330
|
+
return mod;
|
|
1331
|
+
});
|
|
1332
|
+
var ChartRoot = (0, import_styles7.styled)(import_Box7.default, {
|
|
1333
|
+
name: "FrontMcpChart",
|
|
1334
|
+
slot: "Root"
|
|
1335
|
+
})(({ theme }) => ({
|
|
1336
|
+
width: "100%",
|
|
1337
|
+
padding: theme.spacing(2)
|
|
1338
|
+
}));
|
|
1339
|
+
function ChartView({ config, className }) {
|
|
1340
|
+
const themeValues = useRendererTheme();
|
|
1341
|
+
const recharts = useLazyModule(lazyRecharts);
|
|
1342
|
+
const colors = (0, import_react10.useMemo)(() => config.colors ?? themeValues.seriesColors, [config.colors, themeValues.seriesColors]);
|
|
1343
|
+
if (!recharts) {
|
|
1344
|
+
return import_react10.default.createElement(import_Alert3.default, { severity: "info" }, "Loading chart library...");
|
|
1345
|
+
}
|
|
1346
|
+
const { ResponsiveContainer, Tooltip, Legend, CartesianGrid, XAxis, YAxis } = recharts;
|
|
1347
|
+
const height = config.height ?? 400;
|
|
1348
|
+
const xKey = config.xKey ?? "name";
|
|
1349
|
+
const yKeys = config.yKeys ?? Object.keys(config.data?.[0] ?? {}).filter((k) => k !== xKey);
|
|
1350
|
+
const chartContent = renderChartType(
|
|
1351
|
+
recharts,
|
|
1352
|
+
config.type,
|
|
1353
|
+
config.data,
|
|
1354
|
+
xKey,
|
|
1355
|
+
yKeys,
|
|
1356
|
+
colors,
|
|
1357
|
+
themeValues.borderRadius
|
|
1358
|
+
);
|
|
1359
|
+
return import_react10.default.createElement(
|
|
1360
|
+
ChartRoot,
|
|
1361
|
+
{ className },
|
|
1362
|
+
config.title && import_react10.default.createElement(
|
|
1363
|
+
import_Typography4.default,
|
|
1364
|
+
{ variant: "subtitle1", gutterBottom: true, fontWeight: 600, textAlign: "center" },
|
|
1365
|
+
config.title
|
|
1366
|
+
),
|
|
1367
|
+
import_react10.default.createElement(ResponsiveContainer, { width: "100%", height }, chartContent)
|
|
1368
|
+
);
|
|
1369
|
+
}
|
|
1370
|
+
function renderChartType(rc, type, data, xKey, yKeys, colors, borderRadius) {
|
|
1371
|
+
const commonProps = { data };
|
|
1372
|
+
const grid = import_react10.default.createElement(rc.CartesianGrid, { strokeDasharray: "3 3", opacity: 0.3 });
|
|
1373
|
+
const xAxis = import_react10.default.createElement(rc.XAxis, { dataKey: xKey });
|
|
1374
|
+
const yAxis = import_react10.default.createElement(rc.YAxis);
|
|
1375
|
+
const tooltip = import_react10.default.createElement(rc.Tooltip, { contentStyle: { borderRadius } });
|
|
1376
|
+
const legend = import_react10.default.createElement(rc.Legend);
|
|
1377
|
+
switch (type) {
|
|
1378
|
+
case "bar":
|
|
1379
|
+
return import_react10.default.createElement(
|
|
1380
|
+
rc.BarChart,
|
|
1381
|
+
commonProps,
|
|
1382
|
+
grid,
|
|
1383
|
+
xAxis,
|
|
1384
|
+
yAxis,
|
|
1385
|
+
tooltip,
|
|
1386
|
+
legend,
|
|
1387
|
+
...yKeys.map(
|
|
1388
|
+
(key, i) => import_react10.default.createElement(rc.Bar, {
|
|
1389
|
+
key,
|
|
1390
|
+
dataKey: key,
|
|
1391
|
+
fill: colors[i % colors.length],
|
|
1392
|
+
radius: [borderRadius, borderRadius, 0, 0]
|
|
1393
|
+
})
|
|
1394
|
+
)
|
|
1395
|
+
);
|
|
1396
|
+
case "line":
|
|
1397
|
+
return import_react10.default.createElement(
|
|
1398
|
+
rc.LineChart,
|
|
1399
|
+
commonProps,
|
|
1400
|
+
grid,
|
|
1401
|
+
xAxis,
|
|
1402
|
+
yAxis,
|
|
1403
|
+
tooltip,
|
|
1404
|
+
legend,
|
|
1405
|
+
...yKeys.map(
|
|
1406
|
+
(key, i) => import_react10.default.createElement(rc.Line, {
|
|
1407
|
+
key,
|
|
1408
|
+
type: "monotone",
|
|
1409
|
+
dataKey: key,
|
|
1410
|
+
stroke: colors[i % colors.length],
|
|
1411
|
+
strokeWidth: 2
|
|
1412
|
+
})
|
|
1413
|
+
)
|
|
1414
|
+
);
|
|
1415
|
+
case "area":
|
|
1416
|
+
return import_react10.default.createElement(
|
|
1417
|
+
rc.AreaChart,
|
|
1418
|
+
commonProps,
|
|
1419
|
+
grid,
|
|
1420
|
+
xAxis,
|
|
1421
|
+
yAxis,
|
|
1422
|
+
tooltip,
|
|
1423
|
+
legend,
|
|
1424
|
+
...yKeys.map(
|
|
1425
|
+
(key, i) => import_react10.default.createElement(rc.Area, {
|
|
1426
|
+
key,
|
|
1427
|
+
type: "monotone",
|
|
1428
|
+
dataKey: key,
|
|
1429
|
+
stroke: colors[i % colors.length],
|
|
1430
|
+
fill: colors[i % colors.length],
|
|
1431
|
+
fillOpacity: 0.3
|
|
1432
|
+
})
|
|
1433
|
+
)
|
|
1434
|
+
);
|
|
1435
|
+
case "pie":
|
|
1436
|
+
return import_react10.default.createElement(
|
|
1437
|
+
rc.PieChart,
|
|
1438
|
+
{},
|
|
1439
|
+
tooltip,
|
|
1440
|
+
legend,
|
|
1441
|
+
import_react10.default.createElement(
|
|
1442
|
+
rc.Pie,
|
|
1443
|
+
{ data, dataKey: yKeys[0] ?? "value", nameKey: xKey, cx: "50%", cy: "50%", outerRadius: "80%", label: true },
|
|
1444
|
+
...data.map((_, i) => import_react10.default.createElement(rc.Cell, { key: i, fill: colors[i % colors.length] }))
|
|
1445
|
+
)
|
|
1446
|
+
);
|
|
1447
|
+
case "scatter":
|
|
1448
|
+
return import_react10.default.createElement(
|
|
1449
|
+
rc.ScatterChart,
|
|
1450
|
+
{},
|
|
1451
|
+
grid,
|
|
1452
|
+
xAxis,
|
|
1453
|
+
yAxis,
|
|
1454
|
+
tooltip,
|
|
1455
|
+
legend,
|
|
1456
|
+
...yKeys.map(
|
|
1457
|
+
(key, i) => import_react10.default.createElement(rc.Scatter, { key, name: key, dataKey: key, data, fill: colors[i % colors.length] })
|
|
1458
|
+
)
|
|
1459
|
+
);
|
|
1460
|
+
case "radar":
|
|
1461
|
+
return import_react10.default.createElement(
|
|
1462
|
+
rc.RadarChart,
|
|
1463
|
+
{ cx: "50%", cy: "50%", outerRadius: "80%", data },
|
|
1464
|
+
import_react10.default.createElement(rc.PolarGrid),
|
|
1465
|
+
import_react10.default.createElement(rc.PolarAngleAxis, { dataKey: xKey }),
|
|
1466
|
+
import_react10.default.createElement(rc.PolarRadiusAxis),
|
|
1467
|
+
tooltip,
|
|
1468
|
+
legend,
|
|
1469
|
+
...yKeys.map(
|
|
1470
|
+
(key, i) => import_react10.default.createElement(rc.Radar, {
|
|
1471
|
+
key,
|
|
1472
|
+
name: key,
|
|
1473
|
+
dataKey: key,
|
|
1474
|
+
stroke: colors[i % colors.length],
|
|
1475
|
+
fill: colors[i % colors.length],
|
|
1476
|
+
fillOpacity: 0.3
|
|
1477
|
+
})
|
|
1478
|
+
)
|
|
1479
|
+
);
|
|
1480
|
+
case "composed":
|
|
1481
|
+
return import_react10.default.createElement(
|
|
1482
|
+
rc.ComposedChart,
|
|
1483
|
+
commonProps,
|
|
1484
|
+
grid,
|
|
1485
|
+
xAxis,
|
|
1486
|
+
yAxis,
|
|
1487
|
+
tooltip,
|
|
1488
|
+
legend,
|
|
1489
|
+
...yKeys.map((key, i) => {
|
|
1490
|
+
if (i % 2 === 0) {
|
|
1491
|
+
return import_react10.default.createElement(rc.Bar, {
|
|
1492
|
+
key,
|
|
1493
|
+
dataKey: key,
|
|
1494
|
+
fill: colors[i % colors.length],
|
|
1495
|
+
radius: [borderRadius, borderRadius, 0, 0]
|
|
1496
|
+
});
|
|
1497
|
+
}
|
|
1498
|
+
return import_react10.default.createElement(rc.Line, {
|
|
1499
|
+
key,
|
|
1500
|
+
type: "monotone",
|
|
1501
|
+
dataKey: key,
|
|
1502
|
+
stroke: colors[i % colors.length],
|
|
1503
|
+
strokeWidth: 2
|
|
1504
|
+
});
|
|
1505
|
+
})
|
|
1506
|
+
);
|
|
1507
|
+
default:
|
|
1508
|
+
return import_react10.default.createElement(rc.BarChart, commonProps, grid, xAxis, yAxis, tooltip, legend);
|
|
1509
|
+
}
|
|
1510
|
+
}
|
|
1511
|
+
lazyRecharts.load().catch(() => {
|
|
1512
|
+
});
|
|
1513
|
+
var ChartsRenderer = class {
|
|
1514
|
+
type = "chart";
|
|
1515
|
+
priority = 80;
|
|
1516
|
+
canHandle(content) {
|
|
1517
|
+
return isChart(content);
|
|
1518
|
+
}
|
|
1519
|
+
render(content, options) {
|
|
1520
|
+
try {
|
|
1521
|
+
const config = JSON.parse(content);
|
|
1522
|
+
return import_react10.default.createElement(ChartView, {
|
|
1523
|
+
config,
|
|
1524
|
+
className: options?.className ?? "fmcp-chart-content"
|
|
1525
|
+
});
|
|
1526
|
+
} catch {
|
|
1527
|
+
return import_react10.default.createElement(import_Alert3.default, { severity: "error" }, "Invalid chart JSON");
|
|
1528
|
+
}
|
|
1529
|
+
}
|
|
1530
|
+
};
|
|
1531
|
+
var chartsRenderer = new ChartsRenderer();
|
|
1532
|
+
|
|
1533
|
+
// libs/ui/src/renderer/mermaid/index.ts
|
|
1534
|
+
var import_react11 = __toESM(require("react"));
|
|
1535
|
+
var import_Box8 = __toESM(require("@mui/material/Box"));
|
|
1536
|
+
var import_Alert4 = __toESM(require("@mui/material/Alert"));
|
|
1537
|
+
var import_styles8 = require("@mui/material/styles");
|
|
1538
|
+
var MERMAID_PATTERN2 = /^\s*(?:graph|sequenceDiagram|classDiagram|stateDiagram|flowchart|erDiagram|gantt|pie|journey|gitGraph)\b/;
|
|
1539
|
+
function isMermaid(content) {
|
|
1540
|
+
return MERMAID_PATTERN2.test(content.trim());
|
|
1541
|
+
}
|
|
1542
|
+
var lazyMermaid = createLazyImport("mermaid", async () => {
|
|
1543
|
+
const mod = await runtimeImportWithFallback("mermaid", esmShUrl("mermaid@11"));
|
|
1544
|
+
const mermaid = mod["default"] ?? mod;
|
|
1545
|
+
return mermaid;
|
|
1546
|
+
});
|
|
1547
|
+
var MermaidRoot = (0, import_styles8.styled)(import_Box8.default, {
|
|
1548
|
+
name: "FrontMcpMermaid",
|
|
1549
|
+
slot: "Root"
|
|
1550
|
+
})(({ theme }) => ({
|
|
1551
|
+
width: "100%",
|
|
1552
|
+
display: "flex",
|
|
1553
|
+
justifyContent: "center",
|
|
1554
|
+
padding: theme.spacing(2),
|
|
1555
|
+
"& svg": {
|
|
1556
|
+
maxWidth: "100%",
|
|
1557
|
+
height: "auto"
|
|
1558
|
+
}
|
|
1559
|
+
}));
|
|
1560
|
+
function getMermaidTheme(tv) {
|
|
1561
|
+
return tv.mode === "dark" ? "dark" : "default";
|
|
1562
|
+
}
|
|
1563
|
+
function getMermaidThemeVariables(tv) {
|
|
1564
|
+
return {
|
|
1565
|
+
primaryColor: tv.primary,
|
|
1566
|
+
secondaryColor: tv.secondary,
|
|
1567
|
+
tertiaryColor: tv.info,
|
|
1568
|
+
primaryTextColor: tv.textPrimary,
|
|
1569
|
+
secondaryTextColor: tv.textSecondary,
|
|
1570
|
+
lineColor: tv.divider,
|
|
1571
|
+
fontFamily: tv.fontFamily,
|
|
1572
|
+
fontSize: `${tv.fontSize}px`
|
|
1573
|
+
};
|
|
1574
|
+
}
|
|
1575
|
+
function MermaidView({ definition, className }) {
|
|
1576
|
+
const containerRef = (0, import_react11.useRef)(null);
|
|
1577
|
+
const [svg, setSvg] = (0, import_react11.useState)(null);
|
|
1578
|
+
const [error, setError] = (0, import_react11.useState)(null);
|
|
1579
|
+
const themeValues = useRendererTheme();
|
|
1580
|
+
const uniqueId = (0, import_react11.useId)().replace(/:/g, "-");
|
|
1581
|
+
(0, import_react11.useEffect)(() => {
|
|
1582
|
+
let cancelled = false;
|
|
1583
|
+
async function renderDiagram() {
|
|
1584
|
+
try {
|
|
1585
|
+
const mermaid = lazyMermaid.get() ?? await lazyMermaid.load();
|
|
1586
|
+
mermaid.initialize({
|
|
1587
|
+
startOnLoad: false,
|
|
1588
|
+
theme: getMermaidTheme(themeValues),
|
|
1589
|
+
themeVariables: getMermaidThemeVariables(themeValues),
|
|
1590
|
+
securityLevel: "strict"
|
|
1591
|
+
});
|
|
1592
|
+
const result = await mermaid.render(`mermaid-${uniqueId}`, definition);
|
|
1593
|
+
if (!cancelled) {
|
|
1594
|
+
setSvg(result.svg);
|
|
1595
|
+
setError(null);
|
|
1596
|
+
}
|
|
1597
|
+
} catch (err) {
|
|
1598
|
+
if (!cancelled) {
|
|
1599
|
+
setError(err instanceof Error ? err.message : String(err));
|
|
1600
|
+
setSvg(null);
|
|
1601
|
+
}
|
|
1602
|
+
}
|
|
1603
|
+
}
|
|
1604
|
+
renderDiagram();
|
|
1605
|
+
return () => {
|
|
1606
|
+
cancelled = true;
|
|
1607
|
+
};
|
|
1608
|
+
}, [definition, themeValues, uniqueId]);
|
|
1609
|
+
if (error) {
|
|
1610
|
+
return import_react11.default.createElement(
|
|
1611
|
+
import_Box8.default,
|
|
1612
|
+
{ className },
|
|
1613
|
+
import_react11.default.createElement(import_Alert4.default, { severity: "error", sx: { mb: 1 } }, `Mermaid parse error: ${error}`),
|
|
1614
|
+
import_react11.default.createElement(
|
|
1615
|
+
"pre",
|
|
1616
|
+
{ style: { fontFamily: "monospace", whiteSpace: "pre-wrap", fontSize: "0.85em" } },
|
|
1617
|
+
definition
|
|
1618
|
+
)
|
|
1619
|
+
);
|
|
1620
|
+
}
|
|
1621
|
+
if (!svg) {
|
|
1622
|
+
return import_react11.default.createElement(
|
|
1623
|
+
MermaidRoot,
|
|
1624
|
+
{ className },
|
|
1625
|
+
import_react11.default.createElement(import_Box8.default, { sx: { color: "text.secondary" } }, "Rendering diagram...")
|
|
1626
|
+
);
|
|
1627
|
+
}
|
|
1628
|
+
return import_react11.default.createElement(MermaidRoot, {
|
|
1629
|
+
ref: containerRef,
|
|
1630
|
+
className,
|
|
1631
|
+
dangerouslySetInnerHTML: { __html: svg }
|
|
1632
|
+
});
|
|
1633
|
+
}
|
|
1634
|
+
lazyMermaid.load().catch(() => {
|
|
1635
|
+
});
|
|
1636
|
+
var MermaidRenderer = class {
|
|
1637
|
+
type = "mermaid";
|
|
1638
|
+
priority = 50;
|
|
1639
|
+
canHandle(content) {
|
|
1640
|
+
return isMermaid(content);
|
|
1641
|
+
}
|
|
1642
|
+
render(content, options) {
|
|
1643
|
+
return import_react11.default.createElement(MermaidView, {
|
|
1644
|
+
definition: content.trim(),
|
|
1645
|
+
className: options?.className ?? "fmcp-mermaid-content"
|
|
1646
|
+
});
|
|
1647
|
+
}
|
|
1648
|
+
};
|
|
1649
|
+
var mermaidRenderer = new MermaidRenderer();
|
|
1650
|
+
|
|
1651
|
+
// libs/ui/src/renderer/flow/index.ts
|
|
1652
|
+
var import_react12 = __toESM(require("react"));
|
|
1653
|
+
var import_Box9 = __toESM(require("@mui/material/Box"));
|
|
1654
|
+
var import_Alert5 = __toESM(require("@mui/material/Alert"));
|
|
1655
|
+
var import_Typography5 = __toESM(require("@mui/material/Typography"));
|
|
1656
|
+
var import_styles9 = require("@mui/material/styles");
|
|
1657
|
+
var XYFLOW_CSS_URL = "https://esm.sh/@xyflow/react@12/dist/style.css";
|
|
1658
|
+
var XYFLOW_CSS_ID = "fmcp-xyflow-css";
|
|
1659
|
+
function isFlow(content) {
|
|
1660
|
+
const trimmed = content.trim();
|
|
1661
|
+
if (trimmed.charCodeAt(0) !== 123) return false;
|
|
1662
|
+
return trimmed.includes('"nodes"') && trimmed.includes('"edges"');
|
|
1663
|
+
}
|
|
1664
|
+
var lazyXYFlow = createLazyImport("@xyflow/react", async () => {
|
|
1665
|
+
const mod = await runtimeImportWithFallback(
|
|
1666
|
+
"@xyflow/react",
|
|
1667
|
+
esmShUrl("@xyflow/react@12", { external: ["react", "react-dom"] })
|
|
1668
|
+
);
|
|
1669
|
+
return mod;
|
|
1670
|
+
});
|
|
1671
|
+
var FlowRoot = (0, import_styles9.styled)(import_Box9.default, {
|
|
1672
|
+
name: "FrontMcpFlow",
|
|
1673
|
+
slot: "Root"
|
|
1674
|
+
})(({ theme }) => ({
|
|
1675
|
+
width: "100%",
|
|
1676
|
+
borderRadius: theme.shape.borderRadius,
|
|
1677
|
+
overflow: "hidden",
|
|
1678
|
+
border: `1px solid ${theme.palette.divider}`
|
|
1679
|
+
}));
|
|
1680
|
+
function FlowView({ config, className }) {
|
|
1681
|
+
(0, import_react12.useEffect)(() => {
|
|
1682
|
+
injectStylesheet(XYFLOW_CSS_URL, XYFLOW_CSS_ID);
|
|
1683
|
+
}, []);
|
|
1684
|
+
const themeValues = useRendererTheme();
|
|
1685
|
+
const xyflow = useLazyModule(lazyXYFlow);
|
|
1686
|
+
const height = config.height ?? 500;
|
|
1687
|
+
const styledNodes = (0, import_react12.useMemo)(() => {
|
|
1688
|
+
return config.nodes.map((node) => ({
|
|
1689
|
+
...node,
|
|
1690
|
+
style: {
|
|
1691
|
+
background: themeValues.paper,
|
|
1692
|
+
color: themeValues.textPrimary,
|
|
1693
|
+
border: `1px solid ${themeValues.divider}`,
|
|
1694
|
+
borderRadius: themeValues.borderRadius,
|
|
1695
|
+
padding: 8,
|
|
1696
|
+
fontSize: themeValues.fontSize,
|
|
1697
|
+
fontFamily: themeValues.fontFamily,
|
|
1698
|
+
...node.style
|
|
1699
|
+
}
|
|
1700
|
+
}));
|
|
1701
|
+
}, [config.nodes, themeValues]);
|
|
1702
|
+
const styledEdges = (0, import_react12.useMemo)(() => {
|
|
1703
|
+
return config.edges.map((edge, i) => ({
|
|
1704
|
+
...edge,
|
|
1705
|
+
style: {
|
|
1706
|
+
stroke: themeValues.seriesColors[i % themeValues.seriesColors.length],
|
|
1707
|
+
strokeWidth: 2,
|
|
1708
|
+
...edge.style
|
|
1709
|
+
}
|
|
1710
|
+
}));
|
|
1711
|
+
}, [config.edges, themeValues]);
|
|
1712
|
+
if (!xyflow) {
|
|
1713
|
+
return import_react12.default.createElement(import_Alert5.default, { severity: "info" }, "Loading flow diagram library...");
|
|
1714
|
+
}
|
|
1715
|
+
const { ReactFlow, Controls, MiniMap, Background } = xyflow;
|
|
1716
|
+
return import_react12.default.createElement(
|
|
1717
|
+
FlowRoot,
|
|
1718
|
+
{ className },
|
|
1719
|
+
config.title && import_react12.default.createElement(
|
|
1720
|
+
import_Typography5.default,
|
|
1721
|
+
{ variant: "subtitle1", fontWeight: 600, sx: { p: 1.5, borderBottom: 1, borderColor: "divider" } },
|
|
1722
|
+
config.title
|
|
1723
|
+
),
|
|
1724
|
+
import_react12.default.createElement(
|
|
1725
|
+
import_Box9.default,
|
|
1726
|
+
{ sx: { height } },
|
|
1727
|
+
import_react12.default.createElement(
|
|
1728
|
+
ReactFlow,
|
|
1729
|
+
{
|
|
1730
|
+
nodes: styledNodes,
|
|
1731
|
+
edges: styledEdges,
|
|
1732
|
+
fitView: config.fitView !== false,
|
|
1733
|
+
proOptions: { hideAttribution: true }
|
|
1734
|
+
},
|
|
1735
|
+
import_react12.default.createElement(Controls, {
|
|
1736
|
+
style: {
|
|
1737
|
+
backgroundColor: themeValues.paper,
|
|
1738
|
+
borderRadius: themeValues.borderRadius,
|
|
1739
|
+
border: `1px solid ${themeValues.divider}`
|
|
1740
|
+
}
|
|
1741
|
+
}),
|
|
1742
|
+
import_react12.default.createElement(MiniMap, {
|
|
1743
|
+
style: {
|
|
1744
|
+
backgroundColor: themeValues.background,
|
|
1745
|
+
borderRadius: themeValues.borderRadius
|
|
1746
|
+
},
|
|
1747
|
+
nodeColor: themeValues.primary
|
|
1748
|
+
}),
|
|
1749
|
+
Background && import_react12.default.createElement(Background, {
|
|
1750
|
+
color: themeValues.divider,
|
|
1751
|
+
gap: 16
|
|
1752
|
+
})
|
|
1753
|
+
)
|
|
1754
|
+
)
|
|
1755
|
+
);
|
|
1756
|
+
}
|
|
1757
|
+
lazyXYFlow.load().catch(() => {
|
|
1758
|
+
});
|
|
1759
|
+
var FlowRenderer = class {
|
|
1760
|
+
type = "flow";
|
|
1761
|
+
priority = 70;
|
|
1762
|
+
canHandle(content) {
|
|
1763
|
+
return isFlow(content);
|
|
1764
|
+
}
|
|
1765
|
+
render(content, options) {
|
|
1766
|
+
try {
|
|
1767
|
+
const config = JSON.parse(content);
|
|
1768
|
+
return import_react12.default.createElement(FlowView, {
|
|
1769
|
+
config,
|
|
1770
|
+
className: options?.className ?? "fmcp-flow-content"
|
|
1771
|
+
});
|
|
1772
|
+
} catch {
|
|
1773
|
+
return import_react12.default.createElement(import_Alert5.default, { severity: "error" }, "Invalid flow JSON");
|
|
1774
|
+
}
|
|
1775
|
+
}
|
|
1776
|
+
};
|
|
1777
|
+
var flowRenderer = new FlowRenderer();
|
|
1778
|
+
|
|
1779
|
+
// libs/ui/src/renderer/math/index.ts
|
|
1780
|
+
var import_react13 = __toESM(require("react"));
|
|
1781
|
+
var import_Box10 = __toESM(require("@mui/material/Box"));
|
|
1782
|
+
var import_Alert6 = __toESM(require("@mui/material/Alert"));
|
|
1783
|
+
var import_styles10 = require("@mui/material/styles");
|
|
1784
|
+
var KATEX_CSS_URL = "https://esm.sh/katex@0.16.11/dist/katex.min.css";
|
|
1785
|
+
var KATEX_CSS_ID = "fmcp-katex-css";
|
|
1786
|
+
var MATH_DISPLAY = /\$\$(?:[^$]|\$(?!\$))+\$\$/s;
|
|
1787
|
+
var MATH_INLINE = /\$[^$\n]+?\$/;
|
|
1788
|
+
var MATH_BRACKET_DISPLAY = /\\\[(?:[^\\]|\\.)*\\\]/s;
|
|
1789
|
+
var MATH_PAREN_INLINE = /\\\((?:[^\\]|\\.)*\\\)/s;
|
|
1790
|
+
var MATH_BEGIN = /\\begin\{(?:equation|align|gather|matrix|pmatrix|bmatrix|cases)\}/;
|
|
1791
|
+
function isMath(content) {
|
|
1792
|
+
const trimmed = content.trim();
|
|
1793
|
+
return MATH_DISPLAY.test(trimmed) || MATH_INLINE.test(trimmed) || MATH_BRACKET_DISPLAY.test(trimmed) || MATH_PAREN_INLINE.test(trimmed) || MATH_BEGIN.test(trimmed);
|
|
1794
|
+
}
|
|
1795
|
+
var lazyKatex = createLazyImport("katex", async () => {
|
|
1796
|
+
const mod = await runtimeImportWithFallback("katex", esmShUrl("katex@0.16"));
|
|
1797
|
+
return mod;
|
|
1798
|
+
});
|
|
1799
|
+
var MathRoot = (0, import_styles10.styled)(import_Box10.default, {
|
|
1800
|
+
name: "FrontMcpMath",
|
|
1801
|
+
slot: "Root"
|
|
1802
|
+
})(({ theme }) => ({
|
|
1803
|
+
color: theme.palette.text.primary,
|
|
1804
|
+
"& .katex-display": {
|
|
1805
|
+
margin: theme.spacing(2, 0),
|
|
1806
|
+
textAlign: "center"
|
|
1807
|
+
}
|
|
1808
|
+
}));
|
|
1809
|
+
var MathDisplay = (0, import_styles10.styled)(import_Box10.default, {
|
|
1810
|
+
name: "FrontMcpMath",
|
|
1811
|
+
slot: "Display"
|
|
1812
|
+
})(({ theme }) => ({
|
|
1813
|
+
display: "block",
|
|
1814
|
+
textAlign: "center",
|
|
1815
|
+
margin: theme.spacing(2, 0),
|
|
1816
|
+
fontSize: "1.2em",
|
|
1817
|
+
overflow: "auto"
|
|
1818
|
+
}));
|
|
1819
|
+
var MathInline = (0, import_styles10.styled)("span", {
|
|
1820
|
+
name: "FrontMcpMath",
|
|
1821
|
+
slot: "Inline"
|
|
1822
|
+
})({
|
|
1823
|
+
display: "inline"
|
|
1824
|
+
});
|
|
1825
|
+
function parseMathContent(source) {
|
|
1826
|
+
const segments = [];
|
|
1827
|
+
const mathRegex = /(\$\$(?:[^$]|\$(?!\$))+\$\$|\$[^$\n]+?\$|\\\[(?:[^\\]|\\.)*\\\]|\\\((?:[^\\]|\\.)*\\\)|\\begin\{(?:[^\\]|\\.)*\\end\{[^}]+\})/gs;
|
|
1828
|
+
let lastIndex = 0;
|
|
1829
|
+
let match;
|
|
1830
|
+
while ((match = mathRegex.exec(source)) !== null) {
|
|
1831
|
+
if (match.index > lastIndex) {
|
|
1832
|
+
segments.push({ type: "text", content: source.slice(lastIndex, match.index) });
|
|
1833
|
+
}
|
|
1834
|
+
const raw = match[0];
|
|
1835
|
+
if (raw.startsWith("$$")) {
|
|
1836
|
+
segments.push({ type: "display", content: raw.slice(2, -2).trim() });
|
|
1837
|
+
} else if (raw.startsWith("\\[")) {
|
|
1838
|
+
segments.push({ type: "display", content: raw.slice(2, -2).trim() });
|
|
1839
|
+
} else if (raw.startsWith("\\begin")) {
|
|
1840
|
+
segments.push({ type: "display", content: raw });
|
|
1841
|
+
} else if (raw.startsWith("\\(")) {
|
|
1842
|
+
segments.push({ type: "inline", content: raw.slice(2, -2).trim() });
|
|
1843
|
+
} else if (raw.startsWith("$")) {
|
|
1844
|
+
segments.push({ type: "inline", content: raw.slice(1, -1).trim() });
|
|
1845
|
+
}
|
|
1846
|
+
lastIndex = match.index + raw.length;
|
|
1847
|
+
}
|
|
1848
|
+
if (lastIndex < source.length) {
|
|
1849
|
+
segments.push({ type: "text", content: source.slice(lastIndex) });
|
|
1850
|
+
}
|
|
1851
|
+
return segments;
|
|
1852
|
+
}
|
|
1853
|
+
function MathView({ content, className }) {
|
|
1854
|
+
(0, import_react13.useEffect)(() => {
|
|
1855
|
+
injectStylesheet(KATEX_CSS_URL, KATEX_CSS_ID);
|
|
1856
|
+
}, []);
|
|
1857
|
+
const katexMod = useLazyModule(lazyKatex);
|
|
1858
|
+
const segments = (0, import_react13.useMemo)(() => parseMathContent(content), [content]);
|
|
1859
|
+
const renderToString = katexMod?.default?.renderToString ?? katexMod?.renderToString;
|
|
1860
|
+
if (!renderToString) {
|
|
1861
|
+
return import_react13.default.createElement(
|
|
1862
|
+
MathRoot,
|
|
1863
|
+
{ className },
|
|
1864
|
+
import_react13.default.createElement("pre", { style: { fontFamily: "monospace", whiteSpace: "pre-wrap" } }, content)
|
|
1865
|
+
);
|
|
1866
|
+
}
|
|
1867
|
+
const elements = segments.map((seg, i) => {
|
|
1868
|
+
if (seg.type === "text") {
|
|
1869
|
+
return import_react13.default.createElement("span", { key: i }, seg.content);
|
|
1870
|
+
}
|
|
1871
|
+
try {
|
|
1872
|
+
const html = renderToString(seg.content, {
|
|
1873
|
+
displayMode: seg.type === "display",
|
|
1874
|
+
throwOnError: false
|
|
1875
|
+
});
|
|
1876
|
+
if (seg.type === "display") {
|
|
1877
|
+
return import_react13.default.createElement(MathDisplay, {
|
|
1878
|
+
key: i,
|
|
1879
|
+
dangerouslySetInnerHTML: { __html: html }
|
|
1880
|
+
});
|
|
1881
|
+
}
|
|
1882
|
+
return import_react13.default.createElement(MathInline, {
|
|
1883
|
+
key: i,
|
|
1884
|
+
dangerouslySetInnerHTML: { __html: html }
|
|
1885
|
+
});
|
|
1886
|
+
} catch (err) {
|
|
1887
|
+
return import_react13.default.createElement(
|
|
1888
|
+
import_Alert6.default,
|
|
1889
|
+
{ key: i, severity: "error", sx: { my: 1 } },
|
|
1890
|
+
`LaTeX error: ${err instanceof Error ? err.message : String(err)}
|
|
1891
|
+
Source: ${seg.content}`
|
|
1892
|
+
);
|
|
1893
|
+
}
|
|
1894
|
+
});
|
|
1895
|
+
return import_react13.default.createElement(MathRoot, { className }, ...elements);
|
|
1896
|
+
}
|
|
1897
|
+
lazyKatex.load().catch(() => {
|
|
1898
|
+
});
|
|
1899
|
+
var MathRenderer = class {
|
|
1900
|
+
type = "math";
|
|
1901
|
+
priority = 40;
|
|
1902
|
+
canHandle(content) {
|
|
1903
|
+
return isMath(content);
|
|
1904
|
+
}
|
|
1905
|
+
render(content, options) {
|
|
1906
|
+
return import_react13.default.createElement(MathView, {
|
|
1907
|
+
content,
|
|
1908
|
+
className: options?.className ?? "fmcp-math-content"
|
|
1909
|
+
});
|
|
1910
|
+
}
|
|
1911
|
+
};
|
|
1912
|
+
var mathRenderer = new MathRenderer();
|
|
1913
|
+
|
|
1914
|
+
// libs/ui/src/renderer/maps/index.ts
|
|
1915
|
+
var import_react14 = __toESM(require("react"));
|
|
1916
|
+
var import_Box11 = __toESM(require("@mui/material/Box"));
|
|
1917
|
+
var import_Alert7 = __toESM(require("@mui/material/Alert"));
|
|
1918
|
+
var import_Paper = __toESM(require("@mui/material/Paper"));
|
|
1919
|
+
var import_Typography6 = __toESM(require("@mui/material/Typography"));
|
|
1920
|
+
var import_styles11 = require("@mui/material/styles");
|
|
1921
|
+
var LEAFLET_CSS_URL = "https://esm.sh/leaflet@1.9.4/dist/leaflet.css";
|
|
1922
|
+
var LEAFLET_CSS_ID = "fmcp-leaflet-css";
|
|
1923
|
+
var DEFAULT_TILE_URL = "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png";
|
|
1924
|
+
var DEFAULT_ATTRIBUTION = '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors';
|
|
1925
|
+
var GEOJSON_TYPE_RE2 = /"type"\s*:\s*"(?:FeatureCollection|Feature|Point|LineString|Polygon|MultiPoint|MultiLineString|MultiPolygon|GeometryCollection)"/;
|
|
1926
|
+
function isMap(content) {
|
|
1927
|
+
const trimmed = content.trim();
|
|
1928
|
+
if (trimmed.charCodeAt(0) === 123 && GEOJSON_TYPE_RE2.test(trimmed)) return true;
|
|
1929
|
+
try {
|
|
1930
|
+
const parsed = JSON.parse(trimmed);
|
|
1931
|
+
return !!(parsed.center && Array.isArray(parsed.center) || parsed.markers && Array.isArray(parsed.markers) || parsed.geojson && typeof parsed.geojson === "object");
|
|
1932
|
+
} catch {
|
|
1933
|
+
return false;
|
|
1934
|
+
}
|
|
1935
|
+
}
|
|
1936
|
+
var lazyReactLeaflet = createLazyImport("react-leaflet", async () => {
|
|
1937
|
+
const mod = await runtimeImportWithFallback(
|
|
1938
|
+
"react-leaflet",
|
|
1939
|
+
esmShUrl("react-leaflet@5", { external: ["react", "react-dom"] })
|
|
1940
|
+
);
|
|
1941
|
+
return mod;
|
|
1942
|
+
});
|
|
1943
|
+
var MapRoot = (0, import_styles11.styled)(import_Box11.default, {
|
|
1944
|
+
name: "FrontMcpMap",
|
|
1945
|
+
slot: "Root"
|
|
1946
|
+
})(({ theme }) => ({
|
|
1947
|
+
width: "100%",
|
|
1948
|
+
borderRadius: theme.shape.borderRadius,
|
|
1949
|
+
overflow: "hidden",
|
|
1950
|
+
border: `1px solid ${theme.palette.divider}`
|
|
1951
|
+
}));
|
|
1952
|
+
function parseMapConfig(content) {
|
|
1953
|
+
const parsed = JSON.parse(content);
|
|
1954
|
+
if (parsed.type && [
|
|
1955
|
+
"FeatureCollection",
|
|
1956
|
+
"Feature",
|
|
1957
|
+
"Point",
|
|
1958
|
+
"LineString",
|
|
1959
|
+
"Polygon",
|
|
1960
|
+
"MultiPoint",
|
|
1961
|
+
"MultiLineString",
|
|
1962
|
+
"MultiPolygon",
|
|
1963
|
+
"GeometryCollection"
|
|
1964
|
+
].includes(parsed.type)) {
|
|
1965
|
+
return {
|
|
1966
|
+
center: [0, 0],
|
|
1967
|
+
zoom: 2,
|
|
1968
|
+
geojson: parsed
|
|
1969
|
+
};
|
|
1970
|
+
}
|
|
1971
|
+
return parsed;
|
|
1972
|
+
}
|
|
1973
|
+
function MapView({ config, className }) {
|
|
1974
|
+
(0, import_react14.useEffect)(() => {
|
|
1975
|
+
injectStylesheet(LEAFLET_CSS_URL, LEAFLET_CSS_ID);
|
|
1976
|
+
}, []);
|
|
1977
|
+
const leaflet = useLazyModule(lazyReactLeaflet);
|
|
1978
|
+
const height = config.height ?? 400;
|
|
1979
|
+
const center = config.center ?? [51.505, -0.09];
|
|
1980
|
+
const zoom = config.zoom ?? 13;
|
|
1981
|
+
if (!leaflet) {
|
|
1982
|
+
return import_react14.default.createElement(import_Alert7.default, { severity: "info" }, "Loading map library...");
|
|
1983
|
+
}
|
|
1984
|
+
const { MapContainer, TileLayer, Marker, Popup, GeoJSON } = leaflet;
|
|
1985
|
+
const tileUrl = config.tileLayer?.url ?? DEFAULT_TILE_URL;
|
|
1986
|
+
const attribution = config.tileLayer?.attribution ?? DEFAULT_ATTRIBUTION;
|
|
1987
|
+
return import_react14.default.createElement(
|
|
1988
|
+
MapRoot,
|
|
1989
|
+
{ className },
|
|
1990
|
+
config.title && import_react14.default.createElement(
|
|
1991
|
+
import_Typography6.default,
|
|
1992
|
+
{ variant: "subtitle1", fontWeight: 600, sx: { p: 1.5, borderBottom: 1, borderColor: "divider" } },
|
|
1993
|
+
config.title
|
|
1994
|
+
),
|
|
1995
|
+
import_react14.default.createElement(
|
|
1996
|
+
MapContainer,
|
|
1997
|
+
{
|
|
1998
|
+
center,
|
|
1999
|
+
zoom,
|
|
2000
|
+
style: { height, width: "100%" },
|
|
2001
|
+
scrollWheelZoom: true
|
|
2002
|
+
},
|
|
2003
|
+
import_react14.default.createElement(TileLayer, { url: tileUrl, attribution }),
|
|
2004
|
+
config.markers?.map(
|
|
2005
|
+
(marker, i) => import_react14.default.createElement(
|
|
2006
|
+
Marker,
|
|
2007
|
+
{ key: i, position: marker.position },
|
|
2008
|
+
marker.popup && import_react14.default.createElement(Popup, null, import_react14.default.createElement(import_Paper.default, { elevation: 0, sx: { p: 1 } }, marker.popup))
|
|
2009
|
+
)
|
|
2010
|
+
),
|
|
2011
|
+
config.geojson && import_react14.default.createElement(GeoJSON, { data: config.geojson })
|
|
2012
|
+
)
|
|
2013
|
+
);
|
|
2014
|
+
}
|
|
2015
|
+
lazyReactLeaflet.load().catch(() => {
|
|
2016
|
+
});
|
|
2017
|
+
var MapsRenderer = class {
|
|
2018
|
+
type = "map";
|
|
2019
|
+
priority = 60;
|
|
2020
|
+
canHandle(content) {
|
|
2021
|
+
return isMap(content);
|
|
2022
|
+
}
|
|
2023
|
+
render(content, options) {
|
|
2024
|
+
try {
|
|
2025
|
+
const config = parseMapConfig(content);
|
|
2026
|
+
return import_react14.default.createElement(MapView, {
|
|
2027
|
+
config,
|
|
2028
|
+
className: options?.className ?? "fmcp-map-content"
|
|
2029
|
+
});
|
|
2030
|
+
} catch {
|
|
2031
|
+
return import_react14.default.createElement(import_Alert7.default, { severity: "error" }, "Invalid map/GeoJSON data");
|
|
2032
|
+
}
|
|
2033
|
+
}
|
|
2034
|
+
};
|
|
2035
|
+
var mapsRenderer = new MapsRenderer();
|
|
2036
|
+
|
|
2037
|
+
// libs/ui/src/renderer/media/index.ts
|
|
2038
|
+
var import_react15 = __toESM(require("react"));
|
|
2039
|
+
var import_Box12 = __toESM(require("@mui/material/Box"));
|
|
2040
|
+
var import_Paper2 = __toESM(require("@mui/material/Paper"));
|
|
2041
|
+
var import_styles12 = require("@mui/material/styles");
|
|
2042
|
+
var VIDEO_PATTERNS2 = [
|
|
2043
|
+
/^https?:\/\/[^?#\s]+\.(?:mp4|webm|ogg|mov)(?:\?[^#\s]*)?$/i,
|
|
2044
|
+
/^https?:\/\/(?:www\.)?(?:youtube\.com|youtu\.be|vimeo\.com)\//i,
|
|
2045
|
+
/^data:video\//
|
|
2046
|
+
];
|
|
2047
|
+
var AUDIO_PATTERNS2 = [
|
|
2048
|
+
/^https?:\/\/[^?#\s]+\.(?:mp3|wav|ogg|aac|flac|m4a)(?:\?[^#\s]*)?$/i,
|
|
2049
|
+
/^https?:\/\/(?:www\.)?soundcloud\.com\//i,
|
|
2050
|
+
/^data:audio\//
|
|
2051
|
+
];
|
|
2052
|
+
function isVideo(content) {
|
|
2053
|
+
const trimmed = content.trim();
|
|
2054
|
+
return VIDEO_PATTERNS2.some((p) => p.test(trimmed));
|
|
2055
|
+
}
|
|
2056
|
+
function isAudio(content) {
|
|
2057
|
+
const trimmed = content.trim();
|
|
2058
|
+
return AUDIO_PATTERNS2.some((p) => p.test(trimmed));
|
|
2059
|
+
}
|
|
2060
|
+
function isMedia(content) {
|
|
2061
|
+
return isVideo(content) || isAudio(content);
|
|
2062
|
+
}
|
|
2063
|
+
var lazyReactPlayer = createLazyImport("react-player", async () => {
|
|
2064
|
+
const mod = await runtimeImportWithFallback(
|
|
2065
|
+
"react-player",
|
|
2066
|
+
esmShUrl("react-player@2", { external: ["react", "react-dom"] })
|
|
2067
|
+
);
|
|
2068
|
+
return mod;
|
|
2069
|
+
});
|
|
2070
|
+
var MediaRoot = (0, import_styles12.styled)(import_Paper2.default, {
|
|
2071
|
+
name: "FrontMcpMedia",
|
|
2072
|
+
slot: "Root"
|
|
2073
|
+
})(({ theme }) => ({
|
|
2074
|
+
overflow: "hidden",
|
|
2075
|
+
borderRadius: theme.shape.borderRadius
|
|
2076
|
+
}));
|
|
2077
|
+
var VideoWrapper = (0, import_styles12.styled)(import_Box12.default)({
|
|
2078
|
+
position: "relative",
|
|
2079
|
+
paddingTop: "56.25%",
|
|
2080
|
+
// 16:9 aspect ratio
|
|
2081
|
+
"& > *": {
|
|
2082
|
+
position: "absolute",
|
|
2083
|
+
top: 0,
|
|
2084
|
+
left: 0
|
|
2085
|
+
}
|
|
2086
|
+
});
|
|
2087
|
+
var AudioWrapper = (0, import_styles12.styled)(import_Box12.default)(({ theme }) => ({
|
|
2088
|
+
padding: theme.spacing(1),
|
|
2089
|
+
"& > *": {
|
|
2090
|
+
width: "100%"
|
|
2091
|
+
}
|
|
2092
|
+
}));
|
|
2093
|
+
function MediaView({ url, isAudioContent, className }) {
|
|
2094
|
+
const reactPlayerMod = useLazyModule(lazyReactPlayer);
|
|
2095
|
+
if (!reactPlayerMod) {
|
|
2096
|
+
if (isAudioContent) {
|
|
2097
|
+
return import_react15.default.createElement(
|
|
2098
|
+
MediaRoot,
|
|
2099
|
+
{ variant: "outlined", className },
|
|
2100
|
+
import_react15.default.createElement(
|
|
2101
|
+
AudioWrapper,
|
|
2102
|
+
null,
|
|
2103
|
+
import_react15.default.createElement("audio", { controls: true, src: url, style: { width: "100%" } })
|
|
2104
|
+
)
|
|
2105
|
+
);
|
|
2106
|
+
}
|
|
2107
|
+
return import_react15.default.createElement(
|
|
2108
|
+
MediaRoot,
|
|
2109
|
+
{ variant: "outlined", className },
|
|
2110
|
+
import_react15.default.createElement(
|
|
2111
|
+
VideoWrapper,
|
|
2112
|
+
null,
|
|
2113
|
+
import_react15.default.createElement("video", {
|
|
2114
|
+
controls: true,
|
|
2115
|
+
src: url,
|
|
2116
|
+
style: { position: "absolute", top: 0, left: 0, width: "100%", height: "100%" }
|
|
2117
|
+
})
|
|
2118
|
+
)
|
|
2119
|
+
);
|
|
2120
|
+
}
|
|
2121
|
+
const ReactPlayer = reactPlayerMod.default;
|
|
2122
|
+
if (isAudioContent) {
|
|
2123
|
+
return import_react15.default.createElement(
|
|
2124
|
+
MediaRoot,
|
|
2125
|
+
{ variant: "outlined", className },
|
|
2126
|
+
import_react15.default.createElement(
|
|
2127
|
+
AudioWrapper,
|
|
2128
|
+
null,
|
|
2129
|
+
import_react15.default.createElement(ReactPlayer, {
|
|
2130
|
+
url,
|
|
2131
|
+
controls: true,
|
|
2132
|
+
width: "100%",
|
|
2133
|
+
height: 50
|
|
2134
|
+
})
|
|
2135
|
+
)
|
|
2136
|
+
);
|
|
2137
|
+
}
|
|
2138
|
+
return import_react15.default.createElement(
|
|
2139
|
+
MediaRoot,
|
|
2140
|
+
{ variant: "outlined", className },
|
|
2141
|
+
import_react15.default.createElement(
|
|
2142
|
+
VideoWrapper,
|
|
2143
|
+
null,
|
|
2144
|
+
import_react15.default.createElement(ReactPlayer, {
|
|
2145
|
+
url,
|
|
2146
|
+
controls: true,
|
|
2147
|
+
width: "100%",
|
|
2148
|
+
height: "100%"
|
|
2149
|
+
})
|
|
2150
|
+
)
|
|
2151
|
+
);
|
|
2152
|
+
}
|
|
2153
|
+
lazyReactPlayer.load().catch(() => {
|
|
2154
|
+
});
|
|
2155
|
+
var VideoRenderer = class {
|
|
2156
|
+
type = "video";
|
|
2157
|
+
priority = 20;
|
|
2158
|
+
canHandle(content) {
|
|
2159
|
+
return isVideo(content);
|
|
2160
|
+
}
|
|
2161
|
+
render(content, options) {
|
|
2162
|
+
return import_react15.default.createElement(MediaView, {
|
|
2163
|
+
url: content.trim(),
|
|
2164
|
+
isAudioContent: false,
|
|
2165
|
+
className: options?.className ?? "fmcp-media-content"
|
|
2166
|
+
});
|
|
2167
|
+
}
|
|
2168
|
+
};
|
|
2169
|
+
var AudioRenderer = class {
|
|
2170
|
+
type = "audio";
|
|
2171
|
+
priority = 20;
|
|
2172
|
+
canHandle(content) {
|
|
2173
|
+
return isAudio(content);
|
|
2174
|
+
}
|
|
2175
|
+
render(content, options) {
|
|
2176
|
+
return import_react15.default.createElement(MediaView, {
|
|
2177
|
+
url: content.trim(),
|
|
2178
|
+
isAudioContent: true,
|
|
2179
|
+
className: options?.className ?? "fmcp-media-content"
|
|
2180
|
+
});
|
|
2181
|
+
}
|
|
2182
|
+
};
|
|
2183
|
+
var videoRenderer = new VideoRenderer();
|
|
2184
|
+
var audioRenderer = new AudioRenderer();
|
|
2185
|
+
|
|
2186
|
+
// libs/ui/src/renderer/index.ts
|
|
2187
|
+
function registerAllRenderers() {
|
|
2188
|
+
const all = [
|
|
2189
|
+
pdfRenderer,
|
|
2190
|
+
chartsRenderer,
|
|
2191
|
+
flowRenderer,
|
|
2192
|
+
mapsRenderer,
|
|
2193
|
+
mermaidRenderer,
|
|
2194
|
+
mathRenderer,
|
|
2195
|
+
imageRenderer,
|
|
2196
|
+
videoRenderer,
|
|
2197
|
+
audioRenderer,
|
|
2198
|
+
csvRenderer,
|
|
2199
|
+
reactJsxRenderer,
|
|
2200
|
+
mdxRenderer,
|
|
2201
|
+
htmlRenderer
|
|
2202
|
+
];
|
|
2203
|
+
for (const renderer of all) {
|
|
2204
|
+
registerRenderer(renderer);
|
|
2205
|
+
}
|
|
2206
|
+
}
|