@wiliarko/wysiwyg-editor 1.0.1 โ†’ 1.0.4

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.
@@ -0,0 +1,316 @@
1
+ # Installation Guide โ€” @wiliarko/wysiwyg-editor
2
+
3
+ ## NPM Installation
4
+
5
+ ### 1. Install Package
6
+ ```bash
7
+ npm install @wiliarko/wysiwyg-editor
8
+ ```
9
+
10
+ ### 2. Add to HTML
11
+ ```html
12
+ <link rel="stylesheet" href="node_modules/@wiliarko/wysiwyg-editor/wysiwyg.min.css">
13
+ <script src="node_modules/@wiliarko/wysiwyg-editor/wysiwyg.min.js"></script>
14
+ ```
15
+
16
+ ### 3. Initialize
17
+ ```html
18
+ <div id="my-editor"></div>
19
+
20
+ <script>
21
+ const editor = WysiwygEditor.create('#my-editor', {
22
+ uploadUrl: '/api/upload-image', // optional
23
+ placeholder: 'Write something...',
24
+ minHeight: 300
25
+ });
26
+ </script>
27
+ ```
28
+
29
+ ---
30
+
31
+ ## Framework Integration
32
+
33
+ ### Laravel
34
+ ```bash
35
+ npm install @wiliarko/wysiwyg-editor
36
+ ```
37
+
38
+ **In Blade template:**
39
+ ```blade
40
+ <link rel="stylesheet" href="{{ asset('node_modules/@wiliarko/wysiwyg-editor/wysiwyg.min.css') }}">
41
+ <script src="{{ asset('node_modules/@wiliarko/wysiwyg-editor/wysiwyg.min.js') }}"></script>
42
+
43
+ <div id="editor"></div>
44
+
45
+ <script>
46
+ document.addEventListener('DOMContentLoaded', () => {
47
+ const editor = WysiwygEditor.create('#editor', {
48
+ uploadUrl: '{{ route("image.upload") }}'
49
+ });
50
+
51
+ document.querySelector('form').addEventListener('submit', (e) => {
52
+ document.querySelector('[name="content"]').value = editor.getHTML();
53
+ });
54
+ });
55
+ </script>
56
+ ```
57
+
58
+ ### Vue 3
59
+ ```bash
60
+ npm install @wiliarko/wysiwyg-editor
61
+ ```
62
+
63
+ **In component:**
64
+ ```vue
65
+ <template>
66
+ <div class="editor-container">
67
+ <div ref="editorElement"></div>
68
+ <p>{{ content }}</p>
69
+ </div>
70
+ </template>
71
+
72
+ <script setup>
73
+ import { ref, onMounted, onBeforeUnmount } from 'vue'
74
+
75
+ const editorElement = ref(null)
76
+ const content = ref('')
77
+ let editor = null
78
+
79
+ onMounted(() => {
80
+ editor = WysiwygEditor.create(editorElement.value, {
81
+ uploadUrl: '/api/upload-image',
82
+ onChange: (html) => {
83
+ content.value = html
84
+ }
85
+ })
86
+ })
87
+
88
+ onBeforeUnmount(() => {
89
+ editor?.destroy()
90
+ })
91
+ </script>
92
+ ```
93
+
94
+ ### React
95
+ ```bash
96
+ npm install @wiliarko/wysiwyg-editor
97
+ ```
98
+
99
+ **In component:**
100
+ ```jsx
101
+ import { useEffect, useRef } from 'react'
102
+
103
+ export function Editor() {
104
+ const editorRef = useRef(null)
105
+ const editorInstance = useRef(null)
106
+ const [content, setContent] = React.useState('')
107
+
108
+ useEffect(() => {
109
+ if (typeof window !== 'undefined' && window.WysiwygEditor) {
110
+ editorInstance.current = WysiwygEditor.create(editorRef.current, {
111
+ uploadUrl: '/api/upload-image',
112
+ onChange: (html) => setContent(html)
113
+ })
114
+
115
+ return () => editorInstance.current?.destroy()
116
+ }
117
+ }, [])
118
+
119
+ return (
120
+ <div>
121
+ <div ref={editorRef} style={{ minHeight: '400px' }} />
122
+ <p>Content: {content}</p>
123
+ </div>
124
+ )
125
+ }
126
+ ```
127
+
128
+ ### Next.js
129
+ ```bash
130
+ npm install @wiliarko/wysiwyg-editor
131
+ ```
132
+
133
+ **In component:**
134
+ ```jsx
135
+ import { useEffect, useRef } from 'react'
136
+
137
+ export default function Editor() {
138
+ const editorRef = useRef(null)
139
+ const editorInstance = useRef(null)
140
+
141
+ useEffect(() => {
142
+ // Dynamic import to avoid SSR issues
143
+ if (typeof window !== 'undefined') {
144
+ require('@wiliarko/wysiwyg-editor')
145
+
146
+ editorInstance.current = window.WysiwygEditor.create(editorRef.current, {
147
+ uploadUrl: '/api/upload-image'
148
+ })
149
+ }
150
+
151
+ return () => editorInstance.current?.destroy()
152
+ }, [])
153
+
154
+ return <div ref={editorRef} style={{ minHeight: '400px' }} />
155
+ }
156
+ ```
157
+
158
+ ### Nuxt 3
159
+ ```bash
160
+ npm install @wiliarko/wysiwyg-editor
161
+ ```
162
+
163
+ **plugins/wysiwyg.client.ts:**
164
+ ```typescript
165
+ export default defineNuxtPlugin(() => {
166
+ if (process.client) {
167
+ return {
168
+ provide: {
169
+ wysiwyg: window.WysiwygEditor
170
+ }
171
+ }
172
+ }
173
+ })
174
+ ```
175
+
176
+ **In component:**
177
+ ```vue
178
+ <template>
179
+ <div ref="editor"></div>
180
+ </template>
181
+
182
+ <script setup>
183
+ const { $wysiwyg } = useNuxtApp()
184
+ const editor = ref(null)
185
+
186
+ onMounted(() => {
187
+ $wysiwyg.create(editor.value, {
188
+ uploadUrl: '/api/upload-image'
189
+ })
190
+ })
191
+ </script>
192
+ ```
193
+
194
+ ---
195
+
196
+ ## CDN Installation
197
+
198
+ ### From jsDelivr CDN
199
+ ```html
200
+ <link rel="stylesheet"
201
+ href="https://cdn.jsdelivr.net/npm/@wiliarko/wysiwyg-editor@1.0.3/wysiwyg.min.css">
202
+ <script src="https://cdn.jsdelivr.net/npm/@wiliarko/wysiwyg-editor@1.0.3/wysiwyg.min.js"></script>
203
+
204
+ <div id="editor"></div>
205
+
206
+ <script>
207
+ const editor = WysiwygEditor.create('#editor')
208
+ </script>
209
+ ```
210
+
211
+ ### From unpkg CDN
212
+ ```html
213
+ <link rel="stylesheet"
214
+ href="https://unpkg.com/@wiliarko/wysiwyg-editor@1.0.3/wysiwyg.min.css">
215
+ <script src="https://unpkg.com/@wiliarko/wysiwyg-editor@1.0.3/wysiwyg.min.js"></script>
216
+
217
+ <div id="editor"></div>
218
+
219
+ <script>
220
+ const editor = WysiwygEditor.create('#editor')
221
+ </script>
222
+ ```
223
+
224
+ ---
225
+
226
+ ## Configuration
227
+
228
+ ### Basic Setup
229
+ ```javascript
230
+ const editor = WysiwygEditor.create('#editor', {
231
+ placeholder: 'Start typing...',
232
+ minHeight: 300
233
+ })
234
+ ```
235
+
236
+ ### With Upload
237
+ ```javascript
238
+ const editor = WysiwygEditor.create('#editor', {
239
+ uploadUrl: '/api/upload',
240
+ minHeight: 400,
241
+ onChange: (html) => console.log(html)
242
+ })
243
+ ```
244
+
245
+ ### With Input Sync
246
+ ```html
247
+ <textarea id="content" name="content" hidden></textarea>
248
+ <div id="editor"></div>
249
+
250
+ <script>
251
+ const editor = WysiwygEditor.create('#editor', {
252
+ syncInput: '#content',
253
+ uploadUrl: '/api/upload'
254
+ })
255
+ </script>
256
+ ```
257
+
258
+ ---
259
+
260
+ ## Verify Installation
261
+
262
+ **Check in browser console:**
263
+ ```javascript
264
+ console.log(window.WysiwygEditor) // Should show WysiwygEditor class
265
+ console.log(WysiwygEditor.getPlugins()) // Should list all plugins
266
+ ```
267
+
268
+ ---
269
+
270
+ ## Troubleshooting
271
+
272
+ ### "WysiwygEditor is not defined"
273
+ - Verify `<script src="wysiwyg.min.js">` is in HTML
274
+ - Check script loads before your initialization code
275
+ - Hard refresh (Ctrl+Shift+R)
276
+
277
+ ### "CSS not loading / styles broken"
278
+ - Verify `<link>` tag for CSS
279
+ - Check correct path to `wysiwyg.min.css`
280
+ - Ensure CSS loads before JS
281
+
282
+ ### "Upload not working"
283
+ - Set `uploadUrl` to your server endpoint
284
+ - Server must return `{ "ok": true, "url": "..." }`
285
+ - Check CORS if different origin
286
+
287
+ ---
288
+
289
+ ## Version Updates
290
+
291
+ ### Check current version
292
+ ```bash
293
+ npm list @wiliarko/wysiwyg-editor
294
+ ```
295
+
296
+ ### Update to latest
297
+ ```bash
298
+ npm update @wiliarko/wysiwyg-editor
299
+ ```
300
+
301
+ ### Install specific version
302
+ ```bash
303
+ npm install @wiliarko/wysiwyg-editor@1.0.3
304
+ ```
305
+
306
+ ---
307
+
308
+ ## Support & Issues
309
+
310
+ - **GitHub:** [github.com/wiliarko/wysiwyg-editor](https://github.com/wiliarko/wysiwyg-editor)
311
+ - **NPM:** [@wiliarko/wysiwyg-editor](https://www.npmjs.com/package/@wiliarko/wysiwyg-editor)
312
+ - **Issues:** Report at GitHub Issues
313
+
314
+ ---
315
+
316
+ **Happy editing! ๐ŸŽ‰**
package/README.md CHANGED
@@ -71,22 +71,207 @@ editor.destroy();
71
71
  }
72
72
  ```
73
73
 
74
- ## Upload Endpoint Format
74
+ ## Image Alignment
75
75
 
76
- Server should respond with JSON:
76
+ Images can be aligned left, right, center, or as block elements.
77
77
 
78
+ ### In Editor
79
+ Click image โ†’ toolbar appears โ†’ choose alignment button
80
+
81
+ ### In View
82
+ When you display the saved HTML content, image alignment styles are **automatically included** in `wysiwyg.min.css`.
83
+
84
+ Just load the CSS:
85
+ ```html
86
+ <link rel="stylesheet" href="wysiwyg.min.css">
87
+ <!-- Images will display with correct alignment automatically -->
88
+ ```
89
+
90
+ ### Alignment Classes (Generated by Editor)
91
+
92
+ | Alignment | CSS Class | Behavior |
93
+ |-----------|-----------|----------|
94
+ | Default | (no class) | Inline with text |
95
+ | Left | `wy-img-align-left` | Float left, text wraps right |
96
+ | Right | `wy-img-align-right` | Float right, text wraps left |
97
+ | Center | `wy-img-align-center` | Centered, full width block |
98
+ | Block Left | `wy-img-align-block-left` | Block element, margin left 0 |
99
+ | Block Right | `wy-img-align-block-right` | Block element, margin right 0 |
100
+
101
+ ### Example HTML Output
102
+
103
+ ```html
104
+ <!-- User aligned image left in editor -->
105
+ <img src="/uploads/image.jpg" class="wy-img-align-left" alt="Description" />
106
+ <p>Text will wrap around this image...</p>
107
+ ```
108
+
109
+ **CSS in `wysiwyg.min.css` automatically styles this correctly!**
110
+
111
+ ### Quick Setup
112
+
113
+ **Option 1: URL Only (No Upload)**
114
+ ```html
115
+ <!-- Users can only insert from URL, no file upload -->
116
+ <div data-wysiwyg
117
+ data-wysiwyg-height="400"
118
+ data-wysiwyg-input="#content"></div>
119
+ ```
120
+
121
+ **Option 2: With File Upload**
122
+ ```html
123
+ <!-- File upload enabled -->
124
+ <div data-wysiwyg
125
+ data-wysiwyg-upload-url="/api/upload-image"
126
+ data-wysiwyg-height="400"
127
+ data-wysiwyg-input="#content"></div>
128
+ ```
129
+
130
+ ### Upload Endpoint Format
131
+
132
+ Your server endpoint must:
133
+ 1. Accept `POST` request with `multipart/form-data`
134
+ 2. Field name: `image` (binary file)
135
+ 3. Return JSON response
136
+
137
+ **Request:**
138
+ ```
139
+ POST /api/upload-image
140
+ Content-Type: multipart/form-data
141
+
142
+ Field: "image" (File)
143
+ ```
144
+
145
+ **Response (Success):**
78
146
  ```json
79
147
  {
80
- "success": true,
81
- "url": "https://yourserver.com/uploads/image.jpg"
148
+ "ok": true,
149
+ "url": "https://yourserver.com/uploads/image-xyz.jpg"
82
150
  }
83
151
  ```
84
152
 
85
- Request:
153
+ **Response (Error):**
154
+ ```json
155
+ {
156
+ "ok": false,
157
+ "error": "File too large"
158
+ }
86
159
  ```
87
- POST /your-upload-endpoint
88
- Content-Type: multipart/form-data
89
- Field: "file" (binary image)
160
+
161
+ ### Server Implementation
162
+
163
+ #### Node.js/Express
164
+ ```javascript
165
+ const express = require('express');
166
+ const multer = require('multer');
167
+ const path = require('path');
168
+
169
+ const upload = multer({
170
+ dest: 'public/uploads/',
171
+ limits: { fileSize: 5 * 1024 * 1024 },
172
+ fileFilter: (req, file, cb) => {
173
+ if (file.mimetype.startsWith('image/')) {
174
+ cb(null, true);
175
+ } else {
176
+ cb(new Error('Only images allowed'));
177
+ }
178
+ }
179
+ });
180
+
181
+ app.post('/api/upload-image', upload.single('image'), (req, res) => {
182
+ if (!req.file) {
183
+ return res.json({ ok: false, error: 'No file uploaded' });
184
+ }
185
+
186
+ const url = `/uploads/${req.file.filename}`;
187
+ res.json({ ok: true, url });
188
+ });
189
+ ```
190
+
191
+ #### PHP (Laravel)
192
+ ```php
193
+ // routes/api.php
194
+ Route::post('/upload-image', [ImageController::class, 'upload']);
195
+
196
+ // app/Http/Controllers/ImageController.php
197
+ class ImageController extends Controller
198
+ {
199
+ public function upload(Request $request)
200
+ {
201
+ $request->validate([
202
+ 'image' => 'required|image|max:5120'
203
+ ]);
204
+
205
+ $path = $request->file('image')->store('uploads', 'public');
206
+
207
+ return response()->json([
208
+ 'ok' => true,
209
+ 'url' => asset('storage/' . $path)
210
+ ]);
211
+ }
212
+ }
213
+ ```
214
+
215
+ #### PHP (Vanilla)
216
+ ```php
217
+ <?php
218
+ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['image'])) {
219
+ $file = $_FILES['image'];
220
+
221
+ // Validate
222
+ if ($file['size'] > 5 * 1024 * 1024) {
223
+ echo json_encode(['ok' => false, 'error' => 'File too large']);
224
+ exit;
225
+ }
226
+
227
+ if (!strpos($file['type'], 'image/')) {
228
+ echo json_encode(['ok' => false, 'error' => 'Only images allowed']);
229
+ exit;
230
+ }
231
+
232
+ // Save
233
+ $filename = uniqid() . '-' . basename($file['name']);
234
+ move_uploaded_file($file['tmp_name'], 'uploads/' . $filename);
235
+
236
+ echo json_encode([
237
+ 'ok' => true,
238
+ 'url' => '/uploads/' . $filename
239
+ ]);
240
+ }
241
+ ```
242
+
243
+ #### Python/Django
244
+ ```python
245
+ # urls.py
246
+ from django.urls import path
247
+ from . import views
248
+
249
+ urlpatterns = [
250
+ path('api/upload-image/', views.upload_image, name='upload_image'),
251
+ ]
252
+
253
+ # views.py
254
+ from django.http import JsonResponse
255
+ from django.views.decorators.http import require_http_methods
256
+
257
+ @require_http_methods(["POST"])
258
+ def upload_image(request):
259
+ if 'image' not in request.FILES:
260
+ return JsonResponse({'ok': False, 'error': 'No file uploaded'})
261
+
262
+ image = request.FILES['image']
263
+
264
+ if image.size > 5 * 1024 * 1024:
265
+ return JsonResponse({'ok': False, 'error': 'File too large'})
266
+
267
+ # Save file
268
+ from django.core.files.storage import default_storage
269
+ path = default_storage.save(f'uploads/{image.name}', image)
270
+
271
+ return JsonResponse({
272
+ 'ok': True,
273
+ 'url': default_storage.url(path)
274
+ })
90
275
  ```
91
276
 
92
277
  ## Toolbar Plugins
@@ -250,16 +435,92 @@ WysiwygEditor.registerPlugin({
250
435
  - **No dependencies**: Faster load, zero conflicts
251
436
  - **contenteditable based**: Native browser support
252
437
 
253
- ## License
438
+ ## Troubleshooting
439
+
440
+ ### Upload Returns 404
441
+ **Problem:** `POST /wysiwyg/upload-image 404 (Not Found)`
442
+
443
+ **Solution:** Set custom upload URL matching your endpoint
444
+ ```html
445
+ <div data-wysiwyg
446
+ data-wysiwyg-upload-url="/your-api/upload"
447
+ style="height: 400px;"></div>
448
+ ```
449
+
450
+ ### Upload Returns 403 (CSRF/Auth)
451
+ **Problem:** Upload fails with 403 Forbidden
452
+
453
+ **Solution:** Add CSRF token (Laravel) or auth headers
454
+ ```php
455
+ // Laravel: Add middleware or CSRF token
456
+ Route::post('/upload', [...])
457
+ ->middleware('web'); // includes CSRF protection
458
+ ```
459
+
460
+ ### Image Size Limit
461
+ **Problem:** "File too large" error
462
+
463
+ **Editor limit:** 5MB (max file size)
464
+ **Configure in your server:** Allow at least 5MB
465
+
466
+ ```javascript
467
+ // Node.js
468
+ limits: { fileSize: 5 * 1024 * 1024 }
469
+ ```
470
+
471
+ ### No Upload Button Appears
472
+ **Problem:** Upload icon not showing in toolbar
473
+
474
+ **Solution:** Make sure `uploadUrl` is set
475
+ ```html
476
+ <!-- โœ— Wrong - no upload url -->
477
+ <div data-wysiwyg></div>
478
+
479
+ <!-- โœ“ Correct - upload enabled -->
480
+ <div data-wysiwyg
481
+ data-wysiwyg-upload-url="/api/upload"></div>
482
+ ```
483
+
484
+ ### "Cannot read properties of undefined"
485
+ **Problem:** `WysiwygEditor is not defined`
486
+
487
+ **Solution:** Ensure script is loaded before initialization
488
+ ```html
489
+ <!-- โœ“ Correct order -->
490
+ <link rel="stylesheet" href="wysiwyg.min.css">
491
+ <script src="wysiwyg.min.js"></script>
492
+
493
+ <script>
494
+ const editor = WysiwygEditor.create('#editor')
495
+ </script>
496
+ ```
254
497
 
255
- MIT
498
+ ## Browser Support
499
+
500
+ - Chrome/Edge 60+
501
+ - Firefox 55+
502
+ - Safari 11+
503
+ - Mobile browsers (iOS Safari 12+, Chrome Mobile)
256
504
 
257
- ## Support
505
+ ## Performance Tips
258
506
 
259
- For issues, features, or questions:
260
- - GitHub: [github.com/yourusername/wysiwyg-editor](https://github.com/yourusername/wysiwyg-editor)
261
- - Email: support@example.com
507
+ 1. **Lazy load** for large pages
508
+ ```javascript
509
+ if (document.querySelector('[data-wysiwyg]')) {
510
+ const script = document.createElement('script');
511
+ script.src = 'wysiwyg.min.js';
512
+ document.body.appendChild(script);
513
+ }
514
+ ```
262
515
 
263
- ---
516
+ 2. **Compress images** on upload
517
+ ```javascript
518
+ // Server-side: Use ImageMagick, ffmpeg, Pillow, etc.
519
+ ```
264
520
 
265
- **Made with โค๏ธ by [Your Team]**
521
+ 3. **Use CDN** for bundle
522
+ ```html
523
+ <link rel="stylesheet"
524
+ href="https://cdn.example.com/wysiwyg.min.css">
525
+ <script src="https://cdn.example.com/wysiwyg.min.js"></script>
526
+ ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wiliarko/wysiwyg-editor",
3
- "version": "1.0.1",
3
+ "version": "1.0.4",
4
4
  "description": "Custom rich-text editor with zero dependencies. Supports formatting, images, tables, mentions, emojis, and more.",
5
5
  "main": "wysiwyg.min.js",
6
6
  "module": "wysiwyg.min.js",
@@ -8,9 +8,10 @@
8
8
  "files": [
9
9
  "wysiwyg.min.js",
10
10
  "wysiwyg.min.css",
11
- "demo.html",
12
11
  "README.md",
13
- "LICENSE"
12
+ "INSTALLATION.md",
13
+ "LICENSE",
14
+ "wysiwyg.d.ts"
14
15
  ],
15
16
  "scripts": {
16
17
  "test": "echo \"No tests for dist package\""
package/wysiwyg.d.ts ADDED
@@ -0,0 +1,86 @@
1
+ /**
2
+ * WYSIWYG Editor Standalone
3
+ * TypeScript Definitions
4
+ */
5
+
6
+ export interface WysiwygEditorOptions {
7
+ /** Editor placeholder text */
8
+ placeholder?: string;
9
+ /** Minimum height in pixels */
10
+ minHeight?: number;
11
+ /** Image upload endpoint URL */
12
+ uploadUrl?: string;
13
+ /** Custom upload function */
14
+ uploadFn?: (file: File, url: string, onProgress: (percent: number) => void) => Promise<string>;
15
+ /** Content change callback */
16
+ onChange?: (html: string) => void;
17
+ /** Hidden input selector to sync content */
18
+ syncInput?: string;
19
+ }
20
+
21
+ export interface WysiwygPlugin {
22
+ name: string;
23
+ title: string;
24
+ icon: string;
25
+ group?: string;
26
+ action: (editor: WysiwygEditor) => void;
27
+ isActive?: (editor: WysiwygEditor) => boolean;
28
+ }
29
+
30
+ /**
31
+ * WYSIWYG Editor Class
32
+ */
33
+ export class WysiwygEditor {
34
+ constructor(element: HTMLElement | string, options?: WysiwygEditorOptions);
35
+
36
+ /** Get current editor content as HTML */
37
+ getHTML(): string;
38
+
39
+ /** Set editor content */
40
+ setHTML(html: string): void;
41
+
42
+ /** Focus on editor */
43
+ focus(): void;
44
+
45
+ /** Destroy editor and cleanup */
46
+ destroy(): void;
47
+
48
+ /** Toggle between WYSIWYG and HTML source mode */
49
+ toggleSource(): void;
50
+
51
+ /** Check if in HTML source mode */
52
+ isSourceMode(): boolean;
53
+
54
+ /** Open image insertion dialog */
55
+ openImageDialog(): void;
56
+
57
+ /** Get contenteditable element */
58
+ getArea(): HTMLElement;
59
+
60
+ /** Execute browser command */
61
+ exec(command: string, value?: string | null): void;
62
+
63
+ /** Query command state */
64
+ queryCommand(command: string): boolean;
65
+
66
+ /** Get current active block element */
67
+ getActiveBlock(): string;
68
+
69
+ /** Register a custom plugin (static) */
70
+ static registerPlugin(plugin: WysiwygPlugin): void;
71
+
72
+ /** Get all registered plugins (static) */
73
+ static getPlugins(): WysiwygPlugin[];
74
+
75
+ /** Create editor instance (static factory method) */
76
+ static create(element: HTMLElement | string, options?: WysiwygEditorOptions): WysiwygEditor;
77
+ }
78
+
79
+ /** Global namespace */
80
+ declare global {
81
+ interface Window {
82
+ WysiwygEditor: typeof WysiwygEditor;
83
+ }
84
+ }
85
+
86
+ export default WysiwygEditor;
package/wysiwyg.min.css CHANGED
@@ -1 +1 @@
1
- .wysiwyg-editor{--wy-border: #e5e7eb;--wy-border-focus: #6366f1;--wy-bg: #ffffff;--wy-bg-toolbar: #f9fafb;--wy-text: #111827;--wy-muted: #9ca3af;--wy-btn-hover: #f3f4f6;--wy-btn-active: #e0e7ff;--wy-btn-active-fg:#4338ca;--wy-radius: .75rem;--wy-sep: #e5e7eb;display:flex;flex-direction:column;border:1.5px solid var(--wy-border);border-radius:var(--wy-radius);background:var(--wy-bg);overflow:hidden;transition:border-color .15s ease,box-shadow .15s ease;font-family:inherit}.wysiwyg-editor:focus-within{border-color:var(--wy-border-focus);box-shadow:0 0 0 3px #6366f11f}.wysiwyg-toolbar{display:flex;flex-wrap:wrap;align-items:center;gap:2px;padding:6px 8px;background:var(--wy-bg-toolbar);border-bottom:1px solid var(--wy-border)}.wysiwyg-btn{display:inline-flex;align-items:center;justify-content:center;width:30px;height:30px;padding:0;border:none;border-radius:6px;background:transparent;color:var(--wy-text);cursor:pointer;transition:background .1s ease,color .1s ease;flex-shrink:0}.wysiwyg-btn:hover{background:var(--wy-btn-hover)}.wysiwyg-btn.is-active{background:var(--wy-btn-active);color:var(--wy-btn-active-fg)}.wysiwyg-btn span{display:inline-flex;align-items:center;justify-content:center;width:100%;height:100%}.wysiwyg-separator{width:1px;height:20px;background:var(--wy-sep);margin:0 4px;flex-shrink:0}.wysiwyg-area{flex:1;padding:14px 16px;outline:none;color:var(--wy-text);line-height:1.7;word-break:break-word;overflow-y:auto}.wysiwyg-area:empty:before{content:attr(data-placeholder);color:var(--wy-muted);pointer-events:none}.wysiwyg-area h1,.wysiwyg-area h2,.wysiwyg-area h3{font-weight:700;line-height:1.3;margin-top:1em;margin-bottom:.4em;color:var(--wy-text)}.wysiwyg-area h1{font-size:1.75em}.wysiwyg-area h2{font-size:1.35em}.wysiwyg-area h3{font-size:1.1em}.wysiwyg-area h1:first-child,.wysiwyg-area h2:first-child,.wysiwyg-area h3:first-child{margin-top:0}.wysiwyg-area p{margin:0 0 .75em}.wysiwyg-area p:last-child{margin-bottom:0}.wysiwyg-area strong{font-weight:700}.wysiwyg-area em{font-style:italic}.wysiwyg-area u{text-decoration:underline}.wysiwyg-area s{text-decoration:line-through}.wysiwyg-area ul,.wysiwyg-area ol{padding-left:1.5em;margin:0 0 .75em}.wysiwyg-area ul{list-style-type:disc}.wysiwyg-area ol{list-style-type:decimal}.wysiwyg-area li{margin-bottom:.25em}.wysiwyg-area blockquote{border-left:3px solid var(--wy-border-focus);margin:.75em 0;padding:.5em 1em;background:#6366f10d;border-radius:0 6px 6px 0;color:#4b5563}.wysiwyg-area a{color:var(--wy-btn-active-fg);text-decoration:underline}.wysiwyg-area a:hover{opacity:.8}.wysiwyg-source-area{flex:1;padding:14px 16px;outline:none;color:#a5b4fc;background:#1e1b4b;font-family:Fira Code,Cascadia Code,Consolas,Monaco,monospace;font-size:.8125rem;line-height:1.7;resize:none;border:none;width:100%;box-sizing:border-box;min-height:200px}.wysiwyg-source-area:focus{outline:none}.dark .wysiwyg-source-area{background:#0f0c29}@media(prefers-color-scheme:dark){.wysiwyg-editor{--wy-border: #374151;--wy-bg: #1f2937;--wy-bg-toolbar: #111827;--wy-text: #f9fafb;--wy-muted: #6b7280;--wy-btn-hover: #374151;--wy-btn-active: #312e81;--wy-btn-active-fg:#a5b4fc;--wy-sep: #374151}.wysiwyg-area blockquote{background:#6366f11a;color:#d1d5db}}.dark .wysiwyg-editor{--wy-border: #374151;--wy-bg: #1f2937;--wy-bg-toolbar: #111827;--wy-text: #f9fafb;--wy-muted: #6b7280;--wy-btn-hover: #374151;--wy-btn-active: #312e81;--wy-btn-active-fg:#a5b4fc;--wy-sep: #374151}.dark .wysiwyg-area blockquote{background:#6366f11a;color:#d1d5db}.wysiwyg-area img{max-width:100%;height:auto;border-radius:4px;cursor:pointer;vertical-align:bottom;transition:outline-color .1s ease}.wysiwyg-area img:hover{outline:2px solid rgb(99 102 241 / .35);outline-offset:2px}.wysiwyg-area img.wy-img-align-center{display:block;float:none;margin:.5em auto}.wysiwyg-area img.wy-img-align-left{float:left;margin:.25em 1.25em .5em 0}.wysiwyg-area img.wy-img-align-right{float:right;margin:.25em 0 .5em 1.25em}.wysiwyg-area img.wy-img-align-block-left{display:block;float:none;margin:.5em auto .5em 0}.wysiwyg-area img.wy-img-align-block-right{display:block;float:none;margin:.5em 0 .5em auto}.wy-img-uploading{display:inline-block;padding:4px 10px;border-radius:6px;background:#6366f11a;color:#4338ca;font-size:.8125em;font-style:italic}.wy-img-uploading--error{background:#f43f5e1a;color:#e11d48}.wy-img-toolbar{position:fixed;z-index:10000;display:none;align-items:center;gap:2px;padding:4px;background:#fff;border:1px solid #e5e7eb;border-radius:8px;box-shadow:0 8px 24px #00000026}.wy-img-toolbar button{display:inline-flex;align-items:center;justify-content:center;width:26px;height:26px;padding:0;border:none;border-radius:6px;background:transparent;color:#111827;cursor:pointer}.wy-img-toolbar button:hover{background:#f3f4f6}.wy-img-toolbar button.is-active{background:#e0e7ff;color:#4338ca}.wy-img-toolbar__sep{width:1px;height:18px;background:#e5e7eb;margin:0 4px;flex-shrink:0}.wy-img-resize-box{position:fixed;z-index:9999;display:none;box-sizing:border-box;border:1.5px dashed #6366f1;pointer-events:none}.wy-img-resize-handle{position:absolute;width:10px;height:10px;background:#fff;border:2px solid #6366f1;border-radius:2px;pointer-events:all}.wy-img-resize-handle[data-dir=nw]{top:-6px;left:-6px;cursor:nwse-resize}.wy-img-resize-handle[data-dir=ne]{top:-6px;right:-6px;cursor:nesw-resize}.wy-img-resize-handle[data-dir=sw]{bottom:-6px;left:-6px;cursor:nesw-resize}.wy-img-resize-handle[data-dir=se]{bottom:-6px;right:-6px;cursor:nwse-resize}.wy-img-modal{position:fixed;inset:0;z-index:10050;display:flex;align-items:center;justify-content:center}.wy-img-modal__backdrop{position:absolute;inset:0;background:#0f0f1480;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}.wy-img-modal__box{position:relative;width:100%;max-width:440px;max-height:90vh;overflow-y:auto;margin:16px;background:#fff;border-radius:16px;box-shadow:0 20px 60px #0000004d}.wy-img-modal__head{display:flex;align-items:center;justify-content:space-between;padding:16px 20px;border-bottom:1px solid #e5e7eb}.wy-img-modal__title{font-weight:600;font-size:.9375rem;color:#111827}.wy-img-modal__close{display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;border:none;border-radius:8px;background:transparent;color:#9ca3af;cursor:pointer}.wy-img-modal__close:hover{background:#f3f4f6;color:#111827}.wy-img-modal__tabs{display:flex;gap:6px;padding:14px 20px 0}.wy-img-tab{flex:1;padding:8px 12px;border:none;border-radius:8px;background:#f9fafb;color:#6b7280;font-size:.8125rem;font-weight:500;cursor:pointer;transition:background .1s ease,color .1s ease}.wy-img-tab.is-active{background:#e0e7ff;color:#4338ca}.wy-img-modal__panel{padding:16px 20px 0}.wy-img-dropzone{position:relative;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:6px;padding:28px 16px;border:2px dashed #e5e7eb;border-radius:12px;cursor:pointer;text-align:center;transition:border-color .15s ease,background .15s ease}.wy-img-dropzone:hover,.wy-img-dropzone.is-dragover{border-color:#6366f1;background:#6366f10d}.wy-img-dropzone__text{margin:0;font-size:.8125rem;color:#111827}.wy-img-dropzone__text span{color:#6366f1;font-weight:600}.wy-img-dropzone__hint{margin:0;font-size:.6875rem;color:#9ca3af}.wy-img-file{position:absolute;width:1px;height:1px;overflow:hidden;opacity:0}.wy-img-preview{position:relative;display:block;width:max-content;max-width:100%;margin:12px auto 0}.wy-img-preview__img{display:block;max-height:180px;max-width:100%;border-radius:8px}.wy-img-preview__remove{position:absolute;top:-8px;right:-8px;width:22px;height:22px;border:none;border-radius:999px;background:#111827;color:#fff;font-size:14px;line-height:1;cursor:pointer}.wy-img-modal__progress{margin-top:12px;height:6px;border-radius:999px;background:#f3f4f6;overflow:hidden}.wy-img-modal__progress-bar{height:100%;width:0%;background:linear-gradient(90deg,#6366f1,#8b5cf6);transition:width .15s ease}.wy-img-url-label{display:block;font-size:.8125rem;font-weight:500;color:#111827}.wy-img-url-input,.wy-img-alt-input,.wy-img-width-input,.wy-img-align-select{display:block;width:100%;margin-top:6px;padding:8px 12px;border:1.5px solid #e5e7eb;border-radius:8px;background:#fff;color:#111827;font-size:.8125rem;font-family:inherit;box-sizing:border-box}.wy-img-url-input:focus,.wy-img-alt-input:focus,.wy-img-width-input:focus,.wy-img-align-select:focus{outline:none;border-color:#6366f1;box-shadow:0 0 0 3px #6366f11f}.wy-img-url-preview img{max-height:120px;max-width:100%;border-radius:8px}.wy-img-modal__options{display:flex;gap:12px;padding:4px 20px 0}.wy-img-opt-label{flex:1;font-size:.8125rem;font-weight:500;color:#111827}.wy-img-modal__error{margin:12px 20px 0;padding:8px 12px;border-radius:8px;background:#f43f5e1a;color:#e11d48;font-size:.75rem}.wy-img-modal__footer{display:flex;justify-content:flex-end;gap:8px;padding:16px 20px 20px}.wy-img-modal__cancel,.wy-img-modal__insert{padding:8px 18px;border:none;border-radius:8px;font-size:.8125rem;font-weight:600;cursor:pointer}.wy-img-modal__cancel{background:#f3f4f6;color:#111827}.wy-img-modal__cancel:hover{background:#e5e7eb}.wy-img-modal__insert{background:linear-gradient(90deg,#4f46e5,#7c3aed);color:#fff}.wy-img-modal__insert:disabled{opacity:.4;cursor:not-allowed}@media(prefers-color-scheme:dark){.wy-img-toolbar{background:#1f2937;border-color:#374151}.wy-img-toolbar button{color:#f9fafb}.wy-img-toolbar button:hover{background:#374151}.wy-img-toolbar button.is-active{background:#312e81;color:#a5b4fc}.wy-img-toolbar__sep{background:#374151}.wy-img-modal__box{background:#1f2937}.wy-img-modal__head{border-color:#374151}.wy-img-modal__title{color:#f9fafb}.wy-img-modal__close{color:#9ca3af}.wy-img-modal__close:hover{background:#374151;color:#f9fafb}.wy-img-tab{background:#111827;color:#9ca3af}.wy-img-tab.is-active{background:#312e81;color:#a5b4fc}.wy-img-dropzone{border-color:#374151}.wy-img-dropzone:hover,.wy-img-dropzone.is-dragover{border-color:#6366f1;background:#6366f11a}.wy-img-dropzone__text,.wy-img-url-label,.wy-img-opt-label{color:#f9fafb}.wy-img-url-input,.wy-img-alt-input,.wy-img-width-input,.wy-img-align-select{background:#111827;border-color:#374151;color:#f9fafb}.wy-img-modal__progress{background:#111827}.wy-img-modal__cancel{background:#374151;color:#f9fafb}.wy-img-modal__cancel:hover{background:#4b5563}}.dark .wy-img-toolbar{background:#1f2937;border-color:#374151}.dark .wy-img-toolbar button{color:#f9fafb}.dark .wy-img-toolbar button:hover{background:#374151}.dark .wy-img-toolbar button.is-active{background:#312e81;color:#a5b4fc}.dark .wy-img-toolbar__sep{background:#374151}.dark .wy-img-modal__box{background:#1f2937}.dark .wy-img-modal__head{border-color:#374151}.dark .wy-img-modal__title{color:#f9fafb}.dark .wy-img-modal__close{color:#9ca3af}.dark .wy-img-modal__close:hover{background:#374151;color:#f9fafb}.dark .wy-img-tab{background:#111827;color:#9ca3af}.dark .wy-img-tab.is-active{background:#312e81;color:#a5b4fc}.dark .wy-img-dropzone{border-color:#374151}.dark .wy-img-dropzone:hover,.dark .wy-img-dropzone.is-dragover{border-color:#6366f1;background:#6366f11a}.dark .wy-img-dropzone__text,.dark .wy-img-url-label,.dark .wy-img-opt-label{color:#f9fafb}.dark .wy-img-url-input,.dark .wy-img-alt-input,.dark .wy-img-width-input,.dark .wy-img-align-select{background:#111827;border-color:#374151;color:#f9fafb}.dark .wy-img-modal__progress{background:#111827}.dark .wy-img-modal__cancel{background:#374151;color:#f9fafb}.dark .wy-img-modal__cancel:hover{background:#4b5563}.wy-img-modal{position:fixed;inset:0;z-index:9999;display:none;align-items:center;justify-content:center}.wy-img-modal__backdrop{position:absolute;inset:0;background:#0000008c;-webkit-backdrop-filter:blur(3px);backdrop-filter:blur(3px)}.wy-img-modal__box{position:relative;z-index:1;width:min(540px,calc(100vw - 32px));max-height:calc(100vh - 64px);overflow-y:auto;background:#fff;border-radius:16px;box-shadow:0 24px 64px #00000040;padding:24px;display:flex;flex-direction:column;gap:16px}.wy-img-modal__head{display:flex;align-items:center;justify-content:space-between}.wy-img-modal__title{font-size:1rem;font-weight:700;color:#111827}.wy-img-modal__close{width:30px;height:30px;display:inline-flex;align-items:center;justify-content:center;border:none;background:#f3f4f6;border-radius:8px;cursor:pointer;color:#6b7280;transition:background .15s,color .15s}.wy-img-modal__close:hover{background:#e5e7eb;color:#111827}.wy-img-modal__tabs{display:flex;gap:4px;border-bottom:1px solid #e5e7eb;padding-bottom:0}.wy-img-tab{padding:8px 16px;border:none;background:none;font-size:.875rem;font-weight:500;color:#6b7280;cursor:pointer;border-bottom:2px solid transparent;margin-bottom:-1px;transition:color .15s,border-color .15s;border-radius:6px 6px 0 0}.wy-img-tab:hover{color:#374151}.wy-img-tab.is-active{color:#6366f1;border-bottom-color:#6366f1}.wy-img-dropzone{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:10px;padding:32px 24px;border:2px dashed #d1d5db;border-radius:12px;cursor:pointer;transition:border-color .15s,background .15s;text-align:center}.wy-img-dropzone input[type=file]{position:absolute;width:1px;height:1px;opacity:0;pointer-events:none}.wy-img-dropzone:hover,.wy-img-dropzone.is-dragover{border-color:#6366f1;background:#eef2ff}.wy-img-dropzone__icon{color:#9ca3af}.wy-img-dropzone.is-dragover .wy-img-dropzone__icon{color:#6366f1}.wy-img-dropzone__text{font-size:.875rem;color:#6b7280;margin:0}.wy-img-dropzone__text span{color:#6366f1;font-weight:600;text-decoration:underline}.wy-img-dropzone__hint{font-size:.75rem;color:#9ca3af;margin:0}.wy-img-preview{position:relative;display:flex;justify-content:center}.wy-img-preview__img{max-height:200px;max-width:100%;border-radius:10px;object-fit:contain;border:1px solid #e5e7eb}.wy-img-preview__remove{position:absolute;top:-8px;right:-8px;width:24px;height:24px;border-radius:50%;border:none;background:#ef4444;color:#fff;font-size:14px;line-height:1;cursor:pointer;display:flex;align-items:center;justify-content:center;box-shadow:0 2px 6px #0003}.wy-img-preview__remove:hover{background:#dc2626}.wy-img-modal__progress{height:6px;background:#e5e7eb;border-radius:999px;overflow:hidden}.wy-img-modal__progress-bar{height:100%;background:linear-gradient(90deg,#6366f1,#8b5cf6);border-radius:999px;width:0%;transition:width .2s ease}.wy-img-url-label{display:flex;flex-direction:column;gap:6px;font-size:.8125rem;font-weight:500;color:#374151}.wy-img-url-input,.wy-img-alt-input{padding:9px 12px;border:1.5px solid #d1d5db;border-radius:8px;font-size:.875rem;color:#111827;outline:none;transition:border-color .15s,box-shadow .15s;width:100%;box-sizing:border-box}.wy-img-url-input:focus,.wy-img-alt-input:focus{border-color:#6366f1;box-shadow:0 0 0 3px #6366f11f}.wy-img-modal__options{display:grid;grid-template-columns:1fr 1fr;gap:12px}.wy-img-opt-label{display:flex;flex-direction:column;gap:6px;font-size:.8125rem;font-weight:500;color:#374151}.wy-img-width-input,.wy-img-align-select{padding:9px 12px;border:1.5px solid #d1d5db;border-radius:8px;font-size:.875rem;color:#111827;outline:none;background:#fff;transition:border-color .15s;width:100%;box-sizing:border-box}.wy-img-width-input:focus,.wy-img-align-select:focus{border-color:#6366f1;box-shadow:0 0 0 3px #6366f11f}.wy-img-modal__error{padding:10px 14px;background:#fef2f2;border:1px solid #fecaca;border-radius:8px;color:#dc2626;font-size:.8125rem;margin:0}.wy-img-modal__footer{display:flex;justify-content:flex-end;gap:10px;padding-top:4px}.wy-img-modal__cancel{padding:9px 20px;border:1.5px solid #d1d5db;border-radius:10px;background:#fff;color:#374151;font-size:.875rem;font-weight:500;cursor:pointer;transition:background .15s,border-color .15s}.wy-img-modal__cancel:hover{background:#f9fafb;border-color:#9ca3af}.wy-img-modal__insert{padding:9px 20px;border:none;border-radius:10px;background:linear-gradient(135deg,#6366f1,#8b5cf6);color:#fff;font-size:.875rem;font-weight:600;cursor:pointer;transition:opacity .15s,box-shadow .15s;box-shadow:0 2px 8px #6366f159}.wy-img-modal__insert:hover:not(:disabled){opacity:.9;box-shadow:0 4px 12px #6366f166}.wy-img-modal__insert:disabled{opacity:.45;cursor:not-allowed;box-shadow:none}.wy-img-toolbar{position:fixed;z-index:9998;display:none;align-items:center;gap:2px;padding:4px 6px;background:#1f2937;border-radius:8px;box-shadow:0 4px 16px #0000004d}.wy-img-toolbar button{width:26px;height:26px;border:none;background:transparent;color:#d1d5db;border-radius:5px;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;transition:background .12s,color .12s}.wy-img-toolbar button:hover{background:#ffffff1f;color:#fff}.wy-img-toolbar button.is-active{background:#6366f1;color:#fff}.wy-img-toolbar button[data-action=delete]:hover{background:#ef4444;color:#fff}.wy-img-toolbar__sep{width:1px;height:16px;background:#ffffff26;margin:0 2px}.wy-img-resize-box{position:fixed;z-index:9997;pointer-events:none;box-sizing:border-box;outline:2px solid #6366f1;outline-offset:1px}.wy-img-resize-handle{position:absolute;width:10px;height:10px;background:#fff;border:2px solid #6366f1;border-radius:2px;pointer-events:all;cursor:nwse-resize}.wy-img-resize-handle[data-dir=nw]{top:-5px;left:-5px;cursor:nwse-resize}.wy-img-resize-handle[data-dir=ne]{top:-5px;right:-5px;cursor:nesw-resize}.wy-img-resize-handle[data-dir=sw]{bottom:-5px;left:-5px;cursor:nesw-resize}.wy-img-resize-handle[data-dir=se]{bottom:-5px;right:-5px;cursor:nwse-resize}.wysiwyg-area img{max-width:100%;height:auto;cursor:pointer;border-radius:4px;transition:outline .1s}.wysiwyg-area img.wy-img-selected{outline:2px solid #6366f1;outline-offset:2px}.wysiwyg-area img.wy-img-align-center{display:block;margin:0 auto}.wysiwyg-area img.wy-img-align-left{float:left;margin:0 1em .5em 0}.wysiwyg-area img.wy-img-align-right{float:right;margin:0 0 .5em 1em}.wysiwyg-area img.wy-img-align-block-left{display:block;margin:0 auto 0 0}.wysiwyg-area img.wy-img-align-block-right{display:block;margin:0 0 0 auto}.wy-img-uploading{display:inline-flex;align-items:center;gap:6px;padding:4px 10px;background:#eef2ff;color:#6366f1;border-radius:6px;font-size:.8125rem;font-weight:500;border:1px dashed #a5b4fc}.wy-img-uploading--error{background:#fef2f2;color:#ef4444;border-color:#fca5a5}@media(prefers-color-scheme:dark){.wy-img-modal__box{background:#1f2937;color:#f9fafb}.wy-img-modal__title{color:#f9fafb}.wy-img-modal__close{background:#374151;color:#9ca3af}.wy-img-modal__close:hover{background:#4b5563;color:#f9fafb}.wy-img-tab{color:#9ca3af}.wy-img-tab:hover{color:#e5e7eb}.wy-img-modal__tabs{border-color:#374151}.wy-img-dropzone{border-color:#4b5563}.wy-img-dropzone:hover,.wy-img-dropzone.is-dragover{background:#6366f11a}.wy-img-url-label,.wy-img-opt-label{color:#d1d5db}.wy-img-url-input,.wy-img-alt-input,.wy-img-width-input,.wy-img-align-select{background:#111827;border-color:#4b5563;color:#f9fafb}.wy-img-modal__cancel{background:#374151;border-color:#4b5563;color:#d1d5db}.wy-img-modal__cancel:hover{background:#4b5563}}
1
+ .wysiwyg-editor{--wy-border: #e5e7eb;--wy-border-focus: #6366f1;--wy-bg: #ffffff;--wy-bg-toolbar: #f9fafb;--wy-text: #111827;--wy-muted: #9ca3af;--wy-btn-hover: #f3f4f6;--wy-btn-active: #e0e7ff;--wy-btn-active-fg:#4338ca;--wy-radius: .75rem;--wy-sep: #e5e7eb;display:flex;flex-direction:column;border:1.5px solid var(--wy-border);border-radius:var(--wy-radius);background:var(--wy-bg);overflow:hidden;transition:border-color .15s ease,box-shadow .15s ease;font-family:inherit}.wysiwyg-editor:focus-within{border-color:var(--wy-border-focus);box-shadow:0 0 0 3px #6366f11f}.wysiwyg-toolbar{display:flex;flex-wrap:wrap;align-items:center;gap:2px;padding:6px 8px;background:var(--wy-bg-toolbar);border-bottom:1px solid var(--wy-border)}.wysiwyg-btn{display:inline-flex;align-items:center;justify-content:center;width:30px;height:30px;padding:0;border:none;border-radius:6px;background:transparent;color:var(--wy-text);cursor:pointer;transition:background .1s ease,color .1s ease;flex-shrink:0}.wysiwyg-btn:hover{background:var(--wy-btn-hover)}.wysiwyg-btn.is-active{background:var(--wy-btn-active);color:var(--wy-btn-active-fg)}.wysiwyg-btn span{display:inline-flex;align-items:center;justify-content:center;width:100%;height:100%}.wysiwyg-separator{width:1px;height:20px;background:var(--wy-sep);margin:0 4px;flex-shrink:0}.wysiwyg-area{flex:1;padding:14px 16px;outline:none;color:var(--wy-text);line-height:1.7;word-break:break-word;overflow-y:auto}.wysiwyg-area:empty:before{content:attr(data-placeholder);color:var(--wy-muted);pointer-events:none}.wysiwyg-area h1,.wysiwyg-area h2,.wysiwyg-area h3{font-weight:700;line-height:1.3;margin-top:1em;margin-bottom:.4em;color:var(--wy-text)}.wysiwyg-area h1{font-size:1.75em}.wysiwyg-area h2{font-size:1.35em}.wysiwyg-area h3{font-size:1.1em}.wysiwyg-area h1:first-child,.wysiwyg-area h2:first-child,.wysiwyg-area h3:first-child{margin-top:0}.wysiwyg-area p{margin:0 0 .75em}.wysiwyg-area p:last-child{margin-bottom:0}.wysiwyg-area strong{font-weight:700}.wysiwyg-area em{font-style:italic}.wysiwyg-area u{text-decoration:underline}.wysiwyg-area s{text-decoration:line-through}.wysiwyg-area ul,.wysiwyg-area ol{padding-left:1.5em;margin:0 0 .75em}.wysiwyg-area ul{list-style-type:disc}.wysiwyg-area ol{list-style-type:decimal}.wysiwyg-area li{margin-bottom:.25em}.wysiwyg-area blockquote{border-left:3px solid var(--wy-border-focus);margin:.75em 0;padding:.5em 1em;background:#6366f10d;border-radius:0 6px 6px 0;color:#4b5563}.wysiwyg-area a{color:var(--wy-btn-active-fg);text-decoration:underline}.wysiwyg-area a:hover{opacity:.8}.wysiwyg-source-area{flex:1;padding:14px 16px;outline:none;color:#a5b4fc;background:#1e1b4b;font-family:Fira Code,Cascadia Code,Consolas,Monaco,monospace;font-size:.8125rem;line-height:1.7;resize:none;border:none;width:100%;box-sizing:border-box;min-height:200px}.wysiwyg-source-area:focus{outline:none}.dark .wysiwyg-source-area{background:#0f0c29}@media(prefers-color-scheme:dark){.wysiwyg-editor{--wy-border: #374151;--wy-bg: #1f2937;--wy-bg-toolbar: #111827;--wy-text: #f9fafb;--wy-muted: #6b7280;--wy-btn-hover: #374151;--wy-btn-active: #312e81;--wy-btn-active-fg:#a5b4fc;--wy-sep: #374151}.wysiwyg-area blockquote{background:#6366f11a;color:#d1d5db}}.dark .wysiwyg-editor{--wy-border: #374151;--wy-bg: #1f2937;--wy-bg-toolbar: #111827;--wy-text: #f9fafb;--wy-muted: #6b7280;--wy-btn-hover: #374151;--wy-btn-active: #312e81;--wy-btn-active-fg:#a5b4fc;--wy-sep: #374151}.dark .wysiwyg-area blockquote{background:#6366f11a;color:#d1d5db}.wysiwyg-area img{max-width:100%;height:auto;border-radius:4px;cursor:pointer;vertical-align:bottom;transition:outline-color .1s ease}.wysiwyg-area img:hover{outline:2px solid rgb(99 102 241 / .35);outline-offset:2px}.wysiwyg-area img.wy-img-align-center{display:block;float:none;margin:.5em auto}.wysiwyg-area img.wy-img-align-left{float:left;margin:.25em 1.25em .5em 0}.wysiwyg-area img.wy-img-align-right{float:right;margin:.25em 0 .5em 1.25em}.wysiwyg-area img.wy-img-align-block-left{display:block;float:none;margin:.5em auto .5em 0}.wysiwyg-area img.wy-img-align-block-right{display:block;float:none;margin:.5em 0 .5em auto}img.wy-img-align-center{display:block;float:none;margin:.5em auto}img.wy-img-align-left{float:left;margin:.25em 1.25em .5em 0}img.wy-img-align-right{float:right;margin:.25em 0 .5em 1.25em}img.wy-img-align-block-left{display:block;float:none;margin:.5em auto .5em 0}img.wy-img-align-block-right{display:block;float:none;margin:.5em 0 .5em auto}.wy-img-uploading{display:inline-block;padding:4px 10px;border-radius:6px;background:#6366f11a;color:#4338ca;font-size:.8125em;font-style:italic}.wy-img-uploading--error{background:#f43f5e1a;color:#e11d48}.wy-img-toolbar{position:fixed;z-index:10000;display:none;align-items:center;gap:2px;padding:4px;background:#fff;border:1px solid #e5e7eb;border-radius:8px;box-shadow:0 8px 24px #00000026}.wy-img-toolbar button{display:inline-flex;align-items:center;justify-content:center;width:26px;height:26px;padding:0;border:none;border-radius:6px;background:transparent;color:#111827;cursor:pointer}.wy-img-toolbar button:hover{background:#f3f4f6}.wy-img-toolbar button.is-active{background:#e0e7ff;color:#4338ca}.wy-img-toolbar__sep{width:1px;height:18px;background:#e5e7eb;margin:0 4px;flex-shrink:0}.wy-img-resize-box{position:fixed;z-index:9999;display:none;box-sizing:border-box;border:1.5px dashed #6366f1;pointer-events:none}.wy-img-resize-handle{position:absolute;width:10px;height:10px;background:#fff;border:2px solid #6366f1;border-radius:2px;pointer-events:all}.wy-img-resize-handle[data-dir=nw]{top:-6px;left:-6px;cursor:nwse-resize}.wy-img-resize-handle[data-dir=ne]{top:-6px;right:-6px;cursor:nesw-resize}.wy-img-resize-handle[data-dir=sw]{bottom:-6px;left:-6px;cursor:nesw-resize}.wy-img-resize-handle[data-dir=se]{bottom:-6px;right:-6px;cursor:nwse-resize}.wy-img-modal{position:fixed;inset:0;z-index:10050;display:flex;align-items:center;justify-content:center}.wy-img-modal__backdrop{position:absolute;inset:0;background:#0f0f1480;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}.wy-img-modal__box{position:relative;width:100%;max-width:440px;max-height:90vh;overflow-y:auto;margin:16px;background:#fff;border-radius:16px;box-shadow:0 20px 60px #0000004d}.wy-img-modal__head{display:flex;align-items:center;justify-content:space-between;padding:16px 20px;border-bottom:1px solid #e5e7eb}.wy-img-modal__title{font-weight:600;font-size:.9375rem;color:#111827}.wy-img-modal__close{display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;border:none;border-radius:8px;background:transparent;color:#9ca3af;cursor:pointer}.wy-img-modal__close:hover{background:#f3f4f6;color:#111827}.wy-img-modal__tabs{display:flex;gap:6px;padding:14px 20px 0}.wy-img-tab{flex:1;padding:8px 12px;border:none;border-radius:8px;background:#f9fafb;color:#6b7280;font-size:.8125rem;font-weight:500;cursor:pointer;transition:background .1s ease,color .1s ease}.wy-img-tab.is-active{background:#e0e7ff;color:#4338ca}.wy-img-modal__panel{padding:16px 20px 0}.wy-img-dropzone{position:relative;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:6px;padding:28px 16px;border:2px dashed #e5e7eb;border-radius:12px;cursor:pointer;text-align:center;transition:border-color .15s ease,background .15s ease}.wy-img-dropzone:hover,.wy-img-dropzone.is-dragover{border-color:#6366f1;background:#6366f10d}.wy-img-dropzone__text{margin:0;font-size:.8125rem;color:#111827}.wy-img-dropzone__text span{color:#6366f1;font-weight:600}.wy-img-dropzone__hint{margin:0;font-size:.6875rem;color:#9ca3af}.wy-img-file{position:absolute;width:1px;height:1px;overflow:hidden;opacity:0}.wy-img-preview{position:relative;display:block;width:max-content;max-width:100%;margin:12px auto 0}.wy-img-preview__img{display:block;max-height:180px;max-width:100%;border-radius:8px}.wy-img-preview__remove{position:absolute;top:-8px;right:-8px;width:22px;height:22px;border:none;border-radius:999px;background:#111827;color:#fff;font-size:14px;line-height:1;cursor:pointer}.wy-img-modal__progress{margin-top:12px;height:6px;border-radius:999px;background:#f3f4f6;overflow:hidden}.wy-img-modal__progress-bar{height:100%;width:0%;background:linear-gradient(90deg,#6366f1,#8b5cf6);transition:width .15s ease}.wy-img-url-label{display:block;font-size:.8125rem;font-weight:500;color:#111827}.wy-img-url-input,.wy-img-alt-input,.wy-img-width-input,.wy-img-align-select{display:block;width:100%;margin-top:6px;padding:8px 12px;border:1.5px solid #e5e7eb;border-radius:8px;background:#fff;color:#111827;font-size:.8125rem;font-family:inherit;box-sizing:border-box}.wy-img-url-input:focus,.wy-img-alt-input:focus,.wy-img-width-input:focus,.wy-img-align-select:focus{outline:none;border-color:#6366f1;box-shadow:0 0 0 3px #6366f11f}.wy-img-url-preview img{max-height:120px;max-width:100%;border-radius:8px}.wy-img-modal__options{display:flex;gap:12px;padding:4px 20px 0}.wy-img-opt-label{flex:1;font-size:.8125rem;font-weight:500;color:#111827}.wy-img-modal__error{margin:12px 20px 0;padding:8px 12px;border-radius:8px;background:#f43f5e1a;color:#e11d48;font-size:.75rem}.wy-img-modal__footer{display:flex;justify-content:flex-end;gap:8px;padding:16px 20px 20px}.wy-img-modal__cancel,.wy-img-modal__insert{padding:8px 18px;border:none;border-radius:8px;font-size:.8125rem;font-weight:600;cursor:pointer}.wy-img-modal__cancel{background:#f3f4f6;color:#111827}.wy-img-modal__cancel:hover{background:#e5e7eb}.wy-img-modal__insert{background:linear-gradient(90deg,#4f46e5,#7c3aed);color:#fff}.wy-img-modal__insert:disabled{opacity:.4;cursor:not-allowed}@media(prefers-color-scheme:dark){.wy-img-toolbar{background:#1f2937;border-color:#374151}.wy-img-toolbar button{color:#f9fafb}.wy-img-toolbar button:hover{background:#374151}.wy-img-toolbar button.is-active{background:#312e81;color:#a5b4fc}.wy-img-toolbar__sep{background:#374151}.wy-img-modal__box{background:#1f2937}.wy-img-modal__head{border-color:#374151}.wy-img-modal__title{color:#f9fafb}.wy-img-modal__close{color:#9ca3af}.wy-img-modal__close:hover{background:#374151;color:#f9fafb}.wy-img-tab{background:#111827;color:#9ca3af}.wy-img-tab.is-active{background:#312e81;color:#a5b4fc}.wy-img-dropzone{border-color:#374151}.wy-img-dropzone:hover,.wy-img-dropzone.is-dragover{border-color:#6366f1;background:#6366f11a}.wy-img-dropzone__text,.wy-img-url-label,.wy-img-opt-label{color:#f9fafb}.wy-img-url-input,.wy-img-alt-input,.wy-img-width-input,.wy-img-align-select{background:#111827;border-color:#374151;color:#f9fafb}.wy-img-modal__progress{background:#111827}.wy-img-modal__cancel{background:#374151;color:#f9fafb}.wy-img-modal__cancel:hover{background:#4b5563}}.dark .wy-img-toolbar{background:#1f2937;border-color:#374151}.dark .wy-img-toolbar button{color:#f9fafb}.dark .wy-img-toolbar button:hover{background:#374151}.dark .wy-img-toolbar button.is-active{background:#312e81;color:#a5b4fc}.dark .wy-img-toolbar__sep{background:#374151}.dark .wy-img-modal__box{background:#1f2937}.dark .wy-img-modal__head{border-color:#374151}.dark .wy-img-modal__title{color:#f9fafb}.dark .wy-img-modal__close{color:#9ca3af}.dark .wy-img-modal__close:hover{background:#374151;color:#f9fafb}.dark .wy-img-tab{background:#111827;color:#9ca3af}.dark .wy-img-tab.is-active{background:#312e81;color:#a5b4fc}.dark .wy-img-dropzone{border-color:#374151}.dark .wy-img-dropzone:hover,.dark .wy-img-dropzone.is-dragover{border-color:#6366f1;background:#6366f11a}.dark .wy-img-dropzone__text,.dark .wy-img-url-label,.dark .wy-img-opt-label{color:#f9fafb}.dark .wy-img-url-input,.dark .wy-img-alt-input,.dark .wy-img-width-input,.dark .wy-img-align-select{background:#111827;border-color:#374151;color:#f9fafb}.dark .wy-img-modal__progress{background:#111827}.dark .wy-img-modal__cancel{background:#374151;color:#f9fafb}.dark .wy-img-modal__cancel:hover{background:#4b5563}.wy-img-modal{position:fixed;inset:0;z-index:9999;display:none;align-items:center;justify-content:center}.wy-img-modal__backdrop{position:absolute;inset:0;background:#0000008c;-webkit-backdrop-filter:blur(3px);backdrop-filter:blur(3px)}.wy-img-modal__box{position:relative;z-index:1;width:min(540px,calc(100vw - 32px));max-height:calc(100vh - 64px);overflow-y:auto;background:#fff;border-radius:16px;box-shadow:0 24px 64px #00000040;padding:24px;display:flex;flex-direction:column;gap:16px}.wy-img-modal__head{display:flex;align-items:center;justify-content:space-between}.wy-img-modal__title{font-size:1rem;font-weight:700;color:#111827}.wy-img-modal__close{width:30px;height:30px;display:inline-flex;align-items:center;justify-content:center;border:none;background:#f3f4f6;border-radius:8px;cursor:pointer;color:#6b7280;transition:background .15s,color .15s}.wy-img-modal__close:hover{background:#e5e7eb;color:#111827}.wy-img-modal__tabs{display:flex;gap:4px;border-bottom:1px solid #e5e7eb;padding-bottom:0}.wy-img-tab{padding:8px 16px;border:none;background:none;font-size:.875rem;font-weight:500;color:#6b7280;cursor:pointer;border-bottom:2px solid transparent;margin-bottom:-1px;transition:color .15s,border-color .15s;border-radius:6px 6px 0 0}.wy-img-tab:hover{color:#374151}.wy-img-tab.is-active{color:#6366f1;border-bottom-color:#6366f1}.wy-img-dropzone{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:10px;padding:32px 24px;border:2px dashed #d1d5db;border-radius:12px;cursor:pointer;transition:border-color .15s,background .15s;text-align:center}.wy-img-dropzone input[type=file]{position:absolute;width:1px;height:1px;opacity:0;pointer-events:none}.wy-img-dropzone:hover,.wy-img-dropzone.is-dragover{border-color:#6366f1;background:#eef2ff}.wy-img-dropzone__icon{color:#9ca3af}.wy-img-dropzone.is-dragover .wy-img-dropzone__icon{color:#6366f1}.wy-img-dropzone__text{font-size:.875rem;color:#6b7280;margin:0}.wy-img-dropzone__text span{color:#6366f1;font-weight:600;text-decoration:underline}.wy-img-dropzone__hint{font-size:.75rem;color:#9ca3af;margin:0}.wy-img-preview{position:relative;display:flex;justify-content:center}.wy-img-preview__img{max-height:200px;max-width:100%;border-radius:10px;object-fit:contain;border:1px solid #e5e7eb}.wy-img-preview__remove{position:absolute;top:-8px;right:-8px;width:24px;height:24px;border-radius:50%;border:none;background:#ef4444;color:#fff;font-size:14px;line-height:1;cursor:pointer;display:flex;align-items:center;justify-content:center;box-shadow:0 2px 6px #0003}.wy-img-preview__remove:hover{background:#dc2626}.wy-img-modal__progress{height:6px;background:#e5e7eb;border-radius:999px;overflow:hidden}.wy-img-modal__progress-bar{height:100%;background:linear-gradient(90deg,#6366f1,#8b5cf6);border-radius:999px;width:0%;transition:width .2s ease}.wy-img-url-label{display:flex;flex-direction:column;gap:6px;font-size:.8125rem;font-weight:500;color:#374151}.wy-img-url-input,.wy-img-alt-input{padding:9px 12px;border:1.5px solid #d1d5db;border-radius:8px;font-size:.875rem;color:#111827;outline:none;transition:border-color .15s,box-shadow .15s;width:100%;box-sizing:border-box}.wy-img-url-input:focus,.wy-img-alt-input:focus{border-color:#6366f1;box-shadow:0 0 0 3px #6366f11f}.wy-img-modal__options{display:grid;grid-template-columns:1fr 1fr;gap:12px}.wy-img-opt-label{display:flex;flex-direction:column;gap:6px;font-size:.8125rem;font-weight:500;color:#374151}.wy-img-width-input,.wy-img-align-select{padding:9px 12px;border:1.5px solid #d1d5db;border-radius:8px;font-size:.875rem;color:#111827;outline:none;background:#fff;transition:border-color .15s;width:100%;box-sizing:border-box}.wy-img-width-input:focus,.wy-img-align-select:focus{border-color:#6366f1;box-shadow:0 0 0 3px #6366f11f}.wy-img-modal__error{padding:10px 14px;background:#fef2f2;border:1px solid #fecaca;border-radius:8px;color:#dc2626;font-size:.8125rem;margin:0}.wy-img-modal__footer{display:flex;justify-content:flex-end;gap:10px;padding-top:4px}.wy-img-modal__cancel{padding:9px 20px;border:1.5px solid #d1d5db;border-radius:10px;background:#fff;color:#374151;font-size:.875rem;font-weight:500;cursor:pointer;transition:background .15s,border-color .15s}.wy-img-modal__cancel:hover{background:#f9fafb;border-color:#9ca3af}.wy-img-modal__insert{padding:9px 20px;border:none;border-radius:10px;background:linear-gradient(135deg,#6366f1,#8b5cf6);color:#fff;font-size:.875rem;font-weight:600;cursor:pointer;transition:opacity .15s,box-shadow .15s;box-shadow:0 2px 8px #6366f159}.wy-img-modal__insert:hover:not(:disabled){opacity:.9;box-shadow:0 4px 12px #6366f166}.wy-img-modal__insert:disabled{opacity:.45;cursor:not-allowed;box-shadow:none}.wy-img-toolbar{position:fixed;z-index:9998;display:none;align-items:center;gap:2px;padding:4px 6px;background:#1f2937;border-radius:8px;box-shadow:0 4px 16px #0000004d}.wy-img-toolbar button{width:26px;height:26px;border:none;background:transparent;color:#d1d5db;border-radius:5px;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;transition:background .12s,color .12s}.wy-img-toolbar button:hover{background:#ffffff1f;color:#fff}.wy-img-toolbar button.is-active{background:#6366f1;color:#fff}.wy-img-toolbar button[data-action=delete]:hover{background:#ef4444;color:#fff}.wy-img-toolbar__sep{width:1px;height:16px;background:#ffffff26;margin:0 2px}.wy-img-resize-box{position:fixed;z-index:9997;pointer-events:none;box-sizing:border-box;outline:2px solid #6366f1;outline-offset:1px}.wy-img-resize-handle{position:absolute;width:10px;height:10px;background:#fff;border:2px solid #6366f1;border-radius:2px;pointer-events:all;cursor:nwse-resize}.wy-img-resize-handle[data-dir=nw]{top:-5px;left:-5px;cursor:nwse-resize}.wy-img-resize-handle[data-dir=ne]{top:-5px;right:-5px;cursor:nesw-resize}.wy-img-resize-handle[data-dir=sw]{bottom:-5px;left:-5px;cursor:nesw-resize}.wy-img-resize-handle[data-dir=se]{bottom:-5px;right:-5px;cursor:nwse-resize}.wysiwyg-area img{max-width:100%;height:auto;cursor:pointer;border-radius:4px;transition:outline .1s}.wysiwyg-area img.wy-img-selected{outline:2px solid #6366f1;outline-offset:2px}.wysiwyg-area img.wy-img-align-center{display:block;margin:0 auto}.wysiwyg-area img.wy-img-align-left{float:left;margin:0 1em .5em 0}.wysiwyg-area img.wy-img-align-right{float:right;margin:0 0 .5em 1em}.wysiwyg-area img.wy-img-align-block-left{display:block;margin:0 auto 0 0}.wysiwyg-area img.wy-img-align-block-right{display:block;margin:0 0 0 auto}.wy-img-uploading{display:inline-flex;align-items:center;gap:6px;padding:4px 10px;background:#eef2ff;color:#6366f1;border-radius:6px;font-size:.8125rem;font-weight:500;border:1px dashed #a5b4fc}.wy-img-uploading--error{background:#fef2f2;color:#ef4444;border-color:#fca5a5}@media(prefers-color-scheme:dark){.wy-img-modal__box{background:#1f2937;color:#f9fafb}.wy-img-modal__title{color:#f9fafb}.wy-img-modal__close{background:#374151;color:#9ca3af}.wy-img-modal__close:hover{background:#4b5563;color:#f9fafb}.wy-img-tab{color:#9ca3af}.wy-img-tab:hover{color:#e5e7eb}.wy-img-modal__tabs{border-color:#374151}.wy-img-dropzone{border-color:#4b5563}.wy-img-dropzone:hover,.wy-img-dropzone.is-dragover{background:#6366f11a}.wy-img-url-label,.wy-img-opt-label{color:#d1d5db}.wy-img-url-input,.wy-img-alt-input,.wy-img-width-input,.wy-img-align-select{background:#111827;border-color:#4b5563;color:#f9fafb}.wy-img-modal__cancel{background:#374151;border-color:#4b5563;color:#d1d5db}.wy-img-modal__cancel:hover{background:#4b5563}}
package/wysiwyg.min.js CHANGED
@@ -1,4 +1,4 @@
1
- var WysiwygEditor=(function(w,k){"use strict";const E={placeholder:"Tulis sesuatu...",minHeight:200,plugins:[],onChange:null,syncInput:null,uploadUrl:"",uploadFn:null};class m{static#p=new Map;static registerPlugin(e){if(!e.name)throw new Error("[wysiwyg] Plugin harus punya nama.");m.#p.set(e.name,e)}static getPlugins(){return Array.from(m.#p.values())}#l;#e;#n;#u=!1;#s;#k=null;#t;#h;#a=null;#o=null;#i=null;#v=null;#m=null;#c=null;constructor(e,t={}){if(this.#l=typeof e=="string"?document.querySelector(e):e,!this.#l)throw new Error(`[wysiwyg] Element tidak ditemukan: ${e}`);this.#t={...E,...t},this.#h=new AbortController,this.#T(),this.#j(),this.#f()}#T(){this.#l.classList.add("wysiwyg-editor"),this.#l.innerHTML="",this.#s=document.createElement("div"),this.#s.className="wysiwyg-toolbar",this.#s.setAttribute("role","toolbar"),this.#s.setAttribute("aria-label","Toolbar editor"),this.#M(),this.#l.appendChild(this.#s),this.#e=document.createElement("div"),this.#e.className="wysiwyg-area",this.#e.contentEditable="true",this.#e.setAttribute("role","textbox"),this.#e.setAttribute("aria-multiline","true"),this.#e.setAttribute("aria-label","Area editor"),this.#e.setAttribute("spellcheck","true"),this.#e.style.minHeight=this.#t.minHeight+"px",this.#e.dataset.placeholder=this.#t.placeholder,this.#l.appendChild(this.#e),this.#n=document.createElement("textarea"),this.#n.className="wysiwyg-source-area",this.#n.setAttribute("aria-label","HTML source editor"),this.#n.setAttribute("spellcheck","false"),this.#n.setAttribute("autocorrect","off"),this.#n.setAttribute("autocapitalize","off"),this.#n.style.minHeight=this.#t.minHeight+"px",this.#n.style.display="none",this.#l.appendChild(this.#n),this.#t.syncInput&&(this.#k=typeof this.#t.syncInput=="string"?document.querySelector(this.#t.syncInput):this.#t.syncInput),this.#_(),this.#q(),this.#U()}#M(){const e=this.#t.plugins.length?this.#t.plugins.map(i=>typeof i=="string"?m.#p.get(i):i).filter(Boolean):m.getPlugins();let t=null;e.forEach(i=>{if(i.group&&i.group!==t){if(t!==null){const o=document.createElement("div");o.className="wysiwyg-separator",o.setAttribute("aria-hidden","true"),this.#s.appendChild(o)}t=i.group}const s=document.createElement("button");s.type="button",s.className="wysiwyg-btn",s.dataset.plugin=i.name,s.title=i.title||i.name,s.setAttribute("aria-label",i.title||i.name),s.innerHTML=i.icon,this.#s.appendChild(s)})}#_(){const e=document.createElement("div");e.className="wy-img-modal",e.style.display="none",e.setAttribute("role","dialog"),e.setAttribute("aria-modal","true"),e.setAttribute("aria-label","Sisipkan gambar"),e.innerHTML=`
1
+ var WysiwygEditor=(function(w){"use strict";const k={placeholder:"Tulis sesuatu...",minHeight:200,plugins:[],onChange:null,syncInput:null,uploadUrl:"",uploadFn:null};class g{static#p=new Map;static registerPlugin(e){if(!e.name)throw new Error("[wysiwyg] Plugin harus punya nama.");g.#p.set(e.name,e)}static getPlugins(){return Array.from(g.#p.values())}#l;#e;#n;#u=!1;#s;#k=null;#t;#h;#a=null;#o=null;#i=null;#v=null;#g=null;#c=null;constructor(e,t={}){if(this.#l=typeof e=="string"?document.querySelector(e):e,!this.#l)throw new Error(`[wysiwyg] Element tidak ditemukan: ${e}`);this.#t={...k,...t},this.#h=new AbortController,this.#C(),this.#P(),this.#f()}#C(){this.#l.classList.add("wysiwyg-editor"),this.#l.innerHTML="",this.#s=document.createElement("div"),this.#s.className="wysiwyg-toolbar",this.#s.setAttribute("role","toolbar"),this.#s.setAttribute("aria-label","Toolbar editor"),this.#M(),this.#l.appendChild(this.#s),this.#e=document.createElement("div"),this.#e.className="wysiwyg-area",this.#e.contentEditable="true",this.#e.setAttribute("role","textbox"),this.#e.setAttribute("aria-multiline","true"),this.#e.setAttribute("aria-label","Area editor"),this.#e.setAttribute("spellcheck","true"),this.#e.style.minHeight=this.#t.minHeight+"px",this.#e.dataset.placeholder=this.#t.placeholder,this.#l.appendChild(this.#e),this.#n=document.createElement("textarea"),this.#n.className="wysiwyg-source-area",this.#n.setAttribute("aria-label","HTML source editor"),this.#n.setAttribute("spellcheck","false"),this.#n.setAttribute("autocorrect","off"),this.#n.setAttribute("autocapitalize","off"),this.#n.style.minHeight=this.#t.minHeight+"px",this.#n.style.display="none",this.#l.appendChild(this.#n),this.#t.syncInput&&(this.#k=typeof this.#t.syncInput=="string"?document.querySelector(this.#t.syncInput):this.#t.syncInput),this.#_(),this.#q(),this.#U()}#M(){const e=this.#t.plugins.length?this.#t.plugins.map(i=>typeof i=="string"?g.#p.get(i):i).filter(Boolean):g.getPlugins();let t=null;e.forEach(i=>{if(i.group&&i.group!==t){if(t!==null){const o=document.createElement("div");o.className="wysiwyg-separator",o.setAttribute("aria-hidden","true"),this.#s.appendChild(o)}t=i.group}const s=document.createElement("button");s.type="button",s.className="wysiwyg-btn",s.dataset.plugin=i.name,s.title=i.title||i.name,s.setAttribute("aria-label",i.title||i.name),s.innerHTML=i.icon,this.#s.appendChild(s)})}#_(){const e=document.createElement("div");e.className="wy-img-modal",e.style.display="none",e.setAttribute("role","dialog"),e.setAttribute("aria-modal","true"),e.setAttribute("aria-label","Sisipkan gambar"),e.innerHTML=`
2
2
  <div class="wy-img-modal__backdrop"></div>
3
3
  <div class="wy-img-modal__box">
4
4
  <div class="wy-img-modal__head">
@@ -91,16 +91,16 @@ var WysiwygEditor=(function(w,k){"use strict";const E={placeholder:"Tulis sesuat
91
91
  <button type="button" data-action="delete" title="Hapus gambar">
92
92
  <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="3 6 5 6 21 6"/><path d="M19 6l-1 14H6L5 6"/><path d="M10 11v6"/><path d="M14 11v6"/><path d="M9 6V4h6v2"/></svg>
93
93
  </button>
94
- `,document.body.appendChild(e),this.#o=e,this.#N()}openImageDialog(){const e=window.getSelection();this.#v=e.rangeCount?e.getRangeAt(0).cloneRange():null,this.#H(),this.#a.style.display="flex"}#H(){const e=this.#a;e.querySelectorAll(".wy-img-tab").forEach(t=>t.classList.toggle("is-active",t.dataset.tab==="upload")),e.querySelectorAll(".wy-img-modal__panel").forEach(t=>{t.style.display=t.dataset.panel==="upload"?"":"none"}),e.querySelector(".wy-img-file").value="",e.querySelector(".wy-img-preview").style.display="none",e.querySelector(".wy-img-preview__img").src="",e.querySelector(".wy-img-url-input").value="",e.querySelector(".wy-img-alt-input").value="",e.querySelector(".wy-img-url-preview").style.display="none",e.querySelector(".wy-img-url-preview__img").src="",e.querySelector(".wy-img-width-input").value="",e.querySelector(".wy-img-align-select").value="",e.querySelector(".wy-img-modal__progress").style.display="none",e.querySelector(".wy-img-modal__progress-bar").style.width="0%",e.querySelector(".wy-img-modal__insert").disabled=!0,e.querySelector(".wy-img-dropzone").classList.remove("is-dragover"),this.#d(""),this.#m=null}#b(){this.#a.style.display="none",this.#m=null,this.#v=null}#d(e){const t=this.#a.querySelector(".wy-img-modal__error");t.textContent=e||"",t.style.display=e?"":"none"}#R(){const e=this.#a,t={signal:this.#h.signal};e.querySelectorAll(".wy-img-modal__close, .wy-img-modal__cancel, .wy-img-modal__backdrop").forEach(a=>a.addEventListener("click",()=>this.#b(),t)),e.querySelector(".wy-img-modal__box").addEventListener("click",a=>a.stopPropagation(),t),e.querySelectorAll(".wy-img-tab").forEach(a=>{a.addEventListener("click",()=>{e.querySelectorAll(".wy-img-tab").forEach(d=>d.classList.toggle("is-active",d===a)),e.querySelectorAll(".wy-img-modal__panel").forEach(d=>{d.style.display=d.dataset.panel===a.dataset.tab?"":"none"}),this.#d(""),this.#x()},t)});const i=e.querySelector(".wy-img-file"),s=e.querySelector(".wy-img-dropzone");i.addEventListener("change",()=>{const a=i.files?.[0];a&&this.#E(a)},t),["dragover","dragenter"].forEach(a=>{s.addEventListener(a,d=>{d.preventDefault(),s.classList.add("is-dragover")},t)}),["dragleave","dragend"].forEach(a=>{s.addEventListener(a,d=>{d.preventDefault(),s.classList.remove("is-dragover")},t)}),s.addEventListener("drop",a=>{a.preventDefault(),s.classList.remove("is-dragover");const d=a.dataTransfer.files?.[0];d&&this.#E(d)},t),e.querySelector(".wy-img-preview__remove").addEventListener("click",a=>{a.preventDefault(),this.#m=null,i.value="",e.querySelector(".wy-img-preview").style.display="none",this.#x()},t);const o=e.querySelector(".wy-img-url-input"),r=e.querySelector(".wy-img-url-preview"),l=e.querySelector(".wy-img-url-preview__img");let c;o.addEventListener("input",()=>{this.#d(""),this.#x(),clearTimeout(c);const a=o.value.trim();if(!a){r.style.display="none";return}c=setTimeout(()=>{l.onload=()=>{r.style.display=""},l.onerror=()=>{r.style.display="none"},l.src=a},300)},t),e.querySelector(".wy-img-modal__insert").addEventListener("click",()=>this.#B(),t),e.addEventListener("keydown",a=>{a.key==="Escape"&&this.#b()},t)}#x(){const e=this.#a,t=e.querySelector(".wy-img-tab.is-active")?.dataset.tab,i=e.querySelector(".wy-img-modal__insert");t==="upload"?i.disabled=!this.#m:i.disabled=e.querySelector(".wy-img-url-input").value.trim()===""}#E(e){if(this.#d(""),!e.type.startsWith("image/")){this.#d("File harus berupa gambar.");return}if(e.size>5242880){this.#d("Ukuran gambar maksimal 5MB.");return}this.#m=e;const t=this.#a,i=t.querySelector(".wy-img-preview"),s=t.querySelector(".wy-img-preview__img"),o=new FileReader;o.onload=()=>{s.src=o.result,i.style.display=""},o.readAsDataURL(e),this.#x()}async#B(){const e=this.#a,t=e.querySelector(".wy-img-tab.is-active")?.dataset.tab,i=e.querySelector(".wy-img-alt-input").value.trim(),s=e.querySelector(".wy-img-width-input").value.trim(),o=e.querySelector(".wy-img-align-select").value,r=e.querySelector(".wy-img-modal__insert");if(this.#d(""),t==="upload"){if(!this.#m)return;const l=e.querySelector(".wy-img-modal__progress"),c=e.querySelector(".wy-img-modal__progress-bar");r.disabled=!0,l.style.display="",c.style.width="0%";try{const a=await this.#S(this.#m,d=>{c.style.width=d+"%"});this.#A({src:a,alt:i,width:s,align:o}),this.#b()}catch(a){const d=a?.response?.data?.errors?.image?.[0]||a?.response?.data?.message;this.#d(d||"Upload gambar gagal. Silakan coba lagi."),r.disabled=!1}finally{l.style.display="none"}}else{const l=e.querySelector(".wy-img-url-input").value.trim();if(!l)return;this.#A({src:l,alt:i,width:s,align:o}),this.#b()}}#A(e){this.#e.focus();const t=window.getSelection();t.removeAllRanges(),this.#v&&t.addRange(this.#v);const i=document.createElement("img");if(i.src=e.src,i.alt=e.alt||"",this.#z(i,e),t.rangeCount){const s=t.getRangeAt(0);s.deleteContents(),s.insertNode(i),s.setStartAfter(i),s.collapse(!0),t.removeAllRanges(),t.addRange(s)}else this.#e.appendChild(i);this.#r()}async#S(e,t){const i=this.#t.uploadUrl||window.location.origin+"/wysiwyg/upload-image";if(typeof this.#t.uploadFn=="function")return this.#t.uploadFn(e,i,t);const s=new FormData;s.append("image",e);const o=document.querySelector('meta[name="csrf-token"]')?.content,{data:r}=await k.post(i,s,{headers:o?{"X-CSRF-TOKEN":o}:{},onUploadProgress:l=>{!t||!l.total||t(Math.round(l.loaded/l.total*100))}});if(!r?.ok||!r?.url)throw new Error("Respon server tidak valid.");return r.url}async#I(e){if(!e.type.startsWith("image/"))return;if(e.size>5242880){window.alert("Ukuran gambar maksimal 5MB.");return}this.#e.focus();const t=window.getSelection(),i=t.rangeCount?t.getRangeAt(0):null,s=document.createElement("span");s.className="wy-img-uploading",s.contentEditable="false",s.textContent="Mengunggah gambarโ€ฆ",i?(i.deleteContents(),i.insertNode(s),i.setStartAfter(s),i.collapse(!0),t.removeAllRanges(),t.addRange(i)):this.#e.appendChild(s);try{const o=await this.#S(e,l=>{s.textContent=`Mengunggah gambarโ€ฆ ${l}%`}),r=document.createElement("img");r.src=o,r.alt="",s.replaceWith(r)}catch{s.textContent="Gagal mengunggah gambar.",s.classList.add("wy-img-uploading--error"),setTimeout(()=>{s.remove(),this.#r()},3e3)}finally{this.#r()}}#z(e,{width:t,align:i}={}){if(t){const s=String(t).trim();e.style.width=/^\d+$/.test(s)?`${s}px`:s,e.style.height="auto"}this.#L(e,i||"")}#L(e,t){e.classList.remove("wy-img-align-center","wy-img-align-left","wy-img-align-right","wy-img-align-block-left","wy-img-align-block-right"),t&&e.classList.add(`wy-img-align-${t}`)}#N(){const e={signal:this.#h.signal};this.#o.addEventListener("mousedown",t=>t.preventDefault(),e),this.#o.addEventListener("click",t=>{const i=t.target.closest("button");if(!(!i||!this.#i)){if(i.dataset.action==="delete"){const s=this.#i;this.#y(),s.remove(),this.#r();return}i.dataset.align!==void 0&&(this.#L(this.#i,i.dataset.align),this.#C(),this.#g(this.#i),this.#r())}},e)}#C(){if(!this.#i)return;const e=["center","left","right","block-left","block-right"].find(t=>this.#i.classList.contains(`wy-img-align-${t}`))||"";this.#o.querySelectorAll("[data-align]").forEach(t=>{t.classList.toggle("is-active",t.dataset.align===e)})}#D(e){this.#i=e,e.classList.add("wy-img-selected"),this.#o.style.display="flex",this.#c.style.display="block",this.#C(),this.#g(e)}#y(){this.#i&&this.#i.classList.remove("wy-img-selected"),this.#i=null,this.#o.style.display="none",this.#c.style.display="none"}#g(e){const t=e.getBoundingClientRect();this.#c.style.top=`${t.top}px`,this.#c.style.left=`${t.left}px`,this.#c.style.width=`${t.width}px`,this.#c.style.height=`${t.height}px`;const i=this.#o.getBoundingClientRect(),o=t.top>i.height+12?t.top-i.height-8:t.bottom+8,r=Math.max(8,Math.min(t.left,window.innerWidth-i.width-8));this.#o.style.top=`${o}px`,this.#o.style.left=`${r}px`}#U(){const e=document.createElement("div");e.className="wy-img-resize-box",e.style.display="none",e.innerHTML=`
94
+ `,document.body.appendChild(e),this.#o=e,this.#N()}openImageDialog(){const e=window.getSelection();this.#v=e.rangeCount?e.getRangeAt(0).cloneRange():null,this.#H(),this.#a.style.display="flex"}#H(){const e=this.#a;e.querySelectorAll(".wy-img-tab").forEach(t=>t.classList.toggle("is-active",t.dataset.tab==="upload")),e.querySelectorAll(".wy-img-modal__panel").forEach(t=>{t.style.display=t.dataset.panel==="upload"?"":"none"}),e.querySelector(".wy-img-file").value="",e.querySelector(".wy-img-preview").style.display="none",e.querySelector(".wy-img-preview__img").src="",e.querySelector(".wy-img-url-input").value="",e.querySelector(".wy-img-alt-input").value="",e.querySelector(".wy-img-url-preview").style.display="none",e.querySelector(".wy-img-url-preview__img").src="",e.querySelector(".wy-img-width-input").value="",e.querySelector(".wy-img-align-select").value="",e.querySelector(".wy-img-modal__progress").style.display="none",e.querySelector(".wy-img-modal__progress-bar").style.width="0%",e.querySelector(".wy-img-modal__insert").disabled=!0,e.querySelector(".wy-img-dropzone").classList.remove("is-dragover"),this.#d(""),this.#g=null}#b(){this.#a.style.display="none",this.#g=null,this.#v=null}#d(e){const t=this.#a.querySelector(".wy-img-modal__error");t.textContent=e||"",t.style.display=e?"":"none"}#R(){const e=this.#a,t={signal:this.#h.signal};e.querySelectorAll(".wy-img-modal__close, .wy-img-modal__cancel, .wy-img-modal__backdrop").forEach(a=>a.addEventListener("click",()=>this.#b(),t)),e.querySelector(".wy-img-modal__box").addEventListener("click",a=>a.stopPropagation(),t),e.querySelectorAll(".wy-img-tab").forEach(a=>{a.addEventListener("click",()=>{e.querySelectorAll(".wy-img-tab").forEach(d=>d.classList.toggle("is-active",d===a)),e.querySelectorAll(".wy-img-modal__panel").forEach(d=>{d.style.display=d.dataset.panel===a.dataset.tab?"":"none"}),this.#d(""),this.#x()},t)});const i=e.querySelector(".wy-img-file"),s=e.querySelector(".wy-img-dropzone");i.addEventListener("change",()=>{const a=i.files?.[0];a&&this.#E(a)},t),["dragover","dragenter"].forEach(a=>{s.addEventListener(a,d=>{d.preventDefault(),s.classList.add("is-dragover")},t)}),["dragleave","dragend"].forEach(a=>{s.addEventListener(a,d=>{d.preventDefault(),s.classList.remove("is-dragover")},t)}),s.addEventListener("drop",a=>{a.preventDefault(),s.classList.remove("is-dragover");const d=a.dataTransfer.files?.[0];d&&this.#E(d)},t),e.querySelector(".wy-img-preview__remove").addEventListener("click",a=>{a.preventDefault(),this.#g=null,i.value="",e.querySelector(".wy-img-preview").style.display="none",this.#x()},t);const o=e.querySelector(".wy-img-url-input"),r=e.querySelector(".wy-img-url-preview"),l=e.querySelector(".wy-img-url-preview__img");let c;o.addEventListener("input",()=>{this.#d(""),this.#x(),clearTimeout(c);const a=o.value.trim();if(!a){r.style.display="none";return}c=setTimeout(()=>{l.onload=()=>{r.style.display=""},l.onerror=()=>{r.style.display="none"},l.src=a},300)},t),e.querySelector(".wy-img-modal__insert").addEventListener("click",()=>this.#I(),t),e.addEventListener("keydown",a=>{a.key==="Escape"&&this.#b()},t)}#x(){const e=this.#a,t=e.querySelector(".wy-img-tab.is-active")?.dataset.tab,i=e.querySelector(".wy-img-modal__insert");t==="upload"?i.disabled=!this.#g:i.disabled=e.querySelector(".wy-img-url-input").value.trim()===""}#E(e){if(this.#d(""),!e.type.startsWith("image/")){this.#d("File harus berupa gambar.");return}if(e.size>5242880){this.#d("Ukuran gambar maksimal 5MB.");return}this.#g=e;const t=this.#a,i=t.querySelector(".wy-img-preview"),s=t.querySelector(".wy-img-preview__img"),o=new FileReader;o.onload=()=>{s.src=o.result,i.style.display=""},o.readAsDataURL(e),this.#x()}async#I(){const e=this.#a,t=e.querySelector(".wy-img-tab.is-active")?.dataset.tab,i=e.querySelector(".wy-img-alt-input").value.trim(),s=e.querySelector(".wy-img-width-input").value.trim(),o=e.querySelector(".wy-img-align-select").value,r=e.querySelector(".wy-img-modal__insert");if(this.#d(""),t==="upload"){if(!this.#g)return;const l=e.querySelector(".wy-img-modal__progress"),c=e.querySelector(".wy-img-modal__progress-bar");r.disabled=!0,l.style.display="",c.style.width="0%";try{const a=await this.#L(this.#g,d=>{c.style.width=d+"%"});this.#A({src:a,alt:i,width:s,align:o}),this.#b()}catch(a){const d=a?.response?.data?.errors?.image?.[0]||a?.response?.data?.message;this.#d(d||"Upload gambar gagal. Silakan coba lagi."),r.disabled=!1}finally{l.style.display="none"}}else{const l=e.querySelector(".wy-img-url-input").value.trim();if(!l)return;this.#A({src:l,alt:i,width:s,align:o}),this.#b()}}#A(e){this.#e.focus();const t=window.getSelection();t.removeAllRanges(),this.#v&&t.addRange(this.#v);const i=document.createElement("img");if(i.src=e.src,i.alt=e.alt||"",this.#z(i,e),t.rangeCount){const s=t.getRangeAt(0);s.deleteContents(),s.insertNode(i),s.setStartAfter(i),s.collapse(!0),t.removeAllRanges(),t.addRange(s)}else this.#e.appendChild(i);this.#r()}async#L(e,t){const i=this.#t.uploadUrl||window.location.origin+"/wysiwyg/upload-image";if(typeof this.#t.uploadFn=="function")return this.#t.uploadFn(e,i,t);const s=new FormData;return s.append("image",e),new Promise((o,r)=>{const l=new XMLHttpRequest;l.upload.addEventListener("progress",a=>{t&&a.total&&t(Math.round(a.loaded/a.total*100))}),l.addEventListener("load",()=>{if(l.status>=400){r(new Error(`Upload failed: ${l.status} ${l.statusText}`));return}try{const a=JSON.parse(l.responseText);if(!a?.ok||!a?.url)throw new Error("Invalid server response");o(a.url)}catch(a){r(a)}}),l.addEventListener("error",()=>{r(new Error("Network error during upload"))}),l.addEventListener("abort",()=>{r(new Error("Upload aborted"))});const c=document.querySelector('meta[name="csrf-token"]')?.content;c&&l.setRequestHeader("X-CSRF-TOKEN",c),l.open("POST",i,!0),l.send(s)})}async#B(e){if(!e.type.startsWith("image/"))return;if(e.size>5242880){window.alert("Ukuran gambar maksimal 5MB.");return}this.#e.focus();const t=window.getSelection(),i=t.rangeCount?t.getRangeAt(0):null,s=document.createElement("span");s.className="wy-img-uploading",s.contentEditable="false",s.textContent="Mengunggah gambarโ€ฆ",i?(i.deleteContents(),i.insertNode(s),i.setStartAfter(s),i.collapse(!0),t.removeAllRanges(),t.addRange(i)):this.#e.appendChild(s);try{const o=await this.#L(e,l=>{s.textContent=`Mengunggah gambarโ€ฆ ${l}%`}),r=document.createElement("img");r.src=o,r.alt="",s.replaceWith(r)}catch{s.textContent="Gagal mengunggah gambar.",s.classList.add("wy-img-uploading--error"),setTimeout(()=>{s.remove(),this.#r()},3e3)}finally{this.#r()}}#z(e,{width:t,align:i}={}){if(t){const s=String(t).trim();e.style.width=/^\d+$/.test(s)?`${s}px`:s,e.style.height="auto"}this.#S(e,i||"")}#S(e,t){e.classList.remove("wy-img-align-center","wy-img-align-left","wy-img-align-right","wy-img-align-block-left","wy-img-align-block-right"),t&&e.classList.add(`wy-img-align-${t}`)}#N(){const e={signal:this.#h.signal};this.#o.addEventListener("mousedown",t=>t.preventDefault(),e),this.#o.addEventListener("click",t=>{const i=t.target.closest("button");if(!(!i||!this.#i)){if(i.dataset.action==="delete"){const s=this.#i;this.#y(),s.remove(),this.#r();return}i.dataset.align!==void 0&&(this.#S(this.#i,i.dataset.align),this.#T(),this.#m(this.#i),this.#r())}},e)}#T(){if(!this.#i)return;const e=["center","left","right","block-left","block-right"].find(t=>this.#i.classList.contains(`wy-img-align-${t}`))||"";this.#o.querySelectorAll("[data-align]").forEach(t=>{t.classList.toggle("is-active",t.dataset.align===e)})}#D(e){this.#i=e,e.classList.add("wy-img-selected"),this.#o.style.display="flex",this.#c.style.display="block",this.#T(),this.#m(e)}#y(){this.#i&&this.#i.classList.remove("wy-img-selected"),this.#i=null,this.#o.style.display="none",this.#c.style.display="none"}#m(e){const t=e.getBoundingClientRect();this.#c.style.top=`${t.top}px`,this.#c.style.left=`${t.left}px`,this.#c.style.width=`${t.width}px`,this.#c.style.height=`${t.height}px`;const i=this.#o.getBoundingClientRect(),o=t.top>i.height+12?t.top-i.height-8:t.bottom+8,r=Math.max(8,Math.min(t.left,window.innerWidth-i.width-8));this.#o.style.top=`${o}px`,this.#o.style.left=`${r}px`}#U(){const e=document.createElement("div");e.className="wy-img-resize-box",e.style.display="none",e.innerHTML=`
95
95
  <div class="wy-img-resize-handle" data-dir="nw"></div>
96
96
  <div class="wy-img-resize-handle" data-dir="ne"></div>
97
97
  <div class="wy-img-resize-handle" data-dir="sw"></div>
98
98
  <div class="wy-img-resize-handle" data-dir="se"></div>
99
- `,document.body.appendChild(e),this.#c=e;const t={signal:this.#h.signal};e.querySelectorAll(".wy-img-resize-handle").forEach(i=>{i.addEventListener("mousedown",s=>this.#F(s,i.dataset.dir),t)}),window.addEventListener("scroll",()=>{this.#i&&this.#g(this.#i)},{signal:this.#h.signal,capture:!0}),window.addEventListener("resize",()=>{this.#i&&this.#g(this.#i)},t)}#F(e,t){e.preventDefault(),e.stopPropagation();const i=this.#i;if(!i)return;const s=e.clientX,o=i.getBoundingClientRect().width,r=t==="ne"||t==="se"?1:-1,l=30,c=this.#e.getBoundingClientRect().width,a=h=>{const y=(h.clientX-s)*r,p=Math.min(c,Math.max(l,o+y));i.style.width=`${p}px`,i.style.height="auto",this.#g(i)},d=()=>{document.removeEventListener("mousemove",a),document.removeEventListener("mouseup",d),this.#r()};document.addEventListener("mousemove",a),document.addEventListener("mouseup",d)}#j(){const e={signal:this.#h.signal};this.#s.addEventListener("click",t=>{const i=t.target.closest(".wysiwyg-btn");if(!i)return;t.preventDefault(),this.#e.focus();const s=i.dataset.plugin,o=m.#p.get(s)??this.#t.plugins.find(r=>r?.name===s);o?.action&&(o.action(this,i),this.#r())},e),this.#s.addEventListener("mousedown",t=>{t.preventDefault()},e),this.#e.addEventListener("keyup",()=>this.#w(),e),this.#e.addEventListener("mouseup",()=>this.#w(),e),this.#e.addEventListener("selectionchange",()=>this.#w(),e),this.#e.addEventListener("input",()=>this.#r(),e),this.#n.addEventListener("input",()=>{this.#f(),this.#t.onChange?.(this.getHTML())},e),this.#e.addEventListener("paste",t=>{t.preventDefault();const i=t.clipboardData.getData("text/html"),s=t.clipboardData.getData("text/plain"),o=Array.from(t.clipboardData.files||[]);if(i){const r=this.#O(i);document.execCommand("insertHTML",!1,r)}else if(o.length&&o[0].type.startsWith("image/"))this.#I(o[0]);else{const r=s.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/\n/g,"<br>");document.execCommand("insertHTML",!1,r)}},e),this.#e.addEventListener("keydown",t=>{t.key==="Enter"&&this.#P(t)},e),this.#e.addEventListener("click",t=>{const i=t.target.closest("img");i?(t.preventDefault(),this.#D(i)):this.#y()},e),document.addEventListener("click",t=>{!this.#l.contains(t.target)&&!this.#o?.contains(t.target)&&!this.#a?.contains(t.target)&&!this.#c?.contains(t.target)&&this.#y()},e),this.#e.addEventListener("scroll",()=>{this.#i&&this.#g(this.#i)},e)}#P(e){const t=window.getSelection();if(!t.rangeCount)return;const i=t.getRangeAt(0).startContainer,s=i.nodeType===3?i.parentElement.closest("blockquote"):i.closest?.("blockquote");if(s&&(i.nodeType===3?i.parentElement:i).textContent.trim()===""){e.preventDefault(),s.insertAdjacentElement("afterend",Object.assign(document.createElement("p"),{innerHTML:"<br>"}));const r=s.nextElementSibling,l=document.createRange();l.setStart(r,0),l.collapse(!0),t.removeAllRanges(),t.addRange(l)}}#r(){this.#f(),this.#w(),this.#t.onChange?.(this.getHTML())}#w(){const e=this.#t.plugins.length?this.#t.plugins.map(t=>typeof t=="string"?m.#p.get(t):t).filter(Boolean):m.getPlugins();this.#s.querySelectorAll(".wysiwyg-btn").forEach(t=>{const i=e.find(s=>s?.name===t.dataset.plugin);i?.isActive&&(t.classList.toggle("is-active",i.isActive(this)),t.setAttribute("aria-pressed",i.isActive(this)))})}#f(){this.#k&&(this.#k.value=this.getHTML())}getHTML(){if(this.#u)return this.#n.value.trim();const e=this.#e.cloneNode(!0);return e.querySelectorAll("p:empty, div:empty").forEach(t=>{(t.innerHTML===""||t.innerHTML==="<br>")&&t.remove()}),e.querySelectorAll("img.wy-img-selected").forEach(t=>{t.classList.remove("wy-img-selected"),t.className.trim()||t.removeAttribute("class")}),e.innerHTML.trim()}setHTML(e){this.#y(),this.#e.innerHTML=e||"",this.#u&&(this.#n.value=e||""),this.#f()}toggleSource(){if(this.#y(),this.#u){const e=this.#n.value.trim();this.#u=!1,this.#e.innerHTML=e,this.#e.style.display="",this.#n.style.display="none",this.#e.focus(),this.#s.querySelectorAll(".wysiwyg-btn").forEach(t=>{t.disabled=!1,t.style.opacity=""})}else{const e=this.getHTML();this.#u=!0,this.#n.value=this.#$(e),this.#e.style.display="none",this.#n.style.display="",this.#n.focus(),this.#s.querySelectorAll('.wysiwyg-btn:not([data-plugin="source"])').forEach(t=>{t.disabled=!0,t.style.opacity="0.35"})}this.#f(),this.#w()}#$(e){const t=["p","div","h1","h2","h3","h4","h5","h6","ul","ol","li","blockquote","pre","table","thead","tbody","tfoot","tr","th","td","figure","figcaption","section","article","header","footer","nav","br","hr"],s=e.replace(new RegExp(`<(${t.join("|")})(\\s[^>]*)?>`,"gi"),`
99
+ `,document.body.appendChild(e),this.#c=e;const t={signal:this.#h.signal};e.querySelectorAll(".wy-img-resize-handle").forEach(i=>{i.addEventListener("mousedown",s=>this.#F(s,i.dataset.dir),t)}),window.addEventListener("scroll",()=>{this.#i&&this.#m(this.#i)},{signal:this.#h.signal,capture:!0}),window.addEventListener("resize",()=>{this.#i&&this.#m(this.#i)},t)}#F(e,t){e.preventDefault(),e.stopPropagation();const i=this.#i;if(!i)return;const s=e.clientX,o=i.getBoundingClientRect().width,r=t==="ne"||t==="se"?1:-1,l=30,c=this.#e.getBoundingClientRect().width,a=h=>{const y=(h.clientX-s)*r,p=Math.min(c,Math.max(l,o+y));i.style.width=`${p}px`,i.style.height="auto",this.#m(i)},d=()=>{document.removeEventListener("mousemove",a),document.removeEventListener("mouseup",d),this.#r()};document.addEventListener("mousemove",a),document.addEventListener("mouseup",d)}#P(){const e={signal:this.#h.signal};this.#s.addEventListener("click",t=>{const i=t.target.closest(".wysiwyg-btn");if(!i)return;t.preventDefault(),this.#e.focus();const s=i.dataset.plugin,o=g.#p.get(s)??this.#t.plugins.find(r=>r?.name===s);o?.action&&(o.action(this,i),this.#r())},e),this.#s.addEventListener("mousedown",t=>{t.preventDefault()},e),this.#e.addEventListener("keyup",()=>this.#w(),e),this.#e.addEventListener("mouseup",()=>this.#w(),e),this.#e.addEventListener("selectionchange",()=>this.#w(),e),this.#e.addEventListener("input",()=>this.#r(),e),this.#n.addEventListener("input",()=>{this.#f(),this.#t.onChange?.(this.getHTML())},e),this.#e.addEventListener("paste",t=>{t.preventDefault();const i=t.clipboardData.getData("text/html"),s=t.clipboardData.getData("text/plain"),o=Array.from(t.clipboardData.files||[]);if(i){const r=this.#j(i);document.execCommand("insertHTML",!1,r)}else if(o.length&&o[0].type.startsWith("image/"))this.#B(o[0]);else{const r=s.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/\n/g,"<br>");document.execCommand("insertHTML",!1,r)}},e),this.#e.addEventListener("keydown",t=>{t.key==="Enter"&&this.#$(t)},e),this.#e.addEventListener("click",t=>{const i=t.target.closest("img");i?(t.preventDefault(),this.#D(i)):this.#y()},e),document.addEventListener("click",t=>{!this.#l.contains(t.target)&&!this.#o?.contains(t.target)&&!this.#a?.contains(t.target)&&!this.#c?.contains(t.target)&&this.#y()},e),this.#e.addEventListener("scroll",()=>{this.#i&&this.#m(this.#i)},e)}#$(e){const t=window.getSelection();if(!t.rangeCount)return;const i=t.getRangeAt(0).startContainer,s=i.nodeType===3?i.parentElement.closest("blockquote"):i.closest?.("blockquote");if(s&&(i.nodeType===3?i.parentElement:i).textContent.trim()===""){e.preventDefault(),s.insertAdjacentElement("afterend",Object.assign(document.createElement("p"),{innerHTML:"<br>"}));const r=s.nextElementSibling,l=document.createRange();l.setStart(r,0),l.collapse(!0),t.removeAllRanges(),t.addRange(l)}}#r(){this.#f(),this.#w(),this.#t.onChange?.(this.getHTML())}#w(){const e=this.#t.plugins.length?this.#t.plugins.map(t=>typeof t=="string"?g.#p.get(t):t).filter(Boolean):g.getPlugins();this.#s.querySelectorAll(".wysiwyg-btn").forEach(t=>{const i=e.find(s=>s?.name===t.dataset.plugin);i?.isActive&&(t.classList.toggle("is-active",i.isActive(this)),t.setAttribute("aria-pressed",i.isActive(this)))})}#f(){this.#k&&(this.#k.value=this.getHTML())}getHTML(){if(this.#u)return this.#n.value.trim();const e=this.#e.cloneNode(!0);return e.querySelectorAll("p:empty, div:empty").forEach(t=>{(t.innerHTML===""||t.innerHTML==="<br>")&&t.remove()}),e.querySelectorAll("img.wy-img-selected").forEach(t=>{t.classList.remove("wy-img-selected"),t.className.trim()||t.removeAttribute("class")}),e.innerHTML.trim()}setHTML(e){this.#y(),this.#e.innerHTML=e||"",this.#u&&(this.#n.value=e||""),this.#f()}toggleSource(){if(this.#y(),this.#u){const e=this.#n.value.trim();this.#u=!1,this.#e.innerHTML=e,this.#e.style.display="",this.#n.style.display="none",this.#e.focus(),this.#s.querySelectorAll(".wysiwyg-btn").forEach(t=>{t.disabled=!1,t.style.opacity=""})}else{const e=this.getHTML();this.#u=!0,this.#n.value=this.#O(e),this.#e.style.display="none",this.#n.style.display="",this.#n.focus(),this.#s.querySelectorAll('.wysiwyg-btn:not([data-plugin="source"])').forEach(t=>{t.disabled=!0,t.style.opacity="0.35"})}this.#f(),this.#w()}#O(e){const t=["p","div","h1","h2","h3","h4","h5","h6","ul","ol","li","blockquote","pre","table","thead","tbody","tfoot","tr","th","td","figure","figcaption","section","article","header","footer","nav","br","hr"],s=e.replace(new RegExp(`<(${t.join("|")})(\\s[^>]*)?>`,"gi"),`
100
100
  <$1$2>`).replace(new RegExp(`</(${t.join("|")})>`,"gi"),`</$1>
101
101
  `).split(`
102
- `);let o=0;const r=" ";return s.map(c=>{const a=c.trim();if(!a)return null;const d=(a.match(/^<\/[a-z]/i)||[]).length;d&&(o=Math.max(0,o-1));const h=r.repeat(o)+a,y=(a.match(/<[a-zA-Z][^>]*[^/]>/g)||[]).length,p=(a.match(/<\/[a-zA-Z]/g)||[]).length,g=(a.match(/<[a-zA-Z][^>]*\/>/g)||[]).length;return o=Math.max(0,o+y-p-g+(d?1:0)),h}).filter(c=>c!==null).join(`
103
- `).trim()}isSourceMode(){return this.#u}focus(){this.#e.focus()}getArea(){return this.#e}exec(e,t=null){this.#e.focus(),document.execCommand(e,!1,t),this.#r()}wrapBlock(e){document.execCommand("formatBlock",!1,e),this.#r()}#O(e){const t=new DOMParser().parseFromString(e,"text/html");["script","style","meta","link","head","xml","o\\:p","w\\:sdt","w\\:sdtContent"].forEach(l=>{t.querySelectorAll(l).forEach(c=>c.remove())}),["span","font","div > font","ins"].forEach(l=>{t.querySelectorAll(l).forEach(c=>{c.replaceWith(...c.childNodes)})});const o={a:["href","target","rel"],img:["src","alt","width","height"],td:["colspan","rowspan"],th:["colspan","rowspan","scope"],"*":[]};return t.body.querySelectorAll("*").forEach(l=>{const c=l.tagName.toLowerCase(),a=o[c]??o["*"];if(Array.from(l.attributes).map(h=>h.name).forEach(h=>{a.includes(h)||l.removeAttribute(h)}),c==="a"){const h=l.getAttribute("href")||"";/^javascript:/i.test(h.trim())&&l.removeAttribute("href"),l.setAttribute("target","_blank"),l.setAttribute("rel","noopener noreferrer")}}),Object.entries({b:"strong",i:"em",strike:"s",del:"s"}).forEach(([l,c])=>{t.querySelectorAll(l).forEach(a=>{const d=t.createElement(c);d.append(...a.childNodes),a.replaceWith(d)})}),t.querySelectorAll("div:empty, p:empty").forEach(l=>l.remove()),t.body.innerHTML.trim()}destroy(){this.#h.abort(),this.#a?.remove(),this.#o?.remove(),this.#c?.remove(),this.#i=null,this.#l.innerHTML="",this.#l.classList.remove("wysiwyg-editor"),this.#u=!1}queryCommand(e){try{return document.queryCommandState(e)}catch{return!1}}getActiveBlock(){const e=window.getSelection();if(!e.rangeCount)return null;let t=e.getRangeAt(0).startContainer;t.nodeType===3&&(t=t.parentElement);const i=t.closest("h1,h2,h3,h4,h5,h6,p,blockquote,pre,li");return i?i.tagName.toLowerCase():null}}const A={smileys:{title:"๐Ÿ˜Š Smileys",emoji:["๐Ÿ˜€","๐Ÿ˜ƒ","๐Ÿ˜„","๐Ÿ˜","๐Ÿ˜†","๐Ÿ˜…","๐Ÿ˜‚","๐Ÿคฃ","๐Ÿ˜Š","๐Ÿ˜‡","๐Ÿ™‚","๐Ÿค—","๐Ÿ˜‰","๐Ÿ˜Œ","๐Ÿ˜","๐Ÿฅฐ","๐Ÿ˜˜","๐Ÿ˜—","๐Ÿ˜š","๐Ÿ˜™","๐Ÿ˜‹","๐Ÿ˜›","๐Ÿ˜œ","๐Ÿคช","๐Ÿ˜","๐Ÿค‘","๐Ÿค“","๐Ÿ˜Ž"]},hand:{title:"๐Ÿ‘‹ Hand Gestures",emoji:["๐Ÿ‘‹","๐Ÿคš","๐Ÿ–","โœ‹","๐Ÿ––","๐Ÿ‘Œ","๐ŸคŒ","๐Ÿค","โœŒ","๐Ÿคž","๐Ÿซฐ","๐ŸคŸ","๐Ÿค˜","๐Ÿค™","๐Ÿ‘","๐Ÿ‘Ž","โœŠ","๐Ÿ‘Š","๐Ÿค›","๐Ÿคœ","๐Ÿ‘","๐Ÿ™Œ","๐Ÿ‘","๐Ÿคฒ","๐Ÿค","๐Ÿคœ","๐Ÿซฑ","๐Ÿซฒ","๐Ÿซถ"]},hearts:{title:"โค๏ธ Hearts & Love",emoji:["โค๏ธ","๐Ÿงก","๐Ÿ’›","๐Ÿ’š","๐Ÿ’™","๐Ÿ’œ","๐Ÿ–ค","๐Ÿค","๐ŸคŽ","๐Ÿ’”","๐Ÿ’•","๐Ÿ’ž","๐Ÿ’“","๐Ÿ’—","๐Ÿ’–","๐Ÿ’˜","๐Ÿ’","๐Ÿ’Ÿ","๐Ÿ’Œ"]},animals:{title:"๐Ÿถ Animals & Nature",emoji:["๐Ÿถ","๐Ÿฑ","๐Ÿญ","๐Ÿน","๐Ÿฐ","๐ŸฆŠ","๐Ÿป","๐Ÿผ","๐Ÿจ","๐Ÿฏ","๐Ÿฆ","๐Ÿฎ","๐Ÿท","๐Ÿธ","๐Ÿต","๐Ÿ™ˆ","๐Ÿ™‰","๐Ÿ™Š","๐Ÿ’","๐Ÿ”","๐Ÿง","๐Ÿฆ","๐Ÿค","๐Ÿฆ†","๐Ÿฆ…","๐Ÿฆ‰","๐Ÿฆ‡","๐Ÿบ"]},food:{title:"๐Ÿ• Food & Drink",emoji:["๐Ÿ","๐ŸŽ","๐Ÿ","๐ŸŠ","๐Ÿ‹","๐ŸŒ","๐Ÿ‰","๐Ÿ‡","๐Ÿ“","๐Ÿˆ","๐Ÿ’","๐Ÿ‘","๐Ÿฅญ","๐Ÿ","๐Ÿฅฅ","๐Ÿฅ‘","๐Ÿ…","๐Ÿ†","๐Ÿฅ‘","๐Ÿฅฆ","๐Ÿฅฌ","๐Ÿฅ’","๐ŸŒถ","๐ŸŒฝ","๐Ÿฅ”","๐Ÿ ","๐Ÿฅ","๐Ÿž","๐Ÿฅ–","๐Ÿฅจ"]},activities:{title:"โšฝ Activities & Sports",emoji:["โšฝ","๐Ÿ€","๐Ÿˆ","โšพ","๐ŸฅŽ","๐ŸŽพ","๐Ÿ","๐Ÿ‰","๐Ÿฅ","๐ŸŽณ","๐Ÿ“","๐Ÿธ","๐Ÿ’","๐Ÿ‘","๐ŸฅŠ","๐Ÿฅ‹","๐ŸŽฃ","๐ŸŽฝ","๐ŸŽฟ","โ›ท","๐Ÿ‚","๐Ÿช‚","๐Ÿ›น","๐Ÿ›ผ","๐Ÿ›ท","๐ŸฅŒ","๐ŸŽฏ","๐Ÿช€","๐Ÿชƒ"]},travel:{title:"โœˆ๏ธ Travel & Places",emoji:["โœˆ๏ธ","๐Ÿš€","๐Ÿ›ธ","๐Ÿš","๐Ÿš‚","๐Ÿšƒ","๐Ÿš„","๐Ÿš…","๐Ÿš†","๐Ÿš‡","๐Ÿšˆ","๐Ÿš‰","๐ŸšŠ","๐Ÿš","๐Ÿšž","๐Ÿš‹","๐ŸšŒ","๐Ÿš","๐ŸšŽ","๐Ÿš","๐Ÿš‘","๐Ÿš’","๐Ÿš“","๐Ÿš”","๐Ÿš•","๐Ÿš–","๐Ÿš—","๐Ÿš˜","๐Ÿš™"]},symbols:{title:"โญ Symbols & Objects",emoji:["โญ","๐ŸŒŸ","โœจ","โšก","๐Ÿ”ฅ","๐Ÿ’ง","โ„๏ธ","๐ŸŒˆ","๐ŸŽ‰","๐ŸŽŠ","๐ŸŽˆ","๐ŸŽ","๐ŸŽ€","๐ŸŽ‚","๐Ÿฐ","๐ŸŽ†","๐ŸŽ‡","๐Ÿ’ฅ","๐ŸŒธ","๐ŸŒบ","๐ŸŒป","๐ŸŒท","๐ŸŒน","๐Ÿฅ€","๐ŸŒผ"]}};function S(n){const e=document.createElement("div");e.style.cssText=`
102
+ `);let o=0;const r=" ";return s.map(c=>{const a=c.trim();if(!a)return null;const d=(a.match(/^<\/[a-z]/i)||[]).length;d&&(o=Math.max(0,o-1));const h=r.repeat(o)+a,y=(a.match(/<[a-zA-Z][^>]*[^/]>/g)||[]).length,p=(a.match(/<\/[a-zA-Z]/g)||[]).length,m=(a.match(/<[a-zA-Z][^>]*\/>/g)||[]).length;return o=Math.max(0,o+y-p-m+(d?1:0)),h}).filter(c=>c!==null).join(`
103
+ `).trim()}isSourceMode(){return this.#u}focus(){this.#e.focus()}getArea(){return this.#e}exec(e,t=null){this.#e.focus(),document.execCommand(e,!1,t),this.#r()}wrapBlock(e){document.execCommand("formatBlock",!1,e),this.#r()}#j(e){const t=new DOMParser().parseFromString(e,"text/html");["script","style","meta","link","head","xml","o\\:p","w\\:sdt","w\\:sdtContent"].forEach(l=>{t.querySelectorAll(l).forEach(c=>c.remove())}),["span","font","div > font","ins"].forEach(l=>{t.querySelectorAll(l).forEach(c=>{c.replaceWith(...c.childNodes)})});const o={a:["href","target","rel"],img:["src","alt","width","height"],td:["colspan","rowspan"],th:["colspan","rowspan","scope"],"*":[]};return t.body.querySelectorAll("*").forEach(l=>{const c=l.tagName.toLowerCase(),a=o[c]??o["*"];if(Array.from(l.attributes).map(h=>h.name).forEach(h=>{a.includes(h)||l.removeAttribute(h)}),c==="a"){const h=l.getAttribute("href")||"";/^javascript:/i.test(h.trim())&&l.removeAttribute("href"),l.setAttribute("target","_blank"),l.setAttribute("rel","noopener noreferrer")}}),Object.entries({b:"strong",i:"em",strike:"s",del:"s"}).forEach(([l,c])=>{t.querySelectorAll(l).forEach(a=>{const d=t.createElement(c);d.append(...a.childNodes),a.replaceWith(d)})}),t.querySelectorAll("div:empty, p:empty").forEach(l=>l.remove()),t.body.innerHTML.trim()}destroy(){this.#h.abort(),this.#a?.remove(),this.#o?.remove(),this.#c?.remove(),this.#i=null,this.#l.innerHTML="",this.#l.classList.remove("wysiwyg-editor"),this.#u=!1}queryCommand(e){try{return document.queryCommandState(e)}catch{return!1}}getActiveBlock(){const e=window.getSelection();if(!e.rangeCount)return null;let t=e.getRangeAt(0).startContainer;t.nodeType===3&&(t=t.parentElement);const i=t.closest("h1,h2,h3,h4,h5,h6,p,blockquote,pre,li");return i?i.tagName.toLowerCase():null}}const E={smileys:{title:"๐Ÿ˜Š Smileys",emoji:["๐Ÿ˜€","๐Ÿ˜ƒ","๐Ÿ˜„","๐Ÿ˜","๐Ÿ˜†","๐Ÿ˜…","๐Ÿ˜‚","๐Ÿคฃ","๐Ÿ˜Š","๐Ÿ˜‡","๐Ÿ™‚","๐Ÿค—","๐Ÿ˜‰","๐Ÿ˜Œ","๐Ÿ˜","๐Ÿฅฐ","๐Ÿ˜˜","๐Ÿ˜—","๐Ÿ˜š","๐Ÿ˜™","๐Ÿ˜‹","๐Ÿ˜›","๐Ÿ˜œ","๐Ÿคช","๐Ÿ˜","๐Ÿค‘","๐Ÿค“","๐Ÿ˜Ž"]},hand:{title:"๐Ÿ‘‹ Hand Gestures",emoji:["๐Ÿ‘‹","๐Ÿคš","๐Ÿ–","โœ‹","๐Ÿ––","๐Ÿ‘Œ","๐ŸคŒ","๐Ÿค","โœŒ","๐Ÿคž","๐Ÿซฐ","๐ŸคŸ","๐Ÿค˜","๐Ÿค™","๐Ÿ‘","๐Ÿ‘Ž","โœŠ","๐Ÿ‘Š","๐Ÿค›","๐Ÿคœ","๐Ÿ‘","๐Ÿ™Œ","๐Ÿ‘","๐Ÿคฒ","๐Ÿค","๐Ÿคœ","๐Ÿซฑ","๐Ÿซฒ","๐Ÿซถ"]},hearts:{title:"โค๏ธ Hearts & Love",emoji:["โค๏ธ","๐Ÿงก","๐Ÿ’›","๐Ÿ’š","๐Ÿ’™","๐Ÿ’œ","๐Ÿ–ค","๐Ÿค","๐ŸคŽ","๐Ÿ’”","๐Ÿ’•","๐Ÿ’ž","๐Ÿ’“","๐Ÿ’—","๐Ÿ’–","๐Ÿ’˜","๐Ÿ’","๐Ÿ’Ÿ","๐Ÿ’Œ"]},animals:{title:"๐Ÿถ Animals & Nature",emoji:["๐Ÿถ","๐Ÿฑ","๐Ÿญ","๐Ÿน","๐Ÿฐ","๐ŸฆŠ","๐Ÿป","๐Ÿผ","๐Ÿจ","๐Ÿฏ","๐Ÿฆ","๐Ÿฎ","๐Ÿท","๐Ÿธ","๐Ÿต","๐Ÿ™ˆ","๐Ÿ™‰","๐Ÿ™Š","๐Ÿ’","๐Ÿ”","๐Ÿง","๐Ÿฆ","๐Ÿค","๐Ÿฆ†","๐Ÿฆ…","๐Ÿฆ‰","๐Ÿฆ‡","๐Ÿบ"]},food:{title:"๐Ÿ• Food & Drink",emoji:["๐Ÿ","๐ŸŽ","๐Ÿ","๐ŸŠ","๐Ÿ‹","๐ŸŒ","๐Ÿ‰","๐Ÿ‡","๐Ÿ“","๐Ÿˆ","๐Ÿ’","๐Ÿ‘","๐Ÿฅญ","๐Ÿ","๐Ÿฅฅ","๐Ÿฅ‘","๐Ÿ…","๐Ÿ†","๐Ÿฅ‘","๐Ÿฅฆ","๐Ÿฅฌ","๐Ÿฅ’","๐ŸŒถ","๐ŸŒฝ","๐Ÿฅ”","๐Ÿ ","๐Ÿฅ","๐Ÿž","๐Ÿฅ–","๐Ÿฅจ"]},activities:{title:"โšฝ Activities & Sports",emoji:["โšฝ","๐Ÿ€","๐Ÿˆ","โšพ","๐ŸฅŽ","๐ŸŽพ","๐Ÿ","๐Ÿ‰","๐Ÿฅ","๐ŸŽณ","๐Ÿ“","๐Ÿธ","๐Ÿ’","๐Ÿ‘","๐ŸฅŠ","๐Ÿฅ‹","๐ŸŽฃ","๐ŸŽฝ","๐ŸŽฟ","โ›ท","๐Ÿ‚","๐Ÿช‚","๐Ÿ›น","๐Ÿ›ผ","๐Ÿ›ท","๐ŸฅŒ","๐ŸŽฏ","๐Ÿช€","๐Ÿชƒ"]},travel:{title:"โœˆ๏ธ Travel & Places",emoji:["โœˆ๏ธ","๐Ÿš€","๐Ÿ›ธ","๐Ÿš","๐Ÿš‚","๐Ÿšƒ","๐Ÿš„","๐Ÿš…","๐Ÿš†","๐Ÿš‡","๐Ÿšˆ","๐Ÿš‰","๐ŸšŠ","๐Ÿš","๐Ÿšž","๐Ÿš‹","๐ŸšŒ","๐Ÿš","๐ŸšŽ","๐Ÿš","๐Ÿš‘","๐Ÿš’","๐Ÿš“","๐Ÿš”","๐Ÿš•","๐Ÿš–","๐Ÿš—","๐Ÿš˜","๐Ÿš™"]},symbols:{title:"โญ Symbols & Objects",emoji:["โญ","๐ŸŒŸ","โœจ","โšก","๐Ÿ”ฅ","๐Ÿ’ง","โ„๏ธ","๐ŸŒˆ","๐ŸŽ‰","๐ŸŽŠ","๐ŸŽˆ","๐ŸŽ","๐ŸŽ€","๐ŸŽ‚","๐Ÿฐ","๐ŸŽ†","๐ŸŽ‡","๐Ÿ’ฅ","๐ŸŒธ","๐ŸŒบ","๐ŸŒป","๐ŸŒท","๐ŸŒน","๐Ÿฅ€","๐ŸŒผ"]}};function A(n){const e=document.createElement("div");e.style.cssText=`
104
104
  position: fixed;
105
105
  top: 0;
106
106
  left: 0;
@@ -145,7 +145,7 @@ var WysiwygEditor=(function(w,k){"use strict";const E={placeholder:"Tulis sesuat
145
145
  flex: 1;
146
146
  overflow-y: auto;
147
147
  padding: 12px;
148
- `,Object.entries(A).forEach(([l,c],a)=>{const d=document.createElement("button");d.innerHTML=c.emoji[0],d.style.cssText=`
148
+ `,Object.entries(E).forEach(([l,c],a)=>{const d=document.createElement("button");d.innerHTML=c.emoji[0],d.style.cssText=`
149
149
  background: ${a===0?"#e0e7ff":"#f3f4f6"};
150
150
  border: none;
151
151
  width: 36px;
@@ -164,7 +164,7 @@ var WysiwygEditor=(function(w,k){"use strict";const E={placeholder:"Tulis sesuat
164
164
  display: grid;
165
165
  grid-template-columns: repeat(auto-fill, 36px);
166
166
  gap: 4px;
167
- `,c.emoji.forEach(p=>{const g=document.createElement("button");g.textContent=p,g.style.cssText=`
167
+ `,c.emoji.forEach(p=>{const m=document.createElement("button");m.textContent=p,m.style.cssText=`
168
168
  width: 36px;
169
169
  height: 36px;
170
170
  border: 1px solid #ddd;
@@ -173,7 +173,7 @@ var WysiwygEditor=(function(w,k){"use strict";const E={placeholder:"Tulis sesuat
173
173
  cursor: pointer;
174
174
  font-size: 20px;
175
175
  transition: all 0.15s;
176
- `,g.onmouseover=()=>{g.style.background="#f3f4f6",g.style.transform="scale(1.2)"},g.onmouseout=()=>{g.style.background="white",g.style.transform="scale(1)"},g.onclick=()=>{n(p),e.remove(),t.remove()},y.appendChild(g)}),r.appendChild(y)},o.appendChild(d)}),o.querySelector("button").click(),t.appendChild(i),t.appendChild(o),t.appendChild(r),document.body.appendChild(e),document.body.appendChild(t),e.onclick=()=>{e.remove(),t.remove()},t}const u=(n,e="")=>`<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" ${e}>${n}</svg>`,f=(n,e="")=>window.prompt(n,e),v=[{name:"bold",group:"format",title:"Bold (Ctrl+B)",icon:u('<path d="M6 4h8a4 4 0 0 1 4 4 4 4 0 0 1-4 4H6z"/><path d="M6 12h9a4 4 0 0 1 4 4 4 4 0 0 1-4 4H6z"/>'),action:n=>n.exec("bold"),isActive:n=>n.queryCommand("bold")},{name:"italic",group:"format",title:"Italic (Ctrl+I)",icon:u('<line x1="19" y1="4" x2="10" y2="4"/><line x1="14" y1="20" x2="5" y2="20"/><line x1="15" y1="4" x2="9" y2="20"/>'),action:n=>n.exec("italic"),isActive:n=>n.queryCommand("italic")},{name:"underline",group:"format",title:"Underline (Ctrl+U)",icon:u('<path d="M6 3v7a6 6 0 0 0 6 6 6 6 0 0 0 6-6V3"/><line x1="4" y1="21" x2="20" y2="21"/>'),action:n=>n.exec("underline"),isActive:n=>n.queryCommand("underline")},{name:"strikethrough",group:"format",title:"Strikethrough",icon:u('<path d="M17.3 12a4.6 4.6 0 0 1-1.3 3A5 5 0 0 1 12 17a5.7 5.7 0 0 1-4-1.5"/><path d="M6.6 8.8A4.1 4.1 0 0 1 8 6a5 5 0 0 1 4-1.5 5.7 5.7 0 0 1 3.5 1c1 .7 1.6 1.5 1.8 2.5"/><line x1="4" y1="12" x2="20" y2="12"/>'),action:n=>n.exec("strikeThrough"),isActive:n=>n.queryCommand("strikeThrough")},{name:"h1",group:"heading",title:"Heading 1",icon:'<span style="font-weight:700;font-size:12px;line-height:1">H1</span>',action:n=>{const e=n.getActiveBlock()==="h1";n.wrapBlock(e?"p":"h1")},isActive:n=>n.getActiveBlock()==="h1"},{name:"h2",group:"heading",title:"Heading 2",icon:'<span style="font-weight:700;font-size:12px;line-height:1">H2</span>',action:n=>{const e=n.getActiveBlock()==="h2";n.wrapBlock(e?"p":"h2")},isActive:n=>n.getActiveBlock()==="h2"},{name:"h3",group:"heading",title:"Heading 3",icon:'<span style="font-weight:700;font-size:12px;line-height:1">H3</span>',action:n=>{const e=n.getActiveBlock()==="h3";n.wrapBlock(e?"p":"h3")},isActive:n=>n.getActiveBlock()==="h3"},{name:"ul",group:"list",title:"Bullet List",icon:u('<line x1="9" y1="6" x2="20" y2="6"/><line x1="9" y1="12" x2="20" y2="12"/><line x1="9" y1="18" x2="20" y2="18"/><circle cx="4" cy="6" r="1.5" fill="currentColor" stroke="none"/><circle cx="4" cy="12" r="1.5" fill="currentColor" stroke="none"/><circle cx="4" cy="18" r="1.5" fill="currentColor" stroke="none"/>'),action:n=>n.exec("insertUnorderedList"),isActive:n=>n.queryCommand("insertUnorderedList")},{name:"ol",group:"list",title:"Numbered List",icon:u('<line x1="10" y1="6" x2="21" y2="6"/><line x1="10" y1="12" x2="21" y2="12"/><line x1="10" y1="18" x2="21" y2="18"/><path d="M4 6h1v4"/><path d="M4 10h2"/><path d="M6 18H4c0-1 2-2 2-3s-1-1.5-2-1"/>'),action:n=>n.exec("insertOrderedList"),isActive:n=>n.queryCommand("insertOrderedList")},{name:"blockquote",group:"block",title:"Blockquote",icon:u('<path d="M3 21c3 0 7-1 7-8V5c0-1.25-.756-2.017-2-2H4c-1.25 0-2 .75-2 1.972V11c0 1.25.75 2 2 2 1 0 1 0 1 1v1c0 1-1 2-2 2s-1 .008-1 1.031V20c0 1 0 1 1 1z"/><path d="M15 21c3 0 7-1 7-8V5c0-1.25-.757-2.017-2-2h-4c-1.25 0-2 .75-2 1.972V11c0 1.25.75 2 2 2h.75c0 2.25.25 4-2.75 4v3c0 1 0 1 1 1z"/>'),action:n=>{const e=n.getActiveBlock()==="blockquote";n.wrapBlock(e?"p":"blockquote")},isActive:n=>n.getActiveBlock()==="blockquote"},{name:"link",group:"link",title:"Insert Link",icon:u('<path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/>'),action:n=>{const e=document.queryCommandValue("createLink"),t=f("Masukkan URL:",e||"https://");t!==null&&(t.trim()===""?n.exec("unlink"):(n.exec("createLink",t.trim()),n.getArea().querySelectorAll("a").forEach(i=>{i.target="_blank",i.rel="noopener noreferrer"})))},isActive:n=>n.queryCommand("createLink")},{name:"unlink",group:"link",title:"Remove Link",icon:u('<path d="M18.84 12.25l1.72-1.71h-.02a5.004 5.004 0 0 0-.12-7.07 5.006 5.006 0 0 0-6.95 0l-1.72 1.71"/><path d="M5.17 11.75l-1.71 1.71a5.004 5.004 0 0 0 .12 7.07 5.006 5.006 0 0 0 6.95 0l1.71-1.71"/><line x1="8" y1="2" x2="8" y2="5"/><line x1="2" y1="8" x2="5" y2="8"/><line x1="16" y1="19" x2="16" y2="22"/><line x1="19" y1="16" x2="22" y2="16"/>'),action:n=>n.exec("unlink")},{name:"undo",group:"history",title:"Undo (Ctrl+Z)",icon:u('<polyline points="9 14 4 9 9 4"/><path d="M20 20v-7a4 4 0 0 0-4-4H4"/>'),action:n=>n.exec("undo")},{name:"redo",group:"history",title:"Redo (Ctrl+Y)",icon:u('<polyline points="15 14 20 9 15 4"/><path d="M4 20v-7a4 4 0 0 0 4-4h12"/>'),action:n=>n.exec("redo")},{name:"removeFormat",group:"clear",title:"Hapus Formatting",icon:u('<path d="M4 7V4h16v3"/><path d="M5 20h6"/><path d="M13 4 8 20"/><line x1="17" y1="13" x2="22" y2="18"/><line x1="22" y1="13" x2="17" y2="18"/>'),action:n=>n.exec("removeFormat")},{name:"source",group:"source",title:"Edit HTML Source",icon:u('<polyline points="16 18 22 12 16 6"/><polyline points="8 6 2 12 8 18"/>'),action:n=>n.toggleSource(),isActive:n=>n.isSourceMode()},{name:"image",group:"image",title:"Sisipkan Gambar",icon:u('<rect x="3" y="3" width="18" height="18" rx="2"/><circle cx="8.5" cy="8.5" r="1.5"/><path d="m21 15-5-5L5 21"/>'),action:n=>n.openImageDialog()},{name:"table",group:"table",title:"Insert Table (2x2)",icon:u('<rect x="3" y="3" width="18" height="18" rx="1"/><line x1="3" y1="9" x2="21" y2="9"/><line x1="3" y1="15" x2="21" y2="15"/><line x1="9" y1="3" x2="9" y2="21"/><line x1="15" y1="3" x2="15" y2="21"/>'),action:n=>{const e=L(2,2),t=window.getSelection(),i=t.getRangeAt(0);i.insertNode(e),i.collapse(!1),t.removeAllRanges(),t.addRange(i),n.focus()}},{name:"table-add-row",group:"table",title:"Add Row Below",icon:u('<rect x="2" y="2" width="20" height="20"/><line x1="2" y1="12" x2="22" y2="12"/><line x1="12" y1="2" x2="12" y2="22"/><line x1="17" y1="15" x2="23" y2="15"/><line x1="20" y1="12" x2="20" y2="18"/>'),action:n=>C(n)},{name:"table-delete",group:"table",title:"Delete Table",icon:u('<rect x="3" y="3" width="18" height="18" rx="1" stroke-dasharray="3,3"/><line x1="3" y1="9" x2="21" y2="9"/><line x1="3" y1="15" x2="21" y2="15"/><line x1="9" y1="3" x2="9" y2="21"/><line x1="15" y1="3" x2="15" y2="21"/><line x1="9" y1="9" x2="15" y2="15"/><line x1="15" y1="9" x2="9" y2="15"/>'),action:n=>T(n)}];function L(n,e){const t=document.createElement("table");t.style.cssText=`
176
+ `,m.onmouseover=()=>{m.style.background="#f3f4f6",m.style.transform="scale(1.2)"},m.onmouseout=()=>{m.style.background="white",m.style.transform="scale(1)"},m.onclick=()=>{n(p),e.remove(),t.remove()},y.appendChild(m)}),r.appendChild(y)},o.appendChild(d)}),o.querySelector("button").click(),t.appendChild(i),t.appendChild(o),t.appendChild(r),document.body.appendChild(e),document.body.appendChild(t),e.onclick=()=>{e.remove(),t.remove()},t}const u=(n,e="")=>`<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" ${e}>${n}</svg>`,f=(n,e="")=>window.prompt(n,e),v=[{name:"bold",group:"format",title:"Bold (Ctrl+B)",icon:u('<path d="M6 4h8a4 4 0 0 1 4 4 4 4 0 0 1-4 4H6z"/><path d="M6 12h9a4 4 0 0 1 4 4 4 4 0 0 1-4 4H6z"/>'),action:n=>n.exec("bold"),isActive:n=>n.queryCommand("bold")},{name:"italic",group:"format",title:"Italic (Ctrl+I)",icon:u('<line x1="19" y1="4" x2="10" y2="4"/><line x1="14" y1="20" x2="5" y2="20"/><line x1="15" y1="4" x2="9" y2="20"/>'),action:n=>n.exec("italic"),isActive:n=>n.queryCommand("italic")},{name:"underline",group:"format",title:"Underline (Ctrl+U)",icon:u('<path d="M6 3v7a6 6 0 0 0 6 6 6 6 0 0 0 6-6V3"/><line x1="4" y1="21" x2="20" y2="21"/>'),action:n=>n.exec("underline"),isActive:n=>n.queryCommand("underline")},{name:"strikethrough",group:"format",title:"Strikethrough",icon:u('<path d="M17.3 12a4.6 4.6 0 0 1-1.3 3A5 5 0 0 1 12 17a5.7 5.7 0 0 1-4-1.5"/><path d="M6.6 8.8A4.1 4.1 0 0 1 8 6a5 5 0 0 1 4-1.5 5.7 5.7 0 0 1 3.5 1c1 .7 1.6 1.5 1.8 2.5"/><line x1="4" y1="12" x2="20" y2="12"/>'),action:n=>n.exec("strikeThrough"),isActive:n=>n.queryCommand("strikeThrough")},{name:"h1",group:"heading",title:"Heading 1",icon:'<span style="font-weight:700;font-size:12px;line-height:1">H1</span>',action:n=>{const e=n.getActiveBlock()==="h1";n.wrapBlock(e?"p":"h1")},isActive:n=>n.getActiveBlock()==="h1"},{name:"h2",group:"heading",title:"Heading 2",icon:'<span style="font-weight:700;font-size:12px;line-height:1">H2</span>',action:n=>{const e=n.getActiveBlock()==="h2";n.wrapBlock(e?"p":"h2")},isActive:n=>n.getActiveBlock()==="h2"},{name:"h3",group:"heading",title:"Heading 3",icon:'<span style="font-weight:700;font-size:12px;line-height:1">H3</span>',action:n=>{const e=n.getActiveBlock()==="h3";n.wrapBlock(e?"p":"h3")},isActive:n=>n.getActiveBlock()==="h3"},{name:"ul",group:"list",title:"Bullet List",icon:u('<line x1="9" y1="6" x2="20" y2="6"/><line x1="9" y1="12" x2="20" y2="12"/><line x1="9" y1="18" x2="20" y2="18"/><circle cx="4" cy="6" r="1.5" fill="currentColor" stroke="none"/><circle cx="4" cy="12" r="1.5" fill="currentColor" stroke="none"/><circle cx="4" cy="18" r="1.5" fill="currentColor" stroke="none"/>'),action:n=>n.exec("insertUnorderedList"),isActive:n=>n.queryCommand("insertUnorderedList")},{name:"ol",group:"list",title:"Numbered List",icon:u('<line x1="10" y1="6" x2="21" y2="6"/><line x1="10" y1="12" x2="21" y2="12"/><line x1="10" y1="18" x2="21" y2="18"/><path d="M4 6h1v4"/><path d="M4 10h2"/><path d="M6 18H4c0-1 2-2 2-3s-1-1.5-2-1"/>'),action:n=>n.exec("insertOrderedList"),isActive:n=>n.queryCommand("insertOrderedList")},{name:"blockquote",group:"block",title:"Blockquote",icon:u('<path d="M3 21c3 0 7-1 7-8V5c0-1.25-.756-2.017-2-2H4c-1.25 0-2 .75-2 1.972V11c0 1.25.75 2 2 2 1 0 1 0 1 1v1c0 1-1 2-2 2s-1 .008-1 1.031V20c0 1 0 1 1 1z"/><path d="M15 21c3 0 7-1 7-8V5c0-1.25-.757-2.017-2-2h-4c-1.25 0-2 .75-2 1.972V11c0 1.25.75 2 2 2h.75c0 2.25.25 4-2.75 4v3c0 1 0 1 1 1z"/>'),action:n=>{const e=n.getActiveBlock()==="blockquote";n.wrapBlock(e?"p":"blockquote")},isActive:n=>n.getActiveBlock()==="blockquote"},{name:"link",group:"link",title:"Insert Link",icon:u('<path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/>'),action:n=>{const e=document.queryCommandValue("createLink"),t=f("Masukkan URL:",e||"https://");t!==null&&(t.trim()===""?n.exec("unlink"):(n.exec("createLink",t.trim()),n.getArea().querySelectorAll("a").forEach(i=>{i.target="_blank",i.rel="noopener noreferrer"})))},isActive:n=>n.queryCommand("createLink")},{name:"unlink",group:"link",title:"Remove Link",icon:u('<path d="M18.84 12.25l1.72-1.71h-.02a5.004 5.004 0 0 0-.12-7.07 5.006 5.006 0 0 0-6.95 0l-1.72 1.71"/><path d="M5.17 11.75l-1.71 1.71a5.004 5.004 0 0 0 .12 7.07 5.006 5.006 0 0 0 6.95 0l1.71-1.71"/><line x1="8" y1="2" x2="8" y2="5"/><line x1="2" y1="8" x2="5" y2="8"/><line x1="16" y1="19" x2="16" y2="22"/><line x1="19" y1="16" x2="22" y2="16"/>'),action:n=>n.exec("unlink")},{name:"undo",group:"history",title:"Undo (Ctrl+Z)",icon:u('<polyline points="9 14 4 9 9 4"/><path d="M20 20v-7a4 4 0 0 0-4-4H4"/>'),action:n=>n.exec("undo")},{name:"redo",group:"history",title:"Redo (Ctrl+Y)",icon:u('<polyline points="15 14 20 9 15 4"/><path d="M4 20v-7a4 4 0 0 0 4-4h12"/>'),action:n=>n.exec("redo")},{name:"removeFormat",group:"clear",title:"Hapus Formatting",icon:u('<path d="M4 7V4h16v3"/><path d="M5 20h6"/><path d="M13 4 8 20"/><line x1="17" y1="13" x2="22" y2="18"/><line x1="22" y1="13" x2="17" y2="18"/>'),action:n=>n.exec("removeFormat")},{name:"source",group:"source",title:"Edit HTML Source",icon:u('<polyline points="16 18 22 12 16 6"/><polyline points="8 6 2 12 8 18"/>'),action:n=>n.toggleSource(),isActive:n=>n.isSourceMode()},{name:"image",group:"image",title:"Sisipkan Gambar",icon:u('<rect x="3" y="3" width="18" height="18" rx="2"/><circle cx="8.5" cy="8.5" r="1.5"/><path d="m21 15-5-5L5 21"/>'),action:n=>n.openImageDialog()},{name:"table",group:"table",title:"Insert Table (2x2)",icon:u('<rect x="3" y="3" width="18" height="18" rx="1"/><line x1="3" y1="9" x2="21" y2="9"/><line x1="3" y1="15" x2="21" y2="15"/><line x1="9" y1="3" x2="9" y2="21"/><line x1="15" y1="3" x2="15" y2="21"/>'),action:n=>{const e=L(2,2),t=window.getSelection(),i=t.getRangeAt(0);i.insertNode(e),i.collapse(!1),t.removeAllRanges(),t.addRange(i),n.focus()}},{name:"table-add-row",group:"table",title:"Add Row Below",icon:u('<rect x="2" y="2" width="20" height="20"/><line x1="2" y1="12" x2="22" y2="12"/><line x1="12" y1="2" x2="12" y2="22"/><line x1="17" y1="15" x2="23" y2="15"/><line x1="20" y1="12" x2="20" y2="18"/>'),action:n=>S(n)},{name:"table-delete",group:"table",title:"Delete Table",icon:u('<rect x="3" y="3" width="18" height="18" rx="1" stroke-dasharray="3,3"/><line x1="3" y1="9" x2="21" y2="9"/><line x1="3" y1="15" x2="21" y2="15"/><line x1="9" y1="3" x2="9" y2="21"/><line x1="15" y1="3" x2="15" y2="21"/><line x1="9" y1="9" x2="15" y2="15"/><line x1="15" y1="9" x2="9" y2="15"/>'),action:n=>T(n)}];function L(n,e){const t=document.createElement("table");t.style.cssText=`
177
177
  border-collapse: collapse;
178
178
  width: 100%;
179
179
  margin: 12px 0;
@@ -182,7 +182,7 @@ var WysiwygEditor=(function(w,k){"use strict";const E={placeholder:"Tulis sesuat
182
182
  padding: 8px;
183
183
  text-align: left;
184
184
  min-width: 80px;
185
- `,r.innerHTML=i===0?`<strong>Header ${o+1}</strong>`:"<br>",s.appendChild(r)}t.appendChild(s)}return t}function C(n){n.getArea();const e=window.getSelection();if(e.rangeCount===0)return;const t=e.getRangeAt(0),i=t.commonAncestorContainer.closest("td")||t.commonAncestorContainer.closest("th");if(!i){alert("Posisikan kursor di dalam tabel terlebih dahulu");return}const s=i.closest("tr"),o=s.closest("table"),r=document.createElement("tr");Array.from(s.children).forEach(()=>{const l=document.createElement("td");l.style.cssText=i.style.cssText,l.innerHTML="<br>",r.appendChild(l)}),o.appendChild(r)}function T(n){n.getArea();const e=window.getSelection();if(e.rangeCount===0)return;const i=e.getRangeAt(0).commonAncestorContainer.closest("table");if(!i){alert("Posisikan kursor di dalam tabel terlebih dahulu");return}confirm("Hapus tabel ini?")&&(i.remove(),n.focus())}v.push({name:"mention",group:"insert",title:"Mention (@username)",icon:u('<path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M23 11h-6m-2-2 2 2-2 2" stroke-width="1.5"/>'),action:n=>{const e=f("Username:","@");if(e&&e.trim()){const t=document.createElement("span");t.className="mention",t.contentEditable=!1,t.style.cssText=`
185
+ `,r.innerHTML=i===0?`<strong>Header ${o+1}</strong>`:"<br>",s.appendChild(r)}t.appendChild(s)}return t}function S(n){n.getArea();const e=window.getSelection();if(e.rangeCount===0)return;let i=e.getRangeAt(0).commonAncestorContainer;i.nodeType===3&&(i=i.parentElement);const s=i.closest("td")||i.closest("th");if(!s){alert("Posisikan kursor di dalam tabel terlebih dahulu");return}const o=s.closest("tr"),r=o.closest("table"),l=document.createElement("tr");Array.from(o.children).forEach(()=>{const c=document.createElement("td");c.style.cssText=s.style.cssText,c.innerHTML="<br>",l.appendChild(c)}),r.appendChild(l)}function T(n){n.getArea();const e=window.getSelection();if(e.rangeCount===0)return;let i=e.getRangeAt(0).commonAncestorContainer;i.nodeType===3&&(i=i.parentElement);const s=i.closest("table");if(!s){alert("Posisikan kursor di dalam tabel terlebih dahulu");return}confirm("Hapus tabel ini?")&&(s.remove(),n.focus())}v.push({name:"mention",group:"insert",title:"Mention (@username)",icon:u('<path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M23 11h-6m-2-2 2 2-2 2" stroke-width="1.5"/>'),action:n=>{const e=f("Username:","@");if(e&&e.trim()){const t=document.createElement("span");t.className="mention",t.contentEditable=!1,t.style.cssText=`
186
186
  background: #e0e7ff;
187
187
  color: #4f46e5;
188
188
  padding: 2px 6px;
@@ -191,4 +191,4 @@ var WysiwygEditor=(function(w,k){"use strict";const E={placeholder:"Tulis sesuat
191
191
  font-weight: 500;
192
192
  cursor: default;
193
193
  display: inline-block;
194
- `,t.textContent=e,t.dataset.mention=e.replace("@","");const i=window.getSelection().getRangeAt(0);i.insertNode(t),i.setStartAfter(t),i.collapse(!0);const s=window.getSelection();s.removeAllRanges(),s.addRange(i),n.focus()}}},{name:"emoji",group:"insert",title:"Insert Emoji",icon:u('<circle cx="12" cy="12" r="9"/><circle cx="9" cy="9" r="1.5" fill="currentColor"/><circle cx="15" cy="9" r="1.5" fill="currentColor"/><path d="M8 15a4 4 0 0 0 8 0"/>'),action:n=>{S(e=>{const t=window.getSelection().getRangeAt(0),i=document.createTextNode(e);t.insertNode(i),t.setStartAfter(i),t.collapse(!0);const s=window.getSelection();s.removeAllRanges(),s.addRange(t),n.focus()})}});async function b(n,e,t){const i=new FormData;i.append("image",n);const s=document.querySelector('meta[name="csrf-token"]')?.content,o={};return s&&(o["X-CSRF-TOKEN"]=s,o["X-Requested-With"]="XMLHttpRequest"),new Promise((r,l)=>{const c=new XMLHttpRequest;c.open("POST",e),Object.entries(o).forEach(([a,d])=>c.setRequestHeader(a,d)),c.upload.addEventListener("progress",a=>{a.lengthComputable&&t&&t(Math.round(a.loaded/a.total*100))}),c.addEventListener("load",()=>{try{const a=JSON.parse(c.responseText);if(c.status>=200&&c.status<300&&a?.ok&&a?.url)r(a.url);else{const d=a?.message||a?.errors?.image?.[0]||`Server error ${c.status}`;l(new Error(d))}}catch{l(new Error("Respon server tidak valid"))}}),c.addEventListener("error",()=>l(new Error("Koneksi gagal"))),c.addEventListener("abort",()=>l(new Error("Upload dibatalkan"))),c.send(i)})}v.forEach(n=>m.registerPlugin(n));function x(){document.querySelectorAll("[data-wysiwyg]").forEach(n=>{if(n._wysiwygEditor)return;const e=new m(n,{placeholder:n.dataset.wysiwygPlaceholder||"Tulis sesuatu...",minHeight:parseInt(n.dataset.wysiwygHeight||"200",10),syncInput:n.dataset.wysiwygInput||null,uploadUrl:n.dataset.wysiwygUploadUrl||"",uploadFn:b}),t=n.dataset.wysiwygInitial||"";t&&e.setHTML(t),n._wysiwygEditor=e})}return document.readyState==="loading"?document.addEventListener("DOMContentLoaded",x):x(),typeof window<"u"&&(window.WysiwygEditor=m,window.WysiwygEditor.create=(n,e={})=>new m(n,{uploadFn:b,...e})),w.WysiwygEditor=m,Object.defineProperty(w,Symbol.toStringTag,{value:"Module"}),w})({},axios);
194
+ `,t.textContent=e,t.dataset.mention=e.replace("@","");const i=window.getSelection().getRangeAt(0);i.insertNode(t),i.setStartAfter(t),i.collapse(!0);const s=window.getSelection();s.removeAllRanges(),s.addRange(i),n.focus()}}},{name:"emoji",group:"insert",title:"Insert Emoji",icon:u('<circle cx="12" cy="12" r="9"/><circle cx="9" cy="9" r="1.5" fill="currentColor"/><circle cx="15" cy="9" r="1.5" fill="currentColor"/><path d="M8 15a4 4 0 0 0 8 0"/>'),action:n=>{A(e=>{const t=window.getSelection().getRangeAt(0),i=document.createTextNode(e);t.insertNode(i),t.setStartAfter(i),t.collapse(!0);const s=window.getSelection();s.removeAllRanges(),s.addRange(t),n.focus()})}});async function b(n,e,t){const i=new FormData;i.append("image",n);const s=document.querySelector('meta[name="csrf-token"]')?.content,o={};return s&&(o["X-CSRF-TOKEN"]=s,o["X-Requested-With"]="XMLHttpRequest"),new Promise((r,l)=>{const c=new XMLHttpRequest;c.open("POST",e),Object.entries(o).forEach(([a,d])=>c.setRequestHeader(a,d)),c.upload.addEventListener("progress",a=>{a.lengthComputable&&t&&t(Math.round(a.loaded/a.total*100))}),c.addEventListener("load",()=>{try{const a=JSON.parse(c.responseText);if(c.status>=200&&c.status<300&&a?.ok&&a?.url)r(a.url);else{const d=a?.message||a?.errors?.image?.[0]||`Server error ${c.status}`;l(new Error(d))}}catch{l(new Error("Respon server tidak valid"))}}),c.addEventListener("error",()=>l(new Error("Koneksi gagal"))),c.addEventListener("abort",()=>l(new Error("Upload dibatalkan"))),c.send(i)})}v.forEach(n=>g.registerPlugin(n));function x(){document.querySelectorAll("[data-wysiwyg]").forEach(n=>{if(n._wysiwygEditor)return;const e=new g(n,{placeholder:n.dataset.wysiwygPlaceholder||"Tulis sesuatu...",minHeight:parseInt(n.dataset.wysiwygHeight||"200",10),syncInput:n.dataset.wysiwygInput||null,uploadUrl:n.dataset.wysiwygUploadUrl||"",uploadFn:b}),t=n.dataset.wysiwygInitial||"";t&&e.setHTML(t),n._wysiwygEditor=e})}return document.readyState==="loading"?document.addEventListener("DOMContentLoaded",x):x(),typeof window<"u"&&(window.WysiwygEditor=g,window.WysiwygEditor.create=(n,e={})=>new g(n,{uploadFn:b,...e})),w.WysiwygEditor=g,Object.defineProperty(w,Symbol.toStringTag,{value:"Module"}),w})({});