human2ai 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.
Files changed (326) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +120 -0
  3. package/assets/quaternius/License_Standard.txt +22 -0
  4. package/assets/quaternius/README.md +31 -0
  5. package/assets/quaternius/Superhero_Female_FullBody.bin +0 -0
  6. package/assets/quaternius/Superhero_Female_FullBody.gltf +2056 -0
  7. package/assets/quaternius/Superhero_Male_FullBody.bin +0 -0
  8. package/assets/quaternius/Superhero_Male_FullBody.gltf +2018 -0
  9. package/dist/cli/integration.d.ts +39 -0
  10. package/dist/cli/integration.js +466 -0
  11. package/dist/cli/integration.js.map +1 -0
  12. package/dist/cli/main.d.ts +17 -0
  13. package/dist/cli/main.js +1455 -0
  14. package/dist/cli/main.js.map +1 -0
  15. package/dist/database/composition-session-repository.d.ts +37 -0
  16. package/dist/database/composition-session-repository.js +147 -0
  17. package/dist/database/composition-session-repository.js.map +1 -0
  18. package/dist/database/draft-version-errors.d.ts +29 -0
  19. package/dist/database/draft-version-errors.js +47 -0
  20. package/dist/database/draft-version-errors.js.map +1 -0
  21. package/dist/database/draft-version-store.d.ts +30 -0
  22. package/dist/database/draft-version-store.js +168 -0
  23. package/dist/database/draft-version-store.js.map +1 -0
  24. package/dist/database/image-asset-repository.d.ts +37 -0
  25. package/dist/database/image-asset-repository.js +101 -0
  26. package/dist/database/image-asset-repository.js.map +1 -0
  27. package/dist/database/image-input.d.ts +15 -0
  28. package/dist/database/image-input.js +28 -0
  29. package/dist/database/image-input.js.map +1 -0
  30. package/dist/database/migrate.d.ts +4 -0
  31. package/dist/database/migrate.js +45 -0
  32. package/dist/database/migrate.js.map +1 -0
  33. package/dist/database/project-session-repository.d.ts +72 -0
  34. package/dist/database/project-session-repository.js +291 -0
  35. package/dist/database/project-session-repository.js.map +1 -0
  36. package/dist/database/spatial-session-repository.d.ts +26 -0
  37. package/dist/database/spatial-session-repository.js +44 -0
  38. package/dist/database/spatial-session-repository.js.map +1 -0
  39. package/dist/database/style-library-repository.d.ts +70 -0
  40. package/dist/database/style-library-repository.js +290 -0
  41. package/dist/database/style-library-repository.js.map +1 -0
  42. package/dist/database/svg-input.d.ts +1 -0
  43. package/dist/database/svg-input.js +77 -0
  44. package/dist/database/svg-input.js.map +1 -0
  45. package/dist/database/ui-sketch-session-repository.d.ts +19 -0
  46. package/dist/database/ui-sketch-session-repository.js +35 -0
  47. package/dist/database/ui-sketch-session-repository.js.map +1 -0
  48. package/dist/domain/canvas-layer-order.d.ts +6 -0
  49. package/dist/domain/canvas-layer-order.js +40 -0
  50. package/dist/domain/canvas-layer-order.js.map +1 -0
  51. package/dist/domain/canvas-node-metadata.d.ts +20 -0
  52. package/dist/domain/canvas-node-metadata.js +17 -0
  53. package/dist/domain/canvas-node-metadata.js.map +1 -0
  54. package/dist/domain/canvas-states.d.ts +8 -0
  55. package/dist/domain/canvas-states.js +23 -0
  56. package/dist/domain/canvas-states.js.map +1 -0
  57. package/dist/domain/composition/analysis.d.ts +104 -0
  58. package/dist/domain/composition/analysis.js +337 -0
  59. package/dist/domain/composition/analysis.js.map +1 -0
  60. package/dist/domain/composition/camera-reference.d.ts +24 -0
  61. package/dist/domain/composition/camera-reference.js +34 -0
  62. package/dist/domain/composition/camera-reference.js.map +1 -0
  63. package/dist/domain/composition/draft.d.ts +50 -0
  64. package/dist/domain/composition/draft.js +609 -0
  65. package/dist/domain/composition/draft.js.map +1 -0
  66. package/dist/domain/composition/frame.d.ts +23 -0
  67. package/dist/domain/composition/frame.js +154 -0
  68. package/dist/domain/composition/frame.js.map +1 -0
  69. package/dist/domain/composition/geometry.d.ts +15 -0
  70. package/dist/domain/composition/geometry.js +262 -0
  71. package/dist/domain/composition/geometry.js.map +1 -0
  72. package/dist/domain/composition/index.d.ts +13 -0
  73. package/dist/domain/composition/index.js +10 -0
  74. package/dist/domain/composition/index.js.map +1 -0
  75. package/dist/domain/composition/layers.d.ts +4 -0
  76. package/dist/domain/composition/layers.js +12 -0
  77. package/dist/domain/composition/layers.js.map +1 -0
  78. package/dist/domain/composition/records.d.ts +14 -0
  79. package/dist/domain/composition/records.js +2 -0
  80. package/dist/domain/composition/records.js.map +1 -0
  81. package/dist/domain/composition/refinement/engine.d.ts +12 -0
  82. package/dist/domain/composition/refinement/engine.js +521 -0
  83. package/dist/domain/composition/refinement/engine.js.map +1 -0
  84. package/dist/domain/composition/refinement/relations.d.ts +16 -0
  85. package/dist/domain/composition/refinement/relations.js +293 -0
  86. package/dist/domain/composition/refinement/relations.js.map +1 -0
  87. package/dist/domain/composition/refinement/types.d.ts +181 -0
  88. package/dist/domain/composition/refinement/types.js +2 -0
  89. package/dist/domain/composition/refinement/types.js.map +1 -0
  90. package/dist/domain/composition/render.d.ts +5 -0
  91. package/dist/domain/composition/render.js +169 -0
  92. package/dist/domain/composition/render.js.map +1 -0
  93. package/dist/domain/composition/states.d.ts +9 -0
  94. package/dist/domain/composition/states.js +104 -0
  95. package/dist/domain/composition/states.js.map +1 -0
  96. package/dist/domain/composition/types.d.ts +149 -0
  97. package/dist/domain/composition/types.js +2 -0
  98. package/dist/domain/composition/types.js.map +1 -0
  99. package/dist/domain/composition/workflow.d.ts +15 -0
  100. package/dist/domain/composition/workflow.js +77 -0
  101. package/dist/domain/composition/workflow.js.map +1 -0
  102. package/dist/domain/fingerprint.d.ts +2 -0
  103. package/dist/domain/fingerprint.js +25 -0
  104. package/dist/domain/fingerprint.js.map +1 -0
  105. package/dist/domain/session/canvas-edit-history.d.ts +17 -0
  106. package/dist/domain/session/canvas-edit-history.js +53 -0
  107. package/dist/domain/session/canvas-edit-history.js.map +1 -0
  108. package/dist/domain/session/capabilities.d.ts +16 -0
  109. package/dist/domain/session/capabilities.js +84 -0
  110. package/dist/domain/session/capabilities.js.map +1 -0
  111. package/dist/domain/session/draft-version.d.ts +41 -0
  112. package/dist/domain/session/draft-version.js +2 -0
  113. package/dist/domain/session/draft-version.js.map +1 -0
  114. package/dist/domain/session/index.d.ts +5 -0
  115. package/dist/domain/session/index.js +3 -0
  116. package/dist/domain/session/index.js.map +1 -0
  117. package/dist/domain/session/types.d.ts +23 -0
  118. package/dist/domain/session/types.js +2 -0
  119. package/dist/domain/session/types.js.map +1 -0
  120. package/dist/domain/spatial/assets/quaternius-female-rig.json +799 -0
  121. package/dist/domain/spatial/assets/quaternius-rig.json +799 -0
  122. package/dist/domain/spatial/assets/quaternius-superhero-female.json +1 -0
  123. package/dist/domain/spatial/assets/quaternius-superhero.json +1 -0
  124. package/dist/domain/spatial/camera-box.d.ts +13 -0
  125. package/dist/domain/spatial/camera-box.js +52 -0
  126. package/dist/domain/spatial/camera-box.js.map +1 -0
  127. package/dist/domain/spatial/geometric-model.d.ts +4 -0
  128. package/dist/domain/spatial/geometric-model.js +101 -0
  129. package/dist/domain/spatial/geometric-model.js.map +1 -0
  130. package/dist/domain/spatial/hands.d.ts +36 -0
  131. package/dist/domain/spatial/hands.js +128 -0
  132. package/dist/domain/spatial/hands.js.map +1 -0
  133. package/dist/domain/spatial/index.d.ts +30 -0
  134. package/dist/domain/spatial/index.js +381 -0
  135. package/dist/domain/spatial/index.js.map +1 -0
  136. package/dist/domain/spatial/kinematics.d.ts +27 -0
  137. package/dist/domain/spatial/kinematics.js +285 -0
  138. package/dist/domain/spatial/kinematics.js.map +1 -0
  139. package/dist/domain/spatial/lighting.d.ts +35 -0
  140. package/dist/domain/spatial/lighting.js +173 -0
  141. package/dist/domain/spatial/lighting.js.map +1 -0
  142. package/dist/domain/spatial/model.d.ts +5 -0
  143. package/dist/domain/spatial/model.js +193 -0
  144. package/dist/domain/spatial/model.js.map +1 -0
  145. package/dist/domain/spatial/morph.d.ts +3 -0
  146. package/dist/domain/spatial/morph.js +187 -0
  147. package/dist/domain/spatial/morph.js.map +1 -0
  148. package/dist/domain/spatial/proportions.d.ts +46 -0
  149. package/dist/domain/spatial/proportions.js +59 -0
  150. package/dist/domain/spatial/proportions.js.map +1 -0
  151. package/dist/domain/spatial/reference-lines.d.ts +6 -0
  152. package/dist/domain/spatial/reference-lines.js +58 -0
  153. package/dist/domain/spatial/reference-lines.js.map +1 -0
  154. package/dist/domain/spatial/scene-cache.d.ts +15 -0
  155. package/dist/domain/spatial/scene-cache.js +69 -0
  156. package/dist/domain/spatial/scene-cache.js.map +1 -0
  157. package/dist/domain/spatial/scene.d.ts +8 -0
  158. package/dist/domain/spatial/scene.js +69 -0
  159. package/dist/domain/spatial/scene.js.map +1 -0
  160. package/dist/domain/spatial/types.d.ts +187 -0
  161. package/dist/domain/spatial/types.js +5 -0
  162. package/dist/domain/spatial/types.js.map +1 -0
  163. package/dist/domain/style/index.d.ts +1 -0
  164. package/dist/domain/style/index.js +2 -0
  165. package/dist/domain/style/index.js.map +1 -0
  166. package/dist/domain/style/prompt-summary.d.ts +2 -0
  167. package/dist/domain/style/prompt-summary.js +11 -0
  168. package/dist/domain/style/prompt-summary.js.map +1 -0
  169. package/dist/domain/style/types.d.ts +32 -0
  170. package/dist/domain/style/types.js +3 -0
  171. package/dist/domain/style/types.js.map +1 -0
  172. package/dist/domain/ui-sketch/draft.d.ts +12 -0
  173. package/dist/domain/ui-sketch/draft.js +424 -0
  174. package/dist/domain/ui-sketch/draft.js.map +1 -0
  175. package/dist/domain/ui-sketch/geometry.d.ts +7 -0
  176. package/dist/domain/ui-sketch/geometry.js +11 -0
  177. package/dist/domain/ui-sketch/geometry.js.map +1 -0
  178. package/dist/domain/ui-sketch/groups.d.ts +5 -0
  179. package/dist/domain/ui-sketch/groups.js +40 -0
  180. package/dist/domain/ui-sketch/groups.js.map +1 -0
  181. package/dist/domain/ui-sketch/index.d.ts +8 -0
  182. package/dist/domain/ui-sketch/index.js +8 -0
  183. package/dist/domain/ui-sketch/index.js.map +1 -0
  184. package/dist/domain/ui-sketch/layers.d.ts +4 -0
  185. package/dist/domain/ui-sketch/layers.js +11 -0
  186. package/dist/domain/ui-sketch/layers.js.map +1 -0
  187. package/dist/domain/ui-sketch/render.d.ts +2 -0
  188. package/dist/domain/ui-sketch/render.js +58 -0
  189. package/dist/domain/ui-sketch/render.js.map +1 -0
  190. package/dist/domain/ui-sketch/standardize.d.ts +17 -0
  191. package/dist/domain/ui-sketch/standardize.js +139 -0
  192. package/dist/domain/ui-sketch/standardize.js.map +1 -0
  193. package/dist/domain/ui-sketch/states.d.ts +5 -0
  194. package/dist/domain/ui-sketch/states.js +21 -0
  195. package/dist/domain/ui-sketch/states.js.map +1 -0
  196. package/dist/domain/ui-sketch/types.d.ts +73 -0
  197. package/dist/domain/ui-sketch/types.js +2 -0
  198. package/dist/domain/ui-sketch/types.js.map +1 -0
  199. package/dist/server/app.d.ts +18 -0
  200. package/dist/server/app.js +108 -0
  201. package/dist/server/app.js.map +1 -0
  202. package/dist/server/image-content-type-parser.d.ts +2 -0
  203. package/dist/server/image-content-type-parser.js +5 -0
  204. package/dist/server/image-content-type-parser.js.map +1 -0
  205. package/dist/server/routes/composition-sessions.d.ts +3 -0
  206. package/dist/server/routes/composition-sessions.js +190 -0
  207. package/dist/server/routes/composition-sessions.js.map +1 -0
  208. package/dist/server/routes/draft-version-routes.d.ts +10 -0
  209. package/dist/server/routes/draft-version-routes.js +201 -0
  210. package/dist/server/routes/draft-version-routes.js.map +1 -0
  211. package/dist/server/routes/image-assets.d.ts +3 -0
  212. package/dist/server/routes/image-assets.js +114 -0
  213. package/dist/server/routes/image-assets.js.map +1 -0
  214. package/dist/server/routes/project-sessions.d.ts +48 -0
  215. package/dist/server/routes/project-sessions.js +305 -0
  216. package/dist/server/routes/project-sessions.js.map +1 -0
  217. package/dist/server/routes/spatial-sessions.d.ts +3 -0
  218. package/dist/server/routes/spatial-sessions.js +80 -0
  219. package/dist/server/routes/spatial-sessions.js.map +1 -0
  220. package/dist/server/routes/style-library.d.ts +3 -0
  221. package/dist/server/routes/style-library.js +308 -0
  222. package/dist/server/routes/style-library.js.map +1 -0
  223. package/dist/server/routes/ui-sketch-sessions.d.ts +3 -0
  224. package/dist/server/routes/ui-sketch-sessions.js +14 -0
  225. package/dist/server/routes/ui-sketch-sessions.js.map +1 -0
  226. package/dist/server/runtime.d.ts +30 -0
  227. package/dist/server/runtime.js +123 -0
  228. package/dist/server/runtime.js.map +1 -0
  229. package/dist/server/spatial-render.d.ts +5 -0
  230. package/dist/server/spatial-render.js +360 -0
  231. package/dist/server/spatial-render.js.map +1 -0
  232. package/dist/server/start.d.ts +1 -0
  233. package/dist/server/start.js +3 -0
  234. package/dist/server/start.js.map +1 -0
  235. package/licenses/THIRD-PARTY-NOTICES.txt +16664 -0
  236. package/licenses/YisiUI-LICENSE +21 -0
  237. package/locales/en/common.json +671 -0
  238. package/migrations/0001_projects_and_sessions.sql +45 -0
  239. package/migrations/0002_composition_versions_and_refinements.sql +26 -0
  240. package/migrations/0003_ui_sketch_draft_versions.sql +12 -0
  241. package/migrations/0004_image_assets.sql +16 -0
  242. package/migrations/0005_style_library.sql +31 -0
  243. package/migrations/0006_session_styles.sql +6 -0
  244. package/migrations/0007_svg_image_assets.sql +19 -0
  245. package/migrations/0008_spatial_spaces.sql +20 -0
  246. package/package.json +82 -0
  247. package/schemas/composition-draft.schema.json +234 -0
  248. package/schemas/composition-refinement-plan.schema.json +758 -0
  249. package/schemas/spatial-draft.schema.json +517 -0
  250. package/schemas/spatial-operations.schema.json +1082 -0
  251. package/schemas/ui-layout-standardization-plan.schema.json +29 -0
  252. package/schemas/ui-sketch-draft.schema.json +197 -0
  253. package/skills/human2ai/SKILL.md +149 -0
  254. package/skills/human2ai/agents/openai.yaml +3 -0
  255. package/skills/human2ai/references/composition-projection.md +170 -0
  256. package/skills/human2ai/references/composition.md +79 -0
  257. package/skills/human2ai/references/spatial.md +188 -0
  258. package/skills/human2ai/references/svg-images.md +27 -0
  259. package/skills/human2ai/references/ui-layout.md +100 -0
  260. package/web/out/404/index.html +1 -0
  261. package/web/out/404.html +1 -0
  262. package/web/out/__next.__PAGE__.txt +26 -0
  263. package/web/out/__next._full.txt +21 -0
  264. package/web/out/__next._tree.txt +4 -0
  265. package/web/out/_next/static/TV-jgcACg6HANZAMZTE2S/_buildManifest.js +1 -0
  266. package/web/out/_next/static/TV-jgcACg6HANZAMZTE2S/_ssgManifest.js +1 -0
  267. package/web/out/_next/static/chunks/130-9fadd0432daff55d.js +1 -0
  268. package/web/out/_next/static/chunks/158-eb00456e1bab68b3.js +52 -0
  269. package/web/out/_next/static/chunks/20-0801fc297cda2a7a.js +1 -0
  270. package/web/out/_next/static/chunks/248-d4a79649dae2a3f8.js +259 -0
  271. package/web/out/_next/static/chunks/678-1305cadf8254d814.js +1 -0
  272. package/web/out/_next/static/chunks/728-eb8b667f79229443.js +1 -0
  273. package/web/out/_next/static/chunks/83607670-bc1279370476e59f.js +1 -0
  274. package/web/out/_next/static/chunks/app/_global-error/page-5eece43b8152c414.js +1 -0
  275. package/web/out/_next/static/chunks/app/_not-found/page-c0cd75ac39fbf9cf.js +1 -0
  276. package/web/out/_next/static/chunks/app/composition/page-051ee2fabb12110a.js +1 -0
  277. package/web/out/_next/static/chunks/app/layout-745ca27ef8830f4f.js +1 -0
  278. package/web/out/_next/static/chunks/app/page-0027378a269a6168.js +1 -0
  279. package/web/out/_next/static/chunks/app/spatial/page-266dedc81784d4f6.js +1 -0
  280. package/web/out/_next/static/chunks/app/styles/page-d5cb83af828ea9ed.js +1 -0
  281. package/web/out/_next/static/chunks/app/ui-sketch/page-2a8436e05a05c618.js +1 -0
  282. package/web/out/_next/static/chunks/c3f2cda1-9e279dab137b7272.js +342 -0
  283. package/web/out/_next/static/chunks/c7879cf7-7873c8afd9c9c666.js +1 -0
  284. package/web/out/_next/static/chunks/framework-6eacf80ec1e4c887.js +1 -0
  285. package/web/out/_next/static/chunks/main-5ee8fd93319f955c.js +5 -0
  286. package/web/out/_next/static/chunks/main-app-0cf10803ab17c700.js +1 -0
  287. package/web/out/_next/static/chunks/next/dist/client/components/builtin/app-error-5eece43b8152c414.js +1 -0
  288. package/web/out/_next/static/chunks/next/dist/client/components/builtin/forbidden-5eece43b8152c414.js +1 -0
  289. package/web/out/_next/static/chunks/next/dist/client/components/builtin/global-error-728204b7cccc4ed2.js +1 -0
  290. package/web/out/_next/static/chunks/next/dist/client/components/builtin/not-found-5eece43b8152c414.js +1 -0
  291. package/web/out/_next/static/chunks/next/dist/client/components/builtin/unauthorized-5eece43b8152c414.js +1 -0
  292. package/web/out/_next/static/chunks/polyfills-42372ed130431b0a.js +1 -0
  293. package/web/out/_next/static/chunks/webpack-97ae63c0e0b2a512.js +1 -0
  294. package/web/out/_next/static/css/3b7982b41ed8eccd.css +4 -0
  295. package/web/out/_next/static/css/81ae71f1d3e9a866.css +1 -0
  296. package/web/out/_next/static/css/8c3843f4951fa9f6.css +5 -0
  297. package/web/out/_next/static/css/c739d0131cdcc891.css +1 -0
  298. package/web/out/_next/static/css/ce1b4bb3ad3c6073.css +1 -0
  299. package/web/out/_next/static/css/db96ae2e88545d96.css +1 -0
  300. package/web/out/_not-found/__next._full.txt +18 -0
  301. package/web/out/_not-found/__next._not-found.__PAGE__.txt +24 -0
  302. package/web/out/_not-found/__next._tree.txt +3 -0
  303. package/web/out/_not-found/index.html +1 -0
  304. package/web/out/_not-found/index.txt +18 -0
  305. package/web/out/composition/__next._full.txt +25 -0
  306. package/web/out/composition/__next._tree.txt +6 -0
  307. package/web/out/composition/__next.composition.__PAGE__.txt +31 -0
  308. package/web/out/composition/index.html +1 -0
  309. package/web/out/composition/index.txt +25 -0
  310. package/web/out/index.html +1 -0
  311. package/web/out/index.txt +21 -0
  312. package/web/out/spatial/__next._full.txt +23 -0
  313. package/web/out/spatial/__next._tree.txt +4 -0
  314. package/web/out/spatial/__next.spatial.__PAGE__.txt +29 -0
  315. package/web/out/spatial/index.html +1 -0
  316. package/web/out/spatial/index.txt +23 -0
  317. package/web/out/styles/__next._full.txt +23 -0
  318. package/web/out/styles/__next._tree.txt +4 -0
  319. package/web/out/styles/__next.styles.__PAGE__.txt +29 -0
  320. package/web/out/styles/index.html +1 -0
  321. package/web/out/styles/index.txt +23 -0
  322. package/web/out/ui-sketch/__next._full.txt +25 -0
  323. package/web/out/ui-sketch/__next._tree.txt +6 -0
  324. package/web/out/ui-sketch/__next.ui-sketch.__PAGE__.txt +31 -0
  325. package/web/out/ui-sketch/index.html +1 -0
  326. package/web/out/ui-sketch/index.txt +25 -0
@@ -0,0 +1,50 @@
1
+ import type { AddCompositionImageOptions, AddAreaOptions, AreaAspect, CompositionArea, CompositionAreaMetadataPatch, CompositionClipboardItem, CompositionDraft, CompositionFrameBounds, CompositionFrameCorner, CompositionFrameSize, CompositionImage, CompositionNodeMetadataPatch, PasteCompositionItemsResult, CompositionProcessingSemantic, CompositionVisualWeight, Point, Primitive, VisibleAreaMetrics } from "./types.ts";
2
+ export declare const MAX_FOCUS_POINTS = 3;
3
+ export declare const PRIMITIVES: readonly Primitive[];
4
+ export declare const ASPECTS: readonly AreaAspect[];
5
+ export declare const COMPOSITION_TEXT_REGION_SEMANTIC_TYPE = "text-region";
6
+ export declare const COMPOSITION_PROCESSING_SEMANTICS: readonly CompositionProcessingSemantic[];
7
+ export declare const COMPOSITION_VISUAL_WEIGHTS: readonly CompositionVisualWeight[];
8
+ export declare function createDraft(frame?: CompositionFrameSize): CompositionDraft;
9
+ export declare function validateDraft(input: unknown): CompositionDraft;
10
+ export declare function addFocus(input: CompositionDraft, point: Point): {
11
+ draft: CompositionDraft;
12
+ id: string;
13
+ };
14
+ export declare function addArea(input: CompositionDraft, options: AddAreaOptions): {
15
+ draft: CompositionDraft;
16
+ id: string;
17
+ };
18
+ export declare function addTextRegion(input: CompositionDraft, options?: Omit<AddAreaOptions, "primitive" | "aspect">): {
19
+ draft: CompositionDraft;
20
+ id: string;
21
+ };
22
+ export declare function addCompositionImage(input: CompositionDraft, options?: AddCompositionImageOptions): {
23
+ draft: CompositionDraft;
24
+ id: string;
25
+ };
26
+ export declare function isCompositionTextRegion(area: Pick<CompositionArea, "semanticType">): boolean;
27
+ export declare function addDirectionLine(input: CompositionDraft): {
28
+ draft: CompositionDraft;
29
+ id: "direction-1";
30
+ };
31
+ export declare function copyCompositionItems(input: CompositionDraft, ids: readonly string[]): CompositionClipboardItem[];
32
+ export declare function pasteCompositionItems(input: CompositionDraft, clipboard: readonly CompositionClipboardItem[], offset: Point): PasteCompositionItemsResult;
33
+ export declare function moveItem(input: CompositionDraft, id: string, point: Point): CompositionDraft;
34
+ export declare function resizeArea(input: CompositionDraft, id: string, nextArea: number): CompositionDraft;
35
+ export declare function resizeFreeArea(input: CompositionDraft, id: string, width: number, height: number): CompositionDraft;
36
+ export declare function rotateArea(input: CompositionDraft, id: string, rotation: number): CompositionDraft;
37
+ export declare function resizeCompositionImage(input: CompositionDraft, id: string, width: number, height: number): CompositionDraft;
38
+ export declare function rotateCompositionImage(input: CompositionDraft, id: string, rotation: number): CompositionDraft;
39
+ export declare function rotateDirectionLine(input: CompositionDraft, id: string, rotation: number): CompositionDraft;
40
+ export declare function setAreaAspect(input: CompositionDraft, id: string, aspect: AreaAspect): CompositionDraft;
41
+ export declare function removeItem(input: CompositionDraft, id: string): CompositionDraft;
42
+ export declare function updateItemMetadata(input: CompositionDraft, id: string, patch: CompositionNodeMetadataPatch): CompositionDraft;
43
+ export declare function updateAreaMetadata(input: CompositionDraft, id: string, patch: CompositionAreaMetadataPatch): CompositionDraft;
44
+ export declare function updateCompositionImage(input: CompositionDraft, id: string, patch: Partial<Pick<CompositionImage, "assetId" | "crop" | "visualWeight">>): CompositionDraft;
45
+ export declare function setProcessingSemantic(input: CompositionDraft, processingSemantic: CompositionProcessingSemantic): CompositionDraft;
46
+ export declare function changeFrame(input: CompositionDraft, frame: CompositionFrameSize): CompositionDraft;
47
+ export declare function moveFrame(input: CompositionDraft, point: Point): CompositionDraft;
48
+ export declare function resizeFrame(input: CompositionDraft, scale: number, corner?: CompositionFrameCorner): CompositionDraft;
49
+ export declare function resizeFrameToBounds(input: CompositionDraft, bounds: CompositionFrameBounds): CompositionDraft;
50
+ export declare function visibleAreaMetrics(input: CompositionDraft): VisibleAreaMetrics;
@@ -0,0 +1,609 @@
1
+ import { compositionLayerOrder } from "./layers.js";
2
+ import { normalizeCompositionStates } from "./states.js";
3
+ import { Ajv2020 } from "ajv/dist/2020.js";
4
+ import compositionDraftSchema from "../../../schemas/composition-draft.schema.json" with {
5
+ type: "json"
6
+ };
7
+ import { createHuman2AiCanvasNodeMetadata, normalizeHuman2AiCanvasNodeMetadata, } from "../canvas-node-metadata.js";
8
+ import { calculateVisibleAreaMetrics, freeDimensionsFromArea, } from "./geometry.js";
9
+ import { COMPOSITION_CANVAS, changeCompositionFrameSize, createCompositionFrame, isCompositionFrameRatioSupported, moveCompositionFrame, resizeCompositionFrame, resizeCompositionFrameToBounds, } from "./frame.js";
10
+ export const MAX_FOCUS_POINTS = 3;
11
+ export const PRIMITIVES = ["circle", "triangle", "quadrilateral"];
12
+ export const ASPECTS = ["square", "free", "landscape", "portrait"];
13
+ export const COMPOSITION_TEXT_REGION_SEMANTIC_TYPE = "text-region";
14
+ export const COMPOSITION_PROCESSING_SEMANTICS = [
15
+ "scene-composition",
16
+ "editorial-layout",
17
+ ];
18
+ export const COMPOSITION_VISUAL_WEIGHTS = [
19
+ "auto",
20
+ "high",
21
+ "medium",
22
+ "low",
23
+ "decorative",
24
+ ];
25
+ const ajv = new Ajv2020({ allErrors: true });
26
+ const validateSchema = ajv.compile(compositionDraftSchema);
27
+ export function createDraft(frame = { width: 1600, height: 900 }) {
28
+ return validateDraft({
29
+ version: 1,
30
+ kind: "composition-draft",
31
+ processingSemantic: null,
32
+ frame: createCompositionFrame(frame),
33
+ overallNote: "",
34
+ focusPoints: [],
35
+ directionLine: null,
36
+ areas: [],
37
+ images: [],
38
+ });
39
+ }
40
+ export function validateDraft(input) {
41
+ const normalizedInput = normalizeCompositionItemMetadata(input);
42
+ if (!validateSchema(normalizedInput)) {
43
+ throw new Error(formatValidationErrors(validateSchema.errors));
44
+ }
45
+ const validatedInput = normalizedInput;
46
+ validateFrame(validatedInput.frame);
47
+ const legacyFrame = !validatedInput.frame.bounds;
48
+ const draft = structuredClone(validatedInput);
49
+ draft.frame = legacyFrame
50
+ ? createCompositionFrame(validatedInput.frame)
51
+ : structuredClone(validatedInput.frame);
52
+ if (legacyFrame)
53
+ migrateLegacyDraftCoordinates(draft);
54
+ const ids = new Set();
55
+ for (const item of [
56
+ ...draft.focusPoints,
57
+ ...(draft.directionLine ? [draft.directionLine] : []),
58
+ ...draft.areas,
59
+ ...draft.images,
60
+ ]) {
61
+ if (ids.has(item.id))
62
+ throw new Error(`Duplicate draft item id: ${item.id}.`);
63
+ ids.add(item.id);
64
+ }
65
+ draft.directionLine = draft.directionLine
66
+ ? { ...draft.directionLine, rotation: normalizeRotation(draft.directionLine.rotation) }
67
+ : null;
68
+ draft.areas.forEach((area) => {
69
+ if (area.primitive === "circle" && area.aspect !== "free")
70
+ area.rotation = 0;
71
+ if (area.primitive === "quadrilateral" &&
72
+ (area.aspect === "landscape" || area.aspect === "portrait")) {
73
+ Object.assign(area, freeDimensionsFromArea(area.area, COMPOSITION_CANVAS, area.aspect === "landscape" ? 1.6 : 0.625, area.primitive));
74
+ area.aspect = "free";
75
+ }
76
+ });
77
+ if (draft.layerOrder)
78
+ draft.layerOrder = compositionLayerOrder(draft);
79
+ draft.images.forEach((image) => {
80
+ image.rotation = normalizeRotation(image.rotation);
81
+ if (image.crop)
82
+ validateImageCrop(image.crop);
83
+ });
84
+ return normalizeCompositionStates(draft);
85
+ }
86
+ export function addFocus(input, point) {
87
+ const draft = validateDraft(input);
88
+ if (draft.focusPoints.length >= MAX_FOCUS_POINTS) {
89
+ throw new Error(`A draft may contain at most ${MAX_FOCUS_POINTS} focus points.`);
90
+ }
91
+ const focus = {
92
+ id: nextId("focus", [...draft.focusPoints, ...draft.areas]),
93
+ x: point.x,
94
+ y: point.y,
95
+ ...createCompositionNodeMetadata(),
96
+ };
97
+ draft.focusPoints.push(focus);
98
+ return { draft, id: focus.id };
99
+ }
100
+ export function addArea(input, options) {
101
+ const draft = validateDraft(input);
102
+ if (!PRIMITIVES.includes(options.primitive)) {
103
+ throw new Error(`Unsupported primitive: ${options.primitive}.`);
104
+ }
105
+ const initialArea = Number(options.area) > 0 ? Number(options.area) : 0.08;
106
+ const aspect = options.aspect && ASPECTS.includes(options.aspect) ? options.aspect : "square";
107
+ let area = {
108
+ id: nextId("area", [...draft.focusPoints, ...draft.areas]),
109
+ primitive: options.primitive,
110
+ x: Number.isFinite(options.x) ? options.x : 0.5,
111
+ y: Number.isFinite(options.y) ? options.y : 0.5,
112
+ area: initialArea,
113
+ aspect,
114
+ visualWeight: "auto",
115
+ rotation: options.primitive === "circle" ? 0 : normalizeRotation(Number(options.rotation) || 0),
116
+ ...createCompositionNodeMetadata(),
117
+ };
118
+ if (aspect === "free") {
119
+ Object.assign(area, freeDimensionsFromArea(initialArea, COMPOSITION_CANVAS, 1.6, options.primitive));
120
+ }
121
+ draft.areas.push(area);
122
+ return { draft, id: area.id };
123
+ }
124
+ export function addTextRegion(input, options = {}) {
125
+ const added = addArea(input, {
126
+ ...options,
127
+ primitive: "quadrilateral",
128
+ aspect: "free",
129
+ });
130
+ const marked = updateItemMetadata(added.draft, added.id, {
131
+ semanticType: COMPOSITION_TEXT_REGION_SEMANTIC_TYPE,
132
+ });
133
+ return {
134
+ draft: updateAreaMetadata(marked, added.id, { displayText: "" }),
135
+ id: added.id,
136
+ };
137
+ }
138
+ export function addCompositionImage(input, options = {}) {
139
+ const draft = validateDraft(input);
140
+ const image = {
141
+ id: nextId("image", [...draft.focusPoints, ...draft.areas, ...draft.images]),
142
+ x: Number.isFinite(options.x)
143
+ ? options.x
144
+ : draft.frame.bounds.x + draft.frame.bounds.width / 2,
145
+ y: Number.isFinite(options.y)
146
+ ? options.y
147
+ : draft.frame.bounds.y + draft.frame.bounds.height / 2,
148
+ width: Number.isFinite(options.width) && options.width > 0
149
+ ? options.width
150
+ : 320 / COMPOSITION_CANVAS.width,
151
+ height: Number.isFinite(options.height) && options.height > 0
152
+ ? options.height
153
+ : 180 / COMPOSITION_CANVAS.height,
154
+ rotation: normalizeRotation(Number(options.rotation) || 0),
155
+ visualWeight: "auto",
156
+ assetId: null,
157
+ crop: null,
158
+ ...createCompositionNodeMetadata(),
159
+ };
160
+ draft.images.push(image);
161
+ return { draft, id: image.id };
162
+ }
163
+ export function isCompositionTextRegion(area) {
164
+ return area.semanticType === COMPOSITION_TEXT_REGION_SEMANTIC_TYPE;
165
+ }
166
+ export function addDirectionLine(input) {
167
+ const draft = validateDraft(input);
168
+ if (draft.directionLine) {
169
+ throw new Error("A draft may contain at most one direction line.");
170
+ }
171
+ draft.directionLine = {
172
+ id: "direction-1",
173
+ x: 0.5,
174
+ y: 0.5,
175
+ rotation: 0,
176
+ ...createCompositionNodeMetadata(),
177
+ };
178
+ return { draft, id: draft.directionLine.id };
179
+ }
180
+ export function copyCompositionItems(input, ids) {
181
+ const draft = validateDraft(input);
182
+ return [...new Set(ids)].flatMap((id) => {
183
+ const focus = draft.focusPoints.find((item) => item.id === id);
184
+ if (focus)
185
+ return [{ kind: "focus", item: structuredClone(focus) }];
186
+ const area = draft.areas.find((item) => item.id === id);
187
+ if (area)
188
+ return [{ kind: "area", item: structuredClone(area) }];
189
+ const image = draft.images.find((item) => item.id === id);
190
+ if (image)
191
+ return [{ kind: "image", item: structuredClone(image) }];
192
+ if (draft.directionLine?.id === id) {
193
+ return [{ kind: "direction", item: structuredClone(draft.directionLine) }];
194
+ }
195
+ return [];
196
+ });
197
+ }
198
+ export function pasteCompositionItems(input, clipboard, offset) {
199
+ const draft = validateDraft(input);
200
+ const ids = [];
201
+ for (const entry of clipboard) {
202
+ if (entry.kind === "focus") {
203
+ if (draft.focusPoints.length >= MAX_FOCUS_POINTS)
204
+ continue;
205
+ const item = {
206
+ ...structuredClone(entry.item),
207
+ id: nextId("focus", [...draft.focusPoints, ...draft.areas]),
208
+ x: entry.item.x + offset.x,
209
+ y: entry.item.y + offset.y,
210
+ };
211
+ draft.focusPoints.push(item);
212
+ ids.push(item.id);
213
+ continue;
214
+ }
215
+ if (entry.kind === "area") {
216
+ const item = {
217
+ ...structuredClone(entry.item),
218
+ id: nextId("area", [...draft.focusPoints, ...draft.areas]),
219
+ x: entry.item.x + offset.x,
220
+ y: entry.item.y + offset.y,
221
+ };
222
+ draft.areas.push(item);
223
+ ids.push(item.id);
224
+ continue;
225
+ }
226
+ if (entry.kind === "image") {
227
+ const item = {
228
+ ...structuredClone(entry.item),
229
+ id: nextId("image", [...draft.focusPoints, ...draft.areas, ...draft.images]),
230
+ x: entry.item.x + offset.x,
231
+ y: entry.item.y + offset.y,
232
+ };
233
+ draft.images.push(item);
234
+ ids.push(item.id);
235
+ continue;
236
+ }
237
+ if (!draft.directionLine) {
238
+ draft.directionLine = {
239
+ ...structuredClone(entry.item),
240
+ id: "direction-1",
241
+ x: entry.item.x + offset.x,
242
+ y: entry.item.y + offset.y,
243
+ };
244
+ ids.push(draft.directionLine.id);
245
+ }
246
+ }
247
+ return { draft: validateDraft(draft), ids };
248
+ }
249
+ export function moveItem(input, id, point) {
250
+ const draft = validateDraft(input);
251
+ const focus = draft.focusPoints.find((item) => item.id === id);
252
+ if (focus) {
253
+ focus.x = point.x;
254
+ focus.y = point.y;
255
+ return draft;
256
+ }
257
+ if (draft.directionLine?.id === id) {
258
+ draft.directionLine.x = point.x;
259
+ draft.directionLine.y = point.y;
260
+ return draft;
261
+ }
262
+ const item = draft.areas.find((candidate) => candidate.id === id)
263
+ ?? draft.images.find((candidate) => candidate.id === id);
264
+ if (!item)
265
+ throw new Error(`Unknown draft item: ${id}.`);
266
+ item.x = point.x;
267
+ item.y = point.y;
268
+ return draft;
269
+ }
270
+ export function resizeArea(input, id, nextArea) {
271
+ const draft = validateDraft(input);
272
+ const area = findArea(draft, id);
273
+ if (!Number.isFinite(nextArea) || nextArea <= 0)
274
+ return draft;
275
+ if (area.aspect === "free") {
276
+ const scale = Math.sqrt(nextArea / (area.width * area.height));
277
+ area.width *= scale;
278
+ area.height *= scale;
279
+ }
280
+ area.area = nextArea;
281
+ return draft;
282
+ }
283
+ export function resizeFreeArea(input, id, width, height) {
284
+ const draft = validateDraft(input);
285
+ const area = draft.areas.find((item) => item.id === id);
286
+ if (!area)
287
+ throw new Error(`Unknown free area: ${id}.`);
288
+ if (!Number.isFinite(width) || !Number.isFinite(height) || width <= 0 || height <= 0) {
289
+ return draft;
290
+ }
291
+ area.width = width;
292
+ area.height = height;
293
+ area.aspect = "free";
294
+ const areaFactor = area.primitive === "circle" ? Math.PI / 4 : area.primitive === "triangle" ? 0.5 : 1;
295
+ area.area = width * height * areaFactor;
296
+ return draft;
297
+ }
298
+ export function rotateArea(input, id, rotation) {
299
+ const draft = validateDraft(input);
300
+ const area = findArea(draft, id);
301
+ if (area.primitive === "circle" && area.aspect !== "free")
302
+ return draft;
303
+ area.rotation = normalizeRotation(rotation);
304
+ return draft;
305
+ }
306
+ export function resizeCompositionImage(input, id, width, height) {
307
+ const draft = validateDraft(input);
308
+ const image = findImage(draft, id);
309
+ if (!Number.isFinite(width) || !Number.isFinite(height) || width <= 0 || height <= 0) {
310
+ return draft;
311
+ }
312
+ image.width = width;
313
+ image.height = height;
314
+ return draft;
315
+ }
316
+ export function rotateCompositionImage(input, id, rotation) {
317
+ const draft = validateDraft(input);
318
+ findImage(draft, id).rotation = normalizeRotation(rotation);
319
+ return draft;
320
+ }
321
+ export function rotateDirectionLine(input, id, rotation) {
322
+ const draft = validateDraft(input);
323
+ if (draft.directionLine?.id !== id) {
324
+ throw new Error(`Unknown draft direction line: ${id}.`);
325
+ }
326
+ draft.directionLine.rotation = normalizeRotation(rotation);
327
+ return draft;
328
+ }
329
+ export function setAreaAspect(input, id, aspect) {
330
+ const draft = validateDraft(input);
331
+ if (!ASPECTS.includes(aspect))
332
+ throw new Error(`Unsupported aspect: ${aspect}.`);
333
+ const area = findArea(draft, id);
334
+ area.aspect = aspect;
335
+ if (aspect === "free" && (!area.width || !area.height)) {
336
+ Object.assign(area, freeDimensionsFromArea(area.area, COMPOSITION_CANVAS, 1.6, area.primitive));
337
+ }
338
+ else if (aspect !== "free") {
339
+ delete area.width;
340
+ delete area.height;
341
+ }
342
+ return draft;
343
+ }
344
+ export function removeItem(input, id) {
345
+ const draft = validateDraft(input);
346
+ draft.focusPoints = draft.focusPoints.filter((item) => item.id !== id);
347
+ draft.areas = draft.areas.filter((item) => item.id !== id);
348
+ draft.images = draft.images.filter((item) => item.id !== id);
349
+ if (draft.directionLine?.id === id)
350
+ draft.directionLine = null;
351
+ if (draft.layerOrder)
352
+ draft.layerOrder = compositionLayerOrder(draft);
353
+ return draft;
354
+ }
355
+ export function updateItemMetadata(input, id, patch) {
356
+ const draft = validateDraft(input);
357
+ const item = draft.focusPoints.find((candidate) => candidate.id === id)
358
+ ?? draft.areas.find((candidate) => candidate.id === id)
359
+ ?? draft.images.find((candidate) => candidate.id === id)
360
+ ?? (draft.directionLine?.id === id ? draft.directionLine : null);
361
+ if (!item)
362
+ throw new Error(`Unknown draft item: ${id}.`);
363
+ Object.assign(item, patch);
364
+ return draft;
365
+ }
366
+ export function updateAreaMetadata(input, id, patch) {
367
+ const draft = validateDraft(input);
368
+ const area = findArea(draft, id);
369
+ if (patch.visualWeight !== undefined
370
+ && !COMPOSITION_VISUAL_WEIGHTS.includes(patch.visualWeight)) {
371
+ throw new Error(`Unsupported visual weight: ${patch.visualWeight}.`);
372
+ }
373
+ if (patch.displayText !== undefined && !isCompositionTextRegion(area)) {
374
+ throw new Error(`Display text is only supported by text regions: ${id}.`);
375
+ }
376
+ if (patch.visualWeight !== undefined)
377
+ area.visualWeight = patch.visualWeight;
378
+ if (patch.displayText !== undefined)
379
+ area.displayText = patch.displayText;
380
+ if (patch.isLightSource !== undefined)
381
+ area.isLightSource = patch.isLightSource;
382
+ return validateDraft(draft);
383
+ }
384
+ export function updateCompositionImage(input, id, patch) {
385
+ const draft = validateDraft(input);
386
+ const image = findImage(draft, id);
387
+ if (patch.visualWeight !== undefined
388
+ && !COMPOSITION_VISUAL_WEIGHTS.includes(patch.visualWeight)) {
389
+ throw new Error(`Unsupported visual weight: ${patch.visualWeight}.`);
390
+ }
391
+ if (patch.assetId !== undefined && patch.assetId !== null && !patch.assetId.trim()) {
392
+ throw new Error("Image asset id cannot be empty.");
393
+ }
394
+ if (patch.crop)
395
+ validateImageCrop(patch.crop);
396
+ Object.assign(image, patch);
397
+ return draft;
398
+ }
399
+ export function setProcessingSemantic(input, processingSemantic) {
400
+ const draft = validateDraft(input);
401
+ if (!COMPOSITION_PROCESSING_SEMANTICS.includes(processingSemantic)) {
402
+ throw new Error(`Unsupported processing semantic: ${processingSemantic}.`);
403
+ }
404
+ draft.processingSemantic = processingSemantic;
405
+ return draft;
406
+ }
407
+ export function changeFrame(input, frame) {
408
+ const draft = validateDraft(input);
409
+ validateFrame(frame);
410
+ draft.frame = changeCompositionFrameSize(draft.frame, frame);
411
+ return draft;
412
+ }
413
+ export function moveFrame(input, point) {
414
+ const draft = validateDraft(input);
415
+ draft.frame = moveCompositionFrame(draft.frame, point);
416
+ return draft;
417
+ }
418
+ export function resizeFrame(input, scale, corner = "bottom-right") {
419
+ const draft = validateDraft(input);
420
+ if (!Number.isFinite(scale) || scale <= 0)
421
+ return draft;
422
+ draft.frame = resizeCompositionFrame(draft.frame, scale, corner);
423
+ return draft;
424
+ }
425
+ export function resizeFrameToBounds(input, bounds) {
426
+ const draft = validateDraft(input);
427
+ draft.frame = resizeCompositionFrameToBounds(draft.frame, bounds);
428
+ return draft;
429
+ }
430
+ export function visibleAreaMetrics(input) {
431
+ return calculateVisibleAreaMetrics(validateDraft(input));
432
+ }
433
+ function validateFrame(frame) {
434
+ if (!frame || typeof frame !== "object" || Array.isArray(frame)) {
435
+ throw new Error("draft.frame must be an object.");
436
+ }
437
+ const values = frame;
438
+ const unknownFields = Object.keys(values).filter((key) => key !== "width" && key !== "height" && key !== "bounds");
439
+ if (unknownFields.length > 0) {
440
+ throw new Error(`draft.frame contains unknown fields: ${unknownFields.join(", ")}.`);
441
+ }
442
+ for (const key of ["width", "height"]) {
443
+ if (!Number.isInteger(values[key]) ||
444
+ values[key] < 256 ||
445
+ values[key] > 4096) {
446
+ throw new Error(`draft.frame.${key} must be an integer from 256 to 4096.`);
447
+ }
448
+ }
449
+ const ratio = values.width / values.height;
450
+ if (!isCompositionFrameRatioSupported(values.width, values.height)) {
451
+ throw new Error("Draft aspect ratio must be between 1:2 and 2:1.");
452
+ }
453
+ if (values.bounds !== undefined)
454
+ validateFrameBounds(values.bounds, ratio);
455
+ }
456
+ function normalizeCompositionItemMetadata(input) {
457
+ if (!input || typeof input !== "object" || Array.isArray(input))
458
+ return input;
459
+ const focusPoints = "focusPoints" in input && Array.isArray(input.focusPoints)
460
+ ? input.focusPoints.map(normalizeCompositionNodeMetadata)
461
+ : undefined;
462
+ const areas = "areas" in input && Array.isArray(input.areas)
463
+ ? input.areas.map(normalizeCompositionAreaMetadata)
464
+ : undefined;
465
+ const images = "images" in input && Array.isArray(input.images)
466
+ ? input.images.map(normalizeCompositionImageMetadata)
467
+ : [];
468
+ const directionLine = "directionLine" in input
469
+ ? input.directionLine === null
470
+ ? null
471
+ : normalizeCompositionNodeMetadata(input.directionLine)
472
+ : undefined;
473
+ return {
474
+ ...input,
475
+ ...(!("processingSemantic" in input)
476
+ ? { processingSemantic: null }
477
+ : {}),
478
+ ...(!("overallNote" in input) ? { overallNote: "" } : {}),
479
+ ...(focusPoints ? { focusPoints } : {}),
480
+ ...(areas ? { areas } : {}),
481
+ images,
482
+ ...(directionLine !== undefined ? { directionLine } : {}),
483
+ };
484
+ }
485
+ function createCompositionNodeMetadata() {
486
+ return {
487
+ ...createHuman2AiCanvasNodeMetadata(),
488
+ shotScale: "auto",
489
+ };
490
+ }
491
+ function normalizeCompositionNodeMetadata(input) {
492
+ const normalized = normalizeHuman2AiCanvasNodeMetadata(input);
493
+ if (!normalized || typeof normalized !== "object" || Array.isArray(normalized)) {
494
+ return normalized;
495
+ }
496
+ return { shotScale: "auto", ...normalized };
497
+ }
498
+ function normalizeCompositionAreaMetadata(input) {
499
+ const normalized = normalizeCompositionNodeMetadata(input);
500
+ if (!normalized || typeof normalized !== "object" || Array.isArray(normalized)) {
501
+ return normalized;
502
+ }
503
+ const area = {
504
+ visualWeight: "auto",
505
+ ...normalized,
506
+ };
507
+ return area.semanticType === COMPOSITION_TEXT_REGION_SEMANTIC_TYPE
508
+ && !("displayText" in area)
509
+ ? { ...area, displayText: "" }
510
+ : area;
511
+ }
512
+ function normalizeCompositionImageMetadata(input) {
513
+ const normalized = normalizeCompositionNodeMetadata(input);
514
+ if (!normalized || typeof normalized !== "object" || Array.isArray(normalized)) {
515
+ return normalized;
516
+ }
517
+ return {
518
+ visualWeight: "auto",
519
+ assetId: null,
520
+ crop: null,
521
+ ...normalized,
522
+ };
523
+ }
524
+ function validateFrameBounds(bounds, ratio) {
525
+ if (!bounds || typeof bounds !== "object" || Array.isArray(bounds)) {
526
+ throw new Error("draft.frame.bounds must be an object.");
527
+ }
528
+ const values = bounds;
529
+ const unknownFields = Object.keys(values).filter((key) => !["x", "y", "width", "height"].includes(key));
530
+ if (unknownFields.length > 0) {
531
+ throw new Error(`draft.frame.bounds contains unknown fields: ${unknownFields.join(", ")}.`);
532
+ }
533
+ for (const key of ["x", "y", "width", "height"]) {
534
+ if (!Number.isFinite(values[key])) {
535
+ throw new Error(`draft.frame.bounds.${key} must be a finite number.`);
536
+ }
537
+ }
538
+ const width = values.width;
539
+ const height = values.height;
540
+ if (width <= 0 || height <= 0) {
541
+ throw new Error("draft.frame.bounds width and height must be positive.");
542
+ }
543
+ const boundsRatio = (width * COMPOSITION_CANVAS.width) / (height * COMPOSITION_CANVAS.height);
544
+ if (Math.abs(boundsRatio - ratio) > 0.002) {
545
+ throw new Error("draft.frame.bounds must match the frame aspect ratio.");
546
+ }
547
+ }
548
+ function migrateLegacyDraftCoordinates(draft) {
549
+ const bounds = draft.frame.bounds;
550
+ const areaScale = bounds.width * bounds.height;
551
+ const migratePoint = (point) => {
552
+ point.x = bounds.x + point.x * bounds.width;
553
+ point.y = bounds.y + point.y * bounds.height;
554
+ };
555
+ draft.focusPoints.forEach(migratePoint);
556
+ if (draft.directionLine)
557
+ migratePoint(draft.directionLine);
558
+ draft.areas.forEach((area) => {
559
+ migratePoint(area);
560
+ area.area *= areaScale;
561
+ if (area.width !== undefined)
562
+ area.width *= bounds.width;
563
+ if (area.height !== undefined)
564
+ area.height *= bounds.height;
565
+ });
566
+ draft.images.forEach((image) => {
567
+ migratePoint(image);
568
+ image.width *= bounds.width;
569
+ image.height *= bounds.height;
570
+ });
571
+ }
572
+ function findArea(draft, id) {
573
+ const area = draft.areas.find((item) => item.id === id);
574
+ if (!area)
575
+ throw new Error(`Unknown draft area: ${id}.`);
576
+ return area;
577
+ }
578
+ function findImage(draft, id) {
579
+ const image = draft.images.find((item) => item.id === id);
580
+ if (!image)
581
+ throw new Error(`Unknown draft image: ${id}.`);
582
+ return image;
583
+ }
584
+ function nextId(prefix, items) {
585
+ const used = new Set(items.map((item) => item.id));
586
+ let index = 1;
587
+ while (used.has(`${prefix}-${index}`))
588
+ index += 1;
589
+ return `${prefix}-${index}`;
590
+ }
591
+ function validateImageCrop(crop) {
592
+ if (crop.x + crop.width > 1 + 1e-9 || crop.y + crop.height > 1 + 1e-9) {
593
+ throw new Error("Image crop must stay inside the source image.");
594
+ }
595
+ }
596
+ function normalizeRotation(value) {
597
+ return ((value % 360) + 360) % 360;
598
+ }
599
+ function formatValidationErrors(errors) {
600
+ return (errors ?? [])
601
+ .map((error) => {
602
+ if (error.keyword === "additionalProperties") {
603
+ return `${error.instancePath || "draft"} contains unknown field: ${String(error.params.additionalProperty)}`;
604
+ }
605
+ return `${error.instancePath || "draft"} ${error.message ?? "is invalid"}`;
606
+ })
607
+ .join("; ");
608
+ }
609
+ //# sourceMappingURL=draft.js.map