evomeme 0.1.9 → 0.1.10

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 (405) hide show
  1. package/dist/canvas-public/app.js +509 -5999
  2. package/dist/canvas-public/assets/presets/catalog.json +47 -0
  3. package/dist/canvas-public/assets/presets/tiles/A_01_CaoDi.png +0 -0
  4. package/dist/canvas-public/assets/presets/tiles/A_02_ShaMo.png +0 -0
  5. package/dist/canvas-public/assets/presets/tiles/A_03_TianKong.png +0 -0
  6. package/dist/canvas-public/assets/presets/tiles/A_04_ShuiBo.png +0 -0
  7. package/dist/canvas-public/assets/presets/tiles/A_05_HaiMian.png +0 -0
  8. package/dist/canvas-public/assets/presets/tiles/A_06_MuDiBan.png +0 -0
  9. package/dist/canvas-public/assets/presets/tiles/A_07_ShiZhuan.png +0 -0
  10. package/dist/canvas-public/assets/presets/tiles/A_08_AnRongYan.png +0 -0
  11. package/dist/canvas-public/assets/presets/tiles/A_09_QingTaiShi.png +0 -0
  12. package/dist/canvas-public/assets/presets/tiles/A_10_ShenHai.png +0 -0
  13. package/dist/canvas-public/assets/presets/tiles/A_11_HuiYanShi.png +0 -0
  14. package/dist/canvas-public/assets/presets/tiles/A_12_HongTu.png +0 -0
  15. package/dist/canvas-public/assets/presets/tiles/A_13_GengDi.png +0 -0
  16. package/dist/canvas-public/assets/presets/tiles/A_14_HuoShanYan.png +0 -0
  17. package/dist/canvas-public/assets/presets/tiles/A_15_NiTu.png +0 -0
  18. package/dist/canvas-public/assets/presets/tiles/A_16_HuangSha.png +0 -0
  19. package/dist/canvas-public/assets/presets/tiles/A_17_CongLin.png +0 -0
  20. package/dist/canvas-public/assets/presets/tiles/A_18_ZiYanShi.png +0 -0
  21. package/dist/canvas-public/assets/presets/tiles/A_19_MoGuTu.png +0 -0
  22. package/dist/canvas-public/assets/presets/tiles/A_20_HuaDian.png +0 -0
  23. package/dist/canvas-public/assets/presets/tiles/A_21_HaiLang.png +0 -0
  24. package/dist/canvas-public/assets/presets/tiles/A_22_GanTu.png +0 -0
  25. package/dist/canvas-public/assets/presets/tiles/A_23_QingTaiShiBan.png +0 -0
  26. package/dist/canvas-public/assets/presets/tiles/A_24_XingKong.png +0 -0
  27. package/dist/canvas-public/assets/presets/tiles/A_25_MoFaFuWen.png +0 -0
  28. package/dist/canvas-public/assets/presets/tiles/A_26_ShiTuYeDi.png +0 -0
  29. package/dist/canvas-public/assets/presets/tiles/A_27_LanZhuan.png +0 -0
  30. package/dist/canvas-public/assets/presets/tiles/A_28_HongZhuan.png +0 -0
  31. package/dist/canvas-public/assets/presets/tiles/A_29_YueQiu.png +0 -0
  32. package/dist/canvas-public/assets/presets/tiles/A_30_JinShuGe.png +0 -0
  33. package/dist/canvas-public/assets/presets/tiles/A_31_JinShuJingGai.png +0 -0
  34. package/dist/canvas-public/assets/presets/tiles/A_32_ShuZiChuang.png +0 -0
  35. package/dist/canvas-public/canvas/actions.js +143 -0
  36. package/dist/canvas-public/canvas/camera.js +28 -0
  37. package/dist/canvas-public/canvas/chrome.js +13 -0
  38. package/dist/canvas-public/canvas/data.js +123 -0
  39. package/dist/canvas-public/canvas/dependencies.js +19 -0
  40. package/dist/canvas-public/canvas/interactions.js +544 -0
  41. package/dist/canvas-public/canvas/panel-resize.js +5 -0
  42. package/dist/canvas-public/canvas/renderer.js +297 -0
  43. package/dist/canvas-public/canvas/selection.js +62 -0
  44. package/dist/canvas-public/canvas/serialization.js +118 -0
  45. package/dist/canvas-public/canvas/sync.js +202 -0
  46. package/dist/canvas-public/core/api.js +27 -0
  47. package/dist/canvas-public/core/feature-registry.js +29 -0
  48. package/dist/canvas-public/core/feature-state.js +228 -0
  49. package/dist/canvas-public/core/layout.js +133 -0
  50. package/dist/canvas-public/core/operations.js +38 -0
  51. package/dist/canvas-public/core/project.js +203 -0
  52. package/dist/canvas-public/core/state.js +27 -0
  53. package/dist/canvas-public/dialogs/context-menu.js +118 -0
  54. package/dist/canvas-public/elements/base.js +100 -0
  55. package/dist/canvas-public/elements/connections.js +105 -0
  56. package/dist/canvas-public/elements/drag.js +53 -0
  57. package/dist/canvas-public/elements/image.js +259 -0
  58. package/dist/canvas-public/elements/loading-recovery.js +5 -0
  59. package/dist/canvas-public/elements/loading.js +21 -0
  60. package/dist/canvas-public/elements/map.js +64 -0
  61. package/dist/canvas-public/elements/registry.js +58 -0
  62. package/dist/canvas-public/elements/replacement.js +78 -0
  63. package/dist/canvas-public/elements/resize.js +210 -0
  64. package/dist/canvas-public/elements/task-pipeline.js +234 -0
  65. package/dist/canvas-public/elements/types.js +21 -0
  66. package/dist/canvas-public/elements/ui.js +14 -0
  67. package/dist/canvas-public/elements/video.js +64 -0
  68. package/dist/canvas-public/features/assets/local-assets.js +72 -0
  69. package/dist/canvas-public/features/assets/official-assets.js +538 -0
  70. package/dist/canvas-public/features/editing/canvas-size.js +532 -0
  71. package/dist/canvas-public/features/editing/color-key.js +469 -0
  72. package/dist/canvas-public/features/editing/cutout.js +20 -0
  73. package/dist/canvas-public/features/editing/interactive-image-editing.js +981 -0
  74. package/dist/canvas-public/features/editing/layer-decomposition.js +44 -0
  75. package/dist/canvas-public/features/editing/manual-split.js +114 -0
  76. package/dist/canvas-public/features/editing/perfect-pixel.js +336 -0
  77. package/dist/canvas-public/features/editing/scroll-preview.js +129 -0
  78. package/dist/canvas-public/features/editing/scroll-seam-elimination.js +71 -0
  79. package/dist/canvas-public/features/editing/seam-elimination.js +46 -0
  80. package/dist/canvas-public/features/editing/smart-split.js +48 -0
  81. package/dist/canvas-public/features/editing/source-preview.js +43 -0
  82. package/dist/canvas-public/features/editing/video-cycle.js +49 -0
  83. package/dist/canvas-public/features/editing/video-frames.js +35 -0
  84. package/dist/canvas-public/features/frame-editor/frame-editing.js +755 -0
  85. package/dist/canvas-public/features/frame-editor/frame-model.js +63 -0
  86. package/dist/canvas-public/features/frame-editor/playback.js +83 -0
  87. package/dist/canvas-public/features/frame-editor/preview.js +149 -0
  88. package/dist/canvas-public/features/generation/animation.js +272 -0
  89. package/dist/canvas-public/features/generation/asset-batch.js +102 -0
  90. package/dist/canvas-public/features/generation/direction.js +163 -0
  91. package/dist/canvas-public/features/generation/fields.js +73 -0
  92. package/dist/canvas-public/features/generation/game-ui.js +64 -0
  93. package/dist/canvas-public/features/generation/image.js +83 -0
  94. package/dist/canvas-public/features/generation/scroll-image.js +157 -0
  95. package/dist/canvas-public/features/generation/seamless-tile.js +52 -0
  96. package/dist/canvas-public/features/generation/tile-transition-atlas.js +79 -0
  97. package/dist/canvas-public/features/generation/video.js +105 -0
  98. package/dist/canvas-public/features/map/creation.js +73 -0
  99. package/dist/canvas-public/features/map/tile-map-editor.js +2518 -0
  100. package/dist/canvas-public/features/registry.js +59 -0
  101. package/dist/canvas-public/index.html +84 -259
  102. package/dist/canvas-public/inspector/controls.js +49 -0
  103. package/dist/canvas-public/inspector/frame-preview.js +11 -0
  104. package/dist/canvas-public/inspector/inspector.js +190 -0
  105. package/dist/canvas-public/inspector/media-inspector.js +517 -0
  106. package/dist/canvas-public/inspector/media-preview.js +56 -0
  107. package/dist/canvas-public/inspector/number-stepper.js +96 -0
  108. package/dist/canvas-public/inspector/resize.js +88 -0
  109. package/dist/canvas-public/inspector/scroll-preview.js +11 -0
  110. package/dist/canvas-public/inspector/ui-inspector.js +14 -0
  111. package/dist/canvas-public/language/en-US.js +1059 -0
  112. package/dist/canvas-public/language/index.js +79 -0
  113. package/dist/canvas-public/language/zh-CN.js +1059 -0
  114. package/dist/canvas-public/map/export.js +9 -0
  115. package/dist/canvas-public/map/inspector.js +8 -0
  116. package/dist/canvas-public/map/model.js +409 -0
  117. package/dist/canvas-public/map/tile-map-editor.js +2 -0
  118. package/dist/canvas-public/media/metadata.js +183 -0
  119. package/dist/canvas-public/media/support.js +183 -0
  120. package/dist/canvas-public/styles/base.css +49 -0
  121. package/dist/canvas-public/styles/canvas.css +127 -0
  122. package/dist/canvas-public/styles/controls.css +203 -0
  123. package/dist/canvas-public/styles/dialogs.css +521 -0
  124. package/dist/canvas-public/styles/feature-form.css +409 -0
  125. package/dist/canvas-public/styles/inspector.css +441 -0
  126. package/dist/canvas-public/styles/layout.css +344 -0
  127. package/dist/canvas-public/styles/map.css +11 -0
  128. package/dist/canvas-public/styles/nodes.css +636 -0
  129. package/dist/canvas-public/styles.css +9 -2247
  130. package/dist/canvas-public/ui/controls.js +222 -0
  131. package/dist/canvas-public/ui/elements.js +9 -0
  132. package/dist/canvas-public/ui/feature-controller.js +296 -0
  133. package/dist/canvas-public/ui/feature-form.js +401 -0
  134. package/dist/canvas-public/ui/settings.js +83 -0
  135. package/dist/canvas-public/ui/toolbar.js +55 -0
  136. package/dist/canvas-public/vendor/pixi-tilemap.js +126 -0
  137. package/dist/canvas-public/vendor/pixi.min.js +2340 -0
  138. package/dist/canvas-public/workers/color-key-worker.js +289 -0
  139. package/dist/canvas-public/workers/perfect-pixel-worker.js +510 -0
  140. package/dist/index.js +42236 -13382
  141. package/dist/skills/en-US/evomeme-canvas/SKILL.md +52 -0
  142. package/dist/skills/en-US/evomeme-canvas/agents/openai.yaml +7 -0
  143. package/dist/skills/en-US/evomeme-cloud-fs/SKILL.md +176 -0
  144. package/dist/skills/en-US/evomeme-cloud-fs/agents/openai.yaml +7 -0
  145. package/dist/skills/en-US/evomeme-cover/SKILL.md +132 -0
  146. package/dist/skills/en-US/evomeme-cover/agents/openai.yaml +7 -0
  147. package/dist/skills/en-US/evomeme-game-maker/SKILL.md +288 -0
  148. package/dist/skills/en-US/evomeme-game-maker/agents/openai.yaml +4 -0
  149. package/dist/skills/en-US/evomeme-login/SKILL.md +92 -0
  150. package/dist/skills/en-US/evomeme-login/agents/openai.yaml +7 -0
  151. package/dist/skills/en-US/evomeme-native-bridge-sdk/SKILL.md +286 -0
  152. package/dist/skills/en-US/evomeme-native-bridge-sdk/agents/openai.yaml +8 -0
  153. package/dist/skills/en-US/evomeme-tos-upload/SKILL.md +47 -0
  154. package/dist/skills/en-US/evomeme-tos-upload/agents/openai.yaml +5 -0
  155. package/dist/skills/en-US/evomeme-ui/SKILL.md +123 -0
  156. package/dist/skills/en-US/evomeme-ui/agents/openai.yaml +4 -0
  157. package/dist/skills/en-US/evomeme-ui/references/host-layout.md +69 -0
  158. package/dist/skills/en-US/game-art/SKILL.md +121 -0
  159. package/dist/skills/en-US/game-art/agents/openai.yaml +8 -0
  160. package/dist/skills/en-US/game-asset-align/SKILL.md +45 -0
  161. package/dist/skills/en-US/game-asset-align/agents/openai.yaml +8 -0
  162. package/dist/skills/en-US/game-asset-align/references/alignment-contract.md +61 -0
  163. package/dist/skills/en-US/game-asset-align/references/blender-scene-pipeline.md +45 -0
  164. package/dist/skills/en-US/game-asset-align/references/canonical-package.md +26 -0
  165. package/dist/skills/en-US/game-asset-align/references/engine-capabilities.md +14 -0
  166. package/dist/skills/en-US/game-asset-align/references/lightweight-review.md +32 -0
  167. package/dist/skills/en-US/game-asset-align/references/repair-policy.md +30 -0
  168. package/dist/skills/en-US/game-asset-align/references/tool-contract.md +39 -0
  169. package/dist/skills/en-US/game-asset-align/references/visual-review.md +26 -0
  170. package/dist/skills/en-US/game-asset-image-generator/SKILL.md +104 -0
  171. package/dist/skills/en-US/game-asset-image-generator/agents/openai.yaml +7 -0
  172. package/dist/skills/en-US/game-asset-image-generator/references/background.md +32 -0
  173. package/dist/skills/en-US/game-asset-image-generator/references/static-game-assets.md +38 -0
  174. package/dist/skills/en-US/game-audio/SKILL.md +82 -0
  175. package/dist/skills/en-US/game-audio/agents/openai.yaml +4 -0
  176. package/dist/skills/en-US/game-demo/SKILL.md +103 -0
  177. package/dist/skills/en-US/game-demo/agents/openai.yaml +7 -0
  178. package/dist/skills/en-US/game-maker/SKILL.md +111 -0
  179. package/dist/skills/en-US/game-maker/agents/openai.yaml +4 -0
  180. package/dist/skills/en-US/game-test/SKILL.md +58 -0
  181. package/dist/skills/en-US/game-test/agents/openai.yaml +7 -0
  182. package/dist/skills/en-US/game-ui/SKILL.md +177 -0
  183. package/dist/skills/en-US/game-ui/agents/openai.yaml +4 -0
  184. package/dist/skills/en-US/godot-3d-game/SKILL.md +39 -0
  185. package/dist/skills/en-US/godot-3d-game/agents/openai.yaml +8 -0
  186. package/dist/skills/en-US/godot-3d-game/references/alignment-gates.md +26 -0
  187. package/dist/skills/en-US/godot-3d-game/references/appearance-alignment.md +52 -0
  188. package/dist/skills/en-US/godot-3d-game/references/build-and-qa.md +22 -0
  189. package/dist/skills/en-US/godot-3d-game/references/canonical-asset-runtime.md +27 -0
  190. package/dist/skills/en-US/godot-3d-game/references/import-and-wrapper-scenes.md +20 -0
  191. package/dist/skills/en-US/godot-3d-game/references/physics-colliders.md +13 -0
  192. package/dist/skills/en-US/godot-3d-game/references/project-structure.md +22 -0
  193. package/dist/skills/en-US/godot-3d-game/references/skeleton-animation.md +16 -0
  194. package/dist/skills/en-US/phaser-2d-game/SKILL.md +127 -0
  195. package/dist/skills/en-US/phaser-2d-game/agents/openai.yaml +8 -0
  196. package/dist/skills/en-US/phaser-2d-game/references/engine-performance.md +64 -0
  197. package/dist/skills/en-US/phaser-2d-game/references/engine-physics.md +139 -0
  198. package/dist/skills/en-US/phaser-2d-game/references/engine-runtime.md +129 -0
  199. package/dist/skills/en-US/phaser-2d-game/references/engine-spritesheets.md +99 -0
  200. package/dist/skills/en-US/phaser-2d-game/references/engine-tilemaps.md +80 -0
  201. package/dist/skills/en-US/phaser-2d-game/references/file-structure.md +94 -0
  202. package/dist/skills/en-US/phaser-2d-graphics-builder/SKILL.md +68 -0
  203. package/dist/skills/en-US/phaser-2d-graphics-builder/agents/openai.yaml +7 -0
  204. package/dist/skills/en-US/threejs-3d-game/SKILL.md +117 -0
  205. package/dist/skills/en-US/threejs-3d-game/agents/openai.yaml +7 -0
  206. package/dist/skills/en-US/threejs-3d-game/references/engine-asset-pipeline.md +153 -0
  207. package/dist/skills/en-US/threejs-3d-game/references/engine-audio.md +70 -0
  208. package/dist/skills/en-US/threejs-3d-game/references/engine-input-camera.md +84 -0
  209. package/dist/skills/en-US/threejs-3d-game/references/engine-performance.md +96 -0
  210. package/dist/skills/en-US/threejs-3d-game/references/engine-physics.md +142 -0
  211. package/dist/skills/en-US/threejs-3d-game/references/engine-runtime.md +199 -0
  212. package/dist/skills/en-US/threejs-3d-game/references/file-structure.md +353 -0
  213. package/dist/skills/en-US/threejs-aaa-graphics-builder/SKILL.md +62 -0
  214. package/dist/skills/en-US/threejs-aaa-graphics-builder/agents/openai.yaml +7 -0
  215. package/{skills → dist/skills/zh-CN}/evomeme-cloud-fs/SKILL.md +4 -4
  216. package/{skills → dist/skills/zh-CN}/evomeme-cover/SKILL.md +1 -1
  217. package/{skills → dist/skills/zh-CN}/evomeme-game-maker/SKILL.md +91 -88
  218. package/{skills → dist/skills/zh-CN}/evomeme-tos-upload/SKILL.md +6 -5
  219. package/dist/skills/zh-CN/evomeme-ui/SKILL.md +123 -0
  220. package/dist/skills/zh-CN/evomeme-ui/agents/openai.yaml +4 -0
  221. package/dist/skills/zh-CN/evomeme-ui/references/host-layout.md +69 -0
  222. package/dist/skills/zh-CN/game-asset-align/SKILL.md +45 -0
  223. package/dist/skills/zh-CN/game-asset-align/agents/openai.yaml +8 -0
  224. package/dist/skills/zh-CN/game-asset-align/references/alignment-contract.md +61 -0
  225. package/dist/skills/zh-CN/game-asset-align/references/blender-scene-pipeline.md +45 -0
  226. package/dist/skills/zh-CN/game-asset-align/references/canonical-package.md +26 -0
  227. package/dist/skills/zh-CN/game-asset-align/references/engine-capabilities.md +14 -0
  228. package/dist/skills/zh-CN/game-asset-align/references/lightweight-review.md +32 -0
  229. package/dist/skills/zh-CN/game-asset-align/references/repair-policy.md +30 -0
  230. package/dist/skills/zh-CN/game-asset-align/references/tool-contract.md +39 -0
  231. package/dist/skills/zh-CN/game-asset-align/references/visual-review.md +26 -0
  232. package/{skills → dist/skills/zh-CN}/game-asset-image-generator/SKILL.md +1 -1
  233. package/dist/skills/zh-CN/game-audio/references/bgm-cdn.md +127 -0
  234. package/dist/skills/zh-CN/game-audio/references/sfx-cdn.md +77 -0
  235. package/dist/skills/zh-CN/game-test/references/checklists/playtest-qa.md +12 -0
  236. package/{skills → dist/skills/zh-CN}/game-ui/SKILL.md +9 -1
  237. package/dist/skills/zh-CN/game-ui/references/checklists/game-ui-quality.md +14 -0
  238. package/dist/skills/zh-CN/game-ui/references/checklists/hud-readability.md +12 -0
  239. package/dist/skills/zh-CN/game-ui/references/checklists/mobile-input.md +12 -0
  240. package/dist/skills/zh-CN/game-ui/references/checklists/responsive-ui-fit.md +12 -0
  241. package/dist/skills/zh-CN/game-ui/references/ui-patterns.md +140 -0
  242. package/dist/skills/zh-CN/game-ui/references/ui-prompt-templates.md +63 -0
  243. package/dist/skills/zh-CN/godot-3d-game/SKILL.md +39 -0
  244. package/dist/skills/zh-CN/godot-3d-game/agents/openai.yaml +8 -0
  245. package/dist/skills/zh-CN/godot-3d-game/references/alignment-gates.md +26 -0
  246. package/dist/skills/zh-CN/godot-3d-game/references/appearance-alignment.md +52 -0
  247. package/dist/skills/zh-CN/godot-3d-game/references/build-and-qa.md +22 -0
  248. package/dist/skills/zh-CN/godot-3d-game/references/canonical-asset-runtime.md +27 -0
  249. package/dist/skills/zh-CN/godot-3d-game/references/import-and-wrapper-scenes.md +20 -0
  250. package/dist/skills/zh-CN/godot-3d-game/references/physics-colliders.md +13 -0
  251. package/dist/skills/zh-CN/godot-3d-game/references/project-structure.md +22 -0
  252. package/dist/skills/zh-CN/godot-3d-game/references/skeleton-animation.md +16 -0
  253. package/dist/skills/zh-CN/phaser-2d-graphics-builder/assets/scorecard-anchors/scene-1.jpeg +0 -0
  254. package/dist/skills/zh-CN/phaser-2d-graphics-builder/assets/scorecard-anchors/scene-2.jpeg +0 -0
  255. package/dist/skills/zh-CN/phaser-2d-graphics-builder/assets/scorecard-anchors/scene-3.jpg +0 -0
  256. package/dist/skills/zh-CN/phaser-2d-graphics-builder/references/checklists/compose-quality.md +10 -0
  257. package/dist/skills/zh-CN/phaser-2d-graphics-builder/references/checklists/performance-safe-visual-detail.md +9 -0
  258. package/dist/skills/zh-CN/phaser-2d-graphics-builder/references/checklists/premium-game-quality-gate.md +15 -0
  259. package/dist/skills/zh-CN/phaser-2d-graphics-builder/references/checklists/sprite-quality.md +10 -0
  260. package/dist/skills/zh-CN/phaser-2d-graphics-builder/references/checklists/technical-art-quality.md +9 -0
  261. package/dist/skills/zh-CN/phaser-2d-graphics-builder/references/checklists/visual-scorecard.md +9 -0
  262. package/dist/skills/zh-CN/phaser-2d-graphics-builder/references/compose-recipes.md +71 -0
  263. package/dist/skills/zh-CN/phaser-2d-graphics-builder/references/graphics-prompt-templates.md +33 -0
  264. package/dist/skills/zh-CN/phaser-2d-graphics-builder/references/implementation-blueprint.md +82 -0
  265. package/dist/skills/zh-CN/phaser-2d-graphics-builder/references/sprite-recipes.md +90 -0
  266. package/dist/skills/zh-CN/phaser-2d-graphics-builder/references/technical-art.md +67 -0
  267. package/dist/skills/zh-CN/phaser-2d-graphics-builder/references/vfx-recipes.md +67 -0
  268. package/dist/skills/zh-CN/phaser-2d-graphics-builder/references/visual-scorecard.md +129 -0
  269. package/{skills → dist/skills/zh-CN}/threejs-3d-game/SKILL.md +6 -2
  270. package/{skills → dist/skills/zh-CN}/threejs-3d-game/references/engine-asset-pipeline.md +52 -15
  271. package/dist/skills/zh-CN/threejs-aaa-graphics-builder/assets/scorecard-anchors/scene-1.jpg +0 -0
  272. package/dist/skills/zh-CN/threejs-aaa-graphics-builder/assets/scorecard-anchors/scene-2.jpg +0 -0
  273. package/dist/skills/zh-CN/threejs-aaa-graphics-builder/assets/scorecard-anchors/scene-3.jpg +0 -0
  274. package/dist/skills/zh-CN/threejs-aaa-graphics-builder/references/checklists/aaa-game-quality-gate.md +23 -0
  275. package/dist/skills/zh-CN/threejs-aaa-graphics-builder/references/checklists/aaa-visual-scorecard.md +19 -0
  276. package/dist/skills/zh-CN/threejs-aaa-graphics-builder/references/checklists/material-lighting-quality.md +14 -0
  277. package/dist/skills/zh-CN/threejs-aaa-graphics-builder/references/checklists/performance-safe-visual-detail.md +14 -0
  278. package/dist/skills/zh-CN/threejs-aaa-graphics-builder/references/checklists/procedural-model-quality.md +15 -0
  279. package/dist/skills/zh-CN/threejs-aaa-graphics-builder/references/checklists/technical-art-quality.md +17 -0
  280. package/dist/skills/zh-CN/threejs-aaa-graphics-builder/references/graphics-prompt-templates.md +236 -0
  281. package/dist/skills/zh-CN/threejs-aaa-graphics-builder/references/implementation-blueprint.md +161 -0
  282. package/dist/skills/zh-CN/threejs-aaa-graphics-builder/references/model-recipes.md +146 -0
  283. package/dist/skills/zh-CN/threejs-aaa-graphics-builder/references/render-recipes.md +90 -0
  284. package/dist/skills/zh-CN/threejs-aaa-graphics-builder/references/shader-cookbook.md +292 -0
  285. package/dist/skills/zh-CN/threejs-aaa-graphics-builder/references/technical-art.md +167 -0
  286. package/dist/skills/zh-CN/threejs-aaa-graphics-builder/references/visual-scorecard.md +147 -0
  287. package/dist/stage-blender/bake_materials.py +102 -0
  288. package/dist/stage-blender/export_scene.py +275 -0
  289. package/dist/stage-blender/preview_camera.py +90 -0
  290. package/dist/stage-blender/repair_mesh.py +112 -0
  291. package/dist/stage-public/app.js +759 -0
  292. package/dist/stage-public/baked/bakePilot.js +44 -0
  293. package/dist/stage-public/baked/bakedScene.js +129 -0
  294. package/dist/stage-public/baked/sceneAppearance.js +225 -0
  295. package/dist/stage-public/baked/sceneCamera.js +45 -0
  296. package/dist/stage-public/comparison-contract.js +28 -0
  297. package/dist/stage-public/delivery.html +4 -0
  298. package/dist/stage-public/delivery.js +17 -0
  299. package/dist/stage-public/godot/appearance.gd +170 -0
  300. package/dist/stage-public/godot/preview.gd +79 -0
  301. package/dist/stage-public/index.html +141 -0
  302. package/dist/stage-public/review-app.js +289 -0
  303. package/dist/stage-public/review-runtime.js +63 -0
  304. package/dist/stage-public/review.css +24 -0
  305. package/dist/stage-public/review.html +47 -0
  306. package/dist/stage-public/scene-runtime.js +212 -0
  307. package/dist/stage-public/sceneContractRuntime.js +235 -0
  308. package/dist/stage-public/styles.css +328 -0
  309. package/dist/stage-public/three-appearance.js +104 -0
  310. package/dist/stage-public/vendor/three170/LICENSE +21 -0
  311. package/dist/stage-public/vendor/three170/build/three.module.js +54571 -0
  312. package/dist/stage-public/vendor/three170/examples/jsm/controls/OrbitControls.js +1523 -0
  313. package/dist/stage-public/vendor/three170/examples/jsm/environments/RoomEnvironment.js +144 -0
  314. package/dist/stage-public/vendor/three170/examples/jsm/libs/fflate.module.js +2672 -0
  315. package/dist/stage-public/vendor/three170/examples/jsm/loaders/EXRLoader.js +2563 -0
  316. package/dist/stage-public/vendor/three170/examples/jsm/loaders/GLTFLoader.js +4727 -0
  317. package/dist/stage-public/vendor/three170/examples/jsm/utils/BufferGeometryUtils.js +1373 -0
  318. package/dist/tile-transition-mask.svg +40 -0
  319. package/package.json +21 -7
  320. package/dist/canvas-public/cycle-detect.js +0 -166
  321. package/dist/canvas-public/smart-split.js +0 -185
  322. /package/{skills → dist/skills/en-US}/game-audio/references/bgm-cdn.md +0 -0
  323. /package/{skills → dist/skills/en-US}/game-audio/references/sfx-cdn.md +0 -0
  324. /package/{skills → dist/skills/en-US}/game-test/references/checklists/playtest-qa.md +0 -0
  325. /package/{skills → dist/skills/en-US}/game-ui/references/checklists/game-ui-quality.md +0 -0
  326. /package/{skills → dist/skills/en-US}/game-ui/references/checklists/hud-readability.md +0 -0
  327. /package/{skills → dist/skills/en-US}/game-ui/references/checklists/mobile-input.md +0 -0
  328. /package/{skills → dist/skills/en-US}/game-ui/references/checklists/responsive-ui-fit.md +0 -0
  329. /package/{skills → dist/skills/en-US}/game-ui/references/ui-patterns.md +0 -0
  330. /package/{skills → dist/skills/en-US}/game-ui/references/ui-prompt-templates.md +0 -0
  331. /package/{skills → dist/skills/en-US}/phaser-2d-graphics-builder/assets/scorecard-anchors/scene-1.jpeg +0 -0
  332. /package/{skills → dist/skills/en-US}/phaser-2d-graphics-builder/assets/scorecard-anchors/scene-2.jpeg +0 -0
  333. /package/{skills → dist/skills/en-US}/phaser-2d-graphics-builder/assets/scorecard-anchors/scene-3.jpg +0 -0
  334. /package/{skills → dist/skills/en-US}/phaser-2d-graphics-builder/references/checklists/compose-quality.md +0 -0
  335. /package/{skills → dist/skills/en-US}/phaser-2d-graphics-builder/references/checklists/performance-safe-visual-detail.md +0 -0
  336. /package/{skills → dist/skills/en-US}/phaser-2d-graphics-builder/references/checklists/premium-game-quality-gate.md +0 -0
  337. /package/{skills → dist/skills/en-US}/phaser-2d-graphics-builder/references/checklists/sprite-quality.md +0 -0
  338. /package/{skills → dist/skills/en-US}/phaser-2d-graphics-builder/references/checklists/technical-art-quality.md +0 -0
  339. /package/{skills → dist/skills/en-US}/phaser-2d-graphics-builder/references/checklists/visual-scorecard.md +0 -0
  340. /package/{skills → dist/skills/en-US}/phaser-2d-graphics-builder/references/compose-recipes.md +0 -0
  341. /package/{skills → dist/skills/en-US}/phaser-2d-graphics-builder/references/graphics-prompt-templates.md +0 -0
  342. /package/{skills → dist/skills/en-US}/phaser-2d-graphics-builder/references/implementation-blueprint.md +0 -0
  343. /package/{skills → dist/skills/en-US}/phaser-2d-graphics-builder/references/sprite-recipes.md +0 -0
  344. /package/{skills → dist/skills/en-US}/phaser-2d-graphics-builder/references/technical-art.md +0 -0
  345. /package/{skills → dist/skills/en-US}/phaser-2d-graphics-builder/references/vfx-recipes.md +0 -0
  346. /package/{skills → dist/skills/en-US}/phaser-2d-graphics-builder/references/visual-scorecard.md +0 -0
  347. /package/{skills → dist/skills/en-US}/threejs-aaa-graphics-builder/assets/scorecard-anchors/scene-1.jpg +0 -0
  348. /package/{skills → dist/skills/en-US}/threejs-aaa-graphics-builder/assets/scorecard-anchors/scene-2.jpg +0 -0
  349. /package/{skills → dist/skills/en-US}/threejs-aaa-graphics-builder/assets/scorecard-anchors/scene-3.jpg +0 -0
  350. /package/{skills → dist/skills/en-US}/threejs-aaa-graphics-builder/references/checklists/aaa-game-quality-gate.md +0 -0
  351. /package/{skills → dist/skills/en-US}/threejs-aaa-graphics-builder/references/checklists/aaa-visual-scorecard.md +0 -0
  352. /package/{skills → dist/skills/en-US}/threejs-aaa-graphics-builder/references/checklists/material-lighting-quality.md +0 -0
  353. /package/{skills → dist/skills/en-US}/threejs-aaa-graphics-builder/references/checklists/performance-safe-visual-detail.md +0 -0
  354. /package/{skills → dist/skills/en-US}/threejs-aaa-graphics-builder/references/checklists/procedural-model-quality.md +0 -0
  355. /package/{skills → dist/skills/en-US}/threejs-aaa-graphics-builder/references/checklists/technical-art-quality.md +0 -0
  356. /package/{skills → dist/skills/en-US}/threejs-aaa-graphics-builder/references/graphics-prompt-templates.md +0 -0
  357. /package/{skills → dist/skills/en-US}/threejs-aaa-graphics-builder/references/implementation-blueprint.md +0 -0
  358. /package/{skills → dist/skills/en-US}/threejs-aaa-graphics-builder/references/model-recipes.md +0 -0
  359. /package/{skills → dist/skills/en-US}/threejs-aaa-graphics-builder/references/render-recipes.md +0 -0
  360. /package/{skills → dist/skills/en-US}/threejs-aaa-graphics-builder/references/shader-cookbook.md +0 -0
  361. /package/{skills → dist/skills/en-US}/threejs-aaa-graphics-builder/references/technical-art.md +0 -0
  362. /package/{skills → dist/skills/en-US}/threejs-aaa-graphics-builder/references/visual-scorecard.md +0 -0
  363. /package/{skills → dist/skills/zh-CN}/evomeme-canvas/SKILL.md +0 -0
  364. /package/{skills → dist/skills/zh-CN}/evomeme-canvas/agents/openai.yaml +0 -0
  365. /package/{skills → dist/skills/zh-CN}/evomeme-cloud-fs/agents/openai.yaml +0 -0
  366. /package/{skills → dist/skills/zh-CN}/evomeme-cover/agents/openai.yaml +0 -0
  367. /package/{skills → dist/skills/zh-CN}/evomeme-game-maker/agents/openai.yaml +0 -0
  368. /package/{skills → dist/skills/zh-CN}/evomeme-login/SKILL.md +0 -0
  369. /package/{skills → dist/skills/zh-CN}/evomeme-login/agents/openai.yaml +0 -0
  370. /package/{skills → dist/skills/zh-CN}/evomeme-native-bridge-sdk/SKILL.md +0 -0
  371. /package/{skills → dist/skills/zh-CN}/evomeme-native-bridge-sdk/agents/openai.yaml +0 -0
  372. /package/{skills → dist/skills/zh-CN}/evomeme-tos-upload/agents/openai.yaml +0 -0
  373. /package/{skills → dist/skills/zh-CN}/game-art/SKILL.md +0 -0
  374. /package/{skills → dist/skills/zh-CN}/game-art/agents/openai.yaml +0 -0
  375. /package/{skills → dist/skills/zh-CN}/game-asset-image-generator/agents/openai.yaml +0 -0
  376. /package/{skills → dist/skills/zh-CN}/game-asset-image-generator/references/background.md +0 -0
  377. /package/{skills → dist/skills/zh-CN}/game-asset-image-generator/references/static-game-assets.md +0 -0
  378. /package/{skills → dist/skills/zh-CN}/game-audio/SKILL.md +0 -0
  379. /package/{skills → dist/skills/zh-CN}/game-audio/agents/openai.yaml +0 -0
  380. /package/{skills → dist/skills/zh-CN}/game-demo/SKILL.md +0 -0
  381. /package/{skills → dist/skills/zh-CN}/game-demo/agents/openai.yaml +0 -0
  382. /package/{skills → dist/skills/zh-CN}/game-maker/SKILL.md +0 -0
  383. /package/{skills → dist/skills/zh-CN}/game-maker/agents/openai.yaml +0 -0
  384. /package/{skills → dist/skills/zh-CN}/game-test/SKILL.md +0 -0
  385. /package/{skills → dist/skills/zh-CN}/game-test/agents/openai.yaml +0 -0
  386. /package/{skills → dist/skills/zh-CN}/game-ui/agents/openai.yaml +0 -0
  387. /package/{skills → dist/skills/zh-CN}/phaser-2d-game/SKILL.md +0 -0
  388. /package/{skills → dist/skills/zh-CN}/phaser-2d-game/agents/openai.yaml +0 -0
  389. /package/{skills → dist/skills/zh-CN}/phaser-2d-game/references/engine-performance.md +0 -0
  390. /package/{skills → dist/skills/zh-CN}/phaser-2d-game/references/engine-physics.md +0 -0
  391. /package/{skills → dist/skills/zh-CN}/phaser-2d-game/references/engine-runtime.md +0 -0
  392. /package/{skills → dist/skills/zh-CN}/phaser-2d-game/references/engine-spritesheets.md +0 -0
  393. /package/{skills → dist/skills/zh-CN}/phaser-2d-game/references/engine-tilemaps.md +0 -0
  394. /package/{skills → dist/skills/zh-CN}/phaser-2d-game/references/file-structure.md +0 -0
  395. /package/{skills → dist/skills/zh-CN}/phaser-2d-graphics-builder/SKILL.md +0 -0
  396. /package/{skills → dist/skills/zh-CN}/phaser-2d-graphics-builder/agents/openai.yaml +0 -0
  397. /package/{skills → dist/skills/zh-CN}/threejs-3d-game/agents/openai.yaml +0 -0
  398. /package/{skills → dist/skills/zh-CN}/threejs-3d-game/references/engine-audio.md +0 -0
  399. /package/{skills → dist/skills/zh-CN}/threejs-3d-game/references/engine-input-camera.md +0 -0
  400. /package/{skills → dist/skills/zh-CN}/threejs-3d-game/references/engine-performance.md +0 -0
  401. /package/{skills → dist/skills/zh-CN}/threejs-3d-game/references/engine-physics.md +0 -0
  402. /package/{skills → dist/skills/zh-CN}/threejs-3d-game/references/engine-runtime.md +0 -0
  403. /package/{skills → dist/skills/zh-CN}/threejs-3d-game/references/file-structure.md +0 -0
  404. /package/{skills → dist/skills/zh-CN}/threejs-aaa-graphics-builder/SKILL.md +0 -0
  405. /package/{skills → dist/skills/zh-CN}/threejs-aaa-graphics-builder/agents/openai.yaml +0 -0
@@ -0,0 +1,510 @@
1
+ let sourceBitmap = null
2
+
3
+ self.addEventListener('message', async (event) => {
4
+ const message = event.data || {}
5
+ try {
6
+ if (message.type === 'init') {
7
+ const response = await fetch(String(message.url || ''))
8
+ if (!response.ok) throw workerError('workers.imageLoadFailed', { status: response.status })
9
+ sourceBitmap?.close?.()
10
+ sourceBitmap = await createImageBitmap(await response.blob())
11
+ self.postMessage({
12
+ type: 'ready',
13
+ requestId: message.requestId,
14
+ width: sourceBitmap.width,
15
+ height: sourceBitmap.height,
16
+ })
17
+ return
18
+ }
19
+
20
+ if (message.type !== 'process') return
21
+ if (!sourceBitmap) throw workerError('workers.perfectPixel.notInitialized')
22
+
23
+ const settings = normalizeSettings(message.settings)
24
+ const sourceCanvas = new OffscreenCanvas(sourceBitmap.width, sourceBitmap.height)
25
+ const sourceContext = sourceCanvas.getContext('2d', { willReadFrequently: true })
26
+ sourceContext.drawImage(sourceBitmap, 0, 0)
27
+ const source = sourceContext.getImageData(0, 0, sourceBitmap.width, sourceBitmap.height)
28
+ const result = restorePixelGrid(source, settings)
29
+
30
+ const lowResolution = new OffscreenCanvas(result.width, result.height)
31
+ lowResolution.getContext('2d').putImageData(
32
+ new ImageData(result.pixels, result.width, result.height),
33
+ 0,
34
+ 0,
35
+ )
36
+
37
+ const outputWidth = result.width * settings.exportScale
38
+ const outputHeight = result.height * settings.exportScale
39
+ const output = new OffscreenCanvas(outputWidth, outputHeight)
40
+ const outputContext = output.getContext('2d')
41
+ outputContext.imageSmoothingEnabled = false
42
+ outputContext.clearRect(0, 0, outputWidth, outputHeight)
43
+ outputContext.drawImage(lowResolution, 0, 0, outputWidth, outputHeight)
44
+ const blob = await output.convertToBlob({ type: 'image/png' })
45
+
46
+ self.postMessage({
47
+ type: 'result',
48
+ requestId: message.requestId,
49
+ blob,
50
+ width: outputWidth,
51
+ height: outputHeight,
52
+ gridWidth: result.width,
53
+ gridHeight: result.height,
54
+ pixelSizeX: result.pixelSizeX,
55
+ pixelSizeY: result.pixelSizeY,
56
+ confidence: result.confidence,
57
+ automatic: settings.autoGrid,
58
+ })
59
+ } catch (error) {
60
+ self.postMessage({
61
+ type: 'error',
62
+ requestId: message.requestId,
63
+ messageKey: error?.messageKey || '',
64
+ messageVariables: error?.messageVariables || null,
65
+ message: error?.messageKey ? '' : String(error?.message || error),
66
+ })
67
+ }
68
+ })
69
+
70
+ function workerError(messageKey, messageVariables = null) {
71
+ const error = new Error(messageKey)
72
+ error.messageKey = messageKey
73
+ error.messageVariables = messageVariables
74
+ return error
75
+ }
76
+
77
+ function normalizeSettings(value) {
78
+ const settings = value && typeof value === 'object' ? value : {}
79
+ const sampleMethod = ['majority', 'median', 'center'].includes(settings.sampleMethod)
80
+ ? settings.sampleMethod
81
+ : 'median'
82
+ const alphaMode = settings.alphaMode === 'preserve' ? 'preserve' : 'hard'
83
+ return {
84
+ autoGrid: settings.autoGrid !== false,
85
+ pixelSize: clampInteger(settings.pixelSize, 2, 256, 8),
86
+ sampleMethod,
87
+ exportScale: clampInteger(settings.exportScale, 1, 16, 4),
88
+ alphaMode,
89
+ alphaThreshold: clampInteger(settings.alphaThreshold, 0, 255, 128),
90
+ }
91
+ }
92
+
93
+ function clampInteger(value, min, max, fallback) {
94
+ const number = Math.round(Number(value))
95
+ return Number.isFinite(number) ? Math.max(min, Math.min(max, number)) : fallback
96
+ }
97
+
98
+ function restorePixelGrid(image, settings) {
99
+ const width = image.width
100
+ const height = image.height
101
+ if (!width || !height) throw workerError('workers.perfectPixel.invalidSourceSize')
102
+
103
+ const projections = buildAlphaAwareGradientProjections(image.data, width, height)
104
+ let pixelSizeX = settings.pixelSize
105
+ let pixelSizeY = settings.pixelSize
106
+ let gridWidth = Math.ceil(width / settings.pixelSize)
107
+ let gridHeight = Math.ceil(height / settings.pixelSize)
108
+ let confidence = 1
109
+
110
+ if (settings.autoGrid) {
111
+ const detectedX = detectPixelPeriod(projections.x)
112
+ const detectedY = detectPixelPeriod(projections.y)
113
+ if (!detectedX && !detectedY) {
114
+ throw workerError('workers.perfectPixel.gridDetectionFailed')
115
+ }
116
+ let squarePixelSize
117
+ if (detectedX && detectedY) {
118
+ const ratio = Math.max(detectedX.period, detectedY.period) / Math.min(detectedX.period, detectedY.period)
119
+ if (ratio <= 1.5) {
120
+ const totalConfidence = Math.max(1e-6, detectedX.confidence + detectedY.confidence)
121
+ squarePixelSize = (
122
+ detectedX.period * detectedX.confidence +
123
+ detectedY.period * detectedY.confidence
124
+ ) / totalConfidence
125
+ } else {
126
+ // Pixel-art cells are square. If one axis is dominated by illustration
127
+ // content instead of the grid, trust the stronger axis for both directions.
128
+ squarePixelSize = detectedX.confidence >= detectedY.confidence
129
+ ? detectedX.period
130
+ : detectedY.period
131
+ }
132
+ confidence = Math.min(detectedX.confidence, detectedY.confidence)
133
+ } else {
134
+ const detected = detectedX || detectedY
135
+ squarePixelSize = detected.period
136
+ // A single reliable axis is enough for square pixels, but report that the
137
+ // estimate had less supporting evidence than a two-axis match.
138
+ confidence = detected.confidence * 0.78
139
+ }
140
+ pixelSizeX = squarePixelSize
141
+ pixelSizeY = squarePixelSize
142
+ gridWidth = Math.max(1, Math.round(width / pixelSizeX))
143
+ gridHeight = Math.max(1, Math.round(height / pixelSizeY))
144
+ pixelSizeX = width / gridWidth
145
+ pixelSizeY = height / gridHeight
146
+ }
147
+
148
+ const xCoordinates = settings.autoGrid
149
+ ? refineGridCoordinates(width, gridWidth, projections.x)
150
+ : fixedGridCoordinates(width, settings.pixelSize)
151
+ const yCoordinates = settings.autoGrid
152
+ ? refineGridCoordinates(height, gridHeight, projections.y)
153
+ : fixedGridCoordinates(height, settings.pixelSize)
154
+ const outputWidth = xCoordinates.length - 1
155
+ const outputHeight = yCoordinates.length - 1
156
+ if (outputWidth < 1 || outputHeight < 1) {
157
+ throw workerError('workers.perfectPixel.emptyGrid')
158
+ }
159
+ if (outputWidth * outputHeight > 4_194_304) {
160
+ throw workerError('workers.perfectPixel.gridTooLarge')
161
+ }
162
+
163
+ const pixels = sampleGrid(
164
+ image.data,
165
+ width,
166
+ height,
167
+ xCoordinates,
168
+ yCoordinates,
169
+ settings,
170
+ )
171
+ return {
172
+ pixels,
173
+ width: outputWidth,
174
+ height: outputHeight,
175
+ pixelSizeX,
176
+ pixelSizeY,
177
+ confidence,
178
+ }
179
+ }
180
+
181
+ /**
182
+ * Transparent pixels may contain arbitrary hidden RGB values. Work in premultiplied
183
+ * RGB and add the alpha edge itself to the signal, so those hidden colors can never
184
+ * create a fake grid while dark opaque sprites remain detectable.
185
+ */
186
+ function buildAlphaAwareGradientProjections(source, width, height) {
187
+ const x = new Float64Array(width)
188
+ const y = new Float64Array(height)
189
+ for (let row = 0; row < height; row += 1) {
190
+ for (let column = 0; column < width; column += 1) {
191
+ const offset = (row * width + column) * 4
192
+ const alpha = source[offset + 3] / 255
193
+ const red = source[offset] * alpha
194
+ const green = source[offset + 1] * alpha
195
+ const blue = source[offset + 2] * alpha
196
+
197
+ if (column > 0) {
198
+ const previous = offset - 4
199
+ const previousAlpha = source[previous + 3] / 255
200
+ const delta =
201
+ Math.abs(red - source[previous] * previousAlpha) +
202
+ Math.abs(green - source[previous + 1] * previousAlpha) +
203
+ Math.abs(blue - source[previous + 2] * previousAlpha) +
204
+ Math.abs(alpha - previousAlpha) * 255
205
+ x[column] += delta
206
+ }
207
+ if (row > 0) {
208
+ const previous = offset - width * 4
209
+ const previousAlpha = source[previous + 3] / 255
210
+ const delta =
211
+ Math.abs(red - source[previous] * previousAlpha) +
212
+ Math.abs(green - source[previous + 1] * previousAlpha) +
213
+ Math.abs(blue - source[previous + 2] * previousAlpha) +
214
+ Math.abs(alpha - previousAlpha) * 255
215
+ y[row] += delta
216
+ }
217
+ }
218
+ }
219
+ return { x, y }
220
+ }
221
+
222
+ /**
223
+ * Grid edges share one residue modulo the source pixel-block size. Scoring that
224
+ * concentration together with short-lag autocorrelation recovers the same periodic
225
+ * grid targeted by Perfect Pixel's FFT/gradient stages without shipping OpenCV.
226
+ */
227
+ function detectPixelPeriod(projection) {
228
+ const length = projection.length
229
+ if (length < 4) return null
230
+ const maximum = Math.min(64, Math.max(2, Math.floor(length / 3)))
231
+ let total = 0
232
+ for (let i = 1; i < length; i += 1) total += projection[i]
233
+ if (total <= 1e-6) return null
234
+
235
+ let best = null
236
+ for (let period = 2; period <= maximum; period += 1) {
237
+ const bins = new Float64Array(period)
238
+ for (let i = 1; i < length; i += 1) bins[i % period] += projection[i]
239
+ let maximumBin = 0
240
+ for (const value of bins) maximumBin = Math.max(maximumBin, value)
241
+ const concentration = (maximumBin - total / period) / total
242
+
243
+ let numerator = 0
244
+ let leftEnergy = 0
245
+ let rightEnergy = 0
246
+ for (let i = 1; i + period < length; i += 1) {
247
+ const left = projection[i]
248
+ const right = projection[i + period]
249
+ numerator += left * right
250
+ leftEnergy += left * left
251
+ rightEnergy += right * right
252
+ }
253
+ const correlation = numerator / Math.sqrt(Math.max(1e-12, leftEnergy * rightEnergy))
254
+ const score = concentration * 0.78 + correlation * 0.22
255
+ if (!best || score > best.score) best = { period, score, concentration, correlation }
256
+ }
257
+
258
+ const phaseResult = best && best.score >= 0.025 && best.concentration >= 0.01
259
+ ? {
260
+ period: best.period,
261
+ confidence: Math.max(0, Math.min(1, best.score * 2.5)),
262
+ }
263
+ : null
264
+ const peakResult = detectPixelPeriodFromGradientPeaks(projection)
265
+
266
+ if (!phaseResult) return peakResult
267
+ if (!peakResult) return phaseResult
268
+ const ratio = Math.max(phaseResult.period, peakResult.period) /
269
+ Math.min(phaseResult.period, peakResult.period)
270
+ if (ratio <= 1.2) {
271
+ return phaseResult.confidence >= peakResult.confidence ? phaseResult : peakResult
272
+ }
273
+ return phaseResult.confidence >= peakResult.confidence * 1.2 ? phaseResult : peakResult
274
+ }
275
+
276
+ function detectPixelPeriodFromGradientPeaks(projection) {
277
+ let maximum = 0
278
+ for (const value of projection) maximum = Math.max(maximum, value)
279
+ if (maximum <= 1e-6) return null
280
+ const thresholds = [0.2, 0.12, 0.07]
281
+ for (const relativeThreshold of thresholds) {
282
+ const threshold = maximum * relativeThreshold
283
+ const peaks = []
284
+ for (let index = 1; index < projection.length - 1; index += 1) {
285
+ if (
286
+ projection[index] >= threshold &&
287
+ projection[index] > projection[index - 1] &&
288
+ projection[index] >= projection[index + 1]
289
+ ) {
290
+ const previous = peaks[peaks.length - 1]
291
+ if (previous == null || index - previous >= 2) peaks.push(index)
292
+ else if (projection[index] > projection[previous]) peaks[peaks.length - 1] = index
293
+ }
294
+ }
295
+ if (peaks.length < 3) continue
296
+ const intervals = []
297
+ for (let index = 1; index < peaks.length; index += 1) {
298
+ const interval = peaks[index] - peaks[index - 1]
299
+ if (interval >= 2 && interval <= 128) intervals.push(interval)
300
+ }
301
+ if (intervals.length < 2) continue
302
+ const period = median(intervals)
303
+ if (period < 2 || period > 128) continue
304
+ const deviations = intervals.map((interval) => {
305
+ const multiple = Math.max(1, Math.round(interval / period))
306
+ return Math.abs(interval - multiple * period) / period
307
+ })
308
+ const meanDeviation = deviations.reduce((sum, value) => sum + value, 0) / deviations.length
309
+ const support = Math.min(1, intervals.length / 10)
310
+ const confidence = Math.max(0.08, Math.min(0.9, (1 - meanDeviation) * (0.45 + support * 0.45)))
311
+ return { period, confidence }
312
+ }
313
+ return null
314
+ }
315
+
316
+ function refineGridCoordinates(length, gridCount, projection, intensity = 0.25) {
317
+ const count = Math.max(1, Math.min(length, Math.round(gridCount)))
318
+ const cellSize = length / count
319
+ const coordinates = new Int32Array(count + 1)
320
+ coordinates[0] = 0
321
+ coordinates[count] = length
322
+
323
+ for (let index = 1; index < count; index += 1) {
324
+ const expected = index * cellSize
325
+ const radius = Math.max(1, Math.round(cellSize * intensity))
326
+ const minimum = Math.max(coordinates[index - 1] + 1, Math.round(expected) - radius)
327
+ const maximum = Math.min(length - (count - index), Math.round(expected) + radius)
328
+ let best = Math.max(minimum, Math.min(maximum, Math.round(expected)))
329
+ let bestValue = projection[best] || 0
330
+ for (let position = minimum; position <= maximum; position += 1) {
331
+ const value = projection[position] || 0
332
+ if (value > bestValue) {
333
+ best = position
334
+ bestValue = value
335
+ }
336
+ }
337
+ coordinates[index] = best
338
+ }
339
+ return coordinates
340
+ }
341
+
342
+ function fixedGridCoordinates(length, pixelSize) {
343
+ const size = Math.max(2, Math.round(pixelSize))
344
+ const coordinates = []
345
+ for (let position = 0; position < length; position += size) coordinates.push(position)
346
+ if (coordinates[coordinates.length - 1] !== length) coordinates.push(length)
347
+ return Int32Array.from(coordinates)
348
+ }
349
+
350
+ function sampleGrid(source, width, height, xCoordinates, yCoordinates, settings) {
351
+ const outputWidth = xCoordinates.length - 1
352
+ const outputHeight = yCoordinates.length - 1
353
+ const output = new Uint8ClampedArray(outputWidth * outputHeight * 4)
354
+ for (let outputY = 0; outputY < outputHeight; outputY += 1) {
355
+ const y0 = Math.max(0, Math.min(height - 1, yCoordinates[outputY]))
356
+ const y1 = Math.max(y0 + 1, Math.min(height, yCoordinates[outputY + 1]))
357
+ for (let outputX = 0; outputX < outputWidth; outputX += 1) {
358
+ const x0 = Math.max(0, Math.min(width - 1, xCoordinates[outputX]))
359
+ const x1 = Math.max(x0 + 1, Math.min(width, xCoordinates[outputX + 1]))
360
+ const color = sampleCell(source, width, x0, y0, x1, y1, settings)
361
+ const outputOffset = (outputY * outputWidth + outputX) * 4
362
+ output[outputOffset] = color[0]
363
+ output[outputOffset + 1] = color[1]
364
+ output[outputOffset + 2] = color[2]
365
+ output[outputOffset + 3] = color[3]
366
+ }
367
+ }
368
+ return output
369
+ }
370
+
371
+ function sampleCell(source, width, x0, y0, x1, y1, settings) {
372
+ const pixelCount = Math.max(1, (x1 - x0) * (y1 - y0))
373
+ const sampleStep = Math.max(1, Math.ceil(pixelCount / 128))
374
+ const samples = []
375
+ const alphaSamples = []
376
+ let alphaSum = 0
377
+ let sampleIndex = 0
378
+ let centerSample = null
379
+ const centerX = Math.min(x1 - 1, Math.floor((x0 + x1) / 2))
380
+ const centerY = Math.min(y1 - 1, Math.floor((y0 + y1) / 2))
381
+
382
+ for (let y = y0; y < y1; y += 1) {
383
+ for (let x = x0; x < x1; x += 1) {
384
+ const offset = (y * width + x) * 4
385
+ const alpha = source[offset + 3]
386
+ alphaSum += alpha
387
+ if (x === centerX && y === centerY) {
388
+ centerSample = [source[offset], source[offset + 1], source[offset + 2], alpha]
389
+ }
390
+ if (sampleIndex % sampleStep === 0) {
391
+ alphaSamples.push(alpha)
392
+ if (alpha > 4) {
393
+ samples.push([source[offset], source[offset + 1], source[offset + 2], alpha])
394
+ }
395
+ }
396
+ sampleIndex += 1
397
+ }
398
+ }
399
+
400
+ let outputAlpha
401
+ if (settings.alphaMode === 'preserve') {
402
+ outputAlpha = alphaSamples.length ? median(alphaSamples) : 0
403
+ } else {
404
+ const coverageAlpha = alphaSum / pixelCount
405
+ outputAlpha = coverageAlpha >= settings.alphaThreshold ? 255 : 0
406
+ }
407
+ if (outputAlpha <= 0 || !samples.length) return [0, 0, 0, 0]
408
+
409
+ let rgb
410
+ if (settings.sampleMethod === 'center' && centerSample?.[3] > 4) {
411
+ rgb = centerSample.slice(0, 3)
412
+ } else if (settings.sampleMethod === 'median') {
413
+ rgb = weightedMedianColor(samples)
414
+ } else if (settings.sampleMethod === 'center') {
415
+ rgb = weightedMeanColor(samples)
416
+ } else {
417
+ rgb = majorityClusterColor(samples)
418
+ }
419
+ return [rgb[0], rgb[1], rgb[2], Math.round(outputAlpha)]
420
+ }
421
+
422
+ function sampleWeight(sample) {
423
+ const alpha = sample[3] / 255
424
+ return alpha * alpha
425
+ }
426
+
427
+ function weightedMeanColor(samples) {
428
+ let red = 0
429
+ let green = 0
430
+ let blue = 0
431
+ let weightSum = 0
432
+ for (const sample of samples) {
433
+ const weight = sampleWeight(sample)
434
+ red += sample[0] * weight
435
+ green += sample[1] * weight
436
+ blue += sample[2] * weight
437
+ weightSum += weight
438
+ }
439
+ if (weightSum <= 1e-8) return [0, 0, 0]
440
+ return [Math.round(red / weightSum), Math.round(green / weightSum), Math.round(blue / weightSum)]
441
+ }
442
+
443
+ function weightedMedianColor(samples) {
444
+ const channelMedian = (channel) => {
445
+ const values = samples
446
+ .map((sample) => ({ value: sample[channel], weight: sampleWeight(sample) }))
447
+ .sort((left, right) => left.value - right.value)
448
+ const total = values.reduce((sum, item) => sum + item.weight, 0)
449
+ let accumulated = 0
450
+ for (const item of values) {
451
+ accumulated += item.weight
452
+ if (accumulated >= total / 2) return item.value
453
+ }
454
+ return values[values.length - 1]?.value || 0
455
+ }
456
+ return [channelMedian(0), channelMedian(1), channelMedian(2)]
457
+ }
458
+
459
+ function majorityClusterColor(samples) {
460
+ if (samples.length === 1) return samples[0].slice(0, 3)
461
+ let first = samples[0].slice(0, 3)
462
+ let second = first
463
+ let farthestDistance = -1
464
+ for (const sample of samples) {
465
+ const distance = colorDistanceSquared(sample, first)
466
+ if (distance > farthestDistance) {
467
+ farthestDistance = distance
468
+ second = sample.slice(0, 3)
469
+ }
470
+ }
471
+ if (farthestDistance <= 0) return first
472
+
473
+ let firstWeight = 0
474
+ let secondWeight = 0
475
+ for (let iteration = 0; iteration < 6; iteration += 1) {
476
+ const firstSum = [0, 0, 0]
477
+ const secondSum = [0, 0, 0]
478
+ firstWeight = 0
479
+ secondWeight = 0
480
+ for (const sample of samples) {
481
+ const weight = sampleWeight(sample)
482
+ const useSecond = colorDistanceSquared(sample, second) < colorDistanceSquared(sample, first)
483
+ const sum = useSecond ? secondSum : firstSum
484
+ sum[0] += sample[0] * weight
485
+ sum[1] += sample[1] * weight
486
+ sum[2] += sample[2] * weight
487
+ if (useSecond) secondWeight += weight
488
+ else firstWeight += weight
489
+ }
490
+ if (firstWeight > 0) first = firstSum.map((value) => value / firstWeight)
491
+ if (secondWeight > 0) second = secondSum.map((value) => value / secondWeight)
492
+ }
493
+ const result = secondWeight >= firstWeight ? second : first
494
+ return result.map((value) => Math.max(0, Math.min(255, Math.round(value))))
495
+ }
496
+
497
+ function colorDistanceSquared(sample, color) {
498
+ const red = sample[0] - color[0]
499
+ const green = sample[1] - color[1]
500
+ const blue = sample[2] - color[2]
501
+ return red * red + green * green + blue * blue
502
+ }
503
+
504
+ function median(values) {
505
+ const sorted = [...values].sort((left, right) => left - right)
506
+ const middle = Math.floor(sorted.length / 2)
507
+ return sorted.length % 2
508
+ ? sorted[middle]
509
+ : (sorted[middle - 1] + sorted[middle]) / 2
510
+ }