best-email-builder 0.2.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +186 -0
- package/README.md +309 -12
- package/dist/builder.js +44 -0
- package/dist/builder.js.map +1 -0
- package/dist/chunk-AT73Y7JA.js +1427 -0
- package/dist/chunk-AT73Y7JA.js.map +1 -0
- package/dist/chunk-HHLOE6OZ.js +1682 -0
- package/dist/chunk-HHLOE6OZ.js.map +1 -0
- package/dist/chunk-JNHFZXDL.js +1776 -0
- package/dist/chunk-JNHFZXDL.js.map +1 -0
- package/dist/chunk-MY6WPDT4.js +6110 -0
- package/dist/chunk-MY6WPDT4.js.map +1 -0
- package/dist/chunk-NAEGU6PR.js +538 -0
- package/dist/chunk-NAEGU6PR.js.map +1 -0
- package/dist/chunk-TGDZ4NFI.js +114 -0
- package/dist/chunk-TGDZ4NFI.js.map +1 -0
- package/dist/index.js +124 -4866
- package/dist/index.js.map +1 -1
- package/dist/library.js +31 -0
- package/dist/library.js.map +1 -0
- package/dist/server.js +554 -210
- package/dist/server.js.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/types/blocks/shared.d.ts +20 -0
- package/dist/types/builder.d.ts +8 -0
- package/dist/types/core/EmailEditor.d.ts +72 -19
- package/dist/types/core/constants.d.ts +1 -1
- package/dist/types/core/mjmlDefaults.d.ts +13 -0
- package/dist/types/core/scrollbars.d.ts +13 -0
- package/dist/types/defaultEditor.d.ts +11 -0
- package/dist/types/engine/NativeAdapter.d.ts +28 -0
- package/dist/types/engine/canvas/CanvasView.d.ts +88 -0
- package/dist/types/engine/canvas/canvasStyles.d.ts +3 -0
- package/dist/types/engine/canvas/icons.d.ts +14 -0
- package/dist/types/engine/canvas/morph.d.ts +21 -0
- package/dist/types/engine/canvasMjml.d.ts +30 -0
- package/dist/types/engine/mjml.d.ts +31 -0
- package/dist/types/engine/model.d.ts +130 -0
- package/dist/types/engine/placement.d.ts +69 -0
- package/dist/types/engine/richText.d.ts +15 -0
- package/dist/types/engine/unwrapModule.d.ts +29 -0
- package/dist/types/features/brand/BrandButton.d.ts +4 -0
- package/dist/types/features/brand/brand.d.ts +108 -0
- package/dist/types/features/brand/extract.d.ts +61 -0
- package/dist/types/features/brand/index.d.ts +2 -0
- package/dist/types/features/brand/messages.d.ts +13 -0
- package/dist/types/features/brand/useBrand.d.ts +22 -0
- package/dist/types/features/generate/GenerateButton.d.ts +3 -0
- package/dist/types/features/generate/RewriteText.d.ts +5 -0
- package/dist/types/features/generate/SubjectIdeas.d.ts +16 -0
- package/dist/types/features/generate/chip.d.ts +1 -0
- package/dist/types/features/generate/claude.d.ts +21 -0
- package/dist/types/features/generate/draft.d.ts +122 -0
- package/dist/types/features/generate/generator.d.ts +118 -0
- package/dist/types/features/generate/index.d.ts +2 -0
- package/dist/types/features/generate/prompt.d.ts +76 -0
- package/dist/types/features/generate/purposes.d.ts +48 -0
- package/dist/types/features/generate/rewrite.d.ts +83 -0
- package/dist/types/features/generate/subjects.d.ts +83 -0
- package/dist/types/features/preview/PreviewButton.d.ts +1 -1
- package/dist/types/features/preview/darkMode.d.ts +48 -0
- package/dist/types/features/templates/gallery.d.ts +7 -0
- package/dist/types/index.d.ts +14 -10
- package/dist/types/library.d.ts +5 -0
- package/dist/types/server/brand.d.ts +32 -0
- package/dist/types/server/brandImport.d.ts +93 -0
- package/dist/types/server/compileMjml.d.ts +2 -0
- package/dist/types/server/handler.d.ts +25 -0
- package/dist/types/server/index.d.ts +11 -0
- package/dist/types/storage/client.d.ts +79 -3
- package/dist/types/ui/EmailStudio.d.ts +42 -0
- package/dist/types/ui/fields.d.ts +2 -1
- package/dist/types/ui/library/TemplateLibrary.d.ts +41 -0
- package/dist/types/ui/primitives/button.d.ts +2 -2
- package/dist/types/ui/primitives/color-picker.d.ts +2 -1
- package/dist/types/ui/useLayoutWidth.d.ts +1 -1
- package/package.json +27 -4
- package/dist/chunk-MTALS5GC.js +0 -747
- package/dist/chunk-MTALS5GC.js.map +0 -1
- package/dist/types/adapters/grapesjs/GrapesJsAdapter.d.ts +0 -33
- package/dist/types/adapters/grapesjs/engineConfig.d.ts +0 -162
- package/dist/types/adapters/grapesjs/unwrapModule.d.ts +0 -18
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/events.js","../src/core/mjmlDefaults.js","../src/core/EmailEditor.js","../src/core/registry.js","../src/blocks/structure/index.js","../src/blocks/text/index.js","../src/blocks/image/index.js","../src/blocks/button/index.js","../src/blocks/divider/index.js","../src/blocks/spacer/index.js","../src/blocks/heading/index.js","../src/blocks/navbar/index.js","../src/blocks/hero/index.js","../src/blocks/columns/index.js","../src/blocks/index.js","../src/features/autosave/index.js","../src/features/versions/VersionsMenu.jsx","../src/features/versions/index.js","../src/features/variables/VariablesMenu.jsx","../src/features/variables/VariableDialog.jsx","../src/features/variables/VariablePicker.jsx","../src/features/variables/index.js","../src/features/preview/index.js","../src/features/test-email/TestEmailButton.jsx","../src/features/test-email/index.js","../src/features/templates/TemplateGallery.jsx","../src/features/templates/index.js","../src/features/generate/GenerateButton.jsx","../src/features/generate/chip.js","../src/features/generate/index.js","../src/features/brand/BrandButton.jsx","../src/ui/primitives/color-picker.jsx","../src/features/brand/index.js","../src/features/index.js","../src/engine/placement.js","../src/engine/richText.js","../src/engine/canvasMjml.js","../src/engine/canvas/morph.js","../src/engine/canvas/canvasStyles.js","../src/engine/canvas/icons.js","../src/engine/canvas/CanvasView.js","../src/engine/unwrapModule.js","../src/engine/NativeAdapter.js","../src/defaultEditor.js","../src/ui/EmailCanvas.jsx","../src/ui/EmailBuilder.jsx","../src/features/autosave/scheduler.js","../src/features/autosave/localDraft.js","../src/ui/BlockSidebar.jsx","../src/ui/ElementActions.jsx","../src/ui/PropertiesPanel.jsx","../src/ui/fields.jsx","../src/features/variables/VariableInsertButton.jsx","../src/features/generate/RewriteText.jsx","../src/features/generate/SubjectIdeas.jsx","../src/ui/Toolbar.jsx","../src/ui/Drawer.jsx","../src/ui/useEmailEditorState.js","../src/ui/EmailBuilderBoundary.jsx"],"sourcesContent":["// @ts-check\n/**\n * Minimal, dependency-free event emitter.\n *\n * A throwing listener does not prevent the next ones from running: the error\n * goes to `onError` (the console by default). A UI listening to the selection\n * must not break the history because one panel crashed.\n */\n\n/**\n * @typedef {(payload?: any) => void} Listener\n * @typedef {{\n * on: (event: string, listener: Listener) => () => void,\n * off: (event: string, listener: Listener) => void,\n * emit: (event: string, payload?: any) => void,\n * clear: () => void,\n * }} Emitter\n */\n\n/**\n * @param {{onError?: (error: unknown, event: string) => void}} [options]\n * @returns {Emitter}\n */\nexport function createEmitter({ onError } = {}) {\n /** @type {Map<string, Set<Listener>>} */\n const listeners = new Map();\n const report =\n onError ||\n ((error, event) => {\n console.warn(`[best-email-builder] listener for \"${event}\" failed`, error);\n });\n\n /** @param {string} event @param {Listener} listener */\n function off(event, listener) {\n listeners.get(event)?.delete(listener);\n }\n\n return {\n on(event, listener) {\n if (!listeners.has(event)) listeners.set(event, new Set());\n listeners.get(event)?.add(listener);\n return () => off(event, listener);\n },\n off,\n emit(event, payload) {\n for (const listener of [...(listeners.get(event) || [])]) {\n try {\n listener(payload);\n } catch (error) {\n report(error, event);\n }\n }\n },\n clear() {\n listeners.clear();\n },\n };\n}\n","// @ts-check\n/**\n * MJML DEFAULTS — what MJML 5 renders when an attribute is not written.\n *\n * The properties panel shows them, greyed, in empty fields: an empty\n * \"Padding\" of a section is not \"0\" — MJML gives it 20 px above and below,\n * and the panel must say so (and start from there when one side is edited).\n *\n * Copied from the `defaultAttributes` of the mjml 5 components (the same\n * version the server and the canvas compile with); the unit tests check them\n * against the installed components.\n */\n\n/** @type {Record<string, Record<string, string>>} */\nexport const MJML_DEFAULTS = {\n 'mj-body': { width: '600px' },\n 'mj-section': {\n 'background-repeat': 'repeat',\n 'background-size': 'auto',\n 'background-position': 'top center',\n padding: '20px 0',\n 'text-align': 'center',\n },\n 'mj-wrapper': { 'background-repeat': 'repeat', 'background-size': 'auto', 'background-position': 'top center', padding: '20px 0' },\n 'mj-column': { 'vertical-align': 'top' },\n 'mj-text': {\n align: 'left',\n color: '#000000',\n 'font-family': 'Ubuntu, Helvetica, Arial, sans-serif',\n 'font-size': '13px',\n 'line-height': '1',\n padding: '10px 25px',\n },\n 'mj-image': { align: 'center', height: 'auto', padding: '10px 25px' },\n 'mj-button': {\n align: 'center',\n 'background-color': '#414141',\n 'border-radius': '3px',\n color: '#ffffff',\n 'font-family': 'Ubuntu, Helvetica, Arial, sans-serif',\n 'font-size': '13px',\n 'font-weight': 'normal',\n 'inner-padding': '10px 25px',\n 'line-height': '120%',\n padding: '10px 25px',\n },\n 'mj-divider': { 'border-color': '#000000', 'border-style': 'solid', 'border-width': '4px', padding: '10px 25px', width: '100%', align: 'center' },\n 'mj-spacer': { height: '20px' },\n 'mj-social': {\n align: 'center',\n 'border-radius': '3px',\n 'icon-size': '20px',\n mode: 'horizontal',\n padding: '10px 25px',\n },\n 'mj-social-element': { 'border-radius': '3px', padding: '4px' },\n 'mj-navbar': { align: 'center' },\n 'mj-navbar-link': {\n color: '#000000',\n 'font-family': 'Ubuntu, Helvetica, Arial, sans-serif',\n 'font-size': '13px',\n 'font-weight': 'normal',\n 'line-height': '22px',\n padding: '15px 10px',\n 'text-transform': 'uppercase',\n },\n 'mj-hero': { 'background-color': '#ffffff', padding: '0px' },\n};\n","// @ts-check\n/**\n * EmailEditor — THE email builder contract.\n *\n * ── THE ARCHITECTURE RULE ──────────────────────────────────────────────────\n *\n * React UI ─► EmailEditor ─► adapter ─► engine (engine/) ─► MJML\n *\n * The UI (`ui/`), features (`features/`) and blocks (`blocks/`) talk ONLY to\n * this object. None of them knows the canvas or the model: everything\n * engine-related lives in `engine/`. Swapping the engine therefore means\n * writing another adapter that fulfils `EmailEditorAdapter`, rewriting\n * nothing above it.\n *\n * ── WHAT THIS LAYER ADDS TO THE ADAPTER ────────────────────────────────────\n * - the lifecycle (idle → initializing → ready → idle), and a hard refusal\n * of any call made before `initialize` or after `destroy`;\n * - resolving blocks by id in the registry, with their texts translated;\n * - naming elements (a section is named after its layout: \"2 columns\");\n * - the versioned document envelope (`core/document.js`);\n * - starting and stopping registered features.\n *\n * See `docs/ARCHITECTURE.md`.\n */\n\nimport { createEmitter } from './events.js';\nimport { EMAIL_DEVICES } from './constants.js';\nimport { createDocument, readDocument } from './document.js';\nimport { LONGHAND_SPACING, toAttributes, toValues } from './mjmlAttributes.js';\nimport { MJML_DEFAULTS } from './mjmlDefaults.js';\nimport { identity } from '../i18n/index.js';\nimport { applyBrandToFragment } from '../features/brand/brand.js';\n\n/**\n * @typedef {import('./constants.js').EmailDevice} EmailDevice\n * @typedef {import('./document.js').EmailDocument} EmailDocument\n */\n\n/**\n * Editable block property, as shown in the right-hand panel. The key is an\n * MJML ATTRIBUTE (`color`, `padding`, `href`…) — the email's language, not\n * the engine's.\n *\n * @typedef {{\n * key: string,\n * label: string,\n * type: 'text'|'textarea'|'color'|'size'|'select'|'align'|'url'|'image'|'spacing',\n * group: string,\n * options?: {value: string, label: string}[],\n * placeholder?: string,\n * min?: number,\n * max?: number,\n * unit?: string,\n * }} BlockProperty\n */\n\n/**\n * Builder block.\n *\n * `content` : an element (text, image, button…) that lives INSIDE a column;\n * `layout` : an N-column section, living in the email body;\n * `structure` : body, section, column — selectable, not addable.\n *\n * `mjml` is the inserted fragment; `sectionMjml` the same wrapped in a\n * section, for when it must go outside any column. Either may be a function\n * of the translator, so the texts a block brings arrive in the interface's\n * language; `tagName` identifies the\n * block of a selected element (`mj-text` → text).\n * `editableContent`: the content is editable (canvas for text, panel for a\n * button label).\n * `insertOnly`: a preset of another block's element (a Heading is an\n * `mj-text`): offered in the sidebar, but a selected element of that tag is\n * described by the main block.\n *\n * @typedef {{\n * id: string,\n * label: string,\n * description?: string,\n * icon: string,\n * kind: 'content'|'layout'|'structure',\n * tagName: string,\n * order?: number,\n * mjml?: string | ((t: import('../i18n/index.js').Translate) => string),\n * sectionMjml?: string | ((t: import('../i18n/index.js').Translate) => string),\n * properties: BlockProperty[],\n * editableContent?: boolean,\n * insertOnly?: boolean,\n * }} EmailBlock\n */\n\n/**\n * Selected element as described by the ENGINE: MJML tag and raw attributes,\n * nothing more.\n *\n * @typedef {{\n * id: string,\n * tagName: string,\n * attributes: Record<string, string>,\n * content: string|null,\n * html?: string|null,\n * canRemove: boolean,\n * canDuplicate: boolean,\n * canMoveUp: boolean,\n * canMoveDown: boolean,\n * columnCount?: number,\n * multiple?: number,\n * }} EngineSelection\n * `content`: the label of a button or a menu link, as plain text.\n * `html`: the HTML of a text (`mj-text`), as stored.\n * `columnCount`: for a section, how many columns it holds (its name).\n * `multiple`: the whole email is selected (Ctrl+A) — how many sections;\n * the selection is then described as the body, and only removal applies.\n */\n\n/**\n * Selected element, in the builder's vocabulary: its block, its property\n * values (padding recombined, see mjmlAttributes) and, for the properties left\n * empty, what MJML renders instead (`defaults`, see mjmlDefaults).\n *\n * @typedef {EngineSelection & {\n * blockId: string|null,\n * label: string,\n * values: Record<string, string>,\n * defaults: Record<string, string>,\n * }} EmailSelection\n */\n\n/**\n * @typedef {{html: string, errors: {line?: number, message: string, tagName?: string}[]}} HtmlExport\n */\n\n/**\n * What an engine must provide. All element ids are opaque strings returned by\n * the adapter itself.\n *\n * Events emitted through `onEvent(type, payload)`:\n * `change` the document changed (typing, add, remove, undo…)\n * `load` a whole document was just loaded — NOT a modification: the\n * host screen decides whether it needs saving\n * `selection` the selection changed — payload: EngineSelection|null\n * `history` undo/redo state changed — payload: {canUndo, canRedo}\n * `device` the displayed device changed — payload: EmailDevice\n *\n * @typedef {{\n * name: string,\n * version: string,\n * initialize: (options: {\n * container: HTMLElement,\n * blocks: EmailBlock[],\n * document: EmailDocument|null,\n * onEvent: (type: string, payload?: any) => void,\n * t?: import('../i18n/index.js').Translate,\n * labelOf?: (selection: EngineSelection) => string,\n * }) => Promise<void>,\n * destroy: () => void,\n * addBlock: (block: EmailBlock, options?: {targetId?: string|null}) => string|null,\n * remove: (id: string) => boolean,\n * duplicate: (id: string) => string|null,\n * move: (id: string, direction: -1|1) => boolean,\n * select: (id: string|null) => void,\n * getSelection: () => EngineSelection|null,\n * describe: (id: string) => EngineSelection|null,\n * getRootId: () => string|null,\n * updateProperties: (id: string, attributes: Record<string, string|null>) => void,\n * setContent: (id: string, content: string) => void,\n * insertText: (text: string) => boolean,\n * insertLink: (href: string, label: string) => boolean,\n * undo: () => void,\n * redo: () => void,\n * canUndo: () => boolean,\n * canRedo: () => boolean,\n * clearHistory: () => void,\n * getProject: () => object,\n * loadProject: (project: object) => void,\n * loadMjml: (mjml: string) => void,\n * setMjml?: (mjml: string) => void,\n * exportMjml: () => string,\n * exportHtml: (mjml?: string|null) => Promise<HtmlExport>,\n * setDevice: (device: EmailDevice) => void,\n * getDevice: () => EmailDevice,\n * startBlockDrag: (block: EmailBlock, event: Event) => void,\n * endBlockDrag: (cancel?: boolean) => void,\n * addShortcut: (id: string, keys: string, handler: () => void) => (() => void),\n * selectAll?: () => void,\n * }} EmailEditorAdapter\n */\n\n/**\n * Pluggable feature. `setup` receives the ready editor and may return a\n * teardown function, called on `destroy`. `toolbar`: React component placed in\n * the toolbar (it receives the screen context); `options`: its settings, read\n * by the screen; `isAvailable(context)`: hides the toolbar entry when the\n * context cannot support it (e.g. a storage that cannot render).\n *\n * @typedef {{\n * id: string,\n * label?: string,\n * order?: number,\n * enabled?: boolean,\n * setup?: (editor: EmailEditor) => (void | (() => void)),\n * toolbar?: any,\n * isAvailable?: (context: any) => boolean,\n * options?: Record<string, any>,\n * }} EmailBuilderFeature\n */\n\n/**\n * @typedef {'idle'|'initializing'|'ready'} EmailEditorStatus\n */\n\n/**\n * @typedef {{\n * readonly status: EmailEditorStatus,\n * readonly adapterName: string,\n * initialize: (options: {container: HTMLElement, document?: EmailDocument|null}) => Promise<void>,\n * destroy: () => void,\n * listBlocks: () => EmailBlock[],\n * getBlock: (blockId: string) => EmailBlock|undefined,\n * addBlock: (blockId: string, options?: {targetId?: string|null}) => string|null,\n * remove: (id?: string|null) => boolean,\n * duplicate: (id?: string|null) => string|null,\n * move: (direction: -1|1, id?: string|null) => boolean,\n * select: (id: string|null) => void,\n * selectAll: () => void,\n * getSelection: () => EmailSelection|null,\n * getElement: (id: string) => EmailSelection|null,\n * getRootId: () => string|null,\n * updateProperties: (values: Record<string, string|null>, id?: string|null) => void,\n * setContent: (content: string, id?: string|null) => void,\n * insertText: (text: string) => boolean,\n * insertLink: (href: string, label: string) => boolean,\n * undo: () => void,\n * redo: () => void,\n * canUndo: () => boolean,\n * canRedo: () => boolean,\n * getDocument: () => EmailDocument,\n * loadDocument: (document: unknown, options?: {mjml?: string|null}) => void,\n * loadMjml: (mjml: string) => void,\n * setMjml: (mjml: string) => void,\n * exportMjml: () => string,\n * exportHtml: (mjml?: string|null) => Promise<HtmlExport>,\n * setBrand: (brand: import('../features/brand/brand.js').Brand|null) => void,\n * setDevice: (device: EmailDevice) => void,\n * getDevice: () => EmailDevice,\n * startBlockDrag: (blockId: string, event: Event) => void,\n * endBlockDrag: (cancel?: boolean) => void,\n * addShortcut: (id: string, keys: string, handler: () => void) => (() => void),\n * on: (event: string, listener: (payload?: any) => void) => () => void,\n * }} EmailEditor\n */\n\n/**\n * A block with its MJML (and section MJML) as strings, its texts in the\n * translator's language.\n * @param {EmailBlock} block\n * @param {import('../i18n/index.js').Translate} [t]\n * @returns {EmailBlock & {mjml?: string, sectionMjml?: string}}\n */\nexport function resolveBlock(block, t = identity) {\n const text = (/** @type {any} */ value) => (typeof value === 'function' ? String(value(t)) : value);\n return { ...block, mjml: text(block.mjml), sectionMjml: text(block.sectionMjml) };\n}\n\n/**\n * @param {{\n * adapter: EmailEditorAdapter,\n * blocks: import('./registry.js').Registry<EmailBlock>,\n * features?: import('./registry.js').Registry<EmailBuilderFeature> | null,\n * t?: import('../i18n/index.js').Translate,\n * }} options\n * `t`: the interface's translator — texts of inserted blocks, names shown\n * in the canvas.\n * @returns {EmailEditor}\n */\nexport function createEmailEditor({ adapter, blocks, features = null, t = identity }) {\n if (!adapter) throw new Error('EmailEditor: missing adapter');\n if (!blocks) throw new Error('EmailEditor: missing block registry');\n\n const emitter = createEmitter();\n /** @type {EmailEditorStatus} */\n let status = 'idle';\n /** Token of the pending initialization: a `destroy` invalidates it. */\n let generation = 0;\n /** @type {(() => void)[]} */\n let teardowns = [];\n\n function requireReady(action) {\n if (status !== 'ready') {\n throw new Error(`EmailEditor: \"${action}\" called before the editor was initialized`);\n }\n }\n\n /** @param {string|null|undefined} id */\n function targetOf(id, action) {\n const resolved = id ?? adapter.getSelection()?.id ?? null;\n if (!resolved) throw new Error(`EmailEditor: \"${action}\" with no selected element`);\n return resolved;\n }\n\n /**\n * Block describing a tag: structure first (a section stays a section),\n * presets (`insertOnly`) never.\n */\n function blockForTag(tagName) {\n const all = blocks.list((b) => !b.insertOnly);\n return (\n all.find((b) => b.tagName === tagName && b.kind === 'structure') ||\n all.find((b) => b.tagName === tagName) ||\n null\n );\n }\n\n /**\n * Name of an element: its block's, and for a section the layout it was\n * made from (\"2 columns\"), counted from its columns.\n * @param {EngineSelection} selection @param {EmailBlock|null} block\n */\n function labelFor(selection, block) {\n if (selection.multiple) return 'All blocks';\n if (selection.tagName === 'mj-section' && typeof selection.columnCount === 'number') {\n const layout = blocks.get(`columns-${selection.columnCount}`);\n if (layout) return layout.label;\n }\n return block?.label || selection.tagName;\n }\n\n /**\n * Property values, and MJML's defaults for the empty ones. A padding set\n * on some sides only is completed with MJML's default for the others (a\n * text with only left and right paddings still gets 10 px above and below).\n * @param {EngineSelection} selection @param {EmailBlock|null} block\n */\n function valuesOf(selection, block) {\n const properties = block?.properties || [];\n const attributes = selection.attributes || {};\n const fallback = MJML_DEFAULTS[selection.tagName] || {};\n const values = toValues(attributes, properties);\n for (const property of properties) {\n if (LONGHAND_SPACING.has(property.key) && values[property.key]) {\n values[property.key] = toValues({ ...fallback, ...attributes }, [property])[property.key];\n }\n }\n return { values, defaults: toValues(fallback, properties) };\n }\n\n /** @param {EngineSelection|null} selection @returns {EmailSelection|null} */\n function toEmailSelection(selection) {\n if (!selection) return null;\n const block = blockForTag(selection.tagName);\n return {\n ...selection,\n blockId: block?.id || null,\n label: labelFor(selection, block),\n ...valuesOf(selection, block),\n };\n }\n\n /** The brand new blocks are painted in (setBrand). */\n /** @type {import('../features/brand/brand.js').Brand|null} */\n let brand = null;\n\n /** @param {EmailBlock} block */\n const resolved = (block) => {\n const result = resolveBlock(block, t);\n if (!brand) return result;\n return {\n ...result,\n mjml: result.mjml && applyBrandToFragment(result.mjml, brand),\n sectionMjml: result.sectionMjml && applyBrandToFragment(result.sectionMjml, brand),\n };\n };\n\n function startFeatures() {\n if (!features) return;\n for (const feature of features.list((f) => f.enabled !== false)) {\n try {\n const stop = feature.setup?.(editor);\n if (typeof stop === 'function') teardowns.push(stop);\n } catch (error) {\n // A broken feature must not prevent editing.\n console.warn(`[best-email-builder] feature \"${feature.id}\" failed`, error);\n }\n }\n }\n\n function stopFeatures() {\n for (const stop of teardowns.reverse()) {\n try {\n stop();\n } catch (error) {\n console.warn('[best-email-builder] feature teardown failed', error);\n }\n }\n teardowns = [];\n }\n\n /** @type {EmailEditor} */\n const editor = {\n get status() {\n return status;\n },\n get adapterName() {\n return adapter.name;\n },\n\n async initialize({ container, document = null }) {\n if (!container) throw new Error('EmailEditor: missing container');\n if (status !== 'idle') {\n throw new Error(`EmailEditor: initialization refused (status \"${status}\")`);\n }\n const ticket = ++generation;\n status = 'initializing';\n try {\n await adapter.initialize({\n container,\n blocks: blocks.list(),\n document: document ? readDocument(document) : null,\n t,\n labelOf: (selection) => t(labelFor(selection, blockForTag(selection.tagName))),\n onEvent: (type, payload) => {\n if (ticket !== generation) return;\n emitter.emit(type, type === 'selection' ? toEmailSelection(payload) : payload);\n },\n });\n } catch (error) {\n if (ticket === generation) status = 'idle';\n throw error;\n }\n // Destroyed while the engine was loading (React unmount, StrictMode):\n // the adapter is already released, nothing is declared ready.\n if (ticket !== generation) return;\n status = 'ready';\n startFeatures();\n emitter.emit('ready');\n },\n\n destroy() {\n generation += 1;\n stopFeatures();\n const etait = status;\n status = 'idle';\n adapter.destroy();\n if (etait === 'ready') emitter.emit('destroy');\n },\n\n listBlocks: () => blocks.list(),\n getBlock: (blockId) => blocks.get(blockId),\n\n addBlock(blockId, options = {}) {\n requireReady('addBlock');\n const block = blocks.get(blockId);\n if (!block || !block.mjml) throw new Error(`EmailEditor: unknown block \"${blockId}\"`);\n return adapter.addBlock(resolved(block), options);\n },\n\n remove(id = null) {\n requireReady('remove');\n return adapter.remove(targetOf(id, 'remove'));\n },\n\n duplicate(id = null) {\n requireReady('duplicate');\n return adapter.duplicate(targetOf(id, 'duplicate'));\n },\n\n move(direction, id = null) {\n requireReady('move');\n if (direction !== -1 && direction !== 1) throw new Error('EmailEditor: invalid move direction');\n return adapter.move(targetOf(id, 'move'), direction);\n },\n\n select(id) {\n requireReady('select');\n adapter.select(id);\n },\n\n /** Every section of the email at once (Ctrl+A); Delete then empties it. */\n selectAll() {\n requireReady('selectAll');\n adapter.selectAll?.();\n },\n\n getSelection() {\n return status === 'ready' ? toEmailSelection(adapter.getSelection()) : null;\n },\n\n getElement(id) {\n return status === 'ready' && id ? toEmailSelection(adapter.describe(id)) : null;\n },\n\n /** The email body: page background and width, edited without a selection. */\n getRootId: () => (status === 'ready' ? adapter.getRootId() : null),\n\n updateProperties(values, id = null) {\n requireReady('updateProperties');\n adapter.updateProperties(targetOf(id, 'updateProperties'), toAttributes(values));\n },\n\n setContent(content, id = null) {\n requireReady('setContent');\n adapter.setContent(targetOf(id, 'setContent'), content);\n },\n\n insertText(text) {\n requireReady('insertText');\n return adapter.insertText(String(text ?? ''));\n },\n\n /**\n * Link at the caret of the text being edited, at the end of the selected\n * text, or as the selected button's URL. False if nothing fits.\n */\n insertLink(href, label) {\n requireReady('insertLink');\n return adapter.insertLink(String(href || ''), String(label || href || ''));\n },\n\n undo() {\n requireReady('undo');\n adapter.undo();\n },\n redo() {\n requireReady('redo');\n adapter.redo();\n },\n canUndo: () => status === 'ready' && adapter.canUndo(),\n canRedo: () => status === 'ready' && adapter.canRedo(),\n\n getDocument() {\n requireReady('getDocument');\n return createDocument({\n engine: adapter.name,\n engineVersion: adapter.version,\n project: adapter.getProject(),\n });\n },\n\n /**\n * A stored document. One written by another engine (a template saved\n * before the builder had its own) cannot be read as a project: it is\n * opened from its MJML when `options.mjml` gives it, refused otherwise.\n */\n loadDocument(raw, { mjml = null } = {}) {\n requireReady('loadDocument');\n const document = readDocument(raw);\n if (document.engine !== adapter.name) {\n if (mjml) {\n adapter.loadMjml(String(mjml));\n adapter.clearHistory();\n return;\n }\n throw new Error(\n `EmailEditor: document written for engine \"${document.engine}\", ` +\n `editor runs on \"${adapter.name}\"`\n );\n }\n adapter.loadProject(document.project);\n // A reloaded document has no history: undo must not bring back the\n // state before the load.\n adapter.clearHistory();\n },\n\n loadMjml(mjml) {\n requireReady('loadMjml');\n adapter.loadMjml(String(mjml || ''));\n adapter.clearHistory();\n },\n\n /** Replaces the whole email as ONE step: Ctrl+Z brings the previous one back. */\n setMjml(mjml) {\n requireReady('setMjml');\n if (adapter.setMjml) adapter.setMjml(String(mjml || ''));\n else adapter.loadMjml(String(mjml || ''));\n },\n\n /** Blocks inserted from now on take the brand's colors and font (null: the builder's own). */\n setBrand(value) {\n brand = value && Object.keys(value).length ? { ...value } : null;\n },\n\n exportMjml() {\n requireReady('exportMjml');\n return adapter.exportMjml();\n },\n\n /**\n * The email (or the given MJML) compiled by the CANVAS compiler — for\n * display only (thumbnails, inspection). The HTML that is stored and sent\n * is always compiled by the server. Asynchronous: MJML 5 compiles\n * asynchronously.\n */\n exportHtml(mjml = null) {\n requireReady('exportHtml');\n return adapter.exportHtml(mjml === null || mjml === undefined ? null : String(mjml));\n },\n\n setDevice(device) {\n requireReady('setDevice');\n if (!EMAIL_DEVICES.includes(device)) throw new Error(`EmailEditor: unknown device \"${device}\"`);\n adapter.setDevice(device);\n },\n\n getDevice: () => (status === 'ready' ? adapter.getDevice() : 'desktop'),\n\n startBlockDrag(blockId, event) {\n requireReady('startBlockDrag');\n const block = blocks.get(blockId);\n if (!block || !block.mjml) throw new Error(`EmailEditor: unknown block \"${blockId}\"`);\n adapter.startBlockDrag(resolved(block), event);\n },\n\n endBlockDrag(cancel = false) {\n if (status === 'ready') adapter.endBlockDrag(cancel);\n },\n\n /**\n * Keyboard shortcut that also works INSIDE the canvas (an iframe: page\n * listeners hear nothing there). `keys`: `mod+s` (Ctrl, or ⌘ on Mac),\n * several combinations separated by commas.\n */\n addShortcut(id, keys, handler) {\n requireReady('addShortcut');\n return adapter.addShortcut(id, keys, handler);\n },\n\n on: (event, listener) => emitter.on(event, listener),\n };\n\n return editor;\n}\n","// @ts-check\n/**\n * Generic registry — used for blocks (`emailBlocks`) and features\n * (`emailBuilderFeatures`).\n *\n * Removing an entry from the registry is enough to remove it from the builder:\n * neither the core nor the adapter knows a block or feature by name. That is\n * what lets a piece be disabled without touching anything else.\n */\n\n/**\n * @template {{id: string, order?: number}} T\n * @typedef {{\n * kind: string,\n * register: (item: T) => () => void,\n * unregister: (id: string) => boolean,\n * get: (id: string) => T | undefined,\n * has: (id: string) => boolean,\n * list: (filter?: (item: T) => boolean) => T[],\n * ids: () => string[],\n * }} Registry\n */\n\nconst ID_SHAPE = /^[a-z][a-z0-9-]*$/;\n\n/**\n * @template {{id: string, order?: number}} T\n * @param {string} kind registry name, for error messages\n * @param {T[]} [initial]\n * @returns {Registry<T>}\n */\nexport function createRegistry(kind, initial = []) {\n /** @type {Map<string, T>} */\n const items = new Map();\n\n /** @param {string} id */\n function unregister(id) {\n return items.delete(id);\n }\n\n /** @param {T} item */\n function register(item) {\n if (!item || typeof item.id !== 'string' || !ID_SHAPE.test(item.id)) {\n throw new Error(`${kind}: invalid id (\"${item?.id}\")`);\n }\n if (items.has(item.id)) {\n throw new Error(`${kind}: \"${item.id}\" is already registered`);\n }\n items.set(item.id, item);\n return () => {\n unregister(item.id);\n };\n }\n\n initial.forEach(register);\n\n return {\n kind,\n register,\n unregister,\n get: (id) => items.get(id),\n has: (id) => items.has(id),\n // Stable sort: `order` first, then registration order.\n list: (filter) =>\n [...items.values()]\n .map((item, index) => ({ item, index }))\n .sort((a, b) => (a.item.order ?? 1000) - (b.item.order ?? 1000) || a.index - b.index)\n .map(({ item }) => item)\n .filter((item) => (filter ? filter(item) : true)),\n ids: () => [...items.keys()],\n };\n}\n","// @ts-check\n/**\n * STRUCTURE - body, section, column.\n *\n * These are not blocks you add (no `mjml`): they are the containers you\n * SELECT, whose background and padding are set in the right-hand panel. The\n * N-column layouts (`blocks/columns`) create sections; once added, this\n * definition describes them.\n */\n\nimport { GROUPS, prop } from '../shared.js';\n\n/** @typedef {import('../../core/EmailEditor.js').EmailBlock} EmailBlock */\n\n/** @type {EmailBlock} */\nexport const bodyBlock = {\n id: 'body',\n label: 'Email',\n icon: 'Mail',\n kind: 'structure',\n tagName: 'mj-body',\n order: 900,\n properties: [\n prop.background('background-color', 'Page background'),\n {\n key: 'width',\n label: 'Content width',\n type: 'select',\n group: GROUPS.layout,\n options: [\n { value: '600px', label: '600 px (standard)' },\n { value: '640px', label: '640 px' },\n ],\n },\n ],\n};\n\n/** @type {EmailBlock} */\nexport const sectionBlock = {\n id: 'section',\n label: 'Section',\n icon: 'Rows3',\n kind: 'structure',\n tagName: 'mj-section',\n order: 901,\n properties: [\n prop.background('background-color', 'Background'),\n // A background image keeps the color under it: shown when images are blocked.\n { key: 'background-url', label: 'Background image', type: 'image', group: GROUPS.colors },\n {\n key: 'background-size',\n label: 'Image size',\n type: 'select',\n group: GROUPS.colors,\n options: [\n { value: 'cover', label: 'Fill the section' },\n { value: 'contain', label: 'Whole image' },\n { value: 'auto', label: 'Original size' },\n ],\n },\n {\n key: 'background-position',\n label: 'Image position',\n type: 'select',\n group: GROUPS.colors,\n options: [\n { value: 'center center', label: 'Center' },\n { value: 'center top', label: 'Top' },\n { value: 'center bottom', label: 'Bottom' },\n ],\n },\n {\n // A colored band from edge to edge of the screen (headers, footers);\n // the content keeps the email's width.\n key: 'full-width',\n label: 'Background width',\n type: 'select',\n group: GROUPS.colors,\n options: [\n { value: '', label: 'Content width' },\n { value: 'full-width', label: 'Whole screen' },\n ],\n },\n prop.padding('padding', 'Padding'),\n prop.radius(24),\n ],\n};\n\n/** @type {EmailBlock} */\nexport const columnBlock = {\n id: 'column',\n label: 'Column',\n icon: 'Columns2',\n kind: 'structure',\n tagName: 'mj-column',\n order: 902,\n properties: [\n {\n // Share of the section's width. The other columns of the section share\n // the rest (the engine balances them: MJML would leave a gap).\n key: 'width',\n label: 'Width',\n type: 'select',\n group: GROUPS.layout,\n options: [\n { value: '', label: 'Equal' },\n { value: '25%', label: '1/4' },\n { value: '33%', label: '1/3' },\n { value: '50%', label: '1/2' },\n { value: '67%', label: '2/3' },\n { value: '75%', label: '3/4' },\n ],\n },\n prop.background('background-color', 'Background'),\n prop.padding('padding', 'Padding'),\n {\n key: 'vertical-align',\n label: 'Vertical alignment',\n type: 'select',\n group: GROUPS.layout,\n options: [\n { value: 'top', label: 'Top' },\n { value: 'middle', label: 'Middle' },\n { value: 'bottom', label: 'Bottom' },\n ],\n },\n ],\n};\n","// @ts-check\n/**\n * TEXT - `mj-text`.\n *\n * Content is typed in the canvas (double-click: bold, italic, link); the panel\n * only controls the styling. Defaults are readable on mobile: 15 px on a 24 px\n * line height, ink #2b3038 (never pure black, which \"vibrates\" on phone\n * screens).\n */\n\nimport { identity } from '../../i18n/index.js';\nimport { FONT_STACK, GROUPS, PALETTE, escapeXml, inWhiteSection, prop } from '../shared.js';\n\n/** @typedef {import('../../core/EmailEditor.js').EmailBlock} EmailBlock */\n\n/**\n * A text with the block's settings. Also used by the column layouts, which\n * pre-fill each column.\n *\n * @param {string} content Already-safe HTML (fixed builder text)\n */\nexport function textMjml(content) {\n return (\n `<mj-text font-family=\"${FONT_STACK}\" font-size=\"15px\" line-height=\"24px\" color=\"${PALETTE.ink}\" ` +\n `align=\"left\">${content}</mj-text>`\n );\n}\n\n/** @param {import('../../i18n/index.js').Translate} [t] */\nconst mjml = (t = identity) => textMjml(escapeXml(t('Your text.')));\n\n/** @type {EmailBlock} */\nexport const textBlock = {\n id: 'text',\n label: 'Text',\n description: 'Paragraph or heading',\n icon: 'Type',\n kind: 'content',\n tagName: 'mj-text',\n order: 10,\n mjml,\n sectionMjml: (t) => inWhiteSection(mjml(t)),\n editableContent: true,\n properties: [\n prop.fontFamily(),\n prop.fontSize(10, 48),\n prop.lineHeight(),\n {\n key: 'font-weight',\n label: 'Weight',\n type: 'select',\n group: GROUPS.typography,\n options: [\n { value: 'normal', label: 'Normal' },\n { value: 'bold', label: 'Bold' },\n ],\n },\n prop.color('Text'),\n prop.background('container-background-color', 'Background'),\n { ...prop.align(), options: [...prop.align().options || [], { value: 'justify', label: 'Justify' }] },\n prop.padding(),\n ],\n};\n","// @ts-check\n/**\n * IMAGE - `mj-image`.\n *\n * Added WITHOUT a file: the canvas shows a frame to fill, and the panel (file\n * upload or https URL) completes it. A sample image from a third-party service\n * would, one day, end up in a real send.\n *\n * Width is left to MJML (the full column, shrunk on mobile): a fixed width\n * larger than the column would overflow in Outlook.\n *\n * The alt text is not decorative: Outlook blocks images by default, and the\n * recipient reads the alt text in their place.\n */\n\nimport { GROUPS, inWhiteSection, prop } from '../shared.js';\n\n/** @typedef {import('../../core/EmailEditor.js').EmailBlock} EmailBlock */\n\nconst MJML = '<mj-image align=\"center\"></mj-image>';\n\n/** @type {EmailBlock} */\nexport const imageBlock = {\n id: 'image',\n label: 'Image',\n description: 'Photo, visual or logo',\n icon: 'Image',\n kind: 'content',\n tagName: 'mj-image',\n order: 20,\n mjml: MJML,\n sectionMjml: inWhiteSection(MJML),\n properties: [\n { key: 'src', label: 'Image', type: 'image', group: GROUPS.content },\n {\n key: 'alt',\n label: 'Alt text',\n type: 'text',\n group: GROUPS.content,\n placeholder: 'Describes the image if it is blocked',\n },\n prop.href('Link on click'),\n { key: 'width', label: 'Width', type: 'size', group: GROUPS.layout, min: 20, max: 600, unit: 'px' },\n {\n // A photo given a width keeps it on a phone unless told otherwise.\n key: 'fluid-on-mobile',\n label: 'On mobile',\n type: 'select',\n group: GROUPS.layout,\n options: [\n { value: '', label: 'Keep its width' },\n { value: 'true', label: 'Full width' },\n ],\n },\n prop.align(),\n prop.radius(40),\n prop.padding(),\n ],\n};\n","// @ts-check\n/**\n * BUTTON - `mj-button`.\n *\n * MJML renders it as a table (not a styled `<a>`), which keeps it clickable\n * and at its size in Outlook. The default link is `DEFAULT_BUTTON_URL`.\n *\n * Defaults: navy background, bold white text, generous click area\n * (12 x 28 px) - a button that is too small is easy to miss with a finger.\n */\n\nimport { identity } from '../../i18n/index.js';\nimport { DEFAULT_BUTTON_URL, FONT_STACK, GROUPS, PALETTE, escapeXml, inWhiteSection, prop } from '../shared.js';\n\n/** @typedef {import('../../core/EmailEditor.js').EmailBlock} EmailBlock */\n\n/** @param {import('../../i18n/index.js').Translate} [t] */\nconst mjml = (t = identity) =>\n `<mj-button href=\"${DEFAULT_BUTTON_URL}\" background-color=\"${PALETTE.navy}\" color=\"${PALETTE.white}\" ` +\n `font-family=\"${FONT_STACK}\" font-size=\"15px\" font-weight=\"bold\" border-radius=\"6px\" ` +\n `inner-padding=\"12px 28px\" align=\"center\">${escapeXml(t('Learn more'))}</mj-button>`;\n\n/** @type {EmailBlock} */\nexport const buttonBlock = {\n id: 'button',\n label: 'Button',\n description: 'Call to action',\n icon: 'RectangleHorizontal',\n kind: 'content',\n tagName: 'mj-button',\n order: 30,\n mjml,\n sectionMjml: (t) => inWhiteSection(mjml(t)),\n editableContent: true,\n properties: [\n prop.href('Link URL'),\n prop.background('background-color', 'Button background'),\n prop.color('Text'),\n prop.fontFamily(),\n prop.fontSize(11, 28),\n {\n key: 'font-weight',\n label: 'Weight',\n type: 'select',\n group: GROUPS.typography,\n options: [\n { value: 'bold', label: 'Bold' },\n { value: 'normal', label: 'Normal' },\n ],\n },\n prop.radius(30),\n {\n key: 'width',\n label: 'Width',\n type: 'select',\n group: GROUPS.layout,\n options: [\n { value: '', label: 'Fit to text' },\n { value: '100%', label: 'Full width' },\n ],\n },\n prop.align(),\n prop.padding('inner-padding', 'Button padding'),\n prop.padding(),\n ],\n};\n","// @ts-check\n/**\n * DIVIDER - `mj-divider`.\n *\n * A thin rule in the default border color. MJML renders it as a `<p>` border\n * backed by a table for Outlook: it keeps its thickness everywhere, whereas an\n * `<hr>` varies from one email client to another.\n */\n\nimport { GROUPS, PALETTE, inWhiteSection, prop } from '../shared.js';\n\n/** @typedef {import('../../core/EmailEditor.js').EmailBlock} EmailBlock */\n\nconst MJML = `<mj-divider border-color=\"${PALETTE.border}\" border-width=\"1px\"></mj-divider>`;\n\n/** @type {EmailBlock} */\nexport const dividerBlock = {\n id: 'divider',\n label: 'Divider',\n description: 'Horizontal rule',\n icon: 'SeparatorHorizontal',\n kind: 'content',\n tagName: 'mj-divider',\n order: 40,\n mjml: MJML,\n sectionMjml: inWhiteSection(MJML),\n properties: [\n prop.background('border-color', 'Line color'),\n { key: 'border-width', label: 'Thickness', type: 'size', group: GROUPS.layout, min: 1, max: 10, unit: 'px' },\n {\n key: 'border-style',\n label: 'Line style',\n type: 'select',\n group: GROUPS.layout,\n options: [\n { value: 'solid', label: 'Solid' },\n { value: 'dashed', label: 'Dashed' },\n { value: 'dotted', label: 'Dotted' },\n ],\n },\n {\n key: 'width',\n label: 'Length',\n type: 'select',\n group: GROUPS.layout,\n options: [\n { value: '100%', label: 'Full length' },\n { value: '75%', label: '75%' },\n { value: '50%', label: '50%' },\n { value: '25%', label: '25%' },\n ],\n },\n prop.align(),\n prop.padding(),\n ],\n};\n","// @ts-check\n/**\n * SPACER - `mj-spacer`.\n *\n * Fixed-height empty space. MJML renders it as a `<div>` with an explicit line\n * height (`mso-line-height-rule: exactly`): Outlook, which ignores margins,\n * honors it.\n */\n\nimport { GROUPS, inWhiteSection, prop } from '../shared.js';\n\n/** @typedef {import('../../core/EmailEditor.js').EmailBlock} EmailBlock */\n\nconst MJML = '<mj-spacer height=\"24px\"></mj-spacer>';\n\n/** @type {EmailBlock} */\nexport const spacerBlock = {\n id: 'spacer',\n label: 'Spacer',\n description: 'Vertical space',\n icon: 'MoveVertical',\n kind: 'content',\n tagName: 'mj-spacer',\n order: 50,\n mjml: MJML,\n sectionMjml: inWhiteSection(MJML),\n properties: [\n { key: 'height', label: 'Height', type: 'size', group: GROUPS.layout, min: 4, max: 200, unit: 'px' },\n prop.background('container-background-color', 'Background'),\n ],\n};\n","// @ts-check\n/**\n * HEADING - an `mj-text` set as a title.\n *\n * Not a tag of its own: MJML has no heading element, and a `<h1>` inside\n * `mj-text` would bring each email client's default margins and sizes. It is\n * a text written large and bold - the same element as the Text block, so once\n * added it is described by that block (`insertOnly`): same panel, same\n * properties, weight included.\n */\n\nimport { identity } from '../../i18n/index.js';\nimport { FONT_STACK, PALETTE, escapeXml, inWhiteSection } from '../shared.js';\n\n/** @typedef {import('../../core/EmailEditor.js').EmailBlock} EmailBlock */\n\n/** @param {import('../../i18n/index.js').Translate} [t] */\nconst mjml = (t = identity) =>\n `<mj-text font-family=\"${FONT_STACK}\" font-size=\"26px\" line-height=\"34px\" font-weight=\"bold\" ` +\n `color=\"${PALETTE.navy}\" align=\"left\">${escapeXml(t('Your headline'))}</mj-text>`;\n\n/** @type {EmailBlock} */\nexport const headingBlock = {\n id: 'heading',\n label: 'Heading',\n description: 'Large bold title',\n icon: 'Heading',\n kind: 'content',\n tagName: 'mj-text',\n insertOnly: true,\n order: 5,\n mjml,\n sectionMjml: (t) => inWhiteSection(mjml(t)),\n editableContent: true,\n properties: [],\n};\n","// @ts-check\n/**\n * MENU - `mj-navbar` and its `mj-navbar-link` links.\n *\n * A row of text links (shop, blog, contact…) under the logo. No \"hamburger\"\n * mode: MJML builds it with a hidden checkbox, an `<input>` that several\n * clients strip and the template validator refuses; a short row of links\n * wraps on a phone by itself.\n *\n * Each link is edited like a button: its label in the panel, its URL, its\n * color. Duplicate a link to add one.\n */\n\nimport { identity } from '../../i18n/index.js';\nimport { FONT_STACK, GROUPS, PALETTE, escapeXml, inWhiteSection, prop } from '../shared.js';\n\n/** @typedef {import('../../core/EmailEditor.js').EmailBlock} EmailBlock */\n\n/** @param {string} label @param {string} href */\nfunction link(label, href) {\n return (\n `<mj-navbar-link href=\"${href}\" font-family=\"${FONT_STACK}\" font-size=\"14px\" color=\"${PALETTE.navy}\" ` +\n `text-transform=\"none\" padding-top=\"8px\" padding-right=\"12px\" padding-bottom=\"8px\" padding-left=\"12px\">${escapeXml(label)}</mj-navbar-link>`\n );\n}\n\n/** @param {import('../../i18n/index.js').Translate} [t] */\nconst mjml = (t = identity) =>\n '<mj-navbar align=\"center\">' +\n link(t('Shop'), 'https://example.com/shop') +\n link(t('Blog'), 'https://example.com/blog') +\n link(t('Contact'), 'https://example.com/contact') +\n '</mj-navbar>';\n\n/** @type {EmailBlock} */\nexport const navbarBlock = {\n id: 'navbar',\n label: 'Menu',\n description: 'Row of links to your site',\n icon: 'Menu',\n kind: 'content',\n tagName: 'mj-navbar',\n order: 70,\n mjml,\n sectionMjml: (t) => inWhiteSection(mjml(t)),\n properties: [prop.align()],\n};\n\n/** One link of the menu: selectable, not addable (duplicate it instead). */\n/** @type {EmailBlock} */\nexport const navbarLinkBlock = {\n id: 'navbar-link',\n label: 'Menu link',\n icon: 'Link',\n kind: 'structure',\n tagName: 'mj-navbar-link',\n order: 904,\n editableContent: true,\n properties: [\n prop.href('Link URL'),\n prop.color('Text'),\n prop.fontFamily(),\n prop.fontSize(10, 24),\n {\n // MJML writes menu links in capitals unless told otherwise.\n key: 'text-transform',\n label: 'Capitals',\n type: 'select',\n group: GROUPS.typography,\n options: [\n { value: 'none', label: 'As typed' },\n { value: 'uppercase', label: 'All capitals' },\n { value: 'capitalize', label: 'First letters' },\n ],\n },\n prop.padding(),\n ],\n};\n","// @ts-check\n/**\n * HERO - a full-width banner: a background image (or color) under a title, a\n * sentence and a button.\n *\n * A SECTION with a background image, not `mj-hero`: the canvas engine draws\n * `mj-hero` squeezed into a narrow strip, so the screen would lie about the\n * email. A section background is drawn the same in both, and MJML adds the\n * VML that Outlook on Windows needs to show it.\n *\n * The background color stays set under the image: clients that block images\n * show it instead, and the white text stays readable on it. Once added, the\n * banner is a section like any other (`blocks/structure`): its image, size and\n * position are set there.\n */\n\nimport { identity } from '../../i18n/index.js';\nimport { DEFAULT_BUTTON_URL, FONT_STACK, PALETTE, escapeXml } from '../shared.js';\n\n/** @typedef {import('../../core/EmailEditor.js').EmailBlock} EmailBlock */\n\n/** @param {import('../../i18n/index.js').Translate} [t] */\nconst mjml = (t = identity) =>\n `<mj-section background-color=\"${PALETTE.navy}\" background-size=\"cover\" background-position=\"center center\" ` +\n 'background-repeat=\"no-repeat\" padding-top=\"56px\" padding-bottom=\"56px\">' +\n '<mj-column>' +\n `<mj-text font-family=\"${FONT_STACK}\" font-size=\"30px\" line-height=\"38px\" font-weight=\"bold\" ` +\n `color=\"${PALETTE.white}\" align=\"center\" padding-left=\"32px\" padding-right=\"32px\">${escapeXml(t('Your big announcement'))}</mj-text>` +\n `<mj-text font-family=\"${FONT_STACK}\" font-size=\"16px\" line-height=\"24px\" color=\"${PALETTE.border}\" ` +\n `align=\"center\" padding-left=\"32px\" padding-right=\"32px\">${escapeXml(t('One sentence that makes people want to read on.'))}</mj-text>` +\n `<mj-button href=\"${DEFAULT_BUTTON_URL}\" background-color=\"${PALETTE.white}\" color=\"${PALETTE.navy}\" ` +\n `font-family=\"${FONT_STACK}\" font-size=\"15px\" font-weight=\"bold\" border-radius=\"6px\" ` +\n `inner-padding=\"12px 28px\" align=\"center\">${escapeXml(t('Learn more'))}</mj-button>` +\n '</mj-column>' +\n '</mj-section>';\n\n/** @type {EmailBlock} */\nexport const heroBlock = {\n id: 'hero',\n label: 'Hero banner',\n description: 'Background image with a title and a button',\n icon: 'GalleryHorizontal',\n kind: 'layout',\n tagName: 'mj-section',\n order: 110,\n mjml,\n properties: [],\n};\n","// @ts-check\n/**\n * LAYOUTS - 1 to 4 column sections (`mj-section` + `mj-column`).\n *\n * The columns start EMPTY: the canvas shows \"Drop a block here\" in each one\n * (canvas only, never in the email), so a new layout says what it is for\n * instead of filling the email with placeholder text to delete. On mobile\n * (under 480 px), MJML stacks the columns on top of each other.\n *\n * Once added, the section is described by the \"section\" structure\n * (`blocks/structure`): background, padding, corner radius; its name in the\n * canvas and the panel is the layout's (\"2 columns\").\n */\n\nimport { identity } from '../../i18n/index.js';\nimport { DEFAULT_BUTTON_URL, FONT_STACK, PALETTE, escapeXml } from '../shared.js';\nimport { textMjml } from '../text/index.js';\n\n/** @typedef {import('../../core/EmailEditor.js').EmailBlock} EmailBlock */\n\n/** @param {number} count */\nfunction sectionWith(count) {\n return `<mj-section background-color=\"${PALETTE.surface}\">${'<mj-column></mj-column>'.repeat(count)}</mj-section>`;\n}\n\n/**\n * @param {number} count\n * @param {string} icon\n * @returns {EmailBlock}\n */\nfunction layout(count, icon) {\n return {\n id: `columns-${count}`,\n label: count === 1 ? '1 column' : `${count} columns`,\n description: count === 1 ? 'Full-width section' : `${count}-column section`,\n icon,\n kind: 'layout',\n tagName: 'mj-section',\n order: 100 + count,\n mjml: sectionWith(count),\n properties: [],\n };\n}\n\nexport const oneColumnBlock = layout(1, 'Square');\nexport const twoColumnsBlock = layout(2, 'Columns2');\nexport const threeColumnsBlock = layout(3, 'Columns3');\nexport const fourColumnsBlock = layout(4, 'Columns4');\n\n/**\n * Image on one side, title, text and button on the other - the usual\n * \"product\" or \"article\" row. Stacked on mobile, image first.\n * @param {import('../../i18n/index.js').Translate} [t]\n */\nconst imageTextMjml = (t = identity) =>\n `<mj-section background-color=\"${PALETTE.surface}\">` +\n '<mj-column vertical-align=\"middle\"><mj-image align=\"center\"></mj-image></mj-column>' +\n '<mj-column vertical-align=\"middle\">' +\n `<mj-text font-family=\"${FONT_STACK}\" font-size=\"20px\" line-height=\"28px\" font-weight=\"bold\" ` +\n `color=\"${PALETTE.navy}\" align=\"left\">${escapeXml(t('Title'))}</mj-text>` +\n textMjml(escapeXml(t('A few words about it.'))) +\n `<mj-button href=\"${DEFAULT_BUTTON_URL}\" background-color=\"${PALETTE.navy}\" color=\"${PALETTE.white}\" ` +\n `font-family=\"${FONT_STACK}\" font-size=\"14px\" font-weight=\"bold\" border-radius=\"6px\" ` +\n `inner-padding=\"10px 22px\" align=\"left\">${escapeXml(t('Learn more'))}</mj-button>` +\n '</mj-column>' +\n '</mj-section>';\n\n/** @type {EmailBlock} */\nexport const imageTextBlock = {\n id: 'image-text',\n label: 'Image + text',\n description: 'Image beside a title, text and button',\n icon: 'LayoutPanelLeft',\n kind: 'layout',\n tagName: 'mj-section',\n order: 105,\n mjml: imageTextMjml,\n properties: [],\n};\n","// @ts-check\n/**\n * BLOCK REGISTRY - `emailBlocks`.\n *\n * Each block lives in its own folder and depends only on the core. Removing a\n * line below removes the block from the sidebar, the properties panel and\n * drag and drop, without changing anything else.\n */\n\nimport { createRegistry } from '../core/registry.js';\nimport { bodyBlock, columnBlock, sectionBlock } from './structure/index.js';\nimport { textBlock } from './text/index.js';\nimport { imageBlock } from './image/index.js';\nimport { buttonBlock } from './button/index.js';\nimport { dividerBlock } from './divider/index.js';\nimport { spacerBlock } from './spacer/index.js';\nimport { headingBlock } from './heading/index.js';\nimport { socialBlock, socialElementBlock } from './social/index.js';\nimport { navbarBlock, navbarLinkBlock } from './navbar/index.js';\nimport { heroBlock } from './hero/index.js';\nimport {\n fourColumnsBlock,\n imageTextBlock,\n oneColumnBlock,\n threeColumnsBlock,\n twoColumnsBlock,\n} from './columns/index.js';\n\n/** @typedef {import('../core/EmailEditor.js').EmailBlock} EmailBlock */\n\n/** @type {EmailBlock[]} */\nconst BLOCKS = [\n headingBlock,\n textBlock,\n imageBlock,\n buttonBlock,\n dividerBlock,\n spacerBlock,\n socialBlock,\n navbarBlock,\n oneColumnBlock,\n twoColumnsBlock,\n threeColumnsBlock,\n fourColumnsBlock,\n imageTextBlock,\n heroBlock,\n bodyBlock,\n sectionBlock,\n columnBlock,\n socialElementBlock,\n navbarLinkBlock,\n];\n\nexport const emailBlocks = createRegistry('emailBlocks', BLOCKS);\n","// @ts-check\n/**\n * AUTOSAVE feature.\n *\n * template already saved → server save WITHOUT a new version, 20 s after\n * the last change (at most 2 min after the first one);\n * template never saved → local draft (`localDraft.js`), offered the next\n * time a new template is opened.\n *\n * The screen reads `options`; removing this entry from the registry turns both\n * off.\n */\n\n/** @type {import('../../core/EmailEditor.js').EmailBuilderFeature & {options: {idleMs: number, maxWaitMs: number, draftDelayMs: number}}} */\nexport const autosaveFeature = {\n id: 'autosave',\n label: 'Autosave',\n order: 20,\n options: { idleMs: 20_000, maxWaitMs: 120_000, draftDelayMs: 1_500 },\n};\n","import { useState } from 'react';\nimport { History } from 'lucide-react';\nimport { Button } from '../../ui/primitives/button.jsx';\nimport { Popover, PopoverContent, PopoverTrigger } from '../../ui/primitives/overlays.jsx';\nimport { Skeleton } from '../../ui/primitives/misc.jsx';\nimport { useUi } from '../../ui/context.jsx';\n\n/**\n * VERSIONS of a template — toolbar button.\n *\n * Every explicit \"Save\" creates a version (autosave never does). Restoring\n * RELOADS the version into the editor without writing anything: the next save\n * makes it current, by creating one more version. History is never rewritten.\n */\n\nfunction formatWhen(value, locale) {\n if (!value) return '';\n const d = new Date(value);\n return Number.isNaN(d.getTime())\n ? ''\n : d.toLocaleString(locale, { day: '2-digit', month: '2-digit', hour: '2-digit', minute: '2-digit' });\n}\n\nexport default function VersionsMenu({ context }) {\n const { editor, storage, template, isDirty, markDirty, ready } = context;\n const { t, confirm, notify, locale } = useUi();\n const [open, setOpen] = useState(false);\n const [versions, setVersions] = useState(null);\n const [error, setError] = useState(null);\n const [restoring, setRestoring] = useState(null);\n\n const load = async () => {\n setVersions(null);\n setError(null);\n try {\n setVersions(await storage.listVersions(template.id));\n } catch (e) {\n setError(e.message);\n }\n };\n\n const restore = async (version) => {\n if (isDirty()) {\n const ok = await confirm({\n title: t('Restore version {n}?', { n: version.versionNumber }),\n description: t('Unsaved changes will be replaced.'),\n confirmLabel: t('Restore'),\n destructive: true,\n });\n if (!ok) return;\n }\n setRestoring(version.id);\n try {\n const full = await storage.getVersion(template.id, version.id);\n // A version saved by an earlier engine reopens from its MJML.\n editor.loadDocument(full.document, { mjml: full.mjml });\n markDirty();\n setOpen(false);\n notify('success', t('Version {n} restored — save to keep it.', { n: version.versionNumber }));\n } catch (e) {\n notify('error', e.message);\n } finally {\n setRestoring(null);\n }\n };\n\n return (\n <Popover\n open={open}\n onOpenChange={(next) => {\n setOpen(next);\n if (next) load();\n }}\n >\n <PopoverTrigger asChild>\n <Button\n variant=\"outline\"\n size=\"sm-compact\"\n disabled={!ready || !template.id}\n title={!template.id ? t('Save the template first') : undefined}\n >\n <History />\n {t('Versions')}\n </Button>\n </PopoverTrigger>\n <PopoverContent align=\"end\" className=\"eb:w-80 eb:p-0\">\n <div className=\"eb:border-b eb:border-border eb:px-3 eb:py-2.5 eb:text-[13px] eb:font-medium eb:text-foreground\">\n {t('Versions')}\n </div>\n <div className=\"eb:max-h-[320px] eb:overflow-y-auto eb:p-1\" aria-busy={versions === null && !error}>\n {error ? (\n <p role=\"alert\" className=\"eb:px-2 eb:py-1.5 eb:text-[12px] eb:text-destructive\">\n {error}\n </p>\n ) : versions === null ? (\n <div className=\"eb:space-y-1 eb:p-1\" aria-hidden=\"true\">\n <Skeleton className=\"eb:h-8 eb:w-40\" />\n <Skeleton className=\"eb:h-8 eb:w-32\" />\n <Skeleton className=\"eb:h-8 eb:w-36\" />\n </div>\n ) : versions.length === 0 ? (\n <p className=\"eb:px-2 eb:py-1.5 eb:text-[12px] eb:text-foreground-muted\">{t('No versions yet.')}</p>\n ) : (\n versions.map((version, index) => (\n <div\n key={version.id}\n className=\"eb:flex eb:items-center eb:gap-2 eb:rounded-lg2 eb:px-2 eb:py-1.5 eb:hover:bg-surface-100\"\n >\n <div className=\"eb:min-w-0 eb:flex-1\">\n <p className=\"eb:text-[13px] eb:text-foreground\">\n {t('Version {n}', { n: version.versionNumber })}\n {index === 0 && <span className=\"eb:ml-1.5 eb:text-[11px] eb:text-foreground-muted\">{t('current')}</span>}\n </p>\n <p className=\"eb:text-[11px] eb:tabular-nums eb:text-foreground-muted\">\n {formatWhen(version.createdAt, locale)}\n {version.createdBy ? ` · ${version.createdBy}` : ''}\n </p>\n </div>\n <Button\n variant=\"ghost\"\n size=\"xs\"\n disabled={restoring !== null}\n onClick={() => restore(version)}\n aria-label={t('Restore version {n}', { n: version.versionNumber })}\n >\n {t('Restore')}\n </Button>\n </div>\n ))\n )}\n </div>\n </PopoverContent>\n </Popover>\n );\n}\n","// @ts-check\n/**\n * VERSIONS feature: toolbar button (`VersionsMenu`).\n */\n\nimport VersionsMenu from './VersionsMenu.jsx';\n\n/** @type {import('../../core/EmailEditor.js').EmailBuilderFeature} */\nexport const versionsFeature = {\n id: 'versions',\n label: 'Versions',\n order: 30,\n toolbar: VersionsMenu,\n};\n","import { useState } from 'react';\nimport { Braces } from 'lucide-react';\nimport { useUi } from '../../ui/context.jsx';\nimport { Button } from '../../ui/primitives/button.jsx';\nimport { Popover, PopoverContent, PopoverTrigger } from '../../ui/primitives/overlays.jsx';\nimport { tokenOf } from './catalog.js';\nimport VariableDialog from './VariableDialog.jsx';\nimport VariablePicker from './VariablePicker.jsx';\n\n/**\n * VARIABLES — toolbar menu.\n *\n * Inserts the variable's TAG where the user is typing (caret of the text being\n * edited), otherwise at the end of the selected text or button. The\n * unsubscribe link is inserted as a link (or becomes the button's URL). The\n * editor replaces nothing: rendering does, per recipient.\n *\n * When the storage supports it, users create, edit and delete their own\n * variables from here; they are shared by every template.\n *\n * The menu never takes the caret away from the text being edited: it does not\n * give focus back on close, and its mousedown does not reach the document —\n * any mousedown there ends the text editing.\n */\nexport default function VariablesMenu({ context }) {\n const { editor, ready, variables, storage, canManageVariables, reloadVariables } = context;\n const { t, notify } = useUi();\n const [open, setOpen] = useState(false);\n const [dialog, setDialog] = useState(null); // { variable } | { label }\n\n const insert = (variable) => {\n setOpen(false);\n const done =\n variable.kind === 'link'\n ? editor.insertLink(tokenOf(variable), t('Unsubscribe'))\n : editor.insertText(tokenOf(variable));\n if (!done) notify('info', t('Select a text or a button first.'));\n return done;\n };\n\n const manage = canManageVariables\n ? {\n onCreate: (label) => {\n setOpen(false);\n setDialog({ variable: null, label });\n },\n onEdit: (variable) => {\n setOpen(false);\n setDialog({ variable, label: '' });\n },\n }\n : {};\n\n return (\n <>\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger asChild>\n <Button\n variant=\"outline\"\n size=\"sm-compact\"\n disabled={!ready}\n // No mousedown: the text being edited keeps its caret (the click still opens the menu).\n onPointerDown={(e) => e.pointerType === 'mouse' && e.preventDefault()}\n >\n <Braces />\n {t('Variables')}\n </Button>\n </PopoverTrigger>\n <PopoverContent\n align=\"end\"\n className=\"eb:w-80 eb:p-0\"\n onCloseAutoFocus={(e) => e.preventDefault()}\n onMouseDown={(e) => e.stopPropagation()}\n >\n <VariablePicker variables={variables} onPick={insert} {...manage} />\n </PopoverContent>\n </Popover>\n {canManageVariables && (\n <VariableDialog\n open={Boolean(dialog)}\n onOpenChange={(next) => !next && setDialog(null)}\n variable={dialog?.variable || null}\n initialLabel={dialog?.label || ''}\n variables={variables}\n storage={storage}\n onSaved={async (variable, created) => {\n await reloadVariables();\n if (created) {\n // A text was being edited: the new variable goes at its caret.\n if (editor.insertText(tokenOf(variable))) {\n notify('success', t('Variable “{name}” created and inserted.', { name: variable.label }));\n } else {\n notify('success', t('Variable “{name}” created.', { name: variable.label }));\n }\n } else {\n notify('success', t('Variable “{name}” saved.', { name: variable.label }));\n }\n }}\n onDeleted={async () => {\n await reloadVariables();\n notify('success', t('Variable deleted.'));\n }}\n />\n )}\n </>\n );\n}\n","import { useEffect, useMemo, useState } from 'react';\nimport { Braces, Loader2, Trash2 } from 'lucide-react';\nimport { useUi } from '../../ui/context.jsx';\nimport { Button } from '../../ui/primitives/button.jsx';\nimport { Input, Label } from '../../ui/primitives/fields.jsx';\nimport { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from '../../ui/primitives/overlays.jsx';\nimport { CUSTOM_GROUP, VARIABLE_LIMITS, keyFromLabel, validateCustomVariable } from './catalog.js';\n\n/**\n * Create or edit a CUSTOM variable.\n *\n * Name what the menu shows (\"Order number\");\n * Tag proposed from the name, editable until the variable\n * exists — then frozen: templates contain it;\n * Group free text, existing groups suggested;\n * Sample value used by the preview and test sends;\n * Value if empty what a recipient without a value sees.\n *\n * @param {{\n * open: boolean,\n * onOpenChange: (open: boolean) => void,\n * variable?: import('./catalog.js').EmailVariable|null, // null: creation\n * initialLabel?: string,\n * variables: import('./catalog.js').EmailVariable[],\n * storage: import('../../storage/client.js').TemplateStorage,\n * onSaved: (variable: import('./catalog.js').EmailVariable, created: boolean) => void,\n * onDeleted?: (key: string) => void,\n * }} props\n */\nexport default function VariableDialog({ open, onOpenChange, variable = null, initialLabel = '', variables, storage, onSaved, onDeleted }) {\n const { t, notify, confirm } = useUi();\n const editing = Boolean(variable);\n const [form, setForm] = useState({ label: '', key: '', group: '', sample: '', fallback: '' });\n const [keyTouched, setKeyTouched] = useState(false);\n const [errors, setErrors] = useState({});\n const [busy, setBusy] = useState(false);\n\n useEffect(() => {\n if (!open) return;\n setForm(\n variable\n ? {\n label: variable.label,\n key: variable.key,\n group: variable.group || '',\n sample: variable.sample || '',\n fallback: variable.fallback || '',\n }\n : { label: initialLabel, key: initialLabel ? keyFromLabel(initialLabel) : '', group: '', sample: '', fallback: '' }\n );\n setKeyTouched(false);\n setErrors({});\n }, [open, variable, initialLabel]);\n\n const groups = useMemo(\n () => [...new Set([CUSTOM_GROUP, ...variables.filter((v) => v.custom).map((v) => v.group)])].filter(Boolean),\n [variables]\n );\n\n const set = (field) => (e) => {\n const value = e.target.value;\n setForm((f) => {\n const next = { ...f, [field]: value };\n // The tag follows the name until the user types one.\n if (field === 'label' && !editing && !keyTouched) next.key = value.trim() ? keyFromLabel(value) : '';\n return next;\n });\n if (field === 'key') setKeyTouched(true);\n setErrors((errs) => ({ ...errs, [field]: undefined }));\n };\n\n const submit = async (e) => {\n e.preventDefault();\n const existing = variables.filter((v) => !editing || v.key !== variable.key);\n const check = validateCustomVariable(form, { existing, editing: editing ? variable.key : null, t });\n if (check.errors) {\n setErrors(check.errors);\n return;\n }\n setBusy(true);\n try {\n const saved = await storage.saveVariable(check.variable, { create: !editing });\n onSaved(saved, !editing);\n onOpenChange(false);\n } catch (error) {\n notify('error', error.message);\n } finally {\n setBusy(false);\n }\n };\n\n const remove = async () => {\n const ok = await confirm({\n title: t('Delete the variable “{name}”?', { name: variable.label }),\n description: t('Templates that use it will show its “value if empty”.'),\n confirmLabel: t('Delete'),\n destructive: true,\n });\n if (!ok) return;\n setBusy(true);\n try {\n await storage.deleteVariable(variable.key);\n onDeleted?.(variable.key);\n onOpenChange(false);\n } catch (error) {\n notify('error', error.message);\n } finally {\n setBusy(false);\n }\n };\n\n const field = (name, label, props = {}, hint = null) => (\n <div className=\"eb:space-y-1.5\">\n <Label htmlFor={`eb-var-${name}`}>{label}</Label>\n <Input\n id={`eb-var-${name}`}\n value={form[name]}\n onChange={set(name)}\n aria-invalid={errors[name] ? true : undefined}\n aria-describedby={errors[name] || hint ? `eb-var-${name}-hint` : undefined}\n {...props}\n />\n {(errors[name] || hint) && (\n <p id={`eb-var-${name}-hint`} className={errors[name] ? 'eb:text-[12px] eb:text-destructive' : 'eb:text-[11px] eb:text-foreground-muted'}>\n {errors[name] || hint}\n </p>\n )}\n </div>\n );\n\n return (\n <Dialog open={open} onOpenChange={onOpenChange}>\n <DialogContent\n className=\"eb:sm:max-w-[440px]\"\n // A text being edited in the canvas keeps its caret: a mousedown that\n // reaches the document would end the editing.\n onMouseDown={(e) => e.stopPropagation()}\n onCloseAutoFocus={(e) => e.preventDefault()}\n >\n <DialogHeader>\n <div className=\"eb:flex eb:items-center eb:gap-3\">\n <span className=\"eb:flex eb:size-10 eb:shrink-0 eb:items-center eb:justify-center eb:rounded-lg2 eb:bg-primary/10 eb:text-primary\">\n <Braces className=\"eb:size-5\" />\n </span>\n <div>\n <DialogTitle className=\"eb:text-base eb:font-normal\">{editing ? t('Edit variable') : t('New variable')}</DialogTitle>\n <DialogDescription className=\"eb:text-[13px]\">{t('Available in every template.')}</DialogDescription>\n </div>\n </div>\n </DialogHeader>\n <form onSubmit={submit} className=\"eb:space-y-3\" noValidate>\n {field('label', t('Name'), { autoFocus: true, maxLength: VARIABLE_LIMITS.label, placeholder: t('Order number') })}\n {field(\n 'key',\n t('Tag'),\n { disabled: editing, maxLength: VARIABLE_LIMITS.key, className: 'eb:font-mono eb:text-[12px]' },\n form.key ? `{{${form.key}}}` : null\n )}\n <div className=\"eb:space-y-1.5\">\n <Label htmlFor=\"eb-var-group\">{t('Group')}</Label>\n <Input\n id=\"eb-var-group\"\n list=\"eb-var-groups\"\n value={form.group}\n onChange={set('group')}\n maxLength={VARIABLE_LIMITS.group}\n placeholder={t(CUSTOM_GROUP)}\n />\n <datalist id=\"eb-var-groups\">\n {groups.map((g) => (\n <option key={g} value={g} />\n ))}\n </datalist>\n </div>\n <div className=\"eb:grid eb:grid-cols-2 eb:gap-3\">\n {field('sample', t('Sample value'), { maxLength: VARIABLE_LIMITS.sample, placeholder: 'CMD-1042' }, t('Preview and tests'))}\n {field('fallback', t('Value if empty'), { maxLength: VARIABLE_LIMITS.fallback }, t('When a recipient has none'))}\n </div>\n <div className=\"eb:flex eb:items-center eb:gap-2 eb:pt-1\">\n {editing && (\n <Button variant=\"ghost\" className=\"eb:text-destructive eb:hover:text-destructive\" onClick={remove} disabled={busy}>\n <Trash2 />\n {t('Delete')}\n </Button>\n )}\n <div className=\"eb:ml-auto eb:flex eb:gap-2\">\n <Button variant=\"outline\" onClick={() => onOpenChange(false)} disabled={busy}>\n {t('Cancel')}\n </Button>\n <Button type=\"submit\" disabled={busy}>\n {busy && <Loader2 className=\"eb:animate-spin\" />}\n {editing ? t('Save') : t('Create')}\n </Button>\n </div>\n </div>\n </form>\n </DialogContent>\n </Dialog>\n );\n}\n","import { useEffect, useMemo, useRef, useState } from 'react';\nimport { Pencil, Plus, Search } from 'lucide-react';\nimport { useT } from '../../ui/context.jsx';\nimport { cn } from '../../ui/primitives/cn.js';\nimport { tokenOf } from './catalog.js';\n\n/**\n * List of variables with a search field — shared by the toolbar menu and the\n * buttons next to the subject and preview text fields.\n *\n * Keyboard: type to filter, ↑/↓ to move, Enter to insert. A search with no\n * result offers to create the variable under that name.\n *\n * @param {{\n * variables: import('./catalog.js').EmailVariable[],\n * onPick: (variable: import('./catalog.js').EmailVariable) => void,\n * onCreate?: ((label: string) => void) | null,\n * onEdit?: ((variable: import('./catalog.js').EmailVariable) => void) | null,\n * filter?: (variable: import('./catalog.js').EmailVariable) => boolean,\n * }} props\n */\nexport default function VariablePicker({ variables, onPick, onCreate = null, onEdit = null, filter }) {\n const t = useT();\n const [query, setQuery] = useState('');\n const [active, setActive] = useState(0);\n const listRef = useRef(null);\n\n const matches = useMemo(() => {\n const q = query.trim().toLowerCase();\n return variables\n .filter((v) => (filter ? filter(v) : true))\n .filter(\n (v) =>\n !q ||\n t(v.label).toLowerCase().includes(q) ||\n v.key.toLowerCase().includes(q) ||\n t(v.group).toLowerCase().includes(q)\n );\n }, [variables, query, filter, t]);\n const groups = useMemo(() => [...new Set(matches.map((v) => v.group))], [matches]);\n // Display order (grouped) = keyboard order.\n const ordered = useMemo(() => groups.flatMap((g) => matches.filter((v) => v.group === g)), [groups, matches]);\n\n useEffect(() => setActive(0), [query]);\n useEffect(() => {\n listRef.current?.querySelector('[data-active=\"true\"]')?.scrollIntoView({ block: 'nearest' });\n }, [active]);\n\n const onKeyDown = (e) => {\n if (e.key === 'ArrowDown') {\n e.preventDefault();\n setActive((i) => Math.min(i + 1, ordered.length - 1));\n } else if (e.key === 'ArrowUp') {\n e.preventDefault();\n setActive((i) => Math.max(i - 1, 0));\n } else if (e.key === 'Enter') {\n e.preventDefault();\n if (ordered[active]) onPick(ordered[active]);\n else if (onCreate && query.trim()) onCreate(query.trim());\n }\n };\n\n return (\n <div className=\"eb:flex eb:max-h-[min(440px,70vh)] eb:flex-col\" data-testid=\"variable-picker\">\n <div className=\"eb:relative eb:border-b eb:border-border eb:p-2\">\n <Search className=\"eb:pointer-events-none eb:absolute eb:top-1/2 eb:left-4 eb:size-3.5 eb:-translate-y-1/2 eb:text-foreground-muted\" />\n <input\n autoFocus\n value={query}\n onChange={(e) => setQuery(e.target.value)}\n onKeyDown={onKeyDown}\n placeholder={t('Search variables…')}\n aria-label={t('Search variables…')}\n className=\"eb:h-8 eb:w-full eb:rounded-md eb:bg-surface-75 eb:pr-2 eb:pl-7 eb:text-[13px] eb:text-foreground eb:outline-none eb:placeholder:text-foreground-muted eb:focus-visible:ring-2 eb:focus-visible:ring-ring/40\"\n />\n </div>\n <div ref={listRef} role=\"listbox\" aria-label={t('Variables')} className=\"eb:min-h-0 eb:flex-1 eb:overflow-y-auto eb:p-1\">\n {ordered.length === 0 && (\n <div className=\"eb:px-2 eb:py-3 eb:text-center eb:text-[12px] eb:text-foreground-muted\">\n <p>{t('No variable found.')}</p>\n {onCreate && query.trim() && (\n <button\n type=\"button\"\n onClick={() => onCreate(query.trim())}\n className=\"eb:mt-2 eb:inline-flex eb:items-center eb:gap-1 eb:rounded-md eb:px-2 eb:py-1 eb:text-[12px] eb:font-medium eb:text-primary eb:hover:bg-accent\"\n >\n <Plus className=\"eb:size-3.5\" />\n {t('Create “{name}”', { name: query.trim() })}\n </button>\n )}\n </div>\n )}\n {groups.map((group) => (\n <div key={group} role=\"group\" aria-label={t(group)}>\n <p className=\"eb:px-2 eb:pt-2 eb:pb-1 eb:text-[11px] eb:text-foreground-muted\">{t(group)}</p>\n {ordered\n .filter((v) => v.group === group)\n .map((variable) => {\n const index = ordered.indexOf(variable);\n return (\n <div\n key={variable.key}\n data-active={index === active}\n className={cn(\n 'eb:group/var eb:flex eb:items-center eb:gap-1 eb:rounded-md',\n index === active ? 'eb:bg-accent eb:text-accent-foreground' : 'eb:hover:bg-accent/60'\n )}\n onMouseEnter={() => setActive(index)}\n >\n <button\n type=\"button\"\n role=\"option\"\n aria-selected={index === active}\n data-variable={variable.key}\n onClick={() => onPick(variable)}\n className=\"eb:flex eb:min-w-0 eb:flex-1 eb:items-center eb:gap-2 eb:px-2 eb:py-1.5 eb:text-left eb:text-[13px]\"\n title={variable.description || undefined}\n >\n <span className=\"eb:min-w-0 eb:flex-1 eb:truncate\">{variable.custom ? variable.label : t(variable.label)}</span>\n <code className=\"eb:shrink-0 eb:font-mono eb:text-[10.5px] eb:text-foreground-muted\">{tokenOf(variable)}</code>\n </button>\n {onEdit && variable.custom && (\n <button\n type=\"button\"\n aria-label={t('Edit “{name}”', { name: variable.label })}\n title={t('Edit')}\n onClick={() => onEdit(variable)}\n className=\"eb:mr-1 eb:flex eb:size-6 eb:shrink-0 eb:items-center eb:justify-center eb:rounded-md eb:text-foreground-muted eb:opacity-0 eb:group-hover/var:opacity-100 eb:hover:bg-background eb:hover:text-foreground eb:focus-visible:opacity-100\"\n >\n <Pencil className=\"eb:size-3\" />\n </button>\n )}\n </div>\n );\n })}\n </div>\n ))}\n </div>\n {onCreate && (\n <div className=\"eb:border-t eb:border-border eb:p-1\">\n <button\n type=\"button\"\n onClick={() => onCreate(query.trim())}\n className=\"eb:flex eb:w-full eb:items-center eb:gap-2 eb:rounded-md eb:px-2 eb:py-1.5 eb:text-left eb:text-[13px] eb:font-medium eb:text-primary eb:hover:bg-accent\"\n >\n <Plus className=\"eb:size-4\" />\n {t('New variable')}\n </button>\n </div>\n )}\n </div>\n );\n}\n","// @ts-check\n/**\n * VARIABLES feature: insertion menu (`VariablesMenu`), creation and editing of\n * custom variables (`VariableDialog`). The catalog (`catalog.js`) and the\n * replacement (`service.js`) are shared with the server.\n */\n\nimport VariablesMenu from './VariablesMenu.jsx';\n\n/** @type {import('../../core/EmailEditor.js').EmailBuilderFeature} */\nexport const variablesFeature = {\n id: 'variables',\n label: 'Variables',\n order: 10,\n toolbar: VariablesMenu,\n};\n","// @ts-check\n/**\n * PREVIEW feature: server rendering of the final email, desktop and mobile,\n * with the quality checks (`PreviewButton`). Shown when the storage can render.\n */\n\nimport PreviewButton from './PreviewButton.jsx';\n\n/** @type {import('../../core/EmailEditor.js').EmailBuilderFeature} */\nexport const previewFeature = {\n id: 'preview',\n label: 'Preview',\n order: 40,\n toolbar: PreviewButton,\n isAvailable: (context) => typeof context.storage?.render === 'function',\n};\n","import { useState } from 'react';\nimport { CheckCircle2, Loader2, Send, XCircle } from 'lucide-react';\nimport { useUi } from '../../ui/context.jsx';\nimport { Button } from '../../ui/primitives/button.jsx';\nimport { Label, Textarea } from '../../ui/primitives/fields.jsx';\nimport { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from '../../ui/primitives/overlays.jsx';\n\n/**\n * TEST SEND — the only real layout check: a browser preview says nothing about\n * what Outlook will do. Sends the MJML on screen, saved or not.\n *\n * The addresses are remembered in the browser for the next test.\n */\n\nconst KEY = 'best-email-builder:test-addresses';\n\nfunction readAddresses(fallback) {\n try {\n return window.localStorage.getItem(KEY) ?? fallback;\n } catch {\n return fallback;\n }\n}\n\nfunction rememberAddresses(value) {\n try {\n window.localStorage.setItem(KEY, value);\n } catch {\n /* private browsing: nothing to remember */\n }\n}\n\nexport default function TestEmailButton({ context }) {\n const { editor, ready, meta, storage, testRecipients = [] } = context;\n const { t, notify } = useUi();\n const [open, setOpen] = useState(false);\n const [addresses, setAddresses] = useState('');\n const [sending, setSending] = useState(false);\n const [report, setReport] = useState(null);\n\n const emails = addresses\n .split(/[,;\\s]+/)\n .map((a) => a.trim())\n .filter(Boolean);\n\n const send = async () => {\n if (!emails.length) return;\n rememberAddresses(addresses);\n setSending(true);\n setReport(null);\n try {\n const result = await storage.sendTest({\n mjml: editor.exportMjml(),\n subject: meta.subject,\n preheader: meta.preheader,\n emails,\n });\n setReport(result);\n if (result.failed > 0) notify('warning', t('{sent} sent, {failed} failed.', { sent: result.sent, failed: result.failed }));\n else notify('success', t('{sent} test(s) sent — check your inbox.', { sent: result.sent }));\n } catch (error) {\n notify('error', error.message);\n } finally {\n setSending(false);\n }\n };\n\n return (\n <>\n <Button\n variant=\"outline\"\n size=\"sm-compact\"\n disabled={!ready}\n onClick={() => {\n setAddresses(readAddresses(testRecipients.join(', ')));\n setReport(null);\n setOpen(true);\n }}\n >\n <Send />\n {t('Test')}\n </Button>\n <Dialog open={open} onOpenChange={setOpen}>\n <DialogContent className=\"eb:sm:max-w-[460px]\">\n <DialogHeader>\n <div className=\"eb:flex eb:items-center eb:gap-3\">\n <span className=\"eb:flex eb:size-10 eb:shrink-0 eb:items-center eb:justify-center eb:rounded-lg2 eb:bg-primary/10 eb:text-primary\">\n <Send className=\"eb:size-5\" />\n </span>\n <div>\n <DialogTitle className=\"eb:text-base eb:font-normal\">{t('Send a test')}</DialogTitle>\n <DialogDescription className=\"eb:text-[13px]\">{t('The email on screen, to reviewers’ addresses.')}</DialogDescription>\n </div>\n </div>\n </DialogHeader>\n <div className=\"eb:space-y-2\">\n <Label htmlFor=\"eb-test-addresses\">{t('Addresses')}</Label>\n <Textarea\n id=\"eb-test-addresses\"\n value={addresses}\n onChange={(e) => setAddresses(e.target.value)}\n placeholder=\"jane@example.com, john@example.com\"\n rows={3}\n />\n </div>\n {report && (\n <ul className=\"eb:space-y-1\" aria-label={t('Results')}>\n {report.results.map((r) => (\n <li key={r.email} className=\"eb:flex eb:items-start eb:gap-1.5 eb:text-[12px] eb:text-foreground\">\n {r.ok ? (\n <CheckCircle2 className=\"eb:mt-0.5 eb:size-3.5 eb:shrink-0 eb:text-success\" aria-hidden=\"true\" />\n ) : (\n <XCircle className=\"eb:mt-0.5 eb:size-3.5 eb:shrink-0 eb:text-destructive\" aria-hidden=\"true\" />\n )}\n <span className=\"eb:min-w-0 eb:break-all\">\n {r.email}\n {r.error ? ` — ${r.error}` : ''}\n </span>\n </li>\n ))}\n {report.invalid.map((email) => (\n <li key={`invalid-${email}`} className=\"eb:text-[12px] eb:text-foreground-muted\">\n {t('Ignored (invalid): {email}', { email })}\n </li>\n ))}\n </ul>\n )}\n <div className=\"eb:flex eb:justify-end eb:gap-2\">\n <Button variant=\"outline\" onClick={() => setOpen(false)}>\n {t('Close')}\n </Button>\n <Button onClick={send} disabled={sending || !emails.length}>\n {sending ? <Loader2 className=\"eb:animate-spin\" /> : <Send />}\n {t('Send')}\n </Button>\n </div>\n </DialogContent>\n </Dialog>\n </>\n );\n}\n","// @ts-check\n/**\n * TEST SEND feature (`TestEmailButton`) — rendering and sending by the server\n * (`sendTestEmail`). Shown when the storage can send tests.\n */\n\nimport TestEmailButton from './TestEmailButton.jsx';\n\n/** @type {import('../../core/EmailEditor.js').EmailBuilderFeature} */\nexport const testEmailFeature = {\n id: 'test-email',\n label: 'Send a test',\n order: 50,\n toolbar: TestEmailButton,\n isAvailable: (context) => typeof context.storage?.sendTest === 'function',\n};\n","import { useEffect, useMemo, useState } from 'react';\nimport { LayoutTemplate } from 'lucide-react';\nimport { useUi } from '../../ui/context.jsx';\nimport { Button } from '../../ui/primitives/button.jsx';\nimport { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from '../../ui/primitives/overlays.jsx';\nimport { withThumbnailImages } from './gallery.js';\n\n/**\n * TEMPLATE GALLERY — toolbar button and dialog.\n *\n * Each card shows the template as it renders: its MJML compiled by the canvas\n * compiler (`editor.exportHtml(mjml)`), displayed in an iframe with an EMPTY\n * sandbox and scaled down. Picking one REPLACES the email in the editor —\n * after confirmation when there are unsaved changes — and fills the subject\n * and preview text only when they are empty: what the user typed stays.\n *\n * A saved template that gets a new content counts as modified: it is the\n * next save that keeps it.\n */\n\nconst THUMBNAIL_SCALE = 0.38;\nconst EMAIL_WIDTH = 600;\n\nfunction Thumbnail({ html, title }) {\n return (\n <div\n className=\"eb:relative eb:h-[220px] eb:overflow-hidden eb:rounded-md eb:border eb:border-border eb:bg-surface-75\"\n aria-hidden=\"true\"\n >\n <iframe\n title={title}\n sandbox=\"\"\n srcDoc={html}\n tabIndex={-1}\n loading=\"lazy\"\n className=\"eb:pointer-events-none eb:absolute eb:top-0 eb:left-1/2 eb:origin-top eb:border-0\"\n style={{\n width: EMAIL_WIDTH,\n height: 220 / THUMBNAIL_SCALE,\n transform: `translateX(-50%) scale(${THUMBNAIL_SCALE})`,\n }}\n />\n </div>\n );\n}\n\nexport default function TemplateGalleryButton({ context }) {\n const { editor, ready, templates, isDirty, markDirty, template, setMeta } = context;\n const { t, confirm, notify } = useUi();\n const [open, setOpen] = useState(false);\n\n // Thumbnails compiled when the dialog opens (MJML compiles asynchronously).\n const [rendered, setRendered] = useState({});\n useEffect(() => {\n if (!open || !ready) return undefined;\n let alive = true;\n Promise.all(\n templates.map(async (entry) => {\n try {\n return [entry.id, (await editor.exportHtml(withThumbnailImages(entry.mjml))).html];\n } catch {\n return [entry.id, ''];\n }\n })\n ).then((pairs) => {\n if (alive) setRendered(Object.fromEntries(pairs));\n });\n return () => {\n alive = false;\n };\n }, [open, ready, templates, editor]);\n const cards = useMemo(\n () => (open ? templates.map((entry) => ({ ...entry, html: rendered[entry.id] ?? '' })) : []),\n [open, templates, rendered]\n );\n\n const apply = async (entry) => {\n if (isDirty()) {\n setOpen(false);\n const ok = await confirm({\n title: t('Replace the current email?'),\n description: t('Unsaved changes will be replaced.'),\n confirmLabel: t('Replace'),\n destructive: true,\n });\n if (!ok) return;\n }\n editor.loadMjml(entry.mjml);\n setMeta((meta) => ({\n ...meta,\n subject: meta.subject || entry.subject,\n preheader: meta.preheader || entry.preheader,\n }));\n if (template.id) markDirty();\n setOpen(false);\n notify('success', t('“{name}” template applied.', { name: entry.name }));\n };\n\n return (\n <>\n <Button variant=\"outline\" size=\"sm-compact\" disabled={!ready} onClick={() => setOpen(true)}>\n <LayoutTemplate />\n {t('Templates')}\n </Button>\n <Dialog open={open} onOpenChange={setOpen}>\n <DialogContent className=\"eb:max-h-[calc(100dvh-2rem)] eb:overflow-y-auto eb:sm:max-w-4xl\" data-testid=\"eb-template-gallery\">\n <DialogHeader>\n <DialogTitle>{t('Start from a template')}</DialogTitle>\n <DialogDescription>{t('Picking a template replaces the email being edited.')}</DialogDescription>\n </DialogHeader>\n <ul className=\"eb:grid eb:grid-cols-1 eb:gap-3 eb:sm:grid-cols-2 eb:md:grid-cols-3\">\n {cards.map((card) => (\n <li key={card.id}>\n <button\n type=\"button\"\n onClick={() => apply(card)}\n data-template-id={card.id}\n className=\"eb:group eb:flex eb:w-full eb:flex-col eb:gap-2 eb:rounded-lg2 eb:border eb:border-border eb:bg-background eb:p-2 eb:text-left eb:transition-colors eb:hover:border-primary/50 eb:hover:bg-primary/5 eb:focus-visible:outline-none eb:focus-visible:ring-2 eb:focus-visible:ring-ring/50\"\n >\n <Thumbnail html={card.html} title={card.name} />\n <span className=\"eb:px-1\">\n <span className=\"eb:block eb:text-[13px] eb:font-medium eb:text-foreground\">{card.name}</span>\n <span className=\"eb:block eb:text-[12px] eb:text-foreground-muted\">{card.description}</span>\n </span>\n </button>\n </li>\n ))}\n </ul>\n </DialogContent>\n </Dialog>\n </>\n );\n}\n","// @ts-check\n/**\n * TEMPLATES feature: the gallery of ready-made emails (`TemplateGalleryButton`).\n * Shown when the builder has templates to offer (`templates` prop, `[]` hides\n * it).\n */\n\nimport TemplateGalleryButton from './TemplateGallery.jsx';\n\n/** @type {import('../../core/EmailEditor.js').EmailBuilderFeature} */\nexport const templatesFeature = {\n id: 'templates',\n label: 'Templates',\n order: 5,\n toolbar: TemplateGalleryButton,\n isAvailable: (context) => Array.isArray(context.templates) && context.templates.length > 0,\n};\n","import { useEffect, useMemo, useRef, useState } from 'react';\nimport { Check, Loader2, Search, Sparkles, TriangleAlert } from 'lucide-react';\nimport { useUi } from '../../ui/context.jsx';\nimport { Button } from '../../ui/primitives/button.jsx';\nimport { Input, Textarea } from '../../ui/primitives/fields.jsx';\nimport { SectionLabel } from '../../ui/primitives/misc.jsx';\nimport { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from '../../ui/primitives/overlays.jsx';\nimport { chipClassName } from './chip.js';\nimport { MAX_DETAILS_LENGTH } from './generator.js';\nimport { purposesByCategory } from './purposes.js';\nimport { brandTemplate, hasBrand } from '../brand/brand.js';\n\n/**\n * GENERATE — toolbar button and dialog: an email written from scratch.\n *\n * One decision for the user: what the email is for (a badge). Details are\n * optional; the language is the interface's, the sender and the variables\n * are the builder's own. The dialog says up front that the email in the\n * editor will be replaced — no confirmation after a minute of waiting.\n *\n * The result REPLACES the email in the editor, subject and preview text\n * included (they belong to the new email); the name is filled when empty.\n * A saved template counts as modified: the next save keeps it.\n */\n\n/** Lowercase, without accents: \"Été\" matches \"ete\". @param {string} text */\nconst fold = (text) =>\n text\n .normalize('NFD')\n .replace(/[̀-ͯ]/g, '')\n .toLowerCase();\n\nexport default function GenerateButton({ context }) {\n const { editor, ready, storage, isDirty, markDirty, template, setMeta, variables, sender, brand } = context;\n const { t, locale, notify } = useUi();\n const [open, setOpen] = useState(false);\n const [purpose, setPurpose] = useState(/** @type {string|null} */ (null));\n const [details, setDetails] = useState('');\n const [query, setQuery] = useState('');\n const [busy, setBusy] = useState(false);\n const [error, setError] = useState('');\n const [seconds, setSeconds] = useState(0);\n const [dirty, setDirty] = useState(false);\n const abortRef = useRef(/** @type {AbortController|null} */ (null));\n const searchRef = useRef(/** @type {HTMLInputElement|null} */ (null));\n\n useEffect(() => () => abortRef.current?.abort(), []);\n useEffect(() => {\n if (!busy) return undefined;\n setSeconds(0);\n const timer = setInterval(() => setSeconds((s) => s + 1), 1000);\n return () => clearInterval(timer);\n }, [busy]);\n\n const groups = useMemo(() => {\n const words = fold(query.trim()).split(/\\s+/).filter(Boolean);\n return purposesByCategory()\n .map((group) => ({\n ...group,\n purposes: group.purposes.filter((entry) => {\n const label = fold(`${t(entry.label)} ${entry.label} ${t(group.label)}`);\n return words.every((word) => label.includes(word));\n }),\n }))\n .filter((group) => group.purposes.length > 0);\n }, [query, t]);\n\n const openDialog = () => {\n setError('');\n setDirty(isDirty());\n setOpen(true);\n };\n\n const close = (next) => {\n if (next) return;\n abortRef.current?.abort();\n setOpen(false);\n };\n\n const generate = async () => {\n if (busy || (!purpose && !details.trim())) return;\n setError('');\n setBusy(true);\n const controller = new AbortController();\n abortRef.current = controller;\n try {\n const email = await storage.generate(\n {\n purpose,\n details: details.trim(),\n language: String(locale || 'en').slice(0, 2),\n sender: sender || {},\n ...(hasBrand(brand) ? { brand: { primary: brand.primary, heading: brand.heading, font: brand.font } } : {}),\n variables: (variables || []).map((variable) => ({ key: variable.key, label: variable.label })),\n },\n { signal: controller.signal }\n );\n if (controller.signal.aborted) return;\n // The brand's logo where the model wrote the name (an uploaded logo\n // is not an https address the model may be given).\n editor.loadMjml(hasBrand(brand) ? brandTemplate(email.mjml, brand, { sender, t }) : email.mjml);\n setMeta((meta) => ({\n ...meta,\n name: meta.name || email.name,\n subject: email.subject || meta.subject,\n preheader: email.preheader || meta.preheader,\n }));\n if (template.id) markDirty();\n setOpen(false);\n notify('success', t('Your email is ready. Edit anything, then save.'));\n } catch (err) {\n if (!controller.signal.aborted) setError(t(err?.message || 'The email could not be generated.'));\n } finally {\n if (abortRef.current === controller) abortRef.current = null;\n setBusy(false);\n }\n };\n\n const cancel = () => {\n abortRef.current?.abort();\n setBusy(false);\n };\n\n const canGenerate = Boolean(purpose || details.trim());\n\n return (\n <>\n <Button variant=\"outline\" size=\"sm-compact\" disabled={!ready} onClick={openDialog}>\n <Sparkles />\n {t('Generate')}\n </Button>\n <Dialog open={open} onOpenChange={close}>\n <DialogContent\n className=\"eb:flex eb:max-h-[calc(100dvh-2rem)] eb:flex-col eb:gap-0 eb:p-0 eb:sm:max-w-2xl\"\n data-testid=\"eb-generate\"\n onOpenAutoFocus={(event) => {\n // The search field rather than the first badge.\n event.preventDefault();\n searchRef.current?.focus();\n }}\n >\n <DialogHeader className=\"eb:gap-1.5 eb:px-6 eb:pt-6 eb:pb-3\">\n <DialogTitle>{t('Generate an email')}</DialogTitle>\n <DialogDescription>{t('Pick what it is for. AI writes a complete email that opens here, ready to edit.')}</DialogDescription>\n </DialogHeader>\n\n <div className=\"eb:px-6 eb:pb-3\">\n <div className=\"eb:relative\">\n <Search className=\"eb:pointer-events-none eb:absolute eb:top-1/2 eb:left-2.5 eb:size-3.5 eb:-translate-y-1/2 eb:text-foreground-muted\" aria-hidden=\"true\" />\n <Input\n ref={searchRef}\n type=\"search\"\n value={query}\n onChange={(event) => setQuery(event.target.value)}\n placeholder={t('Search: sale, password, birthday…')}\n aria-label={t('Search')}\n className=\"eb:pl-8\"\n disabled={busy}\n />\n </div>\n </div>\n\n {/* The scroll box is a div: a fieldset does not clip its overflow\n as a flex item, and the badges would run under the footer. */}\n <div className=\"eb:min-h-0 eb:flex-1 eb:overflow-y-auto eb:border-y eb:border-border eb:px-6 eb:py-4\" data-testid=\"eb-generate-purposes\">\n <fieldset disabled={busy} className=\"eb:m-0 eb:min-w-0 eb:border-0 eb:p-0\">\n <legend className=\"eb:sr-only\">{t('What is the email for?')}</legend>\n {groups.length === 0 && (\n <p className=\"eb:py-6 eb:text-center eb:text-[13px] eb:text-foreground-muted\">\n {t('Nothing matches. Describe your email in the details below.')}\n </p>\n )}\n <div className=\"eb:flex eb:flex-col eb:gap-4\">\n {groups.map((group) => (\n <section key={group.id} className=\"eb:flex eb:flex-col eb:gap-2\" aria-label={t(group.label)}>\n <SectionLabel>{t(group.label)}</SectionLabel>\n <div className=\"eb:flex eb:flex-wrap eb:gap-1.5\">\n {group.purposes.map((entry) => {\n const selected = purpose === entry.id;\n return (\n <button\n key={entry.id}\n type=\"button\"\n aria-pressed={selected}\n data-purpose={entry.id}\n onClick={() => setPurpose(selected ? null : entry.id)}\n className={chipClassName(selected)}\n >\n {selected && <Check className=\"eb:size-3\" aria-hidden=\"true\" />}\n {t(entry.label)}\n </button>\n );\n })}\n </div>\n </section>\n ))}\n </div>\n </fieldset>\n </div>\n\n <div className=\"eb:flex eb:flex-col eb:gap-3 eb:px-6 eb:pt-3 eb:pb-6\">\n <Textarea\n value={details}\n onChange={(event) => setDetails(event.target.value.slice(0, MAX_DETAILS_LENGTH))}\n placeholder={t('Details (optional): product, dates, offer, tone, language…')}\n aria-label={t('Details (optional)')}\n rows={2}\n className=\"eb:min-h-14\"\n disabled={busy}\n onKeyDown={(event) => {\n if (event.key === 'Enter' && (event.metaKey || event.ctrlKey)) generate();\n }}\n />\n {error ? (\n <p role=\"alert\" className=\"eb:flex eb:items-start eb:gap-1.5 eb:text-[12px] eb:text-destructive\">\n <TriangleAlert className=\"eb:mt-px eb:size-3.5 eb:shrink-0\" aria-hidden=\"true\" />\n {error}\n </p>\n ) : (\n dirty &&\n !busy && (\n <p className=\"eb:text-[12px] eb:text-foreground-muted\">{t('The email being edited will be replaced, unsaved changes included.')}</p>\n )\n )}\n <div className=\"eb:flex eb:items-center eb:justify-end eb:gap-2\">\n {busy && (\n <p className=\"eb:mr-auto eb:text-[12px] eb:text-foreground-muted\" role=\"status\" aria-live=\"polite\">\n {t('Writing your email… {seconds} s', { seconds })}\n </p>\n )}\n {busy && (\n <Button variant=\"outline\" size=\"sm\" onClick={cancel}>\n {t('Cancel')}\n </Button>\n )}\n <Button size=\"sm\" onClick={generate} disabled={!canGenerate || busy} data-testid=\"eb-generate-submit\">\n {busy ? <Loader2 className=\"eb:animate-spin\" /> : <Sparkles />}\n {t('Generate')}\n </Button>\n </div>\n </div>\n </DialogContent>\n </Dialog>\n </>\n );\n}\n","import { cn } from '../../ui/primitives/cn.js';\n\n/**\n * A rounded badge button: the purposes of \"Generate\", the rewrite actions.\n * @param {boolean} [selected]\n */\nexport const chipClassName = (selected = false) =>\n cn(\n 'eb:inline-flex eb:h-7 eb:items-center eb:gap-1 eb:rounded-full eb:border eb:px-3 eb:text-[12px] eb:font-medium eb:transition-colors eb:outline-none eb:focus-visible:ring-[3px] eb:focus-visible:ring-ring/50 eb:disabled:opacity-50',\n selected\n ? 'eb:border-primary eb:bg-primary eb:text-primary-foreground'\n : 'eb:border-border eb:bg-background eb:text-foreground eb:hover:border-primary/50 eb:hover:bg-primary/5'\n );\n","// @ts-check\n/**\n * GENERATE feature: an email written from scratch by AI, from what it is for\n * (`GenerateButton`). Shown when the storage can generate — the host decides,\n * since generation needs a model and its key (see `createEmailGenerator`).\n */\n\nimport GenerateButton from './GenerateButton.jsx';\n\n/** @type {import('../../core/EmailEditor.js').EmailBuilderFeature} */\nexport const generateFeature = {\n id: 'generate',\n label: 'Generate',\n order: 4,\n toolbar: GenerateButton,\n isAvailable: (context) => typeof context.storage?.generate === 'function',\n};\n","import { useEffect, useRef, useState } from 'react';\nimport { Globe, ImageOff, Loader2, Palette, Trash2, TriangleAlert, Upload, WandSparkles } from 'lucide-react';\nimport { useUi } from '../../ui/context.jsx';\nimport { Button } from '../../ui/primitives/button.jsx';\nimport { Input, Label } from '../../ui/primitives/fields.jsx';\nimport { ColorPicker } from '../../ui/primitives/color-picker.jsx';\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogHeader,\n DialogTitle,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '../../ui/primitives/overlays.jsx';\nimport { cn } from '../../ui/primitives/cn.js';\nimport { FONT_OPTIONS, FONT_STACK, PALETTE } from '../../blocks/shared.js';\nimport { imageUploadError } from '../../validation/images.js';\nimport { isSafeUrl } from '../../validation/urls.js';\nimport { logoWidthFor } from './extract.js';\nimport { applyBrand, cleanBrand, contrastRatio, hasBrand, readableOn } from './brand.js';\nimport { BRAND_NOTES } from './messages.js';\n\n/**\n * BRAND — toolbar button and dialog: the company's look, set once.\n *\n * The quickest way is the first field: the company's website, read by the\n * server (logo, colors, font filled in, nothing saved yet). Everything can\n * then be changed by hand, and the small preview shows the result at once.\n *\n * Saving keeps the brand for every new email, template and block, and (the\n * box is ticked by default) repaints the email being edited: one step, Ctrl+Z\n * brings the previous look back.\n */\n\n\n/** @typedef {import('./brand.js').Brand} Brand */\n\n/** The form's text fields: '' rather than undefined, so inputs stay controlled. */\nconst toForm = (/** @type {Brand} */ brand) => ({\n name: brand.name || '',\n logoUrl: brand.logoUrl || '',\n logoWidth: brand.logoWidth || 0,\n primary: brand.primary || '',\n heading: brand.heading || '',\n font: brand.font || '',\n website: brand.website || '',\n});\n\n/** A logo address the builder accepts: uploaded (relative) or https. @param {string} url */\nconst isLogoUrl = (url) => !url || url.startsWith('/') || (/^https:\\/\\//i.test(url) && isSafeUrl(url, 'image'));\n\nexport default function BrandButton({ context }) {\n const { editor, ready, storage, brand, setBrand, hostSender } = context;\n const { t, notify } = useUi();\n const [open, setOpen] = useState(false);\n const [form, setForm] = useState(() => toForm(brand || {}));\n const [applyNow, setApplyNow] = useState(true);\n const [reading, setReading] = useState(false);\n const [readError, setReadError] = useState('');\n const [notes, setNotes] = useState(/** @type {string[]} */ ([]));\n const [uploading, setUploading] = useState(false);\n const [saving, setSaving] = useState(false);\n const [error, setError] = useState('');\n const abortRef = useRef(/** @type {AbortController|null} */ (null));\n const fileRef = useRef(/** @type {HTMLInputElement|null} */ (null));\n const canRead = typeof storage.importBrand === 'function';\n const canUpload = typeof storage.uploadImage === 'function';\n\n useEffect(() => () => abortRef.current?.abort(), []);\n\n // The width a logo is shown at follows its own proportions.\n const logoUrl = form.logoUrl;\n useEffect(() => {\n if (!logoUrl || !isLogoUrl(logoUrl)) return undefined;\n let live = true;\n const image = new Image();\n image.onload = () => {\n if (live && image.naturalWidth) {\n setForm((f) => (f.logoUrl === logoUrl ? { ...f, logoWidth: logoWidthFor({ width: image.naturalWidth, height: image.naturalHeight }) } : f));\n }\n };\n image.src = logoUrl;\n return () => {\n live = false;\n };\n }, [logoUrl]);\n\n const set = (/** @type {Partial<ReturnType<typeof toForm>>} */ patch) => setForm((f) => ({ ...f, ...patch }));\n\n const openDialog = () => {\n setForm(toForm(brand || {}));\n setApplyNow(true);\n setReadError('');\n setNotes([]);\n setError('');\n setOpen(true);\n };\n\n const close = (/** @type {boolean} */ next) => {\n if (next) return;\n abortRef.current?.abort();\n setReading(false);\n setOpen(false);\n };\n\n const readWebsite = async () => {\n const url = form.website.trim();\n if (!url || reading) return;\n setReadError('');\n setNotes([]);\n setReading(true);\n const controller = new AbortController();\n abortRef.current = controller;\n try {\n const result = await storage.importBrand(url, { signal: controller.signal });\n if (controller.signal.aborted) return;\n const found = cleanBrand(result?.brand);\n // What the website did not give keeps what the user had.\n setForm((f) => ({\n ...f,\n ...Object.fromEntries(Object.entries(toForm(found)).filter(([, value]) => value)),\n website: found.website || f.website,\n }));\n setNotes(Array.isArray(result?.notes) ? result.notes.filter((note) => note in BRAND_NOTES) : []);\n } catch (err) {\n if (!controller.signal.aborted) setReadError(err?.message ? t(err.message) : t('The website could not be read.'));\n } finally {\n if (abortRef.current === controller) abortRef.current = null;\n setReading(false);\n }\n };\n\n const pickLogo = async (/** @type {import('react').ChangeEvent<HTMLInputElement>} */ event) => {\n const file = event.target.files?.[0];\n event.target.value = '';\n if (!file) return;\n const refused = imageUploadError(file, { t });\n setError(refused || '');\n if (refused) return;\n setUploading(true);\n try {\n const { path } = await storage.uploadImage(file);\n set({ logoUrl: path, logoWidth: 0 });\n setNotes((list) => list.filter((note) => !note.startsWith('LOGO_')));\n } catch (err) {\n setError(err?.message || t('Upload failed'));\n } finally {\n setUploading(false);\n }\n };\n\n const draft = cleanBrand(form);\n const logoInvalid = !isLogoUrl(form.logoUrl.trim());\n\n const save = async () => {\n if (saving || logoInvalid) return;\n setSaving(true);\n setError('');\n try {\n const saved = cleanBrand(await storage.saveBrand(draft));\n const before = brand || {};\n setBrand(saved);\n let applied = false;\n if (applyNow && ready && hasBrand(saved)) {\n const current = editor.exportMjml();\n const next = applyBrand(current, saved, {\n header: true,\n previous: {\n names: [hostSender?.name, before.name, t('Your company')],\n logos: [hostSender?.logoUrl, before.logoUrl],\n },\n });\n if (next !== current) {\n editor.setMjml(next);\n applied = true;\n }\n }\n setOpen(false);\n notify(\n 'success',\n applied ? t('Brand applied. Ctrl+Z brings back the previous look.') : t('Brand saved. New emails and blocks use it.')\n );\n } catch (err) {\n setError(err?.message || t('The brand could not be saved.'));\n } finally {\n setSaving(false);\n }\n };\n\n const swatch = brand?.primary;\n\n return (\n <>\n <Button variant=\"outline\" size=\"sm-compact\" disabled={!ready} onClick={openDialog} data-testid=\"eb-brand-button\">\n <Palette />\n {t('Brand')}\n {swatch && (\n <span\n aria-hidden=\"true\"\n className=\"eb:size-2.5 eb:shrink-0 eb:rounded-full eb:ring-1 eb:ring-black/10\"\n style={{ backgroundColor: swatch }}\n />\n )}\n </Button>\n <Dialog open={open} onOpenChange={close}>\n <DialogContent\n className=\"eb:flex eb:max-h-[calc(100dvh-2rem)] eb:flex-col eb:gap-0 eb:p-0 eb:sm:max-w-2xl\"\n data-testid=\"eb-brand\"\n >\n <DialogHeader className=\"eb:gap-1.5 eb:px-6 eb:pt-6 eb:pb-4\">\n <DialogTitle>{t('Your brand')}</DialogTitle>\n <DialogDescription>\n {t('Set it once: new emails, templates and blocks take your logo, colors and font.')}\n </DialogDescription>\n </DialogHeader>\n\n <div className=\"eb:min-h-0 eb:flex-1 eb:overflow-y-auto eb:border-y eb:border-border eb:px-6 eb:py-5\">\n {canRead && (\n <form\n className=\"eb:mb-5 eb:flex eb:flex-col eb:gap-1.5\"\n onSubmit={(event) => {\n event.preventDefault();\n readWebsite();\n }}\n >\n <Label htmlFor=\"eb-brand-website\">{t('Your website')}</Label>\n <div className=\"eb:flex eb:flex-col eb:gap-2 eb:sm:flex-row\">\n <div className=\"eb:relative eb:min-w-0 eb:flex-1\">\n <Globe className=\"eb:pointer-events-none eb:absolute eb:top-1/2 eb:left-2.5 eb:size-3.5 eb:-translate-y-1/2 eb:text-foreground-muted\" aria-hidden=\"true\" />\n <Input\n id=\"eb-brand-website\"\n value={form.website}\n onChange={(event) => set({ website: event.target.value })}\n placeholder=\"acme.com\"\n inputMode=\"url\"\n autoComplete=\"url\"\n className=\"eb:pl-8\"\n disabled={reading}\n />\n </div>\n <Button type=\"submit\" size=\"sm\" disabled={reading || !form.website.trim()}>\n {reading ? <Loader2 className=\"eb:animate-spin\" /> : <WandSparkles />}\n {t('Get my brand')}\n </Button>\n </div>\n {reading ? (\n <p role=\"status\" className=\"eb:text-[12px] eb:text-foreground-muted\">\n {t('Reading the website…')}\n </p>\n ) : readError ? (\n <p role=\"alert\" className=\"eb:flex eb:items-start eb:gap-1.5 eb:text-[12px] eb:text-destructive\">\n <TriangleAlert className=\"eb:mt-px eb:size-3.5 eb:shrink-0\" aria-hidden=\"true\" />\n {readError}\n </p>\n ) : notes.length ? (\n <ul className=\"eb:flex eb:flex-col eb:gap-1 eb:text-[12px] eb:text-foreground-muted\" data-testid=\"eb-brand-notes\">\n {notes.map((note) => (\n <li key={note}>{t(BRAND_NOTES[note])}</li>\n ))}\n </ul>\n ) : (\n <p className=\"eb:text-[12px] eb:text-foreground-muted\">\n {t('The logo, colors and font are read from it. You can change them before saving.')}\n </p>\n )}\n </form>\n )}\n\n <div className=\"eb:grid eb:gap-6 eb:sm:grid-cols-[minmax(0,1fr)_220px]\">\n <fieldset disabled={reading} className=\"eb:m-0 eb:flex eb:min-w-0 eb:flex-col eb:gap-4 eb:border-0 eb:p-0\">\n <legend className=\"eb:sr-only\">{t('Your brand')}</legend>\n\n <div className=\"eb:flex eb:flex-col eb:gap-1.5\">\n <Label htmlFor=\"eb-brand-logo\">{t('Logo')}</Label>\n <div className=\"eb:flex eb:items-center eb:gap-3\">\n <div className=\"eb-checker eb:flex eb:h-12 eb:w-24 eb:shrink-0 eb:items-center eb:justify-center eb:overflow-hidden eb:rounded-lg2 eb:ring-1 eb:ring-border eb:ring-inset\">\n {form.logoUrl && !logoInvalid ? (\n <img src={form.logoUrl} alt={t('Logo')} className=\"eb:max-h-10 eb:max-w-20 eb:object-contain\" />\n ) : (\n <ImageOff className=\"eb:size-4 eb:text-foreground-muted\" aria-hidden=\"true\" />\n )}\n </div>\n <div className=\"eb:flex eb:flex-wrap eb:gap-2\">\n {canUpload && (\n <>\n <input\n ref={fileRef}\n type=\"file\"\n accept=\"image/png,image/jpeg,image/gif\"\n className=\"eb:sr-only\"\n tabIndex={-1}\n aria-hidden=\"true\"\n data-testid=\"eb-brand-logo-file\"\n onChange={pickLogo}\n />\n <Button type=\"button\" variant=\"outline\" size=\"sm\" disabled={uploading} onClick={() => fileRef.current?.click()}>\n {uploading ? <Loader2 className=\"eb:animate-spin\" /> : <Upload />}\n {t('Upload')}\n </Button>\n </>\n )}\n {form.logoUrl && (\n <Button type=\"button\" variant=\"ghost\" size=\"sm\" onClick={() => set({ logoUrl: '', logoWidth: 0 })}>\n <Trash2 />\n {t('Remove')}\n </Button>\n )}\n </div>\n </div>\n <Input\n id=\"eb-brand-logo\"\n value={form.logoUrl}\n onChange={(event) => set({ logoUrl: event.target.value.trim(), logoWidth: 0 })}\n placeholder={t('or an image address: https://…')}\n aria-invalid={logoInvalid || undefined}\n className=\"eb:text-[12px]\"\n />\n {logoInvalid && <p className=\"eb:text-[12px] eb:text-destructive\">{t('An https:// address is required')}</p>}\n </div>\n\n <div className=\"eb:flex eb:flex-col eb:gap-1.5\">\n <Label htmlFor=\"eb-brand-name\">{t('Company name')}</Label>\n <Input\n id=\"eb-brand-name\"\n value={form.name}\n maxLength={80}\n onChange={(event) => set({ name: event.target.value })}\n placeholder={hostSender?.name || t('Your company')}\n />\n </div>\n\n <div className=\"eb:grid eb:gap-4 eb:sm:grid-cols-2\">\n <div className=\"eb:flex eb:flex-col eb:gap-1.5\">\n <Label htmlFor=\"eb-brand-primary\">{t('Main color')}</Label>\n <ColorPicker id=\"eb-brand-primary\" value={form.primary} onChange={(primary) => set({ primary })} placeholder={PALETTE.navy} />\n <p className=\"eb:text-[11px] eb:text-foreground-muted\">{t('Buttons, banners, links')}</p>\n </div>\n <div className=\"eb:flex eb:flex-col eb:gap-1.5\">\n <Label htmlFor=\"eb-brand-heading\">{t('Headings color')}</Label>\n <ColorPicker id=\"eb-brand-heading\" value={form.heading} onChange={(heading) => set({ heading })} placeholder={PALETTE.navy} />\n </div>\n </div>\n\n <div className=\"eb:flex eb:flex-col eb:gap-1.5\">\n <Label htmlFor=\"eb-brand-font\">{t('Font')}</Label>\n <Select value={form.font || FONT_STACK} onValueChange={(font) => set({ font })}>\n <SelectTrigger id=\"eb-brand-font\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {FONT_OPTIONS.map((option) => (\n <SelectItem key={option.value} value={option.value}>\n <span style={{ fontFamily: option.value }}>{option.label}</span>\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n </fieldset>\n\n <BrandPreview brand={draft} fallbackName={hostSender?.name || t('Your company')} />\n </div>\n </div>\n\n <div className=\"eb:flex eb:flex-col eb:gap-3 eb:px-6 eb:pt-3 eb:pb-6\">\n {error && (\n <p role=\"alert\" className=\"eb:flex eb:items-start eb:gap-1.5 eb:text-[12px] eb:text-destructive\">\n <TriangleAlert className=\"eb:mt-px eb:size-3.5 eb:shrink-0\" aria-hidden=\"true\" />\n {error}\n </p>\n )}\n <div className=\"eb:flex eb:flex-col eb:gap-3 eb:sm:flex-row eb:sm:items-center\">\n <label className=\"eb:flex eb:cursor-pointer eb:items-center eb:gap-2 eb:text-[13px] eb:sm:mr-auto\">\n <input\n type=\"checkbox\"\n checked={applyNow}\n onChange={(event) => setApplyNow(event.target.checked)}\n className=\"eb:size-4 eb:accent-primary\"\n data-testid=\"eb-brand-apply\"\n />\n {t('Also apply to this email')}\n </label>\n <div className=\"eb:flex eb:justify-end eb:gap-2\">\n <Button variant=\"outline\" size=\"sm\" onClick={() => close(false)}>\n {t('Cancel')}\n </Button>\n <Button size=\"sm\" onClick={save} disabled={saving || reading || uploading || logoInvalid} data-testid=\"eb-brand-save\">\n {saving && <Loader2 className=\"eb:animate-spin\" />}\n {t('Save')}\n </Button>\n </div>\n </div>\n </div>\n </DialogContent>\n </Dialog>\n </>\n );\n}\n\n/**\n * A small email in the brand's look: logo or name, a banner, a heading, a\n * line of text and a button. Plain markup: it follows every keystroke.\n * @param {{brand: Brand, fallbackName: string}} props\n */\nfunction BrandPreview({ brand, fallbackName }) {\n const t = useUi().t;\n const primary = brand.primary || PALETTE.navy;\n const onPrimary = readableOn(primary);\n const heading = brand.heading || PALETTE.navy;\n const link = contrastRatio(primary, PALETTE.white) >= 3 ? primary : heading;\n const font = brand.font || FONT_STACK;\n const name = brand.name || fallbackName;\n return (\n <div className=\"eb:flex eb:flex-col eb:gap-1.5\">\n <span className=\"eb:text-[12px] eb:font-medium eb:text-foreground-muted\">{t('Preview')}</span>\n <div\n className=\"eb:overflow-hidden eb:rounded-lg2 eb:p-2.5 eb:ring-1 eb:ring-border\"\n style={{ backgroundColor: PALETTE.canvas, fontFamily: font }}\n data-testid=\"eb-brand-preview\"\n aria-hidden=\"true\"\n >\n <div className=\"eb:overflow-hidden eb:rounded-[3px]\" style={{ backgroundColor: PALETTE.white }}>\n <div className=\"eb:px-3 eb:pt-3 eb:pb-2\">\n {brand.logoUrl ? (\n <img src={brand.logoUrl} alt=\"\" style={{ width: Math.round((brand.logoWidth || 140) * 0.45), maxWidth: '100%' }} />\n ) : (\n <span className=\"eb:text-[11px] eb:font-bold\" style={{ color: PALETTE.ink }}>\n {name}\n </span>\n )}\n </div>\n <div className=\"eb:px-3 eb:py-4 eb:text-center\" style={{ backgroundColor: primary, color: onPrimary }}>\n <div className=\"eb:text-[13px] eb:leading-tight eb:font-bold\">{t('Big news')}</div>\n <div className=\"eb:mt-1 eb:text-[9px] eb:opacity-90\">{t('A short line under the title.')}</div>\n </div>\n <div className=\"eb:flex eb:flex-col eb:gap-1.5 eb:px-3 eb:py-3\">\n <div className=\"eb:text-[11px] eb:leading-tight eb:font-bold\" style={{ color: heading }}>\n {t('A headline')}\n </div>\n <div className=\"eb:text-[9px] eb:leading-snug\" style={{ color: PALETTE.ink }}>\n {t('Some text, with')}{' '}\n <span className=\"eb:underline\" style={{ color: link }}>\n {t('a link')}\n </span>\n .\n </div>\n <span\n className={cn('eb:mt-1 eb:self-start eb:rounded-[3px] eb:px-2.5 eb:py-1 eb:text-[9px] eb:font-bold')}\n style={{ backgroundColor: primary, color: onPrimary }}\n >\n {t('Learn more')}\n </span>\n </div>\n <div className=\"eb:px-3 eb:pb-2.5 eb:text-center eb:text-[7px]\" style={{ color: '#6d7484' }}>\n {name}\n </div>\n </div>\n </div>\n </div>\n );\n}\n","import { useState } from 'react';\nimport { HexAlphaColorPicker } from 'react-colorful';\nimport { Check } from 'lucide-react';\nimport { useT } from '../context.jsx';\nimport { Input } from './fields.jsx';\nimport { Popover, PopoverContent, PopoverTrigger } from './overlays.jsx';\nimport { cn } from './cn.js';\n\nconst PRESET_COLORS = [\n '#8B5CF6', '#A78BFA', '#6366F1', '#3B82F6', '#06B6D4', '#17A2B8',\n '#10B981', '#22C55E', '#28A745', '#84CC16', '#EAB308', '#FFC107',\n '#F59E0B', '#F97316', '#EF4444', '#DC3545', '#EC4899', '#6B7280',\n];\n\n// Shown by the picker while the typed value is not a colour yet (\"#8B\", empty).\nconst FALLBACK_COLOR = '#8B5CF6';\n\nconst isValidHex = (v) => /^#([0-9A-Fa-f]{8}|[0-9A-Fa-f]{6}|[0-9A-Fa-f]{4}|[0-9A-Fa-f]{3})$/.test(v || '');\n\nfunction normalizeHex(v) {\n if (!v) return '';\n let s = v.trim();\n if (s && !s.startsWith('#')) s = `#${s}`;\n return s.toUpperCase();\n}\n\n/**\n * Colour field: a swatch opening a full-spectrum picker (with alpha), a hex\n * input and presets. `value` is `#RRGGBB` or `#RRGGBBAA`; `onChange(hex)`.\n */\nexport function ColorPicker({ value, onChange, id, className, placeholder = '' }) {\n const t = useT();\n const [open, setOpen] = useState(false);\n const valid = isValidHex(value);\n const normalized = valid ? normalizeHex(value) : '';\n const emit = (hex) => onChange(normalizeHex(hex));\n\n return (\n <div className={cn('eb:flex eb:gap-2', className)}>\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger asChild>\n <button\n type=\"button\"\n aria-label={t('Pick a colour')}\n title={t('Pick a colour')}\n className=\"eb-checker eb:relative eb:h-8 eb:w-[44px] eb:shrink-0 eb:overflow-hidden eb:rounded-lg2 eb:shadow-sm eb:ring-1 eb:ring-black/10 eb:ring-inset eb:transition-transform eb:hover:scale-[1.04]\"\n >\n {/* Empty: the colour MJML renders by default, faded. */}\n <span\n className=\"eb:absolute eb:inset-0\"\n style={{ backgroundColor: valid ? value : placeholder || 'transparent', opacity: valid ? 1 : 0.45 }}\n aria-hidden\n />\n </button>\n </PopoverTrigger>\n <PopoverContent align=\"start\" className=\"eb:w-64 eb:space-y-3 eb:p-3\">\n <div className=\"eb-picker\">\n <HexAlphaColorPicker color={valid ? value : FALLBACK_COLOR} onChange={emit} />\n </div>\n <div className=\"eb:flex eb:items-center eb:gap-2\">\n <span\n className=\"eb-checker eb:relative eb:size-8 eb:shrink-0 eb:overflow-hidden eb:rounded-lg2 eb:ring-1 eb:ring-black/10 eb:ring-inset\"\n aria-hidden\n >\n <span className=\"eb:absolute eb:inset-0\" style={{ backgroundColor: valid ? value : 'transparent' }} />\n </span>\n <Input\n value={value || ''}\n onChange={(e) => emit(e.target.value)}\n placeholder=\"#RRGGBB\"\n maxLength={9}\n aria-label={t('Hex code')}\n className=\"eb:h-8 eb:flex-1 eb:font-mono eb:text-[12px] eb:uppercase\"\n />\n </div>\n <div className=\"eb:grid eb:grid-cols-6 eb:gap-1.5 eb:border-t eb:border-border eb:pt-2.5\">\n {PRESET_COLORS.map((c) => (\n <button\n key={c}\n type=\"button\"\n onClick={() => onChange(c)}\n title={c}\n aria-label={c}\n className=\"eb:relative eb:size-6 eb:rounded-lg2 eb:ring-1 eb:ring-black/10 eb:ring-inset eb:transition-transform eb:hover:scale-110\"\n style={{ backgroundColor: c }}\n >\n {normalized === c && (\n <Check className=\"eb:absolute eb:inset-0 eb:m-auto eb:size-3.5 eb:text-white eb:drop-shadow-[0_1px_1px_rgba(0,0,0,0.6)]\" />\n )}\n </button>\n ))}\n </div>\n </PopoverContent>\n </Popover>\n <Input\n id={id}\n value={value || ''}\n onChange={(e) => onChange(e.target.value)}\n maxLength={9}\n placeholder={placeholder || '#RRGGBB'}\n className=\"eb:h-8 eb:flex-1 eb:font-mono eb:text-[13px]\"\n />\n </div>\n );\n}\n","// @ts-check\n/**\n * BRAND feature: the company's logo, colors and font, set once (`BrandButton`)\n * and used by every new email, template, block and generated email\n * (`brand.js`), optionally read from the company's website (the server's\n * `createBrandImporter`). Shown when the storage keeps a brand.\n */\n\nimport BrandButton from './BrandButton.jsx';\n\n/** @type {import('../../core/EmailEditor.js').EmailBuilderFeature} */\nexport const brandFeature = {\n id: 'brand',\n label: 'Brand',\n order: 6,\n toolbar: BrandButton,\n isAvailable: (context) => typeof context.storage?.saveBrand === 'function',\n};\n","// @ts-check\n/**\n * FEATURES REGISTRY — `emailBuilderFeatures`.\n *\n * A feature (templates, versions, preview, variables, test send…) is a self-contained\n * module. The interface asks this registry what to show; disabling an entry\n * (`enabled: false`) or removing it from here is enough to make it disappear.\n * A toolbar feature may also declare `isAvailable(context)`: the preview, for\n * instance, only appears when the storage can render.\n */\n\nimport { createRegistry } from '../core/registry.js';\nimport { autosaveFeature } from './autosave/index.js';\nimport { versionsFeature } from './versions/index.js';\nimport { variablesFeature } from './variables/index.js';\nimport { previewFeature } from './preview/index.js';\nimport { testEmailFeature } from './test-email/index.js';\nimport { templatesFeature } from './templates/index.js';\nimport { generateFeature } from './generate/index.js';\nimport { brandFeature } from './brand/index.js';\n\n/** @typedef {import('../core/EmailEditor.js').EmailBuilderFeature} EmailBuilderFeature */\n\n/** @type {EmailBuilderFeature[]} */\nconst FEATURES = [\n generateFeature,\n templatesFeature,\n brandFeature,\n variablesFeature,\n autosaveFeature,\n versionsFeature,\n previewFeature,\n testEmailFeature,\n];\n\nexport const emailBuilderFeatures = createRegistry('emailBuilderFeatures', FEATURES);\n\n/** Is a feature enabled? @param {string} id */\nexport function isFeatureEnabled(id) {\n const feature = emailBuilderFeatures.get(id);\n return Boolean(feature && feature.enabled !== false);\n}\n","// @ts-check\n/**\n * PLACEMENT — where a block goes, by click or by drag and drop.\n *\n * MJML enforces its hierarchy: body → section → column → content. So:\n * - a CONTENT block (text, image…) lives in a column. Clicked, it goes into\n * the selected column, after the selected element in its column, and\n * otherwise into a new one-column section (\"wrap\") after the selected\n * section or at the end of the email. Dropped, it goes where the drop\n * line shows: over a column, between two of its elements (beside a\n * shorter column, at its end); over a section's top or bottom padding,\n * or outside the sections, between two sections (wrapped in a new\n * section);\n * - a LAYOUT (a section) lives in the body: after the selected section, or\n * between two sections where it is dropped.\n *\n * Pure functions over the model and, for drops, over the boxes the canvas\n * measured — testable without a browser.\n */\n\nimport { SECTION_TAGS, closestOfTags, findFirst, findNode, pathTo } from './model.js';\n\n/** @typedef {import('./model.js').EmailNode} EmailNode */\n\n/** Containers whose children are content blocks. */\nexport const CONTENT_CONTAINERS = new Set(['mj-column', 'mj-hero']);\n\n/**\n * @typedef {{parentId: string, index: number, wrap: boolean}} Placement\n * `wrap`: the content must be wrapped in a new section first.\n */\n\n/**\n * Click placement.\n * @param {EmailNode} root\n * @param {'content'|'layout'} kind\n * @param {string|null} targetId selected element, if any\n * @returns {Placement}\n */\nexport function placementFor(root, kind, targetId) {\n const body = findFirst(root, 'mj-body');\n if (!body) throw new Error('The email has no body');\n const target = targetId ? findNode(root, targetId) : null;\n const section = target ? sectionOf(root, target.id, body) : null;\n const afterSection = () =>\n section\n ? { parentId: body.id, index: body.children.findIndex((c) => c.id === section.id) + 1 }\n : { parentId: body.id, index: body.children.length };\n\n if (kind === 'layout' || !target) return { ...afterSection(), wrap: kind !== 'layout' };\n\n if (CONTENT_CONTAINERS.has(target.tag)) return { parentId: target.id, index: target.children.length, wrap: false };\n const container = closestOfTags(root, target.id, CONTENT_CONTAINERS);\n if (container && container.id !== target.id) {\n // The container's direct child holding the target: insert after it.\n const path = /** @type {EmailNode[]} */ (pathTo(root, target.id));\n const child = path[path.indexOf(container) + 1];\n return { parentId: container.id, index: container.children.indexOf(child) + 1, wrap: false };\n }\n return { ...afterSection(), wrap: true };\n}\n\n/**\n * The body-level section holding a node (itself if it is one).\n * @param {EmailNode} root @param {string} id @param {EmailNode} body\n */\nexport function sectionOf(root, id, body) {\n const path = pathTo(root, id);\n if (!path) return null;\n const bodyIndex = path.indexOf(body);\n if (bodyIndex === -1 || bodyIndex === path.length - 1) return null;\n return path[bodyIndex + 1];\n}\n\n/**\n * @typedef {{top: number, bottom: number, left: number, right: number}} Box\n * @typedef {Placement & {line: {x: number, y: number, width: number}}} DropTarget\n * `line`: where the canvas draws the drop indicator (frame coordinates).\n */\n\n/**\n * Drop placement for a pointer at (x, y), in canvas frame coordinates.\n *\n * @param {EmailNode} root\n * @param {{kind: 'content'|'layout', nodeId?: string|null}} dragged\n * `nodeId`: the element being moved (it is skipped when measuring, and\n * cannot be dropped into itself)\n * @param {{x: number, y: number}} point\n * @param {string|null} hitId the marked element under the pointer\n * @param {(id: string) => Box|null} boxOf its box in the frame\n * @returns {DropTarget|null}\n */\nexport function dropTargetFor(root, dragged, point, hitId, boxOf) {\n const body = findFirst(root, 'mj-body');\n if (!body) return null;\n const skip = dragged.nodeId || null;\n\n if (dragged.kind === 'content') {\n const column = columnAt(root, point, hitId, boxOf, skip);\n if (column) return withinContainer(column, point, boxOf, skip);\n }\n return betweenSections(body, point, boxOf, skip, dragged.kind === 'content');\n}\n\n/**\n * The content container under the pointer: the one holding the hit element,\n * or, over a section's empty area beside a shorter column, the column whose\n * horizontal span holds the pointer.\n * @param {EmailNode} root @param {{x: number, y: number}} point @param {string|null} hitId\n * @param {(id: string) => Box|null} boxOf @param {string|null} skip\n */\nfunction columnAt(root, point, hitId, boxOf, skip) {\n if (!hitId) return null;\n // Over the element being moved: its own column (never inside itself).\n const moved = skip ? findNode(root, skip) : null;\n const overMoved = Boolean(moved && pathTo(moved, hitId));\n if (moved && overMoved && !CONTENT_CONTAINERS.has(moved.tag)) {\n const own = closestOfTags(root, moved.id, CONTENT_CONTAINERS);\n return own && own.id !== moved.id ? own : null;\n }\n const over = moved && overMoved ? moved.id : hitId;\n const direct = closestOfTags(root, over, CONTENT_CONTAINERS);\n if (direct) return direct;\n const section = closestOfTags(root, over, SECTION_TAGS);\n if (!section) return null;\n const columns = [];\n const collect = (/** @type {EmailNode} */ node) => {\n for (const child of node.children) {\n if (CONTENT_CONTAINERS.has(child.tag)) columns.push(child);\n else if (child.tag === 'mj-group') collect(child);\n }\n };\n collect(section);\n // The section's top and bottom paddings (above or below all its columns)\n // are the place BETWEEN sections: the drop makes a section of its own.\n const boxes = columns.map((column) => boxOf(column.id)).filter(Boolean);\n if (!boxes.length) return null;\n const top = Math.min(...boxes.map((b) => /** @type {Box} */ (b).top));\n const bottom = Math.max(...boxes.map((b) => /** @type {Box} */ (b).bottom));\n if (point.y < top || point.y > bottom) return null;\n // Beside a shorter column: that column.\n return columns.find((column) => {\n const box = boxOf(column.id);\n return box && point.x >= box.left && point.x <= box.right;\n }) || null;\n}\n\n/**\n * Between two children of a column, by the vertical middle of each.\n * @param {EmailNode} container @param {{x: number, y: number}} point\n * @param {(id: string) => Box|null} boxOf @param {string|null} skip\n * @returns {DropTarget|null}\n */\nfunction withinContainer(container, point, boxOf, skip) {\n const box = boxOf(container.id);\n if (!box) return null;\n const width = box.right - box.left;\n const children = container.children.map((child, index) => ({ child, index })).filter(({ child }) => child.id !== skip);\n for (const { child, index } of children) {\n const childBox = boxOf(child.id);\n if (childBox && point.y < (childBox.top + childBox.bottom) / 2) {\n return { parentId: container.id, index, wrap: false, line: { x: box.left, y: childBox.top, width } };\n }\n }\n const last = children.length ? boxOf(children[children.length - 1].child.id) : null;\n return {\n parentId: container.id,\n index: container.children.length,\n wrap: false,\n line: { x: box.left, y: last ? last.bottom : box.top + Math.min(24, (box.bottom - box.top) / 2), width },\n };\n}\n\n/**\n * Between two sections of the body, by the vertical middle of each.\n * @param {EmailNode} body @param {{x: number, y: number}} point\n * @param {(id: string) => Box|null} boxOf @param {string|null} skip @param {boolean} wrap\n * @returns {DropTarget|null}\n */\nfunction betweenSections(body, point, boxOf, skip, wrap) {\n const bodyBox = boxOf(body.id);\n const sections = body.children.map((child, index) => ({ child, index })).filter(({ child }) => child.id !== skip);\n let last = null;\n for (const { child, index } of sections) {\n const box = boxOf(child.id);\n if (!box) continue;\n last = box;\n if (point.y < (box.top + box.bottom) / 2) {\n return { parentId: body.id, index, wrap, line: { x: box.left, y: box.top, width: box.right - box.left } };\n }\n }\n const frame = last || bodyBox;\n if (!frame) return null;\n return {\n parentId: body.id,\n index: body.children.length,\n wrap,\n line: { x: frame.left, y: last ? last.bottom : frame.top + 24, width: frame.right - frame.left },\n };\n}\n","// @ts-check\n/**\n * RICH TEXT — what a text typed in the canvas may keep.\n *\n * The canvas edits text with the browser's own editing (contenteditable):\n * it can produce, or receive by paste, anything. Before it enters the model\n * the HTML is reduced to what an email and the server's validator accept:\n * the formatting tags of `INLINE_TAGS`, a few harmless attributes, safe\n * links. Other tags are unwrapped (their text stays), scripts and styles are\n * dropped with their content.\n *\n * Needs a DOM (the canvas frame's document).\n */\n\nimport { INLINE_TAGS } from '../validation/mjmlValidator.js';\nimport { isSafeUrl } from '../validation/urls.js';\n\nconst DROPPED_WITH_CONTENT = new Set(['script', 'style', 'iframe', 'object', 'embed', 'template', 'svg', 'math', 'head', 'title', 'meta', 'link']);\n\n/** Attributes kept, per tag (`*`: every allowed tag). */\nconst KEPT_ATTRIBUTES = {\n '*': new Set(['style']),\n a: new Set(['href', 'target', 'title', 'rel']),\n font: new Set(['color', 'face', 'size']),\n};\n\n/** CSS properties kept in a `style` attribute (formatting only, no layout tricks). */\nconst KEPT_STYLES = new Set([\n 'color',\n 'background-color',\n 'font-weight',\n 'font-style',\n 'font-size',\n 'font-family',\n 'text-decoration',\n 'text-align',\n 'line-height',\n 'letter-spacing',\n]);\n\n/** @param {string} style */\nfunction cleanStyle(style) {\n return style\n .split(';')\n .map((part) => part.trim())\n .filter(Boolean)\n .map((part) => {\n const colon = part.indexOf(':');\n if (colon === -1) return null;\n const name = part.slice(0, colon).trim().toLowerCase();\n const value = part.slice(colon + 1).trim();\n if (!KEPT_STYLES.has(name) || /expression|url\\s*\\(|javascript:/i.test(value)) return null;\n return `${name}:${value}`;\n })\n .filter(Boolean)\n .join(';');\n}\n\n/**\n * @param {Element} element\n */\nfunction cleanAttributes(element) {\n const tag = element.tagName.toLowerCase();\n const own = /** @type {Record<string, Set<string>>} */ (KEPT_ATTRIBUTES)[tag];\n for (const attribute of [...element.attributes]) {\n const name = attribute.name.toLowerCase();\n if (!KEPT_ATTRIBUTES['*'].has(name) && !(own && own.has(name))) {\n element.removeAttribute(attribute.name);\n continue;\n }\n if (name === 'href' && !isSafeUrl(attribute.value, 'link')) element.removeAttribute(attribute.name);\n if (name === 'style') {\n const style = cleanStyle(attribute.value);\n if (style) element.setAttribute('style', style);\n else element.removeAttribute('style');\n }\n }\n if (tag === 'a' && element.getAttribute('target') === '_blank') element.setAttribute('rel', 'noopener');\n}\n\n/** @param {Node} node */\nfunction cleanChildren(node) {\n for (const child of [...node.childNodes]) {\n if (child.nodeType === 8) {\n child.remove(); // comment\n continue;\n }\n if (child.nodeType !== 1) continue;\n const element = /** @type {Element} */ (child);\n const tag = element.tagName.toLowerCase();\n if (DROPPED_WITH_CONTENT.has(tag)) {\n element.remove();\n continue;\n }\n cleanChildren(element);\n if (!INLINE_TAGS.has(tag)) {\n // Unknown tag: keep its text, drop the tag.\n element.replaceWith(...element.childNodes);\n continue;\n }\n cleanAttributes(element);\n }\n}\n\n/**\n * @param {string} html\n * @param {Document} document any document (to parse without running anything)\n */\nexport function cleanRichText(html, document) {\n const template = document.createElement('template');\n template.innerHTML = String(html || '');\n cleanChildren(template.content);\n return template.innerHTML\n .replace(/<br>/g, '<br />')\n .replace(/(<br \\/>)+$/, '')\n .trim();\n}\n\n/**\n * Plain text, escaped, for a label (button, menu link).\n * @param {string} text\n */\nexport function escapeText(text) {\n return String(text ?? '')\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>');\n}\n\n/**\n * The text of an HTML fragment (`<br>` as a space), entities decoded.\n * @param {string} html\n */\nexport function textOfHtml(html) {\n return String(html || '')\n .replace(/<br\\s*\\/?>/gi, ' ')\n .replace(/<[^>]*>/g, '')\n .replace(/ /g, ' ')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/"/g, '\"')\n .replace(/'/g, \"'\")\n .replace(/&/g, '&')\n .trim();\n}\n","// @ts-check\n/**\n * CANVAS MJML — the email as the canvas compiles it.\n *\n * The canvas shows the REAL compiled email (mjml-browser), not an imitation:\n * what you see is the HTML Outlook, Gmail and Apple Mail will get. To find an\n * element of the model in that HTML, every element is marked through MJML's\n * own `css-class` attribute, which MJML copies onto the element's HTML box:\n *\n * eb-node eb-id-<id> eb-tag-<tag>\n *\n * Canvas-only additions, never in the exported MJML:\n * - an image without a file shows a grey frame saying where to choose one;\n * - an empty column shows \"Drop a block here\" (it would be zero pixels high\n * and impossible to drop into);\n * - an empty email shows the same hint in a section.\n * None of them carries an id: clicking them selects their container.\n */\n\nimport { serializeMjml } from './mjml.js';\n\n/** @typedef {import('./model.js').EmailNode} EmailNode */\n\n/** Elements that accept `css-class` (MJML copies it onto their HTML box). */\nconst MARKED_TAGS = new Set([\n 'mj-body',\n 'mj-wrapper',\n 'mj-section',\n 'mj-group',\n 'mj-column',\n 'mj-hero',\n 'mj-text',\n 'mj-image',\n 'mj-button',\n 'mj-divider',\n 'mj-spacer',\n 'mj-social',\n 'mj-social-element',\n 'mj-navbar',\n 'mj-navbar-link',\n 'mj-table',\n]);\n\nexport const NODE_CLASS = 'eb-node';\nexport const ID_CLASS_PREFIX = 'eb-id-';\nexport const TAG_CLASS_PREFIX = 'eb-tag-';\nexport const PLACEHOLDER_CLASS = 'eb-placeholder';\n\n/** @param {string} text */\nfunction escapeXml(text) {\n return String(text).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/\"/g, '"');\n}\n\n/**\n * Grey frame of an image without a file (an SVG data URL, canvas only),\n * drawn at the width it will be shown so its text stays readable in a narrow\n * column (it says where to choose the image only when there is room).\n * @param {string} label @param {number} [width]\n */\nexport function imagePlaceholder(label, width = 600) {\n const w = Math.max(80, Math.round(width));\n const h = w >= 360 ? 200 : Math.max(90, Math.round(w * 0.62));\n const showText = w >= 220;\n const iconY = showText ? Math.round(h / 2) - 26 : Math.round(h / 2) - 15;\n const svg =\n `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"${w}\" height=\"${h}\" viewBox=\"0 0 ${w} ${h}\">` +\n `<rect width=\"${w}\" height=\"${h}\" fill=\"#e9edf3\"/>` +\n `<g fill=\"none\" stroke=\"#8a94a6\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" transform=\"translate(${Math.round(w / 2) - 18} ${iconY})\">` +\n '<rect x=\"1\" y=\"1\" width=\"34\" height=\"28\" rx=\"4\"/><circle cx=\"11\" cy=\"10\" r=\"3\"/><path d=\"m35 21-8-8-17 17\"/></g>' +\n (showText\n ? `<text x=\"${Math.round(w / 2)}\" y=\"${iconY + 56}\" text-anchor=\"middle\" font-family=\"Arial, Helvetica, sans-serif\" font-size=\"14\" fill=\"#5b6475\">${escapeXml(label)}</text>`\n : '') +\n '</svg>';\n return `data:image/svg+xml;charset=utf-8,${encodeURIComponent(svg)}`;\n}\n\n/**\n * Width each image will roughly get: the body's width shared by the columns\n * of its section (or the column's own width), minus MJML's default padding.\n * @param {EmailNode} root\n * @returns {Map<string, number>}\n */\nfunction imageWidths(root) {\n /** @type {Map<string, number>} */\n const widths = new Map();\n /** @param {string|undefined} value @param {number} of */\n const size = (value, of) => {\n const n = Number.parseFloat(String(value || ''));\n if (!Number.isFinite(n)) return null;\n return String(value).trim().endsWith('%') ? (of * n) / 100 : n;\n };\n /** @param {EmailNode} node @param {number} available */\n const visit = (node, available) => {\n if (node.tag === 'mj-image') {\n widths.set(node.id, size(node.attributes.width, available) || Math.max(60, available - 50));\n return;\n }\n let inner = available;\n if (node.tag === 'mj-body') inner = size(node.attributes.width, 600) || 600;\n const columns = node.children.filter((c) => c.tag === 'mj-column');\n for (const child of node.children) {\n const share = child.tag === 'mj-column' ? size(child.attributes.width, inner) || inner / Math.max(1, columns.length) : inner;\n visit(child, share);\n }\n };\n visit(root, 600);\n return widths;\n}\n\n/**\n * @param {EmailNode} root\n * @param {{t?: (key: string) => string}} [options]\n * @returns {string}\n */\nexport function canvasMjml(root, { t = (key) => key } = {}) {\n const imageLabel = t('Choose an image in the panel');\n const widths = imageWidths(root);\n const dropLabel = t('Drop a block here');\n const hint = (padding) =>\n `<mj-text css-class=\"${PLACEHOLDER_CLASS}\" align=\"center\" color=\"#7b8496\" font-family=\"Arial, Helvetica, sans-serif\" ` +\n `font-size=\"13px\" line-height=\"20px\" padding=\"${padding}\">${escapeXml(dropLabel)}</mj-text>`;\n\n return serializeMjml(root, {\n pretty: false,\n attributes(node) {\n if (!MARKED_TAGS.has(node.tag)) return node.attributes;\n const own = node.attributes['css-class'] ? `${node.attributes['css-class']} ` : '';\n /** @type {Record<string, string>} */\n const attributes = {\n ...node.attributes,\n 'css-class': `${own}${NODE_CLASS} ${ID_CLASS_PREFIX}${node.id} ${TAG_CLASS_PREFIX}${node.tag}`,\n };\n if (node.tag === 'mj-image' && !node.attributes.src) {\n attributes.src = imagePlaceholder(imageLabel, widths.get(node.id));\n if (!attributes.alt) attributes.alt = imageLabel;\n }\n return attributes;\n },\n extraChildren(node) {\n if (node.tag === 'mj-column' && node.children.length === 0) return hint('24px 10px');\n if (node.tag === 'mj-body' && node.children.length === 0) {\n return `<mj-section css-class=\"${PLACEHOLDER_CLASS}\"><mj-column>${hint('48px 10px')}</mj-column></mj-section>`;\n }\n return '';\n },\n });\n}\n\n/**\n * Id of the model element an HTML element belongs to (its own marker or its\n * closest marked ancestor's), or null.\n * @param {Element|null} element\n * @returns {{id: string, element: Element}|null}\n */\nexport function markedAncestor(element) {\n let current = element;\n while (current && current.nodeType === 1) {\n const classes = current.classList;\n if (classes && classes.contains(NODE_CLASS)) {\n for (const name of classes) {\n if (name.startsWith(ID_CLASS_PREFIX) && !name.endsWith('-outlook')) {\n return { id: name.slice(ID_CLASS_PREFIX.length), element: current };\n }\n }\n }\n current = current.parentElement;\n }\n return null;\n}\n","// @ts-check\n/**\n * MORPH — updates the canvas DOM to a newly compiled email in place.\n *\n * Replacing the whole page at every change would reload the images (the\n * email jumps while they come back), lose the scroll position and the caret\n * of a text being typed. Nodes are compared position by position instead:\n * same kind of node → its attributes and children are updated, otherwise it\n * is replaced. An unchanged image keeps its element, so it never reloads.\n *\n * `skip(element)`: an element left exactly as it is, children included (the\n * text being edited: the browser owns it until the edit ends).\n */\n\n/**\n * @param {Element} from @param {Element} to\n */\nexport function syncAttributes(from, to) {\n for (const attribute of [...from.attributes]) {\n if (!to.hasAttribute(attribute.name)) from.removeAttribute(attribute.name);\n }\n for (const attribute of [...to.attributes]) {\n if (from.getAttribute(attribute.name) !== attribute.value) from.setAttribute(attribute.name, attribute.value);\n }\n}\n\n/**\n * @param {Node} from @param {Node} to\n */\nfunction sameKind(from, to) {\n if (from.nodeType !== to.nodeType) return false;\n if (from.nodeType !== 1) return true;\n return /** @type {Element} */ (from).tagName === /** @type {Element} */ (to).tagName;\n}\n\n/**\n * Makes `from`'s children match `to`'s.\n * @param {Node} from @param {Node} to @param {(element: Element) => boolean} [skip]\n */\nexport function morphChildren(from, to, skip = () => false) {\n const document = /** @type {Document} */ (from.ownerDocument || from);\n const targets = [...to.childNodes];\n for (let i = 0; i < targets.length; i += 1) {\n const target = targets[i];\n const current = from.childNodes[i];\n if (!current) {\n from.appendChild(document.importNode(target, true));\n } else if (!sameKind(current, target)) {\n from.replaceChild(document.importNode(target, true), current);\n } else if (current.nodeType === 1) {\n const element = /** @type {Element} */ (current);\n if (skip(element)) continue;\n syncAttributes(element, /** @type {Element} */ (target));\n morphChildren(element, target, skip);\n } else if (current.nodeValue !== target.nodeValue) {\n current.nodeValue = target.nodeValue;\n }\n }\n while (from.childNodes.length > targets.length) {\n /** @type {ChildNode} */ (from.lastChild).remove();\n }\n}\n","// @ts-check\n/**\n * Styles of the canvas's own layer, inside the frame: selection and hover\n * boxes, labels, toolbars, the drop line, placeholders. Never in the email.\n */\n\nimport { FRAME_SCROLLBAR_CSS } from '../../core/scrollbars.js';\n\nconst PRIMARY = '#5b4ff0';\n\nexport const CANVAS_CSS = `\nhtml, body { min-height: 100%; }\nbody { margin: 0; }\n.eb-node { cursor: default; }\n.eb-node a { cursor: pointer; }\n[contenteditable=\"true\"] { outline: none; cursor: text; caret-color: ${PRIMARY}; }\ntd.eb-placeholder { outline: 1.5px dashed #c3cad6; outline-offset: -8px; }\n.eb-placeholder { user-select: none; }\n\n#eb-ui { position: absolute; top: 0; left: 0; width: 0; height: 0; z-index: 2147483000;\n font: 500 11px/1.2 system-ui, -apple-system, 'Segoe UI', Roboto, Arial, sans-serif; }\n#eb-ui * { box-sizing: border-box; }\n#eb-ui [hidden] { display: none !important; }\n.eb-ui-box { position: absolute; pointer-events: none; }\n.eb-ui-hover { box-shadow: inset 0 0 0 1px rgba(91, 79, 240, 0.55); }\n.eb-ui-select { box-shadow: inset 0 0 0 2px ${PRIMARY}; }\n.eb-ui-chip { position: absolute; pointer-events: none; white-space: nowrap; color: #fff; background: ${PRIMARY};\n padding: 4px 7px; border-radius: 5px; font-weight: 600; letter-spacing: 0.01em; }\n.eb-ui-hover-chip { background: rgba(91, 79, 240, 0.85); }\n.eb-ui-tools { position: absolute; display: flex; gap: 1px; padding: 2px; border-radius: 6px; background: ${PRIMARY};\n box-shadow: 0 4px 12px -4px rgba(40, 30, 120, 0.5); pointer-events: auto; }\n.eb-ui-tools button { all: unset; box-sizing: border-box; width: 26px; height: 24px; display: grid; place-items: center;\n color: #fff; border-radius: 4px; cursor: pointer; }\n.eb-ui-tools button:hover, .eb-ui-tools button:focus-visible { background: rgba(255, 255, 255, 0.2); }\n.eb-ui-tools button[data-action=\"move\"] { cursor: grab; touch-action: none; }\n.eb-ui-tools button.eb-ui-parent { width: auto; gap: 4px; padding: 0 7px 0 5px; display: inline-flex; align-items: center;\n font-weight: 600; white-space: nowrap; }\n.eb-ui-tools button.eb-ui-parent + button { margin-left: 2px; box-shadow: -1px 0 0 rgba(255, 255, 255, 0.25); }\n.eb-ui-drop { position: absolute; height: 4px; margin-top: -2px; border-radius: 2px; background: ${PRIMARY};\n box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.85); pointer-events: none; }\n.eb-ui-drop::before, .eb-ui-drop::after { content: ''; position: absolute; top: -3px; width: 10px; height: 10px;\n border-radius: 50%; background: ${PRIMARY}; box-shadow: 0 0 0 2px #fff; }\n.eb-ui-drop::before { left: -5px; }\n.eb-ui-drop::after { right: -5px; }\n.eb-ui-text { position: absolute; display: flex; align-items: center; gap: 1px; padding: 3px; border-radius: 8px;\n background: #fff; border: 1px solid #dfe3ea; box-shadow: 0 8px 22px -10px rgba(16, 24, 40, 0.35); pointer-events: auto; }\n.eb-ui-text button { all: unset; box-sizing: border-box; width: 28px; height: 26px; display: grid; place-items: center;\n color: #2b3038; border-radius: 5px; cursor: pointer; }\n.eb-ui-text button:hover, .eb-ui-text button:focus-visible { background: #eef0f6; }\n.eb-ui-text button[aria-pressed=\"true\"] { background: #e8e6fd; color: ${PRIMARY}; }\n.eb-ui-text .eb-ui-sep { width: 1px; height: 18px; margin: 0 3px; background: #e3e6ec; }\n.eb-ui-text input { all: unset; box-sizing: border-box; width: 220px; height: 26px; padding: 0 8px; border-radius: 5px;\n border: 1px solid #dfe3ea; font: 400 12px/1 system-ui, -apple-system, 'Segoe UI', Roboto, Arial, sans-serif; color: #2b3038; }\n.eb-ui-text input:focus { border-color: ${PRIMARY}; }\n${FRAME_SCROLLBAR_CSS}\n`;\n\n/** The drag label, in the host page (outside the frame): inline styles only. */\nexport const GHOST_STYLE = [\n 'position:fixed',\n 'z-index:2147483646',\n 'pointer-events:none',\n 'padding:6px 10px',\n 'border-radius:7px',\n `background:${PRIMARY}`,\n 'color:#fff',\n \"font:600 12px/1.2 system-ui,-apple-system,'Segoe UI',Roboto,Arial,sans-serif\",\n 'box-shadow:0 8px 20px -8px rgba(40,30,120,.6)',\n 'white-space:nowrap',\n 'transform:translate(12px,12px)',\n].join(';');\n","// @ts-check\n/**\n * Icons of the canvas toolbars (inline SVG: the canvas is a separate document,\n * React and the icon library do not reach it). Paths from Lucide (ISC).\n */\n\nconst svg = (paths) =>\n `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">${paths}</svg>`;\n\nexport const ICONS = {\n parent: svg('<polyline points=\"14 9 9 4 4 9\"/><path d=\"M20 20h-7a4 4 0 0 1-4-4V4\"/>'),\n move: svg(\n '<path d=\"M12 2v20\"/><path d=\"m15 19-3 3-3-3\"/><path d=\"m19 9 3 3-3 3\"/><path d=\"M2 12h20\"/><path d=\"m5 9-3 3 3 3\"/><path d=\"m9 5 3-3 3 3\"/>'\n ),\n duplicate: svg(\n '<rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/>'\n ),\n remove: svg('<path d=\"M3 6h18\"/><path d=\"M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6\"/><path d=\"M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2\"/>'),\n bold: svg('<path d=\"M6 12h9a4 4 0 0 1 0 8H7a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1h7a4 4 0 0 1 0 8\"/>'),\n italic: svg('<line x1=\"19\" x2=\"10\" y1=\"4\" y2=\"4\"/><line x1=\"14\" x2=\"5\" y1=\"20\" y2=\"20\"/><line x1=\"15\" x2=\"9\" y1=\"4\" y2=\"20\"/>'),\n underline: svg('<path d=\"M6 4v6a6 6 0 0 0 12 0V4\"/><line x1=\"4\" x2=\"20\" y1=\"20\" y2=\"20\"/>'),\n strike: svg('<path d=\"M16 4H9a3 3 0 0 0-2.83 4\"/><path d=\"M14 12a4 4 0 0 1 0 8H6\"/><line x1=\"4\" x2=\"20\" y1=\"12\" y2=\"12\"/>'),\n link: svg(\n '<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\"/>'\n ),\n unlink: svg(\n '<path d=\"m18.84 12.25 1.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.75-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\" x2=\"8\" y1=\"2\" y2=\"5\"/><line x1=\"2\" x2=\"5\" y1=\"8\" y2=\"8\"/><line x1=\"16\" x2=\"16\" y1=\"19\" y2=\"22\"/><line x1=\"19\" x2=\"22\" y1=\"16\" y2=\"16\"/>'\n ),\n clear: svg('<path d=\"M4 7V4h16v3\"/><path d=\"M5 20h6\"/><path d=\"M13 4 8 20\"/><path d=\"m15 15 5 5\"/><path d=\"m20 15-5 5\"/>'),\n check: svg('<path d=\"M20 6 9 17l-5-5\"/>'),\n};\n","// @ts-check\n/**\n * CANVAS VIEW — the email on screen, and every gesture made on it.\n *\n * ┌ host (the builder's canvas area) ───────────────────────────────┐\n * │ ┌ frame (iframe: the email's own document) ─────────────────┐ │\n * │ │ <head> the compiled email's styles │ │\n * │ │ <body> the compiled email (mjml-browser), morphed in │ │\n * │ │ #eb-ui our layer: boxes, labels, toolbars, drop line │ │\n * │ └────────────────────────────────────────────────────────────┘ │\n * └──────────────────────────────────────────────────────────────────┘\n *\n * The frame shows the real compiled HTML: what is seen is what is sent. Each\n * model element is found in it by its marker class (`canvasMjml.js`).\n *\n * Gestures, all handled here and reported to the adapter as intentions:\n * click select the element under the pointer\n * double-click edit a text in place (or a click on a selected text)\n * toolbar select the parent, move (drag), duplicate, delete\n * drag and drop from the sidebar, or the ✥ handle of the selection:\n * a line shows where the element will land, the frame\n * scrolls near its edges, Esc cancels\n * text toolbar bold, italic, underline, strike, link, unlink, clear\n *\n * Owns no email data: it reads the tree through `getRoot()` and asks the\n * adapter for every change.\n */\n\nimport { canvasMjml, markedAncestor } from '../canvasMjml.js';\nimport { dropTargetFor } from '../placement.js';\nimport { cleanRichText } from '../richText.js';\nimport { morphChildren, syncAttributes } from './morph.js';\nimport { CANVAS_CSS, GHOST_STYLE } from './canvasStyles.js';\nimport { ICONS } from './icons.js';\n\n/** @typedef {import('../model.js').EmailNode} EmailNode */\n/** @typedef {import('../placement.js').DropTarget} DropTarget */\n/** @typedef {{kind: 'content'|'layout', nodeId?: string|null, block?: any}} DragPayload */\n\n/** Elements edited as rich text in the canvas. */\nexport const EDITABLE_TAGS = new Set(['mj-text']);\n\nconst MOBILE_WIDTH = 375;\nconst EDGE = 56;\n\n/**\n * @param {{\n * container: HTMLElement,\n * compile: (mjml: string) => Promise<{html: string, errors: any[]}>,\n * getRoot: () => EmailNode,\n * t: (key: string, values?: Record<string, any>) => string,\n * info: (id: string) => {label: string, tag: string, canRemove: boolean, canDuplicate: boolean, canMove: boolean, hasParent: boolean, parentLabel: string}|null,\n * onSelect: (id: string|null) => void,\n * onAction: (action: 'parent'|'duplicate'|'remove', id: string) => void,\n * onDrop: (payload: DragPayload, target: DropTarget) => void,\n * onEditStart: (id: string) => void,\n * onEditInput: (id: string, html: string) => void,\n * onEditEnd: (id: string, html: string) => void,\n * onKeyDown: (event: KeyboardEvent) => void,\n * }} options\n */\nexport function createCanvasView(options) {\n const { container, compile, getRoot, t, info } = options;\n const parentDocument = container.ownerDocument;\n\n const host = parentDocument.createElement('div');\n host.className = 'eb-native-canvas';\n host.style.cssText = 'position:relative;width:100%;height:100%;display:flex;justify-content:center;overflow:hidden;';\n const frame = parentDocument.createElement('iframe');\n frame.className = 'eb-canvas-frame';\n frame.title = t('Email canvas');\n frame.setAttribute('data-testid', 'eb-canvas-frame');\n frame.style.cssText =\n 'display:block;border:0;width:100%;height:100%;background:transparent;transition:width .35s ease, box-shadow .35s ease;';\n host.appendChild(frame);\n container.appendChild(host);\n\n const win = /** @type {Window & typeof globalThis} */ (frame.contentWindow);\n const doc = /** @type {Document} */ (frame.contentDocument);\n doc.open();\n doc.write('<!doctype html><html><head></head><body></body></html>');\n doc.close();\n\n /* ── Our layer ─────────────────────────────────────────────────────────── */\n const ui = doc.createElement('div');\n ui.id = 'eb-ui';\n ui.setAttribute('contenteditable', 'false');\n const style = doc.createElement('style');\n style.textContent = CANVAS_CSS;\n ui.appendChild(style);\n doc.documentElement.appendChild(ui);\n\n const make = (className) => {\n const el = doc.createElement('div');\n el.className = className;\n el.hidden = true;\n ui.appendChild(el);\n return el;\n };\n const hoverBox = make('eb-ui-box eb-ui-hover');\n const hoverChip = make('eb-ui-chip eb-ui-hover-chip');\n const selectBox = make('eb-ui-box eb-ui-select');\n const selectChip = make('eb-ui-chip');\n selectChip.setAttribute('data-testid', 'eb-canvas-label');\n const tools = make('eb-ui-tools');\n tools.setAttribute('role', 'toolbar');\n tools.setAttribute('aria-label', t('Element actions'));\n const dropLine = make('eb-ui-drop');\n const textTools = make('eb-ui-text');\n textTools.setAttribute('role', 'toolbar');\n textTools.setAttribute('aria-label', t('Text formatting'));\n\n /** @type {string|null} */ let selectedId = null;\n /** Ctrl+A: the sections drawn as selected, and their boxes. */\n /** @type {string[]} */ let multiIds = [];\n /** @type {HTMLElement[]} */ const multiBoxes = [];\n /** @type {string|null} */ let hoverId = null;\n /** @type {string|null} */ let editingId = null;\n /** @type {HTMLElement|null} */ let editingEl = null;\n /** @type {Range|null} */ let savedRange = null;\n /** @type {null | {payload: DragPayload, target: DropTarget|null, cancel: () => void}} */ let drag = null;\n let renderToken = 0;\n let destroyed = false;\n let lastHead = '';\n let overlayFrame = 0;\n /** @type {'desktop'|'mobile'} */ let device = 'desktop';\n\n /* ── Geometry ──────────────────────────────────────────────────────────── */\n\n /** @param {string} id */\n const elementOf = (id) => /** @type {HTMLElement|null} */ (doc.querySelector(`.eb-id-${id}`));\n\n /** Box in frame viewport coordinates. @param {string} id */\n const boxOf = (id) => {\n const el = elementOf(id);\n if (!el) return null;\n const r = el.getBoundingClientRect();\n if (!r.width && !r.height) return null;\n return { top: r.top, bottom: r.bottom, left: r.left, right: r.right };\n };\n\n /** @param {HTMLElement} el @param {{top: number, left: number, width: number, height: number}} r */\n const place = (el, r) => {\n el.style.top = `${r.top}px`;\n el.style.left = `${r.left}px`;\n el.style.width = `${Math.max(0, r.width)}px`;\n el.style.height = `${Math.max(0, r.height)}px`;\n };\n\n /** Box in document coordinates (what our absolute layer uses). @param {string} id */\n const docBoxOf = (id) => {\n const box = boxOf(id);\n if (!box) return null;\n return { top: box.top + win.scrollY, left: box.left + win.scrollX, width: box.right - box.left, height: box.bottom - box.top };\n };\n\n /** Chip above a box, or inside it when there is no room above. */\n const placeChip = (chip, box, text) => {\n chip.textContent = text;\n chip.hidden = false;\n const above = box.top - win.scrollY > 22;\n chip.style.top = `${above ? box.top - 21 : box.top + 2}px`;\n chip.style.left = `${box.left + (above ? 0 : 2)}px`;\n };\n\n /* ── Overlays ──────────────────────────────────────────────────────────── */\n\n function drawHover() {\n const box = hoverId && hoverId !== selectedId && !drag && !multiIds.length ? docBoxOf(hoverId) : null;\n hoverBox.hidden = hoverChip.hidden = !box;\n if (!box || !hoverId) return;\n place(hoverBox, box);\n placeChip(hoverChip, box, info(hoverId)?.label || '');\n }\n\n function drawSelection() {\n const box = selectedId ? docBoxOf(selectedId) : null;\n const details = selectedId ? info(selectedId) : null;\n selectBox.hidden = selectChip.hidden = tools.hidden = !box;\n if (!box || !details || !selectedId) return;\n place(selectBox, box);\n placeChip(selectChip, box, details.label);\n // While a text is edited its formatting bar takes that place.\n if (editingId) selectChip.hidden = true;\n // Toolbar: top-right, above the element when there is room. The first\n // button climbs to the parent and says which one (\"⤴ Column\"): an arrow\n // alone read as \"move up\".\n const buttons = [\n details.hasParent && ['parent', `${t('Select the parent')}: ${details.parentLabel}`],\n details.canMove && ['move', t('Drag to move')],\n details.canDuplicate && ['duplicate', t('Duplicate')],\n details.canRemove && ['remove', t('Delete')],\n ].filter(Boolean);\n const signature = buttons.map((b) => b && b[1]).join(',');\n if (tools.dataset.signature !== signature || tools.dataset.lang !== t('Delete')) {\n tools.textContent = '';\n for (const button of buttons) {\n if (!button) continue;\n const [action, label] = button;\n const el = doc.createElement('button');\n el.type = 'button';\n el.dataset.action = action;\n el.title = label;\n el.setAttribute('aria-label', label);\n el.innerHTML = ICONS[action];\n if (action === 'parent') {\n el.classList.add('eb-ui-parent');\n const name = doc.createElement('span');\n name.textContent = details.parentLabel;\n el.appendChild(name);\n }\n tools.appendChild(el);\n }\n tools.dataset.signature = signature;\n tools.dataset.lang = t('Delete');\n }\n tools.hidden = editingId !== null || buttons.length === 0;\n const toolsWidth = tools.offsetWidth || buttons.length * 27 + 4;\n const above = box.top - win.scrollY > 30;\n tools.style.top = `${above ? box.top - 28 : box.top + 2}px`;\n // Right-aligned on the element, but never over its name.\n const afterChip = selectChip.hidden ? box.left : box.left + selectChip.offsetWidth + 4;\n tools.style.left = `${Math.max(afterChip, box.left + box.width - toolsWidth)}px`;\n }\n\n function drawTextTools() {\n if (!editingId || !editingEl) {\n textTools.hidden = true;\n return;\n }\n const box = docBoxOf(editingId);\n if (!box) return;\n textTools.hidden = false;\n const height = 34;\n const above = box.top - win.scrollY > height + 8;\n textTools.style.top = `${above ? box.top - height - 6 : box.top + box.height + 6}px`;\n textTools.style.left = `${box.left}px`;\n refreshTextState();\n }\n\n function drawMulti() {\n while (multiBoxes.length < multiIds.length) {\n const box = make('eb-ui-box eb-ui-select');\n box.setAttribute('data-testid', 'eb-canvas-multi');\n multiBoxes.push(box);\n }\n multiBoxes.forEach((box, i) => {\n const r = i < multiIds.length ? docBoxOf(multiIds[i]) : null;\n box.hidden = !r;\n if (r) place(box, r);\n });\n }\n\n function refreshOverlays() {\n if (destroyed) return;\n drawMulti();\n drawSelection();\n drawHover();\n drawTextTools();\n }\n\n function scheduleOverlays() {\n if (overlayFrame) return;\n overlayFrame = win.requestAnimationFrame(() => {\n overlayFrame = 0;\n refreshOverlays();\n });\n }\n\n /* ── Rendering ─────────────────────────────────────────────────────────── */\n\n /**\n * Compiles the tree and brings the frame up to date. The latest call wins:\n * an older compilation that finishes later is dropped.\n */\n async function render() {\n const token = ++renderToken;\n const source = canvasMjml(getRoot(), { t });\n let result;\n try {\n result = await compile(source);\n } catch (error) {\n console.warn('[best-email-builder] canvas compilation failed', error);\n return;\n }\n if (destroyed || token !== renderToken) return;\n const parsed = new DOMParser().parseFromString(result.html, 'text/html');\n const head = parsed.head.innerHTML;\n if (head !== lastHead) {\n doc.head.innerHTML = head;\n lastHead = head;\n }\n syncAttributes(doc.body, parsed.body);\n morphChildren(doc.body, parsed.body, (element) => element === editingEl);\n // The edited text may have been replaced (its element moved): find it again.\n if (editingId && editingEl && !editingEl.isConnected) {\n const again = editableOf(editingId);\n if (again) {\n again.setAttribute('contenteditable', 'true');\n editingEl = again;\n } else finishEditing();\n }\n refreshOverlays();\n }\n\n /* ── Selection and hover ───────────────────────────────────────────────── */\n\n /** @param {EventTarget|null} target */\n const nodeIdAt = (target) => {\n const el = target && /** @type {any} */ (target).nodeType === 1 ? /** @type {Element} */ (target) : /** @type {any} */ (target)?.parentElement;\n if (!el || ui.contains(el)) return null;\n return markedAncestor(el)?.id || null;\n };\n\n const bodyId = () => {\n const root = getRoot();\n const body = root.children.find((c) => c.tag === 'mj-body');\n return body ? body.id : null;\n };\n\n doc.addEventListener('mousemove', (event) => {\n if (drag) return;\n const id = nodeIdAt(event.target);\n if (id !== hoverId) {\n hoverId = id;\n drawHover();\n }\n });\n doc.addEventListener('mouseleave', () => {\n hoverId = null;\n drawHover();\n });\n\n doc.addEventListener('click', (event) => {\n const target = /** @type {Element|null} */ (event.target);\n // Links never navigate in the canvas.\n if (target && target.closest && target.closest('a')) event.preventDefault();\n if (!target || ui.contains(target)) return;\n if (editingEl && editingEl.contains(target)) return;\n // The page around the sections: nothing selected, the panel shows the\n // whole email's settings (name, subject, page).\n const hit = nodeIdAt(target);\n const id = hit && hit !== bodyId() ? hit : null;\n const wasSelected = id !== null && id === selectedId;\n if (editingId && editingId !== id) finishEditing();\n options.onSelect(id);\n const node = id ? findTag(id) : null;\n if (wasSelected && id && node && EDITABLE_TAGS.has(node) && !editingId) {\n startEditing(id, { x: event.clientX, y: event.clientY });\n }\n });\n\n doc.addEventListener('dblclick', (event) => {\n const target = /** @type {Element|null} */ (event.target);\n if (!target || ui.contains(target) || (editingEl && editingEl.contains(target))) return;\n const id = nodeIdAt(target);\n if (id && EDITABLE_TAGS.has(findTag(id) || '')) {\n options.onSelect(id);\n startEditing(id, { x: event.clientX, y: event.clientY });\n }\n });\n\n // Native drag of images and links would fight ours.\n doc.addEventListener('dragstart', (event) => event.preventDefault());\n doc.addEventListener('submit', (event) => event.preventDefault());\n doc.addEventListener('keydown', (event) => options.onKeyDown(event));\n doc.addEventListener('load', scheduleOverlays, true); // images arriving change heights\n win.addEventListener('resize', scheduleOverlays);\n const resizeObserver = new ResizeObserver(scheduleOverlays);\n resizeObserver.observe(doc.documentElement);\n\n /** @param {string} id */\n function findTag(id) {\n /** @param {EmailNode} node @returns {string|null} */\n const search = (node) => {\n if (node.id === id) return node.tag;\n for (const child of node.children) {\n const found = search(child);\n if (found) return found;\n }\n return null;\n };\n return search(getRoot());\n }\n\n /* ── Element toolbar ───────────────────────────────────────────────────── */\n\n tools.addEventListener('click', (event) => {\n const button = /** @type {Element} */ (event.target).closest('button');\n if (!button || !selectedId) return;\n event.preventDefault();\n event.stopPropagation();\n const action = button.getAttribute('data-action');\n if (action === 'parent' || action === 'duplicate' || action === 'remove') options.onAction(action, selectedId);\n });\n tools.addEventListener('pointerdown', (event) => {\n const button = /** @type {Element} */ (event.target).closest('button[data-action=\"move\"]');\n if (!button || !selectedId || event.button !== 0) return;\n event.preventDefault();\n const tag = findTag(selectedId) || '';\n const kind = tag === 'mj-section' || tag === 'mj-wrapper' || tag === 'mj-hero' ? 'layout' : 'content';\n startDrag({\n payload: { kind, nodeId: selectedId },\n label: info(selectedId)?.label || '',\n source: 'frame',\n pointerId: event.pointerId,\n captureTarget: /** @type {Element} */ (button),\n x: event.clientX,\n y: event.clientY,\n });\n });\n\n /* ── Text editing ──────────────────────────────────────────────────────── */\n\n /** The element holding a text's content: MJML's `<td class=…><div>…</div></td>`. @param {string} id */\n function editableOf(id) {\n const cell = elementOf(id);\n const inner = cell && cell.firstElementChild;\n return inner && inner.tagName === 'DIV' ? /** @type {HTMLElement} */ (inner) : null;\n }\n\n /** @param {{x: number, y: number}|null} at */\n function placeCaret(at) {\n if (!editingEl) return;\n const selection = win.getSelection();\n if (!selection) return;\n /** @type {Range|null} */\n let range = null;\n if (at) {\n const anyDoc = /** @type {any} */ (doc);\n if (anyDoc.caretRangeFromPoint) range = anyDoc.caretRangeFromPoint(at.x, at.y);\n else if (anyDoc.caretPositionFromPoint) {\n const position = anyDoc.caretPositionFromPoint(at.x, at.y);\n if (position) {\n range = doc.createRange();\n range.setStart(position.offsetNode, position.offset);\n }\n }\n if (range && !editingEl.contains(range.startContainer)) range = null;\n }\n if (!range) {\n range = doc.createRange();\n range.selectNodeContents(editingEl);\n range.collapse(false);\n }\n selection.removeAllRanges();\n selection.addRange(range);\n savedRange = range.cloneRange();\n }\n\n /**\n * @param {string} id\n * @param {{x: number, y: number}|null} [at] where the caret goes (click point)\n */\n function startEditing(id, at = null) {\n if (editingId === id) return;\n finishEditing();\n const el = editableOf(id);\n if (!el) return;\n editingId = id;\n editingEl = el;\n el.setAttribute('contenteditable', 'true');\n el.setAttribute('spellcheck', 'true');\n el.focus({ preventScroll: true });\n try {\n doc.execCommand('styleWithCSS', false, 'false');\n } catch {\n /* not supported: tags are written anyway */\n }\n placeCaret(at);\n options.onEditStart(id);\n refreshOverlays();\n }\n\n function contentOfEditing() {\n return editingEl ? cleanRichText(editingEl.innerHTML, doc) : '';\n }\n\n function finishEditing() {\n if (!editingId || !editingEl) return;\n const id = editingId;\n const html = contentOfEditing();\n editingEl.removeAttribute('contenteditable');\n editingEl.removeAttribute('spellcheck');\n editingId = null;\n editingEl = null;\n savedRange = null;\n hideLinkInput();\n textTools.hidden = true;\n options.onEditEnd(id, html);\n refreshOverlays();\n }\n\n doc.addEventListener('input', (event) => {\n if (!editingEl || !editingId || !editingEl.contains(/** @type {Node} */ (event.target))) return;\n options.onEditInput(editingId, contentOfEditing());\n scheduleOverlays();\n });\n\n doc.addEventListener('keydown', (event) => {\n if (!editingEl) return;\n if (event.key === 'Enter') {\n // A line break, not a new block: renders the same in every client.\n event.preventDefault();\n if (!doc.execCommand('insertLineBreak')) doc.execCommand('insertHTML', false, '<br>');\n }\n });\n\n doc.addEventListener('paste', (event) => {\n if (!editingEl || !editingEl.contains(/** @type {Node} */ (event.target))) return;\n // Plain text only: no foreign styles or tags in the email.\n event.preventDefault();\n const text = event.clipboardData ? event.clipboardData.getData('text/plain') : '';\n doc.execCommand('insertText', false, text);\n });\n\n doc.addEventListener('selectionchange', () => {\n if (!editingEl) return;\n const selection = win.getSelection();\n if (selection && selection.rangeCount && editingEl.contains(selection.getRangeAt(0).commonAncestorContainer)) {\n savedRange = selection.getRangeAt(0).cloneRange();\n refreshTextState();\n }\n });\n\n /** Puts the caret back where it was (the host page may have taken the focus). */\n function restoreCaret() {\n if (!editingEl) return false;\n editingEl.focus({ preventScroll: true });\n const selection = win.getSelection();\n if (!selection) return false;\n if (savedRange && editingEl.contains(savedRange.commonAncestorContainer)) {\n selection.removeAllRanges();\n selection.addRange(savedRange);\n } else placeCaret(null);\n return true;\n }\n\n /* Text toolbar: built once. */\n const TEXT_BUTTONS = [\n ['bold', t('Bold (Ctrl+B)')],\n ['italic', t('Italic (Ctrl+I)')],\n ['underline', t('Underline (Ctrl+U)')],\n ['strike', t('Strikethrough')],\n ['sep'],\n ['link', t('Link')],\n ['unlink', t('Remove the link')],\n ['sep'],\n ['clear', t('Clear formatting')],\n ];\n const linkInput = doc.createElement('input');\n linkInput.type = 'url';\n linkInput.placeholder = 'https://';\n linkInput.setAttribute('aria-label', t('Link URL'));\n linkInput.hidden = true;\n const linkConfirm = doc.createElement('button');\n linkConfirm.type = 'button';\n linkConfirm.dataset.command = 'link-confirm';\n linkConfirm.title = t('Apply the link');\n linkConfirm.setAttribute('aria-label', t('Apply the link'));\n linkConfirm.innerHTML = ICONS.check;\n linkConfirm.hidden = true;\n\n for (const [command, label] of TEXT_BUTTONS) {\n if (command === 'sep') {\n const sep = doc.createElement('span');\n sep.className = 'eb-ui-sep';\n textTools.appendChild(sep);\n continue;\n }\n const button = doc.createElement('button');\n button.type = 'button';\n button.dataset.command = command;\n button.title = /** @type {string} */ (label);\n button.setAttribute('aria-label', /** @type {string} */ (label));\n button.innerHTML = ICONS[/** @type {keyof typeof ICONS} */ (command)];\n textTools.appendChild(button);\n }\n textTools.appendChild(linkInput);\n textTools.appendChild(linkConfirm);\n\n // Keep the text's selection: a toolbar press must not take the focus.\n textTools.addEventListener('mousedown', (event) => {\n if (event.target !== linkInput) event.preventDefault();\n });\n\n const NATIVE = { bold: 'bold', italic: 'italic', underline: 'underline', strike: 'strikeThrough', unlink: 'unlink', clear: 'removeFormat' };\n\n textTools.addEventListener('click', (event) => {\n const button = /** @type {Element} */ (event.target).closest('button');\n if (!button || !editingEl) return;\n event.preventDefault();\n event.stopPropagation();\n const command = button.getAttribute('data-command') || '';\n if (command === 'link') {\n showLinkInput();\n return;\n }\n if (command === 'link-confirm') {\n applyLink();\n return;\n }\n restoreCaret();\n const native = /** @type {Record<string, string>} */ (NATIVE)[command];\n if (native) {\n if (command === 'unlink') selectLinkUnderCaret();\n doc.execCommand(native);\n if (command === 'clear') doc.execCommand('unlink');\n }\n options.onEditInput(/** @type {string} */ (editingId), contentOfEditing());\n refreshTextState();\n });\n\n linkInput.addEventListener('keydown', (event) => {\n if (event.key === 'Enter') {\n event.preventDefault();\n applyLink();\n } else if (event.key === 'Escape') {\n event.preventDefault();\n hideLinkInput();\n restoreCaret();\n }\n event.stopPropagation();\n });\n\n function linkUnderCaret() {\n if (!savedRange || !editingEl) return null;\n let node = /** @type {Node|null} */ (savedRange.startContainer);\n while (node && node !== editingEl) {\n if (node.nodeType === 1 && /** @type {Element} */ (node).tagName === 'A') return /** @type {HTMLAnchorElement} */ (node);\n node = node.parentNode;\n }\n return null;\n }\n\n function selectLinkUnderCaret() {\n const link = linkUnderCaret();\n const selection = win.getSelection();\n if (!link || !selection || !savedRange || !savedRange.collapsed) return;\n const range = doc.createRange();\n range.selectNodeContents(link);\n selection.removeAllRanges();\n selection.addRange(range);\n }\n\n function showLinkInput() {\n const link = linkUnderCaret();\n linkInput.value = link ? link.getAttribute('href') || '' : '';\n linkInput.hidden = false;\n linkConfirm.hidden = false;\n linkInput.focus();\n linkInput.select();\n }\n\n function hideLinkInput() {\n linkInput.hidden = true;\n linkConfirm.hidden = true;\n }\n\n function applyLink() {\n const href = linkInput.value.trim();\n hideLinkInput();\n restoreCaret();\n if (!href || !editingEl) return;\n const safe = /^(https?:\\/\\/|mailto:|tel:|#|\\{\\{)/i.test(href) ? href : `https://${href}`;\n const existing = linkUnderCaret();\n if (existing) existing.setAttribute('href', safe);\n else if (savedRange && !savedRange.collapsed) doc.execCommand('createLink', false, safe);\n else doc.execCommand('insertHTML', false, `<a href=\"${escapeAttribute(safe)}\">${escapeHtml(safe)}</a>`);\n options.onEditInput(/** @type {string} */ (editingId), contentOfEditing());\n }\n\n function refreshTextState() {\n if (!editingEl) return;\n for (const [command, native] of Object.entries({ bold: 'bold', italic: 'italic', underline: 'underline', strike: 'strikeThrough' })) {\n const button = textTools.querySelector(`[data-command=\"${command}\"]`);\n let on;\n try {\n on = doc.queryCommandState(native);\n } catch {\n on = false;\n }\n button?.setAttribute('aria-pressed', on ? 'true' : 'false');\n }\n }\n\n /* ── Drag and drop ─────────────────────────────────────────────────────── */\n\n /**\n * @param {{\n * payload: DragPayload,\n * label: string,\n * source: 'host'|'frame',\n * pointerId: number,\n * captureTarget: Element,\n * x: number,\n * y: number,\n * }} start\n */\n function startDrag(start) {\n cancelDrag();\n finishEditing();\n const { payload, source, captureTarget } = start;\n const ghost = parentDocument.createElement('div');\n ghost.setAttribute('style', GHOST_STYLE);\n ghost.setAttribute('data-testid', 'eb-drag-ghost');\n ghost.textContent = start.label;\n parentDocument.body.appendChild(ghost);\n try {\n captureTarget.setPointerCapture(start.pointerId);\n } catch {\n /* the pointer is gone already */\n }\n let last = { x: start.x, y: start.y };\n let scrollFrame = 0;\n\n /** Pointer → frame viewport coordinates, or null when outside the frame. */\n const toFrame = (x, y) => {\n if (source === 'frame') {\n const inside = x >= 0 && y >= 0 && x <= win.innerWidth && y <= win.innerHeight;\n return inside ? { x, y } : null;\n }\n const rect = frame.getBoundingClientRect();\n const inside = x >= rect.left && x <= rect.right && y >= rect.top && y <= rect.bottom;\n return inside ? { x: x - rect.left, y: y - rect.top } : null;\n };\n /** Pointer → host page coordinates (for the label). */\n const toHost = (x, y) => {\n if (source === 'host') return { x, y };\n const rect = frame.getBoundingClientRect();\n return { x: x + rect.left, y: y + rect.top };\n };\n\n const update = () => {\n const position = toHost(last.x, last.y);\n ghost.style.left = `${position.x}px`;\n ghost.style.top = `${position.y}px`;\n const point = toFrame(last.x, last.y);\n if (!drag) return;\n if (!point) {\n drag.target = null;\n dropLine.hidden = true;\n return;\n }\n const hit = doc.elementFromPoint(point.x, point.y);\n const hitId = hit && !ui.contains(hit) ? markedAncestor(hit)?.id || null : null;\n const target = dropTargetFor(getRoot(), payload, point, hitId, boxOf);\n drag.target = target;\n if (!target) {\n dropLine.hidden = true;\n return;\n }\n dropLine.hidden = false;\n dropLine.style.top = `${target.line.y + win.scrollY}px`;\n dropLine.style.left = `${target.line.x + win.scrollX}px`;\n dropLine.style.width = `${Math.max(24, target.line.width)}px`;\n };\n\n // Near the top or bottom edge, the frame scrolls by itself.\n const autoscroll = () => {\n scrollFrame = 0;\n if (!drag) return;\n const point = toFrame(last.x, last.y);\n if (point) {\n const height = win.innerHeight;\n const speed = point.y < EDGE ? -(EDGE - point.y) / 3 : point.y > height - EDGE ? (point.y - (height - EDGE)) / 3 : 0;\n if (speed) {\n win.scrollBy(0, speed);\n update();\n }\n if (speed) scrollFrame = win.requestAnimationFrame(autoscroll);\n }\n };\n\n const onMove = (/** @type {PointerEvent} */ event) => {\n if (event.pointerId !== start.pointerId) return;\n last = { x: event.clientX, y: event.clientY };\n update();\n if (!scrollFrame) scrollFrame = win.requestAnimationFrame(autoscroll);\n };\n const onUp = (/** @type {PointerEvent} */ event) => {\n if (event.pointerId !== start.pointerId) return;\n last = { x: event.clientX, y: event.clientY };\n update();\n const target = drag?.target || null;\n end();\n if (target) options.onDrop(payload, target);\n };\n const onKey = (/** @type {KeyboardEvent} */ event) => {\n if (event.key === 'Escape') {\n event.preventDefault();\n end();\n }\n };\n const end = () => {\n captureTarget.removeEventListener('pointermove', /** @type {any} */ (onMove));\n captureTarget.removeEventListener('pointerup', /** @type {any} */ (onUp));\n captureTarget.removeEventListener('pointercancel', /** @type {any} */ (end));\n captureTarget.removeEventListener('lostpointercapture', /** @type {any} */ (end));\n parentDocument.removeEventListener('keydown', onKey, true);\n doc.removeEventListener('keydown', onKey, true);\n if (scrollFrame) win.cancelAnimationFrame(scrollFrame);\n try {\n captureTarget.releasePointerCapture(start.pointerId);\n } catch {\n /* already released */\n }\n ghost.remove();\n dropLine.hidden = true;\n drag = null;\n refreshOverlays();\n };\n\n captureTarget.addEventListener('pointermove', /** @type {any} */ (onMove));\n captureTarget.addEventListener('pointerup', /** @type {any} */ (onUp));\n captureTarget.addEventListener('pointercancel', /** @type {any} */ (end));\n captureTarget.addEventListener('lostpointercapture', /** @type {any} */ (end));\n parentDocument.addEventListener('keydown', onKey, true);\n doc.addEventListener('keydown', onKey, true);\n drag = { payload, target: null, cancel: end };\n hoverId = null;\n refreshOverlays();\n update();\n }\n\n function cancelDrag() {\n drag?.cancel();\n }\n\n /* ── Public ────────────────────────────────────────────────────────────── */\n\n return {\n frame,\n document: doc,\n render,\n refresh: refreshOverlays,\n /** @param {string|null} id */\n setSelection(id) {\n if (editingId && editingId !== id) finishEditing();\n selectedId = id;\n refreshOverlays();\n if (id) {\n const el = elementOf(id);\n // Bring a selected element into view (added by click below the fold).\n if (el) {\n const r = el.getBoundingClientRect();\n if (r.bottom < 0 || r.top > win.innerHeight) el.scrollIntoView({ block: 'center', behavior: 'smooth' });\n }\n }\n },\n /** Ctrl+A: boxes on every given element (empty array: none). @param {string[]} ids */\n setMultiSelection(ids) {\n multiIds = [...ids];\n refreshOverlays();\n },\n /** @param {'desktop'|'mobile'} next */\n setDevice(next) {\n device = next;\n frame.style.width = next === 'mobile' ? `${MOBILE_WIDTH}px` : '100%';\n frame.style.boxShadow = next === 'mobile' ? '0 0 0 1px #dfe3ea, 0 12px 30px -16px rgba(16,24,40,.35)' : 'none';\n frame.dataset.device = next;\n },\n getDevice: () => device,\n startDrag,\n cancelDrag,\n isDragging: () => drag !== null,\n /** @param {string} id @param {{x: number, y: number}|null} [at] */\n startEditing,\n finishEditing,\n editingId: () => editingId,\n /** @param {string} text */\n insertText(text) {\n if (!restoreCaret()) return false;\n doc.execCommand('insertText', false, text);\n options.onEditInput(/** @type {string} */ (editingId), contentOfEditing());\n return true;\n },\n /** @param {string} html */\n insertHtml(html) {\n if (!restoreCaret()) return false;\n doc.execCommand('insertHTML', false, html);\n options.onEditInput(/** @type {string} */ (editingId), contentOfEditing());\n return true;\n },\n destroy() {\n destroyed = true;\n cancelDrag();\n resizeObserver.disconnect();\n if (overlayFrame) win.cancelAnimationFrame(overlayFrame);\n host.remove();\n },\n };\n}\n\n/** @param {string} text */\nfunction escapeHtml(text) {\n return String(text).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');\n}\n\n/** @param {string} text */\nfunction escapeAttribute(text) {\n return escapeHtml(text).replace(/\"/g, '"');\n}\n","// @ts-check\n/**\n * A dynamically imported module → the value it exports by default.\n *\n * `mjml-browser` (the canvas compiler) is a CommonJS/UMD module. How\n * `import()` hands such a module over depends on the bundler:\n *\n * Vite, esbuild { default: value }\n * webpack (Next.js), from an { default: { __esModule: true, default: value } }\n * ES module package\n *\n * so a single `.default` once returned an object instead of the function under\n * Next.js (0.1.1: \"mjmlPlugin is not a function\"). Every interop layer is peeled —\n * a module namespace or an `__esModule` object — never the value itself.\n *\n * @param {any} mod\n * @returns {any}\n */\nexport function unwrapModule(mod) {\n let value = mod;\n for (let depth = 0; depth < 3 && isInteropLayer(value); depth += 1) value = value.default;\n return value;\n}\n\n/** @param {any} value */\nfunction isInteropLayer(value) {\n if (value === null || typeof value !== 'object' || !('default' in value)) return false;\n return value.__esModule === true || Object.prototype.toString.call(value) === '[object Module]';\n}\n\n/**\n * A module whose export is a FUNCTION (`mjml-browser`) → that function, under\n * any bundler. On top of `unwrapModule`, Vite's dynamic import of a CommonJS\n * module hands over a plain object `{ ...props, default: fn }` (no module\n * flag): since a function is expected, `default` is followed while the value\n * is not one.\n *\n * @param {any} mod\n * @returns {Function|null}\n */\nexport function functionExport(mod) {\n let value = unwrapModule(mod);\n for (let depth = 0; depth < 3 && typeof value !== 'function' && value && typeof value === 'object' && 'default' in value; depth += 1) {\n value = value.default;\n }\n return typeof value === 'function' ? value : null;\n}\n","// @ts-check\n/**\n * NATIVE ADAPTER — the builder's own engine behind the `EmailEditorAdapter`\n * contract (core/EmailEditor.js).\n *\n * model.js the email: an MJML tree with ids, changed by pure functions\n * mjml.js MJML ⇄ tree\n * placement.js where a block goes (click, drop)\n * canvasMjml.js the tree as the canvas compiles it (markers, placeholders)\n * canvas/ the canvas: compiled email in a frame, gestures, toolbars\n *\n * MJML is the only converter: the tree is written as MJML, and MJML (the\n * server's `mjml`, the canvas's `mjml-browser`) turns it into the HTML that\n * Outlook, Gmail and Apple Mail receive. Nothing else interprets the email.\n *\n * History: every change keeps the previous tree (trees share their unchanged\n * branches, so this is cheap). Typing in a text, or nudging one field of the\n * panel, is merged into one step while it goes on.\n */\n\nimport { EMAIL_BUILDER_VERSION } from '../core/constants.js';\nimport {\n LOCKED_TAGS,\n SECTION_TAGS,\n cloneWithNewIds,\n createNode,\n findFirst,\n findNode,\n fromProject,\n insertNodes,\n moveNode,\n parentOf,\n positionOf,\n removeNode,\n setAttributes,\n setContent,\n toProject,\n} from './model.js';\nimport { parseMjml, parseMjmlFragment, serializeMjml } from './mjml.js';\nimport { placementFor, sectionOf } from './placement.js';\nimport { escapeText, textOfHtml } from './richText.js';\nimport { EDITABLE_TAGS, createCanvasView } from './canvas/CanvasView.js';\nimport { functionExport } from './unwrapModule.js';\n\n/**\n * @typedef {import('../core/EmailEditor.js').EmailEditorAdapter} EmailEditorAdapter\n * @typedef {import('../core/EmailEditor.js').EmailBlock} EmailBlock\n * @typedef {import('../core/EmailEditor.js').EngineSelection} EngineSelection\n * @typedef {import('./model.js').EmailNode} EmailNode\n */\n\nexport const ENGINE_NAME = 'beb-mjml';\nexport const ENGINE_VERSION = EMAIL_BUILDER_VERSION;\n\nexport const EMPTY_MJML = '<mjml><mj-body background-color=\"#eceff4\" width=\"600px\"></mj-body></mjml>';\n\n/** Elements whose content is a plain label, edited in the panel. */\nconst LABEL_TAGS = new Set(['mj-button', 'mj-navbar-link']);\n\n/**\n * Elements that only live inside one parent (an icon in its social bar, a\n * link in its menu): moved, duplicated and pasted among their siblings only,\n * never dragged elsewhere.\n */\nconst BOUND_TAGS = new Set(['mj-social-element', 'mj-navbar-link', 'mj-column', 'mj-group']);\n\n/** Elements a text or a link can be inserted into, when no text is being edited. */\nconst TEXT_TAGS = new Set(['mj-text', 'mj-button']);\n\nconst HISTORY_LIMIT = 300;\nconst MERGE_MS = 1000;\n\n/**\n * The canvas compiler, loaded on the first `initialize` (1.2 MB). A\n * CommonJS package: bundlers hand it over wrapped once or twice (webpack /\n * Next.js, Vite), `functionExport` gets the function out either way.\n */\nasync function defaultLoadCompiler() {\n const mjml2html = /** @type {any} */ (functionExport(await import('mjml-browser')));\n if (!mjml2html) throw new Error('mjml-browser did not load');\n return async (/** @type {string} */ mjml) => {\n const result = await mjml2html(mjml, { validationLevel: 'soft', keepComments: false });\n return {\n html: String(result.html || ''),\n errors: (result.errors || []).map((/** @type {any} */ e) => ({\n line: e.line,\n message: String(e.formattedMessage || e.message || e),\n tagName: e.tagName,\n })),\n };\n };\n}\n\n/**\n * @param {{\n * loadCompiler?: () => Promise<(mjml: string) => Promise<{html: string, errors: any[]}>>,\n * }} [options]\n * @returns {EmailEditorAdapter & {readonly view: any, readonly root: EmailNode|null}}\n */\nexport function createNativeAdapter({ loadCompiler = defaultLoadCompiler } = {}) {\n /** @type {EmailNode|null} */ let root = null;\n /** @type {string|null} */ let selectedId = null;\n /** @type {ReturnType<typeof createCanvasView>|null} */ let view = null;\n /** @type {(mjml: string) => Promise<{html: string, errors: any[]}>} */ let compile = async () => ({ html: '', errors: [] });\n /** @type {(type: string, payload?: any) => void} */ let emit = () => {};\n /** @type {(key: string, values?: Record<string, any>) => string} */ let t = (key) => key;\n /** @type {(selection: EngineSelection) => string} */ let labelOf = (s) => s.tagName;\n /** @type {HTMLElement|null} */ let container = null;\n let generation = 0;\n /** @type {{past: {root: EmailNode, selectedId: string|null}[], future: {root: EmailNode, selectedId: string|null}[], key: string|null, at: number}} */\n let history = { past: [], future: [], key: null, at: 0 };\n /** @type {Map<string, {keys: string[], handler: () => void}>} */\n const shortcuts = new Map();\n /** @type {EmailNode|null} */ let clipboard = null;\n /**\n * Ctrl+A: every section of the email selected at once (their ids), or null.\n * Any other selection, change or load ends it.\n */\n /** @type {string[]|null} */ let selectedAll = null;\n /** @type {(() => void)|null} */ let removeHostKeys = null;\n\n function requireRoot() {\n if (!root || !view) throw new Error('NativeAdapter: engine not initialized');\n return root;\n }\n\n const body = () => /** @type {EmailNode} */ (findFirst(requireRoot(), 'mj-body'));\n\n /* ── Describing ──────────────────────────────────────────────────────── */\n\n /** @param {string|null} id @returns {EngineSelection|null} */\n function describe(id) {\n if (!root || !id) return null;\n const node = findNode(root, id);\n if (!node || node.tag === 'mjml' || node.tag === 'mj-head') return null;\n const { index, count } = positionOf(root, id);\n const locked = LOCKED_TAGS.has(node.tag);\n return {\n id: node.id,\n tagName: node.tag,\n attributes: { ...node.attributes },\n content: LABEL_TAGS.has(node.tag) ? textOfHtml(node.content || '') : null,\n html: node.tag === 'mj-text' ? node.content || '' : null,\n canRemove: !locked,\n canDuplicate: !locked,\n canMoveUp: !locked && index > 0,\n canMoveDown: !locked && index >= 0 && index < count - 1,\n ...(node.tag === 'mj-section' && node.children.length && node.children.every((c) => c.tag === 'mj-column')\n ? { columnCount: node.children.length }\n : {}),\n };\n }\n\n /** What the canvas shows about an element. @param {string} id */\n function canvasInfo(id) {\n const selection = describe(id);\n if (!selection) return null;\n const parent = root ? parentOf(root, id) : null;\n return {\n label: labelOf(selection),\n tag: selection.tagName,\n canRemove: selection.canRemove,\n canDuplicate: selection.canDuplicate,\n // Dragged: content of a column, and sections. Columns, social icons and\n // menu links move among their siblings, from the panel.\n canMove: selection.canRemove && !BOUND_TAGS.has(selection.tagName),\n // A section's parent is the page: \"select the parent\" would only show\n // the page settings, which a click beside the email does already.\n hasParent: Boolean(parent && parent.tag !== 'mjml' && parent.tag !== 'mj-body'),\n parentLabel: parent && parent.tag !== 'mjml' && parent.tag !== 'mj-body' ? labelOf(/** @type {EngineSelection} */ (describe(parent.id))) : '',\n };\n }\n\n /**\n * The whole email selected (Ctrl+A): described as the body, with the\n * number of sections it holds (`multiple`); only \"delete\" applies.\n * @returns {EngineSelection|null}\n */\n function describeAll() {\n if (!root || !selectedAll) return null;\n const node = findFirst(root, 'mj-body');\n if (!node) return null;\n return {\n id: node.id,\n tagName: 'mj-body',\n attributes: { ...node.attributes },\n content: null,\n html: null,\n canRemove: true,\n canDuplicate: false,\n canMoveUp: false,\n canMoveDown: false,\n multiple: selectedAll.length,\n };\n }\n\n const currentSelection = () => (selectedAll ? describeAll() : describe(selectedId));\n const emitSelection = () => emit('selection', currentSelection());\n\n /** Ctrl+A: every section of the email. */\n function selectAll() {\n if (!root || !view) return;\n view.finishEditing();\n const ids = body().children.map((child) => child.id);\n if (!ids.length) return;\n selectedAll = ids;\n selectedId = null;\n view.setSelection(null);\n view.setMultiSelection(ids);\n emitSelection();\n }\n\n /** Ends a Ctrl+A selection (without emitting). */\n function clearAll() {\n if (!selectedAll) return;\n selectedAll = null;\n view?.setMultiSelection([]);\n }\n\n /** Delete with everything selected: the email's sections, in one step. */\n function removeAll() {\n const current = requireRoot();\n const all = selectedAll || [];\n clearAll();\n let next = current;\n for (const id of all) next = removeNode(next, id);\n commit(next, { select: null });\n if (next === current) emitSelection();\n }\n const emitHistory = () => emit('history', { canUndo: history.past.length > 0, canRedo: history.future.length > 0 });\n\n /* ── Changing ────────────────────────────────────────────────────────── */\n\n /**\n * One step of history.\n * @param {EmailNode} next\n * @param {{merge?: string|null, select?: string|null, render?: boolean}} [options]\n * `merge`: steps with the same key, close in time, become one;\n * `select`: the element to select afterwards (undefined: unchanged);\n * `render`: false while a text is typed (the browser already shows it).\n */\n function commit(next, { merge = null, select, render = true } = {}) {\n const current = requireRoot();\n if (next === current) return;\n clearAll();\n const now = Date.now();\n const merged = merge !== null && merge === history.key && now - history.at < MERGE_MS;\n if (!merged) {\n history.past.push({ root: current, selectedId });\n if (history.past.length > HISTORY_LIMIT) history.past.shift();\n }\n history.future = [];\n history.key = merge;\n history.at = now;\n root = next;\n if (select !== undefined) selectedId = select;\n if (selectedId && !findNode(root, selectedId)) selectedId = null;\n view?.setSelection(selectedId);\n emit('change');\n emitHistory();\n emitSelection();\n if (render) void view?.render();\n }\n\n /**\n * Replaces the email without history (load).\n * @param {EmailNode} next\n */\n function replace(next) {\n view?.finishEditing();\n clearAll();\n root = next;\n selectedId = null;\n history = { past: [], future: [], key: null, at: 0 };\n view?.setSelection(null);\n emit('load');\n emitSelection();\n emitHistory();\n void view?.render();\n }\n\n /** @param {'undo'|'redo'} direction */\n function travel(direction) {\n view?.finishEditing();\n clearAll();\n const from = direction === 'undo' ? history.past : history.future;\n const to = direction === 'undo' ? history.future : history.past;\n const step = from.pop();\n if (!step || !root) return;\n to.push({ root, selectedId });\n root = step.root;\n selectedId = step.selectedId && findNode(root, step.selectedId) ? step.selectedId : null;\n history.key = null;\n view?.setSelection(selectedId);\n emit('change');\n emitHistory();\n emitSelection();\n void view?.render();\n }\n\n /**\n * Inserts MJML at a placement; returns the element to focus.\n * @param {EmailBlock} block\n * @param {{parentId: string, index: number, wrap: boolean}} placement\n */\n function insertBlock(block, placement) {\n const source = placement.wrap\n ? /** @type {string} */ (block.sectionMjml) || `<mj-section><mj-column>${block.mjml}</mj-column></mj-section>`\n : /** @type {string} */ (block.mjml);\n const nodes = parseMjmlFragment(source);\n if (!nodes.length) return null;\n const focus = placement.wrap ? findFirst(nodes[0], block.tagName) || nodes[0] : nodes[0];\n commit(insertNodes(requireRoot(), placement.parentId, placement.index, nodes), { select: focus.id });\n return focus.id;\n }\n\n /**\n * Moves an element where it was dropped. A content element dropped between\n * two sections gets a new one-column section of its own.\n * @param {string} id @param {{parentId: string, index: number, wrap: boolean}} target\n */\n function moveTo(id, target) {\n const current = requireRoot();\n const node = findNode(current, id);\n if (!node) return;\n if (!target.wrap) {\n commit(moveNode(current, id, target.parentId, target.index), { select: id });\n return;\n }\n const section = createNode('mj-section', {\n attributes: { 'background-color': '#ffffff', 'padding-top': '0px', 'padding-bottom': '0px' },\n children: [createNode('mj-column', { children: [node] })],\n });\n commit(insertNodes(removeNode(current, id), target.parentId, target.index, [section]), { select: id });\n }\n\n /**\n * A column given a share of its section: the other columns share the rest\n * equally (MJML would give each of them its equal share of the WHOLE\n * section, leaving a gap or overflowing). Back to \"equal\": all equal again.\n * @param {EmailNode} tree @param {string} id @param {string|null|undefined} width\n */\n function balanceColumns(tree, id, width) {\n const parent = parentOf(tree, id);\n if (!parent) return tree;\n const others = parent.children.filter((c) => c.tag === 'mj-column' && c.id !== id);\n const share = Number.parseFloat(String(width || ''));\n let next = tree;\n for (const other of others) {\n const value =\n Number.isFinite(share) && share > 0 && share < 100 && String(width).trim().endsWith('%')\n ? `${Math.round(((100 - share) / others.length) * 100) / 100}%`\n : null;\n next = setAttributes(next, other.id, { width: value });\n }\n return next;\n }\n\n /** @param {string} id */\n function duplicateNode(id) {\n const current = requireRoot();\n const node = findNode(current, id);\n const parent = parentOf(current, id);\n if (!node || !parent || LOCKED_TAGS.has(node.tag)) return null;\n const copy = cloneWithNewIds(node);\n const index = parent.children.findIndex((c) => c.id === id) + 1;\n commit(insertNodes(current, parent.id, index, [copy]), { select: copy.id });\n return copy.id;\n }\n\n /** @param {string} id */\n function removeById(id) {\n const current = requireRoot();\n const node = findNode(current, id);\n if (!node || LOCKED_TAGS.has(node.tag)) return false;\n view?.finishEditing();\n commit(removeNode(current, id), { select: null });\n return true;\n }\n\n /** Paste: after the selected element of the same level, else by placement. */\n function paste() {\n if (!clipboard || !root) return;\n const copy = cloneWithNewIds(clipboard);\n const isSection = SECTION_TAGS.has(copy.tag);\n const selected = selectedId ? findNode(root, selectedId) : null;\n if (BOUND_TAGS.has(copy.tag)) {\n // A column, a social icon, a menu link: only beside one of its kind.\n const parent = selected && selected.tag === copy.tag ? parentOf(root, selected.id) : null;\n if (!parent) return;\n const index = parent.children.findIndex((c) => c.id === selected?.id) + 1;\n commit(insertNodes(root, parent.id, index, [copy]), { select: copy.id });\n return;\n }\n if (isSection) {\n const section = selected ? sectionOf(root, selected.id, body()) : null;\n const index = section ? body().children.findIndex((c) => c.id === section.id) + 1 : body().children.length;\n commit(insertNodes(root, body().id, index, [copy]), { select: copy.id });\n return;\n }\n const placement = placementFor(root, 'content', selectedId);\n const nodes = placement.wrap\n ? [createNode('mj-section', { attributes: { 'background-color': '#ffffff' }, children: [createNode('mj-column', { children: [copy] })] })]\n : [copy];\n commit(insertNodes(root, placement.parentId, placement.index, nodes), { select: copy.id });\n }\n\n /* ── Keyboard ────────────────────────────────────────────────────────── */\n\n /** `mod+s` → ['ctrl+s', 'meta+s']. @param {string} keys */\n function parseKeys(keys) {\n return keys\n .split(',')\n .map((k) => k.trim().toLowerCase())\n .filter(Boolean)\n .flatMap((k) => (k.startsWith('mod+') ? [`ctrl+${k.slice(4)}`, `meta+${k.slice(4)}`] : [k]));\n }\n\n /** @param {KeyboardEvent} event */\n function comboOf(event) {\n const parts = [];\n if (event.ctrlKey) parts.push('ctrl');\n if (event.metaKey) parts.push('meta');\n if (event.altKey) parts.push('alt');\n if (event.shiftKey) parts.push('shift');\n parts.push(event.key.toLowerCase());\n return parts.join('+');\n }\n\n /**\n * @param {KeyboardEvent} event\n * @param {'frame'|'host'} origin\n */\n function onKey(event, origin) {\n if (!root || !view || event.defaultPrevented) return;\n const combo = comboOf(event);\n for (const { keys, handler } of shortcuts.values()) {\n if (keys.includes(combo)) {\n event.preventDefault();\n handler();\n return;\n }\n }\n const editing = view.editingId() !== null;\n if (editing) {\n if (event.key === 'Escape') {\n event.preventDefault();\n view.finishEditing();\n }\n return; // typing belongs to the text\n }\n if (origin === 'host' && !hostKeyTarget(event.target)) return;\n const mod = event.ctrlKey || event.metaKey;\n const key = event.key.toLowerCase();\n if (mod && key === 'z' && !event.shiftKey) {\n event.preventDefault();\n travel('undo');\n } else if (mod && ((key === 'z' && event.shiftKey) || key === 'y')) {\n event.preventDefault();\n travel('redo');\n } else if (mod && key === 'a' && !event.shiftKey) {\n // The whole email (inside a text being edited, Ctrl+A stays the text's).\n event.preventDefault();\n selectAll();\n } else if (!mod && (event.key === 'Delete' || event.key === 'Backspace') && selectedAll) {\n event.preventDefault();\n removeAll();\n } else if (!mod && (event.key === 'Delete' || event.key === 'Backspace') && selectedId) {\n event.preventDefault();\n removeById(selectedId);\n } else if (mod && key === 'c' && selectedId) {\n const node = findNode(root, selectedId);\n if (node && !LOCKED_TAGS.has(node.tag)) clipboard = node;\n } else if (mod && key === 'v' && clipboard) {\n event.preventDefault();\n paste();\n } else if (mod && key === 'd' && selectedId) {\n event.preventDefault();\n duplicateNode(selectedId);\n } else if (event.key === 'Escape' && selectedAll) {\n event.preventDefault();\n adapter.select(null);\n } else if (event.key === 'Escape' && selectedId) {\n event.preventDefault();\n const parent = parentOf(root, selectedId);\n adapter.select(parent && parent.tag !== 'mjml' && parent.tag !== 'mj-body' ? parent.id : null);\n } else if (event.key === 'Enter' && selectedId && EDITABLE_TAGS.has(findNode(root, selectedId)?.tag || '')) {\n event.preventDefault();\n view.startEditing(selectedId);\n }\n }\n\n /**\n * A key pressed in the host page acts on the canvas only from inside the\n * builder, and never from a field (a field has its own Delete and Ctrl+Z).\n * @param {EventTarget|null} target\n */\n function hostKeyTarget(target) {\n const el = /** @type {HTMLElement|null} */ (target && /** @type {any} */ (target).nodeType === 1 ? target : null);\n if (!el || !container) return false;\n if (el.closest('input, textarea, select, [contenteditable=\"\"], [contenteditable=\"true\"], [role=\"dialog\"], [role=\"menu\"], [role=\"listbox\"]')) {\n return false;\n }\n const builder = container.closest('.eb-root') || container;\n return builder.contains(el) || el === el.ownerDocument.body;\n }\n\n /* ── Contract ────────────────────────────────────────────────────────── */\n\n /** @type {EmailEditorAdapter & {readonly view: any, readonly root: EmailNode|null}} */\n const adapter = {\n name: ENGINE_NAME,\n version: ENGINE_VERSION,\n\n get view() {\n return view;\n },\n\n /** The current tree, read-only (inspection, tests). */\n get root() {\n return root;\n },\n\n async initialize({ container: host, document, onEvent, t: translate, labelOf: label }) {\n if (view) throw new Error('NativeAdapter: already initialized');\n const ticket = ++generation;\n const loaded = await loadCompiler();\n if (ticket !== generation) return;\n\n emit = onEvent;\n if (translate) t = translate;\n if (label) labelOf = label;\n compile = loaded;\n container = host;\n root = document ? fromProject(document.project) : parseMjml(EMPTY_MJML);\n selectedId = null;\n history = { past: [], future: [], key: null, at: 0 };\n\n view = createCanvasView({\n container: host,\n compile,\n getRoot: () => /** @type {EmailNode} */ (root),\n t,\n info: canvasInfo,\n onSelect: (id) => adapter.select(id),\n onAction: (action, id) => {\n if (action === 'parent') {\n const parent = root ? parentOf(root, id) : null;\n adapter.select(parent && parent.tag !== 'mjml' && parent.tag !== 'mj-body' ? parent.id : null);\n } else if (action === 'duplicate') duplicateNode(id);\n else if (action === 'remove') removeById(id);\n },\n onDrop: (payload, target) => {\n if (payload.nodeId) moveTo(payload.nodeId, target);\n else if (payload.block) insertBlock(payload.block, target);\n },\n onEditStart: () => {\n history.key = null;\n },\n onEditInput: (id, html) => {\n const current = requireRoot();\n const node = findNode(current, id);\n if (!node || node.content === html) return;\n commit(setContent(current, id, html), { merge: `text:${id}`, render: false });\n },\n onEditEnd: (id, html) => {\n const current = requireRoot();\n const node = findNode(current, id);\n if (node && node.content !== html) commit(setContent(current, id, html), { merge: `text:${id}` });\n else void view?.render();\n history.key = null;\n },\n onKeyDown: (event) => onKey(event, 'frame'),\n });\n const onHostKey = (/** @type {KeyboardEvent} */ event) => onKey(event, 'host');\n host.ownerDocument.addEventListener('keydown', onHostKey);\n removeHostKeys = () => host.ownerDocument.removeEventListener('keydown', onHostKey);\n\n await view.render();\n if (ticket !== generation) return;\n emitHistory();\n },\n\n destroy() {\n generation += 1;\n removeHostKeys?.();\n removeHostKeys = null;\n view?.destroy();\n view = null;\n root = null;\n selectedId = null;\n container = null;\n emit = () => {};\n },\n\n addBlock(block, { targetId = null } = {}) {\n const current = requireRoot();\n view?.finishEditing();\n const target = targetId && findNode(current, targetId) ? targetId : selectedId;\n const placement = placementFor(current, block.kind === 'layout' ? 'layout' : 'content', target);\n return insertBlock(block, placement);\n },\n\n remove(id) {\n // With everything selected, removing the body means removing its content.\n if (selectedAll && root && id === findFirst(root, 'mj-body')?.id) {\n removeAll();\n return true;\n }\n return removeById(id);\n },\n duplicate: (id) => duplicateNode(id),\n\n move(id, direction) {\n const current = requireRoot();\n const node = findNode(current, id);\n const { parent, index, count } = positionOf(current, id);\n if (!node || !parent || LOCKED_TAGS.has(node.tag)) return false;\n const to = index + direction;\n if (to < 0 || to >= count) return false;\n view?.finishEditing();\n commit(moveNode(current, id, parent.id, direction > 0 ? to + 1 : to), { select: id });\n return true;\n },\n\n select(id) {\n if (!root) return;\n const next = id && findNode(root, id) && describe(id) ? id : null;\n if (selectedAll) {\n clearAll();\n selectedId = next;\n view?.setSelection(next);\n emitSelection();\n return;\n }\n if (next === selectedId) {\n view?.setSelection(next);\n return;\n }\n selectedId = next;\n view?.setSelection(next);\n emitSelection();\n },\n\n selectAll: () => selectAll(),\n\n getSelection: () => currentSelection(),\n describe: (id) => describe(id),\n getRootId: () => (root ? findFirst(root, 'mj-body')?.id || null : null),\n\n updateProperties(id, attributes) {\n const current = requireRoot();\n const node = findNode(current, id);\n if (!node) return;\n if (view?.editingId() === id) view.finishEditing();\n const keys = Object.keys(attributes).sort().join(',');\n let next = setAttributes(current, id, attributes);\n if (node.tag === 'mj-column' && 'width' in attributes) next = balanceColumns(next, id, attributes.width);\n commit(next, { merge: `attributes:${id}:${keys}` });\n },\n\n setContent(id, content) {\n const current = requireRoot();\n const node = findNode(current, id);\n if (!node || node.content === null) return;\n const value = LABEL_TAGS.has(node.tag) ? escapeText(content) : String(content || '');\n if (view?.editingId() === id) view.finishEditing();\n commit(setContent(requireRoot(), id, value), { merge: `content:${id}` });\n },\n\n insertText(text) {\n if (!view || !root) return false;\n if (view.editingId()) return view.insertText(text);\n const node = selectedId ? findNode(root, selectedId) : null;\n if (!node || !TEXT_TAGS.has(node.tag)) return false;\n commit(setContent(root, node.id, `${node.content || ''} ${escapeText(text)}`));\n return true;\n },\n\n insertLink(href, label) {\n if (!view || !root) return false;\n const safeHref = escapeText(href).replace(/\"/g, '"');\n const html = `<a href=\"${safeHref}\">${escapeText(label)}</a>`;\n if (view.editingId()) return view.insertHtml(html);\n const node = selectedId ? findNode(root, selectedId) : null;\n if (node && node.tag === 'mj-button') {\n commit(setAttributes(root, node.id, { href }));\n return true;\n }\n if (node && node.tag === 'mj-text') {\n commit(setContent(root, node.id, `${node.content || ''} ${html}`));\n return true;\n }\n return false;\n },\n\n undo: () => travel('undo'),\n redo: () => travel('redo'),\n canUndo: () => history.past.length > 0,\n canRedo: () => history.future.length > 0,\n clearHistory() {\n history = { past: [], future: [], key: null, at: 0 };\n emitHistory();\n },\n\n getProject: () => toProject(requireRoot()),\n\n loadProject(project) {\n requireRoot();\n replace(fromProject(project));\n },\n\n loadMjml(mjml) {\n requireRoot();\n replace(parseMjml(mjml || EMPTY_MJML));\n },\n\n setMjml(mjml) {\n requireRoot();\n view?.finishEditing();\n commit(parseMjml(mjml || EMPTY_MJML), { select: null });\n },\n\n exportMjml: () => serializeMjml(requireRoot()),\n\n async exportHtml(mjml = null) {\n return compile(mjml ?? serializeMjml(requireRoot()));\n },\n\n setDevice(device) {\n if (!view) return;\n view.setDevice(device);\n emit('device', device);\n },\n\n getDevice: () => (view ? view.getDevice() : 'desktop'),\n\n startBlockDrag(block, event) {\n if (!view) return;\n const pointer = /** @type {PointerEvent} */ (event);\n const target = /** @type {Element|null} */ (pointer.currentTarget || pointer.target);\n if (!target || typeof pointer.pointerId !== 'number') return;\n view.startDrag({\n payload: { kind: block.kind === 'layout' ? 'layout' : 'content', block },\n label: t(block.label),\n source: 'host',\n pointerId: pointer.pointerId,\n captureTarget: target,\n x: pointer.clientX,\n y: pointer.clientY,\n });\n },\n\n endBlockDrag() {\n view?.cancelDrag();\n },\n\n addShortcut(id, keys, handler) {\n shortcuts.set(id, { keys: parseKeys(keys), handler });\n return () => {\n if (shortcuts.get(id)?.handler === handler) shortcuts.delete(id);\n };\n },\n };\n\n return adapter;\n}\n","// @ts-check\n/**\n * The editor wired to the default engine and the built-in registries. In a\n * module of its own so the builder can use it without importing the package\n * entry (and, through it, the template bank).\n */\n\nimport { createEmailEditor } from './core/EmailEditor.js';\nimport { createNativeAdapter } from './engine/NativeAdapter.js';\nimport { emailBlocks } from './blocks/index.js';\nimport { emailBuilderFeatures } from './features/index.js';\nimport { translatorFor } from './i18n/index.js';\n\n/**\n * An editor wired to the default engine and the built-in registries.\n *\n * @param {{locale?: string, t?: import('./i18n/index.js').Translate}} [options]\n * `t`: the interface's translator (texts of inserted blocks, names in the\n * canvas); by default the built-in one of `locale` (`'en'`).\n */\nexport function createDefaultEmailEditor(options = {}) {\n const { locale = 'en', t = translatorFor(locale) } = options;\n return createEmailEditor({\n adapter: createNativeAdapter(),\n blocks: emailBlocks,\n features: emailBuilderFeatures,\n t,\n });\n}\n","import { useEffect, useRef } from 'react';\nimport { cn } from './primitives/cn.js';\n\n/**\n * Canvas area: the node where the editor mounts its engine.\n *\n * Only knows `EmailEditor`: `initialize` on mount, `destroy` on unmount.\n * React strict mode's double mount is absorbed by the editor (an\n * initialization made stale by a `destroy` never reports ready).\n *\n * `document` is only read on mount: reloading a document goes through\n * `editor.loadDocument`, not through a new render.\n */\nexport default function EmailCanvas({ editor, document = null, onReady, onError, className }) {\n const ref = useRef(null);\n const documentRef = useRef(document);\n const callbacks = useRef({ onReady, onError });\n callbacks.current = { onReady, onError };\n\n useEffect(() => {\n if (!editor || !ref.current) return undefined;\n let alive = true;\n editor\n .initialize({ container: ref.current, document: documentRef.current })\n .then(() => {\n if (alive && editor.status === 'ready') callbacks.current.onReady?.(editor);\n })\n .catch((error) => {\n if (alive) callbacks.current.onError?.(error);\n });\n return () => {\n alive = false;\n editor.destroy();\n };\n }, [editor]);\n\n return <div ref={ref} className={cn('eb-canvas eb:h-full eb:w-full', className)} data-testid=\"eb-canvas\" />;\n}\n","import { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { AlertTriangle, Loader2, Plus, Save, SlidersHorizontal } from 'lucide-react';\nimport { createDefaultEmailEditor } from '../defaultEditor.js';\nimport { emailBuilderFeatures, isFeatureEnabled } from '../features/index.js';\nimport { DEFAULT_VARIABLES, defineVariables, mergeVariables } from '../features/variables/catalog.js';\nimport { createStarterMjml } from '../features/templates/starter.js';\nimport { TEMPLATE_GALLERY, buildGallery } from '../features/templates/gallery.js';\nimport { brandTemplate, brandedSender, hasBrand } from '../features/brand/brand.js';\nimport { brandOf, useBrand } from '../features/brand/useBrand.js';\nimport { createAutosaveScheduler } from '../features/autosave/scheduler.js';\nimport { clearLocalDraft, readLocalDraft, saveLocalDraft } from '../features/autosave/localDraft.js';\nimport { createHttpStorage } from '../storage/client.js';\nimport { NoticeArea, UiProvider, useUi } from './context.jsx';\nimport { Button } from './primitives/button.jsx';\nimport { cn } from './primitives/cn.js';\nimport EmailCanvas from './EmailCanvas.jsx';\nimport BlockSidebar from './BlockSidebar.jsx';\nimport ElementActions from './ElementActions.jsx';\nimport PropertiesPanel from './PropertiesPanel.jsx';\nimport Toolbar from './Toolbar.jsx';\nimport Drawer from './Drawer.jsx';\nimport { useEmailEditorState } from './useEmailEditorState.js';\nimport { useLayoutWidth } from './useLayoutWidth.js';\n\n/**\n * THE EMAIL BUILDER — the screen.\n *\n * ┌───────────────────────────────────────────────────────────────┐\n * │ Back · name ↶ ↷ Desktop|Mobile … Save │\n * ├────────────┬───────────────────────────────┬──────────────────┤\n * │ Blocks │ canvas │ Properties │\n * └────────────┴───────────────────────────────┴──────────────────┘\n *\n * Only talks to `EmailEditor` (core/EmailEditor.js) and to the storage\n * (storage/client.js). The engine is loaded when the canvas mounts.\n *\n * ── SAVE ────────────────────────────────────────────────────────────────────\n * \"Save\" (or Ctrl+S, inside the canvas too) sends the PROJECT and its MJML;\n * the server validates, compiles and creates a version. A template changed\n * elsewhere in the meantime is not overwritten: saving a copy is offered.\n *\n * ── INITIAL CONTENT (`initialMjml`, `initialMeta`) ──────────────────────────\n * A new template can start from given MJML instead of the starter template —\n * e.g. a template imported from another format. It counts as modified until\n * the first save.\n *\n * ── NARROW SCREENS (`useLayoutWidth`) ───────────────────────────────────────\n * Measured on the builder's own box. Below the wide layout the properties\n * move to a drawer and the toolbar takes two rows; on a phone the blocks go to\n * a drawer too, and a bar under the canvas opens them (\"Add a block\", \"Edit\").\n * Adding a block from the sidebar opens its properties.\n *\n * ── AUTOSAVE (feature `autosave`) ───────────────────────────────────────────\n * Template already saved: server save without a version. New template: local\n * draft, offered again at the next opening.\n */\n\nconst EMPTY_META = { name: '', subject: '', preheader: '', description: '' };\n\nfunction metaOf(template) {\n return {\n name: template?.name || '',\n subject: template?.subject || '',\n preheader: template?.preheader || '',\n description: template?.description || '',\n };\n}\n\nconst sameMeta = (a, b) => Object.keys(EMPTY_META).every((k) => (a[k] || '') === (b[k] || ''));\n\nfunction Builder({\n editor: injected,\n storage: injectedStorage,\n templateId: initialTemplateId,\n variables: variablesProp,\n sender,\n starterMjml,\n templates: galleryProp,\n testRecipients,\n initialMjml,\n initialMeta,\n onClose,\n onSaved,\n onDirtyChange,\n dirtyCheckRef,\n className,\n}) {\n const { t, locale, notify, confirm } = useUi();\n // The editor reads the translator through a ref: a new `messages` object\n // from the host must not rebuild the editor (and lose the email).\n const tRef = useRef(t);\n tRef.current = t;\n const editor = useMemo(\n () => injected || createDefaultEmailEditor({ locale, t: (key, values) => tRef.current(key, values) }),\n [injected, locale]\n );\n const storage = useMemo(() => injectedStorage || createHttpStorage(), [injectedStorage]);\n const systemVariables = useMemo(() => defineVariables(variablesProp || DEFAULT_VARIABLES), [variablesProp]);\n const [customVariables, setCustomVariables] = useState([]);\n const variables = useMemo(() => mergeVariables(systemVariables, customVariables), [systemVariables, customVariables]);\n const canManageVariables = typeof storage.saveVariable === 'function' && typeof storage.listVariables === 'function';\n const reloadVariables = useCallback(async () => {\n if (typeof storage.listVariables !== 'function') return;\n try {\n setCustomVariables(await storage.listVariables());\n } catch (error) {\n notify('error', error.message);\n }\n }, [storage, notify]);\n useEffect(() => {\n reloadVariables();\n }, [reloadVariables]);\n // The brand (if any) over the host's sender: new emails, templates and\n // blocks take its name, logo, colors and font.\n const { brand, setBrand } = useBrand(storage);\n const brandSender = useMemo(() => brandedSender(sender, brand), [sender, brand]);\n const starter = useMemo(\n () => brandTemplate(starterMjml || createStarterMjml({ sender: brandSender, t }), brand, { sender, t }),\n [starterMjml, brandSender, brand, sender, t]\n );\n const templates = useMemo(\n () =>\n buildGallery({ templates: galleryProp ?? TEMPLATE_GALLERY, sender: brandSender, t }).map((template) => ({\n ...template,\n mjml: brandTemplate(template.mjml, brand, { sender, t }),\n })),\n [galleryProp, brandSender, brand, sender, t]\n );\n useEffect(() => {\n editor.setBrand?.(hasBrand(brand) ? brand : null);\n }, [editor, brand]);\n const services = useMemo(\n () => ({\n uploadImage: (file) => storage.uploadImage(file),\n rewrite: typeof storage.rewrite === 'function' ? (input, options) => storage.rewrite(input, options) : null,\n suggestSubjects:\n typeof storage.suggestSubjects === 'function' ? (input, options) => storage.suggestSubjects(input, options) : null,\n }),\n [storage]\n );\n const state = useEmailEditorState(editor);\n const autosaveOn = isFeatureEnabled('autosave');\n const autosaveOptions = emailBuilderFeatures.get('autosave')?.options || {};\n\n const [template, setTemplate] = useState({ id: initialTemplateId, revision: null, savedAt: null, auto: false });\n /**\n * loading → (error) → ready ; `document`: project to mount (null = starter\n * template, or `mjml`: a template saved by an earlier engine, reopened from\n * its MJML).\n */\n const [boot, setBoot] = useState({ status: 'loading', document: null, mjml: null, draft: false, message: null });\n const [meta, setMeta] = useState(EMPTY_META);\n const [savedMeta, setSavedMeta] = useState(EMPTY_META);\n const [saving, setSaving] = useState(null);\n const [showErrors, setShowErrors] = useState(false);\n const [autosaveBlocked, setAutosaveBlocked] = useState(null);\n const [engineError, setEngineError] = useState(null);\n const [attempt, setAttempt] = useState(0);\n\n const rootRef = useRef(null);\n const layout = useLayoutWidth(rootRef);\n const compact = layout !== 'wide';\n const blocksInDrawer = layout === 'narrow';\n /** Open drawer of the compact layouts: 'blocks', 'properties' or null. */\n const [drawer, setDrawer] = useState(null);\n const closeDrawer = useCallback(() => setDrawer(null), []);\n useEffect(() => {\n if (!compact) setDrawer(null);\n else if (!blocksInDrawer) setDrawer((d) => (d === 'blocks' ? null : d));\n }, [compact, blocksInDrawer]);\n\n const ready = state.status === 'ready';\n const metaDirty = !sameMeta(meta, savedMeta);\n const dirty = state.dirty || metaDirty;\n\n const timeOf = useCallback(\n (date) => (date ? new Date(date).toLocaleTimeString(locale, { hour: '2-digit', minute: '2-digit' }) : ''),\n [locale]\n );\n\n /* ── Start: saved template, local draft, or starter template ── */\n const booted = useRef(false);\n useEffect(() => {\n if (booted.current) return;\n booted.current = true;\n (async () => {\n // A new email starts in the brand's look: it is known first.\n await brandOf(storage).loaded;\n if (initialTemplateId) {\n try {\n const loaded = await storage.load(initialTemplateId);\n setMeta(metaOf(loaded));\n setSavedMeta(metaOf(loaded));\n setTemplate({ id: loaded.id, revision: loaded.revision, savedAt: null, auto: false });\n // Saved by an earlier engine: its project cannot be read, its MJML can.\n const own = loaded.document?.engine === editor.adapterName;\n if (!own && !loaded.mjml) throw new Error(t('This template was saved in a format this builder cannot open.'));\n setBoot({\n status: 'ready',\n document: own ? loaded.document : null,\n mjml: own ? null : loaded.mjml,\n draft: false,\n message: null,\n });\n } catch (error) {\n setBoot({ status: 'error', document: null, mjml: null, draft: false, message: error.message });\n }\n return;\n }\n if (initialMjml) {\n setMeta({ ...EMPTY_META, ...initialMeta });\n setBoot({ status: 'ready', document: null, mjml: null, draft: true, message: null });\n return;\n }\n const stored = autosaveOn ? readLocalDraft() : null;\n // A draft from an earlier engine cannot be reopened: it is let go.\n const draft = stored && stored.document?.engine === editor.adapterName ? stored : null;\n if (stored && !draft) clearLocalDraft();\n if (draft) {\n const when = new Date(draft.savedAt).toLocaleString(locale, {\n day: '2-digit',\n month: '2-digit',\n hour: '2-digit',\n minute: '2-digit',\n });\n const restore = await confirm({\n title: t('Resume the draft?'),\n description: t('Unsaved template from {when}.', { when }),\n confirmLabel: t('Resume'),\n cancelLabel: t('Start over'),\n });\n if (restore) {\n setMeta({ ...EMPTY_META, ...draft.meta });\n setBoot({ status: 'ready', document: draft.document, mjml: null, draft: true, message: null });\n return;\n }\n clearLocalDraft();\n }\n setBoot({ status: 'ready', document: null, mjml: null, draft: false, message: null });\n })();\n // Initial content is read once, at start-up, like `templateId`.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [initialTemplateId, storage, autosaveOn, confirm, t, locale]);\n\n const onReady = useCallback(() => {\n if (!boot.document) editor.loadMjml(boot.mjml || initialMjml || starter);\n }, [editor, boot.document, boot.mjml, starter, initialMjml]);\n\n // A resumed draft was never saved: it is \"modified\".\n const { markDirty, markClean, checkDirty } = state;\n useEffect(() => {\n if (ready && boot.draft) markDirty();\n }, [ready, boot.draft, markDirty]);\n\n /* ── Modified? (the host screen and \"Back\" need the immediate answer) ── */\n const isDirty = useCallback(\n () => (editor.status === 'ready' && checkDirty()) || metaDirty,\n [editor, checkDirty, metaDirty]\n );\n const reportDirty = useRef(onDirtyChange);\n reportDirty.current = onDirtyChange;\n useEffect(() => {\n reportDirty.current?.(dirty);\n }, [dirty]);\n useEffect(() => {\n if (!dirtyCheckRef) return undefined;\n dirtyCheckRef.current = isDirty;\n return () => {\n dirtyCheckRef.current = null;\n };\n }, [dirtyCheckRef, isDirty]);\n\n // Closing the tab with work in progress: the browser asks.\n useEffect(() => {\n if (!dirty) return undefined;\n const warn = (e) => {\n e.preventDefault();\n e.returnValue = '';\n };\n window.addEventListener('beforeunload', warn);\n return () => window.removeEventListener('beforeunload', warn);\n }, [dirty]);\n\n /* ── Save ────────────────────────────────────────────────────────────── */\n const savingRef = useRef(false);\n const latest = useRef({});\n latest.current = { template, meta, onSaved, compact };\n\n const save = useCallback(\n async ({ auto = false } = {}) => {\n if (savingRef.current || editor.status !== 'ready') return false;\n const { template: current, meta: currentMeta } = latest.current;\n if (!currentMeta.name.trim()) {\n if (!auto) {\n setShowErrors(true);\n editor.select(null);\n setDrawer((d) => (d === null && latest.current.compact ? 'properties' : d));\n notify('error', t('Give the template a name before saving it.'));\n }\n return false;\n }\n const document = editor.getDocument();\n const mjml = editor.exportMjml();\n const payload = { ...currentMeta, document, mjml };\n savingRef.current = true;\n setSaving(auto ? 'auto' : 'manual');\n try {\n const result = current.id\n ? await storage.save(current.id, { ...payload, revision: current.revision, createVersion: !auto })\n : await storage.create(payload);\n setTemplate({ id: result.template.id, revision: result.template.revision, savedAt: new Date(), auto });\n setSavedMeta(currentMeta);\n setShowErrors(false);\n setAutosaveBlocked(null);\n markClean(mjml);\n if (!current.id) clearLocalDraft();\n latest.current.onSaved?.(result.template);\n const warnings = result.warnings || [];\n if (warnings.length) {\n notify(\n 'warning',\n t('Saved, with {count} MJML warning(s): {message}', { count: warnings.length, message: warnings[0].message })\n );\n } else if (!auto) {\n notify(\n 'success',\n result.version ? t('Saved — version {n}.', { n: result.version.versionNumber }) : t('Template saved.')\n );\n }\n return true;\n } catch (error) {\n if (error.status === 409 && current.id) {\n if (auto) {\n setAutosaveBlocked(error.message);\n return false;\n }\n const copy = await confirm({\n title: t('Template changed in the meantime'),\n description: t('{message} Your version can be saved as a copy.', { message: error.message }),\n confirmLabel: t('Save a copy'),\n });\n if (!copy) return false;\n try {\n const result = await storage.create({\n ...payload,\n name: t('{name} (copy)', { name: currentMeta.name }).slice(0, 200),\n });\n const copyMeta = { ...currentMeta, name: result.template.name };\n setMeta(copyMeta);\n setSavedMeta(copyMeta);\n setTemplate({ id: result.template.id, revision: result.template.revision, savedAt: new Date(), auto: false });\n setAutosaveBlocked(null);\n markClean(mjml);\n latest.current.onSaved?.(result.template);\n notify('success', t('Copy saved: “{name}”.', { name: result.template.name }));\n return true;\n } catch (copyError) {\n notify('error', copyError.message);\n return false;\n }\n }\n if (auto) setAutosaveBlocked(error.message);\n else notify('error', error.message);\n return false;\n } finally {\n savingRef.current = false;\n setSaving(null);\n }\n },\n [editor, storage, markClean, notify, confirm, t]\n );\n\n // Ctrl+S: in the page (fields included) and in the canvas (iframe).\n useEffect(() => {\n const onKey = (e) => {\n if ((e.ctrlKey || e.metaKey) && !e.shiftKey && !e.altKey && e.key.toLowerCase() === 's') {\n e.preventDefault();\n save();\n }\n };\n window.addEventListener('keydown', onKey, true);\n return () => window.removeEventListener('keydown', onKey, true);\n }, [save]);\n useEffect(() => {\n if (!ready) return undefined;\n return editor.addShortcut('save', 'mod+s', () => save());\n }, [ready, editor, save]);\n\n /* ── Autosave ────────────────────────────────────────────────────────── */\n const scheduler = useMemo(\n () =>\n createAutosaveScheduler({\n run: () => save({ auto: true }),\n idleMs: autosaveOptions.idleMs,\n maxWaitMs: autosaveOptions.maxWaitMs,\n }),\n [save, autosaveOptions.idleMs, autosaveOptions.maxWaitMs]\n );\n useEffect(() => () => scheduler.dispose(), [scheduler]);\n useEffect(() => {\n if (!autosaveOn || !ready || !template.id || autosaveBlocked) return;\n if (dirty) scheduler.notify();\n else scheduler.reset();\n }, [autosaveOn, ready, template.id, autosaveBlocked, dirty, state.changes, meta, scheduler]);\n\n // Never saved template: local draft.\n useEffect(() => {\n if (!autosaveOn || !ready || template.id || !dirty) return undefined;\n const timer = setTimeout(() => {\n if (editor.status === 'ready') saveLocalDraft({ document: editor.getDocument(), meta });\n }, autosaveOptions.draftDelayMs ?? 1500);\n return () => clearTimeout(timer);\n }, [autosaveOn, ready, template.id, dirty, state.changes, meta, editor, autosaveOptions.draftDelayMs]);\n\n /* ── Back ────────────────────────────────────────────────────────────── */\n const back = async () => {\n if (isDirty()) {\n const ok = await confirm({\n title: t('Leave the builder?'),\n description: template.id\n ? t('Unsaved changes will be lost.')\n : t('The draft will be offered again next time.'),\n confirmLabel: t('Leave'),\n destructive: true,\n });\n if (!ok) return;\n }\n onClose?.();\n };\n\n /* ── Render ──────────────────────────────────────────────────────────── */\n const status = !ready\n ? t('Loading…')\n : saving === 'manual'\n ? t('Saving…')\n : saving === 'auto'\n ? t('Autosaving…')\n : autosaveBlocked\n ? t('Autosave paused')\n : dirty\n ? t('Unsaved changes')\n : template.savedAt\n ? template.auto\n ? t('Autosaved at {time}', { time: timeOf(template.savedAt) })\n : t('Saved at {time}', { time: timeOf(template.savedAt) })\n : template.id\n ? t('Saved')\n : t('No changes');\n\n const featureContext = {\n editor,\n storage,\n template,\n meta,\n setMeta,\n templates,\n ready,\n isDirty,\n markDirty,\n save,\n variables,\n systemVariables,\n canManageVariables,\n reloadVariables,\n testRecipients,\n // What emails are signed with (the brand over the host's sender), and the\n // host's own sender (the name a branded email may still show).\n sender: brandSender,\n hostSender: sender,\n brand,\n setBrand,\n };\n const toolbarFeatures = emailBuilderFeatures.list(\n (f) => f.enabled !== false && Boolean(f.toolbar) && (f.isAvailable ? f.isAvailable(featureContext) : true)\n );\n\n const properties = (\n <PropertiesPanel\n onDismiss={compact ? closeDrawer : null}\n editor={editor}\n selection={ready ? state.selection : null}\n meta={meta}\n onMetaChange={setMeta}\n changes={state.changes}\n showErrors={showErrors}\n actions={<ElementActions editor={editor} selection={state.selection} />}\n services={services}\n variables={variables}\n />\n );\n\n return (\n <div\n ref={rootRef}\n className={cn('eb-root eb:relative eb:flex eb:h-full eb:min-h-0 eb:flex-col eb:bg-background eb:text-foreground', className)}\n data-testid=\"email-builder\"\n data-status={state.status}\n data-layout={layout}\n data-template-id={template.id || ''}\n >\n <Toolbar\n title={meta.name}\n status={status}\n ready={ready}\n canUndo={state.canUndo}\n canRedo={state.canRedo}\n onUndo={() => editor.undo()}\n onRedo={() => editor.redo()}\n device={state.device}\n onDeviceChange={(device) => editor.setDevice(device)}\n onBack={onClose ? back : undefined}\n compact={compact}\n actions={toolbarFeatures.map((feature) => {\n const Action = feature.toolbar;\n return <Action key={feature.id} context={featureContext} />;\n })}\n primary={\n <Button size=\"sm-compact\" onClick={() => save()} disabled={!ready || saving !== null}>\n {saving === 'manual' ? <Loader2 className=\"eb:animate-spin\" /> : <Save />}\n {t('Save')}\n </Button>\n }\n />\n <div\n className={cn(\n 'eb:relative eb:grid eb:min-h-0 eb:flex-1 eb:grid-rows-1',\n layout === 'wide' && 'eb:grid-cols-[224px_minmax(0,1fr)_296px]',\n layout === 'medium' && 'eb:grid-cols-[200px_minmax(0,1fr)]',\n layout === 'narrow' && 'eb:grid-cols-1'\n )}\n >\n {!blocksInDrawer && <BlockSidebar editor={editor} disabled={!ready} onAdded={compact ? () => setDrawer('properties') : undefined} />}\n <div className=\"eb:relative eb:min-w-0 eb:bg-surface-75\" aria-busy={!ready}>\n {boot.status === 'error' || engineError ? (\n <div role=\"alert\" className=\"eb:flex eb:h-full eb:flex-col eb:items-center eb:justify-center eb:gap-2 eb:p-6 eb:text-center\">\n <AlertTriangle className=\"eb:size-6 eb:text-destructive\" aria-hidden=\"true\" />\n <p className=\"eb:text-[13px] eb:text-foreground\">\n {boot.status === 'error' ? t('The template could not be loaded.') : t('The builder could not start.')}\n </p>\n <p className=\"eb:max-w-sm eb:text-[12px] eb:text-foreground-muted\">{boot.message || engineError}</p>\n {engineError && (\n <Button\n variant=\"outline\"\n size=\"sm-compact\"\n onClick={() => {\n setEngineError(null);\n setAttempt((n) => n + 1);\n }}\n >\n {t('Retry')}\n </Button>\n )}\n </div>\n ) : (\n <>\n {boot.status === 'ready' && (\n <EmailCanvas\n key={attempt}\n editor={editor}\n document={boot.document}\n onReady={onReady}\n onError={(error) => setEngineError(error.message)}\n />\n )}\n {!ready && (\n <div className=\"eb:absolute eb:inset-0 eb:flex eb:items-center eb:justify-center eb:bg-surface-75\" role=\"status\" aria-live=\"polite\">\n <Loader2 className=\"eb:size-6 eb:animate-spin eb:text-foreground-muted\" aria-hidden=\"true\" />\n <span className=\"eb:sr-only\">{t('Loading the builder')}</span>\n </div>\n )}\n </>\n )}\n </div>\n {!compact && properties}\n {blocksInDrawer && (\n <Drawer open={drawer === 'blocks'} side=\"left\" title={t('Add a block')} onClose={closeDrawer} testId=\"eb-blocks-drawer\">\n <BlockSidebar editor={editor} disabled={!ready} onAdded={() => setDrawer('properties')} />\n </Drawer>\n )}\n {compact && (\n <Drawer\n open={drawer === 'properties'}\n side=\"right\"\n title={t('Properties')}\n onClose={closeDrawer}\n testId=\"eb-properties-drawer\"\n header={false}\n >\n {properties}\n </Drawer>\n )}\n </div>\n {compact && (\n <div className=\"eb:flex eb:shrink-0 eb:items-center eb:gap-2 eb:border-t eb:border-border eb:px-2 eb:py-2\" data-testid=\"eb-compact-bar\">\n {blocksInDrawer && (\n <Button variant=\"outline\" size=\"sm-compact\" disabled={!ready} onClick={() => setDrawer('blocks')}>\n <Plus />\n {t('Add a block')}\n </Button>\n )}\n <Button\n variant={state.selection ? 'default' : 'outline'}\n size=\"sm-compact\"\n className=\"eb:ml-auto eb:min-w-0\"\n disabled={!ready}\n onClick={() => setDrawer('properties')}\n >\n <SlidersHorizontal />\n <span className=\"eb:truncate\">\n {ready && state.selection ? t('Edit: {element}', { element: t(state.selection.label) }) : t('Email settings')}\n </span>\n </Button>\n </div>\n )}\n <NoticeArea />\n </div>\n );\n}\n\n/**\n * @param {{\n * storage?: import('../storage/client.js').TemplateStorage,\n * templateId?: string|number|null,\n * editor?: import('../core/EmailEditor.js').EmailEditor,\n * locale?: string,\n * messages?: Record<string, string>,\n * onNotify?: (level: 'success'|'info'|'warning'|'error', message: string) => void,\n * variables?: import('../features/variables/catalog.js').EmailVariable[],\n * sender?: import('../features/templates/starter.js').StarterSender,\n * starterMjml?: string,\n * templates?: import('../features/templates/gallery.js').GalleryTemplate[],\n * testRecipients?: string[],\n * initialMjml?: string,\n * initialMeta?: {name?: string, subject?: string, preheader?: string, description?: string},\n * onClose?: () => void,\n * onSaved?: (template: object) => void,\n * onDirtyChange?: (dirty: boolean) => void,\n * dirtyCheckRef?: {current: null | (() => boolean)},\n * className?: string,\n * }} props\n */\nexport default function EmailBuilder({ locale = 'en', messages, onNotify, ...props }) {\n return (\n <UiProvider locale={locale} messages={messages} onNotify={onNotify}>\n <Builder {...props} templateId={props.templateId ?? null} />\n </UiProvider>\n );\n}\n","// @ts-check\n/**\n * AUTOSAVE scheduler — no React, no global timer.\n *\n * Two delays, because one is not enough:\n * - `idleMs` after the LAST change (do not save in the middle of a\n * sentence);\n * - `maxWaitMs` since the FIRST unsaved change: someone editing without a\n * pause for ten minutes must still get their work saved.\n *\n * `notify()` on every change, `reset()` after any save (automatic or not),\n * `dispose()` on unmount. Timers are injectable for tests.\n */\n\n/**\n * @param {{\n * run: () => (void | Promise<unknown>),\n * idleMs?: number,\n * maxWaitMs?: number,\n * now?: () => number,\n * setTimer?: (fn: () => void, ms: number) => any,\n * clearTimer?: (handle: any) => void,\n * }} options\n */\nexport function createAutosaveScheduler({\n run,\n idleMs = 20_000,\n maxWaitMs = 120_000,\n now = () => Date.now(),\n setTimer = (fn, ms) => setTimeout(fn, ms),\n clearTimer = (handle) => clearTimeout(handle),\n}) {\n /** @type {number|null} */\n let firstChangeAt = null;\n let handle = null;\n let disposed = false;\n\n function clear() {\n if (handle !== null) clearTimer(handle);\n handle = null;\n }\n\n function fire() {\n handle = null;\n firstChangeAt = null;\n if (!disposed) run();\n }\n\n return {\n notify() {\n if (disposed) return;\n const at = now();\n if (firstChangeAt === null) firstChangeAt = at;\n const remainingMax = Math.max(0, firstChangeAt + maxWaitMs - at);\n clear();\n handle = setTimer(fire, Math.min(idleMs, remainingMax));\n },\n reset() {\n clear();\n firstChangeAt = null;\n },\n get pending() {\n return handle !== null;\n },\n dispose() {\n disposed = true;\n clear();\n },\n };\n}\n","// @ts-check\n/**\n * LOCAL DRAFT of a template that has never been saved.\n *\n * A new template does not exist on the server yet: server-side autosave cannot\n * help it, and creating an \"untitled\" record on every open would clutter the\n * template library. Its work is therefore kept in the browser (document +\n * metadata such as label, subject, preview text), and offered the next time a\n * new template is opened, as long as it was never saved.\n *\n * Cleared on the first successful save. Ignored after seven days, or when it\n * cannot be read (written by another version of the builder).\n */\n\nimport { readDocument } from '../../core/document.js';\n\nconst KEY = 'best-email-builder:new-template-draft';\nconst MAX_AGE_MS = 7 * 24 * 60 * 60 * 1000;\n\n/** @param {Storage|null|undefined} store */\nfunction usable(store) {\n return store && typeof store.getItem === 'function' ? store : null;\n}\n\nfunction defaultStore() {\n try {\n return typeof window !== 'undefined' ? window.localStorage : null;\n } catch {\n return null;\n }\n}\n\n/**\n * @param {{document: object, meta: object}} draft\n * @param {Storage|null} [store]\n */\nexport function saveLocalDraft({ document, meta }, store = defaultStore()) {\n const target = usable(store);\n if (!target) return false;\n try {\n target.setItem(KEY, JSON.stringify({ savedAt: Date.now(), document, meta }));\n return true;\n } catch {\n // Quota exceeded, private browsing: a lost draft is not an error.\n return false;\n }\n}\n\n/**\n * @param {Storage|null} [store]\n * @returns {{savedAt: number, document: import('../../core/document.js').EmailDocument, meta: Record<string, string>}|null}\n */\nexport function readLocalDraft(store = defaultStore(), { now = Date.now() } = {}) {\n const target = usable(store);\n if (!target) return null;\n try {\n const raw = target.getItem(KEY);\n if (!raw) return null;\n const parsed = JSON.parse(raw);\n if (!parsed || now - Number(parsed.savedAt) > MAX_AGE_MS) {\n target.removeItem(KEY);\n return null;\n }\n return { savedAt: Number(parsed.savedAt), document: readDocument(parsed.document), meta: parsed.meta || {} };\n } catch {\n target.removeItem(KEY);\n return null;\n }\n}\n\n/** @param {Storage|null} [store] */\nexport function clearLocalDraft(store = defaultStore()) {\n try {\n usable(store)?.removeItem(KEY);\n } catch {\n /* nothing to clear */\n }\n}\n","import { SectionLabel } from './primitives/misc.jsx';\nimport { TooltipWrap } from './primitives/misc.jsx';\nimport {\n Columns2,\n Columns3,\n Columns4,\n GalleryHorizontal,\n Heading,\n Image as ImageIcon,\n LayoutPanelLeft,\n Menu,\n MoveVertical,\n RectangleHorizontal,\n SeparatorHorizontal,\n Share2,\n Square,\n Type,\n} from 'lucide-react';\nimport { useRef } from 'react';\nimport { cn } from './primitives/cn.js';\nimport { useT } from './context.jsx';\n\n/** Pixels the pointer travels before a press becomes a drag. */\nconst DRAG_THRESHOLD = 5;\n\n/**\n * Block sidebar, left of the canvas.\n *\n * Two gestures for the same block:\n * - CLICK (or Enter): the editor inserts it at the logical place (inside\n * the selected column, after the selected element, otherwise at the end\n * of the email);\n * - DRAG onto the canvas (mouse or pen): past a few pixels the editor takes\n * the pointer over — a line in the canvas shows where the block will land,\n * Esc cancels. On touch screens a tap adds the block (a drag there scrolls\n * the list).\n *\n * Blocks come from the registry (`editor.listBlocks()`): a block removed from\n * the registry disappears from here without touching this file. Only the icon\n * table is local (names come from the registry, components from here).\n */\n\nconst ICONS = {\n Heading,\n Type,\n Share2,\n Menu,\n Columns4,\n LayoutPanelLeft,\n GalleryHorizontal,\n Image: ImageIcon,\n RectangleHorizontal,\n SeparatorHorizontal,\n MoveVertical,\n Square,\n Columns2,\n Columns3,\n};\n\nconst GROUPS = [\n { kind: 'content', title: 'Content' },\n { kind: 'layout', title: 'Layout' },\n];\n\nfunction BlockTile({ block, disabled, onAdd, onDragStart }) {\n const t = useT();\n const Icon = ICONS[block.icon] || Square;\n /** Press in progress: where it started; `dragged` once it became a drag. */\n const press = useRef(null);\n return (\n <TooltipWrap label={block.description ? t(block.description) : block.description}>\n <button\n type=\"button\"\n disabled={disabled}\n onClick={() => {\n // The click that ends a drag is not an \"add\".\n if (press.current?.dragged) {\n press.current = null;\n return;\n }\n press.current = null;\n onAdd(block.id);\n }}\n onPointerDown={(e) => {\n if (disabled || e.button !== 0 || e.pointerType === 'touch') return;\n press.current = { x: e.clientX, y: e.clientY, dragged: false };\n }}\n onPointerMove={(e) => {\n const start = press.current;\n if (!start || start.dragged) return;\n if (Math.hypot(e.clientX - start.x, e.clientY - start.y) < DRAG_THRESHOLD) return;\n start.dragged = true;\n // The tile itself keeps the pointer (React's native event points at its root).\n onDragStart(block.id, {\n pointerId: e.pointerId,\n clientX: e.clientX,\n clientY: e.clientY,\n currentTarget: e.currentTarget,\n target: e.currentTarget,\n });\n }}\n onPointerUp={() => {\n if (press.current && !press.current.dragged) press.current = null;\n }}\n data-block-id={block.id}\n className={cn(\n 'eb:flex eb:h-20 eb:cursor-grab eb:touch-pan-y eb:select-none eb:flex-col eb:items-center eb:justify-center eb:gap-1.5 eb:rounded-lg2 eb:border eb:border-border eb:bg-background eb:px-2 eb:text-center eb:transition-colors eb:active:cursor-grabbing',\n 'eb:hover:border-primary/50 eb:hover:bg-primary/5 eb:focus-visible:outline-none eb:focus-visible:ring-2 eb:focus-visible:ring-ring/50',\n disabled && 'eb:cursor-not-allowed eb:opacity-50'\n )}\n >\n <Icon className=\"eb:h-5 eb:w-5 eb:text-foreground-lighter\" aria-hidden=\"true\" />\n <span className=\"eb:text-[12px] eb:text-foreground\">{t(block.label)}</span>\n </button>\n </TooltipWrap>\n );\n}\n\nexport default function BlockSidebar({ editor, disabled = false, onAdded }) {\n const t = useT();\n const blocks = editor.listBlocks();\n\n return (\n <aside aria-label={t('Blocks')} className=\"eb:min-h-0 eb:space-y-5 eb:overflow-y-auto eb:border-r eb:border-border eb:p-3\">\n {GROUPS.map((group) => {\n const items = blocks.filter((b) => b.kind === group.kind && b.mjml);\n if (!items.length) return null;\n return (\n <section key={group.kind} className=\"eb:space-y-2\">\n <SectionLabel>{t(group.title)}</SectionLabel>\n <div className=\"eb:grid eb:grid-cols-2 eb:gap-2\">\n {items.map((block) => (\n <BlockTile\n key={block.id}\n block={block}\n disabled={disabled}\n onAdd={(id) => {\n if (editor.addBlock(id)) onAdded?.(id);\n }}\n onDragStart={(id, event) => editor.startBlockDrag(id, event)}\n />\n ))}\n </div>\n </section>\n );\n })}\n </aside>\n );\n}\n","import { Button } from './primitives/button.jsx';\nimport { TooltipWrap } from './primitives/misc.jsx';\nimport { ArrowDown, ArrowLeft, ArrowRight, ArrowUp, Copy, Trash2 } from 'lucide-react';\nimport { useT } from './context.jsx';\n\n/**\n * Actions on the selected element: move, duplicate, delete.\n *\n * Same gestures as the canvas toolbar (above the element) and the keyboard\n * (Del), but readable and keyboard-accessible from the panel. No confirmation\n * before deleting: \"Undo\" (Ctrl+Z) reverts it.\n *\n * A column moves left or right, everything else up or down.\n */\nexport default function ElementActions({ editor, selection }) {\n const t = useT();\n if (!selection || (!selection.canRemove && !selection.canDuplicate)) return null;\n const horizontal = selection.tagName === 'mj-column';\n const [Prev, Next] = horizontal ? [ArrowLeft, ArrowRight] : [ArrowUp, ArrowDown];\n const [prevLabel, nextLabel] = horizontal\n ? [t('Move left'), t('Move right')]\n : [t('Move up'), t('Move down')];\n\n return (\n <div className=\"eb:flex eb:items-center eb:gap-0.5 eb:border-b eb:border-border eb:px-3 eb:py-1.5\" role=\"toolbar\" aria-label={t('Element actions')}>\n <TooltipWrap label={prevLabel}>\n <Button\n variant=\"ghost\"\n size=\"icon-sm-compact\"\n aria-label={prevLabel}\n disabled={!selection.canMoveUp}\n onClick={() => editor.move(-1, selection.id)}\n >\n <Prev />\n </Button>\n </TooltipWrap>\n <TooltipWrap label={nextLabel}>\n <Button\n variant=\"ghost\"\n size=\"icon-sm-compact\"\n aria-label={nextLabel}\n disabled={!selection.canMoveDown}\n onClick={() => editor.move(1, selection.id)}\n >\n <Next />\n </Button>\n </TooltipWrap>\n <TooltipWrap label={t('Duplicate')}>\n <Button\n variant=\"ghost\"\n size=\"icon-sm-compact\"\n aria-label={t('Duplicate')}\n disabled={!selection.canDuplicate}\n onClick={() => editor.duplicate(selection.id)}\n >\n <Copy />\n </Button>\n </TooltipWrap>\n <TooltipWrap label={t('Delete (Del)')}>\n <Button\n variant=\"ghost\"\n size=\"icon-sm-compact\"\n aria-label={t('Delete')}\n disabled={!selection.canRemove}\n onClick={() => editor.remove(selection.id)}\n className=\"eb:ml-auto eb:text-foreground-muted eb:hover:bg-destructive/10 eb:hover:text-destructive\"\n >\n <Trash2 />\n </Button>\n </TooltipWrap>\n </div>\n );\n}\n","import { useMemo, useRef } from 'react';\nimport { Button } from './primitives/button.jsx';\nimport { Input } from './primitives/fields.jsx';\nimport { Label } from './primitives/fields.jsx';\nimport { Textarea } from './primitives/fields.jsx';\nimport { SectionLabel } from './primitives/misc.jsx';\nimport { TruncatedText as FadedText } from './primitives/misc.jsx';\nimport { X } from 'lucide-react';\nimport { GROUPS } from '../blocks/shared.js';\nimport { PropertyField } from './fields.jsx';\nimport { useT } from './context.jsx';\nimport VariableInsertButton from '../features/variables/VariableInsertButton.jsx';\nimport RewriteText from '../features/generate/RewriteText.jsx';\nimport SubjectIdeas from '../features/generate/SubjectIdeas.jsx';\n\n/**\n * Properties panel, right of the canvas.\n *\n * an element is selected -> its properties, by group (those of its block in\n * the registry); a button or a menu link also gets its label here;\n * nothing is selected -> the TEMPLATE (name, subject, preview text) and\n * the page (background, width), i.e. the email body.\n *\n * `actions`: the element action bar (move, duplicate, delete), provided by\n * the host screen. `services.rewrite`: a text or a button also gets\n * \"Rewrite with AI\"; `services.suggestSubjects`: the subject gets \"Suggest\n * subjects\". `onDismiss`: the panel is shown in a drawer — its header\n * button closes the drawer rather than deselecting.\n */\n\nconst GROUP_ORDER = Object.values(GROUPS);\n\n/** A block's properties, grouped in panel order. */\nfunction grouped(properties) {\n const map = new Map();\n for (const property of properties) {\n if (!map.has(property.group)) map.set(property.group, []);\n map.get(property.group).push(property);\n }\n return [...map.entries()].sort(\n ([a], [b]) =>\n (GROUP_ORDER.indexOf(a) + 1 || 99) - (GROUP_ORDER.indexOf(b) + 1 || 99)\n );\n}\n\nfunction PropertyGroups({ editor, element, block, idPrefix, services = null }) {\n const t = useT();\n return grouped(block?.properties || []).map(([group, properties]) => (\n <section key={group} className=\"eb:space-y-3\">\n <SectionLabel>{t(group)}</SectionLabel>\n {properties.map((property) => (\n <PropertyField\n key={`${element.id}:${property.key}`}\n idPrefix={idPrefix}\n property={property}\n value={element.values[property.key]}\n fallback={element.defaults?.[property.key]}\n services={services}\n onCommit={(value) => editor.updateProperties({ [property.key]: value }, element.id)}\n />\n ))}\n </section>\n ));\n}\n\nconst LABEL_PROPERTY = { key: 'content', label: 'Label', type: 'text', group: GROUPS.content };\n\n/** Elements whose words the AI may rewrite: texts (headings included) and buttons. */\nconst REWRITABLE_TAGS = new Set(['mj-text', 'mj-button']);\n\nfunction PanelHeader({ title, onClose, closeLabel = 'Deselect' }) {\n const t = useT();\n return (\n <header className=\"eb:sticky eb:top-0 eb:z-10 eb:flex eb:h-11 eb:shrink-0 eb:items-center eb:gap-2 eb:border-b eb:border-border eb:bg-background eb:px-4\">\n <h3 className=\"eb:min-w-0 eb:flex-1 eb:text-[13px] eb:font-medium eb:text-foreground\">\n <FadedText>{title}</FadedText>\n </h3>\n {onClose && (\n <Button variant=\"ghost\" size=\"icon-sm-compact\" onClick={onClose} aria-label={t(closeLabel)}>\n <X />\n </Button>\n )}\n </header>\n );\n}\n\n/** Nothing selected: the template and the page. */\nfunction TemplateSettings({ editor, meta, onMetaChange, changes, showErrors, variables = null, services = null, onDismiss = null }) {\n const t = useT();\n const subjectRef = useRef(null);\n const preheaderRef = useRef(null);\n const rootId = editor.getRootId();\n // `changes`: the page is re-read after every change (background, width).\n const root = useMemo(() => (rootId ? editor.getElement(rootId) : null), [editor, rootId, changes]); // eslint-disable-line react-hooks/exhaustive-deps\n const bodyBlock = root?.blockId ? editor.getBlock(root.blockId) : null;\n const field = (key) => (e) => onMetaChange({ ...meta, [key]: e.target.value });\n\n return (\n <>\n <PanelHeader title={t('Email')} onClose={onDismiss} closeLabel=\"Close\" />\n <div className=\"eb:space-y-5 eb:p-4\">\n <section className=\"eb:space-y-3\">\n <SectionLabel>{t('Template')}</SectionLabel>\n <div className=\"eb:space-y-1.5\">\n <Label htmlFor=\"eb-meta-name\" className=\"eb:text-[12px] eb:font-normal eb:text-foreground-lighter\">\n {t('Name')} <span className=\"eb:text-destructive\">*</span>\n </Label>\n <Input\n id=\"eb-meta-name\"\n maxLength={200}\n value={meta.name}\n onChange={field('name')}\n aria-invalid={(showErrors && !meta.name.trim()) || undefined}\n />\n {showErrors && !meta.name.trim() && (\n <p className=\"eb:text-[12px] eb:text-destructive\">{t('Name is required')}</p>\n )}\n </div>\n <div className=\"eb:space-y-1.5\">\n <div className=\"eb:flex eb:h-6 eb:items-center eb:justify-between\">\n <Label htmlFor=\"eb-meta-subject\" className=\"eb:text-[12px] eb:font-normal eb:text-foreground-lighter\">\n {t('Subject')}\n </Label>\n {variables && (\n <VariableInsertButton\n variables={variables}\n inputRef={subjectRef}\n value={meta.subject}\n onChange={(subject) => onMetaChange({ ...meta, subject })}\n label={t('Insert a variable in the subject')}\n />\n )}\n </div>\n <Input ref={subjectRef} id=\"eb-meta-subject\" maxLength={250} value={meta.subject} onChange={field('subject')} />\n {services?.suggestSubjects && (\n <SubjectIdeas\n editor={editor}\n meta={meta}\n onSubject={(subject) => onMetaChange({ ...meta, subject })}\n suggest={services.suggestSubjects}\n variables={variables}\n />\n )}\n </div>\n <div className=\"eb:space-y-1.5\">\n <div className=\"eb:flex eb:h-6 eb:items-center eb:justify-between\">\n <Label htmlFor=\"eb-meta-preheader\" className=\"eb:text-[12px] eb:font-normal eb:text-foreground-lighter\">\n {t('Preview text')}\n </Label>\n {variables && (\n <VariableInsertButton\n variables={variables}\n inputRef={preheaderRef}\n value={meta.preheader}\n onChange={(preheader) => onMetaChange({ ...meta, preheader })}\n label={t('Insert a variable in the preview text')}\n />\n )}\n </div>\n <Textarea\n ref={preheaderRef}\n id=\"eb-meta-preheader\"\n rows={2}\n maxLength={250}\n value={meta.preheader}\n onChange={field('preheader')}\n placeholder={t('Shown after the subject in the inbox')}\n />\n </div>\n </section>\n {root && bodyBlock && <PropertyGroups editor={editor} element={root} block={bodyBlock} idPrefix=\"eb-page\" />}\n </div>\n </>\n );\n}\n\nexport default function PropertiesPanel({\n editor,\n selection,\n meta,\n onMetaChange,\n changes,\n actions = null,\n showErrors = false,\n services = null,\n variables = null,\n onDismiss = null,\n}) {\n const t = useT();\n const block = selection?.blockId ? editor.getBlock(selection.blockId) : null;\n\n return (\n <aside aria-label={t('Properties')} className=\"eb:min-h-0 eb:overflow-y-auto eb:border-l eb:border-border\" data-testid=\"eb-properties\">\n {!selection ? (\n <TemplateSettings\n editor={editor}\n meta={meta}\n onMetaChange={onMetaChange}\n changes={changes}\n showErrors={showErrors}\n variables={variables}\n services={services}\n onDismiss={onDismiss}\n />\n ) : (\n <>\n <PanelHeader\n title={t(selection.label)}\n onClose={onDismiss || (() => editor.select(null))}\n closeLabel={onDismiss ? 'Close' : 'Deselect'}\n />\n {actions}\n {selection.multiple ? (\n <p className=\"eb:p-4 eb:text-[13px] eb:leading-relaxed eb:text-foreground-lighter\" data-testid=\"eb-select-all\">\n {t('{count} sections selected. Press Delete to remove them (Ctrl+Z brings them back).', {\n count: selection.multiple,\n })}\n </p>\n ) : (\n <div className=\"eb:space-y-5 eb:p-4\">\n {selection.content !== null && selection.content !== undefined && (\n <section className=\"eb:space-y-3\">\n <SectionLabel>{t(GROUPS.content)}</SectionLabel>\n <PropertyField\n key={`${selection.id}:content`}\n idPrefix=\"eb-prop\"\n property={LABEL_PROPERTY}\n value={selection.content || ''}\n onCommit={(value) => editor.setContent(value || '', selection.id)}\n />\n </section>\n )}\n {selection.tagName === 'mj-text' && (\n <p className=\"eb:text-[12px] eb:text-foreground-muted\">{t('Double-click the text to edit it.')}</p>\n )}\n {services?.rewrite && REWRITABLE_TAGS.has(selection.tagName) && (\n <RewriteText key={selection.id} editor={editor} selection={selection} rewrite={services.rewrite} />\n )}\n <PropertyGroups editor={editor} element={selection} block={block} idPrefix=\"eb-prop\" services={services} />\n </div>\n )}\n </>\n )}\n </aside>\n );\n}\n","import { useEffect, useRef, useState } from 'react';\nimport { Input } from './primitives/fields.jsx';\nimport { Textarea } from './primitives/fields.jsx';\nimport { Label } from './primitives/fields.jsx';\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from './primitives/overlays.jsx';\nimport { TooltipWrap } from './primitives/misc.jsx';\nimport { ColorPicker } from './primitives/color-picker.jsx';\nimport { Button } from './primitives/button.jsx';\nimport { AlignCenter, AlignJustify, AlignLeft, AlignRight, Loader2, Upload } from 'lucide-react';\nimport { cn } from './primitives/cn.js';\nimport { isSafeUrl } from '../validation/urls.js';\nimport { imageUploadError } from '../validation/images.js';\nimport { parseSpacing, formatSpacing } from '../core/mjmlAttributes.js';\nimport { useT } from './context.jsx';\n\n/**\n * Properties panel fields - one per `BlockProperty` type.\n *\n * -- ONE EDIT = ONE UNDO STEP -----------------------------------------------\n * Each field keeps a local draft and only hands it to the editor once the\n * edit is FINISHED: on blur or Enter for text, after a 250 ms pause for a\n * color being dragged. Typing \"Hello\" must not leave five steps in the\n * history, nor recompile the canvas on every keystroke. Escape restores the\n * original value.\n *\n * -- WHAT CANNOT BE SENT IS REJECTED HERE -----------------------------------\n * An address the server would refuse (`javascript:`, non-https image) is\n * flagged under the field and not passed on; a color with transparency loses\n * its alpha channel, which no version of Outlook reads.\n *\n * -- AN EMPTY FIELD IS NOT ZERO ----------------------------------------------\n * A property left empty is rendered by MJML with its default (a section's\n * padding is 20 px above and below). `fallback` carries that default: it is\n * shown greyed in the empty field, and a padding edited on one side keeps\n * the defaults of the others instead of turning them into 0.\n *\n * -- IMAGES -----------------------------------------------------------------\n * An image is UPLOADED (application storage, `uploadImage`) or given as an\n * https address. Never `data:`: it would bloat the email.\n */\n\nconst COLOR_DEBOUNCE_MS = 250;\n\n/** `#RGB` or `#RRGGBB`; a `#RRGGBBAA` is reduced to `#RRGGBB`. */\nexport function emailColor(value) {\n const v = String(value || '').trim();\n if (/^#[0-9a-f]{3}$/i.test(v) || /^#[0-9a-f]{6}$/i.test(v)) return v.toLowerCase();\n if (/^#[0-9a-f]{8}$/i.test(v)) return v.slice(0, 7).toLowerCase();\n return null;\n}\n\n/**\n * A field's draft, realigned with the editor value when it changes from\n * elsewhere (undo, redo) - except while typing, which must not be\n * overwritten under the user's fingers.\n */\nfunction useDraft(value, toDraft) {\n const [draft, setDraft] = useState(() => toDraft(value));\n const ref = useRef(null);\n const convert = useRef(toDraft);\n convert.current = toDraft;\n useEffect(() => {\n const el = ref.current;\n const focused = el && el.ownerDocument?.activeElement && el.contains(el.ownerDocument.activeElement);\n if (!focused) setDraft(convert.current(value));\n }, [value]);\n return [draft, setDraft, ref];\n}\n\nconst asText = (v) => v || '';\n\nfunction FieldLabel({ id, children }) {\n return (\n <Label htmlFor={id} className=\"eb:text-[12px] eb:font-normal eb:text-foreground-lighter\">\n {children}\n </Label>\n );\n}\n\nfunction FieldError({ children }) {\n return children ? <p className=\"eb:text-[12px] eb:text-destructive\">{children}</p> : null;\n}\n\n/** Text, address, long text: draft committed on blur or Enter. */\nfunction TextField({ id, property, value, fallback = '', onCommit, addon = null, error = null }) {\n const t = useT();\n const [draft, setDraft, ref] = useDraft(value, asText);\n const isUrl = property.type === 'url' || property.type === 'image';\n const kind = property.type === 'image' ? 'image' : 'link';\n const invalid = isUrl && draft.trim() !== '' && !isSafeUrl(draft, kind);\n\n const commit = () => {\n const next = draft.trim();\n if (invalid || next === (value || '')) return;\n onCommit(next || null);\n };\n const keyDown = (e) => {\n if (e.key === 'Escape') {\n setDraft(value || '');\n e.currentTarget.blur();\n } else if (e.key === 'Enter' && property.type !== 'textarea') {\n e.preventDefault();\n commit();\n }\n };\n\n const shared = {\n id,\n value: draft,\n placeholder: property.placeholder ? t(property.placeholder) : fallback || property.placeholder,\n onChange: (e) => setDraft(e.target.value),\n onBlur: commit,\n onKeyDown: keyDown,\n 'aria-invalid': invalid || undefined,\n };\n return (\n <div ref={ref} className=\"eb:space-y-1.5\">\n <FieldLabel id={id}>{t(property.label)}</FieldLabel>\n {property.type === 'textarea' ? (\n <Textarea rows={3} {...shared} />\n ) : addon ? (\n <div className=\"eb:flex eb:gap-2\">\n <Input {...shared} className=\"eb:min-w-0 eb:flex-1\" />\n {addon}\n </div>\n ) : (\n <Input {...shared} />\n )}\n <FieldError>{invalid ? (kind === 'image' ? t('An https:// address is required') : t('Address not allowed')) : error}</FieldError>\n </div>\n );\n}\n\n/** Image: https address, or a file uploaded to the application storage. */\nfunction ImageField({ id, property, value, onCommit, services }) {\n const t = useT();\n const inputRef = useRef(/** @type {HTMLInputElement|null} */ (null));\n const [busy, setBusy] = useState(false);\n const [error, setError] = useState(/** @type {string|null} */ (null));\n const upload = services?.uploadImage;\n\n const pick = async (event) => {\n const file = event.target.files?.[0];\n event.target.value = '';\n if (!file || !upload) return;\n const refused = imageUploadError(file, { t });\n setError(refused);\n if (refused) return;\n setBusy(true);\n try {\n const { path } = await upload(file);\n onCommit(path);\n } catch (err) {\n setError(err?.message || t('Upload failed'));\n } finally {\n setBusy(false);\n }\n };\n\n const addon = upload ? (\n <>\n <input\n ref={inputRef}\n type=\"file\"\n accept=\"image/png,image/jpeg,image/gif\"\n className=\"eb:sr-only\"\n tabIndex={-1}\n aria-hidden=\"true\"\n data-testid={`${id}-file`}\n onChange={pick}\n />\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n disabled={busy}\n onClick={() => inputRef.current?.click()}\n >\n {busy ? <Loader2 className=\"eb:animate-spin\" /> : <Upload />}\n {t('Upload')}\n </Button>\n </>\n ) : null;\n\n return <TextField id={id} property={property} value={value} onCommit={onCommit} addon={addon} error={error} />;\n}\n\n/** Number in pixels, clamped. Empty = MJML default value. */\nconst asNumber = (v) => {\n const n = Number.parseFloat(String(v || ''));\n return Number.isFinite(n) ? String(n) : '';\n};\n\nfunction SizeField({ id, property, value, fallback = '', onCommit }) {\n const t = useT();\n const [draft, setDraft, ref] = useDraft(value, asNumber);\n\n const commit = (raw = draft) => {\n if (String(raw).trim() === '') {\n if (value) onCommit(null);\n return;\n }\n let n = Number.parseFloat(String(raw));\n if (!Number.isFinite(n)) return;\n if (property.min !== undefined) n = Math.max(property.min, n);\n if (property.max !== undefined) n = Math.min(property.max, n);\n setDraft(String(n));\n const next = `${n}${property.unit || 'px'}`;\n if (next !== value) onCommit(next);\n };\n\n return (\n <div ref={ref} className=\"eb:space-y-1.5\">\n <FieldLabel id={id}>{t(property.label)}</FieldLabel>\n <div className=\"eb:relative\">\n <Input\n id={id}\n type=\"number\"\n inputMode=\"numeric\"\n min={property.min}\n max={property.max}\n value={draft}\n placeholder={asNumber(fallback)}\n onChange={(e) => setDraft(e.target.value)}\n onBlur={() => commit()}\n onKeyDown={(e) => {\n if (e.key === 'Enter') commit();\n if (e.key === 'Escape') setDraft(asNumber(value));\n }}\n className=\"eb:pr-9 eb:tabular-nums\"\n />\n <span className=\"eb:pointer-events-none eb:absolute eb:right-3 eb:top-1/2 eb:-translate-y-1/2 eb:text-[12px] eb:text-foreground-muted\">\n {property.unit || 'px'}\n </span>\n </div>\n </div>\n );\n}\n\n/** Color: swatch + hex code, committed after a short pause. */\nfunction ColorField({ id, property, value, fallback = '', onCommit }) {\n const t = useT();\n const [draft, setDraft, ref] = useDraft(value, asText);\n const timer = useRef(null);\n const latest = useRef({ value, onCommit });\n latest.current = { value, onCommit };\n\n useEffect(() => () => clearTimeout(timer.current), []);\n\n const change = (next) => {\n setDraft(next);\n clearTimeout(timer.current);\n timer.current = setTimeout(() => {\n const color = emailColor(next);\n if (!String(next || '').trim()) {\n if (latest.current.value) latest.current.onCommit(null);\n } else if (color && color !== latest.current.value) {\n latest.current.onCommit(color);\n }\n }, COLOR_DEBOUNCE_MS);\n };\n\n return (\n <div ref={ref} className=\"eb:space-y-1.5\">\n <FieldLabel id={id}>{t(property.label)}</FieldLabel>\n <ColorPicker id={id} value={draft} placeholder={emailColor(fallback) || ''} onChange={change} />\n </div>\n );\n}\n\n/** Radix does not accept an empty option (\"default value\"): use a sentinel. */\nconst DEFAULT_OPTION = '__default__';\n\nfunction SelectField({ id, property, value, fallback = '', onCommit }) {\n const t = useT();\n const current = value || DEFAULT_OPTION;\n // \"Default (Top)\": what MJML renders when nothing is chosen.\n // (MJML writes some defaults in another word order: \"top center\" = \"center top\".)\n const words = (v) => String(v || '').trim().split(/\\s+/).sort().join(' ');\n const fallbackOption = (property.options || []).find((o) => o.value && words(o.value) === words(fallback));\n const defaultLabel = fallbackOption ? t('Default ({value})', { value: t(fallbackOption.label) }) : t('Default');\n return (\n <div className=\"eb:space-y-1.5\">\n <FieldLabel id={id}>{t(property.label)}</FieldLabel>\n <Select\n value={current}\n onValueChange={(next) => {\n const v = next === DEFAULT_OPTION ? '' : next;\n if (v !== (value || '')) onCommit(v || null);\n }}\n >\n <SelectTrigger id={id} className=\"eb:w-full\">\n <SelectValue placeholder={defaultLabel} />\n </SelectTrigger>\n <SelectContent>\n {!(property.options || []).some((o) => !o.value) && (\n <SelectItem value={DEFAULT_OPTION}>{defaultLabel}</SelectItem>\n )}\n {(property.options || []).map((o) => (\n <SelectItem key={o.value || DEFAULT_OPTION} value={o.value || DEFAULT_OPTION}>\n {t(o.label)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n );\n}\n\nconst ALIGN_ICONS = { left: AlignLeft, center: AlignCenter, right: AlignRight, justify: AlignJustify };\n\n/** Alignment: toggle group (solid `bg-primary` on the active one). */\nfunction AlignField({ id, property, value, fallback = '', onCommit }) {\n const t = useT();\n return (\n <div className=\"eb:space-y-1.5\">\n <FieldLabel id={id}>{t(property.label)}</FieldLabel>\n <div\n id={id}\n role=\"radiogroup\"\n aria-label={t(property.label)}\n className=\"eb:flex eb:w-fit eb:items-center eb:gap-0.5 eb:rounded-lg2 eb:border eb:border-border-strong eb:bg-surface-75 eb:p-0.5\"\n >\n {(property.options || []).map((option) => {\n const Icon = ALIGN_ICONS[option.value] || AlignLeft;\n // Nothing chosen: MJML's default is what renders, so it shows as current.\n const active = (value || fallback) === option.value;\n return (\n <TooltipWrap key={option.value} label={t(option.label)}>\n <button\n type=\"button\"\n role=\"radio\"\n aria-checked={active}\n aria-label={t(option.label)}\n onClick={() => option.value !== value && onCommit(option.value)}\n className={cn(\n 'eb:inline-flex eb:h-7 eb:w-7 eb:items-center eb:justify-center eb:rounded-lg2 eb:transition-colors',\n active\n ? 'eb:bg-primary eb:text-primary-foreground'\n : 'eb:text-foreground-lighter eb:hover:bg-surface-200 eb:hover:text-foreground'\n )}\n >\n <Icon className=\"eb:h-3.5 eb:w-3.5\" />\n </button>\n </TooltipWrap>\n );\n })}\n </div>\n </div>\n );\n}\n\nconst SIDE_LABELS = [\n ['top', 'Top'],\n ['right', 'Right'],\n ['bottom', 'Bottom'],\n ['left', 'Left'],\n];\n\n/**\n * Spacing: four sides in pixels, rewritten in their shortest form. Empty\n * (nothing set): the four inputs are empty, MJML's default greyed in each.\n */\nconst asSides = (v) => (v ? parseSpacing(v).map((s) => String(Number.parseFloat(s) || 0)) : ['', '', '', '']);\n\nfunction SpacingField({ id, property, value, fallback = '', onCommit }) {\n const t = useT();\n const [draft, setDraft, ref] = useDraft(value, asSides);\n const defaults = parseSpacing(fallback || '0px').map((s) => String(Number.parseFloat(s) || 0));\n\n const commit = (sides = draft) => {\n // Untouched sides keep what MJML renders (its default), never 0.\n if (!value && sides.every((s) => String(s).trim() === '')) return;\n const next = formatSpacing(\n sides.map((s, i) => {\n const raw = String(s).trim() === '' ? defaults[i] : s;\n return `${Math.max(0, Math.min(200, Number.parseFloat(raw) || 0))}px`;\n })\n );\n if (next !== (value || '')) onCommit(next);\n };\n\n return (\n <fieldset ref={ref} className=\"eb:space-y-1.5\">\n <legend className=\"eb:mb-1.5 eb:text-[12px] eb:text-foreground-lighter\">{t(property.label)}</legend>\n <div className=\"eb:grid eb:grid-cols-4 eb:gap-1.5\">\n {SIDE_LABELS.map(([side, label], i) => (\n <div key={side} className=\"eb:space-y-1\">\n <Input\n id={`${id}-${side}`}\n type=\"number\"\n min={0}\n max={200}\n aria-label={t('{label} — {side}', { label: t(property.label), side: t(label) })}\n title={t(label)}\n value={draft[i]}\n placeholder={defaults[i]}\n onChange={(e) => setDraft((d) => d.map((v, j) => (j === i ? e.target.value : v)))}\n onBlur={() => commit()}\n onKeyDown={(e) => {\n if (e.key === 'Enter') commit();\n }}\n className=\"eb:px-2 eb:text-center eb:tabular-nums\"\n />\n <span className=\"eb:block eb:text-center eb:text-[10.5px] eb:text-foreground-muted\">{t(label)}</span>\n </div>\n ))}\n </div>\n </fieldset>\n );\n}\n\nconst FIELDS = {\n text: TextField,\n textarea: TextField,\n url: TextField,\n image: ImageField,\n size: SizeField,\n color: ColorField,\n select: SelectField,\n align: AlignField,\n spacing: SpacingField,\n};\n\n/**\n * Field of a property. The caller's `key` (element + property) remounts it on\n * every selection change: a draft never carries over from one element to another.\n */\nexport function PropertyField({ property, value, fallback = '', onCommit, idPrefix = 'eb', services = null }) {\n const Field = FIELDS[property.type] || TextField;\n const id = `${idPrefix}-${property.key}`;\n return <Field id={id} property={property} value={value} fallback={fallback} onCommit={onCommit} services={services} />;\n}\n","import { useState } from 'react';\nimport { Braces } from 'lucide-react';\nimport { Button } from '../../ui/primitives/button.jsx';\nimport { Popover, PopoverContent, PopoverTrigger } from '../../ui/primitives/overlays.jsx';\nimport { tokenOf } from './catalog.js';\nimport VariablePicker from './VariablePicker.jsx';\n\n/**\n * `{ }` button next to a plain-text field (subject, preview text): inserts a\n * variable at the field's caret, or at its end.\n *\n * @param {{\n * variables: import('./catalog.js').EmailVariable[],\n * inputRef: {current: HTMLInputElement|HTMLTextAreaElement|null},\n * value: string,\n * onChange: (value: string) => void,\n * label: string,\n * }} props\n */\nexport default function VariableInsertButton({ variables, inputRef, value, onChange, label }) {\n const [open, setOpen] = useState(false);\n\n const insert = (variable) => {\n const input = inputRef.current;\n const text = String(value || '');\n const token = tokenOf(variable);\n const start = input?.selectionStart ?? text.length;\n const end = input?.selectionEnd ?? text.length;\n const next = `${text.slice(0, start)}${token}${text.slice(end)}`;\n onChange(next);\n setOpen(false);\n // Caret right after the inserted tag.\n requestAnimationFrame(() => {\n if (!input) return;\n input.focus();\n input.setSelectionRange(start + token.length, start + token.length);\n });\n };\n\n return (\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger asChild>\n <Button variant=\"ghost\" size=\"icon-xs\" aria-label={label} title={label}>\n <Braces />\n </Button>\n </PopoverTrigger>\n <PopoverContent align=\"end\" className=\"eb:w-72 eb:p-0\" onCloseAutoFocus={(e) => e.preventDefault()}>\n {/* Links have no meaning in a subject line. */}\n <VariablePicker variables={variables} onPick={insert} filter={(v) => v.kind !== 'link'} />\n </PopoverContent>\n </Popover>\n );\n}\n","import { useEffect, useRef, useState } from 'react';\nimport { ChevronDown, Languages, Loader2, Sparkles, TriangleAlert } from 'lucide-react';\nimport { useUi } from '../../ui/context.jsx';\nimport { Button } from '../../ui/primitives/button.jsx';\nimport { Input } from '../../ui/primitives/fields.jsx';\nimport { SectionLabel } from '../../ui/primitives/misc.jsx';\nimport { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from '../../ui/primitives/overlays.jsx';\nimport { cleanRichText } from '../../engine/richText.js';\nimport { chipClassName } from './chip.js';\nimport { MAX_REWRITE_INSTRUCTION, REWRITE_ACTIONS, REWRITE_LANGUAGES } from './rewrite.js';\n\n/**\n * REWRITE WITH AI — in the properties of a selected text or button.\n *\n * One click: shorter, longer, fixed, friendlier, more formal, translated —\n * or a change in the user's words. The result replaces the text at once, in\n * one step of the history: Ctrl+Z brings the previous text back, so there is\n * nothing to accept or compare.\n *\n * Mounted per element (keyed by its id): selecting another element cancels a\n * rewrite in progress. If the text is edited while the AI works, the user's\n * words win and the answer is dropped.\n */\n\n/** A language under its own name: \"Deutsch\", \"Українська\". @param {string} code */\nfunction nativeName(code) {\n try {\n const name = new Intl.DisplayNames([code], { type: 'language' }).of(code) || code;\n return name.charAt(0).toLocaleUpperCase(code) + name.slice(1);\n } catch {\n return code;\n }\n}\n\nexport default function RewriteText({ editor, selection, rewrite }) {\n const { t, notify } = useUi();\n const [running, setRunning] = useState(/** @type {string|null} */ (null));\n const [error, setError] = useState('');\n const [instruction, setInstruction] = useState('');\n const abortRef = useRef(/** @type {AbortController|null} */ (null));\n const label = selection.tagName === 'mj-button';\n\n useEffect(() => () => abortRef.current?.abort(), []);\n\n /** The text as stored: a button's label, a text block's HTML. */\n const currentText = () => {\n const element = editor.getElement(selection.id);\n return (label ? element?.content : element?.html) ?? '';\n };\n\n const run = async (action, extra = {}) => {\n if (running) return;\n const text = currentText();\n setError('');\n setRunning(action);\n const controller = new AbortController();\n abortRef.current = controller;\n try {\n const result = await rewrite({ action, text, format: label ? 'plain' : 'html', ...extra }, { signal: controller.signal });\n if (controller.signal.aborted) return;\n if (currentText() !== text) {\n setError(t('The text changed in the meantime, so it was left as it is.'));\n return;\n }\n editor.setContent(label ? result.text : cleanRichText(result.text, document), selection.id);\n if (action === 'custom') setInstruction('');\n notify('success', t('Text rewritten. Ctrl+Z brings back the previous one.'));\n } catch (err) {\n if (!controller.signal.aborted) setError(t(err?.message || 'The text could not be rewritten.'));\n } finally {\n if (abortRef.current === controller) abortRef.current = null;\n setRunning(null);\n }\n };\n\n const cancel = () => {\n abortRef.current?.abort();\n setRunning(null);\n };\n\n const busy = Boolean(running);\n const spinner = <Loader2 className=\"eb:size-3 eb:animate-spin\" aria-hidden=\"true\" />;\n\n return (\n <section className=\"eb:space-y-2.5\" aria-label={t('Rewrite with AI')} data-testid=\"eb-rewrite\">\n <SectionLabel className=\"eb:flex eb:items-center eb:gap-1.5\">\n <Sparkles className=\"eb:size-3\" aria-hidden=\"true\" />\n {t('Rewrite with AI')}\n </SectionLabel>\n <div className=\"eb:flex eb:flex-wrap eb:gap-1.5\">\n {REWRITE_ACTIONS.map((action) => (\n <button key={action.id} type=\"button\" className={chipClassName()} disabled={busy} onClick={() => run(action.id)}>\n {running === action.id && spinner}\n {t(action.label)}\n </button>\n ))}\n <DropdownMenu>\n <DropdownMenuTrigger asChild disabled={busy}>\n <button type=\"button\" className={chipClassName()}>\n {running === 'translate' ? spinner : <Languages className=\"eb:size-3\" aria-hidden=\"true\" />}\n {t('Translate')}\n <ChevronDown className=\"eb:size-3\" aria-hidden=\"true\" />\n </button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"start\" aria-label={t('Translate into')}>\n {REWRITE_LANGUAGES.map((code) => (\n <DropdownMenuItem key={code} lang={code} onSelect={() => run('translate', { targetLanguage: code })}>\n {nativeName(code)}\n </DropdownMenuItem>\n ))}\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n <form\n className=\"eb:flex eb:gap-1.5\"\n onSubmit={(event) => {\n event.preventDefault();\n if (instruction.trim()) run('custom', { instruction: instruction.trim() });\n }}\n >\n <Input\n value={instruction}\n onChange={(event) => setInstruction(event.target.value)}\n maxLength={MAX_REWRITE_INSTRUCTION}\n placeholder={t('Or say what to change…')}\n aria-label={t('What to change')}\n disabled={busy}\n />\n <Button type=\"submit\" variant=\"outline\" size=\"icon-sm\" aria-label={t('Rewrite')} disabled={busy || !instruction.trim()}>\n {running === 'custom' ? <Loader2 className=\"eb:animate-spin\" /> : <Sparkles />}\n </Button>\n </form>\n {running && (\n <p className=\"eb:flex eb:items-center eb:gap-2 eb:text-[12px] eb:text-foreground-muted\" role=\"status\" aria-live=\"polite\">\n {t('Rewriting…')}\n <Button type=\"button\" variant=\"link\" size=\"xs\" className=\"eb:h-auto eb:px-0\" onClick={cancel}>\n {t('Cancel')}\n </Button>\n </p>\n )}\n {error && (\n <p role=\"alert\" className=\"eb:flex eb:items-start eb:gap-1.5 eb:text-[12px] eb:text-destructive\">\n <TriangleAlert className=\"eb:mt-px eb:size-3.5 eb:shrink-0\" aria-hidden=\"true\" />\n {error}\n </p>\n )}\n </section>\n );\n}\n","import { useEffect, useRef, useState } from 'react';\nimport { Check, Loader2, Sparkles, TriangleAlert } from 'lucide-react';\nimport { useUi } from '../../ui/context.jsx';\nimport { Button } from '../../ui/primitives/button.jsx';\nimport { cn } from '../../ui/primitives/cn.js';\nimport { chipClassName } from './chip.js';\nimport { emailWords } from './subjects.js';\n\n/**\n * SUGGEST SUBJECTS — under the subject of the email.\n *\n * One click: three other subject lines, drawn from the words of the email.\n * They are a list to pick from, the user's own subject first: a click puts\n * one in the field, another click another one, the first row brings the\n * user's subject back. \"More ideas\" asks for three new ones; \"Done\" closes\n * the list and keeps the subject in the field.\n */\nexport default function SubjectIdeas({ editor, meta, onSubject, suggest, variables = null }) {\n const { t, locale } = useUi();\n const [running, setRunning] = useState(false);\n const [error, setError] = useState('');\n const [ideas, setIdeas] = useState(/** @type {string[]|null} */ (null));\n const [original, setOriginal] = useState('');\n const abortRef = useRef(/** @type {AbortController|null} */ (null));\n\n useEffect(() => () => abortRef.current?.abort(), []);\n\n const run = async () => {\n if (running) return;\n // The user's subject, kept as it was before the first idea was picked.\n const yours = ideas ? original : meta.subject.trim();\n const controller = new AbortController();\n abortRef.current = controller;\n setError('');\n setRunning(true);\n try {\n const result = await suggest(\n {\n subject: yours,\n preheader: meta.preheader,\n text: emailWords(editor.exportMjml()),\n language: locale,\n variables: variables?.map(({ key, label }) => ({ key, label })),\n avoid: ideas || [],\n },\n { signal: controller.signal }\n );\n if (controller.signal.aborted) return;\n setOriginal(yours);\n setIdeas(result.subjects);\n } catch (err) {\n if (!controller.signal.aborted) setError(err?.message ? t(err.message) : t('No subject could be suggested.'));\n } finally {\n if (abortRef.current === controller) abortRef.current = null;\n setRunning(false);\n }\n };\n\n const cancel = () => {\n abortRef.current?.abort();\n setRunning(false);\n };\n\n const options = ideas ? [...(original ? [{ text: original, yours: true }] : []), ...ideas.map((text) => ({ text, yours: false }))] : [];\n const spinner = <Loader2 className=\"eb:size-3 eb:animate-spin\" aria-hidden=\"true\" />;\n\n return (\n <div className=\"eb:space-y-2\" data-testid=\"eb-subject-ideas\">\n {!ideas && (\n <button type=\"button\" className={chipClassName()} disabled={running} onClick={run}>\n {running ? spinner : <Sparkles className=\"eb:size-3\" aria-hidden=\"true\" />}\n {t('Suggest subjects')}\n </button>\n )}\n {ideas && (\n <div className=\"eb:space-y-2 eb:rounded-md eb:border eb:border-border eb:p-1.5\">\n <div role=\"radiogroup\" aria-label={t('Subject ideas')} className=\"eb:space-y-0.5\">\n {options.map((option) => {\n const chosen = meta.subject === option.text;\n return (\n <button\n key={`${option.yours ? 'yours' : 'idea'}:${option.text}`}\n type=\"button\"\n role=\"radio\"\n aria-checked={chosen}\n className={cn(\n 'eb:flex eb:w-full eb:items-start eb:gap-2 eb:rounded eb:px-2 eb:py-1.5 eb:text-left eb:text-[12.5px] eb:leading-snug eb:transition-colors eb:outline-none eb:focus-visible:ring-[3px] eb:focus-visible:ring-ring/50',\n chosen ? 'eb:bg-primary/10 eb:text-foreground' : 'eb:text-foreground-lighter eb:hover:bg-muted'\n )}\n onClick={() => onSubject(option.text)}\n >\n <Check className={cn('eb:mt-0.5 eb:size-3.5 eb:shrink-0', chosen ? 'eb:text-primary' : 'eb:invisible')} aria-hidden=\"true\" />\n <span className=\"eb:min-w-0 eb:flex-1 eb:break-words\">{option.text}</span>\n {option.yours && <span className=\"eb:shrink-0 eb:text-[11px] eb:text-foreground-muted\">{t('yours')}</span>}\n </button>\n );\n })}\n </div>\n <div className=\"eb:flex eb:items-center eb:gap-1.5 eb:px-1 eb:pb-0.5\">\n <button type=\"button\" className={chipClassName()} disabled={running} onClick={run}>\n {running ? spinner : <Sparkles className=\"eb:size-3\" aria-hidden=\"true\" />}\n {t('More ideas')}\n </button>\n <Button type=\"button\" variant=\"ghost\" size=\"xs\" className=\"eb:ml-auto\" disabled={running} onClick={() => setIdeas(null)}>\n {t('Done')}\n </Button>\n </div>\n </div>\n )}\n {running && (\n <p className=\"eb:flex eb:items-center eb:gap-2 eb:text-[12px] eb:text-foreground-muted\" role=\"status\" aria-live=\"polite\">\n {t('Reading the email…')}\n <Button type=\"button\" variant=\"link\" size=\"xs\" className=\"eb:h-auto eb:px-0\" onClick={cancel}>\n {t('Cancel')}\n </Button>\n </p>\n )}\n {error && (\n <p role=\"alert\" className=\"eb:flex eb:items-start eb:gap-1.5 eb:text-[12px] eb:text-destructive\">\n <TriangleAlert className=\"eb:mt-px eb:size-3.5 eb:shrink-0\" aria-hidden=\"true\" />\n {error}\n </p>\n )}\n </div>\n );\n}\n","import { Button } from './primitives/button.jsx';\nimport { Separator } from './primitives/misc.jsx';\nimport { Tabs, TabsList, TabsTrigger } from './primitives/misc.jsx';\nimport { TooltipWrap } from './primitives/misc.jsx';\nimport { TruncatedText as FadedText } from './primitives/misc.jsx';\nimport { ArrowLeft, Monitor, Redo2, Smartphone, Undo2 } from 'lucide-react';\nimport { cn } from './primitives/cn.js';\nimport { useT } from './context.jsx';\n\n/**\n * Builder toolbar.\n *\n * left: back, template name and its status;\n * center: undo / redo, device (desktop, mobile);\n * right: actions provided by the host screen (`actions`: variables,\n * preview, test - each one comes from its feature), then `primary`\n * (save).\n *\n * `compact` (builder narrower than its wide layout): two rows. The first keeps\n * what is always needed - back, name, save; the second holds history, device\n * and the feature actions, and scrolls sideways rather than overflow the page.\n */\nexport default function Toolbar({\n title,\n status,\n ready,\n canUndo,\n canRedo,\n onUndo,\n onRedo,\n device,\n onDeviceChange,\n onBack,\n actions = null,\n primary = null,\n compact = false,\n}) {\n const t = useT();\n\n const identity = (\n <>\n <Button\n variant=\"ghost\"\n size={compact ? 'icon-sm-compact' : 'sm-compact'}\n onClick={onBack}\n aria-label={compact ? t('Back') : undefined}\n >\n <ArrowLeft />\n {!compact && t('Back')}\n </Button>\n <Separator orientation=\"vertical\" className=\"eb:h-5\" />\n <div className={cn('eb:min-w-0 eb:flex-1', !compact && 'eb:max-w-[320px]')}>\n <p className=\"eb:text-[13px] eb:font-medium eb:text-foreground\">\n <FadedText>{title || t('New template')}</FadedText>\n </p>\n <p className=\"eb:text-[11px] eb:text-foreground-muted\" role=\"status\" aria-live=\"polite\">\n {status}\n </p>\n </div>\n </>\n );\n\n const editing = (\n <div className=\"eb:flex eb:shrink-0 eb:items-center eb:gap-2\">\n <div className=\"eb:flex eb:items-center eb:gap-0.5\">\n <TooltipWrap label={t('Undo (Ctrl+Z)')}>\n <Button variant=\"ghost\" size=\"icon-sm-compact\" onClick={onUndo} disabled={!ready || !canUndo} aria-label={t('Undo')}>\n <Undo2 />\n </Button>\n </TooltipWrap>\n <TooltipWrap label={t('Redo (Ctrl+Y)')}>\n <Button variant=\"ghost\" size=\"icon-sm-compact\" onClick={onRedo} disabled={!ready || !canRedo} aria-label={t('Redo')}>\n <Redo2 />\n </Button>\n </TooltipWrap>\n </div>\n <Tabs value={device} onValueChange={onDeviceChange}>\n <TabsList aria-label={t('Device')}>\n <TabsTrigger value=\"desktop\" disabled={!ready} aria-label={compact ? t('Desktop') : undefined}>\n <Monitor />\n {!compact && t('Desktop')}\n </TabsTrigger>\n <TabsTrigger value=\"mobile\" disabled={!ready} aria-label={compact ? t('Mobile') : undefined}>\n <Smartphone />\n {!compact && t('Mobile')}\n </TabsTrigger>\n </TabsList>\n </Tabs>\n </div>\n );\n\n if (compact) {\n return (\n <div className=\"eb:shrink-0 eb:border-b eb:border-border\" data-layout=\"compact\">\n <div className=\"eb:flex eb:h-12 eb:items-center eb:gap-2 eb:px-2\">\n {identity}\n {primary}\n </div>\n <div className=\"eb:flex eb:items-center eb:gap-2 eb:overflow-x-auto eb:px-2 eb:pb-2\" data-testid=\"eb-toolbar-actions\">\n {editing}\n <Separator orientation=\"vertical\" className=\"eb:h-5 eb:shrink-0\" />\n <div className=\"eb:flex eb:shrink-0 eb:items-center eb:gap-2\">{actions}</div>\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"eb:flex eb:h-12 eb:shrink-0 eb:items-center eb:gap-3 eb:border-b eb:border-border eb:px-3\">\n {identity}\n {editing}\n <div className=\"eb:ml-auto eb:flex eb:items-center eb:gap-2\" data-testid=\"eb-toolbar-actions\">\n {actions}\n {primary}\n </div>\n </div>\n );\n}\n","import { useEffect } from 'react';\nimport { X } from 'lucide-react';\nimport { Button } from './primitives/button.jsx';\nimport { cn } from './primitives/cn.js';\nimport { useT } from './context.jsx';\n\n/**\n * Side drawer of the compact layouts: the blocks or the properties slide over\n * the canvas instead of squeezing it.\n *\n * Rendered INSIDE the builder (not in a portal): it covers the editing area\n * only, the toolbar stays usable. A tap on the shaded canvas or Escape closes\n * it. `header={false}` when the content has its own header with a close\n * button (the properties panel). While closed it stays mounted but hidden (`hidden`), so a panel keeps\n * its scroll position and its fields their drafts.\n */\nexport default function Drawer({ open, side = 'left', title, onClose, children, testId, header = true }) {\n const t = useT();\n useEffect(() => {\n if (!open) return undefined;\n const onKey = (e) => {\n if (e.key === 'Escape') onClose();\n };\n window.addEventListener('keydown', onKey);\n return () => window.removeEventListener('keydown', onKey);\n }, [open, onClose]);\n\n return (\n <div className={cn('eb:absolute eb:inset-0 eb:z-20', !open && 'eb:hidden')} data-testid={testId} data-open={open ? 'true' : 'false'}>\n <div className=\"eb:absolute eb:inset-0 eb:bg-black/30\" onClick={onClose} aria-hidden=\"true\" />\n <section\n role=\"dialog\"\n aria-label={title}\n className={cn(\n 'eb:absolute eb:inset-y-0 eb:flex eb:w-[min(340px,88%)] eb:flex-col eb:bg-background eb:shadow-lg',\n side === 'left' ? 'eb:left-0 eb:border-r eb:border-border' : 'eb:right-0 eb:border-l eb:border-border'\n )}\n >\n {header && (\n <header className=\"eb:flex eb:h-10 eb:shrink-0 eb:items-center eb:justify-between eb:border-b eb:border-border eb:px-3\">\n <h3 className=\"eb:text-[13px] eb:font-medium eb:text-foreground\">{title}</h3>\n <Button variant=\"ghost\" size=\"icon-sm-compact\" onClick={onClose} aria-label={t('Close')}>\n <X />\n </Button>\n </header>\n )}\n <div className=\"eb:grid eb:min-h-0 eb:flex-1\">{children}</div>\n </section>\n </div>\n );\n}\n","'use client';\n\nimport { useCallback, useEffect, useRef, useState } from 'react';\n\n/**\n * React state of an `EmailEditor`: status, selection, undo/redo, device, and\n * \"modified since the last clean point\".\n *\n * The UI reads the editor ONLY through this hook (and its methods): no\n * component subscribes to the engine.\n *\n * -- \"MODIFIED\" IS MEASURED, NOT COUNTED ------------------------------------\n * Counting `change` events does not work: the engine also emits them outside\n * any edit (deferred canvas render after a load), and undoing back to the\n * saved state would leave a counter at 2. So the exported MJML is compared to\n * the one of the last clean point (load, or `markClean()` after a save). MJML\n * omits default values: engine noise does not show up in it.\n *\n * `dirty` (display) lags by 150 ms; `checkDirty()` measures RIGHT NOW - it is\n * the one to query before leaving, since a click on \"Back\" can follow an edit\n * by a few milliseconds.\n *\n * `markDirty()` forces the state until the next clean point (restored\n * version: identical to nothing saved, but still to be saved).\n * `changes` counts modifications: it is used to re-read what depends on them.\n */\n\nconst DIRTY_CHECK_MS = 150;\n\nexport function useEmailEditorState(editor) {\n const [state, setState] = useState(() => ({\n status: editor?.status || 'idle',\n selection: null,\n canUndo: false,\n canRedo: false,\n device: 'desktop',\n changes: 0,\n dirty: false,\n }));\n const clean = useRef(null);\n const forced = useRef(false);\n const timer = useRef(null);\n\n const snapshot = useCallback(() => {\n try {\n return editor.status === 'ready' ? editor.exportMjml() : null;\n } catch {\n return null;\n }\n }, [editor]);\n\n /** Clean point: the given MJML (the one just saved) or the current one. */\n const markClean = useCallback((saved = null) => {\n clean.current = saved ?? snapshot();\n forced.current = false;\n const current = snapshot();\n // Edited WHILE saving: still needs saving.\n setState((s) => ({ ...s, dirty: current !== null && current !== clean.current }));\n }, [snapshot]);\n\n const checkDirty = useCallback(() => {\n if (forced.current) return true;\n const current = snapshot();\n return current !== null && current !== clean.current;\n }, [snapshot]);\n\n const markDirty = useCallback(() => {\n forced.current = true;\n setState((s) => ({ ...s, dirty: true }));\n }, []);\n\n useEffect(() => {\n if (!editor) return undefined;\n const patch = (values) => setState((s) => ({ ...s, ...values }));\n const measure = () => {\n clearTimeout(timer.current);\n timer.current = setTimeout(() => {\n const current = snapshot();\n patch({ dirty: forced.current || (current !== null && current !== clean.current) });\n }, DIRTY_CHECK_MS);\n };\n const offs = [\n editor.on('ready', () => {\n clean.current = snapshot();\n forced.current = false;\n patch({\n status: 'ready',\n device: editor.getDevice(),\n canUndo: editor.canUndo(),\n canRedo: editor.canRedo(),\n selection: editor.getSelection(),\n dirty: false,\n });\n }),\n editor.on('destroy', () => patch({ status: 'idle', selection: null, canUndo: false, canRedo: false })),\n editor.on('selection', (selection) => patch({ selection })),\n editor.on('history', ({ canUndo, canRedo }) => patch({ canUndo, canRedo })),\n editor.on('device', (device) => patch({ device })),\n editor.on('change', () => {\n setState((s) => ({ ...s, changes: s.changes + 1 }));\n measure();\n }),\n editor.on('load', () => {\n clearTimeout(timer.current);\n clean.current = snapshot();\n forced.current = false;\n setState((s) => ({ ...s, changes: s.changes + 1, dirty: false }));\n }),\n ];\n return () => {\n clearTimeout(timer.current);\n offs.forEach((off) => off());\n };\n }, [editor, snapshot]);\n\n return { ...state, markClean, markDirty, checkDirty };\n}\n","import { Component } from 'react';\nimport { AlertTriangle, ArrowLeft, RefreshCw } from 'lucide-react';\nimport { Button } from './primitives/button.jsx';\n\n/**\n * Guard around the builder: a LOADING failure must not take the page down.\n *\n * Applications usually load the builder lazily (engine + MJML are heavy). Its\n * chunk may not arrive: slow server, or a new version deployed while the page\n * was open (the old chunk no longer exists). Without this guard the error\n * reaches the framework — a blank \"Application error\" page.\n *\n * Retry: missing chunk → reload the page (the loader caches the failure);\n * any other failure → mount the builder again.\n *\n * <EmailBuilderBoundary onClose={…} t={…}>\n * <LazyEmailBuilder … />\n * </EmailBuilderBoundary>\n *\n * `t`: translator for its three strings (class component: no hooks).\n */\n\nconst isChunkError = (error) =>\n error?.name === 'ChunkLoadError' || /Loading (CSS )?chunk .* failed/i.test(String(error?.message || ''));\n\nconst english = (text) => text;\n\nexport default class EmailBuilderBoundary extends Component {\n constructor(props) {\n super(props);\n this.state = { error: null, attempt: 0 };\n }\n\n static getDerivedStateFromError(error) {\n return { error };\n }\n\n componentDidCatch(error) {\n console.warn('[best-email-builder] the builder could not load', error);\n }\n\n retry = () => {\n if (isChunkError(this.state.error)) {\n window.location.reload();\n return;\n }\n this.setState((s) => ({ error: null, attempt: s.attempt + 1 }));\n };\n\n render() {\n const { error, attempt } = this.state;\n const t = this.props.t || english;\n if (!error) {\n return (\n <div key={attempt} style={{ height: '100%' }}>\n {this.props.children}\n </div>\n );\n }\n return (\n <div\n role=\"alert\"\n className=\"eb-root eb:flex eb:h-full eb:flex-col eb:items-center eb:justify-center eb:gap-3 eb:p-6 eb:text-center\"\n >\n <AlertTriangle className=\"eb:size-6 eb:text-destructive\" aria-hidden=\"true\" />\n <p className=\"eb:text-[13px] eb:text-foreground\">{t('The builder could not load.')}</p>\n <div className=\"eb:flex eb:gap-2\">\n {this.props.onClose && (\n <Button variant=\"outline\" size=\"sm\" onClick={this.props.onClose}>\n <ArrowLeft />\n {t('Back')}\n </Button>\n )}\n <Button size=\"sm\" onClick={this.retry}>\n <RefreshCw />\n {t('Retry')}\n </Button>\n </div>\n </div>\n );\n }\n}\n"],"mappings":"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","names":["resolved","layout","document","mjml","mjml","MJML","MJML","mjml","mjml","mjml","useState","Braces","useState","jsx","jsxs","useState","field","useEffect","useMemo","useState","jsx","jsxs","useState","useMemo","useEffect","jsx","jsxs","useState","Braces","useState","Loader2","Fragment","jsx","jsxs","useState","Loader2","useEffect","useMemo","useState","Fragment","jsx","jsxs","useState","useEffect","useMemo","useEffect","useMemo","useRef","useState","Loader2","Search","Fragment","jsx","jsxs","useState","useRef","useEffect","useMemo","Search","Loader2","useEffect","useRef","useState","Loader2","Trash2","TriangleAlert","useState","Check","jsx","jsxs","useState","Check","Fragment","jsx","jsxs","useState","useRef","useEffect","Loader2","TriangleAlert","Trash2","link","document","escapeXml","svg","document","link","inside","mjml","document","useEffect","useRef","jsx","document","useRef","useEffect","useCallback","useEffect","useMemo","useRef","useState","Loader2","Plus","KEY","document","useRef","jsx","jsxs","ICONS","GROUPS","useRef","Trash2","jsx","jsxs","Trash2","useMemo","useRef","useEffect","useRef","useState","Loader2","Upload","Fragment","jsx","jsxs","useState","useRef","useEffect","Loader2","Upload","useState","Braces","jsx","jsxs","useState","Braces","useEffect","useRef","useState","Loader2","Sparkles","TriangleAlert","jsx","jsxs","useState","useRef","useEffect","Loader2","Sparkles","TriangleAlert","useEffect","useRef","useState","Check","Loader2","Sparkles","TriangleAlert","jsx","jsxs","useState","useRef","useEffect","Loader2","Sparkles","Check","TriangleAlert","Fragment","jsx","jsxs","useRef","useMemo","bodyBlock","ArrowLeft","Fragment","jsx","jsxs","identity","ArrowLeft","useEffect","X","jsx","jsxs","useEffect","X","useEffect","useRef","useState","Fragment","jsx","jsxs","useRef","useMemo","useState","useCallback","useEffect","template","layout","document","mjml","Loader2","Plus","AlertTriangle","ArrowLeft","jsx","jsxs","AlertTriangle","ArrowLeft"]}
|