@brftech/filex 0.1.56

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +93 -0
  3. package/dist/ArchiveViewer-CMaBM4yZ.js +98 -0
  4. package/dist/ArchiveViewer-CMaBM4yZ.js.map +1 -0
  5. package/dist/CsvViewer-D5_c7bkP.js +131 -0
  6. package/dist/CsvViewer-D5_c7bkP.js.map +1 -0
  7. package/dist/DrawioViewer-CBOqWzaj.js +140 -0
  8. package/dist/DrawioViewer-CBOqWzaj.js.map +1 -0
  9. package/dist/EpubViewer-Cs6yZIP2.js +143 -0
  10. package/dist/EpubViewer-Cs6yZIP2.js.map +1 -0
  11. package/dist/IpynbViewer-wJhbhUla.js +171 -0
  12. package/dist/IpynbViewer-wJhbhUla.js.map +1 -0
  13. package/dist/MermaidViewer-k_XVXoc5.js +127 -0
  14. package/dist/MermaidViewer-k_XVXoc5.js.map +1 -0
  15. package/dist/PsdViewer-Bo4imBCF.js +109 -0
  16. package/dist/PsdViewer-Bo4imBCF.js.map +1 -0
  17. package/dist/TiffViewer-D73-Gyt-.js +130 -0
  18. package/dist/TiffViewer-D73-Gyt-.js.map +1 -0
  19. package/dist/UTIF-DSbsvqXu.js +3104 -0
  20. package/dist/UTIF-DSbsvqXu.js.map +1 -0
  21. package/dist/Viewer3D-Ba-RPIRz.js +60 -0
  22. package/dist/Viewer3D-Ba-RPIRz.js.map +1 -0
  23. package/dist/_commonjsHelpers-DaMA6jEr.js +9 -0
  24. package/dist/_commonjsHelpers-DaMA6jEr.js.map +1 -0
  25. package/dist/filex.js +5 -0
  26. package/dist/filex.js.map +1 -0
  27. package/dist/filex.umd.cjs +304 -0
  28. package/dist/filex.umd.cjs.map +1 -0
  29. package/dist/index-UFULWo35.js +10736 -0
  30. package/dist/index-UFULWo35.js.map +1 -0
  31. package/dist/index-idz8Cz5t.js +10623 -0
  32. package/dist/index-idz8Cz5t.js.map +1 -0
  33. package/dist/index.d.ts +23 -0
  34. package/dist/katex-yuB6V-q6.js +11616 -0
  35. package/dist/katex-yuB6V-q6.js.map +1 -0
  36. package/dist/papaparse.min-VB1HBwYX.js +441 -0
  37. package/dist/papaparse.min-VB1HBwYX.js.map +1 -0
  38. package/dist/style.css +1 -0
  39. package/dist/useViewerFetch-czqbd2Lj.js +25 -0
  40. package/dist/useViewerFetch-czqbd2Lj.js.map +1 -0
  41. package/package.json +63 -0
@@ -0,0 +1,143 @@
1
+ import { d as U, o as F, h as L, w as V, a as u, c as i, e as c, t as b, F as H, i as g, f as r, _ as R } from "./index-idz8Cz5t.js";
2
+ const S = {
3
+ key: 0,
4
+ class: "filex-viewer-fallback"
5
+ }, z = {
6
+ key: 0,
7
+ class: "filex-viewer-epub__nav"
8
+ }, A = ["disabled"], D = ["disabled"], N = {
9
+ key: 1,
10
+ class: "filex-viewer-epub__loading"
11
+ }, T = /* @__PURE__ */ U({
12
+ __name: "EpubViewer",
13
+ props: {
14
+ url: {},
15
+ mime: {},
16
+ ext: {},
17
+ t: { type: Function },
18
+ authHeaders: { type: Function },
19
+ authCredentials: {}
20
+ },
21
+ setup(k) {
22
+ const s = k, x = r(null), v = r(null), n = r(null), E = r([]), B = r(100), o = r(!1), d = r(!0);
23
+ let a = null, e = null;
24
+ async function p() {
25
+ d.value = !0, o.value = !1, n.value = null;
26
+ let t = null;
27
+ try {
28
+ t = await import(
29
+ /* @vite-ignore */
30
+ "epubjs"
31
+ );
32
+ } catch {
33
+ n.value = s.t ? s.t("viewer.peer_not_installed") : "EPUB viewer requires `epubjs` — install or use download.", d.value = !1;
34
+ return;
35
+ }
36
+ try {
37
+ const l = t.default ?? t;
38
+ let m = s.url;
39
+ if (s.authHeaders) {
40
+ const P = s.authHeaders(), f = await fetch(s.url, {
41
+ headers: P,
42
+ credentials: s.authCredentials || "same-origin"
43
+ });
44
+ if (!f.ok) throw new Error(`${f.status} ${f.statusText}`);
45
+ m = await f.arrayBuffer();
46
+ }
47
+ if (a = l(m), !v.value)
48
+ throw new Error("EPUB mount target missing");
49
+ e = a.renderTo(v.value, {
50
+ width: "100%",
51
+ height: "100%",
52
+ flow: "paginated",
53
+ manager: "default"
54
+ }), await e.display(), e.themes.fontSize(B.value + "%");
55
+ const w = await a.loaded.navigation;
56
+ E.value = (w == null ? void 0 : w.toc) ?? [], o.value = !0;
57
+ } catch (l) {
58
+ n.value = l instanceof Error ? l.message : "EPUB load failed";
59
+ } finally {
60
+ d.value = !1;
61
+ }
62
+ }
63
+ function y() {
64
+ var t;
65
+ (t = e == null ? void 0 : e.next) == null || t.call(e);
66
+ }
67
+ function _() {
68
+ var t;
69
+ (t = e == null ? void 0 : e.prev) == null || t.call(e);
70
+ }
71
+ function h(t) {
72
+ t.key === "ArrowRight" || t.key === "PageDown" ? y() : (t.key === "ArrowLeft" || t.key === "PageUp") && _();
73
+ }
74
+ F(() => {
75
+ p(), window.addEventListener("keydown", h);
76
+ }), L(() => {
77
+ var t, l;
78
+ window.removeEventListener("keydown", h);
79
+ try {
80
+ (t = e == null ? void 0 : e.destroy) == null || t.call(e);
81
+ } catch {
82
+ }
83
+ try {
84
+ (l = a == null ? void 0 : a.destroy) == null || l.call(a);
85
+ } catch {
86
+ }
87
+ e = null, a = null;
88
+ }), V(
89
+ () => s.url,
90
+ () => {
91
+ if (e)
92
+ try {
93
+ e.destroy();
94
+ } catch {
95
+ }
96
+ if (a)
97
+ try {
98
+ a.destroy();
99
+ } catch {
100
+ }
101
+ a = null, e = null, p();
102
+ }
103
+ );
104
+ function C(t, l) {
105
+ return s.t ? s.t(t) : l;
106
+ }
107
+ return (t, l) => (u(), i("div", {
108
+ ref_key: "root",
109
+ ref: x,
110
+ class: "filex-viewer-epub"
111
+ }, [
112
+ n.value ? (u(), i("div", S, [
113
+ l[0] || (l[0] = c("span", { class: "filex-viewer-fallback__icon" }, "📖", -1)),
114
+ c("p", null, b(n.value), 1)
115
+ ])) : (u(), i(H, { key: 1 }, [
116
+ c("div", {
117
+ ref_key: "containerRef",
118
+ ref: v,
119
+ class: "filex-viewer-epub__rendition"
120
+ }, null, 512),
121
+ o.value ? (u(), i("div", z, [
122
+ c("button", {
123
+ type: "button",
124
+ class: "filex-viewer-btn",
125
+ onClick: _,
126
+ disabled: !o.value
127
+ }, "‹", 8, A),
128
+ c("button", {
129
+ type: "button",
130
+ class: "filex-viewer-btn",
131
+ onClick: y,
132
+ disabled: !o.value
133
+ }, "›", 8, D)
134
+ ])) : g("", !0),
135
+ d.value ? (u(), i("div", N, b(C("viewer.loading", "Loading…")), 1)) : g("", !0)
136
+ ], 64))
137
+ ], 512));
138
+ }
139
+ }), j = /* @__PURE__ */ R(T, [["__scopeId", "data-v-cd1c1cee"]]);
140
+ export {
141
+ j as default
142
+ };
143
+ //# sourceMappingURL=EpubViewer-Cs6yZIP2.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EpubViewer-Cs6yZIP2.js","sources":["../../core/src/viewers/EpubViewer.vue"],"sourcesContent":["<script setup lang=\"ts\">\r\n/**\r\n * EpubViewer — flowable EPUB reader via `epubjs`.\r\n *\r\n * Lazy-imports `epubjs` (~80 KB gzipped). epub.js renders the publication\r\n * inside an iframe (default `flow: 'paginated'`), but we use it in\r\n * scrolled-doc mode only when the user toggles the \"fit-width\" flag — by\r\n * default we keep paginated since that matches reader-app expectations.\r\n *\r\n * UX:\r\n * - prev/next page buttons (also keyboard arrow keys via composable)\r\n * - collapsible TOC sidebar (built from `book.loaded.navigation`)\r\n * - font size +/- (Themes API)\r\n * - graceful fallback if peer not installed\r\n */\r\nimport { onBeforeUnmount, onMounted, ref, watch } from 'vue';\r\n\r\nconst props = defineProps<{\r\n url: string;\r\n mime?: string;\r\n ext: string;\r\n t?: (key: string) => string;\r\n authHeaders?: () => Record<string, string>;\r\n authCredentials?: RequestCredentials;\r\n}>();\r\n\r\ninterface TocNode {\r\n href: string;\r\n label: string;\r\n subitems?: TocNode[];\r\n}\r\n\r\nconst root = ref<HTMLDivElement | null>(null);\r\nconst containerRef = ref<HTMLDivElement | null>(null);\r\nconst error = ref<string | null>(null);\r\nconst toc = ref<TocNode[]>([]);\r\nconst tocOpen = ref(false);\r\nconst fontSize = ref(100);\r\nconst ready = ref(false);\r\nconst loading = ref(true);\r\n\r\nlet book: any = null;\r\nlet rendition: any = null;\r\n\r\nasync function load(): Promise<void> {\r\n loading.value = true;\r\n ready.value = false;\r\n error.value = null;\r\n let mod: any = null;\r\n try {\r\n mod = await import(/* @vite-ignore */ 'epubjs');\r\n } catch {\r\n error.value = props.t\r\n ? props.t('viewer.peer_not_installed')\r\n : 'EPUB viewer requires `epubjs` — install or use download.';\r\n loading.value = false;\r\n return;\r\n }\r\n try {\r\n const Epub = mod.default ?? mod;\r\n // epub.js wants a URL (it then fetches with XHR). When the host\r\n // site requires auth headers we have to load the file ourselves\r\n // and pass an ArrayBuffer instead.\r\n let source: string | ArrayBuffer = props.url;\r\n if (props.authHeaders) {\r\n const headers = props.authHeaders();\r\n const res = await fetch(props.url, {\r\n headers,\r\n credentials: props.authCredentials || 'same-origin',\r\n });\r\n if (!res.ok) throw new Error(`${res.status} ${res.statusText}`);\r\n source = await res.arrayBuffer();\r\n }\r\n book = Epub(source);\r\n if (!containerRef.value) {\r\n throw new Error('EPUB mount target missing');\r\n }\r\n rendition = book.renderTo(containerRef.value, {\r\n width: '100%',\r\n height: '100%',\r\n flow: 'paginated',\r\n manager: 'default',\r\n });\r\n await rendition.display();\r\n rendition.themes.fontSize(fontSize.value + '%');\r\n const nav = await book.loaded.navigation;\r\n toc.value = (nav?.toc ?? []) as TocNode[];\r\n ready.value = true;\r\n } catch (err) {\r\n error.value =\r\n err instanceof Error ? err.message : 'EPUB load failed';\r\n } finally {\r\n loading.value = false;\r\n }\r\n}\r\n\r\nfunction next(): void {\r\n rendition?.next?.();\r\n}\r\nfunction prev(): void {\r\n rendition?.prev?.();\r\n}\r\nfunction gotoHref(href: string): void {\r\n rendition?.display?.(href);\r\n tocOpen.value = false;\r\n}\r\nfunction bigger(): void {\r\n fontSize.value = Math.min(200, fontSize.value + 10);\r\n rendition?.themes?.fontSize(fontSize.value + '%');\r\n}\r\nfunction smaller(): void {\r\n fontSize.value = Math.max(60, fontSize.value - 10);\r\n rendition?.themes?.fontSize(fontSize.value + '%');\r\n}\r\n\r\nfunction onKey(ev: KeyboardEvent): void {\r\n if (ev.key === 'ArrowRight' || ev.key === 'PageDown') next();\r\n else if (ev.key === 'ArrowLeft' || ev.key === 'PageUp') prev();\r\n}\r\n\r\nonMounted(() => {\r\n load();\r\n window.addEventListener('keydown', onKey);\r\n});\r\n\r\nonBeforeUnmount(() => {\r\n window.removeEventListener('keydown', onKey);\r\n try {\r\n rendition?.destroy?.();\r\n } catch {\r\n /* ignore */\r\n }\r\n try {\r\n book?.destroy?.();\r\n } catch {\r\n /* ignore */\r\n }\r\n rendition = null;\r\n book = null;\r\n});\r\n\r\nwatch(\r\n () => props.url,\r\n () => {\r\n if (rendition) {\r\n try {\r\n rendition.destroy();\r\n } catch {\r\n /* ignore */\r\n }\r\n }\r\n if (book) {\r\n try {\r\n book.destroy();\r\n } catch {\r\n /* ignore */\r\n }\r\n }\r\n book = null;\r\n rendition = null;\r\n load();\r\n },\r\n);\r\n\r\nfunction tt(key: string, fallback: string): string {\r\n return props.t ? props.t(key) : fallback;\r\n}\r\n</script>\r\n\r\n<template>\r\n <div ref=\"root\" class=\"filex-viewer-epub\">\r\n <div v-if=\"error\" class=\"filex-viewer-fallback\">\r\n <span class=\"filex-viewer-fallback__icon\">📖</span>\r\n <p>{{ error }}</p>\r\n </div>\r\n <template v-else>\r\n <div ref=\"containerRef\" class=\"filex-viewer-epub__rendition\" />\r\n <div v-if=\"ready\" class=\"filex-viewer-epub__nav\">\r\n <button type=\"button\" class=\"filex-viewer-btn\" @click=\"prev\" :disabled=\"!ready\">‹</button>\r\n <button type=\"button\" class=\"filex-viewer-btn\" @click=\"next\" :disabled=\"!ready\">›</button>\r\n </div>\r\n <div v-if=\"loading\" class=\"filex-viewer-epub__loading\">\r\n {{ tt('viewer.loading', 'Loading…') }}\r\n </div>\r\n </template>\r\n </div>\r\n</template>\r\n\r\n<style scoped>\r\n.filex-viewer-epub__nav {\r\n position: absolute;\r\n bottom: 12px;\r\n left: 50%;\r\n transform: translateX(-50%);\r\n display: flex;\r\n gap: 8px;\r\n padding: 4px 8px;\r\n background: var(--fe-bg-elev, rgba(255, 255, 255, 0.9));\r\n border: 1px solid var(--fe-border, #e2e6ed);\r\n border-radius: 6px;\r\n backdrop-filter: blur(4px);\r\n}\r\n.filex-viewer-epub {\r\n display: flex;\r\n flex-direction: column;\r\n width: 100%;\r\n height: 100%;\r\n min-height: 70vh;\r\n background: var(--fe-bg, #fff);\r\n color: var(--fe-text, #1a1e27);\r\n position: relative;\r\n}\r\n.filex-viewer-epub__bar {\r\n display: flex;\r\n align-items: center;\r\n gap: 6px;\r\n padding: 8px 12px;\r\n background: var(--fe-bg-elev, #f7f8fa);\r\n border-bottom: 1px solid var(--fe-border, #e2e6ed);\r\n font-size: 13px;\r\n}\r\n.filex-viewer-spacer { flex: 1; }\r\n.filex-viewer-epub__fs {\r\n display: inline-block;\r\n min-width: 40px;\r\n text-align: center;\r\n font-variant-numeric: tabular-nums;\r\n font-size: 12px;\r\n color: var(--fe-text-muted, #5a6475);\r\n}\r\n.filex-viewer-epub__main {\r\n flex: 1;\r\n min-height: 0;\r\n display: flex;\r\n}\r\n.filex-viewer-epub__rendition {\r\n flex: 1;\r\n min-height: 0;\r\n}\r\n.filex-viewer-epub__toc {\r\n width: 260px;\r\n border-right: 1px solid var(--fe-border, #e2e6ed);\r\n overflow-y: auto;\r\n padding: 12px 0;\r\n background: var(--fe-bg-elev, #f7f8fa);\r\n}\r\n.filex-viewer-epub__toc ul {\r\n list-style: none;\r\n margin: 0;\r\n padding: 0;\r\n}\r\n.filex-viewer-epub__toc-link {\r\n display: block;\r\n width: 100%;\r\n text-align: left;\r\n background: transparent;\r\n border: 0;\r\n padding: 6px 14px;\r\n font: inherit;\r\n color: inherit;\r\n cursor: pointer;\r\n}\r\n.filex-viewer-epub__toc-link:hover {\r\n background: var(--fe-bg-hover, #edf0f5);\r\n}\r\n.filex-viewer-epub__toc-link.is-child {\r\n padding-left: 28px;\r\n color: var(--fe-text-muted, #5a6475);\r\n font-size: 12px;\r\n}\r\n.filex-viewer-epub__loading {\r\n position: absolute;\r\n inset: auto 0 0 0;\r\n text-align: center;\r\n padding: 6px;\r\n background: rgba(0, 0, 0, 0.05);\r\n font-size: 12px;\r\n color: var(--fe-text-muted, #5a6475);\r\n}\r\n.filex-viewer-fallback {\r\n text-align: center;\r\n padding: 32px;\r\n color: var(--fe-text-muted, #5a6475);\r\n}\r\n.filex-viewer-fallback__icon {\r\n font-size: 48px;\r\n display: block;\r\n margin-bottom: 12px;\r\n}\r\n.filex-viewer-btn {\r\n border: 1px solid var(--fe-border, #e2e6ed);\r\n background: var(--fe-bg, #fff);\r\n color: var(--fe-text, #1a1e27);\r\n padding: 4px 10px;\r\n border-radius: 4px;\r\n cursor: pointer;\r\n font: inherit;\r\n font-size: 12px;\r\n}\r\n.filex-viewer-btn:hover:not(:disabled) {\r\n background: var(--fe-bg-hover, #edf0f5);\r\n}\r\n.filex-viewer-btn:disabled {\r\n opacity: 0.5;\r\n cursor: not-allowed;\r\n}\r\n</style>\r\n"],"names":["props","__props","root","ref","containerRef","error","toc","fontSize","ready","loading","book","rendition","load","mod","Epub","source","headers","res","nav","err","next","_a","prev","onKey","ev","onMounted","onBeforeUnmount","_b","watch","tt","key","fallback","_createElementBlock","_openBlock","_hoisted_1","_cache","_createElementVNode","_Fragment","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_toDisplayString"],"mappings":"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"}
@@ -0,0 +1,171 @@
1
+ import { f as J } from "./useViewerFetch-czqbd2Lj.js";
2
+ import { d as R, o as U, h as D, w as q, a as t, c as a, e as o, t as d, F as m, k as C, i as V, f as p, l as z, _ as G } from "./index-idz8Cz5t.js";
3
+ const K = { class: "filex-viewer-ipynb" }, P = { class: "filex-viewer-ipynb__pane" }, Q = {
4
+ key: 0,
5
+ class: "filex-viewer-fallback"
6
+ }, W = {
7
+ key: 1,
8
+ class: "filex-viewer-fallback"
9
+ }, X = { key: 2 }, Y = ["data-type"], Z = { class: "filex-viewer-ipynb__exec" }, ee = { class: "filex-viewer-ipynb__src hljs" }, te = ["innerHTML"], ae = { key: 1 }, ne = {
10
+ key: 0,
11
+ class: "filex-viewer-ipynb__outputs"
12
+ }, re = ["src", "alt"], le = ["innerHTML"], ie = ["data-type"], se = ["innerHTML"], ue = {
13
+ key: 1,
14
+ class: "filex-viewer-ipynb__md-raw"
15
+ }, ce = {
16
+ key: 2,
17
+ class: "filex-viewer-ipynb__src"
18
+ }, oe = /* @__PURE__ */ R({
19
+ __name: "IpynbViewer",
20
+ props: {
21
+ url: {},
22
+ ext: {},
23
+ t: { type: Function },
24
+ authHeaders: { type: Function },
25
+ authCredentials: {}
26
+ },
27
+ setup(E) {
28
+ const u = E, _ = p([]), M = p("python"), f = p(null), y = p(!0), w = p(/* @__PURE__ */ new Map()), k = p(/* @__PURE__ */ new Map());
29
+ let v = 0, x = null, g = null;
30
+ async function F() {
31
+ if (g !== null) return g || null;
32
+ try {
33
+ const e = await import(
34
+ /* @vite-ignore */
35
+ "markdown-it"
36
+ ), n = e.default ?? e;
37
+ return g = new n({ html: !1, linkify: !0, breaks: !0 }), g;
38
+ } catch {
39
+ return g = !1, null;
40
+ }
41
+ }
42
+ function s(e) {
43
+ return Array.isArray(e) ? e.join("") : e ?? "";
44
+ }
45
+ async function H() {
46
+ var i, h, S, j;
47
+ y.value = !0, f.value = null, _.value = [], w.value = /* @__PURE__ */ new Map(), k.value = /* @__PURE__ */ new Map();
48
+ const e = ++v;
49
+ let n;
50
+ try {
51
+ n = await J({
52
+ url: u.url,
53
+ headers: ((i = u.authHeaders) == null ? void 0 : i.call(u)) ?? {},
54
+ credentials: u.authCredentials
55
+ });
56
+ } catch (l) {
57
+ f.value = l instanceof Error ? l.message : "fetch failed", y.value = !1;
58
+ return;
59
+ }
60
+ if (e !== v) return;
61
+ let r;
62
+ try {
63
+ r = JSON.parse(n);
64
+ } catch {
65
+ f.value = "Invalid notebook JSON", y.value = !1;
66
+ return;
67
+ }
68
+ if (_.value = Array.isArray(r.cells) ? r.cells : [], M.value = ((S = (h = r.metadata) == null ? void 0 : h.kernelspec) == null ? void 0 : S.language) || "python", x = await z(), e !== v) return;
69
+ if (x) {
70
+ const l = x.default ?? x, b = (j = l.getLanguage) != null && j.call(l, M.value) ? M.value : null;
71
+ _.value.forEach((A, $) => {
72
+ if (A.cell_type === "code") {
73
+ const B = s(A.source);
74
+ try {
75
+ const O = b ? l.highlight(B, { language: b, ignoreIllegals: !0 }) : l.highlightAuto(B);
76
+ w.value.set($, O.value);
77
+ } catch {
78
+ }
79
+ }
80
+ });
81
+ }
82
+ const c = await F();
83
+ e === v && (c && _.value.forEach((l, b) => {
84
+ if (l.cell_type === "markdown")
85
+ try {
86
+ k.value.set(b, c.render(s(l.source)));
87
+ } catch {
88
+ }
89
+ }), y.value = !1);
90
+ }
91
+ function T(e) {
92
+ var n;
93
+ return e ? e.output_type === "stream" ? s(e.text) : e.output_type === "error" ? [e.ename, e.evalue, ...e.traceback || []].filter(Boolean).join(`
94
+ `) : (e.output_type === "execute_result" || e.output_type === "display_data") && (n = e.data) != null && n["text/plain"] ? s(e.data["text/plain"]) : null : null;
95
+ }
96
+ function L(e) {
97
+ if (!(e != null && e.data)) return null;
98
+ if (e.data["image/png"]) return `data:image/png;base64,${e.data["image/png"]}`;
99
+ if (e.data["image/jpeg"]) return `data:image/jpeg;base64,${e.data["image/jpeg"]}`;
100
+ if (e.data["image/svg+xml"]) {
101
+ const n = s(e.data["image/svg+xml"]);
102
+ return `data:image/svg+xml;utf8,${encodeURIComponent(n)}`;
103
+ }
104
+ return null;
105
+ }
106
+ function I(e) {
107
+ return e != null && e.data && e.data["text/html"] ? s(e.data["text/html"]).replace(/<script[\s\S]*?<\/script>/gi, "") : null;
108
+ }
109
+ U(H), D(() => {
110
+ v++;
111
+ }), q(() => u.url, H);
112
+ function N(e, n) {
113
+ return u.t ? u.t(e) : n;
114
+ }
115
+ return (e, n) => (t(), a("div", K, [
116
+ o("div", P, [
117
+ f.value ? (t(), a("div", Q, [
118
+ n[0] || (n[0] = o("span", { class: "filex-viewer-fallback__icon" }, "📓", -1)),
119
+ o("p", null, d(f.value), 1)
120
+ ])) : y.value ? (t(), a("div", W, [
121
+ n[1] || (n[1] = o("span", { class: "filex-viewer-fallback__icon" }, "⏳", -1)),
122
+ o("p", null, d(N("viewer.loading", "Loading…")), 1)
123
+ ])) : (t(), a("div", X, [
124
+ (t(!0), a(m, null, C(_.value, (r, c) => (t(), a("div", {
125
+ key: c,
126
+ class: "filex-viewer-ipynb__cell",
127
+ "data-type": r.cell_type
128
+ }, [
129
+ r.cell_type === "code" ? (t(), a(m, { key: 0 }, [
130
+ o("div", Z, " In [" + d(r.execution_count ?? " ") + "]: ", 1),
131
+ o("pre", ee, [
132
+ w.value.get(c) ? (t(), a("code", {
133
+ key: 0,
134
+ innerHTML: w.value.get(c)
135
+ }, null, 8, te)) : (t(), a("code", ae, d(s(r.source)), 1))
136
+ ]),
137
+ r.outputs && r.outputs.length ? (t(), a("div", ne, [
138
+ (t(!0), a(m, null, C(r.outputs, (i, h) => (t(), a(m, { key: h }, [
139
+ L(i) ? (t(), a("img", {
140
+ key: 0,
141
+ src: L(i) || "",
142
+ class: "filex-viewer-ipynb__img",
143
+ alt: `output ${h}`
144
+ }, null, 8, re)) : I(i) ? (t(), a("div", {
145
+ key: 1,
146
+ class: "filex-viewer-ipynb__html",
147
+ innerHTML: I(i)
148
+ }, null, 8, le)) : T(i) ? (t(), a("pre", {
149
+ key: 2,
150
+ class: "filex-viewer-ipynb__out",
151
+ "data-type": i.output_type
152
+ }, d(T(i)), 9, ie)) : V("", !0)
153
+ ], 64))), 128))
154
+ ])) : V("", !0)
155
+ ], 64)) : r.cell_type === "markdown" ? (t(), a(m, { key: 1 }, [
156
+ k.value.get(c) ? (t(), a("div", {
157
+ key: 0,
158
+ class: "filex-viewer-ipynb__md",
159
+ innerHTML: k.value.get(c)
160
+ }, null, 8, se)) : (t(), a("pre", ue, d(s(r.source)), 1))
161
+ ], 64)) : (t(), a("pre", ce, d(s(r.source)), 1))
162
+ ], 8, Y))), 128))
163
+ ]))
164
+ ])
165
+ ]));
166
+ }
167
+ }), _e = /* @__PURE__ */ G(oe, [["__scopeId", "data-v-cd9ee977"]]);
168
+ export {
169
+ _e as default
170
+ };
171
+ //# sourceMappingURL=IpynbViewer-wJhbhUla.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IpynbViewer-wJhbhUla.js","sources":["../../core/src/viewers/IpynbViewer.vue"],"sourcesContent":["<script setup lang=\"ts\">\r\n/**\r\n * IpynbViewer — Jupyter notebook (.ipynb JSON) renderer.\r\n *\r\n * Pure-JS render — no peer dependency required:\r\n * - code cells → `<pre><code>` (highlight.js when available)\r\n * - markdown cells → markdown-it when available, plain `<pre>` otherwise\r\n * - output cells → text (stream / display_data 'text/plain'),\r\n * images (display_data 'image/png' base64),\r\n * HTML (display_data 'text/html', sanitized via\r\n * element-only insertion — no script tags)\r\n *\r\n * Source list / output count counters at the top so a 200-cell\r\n * notebook doesn't surprise the user.\r\n */\r\nimport { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue';\r\nimport { fetchViewerText } from '../composables/useViewerFetch';\r\nimport { ensureHighlight } from '../composables/useMonacoLoader';\r\n\r\nconst props = defineProps<{\r\n url: string;\r\n ext: string;\r\n t?: (key: string) => string;\r\n authHeaders?: () => Record<string, string>;\r\n authCredentials?: RequestCredentials;\r\n}>();\r\n\r\ninterface Cell {\r\n cell_type: 'code' | 'markdown' | 'raw' | string;\r\n source: string | string[];\r\n outputs?: any[];\r\n execution_count?: number | null;\r\n metadata?: Record<string, unknown>;\r\n}\r\n\r\ninterface Notebook {\r\n cells: Cell[];\r\n metadata?: { kernelspec?: { language?: string; name?: string } };\r\n}\r\n\r\nconst cells = ref<Cell[]>([]);\r\nconst language = ref<string>('python');\r\nconst error = ref<string | null>(null);\r\nconst loading = ref(true);\r\nconst renderedSources = ref<Map<number, string>>(new Map());\r\nconst renderedMarkdown = ref<Map<number, string>>(new Map());\r\n\r\nlet renderToken = 0;\r\nlet highlight: any = null;\r\nlet mdRenderer: any = null;\r\n\r\nasync function ensureMd(): Promise<any | null> {\r\n if (mdRenderer !== null) return mdRenderer || null;\r\n try {\r\n const mod = await import(/* @vite-ignore */ 'markdown-it');\r\n const Md = (mod as any).default ?? mod;\r\n mdRenderer = new Md({ html: false, linkify: true, breaks: true });\r\n return mdRenderer;\r\n } catch {\r\n mdRenderer = false;\r\n return null;\r\n }\r\n}\r\n\r\nfunction joinSource(source: string | string[]): string {\r\n return Array.isArray(source) ? source.join('') : (source ?? '');\r\n}\r\n\r\nasync function load(): Promise<void> {\r\n loading.value = true;\r\n error.value = null;\r\n cells.value = [];\r\n renderedSources.value = new Map();\r\n renderedMarkdown.value = new Map();\r\n const myToken = ++renderToken;\r\n\r\n let raw: string;\r\n try {\r\n raw = await fetchViewerText({\r\n url: props.url,\r\n headers: props.authHeaders?.() ?? {},\r\n credentials: props.authCredentials,\r\n });\r\n } catch (err) {\r\n error.value = err instanceof Error ? err.message : 'fetch failed';\r\n loading.value = false;\r\n return;\r\n }\r\n\r\n if (myToken !== renderToken) return;\r\n\r\n let nb: Notebook;\r\n try {\r\n nb = JSON.parse(raw);\r\n } catch (err) {\r\n error.value = 'Invalid notebook JSON';\r\n loading.value = false;\r\n return;\r\n }\r\n cells.value = Array.isArray(nb.cells) ? nb.cells : [];\r\n language.value = nb.metadata?.kernelspec?.language || 'python';\r\n\r\n // Best-effort hljs highlight per code cell.\r\n highlight = (await ensureHighlight()) as any;\r\n if (myToken !== renderToken) return;\r\n if (highlight) {\r\n const hljs = highlight.default ?? highlight;\r\n const langOk = hljs.getLanguage?.(language.value) ? language.value : null;\r\n cells.value.forEach((cell, idx) => {\r\n if (cell.cell_type === 'code') {\r\n const text = joinSource(cell.source);\r\n try {\r\n const result = langOk\r\n ? hljs.highlight(text, { language: langOk, ignoreIllegals: true })\r\n : hljs.highlightAuto(text);\r\n renderedSources.value.set(idx, result.value);\r\n } catch {\r\n /* leave unrendered */\r\n }\r\n }\r\n });\r\n }\r\n\r\n const md = await ensureMd();\r\n if (myToken !== renderToken) return;\r\n if (md) {\r\n cells.value.forEach((cell, idx) => {\r\n if (cell.cell_type === 'markdown') {\r\n try {\r\n renderedMarkdown.value.set(idx, md.render(joinSource(cell.source)));\r\n } catch {\r\n /* leave plain */\r\n }\r\n }\r\n });\r\n }\r\n\r\n loading.value = false;\r\n}\r\n\r\nfunction outputText(out: any): string | null {\r\n if (!out) return null;\r\n if (out.output_type === 'stream') {\r\n return joinSource(out.text);\r\n }\r\n if (out.output_type === 'error') {\r\n return [out.ename, out.evalue, ...(out.traceback || [])]\r\n .filter(Boolean)\r\n .join('\\n');\r\n }\r\n if (out.output_type === 'execute_result' || out.output_type === 'display_data') {\r\n if (out.data?.['text/plain']) {\r\n return joinSource(out.data['text/plain']);\r\n }\r\n }\r\n return null;\r\n}\r\n\r\nfunction outputImage(out: any): string | null {\r\n if (!out?.data) return null;\r\n if (out.data['image/png']) return `data:image/png;base64,${out.data['image/png']}`;\r\n if (out.data['image/jpeg']) return `data:image/jpeg;base64,${out.data['image/jpeg']}`;\r\n if (out.data['image/svg+xml']) {\r\n const svg = joinSource(out.data['image/svg+xml']);\r\n return `data:image/svg+xml;utf8,${encodeURIComponent(svg)}`;\r\n }\r\n return null;\r\n}\r\n\r\nfunction outputHtml(out: any): string | null {\r\n if (!out?.data) return null;\r\n if (out.data['text/html']) {\r\n const html = joinSource(out.data['text/html']);\r\n // Strip <script> for safety — outputs from arbitrary notebooks.\r\n return html.replace(/<script[\\s\\S]*?<\\/script>/gi, '');\r\n }\r\n return null;\r\n}\r\n\r\nonMounted(load);\r\nonBeforeUnmount(() => {\r\n renderToken++;\r\n});\r\nwatch(() => props.url, load);\r\n\r\nconst stats = computed(() => {\r\n const codeCount = cells.value.filter((c) => c.cell_type === 'code').length;\r\n const mdCount = cells.value.filter((c) => c.cell_type === 'markdown').length;\r\n return { code: codeCount, md: mdCount, total: cells.value.length };\r\n});\r\n\r\nfunction tt(key: string, fallback: string): string {\r\n return props.t ? props.t(key) : fallback;\r\n}\r\n</script>\r\n\r\n<template>\r\n <div class=\"filex-viewer-ipynb\">\r\n <div class=\"filex-viewer-ipynb__pane\">\r\n <div v-if=\"error\" class=\"filex-viewer-fallback\">\r\n <span class=\"filex-viewer-fallback__icon\">📓</span>\r\n <p>{{ error }}</p>\r\n </div>\r\n <div v-else-if=\"loading\" class=\"filex-viewer-fallback\">\r\n <span class=\"filex-viewer-fallback__icon\">⏳</span>\r\n <p>{{ tt('viewer.loading', 'Loading…') }}</p>\r\n </div>\r\n <div v-else>\r\n <div\r\n v-for=\"(cell, idx) in cells\"\r\n :key=\"idx\"\r\n class=\"filex-viewer-ipynb__cell\"\r\n :data-type=\"cell.cell_type\"\r\n >\r\n <template v-if=\"cell.cell_type === 'code'\">\r\n <div class=\"filex-viewer-ipynb__exec\">\r\n In [{{ cell.execution_count ?? ' ' }}]:\r\n </div>\r\n <pre class=\"filex-viewer-ipynb__src hljs\"><code\r\n v-if=\"renderedSources.get(idx)\"\r\n v-html=\"renderedSources.get(idx)\"\r\n /><code v-else>{{ joinSource(cell.source) }}</code></pre>\r\n <div v-if=\"cell.outputs && cell.outputs.length\" class=\"filex-viewer-ipynb__outputs\">\r\n <template v-for=\"(out, j) in cell.outputs\" :key=\"j\">\r\n <img\r\n v-if=\"outputImage(out)\"\r\n :src=\"outputImage(out) || ''\"\r\n class=\"filex-viewer-ipynb__img\"\r\n :alt=\"`output ${j}`\"\r\n />\r\n <div\r\n v-else-if=\"outputHtml(out)\"\r\n class=\"filex-viewer-ipynb__html\"\r\n v-html=\"outputHtml(out)\"\r\n />\r\n <pre\r\n v-else-if=\"outputText(out)\"\r\n class=\"filex-viewer-ipynb__out\"\r\n :data-type=\"out.output_type\"\r\n >{{ outputText(out) }}</pre>\r\n </template>\r\n </div>\r\n </template>\r\n\r\n <template v-else-if=\"cell.cell_type === 'markdown'\">\r\n <div\r\n v-if=\"renderedMarkdown.get(idx)\"\r\n class=\"filex-viewer-ipynb__md\"\r\n v-html=\"renderedMarkdown.get(idx)\"\r\n />\r\n <pre v-else class=\"filex-viewer-ipynb__md-raw\">{{ joinSource(cell.source) }}</pre>\r\n </template>\r\n\r\n <template v-else>\r\n <pre class=\"filex-viewer-ipynb__src\">{{ joinSource(cell.source) }}</pre>\r\n </template>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</template>\r\n\r\n<style scoped>\r\n.filex-viewer-ipynb {\r\n display: flex;\r\n flex-direction: column;\r\n width: 100%;\r\n height: 100%;\r\n min-height: 70vh;\r\n background: var(--fe-bg, #fff);\r\n color: var(--fe-text, #1a1e27);\r\n}\r\n.filex-viewer-ipynb__bar {\r\n display: flex;\r\n align-items: center;\r\n gap: 12px;\r\n padding: 8px 12px;\r\n background: var(--fe-bg-elev, #f7f8fa);\r\n border-bottom: 1px solid var(--fe-border, #e2e6ed);\r\n font-size: 12px;\r\n color: var(--fe-text-muted, #5a6475);\r\n}\r\n.filex-viewer-ipynb__lang {\r\n font-family: var(--fe-font-mono, monospace);\r\n text-transform: uppercase;\r\n letter-spacing: 0.04em;\r\n}\r\n.filex-viewer-ipynb__pane {\r\n flex: 1;\r\n overflow: auto;\r\n padding: 16px 24px;\r\n}\r\n.filex-viewer-ipynb__cell {\r\n border: 1px solid var(--fe-border, #e2e6ed);\r\n border-radius: 6px;\r\n margin-bottom: 16px;\r\n overflow: hidden;\r\n}\r\n.filex-viewer-ipynb__cell[data-type=\"code\"] {\r\n background: var(--fe-bg-elev, #f7f8fa);\r\n}\r\n.filex-viewer-ipynb__exec {\r\n padding: 4px 12px;\r\n font-family: var(--fe-font-mono, monospace);\r\n font-size: 11px;\r\n color: var(--fe-text-muted, #5a6475);\r\n background: rgba(0, 0, 0, 0.04);\r\n}\r\n.filex-viewer-ipynb__src {\r\n margin: 0;\r\n padding: 12px;\r\n font-family: var(--fe-font-mono, monospace);\r\n font-size: 12px;\r\n line-height: 1.5;\r\n white-space: pre;\r\n overflow-x: auto;\r\n}\r\n.filex-viewer-ipynb__outputs {\r\n border-top: 1px dashed var(--fe-border, #e2e6ed);\r\n background: var(--fe-bg, #fff);\r\n padding: 8px 12px;\r\n}\r\n.filex-viewer-ipynb__out {\r\n margin: 0;\r\n padding: 4px 0;\r\n font-family: var(--fe-font-mono, monospace);\r\n font-size: 12px;\r\n white-space: pre-wrap;\r\n word-wrap: break-word;\r\n}\r\n.filex-viewer-ipynb__out[data-type=\"error\"] {\r\n color: var(--fe-danger, #dc2626);\r\n}\r\n.filex-viewer-ipynb__img {\r\n display: block;\r\n max-width: 100%;\r\n height: auto;\r\n margin: 8px 0;\r\n}\r\n.filex-viewer-ipynb__html {\r\n font-size: 13px;\r\n}\r\n.filex-viewer-ipynb__md {\r\n padding: 12px 16px;\r\n font-size: 14px;\r\n line-height: 1.6;\r\n}\r\n.filex-viewer-ipynb__md-raw {\r\n padding: 12px;\r\n margin: 0;\r\n font-family: var(--fe-font-mono, monospace);\r\n font-size: 12px;\r\n white-space: pre-wrap;\r\n}\r\n.filex-viewer-fallback {\r\n text-align: center;\r\n padding: 32px;\r\n color: var(--fe-text-muted, #5a6475);\r\n}\r\n.filex-viewer-fallback__icon {\r\n font-size: 48px;\r\n display: block;\r\n margin-bottom: 12px;\r\n}\r\n</style>\r\n"],"names":["props","__props","cells","ref","language","error","loading","renderedSources","renderedMarkdown","renderToken","highlight","mdRenderer","ensureMd","mod","Md","joinSource","source","load","myToken","raw","fetchViewerText","_a","err","nb","_c","_b","ensureHighlight","hljs","langOk","_d","cell","idx","text","result","md","outputText","out","outputImage","svg","outputHtml","onMounted","onBeforeUnmount","watch","tt","key","fallback","_openBlock","_createElementBlock","_hoisted_1","_createElementVNode","_hoisted_2","_hoisted_3","_cache","_hoisted_4","_hoisted_5","_Fragment","_renderList","_hoisted_7","_hoisted_8","_hoisted_10","_toDisplayString","_hoisted_11","j","_hoisted_14","_hoisted_16","_hoisted_17"],"mappings":"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"}
@@ -0,0 +1,127 @@
1
+ import { d as E, o as L, h as T, a as _, c as h, e as u, t as k, i as $, j as H, v as Y, n as q, f as c, _ as z } from "./index-idz8Cz5t.js";
2
+ import { f as F } from "./useViewerFetch-czqbd2Lj.js";
3
+ const I = { class: "filex-viewer-mermaid" }, K = {
4
+ key: 0,
5
+ class: "filex-viewer-fallback"
6
+ }, N = {
7
+ key: 1,
8
+ class: "filex-viewer-fallback"
9
+ }, U = /* @__PURE__ */ E({
10
+ __name: "MermaidViewer",
11
+ props: {
12
+ url: {},
13
+ mime: {},
14
+ ext: {},
15
+ t: { type: Function },
16
+ authHeaders: { type: Function },
17
+ authCredentials: {}
18
+ },
19
+ setup(M) {
20
+ const n = M, d = c(null), r = c(null), o = c(!0), m = c(1), v = c(0), p = c(0);
21
+ let y = !1, l = null, f = 0, i = null;
22
+ async function P() {
23
+ var e, t;
24
+ if (i) return i;
25
+ try {
26
+ const a = await import(
27
+ /* @vite-ignore */
28
+ "mermaid"
29
+ );
30
+ return i = a.default ?? a, (t = i.initialize) == null || t.call(i, {
31
+ startOnLoad: !1,
32
+ securityLevel: "strict",
33
+ theme: (e = window.matchMedia) != null && e.call(window, "(prefers-color-scheme: dark)").matches ? "dark" : "default"
34
+ }), i;
35
+ } catch {
36
+ return null;
37
+ }
38
+ }
39
+ async function C() {
40
+ var g;
41
+ o.value = !0, r.value = null;
42
+ const e = ++f, t = await P();
43
+ if (e !== f) return;
44
+ if (!t) {
45
+ r.value = n.t ? n.t("viewer.peer_not_installed") : "Mermaid viewer requires `mermaid` — install or use download.", o.value = !1;
46
+ return;
47
+ }
48
+ let a;
49
+ try {
50
+ a = await F({
51
+ url: n.url,
52
+ headers: ((g = n.authHeaders) == null ? void 0 : g.call(n)) ?? {},
53
+ credentials: n.authCredentials
54
+ });
55
+ } catch (s) {
56
+ r.value = s instanceof Error ? s.message : "fetch failed", o.value = !1;
57
+ return;
58
+ }
59
+ if (e === f)
60
+ try {
61
+ const s = `filex-mermaid-${Date.now()}`, { svg: B } = await t.render(s, a);
62
+ if (e !== f) return;
63
+ if (d.value) {
64
+ d.value.innerHTML = B;
65
+ const w = d.value.querySelector("svg");
66
+ w && (w.style.maxWidth = "100%", w.style.height = "auto");
67
+ }
68
+ } catch (s) {
69
+ r.value = s instanceof Error ? s.message : "render failed";
70
+ } finally {
71
+ o.value = !1;
72
+ }
73
+ }
74
+ function D(e) {
75
+ if (!e.ctrlKey && !e.metaKey) return;
76
+ e.preventDefault();
77
+ const a = -e.deltaY > 0 ? 1.1 : 1 / 1.1;
78
+ m.value = Math.max(0.2, Math.min(8, m.value * a));
79
+ }
80
+ function S(e) {
81
+ var t, a;
82
+ y = !0, l = { x: e.clientX, y: e.clientY, tx: v.value, ty: p.value }, (a = (t = e.target).setPointerCapture) == null || a.call(t, e.pointerId);
83
+ }
84
+ function V(e) {
85
+ !y || !l || (v.value = l.tx + (e.clientX - l.x), p.value = l.ty + (e.clientY - l.y));
86
+ }
87
+ function x() {
88
+ y = !1, l = null;
89
+ }
90
+ L(C), T(() => {
91
+ f++;
92
+ });
93
+ function b(e, t) {
94
+ return n.t ? n.t(e) : t;
95
+ }
96
+ return (e, t) => (_(), h("div", I, [
97
+ u("div", {
98
+ class: "filex-viewer-mermaid__pane",
99
+ onWheel: D,
100
+ onPointerdown: S,
101
+ onPointermove: V,
102
+ onPointerup: x,
103
+ onPointercancel: x
104
+ }, [
105
+ r.value ? (_(), h("div", K, [
106
+ t[0] || (t[0] = u("span", { class: "filex-viewer-fallback__icon" }, "📊", -1)),
107
+ u("p", null, k(r.value), 1)
108
+ ])) : o.value ? (_(), h("div", N, [
109
+ t[1] || (t[1] = u("span", { class: "filex-viewer-fallback__icon" }, "⏳", -1)),
110
+ u("p", null, k(b("viewer.loading", "Loading…")), 1)
111
+ ])) : $("", !0),
112
+ H(u("div", {
113
+ ref_key: "surface",
114
+ ref: d,
115
+ class: "filex-viewer-mermaid__surface",
116
+ style: q({ transform: `translate(${v.value}px, ${p.value}px) scale(${m.value})` })
117
+ }, null, 4), [
118
+ [Y, !o.value && !r.value]
119
+ ])
120
+ ], 32)
121
+ ]));
122
+ }
123
+ }), j = /* @__PURE__ */ z(U, [["__scopeId", "data-v-cd37a551"]]);
124
+ export {
125
+ j as default
126
+ };
127
+ //# sourceMappingURL=MermaidViewer-k_XVXoc5.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MermaidViewer-k_XVXoc5.js","sources":["../../core/src/viewers/MermaidViewer.vue"],"sourcesContent":["<script setup lang=\"ts\">\r\n/**\r\n * MermaidViewer — render a `.mmd` / `.mermaid` source file.\r\n *\r\n * Lazy-imports the `mermaid` library (~150 KB gzipped). Source text is\r\n * fetched from `props.url` (with the auth headers from PreviewModal),\r\n * then rendered to SVG via `mermaid.render('id', src)`. The resulting\r\n * SVG node is inserted into a wrapper that supports pan + scale via\r\n * pure CSS transforms (no extra panzoom dep).\r\n */\r\nimport { onBeforeUnmount, onMounted, ref } from 'vue';\r\nimport { fetchViewerText } from '../composables/useViewerFetch';\r\n\r\nconst props = defineProps<{\r\n url: string;\r\n mime?: string;\r\n ext: string;\r\n t?: (key: string) => string;\r\n authHeaders?: () => Record<string, string>;\r\n authCredentials?: RequestCredentials;\r\n}>();\r\n\r\nconst surface = ref<HTMLDivElement | null>(null);\r\nconst error = ref<string | null>(null);\r\nconst loading = ref(true);\r\nconst scale = ref(1);\r\nconst tx = ref(0);\r\nconst ty = ref(0);\r\n\r\nlet dragging = false;\r\nlet dragStart: { x: number; y: number; tx: number; ty: number } | null = null;\r\nlet renderToken = 0;\r\n\r\nlet cachedMermaid: any = null;\r\nasync function ensureMermaid(): Promise<any | null> {\r\n if (cachedMermaid) return cachedMermaid;\r\n try {\r\n const mod = await import(/* @vite-ignore */ 'mermaid');\r\n cachedMermaid = mod.default ?? mod;\r\n cachedMermaid.initialize?.({\r\n startOnLoad: false,\r\n securityLevel: 'strict',\r\n theme: window.matchMedia?.('(prefers-color-scheme: dark)').matches\r\n ? 'dark'\r\n : 'default',\r\n });\r\n return cachedMermaid;\r\n } catch {\r\n return null;\r\n }\r\n}\r\n\r\nasync function load(): Promise<void> {\r\n loading.value = true;\r\n error.value = null;\r\n const myToken = ++renderToken;\r\n\r\n const mermaid = await ensureMermaid();\r\n if (myToken !== renderToken) return;\r\n if (!mermaid) {\r\n error.value = props.t\r\n ? props.t('viewer.peer_not_installed')\r\n : 'Mermaid viewer requires `mermaid` — install or use download.';\r\n loading.value = false;\r\n return;\r\n }\r\n\r\n let src: string;\r\n try {\r\n src = await fetchViewerText({\r\n url: props.url,\r\n headers: props.authHeaders?.() ?? {},\r\n credentials: props.authCredentials,\r\n });\r\n } catch (err) {\r\n error.value = err instanceof Error ? err.message : 'fetch failed';\r\n loading.value = false;\r\n return;\r\n }\r\n\r\n if (myToken !== renderToken) return;\r\n\r\n try {\r\n const id = `filex-mermaid-${Date.now()}`;\r\n const { svg } = await mermaid.render(id, src);\r\n if (myToken !== renderToken) return;\r\n if (surface.value) {\r\n surface.value.innerHTML = svg;\r\n const svgEl = surface.value.querySelector('svg');\r\n if (svgEl) {\r\n svgEl.style.maxWidth = '100%';\r\n svgEl.style.height = 'auto';\r\n }\r\n }\r\n } catch (err) {\r\n error.value = err instanceof Error ? err.message : 'render failed';\r\n } finally {\r\n loading.value = false;\r\n }\r\n}\r\n\r\nfunction zoomIn(): void {\r\n scale.value = Math.min(8, scale.value * 1.25);\r\n}\r\nfunction zoomOut(): void {\r\n scale.value = Math.max(0.2, scale.value / 1.25);\r\n}\r\nfunction reset(): void {\r\n scale.value = 1;\r\n tx.value = 0;\r\n ty.value = 0;\r\n}\r\n\r\nfunction onWheel(ev: WheelEvent): void {\r\n if (!ev.ctrlKey && !ev.metaKey) return;\r\n ev.preventDefault();\r\n const delta = -ev.deltaY;\r\n const factor = delta > 0 ? 1.1 : 1 / 1.1;\r\n scale.value = Math.max(0.2, Math.min(8, scale.value * factor));\r\n}\r\n\r\nfunction onPointerDown(ev: PointerEvent): void {\r\n dragging = true;\r\n dragStart = { x: ev.clientX, y: ev.clientY, tx: tx.value, ty: ty.value };\r\n (ev.target as HTMLElement).setPointerCapture?.(ev.pointerId);\r\n}\r\nfunction onPointerMove(ev: PointerEvent): void {\r\n if (!dragging || !dragStart) return;\r\n tx.value = dragStart.tx + (ev.clientX - dragStart.x);\r\n ty.value = dragStart.ty + (ev.clientY - dragStart.y);\r\n}\r\nfunction onPointerUp(): void {\r\n dragging = false;\r\n dragStart = null;\r\n}\r\n\r\nonMounted(load);\r\nonBeforeUnmount(() => {\r\n renderToken++;\r\n});\r\n\r\nfunction tt(key: string, fallback: string): string {\r\n return props.t ? props.t(key) : fallback;\r\n}\r\n</script>\r\n\r\n<template>\r\n <div class=\"filex-viewer-mermaid\">\r\n <div\r\n class=\"filex-viewer-mermaid__pane\"\r\n @wheel=\"onWheel\"\r\n @pointerdown=\"onPointerDown\"\r\n @pointermove=\"onPointerMove\"\r\n @pointerup=\"onPointerUp\"\r\n @pointercancel=\"onPointerUp\"\r\n >\r\n <div\r\n v-if=\"error\"\r\n class=\"filex-viewer-fallback\"\r\n >\r\n <span class=\"filex-viewer-fallback__icon\">📊</span>\r\n <p>{{ error }}</p>\r\n </div>\r\n <div\r\n v-else-if=\"loading\"\r\n class=\"filex-viewer-fallback\"\r\n >\r\n <span class=\"filex-viewer-fallback__icon\">⏳</span>\r\n <p>{{ tt('viewer.loading', 'Loading…') }}</p>\r\n </div>\r\n <div\r\n v-show=\"!loading && !error\"\r\n ref=\"surface\"\r\n class=\"filex-viewer-mermaid__surface\"\r\n :style=\"{ transform: `translate(${tx}px, ${ty}px) scale(${scale})` }\"\r\n />\r\n </div>\r\n </div>\r\n</template>\r\n\r\n<style scoped>\r\n.filex-viewer-mermaid {\r\n display: flex;\r\n flex-direction: column;\r\n width: 100%;\r\n height: 100%;\r\n min-height: 70vh;\r\n background: var(--fe-bg, #fff);\r\n color: var(--fe-text, #1a1e27);\r\n}\r\n.filex-viewer-mermaid__bar {\r\n display: flex;\r\n align-items: center;\r\n gap: 6px;\r\n padding: 8px 12px;\r\n background: var(--fe-bg-elev, #f7f8fa);\r\n border-bottom: 1px solid var(--fe-border, #e2e6ed);\r\n font-size: 13px;\r\n}\r\n.filex-viewer-mermaid__zoom {\r\n min-width: 50px;\r\n text-align: center;\r\n font-variant-numeric: tabular-nums;\r\n font-size: 12px;\r\n}\r\n.filex-viewer-mermaid__pane {\r\n flex: 1;\r\n overflow: hidden;\r\n position: relative;\r\n cursor: grab;\r\n background: var(--fe-bg-elev, #f7f8fa);\r\n touch-action: none;\r\n}\r\n.filex-viewer-mermaid__pane:active {\r\n cursor: grabbing;\r\n}\r\n.filex-viewer-mermaid__surface {\r\n position: absolute;\r\n inset: 0;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n transform-origin: center center;\r\n transition: transform 0.05s linear;\r\n user-select: none;\r\n}\r\n.filex-viewer-mermaid__surface :deep(svg) {\r\n max-width: 90%;\r\n max-height: 90%;\r\n}\r\n.filex-viewer-fallback {\r\n text-align: center;\r\n padding: 32px;\r\n color: var(--fe-text-muted, #5a6475);\r\n width: 100%;\r\n display: flex;\r\n flex-direction: column;\r\n align-items: center;\r\n justify-content: center;\r\n}\r\n.filex-viewer-fallback__icon {\r\n font-size: 48px;\r\n display: block;\r\n margin-bottom: 12px;\r\n}\r\n.filex-viewer-btn {\r\n border: 1px solid var(--fe-border, #e2e6ed);\r\n background: var(--fe-bg, #fff);\r\n color: var(--fe-text, #1a1e27);\r\n padding: 4px 10px;\r\n border-radius: 4px;\r\n cursor: pointer;\r\n font: inherit;\r\n font-size: 12px;\r\n}\r\n.filex-viewer-btn:hover:not(:disabled) {\r\n background: var(--fe-bg-hover, #edf0f5);\r\n}\r\n</style>\r\n"],"names":["props","__props","surface","ref","error","loading","scale","tx","ty","dragging","dragStart","renderToken","cachedMermaid","ensureMermaid","mod","_b","_a","load","myToken","mermaid","src","fetchViewerText","err","id","svg","svgEl","onWheel","ev","factor","onPointerDown","onPointerMove","onPointerUp","onMounted","onBeforeUnmount","tt","key","fallback","_openBlock","_createElementBlock","_hoisted_1","_createElementVNode","_hoisted_2","_cache","_hoisted_3","_normalizeStyle","_vShow"],"mappings":"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"}
@@ -0,0 +1,109 @@
1
+ import { d as B, o as E, h as I, w as S, a as m, c as p, e as i, t as x, i as V, j as A, v as L, f as o, _ as T } from "./index-idz8Cz5t.js";
2
+ import { a as F } from "./useViewerFetch-czqbd2Lj.js";
3
+ const H = { class: "filex-viewer-psd" }, N = { class: "filex-viewer-psd__pane" }, j = {
4
+ key: 0,
5
+ class: "filex-viewer-fallback"
6
+ }, q = {
7
+ key: 1,
8
+ class: "filex-viewer-fallback"
9
+ }, M = /* @__PURE__ */ B({
10
+ __name: "PsdViewer",
11
+ props: {
12
+ url: {},
13
+ mime: {},
14
+ ext: {},
15
+ t: { type: Function },
16
+ authHeaders: { type: Function },
17
+ authCredentials: {}
18
+ },
19
+ setup(D) {
20
+ const a = D, f = o(null), w = o([]), s = o(null), l = o(!0), P = o({ width: 0, height: 0 });
21
+ let c = 0, u = null;
22
+ async function b() {
23
+ if (u) return u;
24
+ try {
25
+ return u = await import(
26
+ /* @vite-ignore */
27
+ "./index-UFULWo35.js"
28
+ ), u;
29
+ } catch {
30
+ return null;
31
+ }
32
+ }
33
+ function _(t, e) {
34
+ if (t && Array.isArray(t.children))
35
+ for (const n of t.children)
36
+ e.push({
37
+ index: e.length,
38
+ name: n.name ?? "(unnamed)",
39
+ hidden: !!n.hidden
40
+ }), n.children && _(n, e);
41
+ }
42
+ async function g() {
43
+ var n;
44
+ l.value = !0, s.value = null, w.value = [];
45
+ const t = ++c, e = await b();
46
+ if (t === c) {
47
+ if (!e) {
48
+ s.value = a.t ? a.t("viewer.peer_not_installed") : "PSD viewer requires `ag-psd` — install or use download.", l.value = !1;
49
+ return;
50
+ }
51
+ try {
52
+ const d = await F({
53
+ url: a.url,
54
+ headers: ((n = a.authHeaders) == null ? void 0 : n.call(a)) ?? {},
55
+ credentials: a.authCredentials
56
+ });
57
+ if (t !== c) return;
58
+ const r = e.readPsd(d, {
59
+ skipLayerImageData: !1,
60
+ skipCompositeImageData: !1,
61
+ skipThumbnail: !0
62
+ });
63
+ P.value = { width: r.width, height: r.height };
64
+ const y = r.canvas;
65
+ if (y && f.value) {
66
+ const h = f.value;
67
+ h.width = r.width, h.height = r.height;
68
+ const v = h.getContext("2d");
69
+ v == null || v.drawImage(y, 0, 0);
70
+ } else
71
+ throw new Error("PSD has no composite image (skipCompositeImageData?)");
72
+ const k = [];
73
+ _(r, k), w.value = k;
74
+ } catch (d) {
75
+ s.value = d instanceof Error ? d.message : "PSD decode failed";
76
+ } finally {
77
+ l.value = !1;
78
+ }
79
+ }
80
+ }
81
+ E(g), I(() => {
82
+ c++;
83
+ }), S(() => a.url, g);
84
+ function C(t, e) {
85
+ return a.t ? a.t(t) : e;
86
+ }
87
+ return (t, e) => (m(), p("div", H, [
88
+ i("div", N, [
89
+ s.value ? (m(), p("div", j, [
90
+ e[0] || (e[0] = i("span", { class: "filex-viewer-fallback__icon" }, "🎨", -1)),
91
+ i("p", null, x(s.value), 1)
92
+ ])) : l.value ? (m(), p("div", q, [
93
+ e[1] || (e[1] = i("span", { class: "filex-viewer-fallback__icon" }, "⏳", -1)),
94
+ i("p", null, x(C("viewer.loading", "Loading…")), 1)
95
+ ])) : V("", !0),
96
+ A(i("canvas", {
97
+ ref_key: "canvasEl",
98
+ ref: f
99
+ }, null, 512), [
100
+ [L, !l.value && !s.value]
101
+ ])
102
+ ])
103
+ ]));
104
+ }
105
+ }), G = /* @__PURE__ */ T(M, [["__scopeId", "data-v-e073aaf6"]]);
106
+ export {
107
+ G as default
108
+ };
109
+ //# sourceMappingURL=PsdViewer-Bo4imBCF.js.map