mail-editor-pancake 0.0.0 → 0.0.8
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/README.md +79 -6
- package/package.json +1 -1
- package/packages/blocks/dist/index.d.ts +55 -3
- package/packages/blocks/dist/index.js +267 -208
- package/packages/blocks/dist/index.js.map +1 -1
- package/packages/blocks/node_modules/.bin/resolve +21 -0
- package/packages/blocks/package.json +1 -0
- package/packages/blocks/src/button.ts +1 -0
- package/packages/blocks/src/hero.ts +2 -0
- package/packages/blocks/src/image.ts +1 -0
- package/packages/blocks/src/index.ts +19 -2
- package/packages/blocks/src/logo.ts +1 -0
- package/packages/blocks/src/social.ts +47 -22
- package/packages/blocks/src/socialGroup.ts +49 -22
- package/packages/blocks/src/socialShared.ts +39 -2
- package/packages/blocks/src/text.ts +25 -19
- package/packages/blocks/tsconfig.json +0 -3
- package/packages/blocks/vite.config.ts +2 -0
- package/packages/core/dist/index.d.ts +90 -7
- package/packages/core/dist/index.js +2505 -1462
- package/packages/core/dist/index.js.map +1 -1
- package/packages/core/dist/style.css +1 -1
- package/packages/core/src/editor/Canvas.ts +107 -53
- package/packages/core/src/editor/ColorPickerPopover.ts +291 -0
- package/packages/core/src/editor/Editor.ts +129 -8
- package/packages/core/src/editor/ExportModal.ts +2 -1
- package/packages/core/src/editor/FocusBreadcrumb.ts +120 -0
- package/packages/core/src/editor/ImageGalleryModal.ts +3 -3
- package/packages/core/src/editor/InlineEditor.ts +308 -66
- package/packages/core/src/editor/LeftPanel.ts +1 -2
- package/packages/core/src/editor/PreviewModal.ts +77 -7
- package/packages/core/src/editor/RichTextToolbar.ts +66 -44
- package/packages/core/src/editor/RightPanel.ts +773 -171
- package/packages/core/src/editor/SourceView.ts +2 -1
- package/packages/core/src/editor/Topbar.ts +150 -5
- package/packages/core/src/editor/styles.css +644 -81
- package/packages/core/src/index.ts +18 -1
- package/packages/core/src/renderer/mjml.ts +2 -1
- package/packages/core/src/store/store.ts +44 -3
- package/packages/core/src/types.ts +34 -3
- package/packages/core/src/utils/fontWeightSteps.ts +31 -0
- package/packages/core/src/utils/lockedMjml.ts +2 -1
- package/packages/core/src/utils/richTextCommand.ts +30 -0
- package/packages/core/src/utils/sectionLayout.ts +13 -0
- package/playground/vanilla/src/main.ts +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../src/icons.ts","../src/button.ts","../src/divider.ts","../src/footer.ts","../src/hero.ts","../src/html.ts","../src/image.ts","../src/logo.ts","../src/socialShared.ts","../src/social.ts","../src/socialGroup.ts","../src/spacer.ts","../src/text.ts","../src/index.ts"],"sourcesContent":["/** 24x24 viewBox 的内置组件图标。集中放,避免散落到各 block 文件。 */\nexport const icons = {\n html: `<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\"><rect x=\"3.5\" y=\"4\" width=\"17\" height=\"16\" rx=\"2\" stroke=\"currentColor\" stroke-width=\"1.5\" fill=\"none\"/><path d=\"M8 8.5l3 3.5-3 3.5M16 8.5l-3 3.5 3 3.5\" stroke=\"currentColor\" stroke-width=\"1.6\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>`,\n text: `<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path d=\"M5 6h14M5 10h14M5 14h10M5 18h8\" stroke=\"currentColor\" stroke-width=\"1.6\" stroke-linecap=\"round\" fill=\"none\"/></svg>`,\n image: `<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><rect x=\"3.5\" y=\"5\" width=\"17\" height=\"14\" rx=\"2\" stroke=\"currentColor\" stroke-width=\"1.6\" fill=\"none\"/><circle cx=\"9\" cy=\"10\" r=\"1.5\" fill=\"currentColor\"/><path d=\"M4 18l5-5 4 4 3-3 4 4\" stroke=\"currentColor\" stroke-width=\"1.6\" fill=\"none\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>`,\n hero: `<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><rect x=\"3\" y=\"6\" width=\"18\" height=\"12\" rx=\"1.5\" stroke=\"currentColor\" stroke-width=\"1.5\" fill=\"none\"/><path d=\"M6 14h5M6 17h8\" stroke=\"currentColor\" stroke-width=\"1.4\" stroke-linecap=\"round\"/></svg>`,\n button: `<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><rect x=\"4\" y=\"8\" width=\"16\" height=\"8\" rx=\"4\" fill=\"currentColor\" opacity=\"0.75\"/></svg>`,\n divider: `<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path d=\"M3 12h18\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"/></svg>`,\n spacer: `<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path d=\"M5 8h14M5 16h14\" stroke=\"currentColor\" stroke-width=\"1.6\" stroke-linecap=\"round\"/><path d=\"M12 9v6\" stroke=\"currentColor\" stroke-width=\"1.6\" stroke-linecap=\"round\"/><path d=\"M9 12l3-3 3 3M9 12l3 3 3-3\" stroke=\"currentColor\" stroke-width=\"1.6\" fill=\"none\" stroke-linejoin=\"round\"/></svg>`,\n logo: `<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path d=\"M5 18V6l7 6 7-6v12\" stroke=\"currentColor\" stroke-width=\"1.6\" fill=\"none\" stroke-linejoin=\"round\"/></svg>`,\n social: `<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><circle cx=\"6\" cy=\"12\" r=\"2.5\" stroke=\"currentColor\" stroke-width=\"1.4\" fill=\"none\"/><circle cx=\"12\" cy=\"12\" r=\"2.5\" stroke=\"currentColor\" stroke-width=\"1.4\" fill=\"none\"/><circle cx=\"18\" cy=\"12\" r=\"2.5\" stroke=\"currentColor\" stroke-width=\"1.4\" fill=\"none\"/></svg>`,\n footer: `<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><rect x=\"3.5\" y=\"5\" width=\"17\" height=\"10\" rx=\"1.5\" stroke=\"currentColor\" stroke-width=\"1.4\" fill=\"none\"/><path d=\"M5 18h14\" stroke=\"currentColor\" stroke-width=\"1.6\" stroke-linecap=\"round\"/></svg>`,\n socialGroup: `<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\"><rect x=\"3\" y=\"5\" width=\"18\" height=\"14\" rx=\"2\" stroke=\"currentColor\" stroke-width=\"1.5\"/><circle cx=\"8\" cy=\"12\" r=\"2\" stroke=\"currentColor\" stroke-width=\"1.4\"/><circle cx=\"12\" cy=\"12\" r=\"2\" stroke=\"currentColor\" stroke-width=\"1.4\"/><circle cx=\"16\" cy=\"12\" r=\"2\" stroke=\"currentColor\" stroke-width=\"1.4\"/></svg>`,\n};\n","import { defineBlock, blockButtonWidthCss } from '@simple-mail/core';\nimport { icons } from './icons';\n\ninterface ButtonProps {\n text: string;\n href: string;\n backgroundColor: string;\n color: string;\n borderRadius: number;\n align: 'left' | 'center' | 'right';\n /** 留空或 auto 为自适应;可填 200px、80% 等 */\n width: string;\n paddingTop: number;\n paddingRight: number;\n paddingBottom: number;\n paddingLeft: number;\n innerPaddingV: number;\n innerPaddingH: number;\n fontSize: string;\n}\n\nconst escapeAttr = (s: string) =>\n s.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/\"/g, '"');\n\nexport const buttonBlock = defineBlock<ButtonProps>({\n type: 'button',\n name: '按钮',\n category: 'content',\n icon: icons.button,\n defaultProps: {\n text: '立即查看',\n href: 'https://example.com',\n backgroundColor: '#4f46e5',\n color: '#ffffff',\n borderRadius: 6,\n align: 'center',\n width: '',\n paddingTop: 8,\n paddingRight: 0,\n paddingBottom: 8,\n paddingLeft: 0,\n innerPaddingV: 12,\n innerPaddingH: 24,\n fontSize: '14px',\n },\n schema: [\n { key: 'text', label: '文字', type: 'text' },\n { key: 'href', label: '链接', type: 'url' },\n { key: 'backgroundColor', label: '背景色', type: 'color' },\n { key: 'color', label: '文字颜色', type: 'color' },\n { key: 'borderRadius', label: '圆角 (px)', type: 'number', min: 0, max: 40 },\n { key: 'fontSize', label: '字号', type: 'text' },\n {\n key: 'align',\n label: '对齐',\n type: 'select',\n options: [\n { label: '左', value: 'left' },\n { label: '居中', value: 'center' },\n { label: '右', value: 'right' },\n ],\n },\n {\n key: 'width',\n label: '宽度',\n type: 'text',\n placeholder: '留空=自适应,如 280px、100%',\n help: '支持纯数字(按 px)、带 px 或百分比',\n },\n { key: 'innerPaddingV', label: '按钮内上下边距', type: 'number', min: 0, max: 40 },\n { key: 'innerPaddingH', label: '按钮内左右边距', type: 'number', min: 0, max: 60 },\n { key: 'paddingTop', label: '外边距', type: 'spacing' },\n ],\n inlineEditable: {\n selector: '.sm-button-text',\n mode: 'plain',\n multiline: false,\n propKey: 'text',\n placeholder: '按钮文字',\n },\n toMjml: (p) => {\n const padding = `${p.paddingTop}px ${p.paddingRight}px ${p.paddingBottom}px ${p.paddingLeft}px`;\n const innerPadding = `${p.innerPaddingV}px ${p.innerPaddingH}px`;\n const bw = blockButtonWidthCss(p.width);\n const widthAttr = bw ? ` width=\"${escapeAttr(bw)}\"` : '';\n return `<mj-button href=\"${escapeAttr(p.href)}\" background-color=\"${escapeAttr(\n p.backgroundColor,\n )}\" color=\"${escapeAttr(p.color)}\" border-radius=\"${p.borderRadius}px\" font-size=\"${escapeAttr(\n p.fontSize,\n )}\" align=\"${p.align}\" padding=\"${padding}\" inner-padding=\"${innerPadding}\"${widthAttr}>${escapeAttr(\n p.text,\n )}</mj-button>`;\n },\n renderPreview: (p) => {\n const bw = blockButtonWidthCss(p.width);\n const wst = bw ? `width:${bw};max-width:100%;box-sizing:border-box;` : '';\n /* 画布对 .sm-canvas a 设置了带 !important 的链接色,文字颜色必须写在子节点上才能生效 */\n return `<div style=\"padding:${p.paddingTop}px ${p.paddingRight}px ${p.paddingBottom}px ${p.paddingLeft}px;text-align:${p.align};\">\n <a href=\"${escapeAttr(p.href)}\" style=\"display:inline-block;background:${\n p.backgroundColor\n };border-radius:${p.borderRadius}px;padding:${p.innerPaddingV}px ${\n p.innerPaddingH\n }px;text-decoration:none;font-size:${p.fontSize};line-height:1.2;${wst}\"><span class=\"sm-button-text\" style=\"color:${\n p.color\n }\">${escapeAttr(p.text)}</span></a>\n </div>`;\n },\n});\n","import { defineBlock } from '@simple-mail/core';\nimport { icons } from './icons';\n\ninterface DividerProps {\n color: string;\n width: string;\n thickness: number;\n paddingTop: number;\n paddingBottom: number;\n}\n\nconst esc = (s: string) =>\n s.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/\"/g, '"');\n\nexport const dividerBlock = defineBlock<DividerProps>({\n type: 'divider',\n name: '分隔线',\n category: 'content',\n icon: icons.divider,\n defaultProps: {\n color: '#e6e8ec',\n width: '100%',\n thickness: 1,\n paddingTop: 8,\n paddingBottom: 8,\n },\n schema: [\n { key: 'color', label: '颜色', type: 'color' },\n { key: 'width', label: '宽度 (% 或 px)', type: 'text' },\n { key: 'thickness', label: '粗细 (px)', type: 'number', min: 1, max: 10 },\n { key: 'paddingTop', label: '上边距', type: 'number', min: 0, max: 80 },\n { key: 'paddingBottom', label: '下边距', type: 'number', min: 0, max: 80 },\n ],\n toMjml: (p) =>\n `<mj-divider border-color=\"${esc(p.color)}\" border-width=\"${p.thickness}px\" width=\"${esc(\n p.width,\n )}\" padding=\"${p.paddingTop}px 0px ${p.paddingBottom}px 0px\" />`,\n renderPreview: (p) =>\n `<div style=\"padding:${p.paddingTop}px 0 ${p.paddingBottom}px 0;\"><div style=\"border-top:${p.thickness}px solid ${p.color};width:${p.width};margin:0 auto;\"></div></div>`,\n});\n","import { defineBlock } from '@simple-mail/core';\nimport { icons } from './icons';\n\ninterface FooterProps {\n companyName: string;\n address: string;\n unsubscribeText: string;\n unsubscribeHref: string;\n textColor: string;\n}\n\nconst esc = (s: string) =>\n s.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/\"/g, '"');\n\nexport const footerBlock = defineBlock<FooterProps>({\n type: 'custom:footer',\n name: '页脚',\n category: 'custom',\n icon: icons.footer,\n defaultProps: {\n companyName: '你的公司',\n address: '上海市某区某路某号',\n unsubscribeText: '退订邮件',\n unsubscribeHref: '{{unsubscribeUrl}}',\n textColor: '#9aa0a6',\n },\n schema: [\n { key: 'companyName', label: '公司名称', type: 'text' },\n { key: 'address', label: '地址', type: 'text' },\n { key: 'unsubscribeText', label: '退订文案', type: 'text' },\n { key: 'unsubscribeHref', label: '退订链接', type: 'url' },\n { key: 'textColor', label: '文字颜色', type: 'color' },\n ],\n toMjml: (p) => {\n return `<mj-text align=\"center\" color=\"${esc(p.textColor)}\" font-size=\"12px\" line-height=\"1.6\" padding=\"8px 0px 8px 0px\">\n ${esc(p.companyName)}<br />\n ${esc(p.address)}<br />\n <a href=\"${esc(p.unsubscribeHref)}\" style=\"color:${esc(p.textColor)};\">${esc(p.unsubscribeText)}</a>\n</mj-text>`;\n },\n renderPreview: (p) => {\n return `<div style=\"padding:8px 0;text-align:center;font-size:12px;line-height:1.6;color:${p.textColor};\">\n ${esc(p.companyName)}<br/>\n ${esc(p.address)}<br/>\n <a href=\"${esc(p.unsubscribeHref)}\" style=\"color:${p.textColor};\">${esc(p.unsubscribeText)}</a>\n </div>`;\n },\n});\n","import { defineBlock, docContentWidthCss } from '@simple-mail/core';\nimport { icons } from './icons';\n\ninterface HeroProps {\n backgroundUrl: string;\n backgroundColor: string;\n height: number;\n content: string;\n textAlign: 'left' | 'center' | 'right';\n textColor: string;\n verticalAlign: 'top' | 'middle' | 'bottom';\n paddingTop: number;\n paddingRight: number;\n paddingBottom: number;\n paddingLeft: number;\n}\n\nconst escapeAttr = (s: string) =>\n s.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/\"/g, '"');\n\nexport const heroBlock = defineBlock<HeroProps>({\n type: 'hero',\n name: 'Hero 大图',\n category: 'content',\n icon: icons.hero,\n defaultProps: {\n backgroundUrl:\n 'https://placehold.co/600x320/312e81/c4b5fd/png?text=Hero+Background',\n backgroundColor: '#1e1b4b',\n height: 320,\n content:\n '<p style=\"margin:0;font-size:28px;font-weight:700;line-height:1.25;\">主标题落在大图上</p><p style=\"margin:12px 0 0;font-size:16px;font-weight:400;opacity:0.95;line-height:1.5;\">支援变量与 <strong>双击编辑</strong>,与正文组件一致。</p>',\n textAlign: 'center',\n textColor: '#ffffff',\n verticalAlign: 'middle',\n paddingTop: 8,\n paddingRight: 0,\n paddingBottom: 8,\n paddingLeft: 0,\n },\n schema: [\n { key: 'backgroundUrl', label: '背景图', type: 'image' },\n { key: 'backgroundColor', label: '背景占位色', type: 'color', help: '图片加载失败时的底色' },\n { key: 'height', label: '区域高度 (px)', type: 'number', min: 120, max: 1200, step: 1 },\n {\n key: 'verticalAlign',\n label: '文字垂直位置',\n type: 'select',\n options: [\n { label: '靠上', value: 'top' },\n { label: '居中', value: 'middle' },\n { label: '靠下', value: 'bottom' },\n ],\n },\n {\n key: 'textAlign',\n label: '文字水平对齐',\n type: 'select',\n options: [\n { label: '左', value: 'left' },\n { label: '居中', value: 'center' },\n { label: '右', value: 'right' },\n ],\n },\n { key: 'textColor', label: '文字颜色', type: 'color' },\n { key: 'paddingTop', label: '内边距', type: 'spacing' },\n {\n key: 'content',\n label: '正文(HTML)',\n type: 'textarea',\n help: '建议在画布内双击编辑;此处供高级修改。',\n },\n ],\n inlineEditable: {\n selector: '.sm-hero-content',\n mode: 'rich',\n multiline: true,\n propKey: 'content',\n placeholder: '编写覆盖在图片上的文案…',\n },\n toMjml: (p, ctx) => {\n const w = docContentWidthCss(ctx.doc.meta.width);\n const padding = `${p.paddingTop}px ${p.paddingRight}px ${p.paddingBottom}px ${p.paddingLeft}px`;\n const h = `${p.height}px`;\n return `<mj-hero\n mode=\"fixed-height\"\n height=\"${h}\"\n background-width=\"${w}\"\n background-height=\"${h}\"\n background-url=\"${escapeAttr(p.backgroundUrl)}\"\n background-color=\"${escapeAttr(p.backgroundColor)}\"\n padding=\"${padding}\"\n vertical-align=\"${p.verticalAlign}\"\n >\n <mj-text\n align=\"${p.textAlign}\"\n color=\"${escapeAttr(p.textColor)}\"\n padding=\"0\"\n >${p.content}</mj-text>\n </mj-hero>`;\n },\n renderPreview: (p, ctx) => {\n const w = docContentWidthCss(ctx.doc.meta.width);\n const flexAlign =\n p.verticalAlign === 'top' ? 'flex-start' : p.verticalAlign === 'bottom' ? 'flex-end' : 'center';\n const padding = `${p.paddingTop}px ${p.paddingRight}px ${p.paddingBottom}px ${p.paddingLeft}px`;\n const url = escapeAttr(p.backgroundUrl);\n return `<div\n style=\"\n box-sizing:border-box;\n width:100%;\n max-width:${w};\n min-height:${p.height}px;\n margin:0 auto;\n background-image:linear-gradient(to bottom,rgba(0,0,0,0.25),rgba(0,0,0,0.35)),url(${url});\n background-size:cover;\n background-position:center;\n background-color:${p.backgroundColor};\n display:flex;\n align-items:${flexAlign};\n justify-content:${p.textAlign === 'right' ? 'flex-end' : p.textAlign === 'center' ? 'center' : 'flex-start'};\n padding:${padding};\n color:${escapeAttr(p.textColor)};\n overflow:hidden;\n border-radius:2px;\n \"\n >\n <div\n class=\"sm-hero-content\"\n style=\"\n width:100%;\n text-align:${p.textAlign};\n color:${escapeAttr(p.textColor)};\n text-shadow:0 1px 2px rgba(0,0,0,0.45);\n \"\n >${p.content}</div>\n </div>`;\n },\n});\n","import { defineBlock, mjRawCellTypographyFromStyles, mjRawEmailTableWrap } from '@simple-mail/core';\nimport { icons } from './icons';\n\ninterface HtmlBlockProps {\n html: string;\n paddingTop: number;\n paddingRight: number;\n paddingBottom: number;\n paddingLeft: number;\n}\n\nexport const htmlBlock = defineBlock<HtmlBlockProps>({\n type: 'html',\n name: 'HTML',\n category: 'content',\n icon: icons.html,\n defaultProps: {\n html: '<p style=\"margin:0;\">在此写入任意 HTML,将经 <strong>mj-raw</strong> 原样输出到邮件。支持变量 {{user.name}}</p>',\n paddingTop: 8,\n paddingRight: 0,\n paddingBottom: 8,\n paddingLeft: 0,\n },\n schema: [\n {\n key: 'html',\n label: 'HTML',\n type: 'textarea',\n help: '插入 MJML 的 mj-raw。邮件客户端常会过滤脚本与不支持的标签。',\n },\n { key: 'paddingTop', label: '内边距', type: 'spacing' },\n ],\n inlineEditable: {\n selector: '.sm-html-content',\n mode: 'html',\n multiline: true,\n propKey: 'html',\n placeholder: '输入 HTML…',\n },\n toMjml: (p, ctx) => {\n const padding = `${p.paddingTop}px ${p.paddingRight}px ${p.paddingBottom}px ${p.paddingLeft}px`;\n return mjRawEmailTableWrap(padding, p.html, mjRawCellTypographyFromStyles(ctx.doc.styles));\n },\n renderPreview: (p) => {\n const pad = `${p.paddingTop}px ${p.paddingRight}px ${p.paddingBottom}px ${p.paddingLeft}px`;\n return `<div class=\"sm-html-content\" style=\"padding:${pad};min-height:1em;\">${p.html}</div>`;\n },\n});\n","import { defineBlock } from '@simple-mail/core';\nimport { icons } from './icons';\n\ninterface ImageProps {\n src: string;\n alt: string;\n href: string;\n width: number;\n /** 0 表示不限制高度,按原图比例自适应(推荐邮件场景) */\n height: number;\n align: 'left' | 'center' | 'right';\n paddingTop: number;\n paddingRight: number;\n paddingBottom: number;\n paddingLeft: number;\n}\n\nconst escapeAttr = (s: string) =>\n s.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/\"/g, '"');\n\nexport const imageBlock = defineBlock<ImageProps>({\n type: 'image',\n name: '图片',\n category: 'content',\n icon: icons.image,\n defaultProps: {\n src: 'https://placehold.co/600x240/EEF2FF/4F46E5/png?text=600x240',\n alt: '',\n href: '',\n width: 480,\n height: 0,\n align: 'center',\n paddingTop: 8,\n paddingRight: 0,\n paddingBottom: 8,\n paddingLeft: 0,\n },\n schema: [\n { key: 'src', label: '图片地址', type: 'image' },\n { key: 'alt', label: '替代文本', type: 'text', placeholder: '图片描述' },\n { key: 'href', label: '点击跳转', type: 'url', placeholder: 'https://...' },\n { key: 'width', label: '宽度 (px)', type: 'number', min: 40, max: 600 },\n {\n key: 'height',\n label: '高度 (px)(0 为自适应)',\n type: 'number',\n min: 0,\n max: 1200,\n help: '0 为自适应高度;填写固定值时画布与 MJML 会限制显示高度(预览可用 object-fit: cover)',\n },\n {\n key: 'align',\n label: '对齐',\n type: 'select',\n options: [\n { label: '左', value: 'left' },\n { label: '居中', value: 'center' },\n { label: '右', value: 'right' },\n ],\n },\n { key: 'paddingTop', label: '内边距', type: 'spacing' },\n ],\n toMjml: (p) => {\n const padding = `${p.paddingTop}px ${p.paddingRight}px ${p.paddingBottom}px ${p.paddingLeft}px`;\n const href = p.href ? ` href=\"${escapeAttr(p.href)}\"` : '';\n const alt = ` alt=\"${escapeAttr(p.alt || '')}\"`;\n const h = p.height != null && p.height > 0 ? ` height=\"${p.height}px\"` : '';\n return `<mj-image src=\"${escapeAttr(p.src)}\"${alt}${href} width=\"${p.width}px\"${h} align=\"${p.align}\" padding=\"${padding}\" />`;\n },\n renderPreview: (p) => {\n const align = p.align === 'center' ? 'margin:0 auto;' : p.align === 'right' ? 'margin-left:auto;' : '';\n const fixedH = p.height != null && p.height > 0 ? p.height : 0;\n const sizeStyle =\n fixedH > 0\n ? `width:${p.width}px;height:${fixedH}px;object-fit:cover;object-position:center;`\n : `width:${p.width}px;height:auto;`;\n return `<div style=\"padding:${p.paddingTop}px ${p.paddingRight}px ${p.paddingBottom}px ${p.paddingLeft}px;text-align:${p.align};\"><img src=\"${escapeAttr(\n p.src,\n )}\" alt=\"${escapeAttr(p.alt)}\" style=\"display:block;${align}max-width:100%;${sizeStyle}border:0;outline:none;\" /></div>`;\n },\n});\n","import { defineBlock } from '@simple-mail/core';\nimport { icons } from './icons';\n\n/** 公司 Logo —— 一个语义化的\"图片+链接\"封装,便于运营快速放置品牌资产。 */\ninterface LogoProps {\n src: string;\n href: string;\n width: number;\n align: 'left' | 'center' | 'right';\n}\n\nconst esc = (s: string) =>\n s.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/\"/g, '"');\n\nexport const logoBlock = defineBlock<LogoProps>({\n type: 'custom:logo',\n name: '公司 Logo',\n category: 'custom',\n icon: icons.logo,\n defaultProps: {\n src: 'https://placehold.co/240x60/1f2328/ffffff/png?text=YOUR+LOGO',\n href: 'https://example.com',\n width: 160,\n align: 'center',\n },\n schema: [\n { key: 'src', label: 'Logo 图片', type: 'image' },\n { key: 'href', label: '官网链接', type: 'url' },\n { key: 'width', label: '宽度 (px)', type: 'number', min: 60, max: 400 },\n {\n key: 'align',\n label: '对齐',\n type: 'select',\n options: [\n { label: '左', value: 'left' },\n { label: '居中', value: 'center' },\n { label: '右', value: 'right' },\n ],\n },\n ],\n toMjml: (p) =>\n `<mj-image src=\"${esc(p.src)}\" href=\"${esc(p.href)}\" width=\"${p.width}px\" align=\"${p.align}\" alt=\"logo\" padding=\"8px 0px 8px 0px\" />`,\n renderPreview: (p) => {\n const m =\n p.align === 'center' ? 'margin:0 auto;' : p.align === 'right' ? 'margin-left:auto;' : '';\n return `<div style=\"padding:8px 0;text-align:${p.align};\"><img src=\"${esc(\n p.src,\n )}\" alt=\"logo\" style=\"display:block;${m}width:${p.width}px;max-width:100%;height:auto;\" /></div>`;\n },\n});\n","/** 生成 mj-social-element 的 name 属性(与 MJML 内置图标对齐;未知平台退化为 web)。 */\nexport function mjSocialElementName(network: string): string {\n const n = network.trim();\n if (n === 'ig') return 'instagram';\n if (n === 'rabbit' || n === 'tiktok') return 'web';\n return n;\n}\n\n/** 业务示例:固定海外/垂类五平台(与 custom:social 块配套)。 */\nexport const BIZ_SOCIAL_NETWORK_OPTIONS: { label: string; value: string }[] = [\n { label: 'X', value: 'x' },\n { label: 'Rabbit', value: 'rabbit' },\n { label: 'Facebook', value: 'facebook' },\n { label: 'TikTok', value: 'tiktok' },\n { label: 'Instagram', value: 'ig' },\n];\n\n/** 社交平台与 MJML mj-social-element 的 name 对齐(含常用内置名)。 */\nexport const SOCIAL_NETWORK_OPTIONS: { label: string; value: string }[] = [\n { label: '微信', value: 'wechat' },\n { label: '微博', value: 'weibo' },\n { label: 'X', value: 'x' },\n { label: 'LinkedIn', value: 'linkedin' },\n { label: 'GitHub', value: 'github' },\n { label: 'Facebook', value: 'facebook' },\n { label: 'Instagram', value: 'instagram' },\n { label: 'YouTube', value: 'youtube' },\n { label: '网页', value: 'web' },\n];\n\nconst NETWORK_META: Record<string, { color: string; preview: string }> = {\n wechat: { color: '#1AAD19', preview: '信' },\n weibo: { color: '#E6162D', preview: '微' },\n x: { color: '#000000', preview: 'X' },\n linkedin: { color: '#0A66C2', preview: 'in' },\n github: { color: '#181717', preview: 'GH' },\n facebook: { color: '#1877F2', preview: 'f' },\n instagram: { color: '#E4405F', preview: '◎' },\n ig: { color: '#E4405F', preview: '◎' },\n youtube: { color: '#FF0000', preview: '▶' },\n tiktok: { color: '#000000', preview: '♪' },\n rabbit: { color: '#FF2442', preview: 'R' },\n website: { color: '#6b7280', preview: '◇' },\n web: { color: '#6b7280', preview: '◇' },\n};\n\nexport const escAttr = (s: string) =>\n s.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/\"/g, '"');\n\n/** mj-social-element 体内文本转义(非属性) */\nexport const escMjmlText = (s: string) =>\n s.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');\n\nexport interface SocialLinkItem {\n network: string;\n href: string;\n /** 图标旁文字,对应 mj-social-element 子内容 */\n label?: string;\n /** 自定义图标 URL,对应 mj-social-element src */\n iconSrc?: string;\n /** 图标区域背景色;未设则用平台预设 */\n backgroundColor?: string;\n}\n\n/** 社交组块级:所有带标签的链接共用同一套标签文字样式 */\nexport interface SocialGroupLabelStyle {\n labelFontSize: number;\n labelFontWeight: string;\n labelColor: string;\n}\n\nexport function socialMeta(network: string): { color: string; preview: string } {\n return NETWORK_META[network] ?? { color: '#6b7280', preview: '·' };\n}\n\nexport function paddingQuad(p: {\n paddingTop: number;\n paddingRight: number;\n paddingBottom: number;\n paddingLeft: number;\n}): string {\n return `${p.paddingTop}px ${p.paddingRight}px ${p.paddingBottom}px ${p.paddingLeft}px`;\n}\n\nexport function mjSocialElementsLines(\n links: SocialLinkItem[],\n labelStyle: SocialGroupLabelStyle,\n): string {\n const fontSizeRaw = labelStyle.labelFontSize > 0 ? labelStyle.labelFontSize : 13;\n const fontSize = Math.max(8, Math.min(48, fontSizeRaw));\n const fontWeight = labelStyle.labelFontWeight?.trim() || 'normal';\n const textColor = labelStyle.labelColor?.trim() || '#333333';\n const fwEsc = escAttr(fontWeight);\n return links\n .map((l) => {\n const meta = socialMeta(l.network);\n const bgColor = l.backgroundColor?.trim() || meta.color;\n const attrs = [\n `name=\"${escAttr(mjSocialElementName(l.network))}\"`,\n `href=\"${escAttr(l.href)}\"`,\n `background-color=\"${escAttr(bgColor)}\"`,\n `color=\"${escAttr(textColor)}\"`,\n `font-size=\"${fontSize}px\"`,\n `font-weight=\"${fwEsc}\"`,\n ];\n const attrStr = attrs.join(' ');\n const src = l.iconSrc?.trim();\n const withSrc = src ? `${attrStr} src=\"${escAttr(src)}\"` : attrStr;\n const label = l.label?.trim() ?? '';\n if (!label) {\n return ` <mj-social-element ${withSrc} />`;\n }\n return ` <mj-social-element ${withSrc}>\\n ${escMjmlText(label)}\\n </mj-social-element>`;\n })\n .join('\\n');\n}\n","import { defineBlock } from '@simple-mail/core';\nimport { icons } from './icons';\nimport {\n BIZ_SOCIAL_NETWORK_OPTIONS,\n escAttr,\n mjSocialElementsLines,\n paddingQuad,\n socialMeta,\n type SocialLinkItem,\n} from './socialShared';\n\n/** 与社交组一致,仅平台选项收窄为业务五件套 */\ninterface SocialBizProps {\n elements: SocialLinkItem[];\n align: 'left' | 'center' | 'right';\n iconSize: number;\n labelFontSize: number;\n labelFontWeight: string;\n labelColor: string;\n paddingTop: number;\n paddingRight: number;\n paddingBottom: number;\n paddingLeft: number;\n /** 旧版自定义块:`links` + textarea,仅用于兼容读入 */\n links?: { network: string; href: string }[];\n}\n\nconst DEFAULT_BIZ_ELEMENTS: SocialLinkItem[] = [\n { network: 'x', href: 'https://x.com/' },\n { network: 'rabbit', href: 'https://example.com' },\n { network: 'facebook', href: 'https://facebook.com/' },\n { network: 'tiktok', href: 'https://www.tiktok.com/' },\n { network: 'ig', href: 'https://instagram.com/' },\n];\n\nfunction normalizeElements(p: SocialBizProps): SocialLinkItem[] {\n if (p.elements?.length) return p.elements;\n const legacy = p.links;\n if (Array.isArray(legacy) && legacy.length)\n return legacy.map((l) => ({\n network: String(l.network ?? 'web'),\n href: String(l.href ?? ''),\n }));\n return DEFAULT_BIZ_ELEMENTS;\n}\n\nexport const socialBlock = defineBlock<SocialBizProps>({\n type: 'custom:social',\n name: '社交链接',\n category: 'custom',\n icon: icons.social,\n defaultProps: {\n elements: DEFAULT_BIZ_ELEMENTS,\n align: 'center',\n iconSize: 28,\n labelFontSize: 13,\n labelFontWeight: 'normal',\n labelColor: '#333333',\n paddingTop: 8,\n paddingRight: 0,\n paddingBottom: 8,\n paddingLeft: 0,\n },\n schema: [\n {\n key: 'elements',\n label: '社交链接',\n type: 'socialLinkList',\n options: BIZ_SOCIAL_NETWORK_OPTIONS,\n help: '平台:X、Rabbit、Facebook、TikTok、Instagram (ig)。可填标签、自定义图标 URL。MJML 侧 Rabbit/TikTok 使用 web 占位图标,需要品牌图时请填「图标 URL」。',\n },\n {\n key: 'labelFontSize',\n label: '标签字号 (px)',\n type: 'number',\n min: 8,\n max: 48,\n step: 1,\n },\n {\n key: 'labelFontWeight',\n label: '标签字重',\n type: 'select',\n options: [\n { label: '较细 (300)', value: '300' },\n { label: '常规', value: 'normal' },\n { label: '400', value: '400' },\n { label: '500', value: '500' },\n { label: '600', value: '600' },\n { label: '700', value: '700' },\n { label: '粗体', value: 'bold' },\n { label: '更粗 (800)', value: '800' },\n ],\n },\n { key: 'labelColor', label: '标签颜色', type: 'color' },\n {\n key: 'align',\n label: '对齐',\n type: 'select',\n options: [\n { label: '左', value: 'left' },\n { label: '居中', value: 'center' },\n { label: '右', value: 'right' },\n ],\n },\n { key: 'iconSize', label: '图标尺寸 (px)', type: 'number', min: 16, max: 64 },\n { key: 'paddingTop', label: '外边距', type: 'spacing' },\n ],\n toMjml: (p) => {\n const pad = paddingQuad(p);\n const els = normalizeElements(p).filter((e) => e.href?.trim());\n const labelStyle = {\n labelFontSize: Number(p.labelFontSize ?? 13),\n labelFontWeight: String(p.labelFontWeight ?? 'normal'),\n labelColor: String(p.labelColor ?? '#333333'),\n };\n const inner = mjSocialElementsLines(els, labelStyle);\n if (!inner.trim()) {\n return `<mj-social align=\"${p.align}\" icon-size=\"${p.iconSize}px\" mode=\"horizontal\" padding=\"${pad}\"></mj-social>`;\n }\n return `<mj-social align=\"${p.align}\" icon-size=\"${p.iconSize}px\" mode=\"horizontal\" padding=\"${pad}\">\n${inner}\n</mj-social>`;\n },\n renderPreview: (p) => {\n const fsRaw = p.labelFontSize != null && p.labelFontSize > 0 ? p.labelFontSize : 13;\n const fs = Math.max(8, Math.min(48, fsRaw));\n const fw = p.labelFontWeight?.trim() || 'normal';\n const textColor = p.labelColor?.trim() || '#333333';\n const items = normalizeElements(p)\n .filter((l) => l.href?.trim())\n .map((l) => {\n const meta = socialMeta(l.network);\n const bg = l.backgroundColor?.trim() || meta.color;\n const label = l.label?.trim() ?? '';\n const iconSrc = l.iconSrc?.trim();\n const iconHtml = iconSrc\n ? `<img src=\"${escAttr(iconSrc)}\" alt=\"\" style=\"width:${p.iconSize}px;height:${p.iconSize}px;object-fit:contain;border-radius:3px;flex-shrink:0;\" />`\n : `<span style=\"display:inline-flex;width:${p.iconSize}px;height:${p.iconSize}px;border-radius:50%;background:${bg};color:#fff;align-items:center;justify-content:center;font-size:${Math.round(\n p.iconSize / 2,\n )}px;font-weight:600;flex-shrink:0;\">${meta.preview}</span>`;\n const textHtml = label\n ? `<span style=\"margin-left:6px;font-size:${fs}px !important;font-weight:${fw};color:${escAttr(\n textColor,\n )} !important;line-height:1.2;\">${escAttr(label)}</span>`\n : '';\n return `<span style=\"display:inline-flex;align-items:center;margin:0 6px;vertical-align:middle;\"><a href=\"${escAttr(\n l.href,\n )}\" style=\"display:inline-flex;align-items:center;text-decoration:none;line-height:0;\">${iconHtml}</a>${textHtml}</span>`;\n })\n .join('');\n const pad = paddingQuad(p);\n return `<div style=\"padding:${pad};text-align:${p.align};\">${items || '<span style=\"color:#9ca3af;font-size:12px;\">请填写链接 URL</span>'}</div>`;\n },\n});\n","import { defineBlock } from '@simple-mail/core';\nimport { icons } from './icons';\nimport {\n escAttr,\n mjSocialElementsLines,\n paddingQuad,\n socialMeta,\n SOCIAL_NETWORK_OPTIONS,\n type SocialLinkItem,\n} from './socialShared';\n\ninterface SocialGroupProps {\n elements: SocialLinkItem[];\n align: 'left' | 'center' | 'right';\n iconSize: number;\n /** 标签文字字号(整组统一) */\n labelFontSize: number;\n labelFontWeight: string;\n labelColor: string;\n paddingTop: number;\n paddingRight: number;\n paddingBottom: number;\n paddingLeft: number;\n}\n\nexport const socialGroupBlock = defineBlock<SocialGroupProps>({\n type: 'social-group',\n name: '社交组',\n category: 'content',\n icon: icons.socialGroup,\n defaultProps: {\n elements: [\n { network: 'weibo', href: 'https://weibo.com' },\n { network: 'wechat', href: 'https://example.com' },\n ],\n align: 'center',\n iconSize: 28,\n labelFontSize: 13,\n labelFontWeight: 'normal',\n labelColor: '#333333',\n paddingTop: 8,\n paddingRight: 0,\n paddingBottom: 8,\n paddingLeft: 0,\n },\n schema: [\n {\n key: 'elements',\n label: '社交链接',\n type: 'socialLinkList',\n options: SOCIAL_NETWORK_OPTIONS,\n help: '每行:平台、链接、可选标签文字、自定义图标 URL、图标背景色。标签的字号/字重/颜色在下方统一设置。',\n },\n {\n key: 'labelFontSize',\n label: '标签字号 (px)',\n type: 'number',\n min: 8,\n max: 48,\n step: 1,\n },\n {\n key: 'labelFontWeight',\n label: '标签字重',\n type: 'select',\n options: [\n { label: '较细 (300)', value: '300' },\n { label: '常规', value: 'normal' },\n { label: '400', value: '400' },\n { label: '500', value: '500' },\n { label: '600', value: '600' },\n { label: '700', value: '700' },\n { label: '粗体', value: 'bold' },\n { label: '更粗 (800)', value: '800' },\n ],\n },\n { key: 'labelColor', label: '标签颜色', type: 'color' },\n {\n key: 'align',\n label: '对齐',\n type: 'select',\n options: [\n { label: '左', value: 'left' },\n { label: '居中', value: 'center' },\n { label: '右', value: 'right' },\n ],\n },\n { key: 'iconSize', label: '图标尺寸 (px)', type: 'number', min: 16, max: 64 },\n { key: 'paddingTop', label: '外边距', type: 'spacing' },\n ],\n toMjml: (p) => {\n const pad = paddingQuad(p);\n const filtered = p.elements.filter((e) => e.href?.trim());\n const labelStyle = {\n labelFontSize: Number(p.labelFontSize ?? 13),\n labelFontWeight: String(p.labelFontWeight ?? 'normal'),\n labelColor: String(p.labelColor ?? '#333333'),\n };\n const inner = mjSocialElementsLines(filtered, labelStyle);\n if (!inner.trim()) {\n return `<mj-social align=\"${p.align}\" icon-size=\"${p.iconSize}px\" mode=\"horizontal\" padding=\"${pad}\"></mj-social>`;\n }\n return `<mj-social align=\"${p.align}\" icon-size=\"${p.iconSize}px\" mode=\"horizontal\" padding=\"${pad}\">\n${inner}\n</mj-social>`;\n },\n renderPreview: (p) => {\n const fsRaw = p.labelFontSize != null && p.labelFontSize > 0 ? p.labelFontSize : 13;\n const fs = Math.max(8, Math.min(48, fsRaw));\n const fw = p.labelFontWeight?.trim() || 'normal';\n const textColor = p.labelColor?.trim() || '#333333';\n const items = p.elements\n .filter((l) => l.href?.trim())\n .map((l) => {\n const meta = socialMeta(l.network);\n const bg = l.backgroundColor?.trim() || meta.color;\n const label = l.label?.trim() ?? '';\n const iconSrc = l.iconSrc?.trim();\n const iconHtml = iconSrc\n ? `<img src=\"${escAttr(iconSrc)}\" alt=\"\" style=\"width:${p.iconSize}px;height:${p.iconSize}px;object-fit:contain;border-radius:3px;flex-shrink:0;\" />`\n : `<span style=\"display:inline-flex;width:${p.iconSize}px;height:${p.iconSize}px;border-radius:50%;background:${bg};color:#fff;align-items:center;justify-content:center;font-size:${Math.round(\n p.iconSize / 2,\n )}px;font-weight:600;flex-shrink:0;\">${meta.preview}</span>`;\n const textHtml = label\n ? `<span style=\"margin-left:6px;font-size:${fs}px !important;font-weight:${fw};color:${escAttr(\n textColor,\n )} !important;line-height:1.2;\">${escAttr(label)}</span>`\n : '';\n return `<span style=\"display:inline-flex;align-items:center;margin:0 6px;vertical-align:middle;\"><a href=\"${escAttr(\n l.href,\n )}\" style=\"display:inline-flex;align-items:center;text-decoration:none;line-height:0;\">${iconHtml}</a>${textHtml}</span>`;\n })\n .join('');\n const pad = paddingQuad(p);\n return `<div style=\"padding:${pad};text-align:${p.align};\">${items || '<span style=\"color:#9ca3af;font-size:12px;\">请添加社交链接</span>'}</div>`;\n },\n});\n","import { defineBlock } from '@simple-mail/core';\nimport { icons } from './icons';\n\ninterface SpacerProps {\n height: number;\n}\n\nexport const spacerBlock = defineBlock<SpacerProps>({\n type: 'spacer',\n name: '间距',\n category: 'content',\n icon: icons.spacer,\n defaultProps: { height: 24 },\n schema: [{ key: 'height', label: '高度 (px)', type: 'number', min: 1, max: 200 }],\n toMjml: (p) => `<mj-spacer height=\"${p.height}px\" />`,\n renderPreview: (p) => `<div style=\"height:${p.height}px;line-height:${p.height}px;\"></div>`,\n});\n","import { defineBlock } from '@simple-mail/core';\nimport { icons } from './icons';\n\ninterface TextProps {\n content: string;\n align: 'left' | 'center' | 'right';\n color: string;\n fontSize: string;\n fontFamily: string;\n fontWeight: string;\n /** 空字符串:与邮件全局行距(mj-head)一致 */\n lineHeight: string;\n paddingTop: number;\n paddingRight: number;\n paddingBottom: number;\n paddingLeft: number;\n}\n\nconst escapeAttr = (s: string) =>\n s.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/\"/g, '"');\n\nexport const textBlock = defineBlock<TextProps>({\n type: 'text',\n name: '文本',\n category: 'content',\n icon: icons.text,\n defaultProps: {\n content:\n '<p style=\"margin:0;\">在此处输入文本。<strong>双击</strong>进入编辑模式,<em>选中文字</em>会出现工具条;支持变量 {{user.name}}</p>',\n align: 'left',\n color: '#433f3f',\n fontSize: '16px',\n fontFamily: '',\n fontWeight: 'normal',\n lineHeight: '',\n paddingTop: 8,\n paddingRight: 0,\n paddingBottom: 8,\n paddingLeft: 0,\n },\n schema: [\n {\n key: 'align',\n label: '默认对齐',\n type: 'select',\n options: [\n { label: '左', value: 'left' },\n { label: '居中', value: 'center' },\n { label: '右', value: 'right' },\n ],\n },\n { key: 'color', label: '默认颜色', type: 'color' },\n { key: 'fontSize', label: '默认字号', type: 'text', placeholder: '14px' },\n { key: 'fontFamily', label: '字体', type: 'text', placeholder: '继承全局' },\n {\n key: 'fontWeight',\n label: '字重',\n type: 'select',\n options: [\n { label: '常规 400', value: 'normal' },\n { label: '中等 500', value: '500' },\n { label: '半粗 600', value: '600' },\n { label: '加粗 700', value: 'bold' },\n ],\n },\n {\n key: 'lineHeight',\n label: '行高',\n type: 'select',\n help: '留空则使用邮件设置里的全局行距',\n options: [\n { label: '继承全局', value: '' },\n { label: '1.0', value: '1' },\n { label: '1.15', value: '1.15' },\n { label: '1.25', value: '1.25' },\n { label: '1.4', value: '1.4' },\n { label: '1.5', value: '1.5' },\n { label: '1.75', value: '1.75' },\n { label: '2.0', value: '2' },\n { label: '22px', value: '22px' },\n { label: '24px', value: '24px' },\n { label: '28px', value: '28px' },\n { label: '32px', value: '32px' },\n ],\n },\n { key: 'paddingTop', label: '内边距', type: 'spacing' },\n {\n key: 'content',\n label: '内容(HTML,备用)',\n type: 'textarea',\n help: '建议直接在画布双击编辑;这里保留为高级编辑入口。',\n },\n ],\n inlineEditable: {\n selector: '.sm-text-content',\n mode: 'rich',\n multiline: true,\n propKey: 'content',\n placeholder: '输入文本…',\n },\n toMjml: (p) => {\n const padding = `${p.paddingTop}px ${p.paddingRight}px ${p.paddingBottom}px ${p.paddingLeft}px`;\n const ff = p.fontFamily ? ` font-family=\"${escapeAttr(p.fontFamily)}\"` : '';\n const fw = p.fontWeight && p.fontWeight !== 'normal' ? ` font-weight=\"${p.fontWeight}\"` : '';\n const lh = String(p.lineHeight ?? '').trim();\n const lhAttr = lh ? ` line-height=\"${escapeAttr(lh)}\"` : '';\n return `<mj-text align=\"${p.align}\" color=\"${escapeAttr(p.color)}\" font-size=\"${escapeAttr(\n p.fontSize,\n )}\"${lhAttr}${ff}${fw} padding=\"${padding}\">${p.content}</mj-text>`;\n },\n renderPreview: (p) => {\n const ff = p.fontFamily ? `font-family:${p.fontFamily};` : '';\n const fw = p.fontWeight && p.fontWeight !== 'normal' ? `font-weight:${p.fontWeight};` : '';\n const lhRaw = String(p.lineHeight ?? '').trim();\n const lh = lhRaw ? `line-height:${lhRaw};` : 'line-height:normal;';\n return `<div class=\"sm-text-content\" style=\"text-align:${p.align};color:${p.color};font-size:${p.fontSize};${lh}${ff}${fw}padding:${p.paddingTop}px ${p.paddingRight}px ${p.paddingBottom}px ${p.paddingLeft}px;\">${p.content}</div>`;\n },\n});\n","import type { BlockDefinition } from '@simple-mail/core';\nimport { buttonBlock } from './button';\nimport { dividerBlock } from './divider';\nimport { footerBlock } from './footer';\nimport { heroBlock } from './hero';\nimport { htmlBlock } from './html';\nimport { imageBlock } from './image';\nimport { logoBlock } from './logo';\nimport { socialBlock } from './social';\nimport { socialGroupBlock } from './socialGroup';\nimport { spacerBlock } from './spacer';\nimport { textBlock } from './text';\n\nexport {\n buttonBlock,\n dividerBlock,\n footerBlock,\n heroBlock,\n htmlBlock,\n imageBlock,\n logoBlock,\n socialBlock,\n socialGroupBlock,\n spacerBlock,\n textBlock,\n};\n\n/** 内置组件(content 类)。可直接传给 MailEditor.blocks。 */\nexport const builtinBlocks: BlockDefinition<any>[] = [\n textBlock,\n htmlBlock,\n imageBlock,\n socialGroupBlock,\n heroBlock,\n buttonBlock,\n dividerBlock,\n spacerBlock,\n];\n\n/** 业务示例的\"自定义\"组件。可作为参考或直接使用。 */\nexport const exampleCustomBlocks: BlockDefinition<any>[] = [logoBlock, socialBlock, footerBlock];\n\n/** 全部组件(内置 + 示例自定义) */\nexport const allBlocks: BlockDefinition<any>[] = [...builtinBlocks, ...exampleCustomBlocks];\n"],"names":["icons","escapeAttr","s","buttonBlock","defineBlock","p","padding","innerPadding","bw","blockButtonWidthCss","widthAttr","wst","esc","dividerBlock","footerBlock","heroBlock","ctx","w","docContentWidthCss","h","flexAlign","url","htmlBlock","mjRawEmailTableWrap","mjRawCellTypographyFromStyles","imageBlock","href","alt","align","fixedH","sizeStyle","logoBlock","m","mjSocialElementName","network","n","BIZ_SOCIAL_NETWORK_OPTIONS","SOCIAL_NETWORK_OPTIONS","NETWORK_META","escAttr","escMjmlText","socialMeta","paddingQuad","mjSocialElementsLines","links","labelStyle","fontSizeRaw","fontSize","fontWeight","_a","textColor","_b","fwEsc","l","meta","bgColor","attrStr","src","withSrc","label","_c","DEFAULT_BIZ_ELEMENTS","normalizeElements","legacy","socialBlock","pad","els","e","inner","fsRaw","fs","fw","items","bg","iconSrc","iconHtml","textHtml","socialGroupBlock","filtered","spacerBlock","textBlock","ff","lh","lhAttr","lhRaw","builtinBlocks","exampleCustomBlocks","allBlocks"],"mappings":";AACO,MAAMA,IAAQ;AAAA,EACnB,MAAM;AAAA,EACN,MAAM;AAAA,EACN,OAAO;AAAA,EACP,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,aAAa;AACf,GCQMC,IAAa,CAACC,MAClBA,EAAE,QAAQ,MAAM,OAAO,EAAE,QAAQ,MAAM,MAAM,EAAE,QAAQ,MAAM,MAAM,EAAE,QAAQ,MAAM,QAAQ,GAEhFC,IAAcC,EAAyB;AAAA,EAClD,MAAM;AAAA,EACN,MAAM;AAAA,EACN,UAAU;AAAA,EACV,MAAMJ,EAAM;AAAA,EACZ,cAAc;AAAA,IACZ,MAAM;AAAA,IACN,MAAM;AAAA,IACN,iBAAiB;AAAA,IACjB,OAAO;AAAA,IACP,cAAc;AAAA,IACd,OAAO;AAAA,IACP,OAAO;AAAA,IACP,YAAY;AAAA,IACZ,cAAc;AAAA,IACd,eAAe;AAAA,IACf,aAAa;AAAA,IACb,eAAe;AAAA,IACf,eAAe;AAAA,IACf,UAAU;AAAA,EAAA;AAAA,EAEZ,QAAQ;AAAA,IACN,EAAE,KAAK,QAAQ,OAAO,MAAM,MAAM,OAAA;AAAA,IAClC,EAAE,KAAK,QAAQ,OAAO,MAAM,MAAM,MAAA;AAAA,IAClC,EAAE,KAAK,mBAAmB,OAAO,OAAO,MAAM,QAAA;AAAA,IAC9C,EAAE,KAAK,SAAS,OAAO,QAAQ,MAAM,QAAA;AAAA,IACrC,EAAE,KAAK,gBAAgB,OAAO,WAAW,MAAM,UAAU,KAAK,GAAG,KAAK,GAAA;AAAA,IACtE,EAAE,KAAK,YAAY,OAAO,MAAM,MAAM,OAAA;AAAA,IACtC;AAAA,MACE,KAAK;AAAA,MACL,OAAO;AAAA,MACP,MAAM;AAAA,MACN,SAAS;AAAA,QACP,EAAE,OAAO,KAAK,OAAO,OAAA;AAAA,QACrB,EAAE,OAAO,MAAM,OAAO,SAAA;AAAA,QACtB,EAAE,OAAO,KAAK,OAAO,QAAA;AAAA,MAAQ;AAAA,IAC/B;AAAA,IAEF;AAAA,MACE,KAAK;AAAA,MACL,OAAO;AAAA,MACP,MAAM;AAAA,MACN,aAAa;AAAA,MACb,MAAM;AAAA,IAAA;AAAA,IAER,EAAE,KAAK,iBAAiB,OAAO,WAAW,MAAM,UAAU,KAAK,GAAG,KAAK,GAAA;AAAA,IACvE,EAAE,KAAK,iBAAiB,OAAO,WAAW,MAAM,UAAU,KAAK,GAAG,KAAK,GAAA;AAAA,IACvE,EAAE,KAAK,cAAc,OAAO,OAAO,MAAM,UAAA;AAAA,EAAU;AAAA,EAErD,gBAAgB;AAAA,IACd,UAAU;AAAA,IACV,MAAM;AAAA,IACN,WAAW;AAAA,IACX,SAAS;AAAA,IACT,aAAa;AAAA,EAAA;AAAA,EAEf,QAAQ,CAACK,MAAM;AACb,UAAMC,IAAU,GAAGD,EAAE,UAAU,MAAMA,EAAE,YAAY,MAAMA,EAAE,aAAa,MAAMA,EAAE,WAAW,MACrFE,IAAe,GAAGF,EAAE,aAAa,MAAMA,EAAE,aAAa,MACtDG,IAAKC,EAAoBJ,EAAE,KAAK,GAChCK,IAAYF,IAAK,WAAWP,EAAWO,CAAE,CAAC,MAAM;AACtD,WAAO,oBAAoBP,EAAWI,EAAE,IAAI,CAAC,uBAAuBJ;AAAAA,MAClEI,EAAE;AAAA,IAAA,CACH,YAAYJ,EAAWI,EAAE,KAAK,CAAC,oBAAoBA,EAAE,YAAY,kBAAkBJ;AAAAA,MAClFI,EAAE;AAAA,IAAA,CACH,YAAYA,EAAE,KAAK,cAAcC,CAAO,oBAAoBC,CAAY,IAAIG,CAAS,IAAIT;AAAAA,MACxFI,EAAE;AAAA,IAAA,CACH;AAAA,EACH;AAAA,EACA,eAAe,CAACA,MAAM;AACpB,UAAMG,IAAKC,EAAoBJ,EAAE,KAAK,GAChCM,IAAMH,IAAK,SAASA,CAAE,2CAA2C;AAEvE,WAAO,uBAAuBH,EAAE,UAAU,MAAMA,EAAE,YAAY,MAAMA,EAAE,aAAa,MAAMA,EAAE,WAAW,iBAAiBA,EAAE,KAAK;AAAA,iBACjHJ,EAAWI,EAAE,IAAI,CAAC,4CAC3BA,EAAE,eACJ,kBAAkBA,EAAE,YAAY,cAAcA,EAAE,aAAa,MAC3DA,EAAE,aACJ,qCAAqCA,EAAE,QAAQ,oBAAoBM,CAAG,+CACpEN,EAAE,KACJ,KAAKJ,EAAWI,EAAE,IAAI,CAAC;AAAA;AAAA,EAE3B;AACF,CAAC,GChGKO,IAAM,CAACV,MACXA,EAAE,QAAQ,MAAM,OAAO,EAAE,QAAQ,MAAM,MAAM,EAAE,QAAQ,MAAM,MAAM,EAAE,QAAQ,MAAM,QAAQ,GAEhFW,IAAeT,EAA0B;AAAA,EACpD,MAAM;AAAA,EACN,MAAM;AAAA,EACN,UAAU;AAAA,EACV,MAAMJ,EAAM;AAAA,EACZ,cAAc;AAAA,IACZ,OAAO;AAAA,IACP,OAAO;AAAA,IACP,WAAW;AAAA,IACX,YAAY;AAAA,IACZ,eAAe;AAAA,EAAA;AAAA,EAEjB,QAAQ;AAAA,IACN,EAAE,KAAK,SAAS,OAAO,MAAM,MAAM,QAAA;AAAA,IACnC,EAAE,KAAK,SAAS,OAAO,eAAe,MAAM,OAAA;AAAA,IAC5C,EAAE,KAAK,aAAa,OAAO,WAAW,MAAM,UAAU,KAAK,GAAG,KAAK,GAAA;AAAA,IACnE,EAAE,KAAK,cAAc,OAAO,OAAO,MAAM,UAAU,KAAK,GAAG,KAAK,GAAA;AAAA,IAChE,EAAE,KAAK,iBAAiB,OAAO,OAAO,MAAM,UAAU,KAAK,GAAG,KAAK,GAAA;AAAA,EAAG;AAAA,EAExE,QAAQ,CAACK,MACP,6BAA6BO,EAAIP,EAAE,KAAK,CAAC,mBAAmBA,EAAE,SAAS,cAAcO;AAAAA,IACnFP,EAAE;AAAA,EAAA,CACH,cAAcA,EAAE,UAAU,UAAUA,EAAE,aAAa;AAAA,EACtD,eAAe,CAACA,MACd,uBAAuBA,EAAE,UAAU,QAAQA,EAAE,aAAa,iCAAiCA,EAAE,SAAS,YAAYA,EAAE,KAAK,UAAUA,EAAE,KAAK;AAC9I,CAAC,GC5BKO,IAAM,CAACV,MACXA,EAAE,QAAQ,MAAM,OAAO,EAAE,QAAQ,MAAM,MAAM,EAAE,QAAQ,MAAM,MAAM,EAAE,QAAQ,MAAM,QAAQ,GAEhFY,IAAcV,EAAyB;AAAA,EAClD,MAAM;AAAA,EACN,MAAM;AAAA,EACN,UAAU;AAAA,EACV,MAAMJ,EAAM;AAAA,EACZ,cAAc;AAAA,IACZ,aAAa;AAAA,IACb,SAAS;AAAA,IACT,iBAAiB;AAAA,IACjB,iBAAiB;AAAA,IACjB,WAAW;AAAA,EAAA;AAAA,EAEb,QAAQ;AAAA,IACN,EAAE,KAAK,eAAe,OAAO,QAAQ,MAAM,OAAA;AAAA,IAC3C,EAAE,KAAK,WAAW,OAAO,MAAM,MAAM,OAAA;AAAA,IACrC,EAAE,KAAK,mBAAmB,OAAO,QAAQ,MAAM,OAAA;AAAA,IAC/C,EAAE,KAAK,mBAAmB,OAAO,QAAQ,MAAM,MAAA;AAAA,IAC/C,EAAE,KAAK,aAAa,OAAO,QAAQ,MAAM,QAAA;AAAA,EAAQ;AAAA,EAEnD,QAAQ,CAACK,MACA,kCAAkCO,EAAIP,EAAE,SAAS,CAAC;AAAA,IACzDO,EAAIP,EAAE,WAAW,CAAC;AAAA,IAClBO,EAAIP,EAAE,OAAO,CAAC;AAAA,aACLO,EAAIP,EAAE,eAAe,CAAC,kBAAkBO,EAAIP,EAAE,SAAS,CAAC,MAAMO,EAAIP,EAAE,eAAe,CAAC;AAAA;AAAA,EAG/F,eAAe,CAACA,MACP,oFAAoFA,EAAE,SAAS;AAAA,QAClGO,EAAIP,EAAE,WAAW,CAAC;AAAA,QAClBO,EAAIP,EAAE,OAAO,CAAC;AAAA,iBACLO,EAAIP,EAAE,eAAe,CAAC,kBAAkBA,EAAE,SAAS,MAAMO,EAAIP,EAAE,eAAe,CAAC;AAAA;AAGhG,CAAC,GC9BKJ,IAAa,CAACC,MAClBA,EAAE,QAAQ,MAAM,OAAO,EAAE,QAAQ,MAAM,MAAM,EAAE,QAAQ,MAAM,MAAM,EAAE,QAAQ,MAAM,QAAQ,GAEhFa,IAAYX,EAAuB;AAAA,EAC9C,MAAM;AAAA,EACN,MAAM;AAAA,EACN,UAAU;AAAA,EACV,MAAMJ,EAAM;AAAA,EACZ,cAAc;AAAA,IACZ,eACE;AAAA,IACF,iBAAiB;AAAA,IACjB,QAAQ;AAAA,IACR,SACE;AAAA,IACF,WAAW;AAAA,IACX,WAAW;AAAA,IACX,eAAe;AAAA,IACf,YAAY;AAAA,IACZ,cAAc;AAAA,IACd,eAAe;AAAA,IACf,aAAa;AAAA,EAAA;AAAA,EAEf,QAAQ;AAAA,IACN,EAAE,KAAK,iBAAiB,OAAO,OAAO,MAAM,QAAA;AAAA,IAC5C,EAAE,KAAK,mBAAmB,OAAO,SAAS,MAAM,SAAS,MAAM,aAAA;AAAA,IAC/D,EAAE,KAAK,UAAU,OAAO,aAAa,MAAM,UAAU,KAAK,KAAK,KAAK,MAAM,MAAM,EAAA;AAAA,IAChF;AAAA,MACE,KAAK;AAAA,MACL,OAAO;AAAA,MACP,MAAM;AAAA,MACN,SAAS;AAAA,QACP,EAAE,OAAO,MAAM,OAAO,MAAA;AAAA,QACtB,EAAE,OAAO,MAAM,OAAO,SAAA;AAAA,QACtB,EAAE,OAAO,MAAM,OAAO,SAAA;AAAA,MAAS;AAAA,IACjC;AAAA,IAEF;AAAA,MACE,KAAK;AAAA,MACL,OAAO;AAAA,MACP,MAAM;AAAA,MACN,SAAS;AAAA,QACP,EAAE,OAAO,KAAK,OAAO,OAAA;AAAA,QACrB,EAAE,OAAO,MAAM,OAAO,SAAA;AAAA,QACtB,EAAE,OAAO,KAAK,OAAO,QAAA;AAAA,MAAQ;AAAA,IAC/B;AAAA,IAEF,EAAE,KAAK,aAAa,OAAO,QAAQ,MAAM,QAAA;AAAA,IACzC,EAAE,KAAK,cAAc,OAAO,OAAO,MAAM,UAAA;AAAA,IACzC;AAAA,MACE,KAAK;AAAA,MACL,OAAO;AAAA,MACP,MAAM;AAAA,MACN,MAAM;AAAA,IAAA;AAAA,EACR;AAAA,EAEF,gBAAgB;AAAA,IACd,UAAU;AAAA,IACV,MAAM;AAAA,IACN,WAAW;AAAA,IACX,SAAS;AAAA,IACT,aAAa;AAAA,EAAA;AAAA,EAEf,QAAQ,CAACK,GAAGW,MAAQ;AAClB,UAAMC,IAAIC,EAAmBF,EAAI,IAAI,KAAK,KAAK,GACzCV,IAAU,GAAGD,EAAE,UAAU,MAAMA,EAAE,YAAY,MAAMA,EAAE,aAAa,MAAMA,EAAE,WAAW,MACrFc,IAAI,GAAGd,EAAE,MAAM;AACrB,WAAO;AAAA;AAAA,gBAEKc,CAAC;AAAA,0BACSF,CAAC;AAAA,2BACAE,CAAC;AAAA,wBACJlB,EAAWI,EAAE,aAAa,CAAC;AAAA,0BACzBJ,EAAWI,EAAE,eAAe,CAAC;AAAA,iBACtCC,CAAO;AAAA,wBACAD,EAAE,aAAa;AAAA;AAAA;AAAA,iBAGtBA,EAAE,SAAS;AAAA,iBACXJ,EAAWI,EAAE,SAAS,CAAC;AAAA;AAAA,SAE/BA,EAAE,OAAO;AAAA;AAAA,EAEhB;AAAA,EACA,eAAe,CAACA,GAAGW,MAAQ;AACzB,UAAMC,IAAIC,EAAmBF,EAAI,IAAI,KAAK,KAAK,GACzCI,IACJf,EAAE,kBAAkB,QAAQ,eAAeA,EAAE,kBAAkB,WAAW,aAAa,UACnFC,IAAU,GAAGD,EAAE,UAAU,MAAMA,EAAE,YAAY,MAAMA,EAAE,aAAa,MAAMA,EAAE,WAAW,MACrFgB,IAAMpB,EAAWI,EAAE,aAAa;AACtC,WAAO;AAAA;AAAA;AAAA;AAAA,oBAISY,CAAC;AAAA,qBACAZ,EAAE,MAAM;AAAA;AAAA,4FAE+DgB,CAAG;AAAA;AAAA;AAAA,2BAGpEhB,EAAE,eAAe;AAAA;AAAA,sBAEtBe,CAAS;AAAA,0BACLf,EAAE,cAAc,UAAU,aAAaA,EAAE,cAAc,WAAW,WAAW,YAAY;AAAA,kBACjGC,CAAO;AAAA,gBACTL,EAAWI,EAAE,SAAS,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,uBAShBA,EAAE,SAAS;AAAA,kBAChBJ,EAAWI,EAAE,SAAS,CAAC;AAAA;AAAA;AAAA,SAGhCA,EAAE,OAAO;AAAA;AAAA,EAEhB;AACF,CAAC,GC/HYiB,IAAYlB,EAA4B;AAAA,EACnD,MAAM;AAAA,EACN,MAAM;AAAA,EACN,UAAU;AAAA,EACV,MAAMJ,EAAM;AAAA,EACZ,cAAc;AAAA,IACZ,MAAM;AAAA,IACN,YAAY;AAAA,IACZ,cAAc;AAAA,IACd,eAAe;AAAA,IACf,aAAa;AAAA,EAAA;AAAA,EAEf,QAAQ;AAAA,IACN;AAAA,MACE,KAAK;AAAA,MACL,OAAO;AAAA,MACP,MAAM;AAAA,MACN,MAAM;AAAA,IAAA;AAAA,IAER,EAAE,KAAK,cAAc,OAAO,OAAO,MAAM,UAAA;AAAA,EAAU;AAAA,EAErD,gBAAgB;AAAA,IACd,UAAU;AAAA,IACV,MAAM;AAAA,IACN,WAAW;AAAA,IACX,SAAS;AAAA,IACT,aAAa;AAAA,EAAA;AAAA,EAEf,QAAQ,CAACK,GAAGW,MAAQ;AAClB,UAAMV,IAAU,GAAGD,EAAE,UAAU,MAAMA,EAAE,YAAY,MAAMA,EAAE,aAAa,MAAMA,EAAE,WAAW;AAC3F,WAAOkB,EAAoBjB,GAASD,EAAE,MAAMmB,EAA8BR,EAAI,IAAI,MAAM,CAAC;AAAA,EAC3F;AAAA,EACA,eAAe,CAACX,MAEP,+CADK,GAAGA,EAAE,UAAU,MAAMA,EAAE,YAAY,MAAMA,EAAE,aAAa,MAAMA,EAAE,WAAW,IAC9B,qBAAqBA,EAAE,IAAI;AAExF,CAAC,GC9BKJ,IAAa,CAACC,MAClBA,EAAE,QAAQ,MAAM,OAAO,EAAE,QAAQ,MAAM,MAAM,EAAE,QAAQ,MAAM,MAAM,EAAE,QAAQ,MAAM,QAAQ,GAEhFuB,IAAarB,EAAwB;AAAA,EAChD,MAAM;AAAA,EACN,MAAM;AAAA,EACN,UAAU;AAAA,EACV,MAAMJ,EAAM;AAAA,EACZ,cAAc;AAAA,IACZ,KAAK;AAAA,IACL,KAAK;AAAA,IACL,MAAM;AAAA,IACN,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,YAAY;AAAA,IACZ,cAAc;AAAA,IACd,eAAe;AAAA,IACf,aAAa;AAAA,EAAA;AAAA,EAEf,QAAQ;AAAA,IACN,EAAE,KAAK,OAAO,OAAO,QAAQ,MAAM,QAAA;AAAA,IACnC,EAAE,KAAK,OAAO,OAAO,QAAQ,MAAM,QAAQ,aAAa,OAAA;AAAA,IACxD,EAAE,KAAK,QAAQ,OAAO,QAAQ,MAAM,OAAO,aAAa,cAAA;AAAA,IACxD,EAAE,KAAK,SAAS,OAAO,WAAW,MAAM,UAAU,KAAK,IAAI,KAAK,IAAA;AAAA,IAChE;AAAA,MACE,KAAK;AAAA,MACL,OAAO;AAAA,MACP,MAAM;AAAA,MACN,KAAK;AAAA,MACL,KAAK;AAAA,MACL,MAAM;AAAA,IAAA;AAAA,IAER;AAAA,MACE,KAAK;AAAA,MACL,OAAO;AAAA,MACP,MAAM;AAAA,MACN,SAAS;AAAA,QACP,EAAE,OAAO,KAAK,OAAO,OAAA;AAAA,QACrB,EAAE,OAAO,MAAM,OAAO,SAAA;AAAA,QACtB,EAAE,OAAO,KAAK,OAAO,QAAA;AAAA,MAAQ;AAAA,IAC/B;AAAA,IAEF,EAAE,KAAK,cAAc,OAAO,OAAO,MAAM,UAAA;AAAA,EAAU;AAAA,EAErD,QAAQ,CAACK,MAAM;AACb,UAAMC,IAAU,GAAGD,EAAE,UAAU,MAAMA,EAAE,YAAY,MAAMA,EAAE,aAAa,MAAMA,EAAE,WAAW,MACrFqB,IAAOrB,EAAE,OAAO,UAAUJ,EAAWI,EAAE,IAAI,CAAC,MAAM,IAClDsB,IAAM,SAAS1B,EAAWI,EAAE,OAAO,EAAE,CAAC,KACtCc,IAAId,EAAE,UAAU,QAAQA,EAAE,SAAS,IAAI,YAAYA,EAAE,MAAM,QAAQ;AACzE,WAAO,kBAAkBJ,EAAWI,EAAE,GAAG,CAAC,IAAIsB,CAAG,GAAGD,CAAI,WAAWrB,EAAE,KAAK,MAAMc,CAAC,WAAWd,EAAE,KAAK,cAAcC,CAAO;AAAA,EAC1H;AAAA,EACA,eAAe,CAACD,MAAM;AACpB,UAAMuB,IAAQvB,EAAE,UAAU,WAAW,mBAAmBA,EAAE,UAAU,UAAU,sBAAsB,IAC9FwB,IAASxB,EAAE,UAAU,QAAQA,EAAE,SAAS,IAAIA,EAAE,SAAS,GACvDyB,IACJD,IAAS,IACL,SAASxB,EAAE,KAAK,aAAawB,CAAM,gDACnC,SAASxB,EAAE,KAAK;AACtB,WAAO,uBAAuBA,EAAE,UAAU,MAAMA,EAAE,YAAY,MAAMA,EAAE,aAAa,MAAMA,EAAE,WAAW,iBAAiBA,EAAE,KAAK,gBAAgBJ;AAAAA,MAC5II,EAAE;AAAA,IAAA,CACH,UAAUJ,EAAWI,EAAE,GAAG,CAAC,0BAA0BuB,CAAK,kBAAkBE,CAAS;AAAA,EACxF;AACF,CAAC,GCrEKlB,IAAM,CAACV,MACXA,EAAE,QAAQ,MAAM,OAAO,EAAE,QAAQ,MAAM,MAAM,EAAE,QAAQ,MAAM,MAAM,EAAE,QAAQ,MAAM,QAAQ,GAEhF6B,IAAY3B,EAAuB;AAAA,EAC9C,MAAM;AAAA,EACN,MAAM;AAAA,EACN,UAAU;AAAA,EACV,MAAMJ,EAAM;AAAA,EACZ,cAAc;AAAA,IACZ,KAAK;AAAA,IACL,MAAM;AAAA,IACN,OAAO;AAAA,IACP,OAAO;AAAA,EAAA;AAAA,EAET,QAAQ;AAAA,IACN,EAAE,KAAK,OAAO,OAAO,WAAW,MAAM,QAAA;AAAA,IACtC,EAAE,KAAK,QAAQ,OAAO,QAAQ,MAAM,MAAA;AAAA,IACpC,EAAE,KAAK,SAAS,OAAO,WAAW,MAAM,UAAU,KAAK,IAAI,KAAK,IAAA;AAAA,IAChE;AAAA,MACE,KAAK;AAAA,MACL,OAAO;AAAA,MACP,MAAM;AAAA,MACN,SAAS;AAAA,QACP,EAAE,OAAO,KAAK,OAAO,OAAA;AAAA,QACrB,EAAE,OAAO,MAAM,OAAO,SAAA;AAAA,QACtB,EAAE,OAAO,KAAK,OAAO,QAAA;AAAA,MAAQ;AAAA,IAC/B;AAAA,EACF;AAAA,EAEF,QAAQ,CAACK,MACP,kBAAkBO,EAAIP,EAAE,GAAG,CAAC,WAAWO,EAAIP,EAAE,IAAI,CAAC,YAAYA,EAAE,KAAK,cAAcA,EAAE,KAAK;AAAA,EAC5F,eAAe,CAACA,MAAM;AACpB,UAAM2B,IACJ3B,EAAE,UAAU,WAAW,mBAAmBA,EAAE,UAAU,UAAU,sBAAsB;AACxF,WAAO,wCAAwCA,EAAE,KAAK,gBAAgBO;AAAA,MACpEP,EAAE;AAAA,IAAA,CACH,qCAAqC2B,CAAC,SAAS3B,EAAE,KAAK;AAAA,EACzD;AACF,CAAC;AChDM,SAAS4B,EAAoBC,GAAyB;AAC3D,QAAMC,IAAID,EAAQ,KAAA;AAClB,SAAIC,MAAM,OAAa,cACnBA,MAAM,YAAYA,MAAM,WAAiB,QACtCA;AACT;AAGO,MAAMC,IAAiE;AAAA,EAC5E,EAAE,OAAO,KAAK,OAAO,IAAA;AAAA,EACrB,EAAE,OAAO,UAAU,OAAO,SAAA;AAAA,EAC1B,EAAE,OAAO,YAAY,OAAO,WAAA;AAAA,EAC5B,EAAE,OAAO,UAAU,OAAO,SAAA;AAAA,EAC1B,EAAE,OAAO,aAAa,OAAO,KAAA;AAC/B,GAGaC,IAA6D;AAAA,EACxE,EAAE,OAAO,MAAM,OAAO,SAAA;AAAA,EACtB,EAAE,OAAO,MAAM,OAAO,QAAA;AAAA,EACtB,EAAE,OAAO,KAAK,OAAO,IAAA;AAAA,EACrB,EAAE,OAAO,YAAY,OAAO,WAAA;AAAA,EAC5B,EAAE,OAAO,UAAU,OAAO,SAAA;AAAA,EAC1B,EAAE,OAAO,YAAY,OAAO,WAAA;AAAA,EAC5B,EAAE,OAAO,aAAa,OAAO,YAAA;AAAA,EAC7B,EAAE,OAAO,WAAW,OAAO,UAAA;AAAA,EAC3B,EAAE,OAAO,MAAM,OAAO,MAAA;AACxB,GAEMC,IAAmE;AAAA,EACvE,QAAQ,EAAE,OAAO,WAAW,SAAS,IAAA;AAAA,EACrC,OAAO,EAAE,OAAO,WAAW,SAAS,IAAA;AAAA,EACpC,GAAG,EAAE,OAAO,WAAW,SAAS,IAAA;AAAA,EAChC,UAAU,EAAE,OAAO,WAAW,SAAS,KAAA;AAAA,EACvC,QAAQ,EAAE,OAAO,WAAW,SAAS,KAAA;AAAA,EACrC,UAAU,EAAE,OAAO,WAAW,SAAS,IAAA;AAAA,EACvC,WAAW,EAAE,OAAO,WAAW,SAAS,IAAA;AAAA,EACxC,IAAI,EAAE,OAAO,WAAW,SAAS,IAAA;AAAA,EACjC,SAAS,EAAE,OAAO,WAAW,SAAS,IAAA;AAAA,EACtC,QAAQ,EAAE,OAAO,WAAW,SAAS,IAAA;AAAA,EACrC,QAAQ,EAAE,OAAO,WAAW,SAAS,IAAA;AAAA,EACrC,SAAS,EAAE,OAAO,WAAW,SAAS,IAAA;AAAA,EACtC,KAAK,EAAE,OAAO,WAAW,SAAS,IAAA;AACpC,GAEaC,IAAU,CAACrC,MACtBA,EAAE,QAAQ,MAAM,OAAO,EAAE,QAAQ,MAAM,MAAM,EAAE,QAAQ,MAAM,MAAM,EAAE,QAAQ,MAAM,QAAQ,GAGhFsC,IAAc,CAACtC,MAC1BA,EAAE,QAAQ,MAAM,OAAO,EAAE,QAAQ,MAAM,MAAM,EAAE,QAAQ,MAAM,MAAM;AAoB9D,SAASuC,EAAWP,GAAqD;AAC9E,SAAOI,EAAaJ,CAAO,KAAK,EAAE,OAAO,WAAW,SAAS,IAAA;AAC/D;AAEO,SAASQ,EAAYrC,GAKjB;AACT,SAAO,GAAGA,EAAE,UAAU,MAAMA,EAAE,YAAY,MAAMA,EAAE,aAAa,MAAMA,EAAE,WAAW;AACpF;AAEO,SAASsC,EACdC,GACAC,GACQ;;AACR,QAAMC,IAAcD,EAAW,gBAAgB,IAAIA,EAAW,gBAAgB,IACxEE,IAAW,KAAK,IAAI,GAAG,KAAK,IAAI,IAAID,CAAW,CAAC,GAChDE,MAAaC,IAAAJ,EAAW,oBAAX,gBAAAI,EAA4B,WAAU,UACnDC,MAAYC,IAAAN,EAAW,eAAX,gBAAAM,EAAuB,WAAU,WAC7CC,IAAQb,EAAQS,CAAU;AAChC,SAAOJ,EACJ,IAAI,CAACS,MAAM;;AACV,UAAMC,IAAOb,EAAWY,EAAE,OAAO,GAC3BE,MAAUN,IAAAI,EAAE,oBAAF,gBAAAJ,EAAmB,WAAUK,EAAK,OAS5CE,IARQ;AAAA,MACZ,SAASjB,EAAQN,EAAoBoB,EAAE,OAAO,CAAC,CAAC;AAAA,MAChD,SAASd,EAAQc,EAAE,IAAI,CAAC;AAAA,MACxB,qBAAqBd,EAAQgB,CAAO,CAAC;AAAA,MACrC,UAAUhB,EAAQW,CAAS,CAAC;AAAA,MAC5B,cAAcH,CAAQ;AAAA,MACtB,gBAAgBK,CAAK;AAAA,IAAA,EAED,KAAK,GAAG,GACxBK,KAAMN,IAAAE,EAAE,YAAF,gBAAAF,EAAW,QACjBO,IAAUD,IAAM,GAAGD,CAAO,SAASjB,EAAQkB,CAAG,CAAC,MAAMD,GACrDG,MAAQC,IAAAP,EAAE,UAAF,gBAAAO,EAAS,WAAU;AACjC,WAAKD,IAGE,wBAAwBD,CAAO;AAAA,MAAUlB,EAAYmB,CAAK,CAAC;AAAA,0BAFzD,wBAAwBD,CAAO;AAAA,EAG1C,CAAC,EACA,KAAK;AAAA,CAAI;AACd;ACxFA,MAAMG,IAAyC;AAAA,EAC7C,EAAE,SAAS,KAAK,MAAM,iBAAA;AAAA,EACtB,EAAE,SAAS,UAAU,MAAM,sBAAA;AAAA,EAC3B,EAAE,SAAS,YAAY,MAAM,wBAAA;AAAA,EAC7B,EAAE,SAAS,UAAU,MAAM,0BAAA;AAAA,EAC3B,EAAE,SAAS,MAAM,MAAM,yBAAA;AACzB;AAEA,SAASC,EAAkBzD,GAAqC;;AAC9D,OAAI4C,IAAA5C,EAAE,aAAF,QAAA4C,EAAY,OAAQ,QAAO5C,EAAE;AACjC,QAAM0D,IAAS1D,EAAE;AACjB,SAAI,MAAM,QAAQ0D,CAAM,KAAKA,EAAO,SAC3BA,EAAO,IAAI,CAACV,OAAO;AAAA,IACxB,SAAS,OAAOA,EAAE,WAAW,KAAK;AAAA,IAClC,MAAM,OAAOA,EAAE,QAAQ,EAAE;AAAA,EAAA,EACzB,IACGQ;AACT;AAEO,MAAMG,IAAc5D,EAA4B;AAAA,EACrD,MAAM;AAAA,EACN,MAAM;AAAA,EACN,UAAU;AAAA,EACV,MAAMJ,EAAM;AAAA,EACZ,cAAc;AAAA,IACZ,UAAU6D;AAAA,IACV,OAAO;AAAA,IACP,UAAU;AAAA,IACV,eAAe;AAAA,IACf,iBAAiB;AAAA,IACjB,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ,cAAc;AAAA,IACd,eAAe;AAAA,IACf,aAAa;AAAA,EAAA;AAAA,EAEf,QAAQ;AAAA,IACN;AAAA,MACE,KAAK;AAAA,MACL,OAAO;AAAA,MACP,MAAM;AAAA,MACN,SAASzB;AAAA,MACT,MAAM;AAAA,IAAA;AAAA,IAER;AAAA,MACE,KAAK;AAAA,MACL,OAAO;AAAA,MACP,MAAM;AAAA,MACN,KAAK;AAAA,MACL,KAAK;AAAA,MACL,MAAM;AAAA,IAAA;AAAA,IAER;AAAA,MACE,KAAK;AAAA,MACL,OAAO;AAAA,MACP,MAAM;AAAA,MACN,SAAS;AAAA,QACP,EAAE,OAAO,YAAY,OAAO,MAAA;AAAA,QAC5B,EAAE,OAAO,MAAM,OAAO,SAAA;AAAA,QACtB,EAAE,OAAO,OAAO,OAAO,MAAA;AAAA,QACvB,EAAE,OAAO,OAAO,OAAO,MAAA;AAAA,QACvB,EAAE,OAAO,OAAO,OAAO,MAAA;AAAA,QACvB,EAAE,OAAO,OAAO,OAAO,MAAA;AAAA,QACvB,EAAE,OAAO,MAAM,OAAO,OAAA;AAAA,QACtB,EAAE,OAAO,YAAY,OAAO,MAAA;AAAA,MAAM;AAAA,IACpC;AAAA,IAEF,EAAE,KAAK,cAAc,OAAO,QAAQ,MAAM,QAAA;AAAA,IAC1C;AAAA,MACE,KAAK;AAAA,MACL,OAAO;AAAA,MACP,MAAM;AAAA,MACN,SAAS;AAAA,QACP,EAAE,OAAO,KAAK,OAAO,OAAA;AAAA,QACrB,EAAE,OAAO,MAAM,OAAO,SAAA;AAAA,QACtB,EAAE,OAAO,KAAK,OAAO,QAAA;AAAA,MAAQ;AAAA,IAC/B;AAAA,IAEF,EAAE,KAAK,YAAY,OAAO,aAAa,MAAM,UAAU,KAAK,IAAI,KAAK,GAAA;AAAA,IACrE,EAAE,KAAK,cAAc,OAAO,OAAO,MAAM,UAAA;AAAA,EAAU;AAAA,EAErD,QAAQ,CAAC/B,MAAM;AACb,UAAM4D,IAAMvB,EAAYrC,CAAC,GACnB6D,IAAMJ,EAAkBzD,CAAC,EAAE,OAAO,CAAC8D;;AAAM,cAAAlB,IAAAkB,EAAE,SAAF,gBAAAlB,EAAQ;AAAA,KAAM,GACvDJ,IAAa;AAAA,MACjB,eAAe,OAAOxC,EAAE,iBAAiB,EAAE;AAAA,MAC3C,iBAAiB,OAAOA,EAAE,mBAAmB,QAAQ;AAAA,MACrD,YAAY,OAAOA,EAAE,cAAc,SAAS;AAAA,IAAA,GAExC+D,IAAQzB,EAAsBuB,GAAKrB,CAAU;AACnD,WAAKuB,EAAM,SAGJ,qBAAqB/D,EAAE,KAAK,gBAAgBA,EAAE,QAAQ,kCAAkC4D,CAAG;AAAA,EACpGG,CAAK;AAAA,gBAHM,qBAAqB/D,EAAE,KAAK,gBAAgBA,EAAE,QAAQ,kCAAkC4D,CAAG;AAAA,EAKtG;AAAA,EACA,eAAe,CAAC5D,MAAM;;AACpB,UAAMgE,IAAQhE,EAAE,iBAAiB,QAAQA,EAAE,gBAAgB,IAAIA,EAAE,gBAAgB,IAC3EiE,IAAK,KAAK,IAAI,GAAG,KAAK,IAAI,IAAID,CAAK,CAAC,GACpCE,MAAKtB,IAAA5C,EAAE,oBAAF,gBAAA4C,EAAmB,WAAU,UAClCC,MAAYC,IAAA9C,EAAE,eAAF,gBAAA8C,EAAc,WAAU,WACpCqB,IAAQV,EAAkBzD,CAAC,EAC9B,OAAO,CAACgD;;AAAM,cAAAJ,IAAAI,EAAE,SAAF,gBAAAJ,EAAQ;AAAA,KAAM,EAC5B,IAAI,CAACI,MAAM;;AACV,YAAMC,IAAOb,EAAWY,EAAE,OAAO,GAC3BoB,MAAKxB,IAAAI,EAAE,oBAAF,gBAAAJ,EAAmB,WAAUK,EAAK,OACvCK,MAAQR,IAAAE,EAAE,UAAF,gBAAAF,EAAS,WAAU,IAC3BuB,KAAUd,IAAAP,EAAE,YAAF,gBAAAO,EAAW,QACrBe,IAAWD,IACb,aAAanC,EAAQmC,CAAO,CAAC,yBAAyBrE,EAAE,QAAQ,aAAaA,EAAE,QAAQ,+DACvF,0CAA0CA,EAAE,QAAQ,aAAaA,EAAE,QAAQ,mCAAmCoE,CAAE,mEAAmE,KAAK;AAAA,QACtLpE,EAAE,WAAW;AAAA,MAAA,CACd,sCAAsCiD,EAAK,OAAO,WACjDsB,IAAWjB,IACb,0CAA0CW,CAAE,6BAA6BC,CAAE,UAAUhC;AAAA,QACnFW;AAAA,MAAA,CACD,iCAAiCX,EAAQoB,CAAK,CAAC,YAChD;AACJ,aAAO,qGAAqGpB;AAAA,QAC1Gc,EAAE;AAAA,MAAA,CACH,wFAAwFsB,CAAQ,OAAOC,CAAQ;AAAA,IAClH,CAAC,EACA,KAAK,EAAE;AAEV,WAAO,uBADKlC,EAAYrC,CAAC,CACQ,eAAeA,EAAE,KAAK,MAAMmE,KAAS,8DAA8D;AAAA,EACtI;AACF,CAAC,GCjIYK,IAAmBzE,EAA8B;AAAA,EAC5D,MAAM;AAAA,EACN,MAAM;AAAA,EACN,UAAU;AAAA,EACV,MAAMJ,EAAM;AAAA,EACZ,cAAc;AAAA,IACZ,UAAU;AAAA,MACR,EAAE,SAAS,SAAS,MAAM,oBAAA;AAAA,MAC1B,EAAE,SAAS,UAAU,MAAM,sBAAA;AAAA,IAAsB;AAAA,IAEnD,OAAO;AAAA,IACP,UAAU;AAAA,IACV,eAAe;AAAA,IACf,iBAAiB;AAAA,IACjB,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ,cAAc;AAAA,IACd,eAAe;AAAA,IACf,aAAa;AAAA,EAAA;AAAA,EAEf,QAAQ;AAAA,IACN;AAAA,MACE,KAAK;AAAA,MACL,OAAO;AAAA,MACP,MAAM;AAAA,MACN,SAASqC;AAAA,MACT,MAAM;AAAA,IAAA;AAAA,IAER;AAAA,MACE,KAAK;AAAA,MACL,OAAO;AAAA,MACP,MAAM;AAAA,MACN,KAAK;AAAA,MACL,KAAK;AAAA,MACL,MAAM;AAAA,IAAA;AAAA,IAER;AAAA,MACE,KAAK;AAAA,MACL,OAAO;AAAA,MACP,MAAM;AAAA,MACN,SAAS;AAAA,QACP,EAAE,OAAO,YAAY,OAAO,MAAA;AAAA,QAC5B,EAAE,OAAO,MAAM,OAAO,SAAA;AAAA,QACtB,EAAE,OAAO,OAAO,OAAO,MAAA;AAAA,QACvB,EAAE,OAAO,OAAO,OAAO,MAAA;AAAA,QACvB,EAAE,OAAO,OAAO,OAAO,MAAA;AAAA,QACvB,EAAE,OAAO,OAAO,OAAO,MAAA;AAAA,QACvB,EAAE,OAAO,MAAM,OAAO,OAAA;AAAA,QACtB,EAAE,OAAO,YAAY,OAAO,MAAA;AAAA,MAAM;AAAA,IACpC;AAAA,IAEF,EAAE,KAAK,cAAc,OAAO,QAAQ,MAAM,QAAA;AAAA,IAC1C;AAAA,MACE,KAAK;AAAA,MACL,OAAO;AAAA,MACP,MAAM;AAAA,MACN,SAAS;AAAA,QACP,EAAE,OAAO,KAAK,OAAO,OAAA;AAAA,QACrB,EAAE,OAAO,MAAM,OAAO,SAAA;AAAA,QACtB,EAAE,OAAO,KAAK,OAAO,QAAA;AAAA,MAAQ;AAAA,IAC/B;AAAA,IAEF,EAAE,KAAK,YAAY,OAAO,aAAa,MAAM,UAAU,KAAK,IAAI,KAAK,GAAA;AAAA,IACrE,EAAE,KAAK,cAAc,OAAO,OAAO,MAAM,UAAA;AAAA,EAAU;AAAA,EAErD,QAAQ,CAAChC,MAAM;AACb,UAAM4D,IAAMvB,EAAYrC,CAAC,GACnByE,IAAWzE,EAAE,SAAS,OAAO,CAAC8D;;AAAM,cAAAlB,IAAAkB,EAAE,SAAF,gBAAAlB,EAAQ;AAAA,KAAM,GAClDJ,IAAa;AAAA,MACjB,eAAe,OAAOxC,EAAE,iBAAiB,EAAE;AAAA,MAC3C,iBAAiB,OAAOA,EAAE,mBAAmB,QAAQ;AAAA,MACrD,YAAY,OAAOA,EAAE,cAAc,SAAS;AAAA,IAAA,GAExC+D,IAAQzB,EAAsBmC,GAAUjC,CAAU;AACxD,WAAKuB,EAAM,SAGJ,qBAAqB/D,EAAE,KAAK,gBAAgBA,EAAE,QAAQ,kCAAkC4D,CAAG;AAAA,EACpGG,CAAK;AAAA,gBAHM,qBAAqB/D,EAAE,KAAK,gBAAgBA,EAAE,QAAQ,kCAAkC4D,CAAG;AAAA,EAKtG;AAAA,EACA,eAAe,CAAC5D,MAAM;;AACpB,UAAMgE,IAAQhE,EAAE,iBAAiB,QAAQA,EAAE,gBAAgB,IAAIA,EAAE,gBAAgB,IAC3EiE,IAAK,KAAK,IAAI,GAAG,KAAK,IAAI,IAAID,CAAK,CAAC,GACpCE,MAAKtB,IAAA5C,EAAE,oBAAF,gBAAA4C,EAAmB,WAAU,UAClCC,MAAYC,IAAA9C,EAAE,eAAF,gBAAA8C,EAAc,WAAU,WACpCqB,IAAQnE,EAAE,SACb,OAAO,CAACgD,MAAA;;AAAM,cAAAJ,IAAAI,EAAE,SAAF,gBAAAJ,EAAQ;AAAA,KAAM,EAC5B,IAAI,CAACI,MAAM;;AACV,YAAMC,IAAOb,EAAWY,EAAE,OAAO,GAC3BoB,MAAKxB,IAAAI,EAAE,oBAAF,gBAAAJ,EAAmB,WAAUK,EAAK,OACvCK,MAAQR,IAAAE,EAAE,UAAF,gBAAAF,EAAS,WAAU,IAC3BuB,KAAUd,IAAAP,EAAE,YAAF,gBAAAO,EAAW,QACrBe,IAAWD,IACb,aAAanC,EAAQmC,CAAO,CAAC,yBAAyBrE,EAAE,QAAQ,aAAaA,EAAE,QAAQ,+DACvF,0CAA0CA,EAAE,QAAQ,aAAaA,EAAE,QAAQ,mCAAmCoE,CAAE,mEAAmE,KAAK;AAAA,QACtLpE,EAAE,WAAW;AAAA,MAAA,CACd,sCAAsCiD,EAAK,OAAO,WACjDsB,IAAWjB,IACb,0CAA0CW,CAAE,6BAA6BC,CAAE,UAAUhC;AAAA,QACnFW;AAAA,MAAA,CACD,iCAAiCX,EAAQoB,CAAK,CAAC,YAChD;AACJ,aAAO,qGAAqGpB;AAAA,QAC1Gc,EAAE;AAAA,MAAA,CACH,wFAAwFsB,CAAQ,OAAOC,CAAQ;AAAA,IAClH,CAAC,EACA,KAAK,EAAE;AAEV,WAAO,uBADKlC,EAAYrC,CAAC,CACQ,eAAeA,EAAE,KAAK,MAAMmE,KAAS,4DAA4D;AAAA,EACpI;AACF,CAAC,GCjIYO,IAAc3E,EAAyB;AAAA,EAClD,MAAM;AAAA,EACN,MAAM;AAAA,EACN,UAAU;AAAA,EACV,MAAMJ,EAAM;AAAA,EACZ,cAAc,EAAE,QAAQ,GAAA;AAAA,EACxB,QAAQ,CAAC,EAAE,KAAK,UAAU,OAAO,WAAW,MAAM,UAAU,KAAK,GAAG,KAAK,KAAK;AAAA,EAC9E,QAAQ,CAACK,MAAM,sBAAsBA,EAAE,MAAM;AAAA,EAC7C,eAAe,CAACA,MAAM,sBAAsBA,EAAE,MAAM,kBAAkBA,EAAE,MAAM;AAChF,CAAC,GCEKJ,IAAa,CAACC,MAClBA,EAAE,QAAQ,MAAM,OAAO,EAAE,QAAQ,MAAM,MAAM,EAAE,QAAQ,MAAM,MAAM,EAAE,QAAQ,MAAM,QAAQ,GAEhF8E,KAAY5E,EAAuB;AAAA,EAC9C,MAAM;AAAA,EACN,MAAM;AAAA,EACN,UAAU;AAAA,EACV,MAAMJ,EAAM;AAAA,EACZ,cAAc;AAAA,IACZ,SACE;AAAA,IACF,OAAO;AAAA,IACP,OAAO;AAAA,IACP,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ,cAAc;AAAA,IACd,eAAe;AAAA,IACf,aAAa;AAAA,EAAA;AAAA,EAEf,QAAQ;AAAA,IACN;AAAA,MACE,KAAK;AAAA,MACL,OAAO;AAAA,MACP,MAAM;AAAA,MACN,SAAS;AAAA,QACP,EAAE,OAAO,KAAK,OAAO,OAAA;AAAA,QACrB,EAAE,OAAO,MAAM,OAAO,SAAA;AAAA,QACtB,EAAE,OAAO,KAAK,OAAO,QAAA;AAAA,MAAQ;AAAA,IAC/B;AAAA,IAEF,EAAE,KAAK,SAAS,OAAO,QAAQ,MAAM,QAAA;AAAA,IACrC,EAAE,KAAK,YAAY,OAAO,QAAQ,MAAM,QAAQ,aAAa,OAAA;AAAA,IAC7D,EAAE,KAAK,cAAc,OAAO,MAAM,MAAM,QAAQ,aAAa,OAAA;AAAA,IAC7D;AAAA,MACE,KAAK;AAAA,MACL,OAAO;AAAA,MACP,MAAM;AAAA,MACN,SAAS;AAAA,QACP,EAAE,OAAO,UAAU,OAAO,SAAA;AAAA,QAC1B,EAAE,OAAO,UAAU,OAAO,MAAA;AAAA,QAC1B,EAAE,OAAO,UAAU,OAAO,MAAA;AAAA,QAC1B,EAAE,OAAO,UAAU,OAAO,OAAA;AAAA,MAAO;AAAA,IACnC;AAAA,IAEF;AAAA,MACE,KAAK;AAAA,MACL,OAAO;AAAA,MACP,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS;AAAA,QACP,EAAE,OAAO,QAAQ,OAAO,GAAA;AAAA,QACxB,EAAE,OAAO,OAAO,OAAO,IAAA;AAAA,QACvB,EAAE,OAAO,QAAQ,OAAO,OAAA;AAAA,QACxB,EAAE,OAAO,QAAQ,OAAO,OAAA;AAAA,QACxB,EAAE,OAAO,OAAO,OAAO,MAAA;AAAA,QACvB,EAAE,OAAO,OAAO,OAAO,MAAA;AAAA,QACvB,EAAE,OAAO,QAAQ,OAAO,OAAA;AAAA,QACxB,EAAE,OAAO,OAAO,OAAO,IAAA;AAAA,QACvB,EAAE,OAAO,QAAQ,OAAO,OAAA;AAAA,QACxB,EAAE,OAAO,QAAQ,OAAO,OAAA;AAAA,QACxB,EAAE,OAAO,QAAQ,OAAO,OAAA;AAAA,QACxB,EAAE,OAAO,QAAQ,OAAO,OAAA;AAAA,MAAO;AAAA,IACjC;AAAA,IAEF,EAAE,KAAK,cAAc,OAAO,OAAO,MAAM,UAAA;AAAA,IACzC;AAAA,MACE,KAAK;AAAA,MACL,OAAO;AAAA,MACP,MAAM;AAAA,MACN,MAAM;AAAA,IAAA;AAAA,EACR;AAAA,EAEF,gBAAgB;AAAA,IACd,UAAU;AAAA,IACV,MAAM;AAAA,IACN,WAAW;AAAA,IACX,SAAS;AAAA,IACT,aAAa;AAAA,EAAA;AAAA,EAEf,QAAQ,CAACK,MAAM;AACb,UAAMC,IAAU,GAAGD,EAAE,UAAU,MAAMA,EAAE,YAAY,MAAMA,EAAE,aAAa,MAAMA,EAAE,WAAW,MACrF4E,IAAK5E,EAAE,aAAa,iBAAiBJ,EAAWI,EAAE,UAAU,CAAC,MAAM,IACnEkE,IAAKlE,EAAE,cAAcA,EAAE,eAAe,WAAW,iBAAiBA,EAAE,UAAU,MAAM,IACpF6E,IAAK,OAAO7E,EAAE,cAAc,EAAE,EAAE,KAAA,GAChC8E,IAASD,IAAK,iBAAiBjF,EAAWiF,CAAE,CAAC,MAAM;AACzD,WAAO,mBAAmB7E,EAAE,KAAK,YAAYJ,EAAWI,EAAE,KAAK,CAAC,gBAAgBJ;AAAA,MAC9EI,EAAE;AAAA,IAAA,CACH,IAAI8E,CAAM,GAAGF,CAAE,GAAGV,CAAE,aAAajE,CAAO,KAAKD,EAAE,OAAO;AAAA,EACzD;AAAA,EACA,eAAe,CAACA,MAAM;AACpB,UAAM4E,IAAK5E,EAAE,aAAa,eAAeA,EAAE,UAAU,MAAM,IACrDkE,IAAKlE,EAAE,cAAcA,EAAE,eAAe,WAAW,eAAeA,EAAE,UAAU,MAAM,IAClF+E,IAAQ,OAAO/E,EAAE,cAAc,EAAE,EAAE,KAAA,GACnC6E,IAAKE,IAAQ,eAAeA,CAAK,MAAM;AAC7C,WAAO,kDAAkD/E,EAAE,KAAK,UAAUA,EAAE,KAAK,cAAcA,EAAE,QAAQ,IAAI6E,CAAE,GAAGD,CAAE,GAAGV,CAAE,WAAWlE,EAAE,UAAU,MAAMA,EAAE,YAAY,MAAMA,EAAE,aAAa,MAAMA,EAAE,WAAW,QAAQA,EAAE,OAAO;AAAA,EAC/N;AACF,CAAC,GCzFYgF,KAAwC;AAAA,EACnDL;AAAA,EACA1D;AAAA,EACAG;AAAA,EACAoD;AAAA,EACA9D;AAAA,EACAZ;AAAA,EACAU;AAAA,EACAkE;AACF,GAGaO,KAA8C,CAACvD,GAAWiC,GAAalD,CAAW,GAGlFyE,KAAoC,CAAC,GAAGF,IAAe,GAAGC,EAAmB;"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/icons.ts","../src/button.ts","../src/divider.ts","../src/footer.ts","../src/hero.ts","../src/html.ts","../src/image.ts","../src/logo.ts","../src/socialShared.ts","../src/social.ts","../src/socialGroup.ts","../src/spacer.ts","../src/text.ts","../src/index.ts"],"sourcesContent":["/** 24x24 viewBox 的内置组件图标。集中放,避免散落到各 block 文件。 */\nexport const icons = {\n html: `<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\"><rect x=\"3.5\" y=\"4\" width=\"17\" height=\"16\" rx=\"2\" stroke=\"currentColor\" stroke-width=\"1.5\" fill=\"none\"/><path d=\"M8 8.5l3 3.5-3 3.5M16 8.5l-3 3.5 3 3.5\" stroke=\"currentColor\" stroke-width=\"1.6\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>`,\n text: `<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path d=\"M5 6h14M5 10h14M5 14h10M5 18h8\" stroke=\"currentColor\" stroke-width=\"1.6\" stroke-linecap=\"round\" fill=\"none\"/></svg>`,\n image: `<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><rect x=\"3.5\" y=\"5\" width=\"17\" height=\"14\" rx=\"2\" stroke=\"currentColor\" stroke-width=\"1.6\" fill=\"none\"/><circle cx=\"9\" cy=\"10\" r=\"1.5\" fill=\"currentColor\"/><path d=\"M4 18l5-5 4 4 3-3 4 4\" stroke=\"currentColor\" stroke-width=\"1.6\" fill=\"none\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>`,\n hero: `<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><rect x=\"3\" y=\"6\" width=\"18\" height=\"12\" rx=\"1.5\" stroke=\"currentColor\" stroke-width=\"1.5\" fill=\"none\"/><path d=\"M6 14h5M6 17h8\" stroke=\"currentColor\" stroke-width=\"1.4\" stroke-linecap=\"round\"/></svg>`,\n button: `<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><rect x=\"4\" y=\"8\" width=\"16\" height=\"8\" rx=\"4\" fill=\"currentColor\" opacity=\"0.75\"/></svg>`,\n divider: `<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path d=\"M3 12h18\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"/></svg>`,\n spacer: `<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path d=\"M5 8h14M5 16h14\" stroke=\"currentColor\" stroke-width=\"1.6\" stroke-linecap=\"round\"/><path d=\"M12 9v6\" stroke=\"currentColor\" stroke-width=\"1.6\" stroke-linecap=\"round\"/><path d=\"M9 12l3-3 3 3M9 12l3 3 3-3\" stroke=\"currentColor\" stroke-width=\"1.6\" fill=\"none\" stroke-linejoin=\"round\"/></svg>`,\n logo: `<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path d=\"M5 18V6l7 6 7-6v12\" stroke=\"currentColor\" stroke-width=\"1.6\" fill=\"none\" stroke-linejoin=\"round\"/></svg>`,\n social: `<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><circle cx=\"6\" cy=\"12\" r=\"2.5\" stroke=\"currentColor\" stroke-width=\"1.4\" fill=\"none\"/><circle cx=\"12\" cy=\"12\" r=\"2.5\" stroke=\"currentColor\" stroke-width=\"1.4\" fill=\"none\"/><circle cx=\"18\" cy=\"12\" r=\"2.5\" stroke=\"currentColor\" stroke-width=\"1.4\" fill=\"none\"/></svg>`,\n footer: `<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><rect x=\"3.5\" y=\"5\" width=\"17\" height=\"10\" rx=\"1.5\" stroke=\"currentColor\" stroke-width=\"1.4\" fill=\"none\"/><path d=\"M5 18h14\" stroke=\"currentColor\" stroke-width=\"1.6\" stroke-linecap=\"round\"/></svg>`,\n socialGroup: `<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\"><rect x=\"3\" y=\"5\" width=\"18\" height=\"14\" rx=\"2\" stroke=\"currentColor\" stroke-width=\"1.5\"/><circle cx=\"8\" cy=\"12\" r=\"2\" stroke=\"currentColor\" stroke-width=\"1.4\"/><circle cx=\"12\" cy=\"12\" r=\"2\" stroke=\"currentColor\" stroke-width=\"1.4\"/><circle cx=\"16\" cy=\"12\" r=\"2\" stroke=\"currentColor\" stroke-width=\"1.4\"/></svg>`,\n};\n","import { defineBlock, blockButtonWidthCss } from '@simple-mail/core';\nimport { icons } from './icons';\n\ninterface ButtonProps {\n text: string;\n href: string;\n backgroundColor: string;\n color: string;\n borderRadius: number;\n align: 'left' | 'center' | 'right';\n /** 留空或 auto 为自适应;可填 200px、80% 等 */\n width: string;\n paddingTop: number;\n paddingRight: number;\n paddingBottom: number;\n paddingLeft: number;\n innerPaddingV: number;\n innerPaddingH: number;\n fontSize: string;\n}\n\nconst escapeAttr = (s: string) =>\n s.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/\"/g, '"');\n\nexport const buttonBlock = defineBlock<ButtonProps>({\n type: 'button',\n name: '按钮',\n category: 'content',\n icon: icons.button,\n defaultProps: {\n text: '立即查看',\n href: 'https://example.com',\n backgroundColor: '#4f46e5',\n color: '#ffffff',\n borderRadius: 6,\n align: 'center',\n width: '',\n paddingTop: 8,\n paddingRight: 0,\n paddingBottom: 8,\n paddingLeft: 0,\n innerPaddingV: 12,\n innerPaddingH: 24,\n fontSize: '14px',\n },\n schema: [\n { key: 'text', label: '文字', type: 'text' },\n { key: 'href', label: '链接', type: 'url' },\n { key: 'backgroundColor', label: '背景色', type: 'color' },\n { key: 'color', label: '文字颜色', type: 'color' },\n { key: 'borderRadius', label: '圆角 (px)', type: 'number', min: 0, max: 40 },\n { key: 'fontSize', label: '字号', type: 'text' },\n {\n key: 'align',\n label: '对齐',\n type: 'select',\n selectVariant: 'segmented',\n options: [\n { label: '左', value: 'left' },\n { label: '居中', value: 'center' },\n { label: '右', value: 'right' },\n ],\n },\n {\n key: 'width',\n label: '宽度',\n type: 'text',\n placeholder: '留空=自适应,如 280px、100%',\n help: '支持纯数字(按 px)、带 px 或百分比',\n },\n { key: 'innerPaddingV', label: '按钮内上下边距', type: 'number', min: 0, max: 40 },\n { key: 'innerPaddingH', label: '按钮内左右边距', type: 'number', min: 0, max: 60 },\n { key: 'paddingTop', label: '外边距', type: 'spacing' },\n ],\n inlineEditable: {\n selector: '.sm-button-text',\n mode: 'plain',\n multiline: false,\n propKey: 'text',\n placeholder: '按钮文字',\n },\n toMjml: (p) => {\n const padding = `${p.paddingTop}px ${p.paddingRight}px ${p.paddingBottom}px ${p.paddingLeft}px`;\n const innerPadding = `${p.innerPaddingV}px ${p.innerPaddingH}px`;\n const bw = blockButtonWidthCss(p.width);\n const widthAttr = bw ? ` width=\"${escapeAttr(bw)}\"` : '';\n return `<mj-button href=\"${escapeAttr(p.href)}\" background-color=\"${escapeAttr(\n p.backgroundColor,\n )}\" color=\"${escapeAttr(p.color)}\" border-radius=\"${p.borderRadius}px\" font-size=\"${escapeAttr(\n p.fontSize,\n )}\" align=\"${p.align}\" padding=\"${padding}\" inner-padding=\"${innerPadding}\"${widthAttr}>${escapeAttr(\n p.text,\n )}</mj-button>`;\n },\n renderPreview: (p) => {\n const bw = blockButtonWidthCss(p.width);\n const wst = bw ? `width:${bw};max-width:100%;box-sizing:border-box;` : '';\n /* 画布对 .sm-canvas a 设置了带 !important 的链接色,文字颜色必须写在子节点上才能生效 */\n return `<div style=\"padding:${p.paddingTop}px ${p.paddingRight}px ${p.paddingBottom}px ${p.paddingLeft}px;text-align:${p.align};\">\n <a href=\"${escapeAttr(p.href)}\" style=\"display:inline-block;background:${\n p.backgroundColor\n };border-radius:${p.borderRadius}px;padding:${p.innerPaddingV}px ${\n p.innerPaddingH\n }px;text-decoration:none;font-size:${p.fontSize};line-height:1.2;${wst}\"><span class=\"sm-button-text\" style=\"color:${\n p.color\n }\">${escapeAttr(p.text)}</span></a>\n </div>`;\n },\n});\n","import { defineBlock } from '@simple-mail/core';\nimport { icons } from './icons';\n\ninterface DividerProps {\n color: string;\n width: string;\n thickness: number;\n paddingTop: number;\n paddingBottom: number;\n}\n\nconst esc = (s: string) =>\n s.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/\"/g, '"');\n\nexport const dividerBlock = defineBlock<DividerProps>({\n type: 'divider',\n name: '分隔线',\n category: 'content',\n icon: icons.divider,\n defaultProps: {\n color: '#e6e8ec',\n width: '100%',\n thickness: 1,\n paddingTop: 8,\n paddingBottom: 8,\n },\n schema: [\n { key: 'color', label: '颜色', type: 'color' },\n { key: 'width', label: '宽度 (% 或 px)', type: 'text' },\n { key: 'thickness', label: '粗细 (px)', type: 'number', min: 1, max: 10 },\n { key: 'paddingTop', label: '上边距', type: 'number', min: 0, max: 80 },\n { key: 'paddingBottom', label: '下边距', type: 'number', min: 0, max: 80 },\n ],\n toMjml: (p) =>\n `<mj-divider border-color=\"${esc(p.color)}\" border-width=\"${p.thickness}px\" width=\"${esc(\n p.width,\n )}\" padding=\"${p.paddingTop}px 0px ${p.paddingBottom}px 0px\" />`,\n renderPreview: (p) =>\n `<div style=\"padding:${p.paddingTop}px 0 ${p.paddingBottom}px 0;\"><div style=\"border-top:${p.thickness}px solid ${p.color};width:${p.width};margin:0 auto;\"></div></div>`,\n});\n","import { defineBlock } from '@simple-mail/core';\nimport { icons } from './icons';\n\ninterface FooterProps {\n companyName: string;\n address: string;\n unsubscribeText: string;\n unsubscribeHref: string;\n textColor: string;\n}\n\nconst esc = (s: string) =>\n s.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/\"/g, '"');\n\nexport const footerBlock = defineBlock<FooterProps>({\n type: 'custom:footer',\n name: '页脚',\n category: 'custom',\n icon: icons.footer,\n defaultProps: {\n companyName: '你的公司',\n address: '上海市某区某路某号',\n unsubscribeText: '退订邮件',\n unsubscribeHref: '{{unsubscribeUrl}}',\n textColor: '#9aa0a6',\n },\n schema: [\n { key: 'companyName', label: '公司名称', type: 'text' },\n { key: 'address', label: '地址', type: 'text' },\n { key: 'unsubscribeText', label: '退订文案', type: 'text' },\n { key: 'unsubscribeHref', label: '退订链接', type: 'url' },\n { key: 'textColor', label: '文字颜色', type: 'color' },\n ],\n toMjml: (p) => {\n return `<mj-text align=\"center\" color=\"${esc(p.textColor)}\" font-size=\"12px\" line-height=\"1.6\" padding=\"8px 0px 8px 0px\">\n ${esc(p.companyName)}<br />\n ${esc(p.address)}<br />\n <a href=\"${esc(p.unsubscribeHref)}\" style=\"color:${esc(p.textColor)};\">${esc(p.unsubscribeText)}</a>\n</mj-text>`;\n },\n renderPreview: (p) => {\n return `<div style=\"padding:8px 0;text-align:center;font-size:12px;line-height:1.6;color:${p.textColor};\">\n ${esc(p.companyName)}<br/>\n ${esc(p.address)}<br/>\n <a href=\"${esc(p.unsubscribeHref)}\" style=\"color:${p.textColor};\">${esc(p.unsubscribeText)}</a>\n </div>`;\n },\n});\n","import { defineBlock, docContentWidthCss } from '@simple-mail/core';\nimport { icons } from './icons';\n\ninterface HeroProps {\n backgroundUrl: string;\n backgroundColor: string;\n height: number;\n content: string;\n textAlign: 'left' | 'center' | 'right';\n textColor: string;\n verticalAlign: 'top' | 'middle' | 'bottom';\n paddingTop: number;\n paddingRight: number;\n paddingBottom: number;\n paddingLeft: number;\n}\n\nconst escapeAttr = (s: string) =>\n s.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/\"/g, '"');\n\nexport const heroBlock = defineBlock<HeroProps>({\n type: 'hero',\n name: 'Hero 大图',\n category: 'content',\n icon: icons.hero,\n defaultProps: {\n backgroundUrl:\n 'https://placehold.co/600x320/312e81/c4b5fd/png?text=Hero+Background',\n backgroundColor: '#1e1b4b',\n height: 320,\n content:\n '<p style=\"margin:0;font-size:28px;font-weight:700;line-height:1.25;\">主标题落在大图上</p><p style=\"margin:12px 0 0;font-size:16px;font-weight:400;opacity:0.95;line-height:1.5;\">支援变量与 <strong>双击编辑</strong>,与正文组件一致。</p>',\n textAlign: 'center',\n textColor: '#ffffff',\n verticalAlign: 'middle',\n paddingTop: 8,\n paddingRight: 0,\n paddingBottom: 8,\n paddingLeft: 0,\n },\n schema: [\n { key: 'backgroundUrl', label: '背景图', type: 'image' },\n { key: 'backgroundColor', label: '背景占位色', type: 'color', help: '图片加载失败时的底色' },\n { key: 'height', label: '区域高度 (px)', type: 'number', min: 120, max: 1200, step: 1 },\n {\n key: 'verticalAlign',\n label: '文字垂直位置',\n type: 'select',\n selectVariant: 'segmented',\n options: [\n { label: '靠上', value: 'top' },\n { label: '居中', value: 'middle' },\n { label: '靠下', value: 'bottom' },\n ],\n },\n {\n key: 'textAlign',\n label: '文字水平对齐',\n type: 'select',\n selectVariant: 'segmented',\n options: [\n { label: '左', value: 'left' },\n { label: '居中', value: 'center' },\n { label: '右', value: 'right' },\n ],\n },\n { key: 'textColor', label: '文字颜色', type: 'color' },\n { key: 'paddingTop', label: '内边距', type: 'spacing' },\n {\n key: 'content',\n label: '正文(HTML)',\n type: 'textarea',\n help: '建议在画布内双击编辑;此处供高级修改。',\n },\n ],\n inlineEditable: {\n selector: '.sm-hero-content',\n mode: 'rich',\n multiline: true,\n propKey: 'content',\n placeholder: '编写覆盖在图片上的文案…',\n },\n toMjml: (p, ctx) => {\n const w = docContentWidthCss(ctx.doc.meta.width);\n const padding = `${p.paddingTop}px ${p.paddingRight}px ${p.paddingBottom}px ${p.paddingLeft}px`;\n const h = `${p.height}px`;\n return `<mj-hero\n mode=\"fixed-height\"\n height=\"${h}\"\n background-width=\"${w}\"\n background-height=\"${h}\"\n background-url=\"${escapeAttr(p.backgroundUrl)}\"\n background-color=\"${escapeAttr(p.backgroundColor)}\"\n padding=\"${padding}\"\n vertical-align=\"${p.verticalAlign}\"\n >\n <mj-text\n align=\"${p.textAlign}\"\n color=\"${escapeAttr(p.textColor)}\"\n padding=\"0\"\n >${p.content}</mj-text>\n </mj-hero>`;\n },\n renderPreview: (p, ctx) => {\n const w = docContentWidthCss(ctx.doc.meta.width);\n const flexAlign =\n p.verticalAlign === 'top' ? 'flex-start' : p.verticalAlign === 'bottom' ? 'flex-end' : 'center';\n const padding = `${p.paddingTop}px ${p.paddingRight}px ${p.paddingBottom}px ${p.paddingLeft}px`;\n const url = escapeAttr(p.backgroundUrl);\n return `<div\n style=\"\n box-sizing:border-box;\n width:100%;\n max-width:${w};\n min-height:${p.height}px;\n margin:0 auto;\n background-image:linear-gradient(to bottom,rgba(0,0,0,0.25),rgba(0,0,0,0.35)),url(${url});\n background-size:cover;\n background-position:center;\n background-color:${p.backgroundColor};\n display:flex;\n align-items:${flexAlign};\n justify-content:${p.textAlign === 'right' ? 'flex-end' : p.textAlign === 'center' ? 'center' : 'flex-start'};\n padding:${padding};\n color:${escapeAttr(p.textColor)};\n overflow:hidden;\n border-radius:2px;\n \"\n >\n <div\n class=\"sm-hero-content\"\n style=\"\n width:100%;\n text-align:${p.textAlign};\n color:${escapeAttr(p.textColor)};\n text-shadow:0 1px 2px rgba(0,0,0,0.45);\n \"\n >${p.content}</div>\n </div>`;\n },\n});\n","import { defineBlock, mjRawCellTypographyFromStyles, mjRawEmailTableWrap } from '@simple-mail/core';\nimport { icons } from './icons';\n\ninterface HtmlBlockProps {\n html: string;\n paddingTop: number;\n paddingRight: number;\n paddingBottom: number;\n paddingLeft: number;\n}\n\nexport const htmlBlock = defineBlock<HtmlBlockProps>({\n type: 'html',\n name: 'HTML',\n category: 'content',\n icon: icons.html,\n defaultProps: {\n html: '<p style=\"margin:0;\">在此写入任意 HTML,将经 <strong>mj-raw</strong> 原样输出到邮件。支持变量 {{user.name}}</p>',\n paddingTop: 8,\n paddingRight: 0,\n paddingBottom: 8,\n paddingLeft: 0,\n },\n schema: [\n {\n key: 'html',\n label: 'HTML',\n type: 'textarea',\n help: '插入 MJML 的 mj-raw。邮件客户端常会过滤脚本与不支持的标签。',\n },\n { key: 'paddingTop', label: '内边距', type: 'spacing' },\n ],\n inlineEditable: {\n selector: '.sm-html-content',\n mode: 'html',\n multiline: true,\n propKey: 'html',\n placeholder: '输入 HTML…',\n },\n toMjml: (p, ctx) => {\n const padding = `${p.paddingTop}px ${p.paddingRight}px ${p.paddingBottom}px ${p.paddingLeft}px`;\n return mjRawEmailTableWrap(padding, p.html, mjRawCellTypographyFromStyles(ctx.doc.styles));\n },\n renderPreview: (p) => {\n const pad = `${p.paddingTop}px ${p.paddingRight}px ${p.paddingBottom}px ${p.paddingLeft}px`;\n return `<div class=\"sm-html-content\" style=\"padding:${pad};min-height:1em;\">${p.html}</div>`;\n },\n});\n","import { defineBlock } from '@simple-mail/core';\nimport { icons } from './icons';\n\ninterface ImageProps {\n src: string;\n alt: string;\n href: string;\n width: number;\n /** 0 表示不限制高度,按原图比例自适应(推荐邮件场景) */\n height: number;\n align: 'left' | 'center' | 'right';\n paddingTop: number;\n paddingRight: number;\n paddingBottom: number;\n paddingLeft: number;\n}\n\nconst escapeAttr = (s: string) =>\n s.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/\"/g, '"');\n\nexport const imageBlock = defineBlock<ImageProps>({\n type: 'image',\n name: '图片',\n category: 'content',\n icon: icons.image,\n defaultProps: {\n src: 'https://placehold.co/600x240/EEF2FF/4F46E5/png?text=600x240',\n alt: '',\n href: '',\n width: 480,\n height: 0,\n align: 'center',\n paddingTop: 8,\n paddingRight: 0,\n paddingBottom: 8,\n paddingLeft: 0,\n },\n schema: [\n { key: 'src', label: '图片地址', type: 'image' },\n { key: 'alt', label: '替代文本', type: 'text', placeholder: '图片描述' },\n { key: 'href', label: '点击跳转', type: 'url', placeholder: 'https://...' },\n { key: 'width', label: '宽度 (px)', type: 'number', min: 40, max: 600 },\n {\n key: 'height',\n label: '高度 (px)(0 为自适应)',\n type: 'number',\n min: 0,\n max: 1200,\n help: '0 为自适应高度;填写固定值时画布与 MJML 会限制显示高度(预览可用 object-fit: cover)',\n },\n {\n key: 'align',\n label: '对齐',\n type: 'select',\n selectVariant: 'segmented',\n options: [\n { label: '左', value: 'left' },\n { label: '居中', value: 'center' },\n { label: '右', value: 'right' },\n ],\n },\n { key: 'paddingTop', label: '内边距', type: 'spacing' },\n ],\n toMjml: (p) => {\n const padding = `${p.paddingTop}px ${p.paddingRight}px ${p.paddingBottom}px ${p.paddingLeft}px`;\n const href = p.href ? ` href=\"${escapeAttr(p.href)}\"` : '';\n const alt = ` alt=\"${escapeAttr(p.alt || '')}\"`;\n const h = p.height != null && p.height > 0 ? ` height=\"${p.height}px\"` : '';\n return `<mj-image src=\"${escapeAttr(p.src)}\"${alt}${href} width=\"${p.width}px\"${h} align=\"${p.align}\" padding=\"${padding}\" />`;\n },\n renderPreview: (p) => {\n const align = p.align === 'center' ? 'margin:0 auto;' : p.align === 'right' ? 'margin-left:auto;' : '';\n const fixedH = p.height != null && p.height > 0 ? p.height : 0;\n const sizeStyle =\n fixedH > 0\n ? `width:${p.width}px;height:${fixedH}px;object-fit:cover;object-position:center;`\n : `width:${p.width}px;height:auto;`;\n return `<div style=\"padding:${p.paddingTop}px ${p.paddingRight}px ${p.paddingBottom}px ${p.paddingLeft}px;text-align:${p.align};\"><img src=\"${escapeAttr(\n p.src,\n )}\" alt=\"${escapeAttr(p.alt)}\" style=\"display:block;${align}max-width:100%;${sizeStyle}border:0;outline:none;\" /></div>`;\n },\n});\n","import { defineBlock } from '@simple-mail/core';\nimport { icons } from './icons';\n\n/** 公司 Logo —— 一个语义化的\"图片+链接\"封装,便于运营快速放置品牌资产。 */\ninterface LogoProps {\n src: string;\n href: string;\n width: number;\n align: 'left' | 'center' | 'right';\n}\n\nconst esc = (s: string) =>\n s.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/\"/g, '"');\n\nexport const logoBlock = defineBlock<LogoProps>({\n type: 'custom:logo',\n name: '公司 Logo',\n category: 'custom',\n icon: icons.logo,\n defaultProps: {\n src: 'https://placehold.co/240x60/1f2328/ffffff/png?text=YOUR+LOGO',\n href: 'https://example.com',\n width: 160,\n align: 'center',\n },\n schema: [\n { key: 'src', label: 'Logo 图片', type: 'image' },\n { key: 'href', label: '官网链接', type: 'url' },\n { key: 'width', label: '宽度 (px)', type: 'number', min: 60, max: 400 },\n {\n key: 'align',\n label: '对齐',\n type: 'select',\n selectVariant: 'segmented',\n options: [\n { label: '左', value: 'left' },\n { label: '居中', value: 'center' },\n { label: '右', value: 'right' },\n ],\n },\n ],\n toMjml: (p) =>\n `<mj-image src=\"${esc(p.src)}\" href=\"${esc(p.href)}\" width=\"${p.width}px\" align=\"${p.align}\" alt=\"logo\" padding=\"8px 0px 8px 0px\" />`,\n renderPreview: (p) => {\n const m =\n p.align === 'center' ? 'margin:0 auto;' : p.align === 'right' ? 'margin-left:auto;' : '';\n return `<div style=\"padding:8px 0;text-align:${p.align};\"><img src=\"${esc(\n p.src,\n )}\" alt=\"logo\" style=\"display:block;${m}width:${p.width}px;max-width:100%;height:auto;\" /></div>`;\n },\n});\n","import { normalizeFontWeightStep } from '@simple-mail/core';\n\n/** 生成 mj-social-element 的 name 属性(与 MJML 内置图标对齐;未知平台退化为 web)。 */\nexport function mjSocialElementName(network: string): string {\n const n = network.trim();\n if (n === 'ig') return 'instagram';\n if (n === 'rabbit' || n === 'tiktok' || n === 'reddit') return 'web';\n return n;\n}\n\n/** 业务示例:固定海外/垂类五平台(与 custom:social 块配套)。 */\nexport const BIZ_SOCIAL_NETWORK_OPTIONS: { label: string; value: string }[] = [\n { label: 'X', value: 'x' },\n { label: 'Rabbit', value: 'rabbit' },\n { label: 'Facebook', value: 'facebook' },\n { label: 'TikTok', value: 'tiktok' },\n { label: 'Instagram', value: 'ig' },\n];\n\n/** 社交平台与 MJML mj-social-element 的 name 对齐(含常用内置名)。 */\nexport const SOCIAL_NETWORK_OPTIONS: { label: string; value: string }[] = [\n { label: '微信', value: 'wechat' },\n { label: '微博', value: 'weibo' },\n { label: 'X', value: 'x' },\n { label: 'LinkedIn', value: 'linkedin' },\n { label: 'GitHub', value: 'github' },\n { label: 'Facebook', value: 'facebook' },\n { label: 'Instagram', value: 'instagram' },\n { label: 'YouTube', value: 'youtube' },\n { label: 'Reddit', value: 'reddit' },\n { label: '网页', value: 'web' },\n];\n\nconst NETWORK_META: Record<string, { color: string; preview: string }> = {\n wechat: { color: '#1AAD19', preview: '信' },\n weibo: { color: '#E6162D', preview: '微' },\n x: { color: '#000000', preview: 'X' },\n linkedin: { color: '#0A66C2', preview: 'in' },\n github: { color: '#181717', preview: 'GH' },\n facebook: { color: '#1877F2', preview: 'f' },\n instagram: { color: '#E4405F', preview: '◎' },\n ig: { color: '#E4405F', preview: '◎' },\n youtube: { color: '#FF0000', preview: '▶' },\n reddit: { color: '#FF4500', preview: 'r' },\n tiktok: { color: '#000000', preview: '♪' },\n rabbit: { color: '#FF2442', preview: 'R' },\n website: { color: '#6b7280', preview: '◇' },\n web: { color: '#6b7280', preview: '◇' },\n};\n\nexport const escAttr = (s: string) =>\n s.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/\"/g, '"');\n\n/** mj-social-element 体内文本转义(非属性) */\nexport const escMjmlText = (s: string) =>\n s.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');\n\nexport interface SocialLinkItem {\n network: string;\n href: string;\n /** 图标旁文字,对应 mj-social-element 子内容 */\n label?: string;\n /** 自定义图标 URL,对应 mj-social-element src */\n iconSrc?: string;\n /** 图标区域背景色;未设则用平台预设 */\n backgroundColor?: string;\n}\n\n/** 社交组块级:所有带标签的链接共用同一套标签文字样式 */\nexport interface SocialGroupLabelStyle {\n labelFontSize: number;\n labelFontWeight: string;\n labelColor: string;\n}\n\nexport function socialMeta(network: string): { color: string; preview: string } {\n return NETWORK_META[network] ?? { color: '#6b7280', preview: '·' };\n}\n\nexport function paddingQuad(p: {\n paddingTop: number;\n paddingRight: number;\n paddingBottom: number;\n paddingLeft: number;\n}): string {\n return `${p.paddingTop}px ${p.paddingRight}px ${p.paddingBottom}px ${p.paddingLeft}px`;\n}\n\n/** mj-social `border-radius`:0 直角;≥999 或 ≥图标半边 → 圆形裁切(999px) */\nexport function socialIconBorderRadiusMjml(iconSize: number, radiusPx: unknown): string {\n const size = Math.max(1, Number(iconSize) || 28);\n const r = Number(radiusPx);\n if (!Number.isFinite(r) || r <= 0) return '0px';\n const half = size / 2;\n if (r >= 999 || r >= half) return '999px';\n return `${Math.min(r, size)}px`;\n}\n\n/** 画布预览用图标圆角 CSS(与 {@link socialIconBorderRadiusMjml} 语义一致) */\nexport function socialIconBorderRadiusCss(iconSize: number, radiusPx: unknown): string {\n const size = Math.max(1, Number(iconSize) || 28);\n const r = Number(radiusPx);\n if (!Number.isFinite(r) || r <= 0) return '0';\n const half = size / 2;\n if (r >= 999 || r >= half) return '50%';\n return `${Math.min(r, size)}px`;\n}\n\n/** mj-social `inner-padding`,控制图标之间的可视间距 */\nexport function socialIconSpacingPx(spacing: unknown, fallback = 10): number {\n const n = Number(spacing);\n if (!Number.isFinite(n) || n < 0) return fallback;\n return Math.min(64, Math.round(n));\n}\n\nexport function flexJustifyFromAlign(align: 'left' | 'center' | 'right'): string {\n if (align === 'right') return 'flex-end';\n if (align === 'left') return 'flex-start';\n return 'center';\n}\n\nexport function mjSocialElementsLines(\n links: SocialLinkItem[],\n labelStyle: SocialGroupLabelStyle,\n): string {\n const fontSizeRaw = labelStyle.labelFontSize > 0 ? labelStyle.labelFontSize : 13;\n const fontSize = Math.max(8, Math.min(48, fontSizeRaw));\n const fontWeight = normalizeFontWeightStep(labelStyle.labelFontWeight);\n const textColor = labelStyle.labelColor?.trim() || '#333333';\n const fwEsc = escAttr(fontWeight);\n return links\n .map((l) => {\n const meta = socialMeta(l.network);\n const bgColor = l.backgroundColor?.trim() || meta.color;\n const attrs = [\n `name=\"${escAttr(mjSocialElementName(l.network))}\"`,\n `href=\"${escAttr(l.href)}\"`,\n `background-color=\"${escAttr(bgColor)}\"`,\n `color=\"${escAttr(textColor)}\"`,\n `font-size=\"${fontSize}px\"`,\n `font-weight=\"${fwEsc}\"`,\n ];\n const attrStr = attrs.join(' ');\n const src = l.iconSrc?.trim();\n const withSrc = src ? `${attrStr} src=\"${escAttr(src)}\"` : attrStr;\n const label = l.label?.trim() ?? '';\n if (!label) {\n return ` <mj-social-element ${withSrc} />`;\n }\n return ` <mj-social-element ${withSrc}>\\n ${escMjmlText(label)}\\n </mj-social-element>`;\n })\n .join('\\n');\n}\n","import { defineBlock, FONT_WEIGHT_STEP_OPTIONS, normalizeFontWeightStep } from '@simple-mail/core';\nimport { icons } from './icons';\nimport {\n BIZ_SOCIAL_NETWORK_OPTIONS,\n escAttr,\n flexJustifyFromAlign,\n mjSocialElementsLines,\n paddingQuad,\n socialIconBorderRadiusCss,\n socialIconBorderRadiusMjml,\n socialIconSpacingPx,\n socialMeta,\n type SocialLinkItem,\n} from './socialShared';\n\n/** 与社交组一致,仅平台选项收窄为业务五件套 */\ninterface SocialBizProps {\n elements: SocialLinkItem[];\n align: 'left' | 'center' | 'right';\n iconSize: number;\n iconBorderRadius: number;\n iconSpacing: number;\n labelFontSize: number;\n labelFontWeight: string;\n labelColor: string;\n paddingTop: number;\n paddingRight: number;\n paddingBottom: number;\n paddingLeft: number;\n /** 旧版自定义块:`links` + textarea,仅用于兼容读入 */\n links?: { network: string; href: string }[];\n}\n\nconst DEFAULT_BIZ_ELEMENTS: SocialLinkItem[] = [\n { network: 'x', href: 'https://x.com/' },\n { network: 'rabbit', href: 'https://example.com' },\n { network: 'facebook', href: 'https://facebook.com/' },\n { network: 'tiktok', href: 'https://www.tiktok.com/' },\n { network: 'ig', href: 'https://instagram.com/' },\n];\n\nfunction normalizeElements(p: SocialBizProps): SocialLinkItem[] {\n if (p.elements?.length) return p.elements;\n const legacy = p.links;\n if (Array.isArray(legacy) && legacy.length)\n return legacy.map((l) => ({\n network: String(l.network ?? 'web'),\n href: String(l.href ?? ''),\n }));\n return DEFAULT_BIZ_ELEMENTS;\n}\n\nexport const socialBlock = defineBlock<SocialBizProps>({\n type: 'custom:social',\n name: '社交链接',\n category: 'custom',\n icon: icons.social,\n defaultProps: {\n elements: DEFAULT_BIZ_ELEMENTS,\n align: 'center',\n iconSize: 28,\n iconBorderRadius: 999,\n iconSpacing: 10,\n labelFontSize: 13,\n labelFontWeight: '400',\n labelColor: '#333333',\n paddingTop: 8,\n paddingRight: 0,\n paddingBottom: 8,\n paddingLeft: 0,\n },\n schema: [\n {\n key: 'elements',\n label: '社交链接',\n type: 'socialLinkList',\n options: BIZ_SOCIAL_NETWORK_OPTIONS,\n help: '平台:X、Rabbit、Facebook、TikTok、Instagram (ig)。可填标签、自定义图标 URL。MJML 侧 Rabbit/TikTok 使用 web 占位图标,需要品牌图时请填「图标 URL」。',\n },\n {\n key: 'labelFontSize',\n label: '标签字号 (px)',\n type: 'number',\n min: 8,\n max: 48,\n step: 1,\n },\n {\n key: 'labelFontWeight',\n label: '标签字重',\n type: 'select',\n selectVariant: 'segmented',\n options: [...FONT_WEIGHT_STEP_OPTIONS],\n },\n { key: 'labelColor', label: '标签颜色', type: 'color' },\n {\n key: 'align',\n label: '对齐',\n type: 'select',\n selectVariant: 'segmented',\n options: [\n { label: '左', value: 'left' },\n { label: '居中', value: 'center' },\n { label: '右', value: 'right' },\n ],\n },\n { key: 'iconSize', label: '图标尺寸 (px)', type: 'number', min: 16, max: 64 },\n {\n key: 'iconBorderRadius',\n label: '图标圆角 (px)',\n type: 'number',\n min: 0,\n max: 999,\n step: 1,\n help: '0 为方形直角;较大值(如 999)为圆形(默认)。',\n },\n {\n key: 'iconSpacing',\n label: '图标间距 (px)',\n type: 'number',\n min: 0,\n max: 64,\n step: 1,\n help: '图标之间的间隔(MJML inner-padding)。',\n },\n { key: 'paddingTop', label: '外边距', type: 'spacing' },\n ],\n toMjml: (p) => {\n const pad = paddingQuad(p);\n const br = socialIconBorderRadiusMjml(p.iconSize, p.iconBorderRadius ?? 999);\n const gap = socialIconSpacingPx(p.iconSpacing, 10);\n const socAttrs = `align=\"${p.align}\" icon-size=\"${p.iconSize}px\" mode=\"horizontal\" border-radius=\"${br}\" inner-padding=\"${gap}px\" padding=\"${pad}\"`;\n const els = normalizeElements(p).filter((e) => e.href?.trim());\n const labelStyle = {\n labelFontSize: Number(p.labelFontSize ?? 13),\n labelFontWeight: normalizeFontWeightStep(String(p.labelFontWeight ?? '400')),\n labelColor: String(p.labelColor ?? '#333333'),\n };\n const inner = mjSocialElementsLines(els, labelStyle);\n if (!inner.trim()) {\n return `<mj-social ${socAttrs}></mj-social>`;\n }\n return `<mj-social ${socAttrs}>\n${inner}\n</mj-social>`;\n },\n renderPreview: (p) => {\n const fsRaw = p.labelFontSize != null && p.labelFontSize > 0 ? p.labelFontSize : 13;\n const fs = Math.max(8, Math.min(48, fsRaw));\n const fw = normalizeFontWeightStep(p.labelFontWeight);\n const textColor = p.labelColor?.trim() || '#333333';\n const radiusCss = socialIconBorderRadiusCss(p.iconSize, p.iconBorderRadius ?? 999);\n const gap = socialIconSpacingPx(p.iconSpacing, 10);\n const jc = flexJustifyFromAlign(p.align);\n const items = normalizeElements(p)\n .filter((l) => l.href?.trim())\n .map((l) => {\n const meta = socialMeta(l.network);\n const bg = l.backgroundColor?.trim() || meta.color;\n const label = l.label?.trim() ?? '';\n const iconSrc = l.iconSrc?.trim();\n const iconHtml = iconSrc\n ? `<img src=\"${escAttr(iconSrc)}\" alt=\"\" style=\"width:${p.iconSize}px;height:${p.iconSize}px;object-fit:cover;border-radius:${radiusCss};flex-shrink:0;\" />`\n : `<span style=\"display:inline-flex;width:${p.iconSize}px;height:${p.iconSize}px;border-radius:${radiusCss};background:${bg};color:#fff;align-items:center;justify-content:center;font-size:${Math.round(\n p.iconSize / 2,\n )}px;font-weight:600;flex-shrink:0;overflow:hidden;\">${meta.preview}</span>`;\n const textHtml = label\n ? `<span style=\"font-size:${fs}px !important;font-weight:${fw};color:${escAttr(\n textColor,\n )} !important;line-height:1.2;\">${escAttr(label)}</span>`\n : '';\n return `<span style=\"display:inline-flex;align-items:center;gap:6px;\"><a href=\"${escAttr(\n l.href,\n )}\" style=\"display:inline-flex;align-items:center;text-decoration:none;line-height:0;\">${iconHtml}</a>${textHtml}</span>`;\n })\n .join('');\n const pad = paddingQuad(p);\n return `<div style=\"display:flex;flex-wrap:wrap;justify-content:${jc};align-items:center;gap:${gap}px;padding:${pad};\">${items || '<span style=\"color:#9ca3af;font-size:12px;\">请填写链接 URL</span>'}</div>`;\n },\n});\n","import { defineBlock, FONT_WEIGHT_STEP_OPTIONS, normalizeFontWeightStep } from '@simple-mail/core';\nimport { icons } from './icons';\nimport {\n escAttr,\n flexJustifyFromAlign,\n mjSocialElementsLines,\n paddingQuad,\n socialIconBorderRadiusCss,\n socialIconBorderRadiusMjml,\n socialIconSpacingPx,\n socialMeta,\n SOCIAL_NETWORK_OPTIONS,\n type SocialLinkItem,\n} from './socialShared';\n\ninterface SocialGroupProps {\n elements: SocialLinkItem[];\n align: 'left' | 'center' | 'right';\n iconSize: number;\n /** 图标圆角 (px)。0 为方形;≥999 或不少于图标半边时为圆形(默认 999) */\n iconBorderRadius: number;\n /** 图标之间的间距 (px),对应 mj-social inner-padding */\n iconSpacing: number;\n /** 标签文字字号(整组统一) */\n labelFontSize: number;\n labelFontWeight: string;\n labelColor: string;\n paddingTop: number;\n paddingRight: number;\n paddingBottom: number;\n paddingLeft: number;\n}\n\nexport const socialGroupBlock = defineBlock<SocialGroupProps>({\n type: 'social-group',\n name: '社交组',\n category: 'content',\n icon: icons.socialGroup,\n defaultProps: {\n elements: [\n { network: 'weibo', href: 'https://weibo.com' },\n { network: 'wechat', href: 'https://example.com' },\n ],\n align: 'center',\n iconSize: 28,\n iconBorderRadius: 999,\n iconSpacing: 10,\n labelFontSize: 13,\n labelFontWeight: '400',\n labelColor: '#333333',\n paddingTop: 8,\n paddingRight: 0,\n paddingBottom: 8,\n paddingLeft: 0,\n },\n schema: [\n {\n key: 'elements',\n label: '社交链接',\n type: 'socialLinkList',\n options: SOCIAL_NETWORK_OPTIONS,\n help: '每行:平台、链接、可选标签文字、自定义图标 URL、图标背景色。标签的字号/字重/颜色在下方统一设置。',\n },\n {\n key: 'labelFontSize',\n label: '标签字号 (px)',\n type: 'number',\n min: 8,\n max: 48,\n step: 1,\n },\n {\n key: 'labelFontWeight',\n label: '标签字重',\n type: 'select',\n selectVariant: 'segmented',\n options: [...FONT_WEIGHT_STEP_OPTIONS],\n },\n { key: 'labelColor', label: '标签颜色', type: 'color' },\n {\n key: 'align',\n label: '对齐',\n type: 'select',\n selectVariant: 'segmented',\n options: [\n { label: '左', value: 'left' },\n { label: '居中', value: 'center' },\n { label: '右', value: 'right' },\n ],\n },\n { key: 'iconSize', label: '图标尺寸 (px)', type: 'number', min: 16, max: 64 },\n {\n key: 'iconBorderRadius',\n label: '图标圆角 (px)',\n type: 'number',\n min: 0,\n max: 999,\n step: 1,\n help: '0 为方形直角;填较大值(如 999)或与尺寸一半相当时为圆形(默认圆形)。',\n },\n {\n key: 'iconSpacing',\n label: '图标间距 (px)',\n type: 'number',\n min: 0,\n max: 64,\n step: 1,\n help: '每个图标周围的留白,横向即图标之间的间隔(MJML inner-padding)。',\n },\n { key: 'paddingTop', label: '外边距', type: 'spacing' },\n ],\n toMjml: (p) => {\n const pad = paddingQuad(p);\n const br = socialIconBorderRadiusMjml(p.iconSize, p.iconBorderRadius ?? 999);\n const gap = socialIconSpacingPx(p.iconSpacing, 10);\n const socAttrs = `align=\"${p.align}\" icon-size=\"${p.iconSize}px\" mode=\"horizontal\" border-radius=\"${br}\" inner-padding=\"${gap}px\" padding=\"${pad}\"`;\n const filtered = p.elements.filter((e) => e.href?.trim());\n const labelStyle = {\n labelFontSize: Number(p.labelFontSize ?? 13),\n labelFontWeight: normalizeFontWeightStep(String(p.labelFontWeight ?? '400')),\n labelColor: String(p.labelColor ?? '#333333'),\n };\n const inner = mjSocialElementsLines(filtered, labelStyle);\n if (!inner.trim()) {\n return `<mj-social ${socAttrs}></mj-social>`;\n }\n return `<mj-social ${socAttrs}>\n${inner}\n</mj-social>`;\n },\n renderPreview: (p) => {\n const fsRaw = p.labelFontSize != null && p.labelFontSize > 0 ? p.labelFontSize : 13;\n const fs = Math.max(8, Math.min(48, fsRaw));\n const fw = normalizeFontWeightStep(p.labelFontWeight);\n const textColor = p.labelColor?.trim() || '#333333';\n const radiusCss = socialIconBorderRadiusCss(p.iconSize, p.iconBorderRadius ?? 999);\n const gap = socialIconSpacingPx(p.iconSpacing, 10);\n const jc = flexJustifyFromAlign(p.align);\n const items = p.elements\n .filter((l) => l.href?.trim())\n .map((l) => {\n const meta = socialMeta(l.network);\n const bg = l.backgroundColor?.trim() || meta.color;\n const label = l.label?.trim() ?? '';\n const iconSrc = l.iconSrc?.trim();\n const iconHtml = iconSrc\n ? `<img src=\"${escAttr(iconSrc)}\" alt=\"\" style=\"width:${p.iconSize}px;height:${p.iconSize}px;object-fit:cover;border-radius:${radiusCss};flex-shrink:0;\" />`\n : `<span style=\"display:inline-flex;width:${p.iconSize}px;height:${p.iconSize}px;border-radius:${radiusCss};background:${bg};color:#fff;align-items:center;justify-content:center;font-size:${Math.round(\n p.iconSize / 2,\n )}px;font-weight:600;flex-shrink:0;overflow:hidden;\">${meta.preview}</span>`;\n const textHtml = label\n ? `<span style=\"font-size:${fs}px !important;font-weight:${fw};color:${escAttr(\n textColor,\n )} !important;line-height:1.2;\">${escAttr(label)}</span>`\n : '';\n return `<span style=\"display:inline-flex;align-items:center;gap:6px;\"><a href=\"${escAttr(\n l.href,\n )}\" style=\"display:inline-flex;align-items:center;text-decoration:none;line-height:0;\">${iconHtml}</a>${textHtml}</span>`;\n })\n .join('');\n const pad = paddingQuad(p);\n return `<div style=\"display:flex;flex-wrap:wrap;justify-content:${jc};align-items:center;gap:${gap}px;padding:${pad};\">${items || '<span style=\"color:#9ca3af;font-size:12px;\">请添加社交链接</span>'}</div>`;\n },\n});\n","import { defineBlock } from '@simple-mail/core';\nimport { icons } from './icons';\n\ninterface SpacerProps {\n height: number;\n}\n\nexport const spacerBlock = defineBlock<SpacerProps>({\n type: 'spacer',\n name: '间距',\n category: 'content',\n icon: icons.spacer,\n defaultProps: { height: 24 },\n schema: [{ key: 'height', label: '高度 (px)', type: 'number', min: 1, max: 200 }],\n toMjml: (p) => `<mj-spacer height=\"${p.height}px\" />`,\n renderPreview: (p) => `<div style=\"height:${p.height}px;line-height:${p.height}px;\"></div>`,\n});\n","import { defineBlock, FONT_WEIGHT_STEP_OPTIONS, normalizeFontWeightStep } from '@simple-mail/core';\nimport { icons } from './icons';\n\ninterface TextProps {\n content: string;\n align: 'left' | 'center' | 'right';\n color: string;\n fontSize: string;\n fontFamily: string;\n fontWeight: string;\n /** 空字符串:与邮件全局行距(mj-head)一致 */\n lineHeight: string;\n paddingTop: number;\n paddingRight: number;\n paddingBottom: number;\n paddingLeft: number;\n}\n\nconst escapeAttr = (s: string) =>\n s.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/\"/g, '"');\n\nexport const textBlock = defineBlock<TextProps>({\n type: 'text',\n name: '文本',\n category: 'content',\n icon: icons.text,\n defaultProps: {\n content:\n '<p style=\"margin:0;\">在此处输入文本。<strong>双击</strong>进入编辑模式,<em>选中文字</em>会出现工具条;支持变量 {{user.name}}</p>',\n align: 'left',\n color: '',\n fontSize: '',\n fontFamily: '',\n fontWeight: '',\n lineHeight: '',\n paddingTop: 8,\n paddingRight: 0,\n paddingBottom: 8,\n paddingLeft: 0,\n },\n schema: [\n {\n key: 'align',\n label: '对齐',\n type: 'select',\n selectVariant: 'segmented',\n options: [\n { label: '左', value: 'left' },\n { label: '居中', value: 'center' },\n { label: '右', value: 'right' },\n ],\n },\n { key: 'color', label: '颜色', type: 'color', placeholder: '继承全局' },\n { key: 'fontSize', label: '字号', type: 'text', inheritGlobal: true },\n { key: 'fontFamily', label: '字体', type: 'text', placeholder: '继承全局' },\n {\n key: 'fontWeight',\n label: '字重',\n type: 'select',\n selectVariant: 'segmented',\n inheritGlobal: true,\n options: [...FONT_WEIGHT_STEP_OPTIONS],\n },\n {\n key: 'lineHeight',\n label: '行高',\n type: 'select',\n help: '留空则使用邮件设置里的全局行距',\n options: [\n { label: '继承全局', value: '' },\n { label: '1.0', value: '1' },\n { label: '1.15', value: '1.15' },\n { label: '1.25', value: '1.25' },\n { label: '1.4', value: '1.4' },\n { label: '1.5', value: '1.5' },\n { label: '1.75', value: '1.75' },\n { label: '2.0', value: '2' },\n { label: '22px', value: '22px' },\n { label: '24px', value: '24px' },\n { label: '28px', value: '28px' },\n { label: '32px', value: '32px' },\n ],\n },\n { key: 'paddingTop', label: '内边距', type: 'spacing' },\n {\n key: 'content',\n label: '内容(HTML,备用)',\n type: 'textarea',\n help: '建议直接在画布双击编辑;这里保留为高级编辑入口。',\n },\n ],\n inlineEditable: {\n selector: '.sm-text-content',\n mode: 'rich',\n multiline: true,\n propKey: 'content',\n placeholder: '输入文本…',\n },\n toMjml: (p) => {\n const padding = `${p.paddingTop}px ${p.paddingRight}px ${p.paddingBottom}px ${p.paddingLeft}px`;\n const ff = p.fontFamily ? ` font-family=\"${escapeAttr(p.fontFamily)}\"` : '';\n const fwRaw = String(p.fontWeight ?? '').trim();\n const fw = fwRaw ? ` font-weight=\"${escapeAttr(normalizeFontWeightStep(fwRaw))}\"` : '';\n const lh = String(p.lineHeight ?? '').trim();\n const lhAttr = lh ? ` line-height=\"${escapeAttr(lh)}\"` : '';\n const colorRaw = String(p.color ?? '').trim();\n const colorAttr = colorRaw ? ` color=\"${escapeAttr(colorRaw)}\"` : '';\n const fsRaw = String(p.fontSize ?? '').trim();\n const fsAttr = fsRaw ? ` font-size=\"${escapeAttr(fsRaw)}\"` : '';\n return `<mj-text align=\"${p.align}\"${colorAttr}${fsAttr}${lhAttr}${ff}${fw} padding=\"${padding}\">${p.content}</mj-text>`;\n },\n renderPreview: (p) => {\n const ff = p.fontFamily ? `font-family:${p.fontFamily};` : '';\n const fwRaw = String(p.fontWeight ?? '').trim();\n const fwCss = fwRaw ? `font-weight:${normalizeFontWeightStep(fwRaw)};` : '';\n const lhRaw = String(p.lineHeight ?? '').trim();\n const lh = lhRaw ? `line-height:${lhRaw};` : 'line-height:normal;';\n const colorRaw = String(p.color ?? '').trim();\n const colorCss = colorRaw ? `color:${colorRaw};` : '';\n const fsRaw = String(p.fontSize ?? '').trim();\n const fsCss = fsRaw ? `font-size:${fsRaw};` : '';\n return `<div class=\"sm-text-content\" style=\"text-align:${p.align};${colorCss}${fsCss}${fwCss}${lh}${ff}padding:${p.paddingTop}px ${p.paddingRight}px ${p.paddingBottom}px ${p.paddingLeft}px;\">${p.content}</div>`;\n },\n});\n","import type { BlockDefinition } from '@simple-mail/core';\nimport { buttonBlock } from './button';\nimport { dividerBlock } from './divider';\nimport { footerBlock } from './footer';\nimport { heroBlock } from './hero';\nimport { htmlBlock } from './html';\nimport { imageBlock } from './image';\nimport { logoBlock } from './logo';\nimport { socialBlock } from './social';\nimport { socialGroupBlock } from './socialGroup';\nimport { spacerBlock } from './spacer';\nimport { textBlock } from './text';\n\nexport {\n buttonBlock,\n dividerBlock,\n footerBlock,\n heroBlock,\n htmlBlock,\n imageBlock,\n logoBlock,\n socialBlock,\n socialGroupBlock,\n spacerBlock,\n textBlock,\n};\n\n/** 宿主拼装「社交组」类 block 时可复用(mj-social 序列化、侧栏 socialLinkList)。 */\nexport {\n escAttr,\n escMjmlText,\n flexJustifyFromAlign,\n mjSocialElementName,\n mjSocialElementsLines,\n paddingQuad,\n socialIconBorderRadiusCss,\n socialIconBorderRadiusMjml,\n socialIconSpacingPx,\n socialMeta,\n SOCIAL_NETWORK_OPTIONS,\n type SocialGroupLabelStyle,\n type SocialLinkItem,\n} from './socialShared';\n\n/** 内置组件(content 类)。可直接传给 MailEditor.blocks。 */\nexport const builtinBlocks: BlockDefinition<any>[] = [\n textBlock,\n htmlBlock,\n imageBlock,\n socialGroupBlock,\n heroBlock,\n buttonBlock,\n dividerBlock,\n spacerBlock,\n];\n\n/** 业务示例的“自定义”组件。可作为参考或直接使用;正式业务块应由宿主应用注册。 */\nexport const exampleCustomBlocks: BlockDefinition<any>[] = [logoBlock, socialBlock, footerBlock];\n\n/** 全部组件(内置 + 示例自定义)。业务相关块请在使用侧与 `allBlocks` 合并后传入 MailEditor。 */\nexport const allBlocks: BlockDefinition<any>[] = [...builtinBlocks, ...exampleCustomBlocks];\n"],"names":["icons","escapeAttr","s","buttonBlock","defineBlock","p","padding","innerPadding","bw","blockButtonWidthCss","widthAttr","wst","esc","dividerBlock","footerBlock","heroBlock","ctx","w","docContentWidthCss","h","flexAlign","url","htmlBlock","mjRawEmailTableWrap","mjRawCellTypographyFromStyles","imageBlock","href","alt","align","fixedH","sizeStyle","logoBlock","m","mjSocialElementName","network","n","BIZ_SOCIAL_NETWORK_OPTIONS","SOCIAL_NETWORK_OPTIONS","NETWORK_META","escAttr","escMjmlText","socialMeta","paddingQuad","socialIconBorderRadiusMjml","iconSize","radiusPx","size","r","half","socialIconBorderRadiusCss","socialIconSpacingPx","spacing","fallback","flexJustifyFromAlign","mjSocialElementsLines","links","labelStyle","fontSizeRaw","fontSize","fontWeight","normalizeFontWeightStep","textColor","_a","fwEsc","meta","bgColor","attrStr","src","_b","withSrc","label","_c","DEFAULT_BIZ_ELEMENTS","normalizeElements","legacy","l","socialBlock","FONT_WEIGHT_STEP_OPTIONS","pad","br","gap","socAttrs","els","e","inner","fsRaw","fs","fw","radiusCss","jc","items","bg","iconSrc","iconHtml","textHtml","socialGroupBlock","filtered","spacerBlock","textBlock","ff","fwRaw","lh","lhAttr","colorRaw","colorAttr","fsAttr","fwCss","lhRaw","colorCss","fsCss","builtinBlocks","exampleCustomBlocks","allBlocks"],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
|
3
|
+
|
|
4
|
+
case `uname` in
|
|
5
|
+
*CYGWIN*|*MINGW*|*MSYS*)
|
|
6
|
+
if command -v cygpath > /dev/null 2>&1; then
|
|
7
|
+
basedir=`cygpath -w "$basedir"`
|
|
8
|
+
fi
|
|
9
|
+
;;
|
|
10
|
+
esac
|
|
11
|
+
|
|
12
|
+
if [ -z "$NODE_PATH" ]; then
|
|
13
|
+
export NODE_PATH="/home/runner/work/simple-email/simple-email/node_modules/.pnpm/resolve@1.22.12/node_modules/resolve/bin/node_modules:/home/runner/work/simple-email/simple-email/node_modules/.pnpm/resolve@1.22.12/node_modules/resolve/node_modules:/home/runner/work/simple-email/simple-email/node_modules/.pnpm/resolve@1.22.12/node_modules:/home/runner/work/simple-email/simple-email/node_modules/.pnpm/node_modules"
|
|
14
|
+
else
|
|
15
|
+
export NODE_PATH="/home/runner/work/simple-email/simple-email/node_modules/.pnpm/resolve@1.22.12/node_modules/resolve/bin/node_modules:/home/runner/work/simple-email/simple-email/node_modules/.pnpm/resolve@1.22.12/node_modules/resolve/node_modules:/home/runner/work/simple-email/simple-email/node_modules/.pnpm/resolve@1.22.12/node_modules:/home/runner/work/simple-email/simple-email/node_modules/.pnpm/node_modules:$NODE_PATH"
|
|
16
|
+
fi
|
|
17
|
+
if [ -x "$basedir/node" ]; then
|
|
18
|
+
exec "$basedir/node" "$basedir/../resolve/bin/resolve" "$@"
|
|
19
|
+
else
|
|
20
|
+
exec node "$basedir/../resolve/bin/resolve" "$@"
|
|
21
|
+
fi
|
|
@@ -46,6 +46,7 @@ export const heroBlock = defineBlock<HeroProps>({
|
|
|
46
46
|
key: 'verticalAlign',
|
|
47
47
|
label: '文字垂直位置',
|
|
48
48
|
type: 'select',
|
|
49
|
+
selectVariant: 'segmented',
|
|
49
50
|
options: [
|
|
50
51
|
{ label: '靠上', value: 'top' },
|
|
51
52
|
{ label: '居中', value: 'middle' },
|
|
@@ -56,6 +57,7 @@ export const heroBlock = defineBlock<HeroProps>({
|
|
|
56
57
|
key: 'textAlign',
|
|
57
58
|
label: '文字水平对齐',
|
|
58
59
|
type: 'select',
|
|
60
|
+
selectVariant: 'segmented',
|
|
59
61
|
options: [
|
|
60
62
|
{ label: '左', value: 'left' },
|
|
61
63
|
{ label: '居中', value: 'center' },
|
|
@@ -25,6 +25,23 @@ export {
|
|
|
25
25
|
textBlock,
|
|
26
26
|
};
|
|
27
27
|
|
|
28
|
+
/** 宿主拼装「社交组」类 block 时可复用(mj-social 序列化、侧栏 socialLinkList)。 */
|
|
29
|
+
export {
|
|
30
|
+
escAttr,
|
|
31
|
+
escMjmlText,
|
|
32
|
+
flexJustifyFromAlign,
|
|
33
|
+
mjSocialElementName,
|
|
34
|
+
mjSocialElementsLines,
|
|
35
|
+
paddingQuad,
|
|
36
|
+
socialIconBorderRadiusCss,
|
|
37
|
+
socialIconBorderRadiusMjml,
|
|
38
|
+
socialIconSpacingPx,
|
|
39
|
+
socialMeta,
|
|
40
|
+
SOCIAL_NETWORK_OPTIONS,
|
|
41
|
+
type SocialGroupLabelStyle,
|
|
42
|
+
type SocialLinkItem,
|
|
43
|
+
} from './socialShared';
|
|
44
|
+
|
|
28
45
|
/** 内置组件(content 类)。可直接传给 MailEditor.blocks。 */
|
|
29
46
|
export const builtinBlocks: BlockDefinition<any>[] = [
|
|
30
47
|
textBlock,
|
|
@@ -37,8 +54,8 @@ export const builtinBlocks: BlockDefinition<any>[] = [
|
|
|
37
54
|
spacerBlock,
|
|
38
55
|
];
|
|
39
56
|
|
|
40
|
-
/**
|
|
57
|
+
/** 业务示例的“自定义”组件。可作为参考或直接使用;正式业务块应由宿主应用注册。 */
|
|
41
58
|
export const exampleCustomBlocks: BlockDefinition<any>[] = [logoBlock, socialBlock, footerBlock];
|
|
42
59
|
|
|
43
|
-
/** 全部组件(内置 +
|
|
60
|
+
/** 全部组件(内置 + 示例自定义)。业务相关块请在使用侧与 `allBlocks` 合并后传入 MailEditor。 */
|
|
44
61
|
export const allBlocks: BlockDefinition<any>[] = [...builtinBlocks, ...exampleCustomBlocks];
|