@easybits.cloud/html-tailwind-generator 0.2.142 → 0.2.144
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/dist/{chunk-GL74S2H4.js → chunk-4EYTBL6J.js} +3 -3
- package/dist/{chunk-EP65R6DE.js → chunk-CZSPAIBQ.js} +2 -2
- package/dist/{chunk-H2YYYKUI.js → chunk-DCLDOBYZ.js} +10 -3
- package/dist/{chunk-H2YYYKUI.js.map → chunk-DCLDOBYZ.js.map} +1 -1
- package/dist/{chunk-QFT3PN3L.js → chunk-DJUYMGSU.js} +2 -2
- package/dist/{chunk-SJJZEW5W.js → chunk-FOTINBTC.js} +2 -2
- package/dist/{chunk-ULAQDD23.js → chunk-JNSVHTFN.js} +2 -2
- package/dist/{chunk-EIZRTLU6.js → chunk-UQ6THF6E.js} +2 -2
- package/dist/{chunk-7MGKYJTI.js → chunk-XDJMUIKY.js} +21 -12
- package/dist/chunk-XDJMUIKY.js.map +1 -0
- package/dist/components.js +2 -2
- package/dist/components4.d.ts +4 -0
- package/dist/components4.js +6 -2
- package/dist/components4.js.map +1 -1
- package/dist/deploy.js +2 -2
- package/dist/directions.js +2 -2
- package/dist/generate.js +2 -2
- package/dist/generateDocument.js +3 -3
- package/dist/images.js +1 -1
- package/dist/index.js +8 -8
- package/dist/refine.js +2 -2
- package/package.json +1 -1
- package/dist/chunk-7MGKYJTI.js.map +0 -1
- /package/dist/{chunk-GL74S2H4.js.map → chunk-4EYTBL6J.js.map} +0 -0
- /package/dist/{chunk-EP65R6DE.js.map → chunk-CZSPAIBQ.js.map} +0 -0
- /package/dist/{chunk-QFT3PN3L.js.map → chunk-DJUYMGSU.js.map} +0 -0
- /package/dist/{chunk-SJJZEW5W.js.map → chunk-FOTINBTC.js.map} +0 -0
- /package/dist/{chunk-ULAQDD23.js.map → chunk-JNSVHTFN.js.map} +0 -0
- /package/dist/{chunk-EIZRTLU6.js.map → chunk-UQ6THF6E.js.map} +0 -0
package/dist/deploy.js
CHANGED
package/dist/directions.js
CHANGED
package/dist/generate.js
CHANGED
|
@@ -2,10 +2,10 @@ import {
|
|
|
2
2
|
PROMPT_SUFFIX,
|
|
3
3
|
SYSTEM_PROMPT,
|
|
4
4
|
generateLanding
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-DJUYMGSU.js";
|
|
6
6
|
import {
|
|
7
7
|
extractJsonObjects
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-DCLDOBYZ.js";
|
|
9
9
|
import "./chunk-DCAQAHSU.js";
|
|
10
10
|
export {
|
|
11
11
|
PROMPT_SUFFIX,
|
package/dist/generateDocument.js
CHANGED
|
@@ -6,9 +6,9 @@ import {
|
|
|
6
6
|
generateDocumentParallel,
|
|
7
7
|
getDocumentPromptSuffix,
|
|
8
8
|
getDocumentSystemPrompt
|
|
9
|
-
} from "./chunk-
|
|
10
|
-
import "./chunk-
|
|
11
|
-
import "./chunk-
|
|
9
|
+
} from "./chunk-4EYTBL6J.js";
|
|
10
|
+
import "./chunk-JNSVHTFN.js";
|
|
11
|
+
import "./chunk-DCLDOBYZ.js";
|
|
12
12
|
export {
|
|
13
13
|
DOCUMENT_PROMPT_SUFFIX,
|
|
14
14
|
DOCUMENT_SYSTEM_PROMPT,
|
package/dist/images.js
CHANGED
package/dist/index.js
CHANGED
|
@@ -13,23 +13,23 @@ import {
|
|
|
13
13
|
FloatingToolbar,
|
|
14
14
|
SectionList,
|
|
15
15
|
ViewportToggle
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-CZSPAIBQ.js";
|
|
17
17
|
import "./chunk-DUHALQL7.js";
|
|
18
18
|
import {
|
|
19
19
|
PROMPT_SUFFIX,
|
|
20
20
|
SYSTEM_PROMPT,
|
|
21
21
|
generateLanding
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-DJUYMGSU.js";
|
|
23
23
|
import {
|
|
24
24
|
DOCUMENT_PROMPT_SUFFIX,
|
|
25
25
|
DOCUMENT_SYSTEM_PROMPT,
|
|
26
26
|
generateDocument
|
|
27
|
-
} from "./chunk-
|
|
28
|
-
import "./chunk-
|
|
27
|
+
} from "./chunk-4EYTBL6J.js";
|
|
28
|
+
import "./chunk-JNSVHTFN.js";
|
|
29
29
|
import {
|
|
30
30
|
REFINE_SYSTEM,
|
|
31
31
|
refineLanding
|
|
32
|
-
} from "./chunk-
|
|
32
|
+
} from "./chunk-UQ6THF6E.js";
|
|
33
33
|
import {
|
|
34
34
|
enrichImages,
|
|
35
35
|
extractJsonObjects,
|
|
@@ -37,16 +37,16 @@ import {
|
|
|
37
37
|
generateImage,
|
|
38
38
|
generateSvg,
|
|
39
39
|
searchImage
|
|
40
|
-
} from "./chunk-
|
|
40
|
+
} from "./chunk-DCLDOBYZ.js";
|
|
41
41
|
import {
|
|
42
42
|
deployToEasyBits,
|
|
43
43
|
deployToS3
|
|
44
|
-
} from "./chunk-
|
|
44
|
+
} from "./chunk-FOTINBTC.js";
|
|
45
45
|
import {
|
|
46
46
|
buildDeployHtml,
|
|
47
47
|
buildPreviewHtml,
|
|
48
48
|
getIframeScript
|
|
49
|
-
} from "./chunk-
|
|
49
|
+
} from "./chunk-XDJMUIKY.js";
|
|
50
50
|
import {
|
|
51
51
|
LANDING_THEMES,
|
|
52
52
|
buildCustomTheme,
|
package/dist/refine.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@easybits.cloud/html-tailwind-generator",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.144",
|
|
4
4
|
"description": "AI-powered landing page generator with Tailwind CSS — canvas editor, streaming generation, and one-click deploy",
|
|
5
5
|
"license": "PolyForm-Noncommercial-1.0.0",
|
|
6
6
|
"type": "module",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/iframeScript.ts","../src/buildHtml.ts"],"sourcesContent":["/**\n * JavaScript injected into the landing v3 iframe.\n * Handles hover highlights, click selection, contentEditable text editing,\n * postMessage communication with the parent editor,\n * and incremental section injection from parent.\n */\nexport function getIframeScript(): string {\n return `\n(function() {\n let hoveredEl = null;\n let selectedEl = null;\n const SHADOW_HOVER = 'inset 0 0 0 2px #3B82F6';\n const SHADOW_SELECTED = 'inset 0 0 0 2px #8B5CF6';\n\n function getSectionId(el) {\n let node = el;\n while (node && node !== document.body) {\n if (node.dataset && node.dataset.sectionId) {\n return node.dataset.sectionId;\n }\n node = node.parentElement;\n }\n return null;\n }\n\n function getSectionElement(sectionId) {\n return document.querySelector('[data-section-id=\"' + sectionId + '\"]');\n }\n\n function getElementPath(el) {\n const parts = [];\n let node = el;\n while (node && node !== document.body) {\n let tag = node.tagName.toLowerCase();\n if (node.id) { tag += '#' + node.id; }\n const siblings = node.parentElement ? Array.from(node.parentElement.children).filter(function(c) { return c.tagName === node.tagName; }) : [];\n if (siblings.length > 1) { tag += ':nth(' + siblings.indexOf(node) + ')'; }\n parts.unshift(tag);\n node = node.parentElement;\n }\n return parts.join(' > ');\n }\n\n function getCleanSectionHtml(sectionEl) {\n var els = sectionEl.querySelectorAll('*');\n var saved = [];\n for (var i = 0; i < els.length; i++) {\n var s = els[i].style;\n saved.push({ boxShadow: s.boxShadow, ce: els[i].contentEditable });\n s.boxShadow = '';\n if (els[i].contentEditable === 'true') els[i].removeAttribute('contenteditable');\n }\n // Also clean the section root\n var rootShadow = sectionEl.style.boxShadow;\n sectionEl.style.boxShadow = '';\n var html = sectionEl.innerHTML;\n sectionEl.style.boxShadow = rootShadow;\n for (var i = 0; i < els.length; i++) {\n els[i].style.boxShadow = saved[i].boxShadow;\n if (saved[i].ce === 'true') els[i].contentEditable = 'true';\n }\n return html;\n }\n\n function isTextElement(el) {\n var textTags = ['H1','H2','H3','H4','H5','H6','P','DIV','SPAN','LI','A','BLOCKQUOTE','LABEL','TD','TH','FIGCAPTION','BUTTON'];\n return textTags.indexOf(el.tagName) !== -1;\n }\n\n function emitElementSelected(el) {\n var rect = el.getBoundingClientRect();\n var attrs = {};\n if (el.tagName === 'IMG') attrs = { src: el.getAttribute('src') || '', alt: el.getAttribute('alt') || '' };\n if (el.tagName === 'A') attrs = { href: el.getAttribute('href') || '', target: el.getAttribute('target') || '' };\n var ot = el.outerHTML.split('>')[0] + '>';\n if (ot.length > 200) ot = ot.substring(0, 200);\n window.parent.postMessage({\n type: 'element-selected',\n sectionId: getSectionId(el),\n tagName: el.tagName,\n rect: { top: rect.top, left: rect.left, width: rect.width, height: rect.height },\n text: (el.textContent || '').substring(0, 200),\n openTag: ot,\n elementPath: getElementPath(el),\n isSectionRoot: el.dataset && el.dataset.sectionId ? true : false,\n attrs: attrs,\n className: (typeof el.className === 'string' ? el.className : '') || '',\n }, '*');\n }\n\n // Hover\n document.addEventListener('mouseover', function(e) {\n var el = e.target;\n while (el && el !== document.body && (el instanceof SVGElement) && el.tagName !== 'svg') {\n el = el.parentElement;\n }\n if (el && el.tagName === 'svg' && el.parentElement) el = el.parentElement;\n if (el === document.body || el === document.documentElement) return;\n if (el === selectedEl) return;\n if (hoveredEl && hoveredEl !== selectedEl) {\n hoveredEl.style.boxShadow = '';\n }\n hoveredEl = el;\n if (el !== selectedEl) {\n el.style.boxShadow = SHADOW_HOVER;\n }\n });\n\n document.addEventListener('mouseout', function(e) {\n if (hoveredEl && hoveredEl !== selectedEl) {\n hoveredEl.style.boxShadow = '';\n }\n hoveredEl = null;\n });\n\n // Click — select element\n document.addEventListener('click', function(e) {\n e.preventDefault();\n e.stopPropagation();\n var el = e.target;\n\n // Bubble up from SVG internals to the nearest HTML element\n while (el && el !== document.body && (el instanceof SVGElement) && el.tagName !== 'svg') {\n el = el.parentElement;\n }\n // If we landed on an <svg>, bubble up to its HTML parent\n if (el && el.tagName === 'svg' && el.parentElement) {\n el = el.parentElement;\n }\n\n // Deselect previous\n if (selectedEl) {\n selectedEl.style.boxShadow = '';\n }\n\n if (selectedEl === el) {\n selectedEl = null;\n window.parent.postMessage({ type: 'element-deselected' }, '*');\n return;\n }\n\n selectedEl = el;\n\n // Clear hover styles BEFORE capturing openTag (so it matches source HTML)\n el.style.boxShadow = '';\n var openTag = el.outerHTML.substring(0, el.outerHTML.indexOf('>') + 1).substring(0, 120);\n\n el.style.boxShadow = SHADOW_SELECTED;\n\n var rect = el.getBoundingClientRect();\n var attrs = {};\n if (el.tagName === 'IMG') {\n attrs = { src: el.getAttribute('src') || '', alt: el.getAttribute('alt') || '' };\n }\n if (el.tagName === 'A') {\n attrs = { href: el.getAttribute('href') || '', target: el.getAttribute('target') || '' };\n }\n\n window.parent.postMessage({\n type: 'element-selected',\n sectionId: getSectionId(el),\n tagName: el.tagName,\n rect: { top: rect.top, left: rect.left, width: rect.width, height: rect.height },\n text: (el.textContent || '').substring(0, 200),\n openTag: openTag,\n elementPath: getElementPath(el),\n isSectionRoot: el.dataset && el.dataset.sectionId ? true : false,\n attrs: attrs,\n className: el.className || '',\n }, '*');\n }, true);\n\n // Double-click — contentEditable for text\n document.addEventListener('dblclick', function(e) {\n e.preventDefault();\n e.stopPropagation();\n var el = e.target;\n if (!isTextElement(el)) return;\n\n el.contentEditable = 'true';\n el.focus();\n el.style.boxShadow = 'inset 0 0 0 2px #F59E0B';\n\n function onBlur() {\n el.contentEditable = 'false';\n el.style.boxShadow = '';\n el.removeEventListener('blur', onBlur);\n el.removeEventListener('keydown', onKeydown);\n\n var sid = getSectionId(el);\n var sectionEl = sid ? getSectionElement(sid) : null;\n window.parent.postMessage({\n type: 'text-edited',\n sectionId: sid,\n elementPath: getElementPath(el),\n newText: el.innerHTML,\n sectionHtml: sectionEl ? getCleanSectionHtml(sectionEl) : null,\n }, '*');\n\n selectedEl = null;\n }\n\n function onKeydown(ev) {\n if (ev.key === 'Escape') {\n el.blur();\n }\n }\n\n el.addEventListener('blur', onBlur);\n el.addEventListener('keydown', onKeydown);\n }, true);\n\n // Listen for messages FROM parent (incremental section injection)\n window.addEventListener('message', function(e) {\n var msg = e.data;\n if (!msg || !msg.action) return;\n\n if (msg.action === 'add-section') {\n var wrapper = document.createElement('div');\n wrapper.setAttribute('data-section-id', msg.id);\n wrapper.innerHTML = msg.html;\n wrapper.style.animation = 'fadeInUp 0.4s ease-out';\n document.body.appendChild(wrapper);\n if (msg.scroll) {\n wrapper.scrollIntoView({ behavior: 'smooth', block: 'end' });\n }\n }\n\n if (msg.action === 'update-section') {\n var el = getSectionElement(msg.id);\n if (el && typeof window.morphdom === 'function') {\n var tmp = document.createElement('div');\n tmp.innerHTML = msg.html;\n window.morphdom(el, tmp, {\n childrenOnly: true,\n onBeforeElUpdated: function(fromEl, toEl) {\n if (fromEl.isEqualNode(toEl)) return false;\n return true;\n }\n });\n } else if (el) {\n el.innerHTML = msg.html;\n }\n }\n\n if (msg.action === 'rename-section') {\n var el = getSectionElement(msg.oldId);\n if (el) {\n el.setAttribute('data-section-id', msg.newId);\n if (msg.html) {\n if (typeof window.morphdom === 'function') {\n var tmp = document.createElement('div');\n tmp.innerHTML = msg.html;\n window.morphdom(el, tmp, { childrenOnly: true, onBeforeElUpdated: function(f,t){ return !f.isEqualNode(t); } });\n } else {\n el.innerHTML = msg.html;\n }\n }\n }\n }\n\n if (msg.action === 'remove-section') {\n var el = getSectionElement(msg.id);\n if (el) { el.remove(); }\n }\n\n if (msg.action === 'reorder-sections') {\n // msg.order = [id1, id2, id3, ...]\n var order = msg.order;\n for (var i = 0; i < order.length; i++) {\n var el = getSectionElement(order[i]);\n if (el) { document.body.appendChild(el); }\n }\n }\n\n if (msg.action === 'update-attribute') {\n var sectionEl = getSectionElement(msg.sectionId);\n if (sectionEl) {\n var target = null;\n if (msg.elementPath) {\n // Find element by matching path\n var allEls = sectionEl.querySelectorAll(msg.tagName || '*');\n for (var i = 0; i < allEls.length; i++) {\n if (getElementPath(allEls[i]) === msg.elementPath) {\n target = allEls[i];\n break;\n }\n }\n }\n if (target) {\n if (msg.attr === 'style' && msg.value.indexOf(':') !== -1) {\n // Merge style property instead of replacing entire style\n var parts = msg.value.split(':');\n var prop = parts[0].trim();\n var val = parts.slice(1).join(':').trim();\n target.style.setProperty(prop, val);\n } else {\n target.setAttribute(msg.attr, msg.value);\n }\n window.parent.postMessage({\n type: 'section-html-updated',\n sectionId: msg.sectionId,\n sectionHtml: getCleanSectionHtml(sectionEl),\n }, '*');\n emitElementSelected(target);\n }\n }\n }\n\n if (msg.action === 'replace-class') {\n var sectionEl = getSectionElement(msg.sectionId);\n if (sectionEl && msg.elementPath) {\n var target = null;\n var allEls = sectionEl.querySelectorAll('*');\n for (var i = 0; i < allEls.length; i++) {\n if (getElementPath(allEls[i]) === msg.elementPath) {\n target = allEls[i];\n break;\n }\n }\n if (target) {\n // Remove classes matching prefixes (supports responsive variants like md:p-4)\n var prefixes = msg.removePrefixes || [];\n var toRemove = [];\n for (var ci = 0; ci < target.classList.length; ci++) {\n var cls = target.classList[ci];\n var bare = cls.indexOf(':') !== -1 ? cls.substring(cls.lastIndexOf(':') + 1) : cls;\n for (var pi = 0; pi < prefixes.length; pi++) {\n if (bare === prefixes[pi] || bare.indexOf(prefixes[pi]) === 0) {\n toRemove.push(cls);\n break;\n }\n }\n }\n for (var ri = 0; ri < toRemove.length; ri++) {\n target.classList.remove(toRemove[ri]);\n }\n // Add new class\n if (msg.addClass && !target.classList.contains(msg.addClass)) {\n target.classList.add(msg.addClass);\n }\n window.parent.postMessage({\n type: 'section-html-updated',\n sectionId: msg.sectionId,\n sectionHtml: getCleanSectionHtml(sectionEl),\n }, '*');\n emitElementSelected(target);\n }\n }\n }\n\n if (msg.action === 'delete-element') {\n var sectionEl = getSectionElement(msg.sectionId);\n if (sectionEl && msg.elementPath) {\n var target = null;\n var allEls = sectionEl.querySelectorAll('*');\n for (var i = 0; i < allEls.length; i++) {\n if (getElementPath(allEls[i]) === msg.elementPath) {\n target = allEls[i];\n break;\n }\n }\n if (target && target.parentNode) {\n target.parentNode.removeChild(target);\n window.parent.postMessage({\n type: 'section-html-updated',\n sectionId: msg.sectionId,\n sectionHtml: getCleanSectionHtml(sectionEl),\n }, '*');\n window.parent.postMessage({ type: 'element-deselected' }, '*');\n }\n }\n }\n\n if (msg.action === 'change-tag') {\n var sectionEl = getSectionElement(msg.sectionId);\n if (sectionEl && msg.elementPath && msg.newTag) {\n var target = null;\n var allEls = sectionEl.querySelectorAll('*');\n for (var i = 0; i < allEls.length; i++) {\n if (getElementPath(allEls[i]) === msg.elementPath) {\n target = allEls[i];\n break;\n }\n }\n if (target && target.parentNode) {\n var newEl = document.createElement(msg.newTag);\n for (var a = 0; a < target.attributes.length; a++) {\n newEl.setAttribute(target.attributes[a].name, target.attributes[a].value);\n }\n while (target.firstChild) newEl.appendChild(target.firstChild);\n target.parentNode.replaceChild(newEl, target);\n window.parent.postMessage({\n type: 'section-html-updated',\n sectionId: msg.sectionId,\n sectionHtml: getCleanSectionHtml(sectionEl),\n }, '*');\n emitElementSelected(newEl);\n }\n }\n }\n\n if (msg.action === 'set-theme') {\n if (msg.theme && msg.theme !== 'default') {\n document.documentElement.setAttribute('data-theme', msg.theme);\n } else {\n document.documentElement.removeAttribute('data-theme');\n }\n }\n\n if (msg.action === 'set-custom-css') {\n var customStyle = document.getElementById('custom-theme-css');\n if (!customStyle) {\n customStyle = document.createElement('style');\n customStyle.id = 'custom-theme-css';\n document.head.appendChild(customStyle);\n }\n customStyle.textContent = msg.css || '';\n }\n\n if (msg.action === 'scroll-to-section') {\n var el = getSectionElement(msg.id);\n if (el) { el.scrollIntoView({ behavior: 'smooth', block: 'start' }); }\n }\n\n if (msg.action === 'get-scroll') {\n window.parent.postMessage({ type: 'scroll-position', y: window.scrollY }, '*');\n }\n\n if (msg.action === 'restore-scroll') {\n window.scrollTo(0, msg.y);\n }\n\n if (msg.action === 'element-loading') {\n var sectionEl = getSectionElement(msg.sectionId);\n if (sectionEl && msg.elementPath) {\n var allEls = sectionEl.querySelectorAll('*');\n for (var i = 0; i < allEls.length; i++) {\n if (getElementPath(allEls[i]) === msg.elementPath) {\n var el = allEls[i];\n el.style.position = 'relative';\n el.style.overflow = 'hidden';\n var overlay = document.createElement('div');\n overlay.setAttribute('data-loading-overlay', 'true');\n overlay.style.cssText = 'position:absolute;inset:0;z-index:999;border-radius:inherit;background:linear-gradient(90deg,rgba(255,255,255,0) 0%,rgba(255,255,255,0.6) 50%,rgba(255,255,255,0) 100%);background-size:200% 100%;animation:shimmer 1.5s infinite;pointer-events:none;';\n el.appendChild(overlay);\n break;\n }\n }\n }\n }\n\n if (msg.action === 'element-loading-clear') {\n var overlays = document.querySelectorAll('[data-loading-overlay]');\n for (var i = 0; i < overlays.length; i++) {\n overlays[i].remove();\n }\n }\n\n if (msg.action === 'preview-version') {\n var el = getSectionElement(msg.sectionId);\n if (el) {\n // Store original html if not already stored\n if (!el.dataset.originalHtml) {\n el.dataset.originalHtml = el.innerHTML;\n }\n el.innerHTML = msg.html;\n el.style.outline = '2px dashed #8B5CF6';\n el.style.outlineOffset = '-2px';\n el.style.opacity = '0.85';\n }\n }\n\n if (msg.action === 'exit-preview') {\n var el = getSectionElement(msg.sectionId);\n if (el && el.dataset.originalHtml) {\n el.innerHTML = el.dataset.originalHtml;\n delete el.dataset.originalHtml;\n el.style.outline = '';\n el.style.outlineOffset = '';\n el.style.opacity = '';\n }\n }\n\n if (msg.action === 'full-rewrite') {\n // Fallback: rewrite everything\n document.body.innerHTML = msg.html;\n }\n });\n\n // Forward Cmd/Ctrl+Z undo/redo to parent (iframe captures keyboard focus)\n document.addEventListener('keydown', function(e) {\n if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === 'z') {\n e.preventDefault();\n window.parent.postMessage({ type: e.shiftKey ? 'redo' : 'undo' }, '*');\n }\n if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === 'y') {\n e.preventDefault();\n window.parent.postMessage({ type: 'redo' }, '*');\n }\n });\n\n // Image loading placeholders\n function setupImagePlaceholder(img) {\n if (img.complete && img.naturalWidth > 0) return;\n img.style.background = 'linear-gradient(90deg, #e5e7eb 25%, #f3f4f6 50%, #e5e7eb 75%)';\n img.style.backgroundSize = '200% 100%';\n img.style.animation = 'shimmer 1.5s infinite';\n if (!img.style.minHeight && !img.getAttribute('height')) img.style.minHeight = '120px';\n function onDone() {\n img.style.background = '';\n img.style.backgroundSize = '';\n img.style.animation = '';\n if (img.style.minHeight === '120px') img.style.minHeight = '';\n img.removeEventListener('load', onDone);\n img.removeEventListener('error', onDone);\n }\n img.addEventListener('load', onDone);\n img.addEventListener('error', onDone);\n }\n // Observe new/changed images\n var imgObserver = new MutationObserver(function(mutations) {\n for (var m = 0; m < mutations.length; m++) {\n // New nodes\n for (var n = 0; n < mutations[m].addedNodes.length; n++) {\n var node = mutations[m].addedNodes[n];\n if (node.tagName === 'IMG') setupImagePlaceholder(node);\n if (node.querySelectorAll) {\n var imgs = node.querySelectorAll('img');\n for (var i = 0; i < imgs.length; i++) setupImagePlaceholder(imgs[i]);\n }\n }\n // src attribute changed\n if (mutations[m].type === 'attributes' && mutations[m].attributeName === 'src' && mutations[m].target.tagName === 'IMG') {\n setupImagePlaceholder(mutations[m].target);\n }\n }\n });\n imgObserver.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['src'] });\n // Initial images\n var existingImgs = document.querySelectorAll('img');\n for (var ii = 0; ii < existingImgs.length; ii++) setupImagePlaceholder(existingImgs[ii]);\n\n // Inject animation keyframes\n var style = document.createElement('style');\n style.textContent = '@keyframes fadeInUp { from { opacity:0; transform:translateY(20px); } to { opacity:1; transform:translateY(0); } } @keyframes shimmer { 0% { background-position: -200% 0; } 100% { background-position: 200% 0; } }';\n document.head.appendChild(style);\n\n // Notify parent we're ready\n window.parent.postMessage({ type: 'ready' }, '*');\n})();\n`;\n}\n","import type { Section3 } from \"./types\";\nimport { getIframeScript } from \"./iframeScript\";\nimport { buildThemeCss, buildSingleThemeCss, buildCustomTheme, type CustomColors } from \"./themes\";\n\n/**\n * Build the full HTML for the iframe preview (with editing script).\n */\nexport function buildPreviewHtml(sections: Section3[], theme?: string): string {\n const sorted = [...sections].sort((a, b) => a.order - b.order);\n const body = sorted\n .map((s) => `<div data-section-id=\"${s.id}\">${s.html}</div>`)\n .join(\"\\n\");\n\n const dataTheme = theme && theme !== \"default\" ? ` data-theme=\"${theme}\"` : \"\";\n const { css, tailwindConfig } = buildThemeCss();\n\n return `<!DOCTYPE html>\n<html lang=\"es\"${dataTheme}>\n<head>\n<meta charset=\"UTF-8\"/>\n<meta name=\"viewport\" content=\"width=device-width,initial-scale=1\"/>\n<script src=\"https://cdn.tailwindcss.com\"></script>\n<script src=\"https://unpkg.com/morphdom@2.7.4/dist/morphdom-umd.min.js\"></script>\n<script>tailwind.config = ${tailwindConfig}</script>\n<style>\n${css}\n*{margin:0;padding:0;box-sizing:border-box}\nhtml{scroll-behavior:smooth}\nbody{font-family:system-ui,-apple-system,sans-serif;background-color:var(--color-surface);color:var(--color-on-surface)}\nimg{max-width:100%}\nsection{width:100%}\nsection>*{max-width:80rem;margin-left:auto;margin-right:auto;padding-left:1rem;padding-right:1rem}\n[contenteditable=\"true\"]{cursor:text}\n</style>\n</head>\n<body class=\"bg-surface text-on-surface\">\n${body}\n<script>${getIframeScript()}</script>\n</body>\n</html>`;\n}\n\n/**\n * Build the deploy HTML (no editing script, clean output).\n */\n/**\n * Remove editor artifacts (outline, outlineOffset, contenteditable) from HTML before deploy.\n */\nfunction stripEditorArtifacts(html: string): string {\n return html\n .replace(/\\s*outline:\\s*[^;\"]+;?/gi, \"\")\n .replace(/\\s*outline-offset:\\s*[^;\"]+;?/gi, \"\")\n .replace(/\\s*style=\"\\s*\"/gi, \"\")\n .replace(/\\s+contenteditable=\"[^\"]*\"/gi, \"\")\n .replace(/\\s+data-section-id=\"[^\"]*\"/gi, \"\")\n}\n\nexport function buildDeployHtml(sections: Section3[], theme?: string, customColors?: CustomColors, showBranding = true): string {\n const sorted = [...sections].sort((a, b) => a.order - b.order);\n const body = sorted.map((s) => stripEditorArtifacts(s.html)).join(\"\\n\");\n\n const isCustom = theme === \"custom\" && customColors;\n const dataTheme = theme && theme !== \"default\" && !isCustom ? ` data-theme=\"${theme}\"` : \"\";\n\n // For custom theme, build CSS from the custom colors directly (no data-theme needed, inject as :root)\n const { css: baseCss, tailwindConfig } = isCustom\n ? (() => {\n const ct = buildCustomTheme(customColors);\n const vars = Object.entries(ct.colors).map(([k, v]) => ` --color-${k}: ${v};`).join(\"\\n\");\n return { css: `:root {\\n${vars}\\n}`, tailwindConfig: buildSingleThemeCss(\"default\").tailwindConfig };\n })()\n : buildSingleThemeCss(theme || \"default\");\n\n return `<!DOCTYPE html>\n<html lang=\"es\"${dataTheme}>\n<head>\n<meta charset=\"UTF-8\"/>\n<meta name=\"viewport\" content=\"width=device-width,initial-scale=1\"/>\n<title>Landing Page</title>\n<script src=\"https://cdn.tailwindcss.com\"></script>\n<script>tailwind.config = ${tailwindConfig}</script>\n<style>\n${baseCss}\n*{margin:0;padding:0;box-sizing:border-box}\nhtml{scroll-behavior:smooth}\nbody{font-family:system-ui,-apple-system,sans-serif;background-color:var(--color-surface);color:var(--color-on-surface)}\nsection{width:100%}\nsection>*{max-width:80rem;margin-left:auto;margin-right:auto;padding-left:1rem;padding-right:1rem}\n</style>\n</head>\n<body class=\"bg-surface text-on-surface\">\n${body}\n${showBranding ? `<div style=\"text-align:center;padding:16px 0 12px;font-size:12px\">\n <a href=\"https://www.easybits.cloud\" target=\"_blank\" rel=\"noopener\"\n style=\"color:#9ca3af;text-decoration:none\">\n Powered by easybits.cloud\n </a>\n</div>` : \"\"}\n</body>\n</html>`;\n}\n"],"mappings":";;;;;;;AAMO,SAAS,kBAA0B;AACxC,SAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAiiBT;;;ACjiBO,SAAS,iBAAiB,UAAsB,OAAwB;AAC7E,QAAM,SAAS,CAAC,GAAG,QAAQ,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,QAAQ,EAAE,KAAK;AAC7D,QAAM,OAAO,OACV,IAAI,CAAC,MAAM,yBAAyB,EAAE,EAAE,KAAK,EAAE,IAAI,QAAQ,EAC3D,KAAK,IAAI;AAEZ,QAAM,YAAY,SAAS,UAAU,YAAY,gBAAgB,KAAK,MAAM;AAC5E,QAAM,EAAE,KAAK,eAAe,IAAI,cAAc;AAE9C,SAAO;AAAA,iBACQ,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,4BAME,cAAc;AAAA;AAAA,EAExC,GAAG;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWH,IAAI;AAAA,UACI,gBAAgB,CAAC;AAAA;AAAA;AAG3B;AAQA,SAAS,qBAAqB,MAAsB;AAClD,SAAO,KACJ,QAAQ,4BAA4B,EAAE,EACtC,QAAQ,mCAAmC,EAAE,EAC7C,QAAQ,oBAAoB,EAAE,EAC9B,QAAQ,gCAAgC,EAAE,EAC1C,QAAQ,gCAAgC,EAAE;AAC/C;AAEO,SAAS,gBAAgB,UAAsB,OAAgB,cAA6B,eAAe,MAAc;AAC9H,QAAM,SAAS,CAAC,GAAG,QAAQ,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,QAAQ,EAAE,KAAK;AAC7D,QAAM,OAAO,OAAO,IAAI,CAAC,MAAM,qBAAqB,EAAE,IAAI,CAAC,EAAE,KAAK,IAAI;AAEtE,QAAM,WAAW,UAAU,YAAY;AACvC,QAAM,YAAY,SAAS,UAAU,aAAa,CAAC,WAAW,gBAAgB,KAAK,MAAM;AAGzF,QAAM,EAAE,KAAK,SAAS,eAAe,IAAI,YACpC,MAAM;AACL,UAAM,KAAK,iBAAiB,YAAY;AACxC,UAAM,OAAO,OAAO,QAAQ,GAAG,MAAM,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,aAAa,CAAC,KAAK,CAAC,GAAG,EAAE,KAAK,IAAI;AACzF,WAAO,EAAE,KAAK;AAAA,EAAY,IAAI;AAAA,IAAO,gBAAgB,oBAAoB,SAAS,EAAE,eAAe;AAAA,EACrG,GAAG,IACH,oBAAoB,SAAS,SAAS;AAE1C,SAAO;AAAA,iBACQ,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,4BAME,cAAc;AAAA;AAAA,EAExC,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASP,IAAI;AAAA,EACJ,eAAe;AAAA;AAAA;AAAA;AAAA;AAAA,UAKP,EAAE;AAAA;AAAA;AAGZ;","names":[]}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|