UNPKG

react-latex-editor

Version:

A powerful React rich text editor with mathematical equation support, built on TipTap with MathLive integration

1,595 lines (1,592 loc) 111 kB
import Z, { Component as Et, useRef as D, useCallback as q, useState as P, memo as At, forwardRef as me, useEffect as Q, useImperativeHandle as Rt, useLayoutEffect as Tt } from "react"; import { NodeViewWrapper as xe, ReactNodeViewRenderer as ge, InputRule as fe, useEditor as Mt, EditorContent as Lt } from "@tiptap/react"; import St from "@tiptap/starter-kit"; import Nt from "@tiptap/extension-table"; import _t from "@tiptap/extension-table-row"; import Pt from "@tiptap/extension-table-cell"; import It from "@tiptap/extension-table-header"; import Bt from "@tiptap/extension-link"; import Ht from "@tiptap/extension-text-align"; import Ft from "@tiptap/extension-highlight"; import Dt from "@tiptap/extension-underline"; import $t from "@tiptap/extension-subscript"; import zt from "@tiptap/extension-superscript"; import { CodeBlockLowlight as Wt } from "@tiptap/extension-code-block-lowlight"; import { createLowlight as Ot, common as qt } from "lowlight"; import Vt from "@tiptap/extension-strike"; import Yt from "@tiptap/extension-color"; import Gt from "@tiptap/extension-blockquote"; import Ut from "@tiptap/extension-horizontal-rule"; import Kt from "@tiptap/extension-hard-break"; import Jt from "@tiptap/extension-task-list"; import Xt from "@tiptap/extension-task-item"; import Zt from "@tiptap/extension-placeholder"; import Qt from "@tiptap/extension-character-count"; import ei from "@tiptap/extension-floating-menu"; import { Node as Ge, Extension as ti, mergeAttributes as ye, Mark as Ue } from "@tiptap/core"; import ii from "@tiptap/extension-image"; import ri from "@tiptap/extension-youtube"; import ni from "@tiptap/extension-text-style"; import "mathlive"; var se = { exports: {} }, J = {}; /** * @license React * react-jsx-runtime.production.min.js * * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ var Oe; function si() { if (Oe) return J; Oe = 1; var t = Z, r = Symbol.for("react.element"), n = Symbol.for("react.fragment"), a = Object.prototype.hasOwnProperty, d = t.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner, j = { key: !0, ref: !0, __self: !0, __source: !0 }; function y(b, h, k) { var m, p = {}, u = null, M = null; k !== void 0 && (u = "" + k), h.key !== void 0 && (u = "" + h.key), h.ref !== void 0 && (M = h.ref); for (m in h) a.call(h, m) && !j.hasOwnProperty(m) && (p[m] = h[m]); if (b && b.defaultProps) for (m in h = b.defaultProps, h) p[m] === void 0 && (p[m] = h[m]); return { $$typeof: r, type: b, key: u, ref: M, props: p, _owner: d.current }; } return J.Fragment = n, J.jsx = y, J.jsxs = y, J; } var X = {}; /** * @license React * react-jsx-runtime.development.js * * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ var qe; function oi() { return qe || (qe = 1, process.env.NODE_ENV !== "production" && function() { var t = Z, r = Symbol.for("react.element"), n = Symbol.for("react.portal"), a = Symbol.for("react.fragment"), d = Symbol.for("react.strict_mode"), j = Symbol.for("react.profiler"), y = Symbol.for("react.provider"), b = Symbol.for("react.context"), h = Symbol.for("react.forward_ref"), k = Symbol.for("react.suspense"), m = Symbol.for("react.suspense_list"), p = Symbol.for("react.memo"), u = Symbol.for("react.lazy"), M = Symbol.for("react.offscreen"), A = Symbol.iterator, c = "@@iterator"; function N(i) { if (i === null || typeof i != "object") return null; var s = A && i[A] || i[c]; return typeof s == "function" ? s : null; } var L = t.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED; function C(i) { { for (var s = arguments.length, o = new Array(s > 1 ? s - 1 : 0), l = 1; l < s; l++) o[l - 1] = arguments[l]; E("error", i, o); } } function E(i, s, o) { { var l = L.ReactDebugCurrentFrame, v = l.getStackAddendum(); v !== "" && (s += "%s", o = o.concat([v])); var w = o.map(function(x) { return String(x); }); w.unshift("Warning: " + s), Function.prototype.apply.call(console[i], console, w); } } var B = !1, V = !1, $ = !1, z = !1, H = !1, ee; ee = Symbol.for("react.module.reference"); function Je(i) { return !!(typeof i == "string" || typeof i == "function" || i === a || i === j || H || i === d || i === k || i === m || z || i === M || B || V || $ || typeof i == "object" && i !== null && (i.$$typeof === u || i.$$typeof === p || i.$$typeof === y || i.$$typeof === b || i.$$typeof === h || // This needs to include all possible module reference object // types supported by any Flight configuration anywhere since // we don't know which Flight build this will end up being used // with. i.$$typeof === ee || i.getModuleId !== void 0)); } function Xe(i, s, o) { var l = i.displayName; if (l) return l; var v = s.displayName || s.name || ""; return v !== "" ? o + "(" + v + ")" : o; } function be(i) { return i.displayName || "Context"; } function F(i) { if (i == null) return null; if (typeof i.tag == "number" && C("Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."), typeof i == "function") return i.displayName || i.name || null; if (typeof i == "string") return i; switch (i) { case a: return "Fragment"; case n: return "Portal"; case j: return "Profiler"; case d: return "StrictMode"; case k: return "Suspense"; case m: return "SuspenseList"; } if (typeof i == "object") switch (i.$$typeof) { case b: var s = i; return be(s) + ".Consumer"; case y: var o = i; return be(o._context) + ".Provider"; case h: return Xe(i, i.render, "ForwardRef"); case p: var l = i.displayName || null; return l !== null ? l : F(i.type) || "Memo"; case u: { var v = i, w = v._payload, x = v._init; try { return F(x(w)); } catch { return null; } } } return null; } var W = Object.assign, U = 0, ve, je, ke, we, Ce, Ee, Ae; function Re() { } Re.__reactDisabledLog = !0; function Ze() { { if (U === 0) { ve = console.log, je = console.info, ke = console.warn, we = console.error, Ce = console.group, Ee = console.groupCollapsed, Ae = console.groupEnd; var i = { configurable: !0, enumerable: !0, value: Re, writable: !0 }; Object.defineProperties(console, { info: i, log: i, warn: i, error: i, group: i, groupCollapsed: i, groupEnd: i }); } U++; } } function Qe() { { if (U--, U === 0) { var i = { configurable: !0, enumerable: !0, writable: !0 }; Object.defineProperties(console, { log: W({}, i, { value: ve }), info: W({}, i, { value: je }), warn: W({}, i, { value: ke }), error: W({}, i, { value: we }), group: W({}, i, { value: Ce }), groupCollapsed: W({}, i, { value: Ee }), groupEnd: W({}, i, { value: Ae }) }); } U < 0 && C("disabledDepth fell below zero. This is a bug in React. Please file an issue."); } } var oe = L.ReactCurrentDispatcher, ae; function te(i, s, o) { { if (ae === void 0) try { throw Error(); } catch (v) { var l = v.stack.trim().match(/\n( *(at )?)/); ae = l && l[1] || ""; } return ` ` + ae + i; } } var le = !1, ie; { var et = typeof WeakMap == "function" ? WeakMap : Map; ie = new et(); } function Te(i, s) { if (!i || le) return ""; { var o = ie.get(i); if (o !== void 0) return o; } var l; le = !0; var v = Error.prepareStackTrace; Error.prepareStackTrace = void 0; var w; w = oe.current, oe.current = null, Ze(); try { if (s) { var x = function() { throw Error(); }; if (Object.defineProperty(x.prototype, "props", { set: function() { throw Error(); } }), typeof Reflect == "object" && Reflect.construct) { try { Reflect.construct(x, []); } catch (_) { l = _; } Reflect.construct(i, [], x); } else { try { x.call(); } catch (_) { l = _; } i.call(x.prototype); } } else { try { throw Error(); } catch (_) { l = _; } i(); } } catch (_) { if (_ && l && typeof _.stack == "string") { for (var f = _.stack.split(` `), S = l.stack.split(` `), R = f.length - 1, T = S.length - 1; R >= 1 && T >= 0 && f[R] !== S[T]; ) T--; for (; R >= 1 && T >= 0; R--, T--) if (f[R] !== S[T]) { if (R !== 1 || T !== 1) do if (R--, T--, T < 0 || f[R] !== S[T]) { var I = ` ` + f[R].replace(" at new ", " at "); return i.displayName && I.includes("<anonymous>") && (I = I.replace("<anonymous>", i.displayName)), typeof i == "function" && ie.set(i, I), I; } while (R >= 1 && T >= 0); break; } } } finally { le = !1, oe.current = w, Qe(), Error.prepareStackTrace = v; } var G = i ? i.displayName || i.name : "", O = G ? te(G) : ""; return typeof i == "function" && ie.set(i, O), O; } function tt(i, s, o) { return Te(i, !1); } function it(i) { var s = i.prototype; return !!(s && s.isReactComponent); } function re(i, s, o) { if (i == null) return ""; if (typeof i == "function") return Te(i, it(i)); if (typeof i == "string") return te(i); switch (i) { case k: return te("Suspense"); case m: return te("SuspenseList"); } if (typeof i == "object") switch (i.$$typeof) { case h: return tt(i.render); case p: return re(i.type, s, o); case u: { var l = i, v = l._payload, w = l._init; try { return re(w(v), s, o); } catch { } } } return ""; } var K = Object.prototype.hasOwnProperty, Me = {}, Le = L.ReactDebugCurrentFrame; function ne(i) { if (i) { var s = i._owner, o = re(i.type, i._source, s ? s.type : null); Le.setExtraStackFrame(o); } else Le.setExtraStackFrame(null); } function rt(i, s, o, l, v) { { var w = Function.call.bind(K); for (var x in i) if (w(i, x)) { var f = void 0; try { if (typeof i[x] != "function") { var S = Error((l || "React class") + ": " + o + " type `" + x + "` is invalid; it must be a function, usually from the `prop-types` package, but received `" + typeof i[x] + "`.This often happens because of typos such as `PropTypes.function` instead of `PropTypes.func`."); throw S.name = "Invariant Violation", S; } f = i[x](s, x, l, o, null, "SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"); } catch (R) { f = R; } f && !(f instanceof Error) && (ne(v), C("%s: type specification of %s `%s` is invalid; the type checker function must return `null` or an `Error` but returned a %s. You may have forgotten to pass an argument to the type checker creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and shape all require an argument).", l || "React class", o, x, typeof f), ne(null)), f instanceof Error && !(f.message in Me) && (Me[f.message] = !0, ne(v), C("Failed %s type: %s", o, f.message), ne(null)); } } } var nt = Array.isArray; function ce(i) { return nt(i); } function st(i) { { var s = typeof Symbol == "function" && Symbol.toStringTag, o = s && i[Symbol.toStringTag] || i.constructor.name || "Object"; return o; } } function ot(i) { try { return Se(i), !1; } catch { return !0; } } function Se(i) { return "" + i; } function Ne(i) { if (ot(i)) return C("The provided key is an unsupported type %s. This value must be coerced to a string before before using it here.", st(i)), Se(i); } var _e = L.ReactCurrentOwner, at = { key: !0, ref: !0, __self: !0, __source: !0 }, Pe, Ie; function lt(i) { if (K.call(i, "ref")) { var s = Object.getOwnPropertyDescriptor(i, "ref").get; if (s && s.isReactWarning) return !1; } return i.ref !== void 0; } function ct(i) { if (K.call(i, "key")) { var s = Object.getOwnPropertyDescriptor(i, "key").get; if (s && s.isReactWarning) return !1; } return i.key !== void 0; } function ut(i, s) { typeof i.ref == "string" && _e.current; } function dt(i, s) { { var o = function() { Pe || (Pe = !0, C("%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://reactjs.org/link/special-props)", s)); }; o.isReactWarning = !0, Object.defineProperty(i, "key", { get: o, configurable: !0 }); } } function ht(i, s) { { var o = function() { Ie || (Ie = !0, C("%s: `ref` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://reactjs.org/link/special-props)", s)); }; o.isReactWarning = !0, Object.defineProperty(i, "ref", { get: o, configurable: !0 }); } } var pt = function(i, s, o, l, v, w, x) { var f = { // This tag allows us to uniquely identify this as a React Element $$typeof: r, // Built-in properties that belong on the element type: i, key: s, ref: o, props: x, // Record the component responsible for creating this element. _owner: w }; return f._store = {}, Object.defineProperty(f._store, "validated", { configurable: !1, enumerable: !1, writable: !0, value: !1 }), Object.defineProperty(f, "_self", { configurable: !1, enumerable: !1, writable: !1, value: l }), Object.defineProperty(f, "_source", { configurable: !1, enumerable: !1, writable: !1, value: v }), Object.freeze && (Object.freeze(f.props), Object.freeze(f)), f; }; function ft(i, s, o, l, v) { { var w, x = {}, f = null, S = null; o !== void 0 && (Ne(o), f = "" + o), ct(s) && (Ne(s.key), f = "" + s.key), lt(s) && (S = s.ref, ut(s, v)); for (w in s) K.call(s, w) && !at.hasOwnProperty(w) && (x[w] = s[w]); if (i && i.defaultProps) { var R = i.defaultProps; for (w in R) x[w] === void 0 && (x[w] = R[w]); } if (f || S) { var T = typeof i == "function" ? i.displayName || i.name || "Unknown" : i; f && dt(x, T), S && ht(x, T); } return pt(i, f, S, v, l, _e.current, x); } } var ue = L.ReactCurrentOwner, Be = L.ReactDebugCurrentFrame; function Y(i) { if (i) { var s = i._owner, o = re(i.type, i._source, s ? s.type : null); Be.setExtraStackFrame(o); } else Be.setExtraStackFrame(null); } var de; de = !1; function he(i) { return typeof i == "object" && i !== null && i.$$typeof === r; } function He() { { if (ue.current) { var i = F(ue.current.type); if (i) return ` Check the render method of \`` + i + "`."; } return ""; } } function mt(i) { return ""; } var Fe = {}; function xt(i) { { var s = He(); if (!s) { var o = typeof i == "string" ? i : i.displayName || i.name; o && (s = ` Check the top-level render call using <` + o + ">."); } return s; } } function De(i, s) { { if (!i._store || i._store.validated || i.key != null) return; i._store.validated = !0; var o = xt(s); if (Fe[o]) return; Fe[o] = !0; var l = ""; i && i._owner && i._owner !== ue.current && (l = " It was passed a child from " + F(i._owner.type) + "."), Y(i), C('Each child in a list should have a unique "key" prop.%s%s See https://reactjs.org/link/warning-keys for more information.', o, l), Y(null); } } function $e(i, s) { { if (typeof i != "object") return; if (ce(i)) for (var o = 0; o < i.length; o++) { var l = i[o]; he(l) && De(l, s); } else if (he(i)) i._store && (i._store.validated = !0); else if (i) { var v = N(i); if (typeof v == "function" && v !== i.entries) for (var w = v.call(i), x; !(x = w.next()).done; ) he(x.value) && De(x.value, s); } } } function gt(i) { { var s = i.type; if (s == null || typeof s == "string") return; var o; if (typeof s == "function") o = s.propTypes; else if (typeof s == "object" && (s.$$typeof === h || // Note: Memo only checks outer props here. // Inner props are checked in the reconciler. s.$$typeof === p)) o = s.propTypes; else return; if (o) { var l = F(s); rt(o, i.props, "prop", l, i); } else if (s.PropTypes !== void 0 && !de) { de = !0; var v = F(s); C("Component %s declared `PropTypes` instead of `propTypes`. Did you misspell the property assignment?", v || "Unknown"); } typeof s.getDefaultProps == "function" && !s.getDefaultProps.isReactClassApproved && C("getDefaultProps is only used on classic React.createClass definitions. Use a static property named `defaultProps` instead."); } } function yt(i) { { for (var s = Object.keys(i.props), o = 0; o < s.length; o++) { var l = s[o]; if (l !== "children" && l !== "key") { Y(i), C("Invalid prop `%s` supplied to `React.Fragment`. React.Fragment can only have `key` and `children` props.", l), Y(null); break; } } i.ref !== null && (Y(i), C("Invalid attribute `ref` supplied to `React.Fragment`."), Y(null)); } } var ze = {}; function We(i, s, o, l, v, w) { { var x = Je(i); if (!x) { var f = ""; (i === void 0 || typeof i == "object" && i !== null && Object.keys(i).length === 0) && (f += " You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports."); var S = mt(); S ? f += S : f += He(); var R; i === null ? R = "null" : ce(i) ? R = "array" : i !== void 0 && i.$$typeof === r ? (R = "<" + (F(i.type) || "Unknown") + " />", f = " Did you accidentally export a JSX literal instead of a component?") : R = typeof i, C("React.jsx: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: %s.%s", R, f); } var T = ft(i, s, o, v, w); if (T == null) return T; if (x) { var I = s.children; if (I !== void 0) if (l) if (ce(I)) { for (var G = 0; G < I.length; G++) $e(I[G], i); Object.freeze && Object.freeze(I); } else C("React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead."); else $e(I, i); } if (K.call(s, "key")) { var O = F(i), _ = Object.keys(s).filter(function(Ct) { return Ct !== "key"; }), pe = _.length > 0 ? "{key: someKey, " + _.join(": ..., ") + ": ...}" : "{key: someKey}"; if (!ze[O + pe]) { var wt = _.length > 0 ? "{" + _.join(": ..., ") + ": ...}" : "{}"; C(`A props object containing a "key" prop is being spread into JSX: let props = %s; <%s {...props} /> React keys must be passed directly to JSX without using spread: let props = %s; <%s key={someKey} {...props} />`, pe, O, wt, O), ze[O + pe] = !0; } } return i === a ? yt(T) : gt(T), T; } } function bt(i, s, o) { return We(i, s, o, !0); } function vt(i, s, o) { return We(i, s, o, !1); } var jt = vt, kt = bt; X.Fragment = a, X.jsx = jt, X.jsxs = kt; }()), X; } var Ve; function ai() { return Ve || (Ve = 1, process.env.NODE_ENV === "production" ? se.exports = si() : se.exports = oi()), se.exports; } var e = ai(); class li extends Et { mathFieldRef; cleanup; constructor(r) { super(r), this.mathFieldRef = Z.createRef(); } async componentDidMount() { if (typeof window < "u") { const r = await import("mathlive"); customElements.get("math-field") || customElements.define("math-field", r.MathfieldElement), r.MathfieldElement && (r.MathfieldElement.fontsDirectory = null); } this.setupMathField(); } componentDidUpdate(r) { r.node.attrs.latex !== this.props.node.attrs.latex && this.updateMathField(); } componentWillUnmount() { this.cleanupMathField(); } setupMathField() { const r = this.mathFieldRef.current; if (!r) return; const n = () => { const a = r.value; a !== this.props.node.attrs.latex && this.props.updateAttributes({ latex: a }); }; setTimeout(() => { r && r.isConnected && (r.addEventListener("input", n), r.value = this.props.node.attrs.latex || ""); }, 0), this.cleanup = () => { r && r.isConnected && (r.removeEventListener("input", n), r.menuItems = []); }; } updateMathField() { this.mathFieldRef.current && (this.mathFieldRef.current.value = this.props.node.attrs.latex || ""); } cleanupMathField() { this.cleanup && this.cleanup(); } render() { const { node: r } = this.props, { displayMode: n } = r.attrs; return /* @__PURE__ */ e.jsx( xe, { className: n ? "math-node-wrapper-block" : "math-node-wrapper-inline", children: Z.createElement("math-field", { ref: this.mathFieldRef, className: "test-math-background", readonly: !0 }) } ); } } const ci = Ge.create({ name: "math", group: "inline", inline: !0, atom: !0, addAttributes() { return { latex: { default: "", parseHTML: (t) => t.getAttribute("data-latex"), renderHTML: (t) => ({ "data-latex": t.latex }) }, displayMode: { default: !1, parseHTML: (t) => t.hasAttribute("data-display-mode"), renderHTML: (t) => t.displayMode ? { "data-display-mode": "" } : {} } }; }, parseHTML() { return [ { tag: 'span[data-type="math"]' } ]; }, renderHTML({ HTMLAttributes: t, node: r }) { return [ "span", { ...t, "data-type": "math", "data-latex": r?.attrs?.latex || "" }, r?.attrs?.latex || "" ]; }, addNodeView() { return ge(li); } }), ui = ti.create({ name: "inlineMath", addOptions() { return { inlineDelimiter: "$", blockDelimiter: "$$" }; }, addProseMirrorPlugins() { return []; }, addCommands() { return { insertInlineMath: (t) => ({ commands: r }) => r.insertContent({ type: "math", attrs: { latex: t } }) }; }, addInputRules() { const t = this.options.inlineDelimiter.replace( /[-\/\\^$*+?.()|\[\]{}]/g, "\\$&" ), r = this.options.blockDelimiter.replace( /[-\/\\^$*+?.()|\[\]{}]/g, "\\$&" ); return [ // Inline math: $latex$ new fe({ find: new RegExp( `${t}(.*?)${t}$` ), handler: ({ state: n, range: a, match: d }) => { const [, j] = d, { from: y, to: b } = a; n.tr.replaceWith( y, b, n.schema.nodes.math.create({ latex: j }) ); } }), // Block math: $$latex$$ new fe({ find: new RegExp( `${r}(.*?)${r}$` ), handler: ({ state: n, range: a, match: d }) => { const [, j] = d, { from: y, to: b } = a; n.tr.replaceWith( y, b, n.schema.nodes.math.create({ latex: j, displayMode: !0 }) ); } }), // Inline math: $latex$ with display mode new fe({ find: new RegExp( `${t}(.*?)${t}$` ), handler: ({ state: n, range: a, match: d }) => { const [, j] = d, { from: y, to: b } = a; n.tr.replaceWith( y, b, n.schema.nodes.math.create({ latex: j }) ); } }) ]; } }), di = ({ node: t, updateAttributes: r }) => { const n = D(null), { width: a, align: d } = t.attrs, j = q( (y) => { y.preventDefault(); const b = y.pageX, h = n.current.clientWidth, k = (p) => { const u = h + (p.pageX - b); r({ width: `${Math.max(50, u)}px` }); }, m = () => { document.removeEventListener("mousemove", k), document.removeEventListener("mouseup", m); }; document.addEventListener("mousemove", k), document.addEventListener("mouseup", m); }, [r] ); return /* @__PURE__ */ e.jsxs( xe, { className: `resizable-image-container align-${d}`, style: { width: a }, ref: n, children: [ /* @__PURE__ */ e.jsx( "img", { src: t.attrs.src, alt: t.attrs.alt, title: t.attrs.title, className: "editor-image", draggable: "true" } ), /* @__PURE__ */ e.jsx("div", { className: "resize-handle-left", onMouseDown: j }), /* @__PURE__ */ e.jsx("div", { className: "resize-handle-right", onMouseDown: j }) ] } ); }, hi = ii.extend({ addAttributes() { return { ...this.parent?.(), width: { default: "500px", renderHTML: (t) => ({ width: t.width }) }, height: { default: "auto", renderHTML: (t) => ({ height: t.height }) }, align: { default: "left", renderHTML: (t) => ({ "data-align": t.align }), parseHTML: (t) => t.getAttribute("data-align") || "left" } }; }, addNodeView() { return ge(di); } }), pi = Ge.create({ name: "imageGroup", group: "block", content: "image+", addAttributes() { return { align: { default: "left" } }; }, renderHTML({ node: t, HTMLAttributes: r }) { const n = t.attrs.align || "left", d = { left: "flex-start", center: "center", right: "flex-end" }[n] || "flex-start"; return [ "div", ye(r, { "data-type": "image-group", style: `justify-content: ${d}` }), 0 ]; }, parseHTML() { return [ { tag: 'div[data-type="image-group"]', getAttrs: (t) => { const r = t.style.justifyContent; return r === "center" || r === "flex-end" ? { align: r === "center" ? "center" : "right" } : { align: "left" }; } } ]; } }), fi = Ue.create({ name: "customTextStyle", addAttributes() { return { fontSize: { default: null, parseHTML: (t) => t.style.fontSize?.replace(" !important", "") || null, renderHTML: (t) => t.fontSize ? { style: `font-size: ${t.fontSize} !important;` } : {} }, color: { default: null, parseHTML: (t) => t.style.color || null, renderHTML: (t) => t.color ? { style: `color: ${t.color}` } : {} }, fontFamily: { default: null, parseHTML: (t) => t.style.fontFamily || null, renderHTML: (t) => t.fontFamily ? { style: `font-family: ${t.fontFamily} !important;` } : {} } }; }, parseHTML() { return [ { tag: "span", getAttrs: (t) => { const r = t.style.fontSize, n = t.style.color, a = t.style.fontFamily; return r || n || a ? { fontSize: r ? r.replace(" !important", "") : null, color: n || null, fontFamily: a ? a.replace(" !important", "") : null } : !1; } } ]; }, renderHTML({ HTMLAttributes: t }) { return ["span", ye(t), 0]; } }), mi = Ue.create({ name: "backgroundColor", addOptions() { return { HTMLAttributes: {} }; }, addAttributes() { return { backgroundColor: { default: null, parseHTML: (t) => t.style.backgroundColor || null, renderHTML: (t) => t.backgroundColor ? { style: `background-color: ${t.backgroundColor}` } : {} } }; }, parseHTML() { return [ { style: "background-color" } ]; }, renderHTML({ HTMLAttributes: t }) { return [ "span", ye(this.options.HTMLAttributes, t), 0 ]; }, addCommands() { return { setBackgroundColor: (t) => ({ commands: r }) => r.setMark(this.name, { backgroundColor: t }), unsetBackgroundColor: () => ({ commands: t }) => t.unsetMark(this.name) }; } }), xi = ({ node: t, updateAttributes: r, selected: n }) => { const [a, d] = P(!1), [j, y] = P(0), [b, h] = P(0), [k, m] = P(0), [p, u] = P(0), M = q( (c, N) => { c.preventDefault(), d(!0), y(c.clientX), h(c.clientY), m(parseInt(t.attrs.width)), u(parseInt(t.attrs.height)); const L = (E) => { if (!a) return; const B = E.clientX - j, V = E.clientY - b; let $ = k, z = p; N.includes("right") && ($ = Math.max(200, k + B)), N.includes("left") && ($ = Math.max(200, k - B)), N.includes("bottom") && (z = Math.max(150, p + V)), N.includes("top") && (z = Math.max(150, p - V)), r({ width: `${$}px`, height: `${z}px` }); }, C = () => { d(!1), document.removeEventListener("mousemove", L), document.removeEventListener("mouseup", C); }; document.addEventListener("mousemove", L), document.addEventListener("mouseup", C); }, [ a, j, b, k, p, t.attrs.width, t.attrs.height, r ] ), A = (c) => { r({ align: c }); }; return /* @__PURE__ */ e.jsx( xe, { className: `resizable-youtube-wrapper ${n ? "ProseMirror-selectednode" : ""}`, style: { textAlign: t.attrs.align, position: "relative", display: "inline-block" }, children: /* @__PURE__ */ e.jsxs( "div", { className: "resizable-youtube-container", style: { position: "relative", display: "inline-block", width: t.attrs.width, height: t.attrs.height }, children: [ /* @__PURE__ */ e.jsx( "iframe", { src: t.attrs.src, width: t.attrs.width, height: t.attrs.height, frameBorder: "0", allow: "accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture", allowFullScreen: !0, style: { display: "block", width: "100%", height: "100%" } } ), n && /* @__PURE__ */ e.jsxs(e.Fragment, { children: [ /* @__PURE__ */ e.jsx( "div", { className: "resize-handle resize-handle-bottom-right", onMouseDown: (c) => M(c, "bottom-right"), style: { position: "absolute", bottom: "-5px", right: "-5px", width: "10px", height: "10px", backgroundColor: "#007acc", cursor: "nw-resize", borderRadius: "2px" } } ), /* @__PURE__ */ e.jsx( "div", { className: "resize-handle resize-handle-bottom-left", onMouseDown: (c) => M(c, "bottom-left"), style: { position: "absolute", bottom: "-5px", left: "-5px", width: "10px", height: "10px", backgroundColor: "#007acc", cursor: "ne-resize", borderRadius: "2px" } } ), /* @__PURE__ */ e.jsx( "div", { className: "resize-handle resize-handle-top-right", onMouseDown: (c) => M(c, "top-right"), style: { position: "absolute", top: "-5px", right: "-5px", width: "10px", height: "10px", backgroundColor: "#007acc", cursor: "ne-resize", borderRadius: "2px" } } ), /* @__PURE__ */ e.jsx( "div", { className: "resize-handle resize-handle-top-left", onMouseDown: (c) => M(c, "top-left"), style: { position: "absolute", top: "-5px", left: "-5px", width: "10px", height: "10px", backgroundColor: "#007acc", cursor: "nw-resize", borderRadius: "2px" } } ), /* @__PURE__ */ e.jsxs( "div", { className: "alignment-controls", style: { position: "absolute", top: "-30px", left: "0", display: "flex", gap: "5px", backgroundColor: "white", border: "1px solid #ccc", borderRadius: "4px", padding: "2px" }, children: [ /* @__PURE__ */ e.jsx( "button", { onClick: () => A("left"), style: { padding: "2px 6px", border: "none", backgroundColor: t.attrs.align === "left" ? "#007acc" : "transparent", color: t.attrs.align === "left" ? "white" : "black", cursor: "pointer", borderRadius: "2px" }, type: "button", children: "←" } ), /* @__PURE__ */ e.jsx( "button", { onClick: () => A("center"), style: { padding: "2px 6px", border: "none", backgroundColor: t.attrs.align === "center" ? "#007acc" : "transparent", color: t.attrs.align === "center" ? "white" : "black", cursor: "pointer", borderRadius: "2px" }, type: "button", children: "⟷" } ), /* @__PURE__ */ e.jsx( "button", { onClick: () => A("right"), style: { padding: "2px 6px", border: "none", backgroundColor: t.attrs.align === "right" ? "#007acc" : "transparent", color: t.attrs.align === "right" ? "white" : "black", cursor: "pointer", borderRadius: "2px" }, type: "button", children: "→" } ) ] } ) ] }) ] } ) } ); }, gi = ri.extend({ addAttributes() { return { ...this.parent?.(), width: { default: "640px", renderHTML: (t) => ({ width: t.width }) }, height: { default: "360px", renderHTML: (t) => ({ height: t.height }) }, align: { default: "center", renderHTML: (t) => ({ "data-align": t.align }), parseHTML: (t) => t.getAttribute("data-align") || "center" } }; }, addNodeView() { return ge(xi); } }), yi = Ot(qt); function bi() { return [ St.configure({ heading: { levels: [1, 2, 3, 4, 5, 6] }, codeBlock: !1, blockquote: !1, horizontalRule: !1, hardBreak: !1, strike: !1 }), ci, ui, hi.configure({ allowBase64: !0 }), pi, ni, Yt, mi, Jt, Xt, Nt.configure({ resizable: !0, HTMLAttributes: { class: "editor-table" } }), _t, Pt, It, Bt.configure({ openOnClick: !1, HTMLAttributes: { class: "editor-link", rel: "noopener noreferrer" } }), Ht.configure({ types: ["heading", "paragraph"] }), Ft, Dt, $t, zt, Wt.configure({ lowlight: yi, HTMLAttributes: { class: "editor-code-block" } }), gi.configure({ controls: !0, nocookie: !1 }), Zt.configure({ placeholder: "Start typing..." }), Qt, ei, Gt.configure({ HTMLAttributes: { class: "editor-blockquote" } }), Ut, Kt, Vt, fi.configure({ HTMLAttributes: { class: "editor-text-style" } }) ]; } function vi({ className: t = "", placeholder: r = "Start typing..." }) { return { attributes: { class: `prose focus:outline-none ${t} ${r ? "has-placeholder" : ""}`, "aria-label": "Rich text editor", "aria-placeholder": r } }; } function ji(t, r) { t.chain().focus().setMark("customTextStyle", { fontSize: r }).run(); } function ki(t, r) { t.chain().focus().setBackgroundColor(r).run(); } function wi(t, r) { !r || r === "" ? t.chain().focus().unsetMark("customTextStyle", { fontFamily: null }).run() : t.chain().focus().setMark("customTextStyle", { fontFamily: r }).run(); } function Ci(t) { t && t.chain().focus().insertTable({ rows: 3, cols: 3, withHeaderRow: !0 }).run(); } function Ye(t, r) { if (Array.isArray(r)) if (r.length > 1) { const a = [{ type: "imageGroup", content: r.map((d) => ({ type: "image", attrs: { src: d, width: "250px" } })) }]; t.chain().focus().insertContent(a).run(); } else r.length === 1 && t.chain().focus().setImage({ src: r[0], width: "500px" }).run(); else typeof r == "string" && t.chain().focus().setImage({ src: r, width: "500px" }).run(); } function Ei(t, r) { try { t && t.chain().focus().insertContent({ type: "math", attrs: { latex: r } }).run(); } catch (n) { throw console.error("Math insertion error:", n), new Error("Error inserting math equation"); } } const g = At( me( ({ onClick: t, isActive: r, title: n, children: a, shortcut: d, disabled: j }, y) => { const b = D(null), h = D(null), k = q(() => { if (!b.current || !h.current) return; const m = h.current.getBoundingClientRect(), p = b.current; p.style.left = `${m.left + m.width / 2}px`, p.style.top = `${m.top - 8}px`; const u = p.getBoundingClientRect(); u.left < 0 && (p.style.left = "0px", p.style.transform = "none"), u.right > window.innerWidth && (p.style.left = `${window.innerWidth}px`, p.style.transform = "translateX(-100%)"); }, []); return Q(() => { const m = () => { k(); }, p = () => { k(); }; return window.addEventListener("scroll", m, !0), window.addEventListener("resize", p), () => { window.removeEventListener("scroll", m, !0), window.removeEventListener("resize", p); }; }, [k]), /* @__PURE__ */ e.jsxs("div", { className: "tooltip-container", onMouseEnter: k, children: [ /* @__PURE__ */ e.jsx( "button", { ref: (m) => { h.current = m, typeof y == "function" ? y(m) : y && (y.current = m); }, onClick: t, className: `toolbar-button ${r ? "is-active" : ""} ${j ? "is-disabled" : ""}`, "aria-label": n, "aria-pressed": r, disabled: j, type: "button", children: a } ), /* @__PURE__ */ e.jsxs("div", { ref: b, className: "tooltip", children: [ n, d && /* @__PURE__ */ e.jsx("span", { className: "tooltip-shortcut", children: d }) ] }) ] }); } ) ); g.displayName = "ToolbarButton"; const Ai = ({ editor: t, readOnly: r }) => /* @__PURE__ */ e.jsxs("div", { className: "toolbar-group", role: "group", "aria-label": "Text alignment", children: [ /* @__PURE__ */ e.jsx( g, { onClick: () => t?.chain().focus().setTextAlign("left").run(), isActive: t?.isActive({ textAlign: "left" }), title: "Align Left", disabled: !t || r, children: /* @__PURE__ */ e.jsxs( "svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [ /* @__PURE__ */ e.jsx("line", { x1: "4", y1: "6", x2: "20", y2: "6" }), /* @__PURE__ */ e.jsx("line", { x1: "4", y1: "12", x2: "14", y2: "12" }), /* @__PURE__ */ e.jsx("line", { x1: "4", y1: "18", x2: "18", y2: "18" }) ] } ) } ), /* @__PURE__ */ e.jsx( g, { onClick: () => t?.chain().focus().setTextAlign("center").run(), isActive: t?.isActive({ textAlign: "center" }), title: "Align Center", disabled: !t || r, children: /* @__PURE__ */ e.jsxs( "svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [ /* @__PURE__ */ e.jsx("line", { x1: "6", y1: "6", x2: "18", y2: "6" }), /* @__PURE__ */ e.jsx("line", { x1: "4", y1: "12", x2: "20", y2: "12" }), /* @__PURE__ */ e.jsx("line", { x1: "8", y1: "18", x2: "16", y2: "18" }) ] } ) } ), /* @__PURE__ */ e.jsx( g, { onClick: () => t?.chain().focus().setTextAlign("right").run(), isActive: t?.isActive({ textAlign: "right" }), title: "Align Right", disabled: !t || r, children: /* @__PURE__ */ e.jsxs( "svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [ /* @__PURE__ */ e.jsx("line", { x1: "4", y1: "6", x2: "20", y2: "6" }), /* @__PURE__ */ e.jsx("line", { x1: "10", y1: "12", x2: "20", y2: "12" }), /* @__PURE__ */ e.jsx("line", { x1: "6", y1: "18", x2: "20", y2: "18" }) ] } ) } ) ] }), Ri = ({ editor: t, readOnly: r }) => /* @__PURE__ */ e.jsxs("div", { className: "toolbar-group", role: "group", "aria-label": "Blocks", children: [ /* @__PURE__ */ e.jsx( g, { onClick: () => t?.chain().focus().toggleBlockquote().run(), isActive: t?.isActive("blockquote"), title: "Blockquote", disabled: !t || r, children: /* @__PURE__ */ e.jsxs( "svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [ /* @__PURE__ */ e.jsx("path", { d: "M3 21c3 0 7-1 7-8V5c0-1.25-.756-2.017-2-2H4c-1.25 0-2 .75-2 1.972V11c0 1.25.75 2 2 2 1 0 1 0 1 1v1c0 1-1 2-2 2s-1 .008-1 1.031V20c0 1 0 1 1 1z" }), /* @__PURE__ */ e.jsx("path", { d: "M15 21c3 0 7-1 7-8V5c0-1.25-.757-2.017-2-2h-4c-1.25 0-2 .75-2 1.972V11c0 1.25.75 2 2 2h.75c0 2.25.25 4-2.75 4v3c0 1 0 1 1 1z" }) ] } ) } ), /* @__PURE__ */ e.jsx( g, { onClick: () => t?.chain().focus().setHorizontalRule().run(), title: "Horizontal Rule", disabled: !t || r, children: /* @__PURE__ */ e.jsx( "svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ e.jsx("line", { x1: "5", y1: "12", x2: "19", y2: "12" }) } ) } ), /* @__PURE__ */ e.jsx( g, { onClick: () => t?.chain().focus().setHardBreak().run(), title: "Line Break", disabled: !t || r, children: /* @__PURE__ */ e.jsxs( "svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [ /* @__PURE__ */ e.jsx("path", { d: "M21 8H3M21 8L17 4M21 8L17 12" }), /* @__PURE__ */ e.jsx("path", { d: "M3 16H15M3 16L7 12M3 16L7 20" }) ] } ) } ) ] }), Ti = [ "12px", "14px", "16px", "18px", "20px", "24px", "28px", "32px", "36px", "48px" ], Mi = [ { name: "Default", value: "" }, { name: "Arial", value: "Arial, Helvetica, sans-serif" }, { name: "Times New Roman", value: "'Times New Roman', Times, serif" }, { name: "Georgia", value: "Georgia, serif" }, { name: "Courier New", value: "'Courier New', Courier, monospace" }, { name: "Verdana", value: "Verdana, Geneva, sans-serif" }, { name: "Tahoma", value: "Tahoma, Geneva, sans-serif" }, { name: "Trebuchet MS", value: "'Trebuchet MS', Helvetica, sans-serif" }, { name: "Roboto", value: "Roboto, Arial, sans-serif" }, { name: "Open Sans", value: "'Open Sans', Arial, sans-serif" }, { name: "Noto Sans Bengali", value: "'Noto Sans Bengali', 'Noto Sans Bengali UI', 'Noto Sans', sans-serif" }, { name: "SolaimanLipi", value: "'SolaimanLipi', 'Noto Sans Bengali', 'Noto Sans', sans-serif" }, { name: "Siyam Rupali", value: "'Siyam Rupali', 'Noto Sans Bengali', 'Noto Sans', sans-serif" }, { name: "Kalpurush", value: "'Kalpurush', 'Noto Sans Bengali', 'Noto Sans', sans-serif" }, { name: "Nikosh", value: "'Nikosh', 'Noto Sans Bengali', 'Noto Sans', sans-serif" } ], Li = [1, 2, 3, 4, 5, 6], Si = ({ editor: t, readOnly: r }) => /* @__PURE__ */ e.jsxs("div", { className: "toolbar-group", role: "group", "aria-label": "Font style", children: [