teem-editor 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,186 @@
1
+ # TeemEditor
2
+
3
+ **Simple. Efficient. Fast.** A lightweight WYSIWYG editor for **React** and **Next.js**, with first-class **RTL** support for Persian and Arabic, plus English and other **LTR** languages.
4
+
5
+ ![TeemEditor screenshot](docs/teem-editor.jpg)
6
+
7
+ ## Why TeemEditor
8
+
9
+ - **Simple** — one component, clear API, no heavy schema or plugin maze
10
+ - **Efficient** — small surface area, focused features, easy to drop into any app
11
+ - **Performant** — lean client-side editor built for real product UIs
12
+ - **React & Next.js ready** — works in client components; easy dynamic import for App Router
13
+ - **RTL / LTR** — full bidirectional UI and content direction (`fa`, `ar`, `en`, and more)
14
+
15
+ ## Features
16
+
17
+ - Headings (`h1`–`h6`), paragraphs, and preformatted text
18
+ - Bullet and numbered lists
19
+ - Bold, italic, strikethrough
20
+ - Blockquote
21
+ - Left / center / right alignment
22
+ - Indent / outdent (without accidental blockquotes)
23
+ - Link and image insert (secure upload or URL)
24
+ - Horizontal rule
25
+ - Text color and highlight
26
+ - Undo / redo
27
+ - Visual ↔ HTML source toggle
28
+ - i18n UI: `en` (default), `fa`, `ar`
29
+
30
+ ## Install
31
+
32
+ ```bash
33
+ npm install teem-editor dompurify
34
+ ```
35
+
36
+ `react` and `react-dom` must already be in your project.
37
+
38
+ Optional font for Persian/Arabic UI: [Vazirmatn](https://fonts.google.com/specimen/Vazirmatn)
39
+
40
+ ```html
41
+ <link href="https://fonts.googleapis.com/css2?family=Vazirmatn:wght@400;600;700&display=swap" rel="stylesheet" />
42
+ ```
43
+
44
+ ## Usage (React)
45
+
46
+ ```jsx
47
+ import { useState } from 'react';
48
+ import { TeemEditor } from 'teem-editor';
49
+ import 'teem-editor/styles.css';
50
+
51
+ export default function MyPage() {
52
+ const [html, setHtml] = useState('<p><br></p>');
53
+
54
+ return (
55
+ <TeemEditor
56
+ value={html}
57
+ onChange={setHtml}
58
+ language="en"
59
+ onUpload={async (file) => {
60
+ const form = new FormData();
61
+ form.append('file', file);
62
+ const res = await fetch('/api/upload', { method: 'POST', body: form });
63
+ const data = await res.json();
64
+ return data.url;
65
+ }}
66
+ />
67
+ );
68
+ }
69
+ ```
70
+
71
+ ### Persian / Arabic (RTL)
72
+
73
+ ```jsx
74
+ <TeemEditor language="fa" value={html} onChange={setHtml} />
75
+ <TeemEditor language="ar" value={html} onChange={setHtml} />
76
+ ```
77
+
78
+ `dir` defaults to `ltr` for English and `rtl` for `fa` / `ar`. Override anytime with the `dir` prop.
79
+
80
+ ## Next.js (App Router)
81
+
82
+ Client Component:
83
+
84
+ ```jsx
85
+ 'use client';
86
+
87
+ import { useState } from 'react';
88
+ import { TeemEditor } from 'teem-editor';
89
+ import 'teem-editor/styles.css';
90
+
91
+ export default function RichEditor() {
92
+ const [html, setHtml] = useState('<p>Hello world</p>');
93
+ return (
94
+ <TeemEditor
95
+ language="en"
96
+ value={html}
97
+ onChange={setHtml}
98
+ onUpload={uploadToServer}
99
+ />
100
+ );
101
+ }
102
+ ```
103
+
104
+ Or load from a Server Component:
105
+
106
+ ```jsx
107
+ import dynamic from 'next/dynamic';
108
+
109
+ const TeemEditor = dynamic(
110
+ () => import('teem-editor').then((m) => m.TeemEditor),
111
+ { ssr: false }
112
+ );
113
+ ```
114
+
115
+ ## Image upload security
116
+
117
+ Before upload, TeemEditor checks:
118
+
119
+ 1. Allowed extensions: `.jpg` `.jpeg` `.png` `.gif` `.webp`
120
+ 2. Allowed MIME types
121
+ 3. Real **magic bytes** (anti-spoof)
122
+ 4. Max size (default 2 MB)
123
+ 5. Filename sanitization
124
+ 6. HTML sanitization with DOMPurify (strips `script`, event handlers, `javascript:` URLs)
125
+
126
+ ### Production tip
127
+
128
+ Prefer `onUpload` and re-validate on your server. Without `onUpload`, images are embedded as **base64 data URLs** (works offline, larger HTML).
129
+
130
+ ```js
131
+ uploadOptions={{
132
+ maxSizeBytes: 2 * 1024 * 1024,
133
+ allowedMimeTypes: ['image/jpeg', 'image/png', 'image/webp', 'image/gif'],
134
+ }}
135
+ ```
136
+
137
+ ## Props
138
+
139
+ | Prop | Type | Description |
140
+ |------|------|-------------|
141
+ | `value` | `string` | Controlled HTML |
142
+ | `defaultValue` | `string` | Initial HTML (uncontrolled) |
143
+ | `onChange` | `(html) => void` | Sanitized HTML callback |
144
+ | `language` | `'en' \| 'fa' \| 'ar'` | UI language (default: `en`) |
145
+ | `placeholder` | `string` | Placeholder text |
146
+ | `dir` | `'rtl' \| 'ltr'` | Content direction (defaults from language) |
147
+ | `minHeight` | `number` | Minimum editor height |
148
+ | `disabled` | `boolean` | Disable editing |
149
+ | `onUpload` | `(file, meta) => Promise<string>` | Image upload → URL |
150
+ | `uploadOptions` | `object` | Upload validation options |
151
+ | `toolbar` | `boolean` | Show toolbar |
152
+ | `className` / `style` | — | Root container styling |
153
+
154
+ ## Ref API
155
+
156
+ ```jsx
157
+ const ref = useRef(null);
158
+
159
+ ref.current.focus();
160
+ ref.current.getHTML();
161
+ ref.current.setHTML('<p>Hello</p>');
162
+ ref.current.clear();
163
+ ```
164
+
165
+ ## Helpers
166
+
167
+ ```js
168
+ import {
169
+ sanitizeHtml,
170
+ validateImageFile,
171
+ processImageUpload,
172
+ getMessages,
173
+ } from 'teem-editor';
174
+ ```
175
+
176
+ ## Local development
177
+
178
+ ```bash
179
+ npm install
180
+ npm run dev # Vite demo
181
+ npm run build # Build dist for npm
182
+ ```
183
+
184
+ ## License
185
+
186
+ MIT
@@ -0,0 +1,85 @@
1
+ import type { CSSProperties, ReactNode } from 'react';
2
+
3
+ export type UploadMeta = {
4
+ mime: string;
5
+ safeName: string;
6
+ };
7
+
8
+ export type UploadOptions = {
9
+ maxSizeBytes?: number;
10
+ allowedMimeTypes?: string[];
11
+ allowedExtensions?: string[];
12
+ onUpload?: (file: File | Blob, meta: UploadMeta) => Promise<string>;
13
+ };
14
+
15
+ export type TeemEditorProps = {
16
+ value?: string;
17
+ defaultValue?: string;
18
+ onChange?: (html: string) => void;
19
+ placeholder?: string;
20
+ /** UI language. Default: `en`. Also supports `fa` and `ar`. */
21
+ language?: 'en' | 'fa' | 'ar' | string;
22
+ dir?: 'rtl' | 'ltr';
23
+ className?: string;
24
+ style?: CSSProperties;
25
+ minHeight?: number;
26
+ disabled?: boolean;
27
+ onUpload?: (file: File | Blob, meta: UploadMeta) => Promise<string>;
28
+ uploadOptions?: Omit<UploadOptions, 'onUpload'>;
29
+ toolbar?: boolean;
30
+ children?: ReactNode;
31
+ };
32
+
33
+ export type TeemEditorHandle = {
34
+ focus: () => void;
35
+ getHTML: () => string;
36
+ setHTML: (html: string) => void;
37
+ clear: () => void;
38
+ getEditorElement: () => HTMLDivElement | null;
39
+ };
40
+
41
+ export declare const TeemEditor: React.ForwardRefExoticComponent<
42
+ TeemEditorProps & React.RefAttributes<TeemEditorHandle>
43
+ >;
44
+
45
+ export declare function sanitizeHtml(dirty: string): string;
46
+ export declare function flattenStyleSpans(root: ParentNode): void;
47
+ export declare function isSafeHref(url: string): boolean;
48
+ export declare function isSafeImageSrc(url: string): boolean;
49
+
50
+ export declare function validateImageFile(
51
+ file: File | Blob,
52
+ options?: UploadOptions
53
+ ): Promise<{
54
+ ok: boolean;
55
+ errors: string[];
56
+ mime?: string;
57
+ safeName?: string;
58
+ }>;
59
+
60
+ export declare function processImageUpload(
61
+ file: File | Blob,
62
+ options?: UploadOptions
63
+ ): Promise<string>;
64
+
65
+ export declare const uploadDefaults: {
66
+ maxSizeBytes: number;
67
+ allowedMimeTypes: string[];
68
+ allowedExtensions: string[];
69
+ };
70
+
71
+ export declare function createHistory(limit?: number): {
72
+ push: (html: string) => void;
73
+ undo: () => string | null;
74
+ redo: () => string | null;
75
+ canUndo: () => boolean;
76
+ canRedo: () => boolean;
77
+ current: () => string | null;
78
+ reset: (html?: string) => void;
79
+ };
80
+
81
+ export declare function getMessages(language?: string): Record<string, any>;
82
+ export declare function getDefaultDir(language?: string): 'rtl' | 'ltr';
83
+ export declare function resolveLanguage(language?: string): 'en' | 'fa' | 'ar';
84
+
85
+ export default TeemEditor;
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const l=require("react/jsx-runtime"),u=require("react"),mt=require("dompurify"),b={fill:"none",stroke:"currentColor",strokeWidth:1.8,strokeLinecap:"round",strokeLinejoin:"round"};function j({children:e,size:t=18}){return l.jsx("svg",{width:t,height:t,viewBox:"0 0 24 24","aria-hidden":"true",focusable:"false",children:e})}const v={undo:l.jsxs(j,{children:[l.jsx("path",{...b,d:"M9 14L4 9l5-5"}),l.jsx("path",{...b,d:"M4 9h10a6 6 0 010 12h-3"})]}),redo:l.jsxs(j,{children:[l.jsx("path",{...b,d:"M15 14l5-5-5-5"}),l.jsx("path",{...b,d:"M20 9H10a6 6 0 000 12h3"})]}),bold:l.jsxs(j,{children:[l.jsx("path",{fill:"none",stroke:"currentColor",strokeWidth:2.8,strokeLinecap:"round",strokeLinejoin:"round",d:"M7 5h6a3.5 3.5 0 010 7H7z"}),l.jsx("path",{fill:"none",stroke:"currentColor",strokeWidth:2.8,strokeLinecap:"round",strokeLinejoin:"round",d:"M7 12h7a3.5 3.5 0 010 7H7z"})]}),italic:l.jsxs(j,{children:[l.jsx("path",{...b,d:"M10 5h8"}),l.jsx("path",{...b,d:"M6 19h8"}),l.jsx("path",{...b,d:"M14 5l-4 14"})]}),strike:l.jsxs(j,{children:[l.jsx("path",{...b,d:"M5 12h14"}),l.jsx("path",{...b,d:"M16 7.5A4 4 0 0012 6c-2.8 0-4.5 1.5-4.5 3.2 0 3.3 7.5 1.7 7.5 5.1A3.4 3.4 0 0112 18c-2.2 0-4-1-4.8-2.4"})]}),ul:l.jsxs(j,{children:[l.jsx("path",{...b,d:"M9 6h11M9 12h11M9 18h11"}),l.jsx("circle",{cx:"5",cy:"6",r:"1.2",fill:"currentColor"}),l.jsx("circle",{cx:"5",cy:"12",r:"1.2",fill:"currentColor"}),l.jsx("circle",{cx:"5",cy:"18",r:"1.2",fill:"currentColor"})]}),ol:l.jsxs(j,{children:[l.jsx("path",{...b,d:"M11 6h9M11 12h9M11 18h9"}),l.jsxs("g",{fill:"currentColor",stroke:"none",fontSize:"8",fontWeight:"700",fontFamily:"system-ui, -apple-system, sans-serif",children:[l.jsx("text",{x:"3.5",y:"8",children:"1"}),l.jsx("text",{x:"3.5",y:"14.2",children:"2"}),l.jsx("text",{x:"3.5",y:"20.4",children:"3"})]})]}),quote:l.jsx(j,{children:l.jsx("path",{fill:"currentColor",stroke:"none",d:"M6 17h3l2-4V7H5v6h3zm8 0h3l2-4V7h-6v6h3z"})}),alignRight:l.jsx(j,{children:l.jsx("path",{...b,d:"M4 6h16M8 12h12M4 18h16"})}),alignCenter:l.jsx(j,{children:l.jsx("path",{...b,d:"M4 6h16M7 12h10M4 18h16"})}),alignLeft:l.jsx(j,{children:l.jsx("path",{...b,d:"M4 6h16M4 12h12M4 18h16"})}),link:l.jsxs(j,{children:[l.jsx("path",{...b,d:"M10 13a5 5 0 007.07 0l1.41-1.41a5 5 0 00-7.07-7.07L10 5.93"}),l.jsx("path",{...b,d:"M14 11a5 5 0 00-7.07 0L5.52 12.4a5 5 0 007.07 7.07L14 18.07"})]}),image:l.jsxs(j,{children:[l.jsx("rect",{...b,x:"3",y:"5",width:"18",height:"14",rx:"2"}),l.jsx("circle",{cx:"9",cy:"10",r:"1.5",fill:"currentColor"}),l.jsx("path",{...b,d:"M3 16l5-4 4 3 3-2 6 3"})]}),rtl:l.jsxs(j,{children:[l.jsx("path",{fill:"currentColor",stroke:"none",d:"M9 10v5h2V4h2v11h2V4h2V2H9C6.79 2 5 3.79 5 6s1.79 4 4 4z"}),l.jsx("path",{fill:"currentColor",stroke:"none",d:"M3 18l4-4v3H19v2H7v3l-4-4z"})]}),ltr:l.jsxs(j,{children:[l.jsx("g",{transform:"translate(24 0) scale(-1 1)",children:l.jsx("path",{fill:"currentColor",stroke:"none",d:"M9 10v5h2V4h2v11h2V4h2V2H9C6.79 2 5 3.79 5 6s1.79 4 4 4z"})}),l.jsx("path",{fill:"currentColor",stroke:"none",d:"M21 18l-4-4v3H5v2h12v3l4-4z"})]}),hr:l.jsx(j,{children:l.jsx("path",{...b,d:"M4 12h16"})}),indent:l.jsxs(j,{children:[l.jsx("path",{...b,d:"M4 6h16M12 12h8M4 18h16"}),l.jsx("path",{...b,d:"M4 9l4 3-4 3"})]}),outdent:l.jsxs(j,{children:[l.jsx("path",{...b,d:"M4 6h16M12 12h8M4 18h16"}),l.jsx("path",{...b,d:"M8 9L4 12l4 3"})]}),textColor:l.jsxs(j,{children:[l.jsx("path",{...b,d:"M6 16l3.5-9h1L14 16"}),l.jsx("path",{...b,d:"M7.5 13h5"})]}),bgColor:l.jsxs(j,{children:[l.jsx("path",{...b,d:"M8 4l8 8-4 4-8-8z"}),l.jsx("path",{...b,d:"M5 19h10"})]}),chevronDown:l.jsx(j,{size:12,children:l.jsx("path",{...b,d:"M6 9l6 6 6-6"})}),code:l.jsxs(j,{children:[l.jsx("path",{...b,d:"M8 8L4 12l4 4"}),l.jsx("path",{...b,d:"M16 8l4 4-4 4"}),l.jsx("path",{...b,d:"M14 5l-4 14"})]}),close:l.jsx(j,{size:16,children:l.jsx("path",{...b,d:"M6 6l12 12M18 6L6 18"})})},ht={placeholder:"Write something…",toolbar:"TeemEditor toolbar",undo:"Undo",redo:"Redo",blockType:"Block type",paragraph:"Paragraph",heading1:"Heading 1",heading2:"Heading 2",heading3:"Heading 3",heading4:"Heading 4",heading5:"Heading 5",heading6:"Heading 6",quote:"Quote",preformatted:"Preformatted",bold:"Bold",italic:"Italic",strike:"Strikethrough",bulletList:"Bullet list",numberedList:"Numbered list",alignRight:"Align right",alignCenter:"Align center",alignLeft:"Align left",alignImageRight:"Align image right",alignImageCenter:"Align image center",alignImageLeft:"Align image left",rtl:"Right to left",ltr:"Left to right",indent:"Indent",outdent:"Outdent",insertLink:"Insert link",insertImage:"Insert image",horizontalRule:"Horizontal rule",textColor:"Text color",bgColor:"Highlight color",applyCurrentColor:"Apply current color",openPalette:"Open color palette",noColor:"No color",customColor:"Custom color",pickCustomColor:"Pick custom color",sourceMode:"Edit HTML",visualMode:"Back to visual editor",editorLabel:"Rich text editor",sourceLabel:"HTML source editor",close:"Close",cancel:"Cancel",save:"Save",linkTitle:"Insert link",linkUrl:"URL",linkText:"Display text (optional)",linkTextPlaceholder:"Link text",linkSubmit:"Insert link",linkUrlRequired:"Please enter a link URL.",linkInvalid:"Invalid link.",linkUnsafe:"The link URL is invalid or unsafe.",imageTitle:"Insert image",imageSubmit:"Insert image",imageBusy:"Processing…",imageUploadTab:"Upload file",imageUrlTab:"From URL",imageFile:"Image file",imageUrl:"Image URL",imageAlt:"Alt text",imageAltPlaceholder:"Short image description",imageHint:"Only jpg, png, gif, and webp — max 2 MB",imagePickFile:"Please select an image file.",imageInsertFailed:"Failed to insert image.",imageUploadFailed:"Image upload failed.",imageUnsafe:"The image URL is invalid or unsafe.",altTitle:"Edit image alt text",altLabel:"Alt text",altPlaceholder:"Short description for accessibility and SEO",altHint:"Shown when the image cannot load, and used by screen readers.",editAlt:"Edit Alt",editAltTitle:"Edit image alt text",fileInvalid:"Invalid file.",fileEmpty:"File is empty.",fileTooLarge:e=>`File size must not exceed ${e} MB.`,fileBadExtension:"File extension is not allowed. Only jpg, png, gif, and webp.",fileBadMime:"File type is not allowed.",fileBadContent:"File content is not a valid image.",fileMimeMismatch:"Declared file type does not match actual content.",fileReadError:"Failed to read the file."},pt={placeholder:"متن خود را بنویسید…",toolbar:"نوار ابزار ویرایشگر",undo:"قبل (واگرد)",redo:"بعد (بازگردانی)",blockType:"نوع بلوک",paragraph:"پاراگراف",heading1:"عنوان ۱",heading2:"عنوان ۲",heading3:"عنوان ۳",heading4:"عنوان ۴",heading5:"عنوان ۵",heading6:"عنوان ۶",quote:"نقل‌قول",preformatted:"پیش‌قالب‌بندی‌شده",bold:"ضخیم",italic:"کج",strike:"خط‌خورده",bulletList:"فهرست نقطه‌ای",numberedList:"فهرست عددی",alignRight:"راست‌چین",alignCenter:"وسط‌چین",alignLeft:"چپ‌چین",alignImageRight:"تراز راست تصویر",alignImageCenter:"تراز وسط تصویر",alignImageLeft:"تراز چپ تصویر",rtl:"راست به چپ",ltr:"چپ به راست",indent:"فرورفتگی",outdent:"بیرون‌آمدگی",insertLink:"درج لینک",insertImage:"درج تصویر",horizontalRule:"خط افقی",textColor:"رنگ متن",bgColor:"رنگ پس‌زمینه",applyCurrentColor:"اعمال رنگ فعلی",openPalette:"باز کردن پالت رنگ",noColor:"بدون رنگ",customColor:"رنگ دلخواه",pickCustomColor:"انتخاب رنگ دلخواه",sourceMode:"ویرایش HTML",visualMode:"بازگشت به حالت دیداری",editorLabel:"ویرایشگر متن",sourceLabel:"ویرایشگر کد HTML",close:"بستن",cancel:"انصراف",save:"ذخیره",linkTitle:"درج لینک",linkUrl:"آدرس",linkText:"متن نمایشی (اختیاری)",linkTextPlaceholder:"متن لینک",linkSubmit:"درج لینک",linkUrlRequired:"آدرس لینک را وارد کنید.",linkInvalid:"لینک نامعتبر است.",linkUnsafe:"آدرس لینک نامعتبر یا ناامن است.",imageTitle:"درج تصویر",imageSubmit:"درج تصویر",imageBusy:"در حال پردازش…",imageUploadTab:"آپلود فایل",imageUrlTab:"از آدرس",imageFile:"فایل تصویر",imageUrl:"آدرس تصویر",imageAlt:"متن جایگزین",imageAltPlaceholder:"توضیح کوتاه تصویر",imageHint:"فقط jpg، png، gif و webp — حداکثر ۲ مگابایت",imagePickFile:"یک فایل تصویر انتخاب کنید.",imageInsertFailed:"درج تصویر ناموفق بود.",imageUploadFailed:"آپلود تصویر ناموفق بود.",imageUnsafe:"آدرس تصویر نامعتبر یا ناامن است.",altTitle:"ویرایش متن جایگزین تصویر",altLabel:"متن جایگزین (Alt)",altPlaceholder:"توضیح کوتاه تصویر برای دسترس‌پذیری و SEO",altHint:"این متن وقتی تصویر لود نشود نمایش داده می‌شود و برای خواننده‌های صفحه مهم است.",editAlt:"ویرایش Alt",editAltTitle:"ویرایش متن جایگزین تصویر",fileInvalid:"فایل نامعتبر است.",fileEmpty:"فایل خالی است.",fileTooLarge:e=>`حجم فایل نباید بیشتر از ${e} مگابایت باشد.`,fileBadExtension:"پسوند فایل مجاز نیست. فقط jpg، png، gif و webp.",fileBadMime:"نوع فایل مجاز نیست.",fileBadContent:"محتوای فایل تصویر معتبر نیست.",fileMimeMismatch:"نوع اعلام‌شده فایل با محتوای واقعی هم‌خوانی ندارد.",fileReadError:"خواندن فایل با خطا مواجه شد."},bt={placeholder:"اكتب شيئاً…",toolbar:"شريط أدوات المحرر",undo:"تراجع",redo:"إعادة",blockType:"نوع الكتلة",paragraph:"فقرة",heading1:"عنوان 1",heading2:"عنوان 2",heading3:"عنوان 3",heading4:"عنوان 4",heading5:"عنوان 5",heading6:"عنوان 6",quote:"اقتباس",preformatted:"نص منسق مسبقاً",bold:"عريض",italic:"مائل",strike:"يتوسطه خط",bulletList:"قائمة نقطية",numberedList:"قائمة مرقمة",alignRight:"محاذاة لليمين",alignCenter:"محاذاة للوسط",alignLeft:"محاذاة لليسار",alignImageRight:"محاذاة الصورة لليمين",alignImageCenter:"محاذاة الصورة للوسط",alignImageLeft:"محاذاة الصورة لليسار",rtl:"من اليمين إلى اليسار",ltr:"من اليسار إلى اليمين",indent:"زيادة المسافة البادئة",outdent:"إنقاص المسافة البادئة",insertLink:"إدراج رابط",insertImage:"إدراج صورة",horizontalRule:"خط أفقي",textColor:"لون النص",bgColor:"لون التمييز",applyCurrentColor:"تطبيق اللون الحالي",openPalette:"فتح لوحة الألوان",noColor:"بدون لون",customColor:"لون مخصص",pickCustomColor:"اختيار لون مخصص",sourceMode:"تحرير HTML",visualMode:"العودة إلى المحرر المرئي",editorLabel:"محرر النص",sourceLabel:"محرر مصدر HTML",close:"إغلاق",cancel:"إلغاء",save:"حفظ",linkTitle:"إدراج رابط",linkUrl:"العنوان",linkText:"نص العرض (اختياري)",linkTextPlaceholder:"نص الرابط",linkSubmit:"إدراج الرابط",linkUrlRequired:"يرجى إدخال عنوان الرابط.",linkInvalid:"رابط غير صالح.",linkUnsafe:"عنوان الرابط غير صالح أو غير آمن.",imageTitle:"إدراج صورة",imageSubmit:"إدراج الصورة",imageBusy:"جارٍ المعالجة…",imageUploadTab:"رفع ملف",imageUrlTab:"من رابط",imageFile:"ملف الصورة",imageUrl:"رابط الصورة",imageAlt:"النص البديل",imageAltPlaceholder:"وصف قصير للصورة",imageHint:"فقط jpg و png و gif و webp — بحد أقصى 2 ميجابايت",imagePickFile:"يرجى اختيار ملف صورة.",imageInsertFailed:"فشل إدراج الصورة.",imageUploadFailed:"فشل رفع الصورة.",imageUnsafe:"رابط الصورة غير صالح أو غير آمن.",altTitle:"تحرير النص البديل للصورة",altLabel:"النص البديل (Alt)",altPlaceholder:"وصف قصير لإمكانية الوصول و SEO",altHint:"يظهر عندما يتعذر تحميل الصورة، ويستخدمه قارئات الشاشة.",editAlt:"تحرير Alt",editAltTitle:"تحرير النص البديل للصورة",fileInvalid:"ملف غير صالح.",fileEmpty:"الملف فارغ.",fileTooLarge:e=>`يجب ألا يتجاوز حجم الملف ${e} ميجابايت.`,fileBadExtension:"امتداد الملف غير مسموح. فقط jpg و png و gif و webp.",fileBadMime:"نوع الملف غير مسموح.",fileBadContent:"محتوى الملف ليس صورة صالحة.",fileMimeMismatch:"نوع الملف المعلن لا يطابق المحتوى الفعلي.",fileReadError:"فشل قراءة الملف."},be={en:ht,fa:pt,ar:bt},xt=new Set(["fa","ar"]);function oe(e="en"){const t=String(e||"en").toLowerCase();return be[t]?t:"en"}function xe(e="en"){return be[oe(e)]}function Ie(e="en"){return xt.has(oe(e))?"rtl":"ltr"}function _e(e){return[{value:"p",label:e.paragraph},{value:"h1",label:e.heading1},{value:"h2",label:e.heading2},{value:"h3",label:e.heading3},{value:"h4",label:e.heading4},{value:"h5",label:e.heading5},{value:"h6",label:e.heading6},{value:"blockquote",label:e.quote},{value:"pre",label:e.preformatted}]}const yt=["#111827","#dc2626","#ea580c","#ca8a04","#16a34a","#2563eb","#7c3aed","#db2777","#ffffff"],kt=["transparent","#fef08a","#bbf7d0","#bfdbfe","#fecaca","#e9d5ff","#fed7aa","#e5e7eb","#111827"];function S({label:e,active:t,disabled:n,onClick:r,children:a,className:i=""}){return l.jsx("button",{type:"button",className:`te-tool${t?" is-active":""}${i?` ${i}`:""}`,title:e,"aria-label":e,"aria-pressed":!!t,disabled:n,onMouseDown:o=>{o.preventDefault(),r==null||r(o)},children:a})}function z(){return l.jsx("span",{className:"te-toolbar__divider","aria-hidden":"true"})}function Se({label:e,icon:t,colors:n,value:r,onChange:a,onRememberSelection:i,allowTransparent:o=!1,disabled:c=!1,t:f}){const[k,h]=u.useState(!1),[w,T]=u.useState(null),E=u.useRef(null),A=u.useRef(!1),C=w??r,N=!C||C==="transparent"?o?"repeating-conic-gradient(#ddd 0% 25%, #fff 0% 50%) 50% / 6px 6px":"#111827":C;u.useEffect(()=>{if(!k||c){T(null),c&&h(!1);return}const m=R=>{var F;A.current||(F=E.current)!=null&&F.contains(R.target)||h(!1)},p=R=>{R.key==="Escape"&&!A.current&&h(!1)},d=()=>{window.setTimeout(()=>{A.current=!1},50)};return document.addEventListener("mousedown",m),document.addEventListener("keydown",p),window.addEventListener("focus",d),()=>{document.removeEventListener("mousedown",m),document.removeEventListener("keydown",p),window.removeEventListener("focus",d)}},[k,c]);const y=(m,{close:p=!0}={})=>{c||(i==null||i(),a(m),T(null),p&&h(!1))};return l.jsxs("div",{className:`te-color${k?" is-open":""}${c?" is-disabled":""}`,ref:E,children:[l.jsxs("div",{className:"te-color__split",children:[l.jsxs("button",{type:"button",className:"te-tool te-color__apply",title:`${e} — ${f.applyCurrentColor}`,"aria-label":`${e} — ${f.applyCurrentColor}`,disabled:c,onMouseDown:m=>{m.preventDefault(),!c&&(i==null||i(),a(r))},children:[l.jsx("span",{className:"te-color__icon",children:t}),l.jsx("span",{className:"te-color__bar",style:{background:N},"aria-hidden":"true"})]}),l.jsx("button",{type:"button",className:`te-tool te-color__caret${k?" is-active":""}`,title:`${f.openPalette}: ${e}`,"aria-label":`${f.openPalette}: ${e}`,"aria-expanded":k,"aria-haspopup":"true",disabled:c,onMouseDown:m=>{m.preventDefault(),!c&&(i==null||i(),h(p=>!p))},children:v.chevronDown})]}),k&&!c?l.jsxs("div",{className:"te-color__swatches",role:"group","aria-label":e,onMouseDown:m=>m.stopPropagation(),children:[n.map(m=>l.jsx("button",{type:"button",className:`te-swatch${r===m?" is-selected":""}`,style:{background:m==="transparent"?"repeating-conic-gradient(#ddd 0% 25%, #fff 0% 50%) 50% / 8px 8px":m,borderColor:m==="#ffffff"?"#d1d5db":void 0},title:m==="transparent"?f.noColor:m,"aria-label":m==="transparent"?f.noColor:m,onMouseDown:p=>{p.preventDefault(),p.stopPropagation(),y(m)}},m)),l.jsx("label",{className:"te-swatch te-swatch--picker",title:f.customColor,onMouseDown:m=>{m.stopPropagation(),A.current=!0,i==null||i()},children:l.jsx("input",{type:"color",value:C&&C!=="transparent"?C:"#111827",onMouseDown:m=>{m.stopPropagation(),A.current=!0},onClick:m=>{m.stopPropagation(),A.current=!0},onInput:m=>{T(m.target.value)},onChange:m=>{y(m.target.value,{close:!1}),A.current=!1},onBlur:()=>{window.setTimeout(()=>{A.current=!1,T(null)},50)},"aria-label":`${f.pickCustomColor}: ${e}`})})]}):null]})}function jt({t:e,states:t,canUndo:n,canRedo:r,onCommand:a,onBlockChange:i,onOpenLink:o,onOpenImage:c,onUndo:f,onRedo:k,onRememberSelection:h,sourceMode:w=!1,onToggleSource:T}){const[E,A]=u.useState("#111827"),[C,N]=u.useState("#fef08a"),y=w,m=_e(e);return l.jsxs("div",{className:"te-toolbar",role:"toolbar","aria-label":e.toolbar,children:[l.jsxs("div",{className:"te-toolbar__group",children:[l.jsx(S,{label:e.undo,disabled:y||!n,onClick:f,children:v.undo}),l.jsx(S,{label:e.redo,disabled:y||!r,onClick:k,children:v.redo})]}),l.jsx(z,{}),l.jsx("div",{className:"te-toolbar__group",children:l.jsxs("label",{className:"te-select-wrap",children:[l.jsx("span",{className:"te-sr-only",children:e.blockType}),l.jsx("select",{className:"te-select",value:t.format||"p",disabled:y,onChange:p=>i(p.target.value),onMouseDown:p=>{p.stopPropagation(),h==null||h()},children:m.map(p=>l.jsx("option",{value:p.value,children:p.label},p.value))})]})}),l.jsx(z,{}),l.jsxs("div",{className:"te-toolbar__group",children:[l.jsx(S,{label:e.bold,active:t.bold,disabled:y,onClick:()=>a("bold"),children:v.bold}),l.jsx(S,{label:e.italic,active:t.italic,disabled:y,onClick:()=>a("italic"),children:v.italic}),l.jsx(S,{label:e.strike,active:t.strikeThrough,disabled:y,onClick:()=>a("strikeThrough"),children:v.strike})]}),l.jsx(z,{}),l.jsxs("div",{className:"te-toolbar__group",children:[l.jsx(S,{label:e.bulletList,active:t.unorderedList,disabled:y,onClick:()=>a("insertUnorderedList"),children:v.ul}),l.jsx(S,{label:e.numberedList,active:t.orderedList,disabled:y,onClick:()=>a("insertOrderedList"),children:v.ol}),l.jsx(S,{label:e.quote,active:t.format==="blockquote",disabled:y,onClick:()=>i(t.format==="blockquote"?"p":"blockquote"),children:v.quote})]}),l.jsx(z,{}),l.jsxs("div",{className:"te-toolbar__group",children:[l.jsx(S,{label:t.hasSelectedImage?e.alignImageRight:e.alignRight,active:t.justifyRight,disabled:y,onClick:()=>a("justifyRight"),children:v.alignRight}),l.jsx(S,{label:t.hasSelectedImage?e.alignImageCenter:e.alignCenter,active:t.justifyCenter,disabled:y,onClick:()=>a("justifyCenter"),children:v.alignCenter}),l.jsx(S,{label:t.hasSelectedImage?e.alignImageLeft:e.alignLeft,active:t.justifyLeft,disabled:y,onClick:()=>a("justifyLeft"),children:v.alignLeft})]}),l.jsx(z,{}),l.jsxs("div",{className:"te-toolbar__group",children:[l.jsx(S,{label:e.rtl,disabled:y,onClick:()=>a("rtl"),children:v.rtl}),l.jsx(S,{label:e.ltr,disabled:y,onClick:()=>a("ltr"),children:v.ltr})]}),l.jsx(z,{}),l.jsxs("div",{className:"te-toolbar__group",children:[l.jsx(S,{label:e.indent,className:"te-tool--indent",disabled:y,onClick:()=>a("indent"),children:v.indent}),l.jsx(S,{label:e.outdent,className:"te-tool--outdent",disabled:y,onClick:()=>a("outdent"),children:v.outdent})]}),l.jsx(z,{}),l.jsxs("div",{className:"te-toolbar__group",children:[l.jsx(S,{label:e.insertLink,disabled:y,onClick:o,children:v.link}),l.jsx(S,{label:e.insertImage,disabled:y,onClick:c,children:v.image}),l.jsx(S,{label:e.horizontalRule,disabled:y,onClick:()=>a("insertHorizontalRule"),children:v.hr})]}),l.jsx(z,{}),l.jsxs("div",{className:"te-toolbar__group te-toolbar__colors",children:[l.jsx(Se,{label:e.textColor,icon:v.textColor,colors:yt,value:E,disabled:y,t:e,onRememberSelection:h,onChange:p=>{A(p),a("foreColor",p)}}),l.jsx(Se,{label:e.bgColor,icon:v.bgColor,colors:kt,value:C,allowTransparent:!0,disabled:y,t:e,onRememberSelection:h,onChange:p=>{N(p),a("hiliteColor",p)}})]}),l.jsx(z,{}),l.jsx("div",{className:"te-toolbar__group",children:l.jsx(S,{label:w?e.visualMode:e.sourceMode,active:w,onClick:T,children:v.code})})]})}function ye({open:e,title:t,onClose:n,children:r,footer:a,closeLabel:i="Close"}){const o=u.useId(),c=u.useRef(null);return u.useEffect(()=>{var h,w;if(!e)return;const f=T=>{T.key==="Escape"&&(n==null||n())};document.addEventListener("keydown",f);const k=document.activeElement;return(w=(h=c.current)==null?void 0:h.querySelector("input,button,textarea,select"))==null||w.focus(),()=>{document.removeEventListener("keydown",f),k&&typeof k.focus=="function"&&k.focus()}},[e,n]),e?l.jsx("div",{className:"te-modal-backdrop",role:"presentation",onMouseDown:n,children:l.jsxs("div",{className:"te-modal",role:"dialog","aria-modal":"true","aria-labelledby":o,ref:c,onMouseDown:f=>f.stopPropagation(),children:[l.jsxs("div",{className:"te-modal__header",children:[l.jsx("h3",{id:o,children:t}),l.jsx("button",{type:"button",className:"te-modal__close",onClick:n,"aria-label":i,children:v.close})]}),l.jsx("div",{className:"te-modal__body",children:r}),a?l.jsx("div",{className:"te-modal__footer",children:a}):null]})}):null}function vt({open:e,onClose:t,onSubmit:n,initialUrl:r="",initialText:a="",t:i}){const[o,c]=u.useState(r),[f,k]=u.useState(a),[h,w]=u.useState("");u.useEffect(()=>{e&&(c(r),k(a),w(""))},[e,r,a]);const T=E=>{E.preventDefault();const A=o.trim();if(!A){w(i.linkUrlRequired);return}try{n({url:A,text:f.trim()}),t()}catch(C){w(C.message||i.linkInvalid)}};return l.jsx(ye,{open:e,title:i.linkTitle,onClose:t,closeLabel:i.close,footer:l.jsxs(l.Fragment,{children:[l.jsx("button",{type:"button",className:"te-btn te-btn--ghost",onClick:t,children:i.cancel}),l.jsx("button",{type:"submit",form:"te-link-form",className:"te-btn te-btn--primary",children:i.linkSubmit})]}),children:l.jsxs("form",{id:"te-link-form",onSubmit:T,className:"te-form",children:[l.jsxs("label",{className:"te-field",children:[l.jsx("span",{children:i.linkUrl}),l.jsx("input",{type:"url",dir:"ltr",placeholder:"https://example.com",value:o,onChange:E=>c(E.target.value),required:!0})]}),l.jsxs("label",{className:"te-field",children:[l.jsx("span",{children:i.linkText}),l.jsx("input",{type:"text",placeholder:i.linkTextPlaceholder,value:f,onChange:E=>k(E.target.value)})]}),h?l.jsx("p",{className:"te-error",children:h}):null]})})}function Ct({open:e,onClose:t,onSubmitUrl:n,onSubmitFile:r,accept:a="image/jpeg,image/png,image/gif,image/webp",t:i}){const[o,c]=u.useState("file"),[f,k]=u.useState(""),[h,w]=u.useState(""),[T,E]=u.useState(""),[A,C]=u.useState(!1),N=u.useRef(null);u.useEffect(()=>{e&&(c("file"),k(""),w(""),E(""),C(!1),N.current&&(N.current.value=""))},[e]);const y=async p=>{p.preventDefault(),E(""),C(!0);try{await n({url:f.trim(),alt:h.trim()}),t()}catch(d){E(d.message||i.imageInsertFailed)}finally{C(!1)}},m=async p=>{var R,F;p.preventDefault();const d=(F=(R=N.current)==null?void 0:R.files)==null?void 0:F[0];if(!d){E(i.imagePickFile);return}E(""),C(!0);try{await r({file:d,alt:h.trim()}),t()}catch(O){E(O.message||i.imageUploadFailed)}finally{C(!1)}};return l.jsxs(ye,{open:e,title:i.imageTitle,onClose:t,closeLabel:i.close,footer:l.jsxs(l.Fragment,{children:[l.jsx("button",{type:"button",className:"te-btn te-btn--ghost",onClick:t,disabled:A,children:i.cancel}),l.jsx("button",{type:"submit",form:o==="file"?"te-image-file-form":"te-image-url-form",className:"te-btn te-btn--primary",disabled:A,children:A?i.imageBusy:i.imageSubmit})]}),children:[l.jsxs("div",{className:"te-tabs",role:"tablist",children:[l.jsx("button",{type:"button",role:"tab","aria-selected":o==="file",className:o==="file"?"is-active":"",onClick:()=>c("file"),children:i.imageUploadTab}),l.jsx("button",{type:"button",role:"tab","aria-selected":o==="url",className:o==="url"?"is-active":"",onClick:()=>c("url"),children:i.imageUrlTab})]}),o==="file"?l.jsxs("form",{id:"te-image-file-form",onSubmit:m,className:"te-form",children:[l.jsxs("label",{className:"te-field",children:[l.jsx("span",{children:i.imageFile}),l.jsx("input",{ref:N,type:"file",accept:a})]}),l.jsxs("label",{className:"te-field",children:[l.jsx("span",{children:i.imageAlt}),l.jsx("input",{type:"text",value:h,onChange:p=>w(p.target.value),placeholder:i.imageAltPlaceholder})]}),l.jsx("p",{className:"te-hint",children:i.imageHint}),T?l.jsx("p",{className:"te-error",children:T}):null]}):l.jsxs("form",{id:"te-image-url-form",onSubmit:y,className:"te-form",children:[l.jsxs("label",{className:"te-field",children:[l.jsx("span",{children:i.imageUrl}),l.jsx("input",{type:"url",dir:"ltr",placeholder:"https://...",value:f,onChange:p=>k(p.target.value),required:!0})]}),l.jsxs("label",{className:"te-field",children:[l.jsx("span",{children:i.imageAlt}),l.jsx("input",{type:"text",value:h,onChange:p=>w(p.target.value),placeholder:i.imageAltPlaceholder})]}),T?l.jsx("p",{className:"te-error",children:T}):null]})]})}function Lt({open:e,onClose:t,onSubmit:n,initialAlt:r="",t:a}){const[i,o]=u.useState(r);u.useEffect(()=>{e&&o(r)},[e,r]);const c=f=>{f.preventDefault(),n({alt:i.trim()}),t()};return l.jsx(ye,{open:e,title:a.altTitle,onClose:t,closeLabel:a.close,footer:l.jsxs(l.Fragment,{children:[l.jsx("button",{type:"button",className:"te-btn te-btn--ghost",onClick:t,children:a.cancel}),l.jsx("button",{type:"submit",form:"te-image-alt-form",className:"te-btn te-btn--primary",children:a.save})]}),children:l.jsxs("form",{id:"te-image-alt-form",onSubmit:c,className:"te-form",children:[l.jsxs("label",{className:"te-field",children:[l.jsx("span",{children:a.altLabel}),l.jsx("input",{type:"text",value:i,onChange:f=>o(f.target.value),placeholder:a.altPlaceholder})]}),l.jsx("p",{className:"te-hint",children:a.altHint})]})})}const Et=["p","br","div","span","h1","h2","h3","h4","h5","h6","ul","ol","li","strong","b","em","i","s","strike","del","blockquote","pre","a","img","hr","u","font"],At=["href","target","rel","src","alt","title","width","height","style","dir","class","color","face","size","contenteditable","data-align","loading","draggable"],St=/^(https?:|mailto:|tel:|blob:)/i,wt=/^(https?:|blob:|data:image\/(png|jpeg|jpg|gif|webp);base64,)/i;function ie(e,t=!1){if(!e||typeof e!="string")return!1;const n=e.trim();return n.startsWith("javascript:")||n.startsWith("vbscript:")?!1:n.startsWith("#")||n.startsWith("/")?!0:t?wt.test(n):St.test(n)||n.startsWith("/")}function Nt(e){if(!e||typeof e!="string")return"";const t=new Set(["color","background-color","text-align","direction","margin","margin-top","margin-right","margin-bottom","margin-left","margin-inline-start","margin-inline-end","padding-right","padding-left","padding-inline-start","padding-inline-end","text-indent","font-weight","font-style","text-decoration","text-decoration-line","display","float","max-width","width","height","box-sizing"]);return e.split(";").map(n=>n.trim()).filter(Boolean).map(n=>{const r=n.indexOf(":");if(r===-1)return null;const a=n.slice(0,r).trim().toLowerCase(),i=n.slice(r+1).trim();return!t.has(a)||/expression|url\s*\(|javascript|import/i.test(i)?null:`${a}: ${i}`}).filter(Boolean).join("; ")}function H(e){if(!e)return"";const t=mt.sanitize(e,{ALLOWED_TAGS:Et,ALLOWED_ATTR:At,ALLOW_DATA_ATTR:!1,FORBID_TAGS:["script","iframe","object","embed","form","input","style"],FORBID_ATTR:["onerror","onload","onclick","onmouseover","onfocus","onblur","onchange","onsubmit"]});if(typeof document>"u")return t;const n=document.createElement("div");return n.innerHTML=t,n.querySelectorAll("font").forEach(r=>{const a=document.createElement("span"),i=r.getAttribute("color");for(i&&(a.style.color=i);r.firstChild;)a.appendChild(r.firstChild);r.replaceWith(a)}),n.querySelectorAll("a").forEach(r=>{const a=r.getAttribute("href")||"";ie(a,!1)?(r.setAttribute("rel","noopener noreferrer"),/^https?:/i.test(a)&&r.setAttribute("target","_blank")):r.removeAttribute("href")}),n.querySelectorAll("img").forEach(r=>{var i,o,c,f;const a=r.getAttribute("src")||"";if(!ie(a,!0)){r.remove();return}if(r.removeAttribute("onerror"),r.removeAttribute("onload"),!((o=(i=r.parentElement)==null?void 0:i.classList)!=null&&o.contains("te-figure"))){const k=document.createElement("div");k.className="te-figure",k.setAttribute("contenteditable","false");const h=r.style.textAlign||r.getAttribute("data-align")||((f=(c=r.parentElement)==null?void 0:c.style)==null?void 0:f.textAlign)||"center";k.setAttribute("data-align",h),k.style.textAlign=h,r.replaceWith(k),k.appendChild(r)}}),n.querySelectorAll(".te-figure").forEach(r=>{r.setAttribute("contenteditable","false"),r.getAttribute("data-align")||r.setAttribute("data-align",r.style.textAlign||"center"),r.querySelectorAll(".te-figure__alt-btn, button").forEach(a=>a.remove()),r.classList.remove("is-selected")}),n.querySelectorAll("img.is-selected").forEach(r=>{r.classList.remove("is-selected")}),n.querySelectorAll("[style]").forEach(r=>{const a=Nt(r.getAttribute("style"));a?r.setAttribute("style",a):r.removeAttribute("style")}),Q(n),n.innerHTML}function fe(e){const t=e.parentNode;if(t){for(;e.firstChild;)t.insertBefore(e.firstChild,e);t.removeChild(e)}}function Tt(e){const t=[];for(let n=0;n<e.style.length;n+=1)t.push(e.style.item(n));return t}function ge(e){if(!e||e.nodeType!==Node.ELEMENT_NODE||e.tagName!=="SPAN")return!1;const t=Tt(e);return t.length?t.every(n=>n==="color"||n==="background-color"):!1}function Q(e){if(!e)return;let t=0,n=!0;for(;n&&t<80;)n=!1,t+=1,[...e.querySelectorAll("span")].forEach(r=>{var i;if(!r.isConnected)return;if(!((i=r.getAttribute("style"))!=null&&i.trim())&&!r.className){fe(r),n=!0;return}if(!ge(r))return;const a=r.parentElement;if(a&&ge(a)&&a.childNodes.length===1&&a.firstChild===r){for(r.style.color&&(a.style.color=r.style.color),r.style.backgroundColor&&(a.style.backgroundColor=r.style.backgroundColor);r.firstChild;)a.insertBefore(r.firstChild,r);r.remove(),n=!0;return}a&&ge(a)&&(r.style.color&&(a.style.color=r.style.color),r.style.backgroundColor&&(a.style.backgroundColor=r.style.backgroundColor),fe(r),n=!0)});e.querySelectorAll("span").forEach(r=>{var a;!((a=r.getAttribute("style"))!=null&&a.trim())&&!r.className&&fe(r)})}function De(e){return ie(e,!1)}function Ue(e){return ie(e,!0)}const Mt=[{mime:"image/jpeg",bytes:[255,216,255]},{mime:"image/png",bytes:[137,80,78,71]},{mime:"image/gif",bytes:[71,73,70,56]},{mime:"image/webp",check:e=>e.length>=12&&e[0]===82&&e[1]===73&&e[2]===70&&e[3]===70&&e[8]===87&&e[9]===69&&e[10]===66&&e[11]===80}],He={maxSizeBytes:2*1024*1024,allowedMimeTypes:["image/jpeg","image/png","image/gif","image/webp"],allowedExtensions:[".jpg",".jpeg",".png",".gif",".webp"]};function Rt(e){const t=e.lastIndexOf(".");return t===-1?"":e.slice(t).toLowerCase()}function It(e){return e.replace(/[/\\?%*:|"<>]/g,"_").replace(/\s+/g,"-").replace(/\.+/g,".").slice(0,100)||"image"}async function _t(e,t=16){const r=await e.slice(0,t).arrayBuffer();return new Uint8Array(r)}function Dt(e){for(const t of Mt)if(t.check){if(t.check(e))return t.mime}else if(t.bytes.every((n,r)=>e[r]===n))return t.mime;return null}function Fe(e={}){return e.messages||xe(e.language||"en")}async function Oe(e,t={}){const n={...He,...t},r=Fe(t),a=[];if(!e||!(e instanceof Blob))return{ok:!1,errors:[r.fileInvalid]};if(e.size<=0&&a.push(r.fileEmpty),e.size>n.maxSizeBytes){const f=(n.maxSizeBytes/1048576).toFixed(1);a.push(r.fileTooLarge(f))}const i=Rt(e.name||"");n.allowedExtensions.includes(i)||a.push(r.fileBadExtension);const o=(e.type||"").toLowerCase();o&&!n.allowedMimeTypes.includes(o)&&a.push(r.fileBadMime);let c=null;try{const f=await _t(e);c=Dt(f),c?o&&o!==c&&!(o==="image/jpg"&&c==="image/jpeg")&&a.push(r.fileMimeMismatch):a.push(r.fileBadContent)}catch{a.push(r.fileReadError)}return a.length?{ok:!1,errors:a}:{ok:!0,mime:c||o,safeName:It(e.name||`image${i}`),errors:[]}}function Ut(e,t){return new Promise((n,r)=>{const a=new FileReader;a.onload=()=>{const i=a.result;if(typeof i!="string"||!i.startsWith("data:image/")){r(new Error("Failed to encode image."));return}if(t&&i.startsWith("data:")){const o=i.indexOf(",");if(o!==-1){n(`data:${t};base64,${i.slice(o+1)}`);return}}n(i)},a.onerror=()=>r(a.error||new Error("Failed to read file.")),a.readAsDataURL(e)})}async function Be(e,t={}){const n=Fe(t),r=await Oe(e,t);if(!r.ok)throw new Error(r.errors.join(" "));if(typeof t.onUpload=="function"){const a=await t.onUpload(e,{mime:r.mime,safeName:r.safeName});if(!a||typeof a!="string")throw new Error(n.imageUploadFailed);return a}try{return await Ut(e,r.mime)}catch{throw new Error(n.fileReadError)}}function Pe(e=50){let t=[],n=-1;return{push(r){n>=0&&t[n]===r||(t=t.slice(0,n+1),t.push(r),t.length>e?t.shift():n+=1,n>=e&&(n=e-1),n=t.length-1)},undo(){return n<=0?null:(n-=1,t[n])},redo(){return n>=t.length-1?null:(n+=1,t[n])},canUndo(){return n>0},canRedo(){return n<t.length-1},current(){return n>=0?t[n]:null},reset(r=""){t=[r],n=0}}}function K(e){e&&e.focus({preventScroll:!0})}function Z(e){const t=window.getSelection();if(!t||t.rangeCount===0)return null;const n=t.getRangeAt(0);return e.contains(n.commonAncestorContainer)?n.cloneRange():null}function se(e){if(!e)return!1;const t=window.getSelection();if(!t)return!1;try{return t.removeAllRanges(),t.addRange(e),!0}catch{return!1}}function D(e,t=null){try{return document.execCommand(e,!1,t)}catch{return!1}}function W(e){try{return document.queryCommandState(e)}catch{return!1}}function Ht(e){try{return document.queryCommandValue(e)}catch{return""}}function Ft(){const e=(Ht("formatBlock")||"").toLowerCase();return e?e.replace(/[<>]/g,""):"p"}function qe(){try{document.execCommand("styleWithCSS",!1,!0)}catch{}}function te(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 we(e,t){K(e);let n=te(e);if(!n)return!1;if(n.collapsed){const i=Ot(n);if(i)se(i),n=i;else{const o=document.createElement("span");t.color&&(o.style.color=t.color),t.backgroundColor&&(o.style.backgroundColor=t.backgroundColor),o.appendChild(document.createTextNode("​")),n.insertNode(o);const c=document.createRange();return c.setStart(o.firstChild,1),c.collapse(!0),se(c),!0}}if(qt(n,t))return Q(e),!0;const a=zt(e,t);return Q(e),a}function Ot(e){const t=e.startContainer;if(!t||t.nodeType!==Node.TEXT_NODE)return null;const n=t.textContent||"";if(!n.trim())return null;let r=e.startOffset,a=e.endOffset;for(;r>0&&!/\s/.test(n[r-1]);)r-=1;for(;a<n.length&&!/\s/.test(n[a]);)a+=1;if(r===a)return null;const i=e.cloneRange();return i.setStart(t,r),i.setEnd(t,a),i}function Bt(e){const t=[];for(let n=0;n<e.style.length;n+=1)t.push(e.style.item(n));return t}function Pt(e){if(!e||e.nodeType!==Node.ELEMENT_NODE||e.tagName!=="SPAN")return!1;const t=Bt(e);return t.length?t.every(n=>n==="color"||n==="background-color"):!1}function qt(e,t){var o;let n=e.commonAncestorContainer;n.nodeType===Node.TEXT_NODE&&(n=n.parentElement);let r=null,a=n;for(;a;){if(Pt(a)){const c=document.createRange();if(c.selectNodeContents(a),e.compareBoundaryPoints(Range.START_TO_START,c)>=0&&e.compareBoundaryPoints(Range.END_TO_END,c)<=0){r=a;break}}if((o=a.classList)!=null&&o.contains("te-editor"))break;a=a.parentElement}if(!r)return!1;t.color&&(r.style.color=t.color),t.backgroundColor&&(t.backgroundColor==="transparent"?r.style.backgroundColor="":r.style.backgroundColor=t.backgroundColor);const i=window.getSelection();if(i){const c=document.createRange();c.selectNodeContents(r),i.removeAllRanges(),i.addRange(c)}return!0}function zt(e,t){const n=te(e);if(!n||n.collapsed)return!1;const r=document.createElement("span");t.color&&(r.style.color=t.color),t.backgroundColor&&(r.style.backgroundColor=t.backgroundColor);try{n.surroundContents(r)}catch{const i=n.extractContents(),o=document.createElement("div");for(o.appendChild(i),Q(o);o.firstChild;)r.appendChild(o.firstChild);n.insertNode(r)}const a=window.getSelection();if(a){const i=document.createRange();i.selectNodeContents(r),a.removeAllRanges(),a.addRange(i)}return!0}function $t(e){K(e);const t=te(e);t&&(qe(),D("hiliteColor","transparent"),D("backColor","transparent"),e.querySelectorAll("span[style]").forEach(n=>{var r;t.intersectsNode(n)&&(n.style.backgroundColor="",(r=n.getAttribute("style"))!=null&&r.trim()||n.removeAttribute("style"))}),Q(e))}function Ne(e,t,n,r={}){switch(K(e),qe(),t){case"bold":D("bold");break;case"italic":D("italic");break;case"strikeThrough":D("strikeThrough");break;case"formatBlock":{const a=n||"p";D("formatBlock",a==="p"?"p":a);break}case"insertUnorderedList":D("insertUnorderedList");break;case"insertOrderedList":D("insertOrderedList");break;case"justifyRight":me(e,"right",r.selectedImage);break;case"justifyCenter":me(e,"center",r.selectedImage);break;case"justifyLeft":me(e,"left",r.selectedImage);break;case"indent":Te(e,1);break;case"outdent":Te(e,-1);break;case"insertHorizontalRule":D("insertHorizontalRule");break;case"foreColor":we(e,{color:n});break;case"hiliteColor":!n||n==="transparent"?$t(e):we(e,{backgroundColor:n});break;case"removeFormat":D("removeFormat");break}}function ze(e,t){var r;let n=t;for(n&&n.nodeType===Node.TEXT_NODE&&(n=n.parentElement);n&&n!==e;){if((r=n.matches)!=null&&r.call(n,"p,div,h1,h2,h3,h4,h5,h6,li,blockquote,pre,figure,.te-figure"))return n;n=n.parentElement}return null}const Wt=24,Kt=240;function Vt(e){var r,a,i,o;const t=(r=e.style)==null?void 0:r.marginInlineStart;if(t){const c=parseFloat(t);if(!Number.isNaN(c))return c}const n=(o=(i=(a=e.ownerDocument)==null?void 0:a.defaultView)==null?void 0:i.getComputedStyle(e))==null?void 0:o.marginInlineStart;if(n){const c=parseFloat(n);if(!Number.isNaN(c)&&c>0)return c}return 0}function Xt(e,t){const n=[],r=new Set,a=i=>{var c;const o=ze(e,i);!o||o===e||r.has(o)||(c=o.matches)!=null&&c.call(o,"figure,.te-figure")||(r.add(o),n.push(o))};if(a(t.startContainer),a(t.endContainer),!t.collapsed)try{const i=e.ownerDocument.createTreeWalker(t.commonAncestorContainer.nodeType===Node.ELEMENT_NODE?t.commonAncestorContainer:t.commonAncestorContainer.parentElement||e,NodeFilter.SHOW_ELEMENT,{acceptNode(c){var f;return t.intersectsNode(c)?(f=c.matches)!=null&&f.call(c,"p,div,h1,h2,h3,h4,h5,h6,li,blockquote,pre")?NodeFilter.FILTER_ACCEPT:NodeFilter.FILTER_SKIP:NodeFilter.FILTER_REJECT}});let o=i.currentNode;for((o==null?void 0:o.nodeType)===Node.ELEMENT_NODE&&a(o);o=i.nextNode();)a(o)}catch{}return n}function Te(e,t){K(e);const n=te(e);if(!n)return;const r=Xt(e,n);r.length&&r.forEach(a=>{var c;if(a.tagName==="LI"){Gt(a,t);return}const i=Vt(a),o=Math.max(0,Math.min(Kt,i+t*Wt));o<=0?(a.style.marginInlineStart="",(c=a.getAttribute("style"))!=null&&c.trim()||a.removeAttribute("style")):a.style.marginInlineStart=`${o}px`})}function Gt(e,t){const n=e.parentElement;if(!n||n.tagName!=="UL"&&n.tagName!=="OL")return;if(t>0){const i=e.previousElementSibling;if(!i||i.tagName!=="LI")return;let o=i.querySelector(":scope > ul, :scope > ol");o||(o=document.createElement(n.tagName.toLowerCase()),i.appendChild(o)),o.appendChild(e);return}const r=n.parentElement;!r||r.tagName!=="LI"||!r.parentElement||(r.after(e),n.children.length||n.remove())}function me(e,t,n){var c,f;const r=n&&e.contains(n)?n:null;if(r){Me(r,t);return}const a=te(e),i=a==null?void 0:a.commonAncestorContainer,o=(i==null?void 0:i.nodeType)===Node.ELEMENT_NODE&&i.tagName==="IMG"?i:(f=(c=i==null?void 0:i.parentElement)==null?void 0:c.closest)==null?void 0:f.call(c,"img");if(o&&e.contains(o)){Me(o,t);return}D(t==="right"?"justifyRight":t==="center"?"justifyCenter":"justifyLeft")}function $e(e){var n,r;if((r=(n=e.parentElement)==null?void 0:n.classList)!=null&&r.contains("te-figure"))return e.parentElement;const t=document.createElement("div");return t.className="te-figure",t.setAttribute("contenteditable","false"),e.replaceWith(t),t.appendChild(e),t}function Me(e,t){const n=$e(e);n.setAttribute("data-align",t),n.style.textAlign=t,n.style.width="fit-content",n.style.maxWidth="100%",e.style.display="block",e.style.float="none",e.style.marginLeft="0",e.style.marginRight="0",t==="center"?(n.style.marginLeft="auto",n.style.marginRight="auto"):t==="left"?(n.style.marginLeft="0",n.style.marginRight="auto"):(n.style.marginLeft="auto",n.style.marginRight="0")}function ee(e,t,n){if(!e||!t)return;ae(t);const r=$e(e);r.classList.add("is-selected"),e.classList.add("is-selected");let a=r.querySelector(".te-figure__alt-btn");a||(a=document.createElement("button"),a.type="button",a.className="te-figure__alt-btn",a.setAttribute("contenteditable","false"),r.appendChild(a));const i=n||{},o=e.getAttribute("alt")||"";a.textContent=o?`Alt: ${o.length>28?`${o.slice(0,28)}…`:o}`:i.editAlt||"Edit Alt",a.title=i.editAltTitle||"Edit image alt text";const c=document.createRange();c.selectNode(r);const f=window.getSelection();f==null||f.removeAllRanges(),f==null||f.addRange(c),K(t)}function ae(e){e&&(e.querySelectorAll(".te-figure.is-selected, img.is-selected").forEach(t=>{t.classList.remove("is-selected")}),e.querySelectorAll(".te-figure__alt-btn").forEach(t=>t.remove()))}function Jt(e,t,n){var i;if(!e)return;e.setAttribute("alt",t||"");const r=(i=e.closest)==null?void 0:i.call(e,".te-figure"),a=r==null?void 0:r.querySelector(".te-figure__alt-btn");if(a){const o=n||{};a.textContent=t?`Alt: ${t.length>28?`${t.slice(0,28)}…`:t}`:o.editAlt||"Edit Alt"}}function Qt(e,t){K(e);const n=window.getSelection();if(!n||n.rangeCount===0){e.setAttribute("dir",t);return}let r=n.anchorNode;r&&r.nodeType===Node.TEXT_NODE&&(r=r.parentElement);const a=ze(e,r);a&&a!==e?(a.setAttribute("dir",t),a.style.direction=t):e.setAttribute("dir",t)}function Yt(e,t,n,r){if(K(e),!De(t))throw new Error(r&&r.linkUnsafe||"The link URL is invalid or unsafe.");const a=window.getSelection();if(a&&!a.isCollapsed&&e.contains(a.anchorNode)){D("createLink",t);const o=e.querySelectorAll("a[href]"),c=o[o.length-1];c&&(c.setAttribute("rel","noopener noreferrer"),/^https?:/i.test(t)&&c.setAttribute("target","_blank"))}else{const o=n||t,c=document.createElement("a");c.href=t,c.textContent=o,c.rel="noopener noreferrer",/^https?:/i.test(t)&&(c.target="_blank"),pe(e,c)}}function Re(e,t,n="",r){if(K(e),!Ue(t))throw new Error(r&&r.imageUnsafe||"The image URL is invalid or unsafe.");const a=document.createElement("div");a.className="te-figure",a.setAttribute("contenteditable","false"),a.setAttribute("data-align","center"),a.style.textAlign="center",a.style.width="fit-content",a.style.maxWidth="100%",a.style.marginLeft="auto",a.style.marginRight="auto";const i=document.createElement("img");i.src=t,i.alt=n||"",i.setAttribute("loading","lazy"),i.draggable=!1,i.style.display="block",i.style.maxWidth="100%",a.appendChild(i),pe(e,a);const o=document.createElement("p");return o.innerHTML="<br>",pe(e,o),i}function pe(e,t){const n=window.getSelection();if(!n||n.rangeCount===0){e.appendChild(t);return}const r=n.getRangeAt(0);if(!e.contains(r.commonAncestorContainer)){e.appendChild(t);return}r.deleteContents(),r.insertNode(t),r.setStartAfter(t),r.collapse(!0),n.removeAllRanges(),n.addRange(r)}function Zt(e){var r,a,i;const t=(r=e==null?void 0:e.querySelector)==null?void 0:r.call(e,".te-figure.is-selected, img.is-selected");let n=null;if(t){const o=(a=t.classList)!=null&&a.contains("te-figure")?t:(i=t.closest)==null?void 0:i.call(t,".te-figure");n=(o==null?void 0:o.getAttribute("data-align"))||null}return{bold:W("bold"),italic:W("italic"),strikeThrough:W("strikeThrough"),unorderedList:W("insertUnorderedList"),orderedList:W("insertOrderedList"),justifyRight:n?n==="right":W("justifyRight"),justifyCenter:n?n==="center":W("justifyCenter"),justifyLeft:n?n==="left":W("justifyLeft"),format:Ft(),hasSelectedImage:!!t}}function G(e){const t=(e||"").trim();return!t||t==="<br>"||t==="<div><br></div>"?"<p><br></p>":t}function he(e){if(typeof document<"u"){const t=document.createElement("div");return t.innerHTML=e,t.querySelectorAll(".te-figure__alt-btn").forEach(n=>n.remove()),t.querySelectorAll(".is-selected").forEach(n=>n.classList.remove("is-selected")),t.querySelectorAll('[class=""]').forEach(n=>n.removeAttribute("class")),t.innerHTML}return e.replace(/<button[^>]*class="[^"]*te-figure__alt-btn[^"]*"[^>]*>.*?<\/button>/gi,"").replace(/\s*is-selected/g,"").replace(/\sclass=""/g,"").replace(/\sclass=''/g,"")}const We=u.forwardRef(function({value:t,defaultValue:n="<p><br></p>",onChange:r,placeholder:a,language:i="en",dir:o,className:c="",style:f,minHeight:k=220,disabled:h=!1,onUpload:w,uploadOptions:T,toolbar:E=!0},A){const C=oe(i),N=xe(C),y=o||Ie(C),m=a??N.placeholder,p=u.useRef(null),d=u.useRef(null),R=u.useRef(Pe()),F=u.useRef(null),O=u.useRef(""),ce=u.useRef(!1),M=u.useRef(null),B=u.useRef(N);B.current=N;const[Ke,Ve]=u.useState(()=>({bold:!1,italic:!1,strikeThrough:!1,unorderedList:!1,orderedList:!1,justifyRight:!1,justifyCenter:!1,justifyLeft:!1,format:"p",hasSelectedImage:!1})),[Xe,Ge]=u.useState(!1),[Je,Qe]=u.useState(!1),[Ye,ke]=u.useState(!1),[Ze,je]=u.useState(!1),[et,ve]=u.useState(!1),[tt,rt]=u.useState(""),[nt,V]=u.useState(!0),[U,Ce]=u.useState(!1),[Y,Le]=u.useState(""),P=u.useCallback(()=>{Ge(R.current.canUndo()),Qe(R.current.canRedo())},[]),$=u.useCallback((s,{recordHistory:g=!0}={})=>{const x=H(he(G(s)));O.current=x,V(!x.replace(/<[^>]+>/g,"").replace(/\u200b/g,"").trim()),g&&(R.current.push(x),P()),r==null||r(x)},[r,P]),q=u.useCallback(()=>{var s;return((s=d.current)==null?void 0:s.innerHTML)||""},[]),Ee=u.useCallback((s,{recordHistory:g=!1}={})=>{if(!d.current)return;const x=H(G(s));d.current.innerHTML=x,O.current=x,V(!x.replace(/<[^>]+>/g,"").replace(/\u200b/g,"").trim()),M.current=null,g&&(R.current.push(x),P())},[P]);u.useEffect(()=>{const s=H(G(t??n));d.current&&(d.current.innerHTML=s),O.current=s,R.current.reset(s),V(!s.replace(/<[^>]+>/g,"").replace(/\u200b/g,"").trim()),P()},[]),u.useEffect(()=>{if(t===void 0||!d.current)return;const s=H(G(t));if(s!==O.current){const g=Z(d.current);d.current.innerHTML=s,O.current=s,V(!s.replace(/<[^>]+>/g,"").replace(/\u200b/g,"").trim()),M.current=null,se(g)}},[t]);const L=u.useCallback(()=>{d.current&&Ve(Zt(d.current))},[]);u.useEffect(()=>{const s=()=>{if(!d.current)return;const g=window.getSelection();!g||g.rangeCount===0||d.current.contains(g.anchorNode)&&L()};return document.addEventListener("selectionchange",s),()=>document.removeEventListener("selectionchange",s)},[L]);const J=u.useCallback(()=>{const s=Z(d.current);s&&(F.current=s)},[]),X=u.useCallback(s=>{const g=Z(d.current);g&&(F.current=g),se(F.current),s(),$(q()),L()},[$,q,L]),re=u.useCallback((s,g)=>{h||X(()=>{s==="rtl"||s==="ltr"?Qt(d.current,s):Ne(d.current,s,g,{selectedImage:M.current})})},[h,X]),lt=u.useCallback(s=>{h||X(()=>{Ne(d.current,"formatBlock",s)})},[h,X]),ue=u.useCallback(()=>{const s=R.current.undo();s==null||!d.current||(d.current.innerHTML=s,O.current=s,V(!s.replace(/<[^>]+>/g,"").replace(/\u200b/g,"").trim()),M.current=null,P(),r==null||r(s),L())},[r,L,P]),de=u.useCallback(()=>{const s=R.current.redo();s==null||!d.current||(d.current.innerHTML=s,O.current=s,V(!s.replace(/<[^>]+>/g,"").replace(/\u200b/g,"").trim()),M.current=null,P(),r==null||r(s),L())},[r,L,P]),Ae=u.useCallback(()=>{ce.current||($(q()),L())},[$,q,L]),at=u.useCallback(s=>{var _,I;s.preventDefault();const g=((_=s.clipboardData)==null?void 0:_.getData("text/plain"))||"",x=(I=s.clipboardData)==null?void 0:I.getData("text/html");if(x){const le=H(x);document.execCommand("insertHTML",!1,le)}else document.execCommand("insertText",!1,g);$(q())},[$,q]),it=u.useCallback(s=>{const g=s.metaKey||s.ctrlKey;g&&s.key.toLowerCase()==="z"&&!s.shiftKey?(s.preventDefault(),ue()):g&&(s.key.toLowerCase()==="y"||s.key.toLowerCase()==="z"&&s.shiftKey)?(s.preventDefault(),de()):g&&s.key.toLowerCase()==="b"?(s.preventDefault(),re("bold")):g&&s.key.toLowerCase()==="i"?(s.preventDefault(),re("italic")):s.key==="Escape"&&M.current&&(ae(d.current),M.current=null,L())},[re,de,ue,L]),ne=u.useCallback(s=>{s&&(M.current=s,rt(s.getAttribute("alt")||""),ve(!0))},[]),st=u.useCallback(s=>{const g=s.target;if(!(g instanceof Element)||!d.current)return;if(g.closest(".te-figure__alt-btn")){s.preventDefault(),s.stopPropagation();const I=g.closest(".te-figure"),le=I==null?void 0:I.querySelector("img");le&&ne(le);return}const x=g.closest("img"),_=g.closest(".te-figure");if(x&&d.current.contains(x)){s.preventDefault(),ee(x,d.current,B.current),M.current=x,F.current=Z(d.current),L();return}if(_&&d.current.contains(_)){const I=_.querySelector("img");if(I){s.preventDefault(),ee(I,d.current,B.current),M.current=I,F.current=Z(d.current),L();return}}M.current&&(ae(d.current),M.current=null,L())},[ne,L]),ot=u.useCallback(s=>{const g=s.target;if(!(g instanceof Element)||!d.current)return;const x=g.closest("img"),_=g.closest(".te-figure"),I=x||(_==null?void 0:_.querySelector("img"));I&&d.current.contains(I)&&(s.preventDefault(),ee(I,d.current,B.current),ne(I))},[ne]),ct=u.useCallback(()=>{J(),ke(!0)},[J]),ut=u.useCallback(()=>{J(),je(!0)},[J]),dt=u.useCallback(()=>{if(h)return;if(!U){ae(d.current),M.current=null;const g=H(he(q()));Le(g),Ce(!0);return}const s=H(G(Y));d.current&&(d.current.innerHTML=s),O.current=s,V(!s.replace(/<[^>]+>/g,"").replace(/\u200b/g,"").trim()),R.current.push(s),P(),r==null||r(s),Ce(!1),L()},[h,U,Y,q,r,P,L]),ft=u.useCallback(s=>{Le(s.target.value)},[]),gt=u.useCallback(()=>{const s=H(G(Y));O.current=s,r==null||r(s)},[Y,r]);return u.useImperativeHandle(A,()=>({focus:()=>{var s;return(s=d.current)==null?void 0:s.focus()},getHTML:()=>H(he(q())),setHTML:s=>{Ee(s,{recordHistory:!0}),r==null||r(H(G(s)))},clear:()=>{Ee("<p><br></p>",{recordHistory:!0}),r==null||r(H("<p><br></p>"))},getEditorElement:()=>d.current})),l.jsxs("div",{ref:p,className:`te-root${h?" is-disabled":""}${U?" is-source":""} te-root--${y} ${c}`.trim(),style:f,dir:y,lang:C,onMouseDown:s=>{var g,x;(x=(g=s.target).closest)!=null&&x.call(g,".te-toolbar")&&J()},children:[E?l.jsx(jt,{t:N,states:Ke,canUndo:Xe,canRedo:Je,onCommand:re,onBlockChange:lt,onOpenLink:ct,onOpenImage:ut,onUndo:ue,onRedo:de,onRememberSelection:J,sourceMode:U,onToggleSource:dt}):null,l.jsxs("div",{className:"te-editor-shell",children:[!U&&nt?l.jsx("div",{className:"te-placeholder",children:m}):null,l.jsx("div",{ref:d,className:"te-editor",contentEditable:!h&&!U,role:"textbox","aria-multiline":"true","aria-label":N.editorLabel,"aria-placeholder":m,"aria-hidden":U,suppressContentEditableWarning:!0,style:{minHeight:k,display:U?"none":void 0},dir:y,onInput:Ae,onPaste:at,onKeyDown:it,onMouseDown:st,onDoubleClick:ot,onBlur:()=>{U||$(q(),{recordHistory:!0})},onCompositionStart:()=>{ce.current=!0},onCompositionEnd:()=>{ce.current=!1,Ae()},onMouseUp:L,onKeyUp:L}),U?l.jsx("textarea",{className:"te-source",value:Y,onChange:ft,onBlur:gt,disabled:h,spellCheck:!1,dir:"ltr","aria-label":N.sourceLabel,style:{minHeight:k}}):null]}),l.jsx(vt,{open:Ye&&!U,onClose:()=>ke(!1),t:N,onSubmit:({url:s,text:g})=>{X(()=>{Yt(d.current,s,g,B.current)})}}),l.jsx(Ct,{open:Ze&&!U,onClose:()=>je(!1),t:N,onSubmitUrl:async({url:s,alt:g})=>{X(()=>{const x=Re(d.current,s,g,B.current);x&&(ee(x,d.current,B.current),M.current=x)})},onSubmitFile:async({file:s,alt:g})=>{const x=await Be(s,{...T,onUpload:w,language:C,messages:B.current});X(()=>{const _=Re(d.current,x,g,B.current);_&&(ee(_,d.current,B.current),M.current=_)})}}),l.jsx(Lt,{open:et&&!U,initialAlt:tt,onClose:()=>ve(!1),t:N,onSubmit:({alt:s})=>{var x;const g=M.current;!g||!((x=d.current)!=null&&x.contains(g))||(Jt(g,s,B.current),$(q()),L())}})]})});exports.TeemEditor=We;exports.createHistory=Pe;exports.default=We;exports.flattenStyleSpans=Q;exports.getBlockOptions=_e;exports.getDefaultDir=Ie;exports.getMessages=xe;exports.isSafeHref=De;exports.isSafeImageSrc=Ue;exports.locales=be;exports.processImageUpload=Be;exports.resolveLanguage=oe;exports.sanitizeHtml=H;exports.uploadDefaults=He;exports.validateImageFile=Oe;
2
+ //# sourceMappingURL=teem-editor.cjs.map