ckeditor5-phoenix 1.22.0 → 1.23.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/dist/hooks/editable.d.ts.map +1 -1
  2. package/dist/hooks/editor/editor.d.ts.map +1 -1
  3. package/dist/hooks/editor/plugins/sync-editor-with-phoenix.d.ts +7 -1
  4. package/dist/hooks/editor/plugins/sync-editor-with-phoenix.d.ts.map +1 -1
  5. package/dist/hooks/editor/utils/index.d.ts +1 -0
  6. package/dist/hooks/editor/utils/index.d.ts.map +1 -1
  7. package/dist/hooks/editor/utils/is-editor-with-external-editables.d.ts +9 -0
  8. package/dist/hooks/editor/utils/is-editor-with-external-editables.d.ts.map +1 -0
  9. package/dist/hooks/index.d.ts +0 -1
  10. package/dist/hooks/index.d.ts.map +1 -1
  11. package/dist/hooks/root-value-sentinel/root-attributes-updater.d.ts +1 -1
  12. package/dist/hooks/root-value-sentinel/root-attributes-updater.d.ts.map +1 -1
  13. package/dist/hooks/root-value-sentinel/root-value-sentinel.d.ts +114 -1
  14. package/dist/hooks/root-value-sentinel/root-value-sentinel.d.ts.map +1 -1
  15. package/dist/index.cjs +2 -2
  16. package/dist/index.cjs.map +1 -1
  17. package/dist/index.mjs +464 -351
  18. package/dist/index.mjs.map +1 -1
  19. package/package.json +2 -2
  20. package/src/hooks/editable.ts +18 -0
  21. package/src/hooks/editor/editor.test.ts +10 -5
  22. package/src/hooks/editor/editor.ts +33 -8
  23. package/src/hooks/editor/plugins/phoenix-upload-adapter.ts +2 -0
  24. package/src/hooks/editor/plugins/sync-editor-with-phoenix.ts +46 -2
  25. package/src/hooks/editor/utils/index.ts +1 -0
  26. package/src/hooks/editor/utils/is-editor-with-external-editables.test.ts +25 -0
  27. package/src/hooks/editor/utils/is-editor-with-external-editables.ts +11 -0
  28. package/src/hooks/editor/utils/is-single-root-editor.test.ts +1 -1
  29. package/src/hooks/index.ts +0 -2
  30. package/src/hooks/root-value-sentinel/root-attributes-updater.ts +8 -2
  31. package/src/hooks/root-value-sentinel/root-value-sentinel.test.ts +55 -37
  32. package/src/hooks/root-value-sentinel/root-value-sentinel.ts +159 -33
  33. package/test-utils/editor/index.ts +0 -1
  34. package/test-utils/editor/create-root-value-sentinel-element.ts +0 -28
@@ -1 +1 @@
1
- {"version":3,"file":"editable.d.ts","sourceRoot":"","sources":["../../src/hooks/editable.ts"],"names":[],"mappings":"AA0GA;;GAEG;AACH,eAAO,MAAM,YAAY,+FAA6B,CAAC"}
1
+ {"version":3,"file":"editable.d.ts","sourceRoot":"","sources":["../../src/hooks/editable.ts"],"names":[],"mappings":"AA4HA;;GAEG;AACH,eAAO,MAAM,YAAY,+FAA6B,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"editor.d.ts","sourceRoot":"","sources":["../../../src/hooks/editor/editor.ts"],"names":[],"mappings":"AAqUA;;GAEG;AACH,eAAO,MAAM,UAAU,kGAA2B,CAAC"}
1
+ {"version":3,"file":"editor.d.ts","sourceRoot":"","sources":["../../../src/hooks/editor/editor.ts"],"names":[],"mappings":"AA8VA;;GAEG;AACH,eAAO,MAAM,UAAU,kGAA2B,CAAC"}
@@ -1,4 +1,4 @@
1
- import { PluginConstructor } from 'ckeditor5';
1
+ import { Editor, PluginConstructor } from 'ckeditor5';
2
2
  import { EditorId } from '../typings';
3
3
  /**
4
4
  * Creates a SyncEditorWithPhoenix plugin class. It's not two way binding, but
@@ -24,5 +24,11 @@ type Attrs = {
24
24
  pushEvent: (event: string, payload: any) => void;
25
25
  handleEvent: (event: string, callback: (payload: any) => void) => void;
26
26
  };
27
+ /**
28
+ * Marks pending `change:data` as non-syncable with Phoenix.
29
+ *
30
+ * @param editor Editor instance.
31
+ */
32
+ export declare function skipPendingPhoenixDataChangeSync(editor: Editor): () => void;
27
33
  export {};
28
34
  //# sourceMappingURL=sync-editor-with-phoenix.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"sync-editor-with-phoenix.d.ts","sourceRoot":"","sources":["../../../../src/hooks/editor/plugins/sync-editor-with-phoenix.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAU,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAE3D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAI3C;;;;;;;;;;GAUG;AACH,wBAAsB,iCAAiC,CAAC,OAAO,EAAE,KAAK,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAsHlG;AAED,KAAK,KAAK,GAAG;IACX,QAAQ,EAAE,QAAQ,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE;QACN,MAAM,EAAE,OAAO,CAAC;QAChB,KAAK,EAAE,OAAO,CAAC;QACf,IAAI,EAAE,OAAO,CAAC;QACd,KAAK,EAAE,OAAO,CAAC;KAChB,CAAC;IACF,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,KAAK,IAAI,CAAC;IACjD,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,IAAI,KAAK,IAAI,CAAC;CACxE,CAAC"}
1
+ {"version":3,"file":"sync-editor-with-phoenix.d.ts","sourceRoot":"","sources":["../../../../src/hooks/editor/plugins/sync-editor-with-phoenix.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAE3D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAM3C;;;;;;;;;;GAUG;AACH,wBAAsB,iCAAiC,CAAC,OAAO,EAAE,KAAK,GAAG,OAAO,CAAC,iBAAiB,CAAC,CA4HlG;AAED,KAAK,KAAK,GAAG;IACX,QAAQ,EAAE,QAAQ,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE;QACN,MAAM,EAAE,OAAO,CAAC;QAChB,KAAK,EAAE,OAAO,CAAC;QACf,IAAI,EAAE,OAAO,CAAC;QACd,KAAK,EAAE,OAAO,CAAC;KAChB,CAAC;IACF,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,KAAK,IAAI,CAAC;IACjD,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,IAAI,KAAK,IAAI,CAAC;CACxE,CAAC;AA+BF;;;;GAIG;AACH,wBAAgB,gCAAgC,CAAC,MAAM,EAAE,MAAM,cAe9D"}
@@ -1,4 +1,5 @@
1
1
  export * from './create-editor-in-context';
2
+ export * from './is-editor-with-external-editables';
2
3
  export * from './is-single-root-editor';
3
4
  export * from './load-editor-constructor';
4
5
  export * from './load-editor-plugins';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/hooks/editor/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,4BAA4B,CAAC;AAC3C,cAAc,yBAAyB,CAAC;AACxC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,uBAAuB,CAAC;AACtC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,iCAAiC,CAAC;AAChD,cAAc,8BAA8B,CAAC;AAC7C,cAAc,wBAAwB,CAAC;AACvC,cAAc,6CAA6C,CAAC;AAC5D,cAAc,sCAAsC,CAAC;AACrD,cAAc,8BAA8B,CAAC;AAC7C,cAAc,sBAAsB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/hooks/editor/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,4BAA4B,CAAC;AAC3C,cAAc,qCAAqC,CAAC;AACpD,cAAc,yBAAyB,CAAC;AACxC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,uBAAuB,CAAC;AACtC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,iCAAiC,CAAC;AAChD,cAAc,8BAA8B,CAAC;AAC7C,cAAc,wBAAwB,CAAC;AACvC,cAAc,6CAA6C,CAAC;AAC5D,cAAc,sCAAsC,CAAC;AACrD,cAAc,8BAA8B,CAAC;AAC7C,cAAc,sBAAsB,CAAC"}
@@ -0,0 +1,9 @@
1
+ import { EditorType } from '../typings';
2
+ /**
3
+ * Checks if the given editor type enforces user to define editables using separate components.
4
+ *
5
+ * @param editorType - The type of the editor to check.
6
+ * @returns `true` if the editor type is 'decoupled' or 'multiroot', otherwise `false`.
7
+ */
8
+ export declare function isEditorWithExternalEditables(editorType: EditorType): boolean;
9
+ //# sourceMappingURL=is-editor-with-external-editables.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"is-editor-with-external-editables.d.ts","sourceRoot":"","sources":["../../../../src/hooks/editor/utils/is-editor-with-external-editables.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C;;;;;GAKG;AACH,wBAAgB,6BAA6B,CAAC,UAAU,EAAE,UAAU,GAAG,OAAO,CAE7E"}
@@ -3,6 +3,5 @@ export declare const Hooks: {
3
3
  CKEditable: import('../types').RequiredBy<import('phoenix_live_view').Hook<any>, "mounted" | "destroyed">;
4
4
  CKUIPart: import('../types').RequiredBy<import('phoenix_live_view').Hook<any>, "mounted" | "destroyed">;
5
5
  CKContext: import('../types').RequiredBy<import('phoenix_live_view').Hook<any>, "mounted" | "destroyed">;
6
- CKRootValueSentinel: import('../types').RequiredBy<import('phoenix_live_view').Hook<any>, "mounted" | "destroyed">;
7
6
  };
8
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,KAAK;;;;;;CAMjB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,KAAK;;;;;CAKjB,CAAC"}
@@ -12,5 +12,5 @@ import { Editor } from 'ckeditor5';
12
12
  * Calling the function with `null` or an empty object will clear all attributes previously set by it.
13
13
  */
14
14
  export declare function createRootAttributesUpdater(editor: Editor, rootName: string): RootAttributesUpdater;
15
- export type RootAttributesUpdater = (rootAttributes?: Record<string, unknown> | null) => void;
15
+ export type RootAttributesUpdater = (rootAttributes?: Record<string, unknown> | null) => boolean;
16
16
  //# sourceMappingURL=root-attributes-updater.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"root-attributes-updater.d.ts","sourceRoot":"","sources":["../../../src/hooks/root-value-sentinel/root-attributes-updater.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAExC;;;;;;;;;;;GAWG;AACH,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,qBAAqB,CA6BnG;AAED,MAAM,MAAM,qBAAqB,GAAG,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,KAAK,IAAI,CAAC"}
1
+ {"version":3,"file":"root-attributes-updater.d.ts","sourceRoot":"","sources":["../../../src/hooks/root-value-sentinel/root-attributes-updater.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAExC;;;;;;;;;;;GAWG;AACH,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,qBAAqB,CAmCnG;AAED,MAAM,MAAM,qBAAqB,GAAG,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,KAAK,OAAO,CAAC"}
@@ -1,2 +1,115 @@
1
- export declare const RootValueSentinelHook: import('../../types').RequiredBy<import('phoenix_live_view').Hook<any>, "mounted" | "destroyed">;
1
+ export declare class RootValueSentinel {
2
+ /**
3
+ * The DOM element being observed for attribute changes.
4
+ */
5
+ private el;
6
+ /**
7
+ * The unique identifier of the editor instance this sentinel is attached to.
8
+ */
9
+ private readonly editorId;
10
+ /**
11
+ * The name of the specific root in a multi-root editor setup.
12
+ */
13
+ private readonly rootName;
14
+ /**
15
+ * The name of the HTML attribute storing the value.
16
+ */
17
+ private readonly valueAttrName;
18
+ /**
19
+ * The name of the HTML attribute storing the root attributes.
20
+ */
21
+ private readonly rootAttrsAttrName;
22
+ /**
23
+ * The MutationObserver instance responsible for watching attribute changes on the element.
24
+ */
25
+ private observer;
26
+ /**
27
+ * A flag indicating whether the sentinel has been destroyed, used to prevent operations after cleanup.
28
+ */
29
+ private isDestroyed;
30
+ /**
31
+ * Cleanup callbacks to be executed when the sentinel is destroyed.
32
+ */
33
+ private cleanupCallbacks;
34
+ /**
35
+ * The promise that resolves to the editor instance once it's registered.
36
+ * It can be either a MultiRootEditor or a DecoupledEditor, depending on the type of editor being used.
37
+ * It will be null if the editor is not registered yet or if the hook is being destroyed before the editor is registered.
38
+ */
39
+ private editorPromise;
40
+ /**
41
+ * When the editor is focused and the value attribute changes, we want to wait until it blurs to
42
+ * avoid disrupting the user while typing. This variable holds the pending value that should be applied
43
+ * once the editor blurs. It is set to null when there is no pending value or when the user makes changes in the editor,
44
+ * indicating that the pending value should be discarded.
45
+ */
46
+ private pendingValue;
47
+ /**
48
+ * Cache the previous value to avoid reacting to attribute changes that don't actually change the value.
49
+ * This can happen when the parent LiveView re-renders and sets the same value again, which would otherwise cause an
50
+ * unnecessary update in the editor.
51
+ */
52
+ private previousValue;
53
+ /**
54
+ * Updater created once the editor is ready. Tracks which root attributes
55
+ * were applied by this sentinel so it can clean them up independently of
56
+ * other consumers.
57
+ */
58
+ private attrsUpdater;
59
+ /**
60
+ * When the hook is mounted, we will wait for the editor to be registered and then set the initial value of the root.
61
+ * Accepts an options object to configure element, identifiers, and custom attribute names.
62
+ */
63
+ constructor({ el, editorId, rootName, valueAttrName, rootAttrsAttrName, }: RootValueSentinelOptions);
64
+ /**
65
+ * Helper to read and parse attributes from the element.
66
+ * It uses dynamically provided attribute names.
67
+ */
68
+ private get attrs();
69
+ /**
70
+ * Sets up a MutationObserver to listen for attribute changes on the element.
71
+ */
72
+ private setupObserver;
73
+ /**
74
+ * When the value attribute changes, we want to update the editor root value.
75
+ * However, if the editor is focused, we want to wait until it blurs to avoid disrupting the user while typing.
76
+ */
77
+ private handleUpdate;
78
+ /**
79
+ * Sets up focus-aware sync handlers on the editor.
80
+ * Registers cleanup via onBeforeDestroy.
81
+ */
82
+ private setupSyncHandlers;
83
+ /**
84
+ * Sets the value of a specific root in the editor.
85
+ */
86
+ private setRootValue;
87
+ /**
88
+ * Disconnects the observer and cleans up editor event listeners.
89
+ * This should be called manually when the element is removed from the DOM.
90
+ */
91
+ destroy(): void;
92
+ }
93
+ export type RootValueSentinelOptions = {
94
+ /**
95
+ * The DOM element being observed for attribute changes.
96
+ */
97
+ el: HTMLElement;
98
+ /**
99
+ * The unique identifier of the editor instance this sentinel is attached to.
100
+ */
101
+ editorId: string | null;
102
+ /**
103
+ * The name of the specific root in a multi-root editor setup.
104
+ */
105
+ rootName: string;
106
+ /**
107
+ * The name of the HTML attribute storing the value. Defaults to 'data-cke-value'.
108
+ */
109
+ valueAttrName?: string;
110
+ /**
111
+ * The name of the HTML attribute storing the root attributes. Defaults to 'data-cke-root-attrs'.
112
+ */
113
+ rootAttrsAttrName?: string;
114
+ };
2
115
  //# sourceMappingURL=root-value-sentinel.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"root-value-sentinel.d.ts","sourceRoot":"","sources":["../../../src/hooks/root-value-sentinel/root-value-sentinel.ts"],"names":[],"mappings":"AA0IA,eAAO,MAAM,qBAAqB,kGAA8B,CAAC"}
1
+ {"version":3,"file":"root-value-sentinel.d.ts","sourceRoot":"","sources":["../../../src/hooks/root-value-sentinel/root-value-sentinel.ts"],"names":[],"mappings":"AAUA,qBAAa,iBAAiB;IAC5B;;OAEG;IACH,OAAO,CAAC,EAAE,CAAc;IAExB;;OAEG;IACH,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAkB;IAE3C;;OAEG;IACH,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAElC;;OAEG;IACH,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IAEvC;;OAEG;IACH,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAS;IAE3C;;OAEG;IACH,OAAO,CAAC,QAAQ,CAAiC;IAEjD;;OAEG;IACH,OAAO,CAAC,WAAW,CAAkB;IAErC;;OAEG;IACH,OAAO,CAAC,gBAAgB,CAAyB;IAEjD;;;;OAIG;IACH,OAAO,CAAC,aAAa,CAAuC;IAE5D;;;;;OAKG;IACH,OAAO,CAAC,YAAY,CAAuB;IAE3C;;;;OAIG;IACH,OAAO,CAAC,aAAa,CAAuB;IAE5C;;;;OAIG;IACH,OAAO,CAAC,YAAY,CAAsC;IAE1D;;;OAGG;gBAED,EACE,EAAE,EACF,QAAQ,EACR,QAAQ,EACR,aAAgC,EAChC,iBAAyC,GAC1C,EAAE,wBAAwB;IAwB7B;;;OAGG;IACH,OAAO,KAAK,KAAK,GAKhB;IAED;;OAEG;IACH,OAAO,CAAC,aAAa;IAmBrB;;;OAGG;YACW,YAAY;IAmC1B;;;OAGG;IACH,OAAO,CAAC,iBAAiB;IAwBzB;;OAEG;IACH,OAAO,CAAC,YAAY;IAQpB;;;OAGG;IACI,OAAO;CAOf;AAED,MAAM,MAAM,wBAAwB,GAAG;IACrC;;OAEG;IACH,EAAE,EAAE,WAAW,CAAC;IAEhB;;OAEG;IACH,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IAExB;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB;;OAEG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC"}
package/dist/index.cjs CHANGED
@@ -1,5 +1,5 @@
1
- "use strict";var et=Object.create;var z=Object.defineProperty;var rt=Object.getOwnPropertyDescriptor;var at=Object.getOwnPropertyNames;var it=Object.getPrototypeOf,nt=Object.prototype.hasOwnProperty;var ot=(a,t,e,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of at(t))!nt.call(a,n)&&n!==e&&z(a,n,{get:()=>t[n],enumerable:!(i=rt(t,n))||i.enumerable});return a};var r=(a,t,e)=>(e=a!=null?et(it(a)):{},ot(t||!a||!a.__esModule?z(e,"default",{value:a,enumerable:!0}):e,a));Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});class _{items=new Map;initializationErrors=new Map;pendingCallbacks=new Map;watchers=new Set;execute(t,e,i){const n=this.items.get(t),o=this.initializationErrors.get(t);return o?(i?.(o),Promise.reject(o)):n?Promise.resolve(e(n)):new Promise((s,u)=>{const c=this.getPendingCallbacks(t);c.success.push(async l=>{s(await e(l))}),i?c.error.push(i):c.error.push(u)})}register(t,e){if(this.items.has(t))throw new Error(`Item with ID "${t}" is already registered.`);this.resetErrors(t),this.items.set(t,e);const i=this.pendingCallbacks.get(t);i&&(i.success.forEach(n=>n(e)),this.pendingCallbacks.delete(t)),this.registerAsDefault(t,e),this.notifyWatchers()}error(t,e){this.items.delete(t),this.initializationErrors.set(t,e);const i=this.pendingCallbacks.get(t);i&&(i.error.forEach(n=>n(e)),this.pendingCallbacks.delete(t)),this.initializationErrors.size===1&&!this.items.size&&this.error(null,e),this.notifyWatchers()}resetErrors(t){const{initializationErrors:e}=this;e.has(null)&&e.get(null)===e.get(t)&&e.delete(null),e.delete(t)}unregister(t){if(!this.items.has(t))throw new Error(`Item with ID "${t}" is not registered.`);t&&this.items.get(null)===this.items.get(t)&&this.unregister(null),this.items.delete(t),this.pendingCallbacks.delete(t),this.notifyWatchers()}getItems(){return Array.from(this.items.values())}hasItem(t){return this.items.has(t)}waitFor(t){return new Promise((e,i)=>{this.execute(t,e,i)})}async destroyAll(){const t=Array.from(new Set(this.items.values())).map(e=>e.destroy());this.items.clear(),this.pendingCallbacks.clear(),await Promise.all(t),this.notifyWatchers()}watch(t){return this.watchers.add(t),t(new Map(this.items),new Map(this.initializationErrors)),this.unwatch.bind(this,t)}unwatch(t){this.watchers.delete(t)}notifyWatchers(){this.watchers.forEach(t=>t(new Map(this.items),new Map(this.initializationErrors)))}getPendingCallbacks(t){let e=this.pendingCallbacks.get(t);return e||(e={success:[],error:[]},this.pendingCallbacks.set(t,e)),e}registerAsDefault(t,e){this.items.size===1&&t!==null&&this.register(null,e)}}function st(a){return a.replace(/[-_\s]+(.)?/g,(t,e)=>e?e.toUpperCase():"").replace(/^./,t=>t.toLowerCase())}function $(a,t){let e=null;return(...i)=>{e&&clearTimeout(e),e=setTimeout(()=>{t(...i)},a)}}function ct(a){if(Object.prototype.toString.call(a)!=="[object Object]")return!1;const t=Object.getPrototypeOf(a);return t===Object.prototype||t===null}function A(a){if(Array.isArray(a))return a.map(A);if(ct(a)){const t=Object.create(null);for(const[e,i]of Object.entries(a))t[st(e)]=A(i);return t}return a}function ut(a,t){const e=Object.entries(a).filter(([i,n])=>t(n,i));return Object.fromEntries(e)}function lt(){const a=document.querySelector('meta[name="csrf-token"]');if(a)return a.getAttribute("content");const t=document.cookie.match(/(?:^|; )_csrf_token=([^;]*)/);return t?decodeURIComponent(t[1]):null}class P{state="mounting";el;_beforeDestroyCallbacks=[];onBeforeDestroy(t){this._beforeDestroyCallbacks.push(t)}pushEvent;pushEventTo;handleEvent;mounted(){}destroyed(){}updated(){}isBeingDestroyed(){return this.state==="destroyed"||this.state==="destroying"}_runBeforeDestroyCallbacks(){for(const t of this._beforeDestroyCallbacks.reverse())t();this._beforeDestroyCallbacks=[]}}function C(a){return{async mounted(){const t=new a;this.el.instance=t,t.el=this.el,t.pushEvent=(i,n,o)=>this.pushEvent?.(i,n,o),t.pushEventTo=(i,n,o,s)=>this.pushEventTo?.(i,n,o,s),t.handleEvent=(i,n)=>this.handleEvent?.(i,n),t.state="mounting";const e=await t.mounted?.();return t.state="mounted",e},beforeUpdate(){this.el.instance.beforeUpdate?.()},async destroyed(){const{instance:t}=this.el;t.state="destroying",t._runBeforeDestroyCallbacks(),await t.destroyed?.(),t.state="destroyed"},disconnected(){this.el.instance.disconnected?.()},reconnected(){this.el.instance.reconnected?.()},updated(){this.el.instance.updated?.()}}}function B(a){return Object.keys(a).length===0&&a.constructor===Object}function dt(a){return a==null}function U(a,t){const e=Object.entries(a).map(([i,n])=>[i,t(n,i)]);return Object.fromEntries(e)}function N(a){if(a===null)return null;const t=Number.parseInt(a,10);return Number.isNaN(t)?null:t}function mt(a){return a==null||a.trim()===""?null:JSON.parse(a)}function ht(a,t){if(a===t)return!0;const e=Object.keys(a),i=Object.keys(t);if(e.length!==i.length)return!1;for(const n of e)if(a[n]!==t[n]||!Object.prototype.hasOwnProperty.call(t,n))return!1;return!0}function pt(){return Math.random().toString(36).substring(2)}function ft(a,{timeOutAfter:t=500,retryAfter:e=100}={}){return new Promise((i,n)=>{const o=Date.now();let s=null;const u=setTimeout(()=>{n(s??new Error("Timeout"))},t),c=async()=>{try{const l=await a();clearTimeout(u),i(l)}catch(l){s=l,Date.now()-o>t?n(l):setTimeout(c,e)}};c()})}const V=Symbol.for("context-editor-watchdog");async function wt({element:a,context:t,creator:e,config:i}){const n=pt();await t.add({creator:(c,l)=>e.create(c,l),id:n,sourceElementOrData:a,type:"editor",config:i});const o=t.getItem(n),s={state:"available",editorContextId:n,context:t};o[V]=s;const u=t.destroy.bind(t);return t.destroy=async()=>(s.state="unavailable",u()),{...s,editor:o}}function K(a){return V in a?a[V]:null}function T(a){return["inline","classic","balloon","decoupled"].includes(a)}async function gt(a){const t=await import("ckeditor5"),i={inline:t.InlineEditor,balloon:t.BalloonEditor,classic:t.ClassicEditor,decoupled:t.DecoupledEditor,multiroot:t.MultiRootEditor}[a];if(!i)throw new Error(`Unsupported editor type: ${a}`);return i}class O{static the=new O;plugins=new Map;constructor(){}register(t,e){if(this.plugins.has(t))throw new Error(`Plugin with name "${t}" is already registered.`);return this.plugins.set(t,e),this.unregister.bind(this,t)}unregister(t){if(!this.plugins.has(t))throw new Error(`Plugin with name "${t}" is not registered.`);this.plugins.delete(t)}unregisterAll(){this.plugins.clear()}async get(t){return this.plugins.get(t)?.()}has(t){return this.plugins.has(t)}}async function L(a){const t=await import("ckeditor5");let e=null;const i=a.map(async n=>{const o=await O.the.get(n);if(o)return o;const{[n]:s}=t;if(s)return s;if(!e)try{e=await import("ckeditor5-premium-features")}catch(c){console.error(`Failed to load premium package: ${c}`)}const{[n]:u}=e||{};if(u)return u;throw new Error(`Plugin "${n}" not found in base or premium packages.`)});return{loadedPlugins:await Promise.all(i),hasPremium:!!e}}async function J(a,t){const e=[a.ui,a.content];return await Promise.all([q("ckeditor5",e),t&&q("ckeditor5-premium-features",e)].filter(n=>!!n)).then(n=>n.flat())}async function q(a,t){return await Promise.all(t.filter(e=>e!=="en").map(async e=>{const i=await yt(a,e);return i?.default??i}).filter(Boolean))}async function yt(a,t){try{if(a==="ckeditor5")switch(t){case"af":return await import("ckeditor5/translations/af.js");case"ar":return await import("ckeditor5/translations/ar.js");case"ast":return await import("ckeditor5/translations/ast.js");case"az":return await import("ckeditor5/translations/az.js");case"bg":return await import("ckeditor5/translations/bg.js");case"bn":return await import("ckeditor5/translations/bn.js");case"bs":return await import("ckeditor5/translations/bs.js");case"ca":return await import("ckeditor5/translations/ca.js");case"cs":return await import("ckeditor5/translations/cs.js");case"da":return await import("ckeditor5/translations/da.js");case"de":return await import("ckeditor5/translations/de.js");case"de-ch":return await import("ckeditor5/translations/de-ch.js");case"el":return await import("ckeditor5/translations/el.js");case"en":return await import("ckeditor5/translations/en.js");case"en-au":return await import("ckeditor5/translations/en-au.js");case"en-gb":return await import("ckeditor5/translations/en-gb.js");case"eo":return await import("ckeditor5/translations/eo.js");case"es":return await import("ckeditor5/translations/es.js");case"es-co":return await import("ckeditor5/translations/es-co.js");case"et":return await import("ckeditor5/translations/et.js");case"eu":return await import("ckeditor5/translations/eu.js");case"fa":return await import("ckeditor5/translations/fa.js");case"fi":return await import("ckeditor5/translations/fi.js");case"fr":return await import("ckeditor5/translations/fr.js");case"gl":return await import("ckeditor5/translations/gl.js");case"gu":return await import("ckeditor5/translations/gu.js");case"he":return await import("ckeditor5/translations/he.js");case"hi":return await import("ckeditor5/translations/hi.js");case"hr":return await import("ckeditor5/translations/hr.js");case"hu":return await import("ckeditor5/translations/hu.js");case"hy":return await import("ckeditor5/translations/hy.js");case"id":return await import("ckeditor5/translations/id.js");case"it":return await import("ckeditor5/translations/it.js");case"ja":return await import("ckeditor5/translations/ja.js");case"jv":return await import("ckeditor5/translations/jv.js");case"kk":return await import("ckeditor5/translations/kk.js");case"km":return await import("ckeditor5/translations/km.js");case"kn":return await import("ckeditor5/translations/kn.js");case"ko":return await import("ckeditor5/translations/ko.js");case"ku":return await import("ckeditor5/translations/ku.js");case"lt":return await import("ckeditor5/translations/lt.js");case"lv":return await import("ckeditor5/translations/lv.js");case"ms":return await import("ckeditor5/translations/ms.js");case"nb":return await import("ckeditor5/translations/nb.js");case"ne":return await import("ckeditor5/translations/ne.js");case"nl":return await import("ckeditor5/translations/nl.js");case"no":return await import("ckeditor5/translations/no.js");case"oc":return await import("ckeditor5/translations/oc.js");case"pl":return await import("ckeditor5/translations/pl.js");case"pt":return await import("ckeditor5/translations/pt.js");case"pt-br":return await import("ckeditor5/translations/pt-br.js");case"ro":return await import("ckeditor5/translations/ro.js");case"ru":return await import("ckeditor5/translations/ru.js");case"si":return await import("ckeditor5/translations/si.js");case"sk":return await import("ckeditor5/translations/sk.js");case"sl":return await import("ckeditor5/translations/sl.js");case"sq":return await import("ckeditor5/translations/sq.js");case"sr":return await import("ckeditor5/translations/sr.js");case"sr-latn":return await import("ckeditor5/translations/sr-latn.js");case"sv":return await import("ckeditor5/translations/sv.js");case"th":return await import("ckeditor5/translations/th.js");case"tk":return await import("ckeditor5/translations/tk.js");case"tr":return await import("ckeditor5/translations/tr.js");case"tt":return await import("ckeditor5/translations/tt.js");case"ug":return await import("ckeditor5/translations/ug.js");case"uk":return await import("ckeditor5/translations/uk.js");case"ur":return await import("ckeditor5/translations/ur.js");case"uz":return await import("ckeditor5/translations/uz.js");case"vi":return await import("ckeditor5/translations/vi.js");case"zh":return await import("ckeditor5/translations/zh.js");case"zh-cn":return await import("ckeditor5/translations/zh-cn.js");default:return console.warn(`Language ${t} not found in ckeditor5 translations`),null}else switch(t){case"af":return await import("ckeditor5-premium-features/translations/af.js");case"ar":return await import("ckeditor5-premium-features/translations/ar.js");case"ast":return await import("ckeditor5-premium-features/translations/ast.js");case"az":return await import("ckeditor5-premium-features/translations/az.js");case"bg":return await import("ckeditor5-premium-features/translations/bg.js");case"bn":return await import("ckeditor5-premium-features/translations/bn.js");case"bs":return await import("ckeditor5-premium-features/translations/bs.js");case"ca":return await import("ckeditor5-premium-features/translations/ca.js");case"cs":return await import("ckeditor5-premium-features/translations/cs.js");case"da":return await import("ckeditor5-premium-features/translations/da.js");case"de":return await import("ckeditor5-premium-features/translations/de.js");case"de-ch":return await import("ckeditor5-premium-features/translations/de-ch.js");case"el":return await import("ckeditor5-premium-features/translations/el.js");case"en":return await import("ckeditor5-premium-features/translations/en.js");case"en-au":return await import("ckeditor5-premium-features/translations/en-au.js");case"en-gb":return await import("ckeditor5-premium-features/translations/en-gb.js");case"eo":return await import("ckeditor5-premium-features/translations/eo.js");case"es":return await import("ckeditor5-premium-features/translations/es.js");case"es-co":return await import("ckeditor5-premium-features/translations/es-co.js");case"et":return await import("ckeditor5-premium-features/translations/et.js");case"eu":return await import("ckeditor5-premium-features/translations/eu.js");case"fa":return await import("ckeditor5-premium-features/translations/fa.js");case"fi":return await import("ckeditor5-premium-features/translations/fi.js");case"fr":return await import("ckeditor5-premium-features/translations/fr.js");case"gl":return await import("ckeditor5-premium-features/translations/gl.js");case"gu":return await import("ckeditor5-premium-features/translations/gu.js");case"he":return await import("ckeditor5-premium-features/translations/he.js");case"hi":return await import("ckeditor5-premium-features/translations/hi.js");case"hr":return await import("ckeditor5-premium-features/translations/hr.js");case"hu":return await import("ckeditor5-premium-features/translations/hu.js");case"hy":return await import("ckeditor5-premium-features/translations/hy.js");case"id":return await import("ckeditor5-premium-features/translations/id.js");case"it":return await import("ckeditor5-premium-features/translations/it.js");case"ja":return await import("ckeditor5-premium-features/translations/ja.js");case"jv":return await import("ckeditor5-premium-features/translations/jv.js");case"kk":return await import("ckeditor5-premium-features/translations/kk.js");case"km":return await import("ckeditor5-premium-features/translations/km.js");case"kn":return await import("ckeditor5-premium-features/translations/kn.js");case"ko":return await import("ckeditor5-premium-features/translations/ko.js");case"ku":return await import("ckeditor5-premium-features/translations/ku.js");case"lt":return await import("ckeditor5-premium-features/translations/lt.js");case"lv":return await import("ckeditor5-premium-features/translations/lv.js");case"ms":return await import("ckeditor5-premium-features/translations/ms.js");case"nb":return await import("ckeditor5-premium-features/translations/nb.js");case"ne":return await import("ckeditor5-premium-features/translations/ne.js");case"nl":return await import("ckeditor5-premium-features/translations/nl.js");case"no":return await import("ckeditor5-premium-features/translations/no.js");case"oc":return await import("ckeditor5-premium-features/translations/oc.js");case"pl":return await import("ckeditor5-premium-features/translations/pl.js");case"pt":return await import("ckeditor5-premium-features/translations/pt.js");case"pt-br":return await import("ckeditor5-premium-features/translations/pt-br.js");case"ro":return await import("ckeditor5-premium-features/translations/ro.js");case"ru":return await import("ckeditor5-premium-features/translations/ru.js");case"si":return await import("ckeditor5-premium-features/translations/si.js");case"sk":return await import("ckeditor5-premium-features/translations/sk.js");case"sl":return await import("ckeditor5-premium-features/translations/sl.js");case"sq":return await import("ckeditor5-premium-features/translations/sq.js");case"sr":return await import("ckeditor5-premium-features/translations/sr.js");case"sr-latn":return await import("ckeditor5-premium-features/translations/sr-latn.js");case"sv":return await import("ckeditor5-premium-features/translations/sv.js");case"th":return await import("ckeditor5-premium-features/translations/th.js");case"tk":return await import("ckeditor5-premium-features/translations/tk.js");case"tr":return await import("ckeditor5-premium-features/translations/tr.js");case"tt":return await import("ckeditor5-premium-features/translations/tt.js");case"ug":return await import("ckeditor5-premium-features/translations/ug.js");case"uk":return await import("ckeditor5-premium-features/translations/uk.js");case"ur":return await import("ckeditor5-premium-features/translations/ur.js");case"uz":return await import("ckeditor5-premium-features/translations/uz.js");case"vi":return await import("ckeditor5-premium-features/translations/vi.js");case"zh":return await import("ckeditor5-premium-features/translations/zh.js");case"zh-cn":return await import("ckeditor5-premium-features/translations/zh-cn.js");default:return console.warn(`Language ${t} not found in premium translations`),await import("ckeditor5-premium-features/translations/en.js")}}catch(e){return console.error(`Failed to load translation for ${a}/${t}:`,e),null}}function G(a){return U(a,t=>({dictionary:t}))}function Y(a){const t=X(a);return U(t,({content:e})=>e)}function F(a){const t=X(a),e=U(t,({initialValue:i})=>i);return ut(e,i=>typeof i=="string")}function X(a){const t=document.querySelectorAll([`[data-cke-editor-id="${a}"][data-cke-editable-root-name]`,"[data-cke-editable-root-name]:not([data-cke-editor-id])"].join(", ")),e=Array.from(t).reduce((u,c)=>{const l=c.getAttribute("data-cke-editable-root-name"),d=c.getAttribute("data-cke-editable-initial-value")||"",m=c.querySelector("[data-cke-editable-content]");return!l||!m?u:{...u,[l]:{content:m,initialValue:d}}},Object.create({})),i=document.querySelector(`[phx-hook="CKEditor5"][id="${a}"]`);if(!i)return e;const n=i.getAttribute("data-cke-initial-value")||"",o=i.querySelector(`#${a}_editor `),s=e.main;return s?{...e,main:{...s,initialValue:s.initialValue||n}}:o?{...e,main:{content:o,initialValue:n}}:e}const W=["inline","classic","balloon","decoupled","multiroot"];function bt(a){const t=a.getAttribute("data-cke-preset");if(!t)throw new Error('CKEditor5 hook requires a "cke-preset" attribute on the element.');const{type:e,config:i,license:n,...o}=JSON.parse(t);if(!e||!i||!n)throw new Error('CKEditor5 hook configuration must include "editor", "config", and "license" properties.');if(!W.includes(e))throw new Error(`Invalid editor type: ${e}. Must be one of: ${W.join(", ")}.`);return{type:e,license:n,config:A(i),customTranslations:o.customTranslations||o.custom_translations}}function I(a){if(!a||typeof a!="object")return a;if(Array.isArray(a))return a.map(i=>I(i));const t=a;if(t.$element&&typeof t.$element=="string"){const i=document.querySelector(t.$element);return i||console.warn(`Element not found for selector: ${t.$element}`),i||null}const e=Object.create(null);for(const[i,n]of Object.entries(a))e[i]=I(n);return e}function x(a,t,e){if(!e||typeof e!="object")return e;if(Array.isArray(e))return e.map(o=>x(a,t,o));const i=e;if(i.$translation&&typeof i.$translation=="string"){const o=i.$translation,s=kt(a,o,t);return s===void 0&&console.warn(`Translation not found for key: ${o}`),s!==void 0?s:null}const n=Object.create(null);for(const[o,s]of Object.entries(e))n[o]=x(a,t,s);return n}function kt(a,t,e){for(const i of a){const n=i[e];if(n?.dictionary&&t in n.dictionary)return n.dictionary[t]}}function Et(a,t){const{editing:e}=a;e.view.change(i=>{i.setStyle("height",`${t}px`,e.view.document.getRoot())})}const R=Symbol.for("elixir-editor-watchdog");async function vt(a){const{EditorWatchdog:t}=await import("ckeditor5"),e=new t(a);return e.setCreator(async(...i)=>{const n=await a.create(...i);return n[R]=e,n}),{watchdog:e,Constructor:{create:async(...i)=>(await e.create(...i),e.editor)}}}function Q(a){return R in a?a[R]:null}class g extends _{static the=new g}function Pt(a){const t=a.getAttribute("data-cke-context");if(!t)throw new Error('CKEditor5 hook requires a "data-cke-context" attribute on the element.');const{config:e,...i}=JSON.parse(t);return{config:A(e),customTranslations:i.customTranslations||i.custom_translations,watchdogConfig:i.watchdogConfig||i.watchdog_config}}class Ct extends P{contextPromise=null;get attrs(){const t=i=>this.el.getAttribute(i)||null,e={id:this.el.id,config:Pt(this.el),language:{ui:t("data-cke-language")||"en",content:t("data-cke-content-language")||"en"}};return Object.defineProperty(this,"attrs",{value:e,writable:!1,configurable:!1,enumerable:!0}),e}async mounted(){const{id:t,language:e}=this.attrs,{customTranslations:i,watchdogConfig:n,config:{plugins:o,...s}}=this.attrs.config,{loadedPlugins:u,hasPremium:c}=await L(o??[]),d=[...await J(e,c),G(i?.dictionary||{})].filter(f=>!B(f));let m=I(s);m=x([...d].reverse(),e.ui,m),this.contextPromise=(async()=>{const{ContextWatchdog:f,Context:b}=await import("ckeditor5"),y=new f(b,{crashNumberLimit:10,...n});return await y.create({...m,language:e,plugins:u,...d.length&&{translations:d}}),y.on("itemError",(...E)=>{console.error("Context item error:",...E)}),y})();const w=await this.contextPromise;this.isBeingDestroyed()||g.the.register(t,w)}async destroyed(){const{id:t}=this.attrs;this.el.style.display="none";try{await(await this.contextPromise)?.destroy()}finally{this.contextPromise=null,g.the.hasItem(t)&&g.the.unregister(t)}}}function Tt(a){return a.hasAttribute("data-cke-context")}function At(a){let t=a;for(;t;){if(Tt(t))return t;t=t.parentElement}return null}async function It(a){const t=At(a);return t?g.the.waitFor(t.id):null}const xt=C(Ct);class p extends _{static the=new p}class Ot extends P{editorPromise=null;get attrs(){const t={editableId:this.el.getAttribute("id"),editorId:this.el.getAttribute("data-cke-editor-id")||null,rootName:this.el.getAttribute("data-cke-editable-root-name"),initialValue:this.el.getAttribute("data-cke-editable-initial-value")||""};return Object.defineProperty(this,"attrs",{value:t,writable:!1,configurable:!1,enumerable:!0}),t}async mounted(){const{editableId:t,editorId:e,rootName:i,initialValue:n}=this.attrs,o=this.el.querySelector(`#${t}_input`);this.editorPromise=p.the.execute(e,s=>{if(this.isBeingDestroyed())return null;const{ui:u,editing:c,model:l}=s;if(l.document.getRoot(i))return s;s.addRoot(i,{isUndoable:!1,data:n});const d=this.el.querySelector("[data-cke-editable-content]"),m=u.view.createEditable(i,d);if(u.addEditable(m),c.view.forceRender(),o){const w=St(o,s,i);this.onBeforeDestroy(w)}return s})}async destroyed(){const{rootName:t}=this.attrs;this.el.style.display="none";const e=await this.editorPromise;if(this.editorPromise=null,e&&e.state!=="destroyed"){const i=e.model.document.getRoot(t);i&&"detachEditable"in e&&(e.ui.view.editables[t]&&e.detachEditable(i),i.isAttached()&&e.detachRoot(t,!1))}}}const Dt=C(Ot);function St(a,t,e){const i=()=>{a.value=t.getData({rootName:e})},n=$(200,i);return t.model.document.on("change:data",n),i(),()=>{t.model.document.off("change:data",n)}}async function Vt(){const{Plugin:a,FileRepository:t}=await import("ckeditor5");return class extends a{static get pluginName(){return"PhoenixUploadAdapter"}static get requires(){return[t]}init(){const{editor:i}=this,{plugins:n,config:o}=i,s=o.get("phoenixUpload.url");if(!s||n.has("SimpleUploadAdapter")||n.has("Base64UploadAdapter")||n.has("CKFinderUploadAdapter"))return;const u=n.get(t);u.createUploadAdapter=c=>new Rt(c,s)}}}class Rt{loader;uploadUrl;abortController=null;constructor(t,e){this.loader=t,this.uploadUrl=e}async upload(){const t=await this.loader.file;this.abortController=new AbortController;const e=new FormData;e.append("file",t),t.size&&(this.loader.uploadTotal=t.size,this.loader.uploaded=0);const i={},n=lt();n&&(i["X-CSRF-Token"]=n);try{const o=await fetch(this.uploadUrl,{method:"POST",headers:i,body:e,signal:this.abortController.signal});if(!o.ok){let u="Couldn't upload file!";try{const c=await o.json();c?.error?.message&&(u=c.error.message)}catch{}throw new Error(u)}return this.loader.uploaded=this.loader.uploadTotal,{default:(await o.json()).url}}catch(o){throw o.name==="AbortError"?o:o.message||"Couldn't upload file!"}}abort(){this.abortController?.abort(),this.abortController=null}}async function $t({editorId:a,saveDebounceMs:t}){const{Plugin:e}=await import("ckeditor5");return class extends e{input=null;form=null;static get pluginName(){return"SyncEditorWithInput"}afterInit(){const{editor:n}=this;this.input=document.getElementById(`${a}_input`),this.input&&(n.model.document.on("change:data",$(t,()=>this.sync())),n.once("ready",this.sync),this.form=this.input.closest("form"),this.form?.addEventListener("submit",this.sync))}sync=()=>{const n=this.editor.getData();this.input.value=n,this.input.dispatchEvent(new Event("input",{bubbles:!0}))};destroy(){this.form&&this.form.removeEventListener("submit",this.sync),this.input=null,this.form=null}}}async function Ut(a){const{Plugin:t}=await import("ckeditor5"),{editorId:e,saveDebounceMs:i,events:n,pushEvent:o,handleEvent:s}=a;return class extends t{static get pluginName(){return"SyncEditorWithPhoenix"}init(){const{editor:c}=this;n.change&&this.setupTypingContentPush(),n.blur&&this.setupEventPush("blur"),n.focus&&this.setupEventPush("focus"),n.ready&&this.editor.once("ready",()=>{o("ckeditor5:ready",{editorId:e,data:S(c)})}),s("ckeditor5:set-data",({editorId:l,data:d})=>{(dt(l)||l===e)&&c.setData(d)})}setupTypingContentPush(){const{editor:c}=this;let l=null,d=!1;const m=()=>{if(d)return;const f=S(c);(!l||!ht(l,f))&&(o("ckeditor5:change",{editorId:e,data:f}),l=f)},w=$(i,m);c.model.document.on("change:data",()=>{c.ui.focusTracker.isFocused?w():m()}),c.once("ready",m),c.once("destroy",()=>{d=!0})}setupEventPush(c){const{editor:l}=this,d=()=>{const{isFocused:m}=l.ui.focusTracker;(m?"focus":"blur")===c&&o(`ckeditor5:${c}`,{editorId:e,data:S(l)})};l.ui.focusTracker.on("change:isFocused",d)}}}function S(a){return a.model.document.getRootNames().reduce((e,i)=>(e[i]=a.getData({rootName:i}),e),Object.create({}))}class jt extends P{editorPromise=null;get attrs(){const{el:t}=this,e=t.getAttribute.bind(t),i=t.hasAttribute.bind(t),n={editorId:e("id"),contextId:e("data-cke-context-id"),preset:bt(t),editableHeight:N(e("data-cke-editable-height")),watchdog:i("data-cke-watchdog"),events:{change:i("data-cke-change-event"),blur:i("data-cke-blur-event"),focus:i("data-cke-focus-event"),ready:i("data-cke-ready-event")},saveDebounceMs:N(e("data-cke-save-debounce-ms"))??400,language:{ui:e("data-cke-language")||"en",content:e("data-cke-content-language")||"en"}};return Object.defineProperty(this,"attrs",{value:n,writable:!1,configurable:!1,enumerable:!0}),n}async mounted(){const{editorId:t}=this.attrs;p.the.resetErrors(t);try{this.editorPromise=this.createEditor();const e=await this.editorPromise;this.isBeingDestroyed()||(p.the.register(t,e),e.once("destroy",()=>{p.the.hasItem(t)&&p.the.unregister(t)}))}catch(e){this.editorPromise=null,p.the.error(t,e)}return this}async destroyed(){this.el.style.display="none";try{const t=await this.editorPromise;if(!t)return;const e=K(t),i=Q(t);e?e.state!=="unavailable"&&await e.context.remove(e.editorContextId):i?await i.destroy():await t.destroy()}finally{this.editorPromise=null}}async createEditor(){const{preset:t,editorId:e,contextId:i,editableHeight:n,events:o,saveDebounceMs:s,language:u,watchdog:c}=this.attrs,{customTranslations:l,type:d,license:m,config:{plugins:w,...f}}=t;let b=await gt(d);const y=await(i?g.the.waitFor(i):It(this.el));if(c&&!y){const h=await vt(b);({Constructor:b}=h),h.watchdog.on("restart",()=>{const k=h.watchdog.editor;this.editorPromise=Promise.resolve(k),p.the.register(e,k)})}const{loadedPlugins:E,hasPremium:tt}=await L(w);T(d)&&E.push(await $t({editorId:e,saveDebounceMs:s})),E.push(...await Promise.all([Ut({editorId:e,saveDebounceMs:s,events:o,pushEvent:this.pushEvent.bind(this),handleEvent:this.handleEvent.bind(this)}),Vt()]));const D=[...await J(u,tt),G(l?.dictionary||{})].filter(h=>!B(h));let v=F(e);T(d)&&(v=v.main||"");const j=await(async()=>{let h=Y(e);if(!(h instanceof HTMLElement)&&!("main"in h)){const H=d==="decoupled"?["main"]:Object.keys(v);Z(h,H)||(h=await Mt(e,H),v=F(e))}T(d)&&"main"in h&&(h=h.main);let k=I(f);k=x([...D].reverse(),u.ui,k);const M={...k,initialData:v,licenseKey:m.key,plugins:E,language:u,...D.length&&{translations:D}};return!y||!(h instanceof HTMLElement)?b.create(h,M):(await wt({context:y,element:h,creator:b,config:M})).editor})();return T(d)&&n&&Et(j,n),j}}function Z(a,t){return t.every(e=>a[e])}async function Mt(a,t){return ft(()=>{const e=Y(a);if(!Z(e,t))throw new Error(`It looks like not all required root elements are present yet.
1
+ "use strict";var at=Object.create;var z=Object.defineProperty;var it=Object.getOwnPropertyDescriptor;var nt=Object.getOwnPropertyNames;var st=Object.getPrototypeOf,ot=Object.prototype.hasOwnProperty;var ct=(a,t,e,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of nt(t))!ot.call(a,n)&&n!==e&&z(a,n,{get:()=>t[n],enumerable:!(i=it(t,n))||i.enumerable});return a};var r=(a,t,e)=>(e=a!=null?at(st(a)):{},ct(t||!a||!a.__esModule?z(e,"default",{value:a,enumerable:!0}):e,a));Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});class B{items=new Map;initializationErrors=new Map;pendingCallbacks=new Map;watchers=new Set;execute(t,e,i){const n=this.items.get(t),s=this.initializationErrors.get(t);return s?(i?.(s),Promise.reject(s)):n?Promise.resolve(e(n)):new Promise((o,u)=>{const c=this.getPendingCallbacks(t);c.success.push(async l=>{o(await e(l))}),i?c.error.push(i):c.error.push(u)})}register(t,e){if(this.items.has(t))throw new Error(`Item with ID "${t}" is already registered.`);this.resetErrors(t),this.items.set(t,e);const i=this.pendingCallbacks.get(t);i&&(i.success.forEach(n=>n(e)),this.pendingCallbacks.delete(t)),this.registerAsDefault(t,e),this.notifyWatchers()}error(t,e){this.items.delete(t),this.initializationErrors.set(t,e);const i=this.pendingCallbacks.get(t);i&&(i.error.forEach(n=>n(e)),this.pendingCallbacks.delete(t)),this.initializationErrors.size===1&&!this.items.size&&this.error(null,e),this.notifyWatchers()}resetErrors(t){const{initializationErrors:e}=this;e.has(null)&&e.get(null)===e.get(t)&&e.delete(null),e.delete(t)}unregister(t){if(!this.items.has(t))throw new Error(`Item with ID "${t}" is not registered.`);t&&this.items.get(null)===this.items.get(t)&&this.unregister(null),this.items.delete(t),this.pendingCallbacks.delete(t),this.notifyWatchers()}getItems(){return Array.from(this.items.values())}hasItem(t){return this.items.has(t)}waitFor(t){return new Promise((e,i)=>{this.execute(t,e,i)})}async destroyAll(){const t=Array.from(new Set(this.items.values())).map(e=>e.destroy());this.items.clear(),this.pendingCallbacks.clear(),await Promise.all(t),this.notifyWatchers()}watch(t){return this.watchers.add(t),t(new Map(this.items),new Map(this.initializationErrors)),this.unwatch.bind(this,t)}unwatch(t){this.watchers.delete(t)}notifyWatchers(){this.watchers.forEach(t=>t(new Map(this.items),new Map(this.initializationErrors)))}getPendingCallbacks(t){let e=this.pendingCallbacks.get(t);return e||(e={success:[],error:[]},this.pendingCallbacks.set(t,e)),e}registerAsDefault(t,e){this.items.size===1&&t!==null&&this.register(null,e)}}function ut(a){return a.replace(/[-_\s]+(.)?/g,(t,e)=>e?e.toUpperCase():"").replace(/^./,t=>t.toLowerCase())}function C(a,t){let e=null;return(...i)=>{e&&clearTimeout(e),e=setTimeout(()=>{t(...i)},a)}}function lt(a){if(Object.prototype.toString.call(a)!=="[object Object]")return!1;const t=Object.getPrototypeOf(a);return t===Object.prototype||t===null}function A(a){if(Array.isArray(a))return a.map(A);if(lt(a)){const t=Object.create(null);for(const[e,i]of Object.entries(a))t[ut(e)]=A(i);return t}return a}function dt(a,t){const e=Object.entries(a).filter(([i,n])=>t(n,i));return Object.fromEntries(e)}function ht(){const a=document.querySelector('meta[name="csrf-token"]');if(a)return a.getAttribute("content");const t=document.cookie.match(/(?:^|; )_csrf_token=([^;]*)/);return t?decodeURIComponent(t[1]):null}class I{state="mounting";el;_beforeDestroyCallbacks=[];onBeforeDestroy(t){this._beforeDestroyCallbacks.push(t)}pushEvent;pushEventTo;handleEvent;mounted(){}destroyed(){}updated(){}isBeingDestroyed(){return this.state==="destroyed"||this.state==="destroying"}_runBeforeDestroyCallbacks(){for(const t of this._beforeDestroyCallbacks.reverse())t();this._beforeDestroyCallbacks=[]}}function O(a){return{async mounted(){const t=new a;this.el.instance=t,t.el=this.el,t.pushEvent=(i,n,s)=>this.pushEvent?.(i,n,s),t.pushEventTo=(i,n,s,o)=>this.pushEventTo?.(i,n,s,o),t.handleEvent=(i,n)=>this.handleEvent?.(i,n),t.state="mounting";const e=await t.mounted?.();return t.state="mounted",e},beforeUpdate(){this.el.instance.beforeUpdate?.()},async destroyed(){const{instance:t}=this.el;t.state="destroying",t._runBeforeDestroyCallbacks(),await t.destroyed?.(),t.state="destroyed"},disconnected(){this.el.instance.disconnected?.()},reconnected(){this.el.instance.reconnected?.()},updated(){this.el.instance.updated?.()}}}function L(a){return Object.keys(a).length===0&&a.constructor===Object}function mt(a){return a==null}function $(a,t){const e=Object.entries(a).map(([i,n])=>[i,t(n,i)]);return Object.fromEntries(e)}function _(a){if(a===null)return null;const t=Number.parseInt(a,10);return Number.isNaN(t)?null:t}function pt(a){return a==null||a.trim()===""?null:JSON.parse(a)}function ft(a,t){if(a===t)return!0;const e=Object.keys(a),i=Object.keys(t);if(e.length!==i.length)return!1;for(const n of e)if(a[n]!==t[n]||!Object.prototype.hasOwnProperty.call(t,n))return!1;return!0}function wt(){return Math.random().toString(36).substring(2)}function gt(a,{timeOutAfter:t=500,retryAfter:e=100}={}){return new Promise((i,n)=>{const s=Date.now();let o=null;const u=setTimeout(()=>{n(o??new Error("Timeout"))},t),c=async()=>{try{const l=await a();clearTimeout(u),i(l)}catch(l){o=l,Date.now()-s>t?n(l):setTimeout(c,e)}};c()})}const U=Symbol.for("context-editor-watchdog");async function yt({element:a,context:t,creator:e,config:i}){const n=wt();await t.add({creator:(c,l)=>e.create(c,l),id:n,sourceElementOrData:a,type:"editor",config:i});const s=t.getItem(n),o={state:"available",editorContextId:n,context:t};s[U]=o;const u=t.destroy.bind(t);return t.destroy=async()=>(o.state="unavailable",u()),{...o,editor:s}}function K(a){return U in a?a[U]:null}function bt(a){return["multiroot","decoupled"].includes(a)}function P(a){return["inline","classic","balloon","decoupled"].includes(a)}async function kt(a){const t=await import("ckeditor5"),i={inline:t.InlineEditor,balloon:t.BalloonEditor,classic:t.ClassicEditor,decoupled:t.DecoupledEditor,multiroot:t.MultiRootEditor}[a];if(!i)throw new Error(`Unsupported editor type: ${a}`);return i}class D{static the=new D;plugins=new Map;constructor(){}register(t,e){if(this.plugins.has(t))throw new Error(`Plugin with name "${t}" is already registered.`);return this.plugins.set(t,e),this.unregister.bind(this,t)}unregister(t){if(!this.plugins.has(t))throw new Error(`Plugin with name "${t}" is not registered.`);this.plugins.delete(t)}unregisterAll(){this.plugins.clear()}async get(t){return this.plugins.get(t)?.()}has(t){return this.plugins.has(t)}}async function Y(a){const t=await import("ckeditor5");let e=null;const i=a.map(async n=>{const s=await D.the.get(n);if(s)return s;const{[n]:o}=t;if(o)return o;if(!e)try{e=await import("ckeditor5-premium-features")}catch(c){console.error(`Failed to load premium package: ${c}`)}const{[n]:u}=e||{};if(u)return u;throw new Error(`Plugin "${n}" not found in base or premium packages.`)});return{loadedPlugins:await Promise.all(i),hasPremium:!!e}}async function J(a,t){const e=[a.ui,a.content];return await Promise.all([q("ckeditor5",e),t&&q("ckeditor5-premium-features",e)].filter(n=>!!n)).then(n=>n.flat())}async function q(a,t){return await Promise.all(t.filter(e=>e!=="en").map(async e=>{const i=await Et(a,e);return i?.default??i}).filter(Boolean))}async function Et(a,t){try{if(a==="ckeditor5")switch(t){case"af":return await import("ckeditor5/translations/af.js");case"ar":return await import("ckeditor5/translations/ar.js");case"ast":return await import("ckeditor5/translations/ast.js");case"az":return await import("ckeditor5/translations/az.js");case"bg":return await import("ckeditor5/translations/bg.js");case"bn":return await import("ckeditor5/translations/bn.js");case"bs":return await import("ckeditor5/translations/bs.js");case"ca":return await import("ckeditor5/translations/ca.js");case"cs":return await import("ckeditor5/translations/cs.js");case"da":return await import("ckeditor5/translations/da.js");case"de":return await import("ckeditor5/translations/de.js");case"de-ch":return await import("ckeditor5/translations/de-ch.js");case"el":return await import("ckeditor5/translations/el.js");case"en":return await import("ckeditor5/translations/en.js");case"en-au":return await import("ckeditor5/translations/en-au.js");case"en-gb":return await import("ckeditor5/translations/en-gb.js");case"eo":return await import("ckeditor5/translations/eo.js");case"es":return await import("ckeditor5/translations/es.js");case"es-co":return await import("ckeditor5/translations/es-co.js");case"et":return await import("ckeditor5/translations/et.js");case"eu":return await import("ckeditor5/translations/eu.js");case"fa":return await import("ckeditor5/translations/fa.js");case"fi":return await import("ckeditor5/translations/fi.js");case"fr":return await import("ckeditor5/translations/fr.js");case"gl":return await import("ckeditor5/translations/gl.js");case"gu":return await import("ckeditor5/translations/gu.js");case"he":return await import("ckeditor5/translations/he.js");case"hi":return await import("ckeditor5/translations/hi.js");case"hr":return await import("ckeditor5/translations/hr.js");case"hu":return await import("ckeditor5/translations/hu.js");case"hy":return await import("ckeditor5/translations/hy.js");case"id":return await import("ckeditor5/translations/id.js");case"it":return await import("ckeditor5/translations/it.js");case"ja":return await import("ckeditor5/translations/ja.js");case"jv":return await import("ckeditor5/translations/jv.js");case"kk":return await import("ckeditor5/translations/kk.js");case"km":return await import("ckeditor5/translations/km.js");case"kn":return await import("ckeditor5/translations/kn.js");case"ko":return await import("ckeditor5/translations/ko.js");case"ku":return await import("ckeditor5/translations/ku.js");case"lt":return await import("ckeditor5/translations/lt.js");case"lv":return await import("ckeditor5/translations/lv.js");case"ms":return await import("ckeditor5/translations/ms.js");case"nb":return await import("ckeditor5/translations/nb.js");case"ne":return await import("ckeditor5/translations/ne.js");case"nl":return await import("ckeditor5/translations/nl.js");case"no":return await import("ckeditor5/translations/no.js");case"oc":return await import("ckeditor5/translations/oc.js");case"pl":return await import("ckeditor5/translations/pl.js");case"pt":return await import("ckeditor5/translations/pt.js");case"pt-br":return await import("ckeditor5/translations/pt-br.js");case"ro":return await import("ckeditor5/translations/ro.js");case"ru":return await import("ckeditor5/translations/ru.js");case"si":return await import("ckeditor5/translations/si.js");case"sk":return await import("ckeditor5/translations/sk.js");case"sl":return await import("ckeditor5/translations/sl.js");case"sq":return await import("ckeditor5/translations/sq.js");case"sr":return await import("ckeditor5/translations/sr.js");case"sr-latn":return await import("ckeditor5/translations/sr-latn.js");case"sv":return await import("ckeditor5/translations/sv.js");case"th":return await import("ckeditor5/translations/th.js");case"tk":return await import("ckeditor5/translations/tk.js");case"tr":return await import("ckeditor5/translations/tr.js");case"tt":return await import("ckeditor5/translations/tt.js");case"ug":return await import("ckeditor5/translations/ug.js");case"uk":return await import("ckeditor5/translations/uk.js");case"ur":return await import("ckeditor5/translations/ur.js");case"uz":return await import("ckeditor5/translations/uz.js");case"vi":return await import("ckeditor5/translations/vi.js");case"zh":return await import("ckeditor5/translations/zh.js");case"zh-cn":return await import("ckeditor5/translations/zh-cn.js");default:return console.warn(`Language ${t} not found in ckeditor5 translations`),null}else switch(t){case"af":return await import("ckeditor5-premium-features/translations/af.js");case"ar":return await import("ckeditor5-premium-features/translations/ar.js");case"ast":return await import("ckeditor5-premium-features/translations/ast.js");case"az":return await import("ckeditor5-premium-features/translations/az.js");case"bg":return await import("ckeditor5-premium-features/translations/bg.js");case"bn":return await import("ckeditor5-premium-features/translations/bn.js");case"bs":return await import("ckeditor5-premium-features/translations/bs.js");case"ca":return await import("ckeditor5-premium-features/translations/ca.js");case"cs":return await import("ckeditor5-premium-features/translations/cs.js");case"da":return await import("ckeditor5-premium-features/translations/da.js");case"de":return await import("ckeditor5-premium-features/translations/de.js");case"de-ch":return await import("ckeditor5-premium-features/translations/de-ch.js");case"el":return await import("ckeditor5-premium-features/translations/el.js");case"en":return await import("ckeditor5-premium-features/translations/en.js");case"en-au":return await import("ckeditor5-premium-features/translations/en-au.js");case"en-gb":return await import("ckeditor5-premium-features/translations/en-gb.js");case"eo":return await import("ckeditor5-premium-features/translations/eo.js");case"es":return await import("ckeditor5-premium-features/translations/es.js");case"es-co":return await import("ckeditor5-premium-features/translations/es-co.js");case"et":return await import("ckeditor5-premium-features/translations/et.js");case"eu":return await import("ckeditor5-premium-features/translations/eu.js");case"fa":return await import("ckeditor5-premium-features/translations/fa.js");case"fi":return await import("ckeditor5-premium-features/translations/fi.js");case"fr":return await import("ckeditor5-premium-features/translations/fr.js");case"gl":return await import("ckeditor5-premium-features/translations/gl.js");case"gu":return await import("ckeditor5-premium-features/translations/gu.js");case"he":return await import("ckeditor5-premium-features/translations/he.js");case"hi":return await import("ckeditor5-premium-features/translations/hi.js");case"hr":return await import("ckeditor5-premium-features/translations/hr.js");case"hu":return await import("ckeditor5-premium-features/translations/hu.js");case"hy":return await import("ckeditor5-premium-features/translations/hy.js");case"id":return await import("ckeditor5-premium-features/translations/id.js");case"it":return await import("ckeditor5-premium-features/translations/it.js");case"ja":return await import("ckeditor5-premium-features/translations/ja.js");case"jv":return await import("ckeditor5-premium-features/translations/jv.js");case"kk":return await import("ckeditor5-premium-features/translations/kk.js");case"km":return await import("ckeditor5-premium-features/translations/km.js");case"kn":return await import("ckeditor5-premium-features/translations/kn.js");case"ko":return await import("ckeditor5-premium-features/translations/ko.js");case"ku":return await import("ckeditor5-premium-features/translations/ku.js");case"lt":return await import("ckeditor5-premium-features/translations/lt.js");case"lv":return await import("ckeditor5-premium-features/translations/lv.js");case"ms":return await import("ckeditor5-premium-features/translations/ms.js");case"nb":return await import("ckeditor5-premium-features/translations/nb.js");case"ne":return await import("ckeditor5-premium-features/translations/ne.js");case"nl":return await import("ckeditor5-premium-features/translations/nl.js");case"no":return await import("ckeditor5-premium-features/translations/no.js");case"oc":return await import("ckeditor5-premium-features/translations/oc.js");case"pl":return await import("ckeditor5-premium-features/translations/pl.js");case"pt":return await import("ckeditor5-premium-features/translations/pt.js");case"pt-br":return await import("ckeditor5-premium-features/translations/pt-br.js");case"ro":return await import("ckeditor5-premium-features/translations/ro.js");case"ru":return await import("ckeditor5-premium-features/translations/ru.js");case"si":return await import("ckeditor5-premium-features/translations/si.js");case"sk":return await import("ckeditor5-premium-features/translations/sk.js");case"sl":return await import("ckeditor5-premium-features/translations/sl.js");case"sq":return await import("ckeditor5-premium-features/translations/sq.js");case"sr":return await import("ckeditor5-premium-features/translations/sr.js");case"sr-latn":return await import("ckeditor5-premium-features/translations/sr-latn.js");case"sv":return await import("ckeditor5-premium-features/translations/sv.js");case"th":return await import("ckeditor5-premium-features/translations/th.js");case"tk":return await import("ckeditor5-premium-features/translations/tk.js");case"tr":return await import("ckeditor5-premium-features/translations/tr.js");case"tt":return await import("ckeditor5-premium-features/translations/tt.js");case"ug":return await import("ckeditor5-premium-features/translations/ug.js");case"uk":return await import("ckeditor5-premium-features/translations/uk.js");case"ur":return await import("ckeditor5-premium-features/translations/ur.js");case"uz":return await import("ckeditor5-premium-features/translations/uz.js");case"vi":return await import("ckeditor5-premium-features/translations/vi.js");case"zh":return await import("ckeditor5-premium-features/translations/zh.js");case"zh-cn":return await import("ckeditor5-premium-features/translations/zh-cn.js");default:return console.warn(`Language ${t} not found in premium translations`),await import("ckeditor5-premium-features/translations/en.js")}}catch(e){return console.error(`Failed to load translation for ${a}/${t}:`,e),null}}function G(a){return $(a,t=>({dictionary:t}))}function X(a){const t=Q(a);return $(t,({content:e})=>e)}function F(a){const t=Q(a),e=$(t,({initialValue:i})=>i);return dt(e,i=>typeof i=="string")}function Q(a){const t=document.querySelectorAll([`[data-cke-editor-id="${a}"][data-cke-editable-root-name]`,"[data-cke-editable-root-name]:not([data-cke-editor-id])"].join(", ")),e=Array.from(t).reduce((u,c)=>{const l=c.getAttribute("data-cke-editable-root-name"),d=c.getAttribute("data-cke-editable-initial-value")||"",h=c.querySelector("[data-cke-editable-content]");return!l||!h?u:{...u,[l]:{content:h,initialValue:d}}},Object.create({})),i=document.querySelector(`[phx-hook="CKEditor5"][id="${a}"]`);if(!i)return e;const n=i.getAttribute("data-cke-initial-value")||"",s=i.querySelector(`#${a}_editor `),o=e.main;return o?{...e,main:{...o,initialValue:o.initialValue||n}}:s?{...e,main:{content:s,initialValue:n}}:e}const W=["inline","classic","balloon","decoupled","multiroot"];function vt(a){const t=a.getAttribute("data-cke-preset");if(!t)throw new Error('CKEditor5 hook requires a "cke-preset" attribute on the element.');const{type:e,config:i,license:n,...s}=JSON.parse(t);if(!e||!i||!n)throw new Error('CKEditor5 hook configuration must include "editor", "config", and "license" properties.');if(!W.includes(e))throw new Error(`Invalid editor type: ${e}. Must be one of: ${W.join(", ")}.`);return{type:e,license:n,config:A(i),customTranslations:s.customTranslations||s.custom_translations}}function T(a){if(!a||typeof a!="object")return a;if(Array.isArray(a))return a.map(i=>T(i));const t=a;if(t.$element&&typeof t.$element=="string"){const i=document.querySelector(t.$element);return i||console.warn(`Element not found for selector: ${t.$element}`),i||null}const e=Object.create(null);for(const[i,n]of Object.entries(a))e[i]=T(n);return e}function x(a,t,e){if(!e||typeof e!="object")return e;if(Array.isArray(e))return e.map(s=>x(a,t,s));const i=e;if(i.$translation&&typeof i.$translation=="string"){const s=i.$translation,o=Pt(a,s,t);return o===void 0&&console.warn(`Translation not found for key: ${s}`),o!==void 0?o:null}const n=Object.create(null);for(const[s,o]of Object.entries(e))n[s]=x(a,t,o);return n}function Pt(a,t,e){for(const i of a){const n=i[e];if(n?.dictionary&&t in n.dictionary)return n.dictionary[t]}}function Ct(a,t){const{editing:e}=a;e.view.change(i=>{i.setStyle("height",`${t}px`,e.view.document.getRoot())})}const R=Symbol.for("elixir-editor-watchdog");async function At(a){const{EditorWatchdog:t}=await import("ckeditor5"),e=new t(a);return e.setCreator(async(...i)=>{const n=await a.create(...i);return n[R]=e,n}),{watchdog:e,Constructor:{create:async(...i)=>(await e.create(...i),e.editor)}}}function Z(a){return R in a?a[R]:null}class g extends B{static the=new g}function Tt(a){const t=a.getAttribute("data-cke-context");if(!t)throw new Error('CKEditor5 hook requires a "data-cke-context" attribute on the element.');const{config:e,...i}=JSON.parse(t);return{config:A(e),customTranslations:i.customTranslations||i.custom_translations,watchdogConfig:i.watchdogConfig||i.watchdog_config}}class xt extends I{contextPromise=null;get attrs(){const t=i=>this.el.getAttribute(i)||null,e={id:this.el.id,config:Tt(this.el),language:{ui:t("data-cke-language")||"en",content:t("data-cke-content-language")||"en"}};return Object.defineProperty(this,"attrs",{value:e,writable:!1,configurable:!1,enumerable:!0}),e}async mounted(){const{id:t,language:e}=this.attrs,{customTranslations:i,watchdogConfig:n,config:{plugins:s,...o}}=this.attrs.config,{loadedPlugins:u,hasPremium:c}=await Y(s??[]),d=[...await J(e,c),G(i?.dictionary||{})].filter(f=>!L(f));let h=T(o);h=x([...d].reverse(),e.ui,h),this.contextPromise=(async()=>{const{ContextWatchdog:f,Context:b}=await import("ckeditor5"),y=new f(b,{crashNumberLimit:10,...n});return await y.create({...h,language:e,plugins:u,...d.length&&{translations:d}}),y.on("itemError",(...E)=>{console.error("Context item error:",...E)}),y})();const w=await this.contextPromise;this.isBeingDestroyed()||g.the.register(t,w)}async destroyed(){const{id:t}=this.attrs;this.el.style.display="none";try{await(await this.contextPromise)?.destroy()}finally{this.contextPromise=null,g.the.hasItem(t)&&g.the.unregister(t)}}}function It(a){return a.hasAttribute("data-cke-context")}function Ot(a){let t=a;for(;t;){if(It(t))return t;t=t.parentElement}return null}async function Dt(a){const t=Ot(a);return t?g.the.waitFor(t.id):null}const St=O(xt);class p extends B{static the=new p}function Nt(a,t){const e=new Set;return i=>{let n=!1;return a.model.enqueueChange({isUndoable:!1},s=>{const o=a.model.document.getRoot(t);if(o){for(const u of e)i&&u in i||(s.removeAttribute(u,o),e.delete(u),n=!0);for(const[u,c]of Object.entries(i??{}))s.setAttribute(u,c,o),e.add(u),n=!0}}),n}}async function Ut(){const{Plugin:a,FileRepository:t}=await import("ckeditor5");return class extends a{static get pluginName(){return"PhoenixUploadAdapter"}static get requires(){return[t]}init(){const{editor:i}=this,{plugins:n,config:s}=i,o=s.get("phoenixUpload.url");if(!o||n.has("SimpleUploadAdapter")||n.has("Base64UploadAdapter")||n.has("CKFinderUploadAdapter"))return;const u=n.get(t);u.createUploadAdapter=c=>new Rt(c,o)}}}class Rt{loader;uploadUrl;abortController=null;constructor(t,e){this.loader=t,this.uploadUrl=e}async upload(){const t=await this.loader.file;this.abortController=new AbortController;const e=new FormData;e.append("file",t),t.size&&(this.loader.uploadTotal=t.size,this.loader.uploaded=0);const i={},n=ht();n&&(i["X-CSRF-Token"]=n);try{const s=await fetch(this.uploadUrl,{method:"POST",headers:i,body:e,signal:this.abortController.signal});if(!s.ok){let u="Couldn't upload file!";try{const c=await s.json();c?.error?.message&&(u=c.error.message)}catch{}throw new Error(u)}return this.loader.uploaded=this.loader.uploadTotal,{default:(await s.json()).url}}catch(s){throw s.name==="AbortError"?s:s.message||"Couldn't upload file!"}}abort(){this.abortController?.abort(),this.abortController=null}}async function Vt({editorId:a,saveDebounceMs:t}){const{Plugin:e}=await import("ckeditor5");return class extends e{input=null;form=null;static get pluginName(){return"SyncEditorWithInput"}afterInit(){const{editor:n}=this;this.input=document.getElementById(`${a}_input`),this.input&&(n.model.document.on("change:data",C(t,()=>this.sync())),n.once("ready",this.sync),this.form=this.input.closest("form"),this.form?.addEventListener("submit",this.sync))}sync=()=>{const n=this.editor.getData();this.input.value=n,this.input.dispatchEvent(new Event("input",{bubbles:!0}))};destroy(){this.form&&this.form.removeEventListener("submit",this.sync),this.input=null,this.form=null}}}const V=Symbol("suppress-phoenix-sync");async function $t(a){const{Plugin:t}=await import("ckeditor5"),{editorId:e,saveDebounceMs:i,events:n,pushEvent:s,handleEvent:o}=a;return class extends t{static get pluginName(){return"SyncEditorWithPhoenix"}init(){const{editor:c}=this;n.change&&this.setupTypingContentPush(),n.blur&&this.setupEventPush("blur"),n.focus&&this.setupEventPush("focus"),n.ready&&this.editor.once("ready",()=>{s("ckeditor5:ready",{editorId:e,data:N(c)})}),o("ckeditor5:set-data",({editorId:l,data:d})=>{(mt(l)||l===e)&&c.setData(d)})}setupTypingContentPush(){const{editor:c}=this;let l=null,d=!1;const h=()=>{if(d)return;const f=N(c);(!l||!ft(l,f))&&(s("ckeditor5:change",{editorId:e,data:f}),l=f)},w=C(i,h);c.model.document.on("change:data",C(10,f=>{if(Mt(f)){l=null;return}c.ui.focusTracker.isFocused?w():h()})),c.once("ready",h),c.once("destroy",()=>{d=!0})}setupEventPush(c){const{editor:l}=this,d=()=>{const{isFocused:h}=l.ui.focusTracker;(h?"focus":"blur")===c&&s(`ckeditor5:${c}`,{editorId:e,data:N(l)})};l.ui.focusTracker.on("change:isFocused",d)}}}function N(a){return a.model.document.getRootNames().reduce((e,i)=>(e[i]=a.getData({rootName:i}),e),Object.create({}))}function Mt(a){const t=a[V];return delete a[V],!!t}function jt(a){let t=!1;const e=i=>{t||(i[V]=!0)};return a.model.document.once("change:data",e,{priority:"highest"}),()=>{t=!0,a.model.document.off("change:data",e)}}class tt{el;editorId;rootName;valueAttrName;rootAttrsAttrName;observer=null;isDestroyed=!1;cleanupCallbacks=[];editorPromise=null;pendingValue=null;previousValue=null;attrsUpdater=null;constructor({el:t,editorId:e,rootName:i,valueAttrName:n="data-cke-value",rootAttrsAttrName:s="data-cke-root-attrs"}){this.el=t,this.editorId=e,this.rootName=i,this.valueAttrName=n,this.rootAttrsAttrName=s;const{value:o}=this.attrs;this.previousValue=o,this.editorPromise=p.the.execute(this.editorId,u=>this.isDestroyed?null:(this.setupSyncHandlers(u,this.rootName),u)),this.setupObserver()}get attrs(){return{rootAttributes:pt(this.el.getAttribute(this.rootAttrsAttrName)),value:this.el.getAttribute(this.valueAttrName)}}setupObserver(){this.observer=new MutationObserver(t=>{for(const e of t)if(e.type==="attributes"){this.handleUpdate();break}}),this.observer.observe(this.el,{attributes:!0,attributeFilter:[this.valueAttrName,this.rootAttrsAttrName]})}async handleUpdate(){const{value:t,rootAttributes:e}=this.attrs,i=await this.editorPromise;if(!i||i.state==="destroyed"||this.isDestroyed)return;let n=()=>{};i.model.enqueueChange({isUndoable:!1},()=>{let s=this.attrsUpdater?.(e);t!==this.previousValue&&(this.previousValue=t,i.ui.focusTracker.isFocused?this.pendingValue=t:(this.setRootValue(i,this.rootName,t),s=!0)),s&&(n=jt(i))}),n()}setupSyncHandlers(t,e){this.attrsUpdater=Nt(t,e),this.attrsUpdater(this.attrs.rootAttributes);const i=()=>{this.pendingValue=null},n=()=>{!t.ui.focusTracker.isFocused&&this.pendingValue!==null&&(this.setRootValue(t,e,this.pendingValue),this.pendingValue=null)};t.model.document.on("change:data",i),t.ui.focusTracker.on("change:isFocused",n),this.cleanupCallbacks.push(()=>{t.model.document.off("change:data",i),t.ui.focusTracker.off("change:isFocused",n)})}setRootValue(t,e,i){t.getData({rootName:e})!==i&&t.setData({[e]:i})}destroy(){this.isDestroyed=!0,this.observer?.disconnect(),this.cleanupCallbacks.forEach(t=>t()),this.cleanupCallbacks=[]}}class Ht extends I{editorPromise=null;sentinel=null;get attrs(){const t={editableId:this.el.getAttribute("id"),editorId:this.el.getAttribute("data-cke-editor-id")||null,rootName:this.el.getAttribute("data-cke-editable-root-name"),initialValue:this.el.getAttribute("data-cke-editable-initial-value")||""};return Object.defineProperty(this,"attrs",{value:t,writable:!1,configurable:!1,enumerable:!0}),t}async mounted(){const{editableId:t,editorId:e,rootName:i,initialValue:n}=this.attrs,s=this.el.querySelector(`#${t}_input`);this.sentinel=new tt({el:this.el,valueAttrName:"data-cke-editable-initial-value",rootAttrsAttrName:"data-cke-editable-root-attrs",editorId:e,rootName:i}),this.editorPromise=p.the.execute(e,o=>{if(this.isBeingDestroyed())return null;const{ui:u,editing:c,model:l}=o;if(l.document.getRoot(i))return o;o.addRoot(i,{isUndoable:!1,data:n});const d=this.el.querySelector("[data-cke-editable-content]"),h=u.view.createEditable(i,d);if(u.addEditable(h),c.view.forceRender(),s){const w=_t(s,o,i);this.onBeforeDestroy(w)}return o})}async destroyed(){const{rootName:t}=this.attrs;this.el.style.display="none",this.sentinel?.destroy(),this.sentinel=null;const e=await this.editorPromise;if(this.editorPromise=null,e&&e.state!=="destroyed"){const i=e.model.document.getRoot(t);i&&"detachEditable"in e&&(e.ui.view.editables[t]&&e.detachEditable(i),i.isAttached()&&e.detachRoot(t,!1))}}}const zt=O(Ht);function _t(a,t,e){const i=()=>{a.value=t.getData({rootName:e})},n=C(200,i);return t.model.document.on("change:data",n),i(),()=>{t.model.document.off("change:data",n)}}class qt extends I{editorPromise=null;sentinel=null;get attrs(){const{el:t}=this,e=t.getAttribute.bind(t),i=t.hasAttribute.bind(t),n={editorId:e("id"),contextId:e("data-cke-context-id"),preset:vt(t),editableHeight:_(e("data-cke-editable-height")),watchdog:i("data-cke-watchdog"),events:{change:i("data-cke-change-event"),blur:i("data-cke-blur-event"),focus:i("data-cke-focus-event"),ready:i("data-cke-ready-event")},saveDebounceMs:_(e("data-cke-save-debounce-ms"))??400,language:{ui:e("data-cke-language")||"en",content:e("data-cke-content-language")||"en"}};return Object.defineProperty(this,"attrs",{value:n,writable:!1,configurable:!1,enumerable:!0}),n}async mounted(){const{editorId:t,preset:e}=this.attrs;p.the.resetErrors(t),bt(e.type)||(this.sentinel=new tt({editorId:t,el:this.el,rootName:"main",valueAttrName:"data-cke-initial-value",rootAttrsAttrName:"data-cke-root-attrs"}));try{this.editorPromise=this.createEditor();const i=await this.editorPromise;this.isBeingDestroyed()||(p.the.register(t,i),i.once("destroy",()=>{p.the.hasItem(t)&&p.the.unregister(t)}))}catch(i){this.editorPromise=null,p.the.error(t,i)}return this}async destroyed(){this.el.style.display="none",this.sentinel?.destroy(),this.sentinel=null;try{const t=await this.editorPromise;if(!t)return;const e=K(t),i=Z(t);e?e.state!=="unavailable"&&await e.context.remove(e.editorContextId):i?await i.destroy():await t.destroy()}finally{this.editorPromise=null}}async createEditor(){const{preset:t,editorId:e,contextId:i,editableHeight:n,events:s,saveDebounceMs:o,language:u,watchdog:c}=this.attrs,{customTranslations:l,type:d,license:h,config:{plugins:w,...f}}=t;let b=await kt(d);const y=await(i?g.the.waitFor(i):Dt(this.el));if(c&&!y){const m=await At(b);({Constructor:b}=m),m.watchdog.on("restart",()=>{const k=m.watchdog.editor;this.editorPromise=Promise.resolve(k),p.the.register(e,k)})}const{loadedPlugins:E,hasPremium:rt}=await Y(w);P(d)&&E.push(await Vt({editorId:e,saveDebounceMs:o})),E.push(...await Promise.all([$t({editorId:e,saveDebounceMs:o,events:s,pushEvent:this.pushEvent.bind(this),handleEvent:this.handleEvent.bind(this)}),Ut()]));const S=[...await J(u,rt),G(l?.dictionary||{})].filter(m=>!L(m));let v=F(e);P(d)&&(v=v.main||"");const M=await(async()=>{let m=X(e);if(!(m instanceof HTMLElement)&&!("main"in m)){const H=d==="decoupled"?["main"]:Object.keys(v);et(m,H)||(m=await Ft(e,H),v=F(e))}P(d)&&"main"in m&&(m=m.main);let k=T(f);k=x([...S].reverse(),u.ui,k);const j={...k,initialData:v,licenseKey:h.key,plugins:E,language:u,...S.length&&{translations:S}};return!y||!(m instanceof HTMLElement)?b.create(m,j):(await yt({context:y,element:m,creator:b,config:j})).editor})();return P(d)&&n&&Ct(M,n),M}}function et(a,t){return t.every(e=>a[e])}async function Ft(a,t){return gt(()=>{const e=X(a);if(!et(e,t))throw new Error(`It looks like not all required root elements are present yet.
2
2
  * If you want to wait for them, ensure they are registered before editor initialization.
3
3
  * If you want lazy initialize roots, consider removing root values from the \`initialData\` config and assign initial data in editable components.
4
- Missing roots: ${t.filter(i=>!e[i]).join(", ")}.`);return e},{timeOutAfter:2e3,retryAfter:100})}const Ht=C(jt);function zt(a,t){const e=new Set;return i=>{a.model.enqueueChange({isUndoable:!1},n=>{const o=a.model.document.getRoot(t);if(o){for(const s of e)i&&s in i||(n.removeAttribute(s,o),e.delete(s));for(const[s,u]of Object.entries(i??{}))n.setAttribute(s,u,o),e.add(s)}})}}class Nt extends P{editorPromise=null;pendingValue=null;previousValue=null;attrsUpdater=null;get attrs(){return{editorId:this.el.getAttribute("data-cke-editor-id"),rootName:this.el.getAttribute("data-cke-root-name"),rootAttributes:mt(this.el.getAttribute("data-cke-root-attrs")),value:this.el.getAttribute("data-cke-value")}}async mounted(){const{editorId:t,value:e,rootName:i}=this.attrs;this.previousValue=e,this.editorPromise=p.the.execute(t,n=>this.isBeingDestroyed()?null:(this.setupSyncHandlers(n,i),n))}async updated(){const{rootName:t,value:e,rootAttributes:i}=this.attrs,n=await this.editorPromise;!n||n.state==="destroyed"||(this.attrsUpdater?.(i),e!==this.previousValue&&(this.previousValue=e,n.ui.focusTracker.isFocused?this.pendingValue=e:this.setRootValue(n,t,e)))}setupSyncHandlers(t,e){this.attrsUpdater=zt(t,e),this.attrsUpdater(this.attrs.rootAttributes);const i=()=>{this.pendingValue=null},n=()=>{!t.ui.focusTracker.isFocused&&this.pendingValue!==null&&(this.setRootValue(t,e,this.pendingValue),this.pendingValue=null)};t.model.document.on("change:data",i),t.ui.focusTracker.on("change:isFocused",n),this.onBeforeDestroy(()=>{t.model.document.off("change:data",i),t.ui.focusTracker.off("change:isFocused",n)})}setRootValue(t,e,i){t.getData({rootName:e})!==i&&t.setData({[e]:i})}}const qt=C(Nt);class Ft extends P{mountedPromise=null;get attrs(){const t={editorId:this.el.getAttribute("data-cke-editor-id")||null,name:this.el.getAttribute("data-cke-ui-part-name")};return Object.defineProperty(this,"attrs",{value:t,writable:!1,configurable:!1,enumerable:!0}),t}async mounted(){const{editorId:t,name:e}=this.attrs;this.mountedPromise=p.the.execute(t,i=>{if(this.isBeingDestroyed())return;const{ui:n}=i,o=Wt(e),s=n.view[o];if(!s){console.error(`Unknown UI part name: "${e}". Supported names are "toolbar" and "menubar".`);return}this.el.appendChild(s.element)})}async destroyed(){this.el.style.display="none",await this.mountedPromise,this.mountedPromise=null,this.el.innerHTML=""}}function Wt(a){switch(a){case"toolbar":return"toolbar";case"menubar":return"menuBarView";default:return null}}const _t=C(Ft),Bt={CKEditor5:Ht,CKEditable:Dt,CKUIPart:_t,CKContext:xt,CKRootValueSentinel:qt};exports.ContextsRegistry=g;exports.CustomEditorPluginsRegistry=O;exports.EditorsRegistry=p;exports.Hooks=Bt;exports.unwrapEditorContext=K;exports.unwrapEditorWatchdog=Q;
4
+ Missing roots: ${t.filter(i=>!e[i]).join(", ")}.`);return e},{timeOutAfter:2e3,retryAfter:100})}const Wt=O(qt);class Bt extends I{mountedPromise=null;get attrs(){const t={editorId:this.el.getAttribute("data-cke-editor-id")||null,name:this.el.getAttribute("data-cke-ui-part-name")};return Object.defineProperty(this,"attrs",{value:t,writable:!1,configurable:!1,enumerable:!0}),t}async mounted(){const{editorId:t,name:e}=this.attrs;this.mountedPromise=p.the.execute(t,i=>{if(this.isBeingDestroyed())return;const{ui:n}=i,s=Lt(e),o=n.view[s];if(!o){console.error(`Unknown UI part name: "${e}". Supported names are "toolbar" and "menubar".`);return}this.el.appendChild(o.element)})}async destroyed(){this.el.style.display="none",await this.mountedPromise,this.mountedPromise=null,this.el.innerHTML=""}}function Lt(a){switch(a){case"toolbar":return"toolbar";case"menubar":return"menuBarView";default:return null}}const Kt=O(Bt),Yt={CKEditor5:Wt,CKEditable:zt,CKUIPart:Kt,CKContext:St};exports.ContextsRegistry=g;exports.CustomEditorPluginsRegistry=D;exports.EditorsRegistry=p;exports.Hooks=Yt;exports.unwrapEditorContext=K;exports.unwrapEditorWatchdog=Z;
5
5
  //# sourceMappingURL=index.cjs.map