@orangecatai/adgen-canvas 0.0.39 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/dev/chunk-2K6ZAAHB.js +1535 -0
- package/dist/dev/chunk-2K6ZAAHB.js.map +7 -0
- package/dist/dev/{chunk-E7VZGEUJ.js → chunk-2Q5Z4UTF.js} +2 -2
- package/dist/dev/{chunk-E7VZGEUJ.js.map → chunk-2Q5Z4UTF.js.map} +1 -1
- package/dist/dev/{chunk-LIELFD5T.js → chunk-3WIRZ6S7.js} +6 -1
- package/dist/dev/chunk-3WIRZ6S7.js.map +7 -0
- package/dist/dev/{chunk-5XP2WJAQ.js → chunk-7XZBXIDZ.js} +1300 -1252
- package/dist/dev/chunk-7XZBXIDZ.js.map +7 -0
- package/dist/dev/chunk-AKA4GZ3R.js +62 -0
- package/dist/dev/chunk-AKA4GZ3R.js.map +7 -0
- package/dist/dev/chunk-LWUV2KR2.js +27 -0
- package/dist/dev/chunk-LWUV2KR2.js.map +7 -0
- package/dist/dev/chunk-T57LHRZV.js +2167 -0
- package/dist/dev/chunk-T57LHRZV.js.map +7 -0
- package/dist/dev/components/auto-resize/nativeResizeAgent-5XWJJ74W.js +1074 -0
- package/dist/dev/components/auto-resize/nativeResizeAgent-5XWJJ74W.js.map +7 -0
- package/dist/dev/data/{image-PUPXCX7M.js → image-MTDE3WXB.js} +4 -3
- package/dist/dev/index.css +618 -27
- package/dist/dev/index.css.map +3 -3
- package/dist/dev/index.js +6769 -8217
- package/dist/dev/index.js.map +4 -4
- package/dist/dev/locales/{en-VCZQBJ2N.js → en-3S2H3QGO.js} +2 -2
- package/dist/dev/model-capabilities.js +47 -0
- package/dist/dev/model-capabilities.js.map +7 -0
- package/dist/dev/subset-shared.chunk.js +1 -1
- package/dist/dev/subset-worker.chunk.js +1 -1
- package/dist/prod/chunk-6YYSQB5E.js +1 -0
- package/dist/prod/{chunk-CLQPYXMS.js → chunk-PIM2DC2L.js} +3 -3
- package/dist/prod/chunk-POCDVKZK.js +142 -0
- package/dist/prod/chunk-PWBUVPCU.js +1 -0
- package/dist/prod/{chunk-WBFDC4WN.js → chunk-R4DNAEVN.js} +1 -1
- package/dist/prod/chunk-U2I2OXQ7.js +4 -0
- package/dist/prod/chunk-UR7GPHHO.js +1 -0
- package/dist/prod/components/auto-resize/nativeResizeAgent-45UNA3LO.js +5 -0
- package/dist/prod/data/image-U4RMOYQQ.js +1 -0
- package/dist/prod/index.css +1 -1
- package/dist/prod/index.js +67 -298
- package/dist/prod/locales/{en-ZZURI326.js → en-Z3CKUL4S.js} +1 -1
- package/dist/prod/model-capabilities.js +1 -0
- package/dist/prod/subset-shared.chunk.js +1 -1
- package/dist/prod/subset-worker.chunk.js +1 -1
- package/dist/types/common/src/utils.d.ts +4 -1
- package/dist/types/element/src/index.d.ts +3 -0
- package/dist/types/element/src/newElement.d.ts +2 -1
- package/dist/types/element/src/textHtml.d.ts +14 -0
- package/dist/types/element/src/textLayout.d.ts +97 -0
- package/dist/types/element/src/textStyleRanges.d.ts +62 -0
- package/dist/types/element/src/textWrapping.d.ts +27 -0
- package/dist/types/element/src/types.d.ts +35 -0
- package/dist/types/excalidraw/actions/actionFrame.d.ts +1 -0
- package/dist/types/excalidraw/actions/actionLinearEditor.d.ts +1 -0
- package/dist/types/excalidraw/actions/actionProperties.d.ts +50 -0
- package/dist/types/excalidraw/actions/index.d.ts +1 -1
- package/dist/types/excalidraw/actions/types.d.ts +1 -1
- package/dist/types/excalidraw/components/AIChatPanel.d.ts +18 -2
- package/dist/types/excalidraw/components/App.d.ts +6 -0
- package/dist/types/excalidraw/components/FontSizeInput.d.ts +19 -0
- package/dist/types/excalidraw/components/ImageGeneratorPanel.d.ts +946 -45
- package/dist/types/excalidraw/components/VideoGeneratorPanel.d.ts +67 -53
- package/dist/types/excalidraw/components/ai-chat/ActivityTimeline.d.ts +18 -0
- package/dist/types/excalidraw/components/ai-chat/activitySteps.d.ts +106 -0
- package/dist/types/excalidraw/components/ai-chat/agentLoop.d.ts +66 -3
- package/dist/types/excalidraw/components/ai-chat/canvasTools.d.ts +23 -8
- package/dist/types/excalidraw/components/ai-chat/htmlToExcalidraw.d.ts +3 -0
- package/dist/types/excalidraw/components/ai-chat/openRouterStream.d.ts +13 -0
- package/dist/types/excalidraw/components/auto-resize/ResizeActivityCard.d.ts +7 -0
- package/dist/types/excalidraw/components/auto-resize/autoResizeEngine.d.ts +5 -2
- package/dist/types/excalidraw/components/auto-resize/autoResizeStore.d.ts +23 -0
- package/dist/types/excalidraw/components/auto-resize/imageBounds.d.ts +11 -0
- package/dist/types/excalidraw/components/auto-resize/nativeResizeAgent.d.ts +5 -0
- package/dist/types/excalidraw/components/auto-resize/resizeFitting.d.ts +7 -0
- package/dist/types/excalidraw/components/auto-resize/resizeLayout.d.ts +33 -0
- package/dist/types/excalidraw/components/icons.d.ts +6 -0
- package/dist/types/excalidraw/components/template-builder/TemplateBuilderTray.d.ts +1 -0
- package/dist/types/excalidraw/index.d.ts +9 -0
- package/dist/types/excalidraw/modelCapabilities/index.d.ts +17 -0
- package/dist/types/excalidraw/modelCapabilities/registry.image.d.ts +2 -0
- package/dist/types/excalidraw/modelCapabilities/registry.video.d.ts +2 -0
- package/dist/types/excalidraw/modelCapabilities/shared.d.ts +24 -0
- package/dist/types/excalidraw/modelCapabilities/types.d.ts +276 -0
- package/dist/types/excalidraw/modelCapabilities/validate.d.ts +48 -0
- package/dist/types/excalidraw/types.d.ts +4 -4
- package/dist/types/excalidraw/utils/imageApi.d.ts +3 -0
- package/dist/types/excalidraw/utils/referenceBudget.d.ts +12 -23
- package/dist/types/excalidraw/utils/videoApi.d.ts +21 -1
- package/dist/types/excalidraw/wysiwyg/richTextEditable.d.ts +36 -0
- package/dist/types/excalidraw/wysiwyg/textSelectionStyles.d.ts +32 -0
- package/dist/types/excalidraw/wysiwyg/textWysiwyg.d.ts +6 -2
- package/package.json +10 -4
- package/dist/dev/chunk-5XP2WJAQ.js.map +0 -7
- package/dist/dev/chunk-LIELFD5T.js.map +0 -7
- package/dist/prod/chunk-T3ZLBHX4.js +0 -4
- package/dist/prod/data/image-AG3CTRSJ.js +0 -1
- /package/dist/dev/data/{image-PUPXCX7M.js.map → image-MTDE3WXB.js.map} +0 -0
- /package/dist/dev/locales/{en-VCZQBJ2N.js.map → en-3S2H3QGO.js.map} +0 -0
|
@@ -38,7 +38,7 @@ import {
|
|
|
38
38
|
ttd,
|
|
39
39
|
userList,
|
|
40
40
|
welcomeScreen
|
|
41
|
-
} from "../chunk-
|
|
41
|
+
} from "../chunk-3WIRZ6S7.js";
|
|
42
42
|
import "../chunk-XDFCUUT6.js";
|
|
43
43
|
export {
|
|
44
44
|
alerts,
|
|
@@ -81,4 +81,4 @@ export {
|
|
|
81
81
|
userList,
|
|
82
82
|
welcomeScreen
|
|
83
83
|
};
|
|
84
|
-
//# sourceMappingURL=en-
|
|
84
|
+
//# sourceMappingURL=en-3S2H3QGO.js.map
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ALL_MODEL_CAPABILITIES,
|
|
3
|
+
AUTO_DURATION,
|
|
4
|
+
IMAGE_MODEL_CAPABILITIES,
|
|
5
|
+
VIDEO_MODEL_CAPABILITIES,
|
|
6
|
+
allowedResolutionsFor,
|
|
7
|
+
effectiveUserReferenceLimit,
|
|
8
|
+
getCapabilities,
|
|
9
|
+
groupImages,
|
|
10
|
+
maxResolutionFor,
|
|
11
|
+
normalizeInputs,
|
|
12
|
+
registeredModelIds,
|
|
13
|
+
requiredDurationFor,
|
|
14
|
+
validateInputs
|
|
15
|
+
} from "./chunk-2K6ZAAHB.js";
|
|
16
|
+
import {
|
|
17
|
+
ADAPTIVE_ASPECT_RATIO,
|
|
18
|
+
HOST_ASSET_BYTE_RESERVATION,
|
|
19
|
+
MAX_REFERENCE_IMAGES,
|
|
20
|
+
MAX_USER_REFERENCE_IMAGES,
|
|
21
|
+
REFERENCE_WIRE_BUDGET_BYTES,
|
|
22
|
+
RESOLUTION_RANK
|
|
23
|
+
} from "./chunk-LWUV2KR2.js";
|
|
24
|
+
import "./chunk-2Q5Z4UTF.js";
|
|
25
|
+
import "./chunk-XDFCUUT6.js";
|
|
26
|
+
export {
|
|
27
|
+
ADAPTIVE_ASPECT_RATIO,
|
|
28
|
+
ALL_MODEL_CAPABILITIES,
|
|
29
|
+
AUTO_DURATION,
|
|
30
|
+
HOST_ASSET_BYTE_RESERVATION,
|
|
31
|
+
IMAGE_MODEL_CAPABILITIES,
|
|
32
|
+
MAX_REFERENCE_IMAGES,
|
|
33
|
+
MAX_USER_REFERENCE_IMAGES,
|
|
34
|
+
REFERENCE_WIRE_BUDGET_BYTES,
|
|
35
|
+
RESOLUTION_RANK,
|
|
36
|
+
VIDEO_MODEL_CAPABILITIES,
|
|
37
|
+
allowedResolutionsFor,
|
|
38
|
+
effectiveUserReferenceLimit,
|
|
39
|
+
getCapabilities,
|
|
40
|
+
groupImages,
|
|
41
|
+
maxResolutionFor,
|
|
42
|
+
normalizeInputs,
|
|
43
|
+
registeredModelIds,
|
|
44
|
+
requiredDurationFor,
|
|
45
|
+
validateInputs
|
|
46
|
+
};
|
|
47
|
+
//# sourceMappingURL=model-capabilities.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var t=6,n=12,r=33554432e-1,a=180*1024,o={"0.5k":1,"480p":2,"720p":3,"1k":4,"1.5k":5,"1080p":6,"2k":7,"3k":8,"4k":9},i="adaptive";export{t as a,n as b,r as c,a as d,o as e,i as f};
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
var t={paste:"Paste",pasteAsPlaintext:"Paste as plaintext",pasteCharts:"Paste charts",selectAll:"Select all",multiSelect:"Add element to selection",moveCanvas:"Move canvas",cut:"Cut",copy:"Copy",copyAsPng:"Copy to clipboard as PNG",copyAsSvg:"Copy to clipboard as SVG",copyText:"Copy to clipboard as text",copySource:"Copy source to clipboard",convertToCode:"Convert to code",bringForward:"Bring forward",sendToBack:"Send to back",bringToFront:"Bring to front",sendBackward:"Send backward",delete:"Delete",copyStyles:"Copy styles",pasteStyles:"Paste styles",stroke:"Stroke",changeStroke:"Change stroke color",background:"Background",changeBackground:"Change background color",fill:"Fill",strokeWidth:"Stroke width",strokeStyle:"Stroke style",strokeStyle_solid:"Solid",strokeStyle_dashed:"Dashed",strokeStyle_dotted:"Dotted",sloppiness:"Sloppiness",opacity:"Opacity",textAlign:"Text align",edges:"Edges",sharp:"Sharp",round:"Round",arrowheads:"Arrowheads",arrowhead_none:"None",arrowhead_arrow:"Arrow",arrowhead_bar:"Bar",arrowhead_circle:"Circle",arrowhead_circle_outline:"Circle (outline)",arrowhead_triangle:"Triangle",arrowhead_triangle_outline:"Triangle (outline)",arrowhead_diamond:"Diamond",arrowhead_diamond_outline:"Diamond (outline)",arrowhead_crowfoot_many:"Crow's foot (many)",arrowhead_crowfoot_one:"Crow's foot (one)",arrowhead_crowfoot_one_or_many:"Crow's foot (one or many)",more_options:"More options",arrowtypes:"Arrow type",arrowtype_sharp:"Sharp arrow",arrowtype_round:"Curved arrow",arrowtype_elbowed:"Elbow arrow",fontSize:"Font size",fontFamily:"Font family",addWatermark:'Add "Made with Excalidraw"',handDrawn:"Hand-drawn",normal:"Normal",code:"Code",small:"Small",medium:"Medium",large:"Large",veryLarge:"Very large",solid:"Solid",hachure:"Hachure",zigzag:"Zigzag",crossHatch:"Cross-hatch",thin:"Thin",bold:"Bold",left:"Left",center:"Center",right:"Right",extraBold:"Extra bold",architect:"Architect",artist:"Artist",cartoonist:"Cartoonist",fileTitle:"File name",colorPicker:"Color picker",canvasColors:"Used on canvas",canvasBackground:"Canvas background",drawingCanvas:"Drawing canvas",clearCanvas:"Clear canvas",layers:"Layers",actions:"Actions",language:"Language",liveCollaboration:"Live collaboration...",duplicateSelection:"Duplicate",untitled:"Untitled",name:"Name",yourName:"Your name",madeWithExcalidraw:"Made with Excalidraw",group:"Group selection",ungroup:"Ungroup selection",collaborators:"Collaborators",toggleGrid:"Toggle grid",addToLibrary:"Add to library",removeFromLibrary:"Remove from library",libraryLoadingMessage:"Loading library\u2026",libraries:"Browse libraries",loadingScene:"Loading scene\u2026",loadScene:"Load scene from file",align:"Align",alignTop:"Align top",alignBottom:"Align bottom",alignLeft:"Align left",alignRight:"Align right",centerVertically:"Center vertically",centerHorizontally:"Center horizontally",distributeHorizontally:"Distribute horizontally",distributeVertically:"Distribute vertically",flipHorizontal:"Flip horizontal",flipVertical:"Flip vertical",viewMode:"View mode",share:"Share",showStroke:"Show stroke color picker",showBackground:"Show background color picker",showFonts:"Show font picker",toggleTheme:"Toggle light/dark theme",theme:"Theme",personalLib:"Personal Library",excalidrawLib:"Excalidraw Library",decreaseFontSize:"Decrease font size",increaseFontSize:"Increase font size",unbindText:"Unbind text",bindText:"Bind text to the container",createContainerFromText:"Wrap text in a container",link:{edit:"Edit link",editEmbed:"Edit embeddable link",create:"Add link",label:"Link",labelEmbed:"Link & embed",empty:"No link is set",hint:"Type or paste your link here",goToElement:"Go to target element"},lineEditor:{edit:"Edit line",editArrow:"Edit arrow"},polygon:{breakPolygon:"Break polygon",convertToPolygon:"Convert to polygon"},elementLock:{lock:"Lock",unlock:"Unlock",lockAll:"Lock all",unlockAll:"Unlock all"},statusPublished:"Published",sidebarLock:"Keep sidebar open",selectAllElementsInFrame:"Select all elements in frame",removeAllElementsFromFrame:"Remove all elements from frame",cycleThroughFrameChildren:"Cycle through frame elements",eyeDropper:"Pick color from canvas",textToDiagram:"Text to diagram",prompt:"Prompt",followUs:"Follow us",discordChat:"Discord chat",zoomToFitViewport:"Zoom to fit in viewport",zoomToFitSelection:"Zoom to fit selection",zoomToFit:"Zoom to fit all elements",installPWA:"Install Excalidraw locally (PWA)",autoResize:"Enable text auto-resizing",imageCropping:"Image cropping",unCroppedDimension:"Uncropped dimension",copyElementLink:"Copy link to object",linkToElement:"Link to object",wrapSelectionInFrame:"Wrap selection in frame",tab:"Tab",shapeSwitch:"Switch shape",preferences:"Preferences",preferences_toolLock:"Tool lock"},r={title:"Link to object",desc:"Click on a shape on canvas or paste a link.",notFound:"Linked object wasn't found on canvas."},a={noItems:"No items added yet...",hint_emptyLibrary:"Select an item on canvas to add it here, or install a library from the public repository, below.",hint_emptyPrivateLibrary:"Select an item on canvas to add it here.",search:{inputPlaceholder:"Search library",heading:"Library matches",noResults:"No matching items found...",clearSearch:"Clear search"}},i={title:"Find on canvas",noMatch:"No matches found...",singleResult:"result",multipleResults:"results",placeholder:"Find text on canvas...",frames:"Frames",texts:"Texts"},n={clearReset:"Reset the canvas",exportJSON:"Export to file",exportImage:"Export image...",export:"Save to...",copyToClipboard:"Copy to clipboard",copyLink:"Copy link",save:"Save to current file",saveAs:"Save as",load:"Open",getShareableLink:"Get shareable link",close:"Close",selectLanguage:"Select language",scrollBackToContent:"Scroll back to content",zoomIn:"Zoom in",zoomOut:"Zoom out",resetZoom:"Reset zoom",menu:"Menu",done:"Done",edit:"Edit",undo:"Undo",redo:"Redo",resetLibrary:"Reset library",createNewRoom:"Create new room",fullScreen:"Full screen",darkMode:"Dark mode",lightMode:"Light mode",systemMode:"System mode",zenMode:"Zen mode",objectsSnapMode:"Snap to objects",exitZenMode:"Exit zen mode",cancel:"Cancel",saveLibNames:"Save name(s) and exit",clear:"Clear",remove:"Remove",embed:"Toggle embedding",publishLibrary:"Rename or publish",submit:"Submit",confirm:"Confirm",embeddableInteractionButton:"Click to interact"},l={clearReset:"This will clear the whole canvas. Are you sure?",couldNotCreateShareableLink:"Couldn't create shareable link.",couldNotCreateShareableLinkTooBig:"Couldn't create shareable link: the scene is too big",couldNotLoadInvalidFile:"Couldn't load invalid file",importBackendFailed:"Importing from backend failed.",cannotExportEmptyCanvas:"Cannot export empty canvas.",couldNotCopyToClipboard:"Couldn't copy to clipboard.",decryptFailed:"Couldn't decrypt data.",uploadedSecurly:"The upload has been secured with end-to-end encryption, which means that Excalidraw server and third parties can't read the content.",loadSceneOverridePrompt:"Loading external drawing will replace your existing content. Do you wish to continue?",collabStopOverridePrompt:`Stopping the session will overwrite your previous, locally stored drawing. Are you sure?
|
|
1
|
+
var t={paste:"Paste",pasteAsPlaintext:"Paste as plaintext",pasteCharts:"Paste charts",selectAll:"Select all",multiSelect:"Add element to selection",moveCanvas:"Move canvas",cut:"Cut",copy:"Copy",copyAsPng:"Copy to clipboard as PNG",copyAsSvg:"Copy to clipboard as SVG",copyText:"Copy to clipboard as text",copySource:"Copy source to clipboard",convertToCode:"Convert to code",bringForward:"Bring forward",sendToBack:"Send to back",bringToFront:"Bring to front",sendBackward:"Send backward",delete:"Delete",copyStyles:"Copy styles",pasteStyles:"Paste styles",stroke:"Stroke",changeStroke:"Change stroke color",background:"Background",changeBackground:"Change background color",fill:"Fill",strokeWidth:"Stroke width",strokeStyle:"Stroke style",strokeStyle_solid:"Solid",strokeStyle_dashed:"Dashed",strokeStyle_dotted:"Dotted",sloppiness:"Sloppiness",opacity:"Opacity",textAlign:"Text align",edges:"Edges",sharp:"Sharp",round:"Round",arrowheads:"Arrowheads",arrowhead_none:"None",arrowhead_arrow:"Arrow",arrowhead_bar:"Bar",arrowhead_circle:"Circle",arrowhead_circle_outline:"Circle (outline)",arrowhead_triangle:"Triangle",arrowhead_triangle_outline:"Triangle (outline)",arrowhead_diamond:"Diamond",arrowhead_diamond_outline:"Diamond (outline)",arrowhead_crowfoot_many:"Crow's foot (many)",arrowhead_crowfoot_one:"Crow's foot (one)",arrowhead_crowfoot_one_or_many:"Crow's foot (one or many)",more_options:"More options",arrowtypes:"Arrow type",arrowtype_sharp:"Sharp arrow",arrowtype_round:"Curved arrow",arrowtype_elbowed:"Elbow arrow",fontSize:"Font size",textStyle:"Text style",italic:"Italic",underline:"Underline",strikethrough:"Strikethrough",textHighlight:"Highlight",fontFamily:"Font family",addWatermark:'Add "Made with Excalidraw"',handDrawn:"Hand-drawn",normal:"Normal",code:"Code",small:"Small",medium:"Medium",large:"Large",veryLarge:"Very large",solid:"Solid",hachure:"Hachure",zigzag:"Zigzag",crossHatch:"Cross-hatch",thin:"Thin",bold:"Bold",left:"Left",center:"Center",right:"Right",extraBold:"Extra bold",architect:"Architect",artist:"Artist",cartoonist:"Cartoonist",fileTitle:"File name",colorPicker:"Color picker",canvasColors:"Used on canvas",canvasBackground:"Canvas background",drawingCanvas:"Drawing canvas",clearCanvas:"Clear canvas",layers:"Layers",actions:"Actions",language:"Language",liveCollaboration:"Live collaboration...",duplicateSelection:"Duplicate",untitled:"Untitled",name:"Name",yourName:"Your name",madeWithExcalidraw:"Made with Excalidraw",group:"Group selection",ungroup:"Ungroup selection",collaborators:"Collaborators",toggleGrid:"Toggle grid",addToLibrary:"Add to library",removeFromLibrary:"Remove from library",libraryLoadingMessage:"Loading library\u2026",libraries:"Browse libraries",loadingScene:"Loading scene\u2026",loadScene:"Load scene from file",align:"Align",alignTop:"Align top",alignBottom:"Align bottom",alignLeft:"Align left",alignRight:"Align right",centerVertically:"Center vertically",centerHorizontally:"Center horizontally",distributeHorizontally:"Distribute horizontally",distributeVertically:"Distribute vertically",flipHorizontal:"Flip horizontal",flipVertical:"Flip vertical",viewMode:"View mode",share:"Share",showStroke:"Show stroke color picker",showBackground:"Show background color picker",showFonts:"Show font picker",toggleTheme:"Toggle light/dark theme",theme:"Theme",personalLib:"Personal Library",excalidrawLib:"Excalidraw Library",decreaseFontSize:"Decrease font size",increaseFontSize:"Increase font size",unbindText:"Unbind text",bindText:"Bind text to the container",createContainerFromText:"Wrap text in a container",link:{edit:"Edit link",editEmbed:"Edit embeddable link",create:"Add link",label:"Link",labelEmbed:"Link & embed",empty:"No link is set",hint:"Type or paste your link here",goToElement:"Go to target element"},lineEditor:{edit:"Edit line",editArrow:"Edit arrow"},polygon:{breakPolygon:"Break polygon",convertToPolygon:"Convert to polygon"},elementLock:{lock:"Lock",unlock:"Unlock",lockAll:"Lock all",unlockAll:"Unlock all"},statusPublished:"Published",sidebarLock:"Keep sidebar open",selectAllElementsInFrame:"Select all elements in frame",removeAllElementsFromFrame:"Remove all elements from frame",cycleThroughFrameChildren:"Cycle through frame elements",eyeDropper:"Pick color from canvas",textToDiagram:"Text to diagram",prompt:"Prompt",followUs:"Follow us",discordChat:"Discord chat",zoomToFitViewport:"Zoom to fit in viewport",zoomToFitSelection:"Zoom to fit selection",zoomToFit:"Zoom to fit all elements",installPWA:"Install Excalidraw locally (PWA)",autoResize:"Enable text auto-resizing",imageCropping:"Image cropping",unCroppedDimension:"Uncropped dimension",copyElementLink:"Copy link to object",linkToElement:"Link to object",wrapSelectionInFrame:"Wrap selection in frame",tab:"Tab",shapeSwitch:"Switch shape",preferences:"Preferences",preferences_toolLock:"Tool lock"},r={title:"Link to object",desc:"Click on a shape on canvas or paste a link.",notFound:"Linked object wasn't found on canvas."},a={noItems:"No items added yet...",hint_emptyLibrary:"Select an item on canvas to add it here, or install a library from the public repository, below.",hint_emptyPrivateLibrary:"Select an item on canvas to add it here.",search:{inputPlaceholder:"Search library",heading:"Library matches",noResults:"No matching items found...",clearSearch:"Clear search"}},i={title:"Find on canvas",noMatch:"No matches found...",singleResult:"result",multipleResults:"results",placeholder:"Find text on canvas...",frames:"Frames",texts:"Texts"},n={clearReset:"Reset the canvas",exportJSON:"Export to file",exportImage:"Export image...",export:"Save to...",copyToClipboard:"Copy to clipboard",copyLink:"Copy link",save:"Save to current file",saveAs:"Save as",load:"Open",getShareableLink:"Get shareable link",close:"Close",selectLanguage:"Select language",scrollBackToContent:"Scroll back to content",zoomIn:"Zoom in",zoomOut:"Zoom out",resetZoom:"Reset zoom",menu:"Menu",done:"Done",edit:"Edit",undo:"Undo",redo:"Redo",resetLibrary:"Reset library",createNewRoom:"Create new room",fullScreen:"Full screen",darkMode:"Dark mode",lightMode:"Light mode",systemMode:"System mode",zenMode:"Zen mode",objectsSnapMode:"Snap to objects",exitZenMode:"Exit zen mode",cancel:"Cancel",saveLibNames:"Save name(s) and exit",clear:"Clear",remove:"Remove",embed:"Toggle embedding",publishLibrary:"Rename or publish",submit:"Submit",confirm:"Confirm",embeddableInteractionButton:"Click to interact"},l={clearReset:"This will clear the whole canvas. Are you sure?",couldNotCreateShareableLink:"Couldn't create shareable link.",couldNotCreateShareableLinkTooBig:"Couldn't create shareable link: the scene is too big",couldNotLoadInvalidFile:"Couldn't load invalid file",importBackendFailed:"Importing from backend failed.",cannotExportEmptyCanvas:"Cannot export empty canvas.",couldNotCopyToClipboard:"Couldn't copy to clipboard.",decryptFailed:"Couldn't decrypt data.",uploadedSecurly:"The upload has been secured with end-to-end encryption, which means that Excalidraw server and third parties can't read the content.",loadSceneOverridePrompt:"Loading external drawing will replace your existing content. Do you wish to continue?",collabStopOverridePrompt:`Stopping the session will overwrite your previous, locally stored drawing. Are you sure?
|
|
2
2
|
|
|
3
3
|
(If you want to keep your local drawing, simply close the browser tab instead.)`,errorAddingToLibrary:"Couldn't add item to the library",errorRemovingFromLibrary:"Couldn't remove item from the library",confirmAddLibrary:"This will add {{numShapes}} shape(s) to your library. Are you sure?",imageDoesNotContainScene:"This image does not seem to contain any scene data. Have you enabled scene embedding during export?",cannotRestoreFromImage:"Scene couldn't be restored from this image file",invalidSceneUrl:"Couldn't import scene from the supplied URL. It's either malformed, or doesn't contain valid Excalidraw JSON data.",resetLibrary:"This will clear your library. Are you sure?",removeItemsFromsLibrary:"Delete {{count}} item(s) from library?",invalidEncryptionKey:"Encryption key must be of 22 characters. Live collaboration is disabled.",collabOfflineWarning:`No internet connection available.
|
|
4
4
|
Your changes will not be saved!`,localStorageQuotaExceeded:"Browser storage quota exceeded. Changes will not be saved."},s={unsupportedFileType:"Unsupported file type.",imageInsertError:"Couldn't insert image. Try again later...",fileTooBig:"File is too big. Maximum allowed size is {{maxSize}}.",svgImageInsertError:"Couldn't insert SVG image. The SVG markup looks invalid.",failedToFetchImage:"Failed to fetch image.",cannotResolveCollabServer:"Couldn't connect to the collab server. Please reload the page and try again.",importLibraryError:"Couldn't load library",saveLibraryError:"Couldn't save library to storage. Please save your library to a file locally to make sure you don't lose changes.",collabSaveFailed:"Couldn't save to the backend database. If problems persist, you should save your file locally to ensure you don't lose your work.",collabSaveFailed_sizeExceeded:"Couldn't save to the backend database, the canvas seems to be too big. You should save the file locally to ensure you don't lose your work.",imageToolNotSupported:"Images are disabled.",brave_measure_text_error:{line1:"Looks like you are using Brave browser with the <bold>Aggressively Block Fingerprinting</bold> setting enabled.",line2:"This could result in breaking the <bold>Text Elements</bold> in your drawings.",line3:"We strongly recommend disabling this setting. You can follow <link>these steps</link> on how to do so.",line4:"If disabling this setting doesn't fix the display of text elements, please open an <issueLink>issue</issueLink> on our GitHub, or write us on <discordLink>Discord</discordLink>"},libraryElementTypeError:{embeddable:"Embeddable elements cannot be added to the library.",iframe:"IFrame elements cannot be added to the library.",image:"Support for adding images to the library coming soon!"},asyncPasteFailedOnRead:"Couldn't paste (couldn't read from system clipboard).",asyncPasteFailedOnParse:"Couldn't paste.",copyToSystemClipboardFailed:"Couldn't copy to clipboard."},d={selection:"Selection",lasso:"Lasso selection",image:"Insert image",rectangle:"Rectangle",diamond:"Diamond",ellipse:"Ellipse",arrow:"Arrow",line:"Line",freedraw:"Draw",text:"Text",library:"Library",lock:"Keep selected tool active after drawing",penMode:"Pen mode - prevent touch",link:"Add / Update link for a selected shape",eraser:"Eraser",frame:"Frame tool",magicframe:"Wireframe to code",embeddable:"Web Embed",laser:"Laser pointer",hand:"Hand (panning tool)",extraTools:"More tools",mermaidToExcalidraw:"Mermaid to Excalidraw",convertElementType:"Toggle shape type"},c={rectangle:"Rectangle",diamond:"Diamond",ellipse:"Ellipse",arrow:"Arrow",line:"Line",freedraw:"Freedraw",text:"Text",image:"Image",video:"Video",group:"Group",frame:"Frame",magicframe:"Wireframe to code",embeddable:"Web Embed",selection:"Selection",iframe:"IFrame"},u={canvasActions:"Canvas actions",selectedShapeActions:"Selected shape actions",shapes:"Shapes"},m={dismissSearch:"{{shortcut}} to dismiss search",canvasPanning:"To move canvas, hold {{shortcut_1}} or {{shortcut_2}} while dragging, or use the hand tool",linearElement:"Click to start multiple points, drag for single line",arrowTool:"Click to start multiple points, drag for single line. Press {{shortcut}} again to change arrow type.",arrowBindModifiers:"Hold {{shortcut_1}} to disable binding, or {{shortcut_2}} to bind at a fixed point",freeDraw:"Click and drag, release when you're finished",text:"Tip: you can also add text by double-clicking anywhere with the selection tool",embeddable:"Click-drag to create a website embed",text_selected:"Double-click or press {{shortcut}} to edit text",text_editing:"Press {{shortcut_1}} or {{shortcut_2}} to finish editing",linearElementMulti:"Click on last point or press {{shortcut_1}} or {{shortcut_2}} to finish",lockAngle:"You can constrain angle by holding {{shortcut}}",resize:`You can constrain proportions by holding {{shortcut_1}} while resizing,
|
|
5
5
|
hold {{shortcut_2}} to resize from the center`,resizeImage:`You can resize freely by holding {{shortcut_1}},
|
|
6
6
|
hold {{shortcut_2}} to resize from the center`,rotate:"You can constrain angles by holding {{shortcut}} while rotating",lineEditor_info:"Hold {{shortcut_1}} and Double-click or press {{shortcut_2}} to edit points",lineEditor_line_info:"Double-click or press {{shortcut}} to edit points",lineEditor_pointSelected:`Press {{shortcut_1}} to remove point(s),
|
|
7
7
|
{{shortcut_2}} to duplicate, or drag to move`,lineEditor_nothingSelected:`Select a point to edit (hold {{shortcut_1}} to select multiple),
|
|
8
|
-
or hold {{shortcut_2}} and click to add new points`,publishLibrary:"Publish your own library",bindTextToElement:"{{shortcut}} to add text",createFlowchart:"{{shortcut}} to create a flowchart",deepBoxSelect:"Hold {{shortcut}} to deep select, and to prevent dragging",eraserRevert:"Hold {{shortcut}} to revert the elements marked for deletion",firefox_clipboard_write:'This feature can likely be enabled by setting the "dom.events.asyncClipboard.clipboardItem" flag to "true". To change the browser flags in Firefox, visit the "about:config" page.',disableSnapping:"Hold {{shortcut}} to disable snapping",enterCropEditor:"Double click the image or press {{shortcut}} to crop the image",leaveCropEditor:"Click outside the image or press {{shortcut_1}} or {{shortcut_2}} to finish cropping"},
|
|
8
|
+
or hold {{shortcut_2}} and click to add new points`,publishLibrary:"Publish your own library",bindTextToElement:"{{shortcut}} to add text",createFlowchart:"{{shortcut}} to create a flowchart",deepBoxSelect:"Hold {{shortcut}} to deep select, and to prevent dragging",eraserRevert:"Hold {{shortcut}} to revert the elements marked for deletion",firefox_clipboard_write:'This feature can likely be enabled by setting the "dom.events.asyncClipboard.clipboardItem" flag to "true". To change the browser flags in Firefox, visit the "about:config" page.',disableSnapping:"Hold {{shortcut}} to disable snapping",enterCropEditor:"Double click the image or press {{shortcut}} to crop the image",leaveCropEditor:"Click outside the image or press {{shortcut_1}} or {{shortcut_2}} to finish cropping"},h={cannotShowPreview:"Cannot show preview",canvasTooBig:"The canvas may be too big.",canvasTooBigTip:"Tip: try moving the farthest elements a bit closer together."},p={headingMain:"Encountered an error. Try <button>reloading the page</button>.",clearCanvasMessage:"If reloading doesn't work, try <button>clearing the canvas</button>.",clearCanvasCaveat:" This will result in loss of work ",trackedToSentry:"The error with identifier {{eventId}} was tracked on our system.",openIssueMessage:"We were very cautious not to include your scene information on the error. If your scene is not private, please consider following up on our <button>bug tracker</button>. Please include information below by copying and pasting into the GitHub issue.",sceneContent:"Scene content:"},g={or:"Or"},b={desc_intro:"Invite people to collaborate on your drawing.",desc_privacy:"Don't worry, the session is end-to-end encrypted, and fully private. Not even our server can see what you draw.",button_startSession:"Start session",button_stopSession:"Stop session",desc_inProgressIntro:"Live-collaboration session is now in progress.",desc_shareLink:"Share this link with anyone you want to collaborate with:",desc_exitSession:"Stopping the session will disconnect you from the room, but you'll be able to continue working with the scene, locally. Note that this won't affect other people, and they'll still be able to collaborate on their version.",shareTitle:"Join a live collaboration session on Excalidraw"},y={title:"Error"},w={disk_title:"Save to disk",disk_details:"Export the scene data to a file from which you can import later.",disk_button:"Save to file",link_title:"Shareable link",link_details:"Export as a read-only link.",link_button:"Export to Link",excalidrawplus_description:"Save the scene to your Excalidraw+ workspace.",excalidrawplus_button:"Export",excalidrawplus_exportError:"Couldn't export to Excalidraw+ at this moment..."},f={blog:"Read our blog",click:"click",deepSelect:"Deep select",deepBoxSelect:"Deep select within box, and prevent dragging",createFlowchart:"Create a flowchart from a generic element",navigateFlowchart:"Navigate a flowchart",curvedArrow:"Curved arrow",curvedLine:"Curved line",documentation:"Documentation",doubleClick:"double-click",drag:"drag",editor:"Editor",editLineArrowPoints:"Edit line/arrow points",editText:"Edit text / add label",github:"Found an issue? Submit",howto:"Follow our guides",or:"or",preventBinding:"Prevent arrow binding",tools:"Tools",shortcuts:"Keyboard shortcuts",textFinish:"Finish editing (text editor)",textNewLine:"Add new line (text editor)",title:"Help",view:"View",zoomToFit:"Zoom to fit all elements",zoomToSelection:"Zoom to selection",toggleElementLock:"Lock/unlock selection",movePageUpDown:"Move page up/down",movePageLeftRight:"Move page left/right",cropStart:"Crop image",cropFinish:"Finish image cropping"},k={title:"Clear canvas"},v={title:"Publish library",itemName:"Item name",authorName:"Author name",githubUsername:"GitHub username",twitterUsername:"Twitter username",libraryName:"Library name",libraryDesc:"Library description",website:"Website",placeholder:{authorName:"Your name or username",libraryName:"Name of your library",libraryDesc:"Description of your library to help people understand its usage",githubHandle:"GitHub handle (optional), so you can edit the library once submitted for review",twitterHandle:"Twitter username (optional), so we know who to credit when promoting over Twitter",website:"Link to your personal website or elsewhere (optional)"},errors:{required:"Required",website:"Enter a valid URL"},noteDescription:"Submit your library to be included in the <link>public library repository</link> for other people to use in their drawings.",noteGuidelines:"The library needs to be manually approved first. Please read the <link>guidelines</link> before submitting. You will need a GitHub account to communicate and make changes if requested, but it is not strictly required.",noteLicense:"By submitting, you agree the library will be published under the <link>MIT License</link>, which in short means anyone can use them without restrictions.",noteItems:"Each library item must have its own name so it's filterable. The following library items will be included:",atleastOneLibItem:"Please select at least one library item to get started",republishWarning:"Note: some of the selected items are marked as already published/submitted. You should only resubmit items when updating an existing library or submission."},S={title:"Library submitted",content:"Thank you {{authorName}}. Your library has been submitted for review. You can track the status <link>here</link>"},C={resetLibrary:"Reset library",removeItemsFromLib:"Remove selected items from library"},x={header:"Export image",label:{withBackground:"Background",onlySelected:"Only selected",darkMode:"Dark mode",embedScene:"Embed scene",scale:"Scale",padding:"Padding"},tooltip:{embedScene:`Scene data will be saved into the exported PNG/SVG file so that the scene can be restored from it.
|
|
9
9
|
Will increase exported file size.`},title:{exportToPng:"Export to PNG",exportToSvg:"Export to SVG",copyPngToClipboard:"Copy PNG to clipboard"},button:{exportToPng:"PNG",exportToSvg:"SVG",copyPngToClipboard:"Copy to clipboard"}},T={tooltip:"Your drawings are end-to-end encrypted so Excalidraw's servers will never see them.",link:"Blog post on end-to-end encryption in Excalidraw"},L={angle:"Angle",shapes:"Shapes",height:"Height",scene:"Scene",selected:"Selected",storage:"Storage",fullTitle:"Canvas & Shape properties",title:"Properties",generalStats:"General",elementProperties:"Shape properties",total:"Total",version:"Version",versionCopy:"Click to copy",versionNotAvailable:"Version not available",width:"Width"},E={addedToLibrary:"Added to library",copyStyles:"Copied styles.",copyToClipboard:"Copied to clipboard.",copyToClipboardAsPng:`Copied {{exportSelection}} to clipboard as PNG
|
|
10
10
|
({{exportColorScheme}})`,copyToClipboardAsSvg:`Copied {{exportSelection}} to clipboard as SVG
|
|
11
11
|
({{exportColorScheme}})`,fileSaved:"File saved.",fileSavedToFilename:"Saved to {filename}",canvas:"canvas",selection:"selection",pasteAsSingleElement:`Use {{shortcut}} to paste as a single element,
|
|
12
|
-
or paste into an existing text editor`,unableToEmbed:"Embedding this url is currently not allowed. Raise an issue on GitHub to request the url whitelisted",unrecognizedLinkFormat:"The link you embedded does not match the expected format. Please try to paste the 'embed' string provided by the source site",elementLinkCopied:"Link copied to clipboard"},_={transparent:"Transparent",black:"Black",white:"White",red:"Red",pink:"Pink",grape:"Grape",violet:"Violet",gray:"Gray",blue:"Blue",cyan:"Cyan",teal:"Teal",green:"Green",yellow:"Yellow",orange:"Orange",bronze:"Bronze"},F={app:{center_heading:"Your drawings are saved in your browser's storage.",center_heading_line2:"Browser storage can be cleared unexpectedly.",center_heading_line3:"Save your work to a file regularly to avoid losing it.",center_heading_plus:"Did you want to go to the Excalidraw+ instead?",menuHint:"Export, preferences, languages, ..."},defaults:{menuHint:"Export, preferences, and more...",center_heading:"Diagrams. Made. Simple.",toolbarHint:"Pick a tool & Start drawing!",helpHint:"Shortcuts & help"}},P={color:"Color",mostUsedCustomColors:"Most used custom colors",colors:"Colors",shades:"Shades",hexCode:"Hex code",noShades:"No shades available for this color"},A={action:{exportToImage:{title:"Export as image",button:"Export as image",description:"Export the scene data as an image from which you can import later."},saveToDisk:{title:"Save to disk",button:"Save to disk",description:"Export the scene data to a file from which you can import later."},excalidrawPlus:{title:"Excalidraw+",button:"Export to Excalidraw+",description:"Save the scene to your Excalidraw+ workspace."}},modal:{loadFromFile:{title:"Load from file",button:"Load from file",description:"Loading from a file will <bold>replace your existing content</bold>.<br></br>You can back up your drawing first using one of the options below."},shareableLink:{title:"Load from link",button:"Replace my content",description:"Loading external drawing will <bold>replace your existing content</bold>.<br></br>You can back up your drawing first by using one of the options below."}}},D={title:"Mermaid to Excalidraw",button:"Insert",description:"Currently only <flowchartLink>Flowchart</flowchartLink>,<sequenceLink> Sequence, </sequenceLink> and <classLink>Class </classLink>Diagrams are supported. The other types will be rendered as image in Excalidraw.",syntax:"Mermaid Syntax",preview:"Preview",label:"Mermaid",inputPlaceholder:"Write Mermaid diagram defintion here..."},I={error:"Error!"},M={inputPlaceholder:"Start typing your diagram idea here... ({{shortcut}} for new line)",inputPlaceholderWithMessages:"Continue refining your diagram...",generating:"Generating...",rateLimitRemaining:"{{count}} requests left today",role:{user:"You",assistant:"AI Assistant",system:"System"},aiBeta:"AI Beta",label:"Chat",menu:"Menu",newChat:"New Chat",deleteChat:"Delete chat",deleteMessage:"Delete message",viewAsMermaid:"View as Mermaid",placeholder:{title:"Let's design your diagram",description:"Describe the diagram you want to create, and we'll generate it for you.",hint:"At the moment we know Flowchart, Sequence, and Class diagrams."},preview:"Preview",insert:"Insert",retry:"Retry",errors:{promptTooShort:"Prompt is too short (min {{min}} characters)",promptTooLong:"Prompt is too long (max {{max}} characters)",generationFailed:"Generation failed",invalidDiagram:"Generated an invalid diagram :(. You may edit manually, retry with auto-fix, or try a different prompt.",fixInMermaid:"Edit Mermaid manually \u2192",aiRepair:"Regenerate (auto-fix) \u2192",requestAborted:"Request aborted",requestFailed:"Request failed",mermaidParseError:"Mermaid syntax error"},rateLimit:{messageLimit:"You've hit your AI limit on the free plan. Try out Excalidraw+ for more or come back tomorrow.",generalRateLimit:"Hold your horses, you're too fast for us! Please wait a moment before trying again.",messageLimitInputPlaceholder:"You've reached your message limit"},upsellBtnLabel:"Upgrade to Plus"},N={placeholder:"Quick search"},R={badge:{old:"old"},sceneFonts:"In this scene",availableFonts:"Available fonts",empty:"No fonts found"},B={empty:"No users found",hint:{text:"Click on user to follow",followStatus:"You're currently following this user",inCall:"User is in a voice call",micMuted:"User's microphone is muted",isSpeaking:"User is speaking"}},z={title:"Command palette",shortcuts:{select:"Select",confirm:"Confirm",close:"Close"},recents:"Recently used",search:{placeholder:"Search menus, commands, and discover hidden gems",noMatch:"No matching commands..."},itemNotAvailable:"Command is not available...",shortcutHint:"For Command palette, use {{shortcut}}"},G={ctrl:"Ctrl",option:"Option",cmd:"Cmd",alt:"Alt",escape:"Esc",enter:"Enter",shift:"Shift",spacebar:"Space",delete:"Delete",mmb:"Scroll wheel"},H={labels:t,elementLink:r,library:a,search:i,buttons:n,alerts:l,errors:s,toolBar:d,element:c,headings:u,hints:m,canvasError:
|
|
12
|
+
or paste into an existing text editor`,unableToEmbed:"Embedding this url is currently not allowed. Raise an issue on GitHub to request the url whitelisted",unrecognizedLinkFormat:"The link you embedded does not match the expected format. Please try to paste the 'embed' string provided by the source site",elementLinkCopied:"Link copied to clipboard"},_={transparent:"Transparent",black:"Black",white:"White",red:"Red",pink:"Pink",grape:"Grape",violet:"Violet",gray:"Gray",blue:"Blue",cyan:"Cyan",teal:"Teal",green:"Green",yellow:"Yellow",orange:"Orange",bronze:"Bronze"},F={app:{center_heading:"Your drawings are saved in your browser's storage.",center_heading_line2:"Browser storage can be cleared unexpectedly.",center_heading_line3:"Save your work to a file regularly to avoid losing it.",center_heading_plus:"Did you want to go to the Excalidraw+ instead?",menuHint:"Export, preferences, languages, ..."},defaults:{menuHint:"Export, preferences, and more...",center_heading:"Diagrams. Made. Simple.",toolbarHint:"Pick a tool & Start drawing!",helpHint:"Shortcuts & help"}},P={color:"Color",mostUsedCustomColors:"Most used custom colors",colors:"Colors",shades:"Shades",hexCode:"Hex code",noShades:"No shades available for this color"},A={action:{exportToImage:{title:"Export as image",button:"Export as image",description:"Export the scene data as an image from which you can import later."},saveToDisk:{title:"Save to disk",button:"Save to disk",description:"Export the scene data to a file from which you can import later."},excalidrawPlus:{title:"Excalidraw+",button:"Export to Excalidraw+",description:"Save the scene to your Excalidraw+ workspace."}},modal:{loadFromFile:{title:"Load from file",button:"Load from file",description:"Loading from a file will <bold>replace your existing content</bold>.<br></br>You can back up your drawing first using one of the options below."},shareableLink:{title:"Load from link",button:"Replace my content",description:"Loading external drawing will <bold>replace your existing content</bold>.<br></br>You can back up your drawing first by using one of the options below."}}},D={title:"Mermaid to Excalidraw",button:"Insert",description:"Currently only <flowchartLink>Flowchart</flowchartLink>,<sequenceLink> Sequence, </sequenceLink> and <classLink>Class </classLink>Diagrams are supported. The other types will be rendered as image in Excalidraw.",syntax:"Mermaid Syntax",preview:"Preview",label:"Mermaid",inputPlaceholder:"Write Mermaid diagram defintion here..."},I={error:"Error!"},M={inputPlaceholder:"Start typing your diagram idea here... ({{shortcut}} for new line)",inputPlaceholderWithMessages:"Continue refining your diagram...",generating:"Generating...",rateLimitRemaining:"{{count}} requests left today",role:{user:"You",assistant:"AI Assistant",system:"System"},aiBeta:"AI Beta",label:"Chat",menu:"Menu",newChat:"New Chat",deleteChat:"Delete chat",deleteMessage:"Delete message",viewAsMermaid:"View as Mermaid",placeholder:{title:"Let's design your diagram",description:"Describe the diagram you want to create, and we'll generate it for you.",hint:"At the moment we know Flowchart, Sequence, and Class diagrams."},preview:"Preview",insert:"Insert",retry:"Retry",errors:{promptTooShort:"Prompt is too short (min {{min}} characters)",promptTooLong:"Prompt is too long (max {{max}} characters)",generationFailed:"Generation failed",invalidDiagram:"Generated an invalid diagram :(. You may edit manually, retry with auto-fix, or try a different prompt.",fixInMermaid:"Edit Mermaid manually \u2192",aiRepair:"Regenerate (auto-fix) \u2192",requestAborted:"Request aborted",requestFailed:"Request failed",mermaidParseError:"Mermaid syntax error"},rateLimit:{messageLimit:"You've hit your AI limit on the free plan. Try out Excalidraw+ for more or come back tomorrow.",generalRateLimit:"Hold your horses, you're too fast for us! Please wait a moment before trying again.",messageLimitInputPlaceholder:"You've reached your message limit"},upsellBtnLabel:"Upgrade to Plus"},N={placeholder:"Quick search"},R={badge:{old:"old"},sceneFonts:"In this scene",availableFonts:"Available fonts",empty:"No fonts found"},B={empty:"No users found",hint:{text:"Click on user to follow",followStatus:"You're currently following this user",inCall:"User is in a voice call",micMuted:"User's microphone is muted",isSpeaking:"User is speaking"}},z={title:"Command palette",shortcuts:{select:"Select",confirm:"Confirm",close:"Close"},recents:"Recently used",search:{placeholder:"Search menus, commands, and discover hidden gems",noMatch:"No matching commands..."},itemNotAvailable:"Command is not available...",shortcutHint:"For Command palette, use {{shortcut}}"},G={ctrl:"Ctrl",option:"Option",cmd:"Cmd",alt:"Alt",escape:"Esc",enter:"Enter",shift:"Shift",spacebar:"Space",delete:"Delete",mmb:"Scroll wheel"},H={labels:t,elementLink:r,library:a,search:i,buttons:n,alerts:l,errors:s,toolBar:d,element:c,headings:u,hints:m,canvasError:h,errorSplash:p,shareDialog:g,roomDialog:b,errorDialog:y,exportDialog:w,helpDialog:f,clearCanvasDialog:k,publishDialog:v,publishSuccessDialog:S,confirmDialog:C,imageExportDialog:x,encrypted:T,stats:L,toast:E,colors:_,welcomeScreen:F,colorPicker:P,overwriteConfirm:A,mermaid:D,ttd:I,chat:M,quickSearch:N,fontList:R,userList:B,commandPalette:z,keys:G};export{t as a,r as b,a as c,i as d,n as e,l as f,s as g,d as h,c as i,u as j,m as k,h as l,p as m,g as n,b as o,y as p,w as q,f as r,k as s,v as t,S as u,C as v,x as w,T as x,L as y,E as z,_ as A,F as B,P as C,A as D,D as E,I as F,M as G,N as H,R as I,B as J,z as K,G as L,H as M};
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import{a as ee,b as fe,c as te,d as q}from"./chunk-6YYSQB5E.js";import{getFrameChildren as _e}from"@orangecatai/element";function Le(e,t){return _e(e,t.id).filter(n=>!n.isDeleted)}function It(e,t){let n=Le(e,t);return n.length>1?!0:n.some(r=>r.type==="text"?!0:typeof r.customData?.decomposeType=="string")}var kt="Make this ad editable first \u2014 Auto Resize needs separate layers to re-lay-out.";function $(e){let t=e.indexOf(",");return t>=0?e.length-t-1:e.length}function ne(e){return/^data:image\/(png|jpe?g|gif|webp);base64,/i.test(e)}function ye(e){return new Promise((t,n)=>{let r=new Image,o=setTimeout(()=>{r.onload=null,r.onerror=null,n(new Error("image decode timed out"))},1e4);r.onload=()=>{clearTimeout(o),t(r)},r.onerror=()=>{clearTimeout(o),n(new Error("image decode failed"))},r.src=e})}function be(e,t,n,r){let o=document.createElement("canvas");o.width=t,o.height=n;let a=o.getContext("2d");return a?(a.fillStyle="#ffffff",a.fillRect(0,0,t,n),a.drawImage(e,0,0,t,n),o.toDataURL("image/jpeg",r)):null}async function W(e){if(!ne(e)||$(e)<=204800)return e;try{let t=await ye(e),{width:n,height:r}=t;if(!n||!r)return e;let o=Math.min(1,1280/Math.max(n,r)),a=be(t,Math.max(1,Math.round(n*o)),Math.max(1,Math.round(r*o)),.78);return a&&$(a)<$(e)?a:e}catch{return e}}async function V(e,t,n=.7){if(!ne(e))return e;try{let r=await ye(e);if(!r.width||!r.height)return e;let o=Math.min(1,t/Math.max(r.width,r.height)),a=be(r,Math.max(1,Math.round(r.width*o)),Math.max(1,Math.round(r.height*o)),n);return a&&$(a)<$(e)?a:e}catch{return e}}var xe=[960,720,512];var we=["user","source","logo","brandAsset","adReference"];var re={brandAsset:1,adReference:1},oe=e=>e.bytes??(e.dataUrl?$(e.dataUrl):0),Y=e=>e.reduce((t,n)=>t+oe(n),0);function Ne(e){return[...e].sort((t,n)=>we.indexOf(t.tier)-we.indexOf(n.tier))}function Fe(e,t){let n=s=>e.filter(l=>l.tier===s),r=n("brandAsset"),o=n("adReference"),a=(s,l)=>l.slice(re[s]??0).reverse();return[...a("adReference",o),...a("brandAsset",r),...o.slice(0,re.adReference??0),...r.slice(0,re.brandAsset??0),...t?[]:n("logo")]}function Ue(e,t={}){let n=t.maxImages??12,o=(t.maxBytes??te)-(t.reservedBytes??0),a=t.protectLogo??!0,s=[],l=[],i=0;for(let d of Ne(e)){if(d.tier==="user"&&(i+=1,i>6)){s.push({tier:d.tier,label:d.label,reason:"count"});continue}l.push(d)}let c=(d,u)=>{for(let h of Fe(l,a)){if(!u())return;l=l.filter(p=>p!==h),s.push({tier:h.tier,label:h.label,reason:d})}};return c("count",()=>l.length>n),c("bytes",()=>Y(l)>o),{kept:l,dropped:s,bytes:Y(l),overBudget:l.length>n||Y(l)>o}}async function Ee(e,t={}){let r=(t.maxBytes??te)-(t.reservedBytes??0),o=await Promise.all(e.map(async a=>a.dataUrl?{...a,dataUrl:await W(a.dataUrl),bytes:void 0}:a));for(let a of xe){if(Y(o)<=r)break;let s=o.map((l,i)=>({slot:l,index:i})).filter(({slot:l})=>!!l.dataUrl).sort((l,i)=>oe(i.slot)-oe(l.slot));for(let{slot:l,index:i}of s){if(Y(o)<=r)break;o[i]={...l,dataUrl:await V(l.dataUrl,a),bytes:void 0}}}return Ue(o,t)}var Be=/^\d+x\d+$/,Te=e=>e.startsWith("openai/gpt-image"),J=16,Re=3840,ae=3,ie=655360,se=8294400,ze=[{label:"16:9",value:16/9},{label:"4:3",value:4/3},{label:"1:1",value:1},{label:"3:4",value:3/4},{label:"9:16",value:9/16}];function ve(e,t){let n=e/t;return ze.reduce((r,o)=>Math.abs(o.value-n)<Math.abs(r.value-n)?o:r).label}function Ke(e,t,n){if(!(Number.isFinite(t)&&Number.isFinite(n)&&t>0&&n>0))return{aspectRatio:"1:1",imageSize:null};if(!Te(e))return{aspectRatio:ve(t,n),imageSize:null};let o=t/n,a=Math.max(t,n)/Math.min(t,n),s=a>ae?ae/a:1,l=t>n?t*s:t,i=t>n?n:n*s,c=Math.min(1,Re/Math.max(l,i));l*=c,i*=c;let d=l*i,u=d<ie?Math.sqrt(ie/d):d>se?Math.sqrt(se/d):1;l*=u,i*=u;let h=(g,y)=>Math.max(J,(y?Math.ceil(g/J):Math.floor(g/J))*J),p=null,f=1/0;for(let g of[!1,!0])for(let y of[!1,!0]){let b=h(l,g),w=h(i,y),E=b*w;if(Math.max(b,w)>Re||Math.max(b,w)/Math.min(b,w)>ae||E<ie||E>se)continue;let R=Math.abs(b/w-o);R<f&&(f=R,p={w:b,h:w})}return p?{aspectRatio:null,imageSize:`${p.w}x${p.h}`}:{aspectRatio:ve(t,n),imageSize:null}}var Ge="BRAND DIRECTION \u2014 OPTIONAL DEFAULTS. Everything in this section is subordinate to the user's instruction and the USER REFERENCE images above. Apply it only where they are silent, and discard any part of it that contradicts them \u2014 including colour values, typography, and layout.";function Ye(e,t,n=!1,r=!1){if(e===0&&!r&&t.length===0)return"";let o=["ATTACHED REFERENCE IMAGES (in the order supplied):"],a=0;for(let i=0;i<e;i++)o.push(` ${++a}. USER REFERENCE \u2014 supplied by the user for this specific request.`);if(r&&o.push(` ${++a}. SOURCE IMAGE \u2014 the existing image being edited. Preserve it exactly except for the change the user asked for.`),t.forEach(i=>{o.push(` ${++a}. Brand kit asset \u2014 ${i}.`)}),!(e>0||r))return o.join(`
|
|
2
|
+
`);let l=e===0?"SOURCE IMAGE":e===1?"USER REFERENCE image":"USER REFERENCE images";return o.push("",`PRIORITY \u2014 ABSOLUTE: the user's written instruction and the ${l} above outrank every other input. Follow the user's instruction exactly and treat ${e===0?"it":"them"} as the governing reference for subject, composition, style, colour, and typography. Where they contradict the brand kit, the brand guidelines, or any brand reference ad \u2014 including instructions given earlier in this prompt \u2014 the user's instruction and references WIN and the brand direction is overruled. Apply brand direction only where the user's instruction and references are silent.`),n&&o.push("","LOGO \u2014 EXACT ARTWORK: the brand logo listed above is the ONLY logo permitted in this image. Wherever a logo appears, it must be that artwork reproduced pixel-for-pixel \u2014 no redrawing, simplification, restyling, or recolouring \u2014 and it replaces any logo, emblem, or wordmark visible in the other reference images. This is not overruled by the precedence rule above; the precedence rule governs subject, composition, and style, not the identity of the logo. If the user explicitly asked for no logo, honour that instead."),o.join(`
|
|
3
|
+
`)}async function je(e,t,n,r,o,a,s,l,i,c){let d=c?.referenceMode??"legacy-positional",u=(Array.isArray(s)?s:s?[s]:[]).filter(m=>!!(m&&m.trim())),h=c?.hostBrandAssetSlots??0,p=c?.hostAdReferenceSlots??0,f=(m,S)=>({tier:m,dataUrl:"",label:S,bytes:q}),g=[...u.map(m=>({tier:"user",dataUrl:m})),...c?.sourceImageDataUrl?[{tier:"source",dataUrl:c.sourceImageDataUrl,label:"the image being edited"}]:[],...i?.logo?[{tier:"logo",dataUrl:i.logo,label:"the exact brand logo graphic"}]:[],...i?.fontPreview?[{tier:"brandAsset",dataUrl:i.fontPreview,label:"a brand font specimen (headline typeface)"}]:[],...i?.fontPreviewBody?[{tier:"brandAsset",dataUrl:i.fontPreviewBody,label:"a brand font specimen (body typeface)"}]:[],...Array.from({length:h},()=>f("brandAsset","a brand product/lifestyle photo")),...Array.from({length:p},()=>f("adReference","an existing ad creative or template"))],y=await Ee(g,{protectLogo:c?.protectLogo??!0,reservedBytes:e.length+(i?.brandContextText?.length??0)});y.dropped.length>0&&console.warn(`[imageApi] reference budget \u2014 dropped ${y.dropped.map(m=>`${m.tier}${m.label?` (${m.label})`:""}:${m.reason}`).join(", ")}; kept ${y.kept.length} slot(s), ${Math.round(y.bytes/1024)} KB`);let b=m=>y.kept.filter(S=>S.tier===m),w=y.kept.filter(m=>!!m.dataUrl),E=b("brandAsset").filter(m=>!m.dataUrl).length,R=b("adReference").filter(m=>!m.dataUrl).length,T=b("user").length,k=b("source").length,C=d==="legacy-positional"?[...w.filter(m=>m.tier!=="user"&&m.tier!=="source").map(m=>m.dataUrl),...w.filter(m=>m.tier==="user"||m.tier==="source").map(m=>m.dataUrl)]:w.map(m=>m.dataUrl),O=d==="user-priority"?w.filter(m=>m.tier!=="user"&&m.tier!=="source").map(m=>m.label).filter(m=>!!m):[],x=b("logo").length>0,P=d==="user-priority"?Ye(T,O,x,k>0):"",F=d==="user-priority"&&(T>0||k>0),v=C.map(m=>({type:"image_url",image_url:{url:m}})),z=t.startsWith("x-ai/"),U=t.startsWith("sourceful/"),B=Te(t),M=i?.brandContextText,K=M?F?`${e}
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
${Ge}
|
|
8
|
+
|
|
9
|
+
${M}`:`${M}
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
${e}`:e,I=P?`${K}
|
|
14
|
+
|
|
15
|
+
${P}`:K,D;if(B)D={model:t,prompt:I,...r&&Be.test(r)?{size:r}:{...n?{aspect_ratio:n}:{},...r?{resolution:r}:{}},...v.length>0?{input_references:v}:{},...c?.quality?{quality:c.quality}:{},...c?.background?{background:c.background}:{},...c?.background==="transparent"?{output_format:c.outputFormat??"png"}:{}};else if(z){let m=v.length>0?[...v,{type:"text",text:I}]:I;D={model:t,messages:[{role:"user",content:m}],stream:!1}}else{let m=[...v,{type:"text",text:I}],S={aspect_ratio:n??"1:1"};if(r&&(S.image_size=r),U&&i?.fontUrl){let De=i.fontText||"AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz 0123456789";S.font_inputs=[{font_url:i.fontUrl,text:De}]}D={model:t,messages:[{role:"user",content:m}],modalities:o?["image","text"]:["image"],stream:!1,image_config:S}}d==="user-priority"&&v.length>0&&(D.x_reference_manifest={userReferenceCount:T,sourceReferenceCount:k,totalReferenceCount:v.length,logoAttached:x,brandAssetSlots:E,adReferenceSlots:R,maxHostAssetBytes:q});let X=await fetch(a,{method:"POST",signal:l,headers:{"Content-Type":"application/json"},body:JSON.stringify(D)});if(!X.ok){let m=`OpenRouter API error ${X.status}`;try{let S=await X.json();S?.error?.message&&(m=S.error.message)}catch{}throw new Error(m)}let Q=await X.json(),Z=Q?.data?.[0];if(Z?.b64_json)return`data:${Z.media_type??"image/png"};base64,${Z.b64_json}`;let pe=Q?.choices?.[0]?.message?.images;if(pe?.[0]?.image_url?.url)return pe[0].image_url.url;let G=Q?.choices?.[0]?.message?.content;if(typeof G=="string"&&G.length>0)return G;if(Array.isArray(G)){let m=G.find(S=>S?.type==="image_url"&&S?.image_url?.url);if(m?.image_url?.url)return m.image_url.url}throw new Error("No image was returned by the API.")}var A=[],He=0,j=[],le=new Set;function L(){le.forEach(e=>e())}var zt={startActivity(e,t){A=[...A.filter(r=>r.frameId!==e.frameId),{...e,status:"running",steps:[],cancel:t}];let n=A.filter(r=>r.status!=="running").slice(-20);A=A.filter(r=>r.status==="running"||n.includes(r)),L()},startStep(e,t,n,r){let o=++He;return A.find(s=>s.frameId===e)?.steps.push({id:o,kind:t,name:n,model:r,status:"running",startedAt:Date.now()}),L(),o},endStep(e,t,n,r){let o=A.find(a=>a.frameId===e)?.steps.find(a=>a.id===t);o&&Object.assign(o,{status:n,detail:r,finishedAt:Date.now()}),L()},finishActivity(e,t){let n=A.find(r=>r.frameId===e);n&&(n.status=t,n.cancel=void 0),L()},cancelActivity(e){A.find(t=>t.frameId===e)?.cancel?.()},dismissActivity(e){A=A.filter(t=>t.frameId!==e||t.status==="running"),L()},getActivities(){return A},resetActivity(){A.forEach(e=>e.cancel?.()),A=[],L()},setLoadingFrames(e){j=[...e],L()},markComplete(e){j=j.filter(t=>t.frameId!==e),L()},clear(){j=[],L()},getLoadingFrames(){return j},subscribe(e){return le.add(e),()=>le.delete(e)}};function H(e,t,n){return Math.max(t,Math.min(n,Math.round(e)))}function Se(e,t){return Math.sqrt((e.r-t.r)**2+(e.g-t.g)**2+(e.b-t.b)**2)}function Ie({r:e,g:t,b:n}){let r=o=>H(o,0,255).toString(16).padStart(2,"0");return`#${r(e)}${r(t)}${r(n)}`}function Xe(e,t){let n=H(t.x,0,e.width),r=H(t.y,0,e.height),o=H(t.x+t.w,0,e.width),a=H(t.y+t.h,0,e.height),s=0,l=0,i=0,c=0,d=[];for(let f=r;f<a;f++)for(let g=n;g<o;g++){let y=(f*e.width+g)*4,b=e.data[y],w=e.data[y+1],E=e.data[y+2];s+=b,l+=w,i+=E,d.push(.299*b+.587*w+.114*E),c++}if(c===0)return{mean:{r:0,g:0,b:0},lumaStdev:0};let u={r:s/c,g:l/c,b:i/c},h=d.reduce((f,g)=>f+g,0)/d.length,p=d.reduce((f,g)=>f+(g-h)**2,0)/d.length;return{mean:u,lumaStdev:Math.sqrt(p)}}function qe(e,t){let n=t==="x"?e.width:e.height,r=t==="x"?e.height:e.width,o=[];for(let a=0;a<n;a++){let s=0,l=0,i=0;for(let c=0;c<r;c++){let d=t==="x"?a:c,h=((t==="x"?c:a)*e.width+d)*4;s+=e.data[h],l+=e.data[h+1],i+=e.data[h+2]}o.push({r:s/r,g:l/r,b:i/r})}return o}function We(e){let t=null;for(let r of["x","y"]){let o=qe(e,r),a=o.length;if(a<8)continue;let s=Math.floor(a*.12),l=Math.ceil(a*(1-.12));for(let i=s;i<l-1;i++){let c=Se(o[i],o[i+1]);c>=55&&(!t||c>t.delta)&&(t={axis:r,index:i+1,delta:c})}}if(!t)return null;let n=t.axis==="x"?e.width:e.height;return{axis:t.axis,at:t.index/n}}function ce(e,t){let n=t.w/8,r=t.h/8,o=[],a=[];for(let h=0;h<8;h++)for(let p=0;p<8;p++){let{mean:f,lumaStdev:g}=Xe(e,{x:t.x+p*n,y:t.y+h*r,w:n,h:r});o.push(f),a.push(g)}let s=a.reduce((h,p)=>h+p,0)/a.length,l=o.reduce((h,p)=>({r:h.r+p.r,g:h.g+p.g,b:h.b+p.b}),{r:0,g:0,b:0}),i={r:l.r/o.length,g:l.g/o.length,b:l.b/o.length},c=Math.max(...o.map(h=>Se(h,i))),d=Ve(o),u;return s<4&&c<6?u="solid":c<20?u="texture":d?u="gradient":u="photo",{rect:t,textureEnergy:s,meanSpread:c,monotonic:d,meanColor:i,verdict:u}}function Ve(e){let t=n=>.299*n.r+.587*n.g+.114*n.b;for(let n of["x","y"]){let r=[];for(let i=0;i<8;i++){let c=0;for(let d=0;d<8;d++){let u=n==="x"?d*8+i:i*8+d;c+=t(e[u])}r.push(c/8)}if(Math.max(...r)-Math.min(...r)<18)continue;let a=0,s=0;for(let i=1;i<r.length;i++)r[i]>r[i-1]?a++:r[i]<r[i-1]&&s++;let l=r.length-1;if(Math.max(a,s)/l>=.8)return!0}return!1}function Je(e){let t=We(e);if(!t){let a=ce(e,{x:0,y:0,w:e.width,h:e.height});return{kind:a.verdict,solidColor:a.verdict==="solid"?Ie(a.meanColor):void 0,regions:[a]}}let r=(t.axis==="x"?[{x:0,y:0,w:e.width*t.at,h:e.height},{x:e.width*t.at,y:0,w:e.width*(1-t.at),h:e.height}]:[{x:0,y:0,w:e.width,h:e.height*t.at},{x:0,y:e.height*t.at,w:e.width,h:e.height*(1-t.at)}]).map(a=>ce(e,a));if(!r.every(a=>a.verdict==="solid"||a.verdict==="texture")){let a=ce(e,{x:0,y:0,w:e.width,h:e.height});return{kind:a.verdict==="solid"?"texture":a.verdict,regions:r}}return{kind:"panels",split:t,regions:r}}function ue(e,t){let n=document.createElement("canvas");return n.width=Math.max(1,Math.round(e)),n.height=Math.max(1,Math.round(t)),n}async function he(e){return new Promise((t,n)=>{let r=new Image;r.onload=()=>t(r),r.onerror=()=>n(new Error("Failed to load background image")),r.src=e})}async function Qe(e,t=512){let n=await he(e),r=Math.min(1,t/Math.max(n.width,n.height)),o=Math.max(1,Math.round(n.width*r)),a=Math.max(1,Math.round(n.height*r)),l=ue(o,a).getContext("2d",{willReadFrequently:!0});if(!l)throw new Error("2D canvas context unavailable");return l.drawImage(n,0,0,o,a),{data:l.getImageData(0,0,o,a).data,width:o,height:a}}function Ae(e,t,n,r){let o=Math.max(1,n.w),a=Math.max(1,n.h),s=Math.ceil(r.w/o),l=Math.ceil(r.h/a);e.save(),e.beginPath(),e.rect(r.x,r.y,r.w,r.h),e.clip();for(let i=0;i<l;i++)for(let c=0;c<s;c++){let d=c%2===1,u=i%2===1;e.save(),e.translate(r.x+c*o+(d?o:0),r.y+i*a+(u?a:0)),e.scale(d?-1:1,u?-1:1),e.drawImage(t,n.x,n.y,n.w,n.h,0,0,o,a),e.restore()}e.restore()}function Ze(e,t,n,r){let o=Math.min(n/t.width,r/t.height),a=t.width*o,s=t.height*o,l=(n-a)/2,i=(r-s)/2,c=Math.max(1,Math.round(Math.min(t.width,t.height)*.04));l>0&&(e.drawImage(t,0,0,c,t.height,0,i,l,s),e.drawImage(t,t.width-c,0,c,t.height,l+a,i,n-(l+a),s)),i>0&&(e.drawImage(t,0,0,t.width,c,0,0,n,i),e.drawImage(t,0,t.height-c,t.width,c,0,i+s,n,r-(i+s))),e.drawImage(t,l,i,a,s)}function de(e,t,n,r){let o=Math.max(n/t.width,r/t.height),a=t.width*o,s=t.height*o;e.drawImage(t,(n-a)/2,(r-s)/2,a,s)}async function et(e,t,n,r){if(e.type==="none")return{kind:"none"};if(e.type==="solid")return{kind:"solid",color:e.color};let o=await he(e.dataUrl);if(!r.needsExtension){let u=ue(t,n),h=u.getContext("2d");if(!h)throw new Error("2D canvas context unavailable");return de(h,o,t,n),{kind:"image",dataUrl:u.toDataURL("image/png"),strategy:"scaled"}}r.onProgress?.("Analysing background\u2026");let a=await Qe(e.dataUrl),s=Je(a),l=o.width/a.width,i=o.height/a.height;if(s.kind==="solid"&&s.solidColor)return{kind:"solid",color:s.solidColor};let c=ue(t,n),d=c.getContext("2d");if(!d)throw new Error("2D canvas context unavailable");if(s.kind==="texture"){r.onProgress?.("Tiling background texture\u2026");let u={x:o.width*.25,y:o.height*.25,w:o.width*.5,h:o.height*.5};return Ae(d,o,u,{x:0,y:0,w:t,h:n}),{kind:"image",dataUrl:c.toDataURL("image/png"),strategy:"texture"}}if(s.kind==="panels"&&s.split){r.onProgress?.("Rebuilding background panels\u2026");let{axis:u,at:h}=s.split;for(let p=0;p<2;p++){let f=s.regions[p],g={x:f.rect.x*l,y:f.rect.y*i,w:f.rect.w*l,h:f.rect.h*i},y=u==="x"?{x:p===0?0:t*h,y:0,w:p===0?t*h:t*(1-h),h:n}:{x:0,y:p===0?0:n*h,w:t,h:p===0?n*h:n*(1-h)};f.verdict==="solid"?(d.fillStyle=Ie(f.meanColor),d.fillRect(y.x,y.y,y.w,y.h)):Ae(d,o,{x:g.x+g.w*.15,y:g.y+g.h*.15,w:g.w*(1-.15*2),h:g.h*(1-.15*2)},y)}return{kind:"image",dataUrl:c.toDataURL("image/png"),strategy:"panels"}}if(s.kind==="photo"){if(o.width>=t&&o.height>=n)return r.onProgress?.("Re-cropping background\u2026"),de(d,o,t,n),{kind:"image",dataUrl:c.toDataURL("image/png"),strategy:"scaled"};if(r.outpaint){r.onProgress?.("Extending background\u2026");try{let u=await r.outpaint({dataUrl:e.dataUrl,targetWidth:t,targetHeight:n});if(u){let h=await he(u);return de(d,h,t,n),{kind:"image",dataUrl:c.toDataURL("image/png"),strategy:"photo"}}}catch{}}}return r.onProgress?.("Extending background edges\u2026"),Ze(d,o,t,n),{kind:"image",dataUrl:c.toDataURL("image/png"),strategy:"gradient"}}import{nanoid as sn}from"nanoid";import{newFrameElement as bt,newElement as cn,newTextElement as dn,newImageElement as un,getFrameChildren as hn,syncMovedIndices as xt,styledTextToHtml as gn}from"@orangecatai/element";import{FRAME_STYLE as wt,arrayToMap as Et}from"@orangecatai/common";import{normalizeStyleRanges as tt}from"@orangecatai/element";var nt=6e3,ke=2;function N(e){if(!e||e==="transparent"||e==="rgba(0, 0, 0, 0)")return"transparent";if(e.startsWith("#"))return e;let t=e.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*([0-9.]+))?\)/);if(!t)return e;let n=parseInt(t[1],10),r=parseInt(t[2],10),o=parseInt(t[3],10);return`#${n.toString(16).padStart(2,"0")}${r.toString(16).padStart(2,"0")}${o.toString(16).padStart(2,"0")}`}function rt(e){let t=e.match(/rgba\(\d+,\s*\d+,\s*\d+,\s*([0-9.]+)\)/);return t?Math.round(parseFloat(t[1])*100):100}function Me(e,t){let n=e.toLowerCase();if(t){for(let[r,o]of Object.entries(t))if(n.includes(r))return o}return n.includes("sans-serif")||n.includes("arial")||n.includes("helvetica")||n.includes("verdana")||n.includes("impact")||n.includes("nunito")||n.includes("roboto")||n.includes("inter")||n.includes("liberation sans")||n.includes("tahoma")||n.includes("trebuchet")?2:n.includes("georgia")||n.includes("serif")||n.includes("cursive")||n.includes("script")||n.includes("times")||n.includes("playfair")?1:n.includes("courier")||n.includes("mono")||n.includes("cascadia")?3:2}function ot(e,t){switch(t){case"uppercase":return e.toUpperCase();case"lowercase":return e.toLowerCase();case"capitalize":return e.replace(/\b\w/g,n=>n.toUpperCase());default:return e}}function $e(e){let t=parseFloat(e);return isNaN(t)?16:Math.round(t)}function at(e){let t=e.borderTopLeftRadius||"0",n=parseFloat(t);return isNaN(n)?0:Math.round(n)}function it(e,t,n){let r=e.borderTopLeftRadius||"0";if(r.includes("%")){let o=parseFloat(r);if(!isNaN(o)&&o>=50)return!0}else{let o=parseFloat(r);if(!isNaN(o)&&o>0&&o>=t/2&&o>=n/2)return!0}return!1}function st(e){return e!=="none"&&(e.includes("linear-gradient")||e.includes("radial-gradient"))}function lt(e){let t=[...e.matchAll(/(#[\da-fA-F]{3,8}|rgba?\([^)]+\))/g)];if(t.length===0)return"#1a1a2e";if(t.length===1||e.includes("repeating"))return N(t[0][1]);let n=N(t[0][1]).replace("#","").padEnd(6,"0"),r=N(t[t.length-1][1]).replace("#","").padEnd(6,"0"),o=parseInt(n.slice(0,2),16),a=parseInt(n.slice(2,4),16),s=parseInt(n.slice(4,6),16),l=parseInt(r.slice(0,2),16),i=parseInt(r.slice(2,4),16),c=parseInt(r.slice(4,6),16),d=(u,h)=>Math.round((u+h)/2).toString(16).padStart(2,"0");return`#${d(o,l)}${d(a,i)}${d(s,c)}`}function ct(e){let t=e.match(/url\("?(data:[^")]+)"?\)/);return t?t[1]:null}function dt(e){return e==="center"?"center":e==="right"||e==="end"?"right":"left"}var Ce=new Set(["SPAN","EM","STRONG","B","I","A","LABEL"]);function ut(e){return Oe(e)?.text??null}function Oe(e,t,n){let r="",o=!1,a=[],s=t?.(e),l=d=>{if(!t||!s)return{};let u=t(d),h={},p=parseInt(u.fontWeight,10),f=parseInt(s.fontWeight,10);p>=600&&!(f>=600)&&(h.bold=!0),u.fontStyle!=="normal"&&s.fontStyle==="normal"&&(h.italic=!0);let g=`${u.textDecorationLine||u.textDecoration}`;return g.includes("underline")&&(h.underline=!0),g.includes("line-through")&&(h.strikethrough=!0),u.color&&u.color!==s.color&&(h.color=N(u.color)),u.fontSize&&u.fontSize!==s.fontSize&&(h.fontSize=$e(u.fontSize)),u.fontFamily&&u.fontFamily!==s.fontFamily&&n&&(h.fontFamily=Me(u.fontFamily,n)),h};for(let d of e.childNodes)if(d.nodeType===Node.TEXT_NODE){let u=d.textContent||"";u.trim()&&(o=!0),r+=u}else if(d.nodeType===Node.ELEMENT_NODE){let u=d;if(u.tagName==="BR")r+=`
|
|
16
|
+
`,o=!0;else if(Ce.has(u.tagName)){let h=u.textContent||"";h.trim()&&(o=!0);let p=r.length;r+=h;let f=l(u);Object.keys(f).length&&a.push({start:p,end:r.length,style:f})}}let i=r.match(/^\s+/)?.[0].length??0,c=r.replace(/^\s+|\s+$/g,"");return!o||!c?null:{text:c,styleRanges:tt(a.map(d=>({start:d.start-i,end:d.end-i,style:d.style})),c.length)}}async function ht(e,t,n,r,o,a){let s=document.createElement("iframe");s.style.cssText=`
|
|
17
|
+
position: fixed;
|
|
18
|
+
left: -${r+200}px;
|
|
19
|
+
top: 0;
|
|
20
|
+
width: ${r}px;
|
|
21
|
+
height: ${o}px;
|
|
22
|
+
border: none;
|
|
23
|
+
visibility: hidden;
|
|
24
|
+
`,document.body.appendChild(s);try{await new Promise((p,f)=>{let g=setTimeout(()=>p(),nt);s.addEventListener("load",()=>{clearTimeout(g),p()},{once:!0}),s.addEventListener("error",()=>{clearTimeout(g),f(new Error("iframe load error"))},{once:!0});let y=`<style>
|
|
25
|
+
* { box-sizing: border-box; font-family: Arial, Helvetica, sans-serif; }
|
|
26
|
+
body { margin: 0; padding: 0; }
|
|
27
|
+
</style>`;s.srcdoc=y+e});let l=s.contentDocument;if(!l)return[];let i=l.querySelector(".canvas"),c=i??l.body,d=c.getBoundingClientRect(),u=Array.from(c.querySelectorAll("*")),h=[];for(let p of u){let f=p.getBoundingClientRect();if(f.width<ke||f.height<ke)continue;let g=s.contentWindow.getComputedStyle(p);if(g.display==="none"||g.visibility==="hidden"||Ce.has(p.tagName)&&p.parentElement&&ut(p.parentElement)!==null)continue;let y=g.clipPath||g.webkitClipPath||"none";if(y!=="none"&&y.includes("polygon"))continue;let b=Math.round(t+(f.left-d.left)),w=Math.round(n+(f.top-d.top)),E=Math.round(f.width),R=Math.round(f.height),T=Math.round(parseFloat(g.opacity??"1")*100),k=g.backgroundImage||"none",C=g.backgroundColor||"transparent",O=g.borderColor||"transparent",x=parseFloat(g.borderWidth||"0"),P=ct(k);if(P){h.push({kind:"image",x:b,y:w,width:E,height:R,dataUrl:P});continue}let F=Oe(p,M=>s.contentWindow.getComputedStyle(M),a),v=F?.text??null;if(v){let M=g.textTransform||"none";v=ot(v,M);let K=T<100?T:rt(g.color||"rgb(0,0,0)"),I=dt(g.textAlign||"left"),D=b;I==="center"?D=b+E/2:I==="right"&&(D=b+E),h.push({kind:"text",x:D,y:w,width:E,height:R,text:v,styleRanges:F?.styleRanges,fontSize:$e(g.fontSize||"16px"),fontFamily:Me(g.fontFamily||"",a),color:N(g.color||"#000000"),textAlign:I,opacity:Math.min(T,K)})}let z=C!=="transparent"&&C!=="rgba(0, 0, 0, 0)",U=st(k),B=x>0&&O!=="transparent"&&O!=="rgba(0, 0, 0, 0)";if(z||U||B){let M=U?lt(k):N(C),I=it(g,E,R)?{kind:"ellipse",x:b,y:w,width:E,height:R,backgroundColor:z||U?M:"transparent",strokeColor:B?N(O):"transparent",strokeWidth:B?Math.round(x):0,opacity:T}:{kind:"rectangle",x:b,y:w,width:E,height:R,backgroundColor:z||U?M:"transparent",strokeColor:B?N(O):"transparent",strokeWidth:B?Math.round(x):0,opacity:T,borderRadius:at(g)};U&&(I.backgroundGradient=k),v?h.splice(h.length-1,0,I):h.push(I)}}return h}finally{document.body.removeChild(s)}}var ge=3.5*1024*1024;function gt(e){return!!e&&typeof e=="object"&&e.type==="image_url"&&typeof e.image_url?.url=="string"}function mt(e){let t=[];return e.forEach((n,r)=>{if(Array.isArray(n.content))for(let o of n.content)gt(o)&&t.push({msgIndex:r,part:o})}),t}async function Pe(e){let t=e,n=mt(t);if(n.length===0)return e;let r=await Promise.all(n.map(({part:s})=>W(s.image_url.url)));n.forEach(({part:s},l)=>{s.image_url.url=r[l]});let o=()=>JSON.stringify(e).length;if(o()<=ge)return e;for(let s of[960,720,512]){let l=[...n].sort((i,c)=>$(c.part.image_url.url)-$(i.part.image_url.url));for(let{part:i}of l)if(i.image_url.url=await V(i.image_url.url,s),o()<=ge)return e}let a=t.length-1;for(let{msgIndex:s,part:l}of n){if(s===a)continue;let i=t[s];if(Array.isArray(i.content)&&(i.content=i.content.filter(c=>c!==l),console.warn("[imagePayload] dropped an image from an earlier turn to fit the request cap"),o()<=ge))return e}return e}async function Jt(e){let t=await e.text().catch(()=>"");try{let r=JSON.parse(t);if(r?.error?.message)return r.error.message;if(typeof r?.error=="string")return r.error}catch{}if(e.status===413)return"This request was too large to send. Try attaching fewer images, or start a new chat to clear older ones.";if(e.status===429)return"Rate limited \u2014 please wait a moment and try again.";if(e.status===401||e.status===403)return"This request was not authorised. Please refresh and try again.";if(e.status>=500)return`The AI service is temporarily unavailable (${e.status}). Please try again.`;let n=t.trim().slice(0,200);return n?`Request failed (${e.status}): ${n}`:`Request failed (${e.status}).`}var pt=`You are the Brand Governance Agent \u2014 a Senior Ad Creative Director, Brand Compliance Officer, and Legal QA Auditor combined. You receive a rendered screenshot of a finished advertisement that was generated as a SINGLE AI image \u2014 the visuals AND all copy (headline, subheadline, CTA, body text, sign-off) are part of the image itself.
|
|
28
|
+
|
|
29
|
+
Your job is to evaluate every output before it moves forward, covering BOTH creative quality AND brand-governance compliance. Return precise, actionable fixes that the art director will fold into a REVISED IMAGE-GENERATION PROMPT (the ad is regenerated, not edited element-by-element).
|
|
30
|
+
|
|
31
|
+
## What you check (in priority order)
|
|
32
|
+
|
|
33
|
+
### A \u2014 Creative Quality
|
|
34
|
+
|
|
35
|
+
1. **Copy correctness** \u2014 Is every word of on-image text spelled correctly and rendered cleanly? AI image models frequently garble, misspell, duplicate, or drop letters. Flag any misspelled, malformed, gibberish, or truncated text and state the exact words that must appear.
|
|
36
|
+
2. **Copy legibility** \u2014 Is the text large enough and high-contrast enough to read at a glance? Is it clear of busy areas of the image? Is the visual hierarchy right (headline dominant, CTA distinct)?
|
|
37
|
+
3. **CTA prominence** \u2014 Is the call-to-action clearly readable and styled as an actionable element?
|
|
38
|
+
4. **Composition & polish** \u2014 Balanced layout, adequate margins, no awkward cropping of subjects or text, professional advertising quality.
|
|
39
|
+
|
|
40
|
+
### B \u2014 Brand Governance (check every dimension below)
|
|
41
|
+
|
|
42
|
+
5. **Brand tone** \u2014 Does the copy register match the brand's prescribed tone-of-voice (e.g. friendly vs. authoritative, casual vs. formal, sentence length, vocabulary level, person/voice)? Flag tone drift even if individual words are correct.
|
|
43
|
+
6. **Logo usage** \u2014 If a brand logo is visible in the ad: Is it correctly placed (not distorted, not overlapping busy areas)? Is it at an appropriate size? Has it been cropped, recolored, or stretched in violation of brand standards? If a logo was expected and is absent, flag that too.
|
|
44
|
+
7. **Claim accuracy** \u2014 Are product or service claims in the copy factual and supportable? Flag superlatives ("best", "fastest", "#1") that are unqualified, exaggerated feature claims, and any copy that overpromises.
|
|
45
|
+
8. **Legal mandatories** \u2014 Are required legal elements present where the brief or brand guidelines demand them (e.g. trademark symbols \u2122/\xAE, copyright notices, required taglines, mandated disclosures)?
|
|
46
|
+
9. **Offer disclaimers** \u2014 If the ad contains a promotional offer, price, discount, or time-limited deal, is the appropriate disclaimer or terms-and-conditions reference visible (e.g. "T&Cs apply", "while stocks last", "offer ends DD/MM/YYYY")?
|
|
47
|
+
10. **Regulatory sensitivity** \u2014 Does the ad touch regulated categories (finance, health, alcohol, gambling, children, pharmaceuticals, food nutrition claims)? If so, flag any copy that would likely breach sector-specific advertising standards (e.g. health benefit claims without qualification, alcohol ads implying social success, financial promotions without risk warnings).
|
|
48
|
+
11. **Prohibited language** \u2014 Is there any language that is explicitly banned by the brand's guidelines or that is generally off-limits in advertising (hate speech, discriminatory language, demeaning stereotypes, shock tactics beyond what the brief permits)?
|
|
49
|
+
12. **Competitive claims** \u2014 Does the ad make comparative or disparaging claims about named competitors or competitor products? Unless the brief explicitly permits a named comparison, flag these as requiring legal review.
|
|
50
|
+
13. **Data/privacy concerns** \u2014 Does the copy contain, imply, or reference personally identifiable information, user data, or surveillance-style targeting language that could raise GDPR/CCPA concerns or erode consumer trust?
|
|
51
|
+
|
|
52
|
+
## Rules for your critique
|
|
53
|
+
|
|
54
|
+
- **Express every fix as a prompt-level instruction**, e.g. "Regenerate with the headline reading exactly 'Fresh Pasta, Made Daily' in a bold sans-serif" or "Add 'T&Cs apply' in small text at the bottom of the ad." Do NOT describe CSS, element coordinates, or canvas operations \u2014 there is no editable layer; the whole ad is regenerated from the prompt.
|
|
55
|
+
- **Quote exact copy.** When text is wrong or missing, state the precise words that must appear so the next prompt can render them correctly.
|
|
56
|
+
- If something is fine, do NOT invent issues. Approve confidently.
|
|
57
|
+
- **User brief overrides brand guidelines.** If the user explicitly requested a color, style, or layout, treat it as intentional. Brand guidelines apply only where the brief is silent.
|
|
58
|
+
- **NEVER suggest changes to the logo.** The logo is a supplied brand asset. Do NOT flag it as needing to be altered, recoloured, repositioned based on taste, or replaced. If you believe the logo is absent or severely distorted (e.g. unreadable), you may note it under the "logo" element, but your fix must only ask to reproduce it faithfully \u2014 never to redesign, recolour, or remove it.
|
|
59
|
+
- **NEVER suggest changing the visual content of image elements.** Your mandate covers text copy correctness, legibility, legal mandatories, and brand tone. Do NOT suggest changing what an image depicts, what a product looks like, what the background scene contains, or the composition of any image asset. Only flag content that breaks a named compliance rule.
|
|
60
|
+
- **Severity guide** \u2014 critical: blocks legal/compliance sign-off or is factually wrong; major: clear brand or quality failure that needs fixing before launch; minor: polish or preference that would improve the creative.
|
|
61
|
+
|
|
62
|
+
## Approval criteria
|
|
63
|
+
|
|
64
|
+
Set approved=true with an empty issues array only when ALL of the following are true:
|
|
65
|
+
- All on-image copy is correctly spelled and matches the intended words
|
|
66
|
+
- All text is legible (adequate size and contrast)
|
|
67
|
+
- The CTA is clearly readable and distinct
|
|
68
|
+
- Brand colors/typographic register are respected (where the brief is silent)
|
|
69
|
+
- Brand tone-of-voice matches the prescribed register
|
|
70
|
+
- Logo (if present) follows brand usage standards
|
|
71
|
+
- No unqualified superlatives or unsupportable claims
|
|
72
|
+
- All required legal mandatories and offer disclaimers are present
|
|
73
|
+
- No regulatory red flags for the category
|
|
74
|
+
- No prohibited language or inappropriate content
|
|
75
|
+
- No unlicensed competitive claims or comparative disparagement
|
|
76
|
+
- No data/privacy red flags in the copy
|
|
77
|
+
- The composition looks intentional and professional
|
|
78
|
+
|
|
79
|
+
## Output
|
|
80
|
+
|
|
81
|
+
Return ONLY a JSON object matching this schema exactly. No markdown, no prose, no code fences.
|
|
82
|
+
|
|
83
|
+
{
|
|
84
|
+
"approved": boolean,
|
|
85
|
+
"issues": [
|
|
86
|
+
{
|
|
87
|
+
"element": "headline" | "subheadline" | "cta" | "image" | "layout" | "brand" | "brand_tone" | "logo" | "claim" | "legal" | "disclaimer" | "regulatory" | "prohibited_language" | "competitive_claim" | "privacy",
|
|
88
|
+
"severity": "critical" | "major" | "minor",
|
|
89
|
+
"problem": "string \u2014 one sentence describing what is wrong",
|
|
90
|
+
"fix": "string \u2014 one-line direction",
|
|
91
|
+
"preciseInstruction": "string \u2014 a prompt-level instruction for the regenerated image, quoting exact copy where relevant"
|
|
92
|
+
}
|
|
93
|
+
],
|
|
94
|
+
"summary": "string \u2014 1-2 sentences overall verdict"
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
## Example output (issues found)
|
|
98
|
+
|
|
99
|
+
{
|
|
100
|
+
"approved": false,
|
|
101
|
+
"issues": [
|
|
102
|
+
{
|
|
103
|
+
"element": "headline",
|
|
104
|
+
"severity": "critical",
|
|
105
|
+
"problem": "The headline renders as 'Frsh Psata' \u2014 the AI image garbled the text.",
|
|
106
|
+
"fix": "Regenerate so the headline is spelled correctly.",
|
|
107
|
+
"preciseInstruction": "Regenerate the ad with the headline reading EXACTLY 'Fresh Pasta' in a bold sans-serif, crisp and legible, no misspellings."
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
"element": "claim",
|
|
111
|
+
"severity": "critical",
|
|
112
|
+
"problem": "Copy reads 'The World's Best Pasta' \u2014 an unqualified superlative with no supporting evidence.",
|
|
113
|
+
"fix": "Remove or qualify the superlative.",
|
|
114
|
+
"preciseInstruction": "Replace 'The World's Best Pasta' with a specific, supportable claim such as 'Award-Winning Fresh Pasta' or 'Loved by 10,000 Customers'."
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
"element": "disclaimer",
|
|
118
|
+
"severity": "major",
|
|
119
|
+
"problem": "The ad promotes '50% off today only' with no terms-and-conditions reference.",
|
|
120
|
+
"fix": "Add a disclaimer line for the limited-time offer.",
|
|
121
|
+
"preciseInstruction": "Add small text at the bottom of the ad reading 'Offer valid today only. T&Cs apply. While stocks last.'"
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
"element": "brand_tone",
|
|
125
|
+
"severity": "minor",
|
|
126
|
+
"problem": "The copy uses formal third-person language ('One may enjoy...') against a brand voice that is casual and second-person.",
|
|
127
|
+
"fix": "Rewrite in the brand's casual, direct voice.",
|
|
128
|
+
"preciseInstruction": "Replace the body copy with second-person, conversational language matching the brand tone, e.g. 'You'll love every bite \u2014 made fresh for you, every day.'"
|
|
129
|
+
}
|
|
130
|
+
],
|
|
131
|
+
"summary": "Critical compliance and quality issues: misspelled headline, unqualified superlative, missing offer disclaimer, and tone-of-voice drift. Regenerate the image with the corrections above."
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
## Example output (approved)
|
|
135
|
+
|
|
136
|
+
{
|
|
137
|
+
"approved": true,
|
|
138
|
+
"issues": [],
|
|
139
|
+
"summary": "Clean, compliant creative: copy is correctly spelled and legible, all claims are supportable, legal mandatories are present, brand tone and colors are on-point, and the composition looks polished and professional."
|
|
140
|
+
}`;function ft(e){let t=[];if(e.colors){let{primary:n,secondary:r,accent:o,background:a}=e.colors,s=[n&&`primary: ${n}`,r&&`secondary: ${r}`,o&&`CTA/accent: ${o}`,a&&`background: ${a}`].filter(Boolean);s.length&&t.push(`Brand colors \u2014 ${s.join(", ")}`)}if(e.typography){let{headline:n,body:r}=e.typography;n?.family&&t.push(`Headline font: ${n.family}${n.weight?` ${n.weight}`:""}`),r?.family&&t.push(`Body font: ${r.family}${r.weight?` ${r.weight}`:""}`)}if(e.visualStyle&&t.push(`Visual style: ${e.visualStyle}`),e.toneOfVoice){let{register:n,vocabulary:r,ctaStyle:o,sentenceLength:a,person:s}=e.toneOfVoice,l=[n&&`register: ${n}`,r&&`vocabulary: ${r}`,s&&`person/voice: ${s}`,a&&`sentence length: ${a}`,o&&`CTA style: ${o}`].filter(Boolean);l.length&&t.push(`Tone-of-voice \u2014 ${l.join(", ")}`)}if(e.logoDataUrl){let n=e.logoDataUrl.startsWith("data:");t.push(`Logo: provided as ${n?"base64 data URL":"external URL"} \u2014 a reference image is attached separately; verify it appears correctly in the ad (correct placement, scale, no distortion or recolouring)`)}return t.join(`
|
|
141
|
+
`)}async function yt(e){let{screenshotDataUrl:t,htmlSource:n,frame:r,userBrief:o,originalImageDataUrl:a,brandContext:s,chatUrl:l,reviewerModel:i="google/gemini-2.5-flash",signal:c,iteration:d}=e,u={approved:!0,issues:[],summary:"Reviewer unavailable; skipping.",iteration:d},h=s?.logoDataUrl,p=typeof h=="string"&&h.startsWith("data:"),f=typeof h=="string"&&!p,g=s?.headlineFontPreviewDataUrl,y=typeof g=="string"&&g.startsWith("data:"),b=s?.bodyFontPreviewDataUrl,w=typeof b=="string"&&b.startsWith("data:"),E=typeof a=="string"&&a.startsWith("data:"),R=["## Ad Brief (what the user requested)",o,"","## Frame dimensions",`Width: ${r.width}px, Height: ${r.height}px`];if(E&&R.push("","## Original reference image (what the user uploaded)","The image the user originally attached is included below (immediately after the ad screenshot). Judge fidelity against it: the generated ad should preserve the subject, composition, and style of this reference unless the brief explicitly asked for a different treatment. Flag it as an issue if the ad has drifted from this reference in ways the brief did not request (wrong subject, different color scheme, altered composition)."),s){let x=ft(s);x&&R.push("","## Brand guidelines",x)}if(p?R.push("","## Brand logo (reference)",`The brand logo is attached below (after the ad screenshot${E?" and the original reference image":""}). Use it to evaluate whether the logo in the ad matches the brand's actual logo in colour, shape, and typographic treatment.`):f&&R.push("","## Brand logo (reference \u2014 URL, may not be visible)","A logo URL was provided but could not be embedded as an image. Evaluate logo usage from what is visible in the ad screenshot only."),y||w){let x=y&&w;R.push("",`## Brand font preview${x?"s":""} (reference)`,`The brand font preview${x?"s are":" is"} attached below. Use ${x?"them":"it"} to evaluate whether the on-image text matches the brand typeface \u2014 check letterforms, weight, and typographic style. The brand may use ${x?"either font":"this font"} for headlines or body copy; do NOT flag a font as an issue simply because of which role it is applied to \u2014 only flag text that does not match the brand fonts at all.`)}n&&n.trim()&&R.push("","## Source (legacy)","```",n,"```"),R.push("","## Your task","The screenshot of the generated ad is attached above. The whole ad (visuals + all copy) is a single AI-generated image. Evaluate it as the Brand Governance Agent \u2014 check creative quality (copy correctness, legibility, CTA, composition) AND all brand-governance dimensions (brand tone, logo usage, claim accuracy, legal mandatories, offer disclaimers, regulatory sensitivity, prohibited language, competitive claims, data/privacy concerns). Return your JSON critique. Every fix must be phrased as an instruction for regenerating the image.");let T=[{type:"image_url",image_url:{url:t}}];E&&a&&T.push({type:"image_url",image_url:{url:a}}),p&&h&&T.push({type:"image_url",image_url:{url:h}}),y&&g&&T.push({type:"image_url",image_url:{url:g}}),w&&b&&T.push({type:"image_url",image_url:{url:b}}),T.push({type:"text",text:R.join(`
|
|
142
|
+
`)});let k={model:i,messages:await Pe([{role:"system",content:pt},{role:"user",content:T}]),response_format:{type:"json_object"},stream:!1,temperature:.2},C;try{C=await fetch(l,{method:"POST",headers:{"Content-Type":"application/json","HTTP-Referer":"https://dughub.app","X-Title":"ADGEN Reviewer"},body:JSON.stringify(k),signal:c})}catch(x){if(x instanceof Error&&x.name==="AbortError")throw x;return u}if(!C.ok)return u;let O;try{O=(await C.json())?.choices?.[0]?.message?.content??""}catch{return u}try{let x=JSON.parse(O),P=Array.isArray(x.issues)?x.issues.filter(v=>v&&typeof v.element=="string"&&typeof v.severity=="string"&&typeof v.problem=="string"&&typeof v.preciseInstruction=="string"):[],F=typeof x.approved=="boolean"?x.approved:P.length===0;return{approved:F,issues:P,summary:typeof x.summary=="string"&&x.summary.trim()?x.summary:F?"Banner looks good.":`${P.length} issue(s) found.`,iteration:d}}catch{return u}}var Rt={"21:9":21/9,"16:9":16/9,"4:3":4/3,"3:2":3/2,"1:1":1,"9:16":9/16,"3:4":3/4,"2:3":2/3,"5:4":5/4,"4:5":4/5,"4:1":4/1,"1:4":1/4,"8:1":8/1,"1:8":1/8},vt=.12,Tt=.35;function At(e,t){return e>=t?1-t*1/e:1-e/t}function En(e,t,n,r){let o=e/t,a=n/r;return Math.abs(o-a)<=vt?!1:At(o,a)>Tt}function Rn(e,t){let n=e/t,r="1:1",o=1/0;for(let[a,s]of Object.entries(Rt)){let l=Math.abs(n-s);l<o&&(o=l,r=a)}return r}var me={"1:1":{"0.5K":[512,512],"1K":[1024,1024],"2K":[2048,2048],"4K":[4096,4096]},"1:4":{"0.5K":[256,1024],"1K":[512,2048],"2K":[1024,4096],"4K":[2048,8192]},"1:8":{"0.5K":[192,1536],"1K":[384,3072],"2K":[768,6144],"4K":[1536,12288]},"2:3":{"0.5K":[424,632],"1K":[848,1264],"2K":[1696,2528],"4K":[3392,5056]},"3:2":{"0.5K":[632,424],"1K":[1264,848],"2K":[2528,1696],"4K":[5056,3392]},"3:4":{"0.5K":[448,600],"1K":[896,1200],"2K":[1792,2400],"4K":[3584,4800]},"4:1":{"0.5K":[1024,256],"1K":[2048,512],"2K":[4096,1024],"4K":[8192,2048]},"4:3":{"0.5K":[600,448],"1K":[1200,896],"2K":[2400,1792],"4K":[4800,3584]},"4:5":{"0.5K":[464,576],"1K":[928,1152],"2K":[1856,2304],"4K":[3712,4608]},"5:4":{"0.5K":[576,464],"1K":[1152,928],"2K":[2304,1856],"4K":[4608,3712]},"8:1":{"0.5K":[1536,192],"1K":[3072,384],"2K":[6144,768],"4K":[12288,1536]},"9:16":{"0.5K":[384,688],"1K":[768,1376],"2K":[1536,2752],"4K":[3072,5504]},"16:9":{"0.5K":[688,384],"1K":[1376,768],"2K":[2752,1536],"4K":[5504,3072]},"21:9":{"0.5K":[792,168],"1K":[1584,672],"2K":[3168,1344],"4K":[6336,2688]}},vn=["0.5K","1K","2K","4K"],Tn=[{ratio:"1:1",desc:"Square"},{ratio:"16:9",desc:"Landscape"},{ratio:"9:16",desc:"Portrait / Story"},{ratio:"4:3",desc:"Landscape"},{ratio:"3:4",desc:"Portrait"},{ratio:"3:2",desc:"Landscape"},{ratio:"2:3",desc:"Portrait"},{ratio:"5:4",desc:"Landscape"},{ratio:"4:5",desc:"Portrait"},{ratio:"21:9",desc:"Ultrawide"},{ratio:"4:1",desc:"Wide strip"},{ratio:"1:4",desc:"Tall strip"},{ratio:"8:1",desc:"Banner"},{ratio:"1:8",desc:"Skyscraper"}];function An(e,t){let n=me[e]??me["1:1"],r=n[t]??n["1K"]??[1024,1024];return{width:r[0],height:r[1]}}function Sn(e,t,n){let r=me[n];if(!r)return"1K";let o=e*t,a="1K",s=1/0;for(let[l,[i,c]]of Object.entries(r)){let d=i*c,u=Math.abs(d-o);d>=o?u<s&&(s=u,a=l):(s===1/0||u<s)&&(s=u,a=l)}return a}function In(e,t,n){let r=t.x+t.width+80,o=e.map((i,c)=>{let d=e.slice(0,c).reduce((h,p)=>h+p.height+40,t.y);return{frame:bt({...wt,x:r,y:d,width:i.width,height:i.height,opacity:100,locked:!1,name:i.label??`${i.width}\xD7${i.height}`}),x:r,y:d,width:i.width,height:i.height}}),a=n.getSceneElements(),s=o.map(i=>i.frame),l=[...a,...s];return xt(l,Et(s)),n.updateScene({elements:l}),o.map(i=>({frameId:i.frame.id,x:i.x,y:i.y,width:i.width,height:i.height}))}async function kn(e){let{runNativeAutoResize:t}=await import("./components/auto-resize/nativeResizeAgent-45UNA3LO.js");return t(e)}export{It as a,kt as b,Te as c,Ke as d,Ye as e,je as f,zt as g,ht as h,Pe as i,Jt as j,yt as k,et as l,En as m,Rn as n,vn as o,Tn as p,An as q,Sn as r,In as s,kn as t};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{oa as n,v as c,w as d}from"./chunk-U2I2OXQ7.js";import i from"png-chunk-text";import m from"png-chunks-encode";import s from"png-chunks-extract";import{EXPORT_DATA_TYPES as w,MIME_TYPES as a}from"@orangecatai/common";var p=async e=>{let t=s(new Uint8Array(await n(e))).find(o=>o.name==="tEXt");return t?i.decode(t.data):null},x=async({blob:e,metadata:r})=>{let t=s(new Uint8Array(await n(e))),o=i.encode(a.excalidraw,JSON.stringify(c({text:r,compress:!0})));return t.splice(-1,0,o),new Blob([m(t)],{type:a.png})},b=async e=>{let r=await p(e);if(r?.keyword===a.excalidraw)try{let t=JSON.parse(r.text);if(!("encoded"in t)){if("type"in t&&t.type===w.excalidraw)return r.text;throw new Error("FAILED")}return d(t)}catch(t){throw console.error(t),new Error("FAILED")}throw new Error("INVALID")};export{p as a,x as b,b as c};
|
|
@@ -4,4 +4,4 @@ kPOPxhz+nxUrIoWCD/V4NGmUA1lxwHuO21HN1gzKrN3xHg5EGjyouR9vibT9VDGF
|
|
|
4
4
|
gq6+4Ic/kJX+AD2MM7Yre2+FsOdysrmuW2Fu3ahuC1uQE7pOe1j0k7auNP0y1q53
|
|
5
5
|
PrB8Ts2LUpepWC1l7zIXFm4ViDULuyWXTEpUcHSsEH8vpd1tckjypxCwkipfZsXx
|
|
6
6
|
iPszy0o0Dx2iArPfWMXlFAI9mvyFCyFC3+nSvfyAUb2C4uZgCwAuyFh/ydPF4DEE
|
|
7
|
-
PQIDAQAB`,VITE_APP_DEBUG_ENABLE_TEXT_CONTAINER_BOUNDING_BOX:"false",VITE_APP_COLLAPSE_OVERLAY:"false",VITE_APP_ENABLE_ESLINT:"false",PKG_NAME:"@orangecatai/adgen-canvas",PKG_VERSION:"0.0
|
|
7
|
+
PQIDAQAB`,VITE_APP_DEBUG_ENABLE_TEXT_CONTAINER_BOUNDING_BOX:"false",VITE_APP_COLLAPSE_OVERLAY:"false",VITE_APP_ENABLE_ESLINT:"false",PKG_NAME:"@orangecatai/adgen-canvas",PKG_VERSION:"0.1.0",PROD:!0};export{c as a};
|