@editora/core
Advanced tools
| const w = ".rte-content, .editora-content", F = "[data-editora-editor], .rte-editor, .editora-editor, editora-editor", ee = "__editoraCommandEditorRoot", te = "rte-approval-workflow-styles", d = "rte-approval-panel", h = "approval", y = "approvalWorkflow", v = ':is([data-theme="dark"], .dark, .editora-theme-dark, .rte-theme-dark)', ue = { | ||
| panelTitle: "Approval Workflow", | ||
| panelAriaLabel: "Approval workflow panel", | ||
| statusLabel: "Status", | ||
| statusDraftText: "Draft", | ||
| statusReviewText: "In Review", | ||
| statusApprovedText: "Approved", | ||
| requestReviewText: "Request Review", | ||
| approveText: "Approve", | ||
| reopenDraftText: "Reopen Draft", | ||
| addCommentText: "Add Comment", | ||
| actorLabel: "Actor", | ||
| actorPlaceholder: "Reviewer name", | ||
| commentLabel: "Comment", | ||
| commentPlaceholder: "Add review note or sign-off context", | ||
| closeText: "Close", | ||
| commentsHeading: "Comments", | ||
| signoffsHeading: "Sign-offs", | ||
| noCommentsText: "No comments yet.", | ||
| noSignoffsText: "No sign-offs yet.", | ||
| summaryPrefix: "Workflow", | ||
| lockedSuffix: "Locked", | ||
| shortcutText: "Shortcuts: Ctrl/Cmd+Alt+Shift+A/R/P/D", | ||
| approveCommentRequiredText: "Approval comment is required." | ||
| }, fe = { | ||
| draft: "statusDraftText", | ||
| review: "statusReviewText", | ||
| approved: "statusApprovedText" | ||
| }, p = /* @__PURE__ */ new WeakMap(), I = /* @__PURE__ */ new WeakMap(), k = /* @__PURE__ */ new Map(), O = /* @__PURE__ */ new WeakMap(), H = /* @__PURE__ */ new Set(); | ||
| let _ = 0, me = 0, oe = 0, re = 0, R = null, g = null, T = null, L = null, S = null; | ||
| function c(e) { | ||
| return e.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'"); | ||
| } | ||
| function be(e) { | ||
| return e.replace(/\u00A0/g, " ").replace(/\s+/g, " ").trim(); | ||
| } | ||
| function ne(e) { | ||
| return e === "review" || e === "approved" ? e : "draft"; | ||
| } | ||
| function z(e = {}) { | ||
| var t; | ||
| return { | ||
| defaultStatus: ne(e.defaultStatus), | ||
| lockOnApproval: e.lockOnApproval !== !1, | ||
| maxHistoryEntries: Math.max(10, Math.min(500, Number((t = e.maxHistoryEntries) != null ? t : 120))), | ||
| requireCommentOnApprove: !!e.requireCommentOnApprove, | ||
| defaultActor: (e.defaultActor || "system").trim() || "system", | ||
| labels: { | ||
| ...ue, | ||
| ...e.labels || {} | ||
| }, | ||
| normalizeText: e.normalizeText || be | ||
| }; | ||
| } | ||
| function U(e) { | ||
| return e.closest(F) || e; | ||
| } | ||
| function B(e) { | ||
| if (!e) return null; | ||
| if (e.matches(w)) return e; | ||
| const t = e.querySelector(w); | ||
| return t instanceof HTMLElement ? t : null; | ||
| } | ||
| function ve() { | ||
| if (typeof window == "undefined") return null; | ||
| const e = window[ee]; | ||
| if (!(e instanceof HTMLElement)) return null; | ||
| window[ee] = null; | ||
| const t = B(e); | ||
| if (t) return t; | ||
| const o = e.closest(F); | ||
| if (o) { | ||
| const a = B(o); | ||
| if (a) return a; | ||
| } | ||
| return null; | ||
| } | ||
| function ge(e) { | ||
| const t = e.closest("[data-editora-editor]"); | ||
| if (t && B(t) === e) | ||
| return t; | ||
| let o = e; | ||
| for (; o; ) { | ||
| if (o.matches(F) && (o === e || B(o) === e)) | ||
| return o; | ||
| o = o.parentElement; | ||
| } | ||
| return U(e); | ||
| } | ||
| function W(e) { | ||
| return e ? (e.getAttribute("data-theme") || e.getAttribute("theme") || "").toLowerCase() === "dark" ? !0 : e.classList.contains("dark") || e.classList.contains("editora-theme-dark") || e.classList.contains("rte-theme-dark") : !1; | ||
| } | ||
| function he(e) { | ||
| const t = U(e); | ||
| if (W(t)) return !0; | ||
| const o = t.closest("[data-theme], [theme], .dark, .editora-theme-dark, .rte-theme-dark"); | ||
| return W(o) ? !0 : W(document.documentElement) || W(document.body); | ||
| } | ||
| function K(e, t) { | ||
| e.classList.remove("rte-approval-theme-dark"), he(t) && e.classList.add("rte-approval-theme-dark"); | ||
| } | ||
| function le(e) { | ||
| return e ? e.nodeType === Node.ELEMENT_NODE ? e : e.parentElement : null; | ||
| } | ||
| function x(e, t = !0) { | ||
| if (D(), (e == null ? void 0 : e.contentElement) instanceof HTMLElement) return e.contentElement; | ||
| if ((e == null ? void 0 : e.editorElement) instanceof HTMLElement) { | ||
| const n = e.editorElement; | ||
| if (n.matches(w)) return n; | ||
| const l = n.querySelector(w); | ||
| if (l instanceof HTMLElement) return l; | ||
| } | ||
| const o = ve(); | ||
| if (o) return o; | ||
| const a = window.getSelection(); | ||
| if (a && a.rangeCount > 0) { | ||
| const n = le(a.getRangeAt(0).startContainer), l = n == null ? void 0 : n.closest(w); | ||
| if (l) return l; | ||
| } | ||
| const r = document.activeElement; | ||
| if (r) { | ||
| if (r.matches(w)) return r; | ||
| const n = r.closest(w); | ||
| if (n) return n; | ||
| } | ||
| return g && g.isConnected ? g : (g && !g.isConnected && (g = null), t ? document.querySelector(w) : null); | ||
| } | ||
| function D() { | ||
| Array.from(H).forEach((t) => { | ||
| var o; | ||
| t.isConnected || ((o = k.get(t)) == null || o.remove(), k.delete(t), O.delete(t), p.delete(t), I.delete(t), H.delete(t), g === t && (g = null)); | ||
| }); | ||
| } | ||
| function xe(e) { | ||
| return e ? !!(e.closest(`.${d}`) || e.closest(w) || e.closest(F)) : !1; | ||
| } | ||
| function we() { | ||
| const e = window.getSelection(); | ||
| if (!e || e.rangeCount === 0) return !1; | ||
| const t = e.getRangeAt(0).startContainer, o = le(t); | ||
| return !!(o != null && o.closest(w)); | ||
| } | ||
| function C(e, t, o) { | ||
| const a = ge(e); | ||
| Array.from( | ||
| a.querySelectorAll( | ||
| `.rte-toolbar-button[data-command="${t}"], .editora-toolbar-button[data-command="${t}"]` | ||
| ) | ||
| ).forEach((n) => { | ||
| n.classList.toggle("active", o), n.setAttribute("aria-pressed", o ? "true" : "false"), n.setAttribute("data-active", o ? "true" : "false"); | ||
| }); | ||
| } | ||
| function ie(e, t, o) { | ||
| t !== null ? e.setAttribute("contenteditable", t) : e.setAttribute("contenteditable", "true"), o !== null ? e.setAttribute("data-readonly", o) : e.removeAttribute("data-readonly"); | ||
| } | ||
| function Y(e) { | ||
| e.dispatchEvent(new Event("input", { bubbles: !0 })); | ||
| } | ||
| function X(e, t) { | ||
| if (t === e.innerHTML) return; | ||
| const o = window.execEditorCommand || window.executeEditorCommand; | ||
| if (typeof o == "function") | ||
| try { | ||
| o("recordDomTransaction", e, t, e.innerHTML); | ||
| } catch (a) { | ||
| } | ||
| } | ||
| function J() { | ||
| return oe += 1, `approval-comment-${Date.now().toString(36)}-${oe.toString(36)}`; | ||
| } | ||
| function ke() { | ||
| return re += 1, `approval-signoff-${Date.now().toString(36)}-${re.toString(36)}`; | ||
| } | ||
| function se(e) { | ||
| return { | ||
| status: e.status, | ||
| locked: e.locked, | ||
| comments: e.comments.map((t) => ({ ...t })), | ||
| signoffs: e.signoffs.map((t) => ({ ...t })), | ||
| updatedAt: e.updatedAt | ||
| }; | ||
| } | ||
| function ye(e, t) { | ||
| const o = fe[e]; | ||
| return t.labels[o] || e; | ||
| } | ||
| function pe(e, t, o) { | ||
| var a, r; | ||
| if (e.setAttribute("data-approval-status", t.status), e.setAttribute("data-approval-locked", t.locked ? "true" : "false"), e.classList.toggle("rte-approval-locked-editor", t.locked), C(e, "toggleApprovalWorkflowPanel", Z(e)), C(e, "requestApprovalReview", t.status === "review"), C(e, "approveDocument", t.status === "approved"), C(e, "reopenDraft", t.status === "draft"), t.status === "approved" && o.lockOnApproval) { | ||
| t.locked || (t.preApprovalContentEditable = e.getAttribute("contenteditable"), t.preApprovalReadonly = e.getAttribute("data-readonly")), e.setAttribute("contenteditable", "false"), e.setAttribute("data-readonly", "true"), t.locked = !0; | ||
| return; | ||
| } | ||
| t.locked = !1, ie( | ||
| e, | ||
| (a = t.preApprovalContentEditable) != null ? a : t.originalContentEditable, | ||
| (r = t.preApprovalReadonly) != null ? r : t.originalReadonly | ||
| ), t.preApprovalContentEditable = null, t.preApprovalReadonly = null; | ||
| } | ||
| function f(e, t) { | ||
| let o = I.get(e); | ||
| return o || (o = { | ||
| status: t.defaultStatus, | ||
| locked: !1, | ||
| comments: [], | ||
| signoffs: [], | ||
| updatedAt: (/* @__PURE__ */ new Date()).toISOString(), | ||
| originalContentEditable: e.getAttribute("contenteditable"), | ||
| originalReadonly: e.getAttribute("data-readonly"), | ||
| preApprovalContentEditable: null, | ||
| preApprovalReadonly: null | ||
| }, I.set(e, o), H.add(e), pe(e, o, t), o); | ||
| } | ||
| function j(e, t) { | ||
| return e.length <= t ? e : e.slice(e.length - t); | ||
| } | ||
| function M(e, t) { | ||
| const o = e.querySelector(".rte-approval-live"); | ||
| o && (o.textContent = t); | ||
| } | ||
| function Ae(e, t) { | ||
| const o = se(t); | ||
| e.__approvalWorkflowState = o, e.dispatchEvent( | ||
| new CustomEvent("editora:approval-state-changed", { | ||
| bubbles: !0, | ||
| detail: { | ||
| state: o | ||
| } | ||
| }) | ||
| ); | ||
| } | ||
| function q(e) { | ||
| const t = k.get(e); | ||
| if (!t) return; | ||
| const o = p.get(e) || R; | ||
| if (!o) return; | ||
| const a = f(e, o), r = t.querySelector(".rte-approval-summary"), n = t.querySelector('[data-action="request-review"]'), l = t.querySelector('[data-action="approve"]'), s = t.querySelector('[data-action="reopen-draft"]'), u = t.querySelector(".rte-approval-comments-list"), m = t.querySelector(".rte-approval-signoffs-list"); | ||
| if (r) { | ||
| const i = ye(a.status, o); | ||
| r.textContent = `${o.labels.summaryPrefix}: ${i} | Comments: ${a.comments.length} | Sign-offs: ${a.signoffs.length}${a.locked ? ` | ${o.labels.lockedSuffix}` : ""}`; | ||
| } | ||
| n && (n.disabled = a.status !== "draft"), l && (l.disabled = a.status === "approved"), s && (s.disabled = a.status === "draft"), u && (a.comments.length === 0 ? u.innerHTML = `<li class="rte-approval-empty">${c(o.labels.noCommentsText)}</li>` : u.innerHTML = a.comments.slice().reverse().map( | ||
| (i) => ` | ||
| <li class="rte-approval-item rte-approval-item-${i.kind}" role="listitem"> | ||
| <div class="rte-approval-item-head"> | ||
| <span class="rte-approval-item-author">${c(i.author)}</span> | ||
| <time class="rte-approval-item-time" datetime="${c(i.createdAt)}">${c( | ||
| new Date(i.createdAt).toLocaleString() | ||
| )}</time> | ||
| </div> | ||
| <p class="rte-approval-item-message">${c(i.message)}</p> | ||
| </li> | ||
| ` | ||
| ).join("")), m && (a.signoffs.length === 0 ? m.innerHTML = `<li class="rte-approval-empty">${c(o.labels.noSignoffsText)}</li>` : m.innerHTML = a.signoffs.slice().reverse().map( | ||
| (i) => ` | ||
| <li class="rte-approval-item" role="listitem"> | ||
| <div class="rte-approval-item-head"> | ||
| <span class="rte-approval-item-author">${c(i.author)}</span> | ||
| <time class="rte-approval-item-time" datetime="${c(i.createdAt)}">${c( | ||
| new Date(i.createdAt).toLocaleString() | ||
| )}</time> | ||
| </div> | ||
| <p class="rte-approval-item-message">${c(i.comment || "Approved")}</p> | ||
| </li> | ||
| ` | ||
| ).join("")); | ||
| } | ||
| function G(e, t, o) { | ||
| t.updatedAt = (/* @__PURE__ */ new Date()).toISOString(), pe(e, t, o), q(e), Ae(e, t); | ||
| } | ||
| function ae(e, t, o, a) { | ||
| e.comments.push({ | ||
| id: J(), | ||
| author: o || t.defaultActor, | ||
| message: a, | ||
| kind: "system", | ||
| createdAt: (/* @__PURE__ */ new Date()).toISOString() | ||
| }), e.comments = j(e.comments, t.maxHistoryEntries); | ||
| } | ||
| function E(e, t, o, a) { | ||
| const r = f(e, o); | ||
| if (r.status === t) return !1; | ||
| const n = e.innerHTML; | ||
| return r.status = t, t === "review" ? ae(r, o, a, "Review requested.") : t === "draft" && ae(r, o, a, "Returned to draft."), G(e, r, o), Y(e), X(e, n), !0; | ||
| } | ||
| function ce(e, t, o, a) { | ||
| const r = a.normalizeText(t); | ||
| if (!r) return !1; | ||
| const n = a.normalizeText(o) || a.defaultActor, l = f(e, a), s = e.innerHTML; | ||
| return l.comments.push({ | ||
| id: J(), | ||
| author: n, | ||
| message: r, | ||
| kind: "comment", | ||
| createdAt: (/* @__PURE__ */ new Date()).toISOString() | ||
| }), l.comments = j(l.comments, a.maxHistoryEntries), G(e, l, a), Y(e), X(e, s), !0; | ||
| } | ||
| function Q(e, t, o, a) { | ||
| const r = t.normalizeText(o) || t.defaultActor, n = t.normalizeText(a); | ||
| if (t.requireCommentOnApprove && !n) return !1; | ||
| const l = f(e, t), s = e.innerHTML; | ||
| return l.status = "approved", l.signoffs.push({ | ||
| id: ke(), | ||
| author: r, | ||
| comment: n || void 0, | ||
| createdAt: (/* @__PURE__ */ new Date()).toISOString() | ||
| }), l.signoffs = j(l.signoffs, t.maxHistoryEntries), n && (l.comments.push({ | ||
| id: J(), | ||
| author: r, | ||
| message: n, | ||
| kind: "system", | ||
| createdAt: (/* @__PURE__ */ new Date()).toISOString() | ||
| }), l.comments = j(l.comments, t.maxHistoryEntries)), G(e, l, t), Y(e), X(e, s), !0; | ||
| } | ||
| function N(e, t) { | ||
| return e.querySelector(`[data-field="${t}"]`); | ||
| } | ||
| function Se(e) { | ||
| var a, r; | ||
| const t = ((a = N(e, "actor")) == null ? void 0 : a.value) || "", o = ((r = N(e, "comment")) == null ? void 0 : r.value) || ""; | ||
| return { actor: t, comment: o }; | ||
| } | ||
| function V(e, t) { | ||
| if (!t.classList.contains("show")) return; | ||
| const a = U(e).getBoundingClientRect(), r = Math.min(window.innerWidth - 20, 420), n = Math.max(10, window.innerWidth - r - 10), l = Math.min(Math.max(10, a.right - r), n), s = Math.max(10, Math.min(window.innerHeight - 10 - 280, a.top + 12)); | ||
| t.style.width = `${r}px`, t.style.left = `${l}px`, t.style.top = `${s}px`, t.style.maxHeight = `${Math.max(280, window.innerHeight - 24)}px`; | ||
| } | ||
| function $e(e) { | ||
| const t = k.get(e); | ||
| if (t) return t; | ||
| const o = p.get(e) || R || z(), a = `rte-approval-panel-${me++}`, r = document.createElement("section"); | ||
| return r.className = d, r.id = a, r.setAttribute("role", "dialog"), r.setAttribute("aria-modal", "false"), r.setAttribute("aria-label", o.labels.panelAriaLabel), r.setAttribute("tabindex", "-1"), r.innerHTML = ` | ||
| <header class="rte-approval-header"> | ||
| <h2 class="rte-approval-title">${c(o.labels.panelTitle)}</h2> | ||
| <button type="button" class="rte-approval-icon-btn" data-action="close" aria-label="${c( | ||
| o.labels.closeText | ||
| )}">✕</button> | ||
| </header> | ||
| <div class="rte-approval-body"> | ||
| <p class="rte-approval-summary" aria-live="polite"></p> | ||
| <div class="rte-approval-controls" role="toolbar" aria-label="Approval actions"> | ||
| <button type="button" class="rte-approval-btn" data-action="request-review">${c( | ||
| o.labels.requestReviewText | ||
| )}</button> | ||
| <button type="button" class="rte-approval-btn rte-approval-btn-primary" data-action="approve">${c( | ||
| o.labels.approveText | ||
| )}</button> | ||
| <button type="button" class="rte-approval-btn" data-action="reopen-draft">${c( | ||
| o.labels.reopenDraftText | ||
| )}</button> | ||
| </div> | ||
| <div class="rte-approval-form"> | ||
| <label class="rte-approval-label"> | ||
| ${c(o.labels.actorLabel)} | ||
| <input type="text" data-field="actor" class="rte-approval-field" autocomplete="off" placeholder="${c( | ||
| o.labels.actorPlaceholder | ||
| )}" /> | ||
| </label> | ||
| <label class="rte-approval-label"> | ||
| ${c(o.labels.commentLabel)} | ||
| <textarea data-field="comment" class="rte-approval-field" rows="2" placeholder="${c( | ||
| o.labels.commentPlaceholder | ||
| )}"></textarea> | ||
| </label> | ||
| <button type="button" class="rte-approval-btn" data-action="add-comment">${c( | ||
| o.labels.addCommentText | ||
| )}</button> | ||
| </div> | ||
| <section class="rte-approval-section" aria-label="${c(o.labels.commentsHeading)}"> | ||
| <h3 class="rte-approval-section-title">${c(o.labels.commentsHeading)}</h3> | ||
| <ul class="rte-approval-comments-list" role="list"></ul> | ||
| </section> | ||
| <section class="rte-approval-section" aria-label="${c(o.labels.signoffsHeading)}"> | ||
| <h3 class="rte-approval-section-title">${c(o.labels.signoffsHeading)}</h3> | ||
| <ul class="rte-approval-signoffs-list" role="list"></ul> | ||
| </section> | ||
| <p class="rte-approval-shortcut">${c(o.labels.shortcutText)}</p> | ||
| <span class="rte-approval-live" aria-live="polite"></span> | ||
| </div> | ||
| `, r.addEventListener("click", (n) => { | ||
| const l = n.target; | ||
| if (!l) return; | ||
| const s = l.closest("[data-action]"); | ||
| if (!s) return; | ||
| const u = s.getAttribute("data-action") || "", m = p.get(e) || R || o; | ||
| if (p.set(e, m), f(e, m), u === "close") { | ||
| P(e, !0); | ||
| return; | ||
| } | ||
| const i = Se(r); | ||
| if (u === "request-review") { | ||
| E(e, "review", m, i.actor || m.defaultActor) && M(r, "Status changed to review."); | ||
| return; | ||
| } | ||
| if (u === "reopen-draft") { | ||
| E(e, "draft", m, i.actor || m.defaultActor) && M(r, "Status changed to draft."); | ||
| return; | ||
| } | ||
| if (u === "approve") { | ||
| const b = Q(e, m, i.actor, i.comment); | ||
| if (!b && m.requireCommentOnApprove) { | ||
| M(r, m.labels.approveCommentRequiredText); | ||
| return; | ||
| } | ||
| if (b) { | ||
| const $ = N(r, "comment"); | ||
| $ && ($.value = ""), M(r, "Document approved and signed off."); | ||
| } | ||
| return; | ||
| } | ||
| if (u === "add-comment") { | ||
| if (!ce(e, i.comment, i.actor, m)) return; | ||
| const $ = N(r, "comment"); | ||
| $ && ($.value = ""), M(r, "Comment added."); | ||
| return; | ||
| } | ||
| }), r.addEventListener("keydown", (n) => { | ||
| n.key === "Escape" && (n.preventDefault(), P(e, !0)); | ||
| }), K(r, e), document.body.appendChild(r), k.set(e, r), O.set(e, !1), q(e), r; | ||
| } | ||
| function Z(e) { | ||
| return O.get(e) === !0; | ||
| } | ||
| function A(e) { | ||
| D(); | ||
| const t = $e(e); | ||
| k.forEach((o, a) => { | ||
| a !== e && P(a, !1); | ||
| }), t.classList.add("show"), O.set(e, !0), C(e, "toggleApprovalWorkflowPanel", !0), K(t, e), V(e, t), q(e); | ||
| } | ||
| function P(e, t = !1) { | ||
| const o = k.get(e); | ||
| o && (o.classList.remove("show"), O.set(e, !1), C(e, "toggleApprovalWorkflowPanel", !1), t && e.focus({ preventScroll: !0 })); | ||
| } | ||
| function de(e, t) { | ||
| const o = Z(e); | ||
| return (typeof t == "boolean" ? t : !o) ? A(e) : P(e), !0; | ||
| } | ||
| function Ee(e) { | ||
| const t = e.key.toLowerCase(); | ||
| return (e.metaKey || e.ctrlKey) && e.altKey && e.shiftKey && t === "a"; | ||
| } | ||
| function Ce(e) { | ||
| const t = e.key.toLowerCase(); | ||
| return (e.metaKey || e.ctrlKey) && e.altKey && e.shiftKey && t === "r"; | ||
| } | ||
| function Te(e) { | ||
| const t = e.key.toLowerCase(); | ||
| return (e.metaKey || e.ctrlKey) && e.altKey && e.shiftKey && t === "p"; | ||
| } | ||
| function Le(e) { | ||
| const t = e.key.toLowerCase(); | ||
| return (e.metaKey || e.ctrlKey) && e.altKey && e.shiftKey && t === "d"; | ||
| } | ||
| function Re(e) { | ||
| R = e, T || (T = (t) => { | ||
| D(); | ||
| const o = t.target, a = o == null ? void 0 : o.closest(w); | ||
| if (!a) return; | ||
| g = a; | ||
| const r = p.get(a) || e; | ||
| p.set(a, r), f(a, r); | ||
| const n = k.get(a); | ||
| n && (K(n, a), V(a, n)); | ||
| }, document.addEventListener("focusin", T, !0)), L || (L = (t) => { | ||
| if (t.defaultPrevented) return; | ||
| const o = Ee(t), a = Ce(t), r = Te(t), n = Le(t), l = t.key === "Escape"; | ||
| if (!l && !o && !a && !r && !n) | ||
| return; | ||
| D(); | ||
| const s = t.target, u = !!(s != null && s.closest(`.${d} input, .${d} textarea, .${d} select`)); | ||
| if (!xe(s) && !we()) | ||
| return; | ||
| const i = x(void 0, !1); | ||
| if (!i) return; | ||
| const b = p.get(i) || R || e; | ||
| p.set(i, b); | ||
| const $ = f(i, b); | ||
| if (g = i, l && Z(i)) { | ||
| t.preventDefault(), P(i, !0); | ||
| return; | ||
| } | ||
| if (!u) { | ||
| if (o) { | ||
| t.preventDefault(), t.stopPropagation(), de(i); | ||
| return; | ||
| } | ||
| if (a) { | ||
| t.preventDefault(), t.stopPropagation(), E(i, "review", b, b.defaultActor) && A(i); | ||
| return; | ||
| } | ||
| if (r) { | ||
| t.preventDefault(), t.stopPropagation(), Q(i, b, b.defaultActor, "Approved via keyboard shortcut.") && A(i); | ||
| return; | ||
| } | ||
| n && (t.preventDefault(), t.stopPropagation(), $.status !== "draft" && E(i, "draft", b, b.defaultActor) && A(i)); | ||
| } | ||
| }, document.addEventListener("keydown", L, !0)), S || (S = () => { | ||
| D(), k.forEach((t, o) => { | ||
| !o.isConnected || !t.isConnected || (K(t, o), V(o, t)); | ||
| }); | ||
| }, window.addEventListener("scroll", S, !0), window.addEventListener("resize", S)); | ||
| } | ||
| function Me(e) { | ||
| var o, a; | ||
| const t = I.get(e); | ||
| t && (e.classList.remove("rte-approval-locked-editor"), e.removeAttribute("data-approval-status"), e.removeAttribute("data-approval-locked"), ie( | ||
| e, | ||
| (o = t.preApprovalContentEditable) != null ? o : t.originalContentEditable, | ||
| (a = t.preApprovalReadonly) != null ? a : t.originalReadonly | ||
| )); | ||
| } | ||
| function De() { | ||
| T && (document.removeEventListener("focusin", T, !0), T = null), L && (document.removeEventListener("keydown", L, !0), L = null), S && (window.removeEventListener("scroll", S, !0), window.removeEventListener("resize", S), S = null), k.forEach((e) => e.remove()), k.clear(), H.forEach((e) => Me(e)), H.clear(), R = null, g = null; | ||
| } | ||
| function He() { | ||
| if (typeof document == "undefined" || document.getElementById(te)) return; | ||
| const e = document.createElement("style"); | ||
| e.id = te, e.textContent = ` | ||
| .rte-toolbar-group-items.${h}, | ||
| .editora-toolbar-group-items.${h}, | ||
| .rte-toolbar-group-items.${y}, | ||
| .editora-toolbar-group-items.${y} { | ||
| display: flex; | ||
| border: 1px solid #ccc; | ||
| border-radius: 3px; | ||
| background: #fff; | ||
| } | ||
| .rte-toolbar-group-items.${h} .rte-toolbar-button, | ||
| .editora-toolbar-group-items.${h} .editora-toolbar-button, | ||
| .rte-toolbar-group-items.${y} .rte-toolbar-button, | ||
| .editora-toolbar-group-items.${y} .editora-toolbar-button { | ||
| border: none; | ||
| border-radius: 0; | ||
| border-right: 1px solid #ccc; | ||
| } | ||
| .rte-toolbar-button[data-command="toggleApprovalWorkflowPanel"].active, | ||
| .editora-toolbar-button[data-command="toggleApprovalWorkflowPanel"].active, | ||
| .rte-toolbar-button[data-command="reopenDraft"].active, | ||
| .editora-toolbar-button[data-command="reopenDraft"].active { | ||
| background-color: #ccc; | ||
| } | ||
| ${v} .rte-toolbar-button[data-command="toggleApprovalWorkflowPanel"].active, | ||
| ${v} .editora-toolbar-button[data-command="toggleApprovalWorkflowPanel"].active, | ||
| ${v} .rte-toolbar-button[data-command="reopenDraft"].active, | ||
| ${v} .editora-toolbar-button[data-command="reopenDraft"].active { | ||
| background: linear-gradient(180deg, #5eaaf6 0%, #4a95de 100%); | ||
| } | ||
| .rte-toolbar-group-items.${h} .rte-toolbar-item:last-child .rte-toolbar-button, | ||
| .editora-toolbar-group-items.${h} .editora-toolbar-item:last-child .editora-toolbar-button, | ||
| .rte-toolbar-group-items.${y} .rte-toolbar-item:last-child .rte-toolbar-button, | ||
| .editora-toolbar-group-items.${y} .editora-toolbar-item:last-child .editora-toolbar-button { | ||
| border-right: none; | ||
| } | ||
| ${v} .rte-toolbar-group-items.${h}, | ||
| ${v} .editora-toolbar-group-items.${h}, | ||
| ${v} .rte-toolbar-group-items.${y}, | ||
| ${v} .editora-toolbar-group-items.${y}, | ||
| .${d}.rte-approval-theme-dark { | ||
| border-color: #566275; | ||
| } | ||
| ${v} .rte-toolbar-group-items.${h} .rte-toolbar-button svg, | ||
| ${v} .editora-toolbar-group-items.${h} .editora-toolbar-button svg, | ||
| ${v} .rte-toolbar-group-items.${y} .rte-toolbar-button svg, | ||
| ${v} .editora-toolbar-group-items.${y} .editora-toolbar-button svg | ||
| { | ||
| fill: none; | ||
| } | ||
| ${v} .rte-toolbar-group-items.${h} .rte-toolbar-button, | ||
| ${v} .editora-toolbar-group-items.${h} .editora-toolbar-button | ||
| { | ||
| border-color: #566275; | ||
| } | ||
| .rte-approval-locked-editor { | ||
| background-image: repeating-linear-gradient( | ||
| -45deg, | ||
| rgba(30, 64, 175, 0.04), | ||
| rgba(30, 64, 175, 0.04) 8px, | ||
| rgba(30, 64, 175, 0.08) 8px, | ||
| rgba(30, 64, 175, 0.08) 16px | ||
| ); | ||
| } | ||
| .${d} { | ||
| position: fixed; | ||
| z-index: 1500; | ||
| right: 16px; | ||
| top: 16px; | ||
| width: min(420px, calc(100vw - 20px)); | ||
| max-height: calc(100vh - 24px); | ||
| display: none; | ||
| flex-direction: column; | ||
| border-radius: 12px; | ||
| border: 1px solid #d1d5db; | ||
| background: #ffffff; | ||
| color: #0f172a; | ||
| box-shadow: 0 18px 38px rgba(15, 23, 42, 0.16); | ||
| overflow: hidden; | ||
| } | ||
| .${d}.show { | ||
| display: flex; | ||
| } | ||
| .${d}.rte-approval-theme-dark { | ||
| background: #0f172a; | ||
| color: #e2e8f0; | ||
| border-color: #334155; | ||
| box-shadow: 0 20px 40px rgba(2, 6, 23, 0.5); | ||
| } | ||
| .rte-approval-header { | ||
| display: flex; | ||
| align-items: center; | ||
| justify-content: space-between; | ||
| padding: 10px 12px; | ||
| border-bottom: 1px solid #e2e8f0; | ||
| background: #f8fafc; | ||
| } | ||
| .${d}.rte-approval-theme-dark .rte-approval-header { | ||
| border-bottom-color: #334155; | ||
| background: #111827; | ||
| } | ||
| .rte-approval-title { | ||
| margin: 0; | ||
| font-size: 14px; | ||
| font-weight: 700; | ||
| } | ||
| .rte-approval-icon-btn { | ||
| border: 1px solid #cbd5e1; | ||
| background: #ffffff; | ||
| color: #0f172a; | ||
| border-radius: 6px; | ||
| cursor: pointer; | ||
| min-width: 34px; | ||
| min-height: 34px; | ||
| width: 34px; | ||
| height: 34px; | ||
| padding: 0; | ||
| display: inline-flex; | ||
| align-items: center; | ||
| justify-content: center; | ||
| font-size: 16px; | ||
| line-height: 1; | ||
| font-weight: 600; | ||
| } | ||
| .rte-approval-icon-btn:hover, | ||
| .rte-approval-icon-btn:focus-visible { | ||
| outline: none; | ||
| border-color: #3b82f6; | ||
| box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.2); | ||
| } | ||
| .${d}.rte-approval-theme-dark .rte-approval-icon-btn { | ||
| background: #0f172a; | ||
| border-color: #475569; | ||
| color: #e2e8f0; | ||
| } | ||
| .${d}.rte-approval-theme-dark .rte-approval-icon-btn:hover, | ||
| .${d}.rte-approval-theme-dark .rte-approval-icon-btn:focus-visible { | ||
| border-color: #60a5fa; | ||
| box-shadow: 0 0 0 3px rgba(96, 165, 250, 0.24); | ||
| } | ||
| .rte-approval-body { | ||
| display: flex; | ||
| flex-direction: column; | ||
| gap: 10px; | ||
| padding: 12px; | ||
| overflow: auto; | ||
| } | ||
| .rte-approval-summary { | ||
| margin: 0; | ||
| font-size: 12px; | ||
| color: #475569; | ||
| } | ||
| .${d}.rte-approval-theme-dark .rte-approval-summary { | ||
| color: #94a3b8; | ||
| } | ||
| .rte-approval-controls { | ||
| display: flex; | ||
| flex-wrap: wrap; | ||
| gap: 8px; | ||
| } | ||
| .rte-approval-btn { | ||
| border: 1px solid #cbd5e1; | ||
| background: #f8fafc; | ||
| color: inherit; | ||
| border-radius: 8px; | ||
| padding: 6px 10px; | ||
| font-size: 12px; | ||
| font-weight: 600; | ||
| cursor: pointer; | ||
| } | ||
| .rte-approval-btn:disabled { | ||
| opacity: 0.5; | ||
| cursor: not-allowed; | ||
| } | ||
| .rte-approval-btn:hover:not(:disabled), | ||
| .rte-approval-btn:focus-visible:not(:disabled) { | ||
| outline: none; | ||
| border-color: #1d4ed8; | ||
| box-shadow: 0 0 0 2px rgba(29, 78, 216, 0.2); | ||
| } | ||
| .rte-approval-btn-primary { | ||
| background: #1d4ed8; | ||
| border-color: #1d4ed8; | ||
| color: #ffffff; | ||
| } | ||
| .rte-approval-btn-primary:hover:not(:disabled), | ||
| .rte-approval-btn-primary:focus-visible:not(:disabled) { | ||
| background: #1e40af; | ||
| border-color: #1e40af; | ||
| } | ||
| .${d}.rte-approval-theme-dark .rte-approval-btn { | ||
| border-color: #334155; | ||
| background: #0b1220; | ||
| color: #e2e8f0; | ||
| } | ||
| .${d}.rte-approval-theme-dark .rte-approval-btn-primary { | ||
| border-color: #2563eb; | ||
| background: #2563eb; | ||
| color: #ffffff; | ||
| } | ||
| .rte-approval-form { | ||
| display: grid; | ||
| grid-template-columns: 1fr; | ||
| gap: 8px; | ||
| border: 1px solid #e2e8f0; | ||
| border-radius: 10px; | ||
| padding: 8px; | ||
| } | ||
| .${d}.rte-approval-theme-dark .rte-approval-form { | ||
| border-color: #334155; | ||
| } | ||
| .rte-approval-label { | ||
| display: flex; | ||
| flex-direction: column; | ||
| gap: 4px; | ||
| font-size: 12px; | ||
| font-weight: 600; | ||
| } | ||
| .rte-approval-field { | ||
| width: 100%; | ||
| box-sizing: border-box; | ||
| min-height: 30px; | ||
| border-radius: 8px; | ||
| border: 1px solid #cbd5e1; | ||
| background: #ffffff; | ||
| color: inherit; | ||
| font-size: 13px; | ||
| padding: 6px 8px; | ||
| } | ||
| .rte-approval-field:focus-visible { | ||
| outline: none; | ||
| border-color: #1d4ed8; | ||
| box-shadow: 0 0 0 2px rgba(29, 78, 216, 0.2); | ||
| } | ||
| .${d}.rte-approval-theme-dark .rte-approval-field { | ||
| border-color: #334155; | ||
| background: #0b1220; | ||
| color: #e2e8f0; | ||
| } | ||
| .rte-approval-section { | ||
| border: 1px solid #e2e8f0; | ||
| border-radius: 10px; | ||
| padding: 8px; | ||
| } | ||
| .${d}.rte-approval-theme-dark .rte-approval-section { | ||
| border-color: #334155; | ||
| } | ||
| .rte-approval-section-title { | ||
| margin: 0 0 8px; | ||
| font-size: 12px; | ||
| font-weight: 700; | ||
| } | ||
| .rte-approval-comments-list, | ||
| .rte-approval-signoffs-list { | ||
| margin: 0; | ||
| padding: 0; | ||
| list-style: none; | ||
| display: flex; | ||
| flex-direction: column; | ||
| gap: 6px; | ||
| max-height: 150px; | ||
| overflow: auto; | ||
| } | ||
| .rte-approval-item { | ||
| border: 1px solid #dbeafe; | ||
| background: #eff6ff; | ||
| border-radius: 8px; | ||
| padding: 6px; | ||
| } | ||
| .rte-approval-item-comment { | ||
| border-color: #e2e8f0; | ||
| background: #f8fafc; | ||
| } | ||
| .${d}.rte-approval-theme-dark .rte-approval-item { | ||
| border-color: #334155; | ||
| background: #111827; | ||
| } | ||
| .rte-approval-item-head { | ||
| display: flex; | ||
| align-items: center; | ||
| justify-content: space-between; | ||
| gap: 8px; | ||
| margin-bottom: 4px; | ||
| } | ||
| .rte-approval-item-author { | ||
| font-size: 12px; | ||
| font-weight: 700; | ||
| } | ||
| .rte-approval-item-time { | ||
| font-size: 11px; | ||
| color: #64748b; | ||
| } | ||
| .${d}.rte-approval-theme-dark .rte-approval-item-time { | ||
| color: #94a3b8; | ||
| } | ||
| .rte-approval-item-message { | ||
| margin: 0; | ||
| font-size: 12px; | ||
| line-height: 1.35; | ||
| white-space: pre-wrap; | ||
| } | ||
| .rte-approval-empty { | ||
| border: 1px dashed #cbd5e1; | ||
| border-radius: 8px; | ||
| padding: 8px; | ||
| font-size: 12px; | ||
| color: #64748b; | ||
| } | ||
| .${d}.rte-approval-theme-dark .rte-approval-empty { | ||
| border-color: #334155; | ||
| color: #94a3b8; | ||
| } | ||
| .rte-approval-shortcut { | ||
| margin: 0; | ||
| font-size: 11px; | ||
| color: #64748b; | ||
| } | ||
| .${d}.rte-approval-theme-dark .rte-approval-shortcut { | ||
| color: #94a3b8; | ||
| } | ||
| .rte-approval-live { | ||
| position: absolute; | ||
| width: 1px; | ||
| height: 1px; | ||
| margin: -1px; | ||
| padding: 0; | ||
| overflow: hidden; | ||
| clip: rect(0 0 0 0); | ||
| border: 0; | ||
| } | ||
| @media (max-width: 768px) { | ||
| .${d} { | ||
| left: 10px !important; | ||
| right: 10px; | ||
| top: 10px !important; | ||
| width: auto !important; | ||
| max-height: calc(100vh - 20px); | ||
| } | ||
| } | ||
| `, document.head.appendChild(e); | ||
| } | ||
| const qe = (e = {}) => { | ||
| const t = z(e); | ||
| return He(), { | ||
| name: "approvalWorkflow", | ||
| toolbar: [ | ||
| { | ||
| id: "approvalWorkflowGroup", | ||
| label: "Approval", | ||
| type: "group", | ||
| command: "approvalWorkflow", | ||
| items: [ | ||
| { | ||
| id: "approvalWorkflow", | ||
| label: "Approval Workflow", | ||
| command: "toggleApprovalWorkflowPanel", | ||
| shortcut: "Mod-Alt-Shift-a", | ||
| icon: '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><rect x="4" y="5" width="16" height="14" rx="2.5" stroke="currentColor" stroke-width="1.7"/><path d="M8 10h8M8 14h5" stroke="currentColor" stroke-width="1.7" stroke-linecap="round"/><path d="m16.5 16 1.8 1.8 3.2-3.2" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"/></svg>' | ||
| }, | ||
| { | ||
| id: "approvalRequestReview", | ||
| label: "Request Review", | ||
| command: "requestApprovalReview", | ||
| shortcut: "Mod-Alt-Shift-r", | ||
| icon: '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><circle cx="11" cy="11" r="6.5" stroke="currentColor" stroke-width="1.7"/><path d="M11 8v3l2 2" stroke="currentColor" stroke-width="1.7" stroke-linecap="round"/><path d="M17.5 17.5 20 20" stroke="currentColor" stroke-width="1.7" stroke-linecap="round"/></svg>' | ||
| }, | ||
| { | ||
| id: "approvalApprove", | ||
| label: "Approve", | ||
| command: "approveDocument", | ||
| shortcut: "Mod-Alt-Shift-p", | ||
| icon: '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><path d="M5 12.5 9.5 17 19 7.5" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/><rect x="3.8" y="3.8" width="16.4" height="16.4" rx="3" stroke="currentColor" stroke-width="1.4"/></svg>' | ||
| }, | ||
| { | ||
| id: "approvalReopen", | ||
| label: "Reopen Draft", | ||
| command: "reopenDraft", | ||
| shortcut: "Mod-Alt-Shift-d", | ||
| icon: '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><path d="M8 8H4v4" stroke="currentColor" stroke-width="1.7" stroke-linecap="round"/><path d="M5 12a7 7 0 1 0 2-4.95" stroke="currentColor" stroke-width="1.7" stroke-linecap="round"/></svg>' | ||
| } | ||
| ] | ||
| } | ||
| ], | ||
| commands: { | ||
| approvalWorkflow: (o, a) => { | ||
| const r = x(a); | ||
| if (!r) return !1; | ||
| const n = p.get(r) || t; | ||
| return p.set(r, n), f(r, n), g = r, A(r), q(r), !0; | ||
| }, | ||
| toggleApprovalWorkflowPanel: (o, a) => { | ||
| const r = x(a); | ||
| if (!r) return !1; | ||
| const n = p.get(r) || t; | ||
| return p.set(r, n), f(r, n), g = r, de(r, typeof o == "boolean" ? o : void 0); | ||
| }, | ||
| requestApprovalReview: (o, a) => { | ||
| const r = x(a); | ||
| if (!r) return !1; | ||
| const n = p.get(r) || t; | ||
| p.set(r, n), f(r, n); | ||
| const l = E(r, "review", n, n.defaultActor); | ||
| return A(r), l; | ||
| }, | ||
| approveDocument: (o, a) => { | ||
| const r = x(a); | ||
| if (!r) return !1; | ||
| const n = p.get(r) || t; | ||
| p.set(r, n), f(r, n); | ||
| const l = typeof o == "object" && o ? String(o.author || "") : n.defaultActor, s = typeof o == "object" && o ? String(o.comment || "") : typeof o == "string" ? o : "", u = Q(r, n, l, s); | ||
| return u && A(r), u; | ||
| }, | ||
| reopenDraft: (o, a) => { | ||
| const r = x(a); | ||
| if (!r) return !1; | ||
| const n = p.get(r) || t; | ||
| p.set(r, n), f(r, n); | ||
| const l = E(r, "draft", n, n.defaultActor); | ||
| return l && A(r), l; | ||
| }, | ||
| addApprovalComment: (o, a) => { | ||
| const r = x(a); | ||
| if (!r) return !1; | ||
| const n = p.get(r) || t; | ||
| p.set(r, n), f(r, n); | ||
| const l = typeof o == "object" && o ? String(o.author || "") : n.defaultActor, s = typeof o == "object" && o ? String(o.message || "") : typeof o == "string" ? o : "", u = ce(r, s, l, n); | ||
| return u && A(r), u; | ||
| }, | ||
| setApprovalStatus: (o, a) => { | ||
| const r = x(a); | ||
| if (!r || !o) return !1; | ||
| const n = ne(o), l = p.get(r) || t; | ||
| p.set(r, l), f(r, l); | ||
| const s = E(r, n, l, l.defaultActor); | ||
| return s && A(r), s; | ||
| }, | ||
| setApprovalWorkflowOptions: (o, a) => { | ||
| const r = x(a); | ||
| if (!r || !o || typeof o != "object") return !1; | ||
| const n = p.get(r) || t, l = z({ | ||
| ...n, | ||
| ...o, | ||
| labels: { | ||
| ...n.labels, | ||
| ...o.labels || {} | ||
| }, | ||
| normalizeText: o.normalizeText || n.normalizeText | ||
| }); | ||
| p.set(r, l); | ||
| const s = f(r, l); | ||
| return G(r, s, l), !0; | ||
| }, | ||
| getApprovalWorkflowState: (o, a) => { | ||
| const r = x(a); | ||
| if (!r) return !1; | ||
| const n = p.get(r) || t; | ||
| p.set(r, n); | ||
| const l = f(r, n), s = se(l); | ||
| if (typeof o == "function") | ||
| try { | ||
| o(s); | ||
| } catch (u) { | ||
| } | ||
| return r.__approvalWorkflowState = s, r.dispatchEvent( | ||
| new CustomEvent("editora:approval-state", { | ||
| bubbles: !0, | ||
| detail: { | ||
| state: s | ||
| } | ||
| }) | ||
| ), !0; | ||
| } | ||
| }, | ||
| keymap: { | ||
| "Mod-Alt-Shift-a": "toggleApprovalWorkflowPanel", | ||
| "Mod-Alt-Shift-A": "toggleApprovalWorkflowPanel", | ||
| "Mod-Alt-Shift-r": "requestApprovalReview", | ||
| "Mod-Alt-Shift-R": "requestApprovalReview", | ||
| "Mod-Alt-Shift-p": "approveDocument", | ||
| "Mod-Alt-Shift-P": "approveDocument", | ||
| "Mod-Alt-Shift-d": "reopenDraft", | ||
| "Mod-Alt-Shift-D": "reopenDraft" | ||
| }, | ||
| init: function(a) { | ||
| _ += 1; | ||
| const r = this && typeof this.__pluginConfig == "object" ? z({ ...t, ...this.__pluginConfig }) : t; | ||
| Re(r); | ||
| const n = x( | ||
| a != null && a.editorElement ? { editorElement: a.editorElement } : void 0, | ||
| !1 | ||
| ); | ||
| n && (p.set(n, r), f(n, r), g = n, q(n)); | ||
| }, | ||
| destroy: () => { | ||
| _ = Math.max(0, _ - 1), !(_ > 0) && De(); | ||
| } | ||
| }; | ||
| }; | ||
| export { | ||
| qe as ApprovalWorkflowPlugin | ||
| }; | ||
| //# sourceMappingURL=ApprovalWorkflowPlugin.native-C3jtAYjG.mjs.map |
| const L = ".rte-content, .editora-content", fe = "[data-editora-editor], .rte-editor, .editora-editor, editora-editor", ye = "__editoraCommandEditorRoot", he = "rte-blocks-library-styles", u = "rte-blocks-library-panel", E = "blocks-library", $ = "blocksLibrary", T = ':is([data-theme="dark"], .dark, .editora-theme-dark, .rte-theme-dark)'; | ||
| const Ce = /* @__PURE__ */ new Set(["script", "style", "meta", "link", "object", "embed", "iframe"]), Pe = /^(https?:|mailto:|tel:|#|\/)/i, De = /^data:image\/(?:png|gif|jpeg|jpg|webp);base64,/i, Oe = { | ||
| panelTitle: "Blocks Library", | ||
| panelAriaLabel: "Blocks library panel", | ||
| searchLabel: "Search blocks", | ||
| searchPlaceholder: "Search by name, category, or keyword", | ||
| categoryLabel: "Category", | ||
| allCategoriesText: "All categories", | ||
| recentHeading: "Recent inserts", | ||
| insertText: "Insert Selected", | ||
| closeText: "Close", | ||
| noResultsText: "No matching blocks found.", | ||
| summaryPrefix: "Blocks", | ||
| loadingText: "Loading blocks...", | ||
| loadErrorText: "Unable to load blocks right now.", | ||
| readonlyMessage: "Editor is read-only. Block insertion is disabled.", | ||
| shortcutText: "Shortcuts: Ctrl/Cmd+Alt+Shift+B (panel), Ctrl/Cmd+Alt+Shift+L (insert last)", | ||
| helperText: "Use Arrow keys to move through blocks, Enter to insert, Esc to close.", | ||
| lastInsertedPrefix: "Last inserted", | ||
| resultsListLabel: "Block results" | ||
| }, b = /* @__PURE__ */ new WeakMap(), J = /* @__PURE__ */ new WeakMap(), w = /* @__PURE__ */ new WeakMap(), R = /* @__PURE__ */ new WeakMap(), O = /* @__PURE__ */ new WeakMap(), j = /* @__PURE__ */ new WeakMap(), W = /* @__PURE__ */ new WeakMap(), z = /* @__PURE__ */ new WeakMap(), q = /* @__PURE__ */ new WeakMap(), te = /* @__PURE__ */ new WeakMap(), x = /* @__PURE__ */ new Map(), U = /* @__PURE__ */ new WeakMap(), oe = /* @__PURE__ */ new Set(); | ||
| let X = 0, Ne = 0, ke = 0, A = null, y = null, _ = null, P = null, I = null, D = null; | ||
| function m(e) { | ||
| return e.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'"); | ||
| } | ||
| function Ke(e) { | ||
| return e.replace(/\u00A0/g, " ").replace(/\s+/g, " ").trim(); | ||
| } | ||
| function je(e) { | ||
| return e.toLowerCase().replace(/[^a-z0-9_-]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 80); | ||
| } | ||
| function ce(e) { | ||
| const t = e.trim(); | ||
| return t && (Pe.test(t) || De.test(t)) ? t : ""; | ||
| } | ||
| function xe(e) { | ||
| let t = e; | ||
| return Ce.forEach((r) => { | ||
| const o = new RegExp(`<${r}[\\s\\S]*?>[\\s\\S]*?<\\/${r}>`, "gi"), l = new RegExp(`<${r}\\b[^>]*\\/?>`, "gi"); | ||
| t = t.replace(o, "").replace(l, ""); | ||
| }), t = t.replace(/\son\w+=(\"[^\"]*\"|'[^']*'|[^\s>]+)/gi, "").replace(/\s(xmlns|xml:[^=\s>]+)\s*=\s*(\"[^\"]*\"|'[^']*'|[^\s>]+)/gi, "").replace( | ||
| /\s(href|src|xlink:href)\s*=\s*("|\')\s*(?:javascript:|vbscript:|data:text\/html)[^"']*\2/gi, | ||
| "" | ||
| ).replace(/\s(href|src|xlink:href)\s*=\s*(?:javascript:|vbscript:|data:text\/html)[^\s>]*/gi, "").replace( | ||
| /\s(href|src|xlink:href)\s*=\s*("([^"]*)"|'([^']*)')/gi, | ||
| (r, o, l, n, a) => { | ||
| const s = typeof n == "string" && n.length > 0 ? n : a || "", i = ce(s); | ||
| if (!i) return ""; | ||
| const c = l.startsWith('"') ? '"' : "'"; | ||
| return ` ${o}=${c}${i}${c}`; | ||
| } | ||
| ).replace(/\s(href|src|xlink:href)\s*=\s*([^\s>]+)/gi, (r, o, l) => { | ||
| const n = ce(l); | ||
| return n ? ` ${o}="${n}"` : ""; | ||
| }).replace(/\sstyle\s*=\s*("([^"]*)"|'([^']*)')/gi, (r, o, l, n) => { | ||
| const a = typeof l == "string" && l.length > 0 ? l : n || ""; | ||
| if (/expression\s*\(|javascript\s*:|vbscript\s*:|url\s*\(/i.test(a)) | ||
| return ""; | ||
| const s = o.startsWith('"') ? '"' : "'"; | ||
| return ` style=${s}${a}${s}`; | ||
| }).trim(), t; | ||
| } | ||
| function We(e) { | ||
| if (!e) return ""; | ||
| if (typeof document == "undefined") | ||
| return xe(e); | ||
| const t = document.createElement("template"); | ||
| t.innerHTML = e; | ||
| const r = t.content; | ||
| return !r || typeof r.querySelectorAll != "function" ? xe(e) : (Array.from(r.querySelectorAll("*")).forEach((l) => { | ||
| const n = l.tagName.toLowerCase(); | ||
| if (Ce.has(n)) { | ||
| l.remove(); | ||
| return; | ||
| } | ||
| Array.from(l.attributes).forEach((s) => { | ||
| const i = s.name.toLowerCase(), c = s.value; | ||
| if (i.startsWith("on")) { | ||
| l.removeAttribute(s.name); | ||
| return; | ||
| } | ||
| if (i === "style") { | ||
| /expression\s*\(|javascript\s*:|vbscript\s*:|url\s*\(/i.test(c) && l.removeAttribute(s.name); | ||
| return; | ||
| } | ||
| if (i === "href" || i === "src" || i === "xlink:href") { | ||
| const d = ce(c); | ||
| if (!d) { | ||
| l.removeAttribute(s.name); | ||
| return; | ||
| } | ||
| d !== c && l.setAttribute(s.name, d); | ||
| } | ||
| }); | ||
| }), t.innerHTML.trim()); | ||
| } | ||
| function ne(e) { | ||
| return e.trim().toLowerCase(); | ||
| } | ||
| function Fe(e) { | ||
| if (!e) return ""; | ||
| if (typeof document == "undefined") | ||
| return e.replace(/<[^>]*>/g, " ").replace(/\s+/g, " ").trim(); | ||
| const t = document.createElement("template"); | ||
| t.innerHTML = e; | ||
| const r = t.content; | ||
| return !r || typeof r.textContent != "string" ? e.replace(/<[^>]*>/g, " ").replace(/\s+/g, " ").trim() : r.textContent.replace(/\s+/g, " ").trim(); | ||
| } | ||
| function Be(e, t) { | ||
| if (!Array.isArray(e) || e.length === 0) return []; | ||
| const r = /* @__PURE__ */ new Set(), o = []; | ||
| return e.forEach((l) => { | ||
| const n = t.normalizeText(l.label || ""), a = t.sanitizeBlockHtml(l.html || "", l).trim(); | ||
| if (!n || !a) return; | ||
| const s = t.normalizeText(l.category || "General") || "General", i = ne(s); | ||
| let d = je(t.normalizeText(l.id || n)) || `block-${ke++}`; | ||
| for (; r.has(d); ) | ||
| d = `${d}-${ke++}`; | ||
| r.add(d); | ||
| const f = (l.tags || []).map((H) => t.normalizeText(H)).filter(Boolean), g = (l.keywords || []).map((H) => t.normalizeText(H)).filter(Boolean), h = t.normalizeText(l.description || ""), C = Fe(a), V = [n, h, s, ...f, ...g, C].join(" ").toLowerCase(); | ||
| o.push({ | ||
| id: d, | ||
| label: n, | ||
| html: a, | ||
| description: h, | ||
| category: s, | ||
| categoryKey: i, | ||
| tags: f, | ||
| keywords: g, | ||
| previewText: C, | ||
| searchBlob: V | ||
| }); | ||
| }), o; | ||
| } | ||
| function Q(e = {}) { | ||
| var l, n, a, s; | ||
| const t = e.normalizeText || Ke, r = e.sanitizeBlockHtml || We, o = { | ||
| blocks: [], | ||
| defaultCategory: t(e.defaultCategory || ""), | ||
| maxResults: Math.max(4, Math.min(300, Number((l = e.maxResults) != null ? l : 80))), | ||
| maxRecentBlocks: Math.max(1, Math.min(20, Number((n = e.maxRecentBlocks) != null ? n : 6))), | ||
| debounceMs: Math.max(0, Math.min(700, Number((a = e.debounceMs) != null ? a : 90))), | ||
| cacheTtlMs: Math.max(0, Number((s = e.cacheTtlMs) != null ? s : 6e4)), | ||
| labels: { | ||
| ...Oe, | ||
| ...e.labels || {} | ||
| }, | ||
| normalizeText: t, | ||
| sanitizeBlockHtml: r, | ||
| getBlocks: typeof e.getBlocks == "function" ? e.getBlocks : void 0 | ||
| }; | ||
| return o.blocks = Be(e.blocks, o), o; | ||
| } | ||
| function Ge(e) { | ||
| return { | ||
| blocks: e.blocks.map((t) => ({ | ||
| id: t.id, | ||
| label: t.label, | ||
| html: t.html, | ||
| description: t.description || void 0, | ||
| category: t.category || void 0, | ||
| tags: t.tags.length ? [...t.tags] : void 0, | ||
| keywords: t.keywords.length ? [...t.keywords] : void 0 | ||
| })), | ||
| defaultCategory: e.defaultCategory, | ||
| maxResults: e.maxResults, | ||
| maxRecentBlocks: e.maxRecentBlocks, | ||
| debounceMs: e.debounceMs, | ||
| cacheTtlMs: e.cacheTtlMs, | ||
| labels: { ...e.labels }, | ||
| normalizeText: e.normalizeText, | ||
| sanitizeBlockHtml: e.sanitizeBlockHtml, | ||
| getBlocks: e.getBlocks | ||
| }; | ||
| } | ||
| function le(e) { | ||
| return e.closest(fe) || e; | ||
| } | ||
| function G(e) { | ||
| if (!e) return null; | ||
| if (e.matches(L)) return e; | ||
| const t = e.querySelector(L); | ||
| return t instanceof HTMLElement ? t : null; | ||
| } | ||
| function Ue() { | ||
| if (typeof window == "undefined") return null; | ||
| const e = window[ye]; | ||
| if (!(e instanceof HTMLElement)) return null; | ||
| window[ye] = null; | ||
| const t = G(e); | ||
| if (t) return t; | ||
| const r = e.closest(fe); | ||
| if (r) { | ||
| const l = G(r); | ||
| if (l) return l; | ||
| } | ||
| const o = e.closest(L); | ||
| return o instanceof HTMLElement ? o : null; | ||
| } | ||
| function Ve(e) { | ||
| const t = e.closest("[data-editora-editor]"); | ||
| if (t && G(t) === e) | ||
| return t; | ||
| let r = e; | ||
| for (; r; ) { | ||
| if (r.matches(fe) && (r === e || G(r) === e)) | ||
| return r; | ||
| r = r.parentElement; | ||
| } | ||
| return le(e); | ||
| } | ||
| function $e(e) { | ||
| return e ? e.nodeType === Node.ELEMENT_NODE ? e : e.parentElement : null; | ||
| } | ||
| function ee() { | ||
| Array.from(oe).forEach((t) => { | ||
| t.isConnected || ge(t); | ||
| }); | ||
| } | ||
| function S(e, t = !0, r = !0) { | ||
| if (ee(), (e == null ? void 0 : e.contentElement) instanceof HTMLElement) return e.contentElement; | ||
| if ((e == null ? void 0 : e.editorElement) instanceof HTMLElement) { | ||
| const a = G(e.editorElement); | ||
| if (a) return a; | ||
| } | ||
| const o = Ue(); | ||
| if (o) return o; | ||
| const l = window.getSelection(); | ||
| if (l && l.rangeCount > 0) { | ||
| const a = $e(l.getRangeAt(0).startContainer), s = a == null ? void 0 : a.closest(L); | ||
| if (s) return s; | ||
| } | ||
| const n = document.activeElement; | ||
| if (n) { | ||
| if (n.matches(L)) return n; | ||
| const a = n.closest(L); | ||
| if (a) return a; | ||
| } | ||
| if (r) { | ||
| if (y && y.isConnected) return y; | ||
| y && !y.isConnected && (y = null); | ||
| } | ||
| return t ? document.querySelector(L) : null; | ||
| } | ||
| function Ye(e) { | ||
| const t = e.target; | ||
| if (t) { | ||
| const o = t.closest(L); | ||
| if (o) return o; | ||
| } | ||
| const r = window.getSelection(); | ||
| if (r && r.rangeCount > 0) { | ||
| const o = $e(r.getRangeAt(0).startContainer), l = o == null ? void 0 : o.closest(L); | ||
| if (l) return l; | ||
| } | ||
| return null; | ||
| } | ||
| function Z(e) { | ||
| return e ? (e.getAttribute("data-theme") || e.getAttribute("theme") || "").toLowerCase() === "dark" ? !0 : e.classList.contains("dark") || e.classList.contains("editora-theme-dark") || e.classList.contains("rte-theme-dark") : !1; | ||
| } | ||
| function Xe(e) { | ||
| const t = le(e); | ||
| if (Z(t)) return !0; | ||
| const r = t.closest("[data-theme], [theme], .dark, .editora-theme-dark, .rte-theme-dark"); | ||
| return Z(r) ? !0 : Z(document.documentElement) || Z(document.body); | ||
| } | ||
| function re(e, t) { | ||
| e.classList.remove("rte-blocks-library-theme-dark"), Xe(t) && e.classList.add("rte-blocks-library-theme-dark"); | ||
| } | ||
| function Te(e) { | ||
| return e.getAttribute("contenteditable") === "false" || e.getAttribute("data-readonly") === "true"; | ||
| } | ||
| function we(e, t, r) { | ||
| const o = Ve(e); | ||
| Array.from( | ||
| o.querySelectorAll( | ||
| `.rte-toolbar-button[data-command="${t}"], .editora-toolbar-button[data-command="${t}"]` | ||
| ) | ||
| ).forEach((n) => { | ||
| n.classList.toggle("active", r), n.setAttribute("data-active", r ? "true" : "false"), n.setAttribute("aria-pressed", r ? "true" : "false"); | ||
| }); | ||
| } | ||
| function Ee(e, t) { | ||
| const r = e.querySelector(".rte-blocks-library-live"); | ||
| r && (r.textContent = t); | ||
| } | ||
| function se(e) { | ||
| const t = Re(e); | ||
| if (t) | ||
| try { | ||
| q.set(e, t.cloneRange()); | ||
| } catch (r) { | ||
| } | ||
| } | ||
| function Se(e) { | ||
| const t = q.get(e); | ||
| if (!t) return null; | ||
| if (!e.isConnected) | ||
| return q.delete(e), null; | ||
| try { | ||
| const r = t.cloneRange(); | ||
| return e.contains(r.commonAncestorContainer) ? r : (q.delete(e), null); | ||
| } catch (r) { | ||
| return q.delete(e), null; | ||
| } | ||
| } | ||
| function Ze(e) { | ||
| const t = Se(e); | ||
| return t ? (He(e, t), !0) : !1; | ||
| } | ||
| function Je(e) { | ||
| if (te.has(e)) return; | ||
| const t = () => { | ||
| const r = window.getSelection(); | ||
| if (!r || r.rangeCount === 0) return; | ||
| const o = r.getRangeAt(0); | ||
| e.contains(o.commonAncestorContainer) && se(e); | ||
| }; | ||
| e.addEventListener("keyup", t), e.addEventListener("mouseup", t), e.addEventListener("touchend", t), te.set(e, t); | ||
| } | ||
| function Qe(e) { | ||
| const t = te.get(e); | ||
| t && (e.removeEventListener("keyup", t), e.removeEventListener("mouseup", t), e.removeEventListener("touchend", t), te.delete(e)); | ||
| } | ||
| function k(e, t) { | ||
| b.has(e) || b.set(e, t), R.has(e) || (R.set(e, t.blocks), O.set(e, Date.now())); | ||
| let r = w.get(e); | ||
| return r || (r = { | ||
| query: "", | ||
| category: t.defaultCategory ? ne(t.defaultCategory) : "all", | ||
| selectedBlockId: null, | ||
| recentBlockIds: [], | ||
| lastInsertedBlockId: null, | ||
| loading: !1, | ||
| loadError: null, | ||
| totalMatches: 0, | ||
| visibleMatches: 0, | ||
| filterCache: /* @__PURE__ */ new Map(), | ||
| debounceTimer: null | ||
| }, w.set(e, r)), oe.add(e), Je(e), r; | ||
| } | ||
| function Me(e) { | ||
| const t = w.get(e); | ||
| !t || t.debounceTimer === null || (window.clearTimeout(t.debounceTimer), t.debounceTimer = null); | ||
| } | ||
| function ge(e) { | ||
| var r; | ||
| Me(e), Qe(e), q.delete(e); | ||
| const t = W.get(e); | ||
| t && (t.abort(), W.delete(e)), j.delete(e), z.delete(e), (r = x.get(e)) == null || r.remove(), x.delete(e), U.delete(e), b.delete(e), J.delete(e), w.delete(e), R.delete(e), O.delete(e), oe.delete(e), y === e && (y = null); | ||
| } | ||
| function et(e) { | ||
| var t, r, o, l; | ||
| for (let n = 0; n < e.length; n += 1) { | ||
| const a = e[n]; | ||
| if (!(a.type !== "childList" || a.removedNodes.length === 0)) | ||
| for (let s = 0; s < a.removedNodes.length; s += 1) { | ||
| const i = a.removedNodes[s]; | ||
| if (i.nodeType !== Node.ELEMENT_NODE) continue; | ||
| const c = i; | ||
| if ((t = c.matches) != null && t.call(c, L) || (r = c.matches) != null && r.call(c, `.${u}`) || (o = c.querySelector) != null && o.call(c, L) || (l = c.querySelector) != null && l.call(c, `.${u}`)) | ||
| return !0; | ||
| } | ||
| } | ||
| return !1; | ||
| } | ||
| function pe(e) { | ||
| return U.get(e) === !0; | ||
| } | ||
| function de(e, t) { | ||
| if (!t.classList.contains("show")) return; | ||
| const r = le(e).getBoundingClientRect(), o = Math.min(window.innerWidth - 20, 420), l = Math.max(10, window.innerWidth - o - 10), n = Math.min(Math.max(10, r.right - o), l), a = Math.max(10, Math.min(window.innerHeight - 10, r.top + 12)); | ||
| t.style.width = `${o}px`, t.style.left = `${n}px`, t.style.top = `${a}px`, t.style.maxHeight = `${Math.max(260, window.innerHeight - 20)}px`; | ||
| } | ||
| function ae(e) { | ||
| var t; | ||
| return R.get(e) || ((t = b.get(e)) == null ? void 0 : t.blocks) || []; | ||
| } | ||
| function tt(e, t) { | ||
| const r = /* @__PURE__ */ new Map(); | ||
| ae(e).forEach((l) => { | ||
| r.has(l.categoryKey) || r.set(l.categoryKey, l.category); | ||
| }); | ||
| const o = Array.from(r.entries()).sort((l, n) => l[1].localeCompare(n[1])).map(([l, n]) => ({ value: l, label: n })); | ||
| return [{ value: "all", label: t.labels.allCategoriesText }, ...o]; | ||
| } | ||
| function Ae(e, t) { | ||
| const r = k(e, t), o = ae(e), l = r.query.trim().toLowerCase(), n = r.category || "all", a = `${l}|${n}|${t.maxResults}`, s = r.filterCache.get(a); | ||
| if (s) { | ||
| const d = new Map(o.map((g) => [g.id, g])), f = s.ids.map((g) => d.get(g)).filter(Boolean); | ||
| return r.totalMatches = s.total, r.visibleMatches = f.length, f; | ||
| } | ||
| const i = []; | ||
| let c = 0; | ||
| for (let d = 0; d < o.length; d += 1) { | ||
| const f = o[d]; | ||
| n !== "all" && f.categoryKey !== n || l && !f.searchBlob.includes(l) || (c += 1, i.length < t.maxResults && i.push(f)); | ||
| } | ||
| if (r.totalMatches = c, r.visibleMatches = i.length, r.filterCache.set(a, { | ||
| ids: i.map((d) => d.id), | ||
| total: c | ||
| }), r.filterCache.size > 80) { | ||
| const d = r.filterCache.keys().next().value; | ||
| typeof d == "string" && r.filterCache.delete(d); | ||
| } | ||
| return i; | ||
| } | ||
| function rt(e, t) { | ||
| const r = w.get(e); | ||
| if (!r) return; | ||
| if (t.length === 0) { | ||
| r.selectedBlockId = null; | ||
| return; | ||
| } | ||
| t.some((l) => l.id === r.selectedBlockId) || (r.selectedBlockId = t[0].id); | ||
| } | ||
| function N(e) { | ||
| const t = w.get(e); | ||
| we(e, "toggleBlocksLibraryPanel", pe(e)), we(e, "insertLastBlockSnippet", !!(t != null && t.lastInsertedBlockId)); | ||
| } | ||
| function v(e) { | ||
| const t = x.get(e), r = b.get(e) || A, o = w.get(e); | ||
| if (!t || !r || !o) return; | ||
| re(t, e); | ||
| const l = t.querySelector(".rte-blocks-library-title"); | ||
| l && (l.textContent = r.labels.panelTitle); | ||
| const n = t.querySelector('[data-action="close"]'); | ||
| n && (n.setAttribute("aria-label", r.labels.closeText), n.textContent = "✕"); | ||
| const a = t.querySelector(".rte-blocks-library-search-label"); | ||
| a && (a.textContent = r.labels.searchLabel); | ||
| const s = t.querySelector('[data-field="query"]'); | ||
| s && (s.setAttribute("placeholder", r.labels.searchPlaceholder), s.value !== o.query && (s.value = o.query)); | ||
| const i = t.querySelector(".rte-blocks-library-category-label"); | ||
| i && (i.textContent = r.labels.categoryLabel); | ||
| const c = t.querySelector('[data-field="category"]'); | ||
| if (c) { | ||
| const B = tt(e, r); | ||
| c.innerHTML = B.map((p) => `<option value="${m(p.value)}">${m(p.label)}</option>`).join(""), B.some((p) => p.value === o.category) || (o.category = "all"), c.value = o.category; | ||
| } | ||
| const d = t.querySelector(".rte-blocks-library-helper"); | ||
| d && (d.textContent = r.labels.helperText); | ||
| const f = t.querySelector('.rte-blocks-library-list[role="listbox"]'); | ||
| f && f.setAttribute("aria-label", r.labels.resultsListLabel); | ||
| const g = t.querySelector(".rte-blocks-library-shortcut"); | ||
| g && (g.textContent = r.labels.shortcutText); | ||
| const h = t.querySelector('[data-action="insert-selected"]'); | ||
| if (h) { | ||
| h.textContent = r.labels.insertText; | ||
| const B = !Te(e) && !!o.selectedBlockId; | ||
| h.disabled = !B, h.setAttribute("aria-disabled", B ? "false" : "true"); | ||
| } | ||
| const C = t.querySelector(".rte-blocks-library-empty"), V = t.querySelector(".rte-blocks-library-list"), H = Ae(e, r); | ||
| rt(e, H); | ||
| const Y = t.querySelector(".rte-blocks-library-status"); | ||
| if (Y && (o.loading ? Y.textContent = r.labels.loadingText : o.loadError ? Y.textContent = o.loadError : Y.textContent = `${r.labels.summaryPrefix}: ${o.visibleMatches}/${o.totalMatches}`), V) { | ||
| const B = new Set(o.recentBlockIds); | ||
| V.innerHTML = H.map((p) => { | ||
| const ie = o.selectedBlockId === p.id, qe = p.tags.length ? ` • ${p.tags.join(", ")}` : "", _e = B.has(p.id), me = p.previewText.slice(0, 180); | ||
| return ` | ||
| <li class="rte-blocks-library-item-wrapper" role="presentation"> | ||
| <button | ||
| type="button" | ||
| class="rte-blocks-library-item${ie ? " active" : ""}" | ||
| data-block-id="${m(p.id)}" | ||
| role="option" | ||
| aria-selected="${ie ? "true" : "false"}" | ||
| aria-label="${m(p.label)}" | ||
| tabindex="${ie ? "0" : "-1"}" | ||
| > | ||
| <span class="rte-blocks-library-item-head"> | ||
| <span class="rte-blocks-library-item-label">${m(p.label)}</span> | ||
| ${_e ? `<span class="rte-blocks-library-recent-pill">${m(r.labels.recentHeading)}</span>` : ""} | ||
| </span> | ||
| <span class="rte-blocks-library-item-meta">${m(p.category)}${m(qe)}</span> | ||
| ${p.description ? `<span class="rte-blocks-library-item-description">${m(p.description)}</span>` : ""} | ||
| ${me ? `<span class="rte-blocks-library-item-preview">${m(me)}</span>` : ""} | ||
| </button> | ||
| </li> | ||
| `; | ||
| }).join(""); | ||
| } | ||
| C && (C.hidden = H.length > 0, C.textContent = r.labels.noResultsText); | ||
| const K = t.querySelector(".rte-blocks-library-last-inserted"); | ||
| if (K) | ||
| if (o.lastInsertedBlockId) { | ||
| const B = ae(e).find((p) => p.id === o.lastInsertedBlockId); | ||
| B ? (K.hidden = !1, K.textContent = `${r.labels.lastInsertedPrefix}: ${B.label}`) : K.hidden = !0; | ||
| } else | ||
| K.hidden = !0; | ||
| t.setAttribute("aria-label", r.labels.panelAriaLabel); | ||
| } | ||
| function M(e, t = !1) { | ||
| const r = x.get(e); | ||
| r && (r.classList.remove("show"), U.set(e, !1), N(e), t && (e.focus({ preventScroll: !0 }), Ze(e))); | ||
| } | ||
| function ot(e) { | ||
| const t = e.querySelector(".rte-blocks-library-item.active"); | ||
| t == null || t.focus(); | ||
| } | ||
| function Le(e, t) { | ||
| const r = b.get(e) || A; | ||
| if (!r) return; | ||
| const o = w.get(e); | ||
| if (!o) return; | ||
| const l = Ae(e, r); | ||
| if (l.length === 0) return; | ||
| const a = (Math.max( | ||
| 0, | ||
| l.findIndex((i) => i.id === o.selectedBlockId) | ||
| ) + t + l.length) % l.length; | ||
| o.selectedBlockId = l[a].id, v(e); | ||
| const s = x.get(e); | ||
| s && ot(s); | ||
| } | ||
| function ue(e) { | ||
| const t = it(e); | ||
| se(e), x.forEach((o, l) => { | ||
| l !== e && M(l, !1); | ||
| }), t.classList.add("show"), U.set(e, !0), v(e), de(e, t), N(e); | ||
| const r = t.querySelector('[data-field="query"]'); | ||
| r == null || r.focus(), be(e, !1); | ||
| } | ||
| function Ie(e, t) { | ||
| const r = pe(e); | ||
| return (typeof t == "boolean" ? t : !r) ? ue(e) : M(e, !1), !0; | ||
| } | ||
| function Re(e) { | ||
| const t = window.getSelection(); | ||
| if (!t || t.rangeCount === 0) return null; | ||
| const r = t.getRangeAt(0); | ||
| return e.contains(r.commonAncestorContainer) ? r : null; | ||
| } | ||
| function He(e, t) { | ||
| if (!e.isConnected) return; | ||
| const r = window.getSelection(); | ||
| r && (r.removeAllRanges(), r.addRange(t)); | ||
| } | ||
| function ve(e, t, r) { | ||
| const o = t.cloneRange(); | ||
| if (!e.contains(o.commonAncestorContainer)) return !1; | ||
| o.deleteContents(); | ||
| const l = document.createElement("template"); | ||
| l.innerHTML = r; | ||
| const n = l.content; | ||
| if (!n) return !1; | ||
| const a = n.lastChild; | ||
| if (o.insertNode(n), a) { | ||
| const s = document.createRange(); | ||
| s.setStartAfter(a), s.collapse(!0), He(e, s); | ||
| } | ||
| return se(e), !0; | ||
| } | ||
| function nt(e, t) { | ||
| e.focus({ preventScroll: !0 }); | ||
| const r = Se(e); | ||
| if (r && ve(e, r, t)) | ||
| return !0; | ||
| try { | ||
| if (document.execCommand("insertHTML", !1, t)) | ||
| return se(e), !0; | ||
| } catch (l) { | ||
| } | ||
| const o = Re(e); | ||
| return o ? ve(e, o, t) : !1; | ||
| } | ||
| function lt(e, t) { | ||
| if (t === e.innerHTML) return; | ||
| const r = window.execEditorCommand || window.executeEditorCommand; | ||
| if (typeof r == "function") | ||
| try { | ||
| r("recordDomTransaction", e, t, e.innerHTML); | ||
| } catch (o) { | ||
| } | ||
| } | ||
| function st(e) { | ||
| e.dispatchEvent(new Event("input", { bubbles: !0 })); | ||
| } | ||
| function F(e, t) { | ||
| const r = b.get(e) || A; | ||
| if (!r) return !1; | ||
| const o = k(e, r), l = x.get(e); | ||
| if (Te(e)) | ||
| return l && Ee(l, r.labels.readonlyMessage), !1; | ||
| const n = ae(e).find((i) => i.id === t); | ||
| if (!n) return !1; | ||
| const a = e.innerHTML; | ||
| return nt(e, n.html) ? (o.lastInsertedBlockId = n.id, o.selectedBlockId = n.id, o.recentBlockIds = [n.id, ...o.recentBlockIds.filter((i) => i !== n.id)].slice( | ||
| 0, | ||
| r.maxRecentBlocks | ||
| ), lt(e, a), st(e), N(e), e.dispatchEvent( | ||
| new CustomEvent("editora:blocks-library-insert", { | ||
| bubbles: !0, | ||
| detail: { | ||
| blockId: n.id, | ||
| label: n.label, | ||
| category: n.category | ||
| } | ||
| }) | ||
| ), v(e), l && Ee(l, `${r.labels.lastInsertedPrefix}: ${n.label}`), !0) : !1; | ||
| } | ||
| function ze(e) { | ||
| const t = w.get(e); | ||
| return t != null && t.lastInsertedBlockId ? F(e, t.lastInsertedBlockId) : !1; | ||
| } | ||
| function at(e) { | ||
| const t = b.get(e) || A; | ||
| if (!t) return; | ||
| const r = w.get(e); | ||
| if (!r) return; | ||
| Me(e); | ||
| const o = () => { | ||
| r.debounceTimer = null, r.filterCache.clear(), v(e); | ||
| }; | ||
| if (t.debounceMs <= 0) { | ||
| o(); | ||
| return; | ||
| } | ||
| r.debounceTimer = window.setTimeout(o, t.debounceMs); | ||
| } | ||
| function it(e) { | ||
| const t = x.get(e); | ||
| if (t) return t; | ||
| const r = b.get(e) || A || Q(), o = k(e, r), l = `rte-blocks-library-panel-${Ne++}`, n = `${l}-query`, a = `${l}-category`, s = document.createElement("section"); | ||
| return s.className = u, s.id = l, s.setAttribute("role", "dialog"), s.setAttribute("aria-modal", "false"), s.setAttribute("aria-label", r.labels.panelAriaLabel), s.innerHTML = ` | ||
| <header class="rte-blocks-library-header"> | ||
| <h2 class="rte-blocks-library-title">${m(r.labels.panelTitle)}</h2> | ||
| <button type="button" class="rte-blocks-library-icon-btn" data-action="close" aria-label="${m(r.labels.closeText)}">✕</button> | ||
| </header> | ||
| <div class="rte-blocks-library-body"> | ||
| <label class="rte-blocks-library-search-label" for="${m(n)}"></label> | ||
| <input id="${m(n)}" class="rte-blocks-library-input" type="text" data-field="query" autocomplete="off" /> | ||
| <label class="rte-blocks-library-category-label" for="${m(a)}"></label> | ||
| <select id="${m(a)}" class="rte-blocks-library-select" data-field="category"></select> | ||
| <p class="rte-blocks-library-status" aria-live="polite"></p> | ||
| <p class="rte-blocks-library-helper"></p> | ||
| <p class="rte-blocks-library-last-inserted" hidden></p> | ||
| <div class="rte-blocks-library-list-wrap"> | ||
| <ul class="rte-blocks-library-list" role="listbox" aria-label="${m(r.labels.resultsListLabel)}"></ul> | ||
| <p class="rte-blocks-library-empty" hidden></p> | ||
| </div> | ||
| <div class="rte-blocks-library-actions"> | ||
| <button type="button" class="rte-blocks-library-btn rte-blocks-library-btn-primary" data-action="insert-selected"></button> | ||
| </div> | ||
| <p class="rte-blocks-library-shortcut"></p> | ||
| </div> | ||
| <div class="rte-blocks-library-live" aria-live="polite" aria-atomic="true"></div> | ||
| `, s.addEventListener("click", (i) => { | ||
| const c = i.target, d = c == null ? void 0 : c.closest("[data-action]"); | ||
| if (d) { | ||
| const h = d.getAttribute("data-action"); | ||
| if (h === "close") { | ||
| M(e, !0); | ||
| return; | ||
| } | ||
| if (h === "insert-selected") { | ||
| if (!o.selectedBlockId) return; | ||
| F(e, o.selectedBlockId) && M(e, !0); | ||
| } | ||
| return; | ||
| } | ||
| const f = c == null ? void 0 : c.closest("[data-block-id]"); | ||
| if (!f) return; | ||
| const g = f.getAttribute("data-block-id"); | ||
| g && (o.selectedBlockId = g, v(e), i.detail >= 2 && F(e, g) && M(e, !0)); | ||
| }), s.addEventListener("input", (i) => { | ||
| const c = i.target; | ||
| !(c instanceof HTMLInputElement) || c.getAttribute("data-field") !== "query" || (o.query = r.normalizeText(c.value).toLowerCase(), o.filterCache.clear(), at(e)); | ||
| }), s.addEventListener("change", (i) => { | ||
| const c = i.target; | ||
| !(c instanceof HTMLSelectElement) || c.getAttribute("data-field") !== "category" || (o.category = ne(c.value || "all") || "all", o.filterCache.clear(), v(e)); | ||
| }), s.addEventListener("keydown", (i) => { | ||
| if (i.key === "Escape") { | ||
| i.preventDefault(), M(e, !0); | ||
| return; | ||
| } | ||
| if (i.key === "ArrowDown") { | ||
| i.preventDefault(), Le(e, 1); | ||
| return; | ||
| } | ||
| if (i.key === "ArrowUp") { | ||
| i.preventDefault(), Le(e, -1); | ||
| return; | ||
| } | ||
| if (i.key === "Enter") { | ||
| const c = i.target; | ||
| if (!(c == null ? void 0 : c.matches('[data-field="query"], [data-field="category"], [data-block-id]')) || !o.selectedBlockId) return; | ||
| i.preventDefault(), F(e, o.selectedBlockId) && M(e, !0); | ||
| } | ||
| }), re(s, e), document.body.appendChild(s), x.set(e, s), U.set(e, !1), v(e), s; | ||
| } | ||
| function ct(e) { | ||
| const t = w.get(e); | ||
| return { | ||
| query: (t == null ? void 0 : t.query) || "", | ||
| category: (t == null ? void 0 : t.category) || "all", | ||
| selectedBlockId: (t == null ? void 0 : t.selectedBlockId) || null, | ||
| totalMatches: (t == null ? void 0 : t.totalMatches) || 0, | ||
| visibleMatches: (t == null ? void 0 : t.visibleMatches) || 0, | ||
| recentBlockIds: t != null && t.recentBlockIds ? [...t.recentBlockIds] : [], | ||
| lastInsertedBlockId: (t == null ? void 0 : t.lastInsertedBlockId) || null, | ||
| loading: (t == null ? void 0 : t.loading) === !0, | ||
| loadError: (t == null ? void 0 : t.loadError) || null | ||
| }; | ||
| } | ||
| async function be(e, t) { | ||
| const r = b.get(e) || A; | ||
| if (!r || typeof r.getBlocks != "function") return; | ||
| const o = k(e, r), l = O.get(e) || 0; | ||
| if (!t && r.cacheTtlMs > 0 && Date.now() - l < r.cacheTtlMs) | ||
| return; | ||
| const n = j.get(e); | ||
| if (n && !t) | ||
| return n; | ||
| const a = W.get(e); | ||
| a && a.abort(), t && n && j.delete(e); | ||
| const s = new AbortController(); | ||
| W.set(e, s); | ||
| const i = (z.get(e) || 0) + 1; | ||
| z.set(e, i), o.loading = !0, o.loadError = null, v(e); | ||
| const c = Promise.resolve().then(async () => { | ||
| var C; | ||
| const d = { | ||
| editor: e, | ||
| editorRoot: le(e), | ||
| signal: s.signal | ||
| }, f = await ((C = r.getBlocks) == null ? void 0 : C.call(r, d)); | ||
| if (s.signal.aborted || z.get(e) !== i) return; | ||
| const g = Be(f || [], r); | ||
| R.set(e, g), O.set(e, Date.now()); | ||
| const h = w.get(e); | ||
| h && (h.loading = !1, h.loadError = null, h.filterCache.clear()); | ||
| }).catch(() => { | ||
| if (s.signal.aborted || z.get(e) !== i) return; | ||
| const d = w.get(e); | ||
| d && (d.loading = !1, d.loadError = r.labels.loadErrorText); | ||
| }).finally(() => { | ||
| z.get(e) === i && (j.delete(e), W.delete(e)), v(e); | ||
| }); | ||
| return j.set(e, c), c; | ||
| } | ||
| function dt(e) { | ||
| const t = e.key.toLowerCase(); | ||
| return (e.metaKey || e.ctrlKey) && e.altKey && e.shiftKey && t === "b"; | ||
| } | ||
| function ut(e) { | ||
| const t = e.key.toLowerCase(); | ||
| return (e.metaKey || e.ctrlKey) && e.altKey && e.shiftKey && t === "l"; | ||
| } | ||
| function bt(e) { | ||
| A = e, _ || (_ = (t) => { | ||
| ee(); | ||
| const r = t.target, o = r == null ? void 0 : r.closest(L); | ||
| if (!o) return; | ||
| const l = b.get(o) || e; | ||
| k(o, l), b.set(o, l), y = o, N(o); | ||
| const n = x.get(o); | ||
| n && (re(n, o), de(o, n), v(o)); | ||
| }, document.addEventListener("focusin", _, !0)), P || (P = (t) => { | ||
| if (t.defaultPrevented) return; | ||
| const r = `.${u} input, .${u} textarea, .${u} select`, o = t.target; | ||
| if (o != null && o.closest(r)) { | ||
| if (t.key === "Escape") { | ||
| const a = o.closest(`.${u}`), s = Array.from(x.entries()).find(([, i]) => i === a); | ||
| s && (t.preventDefault(), M(s[0], !0)); | ||
| } | ||
| return; | ||
| } | ||
| const l = Ye(t); | ||
| if (!l) return; | ||
| const n = b.get(l) || A || e; | ||
| if (k(l, n), b.set(l, n), y = l, t.key === "Escape" && pe(l)) { | ||
| t.preventDefault(), M(l, !0); | ||
| return; | ||
| } | ||
| if (dt(t)) { | ||
| t.preventDefault(), t.stopPropagation(), Ie(l); | ||
| return; | ||
| } | ||
| ut(t) && (t.preventDefault(), t.stopPropagation(), ze(l)); | ||
| }, document.addEventListener("keydown", P, !0)), I || (I = () => { | ||
| ee(), x.forEach((t, r) => { | ||
| !r.isConnected || !t.isConnected || (re(t, r), de(r, t)); | ||
| }); | ||
| }, window.addEventListener("scroll", I, !0), window.addEventListener("resize", I)), !D && typeof MutationObserver != "undefined" && document.body && (D = new MutationObserver((t) => { | ||
| et(t) && ee(); | ||
| }), D.observe(document.body, { | ||
| childList: !0, | ||
| subtree: !0 | ||
| })); | ||
| } | ||
| function ft() { | ||
| _ && (document.removeEventListener("focusin", _, !0), _ = null), P && (document.removeEventListener("keydown", P, !0), P = null), I && (window.removeEventListener("scroll", I, !0), window.removeEventListener("resize", I), I = null), D && (D.disconnect(), D = null), x.forEach((t) => t.remove()), x.clear(), Array.from(oe).forEach((t) => ge(t)), A = null, y = null; | ||
| } | ||
| function gt() { | ||
| if (typeof document == "undefined" || document.getElementById(he)) return; | ||
| const e = document.createElement("style"); | ||
| e.id = he, e.textContent = ` | ||
| .rte-toolbar-group-items.${E}, | ||
| .editora-toolbar-group-items.${E}, | ||
| .rte-toolbar-group-items.${$}, | ||
| .editora-toolbar-group-items.${$} { | ||
| display: flex; | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 4px; | ||
| background: #ffffff; | ||
| } | ||
| .rte-toolbar-group-items.${E} .rte-toolbar-button, | ||
| .editora-toolbar-group-items.${E} .editora-toolbar-button, | ||
| .rte-toolbar-group-items.${$} .rte-toolbar-button, | ||
| .editora-toolbar-group-items.${$} .editora-toolbar-button { | ||
| border: none; | ||
| border-right: 1px solid #cbd5e1; | ||
| border-radius: 0; | ||
| } | ||
| .rte-toolbar-group-items.${E} .rte-toolbar-item:last-child .rte-toolbar-button, | ||
| .editora-toolbar-group-items.${E} .editora-toolbar-item:last-child .editora-toolbar-button, | ||
| .rte-toolbar-group-items.${$} .rte-toolbar-item:last-child .rte-toolbar-button, | ||
| .editora-toolbar-group-items.${$} .editora-toolbar-item:last-child .editora-toolbar-button { | ||
| border-right: none; | ||
| } | ||
| .rte-toolbar-button[data-command="insertLastBlockSnippet"].active, | ||
| .editora-toolbar-button[data-command="insertLastBlockSnippet"].active { | ||
| background: rgba(15, 118, 110, 0.12); | ||
| } | ||
| ${T} .rte-toolbar-group-items.${E}, | ||
| ${T} .editora-toolbar-group-items.${E}, | ||
| ${T} .rte-toolbar-group-items.${$}, | ||
| ${T} .editora-toolbar-group-items.${$} { | ||
| border-color: #566275; | ||
| } | ||
| ${T} .rte-toolbar-group-items.${E} .rte-toolbar-button svg, | ||
| ${T} .editora-toolbar-group-items.${E} .editora-toolbar-button svg, | ||
| ${T} .rte-toolbar-group-items.${$} .rte-toolbar-button svg, | ||
| ${T} .editora-toolbar-group-items.${$} .editora-toolbar-button svg | ||
| { | ||
| fill: none; | ||
| } | ||
| ${T} .rte-toolbar-group-items.${E} .rte-toolbar-button, | ||
| ${T} .editora-toolbar-group-items.${E} .editora-toolbar-button | ||
| { | ||
| border-color: #566275; | ||
| } | ||
| .${u} { | ||
| position: fixed; | ||
| z-index: 12000; | ||
| display: none; | ||
| width: min(420px, calc(100vw - 20px)); | ||
| max-height: calc(100vh - 20px); | ||
| border: 1px solid #d1d5db; | ||
| border-radius: 14px; | ||
| background: #ffffff; | ||
| color: #0f172a; | ||
| box-shadow: 0 24px 48px rgba(15, 23, 42, 0.24); | ||
| overflow: hidden; | ||
| } | ||
| .${u}.show { | ||
| display: flex; | ||
| flex-direction: column; | ||
| } | ||
| .${u}.rte-blocks-library-theme-dark { | ||
| border-color: #334155; | ||
| background: #0f172a; | ||
| color: #e2e8f0; | ||
| box-shadow: 0 24px 52px rgba(2, 6, 23, 0.68); | ||
| } | ||
| .rte-blocks-library-header { | ||
| display: flex; | ||
| align-items: center; | ||
| justify-content: space-between; | ||
| gap: 8px; | ||
| padding: 12px 14px; | ||
| border-bottom: 1px solid #e2e8f0; | ||
| background: linear-gradient(180deg, #f8fafc 0%, #f1f5f9 100%); | ||
| } | ||
| .${u}.rte-blocks-library-theme-dark .rte-blocks-library-header { | ||
| border-color: #1e293b; | ||
| background: linear-gradient(180deg, #111827 0%, #0f172a 100%); | ||
| } | ||
| .rte-blocks-library-title { | ||
| margin: 0; | ||
| font-size: 15px; | ||
| line-height: 1.2; | ||
| font-weight: 700; | ||
| } | ||
| .rte-blocks-library-icon-btn { | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 6px; | ||
| min-height: 34px; | ||
| min-width: 34px; | ||
| width: 34px; | ||
| height: 34px; | ||
| padding: 0; | ||
| background: #ffffff; | ||
| color: #0f172a; | ||
| font-size: 16px; | ||
| line-height: 1; | ||
| font-weight: 600; | ||
| display: inline-flex; | ||
| align-items: center; | ||
| justify-content: center; | ||
| cursor: pointer; | ||
| } | ||
| .rte-blocks-library-icon-btn:hover, | ||
| .rte-blocks-library-icon-btn:focus-visible { | ||
| outline: none; | ||
| border-color: #3b82f6; | ||
| box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.2); | ||
| } | ||
| .${u}.rte-blocks-library-theme-dark .rte-blocks-library-icon-btn { | ||
| border-color: #475569; | ||
| background: #0f172a; | ||
| color: #e2e8f0; | ||
| } | ||
| .${u}.rte-blocks-library-theme-dark .rte-blocks-library-icon-btn:hover, | ||
| .${u}.rte-blocks-library-theme-dark .rte-blocks-library-icon-btn:focus-visible { | ||
| border-color: #60a5fa; | ||
| box-shadow: 0 0 0 3px rgba(96, 165, 250, 0.24); | ||
| } | ||
| .rte-blocks-library-body { | ||
| display: flex; | ||
| flex-direction: column; | ||
| gap: 8px; | ||
| padding: 12px; | ||
| overflow: auto; | ||
| } | ||
| .rte-blocks-library-search-label, | ||
| .rte-blocks-library-category-label { | ||
| font-size: 12px; | ||
| line-height: 1.3; | ||
| font-weight: 700; | ||
| color: #334155; | ||
| } | ||
| .${u}.rte-blocks-library-theme-dark .rte-blocks-library-search-label, | ||
| .${u}.rte-blocks-library-theme-dark .rte-blocks-library-category-label { | ||
| color: #cbd5e1; | ||
| } | ||
| .rte-blocks-library-input, | ||
| .rte-blocks-library-select { | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 8px; | ||
| min-height: 34px; | ||
| padding: 0 10px; | ||
| font-size: 13px; | ||
| background: #ffffff; | ||
| color: inherit; | ||
| } | ||
| .rte-blocks-library-input:focus-visible, | ||
| .rte-blocks-library-select:focus-visible { | ||
| border-color: #0f766e; | ||
| box-shadow: 0 0 0 3px rgba(15, 118, 110, 0.18); | ||
| outline: none; | ||
| } | ||
| .${u}.rte-blocks-library-theme-dark .rte-blocks-library-input, | ||
| .${u}.rte-blocks-library-theme-dark .rte-blocks-library-select { | ||
| border-color: #334155; | ||
| background: #0b1220; | ||
| color: #e2e8f0; | ||
| } | ||
| .rte-blocks-library-status, | ||
| .rte-blocks-library-helper, | ||
| .rte-blocks-library-shortcut, | ||
| .rte-blocks-library-last-inserted { | ||
| margin: 0; | ||
| font-size: 12px; | ||
| line-height: 1.35; | ||
| color: #475569; | ||
| } | ||
| .rte-blocks-library-last-inserted { | ||
| font-weight: 600; | ||
| color: #0f766e; | ||
| } | ||
| .${u}.rte-blocks-library-theme-dark .rte-blocks-library-status, | ||
| .${u}.rte-blocks-library-theme-dark .rte-blocks-library-helper, | ||
| .${u}.rte-blocks-library-theme-dark .rte-blocks-library-shortcut { | ||
| color: #94a3b8; | ||
| } | ||
| .${u}.rte-blocks-library-theme-dark .rte-blocks-library-last-inserted { | ||
| color: #5eead4; | ||
| } | ||
| .rte-blocks-library-list-wrap { | ||
| border: 1px solid #e2e8f0; | ||
| border-radius: 10px; | ||
| padding: 6px; | ||
| background: #f8fafc; | ||
| max-height: min(44vh, 360px); | ||
| overflow: auto; | ||
| } | ||
| .${u}.rte-blocks-library-theme-dark .rte-blocks-library-list-wrap { | ||
| border-color: #334155; | ||
| background: #0b1220; | ||
| } | ||
| .rte-blocks-library-list { | ||
| margin: 0; | ||
| padding: 0; | ||
| list-style: none; | ||
| display: grid; | ||
| gap: 6px; | ||
| } | ||
| .rte-blocks-library-item-wrapper { | ||
| margin: 0; | ||
| padding: 0; | ||
| } | ||
| .rte-blocks-library-item { | ||
| width: 100%; | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 8px; | ||
| background: #ffffff; | ||
| color: inherit; | ||
| text-align: left; | ||
| padding: 8px; | ||
| display: grid; | ||
| gap: 3px; | ||
| cursor: pointer; | ||
| } | ||
| .rte-blocks-library-item:hover, | ||
| .rte-blocks-library-item:focus-visible { | ||
| border-color: #0f766e; | ||
| outline: none; | ||
| } | ||
| .rte-blocks-library-item.active { | ||
| border-color: #0f766e; | ||
| background: rgba(15, 118, 110, 0.12); | ||
| } | ||
| .${u}.rte-blocks-library-theme-dark .rte-blocks-library-item { | ||
| border-color: #334155; | ||
| background: #111827; | ||
| color: #e2e8f0; | ||
| } | ||
| .${u}.rte-blocks-library-theme-dark .rte-blocks-library-item.active { | ||
| border-color: #2dd4bf; | ||
| background: rgba(45, 212, 191, 0.15); | ||
| } | ||
| .rte-blocks-library-item-head { | ||
| display: flex; | ||
| align-items: center; | ||
| justify-content: space-between; | ||
| gap: 8px; | ||
| } | ||
| .rte-blocks-library-item-label { | ||
| font-size: 13px; | ||
| line-height: 1.3; | ||
| font-weight: 700; | ||
| } | ||
| .rte-blocks-library-recent-pill { | ||
| font-size: 10px; | ||
| line-height: 1; | ||
| font-weight: 700; | ||
| text-transform: uppercase; | ||
| letter-spacing: 0.02em; | ||
| color: #0f766e; | ||
| border: 1px solid rgba(15, 118, 110, 0.38); | ||
| border-radius: 999px; | ||
| padding: 2px 6px; | ||
| } | ||
| .${u}.rte-blocks-library-theme-dark .rte-blocks-library-recent-pill { | ||
| color: #5eead4; | ||
| border-color: rgba(94, 234, 212, 0.45); | ||
| } | ||
| .rte-blocks-library-item-meta, | ||
| .rte-blocks-library-item-description, | ||
| .rte-blocks-library-item-preview { | ||
| font-size: 11px; | ||
| line-height: 1.3; | ||
| color: #64748b; | ||
| } | ||
| .rte-blocks-library-item-preview { | ||
| color: #334155; | ||
| display: -webkit-box; | ||
| -webkit-line-clamp: 2; | ||
| line-clamp: 2; | ||
| -webkit-box-orient: vertical; | ||
| overflow: hidden; | ||
| } | ||
| .${u}.rte-blocks-library-theme-dark .rte-blocks-library-item-meta, | ||
| .${u}.rte-blocks-library-theme-dark .rte-blocks-library-item-description { | ||
| color: #94a3b8; | ||
| } | ||
| .${u}.rte-blocks-library-theme-dark .rte-blocks-library-item-preview { | ||
| color: #cbd5e1; | ||
| } | ||
| .rte-blocks-library-empty { | ||
| margin: 8px; | ||
| font-size: 12px; | ||
| color: #64748b; | ||
| } | ||
| .rte-blocks-library-actions { | ||
| display: flex; | ||
| gap: 8px; | ||
| } | ||
| .rte-blocks-library-btn { | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 8px; | ||
| min-height: 34px; | ||
| padding: 0 12px; | ||
| background: #ffffff; | ||
| color: inherit; | ||
| font-size: 12px; | ||
| font-weight: 700; | ||
| cursor: pointer; | ||
| } | ||
| .rte-blocks-library-btn:disabled { | ||
| opacity: 0.6; | ||
| cursor: not-allowed; | ||
| } | ||
| .rte-blocks-library-btn-primary { | ||
| border-color: #0f766e; | ||
| background: #0f766e; | ||
| color: #f8fafc; | ||
| } | ||
| .rte-blocks-library-btn-primary:hover, | ||
| .rte-blocks-library-btn-primary:focus-visible { | ||
| border-color: #115e59; | ||
| background: #115e59; | ||
| outline: none; | ||
| } | ||
| .${u}.rte-blocks-library-theme-dark .rte-blocks-library-btn { | ||
| border-color: #334155; | ||
| background: #111827; | ||
| color: #e2e8f0; | ||
| } | ||
| .${u}.rte-blocks-library-theme-dark .rte-blocks-library-btn-primary { | ||
| border-color: #14b8a6; | ||
| background: #0f766e; | ||
| color: #f0fdfa; | ||
| } | ||
| .rte-blocks-library-live { | ||
| position: absolute; | ||
| width: 1px; | ||
| height: 1px; | ||
| margin: -1px; | ||
| padding: 0; | ||
| overflow: hidden; | ||
| clip: rect(0 0 0 0); | ||
| border: 0; | ||
| } | ||
| @media (max-width: 768px) { | ||
| .${u} { | ||
| left: 10px !important; | ||
| right: 10px; | ||
| top: 10px !important; | ||
| width: auto !important; | ||
| max-height: calc(100vh - 20px); | ||
| } | ||
| } | ||
| `, document.head.appendChild(e); | ||
| } | ||
| const pt = (e = {}) => { | ||
| const t = Q(e), r = /* @__PURE__ */ new Set(); | ||
| return gt(), { | ||
| name: "blocksLibrary", | ||
| toolbar: [ | ||
| { | ||
| id: "blocksLibraryGroup", | ||
| label: "Blocks Library", | ||
| type: "group", | ||
| command: "blocksLibrary", | ||
| items: [ | ||
| { | ||
| id: "blocksLibraryPanel", | ||
| label: "Blocks Library Panel", | ||
| command: "toggleBlocksLibraryPanel", | ||
| shortcut: "Mod-Alt-Shift-b", | ||
| icon: '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><rect x="4" y="5" width="7" height="6" rx="1.5" stroke="currentColor" stroke-width="1.6"/><rect x="13" y="5" width="7" height="6" rx="1.5" stroke="currentColor" stroke-width="1.6"/><rect x="4" y="13" width="7" height="6" rx="1.5" stroke="currentColor" stroke-width="1.6"/><rect x="13" y="13" width="7" height="6" rx="1.5" stroke="currentColor" stroke-width="1.6"/></svg>' | ||
| }, | ||
| { | ||
| id: "insertLastBlockSnippet", | ||
| label: "Insert Last Block", | ||
| command: "insertLastBlockSnippet", | ||
| shortcut: "Mod-Alt-Shift-l", | ||
| icon: '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><path d="M7 5.5h10a1.5 1.5 0 0 1 1.5 1.5v10A1.5 1.5 0 0 1 17 18.5H7A1.5 1.5 0 0 1 5.5 17V7A1.5 1.5 0 0 1 7 5.5Z" stroke="currentColor" stroke-width="1.6"/><path d="M12 8.5v7" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/><path d="M8.5 12h7" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/></svg>' | ||
| } | ||
| ] | ||
| } | ||
| ], | ||
| commands: { | ||
| blocksLibrary: (o, l) => { | ||
| const n = S(l, !1, !1); | ||
| if (!n) return !1; | ||
| const a = b.get(n) || t; | ||
| return k(n, a), b.set(n, a), y = n, ue(n), !0; | ||
| }, | ||
| openBlocksLibraryPanel: (o, l) => { | ||
| const n = S(l, !1, !1); | ||
| if (!n) return !1; | ||
| const a = b.get(n) || t; | ||
| return k(n, a), b.set(n, a), y = n, ue(n), !0; | ||
| }, | ||
| toggleBlocksLibraryPanel: (o, l) => { | ||
| const n = S(l, !1, !1); | ||
| if (!n) return !1; | ||
| const a = b.get(n) || t; | ||
| return k(n, a), b.set(n, a), y = n, Ie(n, typeof o == "boolean" ? o : void 0); | ||
| }, | ||
| insertBlockSnippet: (o, l) => { | ||
| const n = S(l, !1, !1); | ||
| if (!n) return !1; | ||
| const a = b.get(n) || t; | ||
| k(n, a), b.set(n, a); | ||
| const s = typeof o == "string" ? o : o == null ? void 0 : o.id; | ||
| return s ? (y = n, F(n, s)) : !1; | ||
| }, | ||
| insertLastBlockSnippet: (o, l) => { | ||
| const n = S(l, !1, !1); | ||
| if (!n) return !1; | ||
| const a = b.get(n) || t; | ||
| return k(n, a), b.set(n, a), y = n, ze(n); | ||
| }, | ||
| refreshBlocksLibraryData: (o, l) => { | ||
| const n = S(l, !1, !1); | ||
| if (!n) return !1; | ||
| const a = b.get(n) || t; | ||
| return k(n, a), b.set(n, a), be(n, !0), !0; | ||
| }, | ||
| setBlocksLibraryOptions: (o, l) => { | ||
| const n = S(l, !1, !1); | ||
| if (!n || !o || typeof o != "object") return !1; | ||
| const a = b.get(n) || t, s = J.get(n) || Ge(a), i = { | ||
| ...s, | ||
| ...o, | ||
| labels: { | ||
| ...s.labels || {}, | ||
| ...o.labels || {} | ||
| }, | ||
| blocks: Array.isArray(o.blocks) ? o.blocks : s.blocks, | ||
| normalizeText: o.normalizeText || a.normalizeText, | ||
| sanitizeBlockHtml: o.sanitizeBlockHtml || a.sanitizeBlockHtml, | ||
| getBlocks: o.getBlocks || a.getBlocks | ||
| }, c = Q(i), d = Array.isArray(o.blocks), f = o.getBlocks !== void 0; | ||
| b.set(n, c), J.set(n, i), (d || f || !R.has(n)) && (R.set(n, c.blocks), O.set(n, f ? 0 : Date.now())); | ||
| const g = k(n, c); | ||
| return g.filterCache.clear(), typeof o.defaultCategory == "string" && (g.category = ne(c.defaultCategory) || "all"), v(n), N(n), f && be(n, !0), !0; | ||
| }, | ||
| getBlocksLibraryState: (o, l) => { | ||
| const n = S(l, !1, !1); | ||
| if (!n) return !1; | ||
| const a = b.get(n) || t; | ||
| k(n, a); | ||
| const s = ct(n); | ||
| if (typeof o == "function") | ||
| try { | ||
| o(s); | ||
| } catch (i) { | ||
| } | ||
| return n.__blocksLibraryState = s, n.dispatchEvent( | ||
| new CustomEvent("editora:blocks-library-state", { | ||
| bubbles: !0, | ||
| detail: s | ||
| }) | ||
| ), !0; | ||
| } | ||
| }, | ||
| keymap: { | ||
| "Mod-Alt-Shift-b": "toggleBlocksLibraryPanel", | ||
| "Mod-Alt-Shift-B": "toggleBlocksLibraryPanel", | ||
| "Mod-Alt-Shift-l": "insertLastBlockSnippet", | ||
| "Mod-Alt-Shift-L": "insertLastBlockSnippet" | ||
| }, | ||
| init: function(l) { | ||
| X += 1; | ||
| const n = this && typeof this.__pluginConfig == "object" ? { ...e, ...this.__pluginConfig } : e, a = Q(n); | ||
| bt(a); | ||
| const s = S( | ||
| l != null && l.editorElement ? { editorElement: l.editorElement } : void 0, | ||
| !1, | ||
| !1 | ||
| ); | ||
| s && (y = s, r.add(s), k(s, a), b.set(s, a), J.set(s, n), R.set(s, a.blocks), O.set(s, Date.now()), N(s)); | ||
| }, | ||
| destroy: () => { | ||
| r.forEach((o) => ge(o)), r.clear(), X = Math.max(0, X - 1), !(X > 0) && ft(); | ||
| } | ||
| }; | ||
| }; | ||
| export { | ||
| pt as BlocksLibraryPlugin | ||
| }; | ||
| //# sourceMappingURL=BlocksLibraryPlugin.native-HMWKxWNs.mjs.map |
| const $ = ".rte-content, .editora-content", gt = "rte-citations-styles", m = "rte-citations-panel", ot = ".rte-citation-ref[data-citation-id]", W = '.rte-citation-bibliography[data-type="citation-bibliography"]', G = '.rte-citation-footnotes[data-type="citation-footnotes"]', x = ':is([data-theme="dark"], .dark, .editora-theme-dark, .rte-theme-dark)', L = ["apa", "mla", "chicago"], Bt = { | ||
| panelTitle: "Citations", | ||
| panelAriaLabel: "Citations panel", | ||
| styleLabel: "Citation style", | ||
| authorLabel: "Author", | ||
| yearLabel: "Year", | ||
| titleLabel: "Title", | ||
| sourceLabel: "Source", | ||
| urlLabel: "URL", | ||
| noteLabel: "Footnote note", | ||
| insertText: "Insert Citation", | ||
| refreshText: "Refresh Bibliography", | ||
| closeText: "Close", | ||
| bibliographyTitle: "References", | ||
| footnotesTitle: "Citation Notes", | ||
| noCitationsText: "No citations inserted yet.", | ||
| styleButtonPrefix: "Style", | ||
| recentHeading: "Recent citations", | ||
| deleteRecentText: "x", | ||
| summaryPrefix: "Citations", | ||
| invalidMessage: "Author and title are required." | ||
| }, f = /* @__PURE__ */ new WeakMap(), T = /* @__PURE__ */ new WeakMap(), pt = /* @__PURE__ */ new WeakMap(), D = /* @__PURE__ */ new WeakMap(), v = /* @__PURE__ */ new Map(), V = /* @__PURE__ */ new WeakMap(), Q = /* @__PURE__ */ new WeakMap(), q = /* @__PURE__ */ new Set(); | ||
| let I = null, B = null, O = null, k = null, Y = 0, Ot = 0, at = 0, M = null, p = null; | ||
| function g(t) { | ||
| return t.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'"); | ||
| } | ||
| function Pt(t) { | ||
| return t.replace(/\u00A0/g, " ").replace(/\s+/g, " ").trim(); | ||
| } | ||
| function ht(t, o) { | ||
| const e = o(t); | ||
| if (!e) return ""; | ||
| const i = e.match(/\d{4}/); | ||
| return i ? i[0] : e; | ||
| } | ||
| function xt(t, o) { | ||
| const e = o(t); | ||
| return e ? /^https?:\/\//i.test(e) ? e : `https://${e}` : ""; | ||
| } | ||
| function F(t) { | ||
| return t.toLowerCase().replace(/[^a-z0-9_-]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 80); | ||
| } | ||
| function yt(t, o) { | ||
| return { | ||
| id: F(o.normalizeText(t.id || "")), | ||
| author: o.normalizeText(t.author || ""), | ||
| year: ht(t.year || "", o.normalizeText) || void 0, | ||
| title: o.normalizeText(t.title || ""), | ||
| source: o.normalizeText(t.source || "") || void 0, | ||
| url: xt(t.url || "", o.normalizeText) || void 0, | ||
| note: o.normalizeText(t.note || "") || void 0 | ||
| }; | ||
| } | ||
| function Z(t = {}) { | ||
| var i, n; | ||
| const o = t.defaultStyle && L.includes(t.defaultStyle) ? t.defaultStyle : "apa", e = { | ||
| ...Bt, | ||
| ...t.labels || {} | ||
| }; | ||
| return { | ||
| defaultStyle: o, | ||
| enableFootnoteSync: t.enableFootnoteSync !== !1, | ||
| debounceMs: Math.max(80, Number((i = t.debounceMs) != null ? i : 220)), | ||
| maxRecentCitations: Math.max(3, Math.min(30, Number((n = t.maxRecentCitations) != null ? n : 8))), | ||
| labels: e, | ||
| normalizeText: t.normalizeText || Pt, | ||
| generateCitationId: typeof t.generateCitationId == "function" ? t.generateCitationId : void 0 | ||
| }; | ||
| } | ||
| function Ct(t) { | ||
| return t ? t.nodeType === Node.ELEMENT_NODE ? t : t.parentElement : null; | ||
| } | ||
| function lt(t) { | ||
| return t.closest("[data-editora-editor], .rte-editor, .editora-editor, editora-editor") || t; | ||
| } | ||
| function X(t) { | ||
| return t ? (t.getAttribute("data-theme") || t.getAttribute("theme") || "").toLowerCase() === "dark" ? !0 : t.classList.contains("dark") || t.classList.contains("editora-theme-dark") || t.classList.contains("rte-theme-dark") : !1; | ||
| } | ||
| function Dt(t) { | ||
| const o = lt(t); | ||
| if (X(o)) return !0; | ||
| const e = o.closest("[data-theme], [theme], .dark, .editora-theme-dark, .rte-theme-dark"); | ||
| return X(e) ? !0 : X(document.documentElement) || X(document.body); | ||
| } | ||
| function tt(t, o) { | ||
| t.classList.remove("rte-citations-theme-dark"), Dt(o) && t.classList.add("rte-citations-theme-dark"); | ||
| } | ||
| function h(t, o = !0) { | ||
| if ((t == null ? void 0 : t.contentElement) instanceof HTMLElement) return t.contentElement; | ||
| if ((t == null ? void 0 : t.editorElement) instanceof HTMLElement) { | ||
| const n = t.editorElement; | ||
| if (n.matches($)) return n; | ||
| const r = n.querySelector($); | ||
| if (r instanceof HTMLElement) return r; | ||
| } | ||
| const e = window.getSelection(); | ||
| if (e && e.rangeCount > 0) { | ||
| const n = e.getRangeAt(0).startContainer, r = Ct(n), a = r == null ? void 0 : r.closest($); | ||
| if (a) return a; | ||
| } | ||
| const i = document.activeElement; | ||
| if (i) { | ||
| if (i.matches($)) return i; | ||
| const n = i.closest($); | ||
| if (n) return n; | ||
| } | ||
| return p && p.isConnected ? p : (p && !p.isConnected && (p = null), o ? document.querySelector($) : null); | ||
| } | ||
| function S(t) { | ||
| return t.getAttribute("contenteditable") === "false" || t.getAttribute("data-readonly") === "true"; | ||
| } | ||
| function j(t) { | ||
| const o = Ct(t); | ||
| return o ? !!(o.closest(W) || o.closest(G)) : !1; | ||
| } | ||
| function Ht(t, o) { | ||
| if (at += 1, o.generateCitationId) { | ||
| const e = o.generateCitationId({ editor: t, index: at }), i = F(o.normalizeText(e || "")); | ||
| if (i) return i; | ||
| } | ||
| return `cite-${Date.now().toString(36)}-${at.toString(36)}`; | ||
| } | ||
| function st(t) { | ||
| return t.map((o) => (o || "").trim()).filter(Boolean).join(" ").trim(); | ||
| } | ||
| function Ft(t, o) { | ||
| const e = t.author || "Unknown", i = t.year || "n.d."; | ||
| return o === "mla" ? `(${e} ${i})` : o === "chicago" ? `(${e} ${i})` : `(${e}, ${i})`; | ||
| } | ||
| function ut(t, o) { | ||
| const e = t.author || "Unknown", i = t.year || "n.d.", n = t.title || "Untitled", r = t.source || "", a = t.url || ""; | ||
| return st(o === "mla" ? [ | ||
| `${e}.`, | ||
| `"${n}."`, | ||
| r ? `${r},` : "", | ||
| `${i}.`, | ||
| a | ||
| ] : o === "chicago" ? [ | ||
| `${e}.`, | ||
| `${n}.`, | ||
| r ? `${r}.` : "", | ||
| `(${i}).`, | ||
| a | ||
| ] : [ | ||
| `${e}.`, | ||
| `(${i}).`, | ||
| `${n}.`, | ||
| r ? `${r}.` : "", | ||
| a | ||
| ]); | ||
| } | ||
| function R(t) { | ||
| return Array.from(t.querySelectorAll(ot)).filter( | ||
| (o) => !o.closest(W) && !o.closest(G) | ||
| ); | ||
| } | ||
| function wt(t, o) { | ||
| const e = F(o.normalizeText(t.getAttribute("data-citation-id") || "")); | ||
| if (!e) return null; | ||
| const i = o.normalizeText(t.getAttribute("data-citation-author") || ""), n = o.normalizeText(t.getAttribute("data-citation-title") || ""); | ||
| return { | ||
| id: e, | ||
| author: i || "Unknown", | ||
| year: ht(t.getAttribute("data-citation-year") || "", o.normalizeText) || void 0, | ||
| title: n || "Untitled", | ||
| source: o.normalizeText(t.getAttribute("data-citation-source") || "") || void 0, | ||
| url: xt(t.getAttribute("data-citation-url") || "", o.normalizeText) || void 0, | ||
| note: o.normalizeText(t.getAttribute("data-citation-note") || "") || void 0 | ||
| }; | ||
| } | ||
| function vt(t, o, e) { | ||
| t.classList.add("rte-citation-ref"), t.setAttribute("data-citation-id", o.id), t.setAttribute("data-citation-author", o.author || ""), t.setAttribute("data-citation-year", o.year || ""), t.setAttribute("data-citation-title", o.title || ""), t.setAttribute("data-citation-source", o.source || ""), t.setAttribute("data-citation-url", o.url || ""), t.setAttribute("data-citation-note", o.note || ""), t.setAttribute("contenteditable", "false"), t.setAttribute("tabindex", "0"), t.setAttribute("role", "doc-biblioref"), t.setAttribute("data-style", e), t.textContent = Ft(o, e); | ||
| } | ||
| function it(t, o, e) { | ||
| const i = lt(t); | ||
| Array.from( | ||
| i.querySelectorAll( | ||
| `.rte-toolbar-button[data-command="${o}"], .editora-toolbar-button[data-command="${o}"]` | ||
| ) | ||
| ).forEach((r) => { | ||
| r.classList.toggle("active", e), r.setAttribute("data-active", e ? "true" : "false"), r.setAttribute("aria-pressed", e ? "true" : "false"); | ||
| }); | ||
| } | ||
| function N(t, o) { | ||
| const e = T.get(t); | ||
| return e && L.includes(e) ? e : (o == null ? void 0 : o.defaultStyle) || "apa"; | ||
| } | ||
| function K(t, o) { | ||
| const e = R(t), i = /* @__PURE__ */ new Map(); | ||
| return e.forEach((n) => { | ||
| const r = wt(n, o); | ||
| if (!r) return; | ||
| if (!i.has(r.id)) { | ||
| i.set(r.id, r); | ||
| return; | ||
| } | ||
| const a = i.get(r.id); | ||
| i.set(r.id, { | ||
| ...a, | ||
| author: a.author || r.author, | ||
| title: a.title || r.title, | ||
| year: a.year || r.year, | ||
| source: a.source || r.source, | ||
| url: a.url || r.url, | ||
| note: a.note || r.note | ||
| }); | ||
| }), Array.from(i.values()); | ||
| } | ||
| function _t(t, o, e) { | ||
| const i = yt(o, e); | ||
| if (!i.id || !i.author || !i.title) return; | ||
| const r = (D.get(t) || []).filter((a) => a.id !== i.id); | ||
| D.set(t, [i, ...r].slice(0, e.maxRecentCitations)); | ||
| } | ||
| function rt(t, o, e) { | ||
| const i = D.get(t) || [], n = /* @__PURE__ */ new Map(); | ||
| o.slice(Math.max(0, o.length - e.maxRecentCitations)).reverse().forEach((a) => { | ||
| a.id && n.set(a.id, a); | ||
| }), i.forEach((a) => { | ||
| !a.id || n.has(a.id) || n.set(a.id, a); | ||
| }); | ||
| const r = Array.from(n.values()).slice(0, e.maxRecentCitations); | ||
| return D.set(t, r), r; | ||
| } | ||
| function Et(t, o, e, i) { | ||
| const n = F(i.normalizeText(o || "")); | ||
| return n && rt(t, e, i).find((a) => a.id === n) || null; | ||
| } | ||
| function qt(t, o, e) { | ||
| const i = F(e.normalizeText(o || "")); | ||
| if (!i) return !1; | ||
| const n = D.get(t) || [], r = n.filter((a) => a.id !== i); | ||
| return r.length === n.length ? !1 : (D.set(t, r), !0); | ||
| } | ||
| function $t(t, o, e) { | ||
| const i = document.createElement("section"); | ||
| i.className = t, i.setAttribute("data-type", o), i.setAttribute("contenteditable", "false"), i.setAttribute("aria-label", e), o === "citation-bibliography" ? i.setAttribute("role", "doc-bibliography") : o === "citation-footnotes" && i.setAttribute("role", "doc-endnotes"); | ||
| const n = document.createElement("h3"); | ||
| n.className = "rte-citation-section-title", n.textContent = e; | ||
| const r = document.createElement("ol"); | ||
| return r.className = "rte-citation-list", r.setAttribute("role", "list"), i.appendChild(n), i.appendChild(r), i; | ||
| } | ||
| function jt(t, o) { | ||
| let e = t.querySelector(W); | ||
| e || (e = $t("rte-citation-bibliography", "citation-bibliography", o.labels.bibliographyTitle), t.appendChild(e)); | ||
| const i = e.querySelector(".rte-citation-section-title"); | ||
| return i && (i.textContent = o.labels.bibliographyTitle), e.setAttribute("aria-label", o.labels.bibliographyTitle), e; | ||
| } | ||
| function Kt(t, o) { | ||
| let e = t.querySelector(G); | ||
| e || (e = $t("rte-citation-footnotes", "citation-footnotes", o.labels.footnotesTitle), t.appendChild(e)); | ||
| const i = e.querySelector(".rte-citation-section-title"); | ||
| return i && (i.textContent = o.labels.footnotesTitle), e.setAttribute("aria-label", o.labels.footnotesTitle), e; | ||
| } | ||
| function St(t, o) { | ||
| const e = t.querySelector(o); | ||
| e == null || e.remove(); | ||
| } | ||
| function Ut(t, o, e, i) { | ||
| if (o.length === 0) { | ||
| St(t, W); | ||
| return; | ||
| } | ||
| const r = jt(t, e).querySelector(".rte-citation-list"); | ||
| if (!r) return; | ||
| const a = document.createDocumentFragment(); | ||
| o.forEach((s, d) => { | ||
| const c = document.createElement("li"); | ||
| c.className = "rte-citation-item", c.id = `rte-citation-entry-${s.id}`, c.setAttribute("data-citation-id", s.id), c.setAttribute("data-citation-number", String(d + 1)), c.textContent = ut(s, i), a.appendChild(c); | ||
| }), r.innerHTML = "", r.appendChild(a); | ||
| } | ||
| function Wt(t, o, e, i) { | ||
| if (!e.enableFootnoteSync || o.length === 0) { | ||
| St(t, G), R(t).forEach((l) => { | ||
| l.removeAttribute("data-footnote-number"), l.removeAttribute("data-footnote-target"); | ||
| }); | ||
| return; | ||
| } | ||
| const r = Kt(t, e).querySelector(".rte-citation-list"); | ||
| if (!r) return; | ||
| const a = /* @__PURE__ */ new Map(), s = /* @__PURE__ */ new Map(); | ||
| o.forEach((l, u) => { | ||
| s.set(l.id, u + 1); | ||
| }); | ||
| const d = /* @__PURE__ */ new Map(); | ||
| R(t).forEach((l) => { | ||
| const u = l.getAttribute("data-citation-id") || ""; | ||
| if (!u || !s.has(u)) return; | ||
| const b = (d.get(u) || 0) + 1; | ||
| d.set(u, b); | ||
| const w = `rte-citation-ref-${u}-${b}`; | ||
| l.id = w; | ||
| const A = s.get(u); | ||
| l.setAttribute("data-footnote-number", String(A)), l.setAttribute("data-footnote-target", `rte-citation-note-${u}`), a.has(u) || a.set(u, w); | ||
| }); | ||
| const c = document.createDocumentFragment(); | ||
| o.forEach((l, u) => { | ||
| const b = document.createElement("li"); | ||
| b.className = "rte-citation-item rte-citation-footnote-item", b.id = `rte-citation-note-${l.id}`, b.setAttribute("data-citation-id", l.id); | ||
| const w = document.createElement("span"); | ||
| w.className = "rte-citation-footnote-number", w.textContent = `${u + 1}. `; | ||
| const A = document.createElement("span"); | ||
| A.className = "rte-citation-footnote-text"; | ||
| const It = l.note ? `${l.note}. ` : ""; | ||
| A.textContent = `${It}${ut(l, i)}`, b.appendChild(w), b.appendChild(A); | ||
| const mt = a.get(l.id); | ||
| if (mt) { | ||
| const _ = document.createElement("a"); | ||
| _.className = "rte-citation-backref", _.href = `#${mt}`, _.setAttribute("aria-label", `Back to citation ${u + 1}`), _.textContent = "Back", b.appendChild(_); | ||
| } | ||
| c.appendChild(b); | ||
| }), r.innerHTML = "", r.appendChild(c); | ||
| } | ||
| function Gt(t, o, e, i) { | ||
| const n = ut(o, e); | ||
| t.setAttribute("data-citation-number", String(i)), t.setAttribute("aria-label", `Citation ${i}: ${n}`); | ||
| } | ||
| function Vt(t, o, e) { | ||
| const i = R(t); | ||
| let n = `${o}:${e ? "1" : "0"}:${i.length}`; | ||
| return i.forEach((r) => { | ||
| n += `|${r.getAttribute("data-citation-id") || ""}`, n += `|${r.getAttribute("data-citation-author") || ""}`, n += `|${r.getAttribute("data-citation-year") || ""}`, n += `|${r.getAttribute("data-citation-title") || ""}`, n += `|${r.getAttribute("data-citation-source") || ""}`, n += `|${r.getAttribute("data-citation-url") || ""}`, n += `|${r.getAttribute("data-citation-note") || ""}`; | ||
| }), n; | ||
| } | ||
| function H(t) { | ||
| const o = v.get(t); | ||
| if (!o) return; | ||
| const e = f.get(t) || M; | ||
| if (!e) return; | ||
| const i = N(t, e), n = K(t, e), r = rt(t, n, e), a = o.querySelector(".rte-citations-status"), s = o.querySelector('[data-action="cycle-style"]'), d = o.querySelector(".rte-citations-recent-list"); | ||
| if (a) { | ||
| const c = n.length; | ||
| a.textContent = `${e.labels.summaryPrefix}: ${c} | Style: ${i.toUpperCase()} | Footnotes: ${e.enableFootnoteSync ? "On" : "Off"}`; | ||
| } | ||
| if (s && (s.textContent = `${e.labels.styleButtonPrefix}: ${i.toUpperCase()}`, s.setAttribute("aria-label", `${e.labels.styleButtonPrefix}: ${i.toUpperCase()}`)), d) { | ||
| if (r.length === 0) { | ||
| d.innerHTML = `<li class="rte-citations-empty">${g(e.labels.noCitationsText)}</li>`; | ||
| return; | ||
| } | ||
| d.innerHTML = r.map( | ||
| (c) => ` | ||
| <li class="rte-citations-recent-item"> | ||
| <div class="rte-citations-recent-row"> | ||
| <button | ||
| type="button" | ||
| class="rte-citations-recent-btn" | ||
| data-action="insert-from-recent" | ||
| data-citation-id="${g(c.id)}" | ||
| aria-label="Insert citation: ${g(c.title)}" | ||
| > | ||
| <span class="rte-citations-recent-title">${g(c.title)}</span> | ||
| <span class="rte-citations-recent-meta">${g(c.author)}${c.year ? ` (${g(c.year)})` : ""}</span> | ||
| </button> | ||
| <button | ||
| type="button" | ||
| class="rte-citations-recent-delete" | ||
| data-action="delete-by-id" | ||
| data-citation-id="${g(c.id)}" | ||
| aria-label="Delete citation: ${g(c.title)}" | ||
| >${g(e.labels.deleteRecentText)}</button> | ||
| </div> | ||
| </li> | ||
| ` | ||
| ).join(""); | ||
| } | ||
| } | ||
| function y(t, o, e = !1) { | ||
| const i = N(t, o), n = Vt(t, i, o.enableFootnoteSync); | ||
| if (!e && pt.get(t) === n) | ||
| return K(t, o); | ||
| const r = R(t), a = /* @__PURE__ */ new Map(); | ||
| r.forEach((c) => { | ||
| const l = wt(c, o); | ||
| l && (a.has(l.id) || a.set(l.id, l)); | ||
| }); | ||
| const s = Array.from(a.values()); | ||
| rt(t, s, o); | ||
| const d = /* @__PURE__ */ new Map(); | ||
| return s.forEach((c, l) => { | ||
| d.set(c.id, l + 1); | ||
| }), r.forEach((c) => { | ||
| const l = c.getAttribute("data-citation-id") || "", u = a.get(l); | ||
| if (!u) return; | ||
| vt(c, u, i); | ||
| const b = d.get(u.id) || 1; | ||
| Gt(c, u, i, Math.max(1, b)); | ||
| }), Ut(t, s, o, i), Wt(t, s, o, i), pt.set(t, n), H(t), t.dispatchEvent( | ||
| new CustomEvent("editora:citations-refreshed", { | ||
| bubbles: !0, | ||
| detail: { | ||
| citations: s, | ||
| style: i, | ||
| footnoteSync: o.enableFootnoteSync | ||
| } | ||
| }) | ||
| ), s; | ||
| } | ||
| function At(t) { | ||
| const o = Q.get(t); | ||
| typeof o == "number" && (window.clearTimeout(o), q.delete(o), Q.delete(t)); | ||
| } | ||
| function kt(t) { | ||
| const o = f.get(t) || M; | ||
| if (!o) return; | ||
| At(t); | ||
| const e = window.setTimeout(() => { | ||
| q.delete(e), Q.delete(t), y(t, o, !1); | ||
| }, o.debounceMs); | ||
| q.add(e), Q.set(t, e); | ||
| } | ||
| function Yt(t) { | ||
| const o = window.getSelection(); | ||
| if (!o) throw new Error("Selection unavailable"); | ||
| if (o.rangeCount > 0) { | ||
| const a = o.getRangeAt(0); | ||
| if (t.contains(a.commonAncestorContainer) && !j(a.commonAncestorContainer)) | ||
| return a.cloneRange(); | ||
| } | ||
| const e = document.createRange(), i = t.querySelector(W), n = t.querySelector(G), r = i || n; | ||
| return r ? (e.setStartBefore(r), e.collapse(!0), e) : (e.selectNodeContents(t), e.collapse(!1), e); | ||
| } | ||
| function dt(t) { | ||
| t.dispatchEvent(new Event("input", { bubbles: !0 })); | ||
| } | ||
| function ft(t, o) { | ||
| if (o === t.innerHTML) return; | ||
| const e = window.execEditorCommand || window.executeEditorCommand; | ||
| if (typeof e == "function") | ||
| try { | ||
| e("recordDomTransaction", t, o, t.innerHTML); | ||
| } catch (i) { | ||
| } | ||
| } | ||
| function Tt(t, o) { | ||
| const e = window.getSelection(); | ||
| if (!e) return; | ||
| const i = document.createRange(); | ||
| if (t.nodeType === Node.TEXT_NODE) { | ||
| const n = t, r = Math.max(0, Math.min(o, n.length)); | ||
| i.setStart(n, r); | ||
| } else { | ||
| const n = t.childNodes.length, r = Math.max(0, Math.min(o, n)); | ||
| i.setStart(t, r); | ||
| } | ||
| i.collapse(!0), e.removeAllRanges(), e.addRange(i); | ||
| } | ||
| function Mt(t) { | ||
| if (t.collapsed || t.startContainer !== t.endContainer || t.endOffset !== t.startOffset + 1 || !(t.startContainer instanceof Element || t.startContainer instanceof DocumentFragment)) | ||
| return null; | ||
| const o = t.startContainer.childNodes[t.startOffset]; | ||
| return !(o instanceof HTMLElement) || !o.matches(ot) ? null : o; | ||
| } | ||
| function J(t, o, e) { | ||
| const { startContainer: i, startOffset: n } = t; | ||
| if (i.nodeType === Node.ELEMENT_NODE) { | ||
| const a = i; | ||
| if (e === "previous") { | ||
| if (n > 0) return a.childNodes[n - 1] || null; | ||
| } else if (n < a.childNodes.length) | ||
| return a.childNodes[n] || null; | ||
| } | ||
| if (i.nodeType === Node.TEXT_NODE && (e === "previous" && n < i.data.length || e === "next" && n > 0)) | ||
| return null; | ||
| let r = i; | ||
| for (; r && r !== o; ) { | ||
| const a = e === "previous" ? r.previousSibling : r.nextSibling; | ||
| if (a) return a; | ||
| r = r.parentNode; | ||
| } | ||
| return null; | ||
| } | ||
| function Lt(t, o, e) { | ||
| if (!t.collapsed) return null; | ||
| const i = (a) => a instanceof HTMLElement && a.matches(ot) ? a : null, { startContainer: n, startOffset: r } = t; | ||
| if (n.nodeType === Node.ELEMENT_NODE) { | ||
| const a = n; | ||
| return e === "Backspace" && r > 0 ? i(a.childNodes[r - 1] || null) : e === "Delete" ? i(a.childNodes[r] || null) : null; | ||
| } | ||
| if (n.nodeType === Node.TEXT_NODE) { | ||
| const a = n; | ||
| if (e === "Backspace" && r === 0) { | ||
| const s = i(a.previousSibling); | ||
| return s || i(J(t, o, "previous")); | ||
| } | ||
| if (e === "Delete" && r === a.data.length) { | ||
| const s = i(a.nextSibling); | ||
| return s || i(J(t, o, "next")); | ||
| } | ||
| } | ||
| return i(e === "Backspace" ? J(t, o, "previous") : J(t, o, "next")); | ||
| } | ||
| function P(t, o, e) { | ||
| const i = t.closest($); | ||
| if (!i || j(t)) return !1; | ||
| const n = t.parentNode; | ||
| if (!n) return !1; | ||
| const r = i.innerHTML, a = Array.from(n.childNodes).indexOf(t); | ||
| if (a < 0) return !1; | ||
| const s = t.nextSibling; | ||
| return s instanceof Text && (s.data === " " ? s.remove() : s.data.startsWith(" ") && (s.data = s.data.slice(1))), t.remove(), Tt(n, a), y(i, e, !0), ft(i, r), dt(i), o === "Delete" && i.focus({ preventScroll: !0 }), !0; | ||
| } | ||
| function Xt(t, o, e) { | ||
| if (t.key !== "Backspace" && t.key !== "Delete") return !1; | ||
| const i = t.key, n = t.target; | ||
| if (n != null && n.matches(ot) && o.contains(n) && !j(n)) | ||
| return t.preventDefault(), t.stopPropagation(), P(n, i, e); | ||
| const r = window.getSelection(); | ||
| if (!r || r.rangeCount === 0) return !1; | ||
| const a = r.getRangeAt(0); | ||
| if (!o.contains(a.commonAncestorContainer) || j(a.commonAncestorContainer)) return !1; | ||
| const s = Mt(a); | ||
| if (s) | ||
| return t.preventDefault(), t.stopPropagation(), P(s, i, e); | ||
| const d = Lt(a, o, i); | ||
| return d ? (t.preventDefault(), t.stopPropagation(), P(d, i, e)) : !1; | ||
| } | ||
| function Rt(t, o, e) { | ||
| const i = F(e.normalizeText(o || "")); | ||
| if (!i) return !1; | ||
| const n = R(t).filter((a) => a.getAttribute("data-citation-id") === i); | ||
| if (n.length === 0) return !1; | ||
| if (n.length === 1) | ||
| return P(n[0], "Delete", e); | ||
| const r = t.innerHTML; | ||
| return n.forEach((a) => { | ||
| const s = a.nextSibling; | ||
| s instanceof Text && (s.data === " " ? s.remove() : s.data.startsWith(" ") && (s.data = s.data.slice(1))), a.remove(); | ||
| }), Tt(t, t.childNodes.length), y(t, e, !0), ft(t, r), dt(t), t.focus({ preventScroll: !0 }), !0; | ||
| } | ||
| function Jt(t, o) { | ||
| const e = window.getSelection(); | ||
| if (!e || e.rangeCount === 0) return !1; | ||
| const i = e.getRangeAt(0); | ||
| if (!t.contains(i.commonAncestorContainer) || j(i.commonAncestorContainer)) return !1; | ||
| const n = Mt(i); | ||
| if (n) | ||
| return P(n, "Delete", o); | ||
| const r = Lt(i, t, "Backspace"); | ||
| return r ? P(r, "Backspace", o) : !1; | ||
| } | ||
| function et(t, o, e) { | ||
| var l, u; | ||
| const i = yt(o, e); | ||
| if (!i.author || !i.title) return !1; | ||
| i.id || (i.id = Ht(t, e)); | ||
| const n = t.innerHTML; | ||
| let r; | ||
| try { | ||
| r = Yt(t); | ||
| } catch (b) { | ||
| return !1; | ||
| } | ||
| const a = window.getSelection(); | ||
| if (!a) return !1; | ||
| r.collapsed || r.deleteContents(); | ||
| const s = document.createElement("span"); | ||
| vt(s, i, N(t, e)); | ||
| try { | ||
| r.insertNode(s); | ||
| } catch (b) { | ||
| return !1; | ||
| } | ||
| const d = document.createTextNode(" "); | ||
| s.nextSibling ? (l = s.parentNode) == null || l.insertBefore(d, s.nextSibling) : (u = s.parentNode) == null || u.appendChild(d); | ||
| const c = document.createRange(); | ||
| if (d.parentNode) { | ||
| const b = Array.from(d.parentNode.childNodes).indexOf(d) + 1; | ||
| c.setStart(d.parentNode, Math.max(0, b)); | ||
| } else | ||
| c.setStartAfter(s); | ||
| return c.collapse(!0), a.removeAllRanges(), a.addRange(c), _t(t, i, e), y(t, e, !0), ft(t, n), dt(t), !0; | ||
| } | ||
| function Zt(t, o) { | ||
| if (!o) return !1; | ||
| const e = R(t).find((r) => r.getAttribute("data-citation-id") === o) || null; | ||
| if (!e) return !1; | ||
| e.scrollIntoView({ behavior: "smooth", block: "center", inline: "nearest" }), e.focus({ preventScroll: !0 }); | ||
| const i = window.getSelection(); | ||
| if (!i) return !0; | ||
| const n = document.createRange(); | ||
| return n.selectNode(e), i.removeAllRanges(), i.addRange(n), !0; | ||
| } | ||
| function nt(t) { | ||
| return V.get(t) === !0; | ||
| } | ||
| function U(t, o = !1) { | ||
| const e = v.get(t); | ||
| e && (e.classList.remove("show"), V.set(t, !1), it(t, "toggleCitationsPanel", !1), o && t.focus({ preventScroll: !0 })); | ||
| } | ||
| function Qt(t) { | ||
| v.forEach((o, e) => { | ||
| e !== t && U(e, !1); | ||
| }); | ||
| } | ||
| function ct(t, o) { | ||
| if (!o.classList.contains("show")) return; | ||
| const i = lt(t).getBoundingClientRect(), n = Math.min(window.innerWidth - 20, 380), r = Math.max(10, window.innerWidth - n - 10), a = Math.min(Math.max(10, i.right - n), r), s = Math.max(10, Math.min(window.innerHeight - 10 - 260, i.top + 10)); | ||
| o.style.width = `${n}px`, o.style.left = `${a}px`, o.style.top = `${s}px`, o.style.maxHeight = `${Math.max(260, window.innerHeight - 24)}px`; | ||
| } | ||
| function C(t, o) { | ||
| return t.querySelector(`[data-field="${o}"]`); | ||
| } | ||
| function te(t) { | ||
| var s, d, c, l, u, b; | ||
| const o = ((s = C(t, "author")) == null ? void 0 : s.value) || "", e = ((d = C(t, "year")) == null ? void 0 : d.value) || "", i = ((c = C(t, "title")) == null ? void 0 : c.value) || "", n = ((l = C(t, "source")) == null ? void 0 : l.value) || "", r = ((u = C(t, "url")) == null ? void 0 : u.value) || "", a = ((b = C(t, "note")) == null ? void 0 : b.value) || ""; | ||
| return { | ||
| author: o, | ||
| year: e, | ||
| title: i, | ||
| source: n, | ||
| url: r, | ||
| note: a | ||
| }; | ||
| } | ||
| function E(t, o) { | ||
| const e = t.querySelector(".rte-citations-live"); | ||
| e && (e.textContent = o); | ||
| } | ||
| function ee(t, o, e) { | ||
| const i = C(o, "style"); | ||
| i && (i.value = N(t, e)); | ||
| } | ||
| function Nt(t, o, e) { | ||
| const i = L.includes(o) ? o : e.defaultStyle; | ||
| return T.set(t, i), y(t, e, !0), i; | ||
| } | ||
| function bt(t, o) { | ||
| const e = N(t, o), i = L.indexOf(e), n = L[(i + 1) % L.length]; | ||
| return T.set(t, n), y(t, o, !0), n; | ||
| } | ||
| function ne(t) { | ||
| const o = v.get(t); | ||
| if (o) return o; | ||
| const e = f.get(t) || M || Z(), i = `rte-citations-panel-${Ot++}`, n = document.createElement("section"); | ||
| n.className = m, n.id = i, n.setAttribute("role", "dialog"), n.setAttribute("aria-modal", "false"), n.setAttribute("aria-label", e.labels.panelAriaLabel), n.setAttribute("tabindex", "-1"), n.innerHTML = ` | ||
| <header class="rte-citations-header"> | ||
| <h2 class="rte-citations-title">${g(e.labels.panelTitle)}</h2> | ||
| <button type="button" class="rte-citations-icon-btn" data-action="close" aria-label="${g(e.labels.closeText)}">✕</button> | ||
| </header> | ||
| <div class="rte-citations-body"> | ||
| <p class="rte-citations-status" aria-live="polite"></p> | ||
| <div class="rte-citations-grid"> | ||
| <label class="rte-citations-label"> | ||
| ${g(e.labels.styleLabel)} | ||
| <select data-field="style" class="rte-citations-field"> | ||
| <option value="apa">APA</option> | ||
| <option value="mla">MLA</option> | ||
| <option value="chicago">Chicago</option> | ||
| </select> | ||
| </label> | ||
| <label class="rte-citations-label"> | ||
| ${g(e.labels.authorLabel)} | ||
| <input type="text" data-field="author" class="rte-citations-field" autocomplete="off" /> | ||
| </label> | ||
| <label class="rte-citations-label"> | ||
| ${g(e.labels.yearLabel)} | ||
| <input type="text" data-field="year" class="rte-citations-field" inputmode="numeric" autocomplete="off" /> | ||
| </label> | ||
| <label class="rte-citations-label"> | ||
| ${g(e.labels.titleLabel)} | ||
| <input type="text" data-field="title" class="rte-citations-field" autocomplete="off" /> | ||
| </label> | ||
| <label class="rte-citations-label"> | ||
| ${g(e.labels.sourceLabel)} | ||
| <input type="text" data-field="source" class="rte-citations-field" autocomplete="off" /> | ||
| </label> | ||
| <label class="rte-citations-label"> | ||
| ${g(e.labels.urlLabel)} | ||
| <input type="url" data-field="url" class="rte-citations-field" autocomplete="off" /> | ||
| </label> | ||
| <label class="rte-citations-label rte-citations-label-note"> | ||
| ${g(e.labels.noteLabel)} | ||
| <textarea data-field="note" class="rte-citations-field" rows="2"></textarea> | ||
| </label> | ||
| </div> | ||
| <div class="rte-citations-controls" role="toolbar" aria-label="Citation actions"> | ||
| <button type="button" class="rte-citations-btn rte-citations-btn-primary" data-action="insert">${g(e.labels.insertText)}</button> | ||
| <button type="button" class="rte-citations-btn" data-action="refresh">${g(e.labels.refreshText)}</button> | ||
| <button type="button" class="rte-citations-btn" data-action="cycle-style"></button> | ||
| </div> | ||
| <section class="rte-citations-recent" aria-label="${g(e.labels.recentHeading)}"> | ||
| <h3 class="rte-citations-recent-heading">${g(e.labels.recentHeading)}</h3> | ||
| <ul class="rte-citations-recent-list" role="list"></ul> | ||
| </section> | ||
| <p class="rte-citations-shortcut">Shortcut: Ctrl/Cmd + Alt + Shift + C</p> | ||
| <span class="rte-citations-live" aria-live="polite"></span> | ||
| </div> | ||
| `, n.addEventListener("click", (a) => { | ||
| const s = a.target; | ||
| if (!s) return; | ||
| const d = s.closest("[data-action]"); | ||
| if (!d) return; | ||
| const c = d.getAttribute("data-action") || "", l = f.get(t) || M || e; | ||
| if (f.set(t, l), c === "close") { | ||
| U(t, !0); | ||
| return; | ||
| } | ||
| if (c === "insert") { | ||
| if (S(t)) return; | ||
| const u = te(n); | ||
| if (!l.normalizeText(u.author) || !l.normalizeText(u.title)) { | ||
| E(n, l.labels.invalidMessage); | ||
| return; | ||
| } | ||
| if (!et(t, u, l)) { | ||
| E(n, l.labels.invalidMessage); | ||
| return; | ||
| } | ||
| E(n, "Citation inserted."); | ||
| const w = C(n, "title"), A = C(n, "note"); | ||
| w && (w.value = ""), A && (A.value = ""); | ||
| return; | ||
| } | ||
| if (c === "refresh") { | ||
| const u = y(t, l, !0); | ||
| E(n, `Refreshed ${u.length} citation${u.length === 1 ? "" : "s"}.`); | ||
| return; | ||
| } | ||
| if (c === "cycle-style") { | ||
| const u = bt(t, l); | ||
| ee(t, n, l), E(n, `Style changed to ${u.toUpperCase()}.`); | ||
| return; | ||
| } | ||
| if (c === "insert-from-recent") { | ||
| if (S(t)) return; | ||
| const u = d.getAttribute("data-citation-id") || "", b = Et(t, u, K(t, l), l); | ||
| if (!b) return; | ||
| et(t, b, l), E(n, `Inserted citation: ${b.title}.`); | ||
| return; | ||
| } | ||
| if (c === "delete-by-id") { | ||
| if (S(t)) return; | ||
| const u = d.getAttribute("data-citation-id") || ""; | ||
| if (Rt(t, u, l)) { | ||
| E(n, "Citation deleted."); | ||
| return; | ||
| } | ||
| qt(t, u, l) && (H(t), E(n, "Removed from recent citations.")); | ||
| } | ||
| }), n.addEventListener("keydown", (a) => { | ||
| if (a.key === "Escape") { | ||
| a.preventDefault(), U(t, !0); | ||
| return; | ||
| } | ||
| const s = a.target; | ||
| if (!s || !s.matches(".rte-citations-recent-btn") || a.key !== "ArrowDown" && a.key !== "ArrowUp") return; | ||
| const d = Array.from(n.querySelectorAll(".rte-citations-recent-btn")); | ||
| if (d.length === 0) return; | ||
| const c = d.indexOf(s); | ||
| if (c < 0) return; | ||
| a.preventDefault(); | ||
| const l = a.key === "ArrowDown" ? 1 : -1, u = (c + l + d.length) % d.length; | ||
| d[u].focus(); | ||
| }); | ||
| const r = C(n, "style"); | ||
| return r == null || r.addEventListener("change", () => { | ||
| const a = f.get(t) || M || e, s = r.value; | ||
| Nt(t, s, a), E(n, `Style changed to ${s.toUpperCase()}.`); | ||
| }), tt(n, t), document.body.appendChild(n), v.set(t, n), V.set(t, !1), H(t), n; | ||
| } | ||
| function z(t) { | ||
| const o = ne(t); | ||
| Qt(t), o.classList.add("show"), V.set(t, !0), it(t, "toggleCitationsPanel", !0), tt(o, t), ct(t, o), H(t); | ||
| const e = C(o, "author"); | ||
| e == null || e.focus(); | ||
| } | ||
| function zt(t, o) { | ||
| const e = nt(t); | ||
| return (typeof o == "boolean" ? o : !e) ? z(t) : U(t, !1), !0; | ||
| } | ||
| function oe(t) { | ||
| const o = t.key.toLowerCase(); | ||
| return (t.metaKey || t.ctrlKey) && t.altKey && t.shiftKey && o === "c"; | ||
| } | ||
| function ie(t) { | ||
| const o = t.key.toLowerCase(); | ||
| return (t.metaKey || t.ctrlKey) && t.altKey && t.shiftKey && o === "b"; | ||
| } | ||
| function re(t) { | ||
| const o = t.key.toLowerCase(); | ||
| return (t.metaKey || t.ctrlKey) && t.altKey && t.shiftKey && o === "j"; | ||
| } | ||
| function ae(t) { | ||
| M = t, I || (I = (o) => { | ||
| const e = o.target, i = e == null ? void 0 : e.closest($); | ||
| if (!i) return; | ||
| p = i, f.has(i) || f.set(i, t), T.has(i) || T.set(i, t.defaultStyle); | ||
| const n = v.get(i); | ||
| n && (tt(n, i), ct(i, n)), it(i, "toggleCitationsPanel", nt(i)); | ||
| }, document.addEventListener("focusin", I, !0)), B || (B = (o) => { | ||
| const e = o.target, i = e == null ? void 0 : e.closest($); | ||
| i && (p = i, kt(i)); | ||
| }, document.addEventListener("input", B, !0)), O || (O = (o) => { | ||
| if (o.defaultPrevented) return; | ||
| const e = o.target, i = !!(e != null && e.closest(`.${m} input, .${m} textarea, .${m} select`)), n = h(void 0, !1); | ||
| if (!n || S(n)) return; | ||
| const r = f.get(n) || M || t; | ||
| if (f.set(n, r), p = n, o.key === "Escape" && nt(n)) { | ||
| o.preventDefault(), U(n, !0); | ||
| return; | ||
| } | ||
| if (!i && !Xt(o, n, r)) { | ||
| if (oe(o)) { | ||
| o.preventDefault(), o.stopPropagation(), zt(n); | ||
| return; | ||
| } | ||
| if (ie(o)) { | ||
| o.preventDefault(), o.stopPropagation(), y(n, r, !0), z(n); | ||
| return; | ||
| } | ||
| re(o) && (o.preventDefault(), o.stopPropagation(), bt(n, r)); | ||
| } | ||
| }, document.addEventListener("keydown", O, !0)), k || (k = () => { | ||
| v.forEach((o, e) => { | ||
| if (!e.isConnected || !o.isConnected) { | ||
| At(e), o.remove(), v.delete(e), V.delete(e); | ||
| return; | ||
| } | ||
| tt(o, e), ct(e, o); | ||
| }); | ||
| }, window.addEventListener("scroll", k, !0), window.addEventListener("resize", k)); | ||
| } | ||
| function se() { | ||
| I && (document.removeEventListener("focusin", I, !0), I = null), B && (document.removeEventListener("input", B, !0), B = null), O && (document.removeEventListener("keydown", O, !0), O = null), k && (window.removeEventListener("scroll", k, !0), window.removeEventListener("resize", k), k = null), v.forEach((t) => t.remove()), v.clear(), M = null, p = null; | ||
| } | ||
| function ce() { | ||
| if (typeof document == "undefined" || document.getElementById(gt)) return; | ||
| const t = document.createElement("style"); | ||
| t.id = gt, t.textContent = ` | ||
| .rte-toolbar-group-items.citations, | ||
| .editora-toolbar-group-items.citations { | ||
| display: flex; | ||
| border: 1px solid #ccc; | ||
| border-radius: 3px; | ||
| background: #fff; | ||
| } | ||
| .rte-toolbar-group-items.citations .rte-toolbar-button, | ||
| .editora-toolbar-group-items.citations .editora-toolbar-button { | ||
| border: none; | ||
| border-radius: 0; | ||
| border-right: 1px solid #ccc; | ||
| } | ||
| .rte-toolbar-group-items.citations .rte-toolbar-item:last-child .rte-toolbar-button, | ||
| .editora-toolbar-group-items.citations .editora-toolbar-item:last-child .editora-toolbar-button { | ||
| border-right: none; | ||
| } | ||
| .rte-toolbar-button[data-command="toggleCitationsPanel"].active, | ||
| .editora-toolbar-button[data-command="toggleCitationsPanel"].active { | ||
| background: #ccc; | ||
| } | ||
| ${x} .rte-toolbar-group-items.citations, | ||
| ${x} .editora-toolbar-group-items.citations, | ||
| .${m}.rte-citations-theme-dark { | ||
| border-color: #566275; | ||
| } | ||
| ${x} .rte-toolbar-group-items.citations .rte-toolbar-button[data-command="refreshCitations"] svg, | ||
| ${x} .editora-toolbar-group-items.citations .editora-toolbar-button[data-command="refreshCitations"] svg | ||
| { | ||
| fill: none; | ||
| } | ||
| ${x} .rte-toolbar-group-items.citations .rte-toolbar-button, | ||
| ${x} .editora-toolbar-group-items.citations .editora-toolbar-button | ||
| { | ||
| border-color: #566275; | ||
| } | ||
| ${x} .rte-toolbar-button[data-command="toggleCitationsPanel"].active, | ||
| ${x} .editora-toolbar-button[data-command="toggleCitationsPanel"].active { | ||
| background: linear-gradient(180deg, #5eaaf6 0%, #4a95de 100%); | ||
| } | ||
| .${m} { | ||
| position: fixed; | ||
| z-index: 1500; | ||
| right: 16px; | ||
| top: 16px; | ||
| width: min(380px, calc(100vw - 20px)); | ||
| max-height: calc(100vh - 24px); | ||
| display: none; | ||
| flex-direction: column; | ||
| border-radius: 12px; | ||
| border: 1px solid #d1d5db; | ||
| background: #ffffff; | ||
| color: #0f172a; | ||
| box-shadow: 0 18px 38px rgba(15, 23, 42, 0.16); | ||
| overflow: hidden; | ||
| } | ||
| .${m}.show { | ||
| display: flex; | ||
| } | ||
| .${m}.rte-citations-theme-dark { | ||
| background: #0f172a; | ||
| color: #e2e8f0; | ||
| border-color: #334155; | ||
| box-shadow: 0 20px 40px rgba(2, 6, 23, 0.5); | ||
| } | ||
| .rte-citations-header { | ||
| display: flex; | ||
| align-items: center; | ||
| justify-content: space-between; | ||
| padding: 10px 12px; | ||
| border-bottom: 1px solid #e2e8f0; | ||
| background: #f8fafc; | ||
| } | ||
| .${m}.rte-citations-theme-dark .rte-citations-header { | ||
| border-bottom-color: #334155; | ||
| background: #111827; | ||
| } | ||
| .rte-citations-title { | ||
| margin: 0; | ||
| font-size: 14px; | ||
| font-weight: 700; | ||
| } | ||
| .rte-citations-icon-btn { | ||
| border: 1px solid #cbd5e1; | ||
| background: #ffffff; | ||
| color: #0f172a; | ||
| border-radius: 6px; | ||
| cursor: pointer; | ||
| min-width: 34px; | ||
| min-height: 34px; | ||
| width: 34px; | ||
| height: 34px; | ||
| padding: 0; | ||
| display: inline-flex; | ||
| align-items: center; | ||
| justify-content: center; | ||
| font-size: 16px; | ||
| line-height: 1; | ||
| font-weight: 600; | ||
| } | ||
| .rte-citations-icon-btn:hover, | ||
| .rte-citations-icon-btn:focus-visible { | ||
| outline: none; | ||
| border-color: #3b82f6; | ||
| box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.2); | ||
| } | ||
| .${m}.rte-citations-theme-dark .rte-citations-icon-btn { | ||
| background: #0f172a; | ||
| border-color: #475569; | ||
| color: #e2e8f0; | ||
| } | ||
| .${m}.rte-citations-theme-dark .rte-citations-icon-btn:hover, | ||
| .${m}.rte-citations-theme-dark .rte-citations-icon-btn:focus-visible { | ||
| border-color: #60a5fa; | ||
| box-shadow: 0 0 0 3px rgba(96, 165, 250, 0.24); | ||
| } | ||
| .rte-citations-body { | ||
| display: flex; | ||
| flex-direction: column; | ||
| gap: 10px; | ||
| padding: 12px; | ||
| overflow: auto; | ||
| } | ||
| .rte-citations-status { | ||
| margin: 0; | ||
| font-size: 12px; | ||
| color: #475569; | ||
| } | ||
| .${m}.rte-citations-theme-dark .rte-citations-status { | ||
| color: #94a3b8; | ||
| } | ||
| .rte-citations-grid { | ||
| display: grid; | ||
| grid-template-columns: 1fr 1fr; | ||
| gap: 8px; | ||
| } | ||
| .rte-citations-label { | ||
| display: flex; | ||
| flex-direction: column; | ||
| gap: 4px; | ||
| font-size: 12px; | ||
| font-weight: 600; | ||
| color: inherit; | ||
| } | ||
| .rte-citations-label-note { | ||
| grid-column: 1 / -1; | ||
| } | ||
| .rte-citations-field { | ||
| width: 100%; | ||
| box-sizing: border-box; | ||
| min-height: 30px; | ||
| border-radius: 8px; | ||
| border: 1px solid #cbd5e1; | ||
| background: #ffffff; | ||
| color: inherit; | ||
| font-size: 13px; | ||
| padding: 6px 8px; | ||
| } | ||
| .rte-citations-field:focus-visible { | ||
| outline: none; | ||
| border-color: #1d4ed8; | ||
| box-shadow: 0 0 0 2px rgba(29, 78, 216, 0.2); | ||
| } | ||
| .${m}.rte-citations-theme-dark .rte-citations-field { | ||
| border-color: #334155; | ||
| background: #0b1220; | ||
| color: #e2e8f0; | ||
| } | ||
| .rte-citations-controls { | ||
| display: flex; | ||
| flex-wrap: wrap; | ||
| gap: 8px; | ||
| } | ||
| .rte-citations-btn { | ||
| border: 1px solid #cbd5e1; | ||
| background: #f8fafc; | ||
| color: inherit; | ||
| border-radius: 8px; | ||
| padding: 6px 10px; | ||
| font-size: 12px; | ||
| font-weight: 600; | ||
| cursor: pointer; | ||
| } | ||
| .rte-citations-btn:hover, | ||
| .rte-citations-btn:focus-visible { | ||
| outline: none; | ||
| border-color: #1d4ed8; | ||
| box-shadow: 0 0 0 2px rgba(29, 78, 216, 0.2); | ||
| } | ||
| .rte-citations-btn-primary { | ||
| background: #1d4ed8; | ||
| border-color: #1d4ed8; | ||
| color: #ffffff; | ||
| } | ||
| .rte-citations-btn-primary:hover, | ||
| .rte-citations-btn-primary:focus-visible { | ||
| background: #1e40af; | ||
| border-color: #1e40af; | ||
| } | ||
| .${m}.rte-citations-theme-dark .rte-citations-btn { | ||
| border-color: #334155; | ||
| background: #0b1220; | ||
| color: #e2e8f0; | ||
| } | ||
| .${m}.rte-citations-theme-dark .rte-citations-btn-primary { | ||
| border-color: #2563eb; | ||
| background: #2563eb; | ||
| color: #ffffff; | ||
| } | ||
| .rte-citations-recent { | ||
| border: 1px solid #e2e8f0; | ||
| border-radius: 10px; | ||
| padding: 8px; | ||
| } | ||
| .${m}.rte-citations-theme-dark .rte-citations-recent { | ||
| border-color: #334155; | ||
| } | ||
| .rte-citations-recent-heading { | ||
| margin: 0 0 8px; | ||
| font-size: 12px; | ||
| font-weight: 700; | ||
| } | ||
| .rte-citations-recent-list { | ||
| margin: 0; | ||
| padding: 0; | ||
| list-style: none; | ||
| display: flex; | ||
| flex-direction: column; | ||
| gap: 6px; | ||
| max-height: 170px; | ||
| overflow: auto; | ||
| } | ||
| .rte-citations-recent-btn { | ||
| width: 100%; | ||
| text-align: left; | ||
| border: 1px solid #cbd5e1; | ||
| background: #ffffff; | ||
| color: inherit; | ||
| border-radius: 8px; | ||
| padding: 7px; | ||
| cursor: pointer; | ||
| display: flex; | ||
| flex-direction: column; | ||
| gap: 2px; | ||
| } | ||
| .rte-citations-recent-row { | ||
| display: flex; | ||
| gap: 6px; | ||
| align-items: stretch; | ||
| } | ||
| .rte-citations-recent-delete { | ||
| flex: 0 0 auto; | ||
| border: 1px solid #fecaca; | ||
| background: #fff1f2; | ||
| color: #b91c1c; | ||
| border-radius: 8px; | ||
| padding: 0 8px; | ||
| font-size: 11px; | ||
| font-weight: 700; | ||
| cursor: pointer; | ||
| min-height: 34px; | ||
| } | ||
| .rte-citations-recent-delete:hover, | ||
| .rte-citations-recent-delete:focus-visible { | ||
| outline: none; | ||
| border-color: #f87171; | ||
| box-shadow: 0 0 0 2px rgba(248, 113, 113, 0.2); | ||
| } | ||
| .rte-citations-recent-btn:focus-visible, | ||
| .rte-citations-recent-btn:hover { | ||
| outline: none; | ||
| border-color: #1d4ed8; | ||
| box-shadow: 0 0 0 2px rgba(29, 78, 216, 0.18); | ||
| } | ||
| .${m}.rte-citations-theme-dark .rte-citations-recent-btn { | ||
| border-color: #334155; | ||
| background: #0b1220; | ||
| color: #e2e8f0; | ||
| } | ||
| .${m}.rte-citations-theme-dark .rte-citations-recent-delete { | ||
| border-color: #7f1d1d; | ||
| background: #2b1218; | ||
| color: #fca5a5; | ||
| } | ||
| .rte-citations-recent-title { | ||
| font-size: 12px; | ||
| font-weight: 700; | ||
| line-height: 1.3; | ||
| } | ||
| .rte-citations-recent-meta { | ||
| font-size: 11px; | ||
| color: #64748b; | ||
| line-height: 1.3; | ||
| } | ||
| .${m}.rte-citations-theme-dark .rte-citations-recent-meta { | ||
| color: #94a3b8; | ||
| } | ||
| .rte-citations-empty { | ||
| border: 1px dashed #cbd5e1; | ||
| border-radius: 8px; | ||
| padding: 8px; | ||
| font-size: 12px; | ||
| color: #64748b; | ||
| } | ||
| .${m}.rte-citations-theme-dark .rte-citations-empty { | ||
| border-color: #334155; | ||
| color: #94a3b8; | ||
| } | ||
| .rte-citations-shortcut { | ||
| margin: 0; | ||
| font-size: 11px; | ||
| color: #64748b; | ||
| } | ||
| .${m}.rte-citations-theme-dark .rte-citations-shortcut { | ||
| color: #94a3b8; | ||
| } | ||
| .rte-citations-live { | ||
| position: absolute; | ||
| width: 1px; | ||
| height: 1px; | ||
| margin: -1px; | ||
| padding: 0; | ||
| overflow: hidden; | ||
| clip: rect(0 0 0 0); | ||
| border: 0; | ||
| } | ||
| .rte-citation-ref { | ||
| display: inline-flex; | ||
| align-items: center; | ||
| border-radius: 6px; | ||
| border: 1px solid rgba(29, 78, 216, 0.24); | ||
| background: rgba(29, 78, 216, 0.08); | ||
| color: #1e3a8a; | ||
| padding: 0 4px; | ||
| margin: 0 1px; | ||
| font-size: 0.92em; | ||
| line-height: 1.35; | ||
| white-space: nowrap; | ||
| cursor: pointer; | ||
| user-select: all; | ||
| } | ||
| .rte-citation-ref:focus, | ||
| .rte-citation-ref:focus-visible { | ||
| outline: none; | ||
| border-color: #1d4ed8; | ||
| box-shadow: 0 0 0 2px rgba(29, 78, 216, 0.22); | ||
| } | ||
| .${x} .rte-citation-ref { | ||
| border-color: rgba(96, 165, 250, 0.45); | ||
| background: rgba(37, 99, 235, 0.22); | ||
| color: #bfdbfe; | ||
| } | ||
| .rte-citation-bibliography, | ||
| .rte-citation-footnotes { | ||
| margin-top: 16px; | ||
| border-top: 1px solid #d1d5db; | ||
| padding-top: 10px; | ||
| } | ||
| .${x} .rte-citation-bibliography, | ||
| .${x} .rte-citation-footnotes { | ||
| border-top-color: #475569; | ||
| } | ||
| .rte-citation-section-title { | ||
| margin: 0 0 8px; | ||
| font-size: 1em; | ||
| font-weight: 700; | ||
| } | ||
| .rte-citation-list { | ||
| margin: 0; | ||
| padding-left: 22px; | ||
| } | ||
| .rte-citation-item { | ||
| margin: 0 0 8px; | ||
| line-height: 1.45; | ||
| } | ||
| .rte-citation-backref { | ||
| margin-left: 8px; | ||
| color: #1d4ed8; | ||
| text-decoration: none; | ||
| font-size: 0.9em; | ||
| } | ||
| .rte-citation-backref:hover, | ||
| .rte-citation-backref:focus-visible { | ||
| text-decoration: underline; | ||
| outline: none; | ||
| } | ||
| .${x} .rte-citation-backref { | ||
| color: #93c5fd; | ||
| } | ||
| @media (max-width: 768px) { | ||
| .${m} { | ||
| left: 10px !important; | ||
| right: 10px; | ||
| top: 10px !important; | ||
| width: auto !important; | ||
| max-height: calc(100vh - 20px); | ||
| } | ||
| .rte-citations-grid { | ||
| grid-template-columns: 1fr; | ||
| } | ||
| .rte-citations-recent-list { | ||
| max-height: 34vh; | ||
| } | ||
| } | ||
| `, document.head.appendChild(t); | ||
| } | ||
| const le = (t = {}) => { | ||
| const o = Z(t); | ||
| return ce(), { | ||
| name: "citations", | ||
| toolbar: [ | ||
| { | ||
| id: "citationsGroup", | ||
| label: "Citations", | ||
| type: "group", | ||
| command: "citations", | ||
| items: [ | ||
| { | ||
| id: "citations", | ||
| label: "Citations", | ||
| command: "toggleCitationsPanel", | ||
| shortcut: "Mod-Alt-Shift-c", | ||
| icon: '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><path d="M6 5h12M6 9h12M6 13h8M6 17h10" stroke="currentColor" stroke-width="1.7" stroke-linecap="round"/><path d="M17 14.5a2.5 2.5 0 0 1 2.5 2.5v2H15v-2a2 2 0 0 1 2-2Z" stroke="currentColor" stroke-width="1.5"/></svg>' | ||
| }, | ||
| { | ||
| id: "citationsRefresh", | ||
| label: "Refresh Citations", | ||
| command: "refreshCitations", | ||
| shortcut: "Mod-Alt-Shift-b", | ||
| icon: '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><path d="M20 12a8 8 0 1 1-2.34-5.66" stroke="currentColor" stroke-width="1.7" stroke-linecap="round"/><path d="M20 4v6h-6" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"/></svg>' | ||
| }, | ||
| { | ||
| id: "citationsStyle", | ||
| label: "Cycle Citation Style", | ||
| command: "cycleCitationStyle", | ||
| shortcut: "Mod-Alt-Shift-j", | ||
| icon: '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><path d="M5 6h14M5 10h8M5 14h14M5 18h10" stroke="currentColor" stroke-width="1.7" stroke-linecap="round"/><circle cx="18" cy="10" r="2" stroke="currentColor" stroke-width="1.6"/></svg>' | ||
| } | ||
| ] | ||
| } | ||
| ], | ||
| commands: { | ||
| citations: (e, i) => { | ||
| const n = h(i); | ||
| if (!n || S(n)) return !1; | ||
| const r = f.get(n) || o; | ||
| return f.set(n, r), T.set(n, N(n, r)), p = n, z(n), y(n, r, !1), !0; | ||
| }, | ||
| toggleCitationsPanel: (e, i) => { | ||
| const n = h(i); | ||
| if (!n || S(n)) return !1; | ||
| const r = f.get(n) || o; | ||
| f.set(n, r), p = n; | ||
| const a = zt(n, typeof e == "boolean" ? e : void 0); | ||
| return nt(n) && y(n, r, !1), a; | ||
| }, | ||
| insertCitation: (e, i) => { | ||
| const n = h(i); | ||
| if (!n || S(n) || !e || typeof e != "object") return !1; | ||
| const r = f.get(n) || o; | ||
| f.set(n, r), p = n; | ||
| const a = et(n, e, r); | ||
| return a && z(n), a; | ||
| }, | ||
| refreshCitations: (e, i) => { | ||
| const n = h(i); | ||
| if (!n) return !1; | ||
| const r = f.get(n) || o; | ||
| return f.set(n, r), p = n, y(n, r, !0), z(n), !0; | ||
| }, | ||
| setCitationStyle: (e, i) => { | ||
| const n = h(i); | ||
| if (!n || !e) return !1; | ||
| const r = f.get(n) || o; | ||
| return f.set(n, r), p = n, Nt(n, e, r), !0; | ||
| }, | ||
| cycleCitationStyle: (e, i) => { | ||
| const n = h(i); | ||
| if (!n) return !1; | ||
| const r = f.get(n) || o; | ||
| return f.set(n, r), p = n, bt(n, r), H(n), !0; | ||
| }, | ||
| getCitationRecords: (e, i) => { | ||
| const n = h(i); | ||
| if (!n) return !1; | ||
| const r = f.get(n) || o, a = K(n, r); | ||
| if (typeof e == "function") | ||
| try { | ||
| e(a); | ||
| } catch (s) { | ||
| } | ||
| return n.__citationRecords = a, n.dispatchEvent( | ||
| new CustomEvent("editora:citations-data", { | ||
| bubbles: !0, | ||
| detail: { | ||
| records: a, | ||
| style: N(n, r) | ||
| } | ||
| }) | ||
| ), !0; | ||
| }, | ||
| setCitationsOptions: (e, i) => { | ||
| const n = h(i); | ||
| if (!n || !e || typeof e != "object") return !1; | ||
| const r = f.get(n) || o, a = Z({ | ||
| ...r, | ||
| ...e, | ||
| labels: { | ||
| ...r.labels, | ||
| ...e.labels || {} | ||
| }, | ||
| normalizeText: e.normalizeText || r.normalizeText, | ||
| generateCitationId: e.generateCitationId || r.generateCitationId | ||
| }); | ||
| return f.set(n, a), e.defaultStyle && L.includes(e.defaultStyle) && T.set(n, e.defaultStyle), y(n, a, !0), H(n), !0; | ||
| }, | ||
| locateCitation: (e, i) => { | ||
| const n = h(i); | ||
| return !n || typeof e != "string" ? !1 : Zt(n, e); | ||
| }, | ||
| deleteCitation: (e, i) => { | ||
| const n = h(i); | ||
| if (!n || S(n)) return !1; | ||
| const r = f.get(n) || o; | ||
| return f.set(n, r), typeof e == "string" && e.trim() ? Rt(n, e, r) : Jt(n, r); | ||
| }, | ||
| insertRecentCitation: (e, i) => { | ||
| const n = h(i); | ||
| if (!n || S(n)) return !1; | ||
| const r = f.get(n) || o; | ||
| f.set(n, r); | ||
| const a = K(n, r), s = rt(n, a, r); | ||
| if (s.length === 0) return !1; | ||
| const d = typeof e == "string" && e.trim() ? Et(n, e, a, r) : s[0]; | ||
| if (!d) return !1; | ||
| const c = et(n, d, r); | ||
| return c && z(n), c; | ||
| } | ||
| }, | ||
| keymap: { | ||
| "Mod-Alt-Shift-c": "toggleCitationsPanel", | ||
| "Mod-Alt-Shift-C": "toggleCitationsPanel", | ||
| "Mod-Alt-Shift-b": "refreshCitations", | ||
| "Mod-Alt-Shift-B": "refreshCitations", | ||
| "Mod-Alt-Shift-j": "cycleCitationStyle", | ||
| "Mod-Alt-Shift-J": "cycleCitationStyle" | ||
| }, | ||
| init: function(i) { | ||
| Y += 1; | ||
| const n = this && typeof this.__pluginConfig == "object" ? Z({ ...o, ...this.__pluginConfig }) : o; | ||
| ae(n); | ||
| const r = h( | ||
| i && i.editorElement ? { editorElement: i.editorElement } : void 0, | ||
| !1 | ||
| ); | ||
| r && (p = r, f.set(r, n), T.set(r, n.defaultStyle), it(r, "toggleCitationsPanel", !1), kt(r)); | ||
| }, | ||
| destroy: () => { | ||
| Y = Math.max(0, Y - 1), !(Y > 0) && (q.forEach((e) => { | ||
| window.clearTimeout(e); | ||
| }), q.clear(), se()); | ||
| } | ||
| }; | ||
| }; | ||
| export { | ||
| le as CitationsPlugin | ||
| }; | ||
| //# sourceMappingURL=CitationsPlugin.native-BnU0qCwR.mjs.map |
| const A = ".rte-content, .editora-content", P = '.rte-conditional-block[data-conditional-content="true"]', b = ':is([data-theme="dark"], .dark, .editora-theme-dark, .rte-theme-dark)', f = ':is([data-theme="acme"], .editora-theme-acme, .rte-theme-acme)', h = ":is(.rte-content.rte-conditional-theme-dark, .editora-content.rte-conditional-theme-dark)", g = ":is(.rte-content.rte-conditional-theme-acme, .editora-content.rte-conditional-theme-acme)", Se = "rte-conditional-content-styles", c = "rte-conditional-dialog-overlay", u = "rte-conditional-floating-toolbar", k = /* @__PURE__ */ new WeakMap(), Ce = /* @__PURE__ */ new WeakMap(), E = /* @__PURE__ */ new WeakMap(), j = /* @__PURE__ */ new Map(), I = /* @__PURE__ */ new Map(); | ||
| let de = null, me = 0, J = null, X = null, Q = null, ee = null, te = null, oe = null, H = null, y = null, ne = null; | ||
| const ze = { | ||
| dialogTitleInsert: "Insert Conditional Content", | ||
| dialogTitleEdit: "Edit Conditional Content", | ||
| conditionLabel: "Condition", | ||
| conditionPlaceholder: 'user.role == "admin"', | ||
| audienceLabel: "Audience (comma separated)", | ||
| audiencePlaceholder: "all", | ||
| localeLabel: "Locale (comma separated)", | ||
| localePlaceholder: "all", | ||
| elseLabel: "Enable Else Block", | ||
| saveText: "Save", | ||
| cancelText: "Cancel", | ||
| blockIfLabel: "IF", | ||
| blockElseLabel: "ELSE", | ||
| allAudiencesText: "all audiences", | ||
| allLocalesText: "all locales" | ||
| }; | ||
| function $(e) { | ||
| return e.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'"); | ||
| } | ||
| function R(e) { | ||
| return e ? e.split(",").map((t) => t.trim()).filter(Boolean) : []; | ||
| } | ||
| function Te(e) { | ||
| return !e || e.length === 0 ? "" : e.join(", "); | ||
| } | ||
| function ie(e) { | ||
| return e ? e.map((t) => t.trim()).filter(Boolean) : []; | ||
| } | ||
| function Fe(e) { | ||
| return { | ||
| ...ze, | ||
| ...e || {} | ||
| }; | ||
| } | ||
| function D(e) { | ||
| return e.getAttribute("contenteditable") === "false" || e.getAttribute("data-readonly") === "true"; | ||
| } | ||
| function se(e) { | ||
| return e.closest("[data-editora-editor], .rte-editor, .editora-editor, editora-editor") || e; | ||
| } | ||
| function pe(e) { | ||
| if (!e) return !1; | ||
| const t = e.getAttribute("data-theme") || e.getAttribute("theme"); | ||
| return t && t.toLowerCase() === "dark" ? !0 : e.classList.contains("dark") || e.classList.contains("editora-theme-dark") || e.classList.contains("rte-theme-dark"); | ||
| } | ||
| function je(e) { | ||
| const t = se(e); | ||
| if (pe(t)) return !0; | ||
| const o = t.closest("[data-theme], [theme], .dark, .editora-theme-dark, .rte-theme-dark"); | ||
| return pe(o) ? !0 : pe(document.documentElement) || pe(document.body); | ||
| } | ||
| function he(e) { | ||
| if (!e) return !1; | ||
| const t = e.getAttribute("data-theme") || e.getAttribute("theme"); | ||
| return t && t.toLowerCase() === "acme" ? !0 : e.classList.contains("editora-theme-acme") || e.classList.contains("rte-theme-acme"); | ||
| } | ||
| function Ie(e) { | ||
| const t = se(e); | ||
| if (he(t)) return !0; | ||
| const o = t.closest("[data-theme], [theme], .editora-theme-acme, .rte-theme-acme"); | ||
| return he(o) ? !0 : he(document.documentElement) || he(document.body); | ||
| } | ||
| function Ve(e) { | ||
| return je(e) ? "dark" : Ie(e) ? "acme" : "light"; | ||
| } | ||
| function xe(e, t) { | ||
| const o = Ve(t); | ||
| e.classList.remove("rte-conditional-theme-dark", "rte-conditional-theme-acme"), o === "dark" ? e.classList.add("rte-conditional-theme-dark") : o === "acme" && e.classList.add("rte-conditional-theme-acme"); | ||
| } | ||
| function w(e, t = !0) { | ||
| if ((e == null ? void 0 : e.contentElement) instanceof HTMLElement) return e.contentElement; | ||
| if ((e == null ? void 0 : e.editorElement) instanceof HTMLElement) { | ||
| const n = e.editorElement; | ||
| if (n.matches(A)) return n; | ||
| const a = n.querySelector(A); | ||
| if (a instanceof HTMLElement) return a; | ||
| } | ||
| const o = window.getSelection(); | ||
| if (o && o.rangeCount > 0) { | ||
| const n = o.getRangeAt(0).startContainer, a = n.nodeType === Node.ELEMENT_NODE ? n : n.parentElement, r = a == null ? void 0 : a.closest(A); | ||
| if (r) return r; | ||
| } | ||
| const i = document.activeElement; | ||
| if (i) { | ||
| if (i.matches(A)) return i; | ||
| const n = i.closest(A); | ||
| if (n) return n; | ||
| } | ||
| return y && y.isConnected ? y : t ? document.querySelector(A) : null; | ||
| } | ||
| function Ne(e) { | ||
| const t = window.getSelection(); | ||
| if (!t || t.rangeCount === 0) return null; | ||
| const o = t.getRangeAt(0); | ||
| return e.contains(o.commonAncestorContainer) ? o.cloneRange() : null; | ||
| } | ||
| function Le(e, t) { | ||
| const o = window.getSelection(); | ||
| o && (o.removeAllRanges(), o.addRange(t), e.focus({ preventScroll: !0 })); | ||
| } | ||
| function De(e) { | ||
| e.dispatchEvent(new Event("input", { bubbles: !0 })); | ||
| } | ||
| function He(e, t) { | ||
| if (t === e.innerHTML) return; | ||
| const o = window.execEditorCommand || window.executeEditorCommand; | ||
| if (typeof o == "function") | ||
| try { | ||
| o("recordDomTransaction", e, t, e.innerHTML); | ||
| } catch (i) { | ||
| } | ||
| } | ||
| function $e(e, t) { | ||
| const o = document.createRange(); | ||
| o.selectNodeContents(t), o.collapse(!1), Le(e, o); | ||
| } | ||
| function ve(e, t) { | ||
| if (t) | ||
| return t.split(".").filter(Boolean).reduce((o, i) => { | ||
| if (o != null && typeof o == "object") | ||
| return o[i]; | ||
| }, e); | ||
| } | ||
| function We(e) { | ||
| const t = e.trim(); | ||
| if (t.startsWith('"') && t.endsWith('"') || t.startsWith("'") && t.endsWith("'")) | ||
| return t.slice(1, -1); | ||
| if (t === "true") return !0; | ||
| if (t === "false") return !1; | ||
| if (t === "null") return null; | ||
| const o = Number(t); | ||
| if (!Number.isNaN(o) && t !== "") return o; | ||
| if (t.startsWith("[") && t.endsWith("]") || t.startsWith("{") && t.endsWith("}")) | ||
| try { | ||
| return JSON.parse(t); | ||
| } catch (i) { | ||
| return t; | ||
| } | ||
| return t; | ||
| } | ||
| function Ze(e, t) { | ||
| const o = e.trim(); | ||
| if (!o) return !0; | ||
| if (o.startsWith("!")) { | ||
| const x = o.slice(1).trim(); | ||
| return !ve(t, x); | ||
| } | ||
| const i = o.match(/^([a-zA-Z_$][\w.$]*)\s*(==|!=|>=|<=|>|<|in|contains|~=)\s*(.+)$/); | ||
| if (!i) | ||
| return !!ve(t, o); | ||
| const [, n, a, r] = i, l = ve(t, n), d = We(r); | ||
| switch (a) { | ||
| case "==": | ||
| return l == d; | ||
| case "!=": | ||
| return l != d; | ||
| case ">": | ||
| return Number(l) > Number(d); | ||
| case "<": | ||
| return Number(l) < Number(d); | ||
| case ">=": | ||
| return Number(l) >= Number(d); | ||
| case "<=": | ||
| return Number(l) <= Number(d); | ||
| case "in": | ||
| return Array.isArray(d) ? d.some((x) => x == l) : typeof d == "string" ? d.split(",").map((x) => x.trim()).includes(String(l)) : !1; | ||
| case "contains": | ||
| case "~=": | ||
| return Array.isArray(l) ? l.some((x) => String(x).toLowerCase() === String(d).toLowerCase()) : typeof l == "string" ? l.toLowerCase().includes(String(d).toLowerCase()) : !1; | ||
| default: | ||
| return !1; | ||
| } | ||
| } | ||
| function Ge() { | ||
| if (typeof document == "undefined" || document.getElementById(Se)) return; | ||
| const e = document.createElement("style"); | ||
| e.id = Se, e.textContent = ` | ||
| .rte-conditional-block { | ||
| border: 1px solid #dbe3ec; | ||
| border-radius: 8px; | ||
| margin: 10px 0; | ||
| background: #f8fafc; | ||
| overflow: hidden; | ||
| } | ||
| .rte-conditional-header, | ||
| .rte-conditional-else-label { | ||
| display: flex; | ||
| align-items: center; | ||
| gap: 8px; | ||
| background: #eef2f7; | ||
| border-bottom: 1px solid #dbe3ec; | ||
| padding: 8px 10px; | ||
| user-select: none; | ||
| } | ||
| .rte-conditional-else-label { | ||
| border-top: 1px solid #dbe3ec; | ||
| border-bottom: 1px solid #dbe3ec; | ||
| } | ||
| .rte-conditional-chip { | ||
| display: inline-flex; | ||
| align-items: center; | ||
| justify-content: center; | ||
| min-width: 34px; | ||
| height: 20px; | ||
| border-radius: 999px; | ||
| border: 1px solid #bfdbfe; | ||
| background: #dbeafe; | ||
| color: #1e3a8a; | ||
| font-size: 11px; | ||
| font-weight: 700; | ||
| letter-spacing: 0.03em; | ||
| text-transform: uppercase; | ||
| padding: 0 7px; | ||
| flex: 0 0 auto; | ||
| } | ||
| .rte-conditional-chip-else { | ||
| border-color: #fecaca; | ||
| background: #fee2e2; | ||
| color: #991b1b; | ||
| } | ||
| .rte-conditional-summary { | ||
| font-size: 12px; | ||
| color: #0f172a; | ||
| font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; | ||
| overflow: hidden; | ||
| text-overflow: ellipsis; | ||
| white-space: nowrap; | ||
| flex: 1; | ||
| } | ||
| .rte-conditional-meta { | ||
| font-size: 11px; | ||
| color: #64748b; | ||
| white-space: nowrap; | ||
| flex: 0 0 auto; | ||
| } | ||
| .rte-conditional-body { | ||
| padding: 10px; | ||
| background: #ffffff; | ||
| min-height: 44px; | ||
| } | ||
| .rte-conditional-hidden { | ||
| display: none !important; | ||
| } | ||
| .rte-toolbar-group-items.conditional-content, | ||
| .editora-toolbar-group-items.conditional-content { | ||
| display: flex; | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 6px; | ||
| background: #ffffff; | ||
| } | ||
| .rte-toolbar-group-items.conditional-content .rte-toolbar-item, | ||
| .editora-toolbar-group-items.conditional-content .editora-toolbar-item { | ||
| display: flex; | ||
| } | ||
| .rte-toolbar-group-items.conditional-content .rte-toolbar-button, | ||
| .editora-toolbar-group-items.conditional-content .editora-toolbar-button { | ||
| border: none; | ||
| border-right: 1px solid #cbd5e1; | ||
| border-radius: 0; | ||
| } | ||
| .rte-toolbar-group-items.conditional-content .rte-toolbar-item:last-child .rte-toolbar-button, | ||
| .editora-toolbar-group-items.conditional-content .editora-toolbar-item:last-child .editora-toolbar-button { | ||
| border-right: none; | ||
| } | ||
| .rte-toolbar-button[data-command="toggleConditionalPreview"].active, | ||
| .editora-toolbar-button[data-command="toggleConditionalPreview"].active { | ||
| background: #ccc; | ||
| } | ||
| .rte-conditional-block.rte-conditional-preview { | ||
| border-style: dashed; | ||
| } | ||
| .rte-conditional-block.rte-conditional-preview .rte-conditional-body[contenteditable="false"] { | ||
| cursor: default; | ||
| } | ||
| .${c} { | ||
| position: fixed; | ||
| inset: 0; | ||
| background: rgba(15, 23, 42, 0.5); | ||
| z-index: 2147483646; | ||
| display: flex; | ||
| align-items: center; | ||
| justify-content: center; | ||
| padding: 20px; | ||
| } | ||
| .rte-conditional-dialog { | ||
| width: min(560px, 96vw); | ||
| max-height: min(88vh, 760px); | ||
| border: 1px solid #dbe3ec; | ||
| border-radius: 8px; | ||
| background: #ffffff; | ||
| box-shadow: 0 24px 50px rgba(15, 23, 42, 0.25); | ||
| display: flex; | ||
| flex-direction: column; | ||
| overflow: hidden; | ||
| } | ||
| .rte-conditional-dialog-header, | ||
| .rte-conditional-dialog-footer { | ||
| padding: 12px 14px; | ||
| border-bottom: 1px solid #e2e8f0; | ||
| background: #f8fafc; | ||
| display: flex; | ||
| align-items: center; | ||
| justify-content: space-between; | ||
| gap: 10px; | ||
| } | ||
| .rte-conditional-dialog-footer { | ||
| border-top: 1px solid #e2e8f0; | ||
| border-bottom: none; | ||
| justify-content: flex-end; | ||
| } | ||
| .rte-conditional-dialog-title { | ||
| margin: 0; | ||
| font-size: 16px; | ||
| font-weight: 700; | ||
| color: #0f172a; | ||
| } | ||
| .rte-conditional-dialog-body { | ||
| padding: 14px; | ||
| overflow: auto; | ||
| display: grid; | ||
| grid-template-columns: 1fr; | ||
| gap: 12px; | ||
| } | ||
| .rte-conditional-field { | ||
| display: grid; | ||
| gap: 6px; | ||
| } | ||
| .rte-conditional-field label { | ||
| font-size: 12px; | ||
| font-weight: 600; | ||
| color: #334155; | ||
| } | ||
| .rte-conditional-field input[type="text"] { | ||
| width: 100%; | ||
| min-height: 36px; | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 6px; | ||
| padding: 8px 10px; | ||
| font-size: 13px; | ||
| line-height: 1.4; | ||
| box-sizing: border-box; | ||
| color: #0f172a; | ||
| background: #ffffff; | ||
| } | ||
| .rte-conditional-field input[type="text"]:focus-visible, | ||
| .rte-conditional-btn:focus-visible { | ||
| outline: none; | ||
| border-color: #3b82f6; | ||
| box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.2); | ||
| } | ||
| .rte-conditional-checkbox { | ||
| display: inline-flex; | ||
| align-items: center; | ||
| gap: 8px; | ||
| font-size: 13px; | ||
| color: #334155; | ||
| min-height: 36px; | ||
| } | ||
| .rte-conditional-help { | ||
| margin: 0; | ||
| font-size: 12px; | ||
| color: #64748b; | ||
| } | ||
| .rte-conditional-btn { | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 6px; | ||
| min-height: 34px; | ||
| padding: 6px 12px; | ||
| background: #ffffff; | ||
| color: #0f172a; | ||
| font-size: 13px; | ||
| cursor: pointer; | ||
| } | ||
| .rte-conditional-btn-primary { | ||
| border-color: #2563eb; | ||
| background: #2563eb; | ||
| color: #ffffff; | ||
| } | ||
| .rte-conditional-btn-primary:hover { | ||
| background: #1d4ed8; | ||
| } | ||
| .${u} { | ||
| position: fixed; | ||
| z-index: 2147483645; | ||
| display: none; | ||
| align-items: center; | ||
| gap: 6px; | ||
| padding: 6px; | ||
| border-radius: 8px; | ||
| border: 1px solid #cbd5e1; | ||
| background: rgba(255, 255, 255, 0.98); | ||
| box-shadow: 0 14px 30px rgba(15, 23, 42, 0.2); | ||
| backdrop-filter: blur(6px); | ||
| } | ||
| .${u}.show { | ||
| display: inline-flex; | ||
| } | ||
| .${u} .rte-conditional-float-btn { | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 6px; | ||
| min-height: 30px; | ||
| min-width: 30px; | ||
| padding: 0 8px; | ||
| display: inline-flex; | ||
| align-items: center; | ||
| justify-content: center; | ||
| gap: 6px; | ||
| background: #ffffff; | ||
| color: #0f172a; | ||
| cursor: pointer; | ||
| font-size: 12px; | ||
| line-height: 1; | ||
| } | ||
| .${u} .rte-conditional-float-btn:hover { | ||
| background: #f8fafc; | ||
| } | ||
| .${u} .rte-conditional-float-btn[data-action="delete"] { | ||
| border-color: #fecaca; | ||
| color: #991b1b; | ||
| background: #fff5f5; | ||
| } | ||
| .rte-conditional-preview-on ${P} { | ||
| border-width: 2px; | ||
| } | ||
| .rte-conditional-preview-on ${P} .rte-conditional-header { | ||
| background: #ecfeff; | ||
| border-color: #bae6fd; | ||
| } | ||
| ${b} .rte-conditional-block, | ||
| ${h} .rte-conditional-block, | ||
| .${c}.rte-conditional-theme-dark .rte-conditional-block { | ||
| background: #111827; | ||
| border-color: #334155; | ||
| } | ||
| ${b} .rte-conditional-header, | ||
| ${b} .rte-conditional-else-label, | ||
| ${h} .rte-conditional-header, | ||
| ${h} .rte-conditional-else-label, | ||
| .${c}.rte-conditional-theme-dark .rte-conditional-header, | ||
| .${c}.rte-conditional-theme-dark .rte-conditional-else-label { | ||
| background: #0f172a; | ||
| border-color: #334155; | ||
| } | ||
| ${b} .rte-conditional-summary, | ||
| ${h} .rte-conditional-summary, | ||
| .${c}.rte-conditional-theme-dark .rte-conditional-summary { | ||
| color: #e2e8f0; | ||
| } | ||
| ${b} .rte-conditional-meta, | ||
| ${h} .rte-conditional-meta, | ||
| .${c}.rte-conditional-theme-dark .rte-conditional-meta { | ||
| color: #94a3b8; | ||
| } | ||
| ${b} .rte-conditional-chip, | ||
| ${h} .rte-conditional-chip, | ||
| .${c}.rte-conditional-theme-dark .rte-conditional-chip { | ||
| background: #1e3a8a; | ||
| border-color: #3b82f6; | ||
| color: #dbeafe; | ||
| } | ||
| ${b} .rte-conditional-chip-else, | ||
| ${h} .rte-conditional-chip-else, | ||
| .${c}.rte-conditional-theme-dark .rte-conditional-chip-else { | ||
| background: #7f1d1d; | ||
| border-color: #ef4444; | ||
| color: #fee2e2; | ||
| } | ||
| ${b} .rte-conditional-body, | ||
| ${h} .rte-conditional-body, | ||
| .${c}.rte-conditional-theme-dark .rte-conditional-body { | ||
| background: #1f2937; | ||
| color: #e2e8f0; | ||
| } | ||
| ${b} .rte-conditional-dialog, | ||
| ${h} .rte-conditional-dialog, | ||
| .${c}.rte-conditional-theme-dark .rte-conditional-dialog { | ||
| background: #1f2937; | ||
| border-color: #334155; | ||
| } | ||
| ${b} .rte-conditional-dialog-header, | ||
| ${b} .rte-conditional-dialog-footer, | ||
| ${h} .rte-conditional-dialog-header, | ||
| ${h} .rte-conditional-dialog-footer, | ||
| .${c}.rte-conditional-theme-dark .rte-conditional-dialog-header, | ||
| .${c}.rte-conditional-theme-dark .rte-conditional-dialog-footer { | ||
| background: #111827; | ||
| border-color: #334155; | ||
| } | ||
| ${b} .rte-conditional-dialog-title, | ||
| ${b} .rte-conditional-field label, | ||
| ${b} .rte-conditional-checkbox, | ||
| ${h} .rte-conditional-dialog-title, | ||
| ${h} .rte-conditional-field label, | ||
| ${h} .rte-conditional-checkbox, | ||
| .${c}.rte-conditional-theme-dark .rte-conditional-dialog-title, | ||
| .${c}.rte-conditional-theme-dark .rte-conditional-field label, | ||
| .${c}.rte-conditional-theme-dark .rte-conditional-checkbox { | ||
| color: #e2e8f0; | ||
| } | ||
| ${b} .rte-conditional-help, | ||
| ${h} .rte-conditional-help, | ||
| .${c}.rte-conditional-theme-dark .rte-conditional-help { | ||
| color: #94a3b8; | ||
| } | ||
| ${b} .rte-conditional-field input[type="text"], | ||
| ${b} .rte-conditional-btn, | ||
| ${h} .rte-conditional-field input[type="text"], | ||
| ${h} .rte-conditional-btn, | ||
| .${c}.rte-conditional-theme-dark .rte-conditional-field input[type="text"], | ||
| .${c}.rte-conditional-theme-dark .rte-conditional-btn { | ||
| background: #0f172a; | ||
| border-color: #475569; | ||
| color: #e2e8f0; | ||
| } | ||
| ${b} .rte-conditional-btn-primary, | ||
| ${h} .rte-conditional-btn-primary, | ||
| .${c}.rte-conditional-theme-dark .rte-conditional-btn-primary { | ||
| border-color: #3b82f6; | ||
| background: #2563eb; | ||
| color: #ffffff; | ||
| } | ||
| ${b} .rte-toolbar-group-items.conditional-content, | ||
| .${c}.rte-conditional-theme-dark .rte-toolbar-group-items.conditional-content, | ||
| ${h} .rte-toolbar-group-items.conditional-content, | ||
| ${b} .editora-toolbar-group-items.conditional-content { | ||
| border-color: #566275; | ||
| } | ||
| ${b} .rte-toolbar-group-items.conditional-content .rte-toolbar-button, | ||
| ${h} .rte-toolbar-group-items.conditional-content .rte-toolbar-button, | ||
| ${b} .editora-toolbar-group-items.conditional-content .editora-toolbar-button { | ||
| border-right-color: #566275; | ||
| } | ||
| ${b} .${u}, | ||
| .${c}.rte-conditional-theme-dark .${u}, | ||
| .${u}.rte-conditional-theme-dark { | ||
| background: rgba(17, 24, 39, 0.98); | ||
| border-color: #334155; | ||
| box-shadow: 0 14px 30px rgba(2, 6, 23, 0.5); | ||
| } | ||
| ${b} .${u} .rte-conditional-float-btn, | ||
| .${c}.rte-conditional-theme-dark .${u} .rte-conditional-float-btn, | ||
| .${u}.rte-conditional-theme-dark .rte-conditional-float-btn { | ||
| background: #0f172a; | ||
| border-color: #475569; | ||
| color: #e2e8f0; | ||
| } | ||
| ${b} .${u} .rte-conditional-float-btn[data-action="delete"], | ||
| .${c}.rte-conditional-theme-dark .${u} .rte-conditional-float-btn[data-action="delete"], | ||
| .${u}.rte-conditional-theme-dark .rte-conditional-float-btn[data-action="delete"] { | ||
| border-color: #ef4444; | ||
| color: #fecaca; | ||
| background: rgba(127, 29, 29, 0.45); | ||
| } | ||
| ${f} .rte-conditional-block, | ||
| ${g} .rte-conditional-block, | ||
| .${c}.rte-conditional-theme-acme .rte-conditional-block { | ||
| background: #f8fbff; | ||
| border-color: #cbd8e8; | ||
| } | ||
| ${f} .rte-conditional-header, | ||
| ${f} .rte-conditional-else-label, | ||
| ${g} .rte-conditional-header, | ||
| ${g} .rte-conditional-else-label, | ||
| .${c}.rte-conditional-theme-acme .rte-conditional-header, | ||
| .${c}.rte-conditional-theme-acme .rte-conditional-else-label { | ||
| background: linear-gradient(180deg, #eef4fb 0%, #e6eef8 100%); | ||
| border-color: #cbd8e8; | ||
| } | ||
| ${f} .rte-conditional-summary, | ||
| ${g} .rte-conditional-summary, | ||
| .${c}.rte-conditional-theme-acme .rte-conditional-summary { | ||
| color: #0f172a; | ||
| } | ||
| ${f} .rte-conditional-meta, | ||
| ${g} .rte-conditional-meta, | ||
| .${c}.rte-conditional-theme-acme .rte-conditional-meta { | ||
| color: #587089; | ||
| } | ||
| ${f} .rte-conditional-chip, | ||
| ${g} .rte-conditional-chip, | ||
| .${c}.rte-conditional-theme-acme .rte-conditional-chip { | ||
| background: #d9f5ee; | ||
| border-color: #66c6b3; | ||
| color: #0f4f4a; | ||
| } | ||
| ${f} .rte-conditional-chip-else, | ||
| ${g} .rte-conditional-chip-else, | ||
| .${c}.rte-conditional-theme-acme .rte-conditional-chip-else { | ||
| background: #fde8ea; | ||
| border-color: #f1a7b2; | ||
| color: #8b1f2f; | ||
| } | ||
| ${f} .rte-conditional-body, | ||
| ${g} .rte-conditional-body, | ||
| .${c}.rte-conditional-theme-acme .rte-conditional-body { | ||
| background: #fcfeff; | ||
| color: #0f172a; | ||
| } | ||
| ${f} .rte-conditional-dialog, | ||
| ${g} .rte-conditional-dialog, | ||
| .${c}.rte-conditional-theme-acme .rte-conditional-dialog { | ||
| background: #ffffff; | ||
| border-color: #cbd8e8; | ||
| box-shadow: 0 20px 44px rgba(15, 23, 42, 0.18); | ||
| } | ||
| ${f} .rte-conditional-dialog-header, | ||
| ${f} .rte-conditional-dialog-footer, | ||
| ${g} .rte-conditional-dialog-header, | ||
| ${g} .rte-conditional-dialog-footer, | ||
| .${c}.rte-conditional-theme-acme .rte-conditional-dialog-header, | ||
| .${c}.rte-conditional-theme-acme .rte-conditional-dialog-footer { | ||
| background: #f3f8fd; | ||
| border-color: #d8e4f1; | ||
| } | ||
| ${f} .rte-conditional-dialog-title, | ||
| ${f} .rte-conditional-field label, | ||
| ${f} .rte-conditional-checkbox, | ||
| ${g} .rte-conditional-dialog-title, | ||
| ${g} .rte-conditional-field label, | ||
| ${g} .rte-conditional-checkbox, | ||
| .${c}.rte-conditional-theme-acme .rte-conditional-dialog-title, | ||
| .${c}.rte-conditional-theme-acme .rte-conditional-field label, | ||
| .${c}.rte-conditional-theme-acme .rte-conditional-checkbox { | ||
| color: #1f334a; | ||
| } | ||
| ${f} .rte-conditional-help, | ||
| ${g} .rte-conditional-help, | ||
| .${c}.rte-conditional-theme-acme .rte-conditional-help { | ||
| color: #5f738d; | ||
| } | ||
| ${f} .rte-conditional-field input[type="text"], | ||
| ${f} .rte-conditional-btn, | ||
| ${g} .rte-conditional-field input[type="text"], | ||
| ${g} .rte-conditional-btn, | ||
| .${c}.rte-conditional-theme-acme .rte-conditional-field input[type="text"], | ||
| .${c}.rte-conditional-theme-acme .rte-conditional-btn { | ||
| background: #ffffff; | ||
| border-color: #bfd0e2; | ||
| color: #0f172a; | ||
| } | ||
| ${f} .rte-conditional-btn-primary, | ||
| ${g} .rte-conditional-btn-primary, | ||
| .${c}.rte-conditional-theme-acme .rte-conditional-btn-primary { | ||
| border-color: #0f766e; | ||
| background: #0f766e; | ||
| color: #ffffff; | ||
| } | ||
| ${f} .rte-toolbar-group-items.conditional-content, | ||
| .${c}.rte-conditional-theme-acme .rte-toolbar-group-items.conditional-content, | ||
| ${g} .rte-toolbar-group-items.conditional-content, | ||
| ${f} .editora-toolbar-group-items.conditional-content { | ||
| border-color: #bfd0e2; | ||
| } | ||
| ${f} .rte-toolbar-group-items.conditional-content .rte-toolbar-button, | ||
| ${g} .rte-toolbar-group-items.conditional-content .rte-toolbar-button, | ||
| ${f} .editora-toolbar-group-items.conditional-content .editora-toolbar-button { | ||
| border-right-color: #bfd0e2; | ||
| } | ||
| ${f} .${u}, | ||
| .${c}.rte-conditional-theme-acme .${u}, | ||
| .${u}.rte-conditional-theme-acme { | ||
| background: rgba(255, 255, 255, 0.98); | ||
| border-color: #bfd0e2; | ||
| box-shadow: 0 14px 28px rgba(15, 23, 42, 0.16); | ||
| } | ||
| ${f} .${u} .rte-conditional-float-btn, | ||
| .${c}.rte-conditional-theme-acme .${u} .rte-conditional-float-btn, | ||
| .${u}.rte-conditional-theme-acme .rte-conditional-float-btn { | ||
| background: #ffffff; | ||
| border-color: #bfd0e2; | ||
| color: #1f334a; | ||
| } | ||
| ${f} .${u} .rte-conditional-float-btn:hover, | ||
| .${c}.rte-conditional-theme-acme .${u} .rte-conditional-float-btn:hover, | ||
| .${u}.rte-conditional-theme-acme .rte-conditional-float-btn:hover { | ||
| background: #eef7f5; | ||
| color: #0f4f4a; | ||
| } | ||
| ${f} .${u} .rte-conditional-float-btn[data-action="delete"], | ||
| .${c}.rte-conditional-theme-acme .${u} .rte-conditional-float-btn[data-action="delete"], | ||
| .${u}.rte-conditional-theme-acme .rte-conditional-float-btn[data-action="delete"] { | ||
| border-color: #f1a7b2; | ||
| color: #8b1f2f; | ||
| background: #fff4f6; | ||
| } | ||
| `, document.head.appendChild(e); | ||
| } | ||
| function Ue(e) { | ||
| return { | ||
| defaultCondition: e.defaultCondition || "", | ||
| defaultAudience: ie(e.defaultAudience || []), | ||
| defaultLocale: ie(e.defaultLocale || []), | ||
| enableElseByDefault: e.enableElseByDefault === !0, | ||
| labels: Fe(e.labels), | ||
| context: e.context, | ||
| getContext: e.getContext, | ||
| currentAudience: e.currentAudience, | ||
| currentLocale: e.currentLocale, | ||
| evaluateCondition: e.evaluateCondition || Ze | ||
| }; | ||
| } | ||
| function Oe() { | ||
| de && (de.cleanup(), de = null); | ||
| } | ||
| function Ye(e) { | ||
| return e ? e.nodeType === Node.ELEMENT_NODE ? e : e.parentElement : null; | ||
| } | ||
| function ae(e, t) { | ||
| e.setAttribute("contenteditable", "false"), e.setAttribute("spellcheck", "false"); | ||
| const o = e.querySelector(".rte-conditional-header"); | ||
| o && (o.setAttribute("contenteditable", "false"), o.setAttribute("tabindex", "0"), o.setAttribute("role", "button"), o.setAttribute("aria-label", "Edit conditional rule")); | ||
| const i = e.querySelector(".rte-conditional-else-label"); | ||
| i && i.setAttribute("contenteditable", "false"), Qe(e, !t); | ||
| } | ||
| function Je(e) { | ||
| const t = e.querySelector('.rte-conditional-body[data-slot="if"]'); | ||
| if (!t) return; | ||
| const o = /* @__PURE__ */ new Set(), i = e.querySelector(".rte-conditional-header"), n = e.querySelector(".rte-conditional-else-label"), a = e.querySelector('.rte-conditional-body[data-slot="else"]'); | ||
| i && o.add(i), o.add(t), n && o.add(n), a && o.add(a), Array.from(e.childNodes).forEach((l) => { | ||
| if (!(l instanceof HTMLElement && o.has(l))) { | ||
| if (l.nodeType === Node.TEXT_NODE && !(l.textContent || "").trim()) { | ||
| l.remove(); | ||
| return; | ||
| } | ||
| t.appendChild(l); | ||
| } | ||
| }); | ||
| } | ||
| function U(e) { | ||
| const t = window.getSelection(); | ||
| if (t && t.rangeCount > 0) { | ||
| const n = t.getRangeAt(0).startContainer, a = n.nodeType === Node.ELEMENT_NODE ? n : n.parentElement, r = a == null ? void 0 : a.closest(P); | ||
| if (r && e.contains(r)) return r; | ||
| } | ||
| const o = document.activeElement, i = o == null ? void 0 : o.closest(P); | ||
| return i && e.contains(i) ? i : null; | ||
| } | ||
| function Ae(e, t) { | ||
| let o = e.querySelector(".rte-conditional-else-label"), i = e.querySelector('.rte-conditional-body[data-slot="else"]'); | ||
| o || (o = document.createElement("div"), o.className = "rte-conditional-else-label", o.setAttribute("contenteditable", "false"), o.innerHTML = ` | ||
| <span class="rte-conditional-chip rte-conditional-chip-else">${$(t.blockElseLabel)}</span> | ||
| <span class="rte-conditional-summary">Else branch</span> | ||
| `, e.appendChild(o)), i || (i = document.createElement("div"), i.className = "rte-conditional-body rte-conditional-else-body", i.setAttribute("data-slot", "else"), i.innerHTML = "<p><br></p>", e.appendChild(i)); | ||
| } | ||
| function Xe(e, t) { | ||
| e.setAttribute("data-has-else", t ? "true" : "false"); | ||
| const o = e.querySelector(".rte-conditional-else-label"), i = e.querySelector('.rte-conditional-body[data-slot="else"]'); | ||
| o && o.classList.toggle("rte-conditional-hidden", !t), i && i.classList.toggle("rte-conditional-hidden", !t); | ||
| } | ||
| function Qe(e, t) { | ||
| Array.from(e.querySelectorAll(".rte-conditional-body")).forEach((i) => { | ||
| i.setAttribute("contenteditable", t ? "true" : "false"); | ||
| }), e.setAttribute("contenteditable", "false"); | ||
| } | ||
| function we(e, t) { | ||
| const o = e.getAttribute("data-condition") || "", i = R(e.getAttribute("data-audience")), n = R(e.getAttribute("data-locale")); | ||
| let a = e.querySelector(".rte-conditional-header"); | ||
| a || (a = document.createElement("div"), a.className = "rte-conditional-header", e.prepend(a)), a.setAttribute("contenteditable", "false"), a.setAttribute("tabindex", "0"), a.setAttribute("role", "button"), a.setAttribute("aria-label", "Edit conditional rule"); | ||
| const r = o || "(always true)", l = i.length > 0 ? i.join(", ") : t.allAudiencesText, d = n.length > 0 ? n.join(", ") : t.allLocalesText; | ||
| if (a.innerHTML = ` | ||
| <span class="rte-conditional-chip">${$(t.blockIfLabel)}</span> | ||
| <span class="rte-conditional-summary">${$(r)}</span> | ||
| <span class="rte-conditional-meta">${$(l)} · ${$(d)}</span> | ||
| `, !e.querySelector('.rte-conditional-body[data-slot="if"]')) { | ||
| const m = document.createElement("div"); | ||
| m.className = "rte-conditional-body", m.setAttribute("data-slot", "if"), m.innerHTML = "<p><br></p>", e.insertBefore(m, e.children[1] || null); | ||
| } | ||
| const v = e.getAttribute("data-has-else") === "true"; | ||
| v && Ae(e, t), Je(e), Xe(e, v); | ||
| } | ||
| function Pe(e, t) { | ||
| const o = document.createElement("section"); | ||
| o.className = "rte-conditional-block", o.setAttribute("data-conditional-content", "true"), o.setAttribute("data-condition", (e.condition || "").trim()), o.setAttribute("data-audience", ie(e.audience).join(",")), o.setAttribute("data-locale", ie(e.locale).join(",")), o.setAttribute("data-has-else", e.hasElse ? "true" : "false"), o.setAttribute("role", "group"), o.setAttribute("aria-label", "Conditional content block"), o.setAttribute("contenteditable", "false"), o.setAttribute("spellcheck", "false"); | ||
| const i = document.createElement("div"); | ||
| i.className = "rte-conditional-header", i.setAttribute("contenteditable", "false"); | ||
| const n = document.createElement("div"); | ||
| return n.className = "rte-conditional-body", n.setAttribute("data-slot", "if"), n.innerHTML = "<p><br></p>", o.appendChild(i), o.appendChild(n), e.hasElse && Ae(o, t), we(o, t), ae(o, !1), o; | ||
| } | ||
| function et(e, t) { | ||
| if (t) | ||
| try { | ||
| if (!e.isConnected) return; | ||
| const o = e.contains(t.startContainer), i = e.contains(t.endContainer); | ||
| if (!o || !i) return; | ||
| Le(e, t); | ||
| } catch (o) { | ||
| } | ||
| } | ||
| function tt(e) { | ||
| return (e.textContent || "").replace(/\u200B/g, "").trim().length > 0 ? !0 : e.querySelector("img, video, table, iframe, hr, pre, blockquote, ul, ol") !== null; | ||
| } | ||
| function Re(e, t, o) { | ||
| let i = null; | ||
| i || (i = Ne(e)), i || (i = document.createRange(), i.selectNodeContents(e), i.collapse(!1)); | ||
| let n = null; | ||
| i.collapsed || (n = i.extractContents()), i.insertNode(t); | ||
| const a = t.querySelector('.rte-conditional-body[data-slot="if"]'); | ||
| a && n && tt(n) && (a.innerHTML = "", a.appendChild(n)), a ? $e(e, a) : $e(e, t), e.normalize(); | ||
| } | ||
| function ot(e) { | ||
| return { | ||
| condition: e.getAttribute("data-condition") || "", | ||
| audience: R(e.getAttribute("data-audience")), | ||
| locale: R(e.getAttribute("data-locale")), | ||
| hasElse: e.getAttribute("data-has-else") === "true" | ||
| }; | ||
| } | ||
| function nt(e, t, o) { | ||
| e.setAttribute("data-condition", (t.condition || "").trim()), e.setAttribute("data-audience", ie(t.audience).join(",")), e.setAttribute("data-locale", ie(t.locale).join(",")), e.setAttribute("data-has-else", t.hasElse ? "true" : "false"), t.hasElse && Ae(e, o), we(e, o), ae(e, e.classList.contains("rte-conditional-preview")); | ||
| } | ||
| function re(e, t) { | ||
| xe(e, e); | ||
| const o = Array.from(e.querySelectorAll(P)), i = k.get(e) === !0; | ||
| return o.forEach((n) => { | ||
| n.classList.add("rte-conditional-block"), n.setAttribute("data-conditional-content", "true"), n.hasAttribute("data-condition") || n.setAttribute("data-condition", ""), n.hasAttribute("data-audience") || n.setAttribute("data-audience", ""), n.hasAttribute("data-locale") || n.setAttribute("data-locale", ""), n.hasAttribute("data-has-else") || n.setAttribute("data-has-else", "false"), n.setAttribute("role", "group"), n.setAttribute("aria-label", "Conditional content block"), n.setAttribute("contenteditable", "false"), n.setAttribute("spellcheck", "false"), we(n, t), ae(n, i); | ||
| }), o; | ||
| } | ||
| async function it(e, t) { | ||
| const o = Ce.get(e); | ||
| if (o) | ||
| return o; | ||
| if (typeof t.getContext == "function") | ||
| try { | ||
| const i = se(e), n = await Promise.resolve(t.getContext({ editor: e, editorRoot: i })); | ||
| if (n && typeof n == "object") | ||
| return n; | ||
| } catch (i) { | ||
| return {}; | ||
| } | ||
| if (typeof t.context == "function") | ||
| try { | ||
| const i = t.context(); | ||
| if (i && typeof i == "object") | ||
| return i; | ||
| } catch (i) { | ||
| return {}; | ||
| } | ||
| return t.context && typeof t.context == "object" ? t.context : {}; | ||
| } | ||
| function ge(e) { | ||
| return Array.isArray(e) ? e.map((t) => t.trim().toLowerCase()).filter(Boolean) : typeof e == "string" ? e.split(",").map((t) => t.trim().toLowerCase()).filter(Boolean) : []; | ||
| } | ||
| function Be(e, t) { | ||
| return e.length === 0 || e.includes("all") ? !0 : t.length === 0 ? !1 : e.some((o) => t.includes(o)); | ||
| } | ||
| async function Y(e, t, o) { | ||
| var T, ue, B, V; | ||
| const i = t.labels, n = re(e, i); | ||
| if (k.set(e, o), qe(e, o), se(e).classList.toggle("rte-conditional-preview-on", o), !o) { | ||
| n.forEach((p) => { | ||
| p.classList.remove("rte-conditional-preview"), ae(p, !1); | ||
| const M = p.querySelector('.rte-conditional-body[data-slot="if"]'), C = p.querySelector('.rte-conditional-body[data-slot="else"]'), q = p.querySelector(".rte-conditional-else-label"), N = p.getAttribute("data-has-else") === "true"; | ||
| M && (M.classList.remove("rte-conditional-hidden"), M.removeAttribute("aria-hidden")), C && (C.classList.toggle("rte-conditional-hidden", !N), C.setAttribute("aria-hidden", N ? "false" : "true")), q && q.classList.toggle("rte-conditional-hidden", !N); | ||
| }); | ||
| return; | ||
| } | ||
| const r = await it(e, t), l = ge(t.currentAudience), d = ge(t.currentLocale), x = ge( | ||
| (ue = r.audience) != null ? ue : (T = r.user) == null ? void 0 : T.audience | ||
| ), v = ge( | ||
| (V = r.locale) != null ? V : (B = r.user) == null ? void 0 : B.locale | ||
| ), m = l.length > 0 ? l : x, S = d.length > 0 ? d : v; | ||
| n.forEach((p) => { | ||
| const M = p.getAttribute("data-condition") || "", C = R(p.getAttribute("data-audience")).map((s) => s.toLowerCase()), q = R(p.getAttribute("data-locale")).map((s) => s.toLowerCase()), N = p.getAttribute("data-has-else") === "true", Ee = t.evaluateCondition(M, r), fe = Be(C, m), be = Be(q, S), K = Ee && fe && be, W = p.querySelector('.rte-conditional-body[data-slot="if"]'), Z = p.querySelector('.rte-conditional-body[data-slot="else"]'), le = p.querySelector(".rte-conditional-else-label"); | ||
| if (p.classList.add("rte-conditional-preview"), ae(p, !0), W && (W.classList.toggle("rte-conditional-hidden", !K), W.setAttribute("aria-hidden", K ? "false" : "true")), Z) { | ||
| const s = N && !K; | ||
| Z.classList.toggle("rte-conditional-hidden", !s), Z.setAttribute("aria-hidden", s ? "false" : "true"); | ||
| } | ||
| if (le) { | ||
| const s = N && !K; | ||
| le.classList.toggle("rte-conditional-hidden", !s); | ||
| } | ||
| }); | ||
| } | ||
| function qe(e, t) { | ||
| const o = se(e); | ||
| Array.from( | ||
| o.querySelectorAll('[data-command="toggleConditionalPreview"], [data-command="conditionalPreview"]') | ||
| ).forEach((n) => { | ||
| n.setAttribute("data-active", t ? "true" : "false"), n.classList.toggle("active", t), n.setAttribute("aria-pressed", t ? "true" : "false"); | ||
| }); | ||
| } | ||
| function at(e) { | ||
| const t = j.get(e); | ||
| if (t && t.isConnected) return t; | ||
| const o = document.createElement("div"); | ||
| return o.className = u, o.setAttribute("role", "toolbar"), o.setAttribute("aria-label", "Conditional block actions"), o.innerHTML = ` | ||
| <button type="button" class="rte-conditional-float-btn" data-action="edit" title="Edit Condition" aria-label="Edit Condition"> | ||
| <svg width="16" height="16" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><path d="M4 17.3V20h2.7l9.7-9.7-2.7-2.7L4 17.3Zm14.7-9.4a1 1 0 0 0 0-1.4l-1.2-1.2a1 1 0 0 0-1.4 0l-1.1 1.1 2.7 2.7 1-1.2Z" fill="currentColor"></path></svg> | ||
| </button> | ||
| <button type="button" class="rte-conditional-float-btn" data-action="delete" title="Delete Block" aria-label="Delete Block"> | ||
| <svg width="16" height="16" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><path d="M8 4h8l1 2h4v2H3V6h4l1-2Zm1 6h2v8H9v-8Zm4 0h2v8h-2v-8Z" fill="currentColor"></path></svg> | ||
| </button> | ||
| `, o.addEventListener("mousedown", (i) => { | ||
| i.preventDefault(); | ||
| }), o.addEventListener("click", (i) => { | ||
| var d; | ||
| const n = i.target, a = (d = n == null ? void 0 : n.closest("[data-action]")) == null ? void 0 : d.getAttribute("data-action"); | ||
| if (!a) return; | ||
| const r = E.get(e) || ne; | ||
| if (!r) return; | ||
| const l = I.get(e); | ||
| if (!(!l || !e.contains(l))) { | ||
| if (a === "edit") { | ||
| L(e, r, "edit", void 0, l); | ||
| return; | ||
| } | ||
| a === "delete" && (_e(e, l), I.set(e, null), F(e)); | ||
| } | ||
| }), document.body.appendChild(o), j.set(e, o), o; | ||
| } | ||
| function F(e) { | ||
| const t = j.get(e); | ||
| t && t.classList.remove("show"); | ||
| } | ||
| function Ke(e, t) { | ||
| const o = t.getBoundingClientRect(); | ||
| e.style.left = "0px", e.style.top = "0px", e.classList.add("show"); | ||
| const i = e.getBoundingClientRect(), n = 8, a = window.innerWidth, r = window.innerHeight; | ||
| let l = o.top - i.height - n; | ||
| l < n && (l = o.bottom + n), l = Math.min(l, r - i.height - n); | ||
| let d = o.right - i.width; | ||
| d = Math.max(n, Math.min(d, a - i.width - n)), e.style.left = `${d}px`, e.style.top = `${l}px`; | ||
| } | ||
| function ye(e, t) { | ||
| const o = at(e); | ||
| xe(o, e), I.set(e, t), Ke(o, t); | ||
| } | ||
| function O(e) { | ||
| const t = E.get(e) || ne; | ||
| if (!t) return; | ||
| const o = U(e); | ||
| if (!o || !e.contains(o) || D(e)) { | ||
| I.set(e, null), F(e); | ||
| return; | ||
| } | ||
| re(e, t.labels), ye(e, o); | ||
| } | ||
| function rt() { | ||
| j.forEach((e, t) => { | ||
| if (!t.isConnected || !e.isConnected) { | ||
| e.remove(), j.delete(t), I.delete(t); | ||
| return; | ||
| } | ||
| if (!e.classList.contains("show")) return; | ||
| xe(e, t); | ||
| const o = I.get(t); | ||
| if (!o || !t.contains(o)) { | ||
| F(t); | ||
| return; | ||
| } | ||
| Ke(e, o); | ||
| }); | ||
| } | ||
| function _e(e, t) { | ||
| if (!e.contains(t)) return !1; | ||
| const o = e.innerHTML, i = t.parentNode, n = t.nextSibling; | ||
| t.remove(), i === e && e.innerHTML.trim() === "" && (e.innerHTML = "<p><br></p>"); | ||
| const a = document.createRange(); | ||
| return n && e.contains(n) ? a.setStartBefore(n) : (a.selectNodeContents(e), a.collapse(!1)), a.collapse(!0), Le(e, a), De(e), He(e, o), !0; | ||
| } | ||
| function Me(e, t, o) { | ||
| const i = e.cloneRange(), n = document.createRange(); | ||
| return n.selectNodeContents(t), n.collapse(o === "start"), i.startContainer === n.startContainer && i.startOffset === n.startOffset && i.endContainer === n.endContainer && i.endOffset === n.endOffset; | ||
| } | ||
| function L(e, t, o, i, n) { | ||
| var K, W, Z, le; | ||
| Oe(); | ||
| const a = t.labels, r = o === "insert" ? Ne(e) : null, l = document.createElement("div"); | ||
| l.className = c, xe(l, e); | ||
| const d = document.createElement("section"); | ||
| d.className = "rte-conditional-dialog", d.setAttribute("role", "dialog"), d.setAttribute("aria-modal", "true"), d.setAttribute("aria-labelledby", "rte-conditional-dialog-title"); | ||
| const x = n ? ot(n) : void 0, v = i || x || {}, m = (K = v.condition) != null ? K : t.defaultCondition, S = (W = v.audience) != null ? W : t.defaultAudience, T = (Z = v.locale) != null ? Z : t.defaultLocale, ue = (le = v.hasElse) != null ? le : t.enableElseByDefault; | ||
| d.innerHTML = ` | ||
| <header class="rte-conditional-dialog-header"> | ||
| <h2 id="rte-conditional-dialog-title" class="rte-conditional-dialog-title">${$( | ||
| o === "edit" ? a.dialogTitleEdit : a.dialogTitleInsert | ||
| )}</h2> | ||
| <button type="button" class="rte-conditional-btn" data-action="cancel" aria-label="${$(a.cancelText)}">✕</button> | ||
| </header> | ||
| <div class="rte-conditional-dialog-body"> | ||
| <div class="rte-conditional-field"> | ||
| <label for="rte-conditional-condition">${$(a.conditionLabel)}</label> | ||
| <input id="rte-conditional-condition" class="rte-conditional-input-condition" type="text" value="${$( | ||
| m || "" | ||
| )}" placeholder="${$(a.conditionPlaceholder)}" /> | ||
| </div> | ||
| <div class="rte-conditional-field"> | ||
| <label for="rte-conditional-audience">${$(a.audienceLabel)}</label> | ||
| <input id="rte-conditional-audience" class="rte-conditional-input-audience" type="text" value="${$( | ||
| Te(S) | ||
| )}" placeholder="${$(a.audiencePlaceholder)}" /> | ||
| </div> | ||
| <div class="rte-conditional-field"> | ||
| <label for="rte-conditional-locale">${$(a.localeLabel)}</label> | ||
| <input id="rte-conditional-locale" class="rte-conditional-input-locale" type="text" value="${$( | ||
| Te(T) | ||
| )}" placeholder="${$(a.localePlaceholder)}" /> | ||
| </div> | ||
| <label class="rte-conditional-checkbox"> | ||
| <input class="rte-conditional-input-else" type="checkbox" ${ue ? "checked" : ""} /> | ||
| <span>${$(a.elseLabel)}</span> | ||
| </label> | ||
| <p class="rte-conditional-help">Example condition: <code>user.role == "admin"</code>, <code>locale == "en-US"</code>, <code>!feature.beta</code></p> | ||
| </div> | ||
| <footer class="rte-conditional-dialog-footer"> | ||
| <button type="button" class="rte-conditional-btn" data-action="cancel">${$(a.cancelText)}</button> | ||
| <button type="button" class="rte-conditional-btn rte-conditional-btn-primary" data-action="save">${$(a.saveText)}</button> | ||
| </footer> | ||
| `, l.appendChild(d), document.body.appendChild(l); | ||
| const B = d.querySelector(".rte-conditional-input-condition"), V = d.querySelector(".rte-conditional-input-audience"), p = d.querySelector(".rte-conditional-input-locale"), M = d.querySelector(".rte-conditional-input-else"), C = () => { | ||
| l.removeEventListener("click", N), l.removeEventListener("keydown", be, !0), document.removeEventListener("keydown", q, !0), l.parentNode && l.parentNode.removeChild(l), de = null, e.focus({ preventScroll: !0 }), O(e); | ||
| }, q = (s) => { | ||
| s.key === "Escape" && (s.preventDefault(), s.stopPropagation(), C()); | ||
| }, N = (s) => { | ||
| s.target === l && C(); | ||
| }, Ee = (s) => { | ||
| if (s.key !== "Tab") return; | ||
| const _ = Array.from( | ||
| d.querySelectorAll('button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])') | ||
| ); | ||
| if (_.length === 0) return; | ||
| const G = _[0], ce = _[_.length - 1], z = document.activeElement; | ||
| if (s.shiftKey && z === G) { | ||
| s.preventDefault(), ce.focus(); | ||
| return; | ||
| } | ||
| !s.shiftKey && z === ce && (s.preventDefault(), G.focus()); | ||
| }, fe = async () => { | ||
| var ce; | ||
| const s = { | ||
| condition: ((ce = B == null ? void 0 : B.value) == null ? void 0 : ce.trim()) || "", | ||
| audience: R(V == null ? void 0 : V.value), | ||
| locale: R(p == null ? void 0 : p.value), | ||
| hasElse: (M == null ? void 0 : M.checked) || !1 | ||
| }, _ = e.innerHTML; | ||
| if (n) | ||
| nt(n, s, a), ae(n, k.get(e) === !0); | ||
| else { | ||
| et(e, r); | ||
| const z = Pe(s, a); | ||
| try { | ||
| Re(e, z); | ||
| } catch (ut) { | ||
| e.appendChild(z); | ||
| const ke = z.querySelector('.rte-conditional-body[data-slot="if"]'); | ||
| ke ? $e(e, ke) : $e(e, z); | ||
| } | ||
| } | ||
| k.get(e) === !0 && await Y(e, t, !0), De(e), He(e, _), O(e), C(); | ||
| }, be = (s) => { | ||
| if (s.key === "Escape") { | ||
| s.preventDefault(), C(); | ||
| return; | ||
| } | ||
| Ee(s), s.key === "Enter" && !s.shiftKey && s.target instanceof HTMLInputElement && (s.preventDefault(), fe()); | ||
| }; | ||
| d.addEventListener("click", (s) => { | ||
| const G = s.target.getAttribute("data-action"); | ||
| if (G === "cancel") { | ||
| C(); | ||
| return; | ||
| } | ||
| G === "save" && fe(); | ||
| }), l.addEventListener("click", N), l.addEventListener("keydown", be, !0), document.addEventListener("keydown", q, !0), de = { cleanup: C }, B == null || B.focus(); | ||
| } | ||
| function lt(e) { | ||
| const t = e.metaKey || e.ctrlKey, i = (typeof e.key == "string" ? e.key : "").toLowerCase(), n = typeof e.code == "string" ? e.code.toLowerCase() : "", a = t && e.altKey && e.shiftKey && (i === "c" || n === "keyc"), r = !e.metaKey && !e.ctrlKey && !e.altKey && !e.shiftKey && (i === "f9" || n === "f9"); | ||
| return a || r; | ||
| } | ||
| function ct(e) { | ||
| const t = e.metaKey || e.ctrlKey, i = (typeof e.key == "string" ? e.key : "").toLowerCase(), n = typeof e.code == "string" ? e.code.toLowerCase() : "", a = t && e.altKey && e.shiftKey && (i === "p" || n === "keyp"), r = !e.metaKey && !e.ctrlKey && !e.altKey && !e.shiftKey && (i === "f10" || n === "f10"); | ||
| return a || r; | ||
| } | ||
| function dt(e) { | ||
| ne = e, X || (X = (t) => { | ||
| const o = t.target, i = o == null ? void 0 : o.closest(A); | ||
| if (!i) return; | ||
| y = i, E.has(i) || E.set(i, e); | ||
| const n = E.get(i) || e; | ||
| re(i, n.labels), qe(i, k.get(i) === !0), O(i); | ||
| }, document.addEventListener("focusin", X, !0)), J || (J = (t) => { | ||
| var v; | ||
| if (document.querySelector(`.${c}`)) return; | ||
| const i = t.target; | ||
| if (!!(i != null && i.closest("input, textarea, select"))) return; | ||
| const r = (i == null ? void 0 : i.closest(A)) || w(void 0, !1) || y; | ||
| if (!r || D(r)) return; | ||
| const l = E.get(r) || ne || e, d = document.activeElement, x = (i == null ? void 0 : i.closest(".rte-conditional-header")) || (d == null ? void 0 : d.closest(".rte-conditional-header")); | ||
| if (x && (t.key === "Enter" || t.key === " ")) { | ||
| const m = x.closest(P); | ||
| if (m && r.contains(m)) { | ||
| t.preventDefault(), t.stopPropagation(), L(r, l, "edit", void 0, m); | ||
| return; | ||
| } | ||
| } | ||
| if (lt(t)) { | ||
| t.preventDefault(), t.stopPropagation(); | ||
| const m = U(r); | ||
| m ? L(r, l, "edit", void 0, m) : L(r, l, "insert"); | ||
| return; | ||
| } | ||
| if (ct(t)) { | ||
| t.preventDefault(), t.stopPropagation(); | ||
| const m = k.get(r) !== !0; | ||
| Y(r, l, m), O(r); | ||
| return; | ||
| } | ||
| if ((t.key === "Backspace" || t.key === "Delete") && !t.altKey && !t.ctrlKey && !t.metaKey) { | ||
| const m = window.getSelection(); | ||
| if (!m || m.rangeCount === 0) return; | ||
| const S = m.getRangeAt(0); | ||
| if (!S.collapsed || !r.contains(S.commonAncestorContainer)) return; | ||
| const T = (v = Ye(S.startContainer)) == null ? void 0 : v.closest(".rte-conditional-body"); | ||
| if (!T || !r.contains(T)) return; | ||
| if (t.key === "Backspace" && Me(S, T, "start")) { | ||
| t.preventDefault(); | ||
| return; | ||
| } | ||
| if (t.key === "Delete" && Me(S, T, "end")) { | ||
| t.preventDefault(); | ||
| return; | ||
| } | ||
| } | ||
| }, document.addEventListener("keydown", J, !0)), ee || (ee = (t) => { | ||
| const o = t.target; | ||
| if (!o || o.closest(`.${u}`)) return; | ||
| const i = o.closest(A); | ||
| if (!i) { | ||
| y && F(y); | ||
| return; | ||
| } | ||
| if (D(i)) return; | ||
| y = i, E.has(i) || E.set(i, e); | ||
| const n = o.closest(P); | ||
| if (!n) { | ||
| F(i); | ||
| return; | ||
| } | ||
| requestAnimationFrame(() => { | ||
| !i.isConnected || !i.contains(n) || ye(i, n); | ||
| }); | ||
| }, document.addEventListener("mousedown", ee, !0)), Q || (Q = (t) => { | ||
| const o = t.target; | ||
| if (!o || o.closest(`.${u}`)) return; | ||
| const i = o.closest(A); | ||
| if (!i) { | ||
| y && F(y); | ||
| return; | ||
| } | ||
| if (D(i)) return; | ||
| y = i, E.has(i) || E.set(i, e); | ||
| const n = E.get(i) || e, a = o.closest(P), r = !!o.closest(".rte-conditional-header, .rte-conditional-summary, .rte-conditional-meta, .rte-conditional-else-label"); | ||
| if (a && r) { | ||
| t.preventDefault(), t.stopPropagation(), L(i, n, "edit", void 0, a), ye(i, a); | ||
| return; | ||
| } | ||
| a ? ye(i, a) : F(i); | ||
| }, document.addEventListener("click", Q, !0)), te || (te = () => { | ||
| const t = w(void 0, !1) || y; | ||
| t && t.isConnected && O(t); | ||
| }, document.addEventListener("selectionchange", te)), oe || (oe = (t) => { | ||
| const o = t.target, i = o == null ? void 0 : o.closest(A); | ||
| if (!i) return; | ||
| const n = E.get(i) || ne || e; | ||
| re(i, n.labels), O(i); | ||
| }, document.addEventListener("input", oe, !0)), H || (H = () => { | ||
| rt(); | ||
| }, window.addEventListener("scroll", H, !0), window.addEventListener("resize", H)); | ||
| } | ||
| function st() { | ||
| X && (document.removeEventListener("focusin", X, !0), X = null), J && (document.removeEventListener("keydown", J, !0), J = null), Q && (document.removeEventListener("click", Q, !0), Q = null), ee && (document.removeEventListener("mousedown", ee, !0), ee = null), te && (document.removeEventListener("selectionchange", te), te = null), oe && (document.removeEventListener("input", oe, !0), oe = null), H && (window.removeEventListener("scroll", H, !0), window.removeEventListener("resize", H), H = null), j.forEach((e) => { | ||
| e.remove(); | ||
| }), j.clear(), I.clear(), ne = null, y = null; | ||
| } | ||
| const ft = (e = {}) => { | ||
| const t = Ue(e); | ||
| return Ge(), { | ||
| name: "conditionalContent", | ||
| toolbar: [ | ||
| { | ||
| id: "conditionalContentGroup", | ||
| label: "Conditional Content", | ||
| type: "group", | ||
| command: "conditionalContent", | ||
| items: [ | ||
| { | ||
| id: "conditionalContent", | ||
| label: "Conditional Rule", | ||
| command: "openConditionalDialog", | ||
| icon: '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><path d="M6 5h12a1 1 0 0 1 1 1v3h-2V7H7v3H5V6a1 1 0 0 1 1-1Zm-1 9h2v3h10v-3h2v4a1 1 0 0 1-1 1H6a1 1 0 0 1-1-1v-4Zm3-2a1 1 0 0 1 1-1h2.6l1.8-2.4a1 1 0 1 1 1.6 1.2L13.8 11H15a1 1 0 1 1 0 2h-2.7l-1.9 2.5a1 1 0 1 1-1.6-1.2L10.1 13H9a1 1 0 0 1-1-1Z" fill="currentColor"></path></svg>', | ||
| shortcut: "Mod-Alt-Shift-c" | ||
| }, | ||
| { | ||
| id: "conditionalPreview", | ||
| label: "Conditional Preview", | ||
| command: "toggleConditionalPreview", | ||
| icon: '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><path d="M4 6h16a1 1 0 0 1 1 1v3h-2V8H5v8h14v-2h2v3a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1Zm5 3h2v2H9V9Zm0 4h2v2H9v-2Zm4-4h6v2h-6V9Zm0 4h6v2h-6v-2Z" fill="currentColor"></path></svg>', | ||
| shortcut: "Mod-Alt-Shift-p" | ||
| } | ||
| ] | ||
| } | ||
| ], | ||
| commands: { | ||
| conditionalContent: (o, i) => { | ||
| const n = w(i); | ||
| if (!n || D(n)) return !1; | ||
| y = n, E.set(n, t), re(n, t.labels); | ||
| const a = o == null ? void 0 : o.target; | ||
| if (a === "insert") | ||
| return L(n, t, "insert", o), !0; | ||
| const r = U(n); | ||
| return a === "edit" || r ? !r && a === "edit" ? !1 : (L(n, t, "edit", o, r || void 0), !0) : (L(n, t, "insert", o), !0); | ||
| }, | ||
| openConditionalDialog: (o, i) => { | ||
| const n = w(i); | ||
| if (!n || D(n)) return !1; | ||
| y = n, E.set(n, t), re(n, t.labels); | ||
| const a = o == null ? void 0 : o.target; | ||
| if (a === "insert") | ||
| return L(n, t, "insert", o), !0; | ||
| const r = U(n); | ||
| return a === "edit" || r ? !r && a === "edit" ? !1 : (L(n, t, "edit", o, r || void 0), !0) : (L(n, t, "insert", o), !0); | ||
| }, | ||
| conditionalPreview: async (o, i) => { | ||
| const n = w(i); | ||
| if (!n) return !1; | ||
| y = n, E.set(n, t); | ||
| const a = typeof o == "boolean" ? o : k.get(n) !== !0; | ||
| return await Y(n, t, a), O(n), !0; | ||
| }, | ||
| editConditionalBlock: (o, i) => { | ||
| const n = w(i); | ||
| if (!n || D(n)) return !1; | ||
| y = n, E.set(n, t); | ||
| const a = U(n); | ||
| return a ? (L(n, t, "edit", o, a), !0) : !1; | ||
| }, | ||
| deleteConditionalBlock: (o, i) => { | ||
| const n = w(i); | ||
| if (!n || D(n)) return !1; | ||
| const a = U(n); | ||
| if (!a) return !1; | ||
| const r = _e(n, a); | ||
| return r && O(n), r; | ||
| }, | ||
| insertConditionalBlock: (o, i) => { | ||
| var d, x, v, m; | ||
| const n = w(i); | ||
| if (!n || D(n)) return !1; | ||
| y = n, E.set(n, t); | ||
| const a = { | ||
| condition: (d = o == null ? void 0 : o.condition) != null ? d : t.defaultCondition, | ||
| audience: (x = o == null ? void 0 : o.audience) != null ? x : t.defaultAudience, | ||
| locale: (v = o == null ? void 0 : o.locale) != null ? v : t.defaultLocale, | ||
| hasElse: (m = o == null ? void 0 : o.hasElse) != null ? m : t.enableElseByDefault | ||
| }, r = Pe(a, t.labels); | ||
| return Re(n, r), k.get(n) === !0 && Y(n, t, !0), !0; | ||
| }, | ||
| toggleConditionalPreview: async (o, i) => { | ||
| const n = w(i); | ||
| if (!n) return !1; | ||
| y = n, E.set(n, t); | ||
| const a = typeof o == "boolean" ? o : k.get(n) !== !0; | ||
| return await Y(n, t, a), !0; | ||
| }, | ||
| setConditionalContext: (o, i) => { | ||
| const n = w(i); | ||
| return n ? (y = n, !o || typeof o != "object" ? Ce.delete(n) : Ce.set(n, o), k.get(n) === !0 && Y(n, t, !0), !0) : !1; | ||
| } | ||
| }, | ||
| keymap: { | ||
| "Mod-Alt-Shift-c": "openConditionalDialog", | ||
| "Mod-Alt-Shift-C": "openConditionalDialog", | ||
| "Mod-Alt-Shift-p": "toggleConditionalPreview", | ||
| "Mod-Alt-Shift-P": "toggleConditionalPreview", | ||
| F9: "openConditionalDialog", | ||
| F10: "toggleConditionalPreview" | ||
| }, | ||
| init: () => { | ||
| me += 1, dt(t); | ||
| }, | ||
| destroy: () => { | ||
| me = Math.max(0, me - 1), me === 0 && (Oe(), st()); | ||
| } | ||
| }; | ||
| }; | ||
| export { | ||
| ft as ConditionalContentPlugin | ||
| }; | ||
| //# sourceMappingURL=ConditionalContentPlugin.native-CfhY46rU.mjs.map |
| const R = ".rte-content, .editora-content", ee = "[data-editora-editor], .rte-editor, .editora-editor, editora-editor", oe = "__editoraCommandEditorRoot", se = "rte-content-rules-styles", f = "rte-content-rules-panel", q = ':is([data-theme="dark"], .dark, .editora-theme-dark, .rte-theme-dark)', he = { | ||
| panelTitle: "Content Rules", | ||
| panelAriaLabel: "Content rules panel", | ||
| runAuditText: "Run Audit", | ||
| realtimeOnText: "Realtime On", | ||
| realtimeOffText: "Realtime Off", | ||
| closeText: "Close", | ||
| noIssuesText: "No rule violations detected.", | ||
| summaryPrefix: "Issues", | ||
| locateText: "Locate", | ||
| bannedWordMessage: "Banned word found", | ||
| requiredHeadingMessage: "Missing required heading", | ||
| sentenceLengthMessage: "Sentence is too long", | ||
| readabilityMessage: "Readability score is below threshold" | ||
| }, d = /* @__PURE__ */ new WeakMap(), v = /* @__PURE__ */ new WeakMap(), de = /* @__PURE__ */ new WeakMap(), T = /* @__PURE__ */ new WeakMap(), V = /* @__PURE__ */ new WeakMap(), le = /* @__PURE__ */ new WeakMap(), Y = /* @__PURE__ */ new WeakMap(), h = /* @__PURE__ */ new Map(), B = /* @__PURE__ */ new WeakMap(), _ = /* @__PURE__ */ new Set(); | ||
| let N = 0, pe = 0, E = null, m = null, L = null, I = null, H = null, S = null; | ||
| function k(e) { | ||
| return e.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'"); | ||
| } | ||
| function xe(e) { | ||
| return { | ||
| ...he, | ||
| ...e || {} | ||
| }; | ||
| } | ||
| function ye(e) { | ||
| return e.replace(/\u00A0/g, " ").replace(/\s+/g, " ").trim(); | ||
| } | ||
| function ae(e) { | ||
| if (!e) return []; | ||
| const t = /* @__PURE__ */ new Set(); | ||
| return e.forEach((n) => { | ||
| const o = n.trim(); | ||
| o && t.add(o); | ||
| }), Array.from(t); | ||
| } | ||
| function j(e = {}) { | ||
| var t, n, o, r; | ||
| return { | ||
| bannedWords: ae(e.bannedWords), | ||
| requiredHeadings: ae(e.requiredHeadings), | ||
| maxSentenceWords: Math.max(8, Number((t = e.maxSentenceWords) != null ? t : 32)), | ||
| minReadabilityScore: Math.max(0, Math.min(120, Number((n = e.minReadabilityScore) != null ? n : 55))), | ||
| maxIssues: Math.max(1, Number((o = e.maxIssues) != null ? o : 100)), | ||
| debounceMs: Math.max(50, Number((r = e.debounceMs) != null ? r : 220)), | ||
| enableRealtime: e.enableRealtime !== !1, | ||
| labels: xe(e.labels), | ||
| normalizeText: e.normalizeText || ye, | ||
| customRules: Array.isArray(e.customRules) ? e.customRules : [] | ||
| }; | ||
| } | ||
| function X(e) { | ||
| return e.closest(ee) || e; | ||
| } | ||
| function F(e) { | ||
| if (!e) return null; | ||
| if (e.matches(R)) return e; | ||
| const t = e.querySelector(R); | ||
| return t instanceof HTMLElement ? t : null; | ||
| } | ||
| function we() { | ||
| if (typeof window == "undefined") return null; | ||
| const e = window[oe]; | ||
| if (!(e instanceof HTMLElement)) return null; | ||
| window[oe] = null; | ||
| const t = F(e); | ||
| if (t) return t; | ||
| const n = e.closest(ee); | ||
| if (n) { | ||
| const o = F(n); | ||
| if (o) return o; | ||
| } | ||
| return null; | ||
| } | ||
| function ke(e) { | ||
| const t = e.closest("[data-editora-editor]"); | ||
| if (t && F(t) === e) | ||
| return t; | ||
| let n = e; | ||
| for (; n; ) { | ||
| if (n.matches(ee) && (n === e || F(n) === e)) | ||
| return n; | ||
| n = n.parentElement; | ||
| } | ||
| return X(e); | ||
| } | ||
| function K(e) { | ||
| return e ? (e.getAttribute("data-theme") || e.getAttribute("theme") || "").toLowerCase() === "dark" ? !0 : e.classList.contains("dark") || e.classList.contains("editora-theme-dark") || e.classList.contains("rte-theme-dark") : !1; | ||
| } | ||
| function Re(e) { | ||
| const t = X(e); | ||
| if (K(t)) return !0; | ||
| const n = t.closest("[data-theme], [theme], .dark, .editora-theme-dark, .rte-theme-dark"); | ||
| return K(n) ? !0 : K(document.documentElement) || K(document.body); | ||
| } | ||
| function G(e, t) { | ||
| e.classList.remove("rte-content-rules-theme-dark"), Re(t) && e.classList.add("rte-content-rules-theme-dark"); | ||
| } | ||
| function Ee(e) { | ||
| return e ? e.nodeType === Node.ELEMENT_NODE ? e : e.parentElement : null; | ||
| } | ||
| function M(e, t = !0) { | ||
| if ((e == null ? void 0 : e.contentElement) instanceof HTMLElement) return e.contentElement; | ||
| if ((e == null ? void 0 : e.editorElement) instanceof HTMLElement) { | ||
| const s = e.editorElement; | ||
| if (s.matches(R)) return s; | ||
| const a = s.querySelector(R); | ||
| if (a instanceof HTMLElement) return a; | ||
| } | ||
| const n = we(); | ||
| if (n) return n; | ||
| const o = window.getSelection(); | ||
| if (o && o.rangeCount > 0) { | ||
| const s = o.getRangeAt(0).startContainer, a = Ee(s), l = a == null ? void 0 : a.closest(R); | ||
| if (l) return l; | ||
| } | ||
| const r = document.activeElement; | ||
| if (r) { | ||
| if (r.matches(R)) return r; | ||
| const s = r.closest(R); | ||
| if (s) return s; | ||
| } | ||
| return m && m.isConnected ? m : (m && !m.isConnected && (m = null), t ? document.querySelector(R) : null); | ||
| } | ||
| function Z(e) { | ||
| return e.getAttribute("contenteditable") === "false" || e.getAttribute("data-readonly") === "true"; | ||
| } | ||
| function Ce(e, t) { | ||
| const n = e.innerText || e.textContent || ""; | ||
| return t(n); | ||
| } | ||
| function ve(e) { | ||
| return e.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); | ||
| } | ||
| function ie(e) { | ||
| let t = 2166136261; | ||
| for (let n = 0; n < e.length; n += 1) | ||
| t ^= e.charCodeAt(n), t = Math.imul(t, 16777619); | ||
| return t >>> 0; | ||
| } | ||
| function ce(e) { | ||
| const t = e.match(/\b[\w'-]+\b/g); | ||
| return t ? t.length : 0; | ||
| } | ||
| function fe(e) { | ||
| const t = e.match(/[^.!?]+[.!?]*/g); | ||
| return t ? t.map((n) => n.trim()).filter(Boolean).length : 0; | ||
| } | ||
| function $e(e) { | ||
| const t = e.toLowerCase().replace(/[^a-z]/g, ""); | ||
| if (!t) return 0; | ||
| if (t.length <= 3) return 1; | ||
| const n = t.match(/[aeiouy]+/g); | ||
| let o = n ? n.length : 1; | ||
| return t.endsWith("e") && (o -= 1), Math.max(1, o); | ||
| } | ||
| function Me(e) { | ||
| const t = e.match(/\b[\w'-]+\b/g) || [], n = t.length; | ||
| if (n === 0) return 100; | ||
| const o = Math.max(1, fe(e)), r = t.reduce((a, l) => a + $e(l), 0), s = 206.835 - 1.015 * (n / o) - 84.6 * (r / Math.max(1, n)); | ||
| return Number.isFinite(s) ? Math.max(0, Math.min(120, s)) : 0; | ||
| } | ||
| function z(e, t) { | ||
| return `${e}-${t}`; | ||
| } | ||
| function x(e, t) { | ||
| return e.length >= t; | ||
| } | ||
| function P(e, t, n) { | ||
| x(e, n) || e.push(t); | ||
| } | ||
| function ge(e, t = 140) { | ||
| return e.length <= t ? e : `${e.slice(0, t - 1).trimEnd()}...`; | ||
| } | ||
| function Se(e, t, n, o) { | ||
| return { | ||
| id: e.id || z(t, o), | ||
| ruleId: e.ruleId || t, | ||
| severity: e.severity || n, | ||
| message: e.message || t, | ||
| excerpt: e.excerpt ? ge(e.excerpt, 220) : void 0, | ||
| suggestion: e.suggestion, | ||
| locateText: e.locateText, | ||
| selector: e.selector | ||
| }; | ||
| } | ||
| function Te(e, t) { | ||
| const n = Array.from(e.querySelectorAll("h1, h2, h3, h4, h5, h6")), o = /* @__PURE__ */ new Set(); | ||
| return n.forEach((r) => { | ||
| const s = t(r.textContent || "").toLowerCase(); | ||
| s && o.add(s); | ||
| }), o; | ||
| } | ||
| function Ae(e) { | ||
| const t = e.match(/[^.!?\n]+[.!?]?/g); | ||
| return t ? t.map((n) => n.trim()).filter(Boolean) : []; | ||
| } | ||
| async function C(e, t, n = !1) { | ||
| const o = Ce(e, t.normalizeText), r = e.innerHTML, s = `${o.length}:${ie(o)}:${r.length}:${ie(r)}`; | ||
| if (!n && le.get(e) === s) | ||
| return v.get(e) || []; | ||
| const a = (Y.get(e) || 0) + 1; | ||
| Y.set(e, a); | ||
| const l = ce(o), c = fe(o), u = Me(o), i = [], y = t.labels; | ||
| if (t.bannedWords.length > 0) { | ||
| let w = 0; | ||
| for (const p of t.bannedWords) { | ||
| const g = new RegExp(`\\b${ve(p)}\\b`, "gi"); | ||
| let b = g.exec(o); | ||
| for (; b && !x(i, t.maxIssues); ) { | ||
| const re = b[0]; | ||
| P( | ||
| i, | ||
| { | ||
| id: z("banned-word", w), | ||
| ruleId: "banned-word", | ||
| severity: "error", | ||
| message: `${y.bannedWordMessage}: "${re}"`, | ||
| locateText: re, | ||
| suggestion: "Replace or remove banned terms." | ||
| }, | ||
| t.maxIssues | ||
| ), w += 1, b = g.exec(o); | ||
| } | ||
| if (x(i, t.maxIssues)) break; | ||
| } | ||
| } | ||
| if (!x(i, t.maxIssues) && t.requiredHeadings.length > 0) { | ||
| const w = Te(e, t.normalizeText); | ||
| let p = 0; | ||
| t.requiredHeadings.forEach((g) => { | ||
| if (x(i, t.maxIssues)) return; | ||
| const b = t.normalizeText(g).toLowerCase(); | ||
| !b || w.has(b) || (P( | ||
| i, | ||
| { | ||
| id: z("required-heading", p), | ||
| ruleId: "required-heading", | ||
| severity: "warning", | ||
| message: `${y.requiredHeadingMessage}: "${g}"`, | ||
| suggestion: `Add a heading named "${g}".` | ||
| }, | ||
| t.maxIssues | ||
| ), p += 1); | ||
| }); | ||
| } | ||
| if (!x(i, t.maxIssues)) { | ||
| const w = Ae(o); | ||
| let p = 0; | ||
| for (const g of w) { | ||
| if (x(i, t.maxIssues)) break; | ||
| const b = ce(g); | ||
| b <= t.maxSentenceWords || (P( | ||
| i, | ||
| { | ||
| id: z("sentence-length", p), | ||
| ruleId: "sentence-length", | ||
| severity: "warning", | ||
| message: `${y.sentenceLengthMessage} (${b}/${t.maxSentenceWords} words)`, | ||
| excerpt: ge(g, 200), | ||
| locateText: g.slice(0, 64), | ||
| suggestion: "Split into shorter sentences for readability." | ||
| }, | ||
| t.maxIssues | ||
| ), p += 1); | ||
| } | ||
| } | ||
| if (!x(i, t.maxIssues) && l > 0 && u < t.minReadabilityScore && P( | ||
| i, | ||
| { | ||
| id: z("readability", 0), | ||
| ruleId: "readability", | ||
| severity: "info", | ||
| message: `${y.readabilityMessage}: ${u.toFixed(1)} < ${t.minReadabilityScore}`, | ||
| suggestion: "Use shorter sentences and simpler wording." | ||
| }, | ||
| t.maxIssues | ||
| ), !x(i, t.maxIssues) && t.customRules.length > 0) { | ||
| const w = { | ||
| editor: e, | ||
| editorRoot: X(e), | ||
| text: o, | ||
| html: r, | ||
| wordCount: l, | ||
| sentenceCount: c, | ||
| readabilityScore: u | ||
| }; | ||
| for (const p of t.customRules) { | ||
| if (x(i, t.maxIssues)) break; | ||
| try { | ||
| const g = await p.evaluate(w); | ||
| if (!Array.isArray(g)) continue; | ||
| for (let b = 0; b < g.length && !x(i, t.maxIssues); b += 1) | ||
| P( | ||
| i, | ||
| Se(g[b], p.id, p.severity || "warning", b), | ||
| t.maxIssues | ||
| ); | ||
| } catch (g) { | ||
| } | ||
| } | ||
| } | ||
| if (Y.get(e) !== a) | ||
| return v.get(e) || []; | ||
| const D = { | ||
| readabilityScore: u, | ||
| wordCount: l, | ||
| sentenceCount: c | ||
| }; | ||
| return le.set(e, s), v.set(e, i), de.set(e, D), te(e), e.dispatchEvent( | ||
| new CustomEvent("editora:content-rules-audit", { | ||
| bubbles: !0, | ||
| detail: { | ||
| issues: i, | ||
| metrics: D | ||
| } | ||
| }) | ||
| ), i; | ||
| } | ||
| function Le(e) { | ||
| return e.reduce( | ||
| (t, n) => (t[n.severity] += 1, t), | ||
| { error: 0, warning: 0, info: 0 } | ||
| ); | ||
| } | ||
| function Ie(e) { | ||
| return e === "error" ? "Error" : e === "warning" ? "Warning" : "Info"; | ||
| } | ||
| function $(e, t, n) { | ||
| const o = ke(e); | ||
| Array.from( | ||
| o.querySelectorAll( | ||
| `.rte-toolbar-button[data-command="${t}"], .editora-toolbar-button[data-command="${t}"]` | ||
| ) | ||
| ).forEach((s) => { | ||
| s.classList.toggle("active", n), s.setAttribute("data-active", n ? "true" : "false"), s.setAttribute("aria-pressed", n ? "true" : "false"); | ||
| }); | ||
| } | ||
| function U(e) { | ||
| return B.get(e) === !0; | ||
| } | ||
| function J(e, t) { | ||
| if (!t.classList.contains("show")) return; | ||
| const o = X(e).getBoundingClientRect(), r = Math.min(window.innerWidth - 20, 360); | ||
| t.style.width = `${r}px`, t.style.maxHeight = `${Math.max(220, window.innerHeight - 24)}px`; | ||
| const s = Math.max(10, o.right - r), a = Math.max(10, window.innerWidth - r - 10), l = Math.min(s, a), c = Math.max(10, Math.min(window.innerHeight - 10 - 240, o.top + 10)); | ||
| t.style.left = `${l}px`, t.style.top = `${c}px`; | ||
| } | ||
| function ue(e, t) { | ||
| const n = t.trim().toLowerCase(); | ||
| if (!n) return !1; | ||
| const o = window.getSelection(); | ||
| if (!o) return !1; | ||
| const r = document.createTreeWalker(e, NodeFilter.SHOW_TEXT, null); | ||
| let s = r.nextNode(); | ||
| for (; s; ) { | ||
| const l = s.data.toLowerCase().indexOf(n); | ||
| if (l !== -1) { | ||
| const c = document.createRange(); | ||
| c.setStart(s, l), c.setEnd(s, Math.min(s.length, l + n.length)), o.removeAllRanges(), o.addRange(c); | ||
| const u = s.parentElement; | ||
| return u && u.scrollIntoView({ behavior: "smooth", block: "center", inline: "nearest" }), e.focus({ preventScroll: !0 }), !0; | ||
| } | ||
| s = r.nextNode(); | ||
| } | ||
| return !1; | ||
| } | ||
| function He(e, t) { | ||
| if (t.selector) { | ||
| const n = e.querySelector(t.selector); | ||
| if (n) | ||
| return n.scrollIntoView({ behavior: "smooth", block: "center", inline: "nearest" }), n.focus({ preventScroll: !0 }), !0; | ||
| } | ||
| return !!(t.locateText && ue(e, t.locateText) || t.excerpt && ue(e, t.excerpt.slice(0, 64))); | ||
| } | ||
| function We(e, t) { | ||
| return (v.get(e) || []).find((o) => o.id === t); | ||
| } | ||
| function A(e, t) { | ||
| const n = T.get(e); | ||
| return typeof n == "boolean" ? n : t ? t.enableRealtime : !0; | ||
| } | ||
| function O(e, t, n) { | ||
| const o = t.querySelector('[data-action="toggle-realtime"]'); | ||
| if (!o) return; | ||
| const r = A(e, n); | ||
| o.textContent = r ? n.labels.realtimeOnText : n.labels.realtimeOffText, o.setAttribute("aria-pressed", r ? "true" : "false"), $(e, "toggleContentRulesRealtime", r); | ||
| } | ||
| function te(e) { | ||
| const t = h.get(e); | ||
| if (!t) return; | ||
| const n = d.get(e) || E; | ||
| if (!n) return; | ||
| const o = v.get(e) || [], r = de.get(e) || { | ||
| readabilityScore: 100 | ||
| }, s = t.querySelector(".rte-content-rules-count"), a = t.querySelector(".rte-content-rules-summary"), l = t.querySelector(".rte-content-rules-list"), c = t.querySelector(".rte-content-rules-live"); | ||
| if (!s || !a || !l || !c) return; | ||
| const u = Le(o); | ||
| if (s.textContent = String(o.length), a.textContent = `${n.labels.summaryPrefix}: ${o.length} | Error ${u.error} | Warning ${u.warning} | Info ${u.info} | Readability ${r.readabilityScore.toFixed(1)}`, c.textContent = `${o.length} issues. ${u.error} errors, ${u.warning} warnings, ${u.info} info.`, o.length === 0) { | ||
| l.innerHTML = `<li class="rte-content-rules-empty">${k(n.labels.noIssuesText)}</li>`; | ||
| return; | ||
| } | ||
| l.innerHTML = o.map((i) => { | ||
| const y = i.excerpt ? `<p class="rte-content-rules-excerpt">${k(i.excerpt)}</p>` : "", D = i.suggestion ? `<p class="rte-content-rules-suggestion">${k(i.suggestion)}</p>` : "", w = `${n.labels.locateText}: ${i.message}`; | ||
| return ` | ||
| <li class="rte-content-rules-item rte-content-rules-item-${i.severity}"> | ||
| <button | ||
| type="button" | ||
| class="rte-content-rules-item-btn" | ||
| data-action="focus-issue" | ||
| data-issue-id="${k(i.id)}" | ||
| data-role="issue-button" | ||
| aria-label="${k(w)}" | ||
| > | ||
| <span class="rte-content-rules-badge">${k(Ie(i.severity))}</span> | ||
| <span class="rte-content-rules-message">${k(i.message)}</span> | ||
| </button> | ||
| ${y} | ||
| ${D} | ||
| </li> | ||
| `; | ||
| }).join(""); | ||
| } | ||
| function W(e, t = !1) { | ||
| const n = h.get(e); | ||
| n && (n.classList.remove("show"), B.set(e, !1), $(e, "toggleContentRulesPanel", !1), t && e.focus({ preventScroll: !0 })); | ||
| } | ||
| function Oe(e) { | ||
| h.forEach((t, n) => { | ||
| n !== e && W(n, !1); | ||
| }); | ||
| } | ||
| function qe(e) { | ||
| const t = h.get(e); | ||
| if (t) return t; | ||
| const n = d.get(e) || E || j(), o = `rte-content-rules-panel-${pe++}`, r = document.createElement("section"); | ||
| return r.className = f, r.id = o, r.setAttribute("role", "dialog"), r.setAttribute("aria-modal", "false"), r.setAttribute("aria-label", n.labels.panelAriaLabel), r.innerHTML = ` | ||
| <header class="rte-content-rules-header"> | ||
| <h2 class="rte-content-rules-title">${k(n.labels.panelTitle)}</h2> | ||
| <button type="button" class="rte-content-rules-icon-btn" data-action="close" aria-label="${k(n.labels.closeText)}">✕</button> | ||
| </header> | ||
| <div class="rte-content-rules-body"> | ||
| <div class="rte-content-rules-topline"> | ||
| <p class="rte-content-rules-summary" aria-live="polite"></p> | ||
| <span class="rte-content-rules-count" aria-hidden="true">0</span> | ||
| </div> | ||
| <div class="rte-content-rules-controls" role="toolbar" aria-label="Content rules controls"> | ||
| <button type="button" class="rte-content-rules-btn rte-content-rules-btn-primary" data-action="run-audit">${k(n.labels.runAuditText)}</button> | ||
| <button type="button" class="rte-content-rules-btn" data-action="toggle-realtime" aria-pressed="false"></button> | ||
| </div> | ||
| <ul class="rte-content-rules-list" role="list" aria-label="Detected content rule issues"></ul> | ||
| <p class="rte-content-rules-shortcut">Shortcut: Ctrl/Cmd + Alt + Shift + R</p> | ||
| <span class="rte-content-rules-live" aria-live="polite"></span> | ||
| </div> | ||
| `, r.addEventListener("click", (s) => { | ||
| const a = s.target, l = a == null ? void 0 : a.closest("[data-action]"); | ||
| if (!l) return; | ||
| const c = l.getAttribute("data-action"); | ||
| if (c) { | ||
| if (c === "close") { | ||
| W(e, !0); | ||
| return; | ||
| } | ||
| if (c === "run-audit") { | ||
| const u = d.get(e) || E || n; | ||
| C(e, u, !0); | ||
| return; | ||
| } | ||
| if (c === "toggle-realtime") { | ||
| const i = !A(e, d.get(e) || E || n); | ||
| if (T.set(e, i), O(e, r, d.get(e) || E || n), i) { | ||
| const y = d.get(e) || E || n; | ||
| C(e, y, !0); | ||
| } | ||
| return; | ||
| } | ||
| if (c === "focus-issue") { | ||
| const u = l.getAttribute("data-issue-id") || "", i = We(e, u); | ||
| if (!i) return; | ||
| He(e, i), W(e, !1); | ||
| } | ||
| } | ||
| }), r.addEventListener("keydown", (s) => { | ||
| if (s.key === "Escape") { | ||
| s.preventDefault(), W(e, !0); | ||
| return; | ||
| } | ||
| if (s.key !== "ArrowDown" && s.key !== "ArrowUp") return; | ||
| const a = Array.from(r.querySelectorAll('[data-role="issue-button"]')); | ||
| if (a.length === 0) return; | ||
| const l = document.activeElement, c = a.findIndex((y) => y === l); | ||
| if (c === -1) return; | ||
| s.preventDefault(); | ||
| const u = s.key === "ArrowDown" ? 1 : -1, i = (c + u + a.length) % a.length; | ||
| a[i].focus(); | ||
| }), G(r, e), document.body.appendChild(r), h.set(e, r), B.set(e, !1), O(e, r, n), r; | ||
| } | ||
| function ne(e) { | ||
| const t = qe(e); | ||
| Oe(e), t.classList.add("show"), B.set(e, !0), G(t, e), J(e, t), te(e), $(e, "toggleContentRulesPanel", !0); | ||
| const n = t.querySelector('[data-action="run-audit"]'); | ||
| n == null || n.focus(); | ||
| } | ||
| function Q(e, t) { | ||
| const n = U(e); | ||
| return (typeof t == "boolean" ? t : !n) ? ne(e) : W(e, !1), !0; | ||
| } | ||
| function me(e) { | ||
| const t = V.get(e); | ||
| typeof t == "number" && (window.clearTimeout(t), _.delete(t), V.delete(e)); | ||
| } | ||
| function be(e) { | ||
| const t = d.get(e) || E; | ||
| if (!t || !A(e, t)) return; | ||
| me(e); | ||
| const n = window.setTimeout(() => { | ||
| _.delete(n), V.delete(e), C(e, t, !1); | ||
| }, t.debounceMs); | ||
| _.add(n), V.set(e, n); | ||
| } | ||
| function Pe(e) { | ||
| const t = e.key.toLowerCase(); | ||
| return (e.metaKey || e.ctrlKey) && e.altKey && e.shiftKey && t === "r"; | ||
| } | ||
| function ze(e) { | ||
| const t = e.key.toLowerCase(); | ||
| return (e.metaKey || e.ctrlKey) && e.altKey && e.shiftKey && t === "l"; | ||
| } | ||
| function _e(e) { | ||
| const t = e.key.toLowerCase(); | ||
| return (e.metaKey || e.ctrlKey) && e.altKey && e.shiftKey && t === "t"; | ||
| } | ||
| function Be() { | ||
| if (typeof document == "undefined" || document.getElementById(se)) return; | ||
| const e = document.createElement("style"); | ||
| e.id = se, e.textContent = ` | ||
| .rte-toolbar-group-items.content-rules, | ||
| .editora-toolbar-group-items.content-rules { | ||
| display: flex; | ||
| border: 1px solid #ccc; | ||
| border-radius: 3px; | ||
| background: #fff; | ||
| } | ||
| .rte-toolbar-group-items.content-rules .rte-toolbar-button, | ||
| .editora-toolbar-group-items.content-rules .editora-toolbar-button { | ||
| border: none; | ||
| border-radius: 0px; | ||
| } | ||
| .rte-toolbar-group-items.content-rules .rte-toolbar-button, | ||
| .editora-toolbar-group-items.content-rules .editora-toolbar-button { | ||
| border-right: 1px solid #ccc; | ||
| } | ||
| .rte-toolbar-group-items.content-rules .rte-toolbar-item:last-child .rte-toolbar-button, | ||
| .editora-toolbar-group-items.content-rules .editora-toolbar-item:last-child .editora-toolbar-button { | ||
| border-right: none; | ||
| } | ||
| .rte-toolbar-button[data-command="toggleContentRulesRealtime"].active, | ||
| .editora-toolbar-button[data-command="toggleContentRulesRealtime"].active { | ||
| background-color: #ccc; | ||
| } | ||
| ${q} .rte-toolbar-group-items.content-rules, | ||
| ${q} .editora-toolbar-group-items.content-rules { | ||
| border-color: #566275; | ||
| } | ||
| ${q} .rte-toolbar-group-items.content-rules .rte-toolbar-button, | ||
| ${q} .editora-toolbar-group-items.content-rules .editora-toolbar-button | ||
| { | ||
| border-color: #566275; | ||
| } | ||
| ${q} .rte-toolbar-group-items.content-rules .rte-toolbar-button svg{ | ||
| fill: none; | ||
| } | ||
| .${f} { | ||
| position: fixed; | ||
| z-index: 12000; | ||
| display: none; | ||
| width: min(360px, calc(100vw - 20px)); | ||
| max-height: calc(100vh - 20px); | ||
| border: 1px solid #d1d5db; | ||
| border-radius: 14px; | ||
| background: #ffffff; | ||
| color: #111827; | ||
| box-shadow: 0 18px 45px rgba(15, 23, 42, 0.25); | ||
| overflow: hidden; | ||
| } | ||
| .${f}.show { | ||
| display: flex; | ||
| flex-direction: column; | ||
| } | ||
| .${f}.rte-content-rules-theme-dark { | ||
| border-color: #334155; | ||
| background: #0f172a; | ||
| color: #e2e8f0; | ||
| box-shadow: 0 20px 46px rgba(2, 6, 23, 0.68); | ||
| } | ||
| .rte-content-rules-header { | ||
| display: flex; | ||
| align-items: center; | ||
| justify-content: space-between; | ||
| gap: 8px; | ||
| padding: 12px 14px; | ||
| border-bottom: 1px solid #e5e7eb; | ||
| background: linear-gradient(180deg, #f9fafb 0%, #f3f4f6 100%); | ||
| } | ||
| .${f}.rte-content-rules-theme-dark .rte-content-rules-header { | ||
| border-color: #1e293b; | ||
| background: linear-gradient(180deg, #111827 0%, #0f172a 100%); | ||
| } | ||
| .rte-content-rules-title { | ||
| margin: 0; | ||
| font-size: 15px; | ||
| line-height: 1.2; | ||
| font-weight: 700; | ||
| } | ||
| .rte-content-rules-icon-btn { | ||
| width: 34px; | ||
| height: 34px; | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 6px; | ||
| background: #ffffff; | ||
| color: #0f172a; | ||
| font-size: 16px; | ||
| line-height: 1; | ||
| font-weight: 600; | ||
| padding: 0; | ||
| display: inline-flex; | ||
| align-items: center; | ||
| justify-content: center; | ||
| cursor: pointer; | ||
| } | ||
| .rte-content-rules-icon-btn:hover, | ||
| .rte-content-rules-icon-btn:focus-visible { | ||
| outline: none; | ||
| border-color: #3b82f6; | ||
| box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.2); | ||
| } | ||
| .${f}.rte-content-rules-theme-dark .rte-content-rules-icon-btn { | ||
| background: #0f172a; | ||
| border-color: #475569; | ||
| color: #e2e8f0; | ||
| } | ||
| .${f}.rte-content-rules-theme-dark .rte-content-rules-icon-btn:hover, | ||
| .${f}.rte-content-rules-theme-dark .rte-content-rules-icon-btn:focus-visible { | ||
| border-color: #60a5fa; | ||
| box-shadow: 0 0 0 3px rgba(96, 165, 250, 0.24); | ||
| } | ||
| .rte-content-rules-body { | ||
| display: flex; | ||
| flex-direction: column; | ||
| gap: 10px; | ||
| padding: 12px; | ||
| overflow: auto; | ||
| } | ||
| .rte-content-rules-topline { | ||
| display: flex; | ||
| align-items: center; | ||
| justify-content: space-between; | ||
| gap: 8px; | ||
| } | ||
| .rte-content-rules-summary { | ||
| margin: 0; | ||
| font-size: 12px; | ||
| line-height: 1.35; | ||
| color: #475569; | ||
| flex: 1; | ||
| } | ||
| .${f}.rte-content-rules-theme-dark .rte-content-rules-summary { | ||
| color: #94a3b8; | ||
| } | ||
| .rte-content-rules-count { | ||
| min-width: 32px; | ||
| height: 32px; | ||
| border-radius: 999px; | ||
| display: inline-flex; | ||
| align-items: center; | ||
| justify-content: center; | ||
| font-weight: 700; | ||
| font-size: 13px; | ||
| border: 1px solid #cbd5e1; | ||
| background: #f8fafc; | ||
| } | ||
| .${f}.rte-content-rules-theme-dark .rte-content-rules-count { | ||
| border-color: #334155; | ||
| background: #111827; | ||
| color: #cbd5e1; | ||
| } | ||
| .rte-content-rules-controls { | ||
| display: flex; | ||
| gap: 8px; | ||
| flex-wrap: wrap; | ||
| } | ||
| .rte-content-rules-btn { | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 8px; | ||
| height: 34px; | ||
| padding: 0 10px; | ||
| background: #ffffff; | ||
| color: inherit; | ||
| font-size: 12px; | ||
| font-weight: 600; | ||
| cursor: pointer; | ||
| } | ||
| .rte-content-rules-btn:hover, | ||
| .rte-content-rules-btn:focus-visible { | ||
| border-color: #94a3b8; | ||
| background: #f8fafc; | ||
| outline: none; | ||
| } | ||
| .rte-content-rules-btn-primary { | ||
| border-color: #0284c7; | ||
| background: #0ea5e9; | ||
| color: #f8fafc; | ||
| } | ||
| .rte-content-rules-btn-primary:hover, | ||
| .rte-content-rules-btn-primary:focus-visible { | ||
| border-color: #0369a1; | ||
| background: #0284c7; | ||
| color: #ffffff; | ||
| } | ||
| .${f}.rte-content-rules-theme-dark .rte-content-rules-btn { | ||
| border-color: #334155; | ||
| background: #111827; | ||
| color: #e2e8f0; | ||
| } | ||
| .${f}.rte-content-rules-theme-dark .rte-content-rules-btn:hover, | ||
| .${f}.rte-content-rules-theme-dark .rte-content-rules-btn:focus-visible { | ||
| border-color: #475569; | ||
| background: #1e293b; | ||
| } | ||
| .rte-content-rules-list { | ||
| list-style: none; | ||
| margin: 0; | ||
| padding: 0; | ||
| display: flex; | ||
| flex-direction: column; | ||
| gap: 8px; | ||
| max-height: min(55vh, 420px); | ||
| overflow: auto; | ||
| } | ||
| .rte-content-rules-item { | ||
| border: 1px solid #e2e8f0; | ||
| border-radius: 10px; | ||
| padding: 8px; | ||
| background: #ffffff; | ||
| } | ||
| .rte-content-rules-item-error { | ||
| border-color: #fca5a5; | ||
| background: #fef2f2; | ||
| } | ||
| .rte-content-rules-item-warning { | ||
| border-color: #fcd34d; | ||
| background: #fffbeb; | ||
| } | ||
| .rte-content-rules-item-info { | ||
| border-color: #93c5fd; | ||
| background: #eff6ff; | ||
| } | ||
| .${f}.rte-content-rules-theme-dark .rte-content-rules-item { | ||
| border-color: #334155; | ||
| background: #0b1220; | ||
| } | ||
| .${f}.rte-content-rules-theme-dark .rte-content-rules-item-error { | ||
| border-color: #7f1d1d; | ||
| background: #2b0b11; | ||
| } | ||
| .${f}.rte-content-rules-theme-dark .rte-content-rules-item-warning { | ||
| border-color: #78350f; | ||
| background: #2b1907; | ||
| } | ||
| .${f}.rte-content-rules-theme-dark .rte-content-rules-item-info { | ||
| border-color: #1d4ed8; | ||
| background: #0a162f; | ||
| } | ||
| .rte-content-rules-item-btn { | ||
| width: 100%; | ||
| border: none; | ||
| background: transparent; | ||
| display: flex; | ||
| align-items: flex-start; | ||
| gap: 8px; | ||
| text-align: left; | ||
| padding: 0; | ||
| color: inherit; | ||
| cursor: pointer; | ||
| } | ||
| .rte-content-rules-item-btn:focus-visible { | ||
| outline: 2px solid #0284c7; | ||
| outline-offset: 3px; | ||
| border-radius: 6px; | ||
| } | ||
| .rte-content-rules-badge { | ||
| flex: 0 0 auto; | ||
| margin-top: 1px; | ||
| border-radius: 999px; | ||
| border: 1px solid currentColor; | ||
| padding: 1px 8px; | ||
| font-size: 10px; | ||
| font-weight: 700; | ||
| line-height: 1.3; | ||
| text-transform: uppercase; | ||
| opacity: 0.86; | ||
| } | ||
| .rte-content-rules-message { | ||
| font-size: 13px; | ||
| line-height: 1.35; | ||
| font-weight: 600; | ||
| } | ||
| .rte-content-rules-excerpt, | ||
| .rte-content-rules-suggestion { | ||
| margin: 8px 0 0; | ||
| font-size: 12px; | ||
| line-height: 1.35; | ||
| color: #334155; | ||
| } | ||
| .${f}.rte-content-rules-theme-dark .rte-content-rules-excerpt, | ||
| .${f}.rte-content-rules-theme-dark .rte-content-rules-suggestion { | ||
| color: #94a3b8; | ||
| } | ||
| .rte-content-rules-empty { | ||
| border: 1px dashed #cbd5e1; | ||
| border-radius: 10px; | ||
| padding: 10px; | ||
| font-size: 13px; | ||
| color: #475569; | ||
| background: #f8fafc; | ||
| } | ||
| .${f}.rte-content-rules-theme-dark .rte-content-rules-empty { | ||
| border-color: #334155; | ||
| background: #0b1220; | ||
| color: #94a3b8; | ||
| } | ||
| .rte-content-rules-shortcut { | ||
| margin: 2px 0 0; | ||
| font-size: 11px; | ||
| color: #64748b; | ||
| } | ||
| .${f}.rte-content-rules-theme-dark .rte-content-rules-shortcut { | ||
| color: #94a3b8; | ||
| } | ||
| .rte-content-rules-live { | ||
| position: absolute; | ||
| width: 1px; | ||
| height: 1px; | ||
| margin: -1px; | ||
| padding: 0; | ||
| overflow: hidden; | ||
| clip: rect(0 0 0 0); | ||
| border: 0; | ||
| } | ||
| @media (max-width: 768px) { | ||
| .${f} { | ||
| left: 10px !important; | ||
| right: 10px; | ||
| top: 10px !important; | ||
| width: auto !important; | ||
| max-height: calc(100vh - 20px); | ||
| } | ||
| .rte-content-rules-list { | ||
| max-height: 45vh; | ||
| } | ||
| } | ||
| `, document.head.appendChild(e); | ||
| } | ||
| function De(e) { | ||
| E = e, L || (L = (t) => { | ||
| const n = t.target, o = n == null ? void 0 : n.closest(R); | ||
| if (!o) return; | ||
| m = o, d.has(o) || d.set(o, e), v.has(o) || v.set(o, []), T.has(o) || T.set(o, e.enableRealtime); | ||
| const r = h.get(o); | ||
| r && (G(r, o), J(o, r), O(o, r, d.get(o) || e)), $(o, "toggleContentRulesPanel", U(o)), $(o, "toggleContentRulesRealtime", A(o, e)); | ||
| }, document.addEventListener("focusin", L, !0)), I || (I = (t) => { | ||
| const n = t.target, o = n == null ? void 0 : n.closest(R); | ||
| o && (m = o, be(o)); | ||
| }, document.addEventListener("input", I, !0)), H || (H = (t) => { | ||
| if (t.defaultPrevented) return; | ||
| const n = t.target; | ||
| if (n != null && n.closest("input, textarea, select")) return; | ||
| const o = t.key === "Escape", r = Pe(t), s = ze(t), a = _e(t); | ||
| if (!o && !r && !s && !a) | ||
| return; | ||
| const l = M(void 0, !1); | ||
| if (!l || Z(l)) return; | ||
| const c = d.get(l) || E || e; | ||
| if (d.set(l, c), m = l, o && U(l)) { | ||
| t.preventDefault(), W(l, !0); | ||
| return; | ||
| } | ||
| if (r) { | ||
| t.preventDefault(), t.stopPropagation(), Q(l); | ||
| return; | ||
| } | ||
| if (s) { | ||
| t.preventDefault(), t.stopPropagation(), C(l, c, !0), ne(l); | ||
| return; | ||
| } | ||
| if (a) { | ||
| t.preventDefault(), t.stopPropagation(); | ||
| const u = !A(l, c); | ||
| T.set(l, u); | ||
| const i = h.get(l); | ||
| i && O(l, i, c), $(l, "toggleContentRulesRealtime", u), u && C(l, c, !0); | ||
| } | ||
| }, document.addEventListener("keydown", H, !0)), S || (S = () => { | ||
| h.forEach((t, n) => { | ||
| if (!n.isConnected || !t.isConnected) { | ||
| me(n), t.remove(), h.delete(n), B.delete(n); | ||
| return; | ||
| } | ||
| G(t, n), J(n, t); | ||
| }); | ||
| }, window.addEventListener("scroll", S, !0), window.addEventListener("resize", S)); | ||
| } | ||
| function Ne() { | ||
| L && (document.removeEventListener("focusin", L, !0), L = null), I && (document.removeEventListener("input", I, !0), I = null), H && (document.removeEventListener("keydown", H, !0), H = null), S && (window.removeEventListener("scroll", S, !0), window.removeEventListener("resize", S), S = null), h.forEach((e) => { | ||
| e.remove(); | ||
| }), h.clear(), E = null, m = null; | ||
| } | ||
| const Ke = (e = {}) => { | ||
| const t = j(e); | ||
| return Be(), { | ||
| name: "contentRules", | ||
| toolbar: [ | ||
| { | ||
| id: "contentRulesGroup", | ||
| label: "Content Rules", | ||
| type: "group", | ||
| command: "contentRules", | ||
| items: [ | ||
| { | ||
| id: "contentRules", | ||
| label: "Content Rules", | ||
| command: "toggleContentRulesPanel", | ||
| shortcut: "Mod-Alt-Shift-r", | ||
| icon: '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><path d="M6 3h9l5 5v11a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2Zm8 2v4h4" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/><path d="M8 11h8M8 15h8M8 19h5" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/></svg>' | ||
| }, | ||
| { | ||
| id: "contentRulesAudit", | ||
| label: "Run Rules Audit", | ||
| command: "runContentRulesAudit", | ||
| shortcut: "Mod-Alt-Shift-l", | ||
| icon: '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><path d="M4 12h4l2 5 4-10 2 5h4" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/><circle cx="12" cy="12" r="9" stroke="currentColor" stroke-width="1.6"/></svg>' | ||
| }, | ||
| { | ||
| id: "contentRulesRealtime", | ||
| label: "Toggle Realtime Rules", | ||
| command: "toggleContentRulesRealtime", | ||
| shortcut: "Mod-Alt-Shift-t", | ||
| icon: '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><path d="M12 3v4M12 17v4M4.9 4.9l2.8 2.8M16.3 16.3l2.8 2.8M3 12h4M17 12h4M4.9 19.1l2.8-2.8M16.3 7.7l2.8-2.8" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/><circle cx="12" cy="12" r="4" stroke="currentColor" stroke-width="1.6"/></svg>' | ||
| } | ||
| ] | ||
| } | ||
| ], | ||
| commands: { | ||
| contentRules: (n, o) => { | ||
| const r = M(o); | ||
| if (!r || Z(r)) return !1; | ||
| const s = d.get(r) || t; | ||
| return d.set(r, s), m = r, Q(r, !0), C(r, s, !1), !0; | ||
| }, | ||
| toggleContentRulesPanel: (n, o) => { | ||
| const r = M(o); | ||
| if (!r || Z(r)) return !1; | ||
| m = r; | ||
| const s = d.get(r) || t; | ||
| d.set(r, s); | ||
| const a = Q(r, typeof n == "boolean" ? n : void 0); | ||
| return U(r) && C(r, s, !1), a; | ||
| }, | ||
| runContentRulesAudit: async (n, o) => { | ||
| const r = M(o); | ||
| if (!r) return !1; | ||
| m = r; | ||
| const s = d.get(r) || t; | ||
| return d.set(r, s), await C(r, s, !0), ne(r), !0; | ||
| }, | ||
| toggleContentRulesRealtime: (n, o) => { | ||
| const r = M(o); | ||
| if (!r) return !1; | ||
| m = r; | ||
| const s = d.get(r) || t; | ||
| d.set(r, s); | ||
| const a = typeof n == "boolean" ? n : !A(r, s); | ||
| T.set(r, a); | ||
| const l = h.get(r); | ||
| return l && O(r, l, s), $(r, "toggleContentRulesRealtime", a), a && C(r, s, !0), !0; | ||
| }, | ||
| getContentRulesIssues: (n, o) => { | ||
| const r = M(o); | ||
| if (!r) return !1; | ||
| const s = v.get(r) || []; | ||
| if (typeof n == "function") | ||
| try { | ||
| n(s); | ||
| } catch (a) { | ||
| } | ||
| return r.__contentRulesIssues = s, r.dispatchEvent( | ||
| new CustomEvent("editora:content-rules-issues", { | ||
| bubbles: !0, | ||
| detail: { issues: s } | ||
| }) | ||
| ), !0; | ||
| }, | ||
| setContentRulesOptions: (n, o) => { | ||
| const r = M(o); | ||
| if (!r || !n || typeof n != "object") return !1; | ||
| const s = d.get(r) || t, a = j({ | ||
| ...s, | ||
| ...n, | ||
| labels: { | ||
| ...s.labels, | ||
| ...n.labels || {} | ||
| } | ||
| }); | ||
| d.set(r, a), typeof n.enableRealtime == "boolean" && T.set(r, n.enableRealtime), A(r, a) && C(r, a, !0); | ||
| const l = h.get(r); | ||
| if (l) { | ||
| l.setAttribute("aria-label", a.labels.panelAriaLabel); | ||
| const c = l.querySelector(".rte-content-rules-title"); | ||
| c && (c.textContent = a.labels.panelTitle), O(r, l, a), te(r); | ||
| } | ||
| return !0; | ||
| } | ||
| }, | ||
| keymap: { | ||
| "Mod-Alt-Shift-r": "toggleContentRulesPanel", | ||
| "Mod-Alt-Shift-R": "toggleContentRulesPanel", | ||
| "Mod-Alt-Shift-l": "runContentRulesAudit", | ||
| "Mod-Alt-Shift-L": "runContentRulesAudit", | ||
| "Mod-Alt-Shift-t": "toggleContentRulesRealtime", | ||
| "Mod-Alt-Shift-T": "toggleContentRulesRealtime" | ||
| }, | ||
| init: function(o) { | ||
| N += 1; | ||
| const r = this && typeof this.__pluginConfig == "object" ? j({ ...t, ...this.__pluginConfig }) : t; | ||
| De(r); | ||
| const s = M( | ||
| o && o.editorElement ? { editorElement: o.editorElement } : void 0, | ||
| !1 | ||
| ); | ||
| s && (m = s, d.set(s, r), T.set(s, r.enableRealtime), v.set(s, []), $(s, "toggleContentRulesPanel", !1), $(s, "toggleContentRulesRealtime", r.enableRealtime), r.enableRealtime && be(s)); | ||
| }, | ||
| destroy: () => { | ||
| N = Math.max(0, N - 1), !(N > 0) && (_.forEach((n) => { | ||
| window.clearTimeout(n); | ||
| }), _.clear(), Ne()); | ||
| } | ||
| }; | ||
| }; | ||
| export { | ||
| Ke as ContentRulesPlugin | ||
| }; | ||
| //# sourceMappingURL=ContentRulesPlugin.native-nBLQ8QFZ.mjs.map |
| const S = ".rte-content, .editora-content", P = '.rte-data-binding[data-binding="true"]', ot = "rte-data-binding-styles", p = "rte-data-binding-dialog-overlay", b = ':is([data-theme="dark"], .dark, .editora-theme-dark, .rte-theme-dark)', pt = { | ||
| dialogTitleInsert: "Insert Data Binding", | ||
| dialogTitleEdit: "Edit Data Binding", | ||
| keyLabel: "Data Key", | ||
| keyPlaceholder: "user.firstName", | ||
| fallbackLabel: "Fallback Text", | ||
| fallbackPlaceholder: "Guest", | ||
| formatLabel: "Format", | ||
| currencyLabel: "Currency", | ||
| currencyPlaceholder: "USD", | ||
| saveText: "Save", | ||
| cancelText: "Cancel", | ||
| previewOnText: "Preview On", | ||
| previewOffText: "Preview Off", | ||
| tokenAriaPrefix: "Data binding token" | ||
| }, v = /* @__PURE__ */ new WeakMap(), J = /* @__PURE__ */ new WeakMap(), g = /* @__PURE__ */ new WeakMap(), R = /* @__PURE__ */ new WeakMap(), I = /* @__PURE__ */ new WeakMap(); | ||
| let K = null, k = null, z = 0, O = null, M = null, B = null, V = null; | ||
| function yt(t) { | ||
| return { | ||
| ...pt, | ||
| ...t || {} | ||
| }; | ||
| } | ||
| function dt(t = {}) { | ||
| var e; | ||
| const a = (t.locale || (typeof navigator != "undefined" ? navigator.language : "en-US")).trim() || "en-US"; | ||
| return { | ||
| data: t.data, | ||
| getData: t.getData, | ||
| api: t.api, | ||
| cacheTtlMs: Math.max(0, Number((e = t.cacheTtlMs) != null ? e : 3e4)), | ||
| labels: yt(t.labels), | ||
| defaultFormat: t.defaultFormat || "text", | ||
| defaultFallback: t.defaultFallback || "", | ||
| locale: a, | ||
| numberFormatOptions: t.numberFormatOptions || {}, | ||
| dateFormatOptions: t.dateFormatOptions || { year: "numeric", month: "short", day: "2-digit" } | ||
| }; | ||
| } | ||
| function h(t) { | ||
| return t.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'"); | ||
| } | ||
| function lt(t) { | ||
| return t ? t.nodeType === Node.ELEMENT_NODE ? t : t.parentElement : null; | ||
| } | ||
| function q(t) { | ||
| return t.closest("[data-editora-editor], .rte-editor, .editora-editor, editora-editor") || t; | ||
| } | ||
| function _(t) { | ||
| return t ? (t.getAttribute("data-theme") || t.getAttribute("theme") || "").toLowerCase() === "dark" ? !0 : t.classList.contains("dark") || t.classList.contains("editora-theme-dark") || t.classList.contains("rte-theme-dark") : !1; | ||
| } | ||
| function ht(t) { | ||
| const a = q(t); | ||
| if (_(a)) return !0; | ||
| const e = a.closest("[data-theme], [theme], .dark, .editora-theme-dark, .rte-theme-dark"); | ||
| return _(e) ? !0 : _(document.documentElement) || _(document.body); | ||
| } | ||
| function A(t, a = !0) { | ||
| if ((t == null ? void 0 : t.contentElement) instanceof HTMLElement) return t.contentElement; | ||
| if ((t == null ? void 0 : t.editorElement) instanceof HTMLElement) { | ||
| const n = t.editorElement; | ||
| if (n.matches(S)) return n; | ||
| const i = n.querySelector(S); | ||
| if (i instanceof HTMLElement) return i; | ||
| } | ||
| const e = window.getSelection(); | ||
| if (e && e.rangeCount > 0) { | ||
| const n = e.getRangeAt(0).startContainer, i = lt(n), o = i == null ? void 0 : i.closest(S); | ||
| if (o) return o; | ||
| } | ||
| const r = document.activeElement; | ||
| if (r) { | ||
| if (r.matches(S)) return r; | ||
| const n = r.closest(S); | ||
| if (n) return n; | ||
| } | ||
| return k && k.isConnected ? k : a ? document.querySelector(S) : null; | ||
| } | ||
| function H(t) { | ||
| return t.getAttribute("contenteditable") === "false" || t.getAttribute("data-readonly") === "true"; | ||
| } | ||
| function st(t) { | ||
| const a = window.getSelection(); | ||
| if (!a || a.rangeCount === 0) return null; | ||
| const e = a.getRangeAt(0); | ||
| return t.contains(e.commonAncestorContainer) ? e.cloneRange() : null; | ||
| } | ||
| function ct(t, a) { | ||
| const e = window.getSelection(); | ||
| e && (e.removeAllRanges(), e.addRange(a), t.focus({ preventScroll: !0 })); | ||
| } | ||
| function kt(t, a) { | ||
| const e = (a || "").trim(); | ||
| if (e) | ||
| return e.split(".").filter(Boolean).reduce((r, n) => { | ||
| if (!(r == null || typeof r != "object")) | ||
| return r[n]; | ||
| }, t); | ||
| } | ||
| function vt() { | ||
| if (typeof document == "undefined" || document.getElementById(ot)) return; | ||
| const t = document.createElement("style"); | ||
| t.id = ot, t.textContent = ` | ||
| .rte-data-binding { | ||
| display: inline-flex; | ||
| align-items: center; | ||
| max-width: 100%; | ||
| gap: 5px; | ||
| padding: 2px 8px 2px 7px; | ||
| border-radius: 999px; | ||
| border: 1px dashed #8b5cf6; | ||
| background: linear-gradient(180deg, #f9f7ff 0%, #f1edff 100%); | ||
| color: #4c1d95; | ||
| font-size: 0.88em; | ||
| font-weight: 600; | ||
| line-height: 1.3; | ||
| vertical-align: baseline; | ||
| white-space: nowrap; | ||
| overflow: hidden; | ||
| text-overflow: ellipsis; | ||
| user-select: all; | ||
| font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; | ||
| cursor: pointer; | ||
| } | ||
| .rte-data-binding::before { | ||
| content: '{}'; | ||
| display: inline-flex; | ||
| align-items: center; | ||
| justify-content: center; | ||
| min-width: 14px; | ||
| height: 14px; | ||
| border-radius: 999px; | ||
| background: rgba(139, 92, 246, 0.16); | ||
| color: #5b21b6; | ||
| font-size: 10px; | ||
| font-weight: 700; | ||
| line-height: 1; | ||
| letter-spacing: -0.2px; | ||
| flex: 0 0 auto; | ||
| } | ||
| .rte-data-binding.rte-data-binding-preview { | ||
| border-style: solid; | ||
| background: #ecfdf5; | ||
| border-color: #34d399; | ||
| color: #065f46; | ||
| user-select: text; | ||
| } | ||
| .rte-data-binding.rte-data-binding-preview::before { | ||
| content: '='; | ||
| background: rgba(16, 185, 129, 0.15); | ||
| color: #047857; | ||
| letter-spacing: 0; | ||
| } | ||
| .rte-data-binding.rte-data-binding-missing { | ||
| border-style: dashed; | ||
| border-color: #f87171; | ||
| background: #fef2f2; | ||
| color: #991b1b; | ||
| } | ||
| .rte-data-binding-dialog-overlay { | ||
| position: fixed; | ||
| inset: 0; | ||
| z-index: 2147483646; | ||
| background: rgba(15, 23, 42, 0.54); | ||
| display: flex; | ||
| align-items: center; | ||
| justify-content: center; | ||
| padding: 20px; | ||
| } | ||
| .rte-data-binding-dialog { | ||
| width: min(560px, 96vw); | ||
| max-height: min(86vh, 720px); | ||
| border: 1px solid #dbe3ec; | ||
| border-radius: 8px; | ||
| background: #ffffff; | ||
| box-shadow: 0 24px 50px rgba(15, 23, 42, 0.26); | ||
| display: flex; | ||
| flex-direction: column; | ||
| overflow: hidden; | ||
| } | ||
| .rte-data-binding-header, | ||
| .rte-data-binding-footer { | ||
| display: flex; | ||
| align-items: center; | ||
| justify-content: space-between; | ||
| gap: 10px; | ||
| padding: 12px 14px; | ||
| background: #f8fafc; | ||
| border-bottom: 1px solid #e2e8f0; | ||
| } | ||
| .rte-data-binding-footer { | ||
| justify-content: flex-end; | ||
| border-bottom: 0; | ||
| border-top: 1px solid #e2e8f0; | ||
| } | ||
| .rte-data-binding-title { | ||
| margin: 0; | ||
| font-size: 16px; | ||
| font-weight: 700; | ||
| color: #0f172a; | ||
| } | ||
| .rte-data-binding-body { | ||
| padding: 14px; | ||
| overflow: auto; | ||
| display: grid; | ||
| gap: 12px; | ||
| grid-template-columns: 1fr; | ||
| } | ||
| .rte-data-binding-field { | ||
| display: grid; | ||
| gap: 6px; | ||
| } | ||
| .rte-data-binding-field label { | ||
| font-size: 12px; | ||
| font-weight: 600; | ||
| color: #334155; | ||
| } | ||
| .rte-data-binding-field input, | ||
| .rte-data-binding-field select { | ||
| width: 100%; | ||
| min-height: 36px; | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 6px; | ||
| padding: 8px 10px; | ||
| font-size: 13px; | ||
| line-height: 1.4; | ||
| color: #0f172a; | ||
| background: #ffffff; | ||
| box-sizing: border-box; | ||
| } | ||
| .rte-data-binding-help { | ||
| margin: 0; | ||
| font-size: 12px; | ||
| color: #64748b; | ||
| } | ||
| .rte-data-binding-btn { | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 6px; | ||
| min-height: 34px; | ||
| padding: 6px 12px; | ||
| background: #ffffff; | ||
| color: #0f172a; | ||
| font-size: 13px; | ||
| cursor: pointer; | ||
| } | ||
| .rte-data-binding-btn-primary { | ||
| background: #2563eb; | ||
| border-color: #2563eb; | ||
| color: #ffffff; | ||
| } | ||
| .rte-data-binding-btn-primary:hover { | ||
| background: #1d4ed8; | ||
| } | ||
| .rte-toolbar-group-items.data-binding, | ||
| .editora-toolbar-group-items.data-binding { | ||
| display: flex; | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 6px; | ||
| overflow: hidden; | ||
| background: #ffffff; | ||
| } | ||
| .rte-toolbar-group-items.data-binding .rte-toolbar-item, | ||
| .editora-toolbar-group-items.data-binding .editora-toolbar-item { | ||
| display: flex; | ||
| } | ||
| .rte-toolbar-group-items.data-binding .rte-toolbar-button, | ||
| .editora-toolbar-group-items.data-binding .editora-toolbar-button { | ||
| border: 0; | ||
| border-radius: 0; | ||
| border-right: 1px solid #cbd5e1; | ||
| } | ||
| .rte-toolbar-group-items.data-binding .rte-toolbar-item:last-child .rte-toolbar-button, | ||
| .editora-toolbar-group-items.data-binding .editora-toolbar-item:last-child .editora-toolbar-button { | ||
| border-right: 0; | ||
| } | ||
| .rte-data-binding-btn:focus-visible, | ||
| .rte-data-binding-field input:focus-visible, | ||
| .rte-data-binding-field select:focus-visible { | ||
| outline: none; | ||
| border-color: #3b82f6; | ||
| box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.2); | ||
| } | ||
| ${b} .rte-data-binding, | ||
| .${p}.rte-data-binding-theme-dark .rte-data-binding { | ||
| background: linear-gradient(180deg, #3b0764 0%, #2e1065 100%); | ||
| border-color: #a78bfa; | ||
| color: #ede9fe; | ||
| } | ||
| ${b} .rte-data-binding::before, | ||
| .${p}.rte-data-binding-theme-dark .rte-data-binding::before { | ||
| background: rgba(167, 139, 250, 0.22); | ||
| color: #ddd6fe; | ||
| } | ||
| ${b} .rte-data-binding.rte-data-binding-preview, | ||
| .${p}.rte-data-binding-theme-dark .rte-data-binding.rte-data-binding-preview { | ||
| background: #064e3b; | ||
| border-color: #10b981; | ||
| color: #d1fae5; | ||
| } | ||
| ${b} .rte-data-binding.rte-data-binding-missing, | ||
| .${p}.rte-data-binding-theme-dark .rte-data-binding.rte-data-binding-missing { | ||
| background: #7f1d1d; | ||
| border-color: #ef4444; | ||
| color: #fee2e2; | ||
| } | ||
| ${b} .rte-toolbar-group-items.data-binding, | ||
| ${b} .editora-toolbar-group-items.data-binding { | ||
| display: flex; | ||
| border: 1px solid #566275; | ||
| border-radius: 6px; | ||
| overflow: hidden; | ||
| } | ||
| ${b} .rte-toolbar-group-items.data-binding .rte-toolbar-button, | ||
| ${b} .editora-toolbar-group-items.data-binding .editora-toolbar-button { | ||
| border-right-color: #566275; | ||
| } | ||
| ${b} .rte-data-binding-dialog, | ||
| .${p}.rte-data-binding-theme-dark .rte-data-binding-dialog { | ||
| background: #1f2937; | ||
| border-color: #334155; | ||
| } | ||
| ${b} .rte-data-binding-header, | ||
| ${b} .rte-data-binding-footer, | ||
| .${p}.rte-data-binding-theme-dark .rte-data-binding-header, | ||
| .${p}.rte-data-binding-theme-dark .rte-data-binding-footer { | ||
| background: #111827; | ||
| border-color: #334155; | ||
| } | ||
| ${b} .rte-data-binding-title, | ||
| ${b} .rte-data-binding-field label, | ||
| .${p}.rte-data-binding-theme-dark .rte-data-binding-title, | ||
| .${p}.rte-data-binding-theme-dark .rte-data-binding-field label { | ||
| color: #e2e8f0; | ||
| } | ||
| ${b} .rte-data-binding-help, | ||
| .${p}.rte-data-binding-theme-dark .rte-data-binding-help { | ||
| color: #94a3b8; | ||
| } | ||
| ${b} .rte-data-binding-field input, | ||
| ${b} .rte-data-binding-field select, | ||
| ${b} .rte-data-binding-btn, | ||
| .${p}.rte-data-binding-theme-dark .rte-data-binding-field input, | ||
| .${p}.rte-data-binding-theme-dark .rte-data-binding-field select, | ||
| .${p}.rte-data-binding-theme-dark .rte-data-binding-btn { | ||
| background: #0f172a; | ||
| border-color: #475569; | ||
| color: #e2e8f0; | ||
| } | ||
| ${b} .rte-data-binding-btn-primary, | ||
| .${p}.rte-data-binding-theme-dark .rte-data-binding-btn-primary { | ||
| background: #2563eb; | ||
| border-color: #2563eb; | ||
| color: #ffffff; | ||
| } | ||
| `, document.head.appendChild(t); | ||
| } | ||
| function Y(t) { | ||
| t.dispatchEvent(new Event("input", { bubbles: !0 })); | ||
| } | ||
| function Q(t, a) { | ||
| if (a === t.innerHTML) return; | ||
| const e = window.execEditorCommand || window.executeEditorCommand; | ||
| if (typeof e == "function") | ||
| try { | ||
| e("recordDomTransaction", t, a, t.innerHTML); | ||
| } catch (r) { | ||
| } | ||
| } | ||
| function j(t, a) { | ||
| var e, r; | ||
| return { | ||
| key: String(t.key || "").trim(), | ||
| fallback: String((r = (e = t.fallback) != null ? e : a.defaultFallback) != null ? r : ""), | ||
| format: t.format || a.defaultFormat || "text", | ||
| currency: String(t.currency || "USD").trim().toUpperCase() || "USD" | ||
| }; | ||
| } | ||
| function ut(t) { | ||
| return `{{${t.key}}}`; | ||
| } | ||
| function ft(t, a) { | ||
| const e = document.createElement("span"); | ||
| return e.className = "rte-data-binding", e.setAttribute("data-binding", "true"), e.setAttribute("data-binding-key", t.key), e.setAttribute("data-binding-fallback", t.fallback || ""), e.setAttribute("data-binding-format", t.format || "text"), e.setAttribute("data-binding-currency", t.currency || "USD"), e.setAttribute("contenteditable", "false"), e.setAttribute("spellcheck", "false"), e.setAttribute("draggable", "false"), e.setAttribute("tabindex", "0"), e.setAttribute("role", "button"), e.setAttribute("aria-label", `${a.tokenAriaPrefix}: ${t.key}. Press Enter to edit.`), e.textContent = ut(t), e; | ||
| } | ||
| function W(t, a) { | ||
| return j( | ||
| { | ||
| key: t.getAttribute("data-binding-key") || "", | ||
| fallback: t.getAttribute("data-binding-fallback") || a.defaultFallback, | ||
| format: t.getAttribute("data-binding-format") || a.defaultFormat, | ||
| currency: t.getAttribute("data-binding-currency") || "USD" | ||
| }, | ||
| a | ||
| ); | ||
| } | ||
| function tt(t, a, e) { | ||
| t.classList.add("rte-data-binding"), t.setAttribute("data-binding", "true"), t.setAttribute("data-binding-key", a.key), t.setAttribute("data-binding-fallback", a.fallback || ""), t.setAttribute("data-binding-format", a.format || "text"), t.setAttribute("data-binding-currency", a.currency || "USD"), t.setAttribute("contenteditable", "false"), t.setAttribute("spellcheck", "false"), t.setAttribute("draggable", "false"), t.setAttribute("tabindex", "0"), t.setAttribute("role", "button"), t.setAttribute("aria-label", `${e.tokenAriaPrefix}: ${a.key}. Press Enter to edit.`); | ||
| } | ||
| function G(t, a) { | ||
| const e = Array.from(t.querySelectorAll(P)); | ||
| return e.forEach((r) => { | ||
| const n = W(r, a); | ||
| tt(r, n, a.labels); | ||
| }), e; | ||
| } | ||
| function X(t) { | ||
| const a = window.getSelection(); | ||
| if (a && a.rangeCount > 0) { | ||
| const n = a.getRangeAt(0).startContainer, i = lt(n), o = i == null ? void 0 : i.closest(P); | ||
| if (o && t.contains(o)) return o; | ||
| } | ||
| const e = document.activeElement, r = e == null ? void 0 : e.closest(P); | ||
| return r && t.contains(r) ? r : null; | ||
| } | ||
| function bt() { | ||
| K && (K.cleanup(), K = null); | ||
| } | ||
| function et(t, a, e) { | ||
| const r = q(t); | ||
| Array.from(r.querySelectorAll('[data-command="toggleDataBindingPreview"]')).forEach((i) => { | ||
| if (i.setAttribute("data-active", a ? "true" : "false"), i.classList.toggle("active", a), i.setAttribute("aria-pressed", a ? "true" : "false"), e) { | ||
| const o = a ? e.labels.previewOnText : e.labels.previewOffText; | ||
| i.setAttribute("title", o), i.setAttribute("aria-label", o); | ||
| } | ||
| }); | ||
| } | ||
| function xt(t, a, e) { | ||
| const r = a.format || "text"; | ||
| if (t == null) return a.fallback || ""; | ||
| if (r === "json") { | ||
| if (typeof t == "string") return t; | ||
| try { | ||
| return JSON.stringify(t); | ||
| } catch (n) { | ||
| return String(t); | ||
| } | ||
| } | ||
| if (r === "date") { | ||
| const n = t instanceof Date ? t : new Date(String(t)); | ||
| if (Number.isNaN(n.getTime())) return String(t); | ||
| try { | ||
| return new Intl.DateTimeFormat(e.locale, e.dateFormatOptions).format(n); | ||
| } catch (i) { | ||
| return n.toISOString(); | ||
| } | ||
| } | ||
| if (r === "number" || r === "currency") { | ||
| const n = typeof t == "number" ? t : Number(t); | ||
| if (!Number.isFinite(n)) return String(t); | ||
| const i = { ...e.numberFormatOptions }; | ||
| if (r === "currency") { | ||
| const o = (a.currency || "USD").toUpperCase(); | ||
| Object.assign(i, { style: "currency", currency: o }); | ||
| } | ||
| try { | ||
| return new Intl.NumberFormat(e.locale, i).format(n); | ||
| } catch (o) { | ||
| return String(n); | ||
| } | ||
| } | ||
| return String(t); | ||
| } | ||
| function C(t, a, e, r) { | ||
| const n = W(t, a), i = n.key; | ||
| if (t.classList.remove("rte-data-binding-preview", "rte-data-binding-missing"), !e) { | ||
| t.textContent = ut(n), t.setAttribute("aria-label", `${a.labels.tokenAriaPrefix}: ${i}. Press Enter to edit.`); | ||
| return; | ||
| } | ||
| const o = kt(r, i), l = o == null, d = l ? n.fallback || "" : xt(o, n, a); | ||
| t.textContent = d || n.fallback || "", t.classList.add("rte-data-binding-preview"), l && !(n.fallback || "").trim() && t.classList.add("rte-data-binding-missing"), t.setAttribute("aria-label", `${a.labels.tokenAriaPrefix}: ${i} = ${t.textContent || ""}. Press Enter to edit.`); | ||
| } | ||
| function w(t) { | ||
| return typeof t == "object" && t !== null && !Array.isArray(t); | ||
| } | ||
| function wt(t, a) { | ||
| return a ? a.split(".").filter(Boolean).reduce((e, r) => { | ||
| if (!(!w(e) && !Array.isArray(e))) | ||
| return e[r]; | ||
| }, t) : t; | ||
| } | ||
| function Et(t, a, e) { | ||
| const r = a.api, n = q(t), i = { editor: t, editorRoot: n, signal: e }; | ||
| if (r.buildRequest) { | ||
| const m = r.buildRequest(i); | ||
| return { url: m.url, init: { ...m.init || {}, signal: e } }; | ||
| } | ||
| const o = (r.method || "GET").toUpperCase(), l = typeof r.headers == "function" ? r.headers(i) : r.headers || {}, d = typeof r.params == "function" ? r.params(i) : r.params, u = new URL(r.url, window.location.origin); | ||
| d && Object.entries(d).forEach(([m, f]) => { | ||
| f != null && u.searchParams.set(m, String(f)); | ||
| }); | ||
| const s = { | ||
| method: o, | ||
| headers: { ...l }, | ||
| credentials: r.credentials, | ||
| mode: r.mode, | ||
| cache: r.cache, | ||
| signal: e | ||
| }; | ||
| if (o !== "GET" && o !== "HEAD") { | ||
| const m = typeof r.body == "function" ? r.body(i) : r.body; | ||
| if (m != null) | ||
| if (w(m)) { | ||
| s.body = JSON.stringify(m); | ||
| const f = s.headers; | ||
| !f["Content-Type"] && !f["content-type"] && (f["Content-Type"] = "application/json"); | ||
| } else | ||
| s.body = m; | ||
| } | ||
| return { url: u.toString(), init: s }; | ||
| } | ||
| async function Dt(t, a) { | ||
| var d, u; | ||
| const e = a.api; | ||
| if (!e) return {}; | ||
| const r = new AbortController(), n = q(t), i = { editor: t, editorRoot: n, signal: r.signal }, o = Math.max(0, Number((d = e.timeoutMs) != null ? d : 1e4)); | ||
| let l = null; | ||
| o > 0 && (l = window.setTimeout(() => r.abort(), o)); | ||
| try { | ||
| const { url: s, init: m } = Et(t, a, r.signal), f = await fetch(s, { ...m, signal: r.signal }); | ||
| if (!f.ok) | ||
| throw new Error(`Data binding API request failed: ${f.status}`); | ||
| const $ = (e.responseType || "json") === "text" ? await f.text() : await f.json(); | ||
| if (e.transformResponse) { | ||
| const F = e.transformResponse($, i); | ||
| return w(F) ? F : {}; | ||
| } | ||
| const x = wt($, e.responsePath); | ||
| return w(x) ? x : w($) ? $ : { value: x }; | ||
| } catch (s) { | ||
| return (s == null ? void 0 : s.name) !== "AbortError" && ((u = e.onError) == null || u.call(e, s, i)), {}; | ||
| } finally { | ||
| l !== null && window.clearTimeout(l); | ||
| } | ||
| } | ||
| async function U(t, a) { | ||
| const e = J.get(t); | ||
| if (e) return e; | ||
| const r = R.get(t), n = Date.now(); | ||
| if (r && n - r.timestamp <= a.cacheTtlMs) | ||
| return r.data; | ||
| const i = I.get(t); | ||
| if (i) return i; | ||
| const o = (async () => { | ||
| try { | ||
| if (typeof a.getData == "function") { | ||
| const d = await Promise.resolve(a.getData({ editor: t, editorRoot: q(t) })); | ||
| if (w(d)) return d; | ||
| } | ||
| if (a.api) { | ||
| const d = await Dt(t, a); | ||
| if (w(d)) return d; | ||
| } | ||
| if (typeof a.data == "function") { | ||
| const d = await Promise.resolve(a.data()); | ||
| if (w(d)) return d; | ||
| } | ||
| return w(a.data) ? a.data : {}; | ||
| } finally { | ||
| I.delete(t); | ||
| } | ||
| })(); | ||
| I.set(t, o); | ||
| const l = await o; | ||
| return R.set(t, { timestamp: n, data: l }), l; | ||
| } | ||
| async function Z(t, a, e) { | ||
| const r = G(t, a); | ||
| if (v.set(t, e), et(t, e, a), !e) { | ||
| r.forEach((i) => C(i, a, !1)); | ||
| return; | ||
| } | ||
| const n = await U(t, a); | ||
| r.forEach((i) => C(i, a, !0, n)); | ||
| } | ||
| function gt(t, a) { | ||
| let e = st(t); | ||
| e || (e = document.createRange(), e.selectNodeContents(t), e.collapse(!1)), e.collapsed || e.deleteContents(), e.insertNode(a); | ||
| const r = document.createTextNode(" "); | ||
| a.after(r); | ||
| const n = document.createRange(); | ||
| n.setStart(r, 1), n.collapse(!0), ct(t, n), t.normalize(); | ||
| } | ||
| function At(t) { | ||
| const a = t.metaKey || t.ctrlKey, e = t.key.toLowerCase(), r = a && t.altKey && t.shiftKey && e === "d", n = !t.metaKey && !t.ctrlKey && !t.altKey && !t.shiftKey && e === "f7"; | ||
| return r || n; | ||
| } | ||
| function St(t) { | ||
| const a = t.metaKey || t.ctrlKey, e = t.key.toLowerCase(), r = a && t.altKey && t.shiftKey && e === "b", n = !t.metaKey && !t.ctrlKey && !t.altKey && !t.shiftKey && e === "f8"; | ||
| return r || n; | ||
| } | ||
| function L(t, a, e, r, n) { | ||
| bt(); | ||
| const i = e === "insert" ? st(t) : null, o = a.labels, l = n ? W(n, a) : j(r || {}, a), d = document.createElement("div"); | ||
| d.className = p, ht(t) && d.classList.add("rte-data-binding-theme-dark"); | ||
| const u = document.createElement("section"); | ||
| u.className = "rte-data-binding-dialog", u.setAttribute("role", "dialog"), u.setAttribute("aria-modal", "true"), u.setAttribute("aria-labelledby", "rte-data-binding-dialog-title"), u.innerHTML = ` | ||
| <header class="rte-data-binding-header"> | ||
| <h2 id="rte-data-binding-dialog-title" class="rte-data-binding-title">${h( | ||
| e === "edit" ? o.dialogTitleEdit : o.dialogTitleInsert | ||
| )}</h2> | ||
| <button type="button" class="rte-data-binding-btn" data-action="cancel" aria-label="${h(o.cancelText)}">✕</button> | ||
| </header> | ||
| <div class="rte-data-binding-body"> | ||
| <div class="rte-data-binding-field"> | ||
| <label for="rte-data-binding-key">${h(o.keyLabel)}</label> | ||
| <input id="rte-data-binding-key" class="rte-data-binding-key" type="text" value="${h(l.key)}" placeholder="${h( | ||
| o.keyPlaceholder | ||
| )}" /> | ||
| </div> | ||
| <div class="rte-data-binding-field"> | ||
| <label for="rte-data-binding-fallback">${h(o.fallbackLabel)}</label> | ||
| <input id="rte-data-binding-fallback" class="rte-data-binding-fallback" type="text" value="${h( | ||
| l.fallback || "" | ||
| )}" placeholder="${h(o.fallbackPlaceholder)}" /> | ||
| </div> | ||
| <div class="rte-data-binding-field"> | ||
| <label for="rte-data-binding-format">${h(o.formatLabel)}</label> | ||
| <select id="rte-data-binding-format" class="rte-data-binding-format"> | ||
| <option value="text" ${l.format === "text" ? "selected" : ""}>Text</option> | ||
| <option value="number" ${l.format === "number" ? "selected" : ""}>Number</option> | ||
| <option value="currency" ${l.format === "currency" ? "selected" : ""}>Currency</option> | ||
| <option value="date" ${l.format === "date" ? "selected" : ""}>Date</option> | ||
| <option value="json" ${l.format === "json" ? "selected" : ""}>JSON</option> | ||
| </select> | ||
| </div> | ||
| <div class="rte-data-binding-field"> | ||
| <label for="rte-data-binding-currency">${h(o.currencyLabel)}</label> | ||
| <input id="rte-data-binding-currency" class="rte-data-binding-currency" type="text" maxlength="3" value="${h( | ||
| l.currency || "USD" | ||
| )}" placeholder="${h(o.currencyPlaceholder)}" /> | ||
| </div> | ||
| <p class="rte-data-binding-help">Use dot paths like <code>user.name</code> or <code>order.total</code>.</p> | ||
| </div> | ||
| <footer class="rte-data-binding-footer"> | ||
| <button type="button" class="rte-data-binding-btn" data-action="cancel">${h(o.cancelText)}</button> | ||
| <button type="button" class="rte-data-binding-btn rte-data-binding-btn-primary" data-action="save">${h(o.saveText)}</button> | ||
| </footer> | ||
| `, d.appendChild(u), document.body.appendChild(d); | ||
| const s = u.querySelector(".rte-data-binding-key"), m = u.querySelector(".rte-data-binding-fallback"), f = u.querySelector(".rte-data-binding-format"), T = u.querySelector(".rte-data-binding-currency"), $ = () => { | ||
| const c = (f == null ? void 0 : f.value) === "currency", y = T == null ? void 0 : T.closest(".rte-data-binding-field"); | ||
| y && (y.style.display = c ? "grid" : "none"); | ||
| }; | ||
| $(), f == null || f.addEventListener("change", $); | ||
| const x = () => { | ||
| d.removeEventListener("click", nt), d.removeEventListener("keydown", rt, !0), document.removeEventListener("keydown", F, !0), d.parentNode && d.parentNode.removeChild(d), K = null, t.focus({ preventScroll: !0 }); | ||
| }, F = (c) => { | ||
| c.key === "Escape" && (c.preventDefault(), c.stopPropagation(), x()); | ||
| }, nt = (c) => { | ||
| c.target === d && x(); | ||
| }, mt = (c) => { | ||
| if (c.key !== "Tab") return; | ||
| const y = Array.from( | ||
| u.querySelectorAll('button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])') | ||
| ); | ||
| if (y.length === 0) return; | ||
| const E = y[0], D = y[y.length - 1], N = document.activeElement; | ||
| if (c.shiftKey && N === E) { | ||
| c.preventDefault(), D.focus(); | ||
| return; | ||
| } | ||
| !c.shiftKey && N === D && (c.preventDefault(), E.focus()); | ||
| }, at = async () => { | ||
| const c = ((s == null ? void 0 : s.value) || "").trim(); | ||
| if (!c) { | ||
| s == null || s.focus(); | ||
| return; | ||
| } | ||
| const y = j( | ||
| { | ||
| key: c, | ||
| fallback: ((m == null ? void 0 : m.value) || "").trim(), | ||
| format: (f == null ? void 0 : f.value) || a.defaultFormat, | ||
| currency: ((T == null ? void 0 : T.value) || "USD").trim().toUpperCase() | ||
| }, | ||
| a | ||
| ), E = t.innerHTML; | ||
| if (n) { | ||
| tt(n, y, o); | ||
| const D = v.get(t) === !0, N = D ? await U(t, a) : void 0; | ||
| C(n, a, D, N); | ||
| } else { | ||
| if (i) | ||
| try { | ||
| ct(t, i); | ||
| } catch (it) { | ||
| } | ||
| const D = ft(y, o); | ||
| if (gt(t, D), v.get(t) === !0) { | ||
| const it = await U(t, a); | ||
| C(D, a, !0, it); | ||
| } | ||
| } | ||
| Y(t), Q(t, E), x(); | ||
| }, rt = (c) => { | ||
| if (c.key === "Escape") { | ||
| c.preventDefault(), x(); | ||
| return; | ||
| } | ||
| mt(c), c.key === "Enter" && !c.shiftKey && c.target instanceof HTMLInputElement && (c.preventDefault(), at()); | ||
| }; | ||
| u.addEventListener("click", (c) => { | ||
| const y = c.target, E = y == null ? void 0 : y.getAttribute("data-action"); | ||
| if (E) { | ||
| if (E === "cancel") { | ||
| x(); | ||
| return; | ||
| } | ||
| E === "save" && at(); | ||
| } | ||
| }), d.addEventListener("click", nt), d.addEventListener("keydown", rt, !0), document.addEventListener("keydown", F, !0), K = { cleanup: x }, s == null || s.focus(); | ||
| } | ||
| function Tt(t) { | ||
| V = t, M || (M = (a) => { | ||
| const e = a.target, r = e == null ? void 0 : e.closest(S); | ||
| if (!r) return; | ||
| k = r, g.has(r) || g.set(r, t); | ||
| const n = g.get(r) || t; | ||
| G(r, n); | ||
| const i = v.get(r) === !0; | ||
| et(r, i, n), i || Array.from(r.querySelectorAll(P)).forEach((l) => C(l, n, !1)); | ||
| }, document.addEventListener("focusin", M, !0)), O || (O = (a) => { | ||
| if (document.querySelector(`.${p}`)) return; | ||
| const e = a.target; | ||
| if (e != null && e.closest("input, textarea, select")) return; | ||
| const r = A(void 0, !1); | ||
| if (!r || H(r)) return; | ||
| const n = g.get(r) || V || t, i = e == null ? void 0 : e.closest(P); | ||
| if (i && (a.key === "Enter" || a.key === " ")) { | ||
| a.preventDefault(), a.stopPropagation(), k = r, L(r, n, "edit", void 0, i); | ||
| return; | ||
| } | ||
| if (At(a)) { | ||
| a.preventDefault(), a.stopPropagation(); | ||
| const o = X(r); | ||
| o ? L(r, n, "edit", void 0, o) : L(r, n, "insert"); | ||
| return; | ||
| } | ||
| if (St(a)) { | ||
| a.preventDefault(), a.stopPropagation(); | ||
| const o = v.get(r) !== !0; | ||
| Z(r, n, o); | ||
| } | ||
| }, document.addEventListener("keydown", O, !0)), B || (B = (a) => { | ||
| if (document.querySelector(`.${p}`) || a.defaultPrevented || a.button !== 0 || a.metaKey || a.ctrlKey || a.altKey || a.shiftKey) return; | ||
| const e = a.target, r = e == null ? void 0 : e.closest(P); | ||
| if (!r) return; | ||
| const n = r.closest(S); | ||
| if (!n || H(n)) return; | ||
| const i = g.get(n) || V || t; | ||
| g.set(n, i), k = n, a.preventDefault(), a.stopPropagation(), r.focus({ preventScroll: !0 }), L(n, i, "edit", void 0, r); | ||
| }, document.addEventListener("click", B, !0)); | ||
| } | ||
| function $t() { | ||
| M && (document.removeEventListener("focusin", M, !0), M = null), O && (document.removeEventListener("keydown", O, !0), O = null), B && (document.removeEventListener("click", B, !0), B = null), V = null, k = null; | ||
| } | ||
| const Lt = (t = {}) => { | ||
| const a = dt(t); | ||
| return vt(), { | ||
| name: "dataBinding", | ||
| toolbar: [ | ||
| { | ||
| id: "dataBindingTools", | ||
| label: "Data Binding", | ||
| type: "group", | ||
| command: "openDataBindingDialog", | ||
| items: [ | ||
| { | ||
| id: "dataBinding", | ||
| label: "Data Binding", | ||
| command: "openDataBindingDialog", | ||
| icon: '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><path d="M7 4a3 3 0 0 0-3 3v3h2V7a1 1 0 0 1 1-1h3V4H7Zm10 0h-3v2h3a1 1 0 0 1 1 1v3h2V7a3 3 0 0 0-3-3ZM4 14v3a3 3 0 0 0 3 3h3v-2H7a1 1 0 0 1-1-1v-3H4Zm14 0v3a1 1 0 0 1-1 1h-3v2h3a3 3 0 0 0 3-3v-3h-2ZM8.5 12a1.5 1.5 0 1 1 0-3h7a1.5 1.5 0 0 1 0 3h-7Zm0 4a1.5 1.5 0 1 1 0-3h4a1.5 1.5 0 0 1 0 3h-4Z" fill="currentColor"></path></svg>' | ||
| }, | ||
| { | ||
| id: "dataBindingPreview", | ||
| label: "Data Preview", | ||
| command: "toggleDataBindingPreview", | ||
| icon: '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><path d="M12 3c-4.4 0-8 1.3-8 3v12c0 1.7 3.6 3 8 3s8-1.3 8-3V6c0-1.7-3.6-3-8-3Zm0 2c3.9 0 6 .9 6 1s-2.1 1-6 1-6-.9-6-1 2.1-1 6-1Zm0 4c3 0 5.6-.5 7-1.3V11c0 .9-2.7 2-7 2s-7-1.1-7-2V7.7C6.4 8.5 9 9 12 9Zm0 6c-4.3 0-7-1.1-7-2v3c0 .9 2.7 2 7 2s7-1.1 7-2v-3c0 .9-2.7 2-7 2Z" fill="currentColor"></path><path d="M16.5 9.4a1 1 0 0 1 1.4 0l1.1 1.1 1.8-1.8a1 1 0 1 1 1.4 1.4l-2.5 2.5a1 1 0 0 1-1.4 0l-1.8-1.8a1 1 0 0 1 0-1.4Z" fill="currentColor"></path></svg>' | ||
| } | ||
| ] | ||
| } | ||
| ], | ||
| commands: { | ||
| openDataBindingDialog: (e, r) => { | ||
| const n = A(r); | ||
| if (!n || H(n)) return !1; | ||
| k = n; | ||
| const i = g.get(n) || a; | ||
| g.set(n, i), G(n, i); | ||
| const o = e == null ? void 0 : e.target; | ||
| if (o === "insert") | ||
| return L(n, i, "insert", e), !0; | ||
| const l = X(n); | ||
| return o === "edit" || l ? !l && o === "edit" ? !1 : (L(n, i, "edit", e, l || void 0), !0) : (L(n, i, "insert", e), !0); | ||
| }, | ||
| insertDataBindingToken: async (e, r) => { | ||
| const n = A(r); | ||
| if (!n || H(n)) return !1; | ||
| k = n; | ||
| const i = g.get(n) || a; | ||
| g.set(n, i); | ||
| const o = j(e || {}, i); | ||
| if (!o.key) return !1; | ||
| const l = n.innerHTML, d = ft(o, i.labels); | ||
| if (gt(n, d), v.get(n) === !0) { | ||
| const s = await U(n, i); | ||
| C(d, i, !0, s); | ||
| } | ||
| return Y(n), Q(n, l), !0; | ||
| }, | ||
| editDataBindingToken: async (e, r) => { | ||
| const n = A(r); | ||
| if (!n || H(n)) return !1; | ||
| k = n; | ||
| const i = g.get(n) || a; | ||
| g.set(n, i); | ||
| const o = X(n); | ||
| if (!o) return !1; | ||
| const l = W(o, i), d = j({ ...l, ...e || {} }, i); | ||
| if (!d.key) return !1; | ||
| const u = n.innerHTML; | ||
| tt(o, d, i.labels); | ||
| const s = v.get(n) === !0, m = s ? await U(n, i) : void 0; | ||
| return C(o, i, s, m), Y(n), Q(n, u), !0; | ||
| }, | ||
| toggleDataBindingPreview: async (e, r) => { | ||
| const n = A(r); | ||
| if (!n) return !1; | ||
| k = n; | ||
| const i = g.get(n) || a; | ||
| g.set(n, i); | ||
| const o = typeof e == "boolean" ? e : v.get(n) !== !0; | ||
| return await Z(n, i, o), !0; | ||
| }, | ||
| setDataBindingData: async (e, r) => { | ||
| const n = A(r); | ||
| if (!n) return !1; | ||
| if (k = n, e && typeof e == "object" ? (J.set(n, e), R.set(n, { timestamp: Date.now(), data: e })) : (J.delete(n), R.delete(n)), v.get(n) === !0) { | ||
| const i = g.get(n) || a; | ||
| await Z(n, i, !0); | ||
| } | ||
| return !0; | ||
| }, | ||
| refreshDataBindings: async (e, r) => { | ||
| const n = A(r); | ||
| if (!n) return !1; | ||
| k = n, R.delete(n); | ||
| const i = g.get(n) || a; | ||
| g.set(n, i); | ||
| const o = v.get(n) === !0; | ||
| return await Z(n, i, o), !0; | ||
| } | ||
| }, | ||
| keymap: { | ||
| "Mod-Alt-Shift-d": "openDataBindingDialog", | ||
| "Mod-Alt-Shift-D": "openDataBindingDialog", | ||
| "Mod-Alt-Shift-b": "toggleDataBindingPreview", | ||
| "Mod-Alt-Shift-B": "toggleDataBindingPreview", | ||
| F7: "openDataBindingDialog", | ||
| F8: "toggleDataBindingPreview" | ||
| }, | ||
| init: function(r) { | ||
| z += 1; | ||
| const n = this && typeof this.__pluginConfig == "object" ? dt({ ...a, ...this.__pluginConfig }) : a; | ||
| Tt(n); | ||
| const i = A( | ||
| r && r.editorElement ? { editorElement: r.editorElement } : void 0, | ||
| !1 | ||
| ); | ||
| if (i) { | ||
| k = i, g.set(i, n), G(i, n); | ||
| const o = v.get(i) === !0; | ||
| et(i, o, n); | ||
| } | ||
| }, | ||
| destroy: () => { | ||
| z = Math.max(0, z - 1), z === 0 && (bt(), $t()); | ||
| } | ||
| }; | ||
| }; | ||
| export { | ||
| Lt as DataBindingPlugin | ||
| }; | ||
| //# sourceMappingURL=DataBindingPlugin.native-jQ1JPRTp.mjs.map |
| const E = ".rte-content, .editora-content", ie = "[data-editora-editor], .rte-editor, .editora-editor, editora-editor", fe = "__editoraCommandEditorRoot", he = "rte-doc-schema-styles", m = "rte-doc-schema-panel", v = "document-schema", T = "doc-schema", R = "docSchema", w = ':is([data-theme="dark"], .dark, .editora-theme-dark, .rte-theme-dark)', Me = { | ||
| panelTitle: "Document Schema", | ||
| panelAriaLabel: "Document schema panel", | ||
| schemaLabel: "Schema", | ||
| schemaDescriptionPrefix: "Description", | ||
| validateText: "Run Validation", | ||
| insertMissingText: "Insert Missing Sections", | ||
| realtimeOnText: "Realtime On", | ||
| realtimeOffText: "Realtime Off", | ||
| closeText: "Close", | ||
| noIssuesText: "No schema violations detected.", | ||
| summaryPrefix: "Schema", | ||
| issueListLabel: "Schema issues", | ||
| shortcutText: "Shortcuts: Ctrl/Cmd+Alt+Shift+G (panel), Ctrl/Cmd+Alt+Shift+J (validate)", | ||
| helperText: "Choose a schema, validate structure, then insert missing sections safely.", | ||
| readonlyMessage: "Editor is read-only. Missing sections cannot be inserted.", | ||
| defaultPlaceholderText: "Add section content.", | ||
| missingSectionMessage: "Missing required section", | ||
| duplicateSectionMessage: "Section appears too many times", | ||
| outOfOrderMessage: "Section appears out of required order", | ||
| unknownHeadingMessage: "Heading is not part of selected schema", | ||
| insertedSummaryPrefix: "Inserted missing sections" | ||
| }, u = /* @__PURE__ */ new WeakMap(), X = /* @__PURE__ */ new WeakMap(), j = /* @__PURE__ */ new WeakMap(), S = /* @__PURE__ */ new Map(), F = /* @__PURE__ */ new WeakMap(), te = /* @__PURE__ */ new WeakMap(), ne = /* @__PURE__ */ new Set(); | ||
| let W = 0, Ae = 0, ge = 0, k = null, y = null, q = null, z = null, B = null, H = null, K = null; | ||
| function M(e) { | ||
| return e.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'"); | ||
| } | ||
| function Le(e) { | ||
| return e.replace(/\u00A0/g, " ").replace(/\s+/g, " ").trim(); | ||
| } | ||
| function P(e, t, n) { | ||
| return Number.isFinite(e) ? Math.max(t, Math.min(n, e)) : t; | ||
| } | ||
| function ye(e) { | ||
| return e.toLowerCase().replace(/[^a-z0-9_-]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 80); | ||
| } | ||
| function ce(e, t) { | ||
| return t(e).toLowerCase().replace(/^[\s\-\u2022]*(?:[0-9]+(?:\.[0-9]+)*)[\)\.\-:\s]+/, "").replace(/^[\s\-\u2022]*(?:[ivxlcdm]+)[\)\.\-:\s]+/i, "").replace(/[::]+$/g, "").replace(/\s+/g, " ").trim(); | ||
| } | ||
| function pe() { | ||
| return [ | ||
| { | ||
| id: "contract", | ||
| label: "Contract", | ||
| description: "Template for legal/commercial agreements with strict section ordering.", | ||
| strictOrder: !0, | ||
| allowUnknownHeadings: !1, | ||
| sections: [ | ||
| { id: "summary", title: "Executive Summary", aliases: ["Overview"] }, | ||
| { id: "scope", title: "Scope" }, | ||
| { id: "terms", title: "Terms and Conditions", aliases: ["Terms"] }, | ||
| { id: "responsibilities", title: "Responsibilities" }, | ||
| { id: "sla", title: "Service Levels", aliases: ["SLA", "Service Level Agreement"] }, | ||
| { id: "termination", title: "Termination" } | ||
| ] | ||
| }, | ||
| { | ||
| id: "sop", | ||
| label: "SOP", | ||
| description: "Standard operating procedure with clear implementation and governance sections.", | ||
| strictOrder: !0, | ||
| allowUnknownHeadings: !0, | ||
| sections: [ | ||
| { id: "purpose", title: "Purpose" }, | ||
| { id: "scope", title: "Scope" }, | ||
| { id: "procedure", title: "Procedure", maxOccurrences: 10 }, | ||
| { id: "roles", title: "Roles and Responsibilities", aliases: ["Responsibilities"] }, | ||
| { id: "validation", title: "Validation" }, | ||
| { id: "revision-history", title: "Revision History", aliases: ["Change History"] } | ||
| ] | ||
| }, | ||
| { | ||
| id: "policy", | ||
| label: "Policy", | ||
| description: "Policy document with control ownership, exception handling, and enforcement.", | ||
| strictOrder: !0, | ||
| allowUnknownHeadings: !0, | ||
| sections: [ | ||
| { id: "statement", title: "Policy Statement" }, | ||
| { id: "applicability", title: "Applicability", aliases: ["Scope"] }, | ||
| { id: "controls", title: "Controls" }, | ||
| { id: "exceptions", title: "Exceptions" }, | ||
| { id: "enforcement", title: "Enforcement" } | ||
| ] | ||
| } | ||
| ]; | ||
| } | ||
| function Oe(e, t, n) { | ||
| var f, h; | ||
| const r = n(e.title || ""); | ||
| if (!r) return null; | ||
| const s = ye(n(e.id || r)) || `section-${t + 1}`, o = P(Number((f = e.minOccurrences) != null ? f : 1), 0, 20), a = Math.max(1, o), c = P(Number((h = e.maxOccurrences) != null ? h : a), o, 40), i = n(e.placeholder || ""), l = Array.isArray(e.aliases) ? e.aliases.map((b) => n(b)).filter(Boolean) : [], d = [r, ...l].map((b) => ce(b, n)).filter(Boolean); | ||
| return { | ||
| id: s, | ||
| title: r, | ||
| minOccurrences: o, | ||
| maxOccurrences: c, | ||
| placeholder: i, | ||
| matchKeys: Array.from(new Set(d)) | ||
| }; | ||
| } | ||
| function Se(e, t) { | ||
| const n = Array.isArray(e) && e.length > 0 ? e : pe(), r = [], s = /* @__PURE__ */ new Set(); | ||
| return n.forEach((o, a) => { | ||
| const c = t(o.label || ""); | ||
| if (!c) return; | ||
| const i = ye(t(o.id || c)) || `schema-${a + 1}`; | ||
| let l = i, d = 1; | ||
| for (; s.has(l); ) | ||
| l = `${i}-${d++}`; | ||
| s.add(l); | ||
| const f = Array.isArray(o.sections) ? o.sections : [], h = [], b = /* @__PURE__ */ new Set(); | ||
| if (f.forEach(($, g) => { | ||
| const x = Oe($, g, t); | ||
| if (!x) return; | ||
| let N = x.id, Ie = 1; | ||
| for (; b.has(N); ) | ||
| N = `${x.id}-${Ie++}`; | ||
| b.add(N), h.push({ | ||
| ...x, | ||
| id: N | ||
| }); | ||
| }), h.length === 0) return; | ||
| const O = /* @__PURE__ */ new Map(), A = /* @__PURE__ */ new Map(); | ||
| h.forEach(($, g) => { | ||
| A.set($.id, g), $.matchKeys.forEach((x) => { | ||
| O.has(x) || O.set(x, $); | ||
| }); | ||
| }), r.push({ | ||
| id: l, | ||
| label: c, | ||
| description: t(o.description || ""), | ||
| strictOrder: o.strictOrder !== !1, | ||
| allowUnknownHeadings: !!o.allowUnknownHeadings, | ||
| sections: h, | ||
| matchKeyToSection: O, | ||
| orderBySectionId: A | ||
| }); | ||
| }), r.length > 0 ? r : Se(pe(), t); | ||
| } | ||
| function Z(e = {}) { | ||
| var o, a, c; | ||
| const t = e.normalizeText || Le, n = Se(e.schemas, t), r = t(e.defaultSchemaId || ""), s = n.some((i) => i.id === r) ? r : ((o = n[0]) == null ? void 0 : o.id) || null; | ||
| return { | ||
| schemas: n, | ||
| defaultSchemaId: s, | ||
| enableRealtime: e.enableRealtime !== !1, | ||
| debounceMs: P(Number((a = e.debounceMs) != null ? a : 260), 60, 2e3), | ||
| maxIssues: P(Number((c = e.maxIssues) != null ? c : 80), 5, 500), | ||
| labels: { | ||
| ...Me, | ||
| ...e.labels || {} | ||
| }, | ||
| normalizeText: t | ||
| }; | ||
| } | ||
| function Re(e) { | ||
| return { | ||
| schemas: e.schemas.map((t) => ({ | ||
| id: t.id, | ||
| label: t.label, | ||
| description: t.description || void 0, | ||
| strictOrder: t.strictOrder, | ||
| allowUnknownHeadings: t.allowUnknownHeadings, | ||
| sections: t.sections.map((n) => ({ | ||
| id: n.id, | ||
| title: n.title, | ||
| minOccurrences: n.minOccurrences, | ||
| maxOccurrences: n.maxOccurrences, | ||
| placeholder: n.placeholder || void 0 | ||
| })) | ||
| })), | ||
| defaultSchemaId: e.defaultSchemaId || void 0, | ||
| enableRealtime: e.enableRealtime, | ||
| debounceMs: e.debounceMs, | ||
| maxIssues: e.maxIssues, | ||
| labels: { ...e.labels }, | ||
| normalizeText: e.normalizeText | ||
| }; | ||
| } | ||
| function le(e) { | ||
| return e.closest(ie) || e; | ||
| } | ||
| function U(e) { | ||
| if (!e) return null; | ||
| if (e.matches(E)) return e; | ||
| const t = e.querySelector(E); | ||
| return t instanceof HTMLElement ? t : null; | ||
| } | ||
| function He() { | ||
| if (typeof window == "undefined") return null; | ||
| const e = window[fe]; | ||
| if (!(e instanceof HTMLElement)) return null; | ||
| window[fe] = null; | ||
| const t = U(e); | ||
| if (t) return t; | ||
| const n = e.closest(ie); | ||
| if (n) { | ||
| const s = U(n); | ||
| if (s) return s; | ||
| } | ||
| const r = e.closest(E); | ||
| return r instanceof HTMLElement ? r : null; | ||
| } | ||
| function De(e) { | ||
| const t = e.closest("[data-editora-editor]"); | ||
| if (t && U(t) === e) | ||
| return t; | ||
| let n = e; | ||
| for (; n; ) { | ||
| if (n.matches(ie) && (n === e || U(n) === e)) | ||
| return n; | ||
| n = n.parentElement; | ||
| } | ||
| return le(e); | ||
| } | ||
| function xe(e) { | ||
| return e ? e.nodeType === Node.ELEMENT_NODE ? e : e.parentElement : null; | ||
| } | ||
| function Y(e) { | ||
| return e ? (e.getAttribute("data-theme") || e.getAttribute("theme") || "").toLowerCase() === "dark" ? !0 : e.classList.contains("dark") || e.classList.contains("editora-theme-dark") || e.classList.contains("rte-theme-dark") : !1; | ||
| } | ||
| function Ne(e) { | ||
| const t = le(e); | ||
| if (Y(t)) return !0; | ||
| const n = t.closest("[data-theme], [theme], .dark, .editora-theme-dark, .rte-theme-dark"); | ||
| return Y(n) ? !0 : Y(document.documentElement) || Y(document.body); | ||
| } | ||
| function oe(e, t) { | ||
| e.classList.remove("rte-doc-schema-theme-dark"), Ne(t) && e.classList.add("rte-doc-schema-theme-dark"); | ||
| } | ||
| function Pe(e) { | ||
| var t, n, r, s; | ||
| for (let o = 0; o < e.length; o += 1) { | ||
| const a = e[o]; | ||
| if (!(a.type !== "childList" || a.removedNodes.length === 0)) | ||
| for (let c = 0; c < a.removedNodes.length; c += 1) { | ||
| const i = a.removedNodes[c]; | ||
| if (i.nodeType !== Node.ELEMENT_NODE) continue; | ||
| const l = i; | ||
| if ((t = l.matches) != null && t.call(l, E) || (n = l.matches) != null && n.call(l, `.${m}`) || (r = l.querySelector) != null && r.call(l, E) || (s = l.querySelector) != null && s.call(l, `.${m}`)) | ||
| return !0; | ||
| } | ||
| } | ||
| return !1; | ||
| } | ||
| function Q() { | ||
| Array.from(ne).forEach((t) => { | ||
| t.isConnected || ue(t); | ||
| }); | ||
| } | ||
| function I(e, t = !0, n = !0) { | ||
| var c; | ||
| if (Q(), (e == null ? void 0 : e.contentElement) instanceof HTMLElement) return e.contentElement; | ||
| if ((e == null ? void 0 : e.editorElement) instanceof HTMLElement) { | ||
| const i = U(e.editorElement); | ||
| if (i) return i; | ||
| } | ||
| const r = He(); | ||
| if (r) return r; | ||
| const s = window.getSelection(); | ||
| if (s && s.rangeCount > 0) { | ||
| const i = (c = xe(s.getRangeAt(0).startContainer)) == null ? void 0 : c.closest( | ||
| E | ||
| ); | ||
| if (i) return i; | ||
| } | ||
| const o = document.activeElement; | ||
| if (o) { | ||
| if (o.matches(E)) return o; | ||
| const i = o.closest(E); | ||
| if (i) return i; | ||
| } | ||
| if (n && y && y.isConnected) | ||
| return y; | ||
| if (!t) return null; | ||
| const a = document.querySelector(E); | ||
| return a instanceof HTMLElement ? a : null; | ||
| } | ||
| function _e(e) { | ||
| const t = e.target; | ||
| if (t) { | ||
| const r = t.closest(`.${m}`); | ||
| if (r) { | ||
| const o = Array.from(S.entries()).find(([, a]) => a === r); | ||
| if (o) return o[0]; | ||
| } | ||
| const s = t.closest(E); | ||
| if (s) return s; | ||
| } | ||
| const n = document.activeElement; | ||
| if (n) { | ||
| const r = n.closest(`.${m}`); | ||
| if (r) { | ||
| const o = Array.from(S.entries()).find(([, a]) => a === r); | ||
| if (o) return o[0]; | ||
| } | ||
| const s = n.closest(E); | ||
| if (s) return s; | ||
| } | ||
| return null; | ||
| } | ||
| function be(e, t, n) { | ||
| const r = De(e); | ||
| Array.from( | ||
| r.querySelectorAll( | ||
| `.rte-toolbar-button[data-command="${t}"], .editora-toolbar-button[data-command="${t}"]` | ||
| ) | ||
| ).forEach((o) => { | ||
| o.classList.toggle("active", n), o.setAttribute("data-active", n ? "true" : "false"), o.setAttribute("aria-pressed", n ? "true" : "false"); | ||
| }); | ||
| } | ||
| function de(e) { | ||
| const t = te.get(e); | ||
| typeof t == "number" && (window.clearTimeout(t), te.delete(e)); | ||
| } | ||
| function L(e, t) { | ||
| return t && e.schemas.find((n) => n.id === t) || null; | ||
| } | ||
| function re(e) { | ||
| var t; | ||
| return e.defaultSchemaId || ((t = e.schemas[0]) == null ? void 0 : t.id) || null; | ||
| } | ||
| function p(e, t) { | ||
| u.has(e) || u.set(e, t); | ||
| let n = j.get(e); | ||
| return n || (n = { | ||
| activeSchemaId: re(t), | ||
| realtimeEnabled: t.enableRealtime, | ||
| issues: [], | ||
| headingCount: 0, | ||
| recognizedHeadingCount: 0, | ||
| missingCount: 0, | ||
| lastRunAt: null, | ||
| snapshot: "" | ||
| }, j.set(e, n)), (!n.activeSchemaId || !L(t, n.activeSchemaId)) && (n.activeSchemaId = re(t)), ne.add(e), n; | ||
| } | ||
| function ue(e) { | ||
| var t; | ||
| de(e), (t = S.get(e)) == null || t.remove(), S.delete(e), F.delete(e), u.delete(e), X.delete(e), j.delete(e), ne.delete(e), y === e && (y = null); | ||
| } | ||
| function me(e) { | ||
| return F.get(e) === !0; | ||
| } | ||
| function Ee(e) { | ||
| return e.getAttribute("contenteditable") === "false" || e.getAttribute("data-readonly") === "true"; | ||
| } | ||
| function se(e, t) { | ||
| if (!t.classList.contains("show")) return; | ||
| const n = le(e).getBoundingClientRect(), r = Math.min(window.innerWidth - 20, 440), s = Math.max(10, window.innerWidth - r - 10), o = Math.min(Math.max(10, n.right - r), s), a = Math.max(10, Math.min(window.innerHeight - 10, n.top + 12)); | ||
| t.style.width = `${r}px`, t.style.left = `${o}px`, t.style.top = `${a}px`, t.style.maxHeight = `${Math.max(260, window.innerHeight - 20)}px`; | ||
| } | ||
| function ee(e, t) { | ||
| const n = e.querySelector(".rte-doc-schema-live"); | ||
| n && (n.textContent = t); | ||
| } | ||
| function qe(e, t) { | ||
| const n = Array.from(e.querySelectorAll("h1, h2, h3, h4, h5, h6")), r = []; | ||
| return n.forEach((s, o) => { | ||
| const a = t(s.textContent || ""); | ||
| if (!a) return; | ||
| const c = Number(s.tagName.slice(1)) || 0, i = ce(a, t); | ||
| r.push({ | ||
| text: a, | ||
| key: i, | ||
| index: o, | ||
| level: c | ||
| }); | ||
| }), r; | ||
| } | ||
| function ve(e, t, n) { | ||
| const r = Array.from(e.querySelectorAll("h1, h2, h3, h4, h5, h6")), s = []; | ||
| return r.forEach((o) => { | ||
| var f; | ||
| const a = n(o.textContent || ""); | ||
| if (!a) return; | ||
| const c = ce(a, n), i = c && t.matchKeyToSection.get(c) || null, l = i && (f = t.orderBySectionId.get(i.id)) != null ? f : null, d = P(Number(o.tagName.slice(1)) || 0, 1, 6); | ||
| s.push({ | ||
| element: o, | ||
| level: d, | ||
| section: i, | ||
| order: l | ||
| }); | ||
| }), s; | ||
| } | ||
| function ze(e, t = 2) { | ||
| const n = e.filter((i) => i.section).map((i) => i.level), r = n.length > 0 ? n : e.map((i) => i.level); | ||
| if (r.length === 0) return t; | ||
| const s = /* @__PURE__ */ new Map(); | ||
| r.forEach((i, l) => { | ||
| s.has(i) || s.set(i, { count: 0, firstIndex: l }); | ||
| const d = s.get(i); | ||
| d.count += 1; | ||
| }); | ||
| let o = t, a = -1, c = Number.MAX_SAFE_INTEGER; | ||
| return s.forEach((i, l) => { | ||
| (i.count > a || i.count === a && i.firstIndex < c || i.count === a && i.firstIndex === c && l < o) && (o = l, a = i.count, c = i.firstIndex); | ||
| }), P(o, 1, 6); | ||
| } | ||
| function Be(e) { | ||
| var o; | ||
| const t = window.getSelection(); | ||
| if (!t || t.rangeCount === 0) return null; | ||
| const n = t.getRangeAt(0); | ||
| if (((o = xe(n.startContainer)) == null ? void 0 : o.closest(E)) !== e) return null; | ||
| if (n.startContainer.nodeType === Node.ELEMENT_NODE) { | ||
| const a = n.startContainer, c = a.childNodes[n.startOffset] || null; | ||
| return { parent: a, referenceNode: c }; | ||
| } | ||
| const s = n.startContainer.parentNode; | ||
| return s ? { | ||
| parent: s, | ||
| referenceNode: n.startContainer.nextSibling || null | ||
| } : null; | ||
| } | ||
| function Ke(e, t, n, r) { | ||
| var i; | ||
| const s = ve(e, n, r), o = n.orderBySectionId.get(t.id); | ||
| if (typeof o != "number" || s.length === 0) | ||
| return { parent: e, referenceNode: null }; | ||
| const a = s.find((l) => typeof l.order == "number" && l.order > o); | ||
| if (a && a.element.parentNode) | ||
| return { | ||
| parent: a.element.parentNode, | ||
| referenceNode: a.element | ||
| }; | ||
| let c = -1; | ||
| for (let l = 0; l < s.length; l += 1) { | ||
| const d = s[l]; | ||
| typeof d.order == "number" && d.order < o && (c = l); | ||
| } | ||
| if (c >= 0) { | ||
| const l = ((i = s[c + 1]) == null ? void 0 : i.element) || null; | ||
| return { | ||
| parent: (l == null ? void 0 : l.parentNode) || s[c].element.parentNode || e, | ||
| referenceNode: l | ||
| }; | ||
| } | ||
| return { parent: e, referenceNode: null }; | ||
| } | ||
| function Ve(e, t, n, r) { | ||
| const s = e.ownerDocument || document, o = `h${P(r, 1, 6)}`, a = s.createElement(o); | ||
| a.setAttribute("data-doc-schema-section", t.id), a.textContent = t.title; | ||
| const c = s.createElement("p"); | ||
| return c.textContent = t.placeholder || n.labels.defaultPlaceholderText, [a, c]; | ||
| } | ||
| function V(e, t, n, r = {}) { | ||
| return ge += 1, { | ||
| id: `doc-schema-issue-${ge}`, | ||
| type: e, | ||
| severity: t, | ||
| message: n, | ||
| ...r | ||
| }; | ||
| } | ||
| function J(e, t, n) { | ||
| return e.replace(/\{section\}/g, t || "").replace(/\{heading\}/g, n || "").trim(); | ||
| } | ||
| function je(e, t, n) { | ||
| var i; | ||
| const r = qe(e, n.normalizeText), s = [], o = /* @__PURE__ */ new Map(), a = []; | ||
| for (let l = 0; l < r.length && !(s.length >= n.maxIssues); l += 1) { | ||
| const d = r[l]; | ||
| if (!d.key) continue; | ||
| const f = t.matchKeyToSection.get(d.key); | ||
| if (f) { | ||
| o.set(f.id, (o.get(f.id) || 0) + 1), a.push({ section: f, heading: d }); | ||
| continue; | ||
| } | ||
| t.allowUnknownHeadings || s.push( | ||
| V( | ||
| "unknown-heading", | ||
| "warning", | ||
| J(n.labels.unknownHeadingMessage, null, d.text), | ||
| { | ||
| headingText: d.text, | ||
| suggestion: "Map this heading to a schema alias or remove it from strict structure mode." | ||
| } | ||
| ) | ||
| ); | ||
| } | ||
| let c = 0; | ||
| for (let l = 0; l < t.sections.length && !(s.length >= n.maxIssues); l += 1) { | ||
| const d = t.sections[l], f = o.get(d.id) || 0; | ||
| f < d.minOccurrences && (c += 1, s.push( | ||
| V( | ||
| "missing-section", | ||
| "error", | ||
| J(n.labels.missingSectionMessage, d.title, null), | ||
| { | ||
| sectionId: d.id, | ||
| sectionTitle: d.title, | ||
| suggestion: `Add heading "${d.title}" to satisfy schema requirements.` | ||
| } | ||
| ) | ||
| )), f > d.maxOccurrences && s.length < n.maxIssues && s.push( | ||
| V( | ||
| "duplicate-section", | ||
| "warning", | ||
| J(n.labels.duplicateSectionMessage, d.title, null), | ||
| { | ||
| sectionId: d.id, | ||
| sectionTitle: d.title, | ||
| suggestion: `Keep at most ${d.maxOccurrences} instance(s) of "${d.title}".` | ||
| } | ||
| ) | ||
| ); | ||
| } | ||
| if (t.strictOrder && s.length < n.maxIssues) { | ||
| let l = -1; | ||
| for (let d = 0; d < a.length && !(s.length >= n.maxIssues); d += 1) { | ||
| const f = a[d], h = (i = t.orderBySectionId.get(f.section.id)) != null ? i : d; | ||
| h < l ? s.push( | ||
| V( | ||
| "out-of-order", | ||
| "warning", | ||
| J(n.labels.outOfOrderMessage, f.section.title, f.heading.text), | ||
| { | ||
| sectionId: f.section.id, | ||
| sectionTitle: f.section.title, | ||
| headingText: f.heading.text, | ||
| suggestion: `Move "${f.section.title}" after earlier required sections.` | ||
| } | ||
| ) | ||
| ) : l = h; | ||
| } | ||
| } | ||
| return { | ||
| issues: s, | ||
| headingCount: r.length, | ||
| recognizedHeadingCount: a.length, | ||
| missingCount: c | ||
| }; | ||
| } | ||
| function we(e) { | ||
| const t = u.get(e) || k, n = j.get(e), r = t ? L(t, (n == null ? void 0 : n.activeSchemaId) || null) : null; | ||
| return { | ||
| activeSchemaId: (n == null ? void 0 : n.activeSchemaId) || null, | ||
| activeSchemaLabel: (r == null ? void 0 : r.label) || null, | ||
| realtimeEnabled: (n == null ? void 0 : n.realtimeEnabled) === !0, | ||
| issues: n != null && n.issues ? n.issues.map((s) => ({ ...s })) : [], | ||
| headingCount: (n == null ? void 0 : n.headingCount) || 0, | ||
| recognizedHeadingCount: (n == null ? void 0 : n.recognizedHeadingCount) || 0, | ||
| missingCount: (n == null ? void 0 : n.missingCount) || 0, | ||
| lastRunAt: (n == null ? void 0 : n.lastRunAt) || null | ||
| }; | ||
| } | ||
| function D(e) { | ||
| const t = j.get(e); | ||
| be(e, "toggleDocSchemaPanel", me(e)), be(e, "toggleDocSchemaRealtime", (t == null ? void 0 : t.realtimeEnabled) === !0); | ||
| } | ||
| function _(e) { | ||
| const t = S.get(e); | ||
| if (!t) return; | ||
| const n = u.get(e) || k; | ||
| if (!n) return; | ||
| const r = p(e, n), s = L(n, r.activeSchemaId), o = t.querySelector(".rte-doc-schema-label"); | ||
| o && (o.textContent = n.labels.schemaLabel); | ||
| const a = t.querySelector('[data-field="schema"]'); | ||
| a && (a.innerHTML = n.schemas.map((g) => `<option value="${M(g.id)}">${M(g.label)}</option>`).join(""), a.value = r.activeSchemaId || ""); | ||
| const c = t.querySelector(".rte-doc-schema-description"); | ||
| if (c) { | ||
| const g = (s == null ? void 0 : s.description) || ""; | ||
| c.textContent = g ? `${n.labels.schemaDescriptionPrefix}: ${g}` : "", c.hidden = !g; | ||
| } | ||
| const i = t.querySelector(".rte-doc-schema-summary"); | ||
| if (i) { | ||
| const g = (s == null ? void 0 : s.label) || "N/A", x = r.issues.length; | ||
| i.textContent = `${n.labels.summaryPrefix}: ${g} • ${x} issue${x === 1 ? "" : "s"}`; | ||
| } | ||
| const l = t.querySelector(".rte-doc-schema-helper"); | ||
| l && (l.textContent = n.labels.helperText); | ||
| const d = t.querySelector(".rte-doc-schema-shortcut"); | ||
| d && (d.textContent = n.labels.shortcutText); | ||
| const f = t.querySelector('[data-action="run-validation"]'); | ||
| f && (f.textContent = n.labels.validateText); | ||
| const h = t.querySelector('[data-action="insert-missing"]'); | ||
| if (h) { | ||
| h.textContent = n.labels.insertMissingText; | ||
| const g = r.issues.some((x) => x.type === "missing-section"); | ||
| h.disabled = !g || Ee(e); | ||
| } | ||
| const b = t.querySelector('[data-action="toggle-realtime"]'); | ||
| b && (b.textContent = r.realtimeEnabled ? n.labels.realtimeOnText : n.labels.realtimeOffText, b.setAttribute("aria-pressed", r.realtimeEnabled ? "true" : "false")); | ||
| const O = t.querySelector('[data-action="close"]'); | ||
| O && O.setAttribute("aria-label", n.labels.closeText); | ||
| const A = t.querySelector(".rte-doc-schema-issues"), $ = t.querySelector(".rte-doc-schema-empty"); | ||
| A && (A.setAttribute("aria-label", n.labels.issueListLabel), r.issues.length === 0 ? (A.innerHTML = "", $ && ($.hidden = !1, $.textContent = n.labels.noIssuesText)) : ($ && ($.hidden = !0), A.innerHTML = r.issues.map((g) => { | ||
| const x = g.severity === "error" ? "error" : g.severity === "warning" ? "warning" : "info", N = g.sectionTitle || g.headingText || ""; | ||
| return ` | ||
| <li class="rte-doc-schema-issue ${x}" role="listitem"> | ||
| <p class="rte-doc-schema-issue-message">${M(g.message)}${N ? `: <strong>${M(N)}</strong>` : ""}</p> | ||
| ${g.suggestion ? `<p class="rte-doc-schema-issue-suggestion">${M(g.suggestion)}</p>` : ""} | ||
| </li> | ||
| `; | ||
| }).join(""))), t.setAttribute("aria-label", n.labels.panelAriaLabel); | ||
| } | ||
| function G(e, t = !1) { | ||
| const n = S.get(e); | ||
| n && (n.classList.remove("show"), F.set(e, !1), D(e), t && e.focus({ preventScroll: !0 })); | ||
| } | ||
| function ae(e) { | ||
| const t = Fe(e); | ||
| S.forEach((r, s) => { | ||
| s !== e && G(s, !1); | ||
| }), t.classList.add("show"), F.set(e, !0), _(e), se(e, t), D(e); | ||
| const n = t.querySelector('[data-field="schema"]'); | ||
| n == null || n.focus(), C(e, "panel-open", !1); | ||
| } | ||
| function ke(e, t) { | ||
| const n = me(e); | ||
| return (typeof t == "boolean" ? t : !n) ? ae(e) : G(e, !1), !0; | ||
| } | ||
| function Ue(e, t) { | ||
| if (t === e.innerHTML) return; | ||
| const n = window.execEditorCommand || window.executeEditorCommand; | ||
| if (typeof n == "function") | ||
| try { | ||
| n("recordDomTransaction", e, t, e.innerHTML); | ||
| } catch (r) { | ||
| } | ||
| } | ||
| function Ge(e) { | ||
| e.dispatchEvent(new Event("input", { bubbles: !0 })); | ||
| } | ||
| function C(e, t, n) { | ||
| const r = u.get(e) || k; | ||
| if (!r) return []; | ||
| const s = p(e, r), o = S.get(e), a = e.innerHTML; | ||
| if (!n && s.snapshot === a) | ||
| return s.issues; | ||
| const c = L(r, s.activeSchemaId); | ||
| if (!c) | ||
| return s.issues = [ | ||
| V("missing-section", "error", "No active schema is configured for this editor.", { | ||
| suggestion: "Set `defaultSchemaId` or update schema options." | ||
| }) | ||
| ], s.headingCount = 0, s.recognizedHeadingCount = 0, s.missingCount = 1, s.lastRunAt = (/* @__PURE__ */ new Date()).toISOString(), s.snapshot = a, _(e), D(e), s.issues; | ||
| const i = je(e, c, r); | ||
| return s.issues = i.issues, s.headingCount = i.headingCount, s.recognizedHeadingCount = i.recognizedHeadingCount, s.missingCount = i.missingCount, s.lastRunAt = (/* @__PURE__ */ new Date()).toISOString(), s.snapshot = a, _(e), D(e), e.dispatchEvent( | ||
| new CustomEvent("editora:doc-schema-validation", { | ||
| bubbles: !0, | ||
| detail: { | ||
| reason: t, | ||
| state: we(e) | ||
| } | ||
| }) | ||
| ), o && ee( | ||
| o, | ||
| i.issues.length === 0 ? r.labels.noIssuesText : `${i.issues.length} issue${i.issues.length === 1 ? "" : "s"} detected.` | ||
| ), s.issues; | ||
| } | ||
| function $e(e) { | ||
| const t = u.get(e) || k; | ||
| if (!t) return; | ||
| de(e); | ||
| const n = window.setTimeout(() => { | ||
| te.delete(e), C(e, "realtime", !1); | ||
| }, t.debounceMs); | ||
| te.set(e, n); | ||
| } | ||
| function Ce(e, t) { | ||
| const n = u.get(e) || k; | ||
| if (!n) return !1; | ||
| const r = p(e, n), s = typeof t == "boolean" ? t : !r.realtimeEnabled; | ||
| return r.realtimeEnabled = s, s ? $e(e) : de(e), _(e), D(e), !0; | ||
| } | ||
| function Te(e) { | ||
| const t = u.get(e) || k; | ||
| if (!t) return !1; | ||
| const n = p(e, t), r = S.get(e); | ||
| if (Ee(e)) | ||
| return r && ee(r, t.labels.readonlyMessage), !1; | ||
| const s = L(t, n.activeSchemaId); | ||
| if (!s) return !1; | ||
| C(e, "insert-missing-pre", !0); | ||
| const o = Array.from( | ||
| new Set( | ||
| n.issues.filter((h) => h.type === "missing-section" && h.sectionId).map((h) => h.sectionId) | ||
| ) | ||
| ), a = s.sections.filter((h) => o.includes(h.id)); | ||
| if (a.length === 0) | ||
| return r && ee(r, t.labels.noIssuesText), !1; | ||
| const c = e.innerHTML, i = ve(e, s, t.normalizeText), l = ze(i, 2), d = Be(e); | ||
| a.forEach((h) => { | ||
| const b = s.strictOrder ? Ke(e, h, s, t.normalizeText) : d || { parent: e, referenceNode: null }, [O, A] = Ve(e, h, t, l); | ||
| b.parent.insertBefore(O, b.referenceNode), b.parent.insertBefore(A, b.referenceNode); | ||
| }), Ue(e, c), Ge(e), C(e, "insert-missing-post", !0); | ||
| const f = a.map((h) => h.title).join(", "); | ||
| return e.dispatchEvent( | ||
| new CustomEvent("editora:doc-schema-insert-missing", { | ||
| bubbles: !0, | ||
| detail: { | ||
| schemaId: s.id, | ||
| sectionIds: a.map((h) => h.id) | ||
| } | ||
| }) | ||
| ), r && ee(r, `${t.labels.insertedSummaryPrefix}: ${f}`), !0; | ||
| } | ||
| function Fe(e) { | ||
| const t = S.get(e); | ||
| if (t) return t; | ||
| const n = u.get(e) || k || Z(); | ||
| p(e, n); | ||
| const r = `rte-doc-schema-panel-${Ae++}`, s = `${r}-schema`, o = document.createElement("section"); | ||
| return o.className = m, o.id = r, o.setAttribute("role", "dialog"), o.setAttribute("aria-modal", "false"), o.setAttribute("aria-label", n.labels.panelAriaLabel), o.innerHTML = ` | ||
| <header class="rte-doc-schema-header"> | ||
| <h2 class="rte-doc-schema-title">${M(n.labels.panelTitle)}</h2> | ||
| <button type="button" class="rte-doc-schema-icon-btn" data-action="close" aria-label="${M( | ||
| n.labels.closeText | ||
| )}">✕</button> | ||
| </header> | ||
| <div class="rte-doc-schema-body"> | ||
| <label class="rte-doc-schema-label" for="${M(s)}"></label> | ||
| <select id="${M(s)}" class="rte-doc-schema-select" data-field="schema"></select> | ||
| <p class="rte-doc-schema-description" hidden></p> | ||
| <p class="rte-doc-schema-summary"></p> | ||
| <div class="rte-doc-schema-actions"> | ||
| <button type="button" class="rte-doc-schema-btn rte-doc-schema-btn-primary" data-action="run-validation"></button> | ||
| <button type="button" class="rte-doc-schema-btn" data-action="insert-missing"></button> | ||
| <button type="button" class="rte-doc-schema-btn" data-action="toggle-realtime" aria-pressed="false"></button> | ||
| </div> | ||
| <p class="rte-doc-schema-helper"></p> | ||
| <p class="rte-doc-schema-shortcut"></p> | ||
| <div class="rte-doc-schema-issues-wrap"> | ||
| <ul class="rte-doc-schema-issues" role="list" aria-label="${M(n.labels.issueListLabel)}"></ul> | ||
| <p class="rte-doc-schema-empty" hidden></p> | ||
| </div> | ||
| </div> | ||
| <div class="rte-doc-schema-live" aria-live="polite" aria-atomic="true"></div> | ||
| `, o.addEventListener("click", (a) => { | ||
| const c = a.target, i = c == null ? void 0 : c.closest("[data-action]"); | ||
| if (!i) return; | ||
| const l = i.getAttribute("data-action"); | ||
| if (l === "close") { | ||
| G(e, !0); | ||
| return; | ||
| } | ||
| if (l === "run-validation") { | ||
| C(e, "panel-button", !0); | ||
| return; | ||
| } | ||
| if (l === "insert-missing") { | ||
| Te(e); | ||
| return; | ||
| } | ||
| l === "toggle-realtime" && Ce(e); | ||
| }), o.addEventListener("change", (a) => { | ||
| const c = a.target; | ||
| if (!(c instanceof HTMLSelectElement) || c.getAttribute("data-field") !== "schema") return; | ||
| const i = u.get(e) || k; | ||
| if (!i) return; | ||
| const l = p(e, i), d = c.value; | ||
| L(i, d) && (l.activeSchemaId = d, l.snapshot = "", C(e, "schema-change", !0)); | ||
| }), o.addEventListener("keydown", (a) => { | ||
| a.key === "Escape" && (a.preventDefault(), G(e, !0)); | ||
| }), oe(o, e), document.body.appendChild(o), S.set(e, o), F.set(e, !1), _(e), o; | ||
| } | ||
| function We(e) { | ||
| const t = e.key.toLowerCase(); | ||
| return (e.metaKey || e.ctrlKey) && e.altKey && e.shiftKey && t === "g"; | ||
| } | ||
| function Ye(e) { | ||
| const t = e.key.toLowerCase(); | ||
| return (e.metaKey || e.ctrlKey) && e.altKey && e.shiftKey && t === "j"; | ||
| } | ||
| function Je(e) { | ||
| k = e, q || (q = (t) => { | ||
| Q(); | ||
| const n = t.target, r = n == null ? void 0 : n.closest(E); | ||
| if (!r) return; | ||
| const s = u.get(r) || e; | ||
| p(r, s), u.set(r, s), y = r, D(r); | ||
| const o = S.get(r); | ||
| o && (oe(o, r), se(r, o), _(r)); | ||
| }, document.addEventListener("focusin", q, !0)), z || (z = (t) => { | ||
| const n = t.target, r = n == null ? void 0 : n.closest(E); | ||
| if (!r) return; | ||
| const s = u.get(r) || k; | ||
| !s || !p(r, s).realtimeEnabled || $e(r); | ||
| }, document.addEventListener("input", z, !0)), B || (B = (t) => { | ||
| if (t.defaultPrevented) return; | ||
| const n = t.target; | ||
| if (n != null && n.closest(`.${m}`) && t.key !== "Escape") return; | ||
| const r = _e(t); | ||
| if (!r) return; | ||
| const s = u.get(r) || k || e; | ||
| if (p(r, s), u.set(r, s), y = r, t.key === "Escape" && me(r)) { | ||
| t.preventDefault(), G(r, !0); | ||
| return; | ||
| } | ||
| if (We(t)) { | ||
| t.preventDefault(), t.stopPropagation(), ke(r); | ||
| return; | ||
| } | ||
| Ye(t) && (t.preventDefault(), t.stopPropagation(), C(r, "shortcut", !0)); | ||
| }, document.addEventListener("keydown", B, !0)), H || (H = () => { | ||
| Q(), S.forEach((t, n) => { | ||
| !n.isConnected || !t.isConnected || (oe(t, n), se(n, t)); | ||
| }); | ||
| }, window.addEventListener("scroll", H, !0), window.addEventListener("resize", H)), !K && typeof MutationObserver != "undefined" && document.body && (K = new MutationObserver((t) => { | ||
| Pe(t) && Q(); | ||
| }), K.observe(document.body, { | ||
| childList: !0, | ||
| subtree: !0 | ||
| })); | ||
| } | ||
| function Xe() { | ||
| q && (document.removeEventListener("focusin", q, !0), q = null), z && (document.removeEventListener("input", z, !0), z = null), B && (document.removeEventListener("keydown", B, !0), B = null), H && (window.removeEventListener("scroll", H, !0), window.removeEventListener("resize", H), H = null), K && (K.disconnect(), K = null), S.forEach((t) => t.remove()), S.clear(), Array.from(ne).forEach((t) => ue(t)), k = null, y = null; | ||
| } | ||
| function Ze() { | ||
| if (typeof document == "undefined" || document.getElementById(he)) return; | ||
| const e = document.createElement("style"); | ||
| e.id = he, e.textContent = ` | ||
| .rte-toolbar-group-items.${v}, | ||
| .editora-toolbar-group-items.${v}, | ||
| .rte-toolbar-group-items.${T}, | ||
| .editora-toolbar-group-items.${T}, | ||
| .rte-toolbar-group-items.${R}, | ||
| .editora-toolbar-group-items.${R} { | ||
| display: flex; | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 4px; | ||
| background: #ffffff; | ||
| } | ||
| .rte-toolbar-group-items.${v} .rte-toolbar-button, | ||
| .editora-toolbar-group-items.${v} .editora-toolbar-button, | ||
| .rte-toolbar-group-items.${T} .rte-toolbar-button, | ||
| .editora-toolbar-group-items.${T} .editora-toolbar-button, | ||
| .rte-toolbar-group-items.${R} .rte-toolbar-button, | ||
| .editora-toolbar-group-items.${R} .editora-toolbar-button { | ||
| border: none; | ||
| border-right: 1px solid #cbd5e1; | ||
| border-radius: 0; | ||
| } | ||
| .rte-toolbar-group-items.${v} .rte-toolbar-item:last-child .rte-toolbar-button, | ||
| .editora-toolbar-group-items.${v} .editora-toolbar-item:last-child .editora-toolbar-button, | ||
| .rte-toolbar-group-items.${T} .rte-toolbar-item:last-child .rte-toolbar-button, | ||
| .editora-toolbar-group-items.${T} .editora-toolbar-item:last-child .editora-toolbar-button, | ||
| .rte-toolbar-group-items.${R} .rte-toolbar-item:last-child .rte-toolbar-button, | ||
| .editora-toolbar-group-items.${R} .editora-toolbar-item:last-child .editora-toolbar-button { | ||
| border-right: none; | ||
| } | ||
| ${w} .rte-toolbar-group-items.${v}, | ||
| ${w} .editora-toolbar-group-items.${v}, | ||
| ${w} .rte-toolbar-group-items.${T}, | ||
| ${w} .editora-toolbar-group-items.${T}, | ||
| ${w} .rte-toolbar-group-items.${R}, | ||
| ${w} .editora-toolbar-group-items.${R} { | ||
| border-color: #566275; | ||
| } | ||
| .rte-toolbar-button[data-command="toggleDocSchemaRealtime"].active, | ||
| .editora-toolbar-button[data-command="toggleDocSchemaRealtime"].active { | ||
| background-color: #ccc; | ||
| } | ||
| ${w} .rte-toolbar-group-items.${v} .rte-toolbar-button svg, | ||
| ${w} .editora-toolbar-group-items.${v} .editora-toolbar-button svg, | ||
| ${w} .rte-toolbar-group-items.${T} .rte-toolbar-button svg, | ||
| ${w} .editora-toolbar-group-items.${T} .editora-toolbar-button svg | ||
| { | ||
| fill: none; | ||
| } | ||
| ${w} .rte-toolbar-group-items.${v} .rte-toolbar-button, | ||
| ${w} .editora-toolbar-group-items.${v} .editora-toolbar-button | ||
| { | ||
| border-color: #566275; | ||
| } | ||
| .${m} { | ||
| position: fixed; | ||
| z-index: 12000; | ||
| display: none; | ||
| width: min(440px, calc(100vw - 20px)); | ||
| max-height: calc(100vh - 20px); | ||
| border: 1px solid #d1d5db; | ||
| border-radius: 14px; | ||
| background: #ffffff; | ||
| color: #0f172a; | ||
| box-shadow: 0 24px 48px rgba(15, 23, 42, 0.24); | ||
| overflow: hidden; | ||
| } | ||
| .${m}.show { | ||
| display: flex; | ||
| flex-direction: column; | ||
| } | ||
| .${m}.rte-doc-schema-theme-dark { | ||
| border-color: #334155; | ||
| background: #0f172a; | ||
| color: #e2e8f0; | ||
| box-shadow: 0 24px 52px rgba(2, 6, 23, 0.68); | ||
| } | ||
| .rte-doc-schema-header { | ||
| display: flex; | ||
| align-items: center; | ||
| justify-content: space-between; | ||
| gap: 8px; | ||
| padding: 12px 14px; | ||
| border-bottom: 1px solid #e2e8f0; | ||
| background: linear-gradient(180deg, #f8fafc 0%, #f1f5f9 100%); | ||
| } | ||
| .${m}.rte-doc-schema-theme-dark .rte-doc-schema-header { | ||
| border-color: #1e293b; | ||
| background: linear-gradient(180deg, #111827 0%, #0f172a 100%); | ||
| } | ||
| .rte-doc-schema-title { | ||
| margin: 0; | ||
| font-size: 15px; | ||
| line-height: 1.2; | ||
| font-weight: 700; | ||
| } | ||
| .rte-doc-schema-icon-btn { | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 6px; | ||
| min-height: 34px; | ||
| width: 34px; | ||
| background: #ffffff; | ||
| color: #0f172a; | ||
| font-size: 16px; | ||
| line-height: 1; | ||
| font-weight: 600; | ||
| padding: 0; | ||
| display: inline-flex; | ||
| align-items: center; | ||
| justify-content: center; | ||
| cursor: pointer; | ||
| } | ||
| .rte-doc-schema-icon-btn:hover, | ||
| .rte-doc-schema-icon-btn:focus-visible { | ||
| outline: none; | ||
| border-color: #3b82f6; | ||
| box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.2); | ||
| } | ||
| .${m}.rte-doc-schema-theme-dark .rte-doc-schema-icon-btn { | ||
| border-color: #475569; | ||
| background: #0f172a; | ||
| color: #e2e8f0; | ||
| } | ||
| .${m}.rte-doc-schema-theme-dark .rte-doc-schema-icon-btn:hover, | ||
| .${m}.rte-doc-schema-theme-dark .rte-doc-schema-icon-btn:focus-visible { | ||
| border-color: #60a5fa; | ||
| box-shadow: 0 0 0 3px rgba(96, 165, 250, 0.24); | ||
| } | ||
| .rte-doc-schema-body { | ||
| display: flex; | ||
| flex-direction: column; | ||
| gap: 8px; | ||
| padding: 12px; | ||
| overflow: auto; | ||
| } | ||
| .rte-doc-schema-label { | ||
| font-size: 12px; | ||
| line-height: 1.3; | ||
| font-weight: 700; | ||
| color: #334155; | ||
| } | ||
| .${m}.rte-doc-schema-theme-dark .rte-doc-schema-label { | ||
| color: #cbd5e1; | ||
| } | ||
| .rte-doc-schema-select { | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 8px; | ||
| min-height: 34px; | ||
| padding: 0 10px; | ||
| font-size: 13px; | ||
| background: #ffffff; | ||
| color: inherit; | ||
| } | ||
| .rte-doc-schema-select:focus-visible { | ||
| border-color: #0f766e; | ||
| box-shadow: 0 0 0 3px rgba(15, 118, 110, 0.18); | ||
| outline: none; | ||
| } | ||
| .${m}.rte-doc-schema-theme-dark .rte-doc-schema-select { | ||
| border-color: #334155; | ||
| background: #0b1220; | ||
| color: #e2e8f0; | ||
| } | ||
| .rte-doc-schema-description, | ||
| .rte-doc-schema-summary, | ||
| .rte-doc-schema-helper, | ||
| .rte-doc-schema-shortcut { | ||
| margin: 0; | ||
| font-size: 12px; | ||
| line-height: 1.35; | ||
| color: #475569; | ||
| } | ||
| .${m}.rte-doc-schema-theme-dark .rte-doc-schema-description, | ||
| .${m}.rte-doc-schema-theme-dark .rte-doc-schema-summary, | ||
| .${m}.rte-doc-schema-theme-dark .rte-doc-schema-helper, | ||
| .${m}.rte-doc-schema-theme-dark .rte-doc-schema-shortcut { | ||
| color: #94a3b8; | ||
| } | ||
| .rte-doc-schema-actions { | ||
| display: grid; | ||
| grid-template-columns: repeat(3, minmax(0, 1fr)); | ||
| gap: 8px; | ||
| } | ||
| .rte-doc-schema-btn { | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 8px; | ||
| min-height: 34px; | ||
| padding: 0 8px; | ||
| background: #ffffff; | ||
| color: inherit; | ||
| font-size: 12px; | ||
| font-weight: 700; | ||
| cursor: pointer; | ||
| } | ||
| .rte-doc-schema-btn:disabled { | ||
| opacity: 0.6; | ||
| cursor: not-allowed; | ||
| } | ||
| .rte-doc-schema-btn-primary { | ||
| border-color: #0f766e; | ||
| background: #0f766e; | ||
| color: #f8fafc; | ||
| } | ||
| .rte-doc-schema-btn:hover, | ||
| .rte-doc-schema-btn:focus-visible { | ||
| border-color: #94a3b8; | ||
| outline: none; | ||
| } | ||
| .rte-doc-schema-btn-primary:hover, | ||
| .rte-doc-schema-btn-primary:focus-visible { | ||
| border-color: #115e59; | ||
| background: #115e59; | ||
| } | ||
| .${m}.rte-doc-schema-theme-dark .rte-doc-schema-btn { | ||
| border-color: #334155; | ||
| background: #111827; | ||
| color: #e2e8f0; | ||
| } | ||
| .${m}.rte-doc-schema-theme-dark .rte-doc-schema-btn-primary { | ||
| border-color: #14b8a6; | ||
| background: #0f766e; | ||
| color: #f0fdfa; | ||
| } | ||
| .rte-doc-schema-issues-wrap { | ||
| border: 1px solid #e2e8f0; | ||
| border-radius: 10px; | ||
| padding: 6px; | ||
| background: #f8fafc; | ||
| max-height: min(40vh, 320px); | ||
| overflow: auto; | ||
| } | ||
| .${m}.rte-doc-schema-theme-dark .rte-doc-schema-issues-wrap { | ||
| border-color: #334155; | ||
| background: #0b1220; | ||
| } | ||
| .rte-doc-schema-issues { | ||
| margin: 0; | ||
| padding: 0; | ||
| list-style: none; | ||
| display: grid; | ||
| gap: 6px; | ||
| } | ||
| .rte-doc-schema-issue { | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 8px; | ||
| background: #ffffff; | ||
| padding: 8px; | ||
| display: grid; | ||
| gap: 4px; | ||
| } | ||
| .rte-doc-schema-issue.error { | ||
| border-color: #ef4444; | ||
| background: #fef2f2; | ||
| } | ||
| .rte-doc-schema-issue.warning { | ||
| border-color: #f59e0b; | ||
| background: #fffbeb; | ||
| } | ||
| .rte-doc-schema-issue.info { | ||
| border-color: #0ea5e9; | ||
| background: #f0f9ff; | ||
| } | ||
| .${m}.rte-doc-schema-theme-dark .rte-doc-schema-issue { | ||
| border-color: #334155; | ||
| background: #111827; | ||
| color: #e2e8f0; | ||
| } | ||
| .${m}.rte-doc-schema-theme-dark .rte-doc-schema-issue.error { | ||
| border-color: rgba(239, 68, 68, 0.7); | ||
| background: rgba(127, 29, 29, 0.28); | ||
| } | ||
| .${m}.rte-doc-schema-theme-dark .rte-doc-schema-issue.warning { | ||
| border-color: rgba(245, 158, 11, 0.72); | ||
| background: rgba(120, 53, 15, 0.28); | ||
| } | ||
| .${m}.rte-doc-schema-theme-dark .rte-doc-schema-issue.info { | ||
| border-color: rgba(14, 165, 233, 0.7); | ||
| background: rgba(7, 89, 133, 0.28); | ||
| } | ||
| .rte-doc-schema-issue-message, | ||
| .rte-doc-schema-issue-suggestion { | ||
| margin: 0; | ||
| font-size: 12px; | ||
| line-height: 1.35; | ||
| color: #1f2937; | ||
| } | ||
| .rte-doc-schema-issue-suggestion { | ||
| color: #475569; | ||
| } | ||
| .${m}.rte-doc-schema-theme-dark .rte-doc-schema-issue-message { | ||
| color: #e2e8f0; | ||
| } | ||
| .${m}.rte-doc-schema-theme-dark .rte-doc-schema-issue-suggestion { | ||
| color: #cbd5e1; | ||
| } | ||
| .rte-doc-schema-empty { | ||
| margin: 8px; | ||
| font-size: 12px; | ||
| color: #64748b; | ||
| } | ||
| .rte-doc-schema-live { | ||
| position: absolute; | ||
| width: 1px; | ||
| height: 1px; | ||
| margin: -1px; | ||
| padding: 0; | ||
| overflow: hidden; | ||
| clip: rect(0 0 0 0); | ||
| border: 0; | ||
| } | ||
| @media (max-width: 768px) { | ||
| .${m} { | ||
| left: 10px !important; | ||
| right: 10px; | ||
| top: 10px !important; | ||
| width: auto !important; | ||
| max-height: calc(100vh - 20px); | ||
| } | ||
| .rte-doc-schema-actions { | ||
| grid-template-columns: 1fr; | ||
| } | ||
| } | ||
| `, document.head.appendChild(e); | ||
| } | ||
| const Qe = (e = {}) => { | ||
| const t = Z(e), n = /* @__PURE__ */ new Set(); | ||
| return Ze(), { | ||
| name: "docSchema", | ||
| toolbar: [ | ||
| { | ||
| id: "docSchemaGroup", | ||
| label: "Document Schema", | ||
| type: "group", | ||
| command: "docSchema", | ||
| items: [ | ||
| { | ||
| id: "toggleDocSchemaPanel", | ||
| label: "Document Schema", | ||
| command: "toggleDocSchemaPanel", | ||
| shortcut: "Mod-Alt-Shift-g", | ||
| icon: '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><path d="M6 4.5h12A1.5 1.5 0 0 1 19.5 6v12A1.5 1.5 0 0 1 18 19.5H6A1.5 1.5 0 0 1 4.5 18V6A1.5 1.5 0 0 1 6 4.5Z" stroke="currentColor" stroke-width="1.6"/><path d="M8 8h8M8 12h8M8 16h5" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/></svg>' | ||
| }, | ||
| { | ||
| id: "runDocSchemaValidation", | ||
| label: "Run Schema Validation", | ||
| command: "runDocSchemaValidation", | ||
| shortcut: "Mod-Alt-Shift-j", | ||
| icon: '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><path d="M12 3.5 4.5 6.5v5c0 4.8 3.1 8.9 7.5 10 4.4-1.1 7.5-5.2 7.5-10v-5L12 3.5Z" stroke="currentColor" stroke-width="1.6"/><path d="m9 12.5 2 2 4-4" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/></svg>' | ||
| }, | ||
| { | ||
| id: "toggleDocSchemaRealtime", | ||
| label: "Toggle Schema Realtime", | ||
| command: "toggleDocSchemaRealtime", | ||
| icon: '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><path d="M4.5 12a7.5 7.5 0 1 1 7.5 7.5" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/><path d="M9.5 19.5H5.5v-4" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/><circle cx="12" cy="12" r="2" fill="currentColor"/></svg>' | ||
| } | ||
| ] | ||
| } | ||
| ], | ||
| commands: { | ||
| docSchema: (r, s) => { | ||
| const o = I(s, !1, !1); | ||
| if (!o) return !1; | ||
| const a = u.get(o) || t; | ||
| return p(o, a), u.set(o, a), y = o, ae(o), !0; | ||
| }, | ||
| openDocSchemaPanel: (r, s) => { | ||
| const o = I(s, !1, !1); | ||
| if (!o) return !1; | ||
| const a = u.get(o) || t; | ||
| return p(o, a), u.set(o, a), y = o, ae(o), !0; | ||
| }, | ||
| toggleDocSchemaPanel: (r, s) => { | ||
| const o = I(s, !1, !1); | ||
| if (!o) return !1; | ||
| const a = u.get(o) || t; | ||
| return p(o, a), u.set(o, a), y = o, ke(o, typeof r == "boolean" ? r : void 0); | ||
| }, | ||
| runDocSchemaValidation: (r, s) => { | ||
| const o = I(s, !1, !1); | ||
| if (!o) return !1; | ||
| const a = u.get(o) || t; | ||
| return p(o, a), u.set(o, a), y = o, C(o, "command", !0), !0; | ||
| }, | ||
| insertMissingDocSchemaSections: (r, s) => { | ||
| const o = I(s, !1, !1); | ||
| if (!o) return !1; | ||
| const a = u.get(o) || t; | ||
| return p(o, a), u.set(o, a), y = o, Te(o); | ||
| }, | ||
| toggleDocSchemaRealtime: (r, s) => { | ||
| const o = I(s, !1, !1); | ||
| if (!o) return !1; | ||
| const a = u.get(o) || t; | ||
| return p(o, a), u.set(o, a), y = o, Ce(o, typeof r == "boolean" ? r : void 0); | ||
| }, | ||
| setDocSchemaMode: (r, s) => { | ||
| const o = I(s, !1, !1); | ||
| if (!o) return !1; | ||
| const a = u.get(o) || t, c = p(o, a); | ||
| u.set(o, a); | ||
| const i = typeof r == "string" ? r : (r == null ? void 0 : r.schemaId) || (r == null ? void 0 : r.id); | ||
| return !i || !L(a, i) ? !1 : (c.activeSchemaId = i, c.snapshot = "", C(o, "set-mode", !0), !0); | ||
| }, | ||
| setDocSchemaOptions: (r, s) => { | ||
| const o = I(s, !1, !1); | ||
| if (!o || !r || typeof r != "object") return !1; | ||
| const a = u.get(o) || t, c = X.get(o) || Re(a), i = { | ||
| ...c, | ||
| ...r, | ||
| labels: { | ||
| ...c.labels || {}, | ||
| ...r.labels || {} | ||
| }, | ||
| schemas: Array.isArray(r.schemas) ? r.schemas : c.schemas, | ||
| normalizeText: r.normalizeText || a.normalizeText | ||
| }, l = Z(i); | ||
| u.set(o, l), X.set(o, i); | ||
| const d = p(o, l); | ||
| return typeof r.enableRealtime == "boolean" && (d.realtimeEnabled = r.enableRealtime), (!d.activeSchemaId || !L(l, d.activeSchemaId)) && (d.activeSchemaId = re(l)), typeof r.defaultSchemaId == "string" && L(l, r.defaultSchemaId) && (d.activeSchemaId = r.defaultSchemaId), d.snapshot = "", C(o, "set-options", !0), _(o), D(o), !0; | ||
| }, | ||
| getDocSchemaState: (r, s) => { | ||
| const o = I(s, !1, !1); | ||
| if (!o) return !1; | ||
| const a = u.get(o) || t; | ||
| p(o, a); | ||
| const c = we(o); | ||
| if (typeof r == "function") | ||
| try { | ||
| r(c); | ||
| } catch (i) { | ||
| } | ||
| return o.__docSchemaState = c, o.dispatchEvent( | ||
| new CustomEvent("editora:doc-schema-state", { | ||
| bubbles: !0, | ||
| detail: c | ||
| }) | ||
| ), !0; | ||
| } | ||
| }, | ||
| keymap: { | ||
| "Mod-Alt-Shift-g": "toggleDocSchemaPanel", | ||
| "Mod-Alt-Shift-G": "toggleDocSchemaPanel", | ||
| "Mod-Alt-Shift-j": "runDocSchemaValidation", | ||
| "Mod-Alt-Shift-J": "runDocSchemaValidation" | ||
| }, | ||
| init: function(s) { | ||
| W += 1; | ||
| const o = this && typeof this.__pluginConfig == "object" ? { ...e, ...this.__pluginConfig } : e, a = Z(o); | ||
| Je(a); | ||
| const c = I( | ||
| s != null && s.editorElement ? { editorElement: s.editorElement } : void 0, | ||
| !1, | ||
| !1 | ||
| ); | ||
| c && (y = c, n.add(c), p(c, a), u.set(c, a), X.set(c, o), D(c), C(c, "init", !0)); | ||
| }, | ||
| destroy: () => { | ||
| n.forEach((r) => ue(r)), n.clear(), W = Math.max(0, W - 1), !(W > 0) && Xe(); | ||
| } | ||
| }; | ||
| }; | ||
| export { | ||
| Qe as DocSchemaPlugin | ||
| }; | ||
| //# sourceMappingURL=DocSchemaPlugin.native-CHOge18O.mjs.map |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
| const p = ".rte-content, .editora-content", ie = "[data-editora-editor], .rte-editor, .editora-editor, editora-editor", w = '.rte-mention[data-mention="true"]', b = ':is([data-theme="dark"], .dark, .editora-theme-dark, .rte-theme-dark)', R = /* @__PURE__ */ new WeakMap(), N = /* @__PURE__ */ new WeakMap(); | ||
| let F = !1, S = !1, T = null, k = 0; | ||
| function X(e, n) { | ||
| if (n === e.innerHTML) return; | ||
| const o = window.execEditorCommand || window.executeEditorCommand; | ||
| if (typeof o == "function") | ||
| try { | ||
| o("recordDomTransaction", e, n, e.innerHTML); | ||
| } catch (t) { | ||
| } | ||
| } | ||
| function J(e) { | ||
| e.dispatchEvent(new Event("input", { bubbles: !0 })); | ||
| } | ||
| function h(e, n) { | ||
| const o = window.getSelection(); | ||
| o && (o.removeAllRanges(), o.addRange(n), e.focus({ preventScroll: !0 })); | ||
| } | ||
| function A(e, n) { | ||
| return e.startContainer === n.startContainer && e.startOffset === n.startOffset && e.endContainer === n.endContainer && e.endOffset === n.endOffset; | ||
| } | ||
| function E(e) { | ||
| const n = window.getSelection(); | ||
| if (!n || n.rangeCount === 0) return null; | ||
| const o = n.getRangeAt(0); | ||
| return e.contains(o.commonAncestorContainer) ? o.cloneRange() : null; | ||
| } | ||
| function C(e) { | ||
| Array.from(e.querySelectorAll(w)).forEach((o) => { | ||
| o.setAttribute("data-mention", "true"), o.setAttribute("contenteditable", "false"), o.setAttribute("spellcheck", "false"), o.setAttribute("draggable", "false"), o.classList.add("rte-mention"); | ||
| }); | ||
| } | ||
| function Q(e) { | ||
| return e ? e.nodeType === Node.ELEMENT_NODE ? e : e.parentElement : null; | ||
| } | ||
| function ae(e) { | ||
| return e.closest(ie) || e; | ||
| } | ||
| function L(e) { | ||
| return e ? (e.getAttribute("data-theme") || e.getAttribute("theme") || "").toLowerCase() === "dark" ? !0 : e.classList.contains("dark") || e.classList.contains("editora-theme-dark") || e.classList.contains("rte-theme-dark") : !1; | ||
| } | ||
| function le(e) { | ||
| const n = ae(e); | ||
| if (L(n)) return !0; | ||
| const o = n.closest("[data-theme], [theme], .dark, .editora-theme-dark, .rte-theme-dark"); | ||
| return L(o) ? !0 : L(document.documentElement) || L(document.body); | ||
| } | ||
| function Z(e, n) { | ||
| e.classList.remove("rte-mention-theme-dark"), le(n) && e.classList.add("rte-mention-theme-dark"); | ||
| } | ||
| function se(e) { | ||
| if ((e == null ? void 0 : e.contentElement) instanceof HTMLElement) return e.contentElement; | ||
| if ((e == null ? void 0 : e.editorElement) instanceof HTMLElement) { | ||
| const t = e.editorElement; | ||
| if (t.matches(p)) return t; | ||
| const r = t.querySelector(p); | ||
| if (r instanceof HTMLElement) return r; | ||
| } | ||
| const n = window.getSelection(); | ||
| if (n && n.rangeCount > 0) { | ||
| const t = n.getRangeAt(0).startContainer, r = t.nodeType === Node.ELEMENT_NODE ? t : t.parentElement, i = r == null ? void 0 : r.closest(p); | ||
| if (i) return i; | ||
| } | ||
| const o = document.activeElement; | ||
| if (o) { | ||
| if (o.matches(p)) return o; | ||
| const t = o.closest(p); | ||
| if (t) return t; | ||
| } | ||
| return document.querySelector(p); | ||
| } | ||
| function x(e) { | ||
| return e.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'"); | ||
| } | ||
| function q(e) { | ||
| return typeof e == "object" && e !== null && !Array.isArray(e); | ||
| } | ||
| function ce(e, n) { | ||
| return n ? n.split(".").filter(Boolean).reduce((o, t) => { | ||
| if (!(!q(o) && !Array.isArray(o))) | ||
| return o[t]; | ||
| }, e) : e; | ||
| } | ||
| function ue(e) { | ||
| return e ? /\s|[([{"'`]/.test(e) : !0; | ||
| } | ||
| function de(e) { | ||
| if (!e.collapsed) return null; | ||
| const n = e.startContainer, o = e.startOffset; | ||
| if (n.nodeType === Node.TEXT_NODE) { | ||
| const t = n; | ||
| return { | ||
| node: t, | ||
| textBefore: t.data.slice(0, o), | ||
| caretOffset: o | ||
| }; | ||
| } | ||
| if (n.nodeType === Node.ELEMENT_NODE) { | ||
| const t = n; | ||
| if (o > 0) { | ||
| const r = t.childNodes[o - 1]; | ||
| if (r && r.nodeType === Node.TEXT_NODE) { | ||
| const i = r; | ||
| return { | ||
| node: i, | ||
| textBefore: i.data, | ||
| caretOffset: i.length | ||
| }; | ||
| } | ||
| } | ||
| } | ||
| return null; | ||
| } | ||
| function fe(e, n, o) { | ||
| let t = -1, r = ""; | ||
| if (n.forEach((a) => { | ||
| const l = e.lastIndexOf(a); | ||
| l > t && (t = l, r = a); | ||
| }), t < 0 || !ue(e[t - 1])) return null; | ||
| const i = e.slice(t + 1); | ||
| return /\s/.test(i) || i.length > o ? null : { | ||
| trigger: r, | ||
| query: i, | ||
| startOffset: t | ||
| }; | ||
| } | ||
| function me(e, n) { | ||
| const o = n.cloneRange(); | ||
| o.collapse(!1); | ||
| const t = o.getClientRects(); | ||
| if (t.length > 0) | ||
| return t[t.length - 1]; | ||
| const r = document.createElement("span"); | ||
| r.textContent = "", r.style.position = "relative", o.insertNode(r); | ||
| const i = r.getBoundingClientRect(); | ||
| return r.remove(), e.normalize(), i; | ||
| } | ||
| function ge(e, n) { | ||
| if (e.panel && e.list) return; | ||
| const o = document.createElement("div"); | ||
| o.className = "rte-mention-panel", o.style.display = "none"; | ||
| const t = document.createElement("div"); | ||
| t.className = "rte-mention-list", o.appendChild(t), document.body.appendChild(o), Z(o, e.editor), e.panel = o, e.list = t, o.addEventListener("mousedown", (r) => { | ||
| r.preventDefault(); | ||
| }), o.addEventListener("click", (r) => { | ||
| const i = r.target; | ||
| if (!i) return; | ||
| const a = i.closest(".rte-mention-item"); | ||
| if (!a) return; | ||
| const l = Number(a.getAttribute("data-index")); | ||
| Number.isFinite(l) && ee(e, n, l); | ||
| }); | ||
| } | ||
| function m(e) { | ||
| e.panel && (e.debounceHandle !== null && (window.clearTimeout(e.debounceHandle), e.debounceHandle = null), e.abortController && (e.abortController.abort(), e.abortController = null), e.panel.style.display = "none", e.panel.classList.remove("show"), e.isOpen = !1, e.loading = !1, e.items = [], e.activeIndex = 0, e.query = "", e.replaceRange = null); | ||
| } | ||
| function U(e, n) { | ||
| if (!e.panel) return; | ||
| Z(e.panel, e.editor); | ||
| const o = me(e.editor, n), t = e.panel; | ||
| t.style.display = "block", t.classList.add("show"), t.style.left = "0px", t.style.top = "0px"; | ||
| const r = t.getBoundingClientRect(), i = window.innerWidth, a = window.innerHeight; | ||
| let l = Math.max(8, Math.min(o.left, i - r.width - 8)), s = o.bottom + 8; | ||
| s + r.height > a - 8 && (s = Math.max(8, o.top - r.height - 8)), t.style.position = "fixed", t.style.left = `${l}px`, t.style.top = `${s}px`; | ||
| } | ||
| function pe(e, n) { | ||
| if (!n) return x(e); | ||
| const o = e.toLowerCase(), t = n.toLowerCase(), r = o.indexOf(t); | ||
| if (r < 0) return x(e); | ||
| const i = x(e.slice(0, r)), a = x(e.slice(r, r + n.length)), l = x(e.slice(r + n.length)); | ||
| return `${i}<mark>${a}</mark>${l}`; | ||
| } | ||
| function W(e, n) { | ||
| if (!e.list) return; | ||
| const o = e.list; | ||
| if (o.innerHTML = "", e.loading) { | ||
| const t = document.createElement("div"); | ||
| t.className = "rte-mention-empty", t.textContent = n.loadingText, o.appendChild(t); | ||
| return; | ||
| } | ||
| if (e.items.length === 0) { | ||
| const t = document.createElement("div"); | ||
| t.className = "rte-mention-empty", t.textContent = e.query.length > 0 ? n.noResultsText : n.emptyStateText, o.appendChild(t); | ||
| return; | ||
| } | ||
| e.items.forEach((t, r) => { | ||
| const i = document.createElement("button"); | ||
| i.type = "button", i.className = "rte-mention-item", r === e.activeIndex && i.classList.add("active"), i.setAttribute("data-index", String(r)); | ||
| const a = n.itemRenderer ? n.itemRenderer(t, e.query) : `<span class="rte-mention-item-label">${pe(t.label, e.query)}</span>${t.meta ? `<span class="rte-mention-item-meta">${x(t.meta)}</span>` : ""}`; | ||
| i.innerHTML = a, o.appendChild(i); | ||
| }); | ||
| } | ||
| function Y(e, n) { | ||
| const o = /* @__PURE__ */ new Set(), t = []; | ||
| return e.forEach((r) => { | ||
| const i = (r.id || "").trim(); | ||
| !i || o.has(i) || (o.add(i), t.push({ | ||
| id: i, | ||
| label: r.label || i, | ||
| value: r.value, | ||
| meta: r.meta | ||
| })); | ||
| }), t.slice(0, n); | ||
| } | ||
| function he(e, n) { | ||
| if (e.buildRequest) { | ||
| const c = e.buildRequest(n); | ||
| return { | ||
| url: c.url, | ||
| init: c.init || {} | ||
| }; | ||
| } | ||
| const o = (e.method || "GET").toUpperCase(), t = typeof e.headers == "function" ? e.headers(n) : e.headers || {}, r = e.queryParam || "q", i = e.triggerParam || "trigger", a = e.limitParam || "limit", l = e.staticParams || {}, s = { | ||
| method: o, | ||
| headers: { ...t }, | ||
| credentials: e.credentials, | ||
| mode: e.mode, | ||
| cache: e.cache, | ||
| signal: n.signal | ||
| }, f = new URL(e.url, window.location.origin); | ||
| if (o === "GET" || o === "HEAD") { | ||
| const c = new URLSearchParams(f.search); | ||
| Object.entries(l).forEach(([u, g]) => c.set(u, String(g))), c.set(r, n.query), c.set(i, n.trigger), c.set(a, String(n.limit)), f.search = c.toString(); | ||
| } else { | ||
| const c = typeof e.body == "function" ? e.body(n) : e.body, u = { | ||
| [r]: n.query, | ||
| [i]: n.trigger, | ||
| [a]: n.limit, | ||
| ...l | ||
| }, g = c != null ? c : u; | ||
| if (q(g)) { | ||
| s.body = JSON.stringify(g); | ||
| const y = s.headers; | ||
| !y["Content-Type"] && !y["content-type"] && (y["Content-Type"] = "application/json"); | ||
| } else | ||
| s.body = g; | ||
| } | ||
| return { url: f.toString(), init: s }; | ||
| } | ||
| async function ye(e, n, o, t) { | ||
| var f, c; | ||
| const r = n.api; | ||
| if (!r) return []; | ||
| e.abortController && e.abortController.abort(); | ||
| const i = new AbortController(); | ||
| e.abortController = i; | ||
| const a = { | ||
| query: o, | ||
| trigger: t, | ||
| limit: n.maxSuggestions, | ||
| signal: i.signal | ||
| }, l = Math.max(0, (f = r.timeoutMs) != null ? f : 1e4); | ||
| let s = null; | ||
| l > 0 && (s = window.setTimeout(() => i.abort(), l)); | ||
| try { | ||
| const { url: u, init: g } = he(r, a), y = await fetch(u, { | ||
| ...g, | ||
| signal: i.signal | ||
| }); | ||
| if (!y.ok) | ||
| throw new Error(`Mention API request failed: ${y.status}`); | ||
| const v = (r.responseType || "json") === "text" ? await y.text() : await y.json(); | ||
| let I = []; | ||
| if (r.transformResponse) | ||
| I = r.transformResponse(v, a) || []; | ||
| else { | ||
| const P = ce(v, r.responsePath); | ||
| I = (Array.isArray(P) ? P : Array.isArray(v) ? v : []).map((d, re) => { | ||
| var _, $, B, j, z; | ||
| if (r.mapItem) | ||
| return r.mapItem(d, re); | ||
| if (!q(d)) return null; | ||
| const H = String((B = ($ = (_ = d.id) != null ? _ : d.value) != null ? $ : d.key) != null ? B : "").trim(); | ||
| if (!H) return null; | ||
| const oe = String((z = (j = d.label) != null ? j : d.name) != null ? z : H).trim(); | ||
| return { | ||
| id: H, | ||
| label: oe, | ||
| value: d.value ? String(d.value) : void 0, | ||
| meta: d.meta ? String(d.meta) : void 0 | ||
| }; | ||
| }).filter((d) => !!d); | ||
| } | ||
| return Y(I, n.maxSuggestions); | ||
| } catch (u) { | ||
| return (u == null ? void 0 : u.name) !== "AbortError" && ((c = r.onError) == null || c.call(r, u, a)), []; | ||
| } finally { | ||
| s !== null && window.clearTimeout(s), e.abortController === i && (e.abortController = null); | ||
| } | ||
| } | ||
| async function be(e, n, o, t) { | ||
| const r = ++e.requestId; | ||
| let i = []; | ||
| if (n.search) { | ||
| const a = await n.search(o, t); | ||
| i = Array.isArray(a) ? a : []; | ||
| } else if (n.api) | ||
| i = await ye(e, n, o, t); | ||
| else { | ||
| const a = o.toLowerCase(); | ||
| i = n.items.filter((l) => a ? l.label.toLowerCase().includes(a) || l.id.toLowerCase().includes(a) : !0); | ||
| } | ||
| return r !== e.requestId ? [] : Y(i, n.maxSuggestions); | ||
| } | ||
| function Ee(e, n, o) { | ||
| const t = e.editor; | ||
| if (C(t), !window.getSelection()) return !1; | ||
| const i = t.innerHTML; | ||
| let a = e.replaceRange ? e.replaceRange.cloneRange() : E(t); | ||
| if (!a || !t.contains(a.commonAncestorContainer) && (a = E(t), !a)) | ||
| return !1; | ||
| const l = O(t, a.cloneRange(), "after"); | ||
| A(l, a) || (h(t, l), a = l), a.deleteContents(); | ||
| const s = document.createElement("span"); | ||
| s.className = "rte-mention", s.setAttribute("data-mention", "true"), s.setAttribute("data-mention-id", o.id), s.setAttribute("contenteditable", "false"), s.textContent = o.value || `${e.trigger}${o.label}`, a.insertNode(s); | ||
| let f = s, c = 1; | ||
| if (n.insertSpaceAfterMention) { | ||
| const g = document.createTextNode(" "); | ||
| s.after(g), f = g, c = 1; | ||
| } | ||
| const u = document.createRange(); | ||
| return u.setStart(f, c), u.collapse(!0), h(t, u), m(e), C(t), J(t), X(t, i), !0; | ||
| } | ||
| function ee(e, n, o) { | ||
| if (o < 0 || o >= e.items.length) return; | ||
| const t = e.items[o]; | ||
| Ee(e, n, t); | ||
| } | ||
| function xe(e) { | ||
| return e.startContainer !== e.endContainer || e.startContainer.nodeType !== Node.ELEMENT_NODE || e.endOffset - e.startOffset !== 1 ? null : e.startContainer.childNodes[e.startOffset] || null; | ||
| } | ||
| function we(e, n) { | ||
| const o = xe(e); | ||
| return !(o instanceof HTMLElement) || !o.matches(w) || !n.contains(o) ? null : o; | ||
| } | ||
| function ne(e, n) { | ||
| const o = we(e, n); | ||
| if (o) return o; | ||
| const t = Q(e.startContainer), r = t == null ? void 0 : t.closest(w); | ||
| if (r && n.contains(r)) return r; | ||
| const i = Q(e.endContainer), a = i == null ? void 0 : i.closest(w); | ||
| return a && n.contains(a) ? a : null; | ||
| } | ||
| function O(e, n, o = "after") { | ||
| const t = ne(n, e); | ||
| if (!t) return n; | ||
| const r = document.createRange(); | ||
| return o === "before" ? r.setStartBefore(t) : r.setStartAfter(t), r.collapse(!0), r; | ||
| } | ||
| function G(e, n, o = "after") { | ||
| const t = document.createRange(); | ||
| o === "before" ? t.setStartBefore(n) : t.setStartAfter(n), t.collapse(!0), h(e, t); | ||
| } | ||
| function Te(e, n, o) { | ||
| if (!e.collapsed) return null; | ||
| const t = e.startContainer, r = e.startOffset; | ||
| let i = null; | ||
| if (t.nodeType === Node.TEXT_NODE) { | ||
| const a = t; | ||
| n === "backward" && r === 0 ? i = a.previousSibling : n === "forward" && r === a.length && (i = a.nextSibling); | ||
| } else if (t.nodeType === Node.ELEMENT_NODE) { | ||
| const a = t; | ||
| n === "backward" && r > 0 ? i = a.childNodes[r - 1] || null : n === "forward" && r < a.childNodes.length && (i = a.childNodes[r] || null); | ||
| } | ||
| return !(i instanceof HTMLElement) || !i.matches(w) || !o.contains(i) ? null : i; | ||
| } | ||
| function K(e, n) { | ||
| const o = E(e); | ||
| if (!o) return !1; | ||
| const t = Te(o, n, e); | ||
| if (!t) return !1; | ||
| const r = t.parentNode; | ||
| if (!r) return !1; | ||
| const i = e.innerHTML, a = Array.prototype.indexOf.call(r.childNodes, t); | ||
| t.remove(); | ||
| const l = document.createRange(); | ||
| return l.setStart(r, Math.max(0, a)), l.collapse(!0), h(e, l), J(e), X(e, i), !0; | ||
| } | ||
| function te(e, n, o, t, r, i) { | ||
| var s; | ||
| if (ge(e, n), e.query = t, e.trigger = r, e.replaceRange = i.cloneRange(), e.loading = !!(n.api && !n.search), e.debounceHandle !== null && (window.clearTimeout(e.debounceHandle), e.debounceHandle = null), !e.panel) return; | ||
| e.isOpen || (e.panel.style.display = "block", e.panel.classList.add("show"), e.isOpen = !0), W(e, n), U(e, o); | ||
| const a = () => { | ||
| e.debounceHandle = null, be(e, n, t, r).then((f) => { | ||
| e.loading = !1, e.items = f, e.activeIndex = 0, e.panel && (W(e, n), U(e, o)); | ||
| }); | ||
| }, l = n.api && !n.search ? Math.max(0, (s = n.api.debounceMs) != null ? s : 180) : 0; | ||
| l > 0 ? e.debounceHandle = window.setTimeout(a, l) : a(); | ||
| } | ||
| function Ce(e, n) { | ||
| const o = e.editor; | ||
| C(o); | ||
| let t = E(o); | ||
| if (!t || !t.collapsed) { | ||
| m(e); | ||
| return; | ||
| } | ||
| const r = O(o, t.cloneRange(), "after"); | ||
| if (!A(r, t)) { | ||
| h(o, r), t = r, m(e); | ||
| return; | ||
| } | ||
| const i = de(t); | ||
| if (!i) { | ||
| m(e); | ||
| return; | ||
| } | ||
| const a = fe(i.textBefore, n.triggerChars, n.maxQueryLength); | ||
| if (!a) { | ||
| m(e); | ||
| return; | ||
| } | ||
| if (a.query.length < n.minChars) { | ||
| m(e); | ||
| return; | ||
| } | ||
| const l = t.cloneRange(); | ||
| l.setStart(i.node, a.startOffset), l.setEnd(i.node, i.caretOffset), te(e, n, t, a.query, a.trigger, l); | ||
| } | ||
| function V(e, n) { | ||
| if (e.items.length === 0) return; | ||
| const o = e.items.length; | ||
| if (e.activeIndex = ((e.activeIndex + n) % o + o) % o, !e.list) return; | ||
| const t = Array.from(e.list.querySelectorAll(".rte-mention-item")); | ||
| t.forEach((i, a) => i.classList.toggle("active", a === e.activeIndex)); | ||
| const r = t[e.activeIndex]; | ||
| r == null || r.scrollIntoView({ block: "nearest" }); | ||
| } | ||
| function ve(e) { | ||
| return { | ||
| editor: e, | ||
| panel: null, | ||
| list: null, | ||
| replaceRange: null, | ||
| items: [], | ||
| activeIndex: 0, | ||
| query: "", | ||
| trigger: "@", | ||
| loading: !1, | ||
| isOpen: !1, | ||
| requestId: 0, | ||
| debounceHandle: null, | ||
| abortController: null | ||
| }; | ||
| } | ||
| function ke(e) { | ||
| var o; | ||
| const n = R.get(e); | ||
| n && ((o = n.panel) != null && o.parentNode && n.panel.parentNode.removeChild(n.panel), R.delete(e)); | ||
| } | ||
| function D(e, n, o) { | ||
| if (N.has(e)) return; | ||
| C(e); | ||
| const t = { | ||
| beforeInput: (r) => { | ||
| C(e); | ||
| const i = E(e); | ||
| if (!i) return; | ||
| const a = ne(i, e); | ||
| if (!a) return; | ||
| const l = r.inputType || ""; | ||
| if (l.startsWith("insert")) { | ||
| if (r.preventDefault(), G(e, a, "after"), l === "insertParagraph" || l === "insertLineBreak") { | ||
| const s = l === "insertLineBreak" ? "insertLineBreak" : "insertParagraph"; | ||
| document.execCommand(s, !1); | ||
| return; | ||
| } | ||
| if (l === "insertText" || l === "insertCompositionText") { | ||
| const s = r.data || ""; | ||
| if (!s) return; | ||
| document.execCommand("insertText", !1, s); | ||
| } | ||
| } | ||
| }, | ||
| input: () => { | ||
| Ce(n, o); | ||
| }, | ||
| keydown: (r) => { | ||
| if (n.isOpen) { | ||
| if (r.key === "ArrowDown") { | ||
| r.preventDefault(), V(n, 1); | ||
| return; | ||
| } | ||
| if (r.key === "ArrowUp") { | ||
| r.preventDefault(), V(n, -1); | ||
| return; | ||
| } | ||
| if (r.key === "Enter" || r.key === "Tab") { | ||
| r.preventDefault(), ee(n, o, n.activeIndex); | ||
| return; | ||
| } | ||
| if (r.key === "Escape") { | ||
| r.preventDefault(), m(n); | ||
| return; | ||
| } | ||
| } | ||
| const i = E(e); | ||
| if (i) { | ||
| const a = O(e, i.cloneRange(), "after"); | ||
| if (!A(a, i)) { | ||
| if (r.key === "Enter") { | ||
| r.preventDefault(), h(e, a), document.execCommand("insertParagraph", !1); | ||
| return; | ||
| } | ||
| r.key.length === 1 && !r.metaKey && !r.ctrlKey && !r.altKey && h(e, a); | ||
| } | ||
| } | ||
| if (r.key === "Backspace" && K(e, "backward")) { | ||
| r.preventDefault(); | ||
| return; | ||
| } | ||
| if (r.key === "Delete" && K(e, "forward")) { | ||
| r.preventDefault(); | ||
| return; | ||
| } | ||
| }, | ||
| click: (r) => { | ||
| const i = r.target; | ||
| if (!i) return; | ||
| const a = i.nodeType === Node.ELEMENT_NODE ? i : i.parentElement, l = a == null ? void 0 : a.closest(w); | ||
| !l || !e.contains(l) || (r.preventDefault(), r.stopPropagation(), G(e, l, "after"), m(n)); | ||
| }, | ||
| blur: () => { | ||
| window.setTimeout(() => { | ||
| const r = document.activeElement; | ||
| n.panel && r && n.panel.contains(r) || m(n); | ||
| }, 0); | ||
| }, | ||
| mousedown: (r) => { | ||
| if (!n.isOpen || !n.panel) return; | ||
| const i = r.target; | ||
| i && !n.panel.contains(i) && !e.contains(i) && m(n); | ||
| } | ||
| }; | ||
| e.addEventListener("beforeinput", t.beforeInput), e.addEventListener("input", t.input), e.addEventListener("keydown", t.keydown), e.addEventListener("click", t.click), e.addEventListener("blur", t.blur), document.addEventListener("mousedown", t.mousedown, !0), N.set(e, t); | ||
| } | ||
| function Le(e) { | ||
| const n = N.get(e); | ||
| n && (e.removeEventListener("beforeinput", n.beforeInput), e.removeEventListener("input", n.input), e.removeEventListener("keydown", n.keydown), e.removeEventListener("click", n.click), e.removeEventListener("blur", n.blur), document.removeEventListener("mousedown", n.mousedown, !0), N.delete(e)); | ||
| } | ||
| function Me() { | ||
| if (F || typeof document == "undefined") return; | ||
| F = !0; | ||
| const e = document.createElement("style"); | ||
| e.id = "rte-mention-plugin-styles", e.textContent = ` | ||
| .rte-mention { | ||
| display: inline-block; | ||
| padding: 0 6px; | ||
| margin: 0 1px; | ||
| border-radius: 10px; | ||
| background: #e8f0ff; | ||
| color: #1d4ed8; | ||
| font-weight: 600; | ||
| line-height: 1.6; | ||
| white-space: nowrap; | ||
| cursor: pointer; | ||
| } | ||
| .rte-mention-panel { | ||
| width: min(320px, calc(100vw - 16px)); | ||
| max-height: min(320px, calc(100vh - 32px)); | ||
| overflow: hidden; | ||
| border: 1px solid #d9dfeb; | ||
| border-radius: 3px; | ||
| background: #ffffff; | ||
| box-shadow: 0 18px 40px rgba(15, 23, 42, 0.2); | ||
| z-index: 2147483646; | ||
| } | ||
| .rte-mention-list { | ||
| max-height: min(300px, calc(100vh - 56px)); | ||
| overflow: auto; | ||
| padding: 0px; | ||
| } | ||
| .rte-mention-item { | ||
| width: 100%; | ||
| display: flex; | ||
| align-items: center; | ||
| justify-content: space-between; | ||
| gap: 12px; | ||
| border: none; | ||
| background: transparent; | ||
| padding: 10px 12px; | ||
| border-radius: 0px; | ||
| color: #0f172a; | ||
| text-align: left; | ||
| cursor: pointer; | ||
| font: inherit; | ||
| } | ||
| .rte-mention-item:hover, | ||
| .rte-mention-item.active { | ||
| background: #eff6ff; | ||
| color: #1d4ed8; | ||
| } | ||
| .rte-mention-item-label mark { | ||
| background: rgba(59, 130, 246, 0.16); | ||
| color: inherit; | ||
| padding: 0 2px; | ||
| border-radius: 3px; | ||
| } | ||
| .rte-mention-item-meta { | ||
| font-size: 12px; | ||
| color: #64748b; | ||
| white-space: nowrap; | ||
| } | ||
| .rte-mention-empty { | ||
| padding: 12px; | ||
| color: #64748b; | ||
| font-size: 13px; | ||
| text-align: center; | ||
| } | ||
| ${b} .rte-mention { | ||
| background: rgba(37, 99, 235, 0.25); | ||
| color: #bfdbfe; | ||
| } | ||
| ${b} .rte-mention-panel, | ||
| .rte-mention-panel.rte-mention-theme-dark { | ||
| border-color: #364152; | ||
| background: #1f2937; | ||
| box-shadow: 0 22px 44px rgba(0, 0, 0, 0.48); | ||
| } | ||
| ${b} .rte-mention-item, | ||
| .rte-mention-panel.rte-mention-theme-dark .rte-mention-item { | ||
| color: #e5e7eb; | ||
| } | ||
| ${b} .rte-mention-item:hover, | ||
| ${b} .rte-mention-item.active, | ||
| .rte-mention-panel.rte-mention-theme-dark .rte-mention-item:hover, | ||
| .rte-mention-panel.rte-mention-theme-dark .rte-mention-item.active { | ||
| background: #334155; | ||
| color: #bfdbfe; | ||
| } | ||
| ${b} .rte-mention-item-meta, | ||
| ${b} .rte-mention-empty, | ||
| .rte-mention-panel.rte-mention-theme-dark .rte-mention-item-meta, | ||
| .rte-mention-panel.rte-mention-theme-dark .rte-mention-empty { | ||
| color: #9ca3af; | ||
| } | ||
| `, document.head.appendChild(e); | ||
| } | ||
| function Re(e) { | ||
| var o, t, r; | ||
| const n = (e.triggerChars || ["@"]).filter((i) => typeof i == "string" && i.length > 0).map((i) => i[0]); | ||
| return { | ||
| triggerChars: n.length > 0 ? n : ["@"], | ||
| minChars: Math.max(0, (o = e.minChars) != null ? o : 1), | ||
| maxQueryLength: Math.max(1, (t = e.maxQueryLength) != null ? t : 32), | ||
| maxSuggestions: Math.max(1, (r = e.maxSuggestions) != null ? r : 8), | ||
| items: e.items || [ | ||
| { id: "john.doe", label: "John Doe", meta: "john@acme.com" }, | ||
| { id: "sarah.lee", label: "Sarah Lee", meta: "sarah@acme.com" }, | ||
| { id: "alex.chen", label: "Alex Chen", meta: "alex@acme.com" } | ||
| ], | ||
| api: e.api, | ||
| search: e.search, | ||
| itemRenderer: e.itemRenderer, | ||
| emptyStateText: e.emptyStateText || "Type to search mentions", | ||
| noResultsText: e.noResultsText || "No matching mentions", | ||
| loadingText: e.loadingText || "Loading...", | ||
| insertSpaceAfterMention: e.insertSpaceAfterMention !== !1 | ||
| }; | ||
| } | ||
| function M(e) { | ||
| const n = R.get(e); | ||
| if (n) return n; | ||
| const o = ve(e); | ||
| return R.set(e, o), o; | ||
| } | ||
| function Ne(e) { | ||
| S || (S = !0, T = (n) => { | ||
| const o = n.target; | ||
| if (!(o instanceof Node)) return; | ||
| const t = o.nodeType === Node.ELEMENT_NODE ? o : o.parentElement, r = (t == null ? void 0 : t.closest(p)) || null; | ||
| if (!r) return; | ||
| const i = M(r); | ||
| D(r, i, e); | ||
| }, document.addEventListener("focusin", T, !0)); | ||
| } | ||
| function Se() { | ||
| !S || !T || (document.removeEventListener("focusin", T, !0), S = !1, T = null); | ||
| } | ||
| const Ie = (e = {}) => { | ||
| Me(); | ||
| const n = Re(e); | ||
| return { | ||
| name: "mentions", | ||
| toolbar: [ | ||
| { | ||
| label: "Mention", | ||
| command: "insertMention", | ||
| icon: '<svg width="24" height="24" focusable="false"><path d="M12.1 4a7.9 7.9 0 0 0-8 8c0 4.4 3.6 8 8 8 1.6 0 3-.4 4.4-1.3.4-.3.5-.9.2-1.3a1 1 0 0 0-1.3-.3 6 6 0 0 1-3.3.9 6 6 0 1 1 6-6v1.6c0 .8-.5 1.4-1.2 1.4-.8 0-1.2-.6-1.2-1.4V12c0-2-1.6-3.5-3.7-3.5s-3.8 1.6-3.8 3.6c0 2 1.7 3.6 3.8 3.6 1 0 1.9-.4 2.6-1 .5 1 1.4 1.6 2.5 1.6 1.8 0 3.2-1.5 3.2-3.4V12A7.9 7.9 0 0 0 12 4Zm0 9.7c-1 0-1.8-.8-1.8-1.7s.8-1.7 1.8-1.7c1 0 1.7.8 1.7 1.7s-.8 1.7-1.7 1.7Z"></path></svg>' | ||
| } | ||
| ], | ||
| commands: { | ||
| insertMention: (o, t) => { | ||
| const r = se(t); | ||
| if (!r) return !1; | ||
| const i = M(r); | ||
| D(r, i, n); | ||
| let a = E(r); | ||
| a || (a = document.createRange(), a.selectNodeContents(r), a.collapse(!1), h(r, a)); | ||
| const l = O(r, a.cloneRange(), "after"); | ||
| A(l, a) || (h(r, l), a = l), i.query = ""; | ||
| const s = a.cloneRange(); | ||
| return i.trigger = n.triggerChars[0], te(i, n, a, "", i.trigger, s), !0; | ||
| } | ||
| }, | ||
| init: () => { | ||
| k += 1, Ne(n), Array.from(document.querySelectorAll(p)).forEach((t) => { | ||
| const r = M(t); | ||
| D(t, r, n); | ||
| }); | ||
| }, | ||
| destroy: () => { | ||
| k = Math.max(0, k - 1), Array.from(document.querySelectorAll(p)).forEach((t) => { | ||
| m(M(t)), Le(t), ke(t); | ||
| }), k === 0 && Se(); | ||
| } | ||
| }; | ||
| }; | ||
| export { | ||
| Ie as MentionPlugin | ||
| }; | ||
| //# sourceMappingURL=MentionPlugin.native-BMDlOqur.mjs.map |
| const u = '.rte-page-break[data-type="page-break"]', f = ".rte-content, .editora-content"; | ||
| let p = null, m = !1; | ||
| const h = (e, n) => { | ||
| if (n === e.innerHTML) return; | ||
| const t = window.execEditorCommand || window.executeEditorCommand; | ||
| if (typeof t == "function") | ||
| try { | ||
| t("recordDomTransaction", e, n, e.innerHTML); | ||
| } catch (r) { | ||
| } | ||
| }, x = /* @__PURE__ */ new Set([ | ||
| "DIV", | ||
| "P", | ||
| "BLOCKQUOTE", | ||
| "PRE", | ||
| "H1", | ||
| "H2", | ||
| "H3", | ||
| "H4", | ||
| "H5", | ||
| "H6", | ||
| "LI", | ||
| "TD", | ||
| "TH" | ||
| ]), N = () => { | ||
| p || typeof document == "undefined" || (p = document.createElement("style"), p.textContent = ` | ||
| .rte-page-break { | ||
| display: block; | ||
| position: relative; | ||
| height: 12px; | ||
| margin: 8px 0; | ||
| background: linear-gradient(90deg, #ccc 0%, transparent 100%); | ||
| border-top: 2px dashed #999; | ||
| border-bottom: none; | ||
| cursor: pointer; | ||
| user-select: none; | ||
| transition: all 0.2s ease; | ||
| outline: none; | ||
| -webkit-user-select: none; | ||
| -moz-user-select: none; | ||
| -ms-user-select: none; | ||
| } | ||
| .rte-page-break::before { | ||
| content: '⎙ PAGE BREAK'; | ||
| position: absolute; | ||
| top: -12px; | ||
| left: 0; | ||
| font-size: 10px; | ||
| font-weight: bold; | ||
| color: #666; | ||
| background: white; | ||
| padding: 2px 6px; | ||
| letter-spacing: 0.5px; | ||
| opacity: 0.7; | ||
| pointer-events: none; | ||
| } | ||
| .rte-page-break:hover { | ||
| background: linear-gradient(90deg, #999 0%, transparent 100%); | ||
| border-top-color: #666; | ||
| box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.1); | ||
| } | ||
| .rte-page-break:hover::before { | ||
| opacity: 1; | ||
| color: #333; | ||
| } | ||
| .rte-page-break:focus, | ||
| .rte-page-break:focus-visible, | ||
| .rte-page-break-selected { | ||
| outline: 2px solid #0066cc; | ||
| outline-offset: -2px; | ||
| border-top-color: #0066cc; | ||
| background: linear-gradient(90deg, #0066cc 0%, transparent 100%); | ||
| } | ||
| .rte-page-break * { | ||
| user-select: none; | ||
| } | ||
| @media print { | ||
| .rte-page-break { | ||
| display: block; | ||
| height: 0; | ||
| margin: 0; | ||
| background: none; | ||
| border: none; | ||
| page-break-after: always; | ||
| } | ||
| .rte-page-break::before { | ||
| display: none; | ||
| } | ||
| } | ||
| `, document.head.appendChild(p)); | ||
| }, T = () => { | ||
| const e = window.getSelection(); | ||
| if (!e || e.rangeCount === 0) return null; | ||
| const n = e.getRangeAt(0), t = n.startContainer.nodeType === Node.ELEMENT_NODE ? n.startContainer : n.startContainer.parentElement; | ||
| return (t == null ? void 0 : t.closest(f)) || null; | ||
| }, w = () => { | ||
| const e = T(); | ||
| if (e) return e; | ||
| const n = document.activeElement, t = n == null ? void 0 : n.closest(f); | ||
| return t || document.querySelector(f); | ||
| }, E = (e, n) => { | ||
| let t = e; | ||
| for (; t && t !== n; ) { | ||
| if (t.nodeType === Node.ELEMENT_NODE) { | ||
| const r = t; | ||
| if (x.has(r.tagName)) | ||
| return r; | ||
| } | ||
| t = t.parentNode; | ||
| } | ||
| return null; | ||
| }, C = () => { | ||
| const e = document.createElement("div"); | ||
| return e.className = "rte-page-break", e.setAttribute("data-page-break", "true"), e.setAttribute("data-type", "page-break"), e.setAttribute("contenteditable", "false"), e.setAttribute("tabindex", "0"), e.setAttribute("role", "separator"), e.setAttribute("aria-label", "Page break"), e; | ||
| }, S = (e) => { | ||
| let n = e.nextElementSibling; | ||
| for (; n && n.matches(u); ) { | ||
| const r = n; | ||
| n = n.nextElementSibling, r.remove(); | ||
| } | ||
| let t = e.previousElementSibling; | ||
| for (; t && t.matches(u); ) { | ||
| const r = t; | ||
| t = t.previousElementSibling, r.remove(); | ||
| } | ||
| }, v = (e) => { | ||
| var r; | ||
| const n = e.nextElementSibling; | ||
| if (n && !n.matches(u)) | ||
| return n; | ||
| const t = document.createElement("p"); | ||
| return t.innerHTML = "<br>", (r = e.parentNode) == null || r.insertBefore(t, e.nextSibling), t; | ||
| }, d = (e) => { | ||
| const n = window.getSelection(); | ||
| if (!n) return; | ||
| const t = document.createRange(); | ||
| e.nodeType, Node.TEXT_NODE, t.setStart(e, 0), t.collapse(!0), n.removeAllRanges(), n.addRange(t); | ||
| }, b = (e) => { | ||
| const n = window.getSelection(); | ||
| if (!n) return; | ||
| const t = document.createRange(); | ||
| if (e.nodeType === Node.TEXT_NODE) { | ||
| const r = e; | ||
| t.setStart(r, r.data.length); | ||
| } else | ||
| t.selectNodeContents(e), t.collapse(!1); | ||
| n.removeAllRanges(), n.addRange(t); | ||
| }, g = (e, n) => { | ||
| let t = e; | ||
| for (; t; ) { | ||
| if (!(t instanceof HTMLElement && t.matches(u))) | ||
| return t; | ||
| t = n === "previous" ? t.previousSibling : t.nextSibling; | ||
| } | ||
| return null; | ||
| }, A = (e) => { | ||
| const n = window.getSelection(); | ||
| if (!n || !e.parentNode) return; | ||
| const t = e.parentNode, r = Array.from(t.childNodes).indexOf(e); | ||
| if (r < 0) return; | ||
| const o = document.createRange(); | ||
| o.setStart(t, r), o.setEnd(t, r + 1), n.removeAllRanges(), n.addRange(o), e.focus({ preventScroll: !0 }); | ||
| }, y = (e) => { | ||
| if (e.collapsed || e.startContainer !== e.endContainer || e.endOffset !== e.startOffset + 1 || !(e.startContainer instanceof Element || e.startContainer instanceof DocumentFragment)) return null; | ||
| const n = e.startContainer.childNodes[e.startOffset]; | ||
| return n instanceof HTMLElement && n.matches(u) ? n : null; | ||
| }, B = (e, n, t) => { | ||
| if (!e.collapsed) return null; | ||
| const { startContainer: r, startOffset: o } = e, a = (i) => i instanceof HTMLElement && i.matches(u) ? i : null, s = (i) => { | ||
| if (r.nodeType === Node.ELEMENT_NODE) { | ||
| const l = r; | ||
| if (i === "previous") { | ||
| if (o > 0) | ||
| return l.childNodes[o - 1] || null; | ||
| } else if (o < l.childNodes.length) | ||
| return l.childNodes[o] || null; | ||
| } | ||
| if (r.nodeType === Node.TEXT_NODE && (i === "previous" && o < r.data.length || i === "next" && o > 0)) | ||
| return null; | ||
| let c = r; | ||
| for (; c && c !== n; ) { | ||
| const l = i === "previous" ? c.previousSibling : c.nextSibling; | ||
| if (l) return l; | ||
| c = c.parentNode; | ||
| } | ||
| return null; | ||
| }; | ||
| if (r.nodeType === Node.ELEMENT_NODE) { | ||
| const i = r; | ||
| return t === "Backspace" && o > 0 ? a(i.childNodes[o - 1] || null) : t === "Delete" ? a(i.childNodes[o] || null) : null; | ||
| } | ||
| if (r.nodeType === Node.TEXT_NODE) { | ||
| const i = r; | ||
| if (t === "Backspace" && o === 0) { | ||
| const c = a(i.previousSibling); | ||
| return c || a(s("previous")); | ||
| } | ||
| if (t === "Delete" && o === i.data.length) { | ||
| const c = a(i.nextSibling); | ||
| return c || a(s("next")); | ||
| } | ||
| } | ||
| return a(s(t === "Backspace" ? "previous" : "next")); | ||
| }, k = (e, n) => { | ||
| var c; | ||
| const t = e.closest(f), r = (c = t == null ? void 0 : t.innerHTML) != null ? c : "", o = e.previousSibling, a = e.nextSibling; | ||
| e.remove(); | ||
| const s = g(o, "previous"), i = g(a, "next"); | ||
| if (n === "Backspace") { | ||
| if (s) | ||
| b(s); | ||
| else if (i) | ||
| d(i); | ||
| else if (t) { | ||
| const l = document.createElement("p"); | ||
| l.innerHTML = "<br>", t.appendChild(l), d(l); | ||
| } | ||
| } else if (i) | ||
| d(i); | ||
| else if (s) | ||
| b(s); | ||
| else if (t) { | ||
| const l = document.createElement("p"); | ||
| l.innerHTML = "<br>", t.appendChild(l), d(l); | ||
| } | ||
| return t && (h(t, r), t.dispatchEvent(new Event("input", { bubbles: !0 }))), !0; | ||
| }, D = () => { | ||
| const e = w(); | ||
| if (!e) return !1; | ||
| const n = e.innerHTML, t = window.getSelection(); | ||
| if (!t) return !1; | ||
| let r; | ||
| t.rangeCount > 0 && e.contains(t.getRangeAt(0).commonAncestorContainer) ? r = t.getRangeAt(0) : (r = document.createRange(), r.selectNodeContents(e), r.collapse(!1), t.removeAllRanges(), t.addRange(r)); | ||
| const o = E(r.endContainer, e) || E(r.startContainer, e), a = C(); | ||
| o && o.parentNode ? o.parentNode.insertBefore(a, o.nextSibling) : e.appendChild(a), S(a); | ||
| const s = v(a); | ||
| return d(s), h(e, n), e.dispatchEvent(new Event("input", { bubbles: !0 })), !0; | ||
| }, R = () => { | ||
| m || typeof document == "undefined" || (m = !0, document.addEventListener("click", (e) => { | ||
| const n = e.target, t = n == null ? void 0 : n.closest(u); | ||
| t && (e.preventDefault(), e.stopPropagation(), A(t)); | ||
| }), document.addEventListener("keydown", (e) => { | ||
| const n = e.key; | ||
| if (!["Backspace", "Delete", "ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight"].includes(n)) | ||
| return; | ||
| const t = window.getSelection(); | ||
| if (!t || t.rangeCount === 0) return; | ||
| const r = t.getRangeAt(0), o = w(); | ||
| if (!o || !o.contains(r.commonAncestorContainer)) return; | ||
| const a = y(r); | ||
| if (a) { | ||
| if (n === "Backspace" || n === "Delete") { | ||
| e.preventDefault(), e.stopPropagation(), k(a, n); | ||
| return; | ||
| } | ||
| if (n === "ArrowRight" || n === "ArrowDown") { | ||
| e.preventDefault(); | ||
| const s = g(a.nextSibling, "next") || v(a); | ||
| d(s); | ||
| return; | ||
| } | ||
| if (n === "ArrowLeft" || n === "ArrowUp") { | ||
| e.preventDefault(); | ||
| const s = g(a.previousSibling, "previous"); | ||
| s ? b(s) : d(o); | ||
| return; | ||
| } | ||
| } | ||
| if (n === "Backspace" || n === "Delete") { | ||
| const s = B( | ||
| r, | ||
| o, | ||
| n | ||
| ); | ||
| if (!s) return; | ||
| e.preventDefault(), e.stopPropagation(), k(s, n); | ||
| } | ||
| })); | ||
| }, P = () => (N(), R(), { | ||
| name: "pageBreak", | ||
| toolbar: [ | ||
| { | ||
| label: "Page Break", | ||
| command: "insertPageBreak", | ||
| icon: '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true" xmlns="http://www.w3.org/2000/svg"><path d="M5 5H19" stroke="currentColor" stroke-width="1.9" stroke-linecap="round"/><path d="M5 9H19" stroke="currentColor" stroke-width="1.9" stroke-linecap="round"/><path d="M5 15H19" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-dasharray="3.2 3.2"/><path d="M5 19H19" stroke="currentColor" stroke-width="1.9" stroke-linecap="round"/></svg>', | ||
| shortcut: "Mod-Enter" | ||
| } | ||
| ], | ||
| commands: { | ||
| insertPageBreak: D | ||
| }, | ||
| keymap: { | ||
| "Mod-Enter": "insertPageBreak" | ||
| } | ||
| }); | ||
| export { | ||
| P as PageBreakPlugin | ||
| }; | ||
| //# sourceMappingURL=PageBreakPlugin.native-DijGuHJZ.mjs.map |
| const x = ".rte-content, .editora-content", ae = "[data-editora-editor], .rte-editor, .editora-editor, editora-editor", we = "__editoraCommandEditorRoot", Ee = "rte-pii-redaction-styles", u = "rte-pii-redaction-panel", k = "pii-redaction", v = "piiRedaction", $ = ':is([data-theme="dark"], .dark, .editora-theme-dark, .rte-theme-dark)', pe = typeof NodeFilter != "undefined" ? NodeFilter.SHOW_TEXT : 4, Oe = [ | ||
| "email", | ||
| "phone", | ||
| "ssn", | ||
| "credit-card", | ||
| "ipv4", | ||
| "api-key", | ||
| "jwt" | ||
| ], ze = { | ||
| panelTitle: "PII Redaction", | ||
| panelAriaLabel: "PII redaction panel", | ||
| scanText: "Scan PII", | ||
| redactAllText: "Redact All", | ||
| redactText: "Redact", | ||
| locateText: "Locate", | ||
| realtimeOnText: "Realtime On", | ||
| realtimeOffText: "Realtime Off", | ||
| closeText: "Close", | ||
| noFindingsText: "No PII detected in the document.", | ||
| summaryPrefix: "Findings", | ||
| shortcutText: "Shortcuts: Ctrl/Cmd+Alt+Shift+I/U/M/Y", | ||
| readonlyRedactionText: "Editor is read-only. Reopen editable mode to redact.", | ||
| matchLabel: "Detected", | ||
| maskedLabel: "Masked", | ||
| excerptLabel: "Context" | ||
| }, Fe = { | ||
| email: { | ||
| label: "Email", | ||
| severity: "medium", | ||
| pattern: /\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}\b/gi | ||
| }, | ||
| phone: { | ||
| label: "Phone", | ||
| severity: "medium", | ||
| pattern: /\b(?:\+?\d{1,3}[\s.-]?)?(?:\(?\d{3}\)?[\s.-]?\d{3}[\s.-]?\d{4})\b/g | ||
| }, | ||
| ssn: { | ||
| label: "SSN", | ||
| severity: "high", | ||
| pattern: /\b\d{3}-\d{2}-\d{4}\b/g | ||
| }, | ||
| "credit-card": { | ||
| label: "Credit Card", | ||
| severity: "high", | ||
| pattern: /\b(?:\d[ -]*?){13,19}\b/g, | ||
| validator: (e) => We(e) | ||
| }, | ||
| ipv4: { | ||
| label: "IPv4", | ||
| severity: "low", | ||
| pattern: /\b(?:(?:25[0-5]|2[0-4]\d|1?\d?\d)\.){3}(?:25[0-5]|2[0-4]\d|1?\d?\d)\b/g | ||
| }, | ||
| "api-key": { | ||
| label: "API Key", | ||
| severity: "high", | ||
| pattern: /\b(?:sk-[A-Za-z0-9]{20,}|AKIA[0-9A-Z]{16}|AIza[0-9A-Za-z\-_]{35}|ghp_[A-Za-z0-9]{36}|xox[baprs]-[A-Za-z0-9-]{10,})\b/g | ||
| }, | ||
| jwt: { | ||
| label: "JWT", | ||
| severity: "high", | ||
| pattern: /\beyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\b/g | ||
| } | ||
| }, f = /* @__PURE__ */ new WeakMap(), I = /* @__PURE__ */ new WeakMap(), E = /* @__PURE__ */ new WeakMap(), S = /* @__PURE__ */ new WeakMap(), te = /* @__PURE__ */ new WeakMap(), de = /* @__PURE__ */ new WeakMap(), Q = /* @__PURE__ */ new WeakMap(), m = /* @__PURE__ */ new Map(), V = /* @__PURE__ */ new WeakMap(), W = /* @__PURE__ */ new Set(), j = /* @__PURE__ */ new Set(); | ||
| let G = 0, He = 0, ve = 0, M = null, g = null, L = null, D = null, _ = null, R = null, N = null; | ||
| function b(e) { | ||
| return e.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'"); | ||
| } | ||
| function Be(e) { | ||
| return e.replace(/\u00A0/g, " ").replace(/\s+/g, " ").trim(); | ||
| } | ||
| function Y(e) { | ||
| const t = e.flags.includes("g") ? e.flags : `${e.flags}g`; | ||
| return new RegExp(e.source, t); | ||
| } | ||
| function be(e) { | ||
| return new RegExp(e.source, e.flags); | ||
| } | ||
| function X(e, t, n) { | ||
| return Math.max(t, Math.min(n, e)); | ||
| } | ||
| function Ke(e, t) { | ||
| return e === "high" || e === "medium" || e === "low" ? e : t; | ||
| } | ||
| function qe(e) { | ||
| const t = (e || "*").slice(0, 1) || "*"; | ||
| return /[A-Za-z0-9._%+\-\s]/.test(t) ? "*" : t; | ||
| } | ||
| function $e(e) { | ||
| let t = 2166136261; | ||
| for (let n = 0; n < e.length; n += 1) | ||
| t ^= e.charCodeAt(n), t = Math.imul(t, 16777619); | ||
| return t >>> 0; | ||
| } | ||
| function We(e) { | ||
| const t = e.replace(/\D/g, ""); | ||
| if (t.length < 13 || t.length > 19) return !1; | ||
| let n = 0, i = !1; | ||
| for (let o = t.length - 1; o >= 0; o -= 1) { | ||
| let r = Number(t[o]); | ||
| i && (r *= 2, r > 9 && (r -= 9)), n += r, i = !i; | ||
| } | ||
| return n % 10 === 0; | ||
| } | ||
| function je(e, t) { | ||
| const n = Fe[e]; | ||
| if (typeof t == "boolean") | ||
| return { | ||
| type: e, | ||
| label: n.label, | ||
| severity: n.severity, | ||
| enabled: t, | ||
| pattern: Y(n.pattern), | ||
| validator: n.validator | ||
| }; | ||
| if (!t) | ||
| return { | ||
| type: e, | ||
| label: n.label, | ||
| severity: n.severity, | ||
| enabled: !0, | ||
| pattern: Y(n.pattern), | ||
| validator: n.validator | ||
| }; | ||
| const i = t.pattern instanceof RegExp ? Y(t.pattern) : Y(n.pattern); | ||
| return { | ||
| type: e, | ||
| label: n.label, | ||
| severity: Ke(t.severity, n.severity), | ||
| enabled: t.enabled !== !1, | ||
| pattern: i, | ||
| validator: n.validator | ||
| }; | ||
| } | ||
| function ee(e = {}) { | ||
| var i, o, r, a; | ||
| const t = Oe.map((l) => { | ||
| var c; | ||
| return je(l, (c = e.detectors) == null ? void 0 : c[l]); | ||
| }), n = t.map((l) => `${l.type}:${l.enabled ? "1" : "0"}:${l.severity}:${l.pattern.source}:${l.pattern.flags}`).join("|"); | ||
| return { | ||
| enableRealtime: e.enableRealtime !== !1, | ||
| debounceMs: X(Number((i = e.debounceMs) != null ? i : 220), 60, 3e3), | ||
| maxFindings: X(Number((o = e.maxFindings) != null ? o : 140), 1, 500), | ||
| maskChar: qe(e.maskChar), | ||
| revealStart: X(Number((r = e.revealStart) != null ? r : 2), 0, 12), | ||
| revealEnd: X(Number((a = e.revealEnd) != null ? a : 2), 0, 12), | ||
| redactionMode: e.redactionMode === "mask" ? "mask" : "token", | ||
| redactionToken: (e.redactionToken || "REDACTED").trim() || "REDACTED", | ||
| skipInCodeBlocks: e.skipInCodeBlocks !== !1, | ||
| labels: { | ||
| ...ze, | ||
| ...e.labels || {} | ||
| }, | ||
| normalizeText: e.normalizeText || Be, | ||
| detectors: t, | ||
| detectorSignature: n | ||
| }; | ||
| } | ||
| function ce(e) { | ||
| const t = {}; | ||
| return e.detectors.forEach((n) => { | ||
| t[n.type] = { | ||
| enabled: n.enabled, | ||
| severity: n.severity, | ||
| pattern: n.pattern | ||
| }; | ||
| }), { | ||
| enableRealtime: e.enableRealtime, | ||
| debounceMs: e.debounceMs, | ||
| maxFindings: e.maxFindings, | ||
| maskChar: e.maskChar, | ||
| revealStart: e.revealStart, | ||
| revealEnd: e.revealEnd, | ||
| redactionMode: e.redactionMode, | ||
| redactionToken: e.redactionToken, | ||
| skipInCodeBlocks: e.skipInCodeBlocks, | ||
| labels: { ...e.labels }, | ||
| normalizeText: e.normalizeText, | ||
| detectors: t | ||
| }; | ||
| } | ||
| function ge(e) { | ||
| return e.closest(ae) || e; | ||
| } | ||
| function Ze(e) { | ||
| const t = e.closest("[data-editora-editor]"); | ||
| if (t && z(t) === e) | ||
| return t; | ||
| let n = e; | ||
| for (; n; ) { | ||
| if (n.matches(ae) && (n === e || z(n) === e)) | ||
| return n; | ||
| n = n.parentElement; | ||
| } | ||
| return ge(e); | ||
| } | ||
| function z(e) { | ||
| if (!e) return null; | ||
| if (e.matches(x)) return e; | ||
| const t = e.querySelector(x); | ||
| return t instanceof HTMLElement ? t : null; | ||
| } | ||
| function Ve() { | ||
| if (typeof window == "undefined") return null; | ||
| const e = window[we]; | ||
| if (!(e instanceof HTMLElement)) return null; | ||
| window[we] = null; | ||
| const t = z(e); | ||
| if (t) return t; | ||
| const n = e.closest(ae); | ||
| if (n) { | ||
| const o = z(n); | ||
| if (o) return o; | ||
| } | ||
| const i = e.closest(x); | ||
| return i instanceof HTMLElement ? i : null; | ||
| } | ||
| function J(e) { | ||
| return e ? (e.getAttribute("data-theme") || e.getAttribute("theme") || "").toLowerCase() === "dark" ? !0 : e.classList.contains("dark") || e.classList.contains("editora-theme-dark") || e.classList.contains("rte-theme-dark") : !1; | ||
| } | ||
| function Ue(e) { | ||
| const t = ge(e); | ||
| if (J(t)) return !0; | ||
| const n = t.closest("[data-theme], [theme], .dark, .editora-theme-dark, .rte-theme-dark"); | ||
| return J(n) ? !0 : J(document.documentElement) || J(document.body); | ||
| } | ||
| function ne(e, t) { | ||
| e.classList.remove("rte-pii-redaction-theme-dark"), Ue(t) && e.classList.add("rte-pii-redaction-theme-dark"); | ||
| } | ||
| function re(e) { | ||
| return e ? e.nodeType === Node.ELEMENT_NODE ? e : e.parentElement : null; | ||
| } | ||
| function me(e) { | ||
| const t = te.get(e); | ||
| typeof t == "number" && (window.clearTimeout(t), j.delete(t), te.delete(e)); | ||
| } | ||
| function U(e) { | ||
| return e.getAttribute("contenteditable") === "false" || e.getAttribute("data-readonly") === "true"; | ||
| } | ||
| function le(e = 0) { | ||
| return { | ||
| total: 0, | ||
| high: 0, | ||
| medium: 0, | ||
| low: 0, | ||
| redactedCount: e, | ||
| byType: { | ||
| email: 0, | ||
| phone: 0, | ||
| ssn: 0, | ||
| "credit-card": 0, | ||
| ipv4: 0, | ||
| "api-key": 0, | ||
| jwt: 0 | ||
| } | ||
| }; | ||
| } | ||
| function q() { | ||
| Array.from(W).forEach((t) => { | ||
| t.isConnected || Te(t); | ||
| }); | ||
| } | ||
| function Ge(e) { | ||
| var t, n, i, o; | ||
| for (let r = 0; r < e.length; r += 1) { | ||
| const a = e[r]; | ||
| if (!(a.type !== "childList" || a.removedNodes.length === 0)) | ||
| for (let l = 0; l < a.removedNodes.length; l += 1) { | ||
| const c = a.removedNodes[l]; | ||
| if (c.nodeType !== Node.ELEMENT_NODE) continue; | ||
| const d = c; | ||
| if ((t = d.matches) != null && t.call(d, x) || (n = d.matches) != null && n.call(d, `.${u}`) || (i = d.querySelector) != null && i.call(d, x) || (o = d.querySelector) != null && o.call(d, `.${u}`)) | ||
| return !0; | ||
| } | ||
| } | ||
| return !1; | ||
| } | ||
| function T(e, t = !0) { | ||
| if (q(), (e == null ? void 0 : e.contentElement) instanceof HTMLElement) return e.contentElement; | ||
| if ((e == null ? void 0 : e.editorElement) instanceof HTMLElement) { | ||
| const r = e.editorElement, a = z(r); | ||
| if (a) return a; | ||
| } | ||
| const n = Ve(); | ||
| if (n) return n; | ||
| const i = window.getSelection(); | ||
| if (i && i.rangeCount > 0) { | ||
| const r = re(i.getRangeAt(0).startContainer), a = r == null ? void 0 : r.closest(x); | ||
| if (a) return a; | ||
| } | ||
| const o = document.activeElement; | ||
| if (o) { | ||
| if (o.matches(x)) return o; | ||
| const r = o.closest(x); | ||
| if (r) return r; | ||
| } | ||
| return g && g.isConnected ? g : (g && !g.isConnected && (g = null), t ? document.querySelector(x) : null); | ||
| } | ||
| function Te(e) { | ||
| var t; | ||
| me(e), (t = m.get(e)) == null || t.remove(), m.delete(e), V.delete(e), f.delete(e), I.delete(e), E.delete(e), S.delete(e), de.delete(e), Q.delete(e), W.delete(e), g === e && (g = null); | ||
| } | ||
| function C(e, t, n) { | ||
| const i = Ze(e); | ||
| Array.from( | ||
| i.querySelectorAll( | ||
| `.rte-toolbar-button[data-command="${t}"], .editora-toolbar-button[data-command="${t}"]` | ||
| ) | ||
| ).forEach((r) => { | ||
| r.classList.toggle("active", n), r.setAttribute("data-active", n ? "true" : "false"), r.setAttribute("aria-pressed", n ? "true" : "false"); | ||
| }); | ||
| } | ||
| function w(e, t) { | ||
| f.has(e) || f.set(e, t), I.has(e) || I.set(e, []), E.has(e) || E.set(e, le(0)), S.has(e) || S.set(e, t.enableRealtime), W.add(e); | ||
| } | ||
| function ie(e) { | ||
| return V.get(e) === !0; | ||
| } | ||
| function Ie(e, t, n, i) { | ||
| if (!e) return e; | ||
| if (e.length <= n + i) | ||
| return t.repeat(e.length); | ||
| const o = e.slice(0, n), r = i > 0 ? e.slice(e.length - i) : ""; | ||
| return `${o}${t.repeat(Math.max(1, e.length - n - i))}${r}`; | ||
| } | ||
| function se(e, t, n) { | ||
| const i = e.replace(/\D/g, ""); | ||
| if (i.length === 0) return e; | ||
| let o = 0; | ||
| const r = Math.max(0, i.length - n); | ||
| return e.split("").map((a) => /\d/.test(a) ? (o += 1, o <= r ? t : a) : a).join(""); | ||
| } | ||
| function Ye(e, t) { | ||
| const n = e.indexOf("@"); | ||
| if (n <= 0) return e; | ||
| const i = e.slice(0, n), o = e.slice(n + 1); | ||
| return i.length <= 2 ? `${i[0] || ""}${t}[at]${o}` : `${i[0]}${t.repeat(Math.max(1, i.length - 2))}${i[i.length - 1]}[at]${o}`; | ||
| } | ||
| function Xe(e, t) { | ||
| const n = e.split("."); | ||
| return n.length !== 4 ? e : `${n[0]}.${n[1]}.${n[2]}.${t.repeat(Math.max(1, n[3].length))}`; | ||
| } | ||
| function Ce(e, t, n) { | ||
| return e && (t === "email" ? Ye(e, n.maskChar) : t === "phone" || t === "ssn" || t === "credit-card" ? se(e, n.maskChar, 4) : t === "ipv4" ? Xe(e, n.maskChar) : t === "api-key" || t === "jwt" ? Ie(e, n.maskChar, 0, 0) : Ie(e, n.maskChar, n.revealStart, n.revealEnd)); | ||
| } | ||
| function Re(e, t, n) { | ||
| return n.redactionMode === "mask" ? Ce(e, t, n) : `[${n.redactionToken}:${t.toUpperCase()}]`; | ||
| } | ||
| function Je(e) { | ||
| return ve += 1, `pii-${e}-${Date.now().toString(36)}-${ve.toString(36)}`; | ||
| } | ||
| function he(e, t) { | ||
| var n; | ||
| return t.skipInCodeBlocks ? !!((n = e.parentElement) != null && n.closest("code, pre, kbd, samp")) : !1; | ||
| } | ||
| function Qe(e, t) { | ||
| return t.some((n) => e.start < n.end && n.start < e.end); | ||
| } | ||
| function et(e, t, n) { | ||
| const i = []; | ||
| t.filter((a) => a.enabled).forEach((a) => { | ||
| const l = be(a.pattern); | ||
| let c = l.exec(e); | ||
| for (; c && i.length < n * 5; ) { | ||
| const d = c[0] || "", s = c.index, p = s + d.length; | ||
| d && p > s && (!a.validator || a.validator(d)) && i.push({ | ||
| type: a.type, | ||
| severity: a.severity, | ||
| value: d, | ||
| start: s, | ||
| end: p | ||
| }), l.lastIndex === c.index && (l.lastIndex += 1), c = l.exec(e); | ||
| } | ||
| }), i.sort((a, l) => a.start !== l.start ? a.start - l.start : l.end - a.end); | ||
| const r = []; | ||
| for (let a = 0; a < i.length && !(r.length >= n); a += 1) { | ||
| const l = i[a]; | ||
| Qe({ start: l.start, end: l.end }, r) || r.push(l); | ||
| } | ||
| return r; | ||
| } | ||
| function ue(e, t = 120) { | ||
| return e.length <= t ? e : `${e.slice(0, t - 1).trimEnd()}...`; | ||
| } | ||
| function tt(e, t, n) { | ||
| const i = Math.max(0, t - 28), o = Math.min(e.length, n + 28); | ||
| return ue(e.slice(i, o).trim(), 180); | ||
| } | ||
| function nt(e, t) { | ||
| const n = le(t); | ||
| return n.total = e.length, e.forEach((i) => { | ||
| n.byType[i.type] += 1, i.severity === "high" ? n.high += 1 : i.severity === "medium" ? n.medium += 1 : n.low += 1; | ||
| }), n; | ||
| } | ||
| function oe(e, t) { | ||
| const n = e.querySelector(".rte-pii-redaction-live"); | ||
| n && (n.textContent = t); | ||
| } | ||
| function F(e, t, n) { | ||
| const i = t.querySelector('[data-action="toggle-realtime"]'); | ||
| if (!i) return; | ||
| const o = H(e, n); | ||
| i.textContent = o ? n.labels.realtimeOnText : n.labels.realtimeOffText, i.setAttribute("aria-pressed", o ? "true" : "false"), C(e, "togglePIIRealtime", o); | ||
| } | ||
| function rt(e, t) { | ||
| e.setAttribute("aria-label", t.labels.panelAriaLabel); | ||
| const n = e.querySelector(".rte-pii-redaction-title"); | ||
| n && (n.textContent = t.labels.panelTitle); | ||
| const i = e.querySelector('[data-action="close"]'); | ||
| i && i.setAttribute("aria-label", t.labels.closeText); | ||
| const o = e.querySelector('[data-action="run-scan"]'); | ||
| o && (o.textContent = t.labels.scanText); | ||
| const r = e.querySelector('[data-action="redact-all"]'); | ||
| r && (r.textContent = t.labels.redactAllText); | ||
| const a = e.querySelector(".rte-pii-redaction-shortcut"); | ||
| a && (a.textContent = t.labels.shortcutText); | ||
| } | ||
| function B(e) { | ||
| const t = m.get(e); | ||
| if (!t) return; | ||
| const n = f.get(e) || M; | ||
| if (!n) return; | ||
| const i = I.get(e) || [], o = E.get(e) || le(0), r = U(e), a = t.querySelector(".rte-pii-redaction-count"), l = t.querySelector(".rte-pii-redaction-summary"), c = t.querySelector(".rte-pii-redaction-list"), d = t.querySelector('[data-action="redact-all"]'); | ||
| if (!(!a || !l || !c || !d)) { | ||
| if (a.textContent = String(o.total), l.textContent = `${n.labels.summaryPrefix}: ${o.total} | High ${o.high} | Medium ${o.medium} | Low ${o.low} | Redacted ${o.redactedCount}`, d.disabled = r || i.length === 0, r ? oe(t, n.labels.readonlyRedactionText) : oe(t, `${o.total} PII findings detected.`), F(e, t, n), i.length === 0) { | ||
| c.innerHTML = `<li class="rte-pii-redaction-empty">${b(n.labels.noFindingsText)}</li>`; | ||
| return; | ||
| } | ||
| c.innerHTML = i.map((s) => { | ||
| const p = s.type.toUpperCase(), A = s.suggestion || "Redact this finding before export/share.", P = `${n.labels.locateText}: ${s.match}`, K = `${n.labels.redactText}: ${s.match}`, y = r ? 'disabled aria-disabled="true"' : ""; | ||
| return ` | ||
| <li class="rte-pii-redaction-item rte-pii-redaction-item-${s.severity}"> | ||
| <button | ||
| type="button" | ||
| class="rte-pii-redaction-item-btn" | ||
| data-action="locate-finding" | ||
| data-finding-id="${b(s.id)}" | ||
| data-role="finding-button" | ||
| aria-label="${b(P)}" | ||
| > | ||
| <span class="rte-pii-redaction-badge">${b(s.severity.toUpperCase())}</span> | ||
| <span class="rte-pii-redaction-type">${b(p)}</span> | ||
| </button> | ||
| <p class="rte-pii-redaction-line"><strong>${b(n.labels.matchLabel)}:</strong> ${b(ue(s.match, 80))}</p> | ||
| <p class="rte-pii-redaction-line"><strong>${b(n.labels.maskedLabel)}:</strong> ${b(ue(s.masked, 80))}</p> | ||
| ${s.excerpt ? `<p class="rte-pii-redaction-line"><strong>${b(n.labels.excerptLabel)}:</strong> ${b(s.excerpt)}</p>` : ""} | ||
| <p class="rte-pii-redaction-help">${b(A)}</p> | ||
| <div class="rte-pii-redaction-item-actions"> | ||
| <button type="button" class="rte-pii-redaction-btn" data-action="redact-finding" data-finding-id="${b( | ||
| s.id | ||
| )}" aria-label="${b(K)}" ${y}>${b(n.labels.redactText)}</button> | ||
| </div> | ||
| </li> | ||
| `; | ||
| }).join(""); | ||
| } | ||
| } | ||
| function fe(e, t) { | ||
| if (!t.classList.contains("show")) return; | ||
| const i = ge(e).getBoundingClientRect(), o = Math.min(window.innerWidth - 20, 390), r = Math.max(10, window.innerWidth - o - 10), a = Math.min(Math.max(10, i.right - o), r), l = Math.max(10, Math.min(window.innerHeight - 10 - 280, i.top + 10)); | ||
| t.style.width = `${o}px`, t.style.left = `${a}px`, t.style.top = `${l}px`, t.style.maxHeight = `${Math.max(260, window.innerHeight - 20)}px`; | ||
| } | ||
| function H(e, t) { | ||
| const n = S.get(e); | ||
| return typeof n == "boolean" ? n : t ? t.enableRealtime : !0; | ||
| } | ||
| function Se(e, t) { | ||
| if (t === e.innerHTML) return; | ||
| const n = window.execEditorCommand || window.executeEditorCommand; | ||
| if (typeof n == "function") | ||
| try { | ||
| n("recordDomTransaction", e, t, e.innerHTML); | ||
| } catch (i) { | ||
| } | ||
| } | ||
| function Ae(e) { | ||
| e.dispatchEvent(new Event("input", { bubbles: !0 })); | ||
| } | ||
| function Me(e, t) { | ||
| e.dispatchEvent( | ||
| new CustomEvent("editora:pii-redacted", { | ||
| bubbles: !0, | ||
| detail: { | ||
| redactedCount: t | ||
| } | ||
| }) | ||
| ); | ||
| } | ||
| function Pe(e, t) { | ||
| return (I.get(e) || []).find((i) => i.id === t); | ||
| } | ||
| function it(e) { | ||
| const t = m.get(e); | ||
| if (t) return t; | ||
| const n = f.get(e) || M || ee(), i = `rte-pii-redaction-panel-${He++}`, o = document.createElement("section"); | ||
| return o.className = u, o.id = i, o.setAttribute("role", "dialog"), o.setAttribute("aria-modal", "false"), o.setAttribute("aria-label", n.labels.panelAriaLabel), o.innerHTML = ` | ||
| <header class="rte-pii-redaction-header"> | ||
| <h2 class="rte-pii-redaction-title">${b(n.labels.panelTitle)}</h2> | ||
| <button type="button" class="rte-pii-redaction-icon-btn" data-action="close" aria-label="${b( | ||
| n.labels.closeText | ||
| )}">✕</button> | ||
| </header> | ||
| <div class="rte-pii-redaction-body"> | ||
| <div class="rte-pii-redaction-topline"> | ||
| <p class="rte-pii-redaction-summary" aria-live="polite"></p> | ||
| <span class="rte-pii-redaction-count" aria-hidden="true">0</span> | ||
| </div> | ||
| <div class="rte-pii-redaction-controls" role="toolbar" aria-label="PII redaction controls"> | ||
| <button type="button" class="rte-pii-redaction-btn rte-pii-redaction-btn-primary" data-action="run-scan">${b( | ||
| n.labels.scanText | ||
| )}</button> | ||
| <button type="button" class="rte-pii-redaction-btn" data-action="redact-all">${b( | ||
| n.labels.redactAllText | ||
| )}</button> | ||
| <button type="button" class="rte-pii-redaction-btn" data-action="toggle-realtime" aria-pressed="false"></button> | ||
| </div> | ||
| <ul class="rte-pii-redaction-list" role="list" aria-label="Detected PII findings"></ul> | ||
| <p class="rte-pii-redaction-shortcut">${b(n.labels.shortcutText)}</p> | ||
| <span class="rte-pii-redaction-live" aria-live="polite"></span> | ||
| </div> | ||
| `, o.addEventListener("click", (r) => { | ||
| const a = r.target, l = a == null ? void 0 : a.closest("[data-action]"); | ||
| if (!l) return; | ||
| const c = l.getAttribute("data-action") || "", d = f.get(e) || M || n; | ||
| if (f.set(e, d), w(e, d), c === "close") { | ||
| Z(e, !0); | ||
| return; | ||
| } | ||
| if (c === "run-scan") { | ||
| h(e, d, !0); | ||
| return; | ||
| } | ||
| if (c === "toggle-realtime") { | ||
| const s = !H(e, d); | ||
| S.set(e, s), F(e, o, d), s && h(e, d, !0); | ||
| return; | ||
| } | ||
| if (c === "redact-all") { | ||
| xe(e, d); | ||
| return; | ||
| } | ||
| if (c === "locate-finding") { | ||
| const s = l.getAttribute("data-finding-id") || "", p = Pe(e, s); | ||
| if (!p) return; | ||
| lt(e, p, d); | ||
| return; | ||
| } | ||
| if (c === "redact-finding") { | ||
| const s = l.getAttribute("data-finding-id") || ""; | ||
| _e(e, s, d); | ||
| } | ||
| }), o.addEventListener("keydown", (r) => { | ||
| if (r.key === "Escape") { | ||
| r.preventDefault(), Z(e, !0); | ||
| return; | ||
| } | ||
| if (r.key !== "ArrowDown" && r.key !== "ArrowUp") return; | ||
| const a = Array.from(o.querySelectorAll('[data-role="finding-button"]')); | ||
| if (a.length === 0) return; | ||
| const l = document.activeElement, c = a.findIndex((p) => p === l); | ||
| if (c === -1) return; | ||
| r.preventDefault(); | ||
| const d = r.key === "ArrowDown" ? 1 : -1, s = (c + d + a.length) % a.length; | ||
| a[s].focus(); | ||
| }), ne(o, e), document.body.appendChild(o), m.set(e, o), V.set(e, !1), B(e), o; | ||
| } | ||
| function Z(e, t = !1) { | ||
| const n = m.get(e); | ||
| n && (n.classList.remove("show"), V.set(e, !1), C(e, "togglePIIRedactionPanel", !1), t && e.focus({ preventScroll: !0 })); | ||
| } | ||
| function O(e) { | ||
| q(); | ||
| const t = it(e); | ||
| m.forEach((i, o) => { | ||
| o !== e && Z(o, !1); | ||
| }), t.classList.add("show"), V.set(e, !0), C(e, "togglePIIRedactionPanel", !0), ne(t, e), fe(e, t), B(e); | ||
| const n = t.querySelector('[data-action="run-scan"]'); | ||
| n == null || n.focus(); | ||
| } | ||
| function Le(e, t) { | ||
| const n = ie(e); | ||
| return (typeof t == "boolean" ? t : !n) ? O(e) : Z(e), !0; | ||
| } | ||
| function ot(e, t) { | ||
| const n = t.normalizeText(e.innerText || e.textContent || ""), i = e.innerHTML; | ||
| return `${n.length}:${$e(n)}:${i.length}:${$e(i)}:${t.detectorSignature}`; | ||
| } | ||
| function at(e, t) { | ||
| const n = [], i = be(e.pattern); | ||
| let o = i.exec(t); | ||
| for (; o; ) { | ||
| const r = o[0] || "", a = o.index, l = a + r.length; | ||
| r && l > a && (!e.validator || e.validator(r)) && n.push({ value: r, start: a, end: l }), i.lastIndex === o.index && (i.lastIndex += 1), o = i.exec(t); | ||
| } | ||
| return n; | ||
| } | ||
| function De(e, t, n) { | ||
| const i = n.detectors.find((c) => c.type === t.type && c.enabled); | ||
| if (!i) return null; | ||
| const o = t.match.toLowerCase(); | ||
| let r = 0; | ||
| const a = document.createTreeWalker(e, pe, null); | ||
| let l = a.nextNode(); | ||
| for (; l; ) { | ||
| if (!he(l, n)) { | ||
| const c = at(i, l.data); | ||
| for (let d = 0; d < c.length; d += 1) { | ||
| const s = c[d]; | ||
| if (s.value.toLowerCase() === o && (r += 1, r === t.occurrence)) { | ||
| const p = document.createRange(); | ||
| return p.setStart(l, s.start), p.setEnd(l, s.end), p; | ||
| } | ||
| } | ||
| } | ||
| l = a.nextNode(); | ||
| } | ||
| return null; | ||
| } | ||
| function lt(e, t, n) { | ||
| const i = De(e, t, n); | ||
| if (!i) return !1; | ||
| const o = window.getSelection(); | ||
| if (!o) return !1; | ||
| o.removeAllRanges(), o.addRange(i); | ||
| const r = re(i.startContainer); | ||
| return r == null || r.scrollIntoView({ behavior: "smooth", block: "center", inline: "nearest" }), e.focus({ preventScroll: !0 }), !0; | ||
| } | ||
| async function h(e, t, n = !1) { | ||
| var p; | ||
| w(e, t); | ||
| const i = ot(e, t); | ||
| if (!n && de.get(e) === i) | ||
| return I.get(e) || []; | ||
| const o = (Q.get(e) || 0) + 1; | ||
| Q.set(e, o); | ||
| const r = [], a = /* @__PURE__ */ new Map(), l = document.createTreeWalker(e, pe, null); | ||
| let c = l.nextNode(); | ||
| for (; c && r.length < t.maxFindings; ) { | ||
| const A = c.data || ""; | ||
| if (A.trim() && !he(c, t)) { | ||
| const P = et(A, t.detectors, t.maxFindings - r.length); | ||
| for (let K = 0; K < P.length && !(r.length >= t.maxFindings); K += 1) { | ||
| const y = P[K], ye = `${y.type}:${y.value.toLowerCase()}`, ke = (a.get(ye) || 0) + 1; | ||
| a.set(ye, ke), r.push({ | ||
| id: Je(y.type), | ||
| type: y.type, | ||
| severity: y.severity, | ||
| match: y.value, | ||
| masked: Ce(y.value, y.type, t), | ||
| occurrence: ke, | ||
| excerpt: tt(A, y.start, y.end), | ||
| suggestion: "Review and redact this value before external sharing." | ||
| }); | ||
| } | ||
| } | ||
| c = l.nextNode(); | ||
| } | ||
| if (Q.get(e) !== o) | ||
| return I.get(e) || []; | ||
| const d = ((p = E.get(e)) == null ? void 0 : p.redactedCount) || 0, s = nt(r, d); | ||
| return de.set(e, i), I.set(e, r), E.set(e, s), B(e), e.dispatchEvent( | ||
| new CustomEvent("editora:pii-scan", { | ||
| bubbles: !0, | ||
| detail: { | ||
| findings: r, | ||
| stats: s | ||
| } | ||
| }) | ||
| ), r; | ||
| } | ||
| function ct(e, t) { | ||
| let n = e, i = 0; | ||
| return t.detectors.filter((r) => r.enabled).forEach((r) => { | ||
| const a = be(r.pattern); | ||
| n = n.replace(a, (l) => r.validator && !r.validator(l) ? l : (i += 1, Re(l, r.type, t))); | ||
| }), { nextValue: n, count: i }; | ||
| } | ||
| async function _e(e, t, n) { | ||
| var d; | ||
| if (U(e)) { | ||
| const s = m.get(e); | ||
| return s && oe(s, n.labels.readonlyRedactionText), !1; | ||
| } | ||
| const i = Pe(e, t); | ||
| if (!i) return !1; | ||
| const o = De(e, i, n); | ||
| if (!o) return !1; | ||
| const r = e.innerHTML, a = Re(i.match, i.type, n); | ||
| if (o.startContainer === o.endContainer && o.startContainer.nodeType === Node.TEXT_NODE) { | ||
| const s = o.startContainer, p = s.data, A = o.startOffset, P = o.endOffset; | ||
| s.data = `${p.slice(0, A)}${a}${p.slice(P)}`; | ||
| } else | ||
| o.deleteContents(), o.insertNode(document.createTextNode(a)); | ||
| Ae(e), Se(e, r); | ||
| const l = ((d = E.get(e)) == null ? void 0 : d.redactedCount) || 0; | ||
| await h(e, n, !0); | ||
| const c = E.get(e); | ||
| return c && (c.redactedCount = l + 1, B(e)), Me(e, 1), !0; | ||
| } | ||
| async function xe(e, t) { | ||
| var d; | ||
| if (U(e)) { | ||
| const s = m.get(e); | ||
| return s && oe(s, t.labels.readonlyRedactionText), 0; | ||
| } | ||
| (I.get(e) || []).length === 0 && await h(e, t, !0); | ||
| const i = e.innerHTML; | ||
| let o = 0; | ||
| const r = document.createTreeWalker(e, pe, null); | ||
| let a = r.nextNode(); | ||
| for (; a; ) { | ||
| if (he(a, t)) { | ||
| a = r.nextNode(); | ||
| continue; | ||
| } | ||
| const s = a.data || ""; | ||
| if (!s) { | ||
| a = r.nextNode(); | ||
| continue; | ||
| } | ||
| const p = ct(s, t); | ||
| p.count > 0 && p.nextValue !== s && (a.data = p.nextValue, o += p.count), a = r.nextNode(); | ||
| } | ||
| if (o === 0) return 0; | ||
| Ae(e), Se(e, i); | ||
| const l = ((d = E.get(e)) == null ? void 0 : d.redactedCount) || 0; | ||
| await h(e, t, !0); | ||
| const c = E.get(e); | ||
| return c && (c.redactedCount = l + o, B(e)), Me(e, o), o; | ||
| } | ||
| function Ne(e) { | ||
| const t = f.get(e) || M; | ||
| if (!t || !H(e, t) || U(e)) return; | ||
| me(e); | ||
| const n = window.setTimeout(() => { | ||
| j.delete(n), te.delete(e), h(e, t, !1); | ||
| }, t.debounceMs); | ||
| j.add(n), te.set(e, n); | ||
| } | ||
| function st(e) { | ||
| const t = e.key.toLowerCase(); | ||
| return (e.metaKey || e.ctrlKey) && e.altKey && e.shiftKey && t === "i"; | ||
| } | ||
| function dt(e) { | ||
| const t = e.key.toLowerCase(); | ||
| return (e.metaKey || e.ctrlKey) && e.altKey && e.shiftKey && t === "u"; | ||
| } | ||
| function ut(e) { | ||
| const t = e.key.toLowerCase(); | ||
| return (e.metaKey || e.ctrlKey) && e.altKey && e.shiftKey && t === "m"; | ||
| } | ||
| function ft(e) { | ||
| const t = e.key.toLowerCase(); | ||
| return (e.metaKey || e.ctrlKey) && e.altKey && e.shiftKey && t === "y"; | ||
| } | ||
| function pt(e) { | ||
| var i; | ||
| const t = re(e.target); | ||
| if (t) { | ||
| const o = t.closest(x); | ||
| if (o) return o; | ||
| const r = t.closest(ae); | ||
| if (r) { | ||
| const l = z(r); | ||
| if (l) return l; | ||
| } | ||
| const a = t.closest(`.${u}`); | ||
| if (a) { | ||
| const l = Array.from(m.entries()).find(([, c]) => c === a); | ||
| if (l) return l[0]; | ||
| } | ||
| } | ||
| const n = window.getSelection(); | ||
| if (n && n.rangeCount > 0) { | ||
| const o = (i = re(n.getRangeAt(0).startContainer)) == null ? void 0 : i.closest( | ||
| x | ||
| ); | ||
| if (o) return o; | ||
| } | ||
| return null; | ||
| } | ||
| function bt() { | ||
| if (typeof document == "undefined" || document.getElementById(Ee)) return; | ||
| const e = document.createElement("style"); | ||
| e.id = Ee, e.textContent = ` | ||
| .rte-toolbar-group-items.${k}, | ||
| .editora-toolbar-group-items.${k}, | ||
| .rte-toolbar-group-items.${v}, | ||
| .editora-toolbar-group-items.${v} { | ||
| display: flex; | ||
| border: 1px solid #ccc; | ||
| border-radius: 3px; | ||
| background: #fff; | ||
| } | ||
| .rte-toolbar-group-items.${k} .rte-toolbar-button, | ||
| .editora-toolbar-group-items.${k} .editora-toolbar-button, | ||
| .rte-toolbar-group-items.${v} .rte-toolbar-button, | ||
| .editora-toolbar-group-items.${v} .editora-toolbar-button { | ||
| border: none; | ||
| border-radius: 0; | ||
| border-right: 1px solid #ccc; | ||
| } | ||
| .rte-toolbar-group-items.${k} .rte-toolbar-item:last-child .rte-toolbar-button, | ||
| .editora-toolbar-group-items.${k} .editora-toolbar-item:last-child .editora-toolbar-button, | ||
| .rte-toolbar-group-items.${v} .rte-toolbar-item:last-child .rte-toolbar-button, | ||
| .editora-toolbar-group-items.${v} .editora-toolbar-item:last-child .editora-toolbar-button { | ||
| border-right: none; | ||
| } | ||
| .rte-toolbar-button[data-command="togglePIIRealtime"].active, | ||
| .editora-toolbar-button[data-command="togglePIIRealtime"].active { | ||
| background-color: #ccc; | ||
| } | ||
| ${$} .rte-toolbar-group-items.${k}, | ||
| ${$} .editora-toolbar-group-items.${k}, | ||
| ${$} .rte-toolbar-group-items.${v}, | ||
| ${$} .editora-toolbar-group-items.${v}, | ||
| .${u}.rte-pii-redaction-theme-dark { | ||
| border-color: #566275; | ||
| } | ||
| ${$} .rte-toolbar-group-items.${k} .rte-toolbar-button svg, | ||
| ${$} .editora-toolbar-group-items.${k} .editora-toolbar-button svg, | ||
| ${$} .rte-toolbar-group-items.${v} .rte-toolbar-button svg, | ||
| ${$} .editora-toolbar-group-items.${v} .editora-toolbar-button svg | ||
| { | ||
| fill: none; | ||
| } | ||
| ${$} .rte-toolbar-group-items.${k} .rte-toolbar-button, | ||
| ${$} .editora-toolbar-group-items.${k} .editora-toolbar-button | ||
| { | ||
| border-color: #566275; | ||
| } | ||
| .${u} { | ||
| position: fixed; | ||
| z-index: 12000; | ||
| display: none; | ||
| width: min(390px, calc(100vw - 20px)); | ||
| max-height: calc(100vh - 20px); | ||
| border: 1px solid #d1d5db; | ||
| border-radius: 14px; | ||
| background: #ffffff; | ||
| color: #111827; | ||
| box-shadow: 0 18px 45px rgba(15, 23, 42, 0.25); | ||
| overflow: hidden; | ||
| } | ||
| .${u}.show { | ||
| display: flex; | ||
| flex-direction: column; | ||
| } | ||
| .${u}.rte-pii-redaction-theme-dark { | ||
| border-color: #334155; | ||
| background: #0f172a; | ||
| color: #e2e8f0; | ||
| box-shadow: 0 20px 46px rgba(2, 6, 23, 0.68); | ||
| } | ||
| .rte-pii-redaction-header { | ||
| display: flex; | ||
| align-items: center; | ||
| justify-content: space-between; | ||
| gap: 8px; | ||
| padding: 12px 14px; | ||
| border-bottom: 1px solid #e5e7eb; | ||
| background: linear-gradient(180deg, #f9fafb 0%, #f3f4f6 100%); | ||
| } | ||
| .${u}.rte-pii-redaction-theme-dark .rte-pii-redaction-header { | ||
| border-color: #1e293b; | ||
| background: linear-gradient(180deg, #111827 0%, #0f172a 100%); | ||
| } | ||
| .rte-pii-redaction-title { | ||
| margin: 0; | ||
| font-size: 15px; | ||
| line-height: 1.2; | ||
| font-weight: 700; | ||
| } | ||
| .rte-pii-redaction-icon-btn { | ||
| width: 34px; | ||
| height: 34px; | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 6px; | ||
| background: #ffffff; | ||
| color: #0f172a; | ||
| font-size: 16px; | ||
| line-height: 1; | ||
| font-weight: 600; | ||
| padding: 0; | ||
| display: inline-flex; | ||
| align-items: center; | ||
| justify-content: center; | ||
| cursor: pointer; | ||
| } | ||
| .rte-pii-redaction-icon-btn:hover, | ||
| .rte-pii-redaction-icon-btn:focus-visible { | ||
| outline: none; | ||
| border-color: #3b82f6; | ||
| box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.2); | ||
| } | ||
| .${u}.rte-pii-redaction-theme-dark .rte-pii-redaction-icon-btn { | ||
| background: #0f172a; | ||
| border-color: #475569; | ||
| color: #e2e8f0; | ||
| } | ||
| .${u}.rte-pii-redaction-theme-dark .rte-pii-redaction-icon-btn:hover, | ||
| .${u}.rte-pii-redaction-theme-dark .rte-pii-redaction-icon-btn:focus-visible { | ||
| border-color: #60a5fa; | ||
| box-shadow: 0 0 0 3px rgba(96, 165, 250, 0.24); | ||
| } | ||
| .rte-pii-redaction-body { | ||
| display: flex; | ||
| flex-direction: column; | ||
| gap: 10px; | ||
| padding: 12px; | ||
| overflow: auto; | ||
| } | ||
| .rte-pii-redaction-topline { | ||
| display: flex; | ||
| align-items: center; | ||
| justify-content: space-between; | ||
| gap: 8px; | ||
| } | ||
| .rte-pii-redaction-summary { | ||
| margin: 0; | ||
| font-size: 12px; | ||
| line-height: 1.35; | ||
| color: #475569; | ||
| flex: 1; | ||
| } | ||
| .${u}.rte-pii-redaction-theme-dark .rte-pii-redaction-summary { | ||
| color: #94a3b8; | ||
| } | ||
| .rte-pii-redaction-count { | ||
| min-width: 32px; | ||
| height: 32px; | ||
| border-radius: 999px; | ||
| display: inline-flex; | ||
| align-items: center; | ||
| justify-content: center; | ||
| font-weight: 700; | ||
| font-size: 13px; | ||
| border: 1px solid #cbd5e1; | ||
| background: #f8fafc; | ||
| } | ||
| .${u}.rte-pii-redaction-theme-dark .rte-pii-redaction-count { | ||
| border-color: #334155; | ||
| background: #111827; | ||
| color: #cbd5e1; | ||
| } | ||
| .rte-pii-redaction-controls { | ||
| display: flex; | ||
| gap: 8px; | ||
| flex-wrap: wrap; | ||
| } | ||
| .rte-pii-redaction-btn { | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 8px; | ||
| height: 34px; | ||
| padding: 0 10px; | ||
| background: #ffffff; | ||
| color: inherit; | ||
| font-size: 12px; | ||
| font-weight: 600; | ||
| cursor: pointer; | ||
| } | ||
| .rte-pii-redaction-btn:hover, | ||
| .rte-pii-redaction-btn:focus-visible { | ||
| border-color: #94a3b8; | ||
| background: #f8fafc; | ||
| outline: none; | ||
| } | ||
| .rte-pii-redaction-btn:disabled { | ||
| opacity: 0.56; | ||
| cursor: not-allowed; | ||
| } | ||
| .rte-pii-redaction-btn-primary { | ||
| border-color: #0284c7; | ||
| background: #0ea5e9; | ||
| color: #f8fafc; | ||
| } | ||
| .rte-pii-redaction-btn-primary:hover, | ||
| .rte-pii-redaction-btn-primary:focus-visible { | ||
| border-color: #0369a1; | ||
| background: #0284c7; | ||
| color: #ffffff; | ||
| } | ||
| .${u}.rte-pii-redaction-theme-dark .rte-pii-redaction-btn { | ||
| border-color: #334155; | ||
| background: #111827; | ||
| color: #e2e8f0; | ||
| } | ||
| .${u}.rte-pii-redaction-theme-dark .rte-pii-redaction-btn:hover, | ||
| .${u}.rte-pii-redaction-theme-dark .rte-pii-redaction-btn:focus-visible { | ||
| border-color: #475569; | ||
| background: #1e293b; | ||
| } | ||
| .rte-pii-redaction-list { | ||
| list-style: none; | ||
| margin: 0; | ||
| padding: 0; | ||
| display: flex; | ||
| flex-direction: column; | ||
| gap: 8px; | ||
| max-height: min(55vh, 420px); | ||
| overflow: auto; | ||
| } | ||
| .rte-pii-redaction-item { | ||
| border: 1px solid #e2e8f0; | ||
| border-radius: 10px; | ||
| padding: 8px; | ||
| background: #ffffff; | ||
| display: grid; | ||
| gap: 6px; | ||
| } | ||
| .rte-pii-redaction-item-high { | ||
| border-color: #fca5a5; | ||
| background: #fef2f2; | ||
| } | ||
| .rte-pii-redaction-item-medium { | ||
| border-color: #fcd34d; | ||
| background: #fffbeb; | ||
| } | ||
| .rte-pii-redaction-item-low { | ||
| border-color: #93c5fd; | ||
| background: #eff6ff; | ||
| } | ||
| .${u}.rte-pii-redaction-theme-dark .rte-pii-redaction-item { | ||
| border-color: #334155; | ||
| background: #0b1220; | ||
| } | ||
| .${u}.rte-pii-redaction-theme-dark .rte-pii-redaction-item-high { | ||
| border-color: #7f1d1d; | ||
| background: #2b0b11; | ||
| } | ||
| .${u}.rte-pii-redaction-theme-dark .rte-pii-redaction-item-medium { | ||
| border-color: #78350f; | ||
| background: #2b1907; | ||
| } | ||
| .${u}.rte-pii-redaction-theme-dark .rte-pii-redaction-item-low { | ||
| border-color: #1d4ed8; | ||
| background: #0a162f; | ||
| } | ||
| .rte-pii-redaction-item-btn { | ||
| border: none; | ||
| background: transparent; | ||
| width: 100%; | ||
| display: flex; | ||
| align-items: center; | ||
| gap: 8px; | ||
| text-align: left; | ||
| padding: 0; | ||
| color: inherit; | ||
| cursor: pointer; | ||
| } | ||
| .rte-pii-redaction-item-btn:focus-visible { | ||
| outline: 2px solid #0284c7; | ||
| outline-offset: 3px; | ||
| border-radius: 6px; | ||
| } | ||
| .rte-pii-redaction-badge { | ||
| border-radius: 999px; | ||
| border: 1px solid currentColor; | ||
| padding: 1px 8px; | ||
| font-size: 10px; | ||
| font-weight: 700; | ||
| line-height: 1.3; | ||
| text-transform: uppercase; | ||
| opacity: 0.86; | ||
| } | ||
| .rte-pii-redaction-type { | ||
| font-size: 12px; | ||
| font-weight: 700; | ||
| letter-spacing: 0.03em; | ||
| } | ||
| .rte-pii-redaction-line, | ||
| .rte-pii-redaction-help { | ||
| margin: 0; | ||
| font-size: 12px; | ||
| line-height: 1.35; | ||
| color: #334155; | ||
| word-break: break-word; | ||
| } | ||
| .${u}.rte-pii-redaction-theme-dark .rte-pii-redaction-line, | ||
| .${u}.rte-pii-redaction-theme-dark .rte-pii-redaction-help { | ||
| color: #94a3b8; | ||
| } | ||
| .rte-pii-redaction-item-actions { | ||
| display: flex; | ||
| justify-content: flex-end; | ||
| } | ||
| .rte-pii-redaction-empty { | ||
| border: 1px dashed #cbd5e1; | ||
| border-radius: 10px; | ||
| padding: 10px; | ||
| font-size: 13px; | ||
| color: #475569; | ||
| background: #f8fafc; | ||
| } | ||
| .${u}.rte-pii-redaction-theme-dark .rte-pii-redaction-empty { | ||
| border-color: #334155; | ||
| background: #0b1220; | ||
| color: #94a3b8; | ||
| } | ||
| .rte-pii-redaction-shortcut { | ||
| margin: 2px 0 0; | ||
| font-size: 11px; | ||
| color: #64748b; | ||
| } | ||
| .${u}.rte-pii-redaction-theme-dark .rte-pii-redaction-shortcut { | ||
| color: #94a3b8; | ||
| } | ||
| .rte-pii-redaction-live { | ||
| position: absolute; | ||
| width: 1px; | ||
| height: 1px; | ||
| margin: -1px; | ||
| padding: 0; | ||
| overflow: hidden; | ||
| clip: rect(0 0 0 0); | ||
| border: 0; | ||
| } | ||
| @media (max-width: 768px) { | ||
| .${u} { | ||
| left: 10px !important; | ||
| right: 10px; | ||
| top: 10px !important; | ||
| width: auto !important; | ||
| max-height: calc(100vh - 20px); | ||
| } | ||
| .rte-pii-redaction-list { | ||
| max-height: 45vh; | ||
| } | ||
| } | ||
| `, document.head.appendChild(e); | ||
| } | ||
| function gt(e) { | ||
| M = e, L || (L = (t) => { | ||
| q(); | ||
| const n = t.target, i = n == null ? void 0 : n.closest(x); | ||
| if (!i) return; | ||
| g = i; | ||
| const o = f.get(i) || e; | ||
| w(i, o), f.set(i, o), C(i, "togglePIIRedactionPanel", ie(i)), C(i, "togglePIIRealtime", H(i, o)); | ||
| const r = m.get(i); | ||
| r && (ne(r, i), fe(i, r), F(i, r, o)); | ||
| }, document.addEventListener("focusin", L, !0)), D || (D = (t) => { | ||
| const n = t.target, i = n == null ? void 0 : n.closest(x); | ||
| i && (g = i, Ne(i)); | ||
| }, document.addEventListener("input", D, !0)), _ || (_ = (t) => { | ||
| if (t.defaultPrevented) return; | ||
| const n = t.target; | ||
| if (n != null && n.closest(`.${u} input, .${u} textarea, .${u} select`)) return; | ||
| const i = pt(t); | ||
| if (!i) return; | ||
| const o = f.get(i) || M || e; | ||
| if (w(i, o), f.set(i, o), g = i, t.key === "Escape" && ie(i)) { | ||
| t.preventDefault(), Z(i, !0); | ||
| return; | ||
| } | ||
| if (st(t)) { | ||
| t.preventDefault(), t.stopPropagation(), Le(i); | ||
| return; | ||
| } | ||
| if (dt(t)) { | ||
| t.preventDefault(), t.stopPropagation(), h(i, o, !0), O(i); | ||
| return; | ||
| } | ||
| if (ut(t)) { | ||
| t.preventDefault(), t.stopPropagation(), U(i) || (xe(i, o), O(i)); | ||
| return; | ||
| } | ||
| if (ft(t)) { | ||
| t.preventDefault(), t.stopPropagation(); | ||
| const r = !H(i, o); | ||
| S.set(i, r); | ||
| const a = m.get(i); | ||
| a && F(i, a, o), C(i, "togglePIIRealtime", r), r && h(i, o, !0); | ||
| } | ||
| }, document.addEventListener("keydown", _, !0)), R || (R = () => { | ||
| q(), m.forEach((t, n) => { | ||
| !n.isConnected || !t.isConnected || (ne(t, n), fe(n, t)); | ||
| }); | ||
| }, window.addEventListener("scroll", R, !0), window.addEventListener("resize", R)), !N && typeof MutationObserver != "undefined" && document.body && (N = new MutationObserver((t) => { | ||
| Ge(t) && q(); | ||
| }), N.observe(document.body, { | ||
| childList: !0, | ||
| subtree: !0 | ||
| })); | ||
| } | ||
| function mt() { | ||
| L && (document.removeEventListener("focusin", L, !0), L = null), D && (document.removeEventListener("input", D, !0), D = null), _ && (document.removeEventListener("keydown", _, !0), _ = null), R && (window.removeEventListener("scroll", R, !0), window.removeEventListener("resize", R), R = null), N && (N.disconnect(), N = null), m.forEach((e) => e.remove()), m.clear(), W.forEach((e) => me(e)), W.clear(), M = null, g = null; | ||
| } | ||
| const ht = (e = {}) => { | ||
| const t = ee(e), n = /* @__PURE__ */ new Set(); | ||
| return bt(), { | ||
| name: "piiRedaction", | ||
| toolbar: [ | ||
| { | ||
| id: "piiRedactionGroup", | ||
| label: "PII Redaction", | ||
| type: "group", | ||
| command: "piiRedaction", | ||
| items: [ | ||
| { | ||
| id: "piiRedaction", | ||
| label: "PII Redaction", | ||
| command: "togglePIIRedactionPanel", | ||
| shortcut: "Mod-Alt-Shift-i", | ||
| icon: '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><path d="M12 3.5 19 6.5v4.8c0 4.4-2.7 8.1-7 9.2-4.3-1.1-7-4.8-7-9.2V6.5l7-3Z" stroke="currentColor" stroke-width="1.6" stroke-linejoin="round"/><path d="M8.8 11.6h6.4" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/><circle cx="12" cy="11.6" r="1.2" fill="currentColor"/></svg>' | ||
| }, | ||
| { | ||
| id: "piiScan", | ||
| label: "Scan PII", | ||
| command: "runPIIScan", | ||
| shortcut: "Mod-Alt-Shift-u", | ||
| icon: '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><rect x="4.5" y="3.5" width="11" height="15" rx="2" stroke="currentColor" stroke-width="1.6"/><path d="M7.5 8.2h5M7.5 11.2h5M7.5 14.2h3.2" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/><circle cx="16.8" cy="16.8" r="2.8" stroke="currentColor" stroke-width="1.6"/><path d="m18.8 18.8 2 2" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/></svg>' | ||
| }, | ||
| { | ||
| id: "piiRedactAll", | ||
| label: "Redact All PII", | ||
| command: "redactAllPII", | ||
| shortcut: "Mod-Alt-Shift-m", | ||
| icon: '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><path d="M5 18h14" stroke="currentColor" stroke-width="1.7" stroke-linecap="round"/><path d="M7 6h10l-1 8H8L7 6Z" stroke="currentColor" stroke-width="1.7"/><path d="m9 9 6 4" stroke="currentColor" stroke-width="1.7" stroke-linecap="round"/></svg>' | ||
| }, | ||
| { | ||
| id: "piiRealtime", | ||
| label: "Toggle Realtime PII Scan", | ||
| command: "togglePIIRealtime", | ||
| shortcut: "Mod-Alt-Shift-y", | ||
| icon: '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><path d="M12 3v4M12 17v4M4 12h4M16 12h4" stroke="currentColor" stroke-width="1.7" stroke-linecap="round"/><circle cx="12" cy="12" r="4" stroke="currentColor" stroke-width="1.7"/></svg>' | ||
| } | ||
| ] | ||
| } | ||
| ], | ||
| commands: { | ||
| piiRedaction: (i, o) => { | ||
| const r = T(o); | ||
| if (!r) return !1; | ||
| const a = f.get(r) || t; | ||
| return w(r, a), f.set(r, a), g = r, O(r), h(r, a, !1), !0; | ||
| }, | ||
| togglePIIRedactionPanel: (i, o) => { | ||
| const r = T(o); | ||
| if (!r) return !1; | ||
| const a = f.get(r) || t; | ||
| w(r, a), f.set(r, a), g = r; | ||
| const l = Le(r, typeof i == "boolean" ? i : void 0); | ||
| return ie(r) && h(r, a, !1), l; | ||
| }, | ||
| runPIIScan: async (i, o) => { | ||
| const r = T(o); | ||
| if (!r) return !1; | ||
| const a = f.get(r) || t; | ||
| return w(r, a), f.set(r, a), g = r, await h(r, a, !0), O(r), !0; | ||
| }, | ||
| redactAllPII: async (i, o) => { | ||
| const r = T(o); | ||
| if (!r) return !1; | ||
| const a = f.get(r) || t; | ||
| w(r, a), f.set(r, a), g = r; | ||
| const l = await xe(r, a); | ||
| return l > 0 && O(r), l > 0; | ||
| }, | ||
| redactPIIFinding: async (i, o) => { | ||
| const r = T(o); | ||
| if (!r || typeof i != "string" || !i) return !1; | ||
| const a = f.get(r) || t; | ||
| return w(r, a), f.set(r, a), g = r, _e(r, i, a); | ||
| }, | ||
| togglePIIRealtime: (i, o) => { | ||
| const r = T(o); | ||
| if (!r) return !1; | ||
| const a = f.get(r) || t; | ||
| w(r, a), f.set(r, a); | ||
| const l = typeof i == "boolean" ? i : !H(r, a); | ||
| S.set(r, l); | ||
| const c = m.get(r); | ||
| return c && F(r, c, a), C(r, "togglePIIRealtime", l), l && h(r, a, !0), !0; | ||
| }, | ||
| getPIIRedactionFindings: (i, o) => { | ||
| const r = T(o); | ||
| if (!r) return !1; | ||
| const a = I.get(r) || [], l = E.get(r) || le(0), c = a.map((s) => ({ ...s })), d = { | ||
| ...l, | ||
| byType: { ...l.byType } | ||
| }; | ||
| if (typeof i == "function") | ||
| try { | ||
| i(c, d); | ||
| } catch (s) { | ||
| } | ||
| return r.__piiRedactionFindings = c, r.dispatchEvent( | ||
| new CustomEvent("editora:pii-findings", { | ||
| bubbles: !0, | ||
| detail: { findings: c, stats: d } | ||
| }) | ||
| ), !0; | ||
| }, | ||
| setPIIRedactionOptions: (i, o) => { | ||
| const r = T(o); | ||
| if (!r || !i || typeof i != "object") return !1; | ||
| const a = f.get(r) || t, l = ee({ | ||
| ...ce(a), | ||
| ...i, | ||
| labels: { | ||
| ...a.labels, | ||
| ...i.labels || {} | ||
| }, | ||
| detectors: { | ||
| ...ce(a).detectors || {}, | ||
| ...i.detectors || {} | ||
| }, | ||
| normalizeText: i.normalizeText || a.normalizeText | ||
| }); | ||
| f.set(r, l), typeof i.enableRealtime == "boolean" && S.set(r, i.enableRealtime); | ||
| const c = m.get(r); | ||
| return c && (rt(c, l), B(r), F(r, c, l)), h(r, l, !0), !0; | ||
| } | ||
| }, | ||
| keymap: { | ||
| "Mod-Alt-Shift-i": "togglePIIRedactionPanel", | ||
| "Mod-Alt-Shift-I": "togglePIIRedactionPanel", | ||
| "Mod-Alt-Shift-u": "runPIIScan", | ||
| "Mod-Alt-Shift-U": "runPIIScan", | ||
| "Mod-Alt-Shift-m": "redactAllPII", | ||
| "Mod-Alt-Shift-M": "redactAllPII", | ||
| "Mod-Alt-Shift-y": "togglePIIRealtime", | ||
| "Mod-Alt-Shift-Y": "togglePIIRealtime" | ||
| }, | ||
| init: function(o) { | ||
| G += 1; | ||
| const r = this && typeof this.__pluginConfig == "object" ? ee({ ...ce(t), ...this.__pluginConfig }) : t; | ||
| gt(r); | ||
| const a = T( | ||
| o != null && o.editorElement ? { editorElement: o.editorElement } : void 0, | ||
| !1 | ||
| ); | ||
| a && (g = a, n.add(a), w(a, r), f.set(a, r), C(a, "togglePIIRedactionPanel", !1), C(a, "togglePIIRealtime", r.enableRealtime), r.enableRealtime && Ne(a)); | ||
| }, | ||
| destroy: () => { | ||
| n.forEach((i) => Te(i)), n.clear(), G = Math.max(0, G - 1), !(G > 0) && (j.forEach((i) => { | ||
| window.clearTimeout(i); | ||
| }), j.clear(), mt()); | ||
| } | ||
| }; | ||
| }; | ||
| export { | ||
| ht as PIIRedactionPlugin | ||
| }; | ||
| //# sourceMappingURL=PIIRedactionPlugin.native-DcsjmtV1.mjs.map |
| let c = !1; | ||
| const g = () => { | ||
| if (typeof document == "undefined") return; | ||
| const i = "rte-preview-plugin-styles"; | ||
| if (document.getElementById(i)) return; | ||
| const t = document.createElement("style"); | ||
| t.id = i, t.textContent = ` | ||
| /* Preview Editor Dialog Styles */ | ||
| .rte-preview-editor-overlay { | ||
| position: fixed !important; | ||
| top: 0 !important; | ||
| left: 0 !important; | ||
| right: 0 !important; | ||
| bottom: 0 !important; | ||
| width: 100vw !important; | ||
| height: 100vh !important; | ||
| background-color: rgba(0, 0, 0, 0.6) !important; | ||
| display: flex !important; | ||
| align-items: center !important; | ||
| justify-content: center !important; | ||
| z-index: 10000 !important; | ||
| padding: 20px !important; | ||
| box-sizing: border-box !important; | ||
| margin: 0 !important; | ||
| } | ||
| .rte-preview-editor-modal { | ||
| background: white; | ||
| border-radius: 8px; | ||
| box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3); | ||
| width: 100%; | ||
| max-width: 1200px; | ||
| max-height: 90vh; | ||
| display: flex; | ||
| flex-direction: column; | ||
| overflow: hidden; | ||
| position: relative; | ||
| } | ||
| .rte-preview-editor-header { | ||
| display: flex; | ||
| align-items: center; | ||
| justify-content: space-between; | ||
| padding: 16px 20px; | ||
| border-bottom: 1px solid #e1e5e9; | ||
| background: #f8f9fa; | ||
| border-radius: 8px 8px 0 0; | ||
| } | ||
| .rte-preview-editor-header h2 { | ||
| margin: 0; | ||
| font-size: 18px; | ||
| font-weight: 600; | ||
| color: #1a1a1a; | ||
| } | ||
| .rte-preview-editor-header-actions { | ||
| display: flex; | ||
| gap: 8px; | ||
| } | ||
| .rte-preview-editor-close-btn { | ||
| background: none; | ||
| border: none; | ||
| cursor: pointer; | ||
| padding: 4px; | ||
| border-radius: 4px; | ||
| color: #666; | ||
| font-size: 16px; | ||
| line-height: 1; | ||
| transition: all 0.2s ease; | ||
| } | ||
| .rte-preview-editor-close-btn:hover { | ||
| background: #e1e5e9; | ||
| color: #1a1a1a; | ||
| } | ||
| .rte-preview-editor-body { | ||
| flex: 1; | ||
| overflow: auto; | ||
| display: flex; | ||
| flex-direction: column; | ||
| padding: 25px; | ||
| } | ||
| .rte-preview-editor-content { | ||
| flex: 1; | ||
| display: flex; | ||
| flex-direction: column; | ||
| } | ||
| .rte-preview-editor-light-editor { | ||
| flex: 1; | ||
| overflow: auto; | ||
| font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif; | ||
| font-size: 16px; | ||
| line-height: 1.6; | ||
| color: #1a1a1a; | ||
| padding: 20px; | ||
| background: #fafafa; | ||
| border: 1px solid #e1e5e9; | ||
| border-radius: 4px; | ||
| min-height: 400px; | ||
| } | ||
| .rte-preview-editor-light-editor h1, | ||
| .rte-preview-editor-light-editor h2, | ||
| .rte-preview-editor-light-editor h3, | ||
| .rte-preview-editor-light-editor h4, | ||
| .rte-preview-editor-light-editor h5, | ||
| .rte-preview-editor-light-editor h6 { | ||
| margin-top: 1.5em; | ||
| margin-bottom: 0.5em; | ||
| font-weight: 600; | ||
| } | ||
| .rte-preview-editor-light-editor h1 { | ||
| font-size: 2em; | ||
| } | ||
| .rte-preview-editor-light-editor h2 { | ||
| font-size: 1.5em; | ||
| } | ||
| .rte-preview-editor-light-editor h3 { | ||
| font-size: 1.25em; | ||
| } | ||
| .rte-preview-editor-light-editor p { | ||
| margin: 1em 0; | ||
| } | ||
| .rte-preview-editor-light-editor ul, | ||
| .rte-preview-editor-light-editor ol { | ||
| padding-left: 2em; | ||
| margin: 1em 0; | ||
| } | ||
| .rte-preview-editor-light-editor li { | ||
| margin: 0.5em 0; | ||
| } | ||
| .rte-preview-editor-light-editor table { | ||
| border-collapse: collapse; | ||
| width: 100%; | ||
| margin: 1em 0; | ||
| } | ||
| .rte-preview-editor-light-editor table td, | ||
| .rte-preview-editor-light-editor table th { | ||
| border: 1px solid #ddd; | ||
| padding: 0.5em; | ||
| } | ||
| .rte-preview-editor-light-editor table th { | ||
| background: #f5f5f5; | ||
| font-weight: 600; | ||
| } | ||
| .rte-preview-editor-light-editor blockquote { | ||
| border-left: 4px solid #ddd; | ||
| margin: 1em 0; | ||
| padding-left: 1em; | ||
| color: #666; | ||
| } | ||
| .rte-preview-editor-light-editor code { | ||
| background: #f5f5f5; | ||
| padding: 2px 6px; | ||
| border-radius: 3px; | ||
| font-family: 'Monaco', 'Menlo', 'Courier New', monospace; | ||
| font-size: 0.9em; | ||
| } | ||
| .rte-preview-editor-light-editor pre { | ||
| background: #f5f5f5; | ||
| padding: 1em; | ||
| border-radius: 4px; | ||
| overflow-x: auto; | ||
| margin: 1em 0; | ||
| } | ||
| .rte-preview-editor-light-editor pre code { | ||
| background: none; | ||
| padding: 0; | ||
| } | ||
| .rte-preview-editor-light-editor img { | ||
| max-width: 100%; | ||
| height: auto; | ||
| } | ||
| .rte-preview-editor-light-editor a { | ||
| color: #007acc; | ||
| text-decoration: underline; | ||
| } | ||
| .rte-preview-editor-light-editor a:hover { | ||
| color: #0056b3; | ||
| } | ||
| /* Responsive design */ | ||
| @media (max-width: 768px) { | ||
| .rte-preview-editor-overlay { | ||
| padding: 10px; | ||
| } | ||
| .rte-preview-editor-modal { | ||
| max-height: 95vh; | ||
| } | ||
| .rte-preview-editor-header { | ||
| padding: 12px 16px; | ||
| } | ||
| .rte-preview-editor-body { | ||
| padding: 16px; | ||
| } | ||
| .rte-preview-editor-light-editor { | ||
| padding: 12px; | ||
| font-size: 14px; | ||
| } | ||
| } | ||
| `, document.head.appendChild(t); | ||
| }, v = () => { | ||
| const i = window.getSelection(); | ||
| if (i && i.rangeCount > 0) { | ||
| let e = i.getRangeAt(0).startContainer; | ||
| for (; e && e !== document.body; ) { | ||
| if (e.nodeType === Node.ELEMENT_NODE) { | ||
| const n = e; | ||
| if (n.getAttribute("contenteditable") === "true") | ||
| return n; | ||
| } | ||
| e = e.parentNode; | ||
| } | ||
| } | ||
| const t = document.activeElement; | ||
| if (t) { | ||
| if (t.getAttribute("contenteditable") === "true") | ||
| return t; | ||
| const e = t.closest('[contenteditable="true"]'); | ||
| if (e) return e; | ||
| } | ||
| return document.querySelector('[contenteditable="true"]'); | ||
| }, h = () => { | ||
| const i = v(); | ||
| if (!i) return ""; | ||
| const t = i.cloneNode(!0); | ||
| return [ | ||
| ".rte-floating-toolbar", | ||
| ".rte-selection-marker", | ||
| ".rte-toolbar", | ||
| ".rte-resize-handle", | ||
| "[data-rte-internal]" | ||
| ].forEach((n) => { | ||
| t.querySelectorAll(n).forEach((r) => r.remove()); | ||
| }), t.innerHTML; | ||
| }, w = (i) => { | ||
| const t = document.createElement("div"); | ||
| return t.innerHTML = i, t.querySelectorAll( | ||
| 'script, iframe[src^="javascript:"], object, embed, form[action^="javascript:"]' | ||
| ).forEach((r) => r.remove()), t.querySelectorAll("*").forEach((r) => { | ||
| Array.from(r.attributes).forEach((o) => { | ||
| o.name.startsWith("on") && r.removeAttribute(o.name), (o.name === "href" || o.name === "src") && o.value.startsWith("javascript:") && r.removeAttribute(o.name), o.name.toLowerCase() === "contenteditable" && r.removeAttribute(o.name); | ||
| }), r.setAttribute("contenteditable", "false"); | ||
| }), t.innerHTML; | ||
| }, u = () => { | ||
| if (typeof window == "undefined" || c) return; | ||
| c = !0, g(); | ||
| const i = h(), t = w(i), e = document.createElement("div"); | ||
| e.className = "rte-preview-editor-overlay", e.setAttribute("role", "dialog"), e.setAttribute("aria-modal", "true"), e.setAttribute("aria-labelledby", "preview-editor-title"); | ||
| const n = document.createElement("div"); | ||
| n.className = "rte-preview-editor-modal"; | ||
| const r = document.createElement("div"); | ||
| r.className = "rte-preview-editor-header", r.innerHTML = ` | ||
| <h2 id="preview-editor-title">Preview Editor</h2> | ||
| <div class="rte-preview-editor-header-actions"> | ||
| <button class="rte-preview-editor-close-btn" aria-label="Close preview editor"> | ||
| <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> | ||
| <line x1="18" y1="6" x2="6" y2="18" /> | ||
| <line x1="6" y1="6" x2="18" y2="18" /> | ||
| </svg> | ||
| </button> | ||
| </div> | ||
| `; | ||
| const o = document.createElement("div"); | ||
| o.className = "rte-preview-editor-body"; | ||
| const a = document.createElement("div"); | ||
| a.className = "rte-preview-editor-content"; | ||
| const l = document.createElement("div"); | ||
| l.className = "rte-preview-editor-light-editor", l.innerHTML = t, a.appendChild(l), o.appendChild(a), n.appendChild(r), n.appendChild(o), e.appendChild(n); | ||
| const p = () => { | ||
| e.parentNode && e.parentNode.removeChild(e), c = !1, document.removeEventListener("keydown", s); | ||
| }, s = (d) => { | ||
| d.key === "Escape" && (d.preventDefault(), d.stopPropagation(), p()); | ||
| }, m = r.querySelector(".rte-preview-editor-close-btn"); | ||
| m && m.addEventListener("click", (d) => { | ||
| d.preventDefault(), d.stopPropagation(), p(); | ||
| }), e.addEventListener("click", (d) => { | ||
| d.target === e && p(); | ||
| }), document.addEventListener("keydown", s), document.body.appendChild(e); | ||
| }, f = () => ({ | ||
| name: "preview", | ||
| toolbar: [ | ||
| { | ||
| label: "Preview", | ||
| command: "togglePreview", | ||
| icon: '<svg fill="#000000" version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24px" height="24px" viewBox="0 0 92 92" enable-background="new 0 0 92 92" xml:space="preserve"><g id="SVGRepo_bgCarrier" stroke-width="0"></g><g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"></g><g id="SVGRepo_iconCarrier"> <path id="XMLID_1239_" d="M91.3,43.8C90.6,42.8,74.4,19,46,19C17.6,19,1.4,42.8,0.7,43.8c-0.9,1.3-0.9,3.1,0,4.5 C1.4,49.2,17.6,73,46,73c28.4,0,44.6-23.8,45.3-24.8C92.2,46.9,92.2,45.1,91.3,43.8z M46,65C26.7,65,13.5,51.4,9,46 c4.5-5.5,17.6-19,37-19c19.3,0,32.5,13.6,37,19C78.4,51.5,65.3,65,46,65z M48.3,29.6c-4.4-0.6-8.7,0.5-12.3,3.2c0,0,0,0,0,0 c-7.3,5.5-8.8,15.9-3.3,23.2c2.7,3.6,6.5,5.8,10.9,6.5c0.8,0.1,1.6,0.2,2.3,0.2c3.6,0,7-1.2,9.9-3.3c7.3-5.5,8.8-15.9,3.3-23.2 C56.6,32.5,52.7,30.2,48.3,29.6z M52.3,54.5c-2.2,1.7-5,2.4-7.8,2c-2.8-0.4-5.3-1.9-7-4.1C34.1,47.7,35,41,39.7,37.5 c2.2-1.7,5-2.4,7.8-2c2.8,0.4,5.3,1.9,7,4.1C57.9,44.3,57,51,52.3,54.5z M51.9,40c0.8,0.7,1.2,1.8,1.2,2.8c0,1-0.4,2.1-1.2,2.8 c-0.7,0.7-1.8,1.2-2.8,1.2c-1.1,0-2.1-0.4-2.8-1.2c-0.8-0.8-1.2-1.8-1.2-2.8c0-1.1,0.4-2.1,1.2-2.8c0.7-0.8,1.8-1.2,2.8-1.2 C50.2,38.9,51.2,39.3,51.9,40z"></path> </g></svg>' | ||
| } | ||
| ], | ||
| commands: { | ||
| togglePreview: () => (u(), !0) | ||
| }, | ||
| keymap: {} | ||
| }); | ||
| export { | ||
| f as PreviewPlugin | ||
| }; | ||
| //# sourceMappingURL=PreviewPlugin.native-WuIwOAOR.mjs.map |
| function O(e, t) { | ||
| const o = Array.from({ length: t }).map(() => "<th><p><br></p></th>").join(""), n = Array.from({ length: e }).map( | ||
| () => `<tr>${Array.from({ length: t }).map(() => "<td><p><br></p></td>").join("")}</tr>` | ||
| ).join(""); | ||
| return `<table class="rte-table"><thead><tr>${o}</tr></thead><tbody>${n}</tbody></table><p><br></p>`; | ||
| } | ||
| function q() { | ||
| return [ | ||
| { | ||
| id: "paragraph", | ||
| label: "Paragraph", | ||
| description: "Switch to paragraph text", | ||
| command: "paragraph", | ||
| keywords: ["text", "normal", "p"] | ||
| }, | ||
| { | ||
| id: "h1", | ||
| label: "Heading 1", | ||
| description: "Large section heading", | ||
| command: "heading1", | ||
| keywords: ["title", "header", "h1"] | ||
| }, | ||
| { | ||
| id: "h2", | ||
| label: "Heading 2", | ||
| description: "Medium section heading", | ||
| command: "heading2", | ||
| keywords: ["subtitle", "header", "h2"] | ||
| }, | ||
| { | ||
| id: "h3", | ||
| label: "Heading 3", | ||
| description: "Small section heading", | ||
| command: "heading3", | ||
| keywords: ["header", "h3"] | ||
| }, | ||
| { | ||
| id: "bulleted-list", | ||
| label: "Bulleted List", | ||
| description: "Create a bullet list", | ||
| command: "toggleBulletList", | ||
| keywords: ["list", "ul", "bullet"] | ||
| }, | ||
| { | ||
| id: "numbered-list", | ||
| label: "Numbered List", | ||
| description: "Create a numbered list", | ||
| command: "toggleOrderedList", | ||
| keywords: ["list", "ol", "numbered"] | ||
| }, | ||
| { | ||
| id: "blockquote", | ||
| label: "Blockquote", | ||
| description: "Insert a quote block", | ||
| command: "toggleBlockquote", | ||
| keywords: ["quote", "citation"] | ||
| }, | ||
| { | ||
| id: "table-3x3", | ||
| label: "Table 3x3", | ||
| description: "Insert a 3 x 3 table", | ||
| action: ({ insertHTML: e }) => e(O(3, 3)), | ||
| keywords: ["table", "grid", "rows", "columns"] | ||
| }, | ||
| { | ||
| id: "horizontal-rule", | ||
| label: "Divider", | ||
| description: "Insert a horizontal rule", | ||
| command: "insertHorizontalRule", | ||
| keywords: ["hr", "separator", "line"] | ||
| }, | ||
| { | ||
| id: "bold", | ||
| label: "Bold", | ||
| description: "Toggle bold formatting", | ||
| command: "toggleBold", | ||
| keywords: ["strong", "b"] | ||
| }, | ||
| { | ||
| id: "italic", | ||
| label: "Italic", | ||
| description: "Toggle italic formatting", | ||
| command: "toggleItalic", | ||
| keywords: ["emphasis", "i"] | ||
| }, | ||
| { | ||
| id: "underline", | ||
| label: "Underline", | ||
| description: "Toggle underline formatting", | ||
| command: "toggleUnderline", | ||
| keywords: ["u"] | ||
| }, | ||
| { | ||
| id: "strikethrough", | ||
| label: "Strikethrough", | ||
| description: "Toggle strikethrough formatting", | ||
| command: "toggleStrikethrough", | ||
| keywords: ["strike", "s"] | ||
| }, | ||
| { | ||
| id: "clear-formatting", | ||
| label: "Clear Formatting", | ||
| description: "Remove text formatting", | ||
| command: "clearFormatting", | ||
| keywords: ["reset", "plain"] | ||
| } | ||
| ]; | ||
| } | ||
| function $(e) { | ||
| const t = [], o = /* @__PURE__ */ new Set(); | ||
| return e.forEach((n) => { | ||
| const r = String(n.id || "").trim(), i = String(n.label || "").trim(); | ||
| !r || !i || o.has(r) || (o.add(r), t.push({ | ||
| ...n, | ||
| id: r, | ||
| label: i, | ||
| description: n.description ? String(n.description) : void 0, | ||
| keywords: Array.isArray(n.keywords) ? n.keywords.map((a) => String(a)).filter(Boolean) : void 0 | ||
| })); | ||
| }), t; | ||
| } | ||
| function D(e) { | ||
| var r, i, a; | ||
| const t = (e.triggerChar || "/")[0] || "/", o = e.includeDefaultItems !== !1, n = o ? [...e.items || [], ...q()] : e.items || []; | ||
| return { | ||
| triggerChar: t, | ||
| minChars: Math.max(0, (r = e.minChars) != null ? r : 0), | ||
| maxQueryLength: Math.max(1, (i = e.maxQueryLength) != null ? i : 48), | ||
| maxSuggestions: Math.max(1, (a = e.maxSuggestions) != null ? a : 10), | ||
| requireBoundary: e.requireBoundary !== !1, | ||
| includeDefaultItems: o, | ||
| items: $(n), | ||
| itemRenderer: e.itemRenderer, | ||
| emptyStateText: e.emptyStateText || "No commands found", | ||
| panelLabel: e.panelLabel || "Slash commands" | ||
| }; | ||
| } | ||
| const u = '[data-theme="dark"], .dark, .editora-theme-dark, .rte-theme-dark'; | ||
| let v = !1; | ||
| function B() { | ||
| if (v || typeof document == "undefined") return; | ||
| v = !0; | ||
| const e = document.createElement("style"); | ||
| e.id = "rte-slash-commands-styles", e.textContent = ` | ||
| .rte-slash-panel { | ||
| width: min(225px, calc(100vw - 16px)); | ||
| max-height: min(360px, calc(100vh - 24px)); | ||
| overflow: hidden; | ||
| border: 1px solid #d9dfeb; | ||
| border-radius: 0px; | ||
| background: #ffffff; | ||
| box-shadow: 0 18px 40px rgba(15, 23, 42, 0.2); | ||
| z-index: 2147483646; | ||
| } | ||
| .rte-slash-list { | ||
| max-height: min(340px, calc(100vh - 32px)); | ||
| overflow: auto; | ||
| padding: 0px; | ||
| display: grid; | ||
| gap: 1px; | ||
| } | ||
| .rte-slash-item { | ||
| width: 100%; | ||
| border: none; | ||
| background: transparent; | ||
| color: #0f172a; | ||
| border-radius: 0px; | ||
| padding: 6px 9px; | ||
| text-align: left; | ||
| display: grid; | ||
| gap: 0px; | ||
| cursor: pointer; | ||
| font: inherit; | ||
| } | ||
| .rte-slash-item:hover, | ||
| .rte-slash-item.active { | ||
| background: #eff6ff; | ||
| color: #1d4ed8; | ||
| } | ||
| .rte-slash-item-title { | ||
| font-size: 13px; | ||
| font-weight: 600; | ||
| line-height: 1.35; | ||
| } | ||
| .rte-slash-item-description { | ||
| font-size: 12px; | ||
| color: #64748b; | ||
| line-height: 1.35; | ||
| } | ||
| .rte-slash-item mark { | ||
| background: rgba(59, 130, 246, 0.16); | ||
| color: inherit; | ||
| padding: 0 2px; | ||
| border-radius: 3px; | ||
| } | ||
| .rte-slash-empty { | ||
| font-size: 13px; | ||
| color: #64748b; | ||
| text-align: center; | ||
| padding: 12px; | ||
| } | ||
| ${u} .rte-slash-panel { | ||
| border-color: #364152; | ||
| background: #1f2937; | ||
| box-shadow: 0 22px 44px rgba(0, 0, 0, 0.48); | ||
| } | ||
| ${u} .rte-slash-item { | ||
| color: #e5e7eb; | ||
| } | ||
| ${u} .rte-slash-item:hover, | ||
| ${u} .rte-slash-item.active { | ||
| background: #334155; | ||
| color: #bfdbfe; | ||
| } | ||
| ${u} .rte-slash-item-description, | ||
| ${u} .rte-slash-empty { | ||
| color: #9ca3af; | ||
| } | ||
| `, document.head.appendChild(e); | ||
| } | ||
| const s = ".rte-content, .editora-content", g = /* @__PURE__ */ new WeakMap(), p = /* @__PURE__ */ new WeakMap(); | ||
| let b = !1, f = null, h = 0, z = 0; | ||
| function P(e) { | ||
| return e ? e.nodeType === Node.ELEMENT_NODE ? e : e.parentElement : null; | ||
| } | ||
| function I(e) { | ||
| return e.closest("[data-editora-editor], .rte-editor, .editora-editor, editora-editor") || e; | ||
| } | ||
| function F(e) { | ||
| if ((e == null ? void 0 : e.contentElement) instanceof HTMLElement) return e.contentElement; | ||
| if ((e == null ? void 0 : e.editorElement) instanceof HTMLElement) { | ||
| const n = e.editorElement; | ||
| if (n.matches(s)) return n; | ||
| const r = n.querySelector(s); | ||
| if (r instanceof HTMLElement) return r; | ||
| } | ||
| const t = window.getSelection(); | ||
| if (t && t.rangeCount > 0) { | ||
| const n = t.getRangeAt(0).startContainer, r = n.nodeType === Node.ELEMENT_NODE ? n : n.parentElement, i = r == null ? void 0 : r.closest(s); | ||
| if (i) return i; | ||
| } | ||
| const o = document.activeElement; | ||
| if (o) { | ||
| if (o.matches(s)) return o; | ||
| const n = o.closest(s); | ||
| if (n) return n; | ||
| } | ||
| return document.querySelector(s); | ||
| } | ||
| function m(e) { | ||
| return e.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'"); | ||
| } | ||
| function _(e) { | ||
| return e ? /\s|[([{"'`]/.test(e) : !0; | ||
| } | ||
| function E(e) { | ||
| const t = window.getSelection(); | ||
| if (!t || t.rangeCount === 0) return null; | ||
| const o = t.getRangeAt(0); | ||
| return e.contains(o.commonAncestorContainer) ? o.cloneRange() : null; | ||
| } | ||
| function y(e, t) { | ||
| const o = window.getSelection(); | ||
| o && (o.removeAllRanges(), o.addRange(t), e.focus({ preventScroll: !0 })); | ||
| } | ||
| function j(e) { | ||
| if (!e.collapsed) return null; | ||
| const t = e.startContainer, o = e.startOffset; | ||
| if (t.nodeType === Node.TEXT_NODE) { | ||
| const n = t; | ||
| return { | ||
| node: n, | ||
| textBefore: n.data.slice(0, o), | ||
| caretOffset: o | ||
| }; | ||
| } | ||
| if (t.nodeType === Node.ELEMENT_NODE) { | ||
| const n = t; | ||
| if (o > 0) { | ||
| const r = n.childNodes[o - 1]; | ||
| if (r && r.nodeType === Node.TEXT_NODE) { | ||
| const i = r; | ||
| return { | ||
| node: i, | ||
| textBefore: i.data, | ||
| caretOffset: i.length | ||
| }; | ||
| } | ||
| } | ||
| } | ||
| return null; | ||
| } | ||
| function K(e, t, o, n) { | ||
| const r = e.lastIndexOf(t); | ||
| if (r < 0 || n && !_(e[r - 1])) | ||
| return null; | ||
| const i = e.slice(r + 1); | ||
| return /\s/.test(i) || i.length > o ? null : { | ||
| trigger: t, | ||
| query: i, | ||
| startOffset: r | ||
| }; | ||
| } | ||
| function Q(e, t) { | ||
| const o = t.cloneRange(); | ||
| o.collapse(!1); | ||
| const n = o.getClientRects(); | ||
| if (n.length > 0) | ||
| return n[n.length - 1]; | ||
| const r = document.createElement("span"); | ||
| r.textContent = "", o.insertNode(r); | ||
| const i = r.getBoundingClientRect(); | ||
| return r.remove(), e.normalize(), i; | ||
| } | ||
| function A(e, t) { | ||
| if (!e.panel) return; | ||
| const o = Q(e.editor, t), n = e.panel; | ||
| n.style.display = "block", n.classList.add("show"), n.style.left = "0px", n.style.top = "0px"; | ||
| const r = n.getBoundingClientRect(), i = window.innerWidth, a = window.innerHeight; | ||
| let l = Math.max(8, Math.min(o.left, i - r.width - 8)), d = o.bottom + 8; | ||
| d + r.height > a - 8 && (d = Math.max(8, o.top - r.height - 8)), n.style.position = "fixed", n.style.left = `${l}px`, n.style.top = `${d}px`; | ||
| } | ||
| function k(e, t) { | ||
| if (!t) return m(e); | ||
| const o = e.toLowerCase(), n = t.toLowerCase(), r = o.indexOf(n); | ||
| if (r < 0) return m(e); | ||
| const i = m(e.slice(0, r)), a = m(e.slice(r, r + t.length)), l = m(e.slice(r + t.length)); | ||
| return `${i}<mark>${a}</mark>${l}`; | ||
| } | ||
| function U(e, t) { | ||
| if (e.panel && e.list) return; | ||
| const o = document.createElement("div"); | ||
| o.className = "rte-slash-panel", o.style.display = "none", o.setAttribute("role", "dialog"), o.setAttribute("aria-modal", "false"); | ||
| const n = document.createElement("div"); | ||
| n.className = "rte-slash-list", n.setAttribute("role", "listbox"), n.setAttribute("aria-label", t.panelLabel), o.appendChild(n), document.body.appendChild(o), e.panel = o, e.list = n, o.addEventListener("mousedown", (r) => { | ||
| r.preventDefault(); | ||
| }), o.addEventListener("click", (r) => { | ||
| const i = r.target; | ||
| if (!i) return; | ||
| const a = i.closest(".rte-slash-item"); | ||
| if (!a) return; | ||
| const l = Number(a.getAttribute("data-index")); | ||
| Number.isFinite(l) && M(e, l); | ||
| }); | ||
| } | ||
| function c(e) { | ||
| e.panel && (e.panel.style.display = "none", e.panel.classList.remove("show"), e.isOpen = !1, e.filteredItems = [], e.activeIndex = 0, e.query = "", e.replaceRange = null, e.anchorRange = null); | ||
| } | ||
| function W(e, t, o) { | ||
| if (!t) return e.slice(0, o); | ||
| const n = t.toLowerCase(); | ||
| return e.filter((i) => [ | ||
| i.id, | ||
| i.label, | ||
| i.description || "", | ||
| i.command || "", | ||
| ...i.keywords || [] | ||
| ].join(" ").toLowerCase().includes(n)).slice(0, o); | ||
| } | ||
| function Z(e, t) { | ||
| if (!e.list) return; | ||
| const o = e.list; | ||
| if (o.innerHTML = "", e.filteredItems.length === 0) { | ||
| const n = document.createElement("div"); | ||
| n.className = "rte-slash-empty", n.textContent = t.emptyStateText, o.appendChild(n), o.removeAttribute("aria-activedescendant"); | ||
| return; | ||
| } | ||
| e.filteredItems.forEach((n, r) => { | ||
| const i = document.createElement("button"); | ||
| i.type = "button", i.className = "rte-slash-item", i.setAttribute("role", "option"), i.setAttribute("data-index", String(r)), i.setAttribute("id", `rte-slash-item-${e.instanceId}-${r}`), i.setAttribute("aria-selected", r === e.activeIndex ? "true" : "false"), i.setAttribute("aria-label", n.description ? `${n.label} - ${n.description}` : n.label), r === e.activeIndex && i.classList.add("active"), t.itemRenderer ? i.innerHTML = t.itemRenderer(n, e.query) : i.innerHTML = ` | ||
| <span class="rte-slash-item-title">${k(n.label, e.query)}</span> | ||
| ${n.description ? `<span class="rte-slash-item-description">${k(n.description, e.query)}</span>` : ""} | ||
| `, o.appendChild(i); | ||
| }), e.filteredItems.length > 0 && o.setAttribute("aria-activedescendant", `rte-slash-item-${e.instanceId}-${e.activeIndex}`); | ||
| } | ||
| function G(e, t) { | ||
| if (t === e.innerHTML) return; | ||
| const o = window.execEditorCommand || window.executeEditorCommand; | ||
| if (typeof o == "function") | ||
| try { | ||
| o("recordDomTransaction", e, t, e.innerHTML); | ||
| } catch (n) { | ||
| } | ||
| } | ||
| function V(e) { | ||
| e.dispatchEvent(new Event("input", { bubbles: !0 })); | ||
| } | ||
| function L(e, t) { | ||
| e.focus({ preventScroll: !0 }); | ||
| try { | ||
| if (document.execCommand("insertHTML", !1, t)) | ||
| return !0; | ||
| } catch (l) { | ||
| } | ||
| const o = window.getSelection(); | ||
| if (!o || o.rangeCount === 0) return !1; | ||
| const n = o.getRangeAt(0); | ||
| if (!e.contains(n.commonAncestorContainer)) return !1; | ||
| n.deleteContents(); | ||
| const r = document.createElement("template"); | ||
| r.innerHTML = t; | ||
| const i = r.content, a = i.lastChild; | ||
| if (n.insertNode(i), a) { | ||
| const l = document.createRange(); | ||
| l.setStartAfter(a), l.collapse(!0), y(e, l); | ||
| } | ||
| return !0; | ||
| } | ||
| function X(e, t) { | ||
| e.focus({ preventScroll: !0 }); | ||
| try { | ||
| if (document.execCommand("insertText", !1, t)) | ||
| return !0; | ||
| } catch (a) { | ||
| } | ||
| const o = window.getSelection(); | ||
| if (!o || o.rangeCount === 0) return !1; | ||
| const n = o.getRangeAt(0); | ||
| if (!e.contains(n.commonAncestorContainer)) return !1; | ||
| n.deleteContents(); | ||
| const r = document.createTextNode(t); | ||
| n.insertNode(r); | ||
| const i = document.createRange(); | ||
| return i.setStart(r, r.length), i.collapse(!0), y(e, i), !0; | ||
| } | ||
| function J(e, t) { | ||
| switch (e.toLowerCase()) { | ||
| case "paragraph": | ||
| case "p": | ||
| return document.execCommand("formatBlock", !1, "<p>"); | ||
| case "heading1": | ||
| case "h1": | ||
| return document.execCommand("formatBlock", !1, "<h1>"); | ||
| case "heading2": | ||
| case "h2": | ||
| return document.execCommand("formatBlock", !1, "<h2>"); | ||
| case "heading3": | ||
| case "h3": | ||
| return document.execCommand("formatBlock", !1, "<h3>"); | ||
| case "blockquote": | ||
| case "toggleblockquote": | ||
| return document.execCommand("formatBlock", !1, "<blockquote>"); | ||
| case "bulletlist": | ||
| case "togglebulletlist": | ||
| case "insertunorderedlist": | ||
| return document.execCommand("insertUnorderedList"); | ||
| case "numberedlist": | ||
| case "toggleorderedlist": | ||
| case "insertorderedlist": | ||
| return document.execCommand("insertOrderedList"); | ||
| case "horizontalrule": | ||
| case "divider": | ||
| case "inserthorizontalrule": | ||
| return document.execCommand("insertHorizontalRule"); | ||
| case "bold": | ||
| case "togglebold": | ||
| return document.execCommand("bold"); | ||
| case "italic": | ||
| case "toggleitalic": | ||
| return document.execCommand("italic"); | ||
| case "underline": | ||
| case "toggleunderline": | ||
| return document.execCommand("underline"); | ||
| case "strikethrough": | ||
| case "togglestrikethrough": | ||
| return document.execCommand("strikeThrough"); | ||
| case "clearformatting": | ||
| case "removeformat": | ||
| return document.execCommand("removeFormat"); | ||
| default: | ||
| try { | ||
| return document.execCommand(e, !1, t); | ||
| } catch (n) { | ||
| return !1; | ||
| } | ||
| } | ||
| } | ||
| function S(e, t, o) { | ||
| const n = I(e); | ||
| if (n && typeof n.execCommand == "function") | ||
| try { | ||
| if (n.execCommand(t, o) !== !1) return !0; | ||
| } catch (i) { | ||
| } | ||
| const r = window.execEditorCommand || window.executeEditorCommand; | ||
| if (typeof r == "function") | ||
| try { | ||
| if (r(t, o, { | ||
| editorElement: n, | ||
| contentElement: e | ||
| }) !== !1) return !0; | ||
| } catch (i) { | ||
| } | ||
| return J(t, o); | ||
| } | ||
| async function Y(e, t) { | ||
| const o = e.editor, n = I(o), r = { | ||
| editor: o, | ||
| editorRoot: n, | ||
| query: e.query, | ||
| trigger: e.trigger, | ||
| executeCommand: (i, a) => S(o, i, a), | ||
| insertHTML: (i) => L(o, i) | ||
| }; | ||
| return t.action ? await Promise.resolve(t.action(r)) !== !1 : t.insertHTML ? L(o, t.insertHTML) : t.command ? S(o, t.command, t.commandValue) : !1; | ||
| } | ||
| async function M(e, t) { | ||
| if (t < 0 || t >= e.filteredItems.length || !e.replaceRange) return; | ||
| const o = e.filteredItems[t], n = e.editor, r = n.innerHTML, i = `${e.trigger}${e.query}`; | ||
| if (!window.getSelection()) return; | ||
| const l = e.replaceRange.cloneRange(); | ||
| if (!n.contains(l.commonAncestorContainer)) return; | ||
| l.deleteContents(); | ||
| const d = l.cloneRange(); | ||
| d.collapse(!0), y(n, d); | ||
| let x = !1; | ||
| try { | ||
| x = await Y(e, o); | ||
| } catch (le) { | ||
| x = !1; | ||
| } | ||
| c(e), x ? (V(n), G(n, r)) : i && X(n, i), n.focus({ preventScroll: !0 }); | ||
| } | ||
| function R(e, t) { | ||
| if (e.filteredItems.length === 0) return; | ||
| const o = e.filteredItems.length; | ||
| if (e.activeIndex = ((e.activeIndex + t) % o + o) % o, !e.list) return; | ||
| const n = Array.from(e.list.querySelectorAll(".rte-slash-item")); | ||
| n.forEach((i, a) => { | ||
| const l = a === e.activeIndex; | ||
| i.classList.toggle("active", l), i.setAttribute("aria-selected", l ? "true" : "false"); | ||
| }); | ||
| const r = n[e.activeIndex]; | ||
| r && (e.list.setAttribute("aria-activedescendant", r.id), r.scrollIntoView({ block: "nearest" })); | ||
| } | ||
| function T(e) { | ||
| if (!(!e.isOpen || !e.panel || !e.anchorRange)) { | ||
| if (!e.editor.isConnected) { | ||
| c(e); | ||
| return; | ||
| } | ||
| A(e, e.anchorRange); | ||
| } | ||
| } | ||
| function N(e, t, o, n, r, i) { | ||
| U(e, t), e.query = n, e.trigger = r, e.replaceRange = i.cloneRange(), e.anchorRange = o.cloneRange(), e.filteredItems = W(e.items, n, t.maxSuggestions), e.activeIndex = 0, e.isOpen = !0, e.panel && (Z(e, t), A(e, o)); | ||
| } | ||
| function ee(e, t) { | ||
| const o = e.editor; | ||
| if (o.getAttribute("contenteditable") === "false") { | ||
| c(e); | ||
| return; | ||
| } | ||
| const n = E(o); | ||
| if (!n || !n.collapsed) { | ||
| c(e); | ||
| return; | ||
| } | ||
| const r = j(n); | ||
| if (!r) { | ||
| c(e); | ||
| return; | ||
| } | ||
| const i = K( | ||
| r.textBefore, | ||
| t.triggerChar, | ||
| t.maxQueryLength, | ||
| t.requireBoundary | ||
| ); | ||
| if (!i) { | ||
| c(e); | ||
| return; | ||
| } | ||
| if (i.query.length < t.minChars) { | ||
| c(e); | ||
| return; | ||
| } | ||
| const a = n.cloneRange(); | ||
| a.setStart(r.node, i.startOffset), a.setEnd(r.node, r.caretOffset), N(e, t, n, i.query, i.trigger, a); | ||
| } | ||
| function H(e, t) { | ||
| const o = e.editor; | ||
| if (o.getAttribute("contenteditable") === "false") | ||
| return !1; | ||
| let n = E(o); | ||
| n || (n = document.createRange(), n.selectNodeContents(o), n.collapse(!1), y(o, n)); | ||
| const r = n.cloneRange(); | ||
| return r.collapse(!0), N(e, t, n, "", t.triggerChar, r), !0; | ||
| } | ||
| function te(e) { | ||
| return !(e.metaKey || e.ctrlKey) || e.altKey ? !1 : e.key === "/" || e.code === "Slash"; | ||
| } | ||
| function ne(e, t) { | ||
| return { | ||
| editor: e, | ||
| panel: null, | ||
| list: null, | ||
| replaceRange: null, | ||
| items: t.items, | ||
| filteredItems: [], | ||
| activeIndex: 0, | ||
| query: "", | ||
| trigger: t.triggerChar, | ||
| isOpen: !1, | ||
| instanceId: ++z, | ||
| anchorRange: null | ||
| }; | ||
| } | ||
| function w(e, t) { | ||
| const o = g.get(e); | ||
| if (o) | ||
| return o.items = t.items, o; | ||
| const n = ne(e, t); | ||
| return g.set(e, n), n; | ||
| } | ||
| function re(e) { | ||
| var o; | ||
| const t = g.get(e); | ||
| t && ((o = t.panel) != null && o.parentNode && t.panel.parentNode.removeChild(t.panel), g.delete(e)); | ||
| } | ||
| function C(e, t, o) { | ||
| if (p.has(e)) return; | ||
| const n = { | ||
| input: () => { | ||
| ee(t, o); | ||
| }, | ||
| keydown: (r) => { | ||
| if (t.editor.getAttribute("contenteditable") === "false") { | ||
| c(t); | ||
| return; | ||
| } | ||
| if (!t.isOpen && te(r)) { | ||
| r.preventDefault(), H(t, o); | ||
| return; | ||
| } | ||
| if (t.isOpen) { | ||
| if (r.key === "ArrowDown") { | ||
| r.preventDefault(), R(t, 1); | ||
| return; | ||
| } | ||
| if (r.key === "ArrowUp") { | ||
| r.preventDefault(), R(t, -1); | ||
| return; | ||
| } | ||
| if (r.key === "Enter" || r.key === "Tab") { | ||
| if (t.filteredItems.length === 0) { | ||
| r.key === "Tab" && r.preventDefault(), c(t); | ||
| return; | ||
| } | ||
| r.preventDefault(), M(t, t.activeIndex); | ||
| return; | ||
| } | ||
| if (r.key === "Escape") { | ||
| r.preventDefault(), c(t); | ||
| return; | ||
| } | ||
| } | ||
| }, | ||
| blur: () => { | ||
| window.setTimeout(() => { | ||
| const r = document.activeElement; | ||
| t.panel && r && t.panel.contains(r) || c(t); | ||
| }, 0); | ||
| }, | ||
| mousedown: (r) => { | ||
| if (!t.isOpen || !t.panel) return; | ||
| const i = r.target; | ||
| i && !t.panel.contains(i) && !e.contains(i) && c(t); | ||
| }, | ||
| selectionchange: () => { | ||
| if (!t.isOpen) return; | ||
| const r = E(e); | ||
| if (!r || !r.collapsed) { | ||
| c(t); | ||
| return; | ||
| } | ||
| t.anchorRange = r.cloneRange(), T(t); | ||
| }, | ||
| reposition: () => { | ||
| T(t); | ||
| } | ||
| }; | ||
| e.addEventListener("input", n.input), e.addEventListener("keydown", n.keydown), e.addEventListener("blur", n.blur), document.addEventListener("mousedown", n.mousedown, !0), document.addEventListener("selectionchange", n.selectionchange), window.addEventListener("resize", n.reposition, { passive: !0 }), window.addEventListener("scroll", n.reposition, !0), p.set(e, n); | ||
| } | ||
| function oe(e) { | ||
| const t = p.get(e); | ||
| t && (e.removeEventListener("input", t.input), e.removeEventListener("keydown", t.keydown), e.removeEventListener("blur", t.blur), document.removeEventListener("mousedown", t.mousedown, !0), document.removeEventListener("selectionchange", t.selectionchange), window.removeEventListener("resize", t.reposition), window.removeEventListener("scroll", t.reposition, !0), p.delete(e)); | ||
| } | ||
| function ie(e) { | ||
| b || (b = !0, f = (t) => { | ||
| const o = t.target; | ||
| if (!(o instanceof Node)) return; | ||
| const n = P(o), r = (n == null ? void 0 : n.closest(s)) || null; | ||
| if (!r) return; | ||
| const i = w(r, e); | ||
| C(r, i, e); | ||
| }, document.addEventListener("focusin", f, !0)); | ||
| } | ||
| function ae() { | ||
| !b || !f || (document.removeEventListener("focusin", f, !0), b = !1, f = null); | ||
| } | ||
| const ce = (e = {}) => { | ||
| B(); | ||
| const t = D(e); | ||
| return { | ||
| name: "slashCommands", | ||
| toolbar: [ | ||
| { | ||
| id: "slashCommands", | ||
| label: "Slash Commands", | ||
| command: "openSlashCommands", | ||
| icon: '<svg width="24" height="24" focusable="false" aria-hidden="true"><path d="M8.7 20a1 1 0 0 1-.7-.3c-.4-.4-.4-1 0-1.4L15.6 5a1 1 0 0 1 1.4 1.4L9.4 19.7a1 1 0 0 1-.7.3Zm7.8 0c-.3 0-.5 0-.7-.3l-1.8-1.8a1 1 0 1 1 1.4-1.4l1.8 1.8a1 1 0 0 1-.7 1.7Zm-9-12a1 1 0 0 1-.7-1.7L8.6 4.5A1 1 0 1 1 10 6L8.2 7.8a1 1 0 0 1-.7.3Z"></path></svg>' | ||
| } | ||
| ], | ||
| commands: { | ||
| openSlashCommands: (o, n) => { | ||
| const r = F(n); | ||
| if (!r) return !1; | ||
| const i = w(r, t); | ||
| return C(r, i, t), H(i, t); | ||
| } | ||
| }, | ||
| keymap: { | ||
| "Mod-/": "openSlashCommands", | ||
| "Mod-Shift-7": "openSlashCommands" | ||
| }, | ||
| init: () => { | ||
| h += 1, ie(t), Array.from(document.querySelectorAll(s)).forEach((n) => { | ||
| const r = w(n, t); | ||
| C(n, r, t); | ||
| }); | ||
| }, | ||
| destroy: () => { | ||
| h = Math.max(0, h - 1), Array.from(document.querySelectorAll(s)).forEach((n) => { | ||
| const r = g.get(n); | ||
| r && (c(r), oe(n), re(n)); | ||
| }), h === 0 && ae(); | ||
| } | ||
| }; | ||
| }; | ||
| export { | ||
| ce as SlashCommandsPlugin | ||
| }; | ||
| //# sourceMappingURL=SlashCommandsPlugin.native-CmxvMEaE.mjs.map |
| const v = ".rte-content, .editora-content", ee = "[data-editora-editor], .rte-editor, .editora-editor, editora-editor", se = "__editoraCommandEditorRoot", le = "rte-smart-paste-styles", u = "rte-smart-paste-panel", x = "smart-paste", E = "smartPaste", k = ':is([data-theme="dark"], .dark, .editora-theme-dark, .rte-theme-dark)', Ee = typeof NodeFilter != "undefined" ? NodeFilter.SHOW_COMMENT : 128, ie = "__editoraSmartPasteHandled", ke = /* @__PURE__ */ new Set([ | ||
| "script", | ||
| "style", | ||
| "meta", | ||
| "link", | ||
| "object", | ||
| "embed", | ||
| "iframe", | ||
| "svg", | ||
| "canvas", | ||
| "math", | ||
| "form", | ||
| "input", | ||
| "button", | ||
| "textarea", | ||
| "select", | ||
| "option" | ||
| ]), Ce = /* @__PURE__ */ new Set(["table", "thead", "tbody", "tfoot", "tr", "td", "th", "colgroup", "col"]), Te = /* @__PURE__ */ new Set(["span", "font"]), Ae = /^(https?:|mailto:|tel:|#|\/)/i, Pe = /^data:image\/(?:png|gif|jpeg|jpg|webp);base64,/i, Le = /* @__PURE__ */ new Set([ | ||
| "color", | ||
| "background-color", | ||
| "font-weight", | ||
| "font-style", | ||
| "text-decoration", | ||
| "text-align", | ||
| "font-size", | ||
| "font-family", | ||
| "line-height", | ||
| "letter-spacing", | ||
| "word-spacing", | ||
| "white-space", | ||
| "vertical-align", | ||
| "margin-left", | ||
| "margin-right", | ||
| "margin-top", | ||
| "margin-bottom", | ||
| "padding-left", | ||
| "padding-right", | ||
| "padding-top", | ||
| "padding-bottom", | ||
| "text-indent", | ||
| "border", | ||
| "border-top", | ||
| "border-right", | ||
| "border-bottom", | ||
| "border-left", | ||
| "border-color", | ||
| "border-width", | ||
| "border-style", | ||
| "list-style-type" | ||
| ]), we = { | ||
| panelTitle: "Smart Paste", | ||
| panelAriaLabel: "Smart paste panel", | ||
| enabledText: "Smart paste is enabled", | ||
| disabledText: "Smart paste is disabled", | ||
| toggleOnText: "Disable Smart Paste", | ||
| toggleOffText: "Enable Smart Paste", | ||
| cycleProfileText: "Cycle Profile", | ||
| profileLabel: "Profile", | ||
| fidelityText: "Fidelity", | ||
| balancedText: "Balanced", | ||
| plainText: "Plain Text", | ||
| lastPasteHeading: "Last Paste Result", | ||
| lastPasteEmptyText: "Paste content to see cleanup metrics.", | ||
| lastPasteSourceLabel: "Source", | ||
| lastPasteProfileLabel: "Profile", | ||
| lastPasteRemovedLabel: "Removed", | ||
| lastPasteCharsLabel: "Output Chars", | ||
| closeText: "Close", | ||
| shortcutText: "Shortcuts: Ctrl/Cmd+Alt+Shift+S/V/G", | ||
| readonlyMessage: "Editor is read-only. Smart paste was skipped." | ||
| }, Y = { | ||
| fidelity: { | ||
| keepStyles: !0, | ||
| keepClasses: !1, | ||
| keepDataAttributes: !1, | ||
| preserveTables: !0 | ||
| }, | ||
| balanced: { | ||
| keepStyles: !1, | ||
| keepClasses: !1, | ||
| keepDataAttributes: !1, | ||
| preserveTables: !0 | ||
| }, | ||
| plain: { | ||
| keepStyles: !1, | ||
| keepClasses: !1, | ||
| keepDataAttributes: !1, | ||
| preserveTables: !1 | ||
| } | ||
| }, d = /* @__PURE__ */ new WeakMap(), M = /* @__PURE__ */ new WeakMap(), h = /* @__PURE__ */ new Map(), I = /* @__PURE__ */ new WeakMap(), F = /* @__PURE__ */ new WeakMap(), _ = /* @__PURE__ */ new Set(); | ||
| let W = 0, $e = 0, O = null, b = null, L = null, w = null, A = null, $ = null; | ||
| function X(e) { | ||
| return e.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'"); | ||
| } | ||
| function Me(e) { | ||
| return e.replace(/\u00A0/g, " ").replace(/\r\n?/g, ` | ||
| `); | ||
| } | ||
| function H(e) { | ||
| return e === "balanced" || e === "plain" ? e : "fidelity"; | ||
| } | ||
| function Z(e, t) { | ||
| var a, r, n, o; | ||
| return { | ||
| keepStyles: (a = e == null ? void 0 : e.keepStyles) != null ? a : t.keepStyles, | ||
| keepClasses: (r = e == null ? void 0 : e.keepClasses) != null ? r : t.keepClasses, | ||
| keepDataAttributes: (n = e == null ? void 0 : e.keepDataAttributes) != null ? n : t.keepDataAttributes, | ||
| preserveTables: (o = e == null ? void 0 : e.preserveTables) != null ? o : t.preserveTables | ||
| }; | ||
| } | ||
| function V(e = {}) { | ||
| var a; | ||
| const t = e.profileOptions || {}; | ||
| return { | ||
| enabled: e.enabled !== !1, | ||
| defaultProfile: H(e.defaultProfile), | ||
| maxHtmlLength: Math.max(8e3, Math.min(8e5, Number((a = e.maxHtmlLength) != null ? a : 22e4))), | ||
| removeComments: e.removeComments !== !1, | ||
| normalizeWhitespace: e.normalizeWhitespace !== !1, | ||
| labels: { | ||
| ...we, | ||
| ...e.labels || {} | ||
| }, | ||
| normalizeText: e.normalizeText || Me, | ||
| profileOptions: { | ||
| fidelity: Z(t.fidelity, Y.fidelity), | ||
| balanced: Z(t.balanced, Y.balanced), | ||
| plain: Z(t.plain, Y.plain) | ||
| } | ||
| }; | ||
| } | ||
| function ce(e) { | ||
| return { | ||
| enabled: e.enabled, | ||
| defaultProfile: e.defaultProfile, | ||
| maxHtmlLength: e.maxHtmlLength, | ||
| removeComments: e.removeComments, | ||
| normalizeWhitespace: e.normalizeWhitespace, | ||
| labels: { ...e.labels }, | ||
| normalizeText: e.normalizeText, | ||
| profileOptions: { | ||
| fidelity: { ...e.profileOptions.fidelity }, | ||
| balanced: { ...e.profileOptions.balanced }, | ||
| plain: { ...e.profileOptions.plain } | ||
| } | ||
| }; | ||
| } | ||
| function te(e) { | ||
| return e.closest(ee) || e; | ||
| } | ||
| function D(e) { | ||
| if (!e) return null; | ||
| if (e.matches(v)) return e; | ||
| const t = e.querySelector(v); | ||
| return t instanceof HTMLElement ? t : null; | ||
| } | ||
| function Oe() { | ||
| if (typeof window == "undefined") return null; | ||
| const e = window[se]; | ||
| if (!(e instanceof HTMLElement)) return null; | ||
| window[se] = null; | ||
| const t = D(e); | ||
| if (t) return t; | ||
| const a = e.closest(ee); | ||
| if (a) { | ||
| const n = D(a); | ||
| if (n) return n; | ||
| } | ||
| const r = e.closest(v); | ||
| return r instanceof HTMLElement ? r : null; | ||
| } | ||
| function Re(e) { | ||
| const t = e.closest("[data-editora-editor]"); | ||
| if (t && D(t) === e) | ||
| return t; | ||
| let a = e; | ||
| for (; a; ) { | ||
| if (a.matches(ee) && (a === e || D(a) === e)) | ||
| return a; | ||
| a = a.parentElement; | ||
| } | ||
| return te(e); | ||
| } | ||
| function pe(e) { | ||
| return e ? e.nodeType === Node.ELEMENT_NODE ? e : e.parentElement : null; | ||
| } | ||
| function T(e, t = !0, a = !0) { | ||
| if (j(), (e == null ? void 0 : e.contentElement) instanceof HTMLElement) return e.contentElement; | ||
| if ((e == null ? void 0 : e.editorElement) instanceof HTMLElement) { | ||
| const s = D(e.editorElement); | ||
| if (s) return s; | ||
| } | ||
| const r = Oe(); | ||
| if (r) return r; | ||
| const n = window.getSelection(); | ||
| if (n && n.rangeCount > 0) { | ||
| const s = pe(n.getRangeAt(0).startContainer), l = s == null ? void 0 : s.closest(v); | ||
| if (l) return l; | ||
| } | ||
| const o = document.activeElement; | ||
| if (o) { | ||
| if (o.matches(v)) return o; | ||
| const s = o.closest(v); | ||
| if (s) return s; | ||
| } | ||
| if (a) { | ||
| if (b && b.isConnected) return b; | ||
| b && !b.isConnected && (b = null); | ||
| } | ||
| return t ? document.querySelector(v) : null; | ||
| } | ||
| function ze(e) { | ||
| const t = e.target; | ||
| if (t) { | ||
| const r = t.closest(v); | ||
| if (r) return r; | ||
| } | ||
| const a = window.getSelection(); | ||
| if (a && a.rangeCount > 0) { | ||
| const r = pe(a.getRangeAt(0).startContainer), n = r == null ? void 0 : r.closest(v); | ||
| if (n) return n; | ||
| } | ||
| return null; | ||
| } | ||
| function B(e) { | ||
| return e ? (e.getAttribute("data-theme") || e.getAttribute("theme") || "").toLowerCase() === "dark" ? !0 : e.classList.contains("dark") || e.classList.contains("editora-theme-dark") || e.classList.contains("rte-theme-dark") : !1; | ||
| } | ||
| function _e(e) { | ||
| const t = te(e); | ||
| if (B(t)) return !0; | ||
| const a = t.closest("[data-theme], [theme], .dark, .editora-theme-dark, .rte-theme-dark"); | ||
| return B(a) ? !0 : B(document.documentElement) || B(document.body); | ||
| } | ||
| function G(e, t) { | ||
| e.classList.remove("rte-smart-paste-theme-dark"), _e(t) && e.classList.add("rte-smart-paste-theme-dark"); | ||
| } | ||
| function de(e) { | ||
| return e.getAttribute("contenteditable") === "false" || e.getAttribute("data-readonly") === "true"; | ||
| } | ||
| function N(e, t, a) { | ||
| const r = Re(e); | ||
| Array.from( | ||
| r.querySelectorAll( | ||
| `.rte-toolbar-button[data-command="${t}"], .editora-toolbar-button[data-command="${t}"]` | ||
| ) | ||
| ).forEach((o) => { | ||
| o.classList.toggle("active", a), o.setAttribute("data-active", a ? "true" : "false"), o.setAttribute("aria-pressed", a ? "true" : "false"); | ||
| }); | ||
| } | ||
| function m(e, t) { | ||
| d.has(e) || d.set(e, t); | ||
| let a = M.get(e); | ||
| return a || (a = { | ||
| enabled: t.enabled, | ||
| profile: t.defaultProfile, | ||
| lastReport: null | ||
| }, M.set(e, a)), Qe(e), _.add(e), a; | ||
| } | ||
| function me(e) { | ||
| const t = F.get(e); | ||
| t && (e.removeEventListener("paste", t, !0), F.delete(e)); | ||
| } | ||
| function be(e) { | ||
| var t; | ||
| me(e), (t = h.get(e)) == null || t.remove(), h.delete(e), I.delete(e), d.delete(e), M.delete(e), _.delete(e), b === e && (b = null); | ||
| } | ||
| function j() { | ||
| Array.from(_).forEach((t) => { | ||
| t.isConnected || be(t); | ||
| }); | ||
| } | ||
| function He(e) { | ||
| var t, a, r, n; | ||
| for (let o = 0; o < e.length; o += 1) { | ||
| const s = e[o]; | ||
| if (!(s.type !== "childList" || s.removedNodes.length === 0)) | ||
| for (let l = 0; l < s.removedNodes.length; l += 1) { | ||
| const c = s.removedNodes[l]; | ||
| if (c.nodeType !== Node.ELEMENT_NODE) continue; | ||
| const i = c; | ||
| if ((t = i.matches) != null && t.call(i, v) || (a = i.matches) != null && a.call(i, `.${u}`) || (r = i.querySelector) != null && r.call(i, v) || (n = i.querySelector) != null && n.call(i, `.${u}`)) | ||
| return !0; | ||
| } | ||
| } | ||
| return !1; | ||
| } | ||
| function re(e) { | ||
| return I.get(e) === !0; | ||
| } | ||
| function R(e, t) { | ||
| const a = e.querySelector(".rte-smart-paste-live"); | ||
| a && (a.textContent = t); | ||
| } | ||
| function J(e, t) { | ||
| const a = t.normalizeText(e); | ||
| return t.normalizeWhitespace ? a.split(` | ||
| `).map((n) => n.replace(/[\t ]+/g, " ").trimEnd()).join(` | ||
| `).replace(/\n{3,}/g, ` | ||
| `).trim() : a; | ||
| } | ||
| function De(e) { | ||
| return /class=["'][^"']*Mso|xmlns:w=|urn:schemas-microsoft-com:office|<o:p\b/i.test(e); | ||
| } | ||
| function Ne(e) { | ||
| return /id=["']docs-internal-guid|docs-\w+|data-sheets-value|data-sheets-userformat/i.test(e); | ||
| } | ||
| function qe(e, t) { | ||
| return e ? De(e) ? "word" : Ne(e) ? "google-docs" : "html" : t ? "plain" : "html"; | ||
| } | ||
| function Ie(e) { | ||
| return e.split(/\s+/).map((a) => a.trim()).filter(Boolean).filter((a) => !/^mso/i.test(a)).filter((a) => !/^docs-/i.test(a)).filter((a) => !/^c\d+$/i.test(a)).join(" "); | ||
| } | ||
| function We(e) { | ||
| if (!e) return { value: "", changed: !1 }; | ||
| const t = e.split(";"), a = []; | ||
| let r = !1; | ||
| return t.forEach((n) => { | ||
| const o = n.indexOf(":"); | ||
| if (o <= 0) { | ||
| n.trim() && (r = !0); | ||
| return; | ||
| } | ||
| const s = n.slice(0, o).trim().toLowerCase(), l = n.slice(o + 1).trim(); | ||
| if (!s || !l) { | ||
| r = !0; | ||
| return; | ||
| } | ||
| if (!Le.has(s)) { | ||
| r = !0; | ||
| return; | ||
| } | ||
| if (/expression\s*\(|javascript\s*:|vbscript\s*:|url\s*\(/i.test(l)) { | ||
| r = !0; | ||
| return; | ||
| } | ||
| a.push(`${s}: ${l}`); | ||
| }), { | ||
| value: a.join("; "), | ||
| changed: r | ||
| }; | ||
| } | ||
| function ue(e) { | ||
| const t = e.trim(); | ||
| return t && (Ae.test(t) || Pe.test(t)) ? t : ""; | ||
| } | ||
| function fe(e) { | ||
| const t = e.parentNode; | ||
| if (t) { | ||
| for (; e.firstChild; ) | ||
| t.insertBefore(e.firstChild, e); | ||
| t.removeChild(e); | ||
| } | ||
| } | ||
| function Be(e, t, a, r) { | ||
| const n = e.tagName.toLowerCase(); | ||
| if (ke.has(n)) { | ||
| r.removedElements += 1, e.remove(); | ||
| return; | ||
| } | ||
| if (!t.preserveTables && Ce.has(n)) { | ||
| const s = e.textContent || "", l = document.createTextNode(s); | ||
| e.replaceWith(l), r.removedElements += 1; | ||
| return; | ||
| } | ||
| if (Array.from(e.attributes).forEach((s) => { | ||
| const l = s.name.toLowerCase(), c = s.value; | ||
| if (l.startsWith("on")) { | ||
| e.removeAttribute(s.name), r.removedAttributes += 1; | ||
| return; | ||
| } | ||
| if (l === "style") { | ||
| if (!t.keepStyles) { | ||
| e.removeAttribute(s.name), r.removedAttributes += 1; | ||
| return; | ||
| } | ||
| const i = We(c); | ||
| if (!i.value) { | ||
| e.removeAttribute(s.name), r.removedAttributes += 1, i.changed && (r.normalizedStyles += 1); | ||
| return; | ||
| } | ||
| (i.changed || i.value !== c) && (e.setAttribute("style", i.value), r.normalizedStyles += 1); | ||
| return; | ||
| } | ||
| if (l === "class") { | ||
| if (!t.keepClasses) { | ||
| e.removeAttribute(s.name), r.removedAttributes += 1; | ||
| return; | ||
| } | ||
| const i = Ie(c); | ||
| if (!i) { | ||
| e.removeAttribute(s.name), r.removedAttributes += 1; | ||
| return; | ||
| } | ||
| i !== c && (e.setAttribute("class", i), r.removedAttributes += 1); | ||
| return; | ||
| } | ||
| if (l.startsWith("data-") && !t.keepDataAttributes) { | ||
| e.removeAttribute(s.name), r.removedAttributes += 1; | ||
| return; | ||
| } | ||
| if (l === "id" || l === "xmlns" || l.startsWith("xml")) { | ||
| e.removeAttribute(s.name), r.removedAttributes += 1; | ||
| return; | ||
| } | ||
| if ((a === "word" || a === "google-docs") && (l === "lang" || l === "dir")) { | ||
| e.removeAttribute(s.name), r.removedAttributes += 1; | ||
| return; | ||
| } | ||
| if (l === "href" || l === "src" || l === "xlink:href") { | ||
| const i = ue(c); | ||
| if (!i) { | ||
| e.removeAttribute(s.name), r.removedAttributes += 1; | ||
| return; | ||
| } | ||
| i !== c && e.setAttribute(s.name, i); | ||
| } | ||
| }), n === "a") { | ||
| if (!e.getAttribute("href")) { | ||
| fe(e), r.removedElements += 1; | ||
| return; | ||
| } | ||
| e.getAttribute("target") === "_blank" && e.setAttribute("rel", "noopener noreferrer"); | ||
| } | ||
| if (n === "img") { | ||
| const s = e.getAttribute("src"); | ||
| if (!s || !ue(s)) { | ||
| r.removedElements += 1, e.remove(); | ||
| return; | ||
| } | ||
| } | ||
| if (Te.has(n) && !e.attributes.length && !e.className && !e.style.cssText) { | ||
| const s = e.children.length > 0, l = (e.textContent || "").trim().length > 0; | ||
| if (!s && !l) { | ||
| e.remove(), r.removedElements += 1; | ||
| return; | ||
| } | ||
| !s && l && (fe(e), r.removedElements += 1); | ||
| } | ||
| } | ||
| function Ke(e, t, a, r, n) { | ||
| const o = document.createElement("template"); | ||
| o.innerHTML = e; | ||
| const s = { | ||
| removedElements: 0, | ||
| removedAttributes: 0, | ||
| removedComments: 0, | ||
| normalizedStyles: 0 | ||
| }; | ||
| if (r.removeComments) | ||
| try { | ||
| const f = document.createTreeWalker(o.content, Ee, null), p = []; | ||
| let y = f.nextNode(); | ||
| for (; y; ) | ||
| p.push(y), y = f.nextNode(); | ||
| p.forEach((g) => { | ||
| g.remove(), s.removedComments += 1; | ||
| }); | ||
| } catch (f) { | ||
| } | ||
| Array.from(o.content.querySelectorAll("*")).forEach((f) => { | ||
| f.isConnected && Be(f, t, a, s); | ||
| }); | ||
| let c = o.innerHTML; | ||
| r.normalizeWhitespace && n !== "fidelity" ? c = c.replace(/\s{2,}/g, " ").replace(/>\s+</g, "><").trim() : r.normalizeWhitespace && (c = c.trim()); | ||
| const i = (o.content.textContent || "").trim().length; | ||
| return { | ||
| html: c, | ||
| textLength: i, | ||
| counters: s | ||
| }; | ||
| } | ||
| function ge(e) { | ||
| const t = window.getSelection(); | ||
| if (!t || t.rangeCount === 0) return null; | ||
| const a = t.getRangeAt(0); | ||
| return e.contains(a.commonAncestorContainer) ? a : null; | ||
| } | ||
| function he(e, t) { | ||
| if (!e.isConnected) return; | ||
| const a = window.getSelection(); | ||
| a && (a.removeAllRanges(), a.addRange(t)); | ||
| } | ||
| function Ve(e, t) { | ||
| e.focus({ preventScroll: !0 }); | ||
| try { | ||
| if (document.execCommand("insertHTML", !1, t)) | ||
| return !0; | ||
| } catch (s) { | ||
| } | ||
| const a = ge(e); | ||
| if (!a) return !1; | ||
| a.deleteContents(); | ||
| const r = document.createElement("template"); | ||
| r.innerHTML = t; | ||
| const n = r.content, o = n.lastChild; | ||
| if (a.insertNode(n), o) { | ||
| const s = document.createRange(); | ||
| s.setStartAfter(o), s.collapse(!0), he(e, s); | ||
| } | ||
| return !0; | ||
| } | ||
| function je(e, t) { | ||
| e.focus({ preventScroll: !0 }); | ||
| try { | ||
| if (document.execCommand("insertText", !1, t)) | ||
| return !0; | ||
| } catch (o) { | ||
| } | ||
| const a = ge(e); | ||
| if (!a) return !1; | ||
| a.deleteContents(); | ||
| const r = document.createTextNode(t); | ||
| a.insertNode(r); | ||
| const n = document.createRange(); | ||
| return n.setStart(r, r.length), n.collapse(!0), he(e, n), !0; | ||
| } | ||
| function Fe(e, t) { | ||
| if (t === e.innerHTML) return; | ||
| const a = window.execEditorCommand || window.executeEditorCommand; | ||
| if (typeof a == "function") | ||
| try { | ||
| a("recordDomTransaction", e, t, e.innerHTML); | ||
| } catch (r) { | ||
| } | ||
| } | ||
| function Ge(e) { | ||
| e.dispatchEvent(new Event("input", { bubbles: !0 })); | ||
| } | ||
| function K(e, t, a, r, n, o) { | ||
| return { | ||
| source: e, | ||
| profile: t, | ||
| inputHtmlLength: a, | ||
| outputHtmlLength: r, | ||
| outputTextLength: n, | ||
| removedElements: o.removedElements, | ||
| removedAttributes: o.removedAttributes, | ||
| removedComments: o.removedComments, | ||
| normalizedStyles: o.normalizedStyles, | ||
| createdAt: (/* @__PURE__ */ new Date()).toISOString() | ||
| }; | ||
| } | ||
| function Ue(e, t, a, r) { | ||
| const n = qe(e, t); | ||
| if (a === "plain") { | ||
| const l = t || e.replace(/<[^>]*>/g, " "), c = J(l, r); | ||
| return { | ||
| mode: "text", | ||
| value: c, | ||
| report: K( | ||
| n, | ||
| a, | ||
| e.length, | ||
| 0, | ||
| c.length, | ||
| { | ||
| removedElements: 0, | ||
| removedAttributes: 0, | ||
| removedComments: 0, | ||
| normalizedStyles: 0 | ||
| } | ||
| ) | ||
| }; | ||
| } | ||
| if (!e || e.length > r.maxHtmlLength) { | ||
| const l = J(t || e.replace(/<[^>]*>/g, " "), r); | ||
| return { | ||
| mode: "text", | ||
| value: l, | ||
| report: K( | ||
| n, | ||
| a, | ||
| e.length, | ||
| 0, | ||
| l.length, | ||
| { | ||
| removedElements: 0, | ||
| removedAttributes: 0, | ||
| removedComments: 0, | ||
| normalizedStyles: 0 | ||
| } | ||
| ) | ||
| }; | ||
| } | ||
| const o = r.profileOptions[a], s = Ke(e, o, n, r, a); | ||
| if (!s.html) { | ||
| const l = J(t || e.replace(/<[^>]*>/g, " "), r); | ||
| return { | ||
| mode: "text", | ||
| value: l, | ||
| report: K(n, a, e.length, 0, l.length, s.counters) | ||
| }; | ||
| } | ||
| return { | ||
| mode: "html", | ||
| value: s.html, | ||
| report: K( | ||
| n, | ||
| a, | ||
| e.length, | ||
| s.html.length, | ||
| s.textLength, | ||
| s.counters | ||
| ) | ||
| }; | ||
| } | ||
| function U(e, t) { | ||
| return e === "balanced" ? t.balancedText : e === "plain" ? t.plainText : t.fidelityText; | ||
| } | ||
| function ae(e) { | ||
| return e === "fidelity" ? "balanced" : e === "balanced" ? "plain" : "fidelity"; | ||
| } | ||
| function Ye(e, t) { | ||
| e.setAttribute("aria-label", t.labels.panelAriaLabel); | ||
| const a = e.querySelector(".rte-smart-paste-title"); | ||
| a && (a.textContent = t.labels.panelTitle); | ||
| const r = e.querySelector('[data-action="close"]'); | ||
| r && r.setAttribute("aria-label", t.labels.closeText); | ||
| const n = e.querySelector('[data-action="toggle-enabled"]'); | ||
| if (n) { | ||
| const Se = n.getAttribute("data-enabled") === "true"; | ||
| n.textContent = Se ? t.labels.toggleOnText : t.labels.toggleOffText; | ||
| } | ||
| const o = e.querySelector('[data-action="cycle-profile"]'); | ||
| o && (o.textContent = t.labels.cycleProfileText); | ||
| const s = e.querySelector(".rte-smart-paste-profile-heading"); | ||
| s && (s.textContent = t.labels.profileLabel); | ||
| const l = e.querySelector('.rte-smart-paste-profile[role="group"]'); | ||
| l && l.setAttribute("aria-label", t.labels.profileLabel); | ||
| const c = e.querySelector('[data-action="set-profile"][data-profile="fidelity"]'); | ||
| c && (c.textContent = t.labels.fidelityText); | ||
| const i = e.querySelector('[data-action="set-profile"][data-profile="balanced"]'); | ||
| i && (i.textContent = t.labels.balancedText); | ||
| const f = e.querySelector('[data-action="set-profile"][data-profile="plain"]'); | ||
| f && (f.textContent = t.labels.plainText); | ||
| const p = e.querySelector(".rte-smart-paste-report-title"); | ||
| p && (p.textContent = t.labels.lastPasteHeading); | ||
| const y = e.querySelector(".rte-smart-paste-empty"); | ||
| y && (y.textContent = t.labels.lastPasteEmptyText); | ||
| const g = e.querySelector('[data-key="source-label"]'); | ||
| g && (g.textContent = t.labels.lastPasteSourceLabel); | ||
| const P = e.querySelector('[data-key="profile-label"]'); | ||
| P && (P.textContent = t.labels.lastPasteProfileLabel); | ||
| const C = e.querySelector('[data-key="removed-label"]'); | ||
| C && (C.textContent = t.labels.lastPasteRemovedLabel); | ||
| const oe = e.querySelector('[data-key="chars-label"]'); | ||
| oe && (oe.textContent = t.labels.lastPasteCharsLabel); | ||
| const ne = e.querySelector(".rte-smart-paste-shortcut"); | ||
| ne && (ne.textContent = t.labels.shortcutText); | ||
| } | ||
| function S(e) { | ||
| const t = h.get(e), a = d.get(e) || O, r = M.get(e); | ||
| if (!t || !a || !r) return; | ||
| Ye(t, a); | ||
| const n = t.querySelector(".rte-smart-paste-status"); | ||
| n && (n.textContent = r.enabled ? a.labels.enabledText : a.labels.disabledText); | ||
| const o = t.querySelector('[data-action="toggle-enabled"]'); | ||
| o && (o.setAttribute("data-enabled", r.enabled ? "true" : "false"), o.textContent = r.enabled ? a.labels.toggleOnText : a.labels.toggleOffText, o.setAttribute("aria-pressed", r.enabled ? "true" : "false")), Array.from( | ||
| t.querySelectorAll('[data-action="set-profile"][data-profile]') | ||
| ).forEach((g) => { | ||
| const C = H(g.getAttribute("data-profile")) === r.profile; | ||
| g.classList.toggle("active", C), g.setAttribute("aria-pressed", C ? "true" : "false"); | ||
| }); | ||
| const l = t.querySelector(".rte-smart-paste-empty"), c = t.querySelector(".rte-smart-paste-report"), i = t.querySelector('[data-key="source-value"]'), f = t.querySelector('[data-key="profile-value"]'), p = t.querySelector('[data-key="removed-value"]'), y = t.querySelector('[data-key="chars-value"]'); | ||
| if (!r.lastReport) { | ||
| l && (l.hidden = !1), c && (c.hidden = !0); | ||
| return; | ||
| } | ||
| if (l && (l.hidden = !0), c && (c.hidden = !1), i && (i.textContent = r.lastReport.source), f && (f.textContent = U(r.lastReport.profile, a.labels)), p) { | ||
| const g = r.lastReport.removedElements + r.lastReport.removedAttributes + r.lastReport.removedComments + r.lastReport.normalizedStyles; | ||
| p.textContent = String(g); | ||
| } | ||
| y && (y.textContent = String(r.lastReport.outputTextLength)); | ||
| } | ||
| function Q(e, t) { | ||
| if (!t.classList.contains("show")) return; | ||
| const a = te(e).getBoundingClientRect(), r = Math.min(window.innerWidth - 20, 360), n = Math.max(10, window.innerWidth - r - 10), o = Math.min(Math.max(10, a.right - r), n), s = Math.max(10, Math.min(window.innerHeight - 10, a.top + 12)); | ||
| t.style.width = `${r}px`, t.style.left = `${o}px`, t.style.top = `${s}px`, t.style.maxHeight = `${Math.max(240, window.innerHeight - 20)}px`; | ||
| } | ||
| function q(e, t = !1) { | ||
| const a = h.get(e); | ||
| a && (a.classList.remove("show"), I.set(e, !1), N(e, "toggleSmartPastePanel", !1), t && e.focus({ preventScroll: !0 })); | ||
| } | ||
| function Xe(e) { | ||
| const t = h.get(e); | ||
| if (t) return t; | ||
| const a = d.get(e) || O || V(), r = `rte-smart-paste-panel-${$e++}`, n = document.createElement("section"); | ||
| return n.className = u, n.id = r, n.setAttribute("role", "dialog"), n.setAttribute("aria-modal", "false"), n.setAttribute("aria-label", a.labels.panelAriaLabel), n.innerHTML = ` | ||
| <header class="rte-smart-paste-header"> | ||
| <h2 class="rte-smart-paste-title">${X(a.labels.panelTitle)}</h2> | ||
| <button type="button" class="rte-smart-paste-icon-btn" data-action="close" aria-label="${X(a.labels.closeText)}">✕</button> | ||
| </header> | ||
| <div class="rte-smart-paste-body"> | ||
| <p class="rte-smart-paste-status"></p> | ||
| <div class="rte-smart-paste-controls"> | ||
| <button type="button" class="rte-smart-paste-btn rte-smart-paste-btn-primary" data-action="toggle-enabled" data-enabled="true"></button> | ||
| <button type="button" class="rte-smart-paste-btn" data-action="cycle-profile"></button> | ||
| </div> | ||
| <div class="rte-smart-paste-profile" role="group" aria-label="${X(a.labels.profileLabel)}"> | ||
| <p class="rte-smart-paste-profile-heading"></p> | ||
| <div class="rte-smart-paste-profile-grid"> | ||
| <button type="button" class="rte-smart-paste-chip" data-action="set-profile" data-profile="fidelity" aria-pressed="false"></button> | ||
| <button type="button" class="rte-smart-paste-chip" data-action="set-profile" data-profile="balanced" aria-pressed="false"></button> | ||
| <button type="button" class="rte-smart-paste-chip" data-action="set-profile" data-profile="plain" aria-pressed="false"></button> | ||
| </div> | ||
| </div> | ||
| <section class="rte-smart-paste-metrics" aria-live="polite"> | ||
| <h3 class="rte-smart-paste-report-title"></h3> | ||
| <p class="rte-smart-paste-empty"></p> | ||
| <dl class="rte-smart-paste-report" hidden> | ||
| <div class="rte-smart-paste-line"><dt data-key="source-label"></dt><dd data-key="source-value"></dd></div> | ||
| <div class="rte-smart-paste-line"><dt data-key="profile-label"></dt><dd data-key="profile-value"></dd></div> | ||
| <div class="rte-smart-paste-line"><dt data-key="removed-label"></dt><dd data-key="removed-value"></dd></div> | ||
| <div class="rte-smart-paste-line"><dt data-key="chars-label"></dt><dd data-key="chars-value"></dd></div> | ||
| </dl> | ||
| </section> | ||
| <p class="rte-smart-paste-shortcut"></p> | ||
| </div> | ||
| <div class="rte-smart-paste-live" aria-live="polite" aria-atomic="true"></div> | ||
| `, n.addEventListener("click", (o) => { | ||
| const s = o.target, l = s == null ? void 0 : s.closest("[data-action]"); | ||
| if (!l) return; | ||
| const c = l.getAttribute("data-action"); | ||
| if (c) { | ||
| if (c === "close") { | ||
| q(e, !0); | ||
| return; | ||
| } | ||
| if (c === "toggle-enabled") { | ||
| const i = m(e, d.get(e) || a); | ||
| i.enabled = !i.enabled, N(e, "toggleSmartPasteEnabled", i.enabled), S(e), R(n, i.enabled ? a.labels.enabledText : a.labels.disabledText); | ||
| return; | ||
| } | ||
| if (c === "cycle-profile") { | ||
| const i = m(e, d.get(e) || a); | ||
| i.profile = ae(i.profile), S(e), R(n, `${a.labels.profileLabel}: ${U(i.profile, a.labels)}`); | ||
| return; | ||
| } | ||
| if (c === "set-profile") { | ||
| const i = m(e, d.get(e) || a); | ||
| i.profile = H(l.getAttribute("data-profile")), S(e), R(n, `${a.labels.profileLabel}: ${U(i.profile, a.labels)}`); | ||
| } | ||
| } | ||
| }), n.addEventListener("keydown", (o) => { | ||
| if (o.key === "Escape") { | ||
| o.preventDefault(), q(e, !0); | ||
| return; | ||
| } | ||
| if (o.key !== "ArrowRight" && o.key !== "ArrowLeft") return; | ||
| const s = Array.from( | ||
| n.querySelectorAll('[data-action="set-profile"][data-profile]') | ||
| ); | ||
| if (s.length === 0) return; | ||
| const l = s.findIndex((f) => f === document.activeElement); | ||
| if (l < 0) return; | ||
| const c = o.key === "ArrowRight" ? 1 : -1, i = (l + c + s.length) % s.length; | ||
| o.preventDefault(), s[i].focus(); | ||
| }), G(n, e), document.body.appendChild(n), h.set(e, n), I.set(e, !1), S(e), n; | ||
| } | ||
| function ye(e) { | ||
| const t = Xe(e); | ||
| h.forEach((r, n) => { | ||
| n !== e && q(n, !1); | ||
| }), t.classList.add("show"), I.set(e, !0), N(e, "toggleSmartPastePanel", !0), G(t, e), Q(e, t); | ||
| const a = t.querySelector('[data-action="toggle-enabled"]'); | ||
| a == null || a.focus(); | ||
| } | ||
| function xe(e, t) { | ||
| const a = re(e); | ||
| return (typeof t == "boolean" ? t : !a) ? ye(e) : q(e, !1), !0; | ||
| } | ||
| function ve(e) { | ||
| return { | ||
| enabled: e.enabled, | ||
| profile: e.profile, | ||
| lastReport: e.lastReport ? { ...e.lastReport } : null | ||
| }; | ||
| } | ||
| function Ze(e, t) { | ||
| const a = d.get(e) || O; | ||
| if (!a) return !1; | ||
| const r = m(e, a); | ||
| if (!r.enabled || de(e)) { | ||
| const p = h.get(e); | ||
| return p && de(e) && R(p, a.labels.readonlyMessage), !1; | ||
| } | ||
| const n = t.clipboardData; | ||
| if (!n) return !1; | ||
| const o = n.getData("text/html") || "", s = n.getData("text/plain") || ""; | ||
| if (!o && !s) return !1; | ||
| const l = Ue(o, s, r.profile, a); | ||
| if (!l.value) return !1; | ||
| const c = e.innerHTML; | ||
| if (!(l.mode === "html" ? Ve(e, l.value) : je(e, l.value))) return !1; | ||
| r.lastReport = { ...l.report }, M.set(e, r), Fe(e, c), Ge(e), e.dispatchEvent( | ||
| new CustomEvent("editora:smart-paste", { | ||
| bubbles: !0, | ||
| detail: ve(r) | ||
| }) | ||
| ), S(e); | ||
| const f = h.get(e); | ||
| if (f) { | ||
| const p = l.report.removedElements + l.report.removedAttributes + l.report.removedComments + l.report.normalizedStyles; | ||
| R( | ||
| f, | ||
| `${a.labels.panelTitle}: ${U(r.profile, a.labels)}. ${a.labels.lastPasteRemovedLabel}: ${p}.` | ||
| ); | ||
| } | ||
| return !0; | ||
| } | ||
| function Je(e) { | ||
| return (t) => { | ||
| t.defaultPrevented || t[ie] === !0 || (b = e, !Ze(e, t)) || (t[ie] = !0, t.preventDefault(), typeof t.stopImmediatePropagation == "function" ? t.stopImmediatePropagation() : t.stopPropagation()); | ||
| }; | ||
| } | ||
| function Qe(e) { | ||
| if (F.has(e)) return; | ||
| const t = Je(e); | ||
| e.addEventListener("paste", t, !0), F.set(e, t); | ||
| } | ||
| function z(e) { | ||
| const t = M.get(e); | ||
| N(e, "toggleSmartPastePanel", re(e)), N(e, "toggleSmartPasteEnabled", (t == null ? void 0 : t.enabled) === !0); | ||
| } | ||
| function et(e) { | ||
| const t = e.key.toLowerCase(); | ||
| return (e.metaKey || e.ctrlKey) && e.altKey && e.shiftKey && t === "s"; | ||
| } | ||
| function tt(e) { | ||
| const t = e.key.toLowerCase(); | ||
| return (e.metaKey || e.ctrlKey) && e.altKey && e.shiftKey && t === "v"; | ||
| } | ||
| function rt(e) { | ||
| const t = e.key.toLowerCase(); | ||
| return (e.metaKey || e.ctrlKey) && e.altKey && e.shiftKey && t === "g"; | ||
| } | ||
| function at(e) { | ||
| O = e, L || (L = (t) => { | ||
| j(); | ||
| const a = t.target, r = a == null ? void 0 : a.closest(v); | ||
| if (!r) return; | ||
| const n = d.get(r) || e; | ||
| m(r, n), d.set(r, n), b = r, z(r); | ||
| const o = h.get(r); | ||
| o && (G(o, r), Q(r, o), S(r)); | ||
| }, document.addEventListener("focusin", L, !0)), w || (w = (t) => { | ||
| if (t.defaultPrevented) return; | ||
| const a = t.target; | ||
| if (a != null && a.closest(`.${u} input, .${u} textarea, .${u} select`)) return; | ||
| const r = ze(t); | ||
| if (!r) return; | ||
| const n = d.get(r) || O || e; | ||
| if (m(r, n), d.set(r, n), b = r, t.key === "Escape" && re(r)) { | ||
| t.preventDefault(), q(r, !0); | ||
| return; | ||
| } | ||
| if (et(t)) { | ||
| t.preventDefault(), t.stopPropagation(), xe(r); | ||
| return; | ||
| } | ||
| if (tt(t)) { | ||
| t.preventDefault(), t.stopPropagation(); | ||
| const o = m(r, n); | ||
| o.profile = ae(o.profile), S(r); | ||
| return; | ||
| } | ||
| if (rt(t)) { | ||
| t.preventDefault(), t.stopPropagation(); | ||
| const o = m(r, n); | ||
| o.enabled = !o.enabled, z(r), S(r); | ||
| } | ||
| }, document.addEventListener("keydown", w, !0)), A || (A = () => { | ||
| j(), h.forEach((t, a) => { | ||
| !a.isConnected || !t.isConnected || (G(t, a), Q(a, t)); | ||
| }); | ||
| }, window.addEventListener("scroll", A, !0), window.addEventListener("resize", A)), !$ && typeof MutationObserver != "undefined" && document.body && ($ = new MutationObserver((t) => { | ||
| He(t) && j(); | ||
| }), $.observe(document.body, { | ||
| childList: !0, | ||
| subtree: !0 | ||
| })); | ||
| } | ||
| function ot() { | ||
| L && (document.removeEventListener("focusin", L, !0), L = null), w && (document.removeEventListener("keydown", w, !0), w = null), A && (window.removeEventListener("scroll", A, !0), window.removeEventListener("resize", A), A = null), $ && ($.disconnect(), $ = null), h.forEach((e) => e.remove()), h.clear(), _.forEach((e) => me(e)), _.clear(), O = null, b = null; | ||
| } | ||
| function nt() { | ||
| if (typeof document == "undefined" || document.getElementById(le)) return; | ||
| const e = document.createElement("style"); | ||
| e.id = le, e.textContent = ` | ||
| .rte-toolbar-group-items.${x}, | ||
| .editora-toolbar-group-items.${x}, | ||
| .rte-toolbar-group-items.${E}, | ||
| .editora-toolbar-group-items.${E} { | ||
| display: flex; | ||
| border: 1px solid #ccc; | ||
| border-radius: 3px; | ||
| background: #fff; | ||
| } | ||
| .rte-toolbar-group-items.${x} .rte-toolbar-button, | ||
| .editora-toolbar-group-items.${x} .editora-toolbar-button, | ||
| .rte-toolbar-group-items.${E} .rte-toolbar-button, | ||
| .editora-toolbar-group-items.${E} .editora-toolbar-button { | ||
| border: none; | ||
| border-right: 1px solid #ccc; | ||
| border-radius: 0; | ||
| } | ||
| .rte-toolbar-group-items.${x} .rte-toolbar-item:last-child .rte-toolbar-button, | ||
| .editora-toolbar-group-items.${x} .editora-toolbar-item:last-child .editora-toolbar-button, | ||
| .rte-toolbar-group-items.${E} .rte-toolbar-item:last-child .rte-toolbar-button, | ||
| .editora-toolbar-group-items.${E} .editora-toolbar-item:last-child .editora-toolbar-button { | ||
| border-right: none; | ||
| } | ||
| .rte-toolbar-button[data-command="toggleSmartPasteEnabled"].active, | ||
| .editora-toolbar-button[data-command="toggleSmartPasteEnabled"].active { | ||
| background-color: #ccc; | ||
| } | ||
| ${k} .rte-toolbar-group-items.${x}, | ||
| ${k} .editora-toolbar-group-items.${x}, | ||
| ${k} .rte-toolbar-group-items.${E}, | ||
| ${k} .editora-toolbar-group-items.${E}, | ||
| .${u}.rte-smart-paste-theme-dark { | ||
| border-color: #566275; | ||
| } | ||
| ${k} .rte-toolbar-group-items.${x} .rte-toolbar-button svg, | ||
| ${k} .editora-toolbar-group-items.${x} .editora-toolbar-button svg, | ||
| ${k} .rte-toolbar-group-items.${E} .rte-toolbar-button svg, | ||
| ${k} .editora-toolbar-group-items.${E} .editora-toolbar-button svg { | ||
| fill: none; | ||
| } | ||
| ${k} .rte-toolbar-group-items.${x} .rte-toolbar-button, | ||
| ${k} .editora-toolbar-group-items.${x} .editora-toolbar-button | ||
| { | ||
| border-color: #566275; | ||
| } | ||
| .${u} { | ||
| position: fixed; | ||
| z-index: 12000; | ||
| display: none; | ||
| width: min(360px, calc(100vw - 20px)); | ||
| max-height: calc(100vh - 20px); | ||
| border: 1px solid #d1d5db; | ||
| border-radius: 14px; | ||
| background: #ffffff; | ||
| color: #111827; | ||
| box-shadow: 0 18px 45px rgba(15, 23, 42, 0.25); | ||
| overflow: hidden; | ||
| } | ||
| .${u}.show { | ||
| display: flex; | ||
| flex-direction: column; | ||
| } | ||
| .${u}.rte-smart-paste-theme-dark { | ||
| border-color: #334155; | ||
| background: #0f172a; | ||
| color: #e2e8f0; | ||
| box-shadow: 0 20px 46px rgba(2, 6, 23, 0.68); | ||
| } | ||
| .rte-smart-paste-header { | ||
| display: flex; | ||
| align-items: center; | ||
| justify-content: space-between; | ||
| gap: 8px; | ||
| padding: 12px 14px; | ||
| border-bottom: 1px solid #e5e7eb; | ||
| background: linear-gradient(180deg, #f9fafb 0%, #f3f4f6 100%); | ||
| } | ||
| .${u}.rte-smart-paste-theme-dark .rte-smart-paste-header { | ||
| border-color: #1e293b; | ||
| background: linear-gradient(180deg, #111827 0%, #0f172a 100%); | ||
| } | ||
| .rte-smart-paste-title { | ||
| margin: 0; | ||
| font-size: 15px; | ||
| line-height: 1.2; | ||
| font-weight: 700; | ||
| } | ||
| .rte-smart-paste-icon-btn { | ||
| width: 34px; | ||
| height: 34px; | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 6px; | ||
| background: #ffffff; | ||
| color: #0f172a; | ||
| font-size: 16px; | ||
| line-height: 1; | ||
| font-weight: 600; | ||
| padding: 0; | ||
| display: inline-flex; | ||
| align-items: center; | ||
| justify-content: center; | ||
| cursor: pointer; | ||
| } | ||
| .rte-smart-paste-icon-btn:hover, | ||
| .rte-smart-paste-icon-btn:focus-visible { | ||
| outline: none; | ||
| border-color: #3b82f6; | ||
| box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.2); | ||
| } | ||
| .${u}.rte-smart-paste-theme-dark .rte-smart-paste-icon-btn { | ||
| background: #0f172a; | ||
| border-color: #475569; | ||
| color: #e2e8f0; | ||
| } | ||
| .${u}.rte-smart-paste-theme-dark .rte-smart-paste-icon-btn:hover, | ||
| .${u}.rte-smart-paste-theme-dark .rte-smart-paste-icon-btn:focus-visible { | ||
| border-color: #60a5fa; | ||
| box-shadow: 0 0 0 3px rgba(96, 165, 250, 0.24); | ||
| } | ||
| .rte-smart-paste-body { | ||
| display: flex; | ||
| flex-direction: column; | ||
| gap: 10px; | ||
| padding: 12px; | ||
| overflow: auto; | ||
| } | ||
| .rte-smart-paste-status { | ||
| margin: 0; | ||
| font-size: 12px; | ||
| line-height: 1.35; | ||
| color: #475569; | ||
| font-weight: 600; | ||
| } | ||
| .${u}.rte-smart-paste-theme-dark .rte-smart-paste-status { | ||
| color: #94a3b8; | ||
| } | ||
| .rte-smart-paste-controls { | ||
| display: flex; | ||
| gap: 8px; | ||
| flex-wrap: wrap; | ||
| } | ||
| .rte-smart-paste-btn { | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 8px; | ||
| height: 34px; | ||
| padding: 0 10px; | ||
| background: #ffffff; | ||
| color: inherit; | ||
| font-size: 12px; | ||
| font-weight: 600; | ||
| cursor: pointer; | ||
| } | ||
| .rte-smart-paste-btn:hover, | ||
| .rte-smart-paste-btn:focus-visible { | ||
| border-color: #94a3b8; | ||
| background: #f8fafc; | ||
| outline: none; | ||
| } | ||
| .rte-smart-paste-btn-primary { | ||
| border-color: #0284c7; | ||
| background: #0ea5e9; | ||
| color: #f8fafc; | ||
| } | ||
| .rte-smart-paste-btn-primary:hover, | ||
| .rte-smart-paste-btn-primary:focus-visible { | ||
| border-color: #0369a1; | ||
| background: #0284c7; | ||
| color: #ffffff; | ||
| } | ||
| .${u}.rte-smart-paste-theme-dark .rte-smart-paste-btn { | ||
| border-color: #334155; | ||
| background: #111827; | ||
| color: #e2e8f0; | ||
| } | ||
| .${u}.rte-smart-paste-theme-dark .rte-smart-paste-btn:hover, | ||
| .${u}.rte-smart-paste-theme-dark .rte-smart-paste-btn:focus-visible { | ||
| border-color: #475569; | ||
| background: #1e293b; | ||
| } | ||
| .rte-smart-paste-profile { | ||
| display: grid; | ||
| gap: 6px; | ||
| } | ||
| .rte-smart-paste-profile-heading { | ||
| margin: 0; | ||
| font-size: 12px; | ||
| line-height: 1.35; | ||
| font-weight: 700; | ||
| color: #334155; | ||
| } | ||
| .${u}.rte-smart-paste-theme-dark .rte-smart-paste-profile-heading { | ||
| color: #cbd5e1; | ||
| } | ||
| .rte-smart-paste-profile-grid { | ||
| display: grid; | ||
| grid-template-columns: repeat(3, minmax(0, 1fr)); | ||
| gap: 8px; | ||
| } | ||
| .rte-smart-paste-chip { | ||
| height: 34px; | ||
| border-radius: 9px; | ||
| border: 1px solid #cbd5e1; | ||
| background: #ffffff; | ||
| color: inherit; | ||
| font-size: 12px; | ||
| font-weight: 600; | ||
| cursor: pointer; | ||
| } | ||
| .rte-smart-paste-chip:hover, | ||
| .rte-smart-paste-chip:focus-visible { | ||
| border-color: #0284c7; | ||
| outline: none; | ||
| } | ||
| .rte-smart-paste-chip.active { | ||
| border-color: #0284c7; | ||
| background: rgba(14, 165, 233, 0.14); | ||
| color: #0c4a6e; | ||
| } | ||
| .${u}.rte-smart-paste-theme-dark .rte-smart-paste-chip { | ||
| border-color: #334155; | ||
| background: #0b1220; | ||
| color: #e2e8f0; | ||
| } | ||
| .${u}.rte-smart-paste-theme-dark .rte-smart-paste-chip.active { | ||
| border-color: #38bdf8; | ||
| background: rgba(14, 165, 233, 0.2); | ||
| color: #e0f2fe; | ||
| } | ||
| .rte-smart-paste-metrics { | ||
| border: 1px solid #e2e8f0; | ||
| border-radius: 10px; | ||
| padding: 10px; | ||
| background: #f8fafc; | ||
| display: grid; | ||
| gap: 8px; | ||
| } | ||
| .${u}.rte-smart-paste-theme-dark .rte-smart-paste-metrics { | ||
| border-color: #334155; | ||
| background: #0b1220; | ||
| } | ||
| .rte-smart-paste-report-title { | ||
| margin: 0; | ||
| font-size: 12px; | ||
| line-height: 1.3; | ||
| font-weight: 700; | ||
| } | ||
| .rte-smart-paste-empty { | ||
| margin: 0; | ||
| font-size: 12px; | ||
| line-height: 1.35; | ||
| color: #475569; | ||
| } | ||
| .${u}.rte-smart-paste-theme-dark .rte-smart-paste-empty { | ||
| color: #94a3b8; | ||
| } | ||
| .rte-smart-paste-report { | ||
| margin: 0; | ||
| display: grid; | ||
| gap: 6px; | ||
| } | ||
| .rte-smart-paste-line { | ||
| display: flex; | ||
| justify-content: space-between; | ||
| gap: 10px; | ||
| font-size: 12px; | ||
| line-height: 1.3; | ||
| } | ||
| .rte-smart-paste-line dt { | ||
| margin: 0; | ||
| color: #475569; | ||
| font-weight: 600; | ||
| } | ||
| .rte-smart-paste-line dd { | ||
| margin: 0; | ||
| font-weight: 700; | ||
| } | ||
| .${u}.rte-smart-paste-theme-dark .rte-smart-paste-line dt { | ||
| color: #94a3b8; | ||
| } | ||
| .rte-smart-paste-shortcut { | ||
| margin: 2px 0 0; | ||
| font-size: 11px; | ||
| color: #64748b; | ||
| } | ||
| .${u}.rte-smart-paste-theme-dark .rte-smart-paste-shortcut { | ||
| color: #94a3b8; | ||
| } | ||
| .rte-smart-paste-live { | ||
| position: absolute; | ||
| width: 1px; | ||
| height: 1px; | ||
| margin: -1px; | ||
| padding: 0; | ||
| overflow: hidden; | ||
| clip: rect(0 0 0 0); | ||
| border: 0; | ||
| } | ||
| @media (max-width: 768px) { | ||
| .${u} { | ||
| left: 10px !important; | ||
| right: 10px; | ||
| top: 10px !important; | ||
| width: auto !important; | ||
| max-height: calc(100vh - 20px); | ||
| } | ||
| .rte-smart-paste-profile-grid { | ||
| grid-template-columns: 1fr; | ||
| } | ||
| } | ||
| `, document.head.appendChild(e); | ||
| } | ||
| const st = (e = {}) => { | ||
| const t = V(e), a = /* @__PURE__ */ new Set(); | ||
| return nt(), { | ||
| name: "smartPaste", | ||
| toolbar: [ | ||
| { | ||
| id: "smartPasteGroup", | ||
| label: "Smart Paste", | ||
| type: "group", | ||
| command: "smartPaste", | ||
| items: [ | ||
| { | ||
| id: "smartPaste", | ||
| label: "Smart Paste Panel", | ||
| command: "toggleSmartPastePanel", | ||
| shortcut: "Mod-Alt-Shift-s", | ||
| icon: '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><path d="M8.5 4.5h7l3 3V18a2.5 2.5 0 0 1-2.5 2.5h-7A2.5 2.5 0 0 1 6.5 18V7a2.5 2.5 0 0 1 2-2.45Z" stroke="currentColor" stroke-width="1.6" stroke-linejoin="round"/><path d="M15.5 4.5V8h3" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/><path d="M9.3 12h5.4M9.3 15h5.4" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/></svg>' | ||
| }, | ||
| { | ||
| id: "smartPasteProfile", | ||
| label: "Cycle Smart Paste Profile", | ||
| command: "cycleSmartPasteProfile", | ||
| shortcut: "Mod-Alt-Shift-v", | ||
| icon: '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><path d="M4.5 7.5h10" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/><circle cx="17.5" cy="7.5" r="2" stroke="currentColor" stroke-width="1.6"/><path d="M4.5 12h5" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/><circle cx="12.5" cy="12" r="2" stroke="currentColor" stroke-width="1.6"/><path d="M4.5 16.5h12" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/><circle cx="9.5" cy="16.5" r="2" stroke="currentColor" stroke-width="1.6"/></svg>' | ||
| }, | ||
| { | ||
| id: "smartPasteToggle", | ||
| label: "Toggle Smart Paste", | ||
| command: "toggleSmartPasteEnabled", | ||
| shortcut: "Mod-Alt-Shift-g", | ||
| icon: '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><rect x="3.5" y="8" width="17" height="8" rx="4" stroke="currentColor" stroke-width="1.6"/><circle cx="8" cy="12" r="2.6" fill="currentColor"/><path d="M14.5 12h3" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/></svg>' | ||
| } | ||
| ] | ||
| } | ||
| ], | ||
| commands: { | ||
| smartPaste: (r, n) => { | ||
| const o = T(n, !1, !1); | ||
| if (!o) return !1; | ||
| const s = d.get(o) || t; | ||
| return m(o, s), d.set(o, s), b = o, ye(o), !0; | ||
| }, | ||
| toggleSmartPastePanel: (r, n) => { | ||
| const o = T(n, !1, !1); | ||
| if (!o) return !1; | ||
| const s = d.get(o) || t; | ||
| return m(o, s), d.set(o, s), b = o, xe(o, typeof r == "boolean" ? r : void 0); | ||
| }, | ||
| cycleSmartPasteProfile: (r, n) => { | ||
| const o = T(n, !1, !1); | ||
| if (!o) return !1; | ||
| const s = d.get(o) || t, l = m(o, s); | ||
| return d.set(o, s), l.profile = ae(l.profile), S(o), !0; | ||
| }, | ||
| setSmartPasteProfile: (r, n) => { | ||
| const o = T(n, !1, !1); | ||
| if (!o) return !1; | ||
| const s = d.get(o) || t, l = m(o, s); | ||
| return d.set(o, s), l.profile = H(r), S(o), !0; | ||
| }, | ||
| toggleSmartPasteEnabled: (r, n) => { | ||
| const o = T(n, !1, !1); | ||
| if (!o) return !1; | ||
| const s = d.get(o) || t, l = m(o, s); | ||
| return d.set(o, s), l.enabled = typeof r == "boolean" ? r : !l.enabled, z(o), S(o), !0; | ||
| }, | ||
| setSmartPasteOptions: (r, n) => { | ||
| var f, p, y, g, P, C; | ||
| const o = T(n, !1, !1); | ||
| if (!o || !r || typeof r != "object") return !1; | ||
| const s = d.get(o) || t, l = ce(s), c = V({ | ||
| ...l, | ||
| ...r, | ||
| labels: { | ||
| ...s.labels, | ||
| ...r.labels || {} | ||
| }, | ||
| profileOptions: { | ||
| ...l.profileOptions, | ||
| ...r.profileOptions || {}, | ||
| fidelity: { | ||
| ...((f = l.profileOptions) == null ? void 0 : f.fidelity) || {}, | ||
| ...((p = r.profileOptions) == null ? void 0 : p.fidelity) || {} | ||
| }, | ||
| balanced: { | ||
| ...((y = l.profileOptions) == null ? void 0 : y.balanced) || {}, | ||
| ...((g = r.profileOptions) == null ? void 0 : g.balanced) || {} | ||
| }, | ||
| plain: { | ||
| ...((P = l.profileOptions) == null ? void 0 : P.plain) || {}, | ||
| ...((C = r.profileOptions) == null ? void 0 : C.plain) || {} | ||
| } | ||
| }, | ||
| normalizeText: r.normalizeText || s.normalizeText | ||
| }); | ||
| d.set(o, c); | ||
| const i = m(o, c); | ||
| return typeof r.enabled == "boolean" && (i.enabled = r.enabled), r.defaultProfile && (i.profile = H(r.defaultProfile)), S(o), z(o), !0; | ||
| }, | ||
| getSmartPasteState: (r, n) => { | ||
| const o = T(n, !1, !1); | ||
| if (!o) return !1; | ||
| const s = d.get(o) || t, l = m(o, s), c = ve(l); | ||
| if (typeof r == "function") | ||
| try { | ||
| r(c); | ||
| } catch (i) { | ||
| } | ||
| return o.__smartPasteState = c, o.dispatchEvent( | ||
| new CustomEvent("editora:smart-paste-state", { | ||
| bubbles: !0, | ||
| detail: c | ||
| }) | ||
| ), !0; | ||
| } | ||
| }, | ||
| keymap: { | ||
| "Mod-Alt-Shift-s": "toggleSmartPastePanel", | ||
| "Mod-Alt-Shift-S": "toggleSmartPastePanel", | ||
| "Mod-Alt-Shift-v": "cycleSmartPasteProfile", | ||
| "Mod-Alt-Shift-V": "cycleSmartPasteProfile", | ||
| "Mod-Alt-Shift-g": "toggleSmartPasteEnabled", | ||
| "Mod-Alt-Shift-G": "toggleSmartPasteEnabled" | ||
| }, | ||
| init: function(n) { | ||
| W += 1; | ||
| const o = this && typeof this.__pluginConfig == "object" ? V({ ...ce(t), ...this.__pluginConfig }) : t; | ||
| at(o); | ||
| const s = T( | ||
| n != null && n.editorElement ? { editorElement: n.editorElement } : void 0, | ||
| !1, | ||
| !1 | ||
| ); | ||
| if (!s) return; | ||
| b = s, a.add(s); | ||
| const l = m(s, o); | ||
| l.enabled = o.enabled, l.profile = o.defaultProfile, d.set(s, o), z(s); | ||
| }, | ||
| destroy: () => { | ||
| a.forEach((r) => be(r)), a.clear(), W = Math.max(0, W - 1), !(W > 0) && ot(); | ||
| } | ||
| }; | ||
| }; | ||
| export { | ||
| st as SmartPastePlugin | ||
| }; | ||
| //# sourceMappingURL=SmartPastePlugin.native-BOKKtF07.mjs.map |
| const p = ".rte-content, .editora-content", g = '.rte-track-insert[data-track-change="insert"]', f = '.rte-track-delete[data-track-change="delete"]', w = `${g}, ${f}`, _ = "__editoraCommandEditorRoot", B = /* @__PURE__ */ new WeakMap(), N = /* @__PURE__ */ new WeakMap(), L = /* @__PURE__ */ new WeakMap(), D = /* @__PURE__ */ new Set(); | ||
| let q = !1, h = null, F = !1, T = {}, j = !1; | ||
| const J = typeof InputEvent != "undefined" && typeof InputEvent.prototype == "object" && "inputType" in InputEvent.prototype, Q = /* @__PURE__ */ new Set([ | ||
| "IMG", | ||
| "TABLE", | ||
| "VIDEO", | ||
| "AUDIO", | ||
| "SVG", | ||
| "MATH", | ||
| "HR", | ||
| "IFRAME", | ||
| "INPUT", | ||
| "TEXTAREA", | ||
| "SELECT", | ||
| "BUTTON", | ||
| "CANVAS" | ||
| ]); | ||
| function ee(e) { | ||
| if (!e) return null; | ||
| const t = e.querySelector('[contenteditable="true"]'); | ||
| return t instanceof HTMLElement ? t : null; | ||
| } | ||
| function te() { | ||
| if (typeof window == "undefined") return null; | ||
| const e = window[_]; | ||
| if (!(e instanceof HTMLElement)) return null; | ||
| window[_] = null; | ||
| const t = e.closest("[data-editora-editor], .rte-editor, .editora-editor, editora-editor") || (e.matches("[data-editora-editor], .rte-editor, .editora-editor, editora-editor") ? e : null); | ||
| if (t) { | ||
| const r = ee(t); | ||
| if (r) return r; | ||
| if (t.getAttribute("contenteditable") === "true") return t; | ||
| } | ||
| if (e.getAttribute("contenteditable") === "true") | ||
| return e; | ||
| const n = e.closest('[contenteditable="true"]'); | ||
| return n instanceof HTMLElement ? n : null; | ||
| } | ||
| function ne(e) { | ||
| if ((e == null ? void 0 : e.contentElement) instanceof HTMLElement) return e.contentElement; | ||
| if ((e == null ? void 0 : e.editorElement) instanceof HTMLElement) { | ||
| const o = e.editorElement; | ||
| if (o.getAttribute("contenteditable") === "true") return o; | ||
| const a = o.querySelector('[contenteditable="true"]'); | ||
| if (a instanceof HTMLElement) return a; | ||
| } | ||
| const t = te(); | ||
| if (t && document.contains(t)) return t; | ||
| const n = window.getSelection(); | ||
| if (n && n.rangeCount > 0) { | ||
| const o = n.getRangeAt(0).startContainer, a = o.nodeType === Node.ELEMENT_NODE ? o : o.parentElement, c = a == null ? void 0 : a.closest(p); | ||
| if (c) return c; | ||
| } | ||
| const r = document.activeElement; | ||
| if (r) { | ||
| if (r.matches(p)) return r; | ||
| const o = r.closest(p); | ||
| if (o) return o; | ||
| } | ||
| return h != null && h.isConnected ? h : document.querySelector(p); | ||
| } | ||
| function R(e, t) { | ||
| var r; | ||
| k(e), H(e); | ||
| let n = B.get(e); | ||
| return n || (n = { | ||
| enabled: !!t.enabledByDefault, | ||
| author: ((r = t.author) == null ? void 0 : r.trim()) || "system", | ||
| includeTimestamp: t.includeTimestamp !== !1 | ||
| }, B.set(e, n), n.enabled && (M(e, n), y(e, n.enabled))), S(e, "toggleTrackChanges", n.enabled), n; | ||
| } | ||
| function y(e, t) { | ||
| e.classList.toggle("rte-track-changes-enabled", t), t ? e.setAttribute("data-track-changes", "true") : e.removeAttribute("data-track-changes"); | ||
| } | ||
| function re(e) { | ||
| return e.closest("[data-editora-editor], .rte-editor, .editora-editor, editora-editor") || e; | ||
| } | ||
| function S(e, t, n) { | ||
| const r = re(e); | ||
| Array.from( | ||
| r.querySelectorAll( | ||
| `.rte-toolbar-button[data-command="${t}"], .editora-toolbar-button[data-command="${t}"]` | ||
| ) | ||
| ).forEach((a) => { | ||
| a.classList.toggle("active", n), a.setAttribute("data-active", n ? "true" : "false"), a.setAttribute("aria-pressed", n ? "true" : "false"), a.setAttribute("title", n ? "Track Changes (On)" : "Track Changes (Off)"); | ||
| }); | ||
| } | ||
| function ae(e) { | ||
| e.dispatchEvent(new Event("input", { bubbles: !0 })); | ||
| } | ||
| function oe(e, t) { | ||
| if (t === e.innerHTML) return; | ||
| const n = window.execEditorCommand || window.executeEditorCommand; | ||
| if (typeof n == "function") | ||
| try { | ||
| n("recordDomTransaction", e, t, e.innerHTML); | ||
| } catch (r) { | ||
| } | ||
| } | ||
| function m(e, t) { | ||
| ae(e), oe(e, t); | ||
| } | ||
| function ce(e, t) { | ||
| return e.startContainer === t.startContainer && e.startOffset === t.startOffset && e.endContainer === t.endContainer && e.endOffset === t.endOffset; | ||
| } | ||
| function G(e) { | ||
| return { | ||
| author: e.author, | ||
| timestamp: e.includeTimestamp ? (/* @__PURE__ */ new Date()).toISOString() : "" | ||
| }; | ||
| } | ||
| function se(e, t) { | ||
| const n = document.createElement("span"); | ||
| n.className = "rte-track-insert", n.setAttribute("data-track-change", "insert"), n.setAttribute("contenteditable", "false"); | ||
| const r = G(t); | ||
| return n.setAttribute("data-track-author", r.author), r.timestamp && n.setAttribute("data-track-time", r.timestamp), n.appendChild(document.createTextNode(e)), n; | ||
| } | ||
| function k(e) { | ||
| Array.from(e.querySelectorAll(g)).forEach((n) => { | ||
| n.setAttribute("contenteditable", "false"); | ||
| }); | ||
| } | ||
| function E(e) { | ||
| return e ? e.nodeType === Node.ELEMENT_NODE ? e : e.parentElement : null; | ||
| } | ||
| function le(e, t) { | ||
| const n = e.startContainer, r = e.startOffset; | ||
| if (n.nodeType === Node.TEXT_NODE) { | ||
| const o = n, a = o.previousSibling || o.nextSibling; | ||
| if (a instanceof HTMLElement && a.matches(g) && t.contains(a)) | ||
| return a; | ||
| } | ||
| if (n.nodeType === Node.ELEMENT_NODE) { | ||
| const o = n, a = o.childNodes[r - 1]; | ||
| if (a instanceof HTMLElement && a.matches(g) && t.contains(a)) | ||
| return a; | ||
| const c = o.childNodes[r]; | ||
| if (c instanceof HTMLElement && c.matches(g) && t.contains(c)) | ||
| return c; | ||
| } | ||
| return null; | ||
| } | ||
| function P(e, t, n) { | ||
| const r = t.lastChild; | ||
| r && r.nodeType === Node.TEXT_NODE ? r.data += n : t.appendChild(document.createTextNode(n)), C(e, t); | ||
| } | ||
| function ie(e, t) { | ||
| const n = document.createElement("span"); | ||
| n.className = "rte-track-delete", n.setAttribute("data-track-change", "delete"), n.setAttribute("contenteditable", "false"); | ||
| const r = G(t); | ||
| return n.setAttribute("data-track-author", r.author), r.timestamp && n.setAttribute("data-track-time", r.timestamp), n.appendChild(e), n; | ||
| } | ||
| function b(e) { | ||
| const t = window.getSelection(); | ||
| if (!t || t.rangeCount === 0) return null; | ||
| const n = t.getRangeAt(0); | ||
| return e.contains(n.commonAncestorContainer) ? n : null; | ||
| } | ||
| function ue() { | ||
| j || typeof document == "undefined" || (j = !0, document.addEventListener( | ||
| "selectionchange", | ||
| () => { | ||
| const e = window.getSelection(); | ||
| if (!e || e.rangeCount === 0) return; | ||
| const t = e.getRangeAt(0), n = E(t.startContainer), r = (n == null ? void 0 : n.closest(p)) || null; | ||
| r && (L.set(r, t.cloneRange()), h = r); | ||
| }, | ||
| !0 | ||
| )); | ||
| } | ||
| function C(e, t) { | ||
| if (!t.parentNode) { | ||
| e.focus({ preventScroll: !0 }); | ||
| return; | ||
| } | ||
| const n = window.getSelection(); | ||
| if (!n) return; | ||
| const r = document.createRange(); | ||
| r.setStartAfter(t), r.collapse(!0), n.removeAllRanges(), n.addRange(r), e.focus({ preventScroll: !0 }); | ||
| } | ||
| function O(e, t) { | ||
| if (!t.parentNode) { | ||
| e.focus({ preventScroll: !0 }); | ||
| return; | ||
| } | ||
| const n = window.getSelection(); | ||
| if (!n) return; | ||
| const r = document.createRange(); | ||
| r.setStartBefore(t), r.collapse(!0), n.removeAllRanges(), n.addRange(r), e.focus({ preventScroll: !0 }); | ||
| } | ||
| function de(e, t, n) { | ||
| const r = window.getSelection(); | ||
| if (!r) return; | ||
| const o = document.createRange(); | ||
| o.setStart(t, Math.max(0, n)), o.collapse(!0), r.removeAllRanges(), r.addRange(o), e.focus({ preventScroll: !0 }); | ||
| } | ||
| function V(e) { | ||
| let t = b(e); | ||
| if (!t) { | ||
| const c = L.get(e); | ||
| c && e.contains(c.commonAncestorContainer) && (t = c.cloneRange()); | ||
| } | ||
| if (!t || !t.collapsed) return; | ||
| const n = E(t.startContainer); | ||
| if (!n) return; | ||
| const r = n.closest(g); | ||
| if (!r || !e.contains(r) || !r.parentNode) return; | ||
| const o = window.getSelection(); | ||
| if (!o) return; | ||
| const a = document.createRange(); | ||
| a.setStartAfter(r), a.collapse(!0), o.removeAllRanges(), o.addRange(a), e.focus({ preventScroll: !0 }); | ||
| } | ||
| function K(e, t) { | ||
| const n = e.innerHTML; | ||
| k(e), V(e), e.focus({ preventScroll: !0 }); | ||
| const r = t === "insertLineBreak" ? "insertLineBreak" : "insertParagraph", o = document.execCommand(r, !1); | ||
| return k(e), m(e, n), o !== !1; | ||
| } | ||
| function fe(e) { | ||
| const t = b(e); | ||
| if (t && t.collapsed) return t; | ||
| const n = L.get(e); | ||
| return n && n.collapsed && e.contains(n.commonAncestorContainer) ? n.cloneRange() : null; | ||
| } | ||
| function ge(e) { | ||
| return e.matches(g) || e.matches(f) ? (e.textContent || "").replace(/\u200B/g, "").trim().length > 0 : Q.has(e.tagName); | ||
| } | ||
| function W(e, t) { | ||
| if (t !== "insertParagraph") return !1; | ||
| const n = fe(e); | ||
| if (!n) return !1; | ||
| const r = E(n.startContainer); | ||
| if (!r) return !1; | ||
| const o = r.closest("li"); | ||
| return !(o instanceof HTMLElement) || !e.contains(o) || (o.textContent || "").replace(/\u200B/g, "").trim().length > 0 ? !1 : !Array.from(o.querySelectorAll("*")).some( | ||
| (s) => ge(s) | ||
| ); | ||
| } | ||
| function he(e) { | ||
| const t = document.createRange(), n = window.getSelection(); | ||
| if (n && n.rangeCount > 0) { | ||
| const r = n.getRangeAt(0); | ||
| if (e.contains(r.commonAncestorContainer)) | ||
| return t.setStart(r.endContainer, r.endOffset), t.collapse(!0), t; | ||
| } | ||
| return t.selectNodeContents(e), t.collapse(!1), t; | ||
| } | ||
| function me(e) { | ||
| return (e.textContent || "").length > 0 ? !0 : Array.from(e.childNodes).some((n) => { | ||
| if (n.nodeType !== Node.ELEMENT_NODE) return !1; | ||
| const r = n; | ||
| return ["BR", "IMG", "TABLE", "VIDEO", "AUDIO", "SVG", "MATH"].includes(r.tagName); | ||
| }); | ||
| } | ||
| function pe(e) { | ||
| return Array.from(e.childNodes).some((t) => { | ||
| if (t.nodeType === Node.TEXT_NODE) | ||
| return (t.textContent || "").length > 0; | ||
| if (t.nodeType !== Node.ELEMENT_NODE) return !1; | ||
| const n = t; | ||
| return ["BR", "IMG", "TABLE", "VIDEO", "AUDIO", "SVG", "MATH"].includes(n.tagName); | ||
| }); | ||
| } | ||
| function Ee(e, t, n) { | ||
| if (!e.collapsed) return null; | ||
| const r = e.startContainer, o = e.startOffset; | ||
| let a = null; | ||
| if (r.nodeType === Node.TEXT_NODE) { | ||
| const c = r; | ||
| t === "backward" && o === 0 ? a = c.previousSibling : t === "forward" && o === c.length && (a = c.nextSibling); | ||
| } else if (r.nodeType === Node.ELEMENT_NODE) { | ||
| const c = r; | ||
| t === "backward" && o > 0 ? a = c.childNodes[o - 1] || null : t === "forward" && o < c.childNodes.length && (a = c.childNodes[o] || null); | ||
| } | ||
| return !(a instanceof HTMLElement) || !a.matches(g) || !n.contains(a) ? null : a; | ||
| } | ||
| function ke(e, t) { | ||
| const n = document.createTreeWalker(e, NodeFilter.SHOW_TEXT), r = []; | ||
| let o = n.nextNode(); | ||
| for (; o; ) { | ||
| const a = o; | ||
| a.data.length > 0 && r.push(a), o = n.nextNode(); | ||
| } | ||
| return r.length === 0 ? null : t ? r[r.length - 1] : r[0]; | ||
| } | ||
| function Te(e, t, n) { | ||
| const r = Ee(t, n, e); | ||
| return r ? x(e, r, n) : !1; | ||
| } | ||
| function x(e, t, n) { | ||
| const r = t.parentNode; | ||
| if (!r) return !1; | ||
| const o = Array.prototype.indexOf.call(r.childNodes, t), a = ke(t, n === "backward"); | ||
| return a ? (n === "backward" ? a.data = a.data.slice(0, -1) : a.data = a.data.slice(1), a.data.length === 0 && a.remove(), pe(t) ? (n === "backward" ? C(e, t) : O(e, t), !0) : (t.remove(), de(e, r, o), !0)) : !1; | ||
| } | ||
| function Z(e) { | ||
| if (e.startContainer !== e.endContainer || e.startContainer.nodeType !== Node.ELEMENT_NODE) return null; | ||
| const t = e.startContainer; | ||
| return e.endOffset - e.startOffset !== 1 ? null : t.childNodes[e.startOffset] || null; | ||
| } | ||
| function I(e, t) { | ||
| const n = Z(e); | ||
| return !(n instanceof HTMLElement) || !n.matches(f) || !t.contains(n) ? null : n; | ||
| } | ||
| function be(e, t) { | ||
| const n = Z(e); | ||
| return !(n instanceof HTMLElement) || !n.matches(g) || !t.contains(n) ? null : n; | ||
| } | ||
| function Ce(e, t) { | ||
| var a, c; | ||
| if (t.collapsed) { | ||
| const s = E(t.startContainer), l = s == null ? void 0 : s.closest(f); | ||
| if (l && e.contains(l)) { | ||
| const i = document.createRange(); | ||
| return i.setStartAfter(l), i.collapse(!0), i; | ||
| } | ||
| return t; | ||
| } | ||
| const n = I(t, e); | ||
| if (n) { | ||
| const s = document.createRange(); | ||
| return s.setStartAfter(n), s.collapse(!0), s; | ||
| } | ||
| const r = (a = E(t.startContainer)) == null ? void 0 : a.closest(f), o = (c = E(t.endContainer)) == null ? void 0 : c.closest(f); | ||
| if (r && o && r === o && e.contains(r)) { | ||
| const s = document.createRange(); | ||
| return s.setStartAfter(r), s.collapse(!0), s; | ||
| } | ||
| return t; | ||
| } | ||
| function Ae(e, t) { | ||
| const r = Array.from(t.querySelectorAll(g)).filter((s) => { | ||
| try { | ||
| return e.intersectsNode(s); | ||
| } catch (l) { | ||
| return !1; | ||
| } | ||
| }); | ||
| if (r.length !== 1) return null; | ||
| const o = r[0], a = (e.toString() || "").replace(/\s+/g, ""), c = (o.textContent || "").replace(/\s+/g, ""); | ||
| return !c || a !== c ? null : o; | ||
| } | ||
| function U(e, t, n) { | ||
| if (t.collapsed) return null; | ||
| const r = t.cloneContents(); | ||
| if (!me(r)) return null; | ||
| const o = ie(r, n); | ||
| return t.deleteContents(), t.insertNode(o), C(e, o), o; | ||
| } | ||
| function Ne(e, t, n) { | ||
| if (!t.collapsed) return t; | ||
| const r = t.startContainer, o = t.startOffset; | ||
| if (r.nodeType === Node.TEXT_NODE) { | ||
| const s = r; | ||
| if (n === "backward" && o > 0) { | ||
| const l = t.cloneRange(); | ||
| return l.setStart(s, o - 1), l; | ||
| } | ||
| if (n === "forward" && o < s.length) { | ||
| const l = t.cloneRange(); | ||
| return l.setEnd(s, o + 1), l; | ||
| } | ||
| } | ||
| if (r.nodeType === Node.ELEMENT_NODE) { | ||
| const s = r; | ||
| if (n === "backward" && o > 0) | ||
| for (let l = o - 1; l >= 0; l -= 1) { | ||
| const i = s.childNodes[l]; | ||
| if (!i || i instanceof HTMLElement && i.matches(f)) | ||
| continue; | ||
| const u = t.cloneRange(); | ||
| if (i.nodeType === Node.TEXT_NODE) { | ||
| const d = i; | ||
| if (d.length === 0) continue; | ||
| u.setStart(d, d.length - 1), u.setEnd(d, d.length); | ||
| } else | ||
| u.setStartBefore(i), u.setEndAfter(i); | ||
| return u; | ||
| } | ||
| if (n === "forward" && o < s.childNodes.length) | ||
| for (let l = o; l < s.childNodes.length; l += 1) { | ||
| const i = s.childNodes[l]; | ||
| if (!i || i instanceof HTMLElement && i.matches(f)) | ||
| continue; | ||
| const u = t.cloneRange(); | ||
| if (i.nodeType === Node.TEXT_NODE) { | ||
| const d = i; | ||
| if (d.length === 0) continue; | ||
| u.setStart(d, 0), u.setEnd(d, 1); | ||
| } else | ||
| u.setStartBefore(i), u.setEndAfter(i); | ||
| return u; | ||
| } | ||
| } | ||
| const a = window.getSelection(); | ||
| if (!a || typeof a.modify != "function") | ||
| return null; | ||
| const c = t.cloneRange(); | ||
| a.removeAllRanges(), a.addRange(c); | ||
| try { | ||
| if (a.modify("extend", n, "character"), a.rangeCount === 0) | ||
| return null; | ||
| const s = a.getRangeAt(0).cloneRange(); | ||
| if (s.collapsed || !e.contains(s.commonAncestorContainer)) | ||
| return null; | ||
| const l = I(s, e); | ||
| return l ? (n === "backward" ? O(e, l) : C(e, l), null) : s; | ||
| } catch (s) { | ||
| return null; | ||
| } finally { | ||
| a.removeAllRanges(), a.addRange(c); | ||
| } | ||
| } | ||
| function z(e, t, n) { | ||
| let r = b(e); | ||
| if (!r) return !1; | ||
| const o = Ce(e, r.cloneRange()); | ||
| if (!ce(o, r)) { | ||
| const d = window.getSelection(); | ||
| d && (d.removeAllRanges(), d.addRange(o)), r = o; | ||
| } | ||
| const a = e.innerHTML; | ||
| r.collapsed || U(e, r.cloneRange(), t); | ||
| const c = E(r.startContainer), s = c == null ? void 0 : c.closest(g); | ||
| if (r.collapsed && s && e.contains(s)) | ||
| return P(e, s, n), m(e, a), !0; | ||
| const l = r.collapsed ? le(r, e) : null; | ||
| if (l) | ||
| return P(e, l, n), m(e, a), !0; | ||
| const i = he(e), u = se(n, t); | ||
| return i.insertNode(u), C(e, u), m(e, a), !0; | ||
| } | ||
| function $(e, t, n) { | ||
| const r = b(e); | ||
| if (!r) return !1; | ||
| const o = n.includes("Backward") ? "backward" : "forward", a = e.innerHTML; | ||
| if (r.collapsed && Te(e, r.cloneRange(), o)) | ||
| return m(e, a), !0; | ||
| const c = be(r, e); | ||
| if (c && x(e, c, o)) | ||
| return m(e, a), !0; | ||
| if (!r.collapsed) { | ||
| const u = Ae(r, e); | ||
| if (u && x(e, u, o)) | ||
| return m(e, a), !0; | ||
| } | ||
| const s = r.collapsed ? Ne(e, r.cloneRange(), o) : r.cloneRange(); | ||
| if (!s) return !1; | ||
| const l = I(s, e); | ||
| return l ? (o === "backward" ? O(e, l) : C(e, l), !0) : U(e, s, t) ? (H(e), m(e, a), !0) : !1; | ||
| } | ||
| function v(e) { | ||
| const t = e.parentNode; | ||
| if (t) { | ||
| for (; e.firstChild; ) | ||
| t.insertBefore(e.firstChild, e); | ||
| t.removeChild(e); | ||
| } | ||
| } | ||
| function H(e) { | ||
| Array.from(e.querySelectorAll(f)).forEach((r) => { | ||
| r.setAttribute("contenteditable", "false"), Array.from(r.querySelectorAll(f)).forEach((a) => { | ||
| a !== r && v(a); | ||
| }); | ||
| }); | ||
| let n = !0; | ||
| for (; n; ) | ||
| n = !1, Array.from(e.querySelectorAll(f)).forEach((o) => { | ||
| if (!o.isConnected) return; | ||
| let a = o.nextSibling; | ||
| for (; a && a.nodeType === Node.TEXT_NODE && !(a.textContent || "").trim(); ) | ||
| a = a.nextSibling; | ||
| if (a instanceof HTMLElement && a.matches(f)) { | ||
| for (; a.firstChild; ) | ||
| o.appendChild(a.firstChild); | ||
| a.remove(), n = !0; | ||
| } | ||
| o.firstChild || (o.remove(), n = !0); | ||
| }); | ||
| } | ||
| function Y(e) { | ||
| return Array.from(e.querySelectorAll(w)); | ||
| } | ||
| function ye(e) { | ||
| const t = b(e); | ||
| if (!t) return []; | ||
| const n = /* @__PURE__ */ new Set(), r = t.startContainer.nodeType === Node.ELEMENT_NODE ? t.startContainer : t.startContainer.parentElement, o = t.endContainer.nodeType === Node.ELEMENT_NODE ? t.endContainer : t.endContainer.parentElement, a = r == null ? void 0 : r.closest(w); | ||
| a && e.contains(a) && n.add(a); | ||
| const c = o == null ? void 0 : o.closest(w); | ||
| return c && e.contains(c) && n.add(c), Y(e).filter((l) => { | ||
| try { | ||
| return t.intersectsNode(l); | ||
| } catch (i) { | ||
| return !1; | ||
| } | ||
| }).forEach((l) => n.add(l)), Array.from(n); | ||
| } | ||
| function A(e, t, n) { | ||
| const r = n === "all" ? Y(e) : ye(e); | ||
| if (r.length === 0) return !1; | ||
| const o = e.innerHTML; | ||
| return r.forEach((a) => { | ||
| if (!a.isConnected) return; | ||
| const c = a.matches(g), s = a.matches(f); | ||
| if (!(!c && !s)) { | ||
| if (t === "accept") { | ||
| c ? v(a) : a.remove(); | ||
| return; | ||
| } | ||
| c ? a.remove() : (a.removeAttribute("contenteditable"), v(a)); | ||
| } | ||
| }), H(e), m(e, o), !0; | ||
| } | ||
| function Se(e) { | ||
| if (!(e instanceof Node)) return null; | ||
| const t = e.nodeType === Node.ELEMENT_NODE ? e : e.parentElement; | ||
| return (t == null ? void 0 : t.closest(p)) || null; | ||
| } | ||
| function Me() { | ||
| F || typeof document == "undefined" || (F = !0, document.addEventListener( | ||
| "focusin", | ||
| (e) => { | ||
| if (!T.enabledByDefault) return; | ||
| const t = Se(e.target); | ||
| if (!t) return; | ||
| h = t; | ||
| const n = R(t, T); | ||
| n.enabled ? (M(t, n), y(t, !0), S(t, "toggleTrackChanges", !0)) : k(t); | ||
| }, | ||
| !0 | ||
| )); | ||
| } | ||
| function we(e, t) { | ||
| return (n) => { | ||
| if (!t.enabled || e.getAttribute("data-track-changes") !== "true") return; | ||
| h = e; | ||
| const r = n.inputType || ""; | ||
| if (r === "insertParagraph" || r === "insertLineBreak") { | ||
| if (W(e, r)) | ||
| return; | ||
| n.preventDefault(), K(e, r); | ||
| return; | ||
| } | ||
| if (r.startsWith("delete")) { | ||
| n.preventDefault(), $(e, t, r); | ||
| return; | ||
| } | ||
| if (r === "insertText" || r === "insertCompositionText") { | ||
| const o = n.data || ""; | ||
| if (!o) return; | ||
| n.preventDefault(), z(e, t, o); | ||
| } | ||
| }; | ||
| } | ||
| function Re(e, t) { | ||
| return (n) => { | ||
| if (!t.enabled || e.getAttribute("data-track-changes") !== "true" || n.key !== "Enter" || J) return; | ||
| const r = n.shiftKey ? "insertLineBreak" : "insertParagraph"; | ||
| W(e, r) || (h = e, n.preventDefault(), n.stopPropagation(), K(e, r)); | ||
| }; | ||
| } | ||
| function xe(e, t) { | ||
| return (n) => { | ||
| var o; | ||
| if (n.__editoraSmartPasteHandled === !0 || n.defaultPrevented || !t.enabled || e.getAttribute("data-track-changes") !== "true") return; | ||
| const r = ((o = n.clipboardData) == null ? void 0 : o.getData("text/plain")) || ""; | ||
| r && (n.preventDefault(), h = e, z(e, t, r)); | ||
| }; | ||
| } | ||
| function ve(e, t) { | ||
| return (n) => { | ||
| if (!t.enabled || e.getAttribute("data-track-changes") !== "true") return; | ||
| const r = b(e); | ||
| if (!r || r.collapsed) return; | ||
| const o = r.toString(); | ||
| n.clipboardData && (n.clipboardData.setData("text/plain", o), n.preventDefault()), h = e, $(e, t, "deleteByCut"); | ||
| }; | ||
| } | ||
| function M(e, t) { | ||
| if (N.has(e)) return; | ||
| k(e); | ||
| const n = { | ||
| beforeInput: we(e, t), | ||
| keydown: Re(e, t), | ||
| paste: xe(e, t), | ||
| cut: ve(e, t) | ||
| }; | ||
| e.addEventListener("beforeinput", n.beforeInput), e.addEventListener("keydown", n.keydown), e.addEventListener("paste", n.paste), e.addEventListener("cut", n.cut), N.set(e, n), D.add(e); | ||
| } | ||
| function X(e) { | ||
| const t = N.get(e); | ||
| t && (e.removeEventListener("beforeinput", t.beforeInput), e.removeEventListener("keydown", t.keydown), e.removeEventListener("paste", t.paste), e.removeEventListener("cut", t.cut), N.delete(e), D.delete(e)); | ||
| } | ||
| function Le() { | ||
| if (q || typeof document == "undefined") return; | ||
| q = !0; | ||
| const e = document.createElement("style"); | ||
| e.id = "rte-track-changes-styles", e.textContent = ` | ||
| .rte-track-insert[data-track-change="insert"] { | ||
| background: rgba(22, 163, 74, 0.2); | ||
| color: inherit; | ||
| text-decoration: underline; | ||
| text-decoration-color: #16a34a; | ||
| text-decoration-thickness: 2px; | ||
| border-radius: 2px; | ||
| padding: 0 1px; | ||
| white-space: pre-wrap; | ||
| } | ||
| .rte-track-delete[data-track-change="delete"] { | ||
| background: rgba(220, 38, 38, 0.16); | ||
| color: inherit; | ||
| text-decoration: line-through; | ||
| text-decoration-color: #dc2626; | ||
| text-decoration-thickness: 2px; | ||
| border-radius: 2px; | ||
| padding: 0 1px; | ||
| white-space: pre-wrap; | ||
| cursor: pointer; | ||
| } | ||
| .editora-theme-dark .rte-track-insert[data-track-change="insert"], | ||
| .rte-theme-dark .rte-track-insert[data-track-change="insert"] { | ||
| background: rgba(74, 222, 128, 0.2); | ||
| text-decoration-color: #4ade80; | ||
| } | ||
| .editora-theme-dark .rte-track-delete[data-track-change="delete"], | ||
| .rte-theme-dark .rte-track-delete[data-track-change="delete"] { | ||
| background: rgba(248, 113, 113, 0.18); | ||
| text-decoration-color: #f87171; | ||
| } | ||
| .rte-content[data-track-changes="true"], | ||
| .editora-content[data-track-changes="true"] { | ||
| caret-color: currentColor; | ||
| } | ||
| .rte-toolbar-group-items.track-changes, | ||
| .editora-toolbar-group-items.track-changes { | ||
| display: flex; | ||
| border: 1px solid #ccc; | ||
| border-radius: 3px; | ||
| background: #fff; | ||
| } | ||
| .rte-toolbar-group-items.track-changes .rte-toolbar-button, | ||
| .editora-toolbar-group-items.track-changes .editora-toolbar-button { | ||
| border: none; | ||
| border-radius: 0px; | ||
| } | ||
| .rte-toolbar-group-items.track-changes .rte-toolbar-button, | ||
| .editora-toolbar-group-items.track-changes .editora-toolbar-button { | ||
| border-right: 1px solid #ccc; | ||
| } | ||
| .rte-toolbar-group-items.track-changes .rte-toolbar-item:last-child .rte-toolbar-button, | ||
| .editora-toolbar-group-items.track-changes .editora-toolbar-item:last-child .editora-toolbar-button { | ||
| border-right: none; | ||
| } | ||
| :is([data-theme="dark"], .dark, .editora-theme-dark, .rte-theme-dark) .rte-toolbar-group-items.track-changes, | ||
| :is([data-theme="dark"], .dark, .editora-theme-dark, .rte-theme-dark) .editora-toolbar-group-items.track-changes { | ||
| border-color: #566275; | ||
| } | ||
| :is([data-theme="dark"], .dark, .editora-theme-dark, .rte-theme-dark) .rte-toolbar-group-items.track-changes .rte-toolbar-button, | ||
| :is([data-theme="dark"], .dark, .editora-theme-dark, .rte-theme-dark) .editora-toolbar-group-items.track-changes .editora-toolbar-button { | ||
| border-right-color: #566275; | ||
| } | ||
| .rte-toolbar-button[data-command="toggleTrackChanges"].active, | ||
| .editora-toolbar-button[data-command="toggleTrackChanges"].active { | ||
| background-color: #ccc; | ||
| } | ||
| `, document.head.appendChild(e); | ||
| } | ||
| const De = (e = {}) => { | ||
| Le(), ue(), T = { ...T, ...e }, Me(), T.enabledByDefault && typeof document != "undefined" && (typeof requestAnimationFrame == "function" ? requestAnimationFrame : (o) => window.setTimeout(o, 0))(() => { | ||
| Array.from(document.querySelectorAll(p)).forEach((a) => { | ||
| const c = R(a, T); | ||
| c.enabled ? (M(a, c), y(a, !0), S(a, "toggleTrackChanges", !0)) : k(a); | ||
| }); | ||
| }); | ||
| const t = (r) => { | ||
| const o = ne(r); | ||
| return o ? (h = o, o) : null; | ||
| }, n = (r) => { | ||
| const o = t(r); | ||
| if (!o) return null; | ||
| const a = R(o, e); | ||
| return { editor: o, state: a }; | ||
| }; | ||
| return { | ||
| name: "trackChanges", | ||
| toolbar: [ | ||
| { | ||
| label: "Track Changes", | ||
| command: "toggleTrackChanges", | ||
| type: "group", | ||
| items: [ | ||
| { | ||
| label: "Track Changes", | ||
| command: "toggleTrackChanges", | ||
| icon: '<svg width="24" height="24" focusable="false"><path d="M4 6h10a1 1 0 1 1 0 2H4a1 1 0 1 1 0-2Zm0 5h7a1 1 0 1 1 0 2H4a1 1 0 1 1 0-2Zm0 5h8a1 1 0 1 1 0 2H4a1 1 0 1 1 0-2Zm13.3-3.6 1.3 1.3 2.9-2.9a1 1 0 1 1 1.4 1.4l-3.6 3.6a1 1 0 0 1-1.4 0l-2-2a1 1 0 1 1 1.4-1.4Z"></path></svg>', | ||
| shortcut: "Mod-Shift-t" | ||
| }, | ||
| { | ||
| label: "Accept All Changes", | ||
| command: "acceptAllTrackChanges", | ||
| icon: '<svg width="24" height="24" focusable="false"><path d="M9.2 16.2 5.8 12.8a1 1 0 1 1 1.4-1.4l2.1 2.1 7.5-7.5a1 1 0 1 1 1.4 1.4l-8.2 8.2a1 1 0 0 1-1.4 0Z"></path></svg>' | ||
| }, | ||
| { | ||
| label: "Reject All Changes", | ||
| command: "rejectAllTrackChanges", | ||
| icon: '<svg width="24" height="24" focusable="false"><path d="M7.8 7.8a1 1 0 0 1 1.4 0L12 10.6l2.8-2.8a1 1 0 1 1 1.4 1.4L13.4 12l2.8 2.8a1 1 0 1 1-1.4 1.4L12 13.4l-2.8 2.8a1 1 0 1 1-1.4-1.4l2.8-2.8-2.8-2.8a1 1 0 0 1 0-1.4Z"></path></svg>' | ||
| } | ||
| ] | ||
| } | ||
| ], | ||
| commands: { | ||
| toggleTrackChanges: (r, o) => { | ||
| const a = n(o); | ||
| if (!a) return !1; | ||
| const { editor: c, state: s } = a; | ||
| return s.enabled = !s.enabled, s.enabled ? M(c, s) : (X(c), k(c), V(c)), y(c, s.enabled), S(c, "toggleTrackChanges", s.enabled), c.dispatchEvent(new CustomEvent("editora:track-changes-toggle", { | ||
| bubbles: !0, | ||
| detail: { | ||
| enabled: s.enabled, | ||
| author: s.author | ||
| } | ||
| })), s.enabled; | ||
| }, | ||
| acceptAllTrackChanges: (r, o) => { | ||
| const a = n(o); | ||
| return a ? A(a.editor, "accept", "all") : !1; | ||
| }, | ||
| rejectAllTrackChanges: (r, o) => { | ||
| const a = n(o); | ||
| return a ? A(a.editor, "reject", "all") : !1; | ||
| }, | ||
| acceptSelectedTrackChanges: (r, o) => { | ||
| const a = n(o); | ||
| return a ? A(a.editor, "accept", "selection") : !1; | ||
| }, | ||
| rejectSelectedTrackChanges: (r, o) => { | ||
| const a = n(o); | ||
| return a ? A(a.editor, "reject", "selection") : !1; | ||
| } | ||
| }, | ||
| keymap: { | ||
| "Mod-Shift-t": "toggleTrackChanges", | ||
| "Mod-Shift-T": "toggleTrackChanges" | ||
| }, | ||
| destroy: () => { | ||
| Array.from(D).forEach((r) => X(r)); | ||
| } | ||
| }; | ||
| }; | ||
| export { | ||
| De as TrackChangesPlugin | ||
| }; | ||
| //# sourceMappingURL=TrackChangesPlugin.native-Bghu2q4a.mjs.map |
| const S = ".rte-content, .editora-content", ke = "[data-editora-editor], .rte-editor, .editora-editor, editora-editor", Te = "__editoraCommandEditorRoot", ve = "rte-translation-workflow-styles", d = "rte-translation-workflow-panel", y = "translation-workflow", $ = "translationWorkflow", k = ':is([data-theme="dark"], .dark, .editora-theme-dark, .rte-theme-dark)', $e = [ | ||
| "p", | ||
| "h1", | ||
| "h2", | ||
| "h3", | ||
| "h4", | ||
| "h5", | ||
| "h6", | ||
| "li", | ||
| "td", | ||
| "th", | ||
| "blockquote", | ||
| "figcaption" | ||
| ].join(", "), Me = /* @__PURE__ */ new Set(["ArrowUp", "ArrowDown", "Home", "End"]), Ee = [ | ||
| { | ||
| locale: "en", | ||
| label: "English", | ||
| minLengthRatio: 0.6, | ||
| maxLengthRatio: 1.4, | ||
| requireDifferentFromSource: !1, | ||
| preserveTokens: !0 | ||
| }, | ||
| { | ||
| locale: "fr", | ||
| label: "French", | ||
| minLengthRatio: 0.75, | ||
| maxLengthRatio: 1.7, | ||
| requireDifferentFromSource: !0, | ||
| preserveTokens: !0 | ||
| }, | ||
| { | ||
| locale: "de", | ||
| label: "German", | ||
| minLengthRatio: 0.8, | ||
| maxLengthRatio: 1.9, | ||
| requireDifferentFromSource: !0, | ||
| preserveTokens: !0 | ||
| }, | ||
| { | ||
| locale: "es", | ||
| label: "Spanish", | ||
| minLengthRatio: 0.7, | ||
| maxLengthRatio: 1.7, | ||
| requireDifferentFromSource: !0, | ||
| preserveTokens: !0 | ||
| }, | ||
| { | ||
| locale: "it", | ||
| label: "Italian", | ||
| minLengthRatio: 0.7, | ||
| maxLengthRatio: 1.7, | ||
| requireDifferentFromSource: !0, | ||
| preserveTokens: !0 | ||
| }, | ||
| { | ||
| locale: "ja", | ||
| label: "Japanese", | ||
| minLengthRatio: 0.45, | ||
| maxLengthRatio: 1.2, | ||
| requireDifferentFromSource: !0, | ||
| preserveTokens: !0 | ||
| }, | ||
| { | ||
| locale: "zh", | ||
| label: "Chinese", | ||
| minLengthRatio: 0.4, | ||
| maxLengthRatio: 1.2, | ||
| requireDifferentFromSource: !0, | ||
| preserveTokens: !0 | ||
| } | ||
| ], Oe = { | ||
| panelTitle: "Translation Workflow", | ||
| panelAriaLabel: "Translation workflow panel", | ||
| sourceLocaleLabel: "Source Locale", | ||
| targetLocaleLabel: "Target Locale", | ||
| validateText: "Validate Locale", | ||
| captureSourceText: "Capture Source", | ||
| lockSelectedText: "Lock Selected", | ||
| unlockSelectedText: "Unlock Selected", | ||
| lockSegmentAriaLabel: "Lock segment", | ||
| unlockSegmentAriaLabel: "Unlock segment", | ||
| realtimeOnText: "Realtime On", | ||
| realtimeOffText: "Realtime Off", | ||
| closeText: "Close", | ||
| summaryPrefix: "Locale QA", | ||
| noIssuesText: "No locale validation issues.", | ||
| issuesLabel: "Locale issues", | ||
| segmentsLabel: "Segments", | ||
| sourcePreviewLabel: "Source", | ||
| targetPreviewLabel: "Target", | ||
| helperText: "Select segments, lock finalized ones, and run locale validation before handoff.", | ||
| shortcutText: "Shortcuts: Ctrl/Cmd+Alt+Shift+L (panel), Ctrl/Cmd+Alt+Shift+V (validate), Ctrl/Cmd+Alt+Shift+K (lock segment)", | ||
| readonlySegmentMessage: "This segment is locked. Unlock before editing.", | ||
| sourceCapturedMessage: "Source snapshot captured from current content.", | ||
| selectedSegmentPrefix: "Selected Segment", | ||
| missingTargetMessage: "Segment is empty in target locale.", | ||
| tokenMismatchMessage: "Tokens/placeholders do not match source segment.", | ||
| untranslatedMessage: "Segment appears untranslated (same as source).", | ||
| lengthOutOfRangeMessage: "Translation length is outside expected locale range." | ||
| }, u = /* @__PURE__ */ new WeakMap(), oe = /* @__PURE__ */ new WeakMap(), D = /* @__PURE__ */ new WeakMap(), h = /* @__PURE__ */ new Map(), Y = /* @__PURE__ */ new WeakMap(), se = /* @__PURE__ */ new WeakMap(), Z = /* @__PURE__ */ new Set(); | ||
| let ee = 0, _e = 0, Ae = 0, Fe = 0, w = null, x = null, N = null, O = null, _ = null, F = null, I = null, W = null; | ||
| function m(e) { | ||
| return e.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'"); | ||
| } | ||
| function We(e) { | ||
| return e.replace(/\u00A0/g, " ").replace(/\s+/g, " ").trim(); | ||
| } | ||
| function B(e, n, t) { | ||
| return Number.isFinite(e) ? Math.max(n, Math.min(t, e)) : n; | ||
| } | ||
| function A(e) { | ||
| return (e || "").trim() || "en-US"; | ||
| } | ||
| function j(e) { | ||
| return e.trim().toLowerCase(); | ||
| } | ||
| function Ke(e) { | ||
| return e.replace(/"/g, """); | ||
| } | ||
| function Ve(e, n = 120) { | ||
| return e.length <= n ? e : `${e.slice(0, Math.max(0, n - 1)).trimEnd()}…`; | ||
| } | ||
| function Re(e) { | ||
| const n = e.match(/\{\{[^{}]+\}\}|%[A-Z0-9_]+%|\$\{[^{}]+\}/gi); | ||
| return !n || n.length === 0 ? [] : n.map((t) => t.trim()).filter(Boolean); | ||
| } | ||
| function je(e, n) { | ||
| const t = Re(e).sort(), r = Re(n).sort(); | ||
| if (t.length !== r.length) return !1; | ||
| for (let a = 0; a < t.length; a += 1) | ||
| if (t[a] !== r[a]) return !1; | ||
| return !0; | ||
| } | ||
| function Ue(e, n) { | ||
| const t = Array.isArray(n) && n.length > 0 ? n : Ee, r = [], a = /* @__PURE__ */ new Set(); | ||
| return t.forEach((o) => { | ||
| var i, c; | ||
| const l = j(o.locale || ""); | ||
| if (!l) return; | ||
| const s = l; | ||
| a.has(s) || (a.add(s), r.push({ | ||
| locale: s, | ||
| label: (o.label || l).trim() || l, | ||
| minLengthRatio: B(Number((i = o.minLengthRatio) != null ? i : 0.5), 0.1, 3), | ||
| maxLengthRatio: B(Number((c = o.maxLengthRatio) != null ? c : 1.8), 0.2, 4), | ||
| requireDifferentFromSource: o.requireDifferentFromSource !== !1, | ||
| preserveTokens: o.preserveTokens !== !1 | ||
| })); | ||
| }), e.forEach((o) => { | ||
| const l = j(o); | ||
| if (a.has(l)) return; | ||
| const s = Ee.find((i) => l.startsWith(i.locale)); | ||
| r.push( | ||
| s ? { ...s, locale: l, label: o } : { | ||
| locale: l, | ||
| label: o, | ||
| minLengthRatio: 0.5, | ||
| maxLengthRatio: 1.8, | ||
| requireDifferentFromSource: !0, | ||
| preserveTokens: !0 | ||
| } | ||
| ); | ||
| }), r; | ||
| } | ||
| function ae(e = {}) { | ||
| var s, i, c, g; | ||
| const n = e.normalizeText || We, t = A(e.sourceLocale || "en-US"), r = A(e.targetLocale || "fr-FR"), a = /* @__PURE__ */ new Set([t, r]); | ||
| (Array.isArray(e.locales) ? e.locales : []).forEach((p) => { | ||
| if (typeof p != "string") return; | ||
| const v = A(p); | ||
| a.add(v); | ||
| }); | ||
| const o = Array.from(a), l = Ue(o, e.localeRules); | ||
| return { | ||
| sourceLocale: t, | ||
| targetLocale: r, | ||
| locales: o, | ||
| localeRules: l, | ||
| enableRealtime: e.enableRealtime !== !1, | ||
| debounceMs: B(Number((s = e.debounceMs) != null ? s : 260), 60, 2e3), | ||
| maxIssues: B(Number((i = e.maxIssues) != null ? i : 120), 5, 1e3), | ||
| maxSegments: B(Number((c = e.maxSegments) != null ? c : 600), 20, 3e3), | ||
| minSourceLengthForRatio: B(Number((g = e.minSourceLengthForRatio) != null ? g : 8), 2, 100), | ||
| segmentSelector: (e.segmentSelector || $e).trim() || $e, | ||
| labels: { | ||
| ...Oe, | ||
| ...e.labels || {} | ||
| }, | ||
| normalizeText: n | ||
| }; | ||
| } | ||
| function Ge(e) { | ||
| return { | ||
| sourceLocale: e.sourceLocale, | ||
| targetLocale: e.targetLocale, | ||
| locales: [...e.locales], | ||
| localeRules: e.localeRules.map((n) => ({ | ||
| locale: n.locale, | ||
| label: n.label, | ||
| minLengthRatio: n.minLengthRatio, | ||
| maxLengthRatio: n.maxLengthRatio, | ||
| requireDifferentFromSource: n.requireDifferentFromSource, | ||
| preserveTokens: n.preserveTokens | ||
| })), | ||
| enableRealtime: e.enableRealtime, | ||
| debounceMs: e.debounceMs, | ||
| maxIssues: e.maxIssues, | ||
| maxSegments: e.maxSegments, | ||
| minSourceLengthForRatio: e.minSourceLengthForRatio, | ||
| segmentSelector: e.segmentSelector, | ||
| labels: { ...e.labels }, | ||
| normalizeText: e.normalizeText | ||
| }; | ||
| } | ||
| function we(e) { | ||
| return e.closest(ke) || e; | ||
| } | ||
| function U(e) { | ||
| if (!e) return null; | ||
| if (e.matches(S)) return e; | ||
| const n = e.querySelector(S); | ||
| return n instanceof HTMLElement ? n : null; | ||
| } | ||
| function Ye() { | ||
| if (typeof window == "undefined") return null; | ||
| const e = window[Te]; | ||
| if (!(e instanceof HTMLElement)) return null; | ||
| window[Te] = null; | ||
| const n = U(e); | ||
| if (n) return n; | ||
| const t = e.closest(ke); | ||
| if (t) { | ||
| const a = U(t); | ||
| if (a) return a; | ||
| } | ||
| const r = e.closest(S); | ||
| return r instanceof HTMLElement ? r : null; | ||
| } | ||
| function Ze(e) { | ||
| const n = e.closest("[data-editora-editor]"); | ||
| if (n && U(n) === e) | ||
| return n; | ||
| let t = e; | ||
| for (; t; ) { | ||
| if (t.matches(ke) && (t === e || U(t) === e)) | ||
| return t; | ||
| t = t.parentElement; | ||
| } | ||
| return we(e); | ||
| } | ||
| function Ce(e) { | ||
| return e ? e.nodeType === Node.ELEMENT_NODE ? e : e.parentElement : null; | ||
| } | ||
| function te(e) { | ||
| return e ? (e.getAttribute("data-theme") || e.getAttribute("theme") || "").toLowerCase() === "dark" ? !0 : e.classList.contains("dark") || e.classList.contains("editora-theme-dark") || e.classList.contains("rte-theme-dark") : !1; | ||
| } | ||
| function Je(e) { | ||
| const n = we(e); | ||
| if (te(n)) return !0; | ||
| const t = n.closest("[data-theme], [theme], .dark, .editora-theme-dark, .rte-theme-dark"); | ||
| return te(t) ? !0 : te(document.documentElement) || te(document.body); | ||
| } | ||
| function ge(e, n) { | ||
| e.classList.remove("rte-translation-workflow-theme-dark"), Je(n) && e.classList.add("rte-translation-workflow-theme-dark"); | ||
| } | ||
| function Qe(e) { | ||
| var n, t, r, a; | ||
| for (let o = 0; o < e.length; o += 1) { | ||
| const l = e[o]; | ||
| if (!(l.type !== "childList" || l.removedNodes.length === 0)) | ||
| for (let s = 0; s < l.removedNodes.length; s += 1) { | ||
| const i = l.removedNodes[s]; | ||
| if (i.nodeType !== Node.ELEMENT_NODE) continue; | ||
| const c = i; | ||
| if ((n = c.matches) != null && n.call(c, S) || (t = c.matches) != null && t.call(c, `.${d}`) || (r = c.querySelector) != null && r.call(c, S) || (a = c.querySelector) != null && a.call(c, `.${d}`)) | ||
| return !0; | ||
| } | ||
| } | ||
| return !1; | ||
| } | ||
| function le() { | ||
| Array.from(Z).forEach((n) => { | ||
| n.isConnected || Se(n); | ||
| }); | ||
| } | ||
| function T(e, n = !0, t = !0) { | ||
| var s; | ||
| if (le(), (e == null ? void 0 : e.contentElement) instanceof HTMLElement) return e.contentElement; | ||
| if ((e == null ? void 0 : e.editorElement) instanceof HTMLElement) { | ||
| const i = U(e.editorElement); | ||
| if (i) return i; | ||
| } | ||
| const r = Ye(); | ||
| if (r) return r; | ||
| const a = window.getSelection(); | ||
| if (a && a.rangeCount > 0) { | ||
| const i = (s = Ce(a.getRangeAt(0).startContainer)) == null ? void 0 : s.closest( | ||
| S | ||
| ); | ||
| if (i) return i; | ||
| } | ||
| const o = document.activeElement; | ||
| if (o) { | ||
| if (o.matches(S)) return o; | ||
| const i = o.closest(S); | ||
| if (i) return i; | ||
| } | ||
| if (t && x && x.isConnected) | ||
| return x; | ||
| if (!n) return null; | ||
| const l = document.querySelector(S); | ||
| return l instanceof HTMLElement ? l : null; | ||
| } | ||
| function Xe(e) { | ||
| const n = e.target; | ||
| if (n) { | ||
| const r = n.closest(`.${d}`); | ||
| if (r) { | ||
| const o = Array.from(h.entries()).find(([, l]) => l === r); | ||
| if (o) return o[0]; | ||
| } | ||
| const a = n.closest(S); | ||
| if (a) return a; | ||
| } | ||
| const t = document.activeElement; | ||
| if (t) { | ||
| const r = t.closest(`.${d}`); | ||
| if (r) { | ||
| const o = Array.from(h.entries()).find(([, l]) => l === r); | ||
| if (o) return o[0]; | ||
| } | ||
| const a = t.closest(S); | ||
| if (a) return a; | ||
| } | ||
| return null; | ||
| } | ||
| function fe(e, n, t) { | ||
| const r = Ze(e); | ||
| Array.from( | ||
| r.querySelectorAll( | ||
| `.rte-toolbar-button[data-command="${n}"], .editora-toolbar-button[data-command="${n}"]` | ||
| ) | ||
| ).forEach((o) => { | ||
| o.classList.toggle("active", t), o.setAttribute("data-active", t ? "true" : "false"), o.setAttribute("aria-pressed", t ? "true" : "false"); | ||
| }); | ||
| } | ||
| function xe(e) { | ||
| const n = se.get(e); | ||
| typeof n == "number" && (window.clearTimeout(n), se.delete(e)); | ||
| } | ||
| function et(e, n) { | ||
| const t = j(n), r = e.localeRules.find((l) => j(l.locale) === t); | ||
| if (r) return r; | ||
| const a = t.split("-")[0], o = e.localeRules.find((l) => j(l.locale).split("-")[0] === a); | ||
| return o || { | ||
| locale: t, | ||
| label: n, | ||
| minLengthRatio: 0.5, | ||
| maxLengthRatio: 1.8, | ||
| requireDifferentFromSource: !0, | ||
| preserveTokens: !0 | ||
| }; | ||
| } | ||
| function ne(e, n, t, r = {}) { | ||
| return Ae += 1, { | ||
| id: `translation-workflow-issue-${Ae}`, | ||
| type: e, | ||
| severity: n, | ||
| message: t, | ||
| ...r | ||
| }; | ||
| } | ||
| function ce(e, n) { | ||
| if (n) { | ||
| e.hasAttribute("data-translation-prev-contenteditable") || e.setAttribute( | ||
| "data-translation-prev-contenteditable", | ||
| e.hasAttribute("contenteditable") && e.getAttribute("contenteditable") || "inherit" | ||
| ), e.setAttribute("data-translation-locked", "true"), e.setAttribute("contenteditable", "false"), e.setAttribute("aria-readonly", "true"), e.classList.add("rte-translation-segment-locked"); | ||
| return; | ||
| } | ||
| if (e.removeAttribute("data-translation-locked"), e.removeAttribute("aria-readonly"), e.classList.remove("rte-translation-segment-locked"), e.hasAttribute("data-translation-prev-contenteditable")) { | ||
| const t = e.getAttribute("data-translation-prev-contenteditable") || ""; | ||
| t === "inherit" ? e.setAttribute("contenteditable", "true") : e.setAttribute("contenteditable", t), e.removeAttribute("data-translation-prev-contenteditable"); | ||
| } else | ||
| e.setAttribute("contenteditable", "true"); | ||
| } | ||
| function ue(e, n) { | ||
| return e.querySelector(`[data-translation-segment-id="${Ke(n)}"]`); | ||
| } | ||
| function He(e) { | ||
| const n = window.getSelection(); | ||
| if (!n || n.rangeCount === 0) return null; | ||
| const t = Ce(n.getRangeAt(0).startContainer); | ||
| return !t || !e.contains(t) ? null : t.closest("[data-translation-segment-id]"); | ||
| } | ||
| function tt(e, n) { | ||
| const t = Array.from(e.querySelectorAll(n)); | ||
| if (t.length <= 1) return t; | ||
| const r = new Set(t); | ||
| return t.filter((a) => { | ||
| let o = a.parentElement; | ||
| for (; o && o !== e; ) { | ||
| if (r.has(o)) | ||
| return !1; | ||
| o = o.parentElement; | ||
| } | ||
| return !0; | ||
| }); | ||
| } | ||
| function nt(e, n, t) { | ||
| let r = (t || "").trim(); | ||
| if (!r || n.has(r)) { | ||
| do | ||
| r = `translation-segment-${_e++}`; | ||
| while (n.has(r)); | ||
| e.setAttribute("data-translation-segment-id", r); | ||
| } | ||
| return r; | ||
| } | ||
| function me(e, n) { | ||
| if (n.lockedSegmentIds.size === 0) return !1; | ||
| let t = !1; | ||
| return n.lockedSegmentIds.forEach((r) => { | ||
| const a = ue(e, r); | ||
| if (!a) return; | ||
| ce(a, !0); | ||
| const o = n.lockedHtmlBySegmentId.get(r); | ||
| if (typeof o == "string") { | ||
| a.innerHTML !== o && (a.innerHTML = o, t = !0); | ||
| return; | ||
| } | ||
| n.lockedHtmlBySegmentId.set(r, a.innerHTML); | ||
| }), t; | ||
| } | ||
| function M(e, n, t) { | ||
| var l; | ||
| const r = tt(e, n.segmentSelector), a = [], o = /* @__PURE__ */ new Set(); | ||
| for (let s = 0; s < r.length && !(a.length >= n.maxSegments); s += 1) { | ||
| const i = r[s], c = nt(i, o, i.getAttribute("data-translation-segment-id")), g = t.lockedSegmentIds.has(c), p = i.getAttribute("data-translation-locked") === "true", v = g || p; | ||
| if (v) | ||
| if (t.lockedSegmentIds.add(c), ce(i, !0), !t.lockedHtmlBySegmentId.has(c)) | ||
| t.lockedHtmlBySegmentId.set(c, i.innerHTML); | ||
| else { | ||
| const H = t.lockedHtmlBySegmentId.get(c) || ""; | ||
| i.innerHTML !== H && (i.innerHTML = H); | ||
| } | ||
| else | ||
| t.lockedHtmlBySegmentId.delete(c); | ||
| const C = n.normalizeText(i.textContent || ""); | ||
| if (!C) continue; | ||
| t.sourceTextBySegmentId.has(c) || t.sourceTextBySegmentId.set(c, C); | ||
| const K = t.sourceTextBySegmentId.get(c) || C; | ||
| a.push({ | ||
| id: c, | ||
| tagName: i.tagName.toLowerCase(), | ||
| index: a.length, | ||
| text: C, | ||
| sourceText: K, | ||
| locked: v | ||
| }), o.add(c); | ||
| } | ||
| return Array.from(t.sourceTextBySegmentId.keys()).forEach((s) => { | ||
| o.has(s) || t.sourceTextBySegmentId.delete(s); | ||
| }), Array.from(t.lockedSegmentIds.keys()).forEach((s) => { | ||
| o.has(s) || t.lockedSegmentIds.delete(s); | ||
| }), Array.from(t.lockedHtmlBySegmentId.keys()).forEach((s) => { | ||
| (!o.has(s) || !t.lockedSegmentIds.has(s)) && t.lockedHtmlBySegmentId.delete(s); | ||
| }), (!t.selectedSegmentId || !a.some((s) => s.id === t.selectedSegmentId)) && (t.selectedSegmentId = ((l = a[0]) == null ? void 0 : l.id) || null), a; | ||
| } | ||
| function b(e, n) { | ||
| u.has(e) || u.set(e, n); | ||
| let t = D.get(e); | ||
| return t || (t = { | ||
| sourceLocale: n.sourceLocale, | ||
| targetLocale: n.targetLocale, | ||
| selectedSegmentId: null, | ||
| realtimeEnabled: n.enableRealtime, | ||
| segments: [], | ||
| issues: [], | ||
| sourceTextBySegmentId: /* @__PURE__ */ new Map(), | ||
| lockedSegmentIds: /* @__PURE__ */ new Set(), | ||
| lockedHtmlBySegmentId: /* @__PURE__ */ new Map(), | ||
| snapshot: "", | ||
| lastRunAt: null | ||
| }, D.set(e, t)), Z.add(e), t; | ||
| } | ||
| function Se(e) { | ||
| xe(e); | ||
| const n = h.get(e); | ||
| n && n.remove(), h.delete(e), Y.delete(e); | ||
| const t = D.get(e); | ||
| t && (t.lockedSegmentIds.forEach((r) => { | ||
| const a = ue(e, r); | ||
| a && ce(a, !1); | ||
| }), t.lockedHtmlBySegmentId.clear()), u.delete(e), oe.delete(e), D.delete(e), Z.delete(e), x === e && (x = null); | ||
| } | ||
| function ye(e) { | ||
| return Y.get(e) === !0; | ||
| } | ||
| function be(e, n) { | ||
| if (!n.classList.contains("show")) return; | ||
| const t = we(e).getBoundingClientRect(), r = Math.min(window.innerWidth - 20, 520), a = Math.max(10, window.innerWidth - r - 10), o = Math.min(Math.max(10, t.right - r), a), l = Math.max(10, Math.min(window.innerHeight - 10, t.top + 12)); | ||
| n.style.width = `${r}px`, n.style.left = `${o}px`, n.style.top = `${l}px`, n.style.maxHeight = `${Math.max(260, window.innerHeight - 20)}px`; | ||
| } | ||
| function P(e, n) { | ||
| const t = e.querySelector(".rte-translation-live"); | ||
| t && (t.textContent = n); | ||
| } | ||
| function rt(e, n) { | ||
| return `${e.innerHTML}::${n.sourceLocale}::${n.targetLocale}::${Array.from(n.lockedSegmentIds).sort().join("|")}`; | ||
| } | ||
| function ot(e, n, t) { | ||
| const r = [], a = et(t, n.targetLocale); | ||
| for (let o = 0; o < e.length && !(r.length >= t.maxIssues); o += 1) { | ||
| const l = e[o], s = t.normalizeText(l.sourceText || ""), i = t.normalizeText(l.text || ""); | ||
| if (!i) { | ||
| r.push( | ||
| ne("missing-target", "error", t.labels.missingTargetMessage, { | ||
| segmentId: l.id, | ||
| sourceText: s, | ||
| targetText: i, | ||
| suggestion: "Provide translated content for this segment before export." | ||
| }) | ||
| ); | ||
| continue; | ||
| } | ||
| if (a.preserveTokens && s && !je(s, i) && (r.push( | ||
| ne("token-mismatch", "error", t.labels.tokenMismatchMessage, { | ||
| segmentId: l.id, | ||
| sourceText: s, | ||
| targetText: i, | ||
| suggestion: "Preserve placeholders/tokens exactly (for example {{name}}, %ID%, ${value})." | ||
| }) | ||
| ), r.length >= t.maxIssues) || a.requireDifferentFromSource && s && t.normalizeText(s) === t.normalizeText(i) && (r.push( | ||
| ne("untranslated", "warning", t.labels.untranslatedMessage, { | ||
| segmentId: l.id, | ||
| sourceText: s, | ||
| targetText: i, | ||
| suggestion: "Translate the segment or mark it intentionally unchanged." | ||
| }) | ||
| ), r.length >= t.maxIssues)) | ||
| break; | ||
| if (s.length >= t.minSourceLengthForRatio) { | ||
| const c = i.length / Math.max(1, s.length); | ||
| (c < a.minLengthRatio || c > a.maxLengthRatio) && r.push( | ||
| ne("length-out-of-range", "warning", t.labels.lengthOutOfRangeMessage, { | ||
| segmentId: l.id, | ||
| sourceText: s, | ||
| targetText: i, | ||
| suggestion: `Expected ratio for ${a.label}: ${a.minLengthRatio.toFixed(2)} - ${a.maxLengthRatio.toFixed(2)}.` | ||
| }) | ||
| ); | ||
| } | ||
| } | ||
| return r; | ||
| } | ||
| function qe(e) { | ||
| const n = u.get(e) || w, t = D.get(e); | ||
| return { | ||
| sourceLocale: (t == null ? void 0 : t.sourceLocale) || (n == null ? void 0 : n.sourceLocale) || "en-US", | ||
| targetLocale: (t == null ? void 0 : t.targetLocale) || (n == null ? void 0 : n.targetLocale) || "fr-FR", | ||
| realtimeEnabled: (t == null ? void 0 : t.realtimeEnabled) === !0, | ||
| selectedSegmentId: (t == null ? void 0 : t.selectedSegmentId) || null, | ||
| segmentCount: (t == null ? void 0 : t.segments.length) || 0, | ||
| lockedSegmentCount: t ? t.segments.filter((r) => r.locked).length : 0, | ||
| issues: t != null && t.issues ? t.issues.map((r) => ({ ...r })) : [], | ||
| segments: (t == null ? void 0 : t.segments.map((r) => ({ | ||
| id: r.id, | ||
| tagName: r.tagName, | ||
| index: r.index, | ||
| sourceLength: r.sourceText.length, | ||
| targetLength: r.text.length, | ||
| locked: r.locked | ||
| }))) || [], | ||
| lastRunAt: (t == null ? void 0 : t.lastRunAt) || null | ||
| }; | ||
| } | ||
| function E(e) { | ||
| const n = D.get(e), t = n && n.selectedSegmentId ? n.segments.find((r) => r.id === n.selectedSegmentId) : null; | ||
| fe(e, "toggleTranslationWorkflowPanel", ye(e)), fe(e, "toggleTranslationRealtime", (n == null ? void 0 : n.realtimeEnabled) === !0), fe(e, "toggleTranslationSegmentLock", (t == null ? void 0 : t.locked) === !0); | ||
| } | ||
| function at(e, n) { | ||
| const t = ue(e, n); | ||
| if (!t) return; | ||
| try { | ||
| t.scrollIntoView({ block: "nearest", inline: "nearest" }); | ||
| } catch (a) { | ||
| } | ||
| const r = window.getSelection(); | ||
| if (!(!r || typeof document.createRange != "function")) | ||
| try { | ||
| const a = document.createRange(); | ||
| a.selectNodeContents(t), a.collapse(!0), r.removeAllRanges(), r.addRange(a), e.focus({ preventScroll: !0 }); | ||
| } catch (a) { | ||
| } | ||
| } | ||
| function R(e) { | ||
| const n = h.get(e); | ||
| if (!n) return; | ||
| const t = u.get(e) || w; | ||
| if (!t) return; | ||
| const r = b(e, t), a = n.querySelector(".rte-translation-source-label"); | ||
| a && (a.textContent = t.labels.sourceLocaleLabel); | ||
| const o = n.querySelector(".rte-translation-target-label"); | ||
| o && (o.textContent = t.labels.targetLocaleLabel); | ||
| const l = n.querySelector('[data-field="source-locale"]'), s = n.querySelector('[data-field="target-locale"]'), i = t.locales.map((f) => `<option value="${m(f)}">${m(f)}</option>`).join(""); | ||
| l && (l.innerHTML = i, l.value = r.sourceLocale), s && (s.innerHTML = i, s.value = r.targetLocale); | ||
| const c = n.querySelector(".rte-translation-summary"); | ||
| if (c) { | ||
| const f = r.issues.length, z = r.selectedSegmentId ? ` • ${t.labels.selectedSegmentPrefix}: ${r.selectedSegmentId}` : ""; | ||
| c.textContent = `${t.labels.summaryPrefix}: ${r.sourceLocale} → ${r.targetLocale} • ${f} issue${f === 1 ? "" : "s"}${z}`; | ||
| } | ||
| const g = n.querySelector(".rte-translation-helper"); | ||
| g && (g.textContent = t.labels.helperText); | ||
| const p = n.querySelector(".rte-translation-shortcut"); | ||
| p && (p.textContent = t.labels.shortcutText); | ||
| const v = n.querySelector('[data-action="run-validation"]'); | ||
| v && (v.textContent = t.labels.validateText); | ||
| const C = n.querySelector('[data-action="capture-source"]'); | ||
| C && (C.textContent = t.labels.captureSourceText); | ||
| const K = n.querySelector('[data-action="toggle-realtime"]'); | ||
| K && (K.textContent = r.realtimeEnabled ? t.labels.realtimeOnText : t.labels.realtimeOffText, K.setAttribute("aria-pressed", r.realtimeEnabled ? "true" : "false")); | ||
| const H = n.querySelector('[data-action="lock-selected"]'), q = r.selectedSegmentId && r.segments.find((f) => f.id === r.selectedSegmentId) || null; | ||
| H && (H.textContent = q != null && q.locked ? t.labels.unlockSelectedText : t.labels.lockSelectedText, H.disabled = !q, H.setAttribute("aria-pressed", q != null && q.locked ? "true" : "false")); | ||
| const Le = n.querySelector('[data-action="close"]'); | ||
| Le && Le.setAttribute("aria-label", t.labels.closeText); | ||
| const J = n.querySelector(".rte-translation-issues"), V = n.querySelector(".rte-translation-empty"); | ||
| J && (J.setAttribute("aria-label", t.labels.issuesLabel), r.issues.length === 0 ? (J.innerHTML = "", V && (V.hidden = !1, V.textContent = t.labels.noIssuesText)) : (V && (V.hidden = !0), J.innerHTML = r.issues.map((f) => ` | ||
| <li class="rte-translation-issue ${f.severity === "error" ? "error" : f.severity === "warning" ? "warning" : "info"}" role="listitem" data-segment-id="${m( | ||
| f.segmentId || "" | ||
| )}"> | ||
| <p class="rte-translation-issue-message">${m(f.message)}</p> | ||
| ${f.suggestion ? `<p class="rte-translation-issue-suggestion">${m(f.suggestion)}</p>` : ""} | ||
| </li> | ||
| `).join(""))); | ||
| const de = n.querySelector(".rte-translation-segments"); | ||
| de && (de.setAttribute("aria-label", t.labels.segmentsLabel), de.innerHTML = r.segments.map((f) => { | ||
| const z = f.id === r.selectedSegmentId ? "selected" : "", Ne = f.locked ? "locked" : ""; | ||
| return ` | ||
| <li class="rte-translation-segment-item ${z} ${Ne}" role="option" aria-selected="${f.id === r.selectedSegmentId ? "true" : "false"}" data-segment-id="${m(f.id)}"> | ||
| <button type="button" class="rte-translation-segment-select" data-action="select-segment" data-segment-id="${m( | ||
| f.id | ||
| )}" title="${m(f.text)}"> | ||
| <span class="rte-translation-segment-meta">#${f.index + 1} • ${m(f.tagName)}</span> | ||
| <span class="rte-translation-segment-text">${m(Ve(f.text, 110))}</span> | ||
| </button> | ||
| <button type="button" class="rte-translation-segment-lock" data-action="toggle-lock" data-segment-id="${m( | ||
| f.id | ||
| )}" aria-label="${f.locked ? t.labels.unlockSegmentAriaLabel : t.labels.lockSegmentAriaLabel}" aria-pressed="${f.locked ? "true" : "false"}"></button> | ||
| </li> | ||
| `; | ||
| }).join("")); | ||
| const Q = n.querySelector(".rte-translation-source-preview"), X = n.querySelector(".rte-translation-target-preview"); | ||
| if (Q || X) { | ||
| const f = r.selectedSegmentId && r.segments.find((z) => z.id === r.selectedSegmentId) || null; | ||
| Q && (Q.textContent = (f == null ? void 0 : f.sourceText) || "—", Q.setAttribute("aria-label", t.labels.sourcePreviewLabel)), X && (X.textContent = (f == null ? void 0 : f.text) || "—", X.setAttribute("aria-label", t.labels.targetPreviewLabel)); | ||
| } | ||
| n.setAttribute("aria-label", t.labels.panelAriaLabel); | ||
| } | ||
| function Be(e) { | ||
| const n = u.get(e) || w; | ||
| if (!n) return; | ||
| xe(e); | ||
| const t = window.setTimeout(() => { | ||
| se.delete(e), L(e, "realtime", !1); | ||
| }, n.debounceMs); | ||
| se.set(e, t); | ||
| } | ||
| function L(e, n, t) { | ||
| const r = u.get(e) || w; | ||
| if (!r) return []; | ||
| const a = b(e, r), o = me(e, a); | ||
| a.segments = M(e, r, a); | ||
| const l = rt(e, a); | ||
| if (!t && a.snapshot === l) | ||
| return a.issues; | ||
| a.issues = ot(a.segments, a, r), a.lastRunAt = (/* @__PURE__ */ new Date()).toISOString(), a.snapshot = l, R(e), E(e), e.dispatchEvent( | ||
| new CustomEvent("editora:translation-workflow-validation", { | ||
| bubbles: !0, | ||
| detail: { | ||
| reason: n, | ||
| state: qe(e) | ||
| } | ||
| }) | ||
| ); | ||
| const s = h.get(e); | ||
| if (s) { | ||
| if (o) | ||
| return P(s, r.labels.readonlySegmentMessage), a.issues; | ||
| P( | ||
| s, | ||
| a.issues.length === 0 ? r.labels.noIssuesText : `${a.issues.length} issue${a.issues.length === 1 ? "" : "s"} detected.` | ||
| ); | ||
| } | ||
| return a.issues; | ||
| } | ||
| function Pe(e) { | ||
| const n = u.get(e) || w; | ||
| if (!n) return !1; | ||
| const t = b(e, n), r = M(e, n, t); | ||
| r.forEach((o) => { | ||
| t.sourceTextBySegmentId.set(o.id, o.text); | ||
| }), t.snapshot = "", L(e, "capture-source", !0); | ||
| const a = h.get(e); | ||
| return a && P(a, n.labels.sourceCapturedMessage), e.dispatchEvent( | ||
| new CustomEvent("editora:translation-source-captured", { | ||
| bubbles: !0, | ||
| detail: { | ||
| sourceLocale: t.sourceLocale, | ||
| segmentCount: r.length | ||
| } | ||
| }) | ||
| ), !0; | ||
| } | ||
| function ie(e, n, t) { | ||
| var c, g; | ||
| const r = u.get(e) || w; | ||
| if (!r) return !1; | ||
| const a = b(e, r); | ||
| a.segments = M(e, r, a); | ||
| const o = ((c = He(e)) == null ? void 0 : c.getAttribute("data-translation-segment-id")) || null, l = n || o || a.selectedSegmentId || ((g = a.segments[0]) == null ? void 0 : g.id) || null; | ||
| if (!l) return !1; | ||
| const s = ue(e, l); | ||
| if (!s) return !1; | ||
| const i = typeof t == "boolean" ? t : !a.lockedSegmentIds.has(l); | ||
| return i ? (a.lockedSegmentIds.add(l), a.lockedHtmlBySegmentId.set(l, s.innerHTML)) : (a.lockedSegmentIds.delete(l), a.lockedHtmlBySegmentId.delete(l)), ce(s, i), a.selectedSegmentId = l, a.snapshot = "", L(e, "lock-segment", !0), e.dispatchEvent( | ||
| new CustomEvent("editora:translation-segment-lock", { | ||
| bubbles: !0, | ||
| detail: { | ||
| segmentId: l, | ||
| locked: i | ||
| } | ||
| }) | ||
| ), !0; | ||
| } | ||
| function De(e, n) { | ||
| const t = u.get(e) || w; | ||
| if (!t) return !1; | ||
| const r = b(e, t), a = typeof n == "boolean" ? n : !r.realtimeEnabled; | ||
| return r.realtimeEnabled = a, a ? Be(e) : xe(e), R(e), E(e), !0; | ||
| } | ||
| function pe(e, n, t = !0) { | ||
| const r = u.get(e) || w; | ||
| if (!r) return !1; | ||
| const a = b(e, r); | ||
| return a.segments = M(e, r, a), a.segments.some((o) => o.id === n) ? (a.selectedSegmentId = n, R(e), E(e), t && at(e, n), !0) : !1; | ||
| } | ||
| function re(e, n) { | ||
| const t = u.get(e) || w; | ||
| if (!t) return !1; | ||
| const r = b(e, t); | ||
| if (r.segments = M(e, t, r), r.segments.length === 0) return !1; | ||
| const a = Math.max( | ||
| 0, | ||
| r.segments.findIndex((s) => s.id === r.selectedSegmentId) | ||
| ); | ||
| let o = a; | ||
| n === "start" ? o = 0 : n === "end" ? o = r.segments.length - 1 : o = B(a + n, 0, r.segments.length - 1); | ||
| const l = r.segments[o]; | ||
| return l ? pe(e, l.id, !0) : !1; | ||
| } | ||
| function G(e, n = !1) { | ||
| const t = h.get(e); | ||
| t && (t.classList.remove("show"), Y.set(e, !1), E(e), n && e.focus({ preventScroll: !0 })); | ||
| } | ||
| function he(e) { | ||
| const n = ut(e); | ||
| h.forEach((r, a) => { | ||
| a !== e && G(a, !1); | ||
| }), n.classList.add("show"), Y.set(e, !0), L(e, "panel-open", !1), R(e), be(e, n), E(e); | ||
| const t = n.querySelector('[data-field="target-locale"]'); | ||
| t == null || t.focus(); | ||
| } | ||
| function ze(e, n) { | ||
| const t = ye(e); | ||
| return (typeof n == "boolean" ? n : !t) ? he(e) : G(e, !1), !0; | ||
| } | ||
| function lt(e) { | ||
| const n = e.key.toLowerCase(); | ||
| return (e.metaKey || e.ctrlKey) && e.altKey && e.shiftKey && n === "l"; | ||
| } | ||
| function st(e) { | ||
| const n = e.key.toLowerCase(); | ||
| return (e.metaKey || e.ctrlKey) && e.altKey && e.shiftKey && n === "v"; | ||
| } | ||
| function it(e) { | ||
| const n = e.key.toLowerCase(); | ||
| return (e.metaKey || e.ctrlKey) && e.altKey && e.shiftKey && n === "k"; | ||
| } | ||
| function ct(e) { | ||
| return e.key.length === 1 && !e.metaKey && !e.ctrlKey && !e.altKey ? !0 : e.key === "Backspace" || e.key === "Delete" || e.key === "Enter"; | ||
| } | ||
| function Ie(e) { | ||
| return e instanceof HTMLElement ? e.closest('[data-translation-locked="true"]') : null; | ||
| } | ||
| function ut(e) { | ||
| const n = h.get(e); | ||
| if (n) return n; | ||
| const t = u.get(e) || w || ae(); | ||
| b(e, t); | ||
| const r = `rte-translation-workflow-panel-${Fe++}`, a = `${r}-source`, o = `${r}-target`, l = document.createElement("section"); | ||
| return l.className = d, l.id = r, l.setAttribute("role", "dialog"), l.setAttribute("aria-modal", "false"), l.setAttribute("aria-label", t.labels.panelAriaLabel), l.innerHTML = ` | ||
| <header class="rte-translation-header"> | ||
| <h2 class="rte-translation-title">${m(t.labels.panelTitle)}</h2> | ||
| <button type="button" class="rte-translation-icon-btn" data-action="close" aria-label="${m( | ||
| t.labels.closeText | ||
| )}">✕</button> | ||
| </header> | ||
| <div class="rte-translation-body"> | ||
| <div class="rte-translation-locales"> | ||
| <div class="rte-translation-locale-field"> | ||
| <label class="rte-translation-source-label" for="${m(a)}"></label> | ||
| <select id="${m(a)}" class="rte-translation-select" data-field="source-locale"></select> | ||
| </div> | ||
| <div class="rte-translation-locale-field"> | ||
| <label class="rte-translation-target-label" for="${m(o)}"></label> | ||
| <select id="${m(o)}" class="rte-translation-select" data-field="target-locale"></select> | ||
| </div> | ||
| </div> | ||
| <p class="rte-translation-summary"></p> | ||
| <div class="rte-translation-actions"> | ||
| <button type="button" class="rte-translation-btn rte-translation-btn-primary" data-action="run-validation"></button> | ||
| <button type="button" class="rte-translation-btn" data-action="capture-source"></button> | ||
| <button type="button" class="rte-translation-btn" data-action="lock-selected"></button> | ||
| <button type="button" class="rte-translation-btn" data-action="toggle-realtime" aria-pressed="false"></button> | ||
| </div> | ||
| <p class="rte-translation-helper"></p> | ||
| <p class="rte-translation-shortcut"></p> | ||
| <div class="rte-translation-grid"> | ||
| <section class="rte-translation-segments-wrap" aria-label="${m(t.labels.segmentsLabel)}"> | ||
| <h3 class="rte-translation-subtitle">${m(t.labels.segmentsLabel)}</h3> | ||
| <ul class="rte-translation-segments" role="listbox" tabindex="0" aria-label="${m( | ||
| t.labels.segmentsLabel | ||
| )}"></ul> | ||
| </section> | ||
| <section class="rte-translation-preview-wrap"> | ||
| <h3 class="rte-translation-subtitle">${m(t.labels.sourcePreviewLabel)} / ${m( | ||
| t.labels.targetPreviewLabel | ||
| )}</h3> | ||
| <div class="rte-translation-preview-block"> | ||
| <p class="rte-translation-preview-label">${m(t.labels.sourcePreviewLabel)}</p> | ||
| <p class="rte-translation-source-preview"></p> | ||
| </div> | ||
| <div class="rte-translation-preview-block"> | ||
| <p class="rte-translation-preview-label">${m(t.labels.targetPreviewLabel)}</p> | ||
| <p class="rte-translation-target-preview"></p> | ||
| </div> | ||
| </section> | ||
| </div> | ||
| <section class="rte-translation-issues-wrap"> | ||
| <h3 class="rte-translation-subtitle">${m(t.labels.issuesLabel)}</h3> | ||
| <ul class="rte-translation-issues" role="list" aria-label="${m(t.labels.issuesLabel)}"></ul> | ||
| <p class="rte-translation-empty" hidden></p> | ||
| </section> | ||
| </div> | ||
| <div class="rte-translation-live" aria-live="polite" aria-atomic="true"></div> | ||
| `, l.addEventListener("click", (s) => { | ||
| const i = s.target; | ||
| if (!i) return; | ||
| const c = i.closest("[data-action]"); | ||
| if (!c) { | ||
| const p = i.closest(".rte-translation-issue[data-segment-id]"), v = (p == null ? void 0 : p.getAttribute("data-segment-id")) || ""; | ||
| v && pe(e, v, !0); | ||
| return; | ||
| } | ||
| const g = c.getAttribute("data-action"); | ||
| if (g === "close") { | ||
| G(e, !0); | ||
| return; | ||
| } | ||
| if (g === "run-validation") { | ||
| L(e, "panel-button", !0); | ||
| return; | ||
| } | ||
| if (g === "capture-source") { | ||
| Pe(e); | ||
| return; | ||
| } | ||
| if (g === "lock-selected") { | ||
| ie(e); | ||
| return; | ||
| } | ||
| if (g === "toggle-realtime") { | ||
| De(e); | ||
| return; | ||
| } | ||
| if (g === "select-segment") { | ||
| const p = c.getAttribute("data-segment-id") || ""; | ||
| p && pe(e, p, !0); | ||
| return; | ||
| } | ||
| if (g === "toggle-lock") { | ||
| const p = c.getAttribute("data-segment-id") || ""; | ||
| p && ie(e, p); | ||
| } | ||
| }), l.addEventListener("change", (s) => { | ||
| const i = s.target; | ||
| if (!(i instanceof HTMLSelectElement)) return; | ||
| const c = u.get(e) || w; | ||
| if (!c) return; | ||
| const g = b(e, c); | ||
| if (i.getAttribute("data-field") === "source-locale") { | ||
| g.sourceLocale = A(i.value), g.snapshot = "", L(e, "source-locale-change", !0); | ||
| return; | ||
| } | ||
| i.getAttribute("data-field") === "target-locale" && (g.targetLocale = A(i.value), g.snapshot = "", L(e, "target-locale-change", !0)); | ||
| }), l.addEventListener("keydown", (s) => { | ||
| const i = s.target; | ||
| if (s.key === "Escape") { | ||
| s.preventDefault(), G(e, !0); | ||
| return; | ||
| } | ||
| !(i != null && i.closest(".rte-translation-segments")) || !Me.has(s.key) || (s.preventDefault(), s.key === "ArrowUp" ? re(e, -1) : s.key === "ArrowDown" ? re(e, 1) : s.key === "Home" ? re(e, "start") : s.key === "End" && re(e, "end")); | ||
| }), ge(l, e), document.body.appendChild(l), h.set(e, l), Y.set(e, !1), R(e), l; | ||
| } | ||
| function dt(e) { | ||
| w = e, N || (N = (n) => { | ||
| var i; | ||
| le(); | ||
| const t = n.target, r = t == null ? void 0 : t.closest(S); | ||
| if (!r) return; | ||
| const a = u.get(r) || e, o = b(r, a); | ||
| u.set(r, a), x = r; | ||
| const l = ((i = He(r)) == null ? void 0 : i.getAttribute("data-translation-segment-id")) || null; | ||
| l && (o.selectedSegmentId = l), E(r); | ||
| const s = h.get(r); | ||
| s && (ge(s, r), be(r, s), R(r)); | ||
| }, document.addEventListener("focusin", N, !0)), O || (O = (n) => { | ||
| const t = n.target, r = t == null ? void 0 : t.closest(S); | ||
| if (!r) return; | ||
| const a = u.get(r) || w; | ||
| if (!a) return; | ||
| const o = b(r, a), l = me(r, o); | ||
| if (o.segments = M(r, a, o), !o.realtimeEnabled) { | ||
| if (l) { | ||
| const s = h.get(r); | ||
| s && P(s, a.labels.readonlySegmentMessage); | ||
| } | ||
| R(r), E(r); | ||
| return; | ||
| } | ||
| Be(r); | ||
| }, document.addEventListener("input", O, !0)), _ || (_ = (n) => { | ||
| const t = n, r = t.target, a = r == null ? void 0 : r.closest(S); | ||
| if (!a) return; | ||
| const o = Ie(r); | ||
| if (!o || !a.contains(o)) return; | ||
| t.preventDefault(); | ||
| const l = h.get(a), s = u.get(a) || w; | ||
| l && s && P(l, s.labels.readonlySegmentMessage); | ||
| }, document.addEventListener("beforeinput", _, !0)), F || (F = (n) => { | ||
| if (n.defaultPrevented) return; | ||
| const t = n.target; | ||
| if ((t == null ? void 0 : t.closest(`.${d}`)) && n.key !== "Escape" && !Me.has(n.key)) return; | ||
| const a = n.key === "Escape", o = lt(n), l = st(n), s = it(n), i = Ie(t); | ||
| if (!a && !o && !l && !s && !i) | ||
| return; | ||
| const c = Xe(n); | ||
| if (!c) return; | ||
| const g = u.get(c) || w || e; | ||
| if (b(c, g), u.set(c, g), x = c, a && ye(c)) { | ||
| n.preventDefault(), G(c, !0); | ||
| return; | ||
| } | ||
| if (i && c.contains(i) && ct(n)) { | ||
| n.preventDefault(); | ||
| const p = h.get(c); | ||
| p && P(p, g.labels.readonlySegmentMessage); | ||
| return; | ||
| } | ||
| if (o) { | ||
| n.preventDefault(), n.stopPropagation(), ze(c); | ||
| return; | ||
| } | ||
| if (l) { | ||
| n.preventDefault(), n.stopPropagation(), L(c, "shortcut", !0); | ||
| return; | ||
| } | ||
| s && (n.preventDefault(), n.stopPropagation(), ie(c)); | ||
| }, document.addEventListener("keydown", F, !0)), I || (I = () => { | ||
| le(), h.forEach((n, t) => { | ||
| !t.isConnected || !n.isConnected || (ge(n, t), be(t, n)); | ||
| }); | ||
| }, window.addEventListener("scroll", I, !0), window.addEventListener("resize", I)), !W && typeof MutationObserver != "undefined" && document.body && (W = new MutationObserver((n) => { | ||
| Qe(n) && le(), n.some((r) => r.type === "characterData" ? !0 : r.type === "childList" && (r.addedNodes.length > 0 || r.removedNodes.length > 0)) && Z.forEach((r) => { | ||
| const a = D.get(r); | ||
| if (!a || a.lockedSegmentIds.size === 0 || !me(r, a)) return; | ||
| a.snapshot = ""; | ||
| const l = u.get(r) || w, s = h.get(r); | ||
| s && l && P(s, l.labels.readonlySegmentMessage), l && (a.segments = M(r, l, a), R(r), E(r)); | ||
| }); | ||
| }), W.observe(document.body, { | ||
| childList: !0, | ||
| subtree: !0, | ||
| characterData: !0 | ||
| })); | ||
| } | ||
| function ft() { | ||
| N && (document.removeEventListener("focusin", N, !0), N = null), O && (document.removeEventListener("input", O, !0), O = null), _ && (document.removeEventListener("beforeinput", _, !0), _ = null), F && (document.removeEventListener("keydown", F, !0), F = null), I && (window.removeEventListener("scroll", I, !0), window.removeEventListener("resize", I), I = null), W && (W.disconnect(), W = null), h.forEach((n) => n.remove()), h.clear(), Array.from(Z).forEach((n) => Se(n)), w = null, x = null; | ||
| } | ||
| function gt() { | ||
| if (typeof document == "undefined" || document.getElementById(ve)) return; | ||
| const e = document.createElement("style"); | ||
| e.id = ve, e.textContent = ` | ||
| .rte-toolbar-group-items.${y}, | ||
| .editora-toolbar-group-items.${y}, | ||
| .rte-toolbar-group-items.${$}, | ||
| .editora-toolbar-group-items.${$} { | ||
| display: flex; | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 4px; | ||
| background: #ffffff; | ||
| } | ||
| .rte-toolbar-group-items.${y} .rte-toolbar-button, | ||
| .editora-toolbar-group-items.${y} .editora-toolbar-button, | ||
| .rte-toolbar-group-items.${$} .rte-toolbar-button, | ||
| .editora-toolbar-group-items.${$} .editora-toolbar-button { | ||
| border: none; | ||
| border-right: 1px solid #cbd5e1; | ||
| border-radius: 0; | ||
| } | ||
| .rte-toolbar-group-items.${y} .rte-toolbar-item:last-child .rte-toolbar-button, | ||
| .editora-toolbar-group-items.${y} .editora-toolbar-item:last-child .editora-toolbar-button, | ||
| .rte-toolbar-group-items.${$} .rte-toolbar-item:last-child .rte-toolbar-button, | ||
| .editora-toolbar-group-items.${$} .editora-toolbar-item:last-child .editora-toolbar-button { | ||
| border-right: none; | ||
| } | ||
| ${k} .rte-toolbar-group-items.${y}, | ||
| ${k} .editora-toolbar-group-items.${y}, | ||
| ${k} .rte-toolbar-group-items.${$}, | ||
| ${k} .editora-toolbar-group-items.${$} { | ||
| border-color: #566275; | ||
| } | ||
| .rte-toolbar-button[data-command="toggleTranslationWorkflowPanel"].active, | ||
| .editora-toolbar-button[data-command="toggleTranslationWorkflowPanel"].active, | ||
| .rte-toolbar-button[data-command="toggleTranslationSegmentLock"].active, | ||
| .editora-toolbar-button[data-command="toggleTranslationSegmentLock"].active, | ||
| .rte-toolbar-button[data-command="toggleTranslationRealtime"].active, | ||
| .editora-toolbar-button[data-command="toggleTranslationRealtime"].active { | ||
| background: #ccc; | ||
| } | ||
| ${k} .rte-toolbar-group-items.${y} .rte-toolbar-button svg, | ||
| ${k} .editora-toolbar-group-items.${y} .editora-toolbar-button svg, | ||
| ${k} .rte-toolbar-group-items.${$} .rte-toolbar-button svg, | ||
| ${k} .editora-toolbar-group-items.${$} .editora-toolbar-button svg | ||
| { | ||
| fill: none; | ||
| } | ||
| ${k} .rte-toolbar-group-items.${y} .rte-toolbar-button, | ||
| ${k} .editora-toolbar-group-items.${y} .editora-toolbar-button | ||
| { | ||
| border-color: #566275; | ||
| } | ||
| ${k} .rte-toolbar-button[data-command="toggleTranslationWorkflowPanel"].active, | ||
| ${k} .editora-toolbar-button[data-command="toggleTranslationWorkflowPanel"].active, | ||
| ${k} .rte-toolbar-button[data-command="toggleTranslationSegmentLock"].active, | ||
| ${k} .editora-toolbar-button[data-command="toggleTranslationSegmentLock"].active, | ||
| ${k} .rte-toolbar-button[data-command="toggleTranslationRealtime"].active, | ||
| ${k} .editora-toolbar-button[data-command="toggleTranslationRealtime"].active { | ||
| background: linear-gradient(180deg, #5eaaf6 0%, #4a95de 100%); | ||
| } | ||
| .${d} { | ||
| position: fixed; | ||
| z-index: 12000; | ||
| display: none; | ||
| width: min(520px, calc(100vw - 20px)); | ||
| max-height: calc(100vh - 20px); | ||
| border: 1px solid #d1d5db; | ||
| border-radius: 14px; | ||
| background: #ffffff; | ||
| color: #0f172a; | ||
| box-shadow: 0 24px 48px rgba(15, 23, 42, 0.24); | ||
| overflow: hidden; | ||
| } | ||
| .${d}.show { | ||
| display: flex; | ||
| flex-direction: column; | ||
| } | ||
| .${d}.rte-translation-workflow-theme-dark { | ||
| border-color: #334155; | ||
| background: #0f172a; | ||
| color: #e2e8f0; | ||
| box-shadow: 0 24px 52px rgba(2, 6, 23, 0.68); | ||
| } | ||
| .rte-translation-header { | ||
| display: flex; | ||
| align-items: center; | ||
| justify-content: space-between; | ||
| gap: 8px; | ||
| padding: 12px 14px; | ||
| border-bottom: 1px solid #e2e8f0; | ||
| background: linear-gradient(180deg, #eff6ff 0%, #e2e8f0 100%); | ||
| } | ||
| .${d}.rte-translation-workflow-theme-dark .rte-translation-header { | ||
| border-color: #1e293b; | ||
| background: linear-gradient(180deg, #111827 0%, #0f172a 100%); | ||
| } | ||
| .rte-translation-title { | ||
| margin: 0; | ||
| font-size: 15px; | ||
| line-height: 1.2; | ||
| font-weight: 700; | ||
| } | ||
| .rte-translation-icon-btn { | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 6px; | ||
| min-height: 34px; | ||
| width: 34px; | ||
| background: #ffffff; | ||
| color: #0f172a; | ||
| font-size: 16px; | ||
| line-height: 1; | ||
| font-weight: 600; | ||
| padding: 0; | ||
| display: inline-flex; | ||
| align-items: center; | ||
| justify-content: center; | ||
| cursor: pointer; | ||
| } | ||
| .rte-translation-icon-btn:hover, | ||
| .rte-translation-icon-btn:focus-visible { | ||
| outline: none; | ||
| border-color: #3b82f6; | ||
| box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.2); | ||
| } | ||
| .${d}.rte-translation-workflow-theme-dark .rte-translation-icon-btn { | ||
| border-color: #475569; | ||
| background: #0f172a; | ||
| color: #e2e8f0; | ||
| } | ||
| .${d}.rte-translation-workflow-theme-dark .rte-translation-icon-btn:hover, | ||
| .${d}.rte-translation-workflow-theme-dark .rte-translation-icon-btn:focus-visible { | ||
| border-color: #60a5fa; | ||
| box-shadow: 0 0 0 3px rgba(96, 165, 250, 0.24); | ||
| } | ||
| .rte-translation-body { | ||
| display: flex; | ||
| flex-direction: column; | ||
| gap: 8px; | ||
| padding: 12px; | ||
| overflow: auto; | ||
| } | ||
| .rte-translation-locales { | ||
| display: grid; | ||
| grid-template-columns: repeat(2, minmax(0, 1fr)); | ||
| gap: 8px; | ||
| } | ||
| .rte-translation-locale-field { | ||
| display: grid; | ||
| gap: 4px; | ||
| } | ||
| .rte-translation-source-label, | ||
| .rte-translation-target-label { | ||
| font-size: 12px; | ||
| font-weight: 700; | ||
| color: #334155; | ||
| } | ||
| .${d}.rte-translation-workflow-theme-dark .rte-translation-source-label, | ||
| .${d}.rte-translation-workflow-theme-dark .rte-translation-target-label { | ||
| color: #cbd5e1; | ||
| } | ||
| .rte-translation-select { | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 8px; | ||
| min-height: 34px; | ||
| padding: 0 10px; | ||
| font-size: 13px; | ||
| background: #ffffff; | ||
| color: inherit; | ||
| } | ||
| .rte-translation-select:focus-visible { | ||
| border-color: #0e7490; | ||
| box-shadow: 0 0 0 3px rgba(14, 116, 144, 0.18); | ||
| outline: none; | ||
| } | ||
| .${d}.rte-translation-workflow-theme-dark .rte-translation-select { | ||
| border-color: #334155; | ||
| background: #0b1220; | ||
| color: #e2e8f0; | ||
| } | ||
| .rte-translation-summary, | ||
| .rte-translation-helper, | ||
| .rte-translation-shortcut { | ||
| margin: 0; | ||
| font-size: 12px; | ||
| line-height: 1.35; | ||
| color: #475569; | ||
| } | ||
| .${d}.rte-translation-workflow-theme-dark .rte-translation-summary, | ||
| .${d}.rte-translation-workflow-theme-dark .rte-translation-helper, | ||
| .${d}.rte-translation-workflow-theme-dark .rte-translation-shortcut { | ||
| color: #94a3b8; | ||
| } | ||
| .rte-translation-actions { | ||
| display: grid; | ||
| grid-template-columns: repeat(4, minmax(0, 1fr)); | ||
| gap: 8px; | ||
| } | ||
| .rte-translation-btn { | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 8px; | ||
| min-height: 34px; | ||
| padding: 0 8px; | ||
| background: #ffffff; | ||
| color: inherit; | ||
| font-size: 12px; | ||
| font-weight: 700; | ||
| cursor: pointer; | ||
| } | ||
| .rte-translation-btn:disabled { | ||
| opacity: 0.6; | ||
| cursor: not-allowed; | ||
| } | ||
| .rte-translation-btn-primary { | ||
| border-color: #0e7490; | ||
| background: #0e7490; | ||
| color: #f8fafc; | ||
| } | ||
| .rte-translation-btn:hover, | ||
| .rte-translation-btn:focus-visible { | ||
| border-color: #94a3b8; | ||
| outline: none; | ||
| } | ||
| .rte-translation-btn-primary:hover, | ||
| .rte-translation-btn-primary:focus-visible { | ||
| border-color: #155e75; | ||
| background: #155e75; | ||
| } | ||
| .${d}.rte-translation-workflow-theme-dark .rte-translation-btn { | ||
| border-color: #334155; | ||
| background: #111827; | ||
| color: #e2e8f0; | ||
| } | ||
| .${d}.rte-translation-workflow-theme-dark .rte-translation-btn-primary { | ||
| border-color: #22d3ee; | ||
| background: #0e7490; | ||
| color: #ecfeff; | ||
| } | ||
| .rte-translation-grid { | ||
| display: grid; | ||
| grid-template-columns: 1fr 1fr; | ||
| gap: 8px; | ||
| } | ||
| .rte-translation-segments-wrap, | ||
| .rte-translation-preview-wrap, | ||
| .rte-translation-issues-wrap { | ||
| border: 1px solid #e2e8f0; | ||
| border-radius: 10px; | ||
| background: #f8fafc; | ||
| padding: 8px; | ||
| min-height: 120px; | ||
| } | ||
| .${d}.rte-translation-workflow-theme-dark .rte-translation-segments-wrap, | ||
| .${d}.rte-translation-workflow-theme-dark .rte-translation-preview-wrap, | ||
| .${d}.rte-translation-workflow-theme-dark .rte-translation-issues-wrap { | ||
| border-color: #334155; | ||
| background: #0b1220; | ||
| } | ||
| .rte-translation-subtitle { | ||
| margin: 0 0 6px; | ||
| font-size: 12px; | ||
| font-weight: 700; | ||
| color: #334155; | ||
| } | ||
| .${d}.rte-translation-workflow-theme-dark .rte-translation-subtitle { | ||
| color: #cbd5e1; | ||
| } | ||
| .rte-translation-segments { | ||
| margin: 0; | ||
| padding: 0; | ||
| list-style: none; | ||
| display: grid; | ||
| gap: 6px; | ||
| max-height: 220px; | ||
| overflow: auto; | ||
| outline: none; | ||
| } | ||
| .rte-translation-segment-item { | ||
| display: grid; | ||
| grid-template-columns: 1fr auto; | ||
| gap: 6px; | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 8px; | ||
| background: #ffffff; | ||
| padding: 6px; | ||
| } | ||
| .rte-translation-segment-item.selected { | ||
| border-color: #0e7490; | ||
| box-shadow: 0 0 0 2px rgba(14, 116, 144, 0.16); | ||
| } | ||
| .rte-translation-segment-item.locked { | ||
| border-color: #f59e0b; | ||
| background: #fffbeb; | ||
| } | ||
| .${d}.rte-translation-workflow-theme-dark .rte-translation-segment-item { | ||
| border-color: #334155; | ||
| background: #111827; | ||
| } | ||
| .${d}.rte-translation-workflow-theme-dark .rte-translation-segment-item.locked { | ||
| border-color: rgba(245, 158, 11, 0.72); | ||
| background: rgba(120, 53, 15, 0.28); | ||
| } | ||
| .rte-translation-segment-select { | ||
| border: none; | ||
| background: transparent; | ||
| color: inherit; | ||
| text-align: left; | ||
| padding: 0; | ||
| cursor: pointer; | ||
| display: grid; | ||
| gap: 2px; | ||
| } | ||
| .rte-translation-segment-meta { | ||
| font-size: 11px; | ||
| color: #64748b; | ||
| font-weight: 700; | ||
| } | ||
| .rte-translation-segment-text { | ||
| font-size: 12px; | ||
| color: #334155; | ||
| line-height: 1.3; | ||
| } | ||
| .${d}.rte-translation-workflow-theme-dark .rte-translation-segment-meta { | ||
| color: #94a3b8; | ||
| } | ||
| .${d}.rte-translation-workflow-theme-dark .rte-translation-segment-text { | ||
| color: #e2e8f0; | ||
| } | ||
| .rte-translation-segment-lock { | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 8px; | ||
| width: 28px; | ||
| min-height: 28px; | ||
| background: #ffffff; | ||
| cursor: pointer; | ||
| position: relative; | ||
| color: inherit; | ||
| font-size: 0; | ||
| } | ||
| .rte-translation-segment-lock::before { | ||
| content: '🔒'; | ||
| font-size: 14px; | ||
| position: absolute; | ||
| inset: 0; | ||
| display: grid; | ||
| place-items: center; | ||
| opacity: 0.35; | ||
| } | ||
| .rte-translation-segment-lock[aria-pressed="true"]::before { | ||
| opacity: 1; | ||
| } | ||
| .${d}.rte-translation-workflow-theme-dark .rte-translation-segment-lock { | ||
| border-color: #334155; | ||
| background: #111827; | ||
| } | ||
| .rte-translation-preview-block { | ||
| display: grid; | ||
| gap: 4px; | ||
| margin-bottom: 8px; | ||
| } | ||
| .rte-translation-preview-label { | ||
| margin: 0; | ||
| font-size: 11px; | ||
| color: #64748b; | ||
| font-weight: 700; | ||
| } | ||
| .rte-translation-source-preview, | ||
| .rte-translation-target-preview { | ||
| margin: 0; | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 8px; | ||
| background: #ffffff; | ||
| padding: 8px; | ||
| font-size: 12px; | ||
| min-height: 56px; | ||
| white-space: pre-wrap; | ||
| line-height: 1.35; | ||
| color: #1f2937; | ||
| } | ||
| .${d}.rte-translation-workflow-theme-dark .rte-translation-preview-label { | ||
| color: #94a3b8; | ||
| } | ||
| .${d}.rte-translation-workflow-theme-dark .rte-translation-source-preview, | ||
| .${d}.rte-translation-workflow-theme-dark .rte-translation-target-preview { | ||
| border-color: #334155; | ||
| background: #111827; | ||
| color: #e2e8f0; | ||
| } | ||
| .rte-translation-issues { | ||
| margin: 0; | ||
| padding: 0; | ||
| list-style: none; | ||
| display: grid; | ||
| gap: 6px; | ||
| max-height: 200px; | ||
| overflow: auto; | ||
| } | ||
| .rte-translation-issue { | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 8px; | ||
| background: #ffffff; | ||
| padding: 8px; | ||
| display: grid; | ||
| gap: 4px; | ||
| cursor: pointer; | ||
| } | ||
| .rte-translation-issue.error { | ||
| border-color: #ef4444; | ||
| background: #fef2f2; | ||
| } | ||
| .rte-translation-issue.warning { | ||
| border-color: #f59e0b; | ||
| background: #fffbeb; | ||
| } | ||
| .rte-translation-issue.info { | ||
| border-color: #0ea5e9; | ||
| background: #f0f9ff; | ||
| } | ||
| .${d}.rte-translation-workflow-theme-dark .rte-translation-issue { | ||
| border-color: #334155; | ||
| background: #111827; | ||
| color: #e2e8f0; | ||
| } | ||
| .${d}.rte-translation-workflow-theme-dark .rte-translation-issue.error { | ||
| border-color: rgba(239, 68, 68, 0.7); | ||
| background: rgba(127, 29, 29, 0.28); | ||
| } | ||
| .${d}.rte-translation-workflow-theme-dark .rte-translation-issue.warning { | ||
| border-color: rgba(245, 158, 11, 0.72); | ||
| background: rgba(120, 53, 15, 0.28); | ||
| } | ||
| .${d}.rte-translation-workflow-theme-dark .rte-translation-issue.info { | ||
| border-color: rgba(14, 165, 233, 0.7); | ||
| background: rgba(7, 89, 133, 0.28); | ||
| } | ||
| .rte-translation-issue-message, | ||
| .rte-translation-issue-suggestion { | ||
| margin: 0; | ||
| font-size: 12px; | ||
| line-height: 1.35; | ||
| color: #1f2937; | ||
| } | ||
| .rte-translation-issue-suggestion { | ||
| color: #475569; | ||
| } | ||
| .${d}.rte-translation-workflow-theme-dark .rte-translation-issue-message { | ||
| color: #e2e8f0; | ||
| } | ||
| .${d}.rte-translation-workflow-theme-dark .rte-translation-issue-suggestion { | ||
| color: #cbd5e1; | ||
| } | ||
| .rte-translation-empty { | ||
| margin: 8px; | ||
| font-size: 12px; | ||
| color: #64748b; | ||
| } | ||
| .rte-translation-live { | ||
| position: absolute; | ||
| width: 1px; | ||
| height: 1px; | ||
| margin: -1px; | ||
| padding: 0; | ||
| overflow: hidden; | ||
| clip: rect(0 0 0 0); | ||
| border: 0; | ||
| } | ||
| [data-translation-locked="true"].rte-translation-segment-locked { | ||
| outline: 2px dashed rgba(245, 158, 11, 0.65); | ||
| outline-offset: 2px; | ||
| background: rgba(255, 251, 235, 0.8); | ||
| border-radius: 4px; | ||
| } | ||
| ${k} [data-translation-locked="true"].rte-translation-segment-locked { | ||
| outline-color: rgba(245, 158, 11, 0.75); | ||
| background: rgba(120, 53, 15, 0.22); | ||
| } | ||
| @media (max-width: 920px) { | ||
| .${d} { | ||
| left: 10px !important; | ||
| right: 10px; | ||
| top: 10px !important; | ||
| width: auto !important; | ||
| max-height: calc(100vh - 20px); | ||
| } | ||
| .rte-translation-locales, | ||
| .rte-translation-actions, | ||
| .rte-translation-grid { | ||
| grid-template-columns: 1fr; | ||
| } | ||
| } | ||
| `, document.head.appendChild(e); | ||
| } | ||
| const mt = (e = {}) => { | ||
| const n = ae(e), t = /* @__PURE__ */ new Set(); | ||
| return gt(), { | ||
| name: "translationWorkflow", | ||
| toolbar: [ | ||
| { | ||
| id: "translationWorkflowGroup", | ||
| label: "Translation Workflow", | ||
| type: "group", | ||
| command: "translationWorkflow", | ||
| items: [ | ||
| { | ||
| id: "toggleTranslationWorkflowPanel", | ||
| label: "Translation Workflow", | ||
| command: "toggleTranslationWorkflowPanel", | ||
| shortcut: "Mod-Alt-Shift-l", | ||
| icon: '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><path d="M4 6.5a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2v4a2 2 0 0 1-2 2H8l-4 3V6.5Z" stroke="currentColor" stroke-width="1.6"/><path d="M20 17.5a2 2 0 0 1-2 2h-8a2 2 0 0 1-2-2v-1.5" stroke="currentColor" stroke-width="1.6"/><path d="m13 8 2 2m0 0 2-2m-2 2V4" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/></svg>' | ||
| }, | ||
| { | ||
| id: "runTranslationLocaleValidation", | ||
| label: "Run Locale Validation", | ||
| command: "runTranslationLocaleValidation", | ||
| shortcut: "Mod-Alt-Shift-v", | ||
| icon: '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><rect x="4.5" y="4" width="12" height="16" rx="2" stroke="currentColor" stroke-width="1.6"/><path d="M8 8h5.5M8 11h4M8 14h3" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/><path d="m15.5 15.5 1.7 1.7 3.3-3.3" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/></svg>' | ||
| }, | ||
| { | ||
| id: "toggleTranslationSegmentLock", | ||
| label: "Toggle Segment Lock", | ||
| command: "toggleTranslationSegmentLock", | ||
| shortcut: "Mod-Alt-Shift-k", | ||
| icon: '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><rect x="5" y="10" width="14" height="10" rx="2" stroke="currentColor" stroke-width="1.6"/><path d="M8.5 10V7.5a3.5 3.5 0 1 1 7 0V10" stroke="currentColor" stroke-width="1.6"/><circle cx="12" cy="15" r="1.2" fill="currentColor"/></svg>' | ||
| }, | ||
| { | ||
| id: "toggleTranslationRealtime", | ||
| label: "Toggle Translation Realtime", | ||
| command: "toggleTranslationRealtime", | ||
| icon: '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><path d="M4.5 12a7.5 7.5 0 1 1 7.5 7.5" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/><path d="M9.5 19.5H5.5v-4" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/><path d="M12 8v4l2.5 2" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/></svg>' | ||
| } | ||
| ] | ||
| } | ||
| ], | ||
| commands: { | ||
| translationWorkflow: (r, a) => { | ||
| const o = T(a, !1, !1); | ||
| if (!o) return !1; | ||
| const l = u.get(o) || n; | ||
| return b(o, l), u.set(o, l), x = o, he(o), !0; | ||
| }, | ||
| openTranslationWorkflowPanel: (r, a) => { | ||
| const o = T(a, !1, !1); | ||
| if (!o) return !1; | ||
| const l = u.get(o) || n; | ||
| return b(o, l), u.set(o, l), x = o, he(o), !0; | ||
| }, | ||
| toggleTranslationWorkflowPanel: (r, a) => { | ||
| const o = T(a, !1, !1); | ||
| if (!o) return !1; | ||
| const l = u.get(o) || n; | ||
| return b(o, l), u.set(o, l), x = o, ze(o, typeof r == "boolean" ? r : void 0); | ||
| }, | ||
| runTranslationLocaleValidation: (r, a) => { | ||
| const o = T(a, !1, !1); | ||
| if (!o) return !1; | ||
| const l = u.get(o) || n; | ||
| return b(o, l), u.set(o, l), x = o, L(o, "command", !0), !0; | ||
| }, | ||
| toggleTranslationRealtime: (r, a) => { | ||
| const o = T(a, !1, !1); | ||
| if (!o) return !1; | ||
| const l = u.get(o) || n; | ||
| return b(o, l), u.set(o, l), x = o, De(o, typeof r == "boolean" ? r : void 0); | ||
| }, | ||
| toggleTranslationSegmentLock: (r, a) => { | ||
| const o = T(a, !1, !1); | ||
| if (!o) return !1; | ||
| const l = u.get(o) || n; | ||
| b(o, l), u.set(o, l), x = o; | ||
| const s = typeof r == "boolean" ? r : r == null ? void 0 : r.locked, i = typeof r == "object" ? r == null ? void 0 : r.segmentId : void 0; | ||
| return ie(o, i, s); | ||
| }, | ||
| setTranslationLocales: (r, a) => { | ||
| const o = T(a, !1, !1); | ||
| if (!o || !r || typeof r != "object") return !1; | ||
| const l = u.get(o) || n, s = b(o, l); | ||
| return u.set(o, l), typeof r.sourceLocale == "string" && r.sourceLocale.trim() && (s.sourceLocale = A(r.sourceLocale)), typeof r.targetLocale == "string" && r.targetLocale.trim() && (s.targetLocale = A(r.targetLocale)), s.snapshot = "", L(o, "set-locales", !0), !0; | ||
| }, | ||
| captureTranslationSourceSnapshot: (r, a) => { | ||
| const o = T(a, !1, !1); | ||
| if (!o) return !1; | ||
| const l = u.get(o) || n; | ||
| return b(o, l), u.set(o, l), x = o, Pe(o); | ||
| }, | ||
| setTranslationWorkflowOptions: (r, a) => { | ||
| const o = T(a, !1, !1); | ||
| if (!o || !r || typeof r != "object") return !1; | ||
| const l = u.get(o) || n, s = oe.get(o) || Ge(l), i = { | ||
| ...s, | ||
| ...r, | ||
| labels: { | ||
| ...s.labels || {}, | ||
| ...r.labels || {} | ||
| }, | ||
| localeRules: Array.isArray(r.localeRules) ? r.localeRules : s.localeRules, | ||
| locales: Array.isArray(r.locales) ? r.locales : s.locales, | ||
| normalizeText: r.normalizeText || l.normalizeText | ||
| }, c = ae(i); | ||
| u.set(o, c), oe.set(o, i); | ||
| const g = b(o, c); | ||
| return typeof r.enableRealtime == "boolean" && (g.realtimeEnabled = r.enableRealtime), typeof r.sourceLocale == "string" && r.sourceLocale.trim() && (g.sourceLocale = A(r.sourceLocale)), typeof r.targetLocale == "string" && r.targetLocale.trim() && (g.targetLocale = A(r.targetLocale)), g.snapshot = "", L(o, "set-options", !0), R(o), E(o), !0; | ||
| }, | ||
| getTranslationWorkflowState: (r, a) => { | ||
| const o = T(a, !1, !1); | ||
| if (!o) return !1; | ||
| const l = u.get(o) || n; | ||
| b(o, l); | ||
| const s = qe(o); | ||
| if (typeof r == "function") | ||
| try { | ||
| r(s); | ||
| } catch (i) { | ||
| } | ||
| return o.__translationWorkflowState = s, o.dispatchEvent( | ||
| new CustomEvent("editora:translation-workflow-state", { | ||
| bubbles: !0, | ||
| detail: s | ||
| }) | ||
| ), !0; | ||
| } | ||
| }, | ||
| keymap: { | ||
| "Mod-Alt-Shift-l": "toggleTranslationWorkflowPanel", | ||
| "Mod-Alt-Shift-L": "toggleTranslationWorkflowPanel", | ||
| "Mod-Alt-Shift-v": "runTranslationLocaleValidation", | ||
| "Mod-Alt-Shift-V": "runTranslationLocaleValidation", | ||
| "Mod-Alt-Shift-k": "toggleTranslationSegmentLock", | ||
| "Mod-Alt-Shift-K": "toggleTranslationSegmentLock" | ||
| }, | ||
| init: function(a) { | ||
| ee += 1; | ||
| const o = this && typeof this.__pluginConfig == "object" ? { ...e, ...this.__pluginConfig } : e, l = ae(o); | ||
| dt(l); | ||
| const s = T( | ||
| a != null && a.editorElement ? { editorElement: a.editorElement } : void 0, | ||
| !1, | ||
| !1 | ||
| ); | ||
| if (!s) return; | ||
| x = s, t.add(s); | ||
| const i = b(s, l); | ||
| u.set(s, l), oe.set(s, o), i.segments = M(s, l, i), L(s, "init", !0), E(s); | ||
| }, | ||
| destroy: () => { | ||
| t.forEach((r) => Se(r)), t.clear(), ee = Math.max(0, ee - 1), !(ee > 0) && ft(); | ||
| } | ||
| }; | ||
| }; | ||
| export { | ||
| mt as TranslationWorkflowPlugin | ||
| }; | ||
| //# sourceMappingURL=TranslationWorkflowPlugin.native-Bz6jDGvj.mjs.map |
| const $ = ".rte-content, .editora-content", d = '[data-theme="dark"], .dark, .editora-theme-dark, .rte-theme-dark', l = "rte-version-diff-overlay", J = "rte-version-diff-styles", fe = { | ||
| title: "Version Diff", | ||
| baseline: "Baseline", | ||
| current: "Current", | ||
| noChanges: "No changes detected between baseline and current content.", | ||
| loading: "Preparing diff...", | ||
| tabInline: "Inline Diff", | ||
| tabSideBySide: "Side by Side", | ||
| refresh: "Refresh", | ||
| setBaseline: "Set Current as Baseline", | ||
| close: "Close", | ||
| mode: "Mode", | ||
| ignoreWhitespace: "Ignore whitespace", | ||
| largeDocFallback: "Large document fallback mode applied for performance." | ||
| }, w = /* @__PURE__ */ new WeakMap(), R = /* @__PURE__ */ new WeakMap(); | ||
| let j = 0, H = null, z = null, V = null, S = null, M = null, D = null; | ||
| function u(e) { | ||
| return e.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'"); | ||
| } | ||
| function de(e) { | ||
| return { | ||
| ...fe, | ||
| ...e || {} | ||
| }; | ||
| } | ||
| function N(e, i = !0) { | ||
| if ((e == null ? void 0 : e.contentElement) instanceof HTMLElement) return e.contentElement; | ||
| if ((e == null ? void 0 : e.editorElement) instanceof HTMLElement) { | ||
| const r = e.editorElement; | ||
| if (r.matches($)) return r; | ||
| const o = r.querySelector($); | ||
| if (o instanceof HTMLElement) return o; | ||
| } | ||
| const t = window.getSelection(); | ||
| if (t && t.rangeCount > 0) { | ||
| const r = t.getRangeAt(0).startContainer, o = r.nodeType === Node.ELEMENT_NODE ? r : r.parentElement, f = o == null ? void 0 : o.closest($); | ||
| if (f) return f; | ||
| } | ||
| const n = document.activeElement; | ||
| if (n) { | ||
| if (n.matches($)) return n; | ||
| const r = n.closest($); | ||
| if (r) return r; | ||
| } | ||
| return D && D.isConnected ? D : i ? document.querySelector($) : null; | ||
| } | ||
| function O(e) { | ||
| return e.closest("[data-editora-editor], .rte-editor, .editora-editor, editora-editor") || e; | ||
| } | ||
| function P(e) { | ||
| if (!e) return !1; | ||
| const i = e.getAttribute("data-theme") || e.getAttribute("theme"); | ||
| if (i && i.toLowerCase() === "dark") return !0; | ||
| const t = e.classList; | ||
| return t.contains("dark") || t.contains("editora-theme-dark") || t.contains("rte-theme-dark"); | ||
| } | ||
| function Q(e) { | ||
| const i = O(e); | ||
| if (P(i)) return !0; | ||
| const t = i.closest("[data-theme], [theme], .dark, .editora-theme-dark, .rte-theme-dark"); | ||
| return !!(P(t) || P(document.documentElement) || P(document.body)); | ||
| } | ||
| function ce(e) { | ||
| const i = document.createElement("textarea"); | ||
| return i.innerHTML = e, i.value; | ||
| } | ||
| function W(e) { | ||
| const t = O(e).getAttribute("data-initial-content"); | ||
| return t ? ce(t) : e.innerHTML; | ||
| } | ||
| function te(e) { | ||
| return e.replace(/\r\n?/g, ` | ||
| `); | ||
| } | ||
| function X(e) { | ||
| const i = document.createElement("div"), t = e.replace(/<br\s*\/?>/gi, ` | ||
| `).replace(/<\/(p|div|h1|h2|h3|h4|h5|h6|li|tr|blockquote|pre|section|article)>/gi, `$& | ||
| `); | ||
| i.innerHTML = t; | ||
| const n = i.textContent || ""; | ||
| return te(n).replace(/\u00a0/g, " ").replace(/\n{3,}/g, ` | ||
| `).trim(); | ||
| } | ||
| function Z(e, i, t) { | ||
| let n = te(e); | ||
| if (t && (n = n.replace(/[ \t]+/g, " ").replace(/\n{3,}/g, ` | ||
| `).trim()), !n) return []; | ||
| if (i === "line") | ||
| return n.split(` | ||
| `); | ||
| if (t) | ||
| return n.split(/\s+/).filter(Boolean); | ||
| const r = [], o = n.split(` | ||
| `); | ||
| return o.forEach((f, g) => { | ||
| const c = f.split(/[ \t]+/).filter(Boolean); | ||
| r.push(...c), g < o.length - 1 && r.push(` | ||
| `); | ||
| }), r; | ||
| } | ||
| function ue(e, i, t) { | ||
| if (e.length === 0) return ""; | ||
| if (i === "line") return e.join(` | ||
| `); | ||
| if (t) return e.join(" "); | ||
| let n = ""; | ||
| for (let r = 0; r < e.length; r += 1) { | ||
| const o = e[r]; | ||
| if (o === ` | ||
| `) { | ||
| n = n.replace(/[ \t]+$/g, ""), n += ` | ||
| `; | ||
| continue; | ||
| } | ||
| n.length > 0 && !n.endsWith(` | ||
| `) && (n += " "), n += o; | ||
| } | ||
| return n; | ||
| } | ||
| function pe(e, i, t) { | ||
| const n = []; | ||
| return e.forEach((r) => { | ||
| const o = n[n.length - 1]; | ||
| if (o && o.type === r.type) { | ||
| o.tokens.push(r.token); | ||
| return; | ||
| } | ||
| n.push({ type: r.type, tokens: [r.token] }); | ||
| }), n.map((r) => ({ | ||
| type: r.type, | ||
| value: ue(r.tokens, i, t), | ||
| count: r.tokens.length | ||
| })); | ||
| } | ||
| function be(e, i) { | ||
| let t = 0; | ||
| for (; t < e.length && t < i.length && e[t] === i[t]; ) | ||
| t += 1; | ||
| let n = e.length - 1, r = i.length - 1; | ||
| for (; n >= t && r >= t && e[n] === i[r]; ) | ||
| n -= 1, r -= 1; | ||
| const o = e.slice(0, t), f = n < e.length - 1 ? e.slice(n + 1) : [], g = t <= n ? e.slice(t, n + 1) : [], c = t <= r ? i.slice(t, r + 1) : []; | ||
| return { prefix: o, suffix: f, aMiddle: g, bMiddle: c }; | ||
| } | ||
| function he(e, i, t, n, r, o) { | ||
| if (e.length === 0 && i.length === 0) | ||
| return { segments: [], insertedCount: 0, deletedCount: 0, equalCount: 0, usedFallback: !1 }; | ||
| const { prefix: f, suffix: g, aMiddle: c, bMiddle: b } = be(e, i); | ||
| let m = []; | ||
| f.forEach((a) => m.push({ type: "equal", token: a })); | ||
| const F = c.length * b.length, T = c.length > o || b.length > o || F > r; | ||
| if (T) | ||
| c.forEach((a) => m.push({ type: "delete", token: a })), b.forEach((a) => m.push({ type: "insert", token: a })); | ||
| else { | ||
| const a = Array.from({ length: c.length + 1 }, () => new Uint32Array(b.length + 1)); | ||
| for (let k = c.length - 1; k >= 0; k -= 1) { | ||
| const A = a[k], I = a[k + 1]; | ||
| for (let x = b.length - 1; x >= 0; x -= 1) | ||
| A[x] = c[k] === b[x] ? I[x + 1] + 1 : Math.max(I[x], A[x + 1]); | ||
| } | ||
| let h = 0, p = 0; | ||
| for (; h < c.length && p < b.length; ) | ||
| c[h] === b[p] ? (m.push({ type: "equal", token: c[h] }), h += 1, p += 1) : a[h + 1][p] >= a[h][p + 1] ? (m.push({ type: "delete", token: c[h] }), h += 1) : (m.push({ type: "insert", token: b[p] }), p += 1); | ||
| for (; h < c.length; ) | ||
| m.push({ type: "delete", token: c[h] }), h += 1; | ||
| for (; p < b.length; ) | ||
| m.push({ type: "insert", token: b[p] }), p += 1; | ||
| } | ||
| g.forEach((a) => m.push({ type: "equal", token: a })); | ||
| const q = pe(m, t, n); | ||
| let B = 0, L = 0, K = 0; | ||
| return q.forEach((a) => { | ||
| a.type === "insert" && (B += a.count), a.type === "delete" && (L += a.count), a.type === "equal" && (K += a.count); | ||
| }), { | ||
| segments: q, | ||
| insertedCount: B, | ||
| deletedCount: L, | ||
| equalCount: K, | ||
| usedFallback: T | ||
| }; | ||
| } | ||
| function re(e) { | ||
| return u(e.value).replace(/\n/g, ` | ||
| `); | ||
| } | ||
| function ve(e, i) { | ||
| return e.length === 0 ? `<p class="rte-version-diff-empty">${u(i.noChanges)}</p>` : e.map((t) => `<span class="${t.type === "equal" ? "rte-version-diff-equal" : t.type === "insert" ? "rte-version-diff-insert" : "rte-version-diff-delete"}">${re(t)}</span>`).join(""); | ||
| } | ||
| function me(e, i) { | ||
| if (e.length === 0) { | ||
| const r = `<p class="rte-version-diff-empty">${u(i.noChanges)}</p>`; | ||
| return { baselineHtml: r, currentHtml: r }; | ||
| } | ||
| const t = [], n = []; | ||
| return e.forEach((r) => { | ||
| const o = re(r); | ||
| if (r.type === "equal") { | ||
| t.push(`<span class="rte-version-diff-equal">${o}</span>`), n.push(`<span class="rte-version-diff-equal">${o}</span>`); | ||
| return; | ||
| } | ||
| if (r.type === "delete") { | ||
| t.push(`<span class="rte-version-diff-delete">${o}</span>`); | ||
| return; | ||
| } | ||
| n.push(`<span class="rte-version-diff-insert">${o}</span>`); | ||
| }), { | ||
| baselineHtml: t.join(""), | ||
| currentHtml: n.join("") | ||
| }; | ||
| } | ||
| function ge(e) { | ||
| const i = e.metaKey || e.ctrlKey, n = (typeof e.key == "string" ? e.key : "").toLowerCase(), r = typeof e.code == "string" ? e.code.toLowerCase() : "", o = i && e.altKey && !e.shiftKey && (n === "d" || r === "keyd"), f = !e.metaKey && !e.ctrlKey && !e.altKey && !e.shiftKey && (n === "f8" || r === "f8"); | ||
| return o || f; | ||
| } | ||
| function ye() { | ||
| if (typeof document == "undefined" || document.getElementById(J)) return; | ||
| const e = document.createElement("style"); | ||
| e.id = J, e.textContent = ` | ||
| .${l} { | ||
| position: fixed; | ||
| inset: 0; | ||
| background: rgba(15, 23, 42, 0.55); | ||
| z-index: 2147483646; | ||
| display: flex; | ||
| align-items: center; | ||
| justify-content: center; | ||
| padding: 20px; | ||
| } | ||
| .rte-version-diff-dialog { | ||
| width: min(980px, 96vw); | ||
| max-height: min(90vh, 860px); | ||
| background: #ffffff; | ||
| color: #0f172a; | ||
| border: 1px solid #d7dee8; | ||
| border-radius: 8px; | ||
| display: flex; | ||
| flex-direction: column; | ||
| box-shadow: 0 24px 48px rgba(15, 23, 42, 0.3); | ||
| overflow: hidden; | ||
| } | ||
| .rte-version-diff-header, | ||
| .rte-version-diff-footer { | ||
| padding: 12px 14px; | ||
| border-bottom: 1px solid #e2e8f0; | ||
| background: #f8fafc; | ||
| display: flex; | ||
| align-items: center; | ||
| gap: 10px; | ||
| flex-wrap: wrap; | ||
| } | ||
| .rte-version-diff-footer { | ||
| border-top: 1px solid #e2e8f0; | ||
| border-bottom: none; | ||
| justify-content: space-between; | ||
| } | ||
| .rte-version-diff-title { | ||
| margin: 0; | ||
| font-size: 16px; | ||
| font-weight: 700; | ||
| flex: 1; | ||
| } | ||
| .rte-version-diff-controls { | ||
| display: flex; | ||
| align-items: center; | ||
| gap: 10px; | ||
| flex-wrap: wrap; | ||
| } | ||
| .rte-version-diff-select, | ||
| .rte-version-diff-btn { | ||
| border: 1px solid #cbd5e1; | ||
| background: #ffffff; | ||
| color: #0f172a; | ||
| border-radius: 6px; | ||
| min-height: 34px; | ||
| padding: 6px 10px; | ||
| font-size: 13px; | ||
| cursor: pointer; | ||
| } | ||
| .rte-version-diff-btn:hover, | ||
| .rte-version-diff-btn:focus-visible, | ||
| .rte-version-diff-select:focus-visible { | ||
| outline: none; | ||
| border-color: #3b82f6; | ||
| box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.2); | ||
| } | ||
| .rte-version-diff-btn-primary { | ||
| background: #2563eb; | ||
| border-color: #2563eb; | ||
| color: #ffffff; | ||
| } | ||
| .rte-version-diff-btn-primary:hover { | ||
| background: #1d4ed8; | ||
| } | ||
| .rte-version-diff-close-btn { | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 6px; | ||
| min-height: 34px; | ||
| min-width: 34px; | ||
| width: 34px; | ||
| height: 34px; | ||
| padding: 0; | ||
| display: inline-flex; | ||
| align-items: center; | ||
| justify-content: center; | ||
| background: #ffffff; | ||
| color: #0f172a; | ||
| font-size: 16px; | ||
| line-height: 1; | ||
| font-weight: 600; | ||
| } | ||
| .rte-version-diff-close-btn:hover, | ||
| .rte-version-diff-close-btn:focus-visible { | ||
| border-color: #3b82f6; | ||
| box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.2); | ||
| background: #ffffff; | ||
| outline: none; | ||
| } | ||
| .rte-version-diff-tabs { | ||
| display: flex; | ||
| gap: 6px; | ||
| border-bottom: 1px solid #e2e8f0; | ||
| background: #f8fafc; | ||
| padding: 8px 14px; | ||
| } | ||
| .rte-version-diff-tab { | ||
| border: 1px solid #cbd5e1; | ||
| background: #ffffff; | ||
| color: #0f172a; | ||
| border-radius: 6px; | ||
| min-height: 32px; | ||
| padding: 4px 10px; | ||
| font-size: 13px; | ||
| cursor: pointer; | ||
| } | ||
| .rte-version-diff-tab[aria-selected="true"] { | ||
| background: #dbeafe; | ||
| border-color: #60a5fa; | ||
| color: #1e3a8a; | ||
| } | ||
| .rte-version-diff-body { | ||
| flex: 1; | ||
| overflow: auto; | ||
| padding: 10px 14px 14px; | ||
| background: #ffffff; | ||
| } | ||
| .rte-version-diff-summary { | ||
| font-size: 12px; | ||
| color: #475569; | ||
| margin-bottom: 10px; | ||
| display: flex; | ||
| gap: 14px; | ||
| flex-wrap: wrap; | ||
| } | ||
| .rte-version-diff-panel { | ||
| display: none; | ||
| } | ||
| .rte-version-diff-panel.active { | ||
| display: block; | ||
| } | ||
| .rte-version-diff-inline, | ||
| .rte-version-diff-side-pane { | ||
| border: 1px solid #dbe3ec; | ||
| border-radius: 6px; | ||
| padding: 10px; | ||
| min-height: 140px; | ||
| max-height: 50vh; | ||
| overflow: auto; | ||
| white-space: pre-wrap; | ||
| word-break: break-word; | ||
| font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; | ||
| font-size: 12px; | ||
| line-height: 1.5; | ||
| background: #ffffff; | ||
| } | ||
| .rte-version-diff-side-grid { | ||
| display: grid; | ||
| grid-template-columns: 1fr 1fr; | ||
| gap: 10px; | ||
| } | ||
| .rte-version-diff-pane-title { | ||
| margin: 0 0 6px; | ||
| font-size: 12px; | ||
| font-weight: 700; | ||
| color: #334155; | ||
| } | ||
| .rte-version-diff-equal { color: inherit; } | ||
| .rte-version-diff-insert { | ||
| background: rgba(22, 163, 74, 0.18); | ||
| color: #14532d; | ||
| border-radius: 2px; | ||
| } | ||
| .rte-version-diff-delete { | ||
| background: rgba(220, 38, 38, 0.18); | ||
| color: #7f1d1d; | ||
| text-decoration: line-through; | ||
| border-radius: 2px; | ||
| } | ||
| .rte-version-diff-empty { | ||
| margin: 0; | ||
| color: #64748b; | ||
| font-size: 13px; | ||
| } | ||
| ${d} .rte-version-diff-dialog, | ||
| .${l}.rte-version-diff-theme-dark .rte-version-diff-dialog { | ||
| background: #1f2937; | ||
| color: #e5e7eb; | ||
| border-color: #334155; | ||
| } | ||
| ${d} .rte-version-diff-header, | ||
| ${d} .rte-version-diff-footer, | ||
| ${d} .rte-version-diff-tabs, | ||
| .${l}.rte-version-diff-theme-dark .rte-version-diff-header, | ||
| .${l}.rte-version-diff-theme-dark .rte-version-diff-footer, | ||
| .${l}.rte-version-diff-theme-dark .rte-version-diff-tabs { | ||
| background: #111827; | ||
| border-color: #334155; | ||
| } | ||
| ${d} .rte-version-diff-body, | ||
| .${l}.rte-version-diff-theme-dark .rte-version-diff-body { | ||
| background: #1f2937; | ||
| } | ||
| ${d} .rte-version-diff-select, | ||
| ${d} .rte-version-diff-btn, | ||
| ${d} .rte-version-diff-tab, | ||
| .${l}.rte-version-diff-theme-dark .rte-version-diff-select, | ||
| .${l}.rte-version-diff-theme-dark .rte-version-diff-btn, | ||
| .${l}.rte-version-diff-theme-dark .rte-version-diff-tab { | ||
| background: #0f172a; | ||
| color: #e5e7eb; | ||
| border-color: #475569; | ||
| } | ||
| ${d} .rte-version-diff-close-btn, | ||
| .${l}.rte-version-diff-theme-dark .rte-version-diff-close-btn { | ||
| background: #0f172a; | ||
| border-color: #475569; | ||
| color: #e2e8f0; | ||
| } | ||
| ${d} .rte-version-diff-close-btn:hover, | ||
| ${d} .rte-version-diff-close-btn:focus-visible, | ||
| .${l}.rte-version-diff-theme-dark .rte-version-diff-close-btn:hover, | ||
| .${l}.rte-version-diff-theme-dark .rte-version-diff-close-btn:focus-visible { | ||
| border-color: #60a5fa; | ||
| box-shadow: 0 0 0 3px rgba(96, 165, 250, 0.24); | ||
| outline: none; | ||
| } | ||
| ${d} .rte-version-diff-tab[aria-selected="true"], | ||
| .${l}.rte-version-diff-theme-dark .rte-version-diff-tab[aria-selected="true"] { | ||
| background: #1e3a8a; | ||
| border-color: #3b82f6; | ||
| color: #dbeafe; | ||
| } | ||
| ${d} .rte-version-diff-inline, | ||
| ${d} .rte-version-diff-side-pane, | ||
| .${l}.rte-version-diff-theme-dark .rte-version-diff-inline, | ||
| .${l}.rte-version-diff-theme-dark .rte-version-diff-side-pane { | ||
| background: #0f172a; | ||
| border-color: #334155; | ||
| color: #e5e7eb; | ||
| } | ||
| ${d} .rte-version-diff-pane-title, | ||
| ${d} .rte-version-diff-summary, | ||
| ${d} .rte-version-diff-empty, | ||
| .${l}.rte-version-diff-theme-dark .rte-version-diff-pane-title, | ||
| .${l}.rte-version-diff-theme-dark .rte-version-diff-summary, | ||
| .${l}.rte-version-diff-theme-dark .rte-version-diff-empty { | ||
| color: #94a3b8; | ||
| } | ||
| ${d} .rte-version-diff-insert, | ||
| .${l}.rte-version-diff-theme-dark .rte-version-diff-insert { | ||
| background: rgba(22, 163, 74, 0.25); | ||
| color: #bbf7d0; | ||
| } | ||
| ${d} .rte-version-diff-delete, | ||
| .${l}.rte-version-diff-theme-dark .rte-version-diff-delete { | ||
| background: rgba(220, 38, 38, 0.25); | ||
| color: #fecaca; | ||
| } | ||
| :is(${d}) .rte-toolbar-item .rte-toolbar-button[data-command="openVersionDiff"] svg{ | ||
| fill: none; | ||
| } | ||
| `, document.head.appendChild(e); | ||
| } | ||
| async function ke(e, i, t) { | ||
| if (t != null) return t; | ||
| if (typeof i.getBaselineHtml == "function") { | ||
| const o = O(e), f = await Promise.resolve(i.getBaselineHtml({ editor: e, editorRoot: o })); | ||
| if (typeof f == "string") return f; | ||
| } | ||
| const n = w.get(e); | ||
| if (typeof n == "string") return n; | ||
| if (typeof i.baselineHtml == "string") return i.baselineHtml; | ||
| const r = W(e); | ||
| return w.set(e, r), r; | ||
| } | ||
| function xe(e) { | ||
| const i = e.querySelector( | ||
| 'button:not([disabled]), select:not([disabled]), input:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])' | ||
| ); | ||
| i == null || i.focus(); | ||
| } | ||
| function $e(e, i) { | ||
| if (e.key !== "Tab") return; | ||
| const t = Array.from(i.querySelectorAll( | ||
| 'button:not([disabled]), select:not([disabled]), input:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])' | ||
| )).filter((f) => !f.hasAttribute("disabled")); | ||
| if (t.length === 0) return; | ||
| const n = t[0], r = t[t.length - 1], o = document.activeElement; | ||
| e.shiftKey && o === n ? (e.preventDefault(), r.focus()) : !e.shiftKey && o === r && (e.preventDefault(), n.focus()); | ||
| } | ||
| function ne() { | ||
| z && (z(), z = null); | ||
| } | ||
| function ee(e) { | ||
| !e || w.has(e) || w.set(e, W(e)); | ||
| } | ||
| function Ee(e) { | ||
| var i, t; | ||
| return { | ||
| baselineHtml: e.baselineHtml, | ||
| getBaselineHtml: e.getBaselineHtml, | ||
| mode: e.mode || "word", | ||
| ignoreWhitespace: e.ignoreWhitespace !== !1, | ||
| maxTokens: Math.max(200, (i = e.maxTokens) != null ? i : 1200), | ||
| maxMatrixSize: Math.max(5e4, (t = e.maxMatrixSize) != null ? t : 1e6), | ||
| labels: de(e.labels) | ||
| }; | ||
| } | ||
| function ie(e, i, t) { | ||
| var _; | ||
| ne(), D = e, R.set(e, i); | ||
| const n = document.createElement("div"); | ||
| n.className = l, Q(e) && n.classList.add("rte-version-diff-theme-dark"); | ||
| const r = document.createElement("section"); | ||
| r.className = "rte-version-diff-dialog", r.setAttribute("role", "dialog"), r.setAttribute("aria-modal", "true"), r.setAttribute("aria-labelledby", "rte-version-diff-title"); | ||
| const o = i.labels; | ||
| let f = (t == null ? void 0 : t.mode) || i.mode, g = (_ = t == null ? void 0 : t.ignoreWhitespace) != null ? _ : i.ignoreWhitespace, c = "inline"; | ||
| r.innerHTML = ` | ||
| <header class="rte-version-diff-header"> | ||
| <h2 id="rte-version-diff-title" class="rte-version-diff-title">${u(o.title)}</h2> | ||
| <div class="rte-version-diff-controls"> | ||
| <label> | ||
| <span>${u(o.mode)}:</span> | ||
| <select class="rte-version-diff-select" aria-label="${u(o.mode)}"> | ||
| <option value="word">Word</option> | ||
| <option value="line">Line</option> | ||
| </select> | ||
| </label> | ||
| <label class="rte-version-diff-checkbox"> | ||
| <input type="checkbox" class="rte-version-diff-ignore-ws" ${g ? "checked" : ""}> | ||
| ${u(o.ignoreWhitespace)} | ||
| </label> | ||
| <button type="button" class="rte-version-diff-btn rte-version-diff-set-baseline" aria-label="${u(o.setBaseline)}">${u(o.setBaseline)}</button> | ||
| <button type="button" class="rte-version-diff-btn" data-action="refresh" aria-label="${u(o.refresh)}">${u(o.refresh)}</button> | ||
| <button type="button" class="rte-version-diff-btn rte-version-diff-close-btn" data-action="close" aria-label="${u(o.close)}">✕</button> | ||
| </div> | ||
| </header> | ||
| <div class="rte-version-diff-tabs" role="tablist" aria-label="Diff views"> | ||
| <button type="button" role="tab" class="rte-version-diff-tab" data-tab="inline" aria-selected="true">${u(o.tabInline)}</button> | ||
| <button type="button" role="tab" class="rte-version-diff-tab" data-tab="side" aria-selected="false">${u(o.tabSideBySide)}</button> | ||
| </div> | ||
| <main class="rte-version-diff-body"> | ||
| <div class="rte-version-diff-summary" aria-live="polite"></div> | ||
| <section class="rte-version-diff-panel active" data-panel="inline" role="tabpanel"> | ||
| <div class="rte-version-diff-inline" aria-label="Inline diff result"></div> | ||
| </section> | ||
| <section class="rte-version-diff-panel" data-panel="side" role="tabpanel"> | ||
| <div class="rte-version-diff-side-grid"> | ||
| <div> | ||
| <h3 class="rte-version-diff-pane-title">${u(o.baseline)}</h3> | ||
| <div class="rte-version-diff-side-pane" data-side="baseline" aria-label="${u(o.baseline)}"></div> | ||
| </div> | ||
| <div> | ||
| <h3 class="rte-version-diff-pane-title">${u(o.current)}</h3> | ||
| <div class="rte-version-diff-side-pane" data-side="current" aria-label="${u(o.current)}"></div> | ||
| </div> | ||
| </div> | ||
| </section> | ||
| </main> | ||
| <footer class="rte-version-diff-footer"> | ||
| <small>Shortcut: Ctrl/Cmd + Alt + D (fallback: F8)</small> | ||
| <small>Esc: close</small> | ||
| </footer> | ||
| `, n.appendChild(r), document.body.appendChild(n); | ||
| const b = r.querySelector(".rte-version-diff-select"); | ||
| b.value = f; | ||
| const m = r.querySelector(".rte-version-diff-ignore-ws"), F = r.querySelector(".rte-version-diff-summary"), T = r.querySelector(".rte-version-diff-inline"), q = r.querySelector('[data-side="baseline"]'), B = r.querySelector('[data-side="current"]'); | ||
| let L = 0; | ||
| const K = () => { | ||
| const s = `<p class="rte-version-diff-empty">${u(o.loading)}</p>`; | ||
| T.innerHTML = s, q.innerHTML = s, B.innerHTML = s, F.textContent = ""; | ||
| }, a = async (s) => { | ||
| var Y; | ||
| L += 1; | ||
| const v = L; | ||
| n.classList.toggle("rte-version-diff-theme-dark", Q(e)), K(); | ||
| const y = e.innerHTML; | ||
| let E = ""; | ||
| try { | ||
| E = await ke(e, i, s != null ? s : t == null ? void 0 : t.baselineHtml); | ||
| } catch (Se) { | ||
| E = (Y = w.get(e)) != null ? Y : W(e); | ||
| } | ||
| if (v !== L || !n.isConnected) return; | ||
| const oe = X(E), se = X(y), ae = Z(oe, f, g), le = Z(se, f, g), C = he( | ||
| ae, | ||
| le, | ||
| f, | ||
| g, | ||
| i.maxMatrixSize, | ||
| i.maxTokens | ||
| ), G = me(C.segments, o); | ||
| T.innerHTML = ve(C.segments, o), q.innerHTML = G.baselineHtml, B.innerHTML = G.currentHtml; | ||
| const U = [ | ||
| `+${C.insertedCount} inserted`, | ||
| `-${C.deletedCount} deleted`, | ||
| `${C.equalCount} unchanged` | ||
| ]; | ||
| C.usedFallback && U.push(o.largeDocFallback), F.textContent = U.join(" | "); | ||
| }, h = (s) => { | ||
| c = s, r.querySelectorAll(".rte-version-diff-tab").forEach((v) => { | ||
| const y = v.getAttribute("data-tab") === s; | ||
| v.setAttribute("aria-selected", y ? "true" : "false"), v.tabIndex = y ? 0 : -1; | ||
| }), r.querySelectorAll(".rte-version-diff-panel").forEach((v) => { | ||
| v.classList.toggle("active", v.getAttribute("data-panel") === s); | ||
| }); | ||
| }, p = () => { | ||
| n.removeEventListener("keydown", I, !0), n.removeEventListener("click", A), document.removeEventListener("keydown", k, !0), n.parentNode && n.parentNode.removeChild(n), z = null, e.focus({ preventScroll: !0 }); | ||
| }, k = (s) => { | ||
| s.key === "Escape" && (s.preventDefault(), s.stopPropagation(), p()); | ||
| }, A = (s) => { | ||
| s.target === n && p(); | ||
| }, I = (s) => { | ||
| if (s.key === "Escape") { | ||
| s.preventDefault(), p(); | ||
| return; | ||
| } | ||
| if ($e(s, r), s.target && s.target.classList.contains("rte-version-diff-tab") && (s.key === "ArrowRight" || s.key === "ArrowLeft")) { | ||
| s.preventDefault(); | ||
| const v = c === "inline" ? "side" : "inline"; | ||
| h(v); | ||
| const y = r.querySelector(`.rte-version-diff-tab[data-tab="${v}"]`); | ||
| y == null || y.focus(); | ||
| } | ||
| }; | ||
| r.addEventListener("click", (s) => { | ||
| const v = s.target, y = v.getAttribute("data-action"); | ||
| if (y === "close") { | ||
| p(); | ||
| return; | ||
| } | ||
| if (y === "refresh") { | ||
| a(); | ||
| return; | ||
| } | ||
| const E = v.getAttribute("data-tab"); | ||
| (E === "inline" || E === "side") && h(E); | ||
| }), b.addEventListener("change", () => { | ||
| f = b.value === "line" ? "line" : "word", a(); | ||
| }), m.addEventListener("change", () => { | ||
| g = m.checked, a(); | ||
| }), r.querySelector(".rte-version-diff-set-baseline").addEventListener("click", () => { | ||
| w.set(e, e.innerHTML), a(e.innerHTML); | ||
| }), n.addEventListener("keydown", I, !0), n.addEventListener("click", A), document.addEventListener("keydown", k, !0), z = p, xe(r), a(); | ||
| } | ||
| function we(e) { | ||
| V = e, !H && (H = (i) => { | ||
| if (!ge(i)) return; | ||
| if (document.querySelector(`.${l}`)) { | ||
| i.preventDefault(); | ||
| return; | ||
| } | ||
| const t = i.target; | ||
| if (!!(t != null && t.closest("input, textarea, select"))) return; | ||
| const r = N(void 0, !1); | ||
| if (!r || r.getAttribute("contenteditable") === "false") return; | ||
| i.preventDefault(), i.stopPropagation(); | ||
| const o = R.get(r) || V || e; | ||
| ie(r, o); | ||
| }, document.addEventListener("keydown", H, !0)); | ||
| } | ||
| function Le() { | ||
| H && (document.removeEventListener("keydown", H, !0), H = null, V = null); | ||
| } | ||
| function Ce() { | ||
| S || (S = (e) => { | ||
| const i = e.target, t = i == null ? void 0 : i.closest($); | ||
| t && (D = t, ee(t)); | ||
| }, document.addEventListener("focusin", S, !0)), M || (M = (e) => { | ||
| const t = e.target, n = t == null ? void 0 : t.closest($); | ||
| n && n.getAttribute("contenteditable") !== "false" && (D = n, ee(n)); | ||
| }, document.addEventListener("beforeinput", M, !0)); | ||
| } | ||
| function He() { | ||
| S && (document.removeEventListener("focusin", S, !0), S = null), M && (document.removeEventListener("beforeinput", M, !0), M = null); | ||
| } | ||
| const Me = (e = {}) => { | ||
| const i = Ee(e); | ||
| return ye(), { | ||
| name: "versionDiff", | ||
| toolbar: [ | ||
| { | ||
| id: "versionDiff", | ||
| label: "Version Diff", | ||
| command: "openVersionDiff", | ||
| icon: '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><rect x="3.5" y="4.5" width="7" height="15" rx="1.5" stroke="currentColor" stroke-width="1.8"></rect><rect x="13.5" y="4.5" width="7" height="15" rx="1.5" stroke="currentColor" stroke-width="1.8"></rect><path d="M5.5 12h3" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"></path><path d="M15.5 12h3m-1.5-1.5v3" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"></path></svg>' | ||
| } | ||
| ], | ||
| commands: { | ||
| openVersionDiff: (t, n) => { | ||
| const r = N(n); | ||
| return r ? (R.set(r, i), ie(r, i, t), !0) : !1; | ||
| }, | ||
| setVersionDiffBaseline: (t, n) => { | ||
| const r = N(n); | ||
| if (!r) return !1; | ||
| R.set(r, i); | ||
| const o = typeof t == "string" ? t : typeof (t == null ? void 0 : t.html) == "string" ? t.html : r.innerHTML; | ||
| return w.set(r, o), !0; | ||
| } | ||
| }, | ||
| keymap: { | ||
| "Mod-Alt-d": "openVersionDiff", | ||
| "Mod-Alt-D": "openVersionDiff", | ||
| F8: "openVersionDiff" | ||
| }, | ||
| init: () => { | ||
| j += 1, we(i), Ce(); | ||
| }, | ||
| destroy: () => { | ||
| j = Math.max(0, j - 1), j === 0 && (ne(), Le(), He()); | ||
| } | ||
| }; | ||
| }; | ||
| export { | ||
| Me as VersionDiffPlugin | ||
| }; | ||
| //# sourceMappingURL=VersionDiffPlugin.native-Bvxgy--t.mjs.map |
+21
| MIT License | ||
| Copyright (c) 2026 Ajay Kumar | ||
| Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| of this software and associated documentation files (the "Software"), to deal | ||
| in the Software without restriction, including without limitation the rights | ||
| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
| copies of the Software, and to permit persons to whom the Software is | ||
| furnished to do so, subject to the following conditions: | ||
| The above copyright notice and this permission notice shall be included in all | ||
| copies or substantial portions of the Software. | ||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
| SOFTWARE. |
@@ -1,2 +0,2 @@ | ||
| "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const l=require("./index-BpE6GFbz.js");class v{constructor(e){if(this.listeners=[],e instanceof l.PluginManager)this.pluginManager=e;else{const i=e;this.pluginManager=new l.PluginManager,i.plugins&&Array.isArray(i.plugins)&&i.plugins.forEach(n=>{this.pluginManager.register(n)}),i.element&&(this.domElement=i.element,this.setupDOMElement(i))}const t=this.pluginManager.buildSchema();this.state=l.EditorState.create(t),this.commands=this.pluginManager.getCommands()}setupDOMElement(e){this.domElement&&(e.enableToolbar!==!1&&e.toolbarElement?this.toolbarElement=e.toolbarElement:e.enableToolbar!==!1&&(this.toolbarElement=document.createElement("div"),this.toolbarElement.className="editora-toolbar-container",this.domElement.appendChild(this.toolbarElement)),this.contentElement=document.createElement("div"),this.contentElement.contentEditable="true",this.contentElement.className="editora-content",this.contentElement.style.minHeight="200px",this.contentElement.style.outline="none",this.contentElement.style.padding="12px",e.content&&(this.contentElement.innerHTML=e.content),this.domElement.appendChild(this.contentElement),this.contentElement.addEventListener("input",()=>{this.listeners.forEach(t=>t(this.state))}))}setupKeyboardShortcuts(e){const t={};e.forEach(i=>{i.shortcut&&(t[i.shortcut.toLowerCase()]=i.command)}),document.addEventListener("keydown",i=>{if(this.contentElement!==document.activeElement&&!(document.activeElement instanceof HTMLElement&&document.activeElement.contentEditable==="true"))return;const n=[];(i.ctrlKey||i.metaKey)&&n.push("ctrl"),i.shiftKey&&n.push("shift"),i.altKey&&n.push("alt");const o=i.key.toLowerCase(),s=n.length>0?`${n.join("+")}+${o}`:o,a=t[s];a&&(i.preventDefault(),this.execCommand(a))})}handleToolbarCommand(e,t){const n=this.pluginManager.getToolbarItems().find(o=>o.id&&o.id===e||o.command===e);n!=null&&n.command&&(t!==void 0?this.execCommand(n.command,t):this.execCommand(n.command))}setState(e){this.state=e,this.listeners.forEach(t=>t(e))}onChange(e){return this.listeners.push(e),()=>{this.listeners=this.listeners.filter(t=>t!==e)}}on(e,t){return e==="change"||e==="input"?this.onChange(t):()=>{}}getElement(){return this.contentElement||this.domElement||null}execCommand(e,t){const i=this.commands[e];if(!i)return console.warn(`Command not found: ${e}`),!1;let n;return t!==void 0?n=i(this.state,t):n=i(this.state),n instanceof Promise?(n.then(o=>{o&&typeof o=="object"&&"doc"in o&&"selection"in o&&this.setState(o)}).catch(o=>{console.error(`Async command failed: ${e}`,o)}),!0):n&&typeof n=="object"&&"doc"in n&&"selection"in n?(this.setState(n),!0):n!==!1&&n!=null}setContent(e){typeof e=="string"?this.contentElement&&(this.contentElement.innerHTML=e):this.setState(this.state.apply(e))}getContent(){return this.contentElement?this.contentElement.innerHTML:this.state.doc}destroy(){this.listeners=[],this.contentElement&&this.contentElement.removeEventListener("input",()=>{})}}class b{constructor(e){this.initialized=!1,this.plugin=e}initialize(e){var t,i;if(this.initialized)return console.warn(`Plugin "${this.plugin.name}" already initialized`),!1;try{return this.context=e,(t=this.plugin.context)!=null&&t.initialize&&this.plugin.context.initialize(),(i=this.plugin.context)!=null&&i.onEditorReady&&e.provider&&this.plugin.context.onEditorReady(e),this.initialized=!0,!0}catch(n){return console.error(`Failed to initialize plugin "${this.plugin.name}":`,n),!1}}destroy(){var e;if(!this.initialized)return!1;try{return(e=this.plugin.context)!=null&&e.destroy&&this.plugin.context.destroy(),this.initialized=!1,this.context=void 0,!0}catch(t){return console.error(`Failed to destroy plugin "${this.plugin.name}":`,t),!1}}executeCommand(e,...t){var i;if(!this.initialized)return console.warn(`Plugin "${this.plugin.name}" not initialized, cannot execute command "${e}"`),null;try{const n=(i=this.plugin.commands)==null?void 0:i[e];return n?n(...t):(console.warn(`Command "${e}" not found in plugin "${this.plugin.name}"`),null)}catch(n){return console.error(`Error executing command "${e}" in plugin "${this.plugin.name}":`,n),null}}getName(){return this.plugin.name}isInitialized(){return this.initialized}getPlugin(){return this.plugin}getContext(){return this.context}}function E(r){return new b(r)}function x(r={}){const{enabled:e=!1,provider:t="browser",apiUrl:i="",apiHeaders:n={},language:o="en",customDictionary:s=[],ignoreAllCaps:a=!0,ignoreNumbers:c=!0}=r;return{name:"spellcheck",context:{initialize:()=>{if(e)switch(console.log("[Spellcheck Plugin] Initialized",{provider:t,language:o}),t){case"browser":console.log("[Spellcheck] Using browser spellcheck");break;case"local":console.log("[Spellcheck] Using local dictionary (not implemented)");break;case"api":i?console.log("[Spellcheck] Using API:",i):console.warn("[Spellcheck] API provider selected but no apiUrl provided");break}},destroy:()=>{console.log("[Spellcheck Plugin] Destroyed")},onEditorReady:h=>{console.log("[Spellcheck Plugin] Editor ready")}},commands:{toggleSpellcheck:()=>(console.log("[Spellcheck] Toggle command (not implemented)"),null),addToDictionary:h=>(console.log("[Spellcheck] Add to dictionary:",h),null),checkSpelling:async()=>(console.log("[Spellcheck] Check spelling (not implemented)"),null)},toolbar:e?[{label:"Spellcheck",command:"toggleSpellcheck",icon:"Aa",type:"button"}]:[]}}function w(r={}){const{uploadUrl:e="",libraryUrl:t="",maxFileSize:i=10*1024*1024,allowedTypes:n=["image/jpeg","image/png","image/gif","image/webp"],headers:o={},withCredentials:s=!1,chunkSize:a=1024*1024,enableChunking:c=!0,onProgress:h,onError:u,onSuccess:$}=r;return{name:"media",context:{initialize:()=>{console.log("[Media Plugin] Initialized",{uploadUrl:e,libraryUrl:t,maxFileSize:i,allowedTypes:n}),e||console.warn("[Media] No uploadUrl provided - upload will not work")},destroy:()=>{console.log("[Media Plugin] Destroyed")},onEditorReady:d=>{console.log("[Media Plugin] Editor ready")}},commands:{insertImage:async d=>{if(console.log("[Media] Insert image command (not implemented)",d),!d)return console.log("[Media] No file provided - should open picker"),null;if(!n.includes(d.type)){const g=new Error(`File type ${d.type} not allowed`);return u==null||u(g),null}if(d.size>i){const g=new Error(`File size ${d.size} exceeds max ${i}`);return u==null||u(g),null}return null},openMediaLibrary:()=>(console.log("[Media] Open media library (not implemented)"),t||console.warn("[Media] No libraryUrl provided"),null),uploadMedia:async d=>(console.log("[Media] Upload media (not implemented)",{name:d.name,size:d.size,type:d.type}),null)},toolbar:[{label:"Image",command:"insertImage",icon:"🖼️",type:"button"},{label:"Media Library",command:"openMediaLibrary",icon:"📁",type:"button"}]}}class p{constructor(e,t={anchor:0,head:0}){this.doc=e,this.selection=t}getDocument(){return this.doc}setDocument(e){return new p(e,this.selection)}getSelection(){return{...this.selection}}setSelection(e){return new p(this.doc,e)}update(e,t){return new p(e||this.doc,t||this.selection)}getTextContent(){return""}isSelectionEmpty(){return this.selection.anchor===this.selection.head}}class m{constructor(e){this.config={closeOnEscape:!0,closeOnBackdrop:!0,...e},this.element=this.createElement(),this.attachEventListeners()}createElement(){const e=document.createElement("dialog");e.className="editora-dialog",this.config.width&&(e.style.width=this.config.width),this.config.height&&(e.style.height=this.config.height);const t=this.config.buttons&&this.config.buttons.length>0?this.config.buttons.map((i,n)=>`<button type="button" class="editora-btn ${i.type==="danger"?"editora-btn-danger":i.type==="primary"||i.primary?"editora-btn-primary":"editora-btn-cancel"}" data-dialog-button="${n}">${i.label}</button>`).join(""):` | ||
| "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const l=require("./index-D1LOqg5C.js");class v{constructor(e){if(this.listeners=[],e instanceof l.PluginManager)this.pluginManager=e;else{const i=e;this.pluginManager=new l.PluginManager,i.plugins&&Array.isArray(i.plugins)&&i.plugins.forEach(n=>{this.pluginManager.register(n)}),i.element&&(this.domElement=i.element,this.setupDOMElement(i))}const t=this.pluginManager.buildSchema();this.state=l.EditorState.create(t),this.commands=this.pluginManager.getCommands()}setupDOMElement(e){this.domElement&&(e.enableToolbar!==!1&&e.toolbarElement?this.toolbarElement=e.toolbarElement:e.enableToolbar!==!1&&(this.toolbarElement=document.createElement("div"),this.toolbarElement.className="editora-toolbar-container",this.domElement.appendChild(this.toolbarElement)),this.contentElement=document.createElement("div"),this.contentElement.contentEditable="true",this.contentElement.className="editora-content",this.contentElement.style.minHeight="200px",this.contentElement.style.outline="none",this.contentElement.style.padding="12px",e.content&&(this.contentElement.innerHTML=e.content),this.domElement.appendChild(this.contentElement),this.contentElement.addEventListener("input",()=>{this.listeners.forEach(t=>t(this.state))}))}setupKeyboardShortcuts(e){const t={};e.forEach(i=>{i.shortcut&&(t[i.shortcut.toLowerCase()]=i.command)}),document.addEventListener("keydown",i=>{if(this.contentElement!==document.activeElement&&!(document.activeElement instanceof HTMLElement&&document.activeElement.contentEditable==="true"))return;const n=[];(i.ctrlKey||i.metaKey)&&n.push("ctrl"),i.shiftKey&&n.push("shift"),i.altKey&&n.push("alt");const o=i.key.toLowerCase(),s=n.length>0?`${n.join("+")}+${o}`:o,a=t[s];a&&(i.preventDefault(),this.execCommand(a))})}handleToolbarCommand(e,t){const n=this.pluginManager.getToolbarItems().find(o=>o.id&&o.id===e||o.command===e);n!=null&&n.command&&(t!==void 0?this.execCommand(n.command,t):this.execCommand(n.command))}setState(e){this.state=e,this.listeners.forEach(t=>t(e))}onChange(e){return this.listeners.push(e),()=>{this.listeners=this.listeners.filter(t=>t!==e)}}on(e,t){return e==="change"||e==="input"?this.onChange(t):()=>{}}getElement(){return this.contentElement||this.domElement||null}execCommand(e,t){const i=this.commands[e];if(!i)return console.warn(`Command not found: ${e}`),!1;let n;return t!==void 0?n=i(this.state,t):n=i(this.state),n instanceof Promise?(n.then(o=>{o&&typeof o=="object"&&"doc"in o&&"selection"in o&&this.setState(o)}).catch(o=>{console.error(`Async command failed: ${e}`,o)}),!0):n&&typeof n=="object"&&"doc"in n&&"selection"in n?(this.setState(n),!0):n!==!1&&n!=null}setContent(e){typeof e=="string"?this.contentElement&&(this.contentElement.innerHTML=e):this.setState(this.state.apply(e))}getContent(){return this.contentElement?this.contentElement.innerHTML:this.state.doc}destroy(){this.listeners=[],this.contentElement&&this.contentElement.removeEventListener("input",()=>{})}}class b{constructor(e){this.initialized=!1,this.plugin=e}initialize(e){var t,i;if(this.initialized)return console.warn(`Plugin "${this.plugin.name}" already initialized`),!1;try{return this.context=e,(t=this.plugin.context)!=null&&t.initialize&&this.plugin.context.initialize(),(i=this.plugin.context)!=null&&i.onEditorReady&&e.provider&&this.plugin.context.onEditorReady(e),this.initialized=!0,!0}catch(n){return console.error(`Failed to initialize plugin "${this.plugin.name}":`,n),!1}}destroy(){var e;if(!this.initialized)return!1;try{return(e=this.plugin.context)!=null&&e.destroy&&this.plugin.context.destroy(),this.initialized=!1,this.context=void 0,!0}catch(t){return console.error(`Failed to destroy plugin "${this.plugin.name}":`,t),!1}}executeCommand(e,...t){var i;if(!this.initialized)return console.warn(`Plugin "${this.plugin.name}" not initialized, cannot execute command "${e}"`),null;try{const n=(i=this.plugin.commands)==null?void 0:i[e];return n?n(...t):(console.warn(`Command "${e}" not found in plugin "${this.plugin.name}"`),null)}catch(n){return console.error(`Error executing command "${e}" in plugin "${this.plugin.name}":`,n),null}}getName(){return this.plugin.name}isInitialized(){return this.initialized}getPlugin(){return this.plugin}getContext(){return this.context}}function E(r){return new b(r)}function x(r={}){const{enabled:e=!1,provider:t="browser",apiUrl:i="",apiHeaders:n={},language:o="en",customDictionary:s=[],ignoreAllCaps:a=!0,ignoreNumbers:c=!0}=r;return{name:"spellcheck",context:{initialize:()=>{if(e)switch(console.log("[Spellcheck Plugin] Initialized",{provider:t,language:o}),t){case"browser":console.log("[Spellcheck] Using browser spellcheck");break;case"local":console.log("[Spellcheck] Using local dictionary (not implemented)");break;case"api":i?console.log("[Spellcheck] Using API:",i):console.warn("[Spellcheck] API provider selected but no apiUrl provided");break}},destroy:()=>{console.log("[Spellcheck Plugin] Destroyed")},onEditorReady:h=>{console.log("[Spellcheck Plugin] Editor ready")}},commands:{toggleSpellcheck:()=>(console.log("[Spellcheck] Toggle command (not implemented)"),null),addToDictionary:h=>(console.log("[Spellcheck] Add to dictionary:",h),null),checkSpelling:async()=>(console.log("[Spellcheck] Check spelling (not implemented)"),null)},toolbar:e?[{label:"Spellcheck",command:"toggleSpellcheck",icon:"Aa",type:"button"}]:[]}}function w(r={}){const{uploadUrl:e="",libraryUrl:t="",maxFileSize:i=10*1024*1024,allowedTypes:n=["image/jpeg","image/png","image/gif","image/webp"],headers:o={},withCredentials:s=!1,chunkSize:a=1024*1024,enableChunking:c=!0,onProgress:h,onError:u,onSuccess:$}=r;return{name:"media",context:{initialize:()=>{console.log("[Media Plugin] Initialized",{uploadUrl:e,libraryUrl:t,maxFileSize:i,allowedTypes:n}),e||console.warn("[Media] No uploadUrl provided - upload will not work")},destroy:()=>{console.log("[Media Plugin] Destroyed")},onEditorReady:d=>{console.log("[Media Plugin] Editor ready")}},commands:{insertImage:async d=>{if(console.log("[Media] Insert image command (not implemented)",d),!d)return console.log("[Media] No file provided - should open picker"),null;if(!n.includes(d.type)){const g=new Error(`File type ${d.type} not allowed`);return u==null||u(g),null}if(d.size>i){const g=new Error(`File size ${d.size} exceeds max ${i}`);return u==null||u(g),null}return null},openMediaLibrary:()=>(console.log("[Media] Open media library (not implemented)"),t||console.warn("[Media] No libraryUrl provided"),null),uploadMedia:async d=>(console.log("[Media] Upload media (not implemented)",{name:d.name,size:d.size,type:d.type}),null)},toolbar:[{label:"Image",command:"insertImage",icon:"🖼️",type:"button"},{label:"Media Library",command:"openMediaLibrary",icon:"📁",type:"button"}]}}class p{constructor(e,t={anchor:0,head:0}){this.doc=e,this.selection=t}getDocument(){return this.doc}setDocument(e){return new p(e,this.selection)}getSelection(){return{...this.selection}}setSelection(e){return new p(this.doc,e)}update(e,t){return new p(e||this.doc,t||this.selection)}getTextContent(){return""}isSelectionEmpty(){return this.selection.anchor===this.selection.head}}class m{constructor(e){this.config={closeOnEscape:!0,closeOnBackdrop:!0,...e},this.element=this.createElement(),this.attachEventListeners()}createElement(){const e=document.createElement("dialog");e.className="editora-dialog",this.config.width&&(e.style.width=this.config.width),this.config.height&&(e.style.height=this.config.height);const t=this.config.buttons&&this.config.buttons.length>0?this.config.buttons.map((i,n)=>`<button type="button" class="editora-btn ${i.type==="danger"?"editora-btn-danger":i.type==="primary"||i.primary?"editora-btn-primary":"editora-btn-cancel"}" data-dialog-button="${n}">${i.label}</button>`).join(""):` | ||
| <button type="button" class="editora-btn editora-btn-cancel" data-dialog-default="cancel">Cancel</button> | ||
@@ -3,0 +3,0 @@ <button type="button" class="editora-btn editora-btn-primary" data-dialog-default="ok">OK</button> |
@@ -1,3 +0,3 @@ | ||
| import { P as g, E as y, a as b, T as f, R as v } from "./index-yzU4NdPT.mjs"; | ||
| import { C as G, h as O, F as V, K, i as B, S as W, b as X, e as _, d as Y, g as J, f as Q, c as Z } from "./index-yzU4NdPT.mjs"; | ||
| import { P as g, E as y, a as b, T as f, R as v } from "./index-DqC57IEH.mjs"; | ||
| import { C as G, h as O, F as V, K, i as B, S as W, b as X, e as _, d as Y, g as J, f as Q, c as Z } from "./index-DqC57IEH.mjs"; | ||
| class L { | ||
@@ -4,0 +4,0 @@ constructor(e) { |
+77
-40
| const r = { | ||
| codeSample: () => import("./CodeSamplePlugin.native-CgGoH-X4.mjs").then((e) => e.CodeSamplePlugin()), | ||
| checklist: () => import("./ChecklistPlugin.native-nuSSEFNI.mjs").then((e) => e.ChecklistPlugin()), | ||
| textAlignment: () => import("./TextAlignmentPlugin.native-sM_1s00t.mjs").then((e) => e.TextAlignmentPlugin()), | ||
| indent: () => import("./IndentPlugin.native-BHixp8sP.mjs").then((e) => e.IndentPlugin()), | ||
| direction: () => import("./DirectionPlugin.native-CDnbdNyl.mjs").then((e) => e.DirectionPlugin()), | ||
| textColor: () => import("./TextColorPlugin.native-Bwl_bSmc.mjs").then((e) => e.TextColorPlugin()), | ||
| backgroundColor: () => import("./BackgroundColorPlugin.native-50iAT9xU.mjs").then((e) => e.BackgroundColorPlugin()), | ||
| fontSize: () => import("./FontSizePlugin.native-B_jCh7dY.mjs").then((e) => e.FontSizePlugin()), | ||
| fontFamily: () => import("./FontFamilyPlugin.native-j8hMTbg4.mjs").then((e) => e.FontFamilyPlugin()), | ||
| lineHeight: () => import("./LineHeightPlugin.native-CM7iXdQj.mjs").then((e) => e.LineHeightPlugin()), | ||
| capitalization: () => import("./CapitalizationPlugin.native-DOMsh5R7.mjs").then((e) => e.CapitalizationPlugin()), | ||
| link: () => import("./LinkPlugin.native-DYCIcdTm.mjs").then((e) => e.LinkPlugin()), | ||
| table: () => import("./TablePlugin.native-DrHX-efe.mjs").then((e) => e.TablePlugin()), | ||
| anchor: () => import("./AnchorPlugin.native-BcYGEtd9.mjs").then((e) => e.AnchorPlugin()), | ||
| embedIframe: () => import("./EmbedIframePlugin.native-DKJx2OS7.mjs").then((e) => e.EmbedIframePlugin()), | ||
| math: () => import("./MathPlugin.native-f_mDp8VL.mjs").then((e) => e.MathPlugin()), | ||
| image: () => import("./MediaManagerPlugin.native-BiXiK8FC.mjs").then((e) => e.MediaManagerPlugin()), | ||
| mergeTag: () => import("./MergeTagPlugin.native-C3eOfEgw.mjs").then((e) => e.MergeTagPlugin()), | ||
| pageBreak: () => import("./PageBreakPlugin.native-CXdX5fAv.mjs").then((e) => e.PageBreakPlugin()), | ||
| print: () => import("./PrintPlugin.native-7qt5v7L5.mjs").then((e) => e.PrintPlugin()), | ||
| preview: () => import("./PreviewPlugin.native-DBvfpmIv.mjs").then((e) => e.PreviewPlugin()), | ||
| specialCharacters: () => import("./SpecialCharactersPlugin.native-CZDato89.mjs").then((e) => e.SpecialCharactersPlugin()), | ||
| spellCheck: () => import("./SpellCheckPlugin.native-BZB9AewP.mjs").then((e) => e.SpellCheckPlugin()), | ||
| emojis: () => import("./EmojisPlugin.native-CitxxlWX.mjs").then((e) => e.EmojisPlugin()), | ||
| a11yChecker: () => import("./A11yCheckerPlugin.native-BRdGYMju.mjs").then((e) => e.A11yCheckerPlugin()), | ||
| comments: () => import("./CommentsPlugin.native-DPSqTkiv.mjs").then((e) => e.CommentsPlugin()), | ||
| "document-manager": () => import("./DocumentManagerPlugin.native-C2cs_1w4.mjs").then((e) => e.DocumentManagerPlugin()), | ||
| fullscreen: () => import("./FullscreenPlugin.native-ChXyxeNw.mjs").then((e) => e.FullscreenPlugin()), | ||
| template: () => import("./TemplatePlugin.native-CrpfKRJ8.mjs").then((e) => e.TemplatePlugin()), | ||
| footnote: () => import("./FootnotePlugin.native-D730OGRm.mjs").then((e) => e.FootnotePlugin()) | ||
| codeSample: () => import("./CodeSamplePlugin.native-CgGoH-X4.mjs").then((n) => n.CodeSamplePlugin()), | ||
| checklist: () => import("./ChecklistPlugin.native-nuSSEFNI.mjs").then((n) => n.ChecklistPlugin()), | ||
| textAlignment: () => import("./TextAlignmentPlugin.native-sM_1s00t.mjs").then((n) => n.TextAlignmentPlugin()), | ||
| indent: () => import("./IndentPlugin.native-BHixp8sP.mjs").then((n) => n.IndentPlugin()), | ||
| direction: () => import("./DirectionPlugin.native-CDnbdNyl.mjs").then((n) => n.DirectionPlugin()), | ||
| textColor: () => import("./TextColorPlugin.native-Bwl_bSmc.mjs").then((n) => n.TextColorPlugin()), | ||
| backgroundColor: () => import("./BackgroundColorPlugin.native-50iAT9xU.mjs").then((n) => n.BackgroundColorPlugin()), | ||
| fontSize: () => import("./FontSizePlugin.native-B_jCh7dY.mjs").then((n) => n.FontSizePlugin()), | ||
| fontFamily: () => import("./FontFamilyPlugin.native-j8hMTbg4.mjs").then((n) => n.FontFamilyPlugin()), | ||
| lineHeight: () => import("./LineHeightPlugin.native-CM7iXdQj.mjs").then((n) => n.LineHeightPlugin()), | ||
| capitalization: () => import("./CapitalizationPlugin.native-DOMsh5R7.mjs").then((n) => n.CapitalizationPlugin()), | ||
| link: () => import("./LinkPlugin.native-DYCIcdTm.mjs").then((n) => n.LinkPlugin()), | ||
| table: () => import("./TablePlugin.native-DrHX-efe.mjs").then((n) => n.TablePlugin()), | ||
| trackChanges: () => import("./TrackChangesPlugin.native-Bghu2q4a.mjs").then((n) => n.TrackChangesPlugin()), | ||
| versionDiff: () => import("./VersionDiffPlugin.native-Bvxgy--t.mjs").then((n) => n.VersionDiffPlugin()), | ||
| "version-diff": () => import("./VersionDiffPlugin.native-Bvxgy--t.mjs").then((n) => n.VersionDiffPlugin()), | ||
| versiondiff: () => import("./VersionDiffPlugin.native-Bvxgy--t.mjs").then((n) => n.VersionDiffPlugin()), | ||
| conditionalContent: () => import("./ConditionalContentPlugin.native-CfhY46rU.mjs").then((n) => n.ConditionalContentPlugin()), | ||
| "conditional-content": () => import("./ConditionalContentPlugin.native-CfhY46rU.mjs").then((n) => n.ConditionalContentPlugin()), | ||
| conditionalcontent: () => import("./ConditionalContentPlugin.native-CfhY46rU.mjs").then((n) => n.ConditionalContentPlugin()), | ||
| dataBinding: () => import("./DataBindingPlugin.native-jQ1JPRTp.mjs").then((n) => n.DataBindingPlugin()), | ||
| "data-binding": () => import("./DataBindingPlugin.native-jQ1JPRTp.mjs").then((n) => n.DataBindingPlugin()), | ||
| databinding: () => import("./DataBindingPlugin.native-jQ1JPRTp.mjs").then((n) => n.DataBindingPlugin()), | ||
| docSchema: () => import("./DocSchemaPlugin.native-CHOge18O.mjs").then((n) => n.DocSchemaPlugin()), | ||
| "doc-schema": () => import("./DocSchemaPlugin.native-CHOge18O.mjs").then((n) => n.DocSchemaPlugin()), | ||
| docschema: () => import("./DocSchemaPlugin.native-CHOge18O.mjs").then((n) => n.DocSchemaPlugin()), | ||
| translationWorkflow: () => import("./TranslationWorkflowPlugin.native-Bz6jDGvj.mjs").then((n) => n.TranslationWorkflowPlugin()), | ||
| "translation-workflow": () => import("./TranslationWorkflowPlugin.native-Bz6jDGvj.mjs").then((n) => n.TranslationWorkflowPlugin()), | ||
| translationworkflow: () => import("./TranslationWorkflowPlugin.native-Bz6jDGvj.mjs").then((n) => n.TranslationWorkflowPlugin()), | ||
| contentRules: () => import("./ContentRulesPlugin.native-nBLQ8QFZ.mjs").then((n) => n.ContentRulesPlugin()), | ||
| "content-rules": () => import("./ContentRulesPlugin.native-nBLQ8QFZ.mjs").then((n) => n.ContentRulesPlugin()), | ||
| contentrules: () => import("./ContentRulesPlugin.native-nBLQ8QFZ.mjs").then((n) => n.ContentRulesPlugin()), | ||
| citations: () => import("./CitationsPlugin.native-BnU0qCwR.mjs").then((n) => n.CitationsPlugin()), | ||
| citation: () => import("./CitationsPlugin.native-BnU0qCwR.mjs").then((n) => n.CitationsPlugin()), | ||
| approvalWorkflow: () => import("./ApprovalWorkflowPlugin.native-C3jtAYjG.mjs").then((n) => n.ApprovalWorkflowPlugin()), | ||
| "approval-workflow": () => import("./ApprovalWorkflowPlugin.native-C3jtAYjG.mjs").then((n) => n.ApprovalWorkflowPlugin()), | ||
| approvalworkflow: () => import("./ApprovalWorkflowPlugin.native-C3jtAYjG.mjs").then((n) => n.ApprovalWorkflowPlugin()), | ||
| piiRedaction: () => import("./PIIRedactionPlugin.native-DcsjmtV1.mjs").then((n) => n.PIIRedactionPlugin()), | ||
| "pii-redaction": () => import("./PIIRedactionPlugin.native-DcsjmtV1.mjs").then((n) => n.PIIRedactionPlugin()), | ||
| piiredaction: () => import("./PIIRedactionPlugin.native-DcsjmtV1.mjs").then((n) => n.PIIRedactionPlugin()), | ||
| smartPaste: () => import("./SmartPastePlugin.native-BOKKtF07.mjs").then((n) => n.SmartPastePlugin()), | ||
| "smart-paste": () => import("./SmartPastePlugin.native-BOKKtF07.mjs").then((n) => n.SmartPastePlugin()), | ||
| smartpaste: () => import("./SmartPastePlugin.native-BOKKtF07.mjs").then((n) => n.SmartPastePlugin()), | ||
| blocksLibrary: () => import("./BlocksLibraryPlugin.native-HMWKxWNs.mjs").then((n) => n.BlocksLibraryPlugin()), | ||
| "blocks-library": () => import("./BlocksLibraryPlugin.native-HMWKxWNs.mjs").then((n) => n.BlocksLibraryPlugin()), | ||
| blockslibrary: () => import("./BlocksLibraryPlugin.native-HMWKxWNs.mjs").then((n) => n.BlocksLibraryPlugin()), | ||
| mentions: () => import("./MentionPlugin.native-BMDlOqur.mjs").then((n) => n.MentionPlugin()), | ||
| mention: () => import("./MentionPlugin.native-BMDlOqur.mjs").then((n) => n.MentionPlugin()), | ||
| anchor: () => import("./AnchorPlugin.native-BcYGEtd9.mjs").then((n) => n.AnchorPlugin()), | ||
| embedIframe: () => import("./EmbedIframePlugin.native-DKJx2OS7.mjs").then((n) => n.EmbedIframePlugin()), | ||
| math: () => import("./MathPlugin.native-f_mDp8VL.mjs").then((n) => n.MathPlugin()), | ||
| image: () => import("./MediaManagerPlugin.native-BiXiK8FC.mjs").then((n) => n.MediaManagerPlugin()), | ||
| mergeTag: () => import("./MergeTagPlugin.native-C3eOfEgw.mjs").then((n) => n.MergeTagPlugin()), | ||
| pageBreak: () => import("./PageBreakPlugin.native-DijGuHJZ.mjs").then((n) => n.PageBreakPlugin()), | ||
| print: () => import("./PrintPlugin.native-7qt5v7L5.mjs").then((n) => n.PrintPlugin()), | ||
| preview: () => import("./PreviewPlugin.native-WuIwOAOR.mjs").then((n) => n.PreviewPlugin()), | ||
| specialCharacters: () => import("./SpecialCharactersPlugin.native-CZDato89.mjs").then((n) => n.SpecialCharactersPlugin()), | ||
| slashCommands: () => import("./SlashCommandsPlugin.native-CmxvMEaE.mjs").then((n) => n.SlashCommandsPlugin()), | ||
| "slash-commands": () => import("./SlashCommandsPlugin.native-CmxvMEaE.mjs").then((n) => n.SlashCommandsPlugin()), | ||
| spellCheck: () => import("./SpellCheckPlugin.native-BZB9AewP.mjs").then((n) => n.SpellCheckPlugin()), | ||
| emojis: () => import("./EmojisPlugin.native-CitxxlWX.mjs").then((n) => n.EmojisPlugin()), | ||
| a11yChecker: () => import("./A11yCheckerPlugin.native-BRdGYMju.mjs").then((n) => n.A11yCheckerPlugin()), | ||
| comments: () => import("./CommentsPlugin.native-DPSqTkiv.mjs").then((n) => n.CommentsPlugin()), | ||
| "document-manager": () => import("./DocumentManagerPlugin.native-C2cs_1w4.mjs").then((n) => n.DocumentManagerPlugin()), | ||
| fullscreen: () => import("./FullscreenPlugin.native-ChXyxeNw.mjs").then((n) => n.FullscreenPlugin()), | ||
| template: () => import("./TemplatePlugin.native-CrpfKRJ8.mjs").then((n) => n.TemplatePlugin()), | ||
| footnote: () => import("./FootnotePlugin.native-D730OGRm.mjs").then((n) => n.FootnotePlugin()) | ||
| }; | ||
| async function a(e) { | ||
| var t, i; | ||
| const n = ((t = window.EditoraCore) == null ? void 0 : t.__globalPluginLoader) || ((i = window.Editora) == null ? void 0 : i.__globalPluginLoader); | ||
| if (!n) { | ||
| async function a(n) { | ||
| var i, o; | ||
| const t = ((i = window.EditoraCore) == null ? void 0 : i.__globalPluginLoader) || ((o = window.Editora) == null ? void 0 : o.__globalPluginLoader); | ||
| if (!t) { | ||
| console.warn("Editora plugin loader not found. Make sure to load the core bundle first."); | ||
| return; | ||
| } | ||
| Object.entries(r).forEach(([o, l]) => { | ||
| n.getRegisteredPluginNames().includes(o) || n.register(o, l); | ||
| }), await n.loadMultiple(e); | ||
| Object.entries(r).forEach(([e, l]) => { | ||
| t.getRegisteredPluginNames().includes(e) || t.register(e, l); | ||
| }), await t.loadMultiple(n); | ||
| } | ||
| function g() { | ||
| function m() { | ||
| return Object.keys(r); | ||
@@ -49,8 +86,8 @@ } | ||
| loadPlugins: a, | ||
| getAvailablePlugins: g | ||
| getAvailablePlugins: m | ||
| }); | ||
| export { | ||
| g as getAvailablePlugins, | ||
| m as getAvailablePlugins, | ||
| a as loadPlugins | ||
| }; | ||
| //# sourceMappingURL=plugin-loader.js.map |
@@ -1,1 +0,1 @@ | ||
| .editora-editor{display:flex;flex-direction:column;border:1px solid #ddd;border-radius:4px;background:#fff;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,sans-serif;font-size:14px;overflow:hidden}.editora-editor *{box-sizing:border-box}.editora-theme-light{background:#fff;color:#333}.editora-theme-dark{--editora-dark-toolbar-bg-start: #353d48;--editora-dark-toolbar-bg-end: #2d3540;--editora-dark-button-bg-start: #46505f;--editora-dark-button-bg-end: #3b4553;--editora-dark-button-hover-start: #525d6d;--editora-dark-button-hover-end: #465262;--editora-dark-button-active-start: #5eaaf6;--editora-dark-button-active-end: #4a95de;--editora-dark-border: #475263;--editora-dark-border-strong: #566275;--editora-dark-text: #e1e9f5;--editora-dark-text-strong: #f3f7ff;--editora-dark-text-muted: #aeb9cc;--editora-dark-surface: #1d242d;--editora-dark-content: #1f2732;background:linear-gradient(180deg,#1b2330,#1c2430);color:var(--editora-dark-text);border-color:var(--editora-dark-border)}.editora-toolbar{display:flex;align-items:center;gap:4px;padding:8px;background:#f5f5f5;border-bottom:1px solid #ddd;flex-wrap:wrap}.editora-theme-dark .editora-toolbar{background:linear-gradient(180deg,var(--editora-dark-toolbar-bg-start) 0%,var(--editora-dark-toolbar-bg-end) 100%);border-bottom-color:var(--editora-dark-border);box-shadow:inset 0 1px #ffffff0d}.editora-toolbar-sticky{position:sticky;top:0;z-index:100;position:-webkit-sticky}.editora-toolbar-group{display:flex;align-items:center;gap:2px}.editora-toolbar-button{padding:6px 12px;border:1px solid #ccc;background:#fff;cursor:pointer;border-radius:3px;font-weight:600;font-size:14px;height:30px;display:flex;align-items:center;white-space:nowrap}.editora-toolbar-group-button{display:flex;align-items:center}.editora-toolbar-input.font-size{width:40px;padding:.25rem;text-align:center;font-size:14px;background:#fff;border:1px solid var(--rte-color-border-light);border-radius:var(--rte-radius-sm)}.editora-toolbar-group-items{display:flex;align-items:center;border:1px solid #ccc;.editora-toolbar-button{border:none;border-radius:0;&:first-child{border-right:1px solid #ccc;border-top-left-radius:3px;border-bottom-left-radius:3px}&:last-child{border-left:1px solid #ccc;border-top-right-radius:3px;border-bottom-right-radius:3px}}}.editora-theme-dark .editora-toolbar-button{background:linear-gradient(180deg,var(--editora-dark-button-bg-start) 0%,var(--editora-dark-button-bg-end) 100%);border-color:var(--editora-dark-border-strong);color:var(--editora-dark-text);box-shadow:inset 0 1px #ffffff14,0 1px 1px #00000059}.editora-theme-dark .editora-toolbar-group-items{border-color:var(--editora-dark-border-strong);background:linear-gradient(180deg,var(--editora-dark-button-bg-start) 0%,var(--editora-dark-button-bg-end) 100%)}.editora-theme-dark .editora-toolbar-group-items .editora-toolbar-button:first-child{border-right-color:#566275}.editora-theme-dark .editora-toolbar-group-items .editora-toolbar-button:last-child{border-left-color:#566275}.editora-theme-dark .editora-toolbar-input.font-size{background-color:#2e3642;color:var(--editora-dark-text-strong);border-color:var(--editora-dark-border-strong);caret-color:var(--editora-dark-text-strong)}.editora-theme-dark .editora-toolbar-input.font-size::placeholder{color:var(--editora-dark-text-strong);opacity:1}.editora-toolbar-button:hover{background:#e0e0e0;border-color:#ccc}.editora-theme-dark .editora-toolbar-button:hover{background:linear-gradient(180deg,var(--editora-dark-button-hover-start) 0%,var(--editora-dark-button-hover-end) 100%);border-color:#66748a;color:var(--editora-dark-text-strong)}.editora-toolbar-button:active,.editora-toolbar-button.active{background:#d0d0d0;border-color:#999}.editora-theme-dark .editora-toolbar-button:active,.editora-theme-dark .editora-toolbar-button.active{background:linear-gradient(180deg,var(--editora-dark-button-active-start) 0%,var(--editora-dark-button-active-end) 100%);border-color:#67adf4;color:#0f1b2a}.editora-theme-dark .editora-toolbar-button:disabled{background:#313946;border-color:#424d5e;color:#7f8ca1}.editora-theme-dark .editora-toolbar-button[data-command=insertTable],.editora-theme-dark .editora-toolbar-button[data-command=print],.editora-theme-dark .editora-toolbar-button[data-command=toggleSpellCheck],.editora-theme-dark .editora-toolbar-button[data-command=toggleA11yChecker],.editora-theme-dark .editora-toolbar-button[data-command=setDirectionLTR],.editora-theme-dark .editora-toolbar-button[data-command=setDirectionRTL]{color:#f1f6ff}.editora-toolbar-button:disabled{opacity:.5;cursor:not-allowed}.editora-toolbar-icon{display:inline-flex;align-items:center;justify-content:center;width:24px;height:24px;line-height:1}.editora-toolbar-button svg,.editora-toolbar-icon svg{width:20px;height:20px;display:block;color:currentColor;fill:currentColor}.editora-theme-dark .editora-toolbar-icon,.editora-theme-dark .editora-toolbar-icon *{color:inherit}.editora-theme-dark :is(.editora-toolbar-button,.editora-toolbar-icon) svg :is([stroke="#000" i],[stroke="#000000" i],[stroke=black i],[stroke="#0f0f0f" i],[stroke="#111111" i],[style*="stroke:#000" i],[style*="stroke: #000" i],[style*="stroke:black" i],[style*="stroke: black" i],[style*="stroke:#0f0f0f" i],[style*="stroke: #0f0f0f" i]){stroke:currentColor!important}.editora-theme-dark :is(.editora-toolbar-button,.editora-toolbar-icon) svg :is([fill="#000" i],[fill="#000000" i],[fill=black i],[fill="#0f0f0f" i],[fill="#111111" i],[style*="fill:#000" i],[style*="fill: #000" i],[style*="fill:black" i],[style*="fill: black" i],[style*="fill:#0f0f0f" i],[style*="fill: #0f0f0f" i]){fill:currentColor!important}.editora-toolbar-separator{width:1px;height:24px;background:#ddd;margin:0 4px}.editora-theme-dark .editora-toolbar-separator{background:#4d596b}.editora-toolbar-dropdown{position:relative}.editora-toolbar-dropdown-menu{position:absolute;top:100%;left:0;min-width:150px;margin-top:4px;padding:4px 0;background:#fff;border:1px solid #ddd;border-radius:4px;box-shadow:0 2px 8px #00000026;z-index:1000}.editora-theme-dark .editora-toolbar-dropdown-menu{background:#29323d;border-color:#4d596b;box-shadow:0 8px 20px #00000073}.editora-toolbar-dropdown-item{display:block;width:100%;padding:8px 12px;border:none;background:transparent;color:#333;text-align:left;cursor:pointer;font-size:13px;transition:background .15s ease}.editora-theme-dark .editora-toolbar-dropdown-item{color:#d7deea}.editora-toolbar-dropdown-item:hover{background:#f5f5f5}.editora-theme-dark .editora-toolbar-dropdown-item:hover{background:#3a4554;color:#f0f6ff}.editora-content{flex:1;min-height:200px;padding:16px;outline:none;overflow-y:auto;line-height:1.6}.editora-theme-dark .editora-content{color:#ecf3ff;background:linear-gradient(180deg,var(--editora-dark-content) 0%,#1c232e 100%)}.editora-content:empty:before{content:attr(data-placeholder);color:#999;pointer-events:none}.editora-theme-dark .editora-content:empty:before{color:#8f9bb0}.editora-content h1{font-size:2em;margin:.67em 0;font-weight:600}.editora-content h2{font-size:1.5em;margin:.75em 0;font-weight:600}.editora-content h3{font-size:1.17em;margin:.83em 0;font-weight:600}.editora-content p{margin:1em 0}.editora-content ul,.editora-content ol{margin:1em 0;padding-left:2em}.editora-content a{color:#06c;text-decoration:underline}.editora-theme-dark .editora-content a{color:#4db8ff}.editora-content code{padding:2px 4px;background:#f5f5f5;border-radius:3px;font-family:Monaco,Menlo,Consolas,monospace;font-size:.9em}.editora-theme-dark .editora-content code{background:#1e1e1e}.editora-content pre{padding:12px;background:#f5f5f5;border-radius:4px;overflow-x:auto;margin:1em 0}.editora-theme-dark .editora-content pre{background:#1e1e1e}.editora-theme-dark .rte-code-block{background:linear-gradient(180deg,#212a36,#1b2430)!important;border-color:#4f5b70!important;color:#e7effc!important}.editora-theme-dark .rte-code-block code{color:#e7effc!important}.editora-theme-dark .rte-code-block:before{background:#111927!important;color:#dce8ff!important}.editora-theme-dark .rte-code-block .rte-code-copy{background:#2b3441!important;border-color:#5a667b!important;color:#dce8ff!important}.editora-content blockquote{margin:1em 0;padding-left:1em;border-left:4px solid #ddd;color:#666}.editora-theme-dark .editora-content blockquote{border-left-color:#3c3c3c;color:#9a9a9a}.editora-floating-toolbar{position:absolute;padding:4px;background:#fff;border:1px solid #ddd;border-radius:4px;box-shadow:0 2px 8px #00000026;z-index:1000}.editora-theme-dark .editora-floating-toolbar{background:#29323d;border-color:#4d596b;box-shadow:0 8px 20px #00000073}.editora-theme-dark .editora-statusbar{background:linear-gradient(180deg,#2c3440,#252d37);border-top-color:#3f4a5b;color:#d7deea}.editora-statusbar-item{white-space:nowrap}.editora-theme-dark .editora-statusbar-separator{color:#566275}.editora-editor[readonly] .editora-content{background:#fafafa;cursor:not-allowed}.editora-theme-dark.editora-editor[readonly] .editora-content{background:#1a1a1a}.editora-editor:focus-within{border-color:#06c;box-shadow:0 0 0 3px #0066cc1a}.editora-theme-dark.editora-editor:focus-within{border-color:#4db8ff;box-shadow:0 0 0 3px #4db8ff1a}.editora-editor[disabled]{opacity:.6;pointer-events:none}@media(max-width:768px){.editora-toolbar{padding:4px}.editora-toolbar-button{min-width:28px;min-height:28px;padding:4px 8px;font-size:12px}.editora-content{padding:12px}}.editora-content ::selection{background:#06c3}.editora-theme-dark .editora-content ::selection{background:#4db8ff33}.editora-content table{border-collapse:collapse;width:100%;margin:1em 0}.editora-content th,.editora-content td{border:1px solid #ddd;padding:8px 12px;text-align:left}.editora-theme-dark .editora-content th,.editora-theme-dark .editora-content td{border-color:#3c3c3c}.editora-content th{background:#f5f5f5;font-weight:600}.editora-theme-dark .editora-content th{background:#252526}.editora-content img{max-width:100%;height:auto;border-radius:4px;display:block}.editora-content video{max-width:100%;height:auto;border-radius:4px;display:block}.editora-editor.loading{opacity:.7;pointer-events:none}.editora-editor.loading:after{content:"";position:absolute;top:50%;left:50%;width:24px;height:24px;margin:-12px 0 0 -12px;border:3px solid #ddd;border-top-color:#06c;border-radius:50%;animation:editora-spin .8s linear infinite}@keyframes editora-spin{to{transform:rotate(360deg)}}.toolbar-container-wrapper{display:flex;align-items:center;background:#fff;border-bottom:1px solid #e0e0e0;padding:0;margin:0;width:100%;box-sizing:border-box;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif;font-size:14px;line-height:1.5;position:relative}.toolbar-container-wrapper[data-toolbar-sticky=true]{position:sticky;top:0;z-index:999;box-shadow:0 2px 4px #0000001a}.toolbar-container-wrapper[data-toolbar-floating=true]{position:fixed;top:0;left:0;right:0;z-index:1000;box-shadow:0 4px 12px #00000026}.toolbar-container-wrapper[data-toolbar-position=bottom]{border-bottom:none;border-top:1px solid #e0e0e0}.toolbar-container-wrapper .toolbar-wrapper{display:flex;width:100%;padding:8px;gap:4px;flex-wrap:wrap;align-items:center}.toolbar-container-wrapper .toolbar{display:flex;width:100%;gap:4px;flex-wrap:wrap;align-items:center}.toolbar-container-wrapper .toolbar-container{display:flex;gap:4px;flex-wrap:wrap;align-items:center;flex:1;position:relative}.toolbar-container-wrapper .toolbar-item{display:flex;align-items:center;gap:2px}.toolbar-container-wrapper .toolbar-button{padding:6px 10px;border:1px solid #d1d5db;background:#fff;border-radius:4px;cursor:pointer;font-size:13px;display:flex;align-items:center;justify-content:center;gap:4px;transition:all .15s ease;min-height:32px;white-space:nowrap}.toolbar-container-wrapper .toolbar-button:hover{background-color:#f3f4f6;border-color:#9ca3af}.toolbar-container-wrapper .toolbar-button:active,.toolbar-container-wrapper .toolbar-button[data-active=true]{background-color:#06c;color:#fff;border-color:#0052a3;box-shadow:inset 0 1px 3px #0000001a}.toolbar-container-wrapper .toolbar-button:disabled{opacity:.5;cursor:not-allowed;background-color:#f9fafb}.toolbar-container-wrapper .toolbar-more-button{padding:6px 8px;font-size:16px;font-weight:500;line-height:1}.toolbar-container-wrapper .toolbar-separator{width:1px;height:24px;background-color:#d1d5db;margin:0 4px}.toolbar-container-wrapper .toolbar-icon{display:inline-flex;align-items:center;justify-content:center;width:18px;height:18px;flex-shrink:0}.toolbar-container-wrapper .toolbar-icon svg{width:100%;height:100%}.toolbar-container-wrapper .toolbar-dropdown{position:relative;display:flex;align-items:center}.toolbar-container-wrapper .toolbar-dropdown-arrow{font-size:10px;margin-left:2px;line-height:1}.toolbar-container-wrapper .toolbar-dropdown-menu{position:absolute;top:100%;left:0;background:#fff;border:1px solid #d1d5db;border-radius:6px;box-shadow:0 4px 12px #00000026;z-index:1000;min-width:160px;padding:4px 0;margin-top:4px;display:none}.toolbar-container-wrapper .toolbar-dropdown-menu.show{display:block}.toolbar-container-wrapper .toolbar-dropdown-item{display:block;width:100%;padding:8px 12px;border:none;background:transparent;text-align:left;cursor:pointer;font-size:13px;color:#1f2937;transition:background-color .15s ease;font-family:inherit}.toolbar-container-wrapper .toolbar-dropdown-item:hover{background-color:#f3f4f6}.toolbar-container-wrapper .toolbar-dropdown-item:active{background-color:#e5e7eb}.toolbar-container-wrapper .toolbar-input{padding:6px 8px;border:1px solid #d1d5db;border-radius:4px;font-size:13px;font-family:inherit;background-color:#fff;color:#1f2937;transition:all .15s ease}.toolbar-container-wrapper .toolbar-input:focus{outline:none;border-color:#06c;box-shadow:0 0 0 3px #0066cc1a;background-color:#fff}.toolbar-container-wrapper .toolbar-input::placeholder{color:#9ca3af}.toolbar-overflow-menu{animation:slideDown .2s ease-out}@keyframes slideDown{0%{opacity:0;transform:translateY(-8px)}to{opacity:1;transform:translateY(0)}}.toolbar-overflow-item{transition:background-color .15s ease}.floating-toolbar{user-select:none;-webkit-user-select:none;font-family:system-ui,-apple-system,sans-serif;font-size:14px;animation:fadeInUp .15s ease-out}@keyframes fadeInUp{0%{opacity:0;transform:translate(-50%) translateY(10px)}to{opacity:1;transform:translate(-50%) translateY(0)}}.floating-toolbar-btn{display:flex;align-items:center;justify-content:center;width:32px;height:32px;border:none;background:transparent;border-radius:4px;color:#495057;cursor:pointer;font-size:14px;font-weight:500;transition:all .15s ease;outline:none}.floating-toolbar-btn:hover{background:#f8f9fa;color:#212529}.floating-toolbar-btn:active{background:#e9ecef;transform:scale(.95)}.floating-toolbar-btn.floating-toolbar-toggle{color:#dc3545;font-weight:700}.floating-toolbar-btn.floating-toolbar-toggle:hover{background:#f8d7da;color:#721c24}.floating-toolbar-separator{width:1px;height:20px;background:#e1e5e9;margin:0 2px}@media(max-width:768px){.toolbar-container-wrapper .toolbar-button{padding:5px 8px;font-size:12px;min-height:28px}.toolbar-container-wrapper .toolbar-icon{width:16px;height:16px}.toolbar-container-wrapper .toolbar-dropdown-menu{min-width:140px}.toolbar-container-wrapper .toolbar-dropdown-item{padding:6px 10px;font-size:12px}.floating-toolbar{padding:4px;gap:2px}.floating-toolbar-btn{width:28px;height:28px;font-size:12px}}@media(max-width:480px){.toolbar-container-wrapper{padding:4px}.toolbar-container-wrapper .toolbar-wrapper{padding:4px;gap:2px}.toolbar-container-wrapper .toolbar-button{padding:4px 6px;font-size:11px;min-height:24px}.toolbar-container-wrapper .toolbar-icon{width:14px;height:14px}}.floating-toolbar{pointer-events:auto}.floating-toolbar{max-width:calc(100vw - 20px);overflow-x:auto}@media(prefers-color-scheme:dark){.floating-toolbar{background:#2d3748;border-color:#4a5568;color:#e2e8f0}.floating-toolbar-btn:hover{background:#4a5568;color:#f7fafc}.floating-toolbar-btn:active{background:#718096}.floating-toolbar-separator{background:#4a5568}}.rte-editor{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif}.rte-toolbar-wrapper{border-radius:4px 4px 0 0}.rte-toolbar{display:flex;gap:4px;padding:8px;background:#f5f5f5;border:1px solid #ddd;border-bottom:none;border-radius:4px 4px 0 0;align-items:center;position:relative}.rte-toolbar-items-container{display:flex;gap:4px;flex-wrap:nowrap;align-items:center;flex:1}.rte-toolbar-item{position:relative;display:flex;align-items:center;white-space:nowrap}.rte-toolbar-group-items.font-size{display:flex;align-items:center;border:1px solid #ccc;.rte-toolbar-input.font-size{width:40px;padding:.25rem;text-align:center;font-size:14px;background:#fff;border:1px solid var(--rte-color-border-light);border-radius:var(--rte-radius-sm)}.rte-toolbar-button{border:none;border-radius:0}.rte-toolbar-item{&:first-child{border-right:1px solid #ccc;border-top-left-radius:3px;border-bottom-left-radius:3px}&:last-child{border-left:1px solid #ccc;border-top-right-radius:3px;border-bottom-right-radius:3px}}}.rte-toolbar-button{padding:6px 12px;border:1px solid #ccc;background:#fff;cursor:pointer;border-radius:3px;font-weight:600;font-size:14px;height:30px;display:flex;align-items:center;white-space:nowrap}.rte-toolbar-button:hover{background:#e9e9e9}.rte-toolbar-input{width:26px;padding:6px 8px;border:1px solid #ccc;border-radius:3px;font-size:14px;text-align:center}.rte-toolbar-dropdown{position:relative}.rte-toolbar-dropdown-menu{position:absolute;top:100%;left:0;background:#fff;border:1px solid #ccc;border-radius:3px;box-shadow:0 2px 8px #00000026;min-width:150px;z-index:1000;margin-top:2px}.rte-toolbar-dropdown-item{padding:8px 12px;cursor:pointer}.rte-toolbar-dropdown-item:hover{background:#f0f0f0}.rte-toolbar-more-button{padding:6px 10px;border:1px solid #ccc;background:#fff;cursor:pointer;border-radius:3px;font-weight:600;font-size:16px;height:30px;display:flex;align-items:center;justify-content:center;min-width:30px;transition:background-color .2s ease;margin-left:auto}.rte-toolbar-more-button:hover{background:#e9e9e9}.rte-toolbar-more-button.active{background:#ddd;border-color:#999}.rte-toolbar-expanded-row{display:flex;flex-wrap:wrap;align-items:flex-start;transform:scaleY(0);transform-origin:top;max-height:0;padding:0;overflow:hidden;opacity:0;transition:transform .25s ease,opacity .2s ease,max-height .25s ease}.rte-toolbar-expanded-row.show{transform:scaleY(1);max-height:320px;padding:1px 8px 8px;opacity:1;background:#f5f5f5;border:1px solid #ddd;border-top:none;gap:4px;overflow-y:auto;overflow-x:hidden}.rte-content{font-size:16px;line-height:1.6}.rte-content.rte-content-empty:before,.rte-content:empty:before{content:attr(data-placeholder);color:var(--rte-color-text-muted, #6b7280);pointer-events:none}.rte-content p{margin:0 0 1em}.rte-content h1{font-size:2em;margin:.67em 0}.rte-content h2{font-size:1.5em;margin:.75em 0}.rte-content h3{font-size:1.17em;margin:.83em 0}.rte-content h4{font-size:1em;margin:1em 0}.rte-content h5{font-size:.83em;margin:1.17em 0}.rte-content h6{font-size:.67em;margin:1.33em 0}.rte-content ul,.rte-content ol{margin:1em 0;padding-left:2em}.rte-content .rte-table,.rte-content table{border-collapse:collapse;width:100%;margin:1rem 0;border:1px solid #ddd;font-size:14px;line-height:1.4}.rte-content .rte-table td,.rte-content .rte-table th,.rte-content table td,.rte-content table th{border:1px solid #ddd;padding:8px 12px;min-width:80px;text-align:left;vertical-align:top}.rte-content .rte-table th,.rte-content table th{background-color:#f8f9fa;font-weight:600}.rte-content .rte-table td p,.rte-content table td p{margin:0}.table-toolbar{background:#fff;border:1px solid #d0d0d0;border-radius:4px;box-shadow:0 2px 8px #0000001a;padding:4px;display:flex;align-items:center}.toolbar-icon-btn{display:flex;align-items:center;justify-content:center;width:28px;height:28px;padding:0;border:1px solid transparent;background:transparent;color:#333;border-radius:3px;cursor:pointer}.toolbar-icon-btn:hover:not(:disabled){background:#f0f0f0;border-color:#d0d0d0}.rte-content code{background:#f4f4f4;padding:2px 6px;border-radius:3px;font-family:Courier New,monospace;font-size:.9em}.rte-content blockquote{border-left:4px solid #ddd;margin:1em 0;padding-left:1em;color:#666}.rte-content a{color:#06c;text-decoration:underline}.rte-content a:hover{color:#0052a3}.rte-dialog-overlay{position:fixed;inset:0;background:#00000080;display:flex;align-items:center;justify-content:center;z-index:10000}.rte-dialog-content{background:#fff;border-radius:8px;box-shadow:0 4px 20px #0000004d;max-width:400px;width:90%;max-height:90vh;overflow-y:auto}.rte-dialog-header{padding:16px 20px;border-bottom:1px solid #e0e0e0;display:flex;justify-content:space-between;align-items:center}.rte-dialog-header h3{margin:0;font-size:18px;font-weight:600;color:#333}.rte-dialog-close{background:none;border:none;font-size:24px;cursor:pointer;color:#666;padding:0;width:30px;height:30px;display:flex;align-items:center;justify-content:center}.rte-dialog-close:hover{color:#333}.rte-dialog-body{padding:20px}.rte-dialog-footer{padding:16px 20px;border-top:1px solid #e0e0e0;display:flex;justify-content:flex-end;gap:12px}.rte-btn{padding:8px 16px;border:1px solid #ccc;border-radius:4px;cursor:pointer;font-size:14px;font-weight:500;transition:all .2s}.rte-btn:hover{border-color:#999}.rte-btn-primary{background:#06c;color:#fff;border-color:#06c}.rte-btn-primary:hover{background:#0052a3;border-color:#0052a3}.rte-btn-secondary{background:#fff;color:#333}.rte-btn-secondary:hover{background:#f5f5f5}.rte-form-group{margin-bottom:16px}.rte-form-label{display:block;margin-bottom:6px;font-weight:500;color:#333;font-size:14px}.rte-form-input{width:100%;padding:8px 12px;border:1px solid #ccc;border-radius:4px;font-size:14px;box-sizing:border-box}.rte-form-input:focus{outline:none;border-color:#06c;box-shadow:0 0 0 2px #06c3}.rte-form-row{display:flex;gap:12px}.rte-form-row .rte-form-group{flex:1}.rte-color-preview{display:flex;align-items:center;gap:12px;margin-bottom:20px;padding:12px;background:#f8f9fa;border-radius:4px}.rte-color-sample{width:40px;height:40px;border-radius:4px;border:2px solid #ddd}.rte-color-value{font-family:monospace;font-size:14px;font-weight:500;color:#333}.rte-color-section{margin-bottom:20px}.rte-color-label{margin-bottom:8px;font-size:14px;font-weight:500}.rte-color-palette{display:grid;grid-template-columns:repeat(6,1fr);gap:8px;margin-bottom:16px}.rte-color-swatch{width:24px;height:24px;border:2px solid #ddd;border-radius:4px;cursor:pointer;transition:all .2s}.rte-color-swatch:hover{border-color:#999;transform:scale(1.1)}.rte-color-swatch.selected{border-color:#06c;box-shadow:0 0 0 2px #0066cc4d}.rte-custom-color{display:flex;align-items:center;gap:12px}.rte-color-input{width:60px;height:40px;border:2px solid #ddd;border-radius:4px;cursor:pointer}.rte-color-text-input{flex:1;padding:8px 12px;border:1px solid #ccc;border-radius:4px;font-family:monospace;font-size:14px}.rte-color-text-input:focus{outline:none;border-color:#06c;box-shadow:0 0 0 2px #06c3}.rte-iframe-preview{border:1px solid #ddd;border-radius:4px;overflow:hidden;background:#f8f9fa}.rte-iframe-preview iframe{display:block;border:none}.rte-size-presets{display:flex;flex-direction:column;gap:8px}.rte-radio-option{display:flex;align-items:flex-start;gap:8px;padding:8px;border:1px solid #e0e0e0;border-radius:4px;background:#fafbfc}.rte-radio-option:hover{background:#f1f3f4}.rte-radio-option input[type=radio]{margin-top:2px}.rte-radio-label{flex:1;line-height:1.4}.rte-content ul[data-type=checklist]{list-style:none;padding-left:0;margin:1em 0}.rte-content li[data-type=checklist-item]{position:relative;padding-left:2em;margin-bottom:.5em;line-height:1.6}.rte-content li[data-type=checklist-item]:before{content:"";position:absolute;left:0;top:.1em;width:1.2em;height:1.2em;border:2px solid #ccc;border-radius:3px;background:#fff;cursor:pointer;transition:all .2s ease}.rte-content li[data-type=checklist-item]:hover:before{border-color:#999}.rte-content li[data-type=checklist-item][data-checked=true]:before{background:#06c;border-color:#06c}.rte-content li[data-type=checklist-item][data-checked=true]:after{content:"✓";position:absolute;left:.36em;top:.12em;color:#fff;font-size:.9em;font-weight:700;pointer-events:none}.rte-content li[data-type=checklist-item][data-checked=true] p{text-decoration:line-through;color:#666}.editora-statusbar-container{display:flex;flex-direction:column}.rte-editor{.editora-statusbar-bottom{top:-32px}}.editora-statusbar-bottom{position:relative;border-left:1px solid rgb(221,221,221);border-right:1px solid rgb(221,221,221)}.editora-statusbar{display:flex;align-items:center;gap:12px;padding:6px 12px;background:#f5f5f5;border-top:1px solid #ddd;font-size:12px;color:#666}.editora-theme-dark .editora-statusbar{background:#252526;border-top-color:#3c3c3c;color:#9a9a9a}.editora-statusbar-top{border-top:none;border-bottom:1px solid #e0e0e0}.editora-statusbar-left{display:flex;align-items:center;gap:8px}.editora-statusbar-right{display:flex;align-items:center;gap:8px;margin-left:auto}.editora-statusbar-item{white-space:nowrap;padding:2px 4px}.editora-statusbar-separator{color:#ddd}.editora-theme-dark .editora-statusbar-separator{color:#3c3c3c}.editora-theme-dark .rte-content,.editora-theme-dark .rte-content h1,.editora-theme-dark .rte-content h2,.editora-theme-dark .rte-content h3,.editora-theme-dark .rte-content h4,.editora-theme-dark .rte-content h5,.editora-theme-dark .rte-content h6{color:#fff}.rte-inline-menu{position:fixed;z-index:1000;background:#fff;border:1px solid #ccc;border-radius:4px;box-shadow:0 2px 8px #00000026;min-width:120px;max-width:200px;pointer-events:auto}.rte-inline-menu-item{padding:8px 12px;cursor:pointer;font-size:14px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;background-color:transparent}.rte-inline-menu-item:hover{background-color:#f5f5f5}.floating-toolbar{--rte-floating-toolbar-bg: #ffffff;--rte-floating-toolbar-border: #d7dee8;--rte-floating-toolbar-text: #364152;--rte-floating-toolbar-hover-bg: #f2f6fb;--rte-floating-toolbar-hover-text: #101828;--rte-floating-toolbar-active-bg: #e7eef7;--rte-floating-toolbar-separator: #d8e1ec;--rte-floating-toolbar-shadow: 0 10px 28px rgba(15, 23, 36, .16);user-select:none;-webkit-user-select:none;align-items:center;gap:4px;padding:6px;border-radius:8px;border:1px solid var(--rte-floating-toolbar-border);background:var(--rte-floating-toolbar-bg);color:var(--rte-floating-toolbar-text);box-shadow:var(--rte-floating-toolbar-shadow);pointer-events:auto;animation:rteFloatingToolbarIn .15s ease-out}.floating-toolbar-btn{display:inline-flex;align-items:center;justify-content:center;min-width:32px;height:32px;border:none;border-radius:6px;background:transparent;color:inherit;cursor:pointer;font-size:14px;font-weight:600;transition:background-color .15s ease,color .15s ease,transform .12s ease}.floating-toolbar-btn:hover{background:var(--rte-floating-toolbar-hover-bg);color:var(--rte-floating-toolbar-hover-text)}.floating-toolbar-btn:active{background:var(--rte-floating-toolbar-active-bg);transform:scale(.96)}.floating-toolbar-separator{width:1px;height:20px;margin:0 2px;background:var(--rte-floating-toolbar-separator)}@keyframes rteFloatingToolbarIn{0%{opacity:0;transform:translate(-50%) translateY(8px)}to{opacity:1;transform:translate(-50%) translateY(0)}}.editora-toolbar-group-button{display:flex;align-items:center;border-radius:var(--rte-radius);overflow:hidden;border:1px solid var(--rte-color-border-light);background:var(--rte-color-bg-secondary, #f9fafb);margin-right:.5rem;padding:0}.editora-toolbar-group-items{display:flex;align-items:center;gap:0}.editora-toolbar-group-button .editora-toolbar-button,.editora-toolbar-group-button .editora-toolbar-input{border-radius:0;border:none;margin:0;background:transparent;box-shadow:none}.editora-toolbar-group-button .editora-toolbar-button:first-child{border-radius:var(--rte-radius) 0 0 var(--rte-radius)}.editora-toolbar-group-button .editora-toolbar-button:last-child{border-radius:0 var(--rte-radius) var(--rte-radius) 0}.editora-toolbar-group-button .editora-toolbar-input{min-width:44px;width:44px;text-align:center;font-size:15px;background:#fff;border-left:1px solid var(--rte-color-border-light);border-right:1px solid var(--rte-color-border-light)}.editora-toolbar-group-button .editora-toolbar-button:active,.editora-toolbar-group-button .editora-toolbar-button:focus{background:#e5e7eb}.editora-toolbar-group-button .editora-toolbar-input:focus{outline:1.5px solid var(--rte-color-primary, #2563eb)}:root{--rte-color-primary: #007bff;--rte-color-primary-hover: #0056b3;--rte-color-secondary: #6c757d;--rte-color-success: #28a745;--rte-color-danger: #dc3545;--rte-color-warning: #ffc107;--rte-color-info: #17a2b8;--rte-color-text-primary: #212529;--rte-color-text-secondary: #6c757d;--rte-color-text-muted: #868e96;--rte-color-text-inverse: #ffffff;--rte-color-bg-primary: #ffffff;--rte-color-bg-secondary: #f8f9fa;--rte-color-bg-tertiary: #e9ecef;--rte-color-bg-hover: #f8f9fa;--rte-color-bg-active: #e9ecef;--rte-color-border: #dee2e6;--rte-color-border-light: #f8f9fa;--rte-color-border-focus: #007bff;--rte-shadow-sm: 0 1px 2px rgba(0, 0, 0, .05);--rte-shadow: 0 1px 3px rgba(0, 0, 0, .1), 0 1px 2px rgba(0, 0, 0, .06);--rte-shadow-lg: 0 10px 15px rgba(0, 0, 0, .1), 0 4px 6px rgba(0, 0, 0, .05);--rte-space-xs: .25rem;--rte-space-sm: .5rem;--rte-space-md: 1rem;--rte-space-lg: 1.5rem;--rte-space-xl: 2rem;--rte-space-xxl: 3rem;--rte-font-family-base: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;--rte-font-family-mono: "SFMono-Regular", Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--rte-font-size-xs: .75rem;--rte-font-size-sm: .875rem;--rte-font-size-base: 1rem;--rte-font-size-lg: 1.125rem;--rte-font-size-xl: 1.25rem;--rte-font-size-xxl: 1.5rem;--rte-font-size-xxxl: 2rem;--rte-font-weight-normal: 400;--rte-font-weight-medium: 500;--rte-font-weight-semibold: 600;--rte-font-weight-bold: 700;--rte-line-height-tight: 1.25;--rte-line-height-normal: 1.5;--rte-line-height-relaxed: 1.75;--rte-radius-sm: .125rem;--rte-radius: .25rem;--rte-radius-md: .375rem;--rte-radius-lg: .5rem;--rte-radius-xl: .75rem;--rte-transition-fast: .15s ease-in-out;--rte-transition-normal: .25s ease-in-out;--rte-transition-slow: .35s ease-in-out;--rte-z-dropdown: 1000;--rte-z-sticky: 1020;--rte-z-modal: 1050;--rte-z-popover: 1060;--rte-z-tooltip: 1070}.rte-editor{font-family:var(--rte-font-family-base);font-size:var(--rte-font-size-base);line-height:var(--rte-line-height-normal);color:var(--rte-color-text-primary);background-color:var(--rte-color-bg-primary);border:1px solid var(--rte-color-border);border-radius:var(--rte-radius);box-shadow:var(--rte-shadow);transition:border-color var(--rte-transition-fast),box-shadow var(--rte-transition-fast)}.rte-editor:focus-within{border-color:var(--rte-color-border-focus);box-shadow:var(--rte-shadow),0 0 0 3px #007bff1a}.rte-toolbar{display:flex;align-items:center;padding:var(--rte-space-sm);border-bottom:1px solid var(--rte-color-border);background-color:var(--rte-color-bg-secondary);border-radius:var(--rte-radius) var(--rte-radius) 0 0;flex-wrap:wrap;gap:2px}.rte-toolbar-group{display:flex;align-items:center;border-radius:var(--rte-radius);overflow:hidden;border:1px solid var(--rte-color-border-light)}.rte-toolbar-button{display:flex;align-items:center;justify-content:center;width:2rem;height:2rem;padding:0;border:none;background:transparent;color:var(--rte-color-text-secondary);cursor:pointer;border-radius:var(--rte-radius-sm);transition:background-color var(--rte-transition-fast),color var(--rte-transition-fast);font-size:14px;line-height:1}.rte-toolbar-button span{display:flex;justify-content:center;align-items:center}.rte-toolbar-button svg,.editora-toolbar-button svg,.editora-toolbar-icon svg{flex-shrink:0;width:20px;height:20px;display:block;color:currentColor;fill:currentColor}.rte-toolbar-button:hover svg{opacity:.9}:is(.rte-toolbar-button[data-active=true],.editora-toolbar-button.active) svg{color:var(--rte-color-text-inverse)}.rte-toolbar-button:hover{background-color:var(--rte-color-bg-hover);color:var(--rte-color-text-primary)}.rte-toolbar-button:active,.rte-toolbar-button[data-active=true]{background-color:var(--rte-color-primary);color:var(--rte-color-text-inverse)}.rte-toolbar-button:disabled{opacity:.5;cursor:not-allowed}.rte-content{padding:var(--rte-space-md);min-height:200px;outline:none;overflow-wrap:break-word;word-wrap:break-word}.rte-content[contenteditable=true]{cursor:text}.rte-content h1,.rte-content h2,.rte-content h3,.rte-content h4,.rte-content h5,.rte-content h6{margin:var(--rte-space-lg) 0 var(--rte-space-md) 0;font-weight:var(--rte-font-weight-semibold);line-height:var(--rte-line-height-tight);color:var(--rte-color-text-primary)}.rte-content h1{font-size:var(--rte-font-size-xxxl)}.rte-content h2{font-size:var(--rte-font-size-xxl)}.rte-content h3{font-size:var(--rte-font-size-xl)}.rte-content h4{font-size:var(--rte-font-size-lg)}.rte-content h5{font-size:var(--rte-font-size-base)}.rte-content h6{font-size:var(--rte-font-size-sm)}.rte-content p{margin:var(--rte-space-md) 0}.rte-content blockquote{margin:var(--rte-space-lg) 0;padding:var(--rte-space-md);padding-left:var(--rte-space-lg);border-left:4px solid var(--rte-color-primary);background-color:var(--rte-color-bg-secondary);font-style:italic;color:var(--rte-color-text-secondary)}.rte-content ul,.rte-content ol{margin:var(--rte-space-md) 0;padding-left:var(--rte-space-xl)}.rte-content li{margin:var(--rte-space-xs) 0}.rte-content ul{list-style-type:disc}.rte-content ol{list-style-type:decimal}.rte-link{color:var(--rte-color-primary);text-decoration:none;transition:color var(--rte-transition-fast)}.rte-link:hover{color:var(--rte-color-primary-hover);text-decoration:underline}.rte-content code{font-family:var(--rte-font-family-mono);font-size:.875em;background-color:var(--rte-color-bg-tertiary);padding:.125rem .25rem;border-radius:var(--rte-radius-sm);color:var(--rte-color-danger)}.rte-content::selection{background-color:#007bff33}.rte-content:empty:before,.rte-content.rte-content-empty:before{content:attr(data-placeholder);color:var(--rte-color-text-muted);pointer-events:none}.rte-content:focus{outline:none}.rte-sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.rte-text-left{text-align:left}.rte-text-center{text-align:center}.rte-text-right{text-align:right}.rte-text-justify{text-align:justify}.rte-table,table{border-collapse:collapse;width:100%;margin:1rem 0;border:1px solid #ddd;font-size:14px;line-height:1.4;position:relative}.rte-table td,.rte-table th,table td,table th{border:1px solid #ddd;padding:8px 12px;min-width:80px;vertical-align:top;position:relative;-webkit-user-select:none;user-select:none}.rte-table td:focus,.rte-table th:focus,table td:focus,table th:focus{outline:2px solid #007acc;outline-offset:-2px}.rte-table th,table th{background-color:#f8f9fa;font-weight:600;text-align:left}.rte-table td p,table td p{margin:0;padding:0}.rte-table td p:empty:before,table td p:empty:before{content:"";display:inline-block}.rte-table td[contenteditable]:empty:before,table td[contenteditable]:empty:before{content:"Type here...";color:#999;font-style:italic;pointer-events:none}.rte-table tr:hover,table tr:hover{background-color:#f8f9fa}.rte-table td.selected,table td.selected{background-color:#e3f2fd;border-color:#2196f3}.table-toolbar{background:#fff;border:1px solid #d0d0d0;border-radius:4px;box-shadow:0 2px 8px #0000001a;padding:4px;display:flex;align-items:center;gap:0;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,sans-serif;min-width:max-content}.toolbar-section{display:flex;align-items:center;gap:2px}.toolbar-divider{width:1px;height:20px;background:#e0e0e0;margin:0 4px}.toolbar-icon-btn{display:flex;align-items:center;justify-content:center;width:28px;height:28px;padding:0;border:1px solid transparent;background:transparent;cursor:pointer;color:#333;border-radius:3px;transition:all .2s ease;flex-shrink:0;font-size:14px;line-height:1}.toolbar-icon-btn svg{width:16px;height:16px}.toolbar-icon-btn:hover:not(:disabled){background:#f0f0f0;border-color:#d0d0d0;color:#06c}.toolbar-icon-btn:active:not(:disabled){background:#e8f0ff;border-color:#06c;transform:scale(.95)}.toolbar-icon-btn:disabled{opacity:.4;cursor:not-allowed;color:#ccc}.toolbar-icon-btn-danger{color:#d32f2f}.toolbar-icon-btn-danger:hover:not(:disabled){background:#fff3f3;border-color:#fcc;color:#d32f2f}.toolbar-icon-btn-danger:active:not(:disabled){background:#ffebee}.toolbar-icon-btn-delete{color:#d32f2f}.toolbar-icon-btn-delete:hover:not(:disabled){background:#fff3f3;border-color:#fcc;color:#d32f2f}.toolbar-icon-btn-delete:active:not(:disabled){background:#ffebee}.resize-handle{opacity:0;transition:all .15s ease}.resize-handle:hover{opacity:1}td:hover>.resize-handle,th:hover>.resize-handle{opacity:1}.table-resize-handle{position:absolute;bottom:-4px;right:-4px;width:12px;height:12px;background:transparent;cursor:nwse-resize;z-index:10;transition:background .15s ease}.table-resize-handle:after{content:"";position:absolute;bottom:0;right:0;width:8px;height:8px;background:#0066cc4d;border-bottom:2px solid #0066cc;border-right:2px solid #0066cc;border-radius:0 0 2px;opacity:0;transition:opacity .15s ease}.table-resize-handle:hover:after{opacity:1}.rte-table:hover .table-resize-handle:after,table:hover .table-resize-handle:after{opacity:1}:is([data-theme=dark],.dark,.editora-theme-dark) :is(.rte-table,table){border-color:#607088;background:#24303c;color:#e6eefb}:is([data-theme=dark],.dark,.editora-theme-dark) :is(.rte-table td,.rte-table th,table td,table th){border-color:#607088;color:#e6eefb}:is([data-theme=dark],.dark,.editora-theme-dark) :is(.rte-table th,table th){background:linear-gradient(180deg,#3b4553,#333d4a);color:#f3f8ff}:is([data-theme=dark],.dark,.editora-theme-dark) :is(.rte-table tr:hover,table tr:hover){background-color:#58a6ff1f}:is([data-theme=dark],.dark,.editora-theme-dark) :is(.rte-table td.selected,table td.selected){background-color:#58a6ff47;border-color:#79beff}:is([data-theme=dark],.dark,.editora-theme-dark) :is(.rte-table td[contenteditable]:empty:before,table td[contenteditable]:empty:before){color:#94a3b8}:is([data-theme=dark],.dark,.editora-theme-dark) .table-toolbar{background:linear-gradient(180deg,#2f3844,#2a323c);border-color:#4d596b;box-shadow:0 8px 20px #00000073}.table-toolbar.rte-theme-dark{background:linear-gradient(180deg,#2f3844,#2a323c);border-color:#4d596b;box-shadow:0 8px 20px #00000073}:is([data-theme=dark],.dark,.editora-theme-dark) .toolbar-divider{background:#4d596b}.table-toolbar.rte-theme-dark .toolbar-divider{background:#4d596b}:is([data-theme=dark],.dark,.editora-theme-dark) .toolbar-icon-btn{color:#d7deea;border-color:transparent}.table-toolbar.rte-theme-dark .toolbar-icon-btn{color:#d7deea;border-color:transparent}:is([data-theme=dark],.dark,.editora-theme-dark) .toolbar-icon-btn svg{color:currentColor;fill:currentColor}.table-toolbar.rte-theme-dark .toolbar-icon-btn svg{color:currentColor;fill:currentColor}:is([data-theme=dark],.dark,.editora-theme-dark) .toolbar-icon-btn svg [stroke="#000" i],:is([data-theme=dark],.dark,.editora-theme-dark) .toolbar-icon-btn svg [stroke="#000000" i],:is([data-theme=dark],.dark,.editora-theme-dark) .toolbar-icon-btn svg [stroke=black i]{stroke:currentColor!important}.table-toolbar.rte-theme-dark .toolbar-icon-btn svg [stroke="#000" i],.table-toolbar.rte-theme-dark .toolbar-icon-btn svg [stroke="#000000" i],.table-toolbar.rte-theme-dark .toolbar-icon-btn svg [stroke=black i]{stroke:currentColor!important}:is([data-theme=dark],.dark,.editora-theme-dark) .toolbar-icon-btn svg [fill="#000" i],:is([data-theme=dark],.dark,.editora-theme-dark) .toolbar-icon-btn svg [fill="#000000" i],:is([data-theme=dark],.dark,.editora-theme-dark) .toolbar-icon-btn svg [fill=black i]{fill:currentColor!important}.table-toolbar.rte-theme-dark .toolbar-icon-btn svg [fill="#000" i],.table-toolbar.rte-theme-dark .toolbar-icon-btn svg [fill="#000000" i],.table-toolbar.rte-theme-dark .toolbar-icon-btn svg [fill=black i]{fill:currentColor!important}:is([data-theme=dark],.dark,.editora-theme-dark) .toolbar-icon-btn:hover:not(:disabled){background:#3a4554;border-color:#607088;color:#f3f8ff}.table-toolbar.rte-theme-dark .toolbar-icon-btn:hover:not(:disabled){background:#3a4554;border-color:#607088;color:#f3f8ff}:is([data-theme=dark],.dark,.editora-theme-dark) .toolbar-icon-btn:active:not(:disabled){background:#4a95de;border-color:#67adf4;color:#0f1b2a}.table-toolbar.rte-theme-dark .toolbar-icon-btn:active:not(:disabled){background:#4a95de;border-color:#67adf4;color:#0f1b2a}:is([data-theme=dark],.dark,.editora-theme-dark) .toolbar-icon-btn:disabled{color:#7f8ca1}.table-toolbar.rte-theme-dark .toolbar-icon-btn:disabled{color:#7f8ca1}@media(max-width:768px){.rte-table,table{font-size:12px}.rte-table td,.rte-table th,table td,table th{padding:4px 6px;min-width:60px}.table-toolbar{padding:3px;gap:0;max-width:90vw;overflow-x:auto}.toolbar-icon-btn{width:26px;height:26px}.toolbar-divider{height:18px}}@media print{.rte-table,table{border:1px solid #000}.rte-table td,.rte-table th,table td,table th{border:1px solid #000;padding:4px}.table-toolbar{display:none}} | ||
| .editora-editor{display:flex;flex-direction:column;border:1px solid #ddd;border-radius:4px;background:#fff;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,sans-serif;font-size:14px;overflow:hidden}.editora-editor *{box-sizing:border-box}.editora-theme-light{background:#fff;color:#333}.editora-theme-dark{--editora-dark-toolbar-bg-start: #353d48;--editora-dark-toolbar-bg-end: #2d3540;--editora-dark-button-bg-start: #46505f;--editora-dark-button-bg-end: #3b4553;--editora-dark-button-hover-start: #525d6d;--editora-dark-button-hover-end: #465262;--editora-dark-button-active-start: #5eaaf6;--editora-dark-button-active-end: #4a95de;--editora-dark-border: #475263;--editora-dark-border-strong: #566275;--editora-dark-text: #e1e9f5;--editora-dark-text-strong: #f3f7ff;--editora-dark-text-muted: #aeb9cc;--editora-dark-surface: #1d242d;--editora-dark-content: #1f2732;background:linear-gradient(180deg,#1b2330,#1c2430);color:var(--editora-dark-text);border-color:var(--editora-dark-border)}.editora-toolbar{display:flex;align-items:center;gap:4px;padding:8px;background:#f5f5f5;border-bottom:1px solid #ddd;flex-wrap:wrap}.editora-theme-dark .editora-toolbar{background:linear-gradient(180deg,var(--editora-dark-toolbar-bg-start) 0%,var(--editora-dark-toolbar-bg-end) 100%);border-bottom-color:var(--editora-dark-border);box-shadow:inset 0 1px #ffffff0d}.editora-toolbar-sticky{position:sticky;top:0;z-index:100;position:-webkit-sticky}.editora-toolbar-group{display:flex;align-items:center;gap:2px}.editora-toolbar-button{padding:6px 12px;border:1px solid #ccc;background:#fff;cursor:pointer;border-radius:3px;font-weight:600;font-size:14px;height:30px;display:flex;align-items:center;white-space:nowrap}.editora-toolbar-group-button{display:flex;align-items:center}.editora-toolbar-input.font-size{width:40px;padding:.25rem;text-align:center;font-size:14px;background:#fff;border:1px solid var(--rte-color-border-light);border-radius:var(--rte-radius-sm)}.editora-toolbar-group-items{display:flex;align-items:center;border:1px solid #ccc;.editora-toolbar-button{border:none;border-radius:0;&:first-child{border-right:1px solid #ccc;border-top-left-radius:3px;border-bottom-left-radius:3px}&:last-child{border:0px solid #ccc;border-radius:0!important}&:hover{background:#e0e0e0;border-color:#ccc}}}.editora-theme-dark .editora-toolbar-button{background:linear-gradient(180deg,var(--editora-dark-button-bg-start) 0%,var(--editora-dark-button-bg-end) 100%);border-color:var(--editora-dark-border-strong);color:var(--editora-dark-text);box-shadow:inset 0 1px #ffffff14,0 1px 1px #00000059}.editora-theme-dark .editora-toolbar-group-items{border-color:var(--editora-dark-border-strong);background:linear-gradient(180deg,var(--editora-dark-button-bg-start) 0%,var(--editora-dark-button-bg-end) 100%)}.editora-theme-dark .editora-toolbar-group-items .editora-toolbar-button:first-child{border-right-color:#566275}.editora-theme-dark .editora-toolbar-group-items .editora-toolbar-button:last-child{border-left-color:#566275}.editora-theme-dark .editora-toolbar-input.font-size{background-color:#2e3642;color:var(--editora-dark-text-strong);border-color:var(--editora-dark-border-strong);caret-color:var(--editora-dark-text-strong)}.editora-theme-dark .editora-toolbar-input.font-size::placeholder{color:var(--editora-dark-text-strong);opacity:1}.editora-toolbar-button:hover{background:#e0e0e0;border-color:#ccc}.editora-theme-dark .editora-toolbar-button:hover{background:linear-gradient(180deg,var(--editora-dark-button-hover-start) 0%,var(--editora-dark-button-hover-end) 100%);border-color:#66748a;color:var(--editora-dark-text-strong)}.editora-toolbar-button:active,.editora-toolbar-button.active{background:#d0d0d0;border-color:#999}.editora-theme-dark .editora-toolbar-button:active,.editora-theme-dark .editora-toolbar-button.active{background:linear-gradient(180deg,var(--editora-dark-button-active-start) 0%,var(--editora-dark-button-active-end) 100%);border-color:#67adf4;color:#0f1b2a}.editora-theme-dark .editora-toolbar-button:disabled{background:#313946;border-color:#424d5e;color:#7f8ca1}.editora-theme-dark .editora-toolbar-button[data-command=insertTable],.editora-theme-dark .editora-toolbar-button[data-command=print],.editora-theme-dark .editora-toolbar-button[data-command=toggleSpellCheck],.editora-theme-dark .editora-toolbar-button[data-command=toggleA11yChecker],.editora-theme-dark .editora-toolbar-button[data-command=setDirectionLTR],.editora-theme-dark .editora-toolbar-button[data-command=setDirectionRTL]{color:#f1f6ff}.editora-toolbar-button:disabled{opacity:.5;cursor:not-allowed}.editora-toolbar-icon{display:inline-flex;align-items:center;justify-content:center;width:24px;height:24px;line-height:1}.editora-toolbar-button svg,.editora-toolbar-icon svg{width:20px;height:20px;display:block;color:currentColor;fill:currentColor}.editora-theme-dark .editora-toolbar-icon,.editora-theme-dark .editora-toolbar-icon *{color:inherit}.editora-theme-dark :is(.editora-toolbar-button,.editora-toolbar-icon) svg :is([stroke="#000" i],[stroke="#000000" i],[stroke=black i],[stroke="#0f0f0f" i],[stroke="#111111" i],[style*="stroke:#000" i],[style*="stroke: #000" i],[style*="stroke:black" i],[style*="stroke: black" i],[style*="stroke:#0f0f0f" i],[style*="stroke: #0f0f0f" i]){stroke:currentColor!important}.editora-theme-dark :is(.editora-toolbar-button,.editora-toolbar-icon) svg :is([fill="#000" i],[fill="#000000" i],[fill=black i],[fill="#0f0f0f" i],[fill="#111111" i],[style*="fill:#000" i],[style*="fill: #000" i],[style*="fill:black" i],[style*="fill: black" i],[style*="fill:#0f0f0f" i],[style*="fill: #0f0f0f" i]){fill:currentColor!important}.editora-toolbar-separator{width:1px;height:24px;background:#ddd;margin:0 4px}.editora-theme-dark .editora-toolbar-separator{background:#4d596b}.editora-toolbar-dropdown{position:relative}.editora-toolbar-dropdown-menu{position:absolute;top:100%;left:0;min-width:150px;margin-top:4px;padding:4px 0;background:#fff;border:1px solid #ddd;border-radius:4px;box-shadow:0 2px 8px #00000026;z-index:1000}.editora-theme-dark .editora-toolbar-dropdown-menu{background:#29323d;border-color:#4d596b;box-shadow:0 8px 20px #00000073}.editora-toolbar-dropdown-item{display:block;width:100%;padding:8px 12px;border:none;background:transparent;color:#333;text-align:left;cursor:pointer;font-size:13px;transition:background .15s ease}.editora-theme-dark .editora-toolbar-dropdown-item{color:#d7deea}.editora-toolbar-dropdown-item:hover{background:#f5f5f5}.editora-theme-dark .editora-toolbar-dropdown-item:hover{background:#3a4554;color:#f0f6ff}.editora-content{flex:1;min-height:200px;padding:16px;outline:none;overflow-y:auto;line-height:1.6}.editora-theme-dark .editora-content{color:#ecf3ff;background:linear-gradient(180deg,var(--editora-dark-content) 0%,#1c232e 100%)}.editora-content:empty:before{content:attr(data-placeholder);color:#999;pointer-events:none}.editora-theme-dark .editora-content:empty:before{color:#8f9bb0}.editora-content h1{font-size:2em;margin:.67em 0;font-weight:600}.editora-content h2{font-size:1.5em;margin:.75em 0;font-weight:600}.editora-content h3{font-size:1.17em;margin:.83em 0;font-weight:600}.editora-content p{margin:1em 0}.editora-theme-dark .editora-content,.editora-theme-dark .editora-content :is(p,span,div,li,ul,ol,td,th,h1,h2,h3,h4,h5,h6,strong,em,u,s,small,sub,sup,blockquote,code,pre,a){color:#ecf3ff}.editora-content ul,.editora-content ol{margin:1em 0;padding-left:2em}.editora-content a{color:#06c;text-decoration:underline}.editora-theme-dark .editora-content a{color:#ecf3ff}.editora-content code{padding:2px 4px;background:#f5f5f5;border-radius:3px;font-family:Monaco,Menlo,Consolas,monospace;font-size:.9em}.editora-theme-dark .editora-content code{background:#1e1e1e}.editora-content pre{padding:12px;background:#f5f5f5;border-radius:4px;overflow-x:auto;margin:1em 0}.editora-theme-dark .editora-content pre{background:#1e1e1e}.editora-theme-dark .rte-code-block{background:linear-gradient(180deg,#212a36,#1b2430)!important;border-color:#4f5b70!important;color:#e7effc!important}.editora-theme-dark .rte-code-block code{color:#e7effc!important}.editora-theme-dark .rte-code-block:before{background:#111927!important;color:#dce8ff!important}.editora-theme-dark .rte-code-block .rte-code-copy{background:#2b3441!important;border-color:#5a667b!important;color:#dce8ff!important}.editora-content blockquote{margin:1em 0;padding-left:1em;border-left:4px solid #ddd;color:#666}.editora-theme-dark .editora-content blockquote{border-left-color:#3c3c3c;color:#ecf3ff}.editora-floating-toolbar{position:absolute;padding:4px;background:#fff;border:1px solid #ddd;border-radius:4px;box-shadow:0 2px 8px #00000026;z-index:1000}.editora-theme-dark .editora-floating-toolbar{background:#29323d;border-color:#4d596b;box-shadow:0 8px 20px #00000073}.editora-theme-dark .editora-statusbar{background:linear-gradient(180deg,#2c3440,#252d37);border-top-color:#3f4a5b;color:#d7deea}.editora-statusbar-item{white-space:nowrap}.editora-theme-dark .editora-statusbar-separator{color:#566275}.editora-editor[readonly] .editora-content{background:#fafafa;cursor:not-allowed}.editora-theme-dark.editora-editor[readonly] .editora-content{background:#1a1a1a}.editora-editor:focus-within{border-color:#06c;box-shadow:0 0 0 3px #0066cc1a}.editora-theme-dark.editora-editor:focus-within{border-color:#4db8ff;box-shadow:0 0 0 3px #4db8ff1a}.editora-editor[disabled]{opacity:.6;pointer-events:none}@media(max-width:768px){.editora-toolbar{padding:4px}.editora-toolbar-button{min-width:28px;min-height:28px;padding:4px 8px;font-size:12px}.editora-content{padding:12px}}.editora-content ::selection{background:#06c3}.editora-theme-dark .editora-content ::selection{background:#4db8ff33}.editora-content table{border-collapse:collapse;width:100%;margin:1em 0}.editora-content th,.editora-content td{border:1px solid #ddd;padding:8px 12px;text-align:left}.editora-theme-dark .editora-content th,.editora-theme-dark .editora-content td{border-color:#3c3c3c}.editora-content th{background:#f5f5f5;font-weight:600}.editora-theme-dark .editora-content th{background:#252526}.editora-content img{max-width:100%;height:auto;border-radius:4px;display:block}.editora-content video{max-width:100%;height:auto;border-radius:4px;display:block}.editora-editor.loading{opacity:.7;pointer-events:none}.editora-editor.loading:after{content:"";position:absolute;top:50%;left:50%;width:24px;height:24px;margin:-12px 0 0 -12px;border:3px solid #ddd;border-top-color:#06c;border-radius:50%;animation:editora-spin .8s linear infinite}@keyframes editora-spin{to{transform:rotate(360deg)}}.toolbar-container-wrapper{display:flex;align-items:center;background:#fff;border-bottom:1px solid #e0e0e0;padding:0;margin:0;width:100%;box-sizing:border-box;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif;font-size:14px;line-height:1.5;position:relative}.toolbar-container-wrapper[data-toolbar-sticky=true]{position:sticky;top:0;z-index:999;box-shadow:0 2px 4px #0000001a}.toolbar-container-wrapper[data-toolbar-floating=true]{position:fixed;top:0;left:0;right:0;z-index:1000;box-shadow:0 4px 12px #00000026}.toolbar-container-wrapper[data-toolbar-position=bottom]{border-bottom:none;border-top:1px solid #e0e0e0}.toolbar-container-wrapper .toolbar-wrapper{display:flex;width:100%;padding:8px;gap:4px;flex-wrap:wrap;align-items:center}.toolbar-container-wrapper .toolbar{display:flex;width:100%;gap:4px;flex-wrap:wrap;align-items:center}.toolbar-container-wrapper .toolbar-container{display:flex;gap:4px;flex-wrap:wrap;align-items:center;flex:1;position:relative}.toolbar-container-wrapper .toolbar-item{display:flex;align-items:center;gap:2px}.toolbar-container-wrapper .toolbar-button{padding:6px 10px;border:1px solid #d1d5db;background:#fff;border-radius:4px;cursor:pointer;font-size:13px;display:flex;align-items:center;justify-content:center;gap:4px;transition:all .15s ease;min-height:32px;white-space:nowrap}.toolbar-container-wrapper .toolbar-button:hover{background-color:#f3f4f6;border-color:#9ca3af}.toolbar-container-wrapper .toolbar-button:active,.toolbar-container-wrapper .toolbar-button[data-active=true]{background-color:#06c;color:#fff;border-color:#0052a3;box-shadow:inset 0 1px 3px #0000001a}.toolbar-container-wrapper .toolbar-button:disabled{opacity:.5;cursor:not-allowed;background-color:#f9fafb}.toolbar-container-wrapper .toolbar-more-button{padding:6px 8px;font-size:16px;font-weight:500;line-height:1}.toolbar-container-wrapper .toolbar-separator{width:1px;height:24px;background-color:#d1d5db;margin:0 4px}.toolbar-container-wrapper .toolbar-icon{display:inline-flex;align-items:center;justify-content:center;width:18px;height:18px;flex-shrink:0}.toolbar-container-wrapper .toolbar-icon svg{width:100%;height:100%}.toolbar-container-wrapper .toolbar-dropdown{position:relative;display:flex;align-items:center}.toolbar-container-wrapper .toolbar-dropdown-arrow{font-size:10px;margin-left:2px;line-height:1}.toolbar-container-wrapper .toolbar-dropdown-menu{position:absolute;top:100%;left:0;background:#fff;border:1px solid #d1d5db;border-radius:6px;box-shadow:0 4px 12px #00000026;z-index:1000;min-width:160px;padding:4px 0;margin-top:4px;display:none}.toolbar-container-wrapper .toolbar-dropdown-menu.show{display:block}.toolbar-container-wrapper .toolbar-dropdown-item{display:block;width:100%;padding:8px 12px;border:none;background:transparent;text-align:left;cursor:pointer;font-size:13px;color:#1f2937;transition:background-color .15s ease;font-family:inherit}.toolbar-container-wrapper .toolbar-dropdown-item:hover{background-color:#f3f4f6}.toolbar-container-wrapper .toolbar-dropdown-item:active{background-color:#e5e7eb}.toolbar-container-wrapper .toolbar-input{padding:6px 8px;border:1px solid #d1d5db;border-radius:4px;font-size:13px;font-family:inherit;background-color:#fff;color:#1f2937;transition:all .15s ease}.toolbar-container-wrapper .toolbar-input:focus{outline:none;border-color:#06c;box-shadow:0 0 0 3px #0066cc1a;background-color:#fff}.toolbar-container-wrapper .toolbar-input::placeholder{color:#9ca3af}.toolbar-overflow-menu{animation:slideDown .2s ease-out}@keyframes slideDown{0%{opacity:0;transform:translateY(-8px)}to{opacity:1;transform:translateY(0)}}.toolbar-overflow-item{transition:background-color .15s ease}.floating-toolbar{user-select:none;-webkit-user-select:none;font-family:system-ui,-apple-system,sans-serif;font-size:14px;animation:fadeInUp .15s ease-out}@keyframes fadeInUp{0%{opacity:0;transform:translate(-50%) translateY(10px)}to{opacity:1;transform:translate(-50%) translateY(0)}}.floating-toolbar-btn{display:flex;align-items:center;justify-content:center;width:32px;height:32px;border:none;background:transparent;border-radius:4px;color:#495057;cursor:pointer;font-size:14px;font-weight:500;transition:all .15s ease;outline:none}.floating-toolbar-btn:hover{background:#f8f9fa;color:#212529}.floating-toolbar-btn:active{background:#e9ecef;transform:scale(.95)}.floating-toolbar-btn.floating-toolbar-toggle{color:#dc3545;font-weight:700}.floating-toolbar-btn.floating-toolbar-toggle:hover{background:#f8d7da;color:#721c24}.floating-toolbar-separator{width:1px;height:20px;background:#e1e5e9;margin:0 2px}@media(max-width:768px){.toolbar-container-wrapper .toolbar-button{padding:5px 8px;font-size:12px;min-height:28px}.toolbar-container-wrapper .toolbar-icon{width:16px;height:16px}.toolbar-container-wrapper .toolbar-dropdown-menu{min-width:140px}.toolbar-container-wrapper .toolbar-dropdown-item{padding:6px 10px;font-size:12px}.floating-toolbar{padding:4px;gap:2px}.floating-toolbar-btn{width:28px;height:28px;font-size:12px}}@media(max-width:480px){.toolbar-container-wrapper{padding:4px}.toolbar-container-wrapper .toolbar-wrapper{padding:4px;gap:2px}.toolbar-container-wrapper .toolbar-button{padding:4px 6px;font-size:11px;min-height:24px}.toolbar-container-wrapper .toolbar-icon{width:14px;height:14px}}.floating-toolbar{pointer-events:auto}.floating-toolbar{max-width:calc(100vw - 20px);overflow-x:auto}@media(prefers-color-scheme:dark){.floating-toolbar{background:#2d3748;border-color:#4a5568;color:#e2e8f0}.floating-toolbar-btn:hover{background:#4a5568;color:#f7fafc}.floating-toolbar-btn:active{background:#718096}.floating-toolbar-separator{background:#4a5568}}.rte-editor{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif}.rte-toolbar-wrapper{border-radius:4px 4px 0 0}.rte-toolbar{display:flex;gap:4px;padding:8px;background:#f5f5f5;border:1px solid #ddd;border-bottom:none;border-radius:4px 4px 0 0;align-items:center;position:relative}.rte-toolbar-items-container{display:flex;gap:4px;flex-wrap:nowrap;align-items:center;flex:1}.rte-toolbar-item{position:relative;display:flex;align-items:center;white-space:nowrap}.rte-toolbar-group-items.font-size{display:flex;align-items:center;border:1px solid #ccc;.rte-toolbar-input.font-size{width:40px;padding:.25rem;text-align:center;font-size:14px;background:#fff;border:1px solid var(--rte-color-border-light);border-radius:var(--rte-radius-sm)}.rte-toolbar-button{border:none;border-radius:0}.rte-toolbar-item{&:first-child{border-right:1px solid #ccc;border-top-left-radius:3px;border-bottom-left-radius:3px}&:last-child{border-left:1px solid #ccc;border-top-right-radius:3px;border-bottom-right-radius:3px}}}.rte-toolbar-button{padding:6px 12px;border:1px solid #ccc;background:#fff;cursor:pointer;border-radius:3px;font-weight:600;font-size:14px;height:30px;display:flex;align-items:center;white-space:nowrap}.rte-toolbar-button:hover{background:#e9e9e9}.rte-toolbar-input{width:26px;padding:6px 8px;border:1px solid #ccc;border-radius:3px;font-size:14px;text-align:center}.rte-toolbar-dropdown{position:relative}.rte-toolbar-dropdown-menu{position:absolute;top:100%;left:0;background:#fff;border:1px solid #ccc;border-radius:3px;box-shadow:0 2px 8px #00000026;min-width:150px;z-index:1000;margin-top:2px}.rte-toolbar-dropdown-item{padding:8px 12px;cursor:pointer}.rte-toolbar-dropdown-item:hover{background:#f0f0f0}.rte-toolbar-more-button{padding:6px 10px;border:1px solid #ccc;background:#fff;cursor:pointer;border-radius:3px;font-weight:600;font-size:16px;height:30px;display:flex;align-items:center;justify-content:center;min-width:30px;transition:background-color .2s ease;margin-left:auto}.rte-toolbar-more-button:hover{background:#e9e9e9}.rte-toolbar-more-button.active{background:#ddd;border-color:#999}.rte-toolbar-expanded-row{display:flex;flex-wrap:wrap;align-items:flex-start;transform:scaleY(0);transform-origin:top;max-height:0;padding:0;overflow:hidden;opacity:0;transition:transform .25s ease,opacity .2s ease,max-height .25s ease}.rte-toolbar-expanded-row.show{transform:scaleY(1);max-height:320px;padding:1px 8px 8px;opacity:1;background:#f5f5f5;border:1px solid #ddd;border-top:none;gap:4px;overflow-y:auto;overflow-x:hidden}.rte-content{font-size:16px;line-height:1.6}.rte-content.rte-content-empty:before,.rte-content:empty:before{content:attr(data-placeholder);color:var(--rte-color-text-muted, #6b7280);pointer-events:none}.rte-content p{margin:0 0 1em}.rte-content h1{font-size:2em;margin:.67em 0}.rte-content h2{font-size:1.5em;margin:.75em 0}.rte-content h3{font-size:1.17em;margin:.83em 0}.rte-content h4{font-size:1em;margin:1em 0}.rte-content h5{font-size:.83em;margin:1.17em 0}.rte-content h6{font-size:.67em;margin:1.33em 0}.rte-content ul,.rte-content ol{margin:1em 0;padding-left:2em}.rte-content .rte-table,.rte-content table{border-collapse:collapse;width:100%;margin:1rem 0;border:1px solid #ddd;font-size:14px;line-height:1.4}.rte-content .rte-table td,.rte-content .rte-table th,.rte-content table td,.rte-content table th{border:1px solid #ddd;padding:8px 12px;min-width:80px;text-align:left;vertical-align:top}.rte-content .rte-table th,.rte-content table th{background-color:#f8f9fa;font-weight:600}.rte-content .rte-table td p,.rte-content table td p{margin:0}.table-toolbar{background:#fff;border:1px solid #d0d0d0;border-radius:4px;box-shadow:0 2px 8px #0000001a;padding:4px;display:flex;align-items:center}.toolbar-icon-btn{display:flex;align-items:center;justify-content:center;width:28px;height:28px;padding:0;border:1px solid transparent;background:transparent;color:#333;border-radius:3px;cursor:pointer}.toolbar-icon-btn:hover:not(:disabled){background:#f0f0f0;border-color:#d0d0d0}.rte-content code{background:#f4f4f4;padding:2px 6px;border-radius:3px;font-family:Courier New,monospace;font-size:.9em}.rte-content blockquote{border-left:4px solid #ddd;margin:1em 0;padding-left:1em;color:#666}.rte-content a{color:#06c;text-decoration:underline}.rte-content a:hover{color:#0052a3}.rte-dialog-overlay{position:fixed;inset:0;background:#00000080;display:flex;align-items:center;justify-content:center;z-index:10000}.rte-dialog-content{background:#fff;border-radius:8px;box-shadow:0 4px 20px #0000004d;max-width:400px;width:90%;max-height:90vh;overflow-y:auto}.rte-dialog-header{padding:16px 20px;border-bottom:1px solid #e0e0e0;display:flex;justify-content:space-between;align-items:center}.rte-dialog-header h3{margin:0;font-size:18px;font-weight:600;color:#333}.rte-dialog-close{background:none;border:none;font-size:24px;cursor:pointer;color:#666;padding:0;width:30px;height:30px;display:flex;align-items:center;justify-content:center}.rte-dialog-close:hover{color:#333}.rte-dialog-body{padding:20px}.rte-dialog-footer{padding:16px 20px;border-top:1px solid #e0e0e0;display:flex;justify-content:flex-end;gap:12px}.rte-btn{padding:8px 16px;border:1px solid #ccc;border-radius:4px;cursor:pointer;font-size:14px;font-weight:500;transition:all .2s}.rte-btn:hover{border-color:#999}.rte-btn-primary{background:#06c;color:#fff;border-color:#06c}.rte-btn-primary:hover{background:#0052a3;border-color:#0052a3}.rte-btn-secondary{background:#fff;color:#333}.rte-btn-secondary:hover{background:#f5f5f5}.rte-form-group{margin-bottom:16px}.rte-form-label{display:block;margin-bottom:6px;font-weight:500;color:#333;font-size:14px}.rte-form-input{width:100%;padding:8px 12px;border:1px solid #ccc;border-radius:4px;font-size:14px;box-sizing:border-box}.rte-form-input:focus{outline:none;border-color:#06c;box-shadow:0 0 0 2px #06c3}.rte-form-row{display:flex;gap:12px}.rte-form-row .rte-form-group{flex:1}.rte-color-preview{display:flex;align-items:center;gap:12px;margin-bottom:20px;padding:12px;background:#f8f9fa;border-radius:4px}.rte-color-sample{width:40px;height:40px;border-radius:4px;border:2px solid #ddd}.rte-color-value{font-family:monospace;font-size:14px;font-weight:500;color:#333}.rte-color-section{margin-bottom:20px}.rte-color-label{margin-bottom:8px;font-size:14px;font-weight:500}.rte-color-palette{display:grid;grid-template-columns:repeat(6,1fr);gap:8px;margin-bottom:16px}.rte-color-swatch{width:24px;height:24px;border:2px solid #ddd;border-radius:4px;cursor:pointer;transition:all .2s}.rte-color-swatch:hover{border-color:#999;transform:scale(1.1)}.rte-color-swatch.selected{border-color:#06c;box-shadow:0 0 0 2px #0066cc4d}.rte-custom-color{display:flex;align-items:center;gap:12px}.rte-color-input{width:60px;height:40px;border:2px solid #ddd;border-radius:4px;cursor:pointer}.rte-color-text-input{flex:1;padding:8px 12px;border:1px solid #ccc;border-radius:4px;font-family:monospace;font-size:14px}.rte-color-text-input:focus{outline:none;border-color:#06c;box-shadow:0 0 0 2px #06c3}.rte-iframe-preview{border:1px solid #ddd;border-radius:4px;overflow:hidden;background:#f8f9fa}.rte-iframe-preview iframe{display:block;border:none}.rte-size-presets{display:flex;flex-direction:column;gap:8px}.rte-radio-option{display:flex;align-items:flex-start;gap:8px;padding:8px;border:1px solid #e0e0e0;border-radius:4px;background:#fafbfc}.rte-radio-option:hover{background:#f1f3f4}.rte-radio-option input[type=radio]{margin-top:2px}.rte-radio-label{flex:1;line-height:1.4}.rte-content ul[data-type=checklist]{list-style:none;padding-left:0;margin:1em 0}.rte-content li[data-type=checklist-item]{position:relative;padding-left:2em;margin-bottom:.5em;line-height:1.6}.rte-content li[data-type=checklist-item]:before{content:"";position:absolute;left:0;top:.1em;width:1.2em;height:1.2em;border:2px solid #ccc;border-radius:3px;background:#fff;cursor:pointer;transition:all .2s ease}.rte-content li[data-type=checklist-item]:hover:before{border-color:#999}.rte-content li[data-type=checklist-item][data-checked=true]:before{background:#06c;border-color:#06c}.rte-content li[data-type=checklist-item][data-checked=true]:after{content:"✓";position:absolute;left:.36em;top:.12em;color:#fff;font-size:.9em;font-weight:700;pointer-events:none}.rte-content li[data-type=checklist-item][data-checked=true] p{text-decoration:line-through;color:#666}.editora-statusbar-container{display:flex;flex-direction:column}.rte-editor{.editora-statusbar-bottom{top:-32px}}.editora-statusbar-bottom{position:relative;border-left:1px solid rgb(221,221,221);border-right:1px solid rgb(221,221,221)}.editora-statusbar{display:flex;align-items:center;gap:12px;padding:6px 12px;background:#f5f5f5;border-top:1px solid #ddd;font-size:12px;color:#666}.editora-theme-dark .editora-statusbar{background:#252526;border-top-color:#3c3c3c;color:#9a9a9a}.editora-statusbar-top{border-top:none;border-bottom:1px solid #e0e0e0}.editora-statusbar-left{display:flex;align-items:center;gap:8px}.editora-statusbar-right{display:flex;align-items:center;gap:8px;margin-left:auto}.editora-statusbar-item{white-space:nowrap;padding:2px 4px}.editora-statusbar-separator{color:#ddd}.editora-theme-dark .editora-statusbar-separator{color:#3c3c3c}.editora-theme-dark .rte-content,.editora-theme-dark .rte-content h1,.editora-theme-dark .rte-content h2,.editora-theme-dark .rte-content h3,.editora-theme-dark .rte-content h4,.editora-theme-dark .rte-content h5,.editora-theme-dark .rte-content h6{color:#fff}.rte-inline-menu{position:fixed;z-index:1000;background:#fff;border:1px solid #ccc;border-radius:4px;box-shadow:0 2px 8px #00000026;min-width:120px;max-width:200px;pointer-events:auto}.rte-inline-menu-item{padding:8px 12px;cursor:pointer;font-size:14px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;background-color:transparent}.rte-inline-menu-item:hover{background-color:#f5f5f5}.floating-toolbar{--rte-floating-toolbar-bg: #ffffff;--rte-floating-toolbar-border: #d7dee8;--rte-floating-toolbar-text: #364152;--rte-floating-toolbar-hover-bg: #f2f6fb;--rte-floating-toolbar-hover-text: #101828;--rte-floating-toolbar-active-bg: #e7eef7;--rte-floating-toolbar-separator: #d8e1ec;--rte-floating-toolbar-shadow: 0 10px 28px rgba(15, 23, 36, .16);user-select:none;-webkit-user-select:none;align-items:center;gap:4px;padding:6px;border-radius:8px;border:1px solid var(--rte-floating-toolbar-border);background:var(--rte-floating-toolbar-bg);color:var(--rte-floating-toolbar-text);box-shadow:var(--rte-floating-toolbar-shadow);pointer-events:auto;animation:rteFloatingToolbarIn .15s ease-out}.floating-toolbar-btn{display:inline-flex;align-items:center;justify-content:center;min-width:32px;height:32px;border:none;border-radius:6px;background:transparent;color:inherit;cursor:pointer;font-size:14px;font-weight:600;transition:background-color .15s ease,color .15s ease,transform .12s ease}.floating-toolbar-btn:hover{background:var(--rte-floating-toolbar-hover-bg);color:var(--rte-floating-toolbar-hover-text)}.floating-toolbar-btn:active{background:var(--rte-floating-toolbar-active-bg);transform:scale(.96)}.floating-toolbar-separator{width:1px;height:20px;margin:0 2px;background:var(--rte-floating-toolbar-separator)}@keyframes rteFloatingToolbarIn{0%{opacity:0;transform:translate(-50%) translateY(8px)}to{opacity:1;transform:translate(-50%) translateY(0)}}.editora-toolbar-group-button{display:flex;align-items:center;border-radius:var(--rte-radius);overflow:hidden;margin-right:.5rem;padding:0}.editora-toolbar-group-items{display:flex;align-items:center;gap:0}.editora-toolbar-group-button .editora-toolbar-button,.editora-toolbar-group-button .editora-toolbar-input{border-radius:0;border:none;margin:0;background:transparent;box-shadow:none}.editora-toolbar-group-button .editora-toolbar-button:first-child{border-radius:var(--rte-radius) 0 0 var(--rte-radius)}.editora-toolbar-group-button .editora-toolbar-button:last-child{border-radius:0 var(--rte-radius) var(--rte-radius) 0}.editora-toolbar-group-button .editora-toolbar-input{min-width:44px;width:44px;text-align:center;font-size:15px;background:#fff;border-left:1px solid var(--rte-color-border-light);border-right:1px solid var(--rte-color-border-light)}.editora-toolbar-group-button .editora-toolbar-button:active,.editora-toolbar-group-button .editora-toolbar-button:focus{background:#e5e7eb}.editora-toolbar-group-button .editora-toolbar-input:focus{outline:1.5px solid var(--rte-color-primary, #2563eb)}:root{--rte-color-primary: #007bff;--rte-color-primary-hover: #0056b3;--rte-color-secondary: #6c757d;--rte-color-success: #28a745;--rte-color-danger: #dc3545;--rte-color-warning: #ffc107;--rte-color-info: #17a2b8;--rte-color-text-primary: #212529;--rte-color-text-secondary: #6c757d;--rte-color-text-muted: #868e96;--rte-color-text-inverse: #ffffff;--rte-color-bg-primary: #ffffff;--rte-color-bg-secondary: #f8f9fa;--rte-color-bg-tertiary: #e9ecef;--rte-color-bg-hover: #f8f9fa;--rte-color-bg-active: #e9ecef;--rte-color-border: #dee2e6;--rte-color-border-light: #f8f9fa;--rte-color-border-focus: #007bff;--rte-shadow-sm: 0 1px 2px rgba(0, 0, 0, .05);--rte-shadow: 0 1px 3px rgba(0, 0, 0, .1), 0 1px 2px rgba(0, 0, 0, .06);--rte-shadow-lg: 0 10px 15px rgba(0, 0, 0, .1), 0 4px 6px rgba(0, 0, 0, .05);--rte-space-xs: .25rem;--rte-space-sm: .5rem;--rte-space-md: 1rem;--rte-space-lg: 1.5rem;--rte-space-xl: 2rem;--rte-space-xxl: 3rem;--rte-font-family-base: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;--rte-font-family-mono: "SFMono-Regular", Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--rte-font-size-xs: .75rem;--rte-font-size-sm: .875rem;--rte-font-size-base: 1rem;--rte-font-size-lg: 1.125rem;--rte-font-size-xl: 1.25rem;--rte-font-size-xxl: 1.5rem;--rte-font-size-xxxl: 2rem;--rte-font-weight-normal: 400;--rte-font-weight-medium: 500;--rte-font-weight-semibold: 600;--rte-font-weight-bold: 700;--rte-line-height-tight: 1.25;--rte-line-height-normal: 1.5;--rte-line-height-relaxed: 1.75;--rte-radius-sm: .125rem;--rte-radius: .25rem;--rte-radius-md: .375rem;--rte-radius-lg: .5rem;--rte-radius-xl: .75rem;--rte-transition-fast: .15s ease-in-out;--rte-transition-normal: .25s ease-in-out;--rte-transition-slow: .35s ease-in-out;--rte-z-dropdown: 1000;--rte-z-sticky: 1020;--rte-z-modal: 1050;--rte-z-popover: 1060;--rte-z-tooltip: 1070}.rte-editor{font-family:var(--rte-font-family-base);font-size:var(--rte-font-size-base);line-height:var(--rte-line-height-normal);color:var(--rte-color-text-primary);background-color:var(--rte-color-bg-primary);border:1px solid var(--rte-color-border);border-radius:var(--rte-radius);box-shadow:var(--rte-shadow);transition:border-color var(--rte-transition-fast),box-shadow var(--rte-transition-fast)}.rte-editor:focus-within{border-color:var(--rte-color-border-focus);box-shadow:var(--rte-shadow),0 0 0 3px #007bff1a}.rte-toolbar{display:flex;align-items:center;padding:var(--rte-space-sm);border-bottom:1px solid var(--rte-color-border);background-color:var(--rte-color-bg-secondary);border-radius:var(--rte-radius) var(--rte-radius) 0 0;flex-wrap:wrap;gap:2px}.rte-toolbar-group{display:flex;align-items:center;border-radius:var(--rte-radius);overflow:hidden;border:1px solid var(--rte-color-border-light)}.rte-toolbar-button{display:flex;align-items:center;justify-content:center;width:2rem;height:2rem;padding:0;border:none;background:transparent;color:var(--rte-color-text-secondary);cursor:pointer;border-radius:var(--rte-radius-sm);transition:background-color var(--rte-transition-fast),color var(--rte-transition-fast);font-size:14px;line-height:1}.rte-toolbar-button span{display:flex;justify-content:center;align-items:center}.rte-toolbar-button svg,.editora-toolbar-button svg,.editora-toolbar-icon svg{flex-shrink:0;width:20px;height:20px;display:block;color:currentColor;fill:currentColor}.rte-toolbar-button:hover svg{opacity:.9}:is(.rte-toolbar-button[data-active=true],.editora-toolbar-button.active) svg{color:var(--rte-color-text-inverse)}.rte-toolbar-button:hover{background-color:var(--rte-color-bg-hover);color:var(--rte-color-text-primary)}.rte-toolbar-button:active,.rte-toolbar-button[data-active=true]{background-color:var(--rte-color-primary);color:var(--rte-color-text-inverse)}.rte-toolbar-button:disabled{opacity:.5;cursor:not-allowed}.rte-content{padding:var(--rte-space-md);min-height:200px;outline:none;overflow-wrap:break-word;word-wrap:break-word}.rte-content[contenteditable=true]{cursor:text}.rte-content h1,.rte-content h2,.rte-content h3,.rte-content h4,.rte-content h5,.rte-content h6{margin:var(--rte-space-lg) 0 var(--rte-space-md) 0;font-weight:var(--rte-font-weight-semibold);line-height:var(--rte-line-height-tight);color:var(--rte-color-text-primary)}.rte-content h1{font-size:var(--rte-font-size-xxxl)}.rte-content h2{font-size:var(--rte-font-size-xxl)}.rte-content h3{font-size:var(--rte-font-size-xl)}.rte-content h4{font-size:var(--rte-font-size-lg)}.rte-content h5{font-size:var(--rte-font-size-base)}.rte-content h6{font-size:var(--rte-font-size-sm)}.rte-content p{margin:var(--rte-space-md) 0}.rte-content blockquote{margin:var(--rte-space-lg) 0;padding:var(--rte-space-md);padding-left:var(--rte-space-lg);border-left:4px solid var(--rte-color-primary);background-color:var(--rte-color-bg-secondary);font-style:italic;color:var(--rte-color-text-secondary)}.rte-content ul,.rte-content ol{margin:var(--rte-space-md) 0;padding-left:var(--rte-space-xl)}.rte-content li{margin:var(--rte-space-xs) 0}.rte-content ul{list-style-type:disc}.rte-content ol{list-style-type:decimal}.rte-link{color:var(--rte-color-primary);text-decoration:none;transition:color var(--rte-transition-fast)}.rte-link:hover{color:var(--rte-color-primary-hover);text-decoration:underline}.rte-content code{font-family:var(--rte-font-family-mono);font-size:.875em;background-color:var(--rte-color-bg-tertiary);padding:.125rem .25rem;border-radius:var(--rte-radius-sm);color:var(--rte-color-danger)}.rte-content::selection{background-color:#007bff33}.rte-content:empty:before,.rte-content.rte-content-empty:before{content:attr(data-placeholder);color:var(--rte-color-text-muted);pointer-events:none}.rte-content:focus{outline:none}.rte-sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.rte-text-left{text-align:left}.rte-text-center{text-align:center}.rte-text-right{text-align:right}.rte-text-justify{text-align:justify}.rte-table,table{border-collapse:collapse;width:100%;margin:1rem 0;border:1px solid #ddd;font-size:14px;line-height:1.4;position:relative}.rte-table td,.rte-table th,table td,table th{border:1px solid #ddd;padding:8px 12px;min-width:80px;vertical-align:top;position:relative;-webkit-user-select:none;user-select:none}.rte-table td:focus,.rte-table th:focus,table td:focus,table th:focus{outline:2px solid #007acc;outline-offset:-2px}.rte-table th,table th{background-color:#f8f9fa;font-weight:600;text-align:left}.rte-table td p,table td p{margin:0;padding:0}.rte-table td p:empty:before,table td p:empty:before{content:"";display:inline-block}.rte-table td[contenteditable]:empty:before,table td[contenteditable]:empty:before{content:"Type here...";color:#999;font-style:italic;pointer-events:none}.rte-table tr:hover,table tr:hover{background-color:#f8f9fa}.rte-table td.selected,table td.selected{background-color:#e3f2fd;border-color:#2196f3}.table-toolbar{background:#fff;border:1px solid #d0d0d0;border-radius:4px;box-shadow:0 2px 8px #0000001a;padding:4px;display:flex;align-items:center;gap:0;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,sans-serif;min-width:max-content}.toolbar-section{display:flex;align-items:center;gap:2px}.toolbar-divider{width:1px;height:20px;background:#e0e0e0;margin:0 4px}.toolbar-icon-btn{display:flex;align-items:center;justify-content:center;width:28px;height:28px;padding:0;border:1px solid transparent;background:transparent;cursor:pointer;color:#333;border-radius:3px;transition:all .2s ease;flex-shrink:0;font-size:14px;line-height:1}.toolbar-icon-btn svg{width:16px;height:16px}.toolbar-icon-btn:hover:not(:disabled){background:#f0f0f0;border-color:#d0d0d0;color:#06c}.toolbar-icon-btn:active:not(:disabled){background:#e8f0ff;border-color:#06c;transform:scale(.95)}.toolbar-icon-btn:disabled{opacity:.4;cursor:not-allowed;color:#ccc}.toolbar-icon-btn-danger{color:#d32f2f}.toolbar-icon-btn-danger:hover:not(:disabled){background:#fff3f3;border-color:#fcc;color:#d32f2f}.toolbar-icon-btn-danger:active:not(:disabled){background:#ffebee}.toolbar-icon-btn-delete{color:#d32f2f}.toolbar-icon-btn-delete:hover:not(:disabled){background:#fff3f3;border-color:#fcc;color:#d32f2f}.toolbar-icon-btn-delete:active:not(:disabled){background:#ffebee}.resize-handle{opacity:0;transition:all .15s ease}.resize-handle:hover{opacity:1}td:hover>.resize-handle,th:hover>.resize-handle{opacity:1}.table-resize-handle{position:absolute;bottom:-4px;right:-4px;width:12px;height:12px;background:transparent;cursor:nwse-resize;z-index:10;transition:background .15s ease}.table-resize-handle:after{content:"";position:absolute;bottom:0;right:0;width:8px;height:8px;background:#0066cc4d;border-bottom:2px solid #0066cc;border-right:2px solid #0066cc;border-radius:0 0 2px;opacity:0;transition:opacity .15s ease}.table-resize-handle:hover:after{opacity:1}.rte-table:hover .table-resize-handle:after,table:hover .table-resize-handle:after{opacity:1}:is([data-theme=dark],.dark,.editora-theme-dark) :is(.rte-table,table){border-color:#607088;background:#24303c;color:#e6eefb}:is([data-theme=dark],.dark,.editora-theme-dark) :is(.rte-table td,.rte-table th,table td,table th){border-color:#607088;color:#e6eefb}:is([data-theme=dark],.dark,.editora-theme-dark) :is(.rte-table th,table th){background:linear-gradient(180deg,#3b4553,#333d4a);color:#f3f8ff}:is([data-theme=dark],.dark,.editora-theme-dark) :is(.rte-table tr:hover,table tr:hover){background-color:#58a6ff1f}:is([data-theme=dark],.dark,.editora-theme-dark) :is(.rte-table td.selected,table td.selected){background-color:#58a6ff47;border-color:#79beff}:is([data-theme=dark],.dark,.editora-theme-dark) :is(.rte-table td[contenteditable]:empty:before,table td[contenteditable]:empty:before){color:#94a3b8}:is([data-theme=dark],.dark,.editora-theme-dark) .table-toolbar{background:linear-gradient(180deg,#2f3844,#2a323c);border-color:#4d596b;box-shadow:0 8px 20px #00000073}.table-toolbar.rte-theme-dark{background:linear-gradient(180deg,#2f3844,#2a323c);border-color:#4d596b;box-shadow:0 8px 20px #00000073}:is([data-theme=dark],.dark,.editora-theme-dark) .toolbar-divider{background:#4d596b}.table-toolbar.rte-theme-dark .toolbar-divider{background:#4d596b}:is([data-theme=dark],.dark,.editora-theme-dark) .toolbar-icon-btn{color:#d7deea;border-color:transparent}.table-toolbar.rte-theme-dark .toolbar-icon-btn{color:#d7deea;border-color:transparent}:is([data-theme=dark],.dark,.editora-theme-dark) .toolbar-icon-btn svg{color:currentColor;fill:currentColor}.table-toolbar.rte-theme-dark .toolbar-icon-btn svg{color:currentColor;fill:currentColor}:is([data-theme=dark],.dark,.editora-theme-dark) .toolbar-icon-btn svg [stroke="#000" i],:is([data-theme=dark],.dark,.editora-theme-dark) .toolbar-icon-btn svg [stroke="#000000" i],:is([data-theme=dark],.dark,.editora-theme-dark) .toolbar-icon-btn svg [stroke=black i]{stroke:currentColor!important}.table-toolbar.rte-theme-dark .toolbar-icon-btn svg [stroke="#000" i],.table-toolbar.rte-theme-dark .toolbar-icon-btn svg [stroke="#000000" i],.table-toolbar.rte-theme-dark .toolbar-icon-btn svg [stroke=black i]{stroke:currentColor!important}:is([data-theme=dark],.dark,.editora-theme-dark) .toolbar-icon-btn svg [fill="#000" i],:is([data-theme=dark],.dark,.editora-theme-dark) .toolbar-icon-btn svg [fill="#000000" i],:is([data-theme=dark],.dark,.editora-theme-dark) .toolbar-icon-btn svg [fill=black i]{fill:currentColor!important}.table-toolbar.rte-theme-dark .toolbar-icon-btn svg [fill="#000" i],.table-toolbar.rte-theme-dark .toolbar-icon-btn svg [fill="#000000" i],.table-toolbar.rte-theme-dark .toolbar-icon-btn svg [fill=black i]{fill:currentColor!important}:is([data-theme=dark],.dark,.editora-theme-dark) .toolbar-icon-btn:hover:not(:disabled){background:#3a4554;border-color:#607088;color:#f3f8ff}.table-toolbar.rte-theme-dark .toolbar-icon-btn:hover:not(:disabled){background:#3a4554;border-color:#607088;color:#f3f8ff}:is([data-theme=dark],.dark,.editora-theme-dark) .toolbar-icon-btn:active:not(:disabled){background:#4a95de;border-color:#67adf4;color:#0f1b2a}.table-toolbar.rte-theme-dark .toolbar-icon-btn:active:not(:disabled){background:#4a95de;border-color:#67adf4;color:#0f1b2a}:is([data-theme=dark],.dark,.editora-theme-dark) .toolbar-icon-btn:disabled{color:#7f8ca1}.table-toolbar.rte-theme-dark .toolbar-icon-btn:disabled{color:#7f8ca1}@media(max-width:768px){.rte-table,table{font-size:12px}.rte-table td,.rte-table th,table td,table th{padding:4px 6px;min-width:60px}.table-toolbar{padding:3px;gap:0;max-width:90vw;overflow-x:auto}.toolbar-icon-btn{width:26px;height:26px}.toolbar-divider{height:18px}}@media print{.rte-table,table{border:1px solid #000}.rte-table td,.rte-table th,table td,table th{border:1px solid #000;padding:4px}.table-toolbar{display:none}} |
@@ -1,2 +0,2 @@ | ||
| "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("./index-BpE6GFbz.js");exports.RichTextEditorElement=e.RichTextEditorElement;exports.initWebComponent=e.initWebComponent; | ||
| "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("./index-D1LOqg5C.js");exports.RichTextEditorElement=e.RichTextEditorElement;exports.initWebComponent=e.initWebComponent; | ||
| //# sourceMappingURL=webcomponent.cjs.js.map |
@@ -1,2 +0,2 @@ | ||
| import { R as o, j as i } from "./index-yzU4NdPT.mjs"; | ||
| import { R as o, j as i } from "./index-DqC57IEH.mjs"; | ||
| export { | ||
@@ -3,0 +3,0 @@ o as RichTextEditorElement, |
@@ -1,1 +0,1 @@ | ||
| .editora-editor{display:flex;flex-direction:column;border:1px solid #ddd;border-radius:4px;background:#fff;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,sans-serif;font-size:14px;overflow:hidden}.editora-editor *{box-sizing:border-box}.editora-theme-light{background:#fff;color:#333}.editora-theme-dark{--editora-dark-toolbar-bg-start: #353d48;--editora-dark-toolbar-bg-end: #2d3540;--editora-dark-button-bg-start: #46505f;--editora-dark-button-bg-end: #3b4553;--editora-dark-button-hover-start: #525d6d;--editora-dark-button-hover-end: #465262;--editora-dark-button-active-start: #5eaaf6;--editora-dark-button-active-end: #4a95de;--editora-dark-border: #475263;--editora-dark-border-strong: #566275;--editora-dark-text: #e1e9f5;--editora-dark-text-strong: #f3f7ff;--editora-dark-text-muted: #aeb9cc;--editora-dark-surface: #1d242d;--editora-dark-content: #1f2732;background:linear-gradient(180deg,#1b2330,#1c2430);color:var(--editora-dark-text);border-color:var(--editora-dark-border)}.editora-toolbar{display:flex;align-items:center;gap:4px;padding:8px;background:#f5f5f5;border-bottom:1px solid #ddd;flex-wrap:wrap}.editora-theme-dark .editora-toolbar{background:linear-gradient(180deg,var(--editora-dark-toolbar-bg-start) 0%,var(--editora-dark-toolbar-bg-end) 100%);border-bottom-color:var(--editora-dark-border);box-shadow:inset 0 1px #ffffff0d}.editora-toolbar-sticky{position:sticky;top:0;z-index:100;position:-webkit-sticky}.editora-toolbar-group{display:flex;align-items:center;gap:2px}.editora-toolbar-button{padding:6px 12px;border:1px solid #ccc;background:#fff;cursor:pointer;border-radius:3px;font-weight:600;font-size:14px;height:30px;display:flex;align-items:center;white-space:nowrap}.editora-toolbar-group-button{display:flex;align-items:center}.editora-toolbar-input.font-size{width:40px;padding:.25rem;text-align:center;font-size:14px;background:#fff;border:1px solid var(--rte-color-border-light);border-radius:var(--rte-radius-sm)}.editora-toolbar-group-items{display:flex;align-items:center;border:1px solid #ccc;.editora-toolbar-button{border:none;border-radius:0;&:first-child{border-right:1px solid #ccc;border-top-left-radius:3px;border-bottom-left-radius:3px}&:last-child{border-left:1px solid #ccc;border-top-right-radius:3px;border-bottom-right-radius:3px}}}.editora-theme-dark .editora-toolbar-button{background:linear-gradient(180deg,var(--editora-dark-button-bg-start) 0%,var(--editora-dark-button-bg-end) 100%);border-color:var(--editora-dark-border-strong);color:var(--editora-dark-text);box-shadow:inset 0 1px #ffffff14,0 1px 1px #00000059}.editora-theme-dark .editora-toolbar-group-items{border-color:var(--editora-dark-border-strong);background:linear-gradient(180deg,var(--editora-dark-button-bg-start) 0%,var(--editora-dark-button-bg-end) 100%)}.editora-theme-dark .editora-toolbar-group-items .editora-toolbar-button:first-child{border-right-color:#566275}.editora-theme-dark .editora-toolbar-group-items .editora-toolbar-button:last-child{border-left-color:#566275}.editora-theme-dark .editora-toolbar-input.font-size{background-color:#2e3642;color:var(--editora-dark-text-strong);border-color:var(--editora-dark-border-strong);caret-color:var(--editora-dark-text-strong)}.editora-theme-dark .editora-toolbar-input.font-size::placeholder{color:var(--editora-dark-text-strong);opacity:1}.editora-toolbar-button:hover{background:#e0e0e0;border-color:#ccc}.editora-theme-dark .editora-toolbar-button:hover{background:linear-gradient(180deg,var(--editora-dark-button-hover-start) 0%,var(--editora-dark-button-hover-end) 100%);border-color:#66748a;color:var(--editora-dark-text-strong)}.editora-toolbar-button:active,.editora-toolbar-button.active{background:#d0d0d0;border-color:#999}.editora-theme-dark .editora-toolbar-button:active,.editora-theme-dark .editora-toolbar-button.active{background:linear-gradient(180deg,var(--editora-dark-button-active-start) 0%,var(--editora-dark-button-active-end) 100%);border-color:#67adf4;color:#0f1b2a}.editora-theme-dark .editora-toolbar-button:disabled{background:#313946;border-color:#424d5e;color:#7f8ca1}.editora-theme-dark .editora-toolbar-button[data-command=insertTable],.editora-theme-dark .editora-toolbar-button[data-command=print],.editora-theme-dark .editora-toolbar-button[data-command=toggleSpellCheck],.editora-theme-dark .editora-toolbar-button[data-command=toggleA11yChecker],.editora-theme-dark .editora-toolbar-button[data-command=setDirectionLTR],.editora-theme-dark .editora-toolbar-button[data-command=setDirectionRTL]{color:#f1f6ff}.editora-toolbar-button:disabled{opacity:.5;cursor:not-allowed}.editora-toolbar-icon{display:inline-flex;align-items:center;justify-content:center;width:24px;height:24px;line-height:1}.editora-toolbar-button svg,.editora-toolbar-icon svg{width:20px;height:20px;display:block;color:currentColor;fill:currentColor}.editora-theme-dark .editora-toolbar-icon,.editora-theme-dark .editora-toolbar-icon *{color:inherit}.editora-theme-dark :is(.editora-toolbar-button,.editora-toolbar-icon) svg :is([stroke="#000" i],[stroke="#000000" i],[stroke=black i],[stroke="#0f0f0f" i],[stroke="#111111" i],[style*="stroke:#000" i],[style*="stroke: #000" i],[style*="stroke:black" i],[style*="stroke: black" i],[style*="stroke:#0f0f0f" i],[style*="stroke: #0f0f0f" i]){stroke:currentColor!important}.editora-theme-dark :is(.editora-toolbar-button,.editora-toolbar-icon) svg :is([fill="#000" i],[fill="#000000" i],[fill=black i],[fill="#0f0f0f" i],[fill="#111111" i],[style*="fill:#000" i],[style*="fill: #000" i],[style*="fill:black" i],[style*="fill: black" i],[style*="fill:#0f0f0f" i],[style*="fill: #0f0f0f" i]){fill:currentColor!important}.editora-toolbar-separator{width:1px;height:24px;background:#ddd;margin:0 4px}.editora-theme-dark .editora-toolbar-separator{background:#4d596b}.editora-toolbar-dropdown{position:relative}.editora-toolbar-dropdown-menu{position:absolute;top:100%;left:0;min-width:150px;margin-top:4px;padding:4px 0;background:#fff;border:1px solid #ddd;border-radius:4px;box-shadow:0 2px 8px #00000026;z-index:1000}.editora-theme-dark .editora-toolbar-dropdown-menu{background:#29323d;border-color:#4d596b;box-shadow:0 8px 20px #00000073}.editora-toolbar-dropdown-item{display:block;width:100%;padding:8px 12px;border:none;background:transparent;color:#333;text-align:left;cursor:pointer;font-size:13px;transition:background .15s ease}.editora-theme-dark .editora-toolbar-dropdown-item{color:#d7deea}.editora-toolbar-dropdown-item:hover{background:#f5f5f5}.editora-theme-dark .editora-toolbar-dropdown-item:hover{background:#3a4554;color:#f0f6ff}.editora-content{flex:1;min-height:200px;padding:16px;outline:none;overflow-y:auto;line-height:1.6}.editora-theme-dark .editora-content{color:#ecf3ff;background:linear-gradient(180deg,var(--editora-dark-content) 0%,#1c232e 100%)}.editora-content:empty:before{content:attr(data-placeholder);color:#999;pointer-events:none}.editora-theme-dark .editora-content:empty:before{color:#8f9bb0}.editora-content h1{font-size:2em;margin:.67em 0;font-weight:600}.editora-content h2{font-size:1.5em;margin:.75em 0;font-weight:600}.editora-content h3{font-size:1.17em;margin:.83em 0;font-weight:600}.editora-content p{margin:1em 0}.editora-content ul,.editora-content ol{margin:1em 0;padding-left:2em}.editora-content a{color:#06c;text-decoration:underline}.editora-theme-dark .editora-content a{color:#4db8ff}.editora-content code{padding:2px 4px;background:#f5f5f5;border-radius:3px;font-family:Monaco,Menlo,Consolas,monospace;font-size:.9em}.editora-theme-dark .editora-content code{background:#1e1e1e}.editora-content pre{padding:12px;background:#f5f5f5;border-radius:4px;overflow-x:auto;margin:1em 0}.editora-theme-dark .editora-content pre{background:#1e1e1e}.editora-theme-dark .rte-code-block{background:linear-gradient(180deg,#212a36,#1b2430)!important;border-color:#4f5b70!important;color:#e7effc!important}.editora-theme-dark .rte-code-block code{color:#e7effc!important}.editora-theme-dark .rte-code-block:before{background:#111927!important;color:#dce8ff!important}.editora-theme-dark .rte-code-block .rte-code-copy{background:#2b3441!important;border-color:#5a667b!important;color:#dce8ff!important}.editora-content blockquote{margin:1em 0;padding-left:1em;border-left:4px solid #ddd;color:#666}.editora-theme-dark .editora-content blockquote{border-left-color:#3c3c3c;color:#9a9a9a}.editora-floating-toolbar{position:absolute;padding:4px;background:#fff;border:1px solid #ddd;border-radius:4px;box-shadow:0 2px 8px #00000026;z-index:1000}.editora-theme-dark .editora-floating-toolbar{background:#29323d;border-color:#4d596b;box-shadow:0 8px 20px #00000073}.editora-theme-dark .editora-statusbar{background:linear-gradient(180deg,#2c3440,#252d37);border-top-color:#3f4a5b;color:#d7deea}.editora-statusbar-item{white-space:nowrap}.editora-theme-dark .editora-statusbar-separator{color:#566275}.editora-editor[readonly] .editora-content{background:#fafafa;cursor:not-allowed}.editora-theme-dark.editora-editor[readonly] .editora-content{background:#1a1a1a}.editora-editor:focus-within{border-color:#06c;box-shadow:0 0 0 3px #0066cc1a}.editora-theme-dark.editora-editor:focus-within{border-color:#4db8ff;box-shadow:0 0 0 3px #4db8ff1a}.editora-editor[disabled]{opacity:.6;pointer-events:none}@media(max-width:768px){.editora-toolbar{padding:4px}.editora-toolbar-button{min-width:28px;min-height:28px;padding:4px 8px;font-size:12px}.editora-content{padding:12px}}.editora-content ::selection{background:#06c3}.editora-theme-dark .editora-content ::selection{background:#4db8ff33}.editora-content table{border-collapse:collapse;width:100%;margin:1em 0}.editora-content th,.editora-content td{border:1px solid #ddd;padding:8px 12px;text-align:left}.editora-theme-dark .editora-content th,.editora-theme-dark .editora-content td{border-color:#3c3c3c}.editora-content th{background:#f5f5f5;font-weight:600}.editora-theme-dark .editora-content th{background:#252526}.editora-content img{max-width:100%;height:auto;border-radius:4px;display:block}.editora-content video{max-width:100%;height:auto;border-radius:4px;display:block}.editora-editor.loading{opacity:.7;pointer-events:none}.editora-editor.loading:after{content:"";position:absolute;top:50%;left:50%;width:24px;height:24px;margin:-12px 0 0 -12px;border:3px solid #ddd;border-top-color:#06c;border-radius:50%;animation:editora-spin .8s linear infinite}@keyframes editora-spin{to{transform:rotate(360deg)}}.toolbar-container-wrapper{display:flex;align-items:center;background:#fff;border-bottom:1px solid #e0e0e0;padding:0;margin:0;width:100%;box-sizing:border-box;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif;font-size:14px;line-height:1.5;position:relative}.toolbar-container-wrapper[data-toolbar-sticky=true]{position:sticky;top:0;z-index:999;box-shadow:0 2px 4px #0000001a}.toolbar-container-wrapper[data-toolbar-floating=true]{position:fixed;top:0;left:0;right:0;z-index:1000;box-shadow:0 4px 12px #00000026}.toolbar-container-wrapper[data-toolbar-position=bottom]{border-bottom:none;border-top:1px solid #e0e0e0}.toolbar-container-wrapper .toolbar-wrapper{display:flex;width:100%;padding:8px;gap:4px;flex-wrap:wrap;align-items:center}.toolbar-container-wrapper .toolbar{display:flex;width:100%;gap:4px;flex-wrap:wrap;align-items:center}.toolbar-container-wrapper .toolbar-container{display:flex;gap:4px;flex-wrap:wrap;align-items:center;flex:1;position:relative}.toolbar-container-wrapper .toolbar-item{display:flex;align-items:center;gap:2px}.toolbar-container-wrapper .toolbar-button{padding:6px 10px;border:1px solid #d1d5db;background:#fff;border-radius:4px;cursor:pointer;font-size:13px;display:flex;align-items:center;justify-content:center;gap:4px;transition:all .15s ease;min-height:32px;white-space:nowrap}.toolbar-container-wrapper .toolbar-button:hover{background-color:#f3f4f6;border-color:#9ca3af}.toolbar-container-wrapper .toolbar-button:active,.toolbar-container-wrapper .toolbar-button[data-active=true]{background-color:#06c;color:#fff;border-color:#0052a3;box-shadow:inset 0 1px 3px #0000001a}.toolbar-container-wrapper .toolbar-button:disabled{opacity:.5;cursor:not-allowed;background-color:#f9fafb}.toolbar-container-wrapper .toolbar-more-button{padding:6px 8px;font-size:16px;font-weight:500;line-height:1}.toolbar-container-wrapper .toolbar-separator{width:1px;height:24px;background-color:#d1d5db;margin:0 4px}.toolbar-container-wrapper .toolbar-icon{display:inline-flex;align-items:center;justify-content:center;width:18px;height:18px;flex-shrink:0}.toolbar-container-wrapper .toolbar-icon svg{width:100%;height:100%}.toolbar-container-wrapper .toolbar-dropdown{position:relative;display:flex;align-items:center}.toolbar-container-wrapper .toolbar-dropdown-arrow{font-size:10px;margin-left:2px;line-height:1}.toolbar-container-wrapper .toolbar-dropdown-menu{position:absolute;top:100%;left:0;background:#fff;border:1px solid #d1d5db;border-radius:6px;box-shadow:0 4px 12px #00000026;z-index:1000;min-width:160px;padding:4px 0;margin-top:4px;display:none}.toolbar-container-wrapper .toolbar-dropdown-menu.show{display:block}.toolbar-container-wrapper .toolbar-dropdown-item{display:block;width:100%;padding:8px 12px;border:none;background:transparent;text-align:left;cursor:pointer;font-size:13px;color:#1f2937;transition:background-color .15s ease;font-family:inherit}.toolbar-container-wrapper .toolbar-dropdown-item:hover{background-color:#f3f4f6}.toolbar-container-wrapper .toolbar-dropdown-item:active{background-color:#e5e7eb}.toolbar-container-wrapper .toolbar-input{padding:6px 8px;border:1px solid #d1d5db;border-radius:4px;font-size:13px;font-family:inherit;background-color:#fff;color:#1f2937;transition:all .15s ease}.toolbar-container-wrapper .toolbar-input:focus{outline:none;border-color:#06c;box-shadow:0 0 0 3px #0066cc1a;background-color:#fff}.toolbar-container-wrapper .toolbar-input::placeholder{color:#9ca3af}.toolbar-overflow-menu{animation:slideDown .2s ease-out}@keyframes slideDown{0%{opacity:0;transform:translateY(-8px)}to{opacity:1;transform:translateY(0)}}.toolbar-overflow-item{transition:background-color .15s ease}.floating-toolbar{user-select:none;-webkit-user-select:none;font-family:system-ui,-apple-system,sans-serif;font-size:14px;animation:fadeInUp .15s ease-out}@keyframes fadeInUp{0%{opacity:0;transform:translate(-50%) translateY(10px)}to{opacity:1;transform:translate(-50%) translateY(0)}}.floating-toolbar-btn{display:flex;align-items:center;justify-content:center;width:32px;height:32px;border:none;background:transparent;border-radius:4px;color:#495057;cursor:pointer;font-size:14px;font-weight:500;transition:all .15s ease;outline:none}.floating-toolbar-btn:hover{background:#f8f9fa;color:#212529}.floating-toolbar-btn:active{background:#e9ecef;transform:scale(.95)}.floating-toolbar-btn.floating-toolbar-toggle{color:#dc3545;font-weight:700}.floating-toolbar-btn.floating-toolbar-toggle:hover{background:#f8d7da;color:#721c24}.floating-toolbar-separator{width:1px;height:20px;background:#e1e5e9;margin:0 2px}@media(max-width:768px){.toolbar-container-wrapper .toolbar-button{padding:5px 8px;font-size:12px;min-height:28px}.toolbar-container-wrapper .toolbar-icon{width:16px;height:16px}.toolbar-container-wrapper .toolbar-dropdown-menu{min-width:140px}.toolbar-container-wrapper .toolbar-dropdown-item{padding:6px 10px;font-size:12px}.floating-toolbar{padding:4px;gap:2px}.floating-toolbar-btn{width:28px;height:28px;font-size:12px}}@media(max-width:480px){.toolbar-container-wrapper{padding:4px}.toolbar-container-wrapper .toolbar-wrapper{padding:4px;gap:2px}.toolbar-container-wrapper .toolbar-button{padding:4px 6px;font-size:11px;min-height:24px}.toolbar-container-wrapper .toolbar-icon{width:14px;height:14px}}.floating-toolbar{pointer-events:auto}.floating-toolbar{max-width:calc(100vw - 20px);overflow-x:auto}@media(prefers-color-scheme:dark){.floating-toolbar{background:#2d3748;border-color:#4a5568;color:#e2e8f0}.floating-toolbar-btn:hover{background:#4a5568;color:#f7fafc}.floating-toolbar-btn:active{background:#718096}.floating-toolbar-separator{background:#4a5568}}.rte-editor{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif}.rte-toolbar-wrapper{border-radius:4px 4px 0 0}.rte-toolbar{display:flex;gap:4px;padding:8px;background:#f5f5f5;border:1px solid #ddd;border-bottom:none;border-radius:4px 4px 0 0;align-items:center;position:relative}.rte-toolbar-items-container{display:flex;gap:4px;flex-wrap:nowrap;align-items:center;flex:1}.rte-toolbar-item{position:relative;display:flex;align-items:center;white-space:nowrap}.rte-toolbar-group-items.font-size{display:flex;align-items:center;border:1px solid #ccc;.rte-toolbar-input.font-size{width:40px;padding:.25rem;text-align:center;font-size:14px;background:#fff;border:1px solid var(--rte-color-border-light);border-radius:var(--rte-radius-sm)}.rte-toolbar-button{border:none;border-radius:0}.rte-toolbar-item{&:first-child{border-right:1px solid #ccc;border-top-left-radius:3px;border-bottom-left-radius:3px}&:last-child{border-left:1px solid #ccc;border-top-right-radius:3px;border-bottom-right-radius:3px}}}.rte-toolbar-button{padding:6px 12px;border:1px solid #ccc;background:#fff;cursor:pointer;border-radius:3px;font-weight:600;font-size:14px;height:30px;display:flex;align-items:center;white-space:nowrap}.rte-toolbar-button:hover{background:#e9e9e9}.rte-toolbar-input{width:26px;padding:6px 8px;border:1px solid #ccc;border-radius:3px;font-size:14px;text-align:center}.rte-toolbar-dropdown{position:relative}.rte-toolbar-dropdown-menu{position:absolute;top:100%;left:0;background:#fff;border:1px solid #ccc;border-radius:3px;box-shadow:0 2px 8px #00000026;min-width:150px;z-index:1000;margin-top:2px}.rte-toolbar-dropdown-item{padding:8px 12px;cursor:pointer}.rte-toolbar-dropdown-item:hover{background:#f0f0f0}.rte-toolbar-more-button{padding:6px 10px;border:1px solid #ccc;background:#fff;cursor:pointer;border-radius:3px;font-weight:600;font-size:16px;height:30px;display:flex;align-items:center;justify-content:center;min-width:30px;transition:background-color .2s ease;margin-left:auto}.rte-toolbar-more-button:hover{background:#e9e9e9}.rte-toolbar-more-button.active{background:#ddd;border-color:#999}.rte-toolbar-expanded-row{display:flex;flex-wrap:wrap;align-items:flex-start;transform:scaleY(0);transform-origin:top;max-height:0;padding:0;overflow:hidden;opacity:0;transition:transform .25s ease,opacity .2s ease,max-height .25s ease}.rte-toolbar-expanded-row.show{transform:scaleY(1);max-height:320px;padding:1px 8px 8px;opacity:1;background:#f5f5f5;border:1px solid #ddd;border-top:none;gap:4px;overflow-y:auto;overflow-x:hidden}.rte-content{font-size:16px;line-height:1.6}.rte-content.rte-content-empty:before,.rte-content:empty:before{content:attr(data-placeholder);color:var(--rte-color-text-muted, #6b7280);pointer-events:none}.rte-content p{margin:0 0 1em}.rte-content h1{font-size:2em;margin:.67em 0}.rte-content h2{font-size:1.5em;margin:.75em 0}.rte-content h3{font-size:1.17em;margin:.83em 0}.rte-content h4{font-size:1em;margin:1em 0}.rte-content h5{font-size:.83em;margin:1.17em 0}.rte-content h6{font-size:.67em;margin:1.33em 0}.rte-content ul,.rte-content ol{margin:1em 0;padding-left:2em}.rte-content .rte-table,.rte-content table{border-collapse:collapse;width:100%;margin:1rem 0;border:1px solid #ddd;font-size:14px;line-height:1.4}.rte-content .rte-table td,.rte-content .rte-table th,.rte-content table td,.rte-content table th{border:1px solid #ddd;padding:8px 12px;min-width:80px;text-align:left;vertical-align:top}.rte-content .rte-table th,.rte-content table th{background-color:#f8f9fa;font-weight:600}.rte-content .rte-table td p,.rte-content table td p{margin:0}.table-toolbar{background:#fff;border:1px solid #d0d0d0;border-radius:4px;box-shadow:0 2px 8px #0000001a;padding:4px;display:flex;align-items:center}.toolbar-icon-btn{display:flex;align-items:center;justify-content:center;width:28px;height:28px;padding:0;border:1px solid transparent;background:transparent;color:#333;border-radius:3px;cursor:pointer}.toolbar-icon-btn:hover:not(:disabled){background:#f0f0f0;border-color:#d0d0d0}.rte-content code{background:#f4f4f4;padding:2px 6px;border-radius:3px;font-family:Courier New,monospace;font-size:.9em}.rte-content blockquote{border-left:4px solid #ddd;margin:1em 0;padding-left:1em;color:#666}.rte-content a{color:#06c;text-decoration:underline}.rte-content a:hover{color:#0052a3}.rte-dialog-overlay{position:fixed;inset:0;background:#00000080;display:flex;align-items:center;justify-content:center;z-index:10000}.rte-dialog-content{background:#fff;border-radius:8px;box-shadow:0 4px 20px #0000004d;max-width:400px;width:90%;max-height:90vh;overflow-y:auto}.rte-dialog-header{padding:16px 20px;border-bottom:1px solid #e0e0e0;display:flex;justify-content:space-between;align-items:center}.rte-dialog-header h3{margin:0;font-size:18px;font-weight:600;color:#333}.rte-dialog-close{background:none;border:none;font-size:24px;cursor:pointer;color:#666;padding:0;width:30px;height:30px;display:flex;align-items:center;justify-content:center}.rte-dialog-close:hover{color:#333}.rte-dialog-body{padding:20px}.rte-dialog-footer{padding:16px 20px;border-top:1px solid #e0e0e0;display:flex;justify-content:flex-end;gap:12px}.rte-btn{padding:8px 16px;border:1px solid #ccc;border-radius:4px;cursor:pointer;font-size:14px;font-weight:500;transition:all .2s}.rte-btn:hover{border-color:#999}.rte-btn-primary{background:#06c;color:#fff;border-color:#06c}.rte-btn-primary:hover{background:#0052a3;border-color:#0052a3}.rte-btn-secondary{background:#fff;color:#333}.rte-btn-secondary:hover{background:#f5f5f5}.rte-form-group{margin-bottom:16px}.rte-form-label{display:block;margin-bottom:6px;font-weight:500;color:#333;font-size:14px}.rte-form-input{width:100%;padding:8px 12px;border:1px solid #ccc;border-radius:4px;font-size:14px;box-sizing:border-box}.rte-form-input:focus{outline:none;border-color:#06c;box-shadow:0 0 0 2px #06c3}.rte-form-row{display:flex;gap:12px}.rte-form-row .rte-form-group{flex:1}.rte-color-preview{display:flex;align-items:center;gap:12px;margin-bottom:20px;padding:12px;background:#f8f9fa;border-radius:4px}.rte-color-sample{width:40px;height:40px;border-radius:4px;border:2px solid #ddd}.rte-color-value{font-family:monospace;font-size:14px;font-weight:500;color:#333}.rte-color-section{margin-bottom:20px}.rte-color-label{margin-bottom:8px;font-size:14px;font-weight:500}.rte-color-palette{display:grid;grid-template-columns:repeat(6,1fr);gap:8px;margin-bottom:16px}.rte-color-swatch{width:24px;height:24px;border:2px solid #ddd;border-radius:4px;cursor:pointer;transition:all .2s}.rte-color-swatch:hover{border-color:#999;transform:scale(1.1)}.rte-color-swatch.selected{border-color:#06c;box-shadow:0 0 0 2px #0066cc4d}.rte-custom-color{display:flex;align-items:center;gap:12px}.rte-color-input{width:60px;height:40px;border:2px solid #ddd;border-radius:4px;cursor:pointer}.rte-color-text-input{flex:1;padding:8px 12px;border:1px solid #ccc;border-radius:4px;font-family:monospace;font-size:14px}.rte-color-text-input:focus{outline:none;border-color:#06c;box-shadow:0 0 0 2px #06c3}.rte-iframe-preview{border:1px solid #ddd;border-radius:4px;overflow:hidden;background:#f8f9fa}.rte-iframe-preview iframe{display:block;border:none}.rte-size-presets{display:flex;flex-direction:column;gap:8px}.rte-radio-option{display:flex;align-items:flex-start;gap:8px;padding:8px;border:1px solid #e0e0e0;border-radius:4px;background:#fafbfc}.rte-radio-option:hover{background:#f1f3f4}.rte-radio-option input[type=radio]{margin-top:2px}.rte-radio-label{flex:1;line-height:1.4}.rte-content ul[data-type=checklist]{list-style:none;padding-left:0;margin:1em 0}.rte-content li[data-type=checklist-item]{position:relative;padding-left:2em;margin-bottom:.5em;line-height:1.6}.rte-content li[data-type=checklist-item]:before{content:"";position:absolute;left:0;top:.1em;width:1.2em;height:1.2em;border:2px solid #ccc;border-radius:3px;background:#fff;cursor:pointer;transition:all .2s ease}.rte-content li[data-type=checklist-item]:hover:before{border-color:#999}.rte-content li[data-type=checklist-item][data-checked=true]:before{background:#06c;border-color:#06c}.rte-content li[data-type=checklist-item][data-checked=true]:after{content:"✓";position:absolute;left:.36em;top:.12em;color:#fff;font-size:.9em;font-weight:700;pointer-events:none}.rte-content li[data-type=checklist-item][data-checked=true] p{text-decoration:line-through;color:#666}.editora-statusbar-container{display:flex;flex-direction:column}.rte-editor{.editora-statusbar-bottom{top:-32px}}.editora-statusbar-bottom{position:relative;border-left:1px solid rgb(221,221,221);border-right:1px solid rgb(221,221,221)}.editora-statusbar{display:flex;align-items:center;gap:12px;padding:6px 12px;background:#f5f5f5;border-top:1px solid #ddd;font-size:12px;color:#666}.editora-theme-dark .editora-statusbar{background:#252526;border-top-color:#3c3c3c;color:#9a9a9a}.editora-statusbar-top{border-top:none;border-bottom:1px solid #e0e0e0}.editora-statusbar-left{display:flex;align-items:center;gap:8px}.editora-statusbar-right{display:flex;align-items:center;gap:8px;margin-left:auto}.editora-statusbar-item{white-space:nowrap;padding:2px 4px}.editora-statusbar-separator{color:#ddd}.editora-theme-dark .editora-statusbar-separator{color:#3c3c3c}.editora-theme-dark .rte-content,.editora-theme-dark .rte-content h1,.editora-theme-dark .rte-content h2,.editora-theme-dark .rte-content h3,.editora-theme-dark .rte-content h4,.editora-theme-dark .rte-content h5,.editora-theme-dark .rte-content h6{color:#fff}.rte-inline-menu{position:fixed;z-index:1000;background:#fff;border:1px solid #ccc;border-radius:4px;box-shadow:0 2px 8px #00000026;min-width:120px;max-width:200px;pointer-events:auto}.rte-inline-menu-item{padding:8px 12px;cursor:pointer;font-size:14px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;background-color:transparent}.rte-inline-menu-item:hover{background-color:#f5f5f5}.floating-toolbar{--rte-floating-toolbar-bg: #ffffff;--rte-floating-toolbar-border: #d7dee8;--rte-floating-toolbar-text: #364152;--rte-floating-toolbar-hover-bg: #f2f6fb;--rte-floating-toolbar-hover-text: #101828;--rte-floating-toolbar-active-bg: #e7eef7;--rte-floating-toolbar-separator: #d8e1ec;--rte-floating-toolbar-shadow: 0 10px 28px rgba(15, 23, 36, .16);user-select:none;-webkit-user-select:none;align-items:center;gap:4px;padding:6px;border-radius:8px;border:1px solid var(--rte-floating-toolbar-border);background:var(--rte-floating-toolbar-bg);color:var(--rte-floating-toolbar-text);box-shadow:var(--rte-floating-toolbar-shadow);pointer-events:auto;animation:rteFloatingToolbarIn .15s ease-out}.floating-toolbar-btn{display:inline-flex;align-items:center;justify-content:center;min-width:32px;height:32px;border:none;border-radius:6px;background:transparent;color:inherit;cursor:pointer;font-size:14px;font-weight:600;transition:background-color .15s ease,color .15s ease,transform .12s ease}.floating-toolbar-btn:hover{background:var(--rte-floating-toolbar-hover-bg);color:var(--rte-floating-toolbar-hover-text)}.floating-toolbar-btn:active{background:var(--rte-floating-toolbar-active-bg);transform:scale(.96)}.floating-toolbar-separator{width:1px;height:20px;margin:0 2px;background:var(--rte-floating-toolbar-separator)}@keyframes rteFloatingToolbarIn{0%{opacity:0;transform:translate(-50%) translateY(8px)}to{opacity:1;transform:translate(-50%) translateY(0)}}.editora-toolbar-group-button{display:flex;align-items:center;border-radius:var(--rte-radius);overflow:hidden;border:1px solid var(--rte-color-border-light);background:var(--rte-color-bg-secondary, #f9fafb);margin-right:.5rem;padding:0}.editora-toolbar-group-items{display:flex;align-items:center;gap:0}.editora-toolbar-group-button .editora-toolbar-button,.editora-toolbar-group-button .editora-toolbar-input{border-radius:0;border:none;margin:0;background:transparent;box-shadow:none}.editora-toolbar-group-button .editora-toolbar-button:first-child{border-radius:var(--rte-radius) 0 0 var(--rte-radius)}.editora-toolbar-group-button .editora-toolbar-button:last-child{border-radius:0 var(--rte-radius) var(--rte-radius) 0}.editora-toolbar-group-button .editora-toolbar-input{min-width:44px;width:44px;text-align:center;font-size:15px;background:#fff;border-left:1px solid var(--rte-color-border-light);border-right:1px solid var(--rte-color-border-light)}.editora-toolbar-group-button .editora-toolbar-button:active,.editora-toolbar-group-button .editora-toolbar-button:focus{background:#e5e7eb}.editora-toolbar-group-button .editora-toolbar-input:focus{outline:1.5px solid var(--rte-color-primary, #2563eb)}:root{--rte-color-primary: #007bff;--rte-color-primary-hover: #0056b3;--rte-color-secondary: #6c757d;--rte-color-success: #28a745;--rte-color-danger: #dc3545;--rte-color-warning: #ffc107;--rte-color-info: #17a2b8;--rte-color-text-primary: #212529;--rte-color-text-secondary: #6c757d;--rte-color-text-muted: #868e96;--rte-color-text-inverse: #ffffff;--rte-color-bg-primary: #ffffff;--rte-color-bg-secondary: #f8f9fa;--rte-color-bg-tertiary: #e9ecef;--rte-color-bg-hover: #f8f9fa;--rte-color-bg-active: #e9ecef;--rte-color-border: #dee2e6;--rte-color-border-light: #f8f9fa;--rte-color-border-focus: #007bff;--rte-shadow-sm: 0 1px 2px rgba(0, 0, 0, .05);--rte-shadow: 0 1px 3px rgba(0, 0, 0, .1), 0 1px 2px rgba(0, 0, 0, .06);--rte-shadow-lg: 0 10px 15px rgba(0, 0, 0, .1), 0 4px 6px rgba(0, 0, 0, .05);--rte-space-xs: .25rem;--rte-space-sm: .5rem;--rte-space-md: 1rem;--rte-space-lg: 1.5rem;--rte-space-xl: 2rem;--rte-space-xxl: 3rem;--rte-font-family-base: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;--rte-font-family-mono: "SFMono-Regular", Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--rte-font-size-xs: .75rem;--rte-font-size-sm: .875rem;--rte-font-size-base: 1rem;--rte-font-size-lg: 1.125rem;--rte-font-size-xl: 1.25rem;--rte-font-size-xxl: 1.5rem;--rte-font-size-xxxl: 2rem;--rte-font-weight-normal: 400;--rte-font-weight-medium: 500;--rte-font-weight-semibold: 600;--rte-font-weight-bold: 700;--rte-line-height-tight: 1.25;--rte-line-height-normal: 1.5;--rte-line-height-relaxed: 1.75;--rte-radius-sm: .125rem;--rte-radius: .25rem;--rte-radius-md: .375rem;--rte-radius-lg: .5rem;--rte-radius-xl: .75rem;--rte-transition-fast: .15s ease-in-out;--rte-transition-normal: .25s ease-in-out;--rte-transition-slow: .35s ease-in-out;--rte-z-dropdown: 1000;--rte-z-sticky: 1020;--rte-z-modal: 1050;--rte-z-popover: 1060;--rte-z-tooltip: 1070}.rte-editor{font-family:var(--rte-font-family-base);font-size:var(--rte-font-size-base);line-height:var(--rte-line-height-normal);color:var(--rte-color-text-primary);background-color:var(--rte-color-bg-primary);border:1px solid var(--rte-color-border);border-radius:var(--rte-radius);box-shadow:var(--rte-shadow);transition:border-color var(--rte-transition-fast),box-shadow var(--rte-transition-fast)}.rte-editor:focus-within{border-color:var(--rte-color-border-focus);box-shadow:var(--rte-shadow),0 0 0 3px #007bff1a}.rte-toolbar{display:flex;align-items:center;padding:var(--rte-space-sm);border-bottom:1px solid var(--rte-color-border);background-color:var(--rte-color-bg-secondary);border-radius:var(--rte-radius) var(--rte-radius) 0 0;flex-wrap:wrap;gap:2px}.rte-toolbar-group{display:flex;align-items:center;border-radius:var(--rte-radius);overflow:hidden;border:1px solid var(--rte-color-border-light)}.rte-toolbar-button{display:flex;align-items:center;justify-content:center;width:2rem;height:2rem;padding:0;border:none;background:transparent;color:var(--rte-color-text-secondary);cursor:pointer;border-radius:var(--rte-radius-sm);transition:background-color var(--rte-transition-fast),color var(--rte-transition-fast);font-size:14px;line-height:1}.rte-toolbar-button span{display:flex;justify-content:center;align-items:center}.rte-toolbar-button svg,.editora-toolbar-button svg,.editora-toolbar-icon svg{flex-shrink:0;width:20px;height:20px;display:block;color:currentColor;fill:currentColor}.rte-toolbar-button:hover svg{opacity:.9}:is(.rte-toolbar-button[data-active=true],.editora-toolbar-button.active) svg{color:var(--rte-color-text-inverse)}.rte-toolbar-button:hover{background-color:var(--rte-color-bg-hover);color:var(--rte-color-text-primary)}.rte-toolbar-button:active,.rte-toolbar-button[data-active=true]{background-color:var(--rte-color-primary);color:var(--rte-color-text-inverse)}.rte-toolbar-button:disabled{opacity:.5;cursor:not-allowed}.rte-content{padding:var(--rte-space-md);min-height:200px;outline:none;overflow-wrap:break-word;word-wrap:break-word}.rte-content[contenteditable=true]{cursor:text}.rte-content h1,.rte-content h2,.rte-content h3,.rte-content h4,.rte-content h5,.rte-content h6{margin:var(--rte-space-lg) 0 var(--rte-space-md) 0;font-weight:var(--rte-font-weight-semibold);line-height:var(--rte-line-height-tight);color:var(--rte-color-text-primary)}.rte-content h1{font-size:var(--rte-font-size-xxxl)}.rte-content h2{font-size:var(--rte-font-size-xxl)}.rte-content h3{font-size:var(--rte-font-size-xl)}.rte-content h4{font-size:var(--rte-font-size-lg)}.rte-content h5{font-size:var(--rte-font-size-base)}.rte-content h6{font-size:var(--rte-font-size-sm)}.rte-content p{margin:var(--rte-space-md) 0}.rte-content blockquote{margin:var(--rte-space-lg) 0;padding:var(--rte-space-md);padding-left:var(--rte-space-lg);border-left:4px solid var(--rte-color-primary);background-color:var(--rte-color-bg-secondary);font-style:italic;color:var(--rte-color-text-secondary)}.rte-content ul,.rte-content ol{margin:var(--rte-space-md) 0;padding-left:var(--rte-space-xl)}.rte-content li{margin:var(--rte-space-xs) 0}.rte-content ul{list-style-type:disc}.rte-content ol{list-style-type:decimal}.rte-link{color:var(--rte-color-primary);text-decoration:none;transition:color var(--rte-transition-fast)}.rte-link:hover{color:var(--rte-color-primary-hover);text-decoration:underline}.rte-content code{font-family:var(--rte-font-family-mono);font-size:.875em;background-color:var(--rte-color-bg-tertiary);padding:.125rem .25rem;border-radius:var(--rte-radius-sm);color:var(--rte-color-danger)}.rte-content::selection{background-color:#007bff33}.rte-content:empty:before,.rte-content.rte-content-empty:before{content:attr(data-placeholder);color:var(--rte-color-text-muted);pointer-events:none}.rte-content:focus{outline:none}.rte-sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.rte-text-left{text-align:left}.rte-text-center{text-align:center}.rte-text-right{text-align:right}.rte-text-justify{text-align:justify}.rte-table td,.rte-table th,table td,table th{border:1px solid #ddd;padding:8px 12px;min-width:80px;vertical-align:top;position:relative;-webkit-user-select:none;user-select:none}.table-toolbar{background:#fff;border:1px solid #d0d0d0;border-radius:4px;box-shadow:0 2px 8px #0000001a;padding:4px;display:flex;align-items:center;gap:0;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,sans-serif;min-width:max-content}.rte-table,table{border-collapse:collapse;width:100%;margin:1rem 0;border:1px solid #ddd;font-size:14px;line-height:1.4;position:relative}.rte-table td,.rte-table th,table td,table th{border:1px solid #ddd;padding:8px 12px;min-width:80px;vertical-align:top;position:relative;user-select:none}.rte-table td:focus,.rte-table th:focus,table td:focus,table th:focus{outline:2px solid #007acc;outline-offset:-2px}.rte-table th,table th{background-color:#f8f9fa;font-weight:600;text-align:left}.rte-table td p,table td p{margin:0;padding:0}.rte-table td p:empty:before,table td p:empty:before{content:"";display:inline-block}.rte-table td[contenteditable]:empty:before,table td[contenteditable]:empty:before{content:"Type here...";color:#999;font-style:italic;pointer-events:none}.rte-table tr:hover,table tr:hover{background-color:#f8f9fa}.rte-table td.selected,table td.selected{background-color:#e3f2fd;border-color:#2196f3}.table-toolbar{background:#fff;border:1px solid #d0d0d0;border-radius:4px;box-shadow:0 2px 8px #0000001a;padding:4px;display:flex;align-items:center;gap:0;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,sans-serif;min-width:max-content}.toolbar-section{display:flex;align-items:center;gap:2px}.toolbar-divider{width:1px;height:20px;background:#e0e0e0;margin:0 4px}.toolbar-icon-btn{display:flex;align-items:center;justify-content:center;width:28px;height:28px;padding:0;border:1px solid transparent;background:transparent;cursor:pointer;color:#333;border-radius:3px;transition:all .2s ease;flex-shrink:0;font-size:14px;line-height:1}.toolbar-icon-btn svg{width:16px;height:16px}.toolbar-icon-btn:hover:not(:disabled){background:#f0f0f0;border-color:#d0d0d0;color:#06c}.toolbar-icon-btn:active:not(:disabled){background:#e8f0ff;border-color:#06c;transform:scale(.95)}.toolbar-icon-btn:disabled{opacity:.4;cursor:not-allowed;color:#ccc}.toolbar-icon-btn-danger{color:#d32f2f}.toolbar-icon-btn-danger:hover:not(:disabled){background:#fff3f3;border-color:#fcc;color:#d32f2f}.toolbar-icon-btn-danger:active:not(:disabled){background:#ffebee}.toolbar-icon-btn-delete{color:#d32f2f}.toolbar-icon-btn-delete:hover:not(:disabled){background:#fff3f3;border-color:#fcc;color:#d32f2f}.toolbar-icon-btn-delete:active:not(:disabled){background:#ffebee}.resize-handle{opacity:0;transition:all .15s ease}.resize-handle:hover{opacity:1}td:hover>.resize-handle,th:hover>.resize-handle{opacity:1}.table-resize-handle{position:absolute;bottom:-4px;right:-4px;width:12px;height:12px;background:transparent;cursor:nwse-resize;z-index:10;transition:background .15s ease}.table-resize-handle:after{content:"";position:absolute;bottom:0;right:0;width:8px;height:8px;background:#0066cc4d;border-bottom:2px solid #0066cc;border-right:2px solid #0066cc;border-radius:0 0 2px;opacity:0;transition:opacity .15s ease}.table-resize-handle:hover:after{opacity:1}.rte-table:hover .table-resize-handle:after,table:hover .table-resize-handle:after{opacity:1}:is([data-theme=dark],.dark,.editora-theme-dark) :is(.rte-table,table){border-color:#607088;background:#24303c;color:#e6eefb}:is([data-theme=dark],.dark,.editora-theme-dark) :is(.rte-table td,.rte-table th,table td,table th){border-color:#607088;color:#e6eefb}:is([data-theme=dark],.dark,.editora-theme-dark) :is(.rte-table th,table th){background:linear-gradient(180deg,#3b4553,#333d4a);color:#f3f8ff}:is([data-theme=dark],.dark,.editora-theme-dark) :is(.rte-table tr:hover,table tr:hover){background-color:#58a6ff1f}:is([data-theme=dark],.dark,.editora-theme-dark) :is(.rte-table td.selected,table td.selected){background-color:#58a6ff47;border-color:#79beff}:is([data-theme=dark],.dark,.editora-theme-dark) :is(.rte-table td[contenteditable]:empty:before,table td[contenteditable]:empty:before){color:#94a3b8}:is([data-theme=dark],.dark,.editora-theme-dark) .table-toolbar{background:linear-gradient(180deg,#2f3844,#2a323c);border-color:#4d596b;box-shadow:0 8px 20px #00000073}.table-toolbar.rte-theme-dark{background:linear-gradient(180deg,#2f3844,#2a323c);border-color:#4d596b;box-shadow:0 8px 20px #00000073}:is([data-theme=dark],.dark,.editora-theme-dark) .toolbar-divider{background:#4d596b}.table-toolbar.rte-theme-dark .toolbar-divider{background:#4d596b}:is([data-theme=dark],.dark,.editora-theme-dark) .toolbar-icon-btn{color:#d7deea;border-color:transparent}.table-toolbar.rte-theme-dark .toolbar-icon-btn{color:#d7deea;border-color:transparent}:is([data-theme=dark],.dark,.editora-theme-dark) .toolbar-icon-btn svg{color:currentColor;fill:currentColor}.table-toolbar.rte-theme-dark .toolbar-icon-btn svg{color:currentColor;fill:currentColor}:is([data-theme=dark],.dark,.editora-theme-dark) .toolbar-icon-btn svg [stroke="#000" i],:is([data-theme=dark],.dark,.editora-theme-dark) .toolbar-icon-btn svg [stroke="#000000" i],:is([data-theme=dark],.dark,.editora-theme-dark) .toolbar-icon-btn svg [stroke=black i]{stroke:currentColor!important}.table-toolbar.rte-theme-dark .toolbar-icon-btn svg [stroke="#000" i],.table-toolbar.rte-theme-dark .toolbar-icon-btn svg [stroke="#000000" i],.table-toolbar.rte-theme-dark .toolbar-icon-btn svg [stroke=black i]{stroke:currentColor!important}:is([data-theme=dark],.dark,.editora-theme-dark) .toolbar-icon-btn svg [fill="#000" i],:is([data-theme=dark],.dark,.editora-theme-dark) .toolbar-icon-btn svg [fill="#000000" i],:is([data-theme=dark],.dark,.editora-theme-dark) .toolbar-icon-btn svg [fill=black i]{fill:currentColor!important}.table-toolbar.rte-theme-dark .toolbar-icon-btn svg [fill="#000" i],.table-toolbar.rte-theme-dark .toolbar-icon-btn svg [fill="#000000" i],.table-toolbar.rte-theme-dark .toolbar-icon-btn svg [fill=black i]{fill:currentColor!important}:is([data-theme=dark],.dark,.editora-theme-dark) .toolbar-icon-btn:hover:not(:disabled){background:#3a4554;border-color:#607088;color:#f3f8ff}.table-toolbar.rte-theme-dark .toolbar-icon-btn:hover:not(:disabled){background:#3a4554;border-color:#607088;color:#f3f8ff}:is([data-theme=dark],.dark,.editora-theme-dark) .toolbar-icon-btn:active:not(:disabled){background:#4a95de;border-color:#67adf4;color:#0f1b2a}.table-toolbar.rte-theme-dark .toolbar-icon-btn:active:not(:disabled){background:#4a95de;border-color:#67adf4;color:#0f1b2a}:is([data-theme=dark],.dark,.editora-theme-dark) .toolbar-icon-btn:disabled{color:#7f8ca1}.table-toolbar.rte-theme-dark .toolbar-icon-btn:disabled{color:#7f8ca1}@media(max-width:768px){.rte-table,table{font-size:12px}.rte-table td,.rte-table th,table td,table th{padding:4px 6px;min-width:60px}.table-toolbar{padding:3px;gap:0;max-width:90vw;overflow-x:auto}.toolbar-icon-btn{width:26px;height:26px}.toolbar-divider{height:18px}}@media print{.rte-table,table{border:1px solid #000}.rte-table td,.rte-table th,table td,table th{border:1px solid #000;padding:4px}.table-toolbar{display:none}} | ||
| .editora-editor{display:flex;flex-direction:column;border:1px solid #ddd;border-radius:4px;background:#fff;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,sans-serif;font-size:14px;overflow:hidden}.editora-editor *{box-sizing:border-box}.editora-theme-light{background:#fff;color:#333}.editora-theme-dark{--editora-dark-toolbar-bg-start: #353d48;--editora-dark-toolbar-bg-end: #2d3540;--editora-dark-button-bg-start: #46505f;--editora-dark-button-bg-end: #3b4553;--editora-dark-button-hover-start: #525d6d;--editora-dark-button-hover-end: #465262;--editora-dark-button-active-start: #5eaaf6;--editora-dark-button-active-end: #4a95de;--editora-dark-border: #475263;--editora-dark-border-strong: #566275;--editora-dark-text: #e1e9f5;--editora-dark-text-strong: #f3f7ff;--editora-dark-text-muted: #aeb9cc;--editora-dark-surface: #1d242d;--editora-dark-content: #1f2732;background:linear-gradient(180deg,#1b2330,#1c2430);color:var(--editora-dark-text);border-color:var(--editora-dark-border)}.editora-toolbar{display:flex;align-items:center;gap:4px;padding:8px;background:#f5f5f5;border-bottom:1px solid #ddd;flex-wrap:wrap}.editora-theme-dark .editora-toolbar{background:linear-gradient(180deg,var(--editora-dark-toolbar-bg-start) 0%,var(--editora-dark-toolbar-bg-end) 100%);border-bottom-color:var(--editora-dark-border);box-shadow:inset 0 1px #ffffff0d}.editora-toolbar-sticky{position:sticky;top:0;z-index:100;position:-webkit-sticky}.editora-toolbar-group{display:flex;align-items:center;gap:2px}.editora-toolbar-button{padding:6px 12px;border:1px solid #ccc;background:#fff;cursor:pointer;border-radius:3px;font-weight:600;font-size:14px;height:30px;display:flex;align-items:center;white-space:nowrap}.editora-toolbar-group-button{display:flex;align-items:center}.editora-toolbar-input.font-size{width:40px;padding:.25rem;text-align:center;font-size:14px;background:#fff;border:1px solid var(--rte-color-border-light);border-radius:var(--rte-radius-sm)}.editora-toolbar-group-items{display:flex;align-items:center;border:1px solid #ccc;.editora-toolbar-button{border:none;border-radius:0;&:first-child{border-right:1px solid #ccc;border-top-left-radius:3px;border-bottom-left-radius:3px}&:last-child{border:0px solid #ccc;border-radius:0!important}&:hover{background:#e0e0e0;border-color:#ccc}}}.editora-theme-dark .editora-toolbar-button{background:linear-gradient(180deg,var(--editora-dark-button-bg-start) 0%,var(--editora-dark-button-bg-end) 100%);border-color:var(--editora-dark-border-strong);color:var(--editora-dark-text);box-shadow:inset 0 1px #ffffff14,0 1px 1px #00000059}.editora-theme-dark .editora-toolbar-group-items{border-color:var(--editora-dark-border-strong);background:linear-gradient(180deg,var(--editora-dark-button-bg-start) 0%,var(--editora-dark-button-bg-end) 100%)}.editora-theme-dark .editora-toolbar-group-items .editora-toolbar-button:first-child{border-right-color:#566275}.editora-theme-dark .editora-toolbar-group-items .editora-toolbar-button:last-child{border-left-color:#566275}.editora-theme-dark .editora-toolbar-input.font-size{background-color:#2e3642;color:var(--editora-dark-text-strong);border-color:var(--editora-dark-border-strong);caret-color:var(--editora-dark-text-strong)}.editora-theme-dark .editora-toolbar-input.font-size::placeholder{color:var(--editora-dark-text-strong);opacity:1}.editora-toolbar-button:hover{background:#e0e0e0;border-color:#ccc}.editora-theme-dark .editora-toolbar-button:hover{background:linear-gradient(180deg,var(--editora-dark-button-hover-start) 0%,var(--editora-dark-button-hover-end) 100%);border-color:#66748a;color:var(--editora-dark-text-strong)}.editora-toolbar-button:active,.editora-toolbar-button.active{background:#d0d0d0;border-color:#999}.editora-theme-dark .editora-toolbar-button:active,.editora-theme-dark .editora-toolbar-button.active{background:linear-gradient(180deg,var(--editora-dark-button-active-start) 0%,var(--editora-dark-button-active-end) 100%);border-color:#67adf4;color:#0f1b2a}.editora-theme-dark .editora-toolbar-button:disabled{background:#313946;border-color:#424d5e;color:#7f8ca1}.editora-theme-dark .editora-toolbar-button[data-command=insertTable],.editora-theme-dark .editora-toolbar-button[data-command=print],.editora-theme-dark .editora-toolbar-button[data-command=toggleSpellCheck],.editora-theme-dark .editora-toolbar-button[data-command=toggleA11yChecker],.editora-theme-dark .editora-toolbar-button[data-command=setDirectionLTR],.editora-theme-dark .editora-toolbar-button[data-command=setDirectionRTL]{color:#f1f6ff}.editora-toolbar-button:disabled{opacity:.5;cursor:not-allowed}.editora-toolbar-icon{display:inline-flex;align-items:center;justify-content:center;width:24px;height:24px;line-height:1}.editora-toolbar-button svg,.editora-toolbar-icon svg{width:20px;height:20px;display:block;color:currentColor;fill:currentColor}.editora-theme-dark .editora-toolbar-icon,.editora-theme-dark .editora-toolbar-icon *{color:inherit}.editora-theme-dark :is(.editora-toolbar-button,.editora-toolbar-icon) svg :is([stroke="#000" i],[stroke="#000000" i],[stroke=black i],[stroke="#0f0f0f" i],[stroke="#111111" i],[style*="stroke:#000" i],[style*="stroke: #000" i],[style*="stroke:black" i],[style*="stroke: black" i],[style*="stroke:#0f0f0f" i],[style*="stroke: #0f0f0f" i]){stroke:currentColor!important}.editora-theme-dark :is(.editora-toolbar-button,.editora-toolbar-icon) svg :is([fill="#000" i],[fill="#000000" i],[fill=black i],[fill="#0f0f0f" i],[fill="#111111" i],[style*="fill:#000" i],[style*="fill: #000" i],[style*="fill:black" i],[style*="fill: black" i],[style*="fill:#0f0f0f" i],[style*="fill: #0f0f0f" i]){fill:currentColor!important}.editora-toolbar-separator{width:1px;height:24px;background:#ddd;margin:0 4px}.editora-theme-dark .editora-toolbar-separator{background:#4d596b}.editora-toolbar-dropdown{position:relative}.editora-toolbar-dropdown-menu{position:absolute;top:100%;left:0;min-width:150px;margin-top:4px;padding:4px 0;background:#fff;border:1px solid #ddd;border-radius:4px;box-shadow:0 2px 8px #00000026;z-index:1000}.editora-theme-dark .editora-toolbar-dropdown-menu{background:#29323d;border-color:#4d596b;box-shadow:0 8px 20px #00000073}.editora-toolbar-dropdown-item{display:block;width:100%;padding:8px 12px;border:none;background:transparent;color:#333;text-align:left;cursor:pointer;font-size:13px;transition:background .15s ease}.editora-theme-dark .editora-toolbar-dropdown-item{color:#d7deea}.editora-toolbar-dropdown-item:hover{background:#f5f5f5}.editora-theme-dark .editora-toolbar-dropdown-item:hover{background:#3a4554;color:#f0f6ff}.editora-content{flex:1;min-height:200px;padding:16px;outline:none;overflow-y:auto;line-height:1.6}.editora-theme-dark .editora-content{color:#ecf3ff;background:linear-gradient(180deg,var(--editora-dark-content) 0%,#1c232e 100%)}.editora-content:empty:before{content:attr(data-placeholder);color:#999;pointer-events:none}.editora-theme-dark .editora-content:empty:before{color:#8f9bb0}.editora-content h1{font-size:2em;margin:.67em 0;font-weight:600}.editora-content h2{font-size:1.5em;margin:.75em 0;font-weight:600}.editora-content h3{font-size:1.17em;margin:.83em 0;font-weight:600}.editora-content p{margin:1em 0}.editora-theme-dark .editora-content,.editora-theme-dark .editora-content :is(p,span,div,li,ul,ol,td,th,h1,h2,h3,h4,h5,h6,strong,em,u,s,small,sub,sup,blockquote,code,pre,a){color:#ecf3ff}.editora-content ul,.editora-content ol{margin:1em 0;padding-left:2em}.editora-content a{color:#06c;text-decoration:underline}.editora-theme-dark .editora-content a{color:#ecf3ff}.editora-content code{padding:2px 4px;background:#f5f5f5;border-radius:3px;font-family:Monaco,Menlo,Consolas,monospace;font-size:.9em}.editora-theme-dark .editora-content code{background:#1e1e1e}.editora-content pre{padding:12px;background:#f5f5f5;border-radius:4px;overflow-x:auto;margin:1em 0}.editora-theme-dark .editora-content pre{background:#1e1e1e}.editora-theme-dark .rte-code-block{background:linear-gradient(180deg,#212a36,#1b2430)!important;border-color:#4f5b70!important;color:#e7effc!important}.editora-theme-dark .rte-code-block code{color:#e7effc!important}.editora-theme-dark .rte-code-block:before{background:#111927!important;color:#dce8ff!important}.editora-theme-dark .rte-code-block .rte-code-copy{background:#2b3441!important;border-color:#5a667b!important;color:#dce8ff!important}.editora-content blockquote{margin:1em 0;padding-left:1em;border-left:4px solid #ddd;color:#666}.editora-theme-dark .editora-content blockquote{border-left-color:#3c3c3c;color:#ecf3ff}.editora-floating-toolbar{position:absolute;padding:4px;background:#fff;border:1px solid #ddd;border-radius:4px;box-shadow:0 2px 8px #00000026;z-index:1000}.editora-theme-dark .editora-floating-toolbar{background:#29323d;border-color:#4d596b;box-shadow:0 8px 20px #00000073}.editora-theme-dark .editora-statusbar{background:linear-gradient(180deg,#2c3440,#252d37);border-top-color:#3f4a5b;color:#d7deea}.editora-statusbar-item{white-space:nowrap}.editora-theme-dark .editora-statusbar-separator{color:#566275}.editora-editor[readonly] .editora-content{background:#fafafa;cursor:not-allowed}.editora-theme-dark.editora-editor[readonly] .editora-content{background:#1a1a1a}.editora-editor:focus-within{border-color:#06c;box-shadow:0 0 0 3px #0066cc1a}.editora-theme-dark.editora-editor:focus-within{border-color:#4db8ff;box-shadow:0 0 0 3px #4db8ff1a}.editora-editor[disabled]{opacity:.6;pointer-events:none}@media(max-width:768px){.editora-toolbar{padding:4px}.editora-toolbar-button{min-width:28px;min-height:28px;padding:4px 8px;font-size:12px}.editora-content{padding:12px}}.editora-content ::selection{background:#06c3}.editora-theme-dark .editora-content ::selection{background:#4db8ff33}.editora-content table{border-collapse:collapse;width:100%;margin:1em 0}.editora-content th,.editora-content td{border:1px solid #ddd;padding:8px 12px;text-align:left}.editora-theme-dark .editora-content th,.editora-theme-dark .editora-content td{border-color:#3c3c3c}.editora-content th{background:#f5f5f5;font-weight:600}.editora-theme-dark .editora-content th{background:#252526}.editora-content img{max-width:100%;height:auto;border-radius:4px;display:block}.editora-content video{max-width:100%;height:auto;border-radius:4px;display:block}.editora-editor.loading{opacity:.7;pointer-events:none}.editora-editor.loading:after{content:"";position:absolute;top:50%;left:50%;width:24px;height:24px;margin:-12px 0 0 -12px;border:3px solid #ddd;border-top-color:#06c;border-radius:50%;animation:editora-spin .8s linear infinite}@keyframes editora-spin{to{transform:rotate(360deg)}}.toolbar-container-wrapper{display:flex;align-items:center;background:#fff;border-bottom:1px solid #e0e0e0;padding:0;margin:0;width:100%;box-sizing:border-box;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif;font-size:14px;line-height:1.5;position:relative}.toolbar-container-wrapper[data-toolbar-sticky=true]{position:sticky;top:0;z-index:999;box-shadow:0 2px 4px #0000001a}.toolbar-container-wrapper[data-toolbar-floating=true]{position:fixed;top:0;left:0;right:0;z-index:1000;box-shadow:0 4px 12px #00000026}.toolbar-container-wrapper[data-toolbar-position=bottom]{border-bottom:none;border-top:1px solid #e0e0e0}.toolbar-container-wrapper .toolbar-wrapper{display:flex;width:100%;padding:8px;gap:4px;flex-wrap:wrap;align-items:center}.toolbar-container-wrapper .toolbar{display:flex;width:100%;gap:4px;flex-wrap:wrap;align-items:center}.toolbar-container-wrapper .toolbar-container{display:flex;gap:4px;flex-wrap:wrap;align-items:center;flex:1;position:relative}.toolbar-container-wrapper .toolbar-item{display:flex;align-items:center;gap:2px}.toolbar-container-wrapper .toolbar-button{padding:6px 10px;border:1px solid #d1d5db;background:#fff;border-radius:4px;cursor:pointer;font-size:13px;display:flex;align-items:center;justify-content:center;gap:4px;transition:all .15s ease;min-height:32px;white-space:nowrap}.toolbar-container-wrapper .toolbar-button:hover{background-color:#f3f4f6;border-color:#9ca3af}.toolbar-container-wrapper .toolbar-button:active,.toolbar-container-wrapper .toolbar-button[data-active=true]{background-color:#06c;color:#fff;border-color:#0052a3;box-shadow:inset 0 1px 3px #0000001a}.toolbar-container-wrapper .toolbar-button:disabled{opacity:.5;cursor:not-allowed;background-color:#f9fafb}.toolbar-container-wrapper .toolbar-more-button{padding:6px 8px;font-size:16px;font-weight:500;line-height:1}.toolbar-container-wrapper .toolbar-separator{width:1px;height:24px;background-color:#d1d5db;margin:0 4px}.toolbar-container-wrapper .toolbar-icon{display:inline-flex;align-items:center;justify-content:center;width:18px;height:18px;flex-shrink:0}.toolbar-container-wrapper .toolbar-icon svg{width:100%;height:100%}.toolbar-container-wrapper .toolbar-dropdown{position:relative;display:flex;align-items:center}.toolbar-container-wrapper .toolbar-dropdown-arrow{font-size:10px;margin-left:2px;line-height:1}.toolbar-container-wrapper .toolbar-dropdown-menu{position:absolute;top:100%;left:0;background:#fff;border:1px solid #d1d5db;border-radius:6px;box-shadow:0 4px 12px #00000026;z-index:1000;min-width:160px;padding:4px 0;margin-top:4px;display:none}.toolbar-container-wrapper .toolbar-dropdown-menu.show{display:block}.toolbar-container-wrapper .toolbar-dropdown-item{display:block;width:100%;padding:8px 12px;border:none;background:transparent;text-align:left;cursor:pointer;font-size:13px;color:#1f2937;transition:background-color .15s ease;font-family:inherit}.toolbar-container-wrapper .toolbar-dropdown-item:hover{background-color:#f3f4f6}.toolbar-container-wrapper .toolbar-dropdown-item:active{background-color:#e5e7eb}.toolbar-container-wrapper .toolbar-input{padding:6px 8px;border:1px solid #d1d5db;border-radius:4px;font-size:13px;font-family:inherit;background-color:#fff;color:#1f2937;transition:all .15s ease}.toolbar-container-wrapper .toolbar-input:focus{outline:none;border-color:#06c;box-shadow:0 0 0 3px #0066cc1a;background-color:#fff}.toolbar-container-wrapper .toolbar-input::placeholder{color:#9ca3af}.toolbar-overflow-menu{animation:slideDown .2s ease-out}@keyframes slideDown{0%{opacity:0;transform:translateY(-8px)}to{opacity:1;transform:translateY(0)}}.toolbar-overflow-item{transition:background-color .15s ease}.floating-toolbar{user-select:none;-webkit-user-select:none;font-family:system-ui,-apple-system,sans-serif;font-size:14px;animation:fadeInUp .15s ease-out}@keyframes fadeInUp{0%{opacity:0;transform:translate(-50%) translateY(10px)}to{opacity:1;transform:translate(-50%) translateY(0)}}.floating-toolbar-btn{display:flex;align-items:center;justify-content:center;width:32px;height:32px;border:none;background:transparent;border-radius:4px;color:#495057;cursor:pointer;font-size:14px;font-weight:500;transition:all .15s ease;outline:none}.floating-toolbar-btn:hover{background:#f8f9fa;color:#212529}.floating-toolbar-btn:active{background:#e9ecef;transform:scale(.95)}.floating-toolbar-btn.floating-toolbar-toggle{color:#dc3545;font-weight:700}.floating-toolbar-btn.floating-toolbar-toggle:hover{background:#f8d7da;color:#721c24}.floating-toolbar-separator{width:1px;height:20px;background:#e1e5e9;margin:0 2px}@media(max-width:768px){.toolbar-container-wrapper .toolbar-button{padding:5px 8px;font-size:12px;min-height:28px}.toolbar-container-wrapper .toolbar-icon{width:16px;height:16px}.toolbar-container-wrapper .toolbar-dropdown-menu{min-width:140px}.toolbar-container-wrapper .toolbar-dropdown-item{padding:6px 10px;font-size:12px}.floating-toolbar{padding:4px;gap:2px}.floating-toolbar-btn{width:28px;height:28px;font-size:12px}}@media(max-width:480px){.toolbar-container-wrapper{padding:4px}.toolbar-container-wrapper .toolbar-wrapper{padding:4px;gap:2px}.toolbar-container-wrapper .toolbar-button{padding:4px 6px;font-size:11px;min-height:24px}.toolbar-container-wrapper .toolbar-icon{width:14px;height:14px}}.floating-toolbar{pointer-events:auto}.floating-toolbar{max-width:calc(100vw - 20px);overflow-x:auto}@media(prefers-color-scheme:dark){.floating-toolbar{background:#2d3748;border-color:#4a5568;color:#e2e8f0}.floating-toolbar-btn:hover{background:#4a5568;color:#f7fafc}.floating-toolbar-btn:active{background:#718096}.floating-toolbar-separator{background:#4a5568}}.rte-editor{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif}.rte-toolbar-wrapper{border-radius:4px 4px 0 0}.rte-toolbar{display:flex;gap:4px;padding:8px;background:#f5f5f5;border:1px solid #ddd;border-bottom:none;border-radius:4px 4px 0 0;align-items:center;position:relative}.rte-toolbar-items-container{display:flex;gap:4px;flex-wrap:nowrap;align-items:center;flex:1}.rte-toolbar-item{position:relative;display:flex;align-items:center;white-space:nowrap}.rte-toolbar-group-items.font-size{display:flex;align-items:center;border:1px solid #ccc;.rte-toolbar-input.font-size{width:40px;padding:.25rem;text-align:center;font-size:14px;background:#fff;border:1px solid var(--rte-color-border-light);border-radius:var(--rte-radius-sm)}.rte-toolbar-button{border:none;border-radius:0}.rte-toolbar-item{&:first-child{border-right:1px solid #ccc;border-top-left-radius:3px;border-bottom-left-radius:3px}&:last-child{border-left:1px solid #ccc;border-top-right-radius:3px;border-bottom-right-radius:3px}}}.rte-toolbar-button{padding:6px 12px;border:1px solid #ccc;background:#fff;cursor:pointer;border-radius:3px;font-weight:600;font-size:14px;height:30px;display:flex;align-items:center;white-space:nowrap}.rte-toolbar-button:hover{background:#e9e9e9}.rte-toolbar-input{width:26px;padding:6px 8px;border:1px solid #ccc;border-radius:3px;font-size:14px;text-align:center}.rte-toolbar-dropdown{position:relative}.rte-toolbar-dropdown-menu{position:absolute;top:100%;left:0;background:#fff;border:1px solid #ccc;border-radius:3px;box-shadow:0 2px 8px #00000026;min-width:150px;z-index:1000;margin-top:2px}.rte-toolbar-dropdown-item{padding:8px 12px;cursor:pointer}.rte-toolbar-dropdown-item:hover{background:#f0f0f0}.rte-toolbar-more-button{padding:6px 10px;border:1px solid #ccc;background:#fff;cursor:pointer;border-radius:3px;font-weight:600;font-size:16px;height:30px;display:flex;align-items:center;justify-content:center;min-width:30px;transition:background-color .2s ease;margin-left:auto}.rte-toolbar-more-button:hover{background:#e9e9e9}.rte-toolbar-more-button.active{background:#ddd;border-color:#999}.rte-toolbar-expanded-row{display:flex;flex-wrap:wrap;align-items:flex-start;transform:scaleY(0);transform-origin:top;max-height:0;padding:0;overflow:hidden;opacity:0;transition:transform .25s ease,opacity .2s ease,max-height .25s ease}.rte-toolbar-expanded-row.show{transform:scaleY(1);max-height:320px;padding:1px 8px 8px;opacity:1;background:#f5f5f5;border:1px solid #ddd;border-top:none;gap:4px;overflow-y:auto;overflow-x:hidden}.rte-content{font-size:16px;line-height:1.6}.rte-content.rte-content-empty:before,.rte-content:empty:before{content:attr(data-placeholder);color:var(--rte-color-text-muted, #6b7280);pointer-events:none}.rte-content p{margin:0 0 1em}.rte-content h1{font-size:2em;margin:.67em 0}.rte-content h2{font-size:1.5em;margin:.75em 0}.rte-content h3{font-size:1.17em;margin:.83em 0}.rte-content h4{font-size:1em;margin:1em 0}.rte-content h5{font-size:.83em;margin:1.17em 0}.rte-content h6{font-size:.67em;margin:1.33em 0}.rte-content ul,.rte-content ol{margin:1em 0;padding-left:2em}.rte-content .rte-table,.rte-content table{border-collapse:collapse;width:100%;margin:1rem 0;border:1px solid #ddd;font-size:14px;line-height:1.4}.rte-content .rte-table td,.rte-content .rte-table th,.rte-content table td,.rte-content table th{border:1px solid #ddd;padding:8px 12px;min-width:80px;text-align:left;vertical-align:top}.rte-content .rte-table th,.rte-content table th{background-color:#f8f9fa;font-weight:600}.rte-content .rte-table td p,.rte-content table td p{margin:0}.table-toolbar{background:#fff;border:1px solid #d0d0d0;border-radius:4px;box-shadow:0 2px 8px #0000001a;padding:4px;display:flex;align-items:center}.toolbar-icon-btn{display:flex;align-items:center;justify-content:center;width:28px;height:28px;padding:0;border:1px solid transparent;background:transparent;color:#333;border-radius:3px;cursor:pointer}.toolbar-icon-btn:hover:not(:disabled){background:#f0f0f0;border-color:#d0d0d0}.rte-content code{background:#f4f4f4;padding:2px 6px;border-radius:3px;font-family:Courier New,monospace;font-size:.9em}.rte-content blockquote{border-left:4px solid #ddd;margin:1em 0;padding-left:1em;color:#666}.rte-content a{color:#06c;text-decoration:underline}.rte-content a:hover{color:#0052a3}.rte-dialog-overlay{position:fixed;inset:0;background:#00000080;display:flex;align-items:center;justify-content:center;z-index:10000}.rte-dialog-content{background:#fff;border-radius:8px;box-shadow:0 4px 20px #0000004d;max-width:400px;width:90%;max-height:90vh;overflow-y:auto}.rte-dialog-header{padding:16px 20px;border-bottom:1px solid #e0e0e0;display:flex;justify-content:space-between;align-items:center}.rte-dialog-header h3{margin:0;font-size:18px;font-weight:600;color:#333}.rte-dialog-close{background:none;border:none;font-size:24px;cursor:pointer;color:#666;padding:0;width:30px;height:30px;display:flex;align-items:center;justify-content:center}.rte-dialog-close:hover{color:#333}.rte-dialog-body{padding:20px}.rte-dialog-footer{padding:16px 20px;border-top:1px solid #e0e0e0;display:flex;justify-content:flex-end;gap:12px}.rte-btn{padding:8px 16px;border:1px solid #ccc;border-radius:4px;cursor:pointer;font-size:14px;font-weight:500;transition:all .2s}.rte-btn:hover{border-color:#999}.rte-btn-primary{background:#06c;color:#fff;border-color:#06c}.rte-btn-primary:hover{background:#0052a3;border-color:#0052a3}.rte-btn-secondary{background:#fff;color:#333}.rte-btn-secondary:hover{background:#f5f5f5}.rte-form-group{margin-bottom:16px}.rte-form-label{display:block;margin-bottom:6px;font-weight:500;color:#333;font-size:14px}.rte-form-input{width:100%;padding:8px 12px;border:1px solid #ccc;border-radius:4px;font-size:14px;box-sizing:border-box}.rte-form-input:focus{outline:none;border-color:#06c;box-shadow:0 0 0 2px #06c3}.rte-form-row{display:flex;gap:12px}.rte-form-row .rte-form-group{flex:1}.rte-color-preview{display:flex;align-items:center;gap:12px;margin-bottom:20px;padding:12px;background:#f8f9fa;border-radius:4px}.rte-color-sample{width:40px;height:40px;border-radius:4px;border:2px solid #ddd}.rte-color-value{font-family:monospace;font-size:14px;font-weight:500;color:#333}.rte-color-section{margin-bottom:20px}.rte-color-label{margin-bottom:8px;font-size:14px;font-weight:500}.rte-color-palette{display:grid;grid-template-columns:repeat(6,1fr);gap:8px;margin-bottom:16px}.rte-color-swatch{width:24px;height:24px;border:2px solid #ddd;border-radius:4px;cursor:pointer;transition:all .2s}.rte-color-swatch:hover{border-color:#999;transform:scale(1.1)}.rte-color-swatch.selected{border-color:#06c;box-shadow:0 0 0 2px #0066cc4d}.rte-custom-color{display:flex;align-items:center;gap:12px}.rte-color-input{width:60px;height:40px;border:2px solid #ddd;border-radius:4px;cursor:pointer}.rte-color-text-input{flex:1;padding:8px 12px;border:1px solid #ccc;border-radius:4px;font-family:monospace;font-size:14px}.rte-color-text-input:focus{outline:none;border-color:#06c;box-shadow:0 0 0 2px #06c3}.rte-iframe-preview{border:1px solid #ddd;border-radius:4px;overflow:hidden;background:#f8f9fa}.rte-iframe-preview iframe{display:block;border:none}.rte-size-presets{display:flex;flex-direction:column;gap:8px}.rte-radio-option{display:flex;align-items:flex-start;gap:8px;padding:8px;border:1px solid #e0e0e0;border-radius:4px;background:#fafbfc}.rte-radio-option:hover{background:#f1f3f4}.rte-radio-option input[type=radio]{margin-top:2px}.rte-radio-label{flex:1;line-height:1.4}.rte-content ul[data-type=checklist]{list-style:none;padding-left:0;margin:1em 0}.rte-content li[data-type=checklist-item]{position:relative;padding-left:2em;margin-bottom:.5em;line-height:1.6}.rte-content li[data-type=checklist-item]:before{content:"";position:absolute;left:0;top:.1em;width:1.2em;height:1.2em;border:2px solid #ccc;border-radius:3px;background:#fff;cursor:pointer;transition:all .2s ease}.rte-content li[data-type=checklist-item]:hover:before{border-color:#999}.rte-content li[data-type=checklist-item][data-checked=true]:before{background:#06c;border-color:#06c}.rte-content li[data-type=checklist-item][data-checked=true]:after{content:"✓";position:absolute;left:.36em;top:.12em;color:#fff;font-size:.9em;font-weight:700;pointer-events:none}.rte-content li[data-type=checklist-item][data-checked=true] p{text-decoration:line-through;color:#666}.editora-statusbar-container{display:flex;flex-direction:column}.rte-editor{.editora-statusbar-bottom{top:-32px}}.editora-statusbar-bottom{position:relative;border-left:1px solid rgb(221,221,221);border-right:1px solid rgb(221,221,221)}.editora-statusbar{display:flex;align-items:center;gap:12px;padding:6px 12px;background:#f5f5f5;border-top:1px solid #ddd;font-size:12px;color:#666}.editora-theme-dark .editora-statusbar{background:#252526;border-top-color:#3c3c3c;color:#9a9a9a}.editora-statusbar-top{border-top:none;border-bottom:1px solid #e0e0e0}.editora-statusbar-left{display:flex;align-items:center;gap:8px}.editora-statusbar-right{display:flex;align-items:center;gap:8px;margin-left:auto}.editora-statusbar-item{white-space:nowrap;padding:2px 4px}.editora-statusbar-separator{color:#ddd}.editora-theme-dark .editora-statusbar-separator{color:#3c3c3c}.editora-theme-dark .rte-content,.editora-theme-dark .rte-content h1,.editora-theme-dark .rte-content h2,.editora-theme-dark .rte-content h3,.editora-theme-dark .rte-content h4,.editora-theme-dark .rte-content h5,.editora-theme-dark .rte-content h6{color:#fff}.rte-inline-menu{position:fixed;z-index:1000;background:#fff;border:1px solid #ccc;border-radius:4px;box-shadow:0 2px 8px #00000026;min-width:120px;max-width:200px;pointer-events:auto}.rte-inline-menu-item{padding:8px 12px;cursor:pointer;font-size:14px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;background-color:transparent}.rte-inline-menu-item:hover{background-color:#f5f5f5}.floating-toolbar{--rte-floating-toolbar-bg: #ffffff;--rte-floating-toolbar-border: #d7dee8;--rte-floating-toolbar-text: #364152;--rte-floating-toolbar-hover-bg: #f2f6fb;--rte-floating-toolbar-hover-text: #101828;--rte-floating-toolbar-active-bg: #e7eef7;--rte-floating-toolbar-separator: #d8e1ec;--rte-floating-toolbar-shadow: 0 10px 28px rgba(15, 23, 36, .16);user-select:none;-webkit-user-select:none;align-items:center;gap:4px;padding:6px;border-radius:8px;border:1px solid var(--rte-floating-toolbar-border);background:var(--rte-floating-toolbar-bg);color:var(--rte-floating-toolbar-text);box-shadow:var(--rte-floating-toolbar-shadow);pointer-events:auto;animation:rteFloatingToolbarIn .15s ease-out}.floating-toolbar-btn{display:inline-flex;align-items:center;justify-content:center;min-width:32px;height:32px;border:none;border-radius:6px;background:transparent;color:inherit;cursor:pointer;font-size:14px;font-weight:600;transition:background-color .15s ease,color .15s ease,transform .12s ease}.floating-toolbar-btn:hover{background:var(--rte-floating-toolbar-hover-bg);color:var(--rte-floating-toolbar-hover-text)}.floating-toolbar-btn:active{background:var(--rte-floating-toolbar-active-bg);transform:scale(.96)}.floating-toolbar-separator{width:1px;height:20px;margin:0 2px;background:var(--rte-floating-toolbar-separator)}@keyframes rteFloatingToolbarIn{0%{opacity:0;transform:translate(-50%) translateY(8px)}to{opacity:1;transform:translate(-50%) translateY(0)}}.editora-toolbar-group-button{display:flex;align-items:center;border-radius:var(--rte-radius);overflow:hidden;margin-right:.5rem;padding:0}.editora-toolbar-group-items{display:flex;align-items:center;gap:0}.editora-toolbar-group-button .editora-toolbar-button,.editora-toolbar-group-button .editora-toolbar-input{border-radius:0;border:none;margin:0;background:transparent;box-shadow:none}.editora-toolbar-group-button .editora-toolbar-button:first-child{border-radius:var(--rte-radius) 0 0 var(--rte-radius)}.editora-toolbar-group-button .editora-toolbar-button:last-child{border-radius:0 var(--rte-radius) var(--rte-radius) 0}.editora-toolbar-group-button .editora-toolbar-input{min-width:44px;width:44px;text-align:center;font-size:15px;background:#fff;border-left:1px solid var(--rte-color-border-light);border-right:1px solid var(--rte-color-border-light)}.editora-toolbar-group-button .editora-toolbar-button:active,.editora-toolbar-group-button .editora-toolbar-button:focus{background:#e5e7eb}.editora-toolbar-group-button .editora-toolbar-input:focus{outline:1.5px solid var(--rte-color-primary, #2563eb)}:root{--rte-color-primary: #007bff;--rte-color-primary-hover: #0056b3;--rte-color-secondary: #6c757d;--rte-color-success: #28a745;--rte-color-danger: #dc3545;--rte-color-warning: #ffc107;--rte-color-info: #17a2b8;--rte-color-text-primary: #212529;--rte-color-text-secondary: #6c757d;--rte-color-text-muted: #868e96;--rte-color-text-inverse: #ffffff;--rte-color-bg-primary: #ffffff;--rte-color-bg-secondary: #f8f9fa;--rte-color-bg-tertiary: #e9ecef;--rte-color-bg-hover: #f8f9fa;--rte-color-bg-active: #e9ecef;--rte-color-border: #dee2e6;--rte-color-border-light: #f8f9fa;--rte-color-border-focus: #007bff;--rte-shadow-sm: 0 1px 2px rgba(0, 0, 0, .05);--rte-shadow: 0 1px 3px rgba(0, 0, 0, .1), 0 1px 2px rgba(0, 0, 0, .06);--rte-shadow-lg: 0 10px 15px rgba(0, 0, 0, .1), 0 4px 6px rgba(0, 0, 0, .05);--rte-space-xs: .25rem;--rte-space-sm: .5rem;--rte-space-md: 1rem;--rte-space-lg: 1.5rem;--rte-space-xl: 2rem;--rte-space-xxl: 3rem;--rte-font-family-base: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;--rte-font-family-mono: "SFMono-Regular", Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--rte-font-size-xs: .75rem;--rte-font-size-sm: .875rem;--rte-font-size-base: 1rem;--rte-font-size-lg: 1.125rem;--rte-font-size-xl: 1.25rem;--rte-font-size-xxl: 1.5rem;--rte-font-size-xxxl: 2rem;--rte-font-weight-normal: 400;--rte-font-weight-medium: 500;--rte-font-weight-semibold: 600;--rte-font-weight-bold: 700;--rte-line-height-tight: 1.25;--rte-line-height-normal: 1.5;--rte-line-height-relaxed: 1.75;--rte-radius-sm: .125rem;--rte-radius: .25rem;--rte-radius-md: .375rem;--rte-radius-lg: .5rem;--rte-radius-xl: .75rem;--rte-transition-fast: .15s ease-in-out;--rte-transition-normal: .25s ease-in-out;--rte-transition-slow: .35s ease-in-out;--rte-z-dropdown: 1000;--rte-z-sticky: 1020;--rte-z-modal: 1050;--rte-z-popover: 1060;--rte-z-tooltip: 1070}.rte-editor{font-family:var(--rte-font-family-base);font-size:var(--rte-font-size-base);line-height:var(--rte-line-height-normal);color:var(--rte-color-text-primary);background-color:var(--rte-color-bg-primary);border:1px solid var(--rte-color-border);border-radius:var(--rte-radius);box-shadow:var(--rte-shadow);transition:border-color var(--rte-transition-fast),box-shadow var(--rte-transition-fast)}.rte-editor:focus-within{border-color:var(--rte-color-border-focus);box-shadow:var(--rte-shadow),0 0 0 3px #007bff1a}.rte-toolbar{display:flex;align-items:center;padding:var(--rte-space-sm);border-bottom:1px solid var(--rte-color-border);background-color:var(--rte-color-bg-secondary);border-radius:var(--rte-radius) var(--rte-radius) 0 0;flex-wrap:wrap;gap:2px}.rte-toolbar-group{display:flex;align-items:center;border-radius:var(--rte-radius);overflow:hidden;border:1px solid var(--rte-color-border-light)}.rte-toolbar-button{display:flex;align-items:center;justify-content:center;width:2rem;height:2rem;padding:0;border:none;background:transparent;color:var(--rte-color-text-secondary);cursor:pointer;border-radius:var(--rte-radius-sm);transition:background-color var(--rte-transition-fast),color var(--rte-transition-fast);font-size:14px;line-height:1}.rte-toolbar-button span{display:flex;justify-content:center;align-items:center}.rte-toolbar-button svg,.editora-toolbar-button svg,.editora-toolbar-icon svg{flex-shrink:0;width:20px;height:20px;display:block;color:currentColor;fill:currentColor}.rte-toolbar-button:hover svg{opacity:.9}:is(.rte-toolbar-button[data-active=true],.editora-toolbar-button.active) svg{color:var(--rte-color-text-inverse)}.rte-toolbar-button:hover{background-color:var(--rte-color-bg-hover);color:var(--rte-color-text-primary)}.rte-toolbar-button:active,.rte-toolbar-button[data-active=true]{background-color:var(--rte-color-primary);color:var(--rte-color-text-inverse)}.rte-toolbar-button:disabled{opacity:.5;cursor:not-allowed}.rte-content{padding:var(--rte-space-md);min-height:200px;outline:none;overflow-wrap:break-word;word-wrap:break-word}.rte-content[contenteditable=true]{cursor:text}.rte-content h1,.rte-content h2,.rte-content h3,.rte-content h4,.rte-content h5,.rte-content h6{margin:var(--rte-space-lg) 0 var(--rte-space-md) 0;font-weight:var(--rte-font-weight-semibold);line-height:var(--rte-line-height-tight);color:var(--rte-color-text-primary)}.rte-content h1{font-size:var(--rte-font-size-xxxl)}.rte-content h2{font-size:var(--rte-font-size-xxl)}.rte-content h3{font-size:var(--rte-font-size-xl)}.rte-content h4{font-size:var(--rte-font-size-lg)}.rte-content h5{font-size:var(--rte-font-size-base)}.rte-content h6{font-size:var(--rte-font-size-sm)}.rte-content p{margin:var(--rte-space-md) 0}.rte-content blockquote{margin:var(--rte-space-lg) 0;padding:var(--rte-space-md);padding-left:var(--rte-space-lg);border-left:4px solid var(--rte-color-primary);background-color:var(--rte-color-bg-secondary);font-style:italic;color:var(--rte-color-text-secondary)}.rte-content ul,.rte-content ol{margin:var(--rte-space-md) 0;padding-left:var(--rte-space-xl)}.rte-content li{margin:var(--rte-space-xs) 0}.rte-content ul{list-style-type:disc}.rte-content ol{list-style-type:decimal}.rte-link{color:var(--rte-color-primary);text-decoration:none;transition:color var(--rte-transition-fast)}.rte-link:hover{color:var(--rte-color-primary-hover);text-decoration:underline}.rte-content code{font-family:var(--rte-font-family-mono);font-size:.875em;background-color:var(--rte-color-bg-tertiary);padding:.125rem .25rem;border-radius:var(--rte-radius-sm);color:var(--rte-color-danger)}.rte-content::selection{background-color:#007bff33}.rte-content:empty:before,.rte-content.rte-content-empty:before{content:attr(data-placeholder);color:var(--rte-color-text-muted);pointer-events:none}.rte-content:focus{outline:none}.rte-sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.rte-text-left{text-align:left}.rte-text-center{text-align:center}.rte-text-right{text-align:right}.rte-text-justify{text-align:justify}.rte-table td,.rte-table th,table td,table th{border:1px solid #ddd;padding:8px 12px;min-width:80px;vertical-align:top;position:relative;-webkit-user-select:none;user-select:none}.table-toolbar{background:#fff;border:1px solid #d0d0d0;border-radius:4px;box-shadow:0 2px 8px #0000001a;padding:4px;display:flex;align-items:center;gap:0;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,sans-serif;min-width:max-content}.rte-table,table{border-collapse:collapse;width:100%;margin:1rem 0;border:1px solid #ddd;font-size:14px;line-height:1.4;position:relative}.rte-table td,.rte-table th,table td,table th{border:1px solid #ddd;padding:8px 12px;min-width:80px;vertical-align:top;position:relative;user-select:none}.rte-table td:focus,.rte-table th:focus,table td:focus,table th:focus{outline:2px solid #007acc;outline-offset:-2px}.rte-table th,table th{background-color:#f8f9fa;font-weight:600;text-align:left}.rte-table td p,table td p{margin:0;padding:0}.rte-table td p:empty:before,table td p:empty:before{content:"";display:inline-block}.rte-table td[contenteditable]:empty:before,table td[contenteditable]:empty:before{content:"Type here...";color:#999;font-style:italic;pointer-events:none}.rte-table tr:hover,table tr:hover{background-color:#f8f9fa}.rte-table td.selected,table td.selected{background-color:#e3f2fd;border-color:#2196f3}.table-toolbar{background:#fff;border:1px solid #d0d0d0;border-radius:4px;box-shadow:0 2px 8px #0000001a;padding:4px;display:flex;align-items:center;gap:0;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,sans-serif;min-width:max-content}.toolbar-section{display:flex;align-items:center;gap:2px}.toolbar-divider{width:1px;height:20px;background:#e0e0e0;margin:0 4px}.toolbar-icon-btn{display:flex;align-items:center;justify-content:center;width:28px;height:28px;padding:0;border:1px solid transparent;background:transparent;cursor:pointer;color:#333;border-radius:3px;transition:all .2s ease;flex-shrink:0;font-size:14px;line-height:1}.toolbar-icon-btn svg{width:16px;height:16px}.toolbar-icon-btn:hover:not(:disabled){background:#f0f0f0;border-color:#d0d0d0;color:#06c}.toolbar-icon-btn:active:not(:disabled){background:#e8f0ff;border-color:#06c;transform:scale(.95)}.toolbar-icon-btn:disabled{opacity:.4;cursor:not-allowed;color:#ccc}.toolbar-icon-btn-danger{color:#d32f2f}.toolbar-icon-btn-danger:hover:not(:disabled){background:#fff3f3;border-color:#fcc;color:#d32f2f}.toolbar-icon-btn-danger:active:not(:disabled){background:#ffebee}.toolbar-icon-btn-delete{color:#d32f2f}.toolbar-icon-btn-delete:hover:not(:disabled){background:#fff3f3;border-color:#fcc;color:#d32f2f}.toolbar-icon-btn-delete:active:not(:disabled){background:#ffebee}.resize-handle{opacity:0;transition:all .15s ease}.resize-handle:hover{opacity:1}td:hover>.resize-handle,th:hover>.resize-handle{opacity:1}.table-resize-handle{position:absolute;bottom:-4px;right:-4px;width:12px;height:12px;background:transparent;cursor:nwse-resize;z-index:10;transition:background .15s ease}.table-resize-handle:after{content:"";position:absolute;bottom:0;right:0;width:8px;height:8px;background:#0066cc4d;border-bottom:2px solid #0066cc;border-right:2px solid #0066cc;border-radius:0 0 2px;opacity:0;transition:opacity .15s ease}.table-resize-handle:hover:after{opacity:1}.rte-table:hover .table-resize-handle:after,table:hover .table-resize-handle:after{opacity:1}:is([data-theme=dark],.dark,.editora-theme-dark) :is(.rte-table,table){border-color:#607088;background:#24303c;color:#e6eefb}:is([data-theme=dark],.dark,.editora-theme-dark) :is(.rte-table td,.rte-table th,table td,table th){border-color:#607088;color:#e6eefb}:is([data-theme=dark],.dark,.editora-theme-dark) :is(.rte-table th,table th){background:linear-gradient(180deg,#3b4553,#333d4a);color:#f3f8ff}:is([data-theme=dark],.dark,.editora-theme-dark) :is(.rte-table tr:hover,table tr:hover){background-color:#58a6ff1f}:is([data-theme=dark],.dark,.editora-theme-dark) :is(.rte-table td.selected,table td.selected){background-color:#58a6ff47;border-color:#79beff}:is([data-theme=dark],.dark,.editora-theme-dark) :is(.rte-table td[contenteditable]:empty:before,table td[contenteditable]:empty:before){color:#94a3b8}:is([data-theme=dark],.dark,.editora-theme-dark) .table-toolbar{background:linear-gradient(180deg,#2f3844,#2a323c);border-color:#4d596b;box-shadow:0 8px 20px #00000073}.table-toolbar.rte-theme-dark{background:linear-gradient(180deg,#2f3844,#2a323c);border-color:#4d596b;box-shadow:0 8px 20px #00000073}:is([data-theme=dark],.dark,.editora-theme-dark) .toolbar-divider{background:#4d596b}.table-toolbar.rte-theme-dark .toolbar-divider{background:#4d596b}:is([data-theme=dark],.dark,.editora-theme-dark) .toolbar-icon-btn{color:#d7deea;border-color:transparent}.table-toolbar.rte-theme-dark .toolbar-icon-btn{color:#d7deea;border-color:transparent}:is([data-theme=dark],.dark,.editora-theme-dark) .toolbar-icon-btn svg{color:currentColor;fill:currentColor}.table-toolbar.rte-theme-dark .toolbar-icon-btn svg{color:currentColor;fill:currentColor}:is([data-theme=dark],.dark,.editora-theme-dark) .toolbar-icon-btn svg [stroke="#000" i],:is([data-theme=dark],.dark,.editora-theme-dark) .toolbar-icon-btn svg [stroke="#000000" i],:is([data-theme=dark],.dark,.editora-theme-dark) .toolbar-icon-btn svg [stroke=black i]{stroke:currentColor!important}.table-toolbar.rte-theme-dark .toolbar-icon-btn svg [stroke="#000" i],.table-toolbar.rte-theme-dark .toolbar-icon-btn svg [stroke="#000000" i],.table-toolbar.rte-theme-dark .toolbar-icon-btn svg [stroke=black i]{stroke:currentColor!important}:is([data-theme=dark],.dark,.editora-theme-dark) .toolbar-icon-btn svg [fill="#000" i],:is([data-theme=dark],.dark,.editora-theme-dark) .toolbar-icon-btn svg [fill="#000000" i],:is([data-theme=dark],.dark,.editora-theme-dark) .toolbar-icon-btn svg [fill=black i]{fill:currentColor!important}.table-toolbar.rte-theme-dark .toolbar-icon-btn svg [fill="#000" i],.table-toolbar.rte-theme-dark .toolbar-icon-btn svg [fill="#000000" i],.table-toolbar.rte-theme-dark .toolbar-icon-btn svg [fill=black i]{fill:currentColor!important}:is([data-theme=dark],.dark,.editora-theme-dark) .toolbar-icon-btn:hover:not(:disabled){background:#3a4554;border-color:#607088;color:#f3f8ff}.table-toolbar.rte-theme-dark .toolbar-icon-btn:hover:not(:disabled){background:#3a4554;border-color:#607088;color:#f3f8ff}:is([data-theme=dark],.dark,.editora-theme-dark) .toolbar-icon-btn:active:not(:disabled){background:#4a95de;border-color:#67adf4;color:#0f1b2a}.table-toolbar.rte-theme-dark .toolbar-icon-btn:active:not(:disabled){background:#4a95de;border-color:#67adf4;color:#0f1b2a}:is([data-theme=dark],.dark,.editora-theme-dark) .toolbar-icon-btn:disabled{color:#7f8ca1}.table-toolbar.rte-theme-dark .toolbar-icon-btn:disabled{color:#7f8ca1}@media(max-width:768px){.rte-table,table{font-size:12px}.rte-table td,.rte-table th,table td,table th{padding:4px 6px;min-width:60px}.table-toolbar{padding:3px;gap:0;max-width:90vw;overflow-x:auto}.toolbar-icon-btn{width:26px;height:26px}.toolbar-divider{height:18px}}@media print{.rte-table,table{border:1px solid #000}.rte-table td,.rte-table th,table td,table th{border:1px solid #000;padding:4px}.table-toolbar{display:none}} |
+2
-2
| { | ||
| "name": "@editora/core", | ||
| "version": "1.0.7", | ||
| "version": "1.0.8", | ||
| "description": "Framework-agnostic core editor engine for Editora Rich Text Editor", | ||
@@ -130,3 +130,3 @@ "author": "Ajay Kumar <ajaykr089@gmail.com>", | ||
| }, | ||
| "gitHead": "694494db58b809f0dcf24501696284faa1ab68a5" | ||
| "gitHead": "80e0808ae4909de63b8e0f1dd915b06b33a8ed44" | ||
| } |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
| const u = '.rte-page-break[data-type="page-break"]', g = ".rte-content, .editora-content"; | ||
| let p = null, m = !1; | ||
| const h = (e, n) => { | ||
| if (n === e.innerHTML) return; | ||
| const t = window.execEditorCommand || window.executeEditorCommand; | ||
| if (typeof t == "function") | ||
| try { | ||
| t("recordDomTransaction", e, n, e.innerHTML); | ||
| } catch (r) { | ||
| } | ||
| }, v = /* @__PURE__ */ new Set([ | ||
| "DIV", | ||
| "P", | ||
| "BLOCKQUOTE", | ||
| "PRE", | ||
| "H1", | ||
| "H2", | ||
| "H3", | ||
| "H4", | ||
| "H5", | ||
| "H6", | ||
| "LI", | ||
| "TD", | ||
| "TH" | ||
| ]), w = () => { | ||
| p || typeof document == "undefined" || (p = document.createElement("style"), p.textContent = ` | ||
| .rte-page-break { | ||
| display: block; | ||
| position: relative; | ||
| height: 12px; | ||
| margin: 8px 0; | ||
| background: linear-gradient(90deg, #ccc 0%, transparent 100%); | ||
| border-top: 2px dashed #999; | ||
| border-bottom: none; | ||
| cursor: pointer; | ||
| user-select: none; | ||
| transition: all 0.2s ease; | ||
| outline: none; | ||
| -webkit-user-select: none; | ||
| -moz-user-select: none; | ||
| -ms-user-select: none; | ||
| } | ||
| .rte-page-break::before { | ||
| content: '⎙ PAGE BREAK'; | ||
| position: absolute; | ||
| top: -12px; | ||
| left: 0; | ||
| font-size: 10px; | ||
| font-weight: bold; | ||
| color: #666; | ||
| background: white; | ||
| padding: 2px 6px; | ||
| letter-spacing: 0.5px; | ||
| opacity: 0.7; | ||
| pointer-events: none; | ||
| } | ||
| .rte-page-break:hover { | ||
| background: linear-gradient(90deg, #999 0%, transparent 100%); | ||
| border-top-color: #666; | ||
| box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.1); | ||
| } | ||
| .rte-page-break:hover::before { | ||
| opacity: 1; | ||
| color: #333; | ||
| } | ||
| .rte-page-break:focus, | ||
| .rte-page-break:focus-visible, | ||
| .rte-page-break-selected { | ||
| outline: 2px solid #0066cc; | ||
| outline-offset: -2px; | ||
| border-top-color: #0066cc; | ||
| background: linear-gradient(90deg, #0066cc 0%, transparent 100%); | ||
| } | ||
| .rte-page-break * { | ||
| user-select: none; | ||
| } | ||
| @media print { | ||
| .rte-page-break { | ||
| display: block; | ||
| height: 0; | ||
| margin: 0; | ||
| background: none; | ||
| border: none; | ||
| page-break-after: always; | ||
| } | ||
| .rte-page-break::before { | ||
| display: none; | ||
| } | ||
| } | ||
| `, document.head.appendChild(p)); | ||
| }, N = () => { | ||
| const e = window.getSelection(); | ||
| if (!e || e.rangeCount === 0) return null; | ||
| const n = e.getRangeAt(0), t = n.startContainer.nodeType === Node.ELEMENT_NODE ? n.startContainer : n.startContainer.parentElement; | ||
| return (t == null ? void 0 : t.closest(g)) || null; | ||
| }, k = () => { | ||
| const e = N(); | ||
| if (e) return e; | ||
| const n = document.activeElement, t = n == null ? void 0 : n.closest(g); | ||
| return t || document.querySelector(g); | ||
| }, E = (e, n) => { | ||
| let t = e; | ||
| for (; t && t !== n; ) { | ||
| if (t.nodeType === Node.ELEMENT_NODE) { | ||
| const r = t; | ||
| if (v.has(r.tagName)) | ||
| return r; | ||
| } | ||
| t = t.parentNode; | ||
| } | ||
| return null; | ||
| }, T = () => { | ||
| const e = document.createElement("div"); | ||
| return e.className = "rte-page-break", e.setAttribute("data-page-break", "true"), e.setAttribute("data-type", "page-break"), e.setAttribute("contenteditable", "false"), e.setAttribute("tabindex", "0"), e.setAttribute("role", "separator"), e.setAttribute("aria-label", "Page break"), e; | ||
| }, S = (e) => { | ||
| let n = e.nextElementSibling; | ||
| for (; n && n.matches(u); ) { | ||
| const r = n; | ||
| n = n.nextElementSibling, r.remove(); | ||
| } | ||
| let t = e.previousElementSibling; | ||
| for (; t && t.matches(u); ) { | ||
| const r = t; | ||
| t = t.previousElementSibling, r.remove(); | ||
| } | ||
| }, x = (e) => { | ||
| var r; | ||
| const n = e.nextElementSibling; | ||
| if (n && !n.matches(u)) | ||
| return n; | ||
| const t = document.createElement("p"); | ||
| return t.innerHTML = "<br>", (r = e.parentNode) == null || r.insertBefore(t, e.nextSibling), t; | ||
| }, d = (e) => { | ||
| const n = window.getSelection(); | ||
| if (!n) return; | ||
| const t = document.createRange(); | ||
| e.nodeType, Node.TEXT_NODE, t.setStart(e, 0), t.collapse(!0), n.removeAllRanges(), n.addRange(t); | ||
| }, b = (e) => { | ||
| const n = window.getSelection(); | ||
| if (!n) return; | ||
| const t = document.createRange(); | ||
| if (e.nodeType === Node.TEXT_NODE) { | ||
| const r = e; | ||
| t.setStart(r, r.data.length); | ||
| } else | ||
| t.selectNodeContents(e), t.collapse(!1); | ||
| n.removeAllRanges(), n.addRange(t); | ||
| }, f = (e, n) => { | ||
| let t = e; | ||
| for (; t; ) { | ||
| if (!(t instanceof HTMLElement && t.matches(u))) | ||
| return t; | ||
| t = n === "previous" ? t.previousSibling : t.nextSibling; | ||
| } | ||
| return null; | ||
| }, L = (e) => { | ||
| const n = window.getSelection(); | ||
| if (!n || !e.parentNode) return; | ||
| const t = e.parentNode, r = Array.from(t.childNodes).indexOf(e); | ||
| if (r < 0) return; | ||
| const o = document.createRange(); | ||
| o.setStart(t, r), o.setEnd(t, r + 1), n.removeAllRanges(), n.addRange(o), e.focus({ preventScroll: !0 }); | ||
| }, A = (e) => { | ||
| if (e.collapsed || e.startContainer !== e.endContainer || e.endOffset !== e.startOffset + 1 || !(e.startContainer instanceof Element || e.startContainer instanceof DocumentFragment)) return null; | ||
| const n = e.startContainer.childNodes[e.startOffset]; | ||
| return n instanceof HTMLElement && n.matches(u) ? n : null; | ||
| }, R = (e, n, t) => { | ||
| if (!e.collapsed) return null; | ||
| const { startContainer: r, startOffset: o } = e, a = (i) => i instanceof HTMLElement && i.matches(u) ? i : null, s = (i) => { | ||
| if (r.nodeType === Node.ELEMENT_NODE) { | ||
| const l = r; | ||
| if (i === "previous") { | ||
| if (o > 0) | ||
| return l.childNodes[o - 1] || null; | ||
| } else if (o < l.childNodes.length) | ||
| return l.childNodes[o] || null; | ||
| } | ||
| if (r.nodeType === Node.TEXT_NODE && (i === "previous" && o < r.data.length || i === "next" && o > 0)) | ||
| return null; | ||
| let c = r; | ||
| for (; c && c !== n; ) { | ||
| const l = i === "previous" ? c.previousSibling : c.nextSibling; | ||
| if (l) return l; | ||
| c = c.parentNode; | ||
| } | ||
| return null; | ||
| }; | ||
| if (r.nodeType === Node.ELEMENT_NODE) { | ||
| const i = r; | ||
| return t === "Backspace" && o > 0 ? a(i.childNodes[o - 1] || null) : t === "Delete" ? a(i.childNodes[o] || null) : null; | ||
| } | ||
| if (r.nodeType === Node.TEXT_NODE) { | ||
| const i = r; | ||
| if (t === "Backspace" && o === 0) { | ||
| const c = a(i.previousSibling); | ||
| return c || a(s("previous")); | ||
| } | ||
| if (t === "Delete" && o === i.data.length) { | ||
| const c = a(i.nextSibling); | ||
| return c || a(s("next")); | ||
| } | ||
| } | ||
| return a(s(t === "Backspace" ? "previous" : "next")); | ||
| }, C = (e, n) => { | ||
| var c; | ||
| const t = e.closest(g), r = (c = t == null ? void 0 : t.innerHTML) != null ? c : "", o = e.previousSibling, a = e.nextSibling; | ||
| e.remove(); | ||
| const s = f(o, "previous"), i = f(a, "next"); | ||
| if (n === "Backspace") { | ||
| if (s) | ||
| b(s); | ||
| else if (i) | ||
| d(i); | ||
| else if (t) { | ||
| const l = document.createElement("p"); | ||
| l.innerHTML = "<br>", t.appendChild(l), d(l); | ||
| } | ||
| } else if (i) | ||
| d(i); | ||
| else if (s) | ||
| b(s); | ||
| else if (t) { | ||
| const l = document.createElement("p"); | ||
| l.innerHTML = "<br>", t.appendChild(l), d(l); | ||
| } | ||
| return t && (h(t, r), t.dispatchEvent(new Event("input", { bubbles: !0 }))), !0; | ||
| }, y = () => { | ||
| const e = k(); | ||
| if (!e) return !1; | ||
| const n = e.innerHTML, t = window.getSelection(); | ||
| if (!t) return !1; | ||
| let r; | ||
| t.rangeCount > 0 && e.contains(t.getRangeAt(0).commonAncestorContainer) ? r = t.getRangeAt(0) : (r = document.createRange(), r.selectNodeContents(e), r.collapse(!1), t.removeAllRanges(), t.addRange(r)); | ||
| const o = E(r.endContainer, e) || E(r.startContainer, e), a = T(); | ||
| o && o.parentNode ? o.parentNode.insertBefore(a, o.nextSibling) : e.appendChild(a), S(a); | ||
| const s = x(a); | ||
| return d(s), h(e, n), e.dispatchEvent(new Event("input", { bubbles: !0 })), !0; | ||
| }, B = () => { | ||
| m || typeof document == "undefined" || (m = !0, document.addEventListener("click", (e) => { | ||
| const n = e.target, t = n == null ? void 0 : n.closest(u); | ||
| t && (e.preventDefault(), e.stopPropagation(), L(t)); | ||
| }), document.addEventListener("keydown", (e) => { | ||
| const n = e.key; | ||
| if (!["Backspace", "Delete", "ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight"].includes(n)) | ||
| return; | ||
| const t = window.getSelection(); | ||
| if (!t || t.rangeCount === 0) return; | ||
| const r = t.getRangeAt(0), o = k(); | ||
| if (!o || !o.contains(r.commonAncestorContainer)) return; | ||
| const a = A(r); | ||
| if (a) { | ||
| if (n === "Backspace" || n === "Delete") { | ||
| e.preventDefault(), e.stopPropagation(), C(a, n); | ||
| return; | ||
| } | ||
| if (n === "ArrowRight" || n === "ArrowDown") { | ||
| e.preventDefault(); | ||
| const s = f(a.nextSibling, "next") || x(a); | ||
| d(s); | ||
| return; | ||
| } | ||
| if (n === "ArrowLeft" || n === "ArrowUp") { | ||
| e.preventDefault(); | ||
| const s = f(a.previousSibling, "previous"); | ||
| s ? b(s) : d(o); | ||
| return; | ||
| } | ||
| } | ||
| if (n === "Backspace" || n === "Delete") { | ||
| const s = R( | ||
| r, | ||
| o, | ||
| n | ||
| ); | ||
| if (!s) return; | ||
| e.preventDefault(), e.stopPropagation(), C(s, n); | ||
| } | ||
| })); | ||
| }, D = () => (w(), B(), { | ||
| name: "pageBreak", | ||
| toolbar: [ | ||
| { | ||
| label: "Page Break", | ||
| command: "insertPageBreak", | ||
| icon: '<svg fill="#000000" width="24px" height="24px" viewBox="0 0 14 14" xmlns="http://www.w3.org/2000/svg"><g id="SVGRepo_bgCarrier" stroke-width="0"></g><g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"></g><g id="SVGRepo_iconCarrier"><path d="M1,6 L3,6 C3.55228475,6 4,6.44771525 4,7 C4,7.55228475 3.55228475,8 3,8 L1,8 C0.44771525,8 0,7.55228475 0,7 C0,6.44771525 0.44771525,6 1,6 Z M11,6 L13,6 C13.5522847,6 14,6.44771525 14,7 C14,7.55228475 13.5522847,8 13,8 L11,8 C10.4477153,8 10,7.55228475 10,7 C10,6.44771525 10.4477153,6 11,6 Z M6,6 L8,6 C8.55228475,6 9,6.44771525 9,7 C9,7.55228475 8.55228475,8 8,8 L6,8 C5.44771525,8 5,7.55228475 5,7 C5,6.44771525 5.44771525,6 6,6 Z M0,1 C0,0.44771525 0.44771525,-2.26485497e-13 1,-2.26485497e-13 C1.55228475,-2.26485497e-13 2,0.44771525 2,1 L2,3.0142458 L12,3.0142458 L12,1 C12,0.44771525 12.4477153,-2.26485497e-13 13,-2.26485497e-13 C13.5522847,-2.26485497e-13 14,0.44771525 14,1 L14,3.0142458 C14,4.1188153 13.1045695,5.0142458 12,5.0142458 L2,5.0142458 C0.8954305,5.0142458 0,4.1188153 0,3.0142458 L0,1 Z M0,13.0142458 L0,11 C0,9.8954305 0.8954305,9 2,9 L12,9 C13.1045695,9 14,9.8954305 14,11 L14,13.0142458 C14,13.5665305 13.5522847,14.0142458 13,14.0142458 C12.4477153,14.0142458 12,13.5665305 12,13.0142458 L12,11 L2,11 L2,13.0142458 C2,13.5665305 1.55228475,14.0142458 1,14.0142458 C0.44771525,14.0142458 0,13.5665305 0,13.0142458 Z"></path></g></svg>', | ||
| shortcut: "Mod-Enter" | ||
| } | ||
| ], | ||
| commands: { | ||
| insertPageBreak: y | ||
| }, | ||
| keymap: { | ||
| "Mod-Enter": "insertPageBreak" | ||
| } | ||
| }); | ||
| export { | ||
| D as PageBreakPlugin | ||
| }; | ||
| //# sourceMappingURL=PageBreakPlugin.native-CXdX5fAv.mjs.map |
| let c = !1; | ||
| const g = () => { | ||
| if (typeof document == "undefined") return; | ||
| const r = "rte-preview-plugin-styles"; | ||
| if (document.getElementById(r)) return; | ||
| const t = document.createElement("style"); | ||
| t.id = r, t.textContent = ` | ||
| /* Preview Editor Dialog Styles */ | ||
| .rte-preview-editor-overlay { | ||
| position: fixed !important; | ||
| top: 0 !important; | ||
| left: 0 !important; | ||
| right: 0 !important; | ||
| bottom: 0 !important; | ||
| width: 100vw !important; | ||
| height: 100vh !important; | ||
| background-color: rgba(0, 0, 0, 0.6) !important; | ||
| display: flex !important; | ||
| align-items: center !important; | ||
| justify-content: center !important; | ||
| z-index: 10000 !important; | ||
| padding: 20px !important; | ||
| box-sizing: border-box !important; | ||
| margin: 0 !important; | ||
| } | ||
| .rte-preview-editor-modal { | ||
| background: white; | ||
| border-radius: 8px; | ||
| box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3); | ||
| width: 100%; | ||
| max-width: 1200px; | ||
| max-height: 90vh; | ||
| display: flex; | ||
| flex-direction: column; | ||
| overflow: hidden; | ||
| position: relative; | ||
| } | ||
| .rte-preview-editor-header { | ||
| display: flex; | ||
| align-items: center; | ||
| justify-content: space-between; | ||
| padding: 16px 20px; | ||
| border-bottom: 1px solid #e1e5e9; | ||
| background: #f8f9fa; | ||
| border-radius: 8px 8px 0 0; | ||
| } | ||
| .rte-preview-editor-header h2 { | ||
| margin: 0; | ||
| font-size: 18px; | ||
| font-weight: 600; | ||
| color: #1a1a1a; | ||
| } | ||
| .rte-preview-editor-header-actions { | ||
| display: flex; | ||
| gap: 8px; | ||
| } | ||
| .rte-preview-editor-close-btn { | ||
| background: none; | ||
| border: none; | ||
| cursor: pointer; | ||
| padding: 4px; | ||
| border-radius: 4px; | ||
| color: #666; | ||
| font-size: 16px; | ||
| line-height: 1; | ||
| transition: all 0.2s ease; | ||
| } | ||
| .rte-preview-editor-close-btn:hover { | ||
| background: #e1e5e9; | ||
| color: #1a1a1a; | ||
| } | ||
| .rte-preview-editor-body { | ||
| flex: 1; | ||
| overflow: auto; | ||
| display: flex; | ||
| flex-direction: column; | ||
| padding: 25px; | ||
| } | ||
| .rte-preview-editor-content { | ||
| flex: 1; | ||
| display: flex; | ||
| flex-direction: column; | ||
| } | ||
| .rte-preview-editor-light-editor { | ||
| flex: 1; | ||
| overflow: auto; | ||
| font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif; | ||
| font-size: 16px; | ||
| line-height: 1.6; | ||
| color: #1a1a1a; | ||
| padding: 20px; | ||
| background: #fafafa; | ||
| border: 1px solid #e1e5e9; | ||
| border-radius: 4px; | ||
| min-height: 400px; | ||
| } | ||
| .rte-preview-editor-light-editor h1, | ||
| .rte-preview-editor-light-editor h2, | ||
| .rte-preview-editor-light-editor h3, | ||
| .rte-preview-editor-light-editor h4, | ||
| .rte-preview-editor-light-editor h5, | ||
| .rte-preview-editor-light-editor h6 { | ||
| margin-top: 1.5em; | ||
| margin-bottom: 0.5em; | ||
| font-weight: 600; | ||
| } | ||
| .rte-preview-editor-light-editor h1 { | ||
| font-size: 2em; | ||
| } | ||
| .rte-preview-editor-light-editor h2 { | ||
| font-size: 1.5em; | ||
| } | ||
| .rte-preview-editor-light-editor h3 { | ||
| font-size: 1.25em; | ||
| } | ||
| .rte-preview-editor-light-editor p { | ||
| margin: 1em 0; | ||
| } | ||
| .rte-preview-editor-light-editor ul, | ||
| .rte-preview-editor-light-editor ol { | ||
| padding-left: 2em; | ||
| margin: 1em 0; | ||
| } | ||
| .rte-preview-editor-light-editor li { | ||
| margin: 0.5em 0; | ||
| } | ||
| .rte-preview-editor-light-editor table { | ||
| border-collapse: collapse; | ||
| width: 100%; | ||
| margin: 1em 0; | ||
| } | ||
| .rte-preview-editor-light-editor table td, | ||
| .rte-preview-editor-light-editor table th { | ||
| border: 1px solid #ddd; | ||
| padding: 0.5em; | ||
| } | ||
| .rte-preview-editor-light-editor table th { | ||
| background: #f5f5f5; | ||
| font-weight: 600; | ||
| } | ||
| .rte-preview-editor-light-editor blockquote { | ||
| border-left: 4px solid #ddd; | ||
| margin: 1em 0; | ||
| padding-left: 1em; | ||
| color: #666; | ||
| } | ||
| .rte-preview-editor-light-editor code { | ||
| background: #f5f5f5; | ||
| padding: 2px 6px; | ||
| border-radius: 3px; | ||
| font-family: 'Monaco', 'Menlo', 'Courier New', monospace; | ||
| font-size: 0.9em; | ||
| } | ||
| .rte-preview-editor-light-editor pre { | ||
| background: #f5f5f5; | ||
| padding: 1em; | ||
| border-radius: 4px; | ||
| overflow-x: auto; | ||
| margin: 1em 0; | ||
| } | ||
| .rte-preview-editor-light-editor pre code { | ||
| background: none; | ||
| padding: 0; | ||
| } | ||
| .rte-preview-editor-light-editor img { | ||
| max-width: 100%; | ||
| height: auto; | ||
| } | ||
| .rte-preview-editor-light-editor a { | ||
| color: #007acc; | ||
| text-decoration: underline; | ||
| } | ||
| .rte-preview-editor-light-editor a:hover { | ||
| color: #0056b3; | ||
| } | ||
| /* Responsive design */ | ||
| @media (max-width: 768px) { | ||
| .rte-preview-editor-overlay { | ||
| padding: 10px; | ||
| } | ||
| .rte-preview-editor-modal { | ||
| max-height: 95vh; | ||
| } | ||
| .rte-preview-editor-header { | ||
| padding: 12px 16px; | ||
| } | ||
| .rte-preview-editor-body { | ||
| padding: 16px; | ||
| } | ||
| .rte-preview-editor-light-editor { | ||
| padding: 12px; | ||
| font-size: 14px; | ||
| } | ||
| } | ||
| `, document.head.appendChild(t); | ||
| }, v = () => { | ||
| const r = window.getSelection(); | ||
| if (r && r.rangeCount > 0) { | ||
| let e = r.getRangeAt(0).startContainer; | ||
| for (; e && e !== document.body; ) { | ||
| if (e.nodeType === Node.ELEMENT_NODE) { | ||
| const o = e; | ||
| if (o.getAttribute("contenteditable") === "true") | ||
| return o; | ||
| } | ||
| e = e.parentNode; | ||
| } | ||
| } | ||
| const t = document.activeElement; | ||
| if (t) { | ||
| if (t.getAttribute("contenteditable") === "true") | ||
| return t; | ||
| const e = t.closest('[contenteditable="true"]'); | ||
| if (e) return e; | ||
| } | ||
| return document.querySelector('[contenteditable="true"]'); | ||
| }, h = () => { | ||
| const r = v(); | ||
| if (!r) return ""; | ||
| const t = r.cloneNode(!0); | ||
| return [ | ||
| ".rte-floating-toolbar", | ||
| ".rte-selection-marker", | ||
| ".rte-toolbar", | ||
| ".rte-resize-handle", | ||
| "[data-rte-internal]" | ||
| ].forEach((o) => { | ||
| t.querySelectorAll(o).forEach((i) => i.remove()); | ||
| }), t.innerHTML; | ||
| }, w = (r) => { | ||
| const t = document.createElement("div"); | ||
| return t.innerHTML = r, t.querySelectorAll( | ||
| 'script, iframe[src^="javascript:"], object, embed, form[action^="javascript:"]' | ||
| ).forEach((i) => i.remove()), t.querySelectorAll("*").forEach((i) => { | ||
| Array.from(i.attributes).forEach((n) => { | ||
| n.name.startsWith("on") && i.removeAttribute(n.name), (n.name === "href" || n.name === "src") && n.value.startsWith("javascript:") && i.removeAttribute(n.name); | ||
| }); | ||
| }), t.innerHTML; | ||
| }, u = () => { | ||
| if (typeof window == "undefined" || c) return; | ||
| c = !0, g(); | ||
| const r = h(), t = w(r), e = document.createElement("div"); | ||
| e.className = "rte-preview-editor-overlay", e.setAttribute("role", "dialog"), e.setAttribute("aria-modal", "true"), e.setAttribute("aria-labelledby", "preview-editor-title"); | ||
| const o = document.createElement("div"); | ||
| o.className = "rte-preview-editor-modal"; | ||
| const i = document.createElement("div"); | ||
| i.className = "rte-preview-editor-header", i.innerHTML = ` | ||
| <h2 id="preview-editor-title">Preview Editor</h2> | ||
| <div class="rte-preview-editor-header-actions"> | ||
| <button class="rte-preview-editor-close-btn" aria-label="Close preview editor"> | ||
| <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> | ||
| <line x1="18" y1="6" x2="6" y2="18" /> | ||
| <line x1="6" y1="6" x2="18" y2="18" /> | ||
| </svg> | ||
| </button> | ||
| </div> | ||
| `; | ||
| const n = document.createElement("div"); | ||
| n.className = "rte-preview-editor-body"; | ||
| const a = document.createElement("div"); | ||
| a.className = "rte-preview-editor-content"; | ||
| const l = document.createElement("div"); | ||
| l.className = "rte-preview-editor-light-editor", l.innerHTML = t, a.appendChild(l), n.appendChild(a), o.appendChild(i), o.appendChild(n), e.appendChild(o); | ||
| const p = () => { | ||
| e.parentNode && e.parentNode.removeChild(e), c = !1, document.removeEventListener("keydown", s); | ||
| }, s = (d) => { | ||
| d.key === "Escape" && (d.preventDefault(), d.stopPropagation(), p()); | ||
| }, m = i.querySelector(".rte-preview-editor-close-btn"); | ||
| m && m.addEventListener("click", (d) => { | ||
| d.preventDefault(), d.stopPropagation(), p(); | ||
| }), e.addEventListener("click", (d) => { | ||
| d.target === e && p(); | ||
| }), document.addEventListener("keydown", s), document.body.appendChild(e); | ||
| }, f = () => ({ | ||
| name: "preview", | ||
| toolbar: [ | ||
| { | ||
| label: "Preview", | ||
| command: "togglePreview", | ||
| icon: '<svg fill="#000000" version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24px" height="24px" viewBox="0 0 92 92" enable-background="new 0 0 92 92" xml:space="preserve"><g id="SVGRepo_bgCarrier" stroke-width="0"></g><g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"></g><g id="SVGRepo_iconCarrier"> <path id="XMLID_1239_" d="M91.3,43.8C90.6,42.8,74.4,19,46,19C17.6,19,1.4,42.8,0.7,43.8c-0.9,1.3-0.9,3.1,0,4.5 C1.4,49.2,17.6,73,46,73c28.4,0,44.6-23.8,45.3-24.8C92.2,46.9,92.2,45.1,91.3,43.8z M46,65C26.7,65,13.5,51.4,9,46 c4.5-5.5,17.6-19,37-19c19.3,0,32.5,13.6,37,19C78.4,51.5,65.3,65,46,65z M48.3,29.6c-4.4-0.6-8.7,0.5-12.3,3.2c0,0,0,0,0,0 c-7.3,5.5-8.8,15.9-3.3,23.2c2.7,3.6,6.5,5.8,10.9,6.5c0.8,0.1,1.6,0.2,2.3,0.2c3.6,0,7-1.2,9.9-3.3c7.3-5.5,8.8-15.9,3.3-23.2 C56.6,32.5,52.7,30.2,48.3,29.6z M52.3,54.5c-2.2,1.7-5,2.4-7.8,2c-2.8-0.4-5.3-1.9-7-4.1C34.1,47.7,35,41,39.7,37.5 c2.2-1.7,5-2.4,7.8-2c2.8,0.4,5.3,1.9,7,4.1C57.9,44.3,57,51,52.3,54.5z M51.9,40c0.8,0.7,1.2,1.8,1.2,2.8c0,1-0.4,2.1-1.2,2.8 c-0.7,0.7-1.8,1.2-2.8,1.2c-1.1,0-2.1-0.4-2.8-1.2c-0.8-0.8-1.2-1.8-1.2-2.8c0-1.1,0.4-2.1,1.2-2.8c0.7-0.8,1.8-1.2,2.8-1.2 C50.2,38.9,51.2,39.3,51.9,40z"></path> </g></svg>' | ||
| } | ||
| ], | ||
| commands: { | ||
| togglePreview: () => (u(), !0) | ||
| }, | ||
| keymap: {} | ||
| }); | ||
| export { | ||
| f as PreviewPlugin | ||
| }; | ||
| //# sourceMappingURL=PreviewPlugin.native-DBvfpmIv.mjs.map |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
Found 7 instances in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
Found 2 instances in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
6898189
18.05%83
22.06%109396
24.94%33
57.14%79
16.18%36
2.86%