@fraziym/axoniz 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 (512) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +76 -0
  3. package/dist/agents/definition.d.ts +15 -0
  4. package/dist/agents/definition.d.ts.map +1 -0
  5. package/dist/agents/definition.js +41 -0
  6. package/dist/agents/definition.js.map +1 -0
  7. package/dist/agents/index.d.ts +12 -0
  8. package/dist/agents/index.d.ts.map +1 -0
  9. package/dist/agents/index.js +11 -0
  10. package/dist/agents/index.js.map +1 -0
  11. package/dist/agents/registry.d.ts +17 -0
  12. package/dist/agents/registry.d.ts.map +1 -0
  13. package/dist/agents/registry.js +23 -0
  14. package/dist/agents/registry.js.map +1 -0
  15. package/dist/agents/specialized.d.ts +31 -0
  16. package/dist/agents/specialized.d.ts.map +1 -0
  17. package/dist/agents/specialized.js +75 -0
  18. package/dist/agents/specialized.js.map +1 -0
  19. package/dist/awareness/index.d.ts +14 -0
  20. package/dist/awareness/index.d.ts.map +1 -0
  21. package/dist/awareness/index.js +22 -0
  22. package/dist/awareness/index.js.map +1 -0
  23. package/dist/awareness/service.d.ts +180 -0
  24. package/dist/awareness/service.d.ts.map +1 -0
  25. package/dist/awareness/service.js +789 -0
  26. package/dist/awareness/service.js.map +1 -0
  27. package/dist/cli/entry.d.ts +13 -0
  28. package/dist/cli/entry.d.ts.map +1 -0
  29. package/dist/cli/entry.js +35 -0
  30. package/dist/cli/entry.js.map +1 -0
  31. package/dist/comms/telegram.d.ts +41 -0
  32. package/dist/comms/telegram.d.ts.map +1 -0
  33. package/dist/comms/telegram.js +332 -0
  34. package/dist/comms/telegram.js.map +1 -0
  35. package/dist/core/agent.d.ts +252 -0
  36. package/dist/core/agent.d.ts.map +1 -0
  37. package/dist/core/agent.js +1399 -0
  38. package/dist/core/agent.js.map +1 -0
  39. package/dist/core/auth.d.ts +23 -0
  40. package/dist/core/auth.d.ts.map +1 -0
  41. package/dist/core/auth.js +113 -0
  42. package/dist/core/auth.js.map +1 -0
  43. package/dist/core/authority.d.ts +118 -0
  44. package/dist/core/authority.d.ts.map +1 -0
  45. package/dist/core/authority.js +402 -0
  46. package/dist/core/authority.js.map +1 -0
  47. package/dist/core/backend/async_queue.d.ts +17 -0
  48. package/dist/core/backend/async_queue.d.ts.map +1 -0
  49. package/dist/core/backend/async_queue.js +66 -0
  50. package/dist/core/backend/async_queue.js.map +1 -0
  51. package/dist/core/backend/index.d.ts +24 -0
  52. package/dist/core/backend/index.d.ts.map +1 -0
  53. package/dist/core/backend/index.js +128 -0
  54. package/dist/core/backend/index.js.map +1 -0
  55. package/dist/core/backend/llama_server.d.ts +39 -0
  56. package/dist/core/backend/llama_server.d.ts.map +1 -0
  57. package/dist/core/backend/llama_server.js +182 -0
  58. package/dist/core/backend/llama_server.js.map +1 -0
  59. package/dist/core/backend/llamacpp.d.ts +40 -0
  60. package/dist/core/backend/llamacpp.d.ts.map +1 -0
  61. package/dist/core/backend/llamacpp.js +200 -0
  62. package/dist/core/backend/llamacpp.js.map +1 -0
  63. package/dist/core/backend/lmstudio.d.ts +53 -0
  64. package/dist/core/backend/lmstudio.d.ts.map +1 -0
  65. package/dist/core/backend/lmstudio.js +274 -0
  66. package/dist/core/backend/lmstudio.js.map +1 -0
  67. package/dist/core/backend/ollama.d.ts +25 -0
  68. package/dist/core/backend/ollama.d.ts.map +1 -0
  69. package/dist/core/backend/ollama.js +86 -0
  70. package/dist/core/backend/ollama.js.map +1 -0
  71. package/dist/core/backend/openai.d.ts +27 -0
  72. package/dist/core/backend/openai.d.ts.map +1 -0
  73. package/dist/core/backend/openai.js +84 -0
  74. package/dist/core/backend/openai.js.map +1 -0
  75. package/dist/core/backend/types.d.ts +73 -0
  76. package/dist/core/backend/types.d.ts.map +1 -0
  77. package/dist/core/backend/types.js +137 -0
  78. package/dist/core/backend/types.js.map +1 -0
  79. package/dist/core/chat_store.d.ts +77 -0
  80. package/dist/core/chat_store.d.ts.map +1 -0
  81. package/dist/core/chat_store.js +332 -0
  82. package/dist/core/chat_store.js.map +1 -0
  83. package/dist/core/cli.d.ts +82 -0
  84. package/dist/core/cli.d.ts.map +1 -0
  85. package/dist/core/cli.js +602 -0
  86. package/dist/core/cli.js.map +1 -0
  87. package/dist/core/config.d.ts +127 -0
  88. package/dist/core/config.d.ts.map +1 -0
  89. package/dist/core/config.js +295 -0
  90. package/dist/core/config.js.map +1 -0
  91. package/dist/core/debug.d.ts +8 -0
  92. package/dist/core/debug.d.ts.map +1 -0
  93. package/dist/core/debug.js +8 -0
  94. package/dist/core/debug.js.map +1 -0
  95. package/dist/core/downloader.d.ts +31 -0
  96. package/dist/core/downloader.d.ts.map +1 -0
  97. package/dist/core/downloader.js +180 -0
  98. package/dist/core/downloader.js.map +1 -0
  99. package/dist/core/errors.d.ts +80 -0
  100. package/dist/core/errors.d.ts.map +1 -0
  101. package/dist/core/errors.js +134 -0
  102. package/dist/core/errors.js.map +1 -0
  103. package/dist/core/extras.d.ts +160 -0
  104. package/dist/core/extras.d.ts.map +1 -0
  105. package/dist/core/extras.js +553 -0
  106. package/dist/core/extras.js.map +1 -0
  107. package/dist/core/health.d.ts +27 -0
  108. package/dist/core/health.d.ts.map +1 -0
  109. package/dist/core/health.js +96 -0
  110. package/dist/core/health.js.map +1 -0
  111. package/dist/core/history.d.ts +50 -0
  112. package/dist/core/history.d.ts.map +1 -0
  113. package/dist/core/history.js +276 -0
  114. package/dist/core/history.js.map +1 -0
  115. package/dist/core/index.d.ts +6 -0
  116. package/dist/core/index.d.ts.map +1 -0
  117. package/dist/core/index.js +6 -0
  118. package/dist/core/index.js.map +1 -0
  119. package/dist/core/intelligence/ast_index.d.ts +255 -0
  120. package/dist/core/intelligence/ast_index.d.ts.map +1 -0
  121. package/dist/core/intelligence/ast_index.js +1369 -0
  122. package/dist/core/intelligence/ast_index.js.map +1 -0
  123. package/dist/core/intelligence/confidence.d.ts +113 -0
  124. package/dist/core/intelligence/confidence.d.ts.map +1 -0
  125. package/dist/core/intelligence/confidence.js +298 -0
  126. package/dist/core/intelligence/confidence.js.map +1 -0
  127. package/dist/core/intelligence/context_compressor.d.ts +80 -0
  128. package/dist/core/intelligence/context_compressor.d.ts.map +1 -0
  129. package/dist/core/intelligence/context_compressor.js +245 -0
  130. package/dist/core/intelligence/context_compressor.js.map +1 -0
  131. package/dist/core/intelligence/daemon.d.ts +247 -0
  132. package/dist/core/intelligence/daemon.d.ts.map +1 -0
  133. package/dist/core/intelligence/daemon.js +842 -0
  134. package/dist/core/intelligence/daemon.js.map +1 -0
  135. package/dist/core/intelligence/index.d.ts +60 -0
  136. package/dist/core/intelligence/index.d.ts.map +1 -0
  137. package/dist/core/intelligence/index.js +101 -0
  138. package/dist/core/intelligence/index.js.map +1 -0
  139. package/dist/core/intelligence/predictor.d.ts +246 -0
  140. package/dist/core/intelligence/predictor.d.ts.map +1 -0
  141. package/dist/core/intelligence/predictor.js +590 -0
  142. package/dist/core/intelligence/predictor.js.map +1 -0
  143. package/dist/core/intelligence/reflex.d.ts +84 -0
  144. package/dist/core/intelligence/reflex.d.ts.map +1 -0
  145. package/dist/core/intelligence/reflex.js +344 -0
  146. package/dist/core/intelligence/reflex.js.map +1 -0
  147. package/dist/core/intelligence/self_correction.d.ts +121 -0
  148. package/dist/core/intelligence/self_correction.d.ts.map +1 -0
  149. package/dist/core/intelligence/self_correction.js +327 -0
  150. package/dist/core/intelligence/self_correction.js.map +1 -0
  151. package/dist/core/intelligence/skill_distiller.d.ts +100 -0
  152. package/dist/core/intelligence/skill_distiller.d.ts.map +1 -0
  153. package/dist/core/intelligence/skill_distiller.js +246 -0
  154. package/dist/core/intelligence/skill_distiller.js.map +1 -0
  155. package/dist/core/intelligence/swarm.d.ts +330 -0
  156. package/dist/core/intelligence/swarm.d.ts.map +1 -0
  157. package/dist/core/intelligence/swarm.js +1064 -0
  158. package/dist/core/intelligence/swarm.js.map +1 -0
  159. package/dist/core/intelligence/trajectory.d.ts +107 -0
  160. package/dist/core/intelligence/trajectory.d.ts.map +1 -0
  161. package/dist/core/intelligence/trajectory.js +330 -0
  162. package/dist/core/intelligence/trajectory.js.map +1 -0
  163. package/dist/core/logger.d.ts +111 -0
  164. package/dist/core/logger.d.ts.map +1 -0
  165. package/dist/core/logger.js +640 -0
  166. package/dist/core/logger.js.map +1 -0
  167. package/dist/core/loop.d.ts +123 -0
  168. package/dist/core/loop.d.ts.map +1 -0
  169. package/dist/core/loop.js +423 -0
  170. package/dist/core/loop.js.map +1 -0
  171. package/dist/core/memory.d.ts +81 -0
  172. package/dist/core/memory.d.ts.map +1 -0
  173. package/dist/core/memory.js +328 -0
  174. package/dist/core/memory.js.map +1 -0
  175. package/dist/core/metrics.d.ts +29 -0
  176. package/dist/core/metrics.d.ts.map +1 -0
  177. package/dist/core/metrics.js +109 -0
  178. package/dist/core/metrics.js.map +1 -0
  179. package/dist/core/models.d.ts +51 -0
  180. package/dist/core/models.d.ts.map +1 -0
  181. package/dist/core/models.js +146 -0
  182. package/dist/core/models.js.map +1 -0
  183. package/dist/core/optimizer.d.ts +34 -0
  184. package/dist/core/optimizer.d.ts.map +1 -0
  185. package/dist/core/optimizer.js +131 -0
  186. package/dist/core/optimizer.js.map +1 -0
  187. package/dist/core/persona.d.ts +35 -0
  188. package/dist/core/persona.d.ts.map +1 -0
  189. package/dist/core/persona.js +126 -0
  190. package/dist/core/persona.js.map +1 -0
  191. package/dist/core/rate_limit.d.ts +23 -0
  192. package/dist/core/rate_limit.d.ts.map +1 -0
  193. package/dist/core/rate_limit.js +62 -0
  194. package/dist/core/rate_limit.js.map +1 -0
  195. package/dist/core/runner.d.ts +63 -0
  196. package/dist/core/runner.d.ts.map +1 -0
  197. package/dist/core/runner.js +671 -0
  198. package/dist/core/runner.js.map +1 -0
  199. package/dist/core/stream_parser.d.ts +43 -0
  200. package/dist/core/stream_parser.d.ts.map +1 -0
  201. package/dist/core/stream_parser.js +140 -0
  202. package/dist/core/stream_parser.js.map +1 -0
  203. package/dist/core/tool_schemas.d.ts +26 -0
  204. package/dist/core/tool_schemas.d.ts.map +1 -0
  205. package/dist/core/tool_schemas.js +124 -0
  206. package/dist/core/tool_schemas.js.map +1 -0
  207. package/dist/core/which.d.ts +2 -0
  208. package/dist/core/which.d.ts.map +1 -0
  209. package/dist/core/which.js +35 -0
  210. package/dist/core/which.js.map +1 -0
  211. package/dist/goals/index.d.ts +9 -0
  212. package/dist/goals/index.d.ts.map +1 -0
  213. package/dist/goals/index.js +17 -0
  214. package/dist/goals/index.js.map +1 -0
  215. package/dist/goals/service.d.ts +115 -0
  216. package/dist/goals/service.d.ts.map +1 -0
  217. package/dist/goals/service.js +415 -0
  218. package/dist/goals/service.js.map +1 -0
  219. package/dist/goals/types.d.ts +47 -0
  220. package/dist/goals/types.d.ts.map +1 -0
  221. package/dist/goals/types.js +66 -0
  222. package/dist/goals/types.js.map +1 -0
  223. package/dist/index.d.ts +22 -0
  224. package/dist/index.d.ts.map +1 -0
  225. package/dist/index.js +22 -0
  226. package/dist/index.js.map +1 -0
  227. package/dist/integrations/autonomous_startup.d.ts +51 -0
  228. package/dist/integrations/autonomous_startup.d.ts.map +1 -0
  229. package/dist/integrations/autonomous_startup.js +419 -0
  230. package/dist/integrations/autonomous_startup.js.map +1 -0
  231. package/dist/integrations/goose.d.ts +105 -0
  232. package/dist/integrations/goose.d.ts.map +1 -0
  233. package/dist/integrations/goose.js +408 -0
  234. package/dist/integrations/goose.js.map +1 -0
  235. package/dist/integrations/index.d.ts +21 -0
  236. package/dist/integrations/index.d.ts.map +1 -0
  237. package/dist/integrations/index.js +17 -0
  238. package/dist/integrations/index.js.map +1 -0
  239. package/dist/integrations/mcp.d.ts +73 -0
  240. package/dist/integrations/mcp.d.ts.map +1 -0
  241. package/dist/integrations/mcp.js +307 -0
  242. package/dist/integrations/mcp.js.map +1 -0
  243. package/dist/integrations/mempalace.d.ts +18 -0
  244. package/dist/integrations/mempalace.d.ts.map +1 -0
  245. package/dist/integrations/mempalace.js +25 -0
  246. package/dist/integrations/mempalace.js.map +1 -0
  247. package/dist/integrations/multi_agent.d.ts +82 -0
  248. package/dist/integrations/multi_agent.d.ts.map +1 -0
  249. package/dist/integrations/multi_agent.js +280 -0
  250. package/dist/integrations/multi_agent.js.map +1 -0
  251. package/dist/integrations/unified_memory.d.ts +415 -0
  252. package/dist/integrations/unified_memory.d.ts.map +1 -0
  253. package/dist/integrations/unified_memory.js +1489 -0
  254. package/dist/integrations/unified_memory.js.map +1 -0
  255. package/dist/roles/beru.yaml +48 -0
  256. package/dist/sidecar/client.d.ts +63 -0
  257. package/dist/sidecar/client.d.ts.map +1 -0
  258. package/dist/sidecar/client.js +222 -0
  259. package/dist/sidecar/client.js.map +1 -0
  260. package/dist/sidecar/index.d.ts +7 -0
  261. package/dist/sidecar/index.d.ts.map +1 -0
  262. package/dist/sidecar/index.js +6 -0
  263. package/dist/sidecar/index.js.map +1 -0
  264. package/dist/startup.d.ts +22 -0
  265. package/dist/startup.d.ts.map +1 -0
  266. package/dist/startup.js +194 -0
  267. package/dist/startup.js.map +1 -0
  268. package/dist/tools/_internal.d.ts +90 -0
  269. package/dist/tools/_internal.d.ts.map +1 -0
  270. package/dist/tools/_internal.js +375 -0
  271. package/dist/tools/_internal.js.map +1 -0
  272. package/dist/tools/_smoke.d.ts +2 -0
  273. package/dist/tools/_smoke.d.ts.map +1 -0
  274. package/dist/tools/_smoke.js +203 -0
  275. package/dist/tools/_smoke.js.map +1 -0
  276. package/dist/tools/axodex_tools.d.ts +51 -0
  277. package/dist/tools/axodex_tools.d.ts.map +1 -0
  278. package/dist/tools/axodex_tools.js +181 -0
  279. package/dist/tools/axodex_tools.js.map +1 -0
  280. package/dist/tools/code_tools.d.ts +33 -0
  281. package/dist/tools/code_tools.d.ts.map +1 -0
  282. package/dist/tools/code_tools.js +191 -0
  283. package/dist/tools/code_tools.js.map +1 -0
  284. package/dist/tools/computer_tools.d.ts +59 -0
  285. package/dist/tools/computer_tools.d.ts.map +1 -0
  286. package/dist/tools/computer_tools.js +348 -0
  287. package/dist/tools/computer_tools.js.map +1 -0
  288. package/dist/tools/file_tools.d.ts +51 -0
  289. package/dist/tools/file_tools.d.ts.map +1 -0
  290. package/dist/tools/file_tools.js +424 -0
  291. package/dist/tools/file_tools.js.map +1 -0
  292. package/dist/tools/index.d.ts +13 -0
  293. package/dist/tools/index.d.ts.map +1 -0
  294. package/dist/tools/index.js +13 -0
  295. package/dist/tools/index.js.map +1 -0
  296. package/dist/tools/shell_tools.d.ts +39 -0
  297. package/dist/tools/shell_tools.d.ts.map +1 -0
  298. package/dist/tools/shell_tools.js +163 -0
  299. package/dist/tools/shell_tools.js.map +1 -0
  300. package/dist/tools/web_tools.d.ts +31 -0
  301. package/dist/tools/web_tools.d.ts.map +1 -0
  302. package/dist/tools/web_tools.js +117 -0
  303. package/dist/tools/web_tools.js.map +1 -0
  304. package/dist/voice/index.d.ts +41 -0
  305. package/dist/voice/index.d.ts.map +1 -0
  306. package/dist/voice/index.js +58 -0
  307. package/dist/voice/index.js.map +1 -0
  308. package/dist/voice/light_daemon.d.ts +197 -0
  309. package/dist/voice/light_daemon.d.ts.map +1 -0
  310. package/dist/voice/light_daemon.js +746 -0
  311. package/dist/voice/light_daemon.js.map +1 -0
  312. package/dist/voice/setup.d.ts +63 -0
  313. package/dist/voice/setup.d.ts.map +1 -0
  314. package/dist/voice/setup.js +443 -0
  315. package/dist/voice/setup.js.map +1 -0
  316. package/dist/voice/stt.d.ts +148 -0
  317. package/dist/voice/stt.d.ts.map +1 -0
  318. package/dist/voice/stt.js +361 -0
  319. package/dist/voice/stt.js.map +1 -0
  320. package/dist/voice/tts.d.ts +168 -0
  321. package/dist/voice/tts.d.ts.map +1 -0
  322. package/dist/voice/tts.js +698 -0
  323. package/dist/voice/tts.js.map +1 -0
  324. package/dist/voice/voice_loop.d.ts +101 -0
  325. package/dist/voice/voice_loop.d.ts.map +1 -0
  326. package/dist/voice/voice_loop.js +463 -0
  327. package/dist/voice/voice_loop.js.map +1 -0
  328. package/dist/voice/wake_word.d.ts +153 -0
  329. package/dist/voice/wake_word.d.ts.map +1 -0
  330. package/dist/voice/wake_word.js +458 -0
  331. package/dist/voice/wake_word.js.map +1 -0
  332. package/dist/voice/wav.d.ts +99 -0
  333. package/dist/voice/wav.d.ts.map +1 -0
  334. package/dist/voice/wav.js +306 -0
  335. package/dist/voice/wav.js.map +1 -0
  336. package/dist/web/broker.d.ts +33 -0
  337. package/dist/web/broker.d.ts.map +1 -0
  338. package/dist/web/broker.js +58 -0
  339. package/dist/web/broker.js.map +1 -0
  340. package/dist/web/open_browser.d.ts +2 -0
  341. package/dist/web/open_browser.d.ts.map +1 -0
  342. package/dist/web/open_browser.js +42 -0
  343. package/dist/web/open_browser.js.map +1 -0
  344. package/dist/web/server.d.ts +54 -0
  345. package/dist/web/server.d.ts.map +1 -0
  346. package/dist/web/server.js +831 -0
  347. package/dist/web/server.js.map +1 -0
  348. package/dist/web/static/app.js +4121 -0
  349. package/dist/web/static/index.html +2281 -0
  350. package/dist/web/static/js/MODULE_SUMMARY.md +124 -0
  351. package/dist/web/static/js/a11y.js +165 -0
  352. package/dist/web/static/js/admin.js +2145 -0
  353. package/dist/web/static/js/assistant.js +475 -0
  354. package/dist/web/static/js/calendar/reminders.js +114 -0
  355. package/dist/web/static/js/calendar/utils.js +166 -0
  356. package/dist/web/static/js/calendar.js +3348 -0
  357. package/dist/web/static/js/censor.js +356 -0
  358. package/dist/web/static/js/chat.js +4546 -0
  359. package/dist/web/static/js/chatRenderer.js +2294 -0
  360. package/dist/web/static/js/chatStream.js +276 -0
  361. package/dist/web/static/js/codeRunner.js +398 -0
  362. package/dist/web/static/js/color/hex.js +14 -0
  363. package/dist/web/static/js/colorPicker.js +453 -0
  364. package/dist/web/static/js/compare/icons.js +77 -0
  365. package/dist/web/static/js/compare/index.js +1482 -0
  366. package/dist/web/static/js/compare/models.js +104 -0
  367. package/dist/web/static/js/compare/panes.js +817 -0
  368. package/dist/web/static/js/compare/probe.js +78 -0
  369. package/dist/web/static/js/compare/scoreboard.js +223 -0
  370. package/dist/web/static/js/compare/selector.js +1335 -0
  371. package/dist/web/static/js/compare/state.js +58 -0
  372. package/dist/web/static/js/compare/stream.js +695 -0
  373. package/dist/web/static/js/compare/vote.js +254 -0
  374. package/dist/web/static/js/cookbook-diagnosis.js +694 -0
  375. package/dist/web/static/js/cookbook-hwfit.js +1888 -0
  376. package/dist/web/static/js/cookbook.js +2093 -0
  377. package/dist/web/static/js/cookbookDownload.js +633 -0
  378. package/dist/web/static/js/cookbookProgressSignal.js +29 -0
  379. package/dist/web/static/js/cookbookRunning.js +3506 -0
  380. package/dist/web/static/js/cookbookServe.js +2128 -0
  381. package/dist/web/static/js/document.js +9731 -0
  382. package/dist/web/static/js/documentLibrary.js +3376 -0
  383. package/dist/web/static/js/dragSort.js +265 -0
  384. package/dist/web/static/js/editor/ai-inpaint.js +374 -0
  385. package/dist/web/static/js/editor/ai-models.js +273 -0
  386. package/dist/web/static/js/editor/ai-rembg.js +230 -0
  387. package/dist/web/static/js/editor/ai-tool-runner.js +147 -0
  388. package/dist/web/static/js/editor/ai-tools-misc.js +216 -0
  389. package/dist/web/static/js/editor/build/controls.js +366 -0
  390. package/dist/web/static/js/editor/build/popups.js +112 -0
  391. package/dist/web/static/js/editor/build/right-panel.js +200 -0
  392. package/dist/web/static/js/editor/build/toolbar.js +73 -0
  393. package/dist/web/static/js/editor/build/topbar.js +131 -0
  394. package/dist/web/static/js/editor/build/transform-popup.js +109 -0
  395. package/dist/web/static/js/editor/canvas-coords.js +21 -0
  396. package/dist/web/static/js/editor/canvas-events.js +197 -0
  397. package/dist/web/static/js/editor/canvas-transforms.js +132 -0
  398. package/dist/web/static/js/editor/checkerboard.js +24 -0
  399. package/dist/web/static/js/editor/clipboard-and-drop.js +133 -0
  400. package/dist/web/static/js/editor/composite-helpers.js +83 -0
  401. package/dist/web/static/js/editor/filters/blur.js +118 -0
  402. package/dist/web/static/js/editor/filters/edge-feather.js +70 -0
  403. package/dist/web/static/js/editor/fx/adj-popup.js +677 -0
  404. package/dist/web/static/js/editor/fx/filter-string.js +38 -0
  405. package/dist/web/static/js/editor/fx/histogram.js +67 -0
  406. package/dist/web/static/js/editor/fx/pixel-pass.js +249 -0
  407. package/dist/web/static/js/editor/harmonize-masks.js +116 -0
  408. package/dist/web/static/js/editor/history-panel.js +176 -0
  409. package/dist/web/static/js/editor/keyboard-shortcuts.js +271 -0
  410. package/dist/web/static/js/editor/layer-helpers.js +131 -0
  411. package/dist/web/static/js/editor/layer-panel.js +600 -0
  412. package/dist/web/static/js/editor/mask-utils.js +91 -0
  413. package/dist/web/static/js/editor/shortcuts-popover.js +149 -0
  414. package/dist/web/static/js/editor/slider-ux.js +191 -0
  415. package/dist/web/static/js/editor/snap.js +107 -0
  416. package/dist/web/static/js/editor/state.js +257 -0
  417. package/dist/web/static/js/editor/stroke-pipeline.js +162 -0
  418. package/dist/web/static/js/editor/stroke-tool-sliders.js +64 -0
  419. package/dist/web/static/js/editor/tools/clone.js +81 -0
  420. package/dist/web/static/js/editor/tools/crop.js +137 -0
  421. package/dist/web/static/js/editor/tools/flood-fill.js +72 -0
  422. package/dist/web/static/js/editor/tools/lasso-mask.js +171 -0
  423. package/dist/web/static/js/editor/tools/lasso.js +65 -0
  424. package/dist/web/static/js/editor/tools/move.js +79 -0
  425. package/dist/web/static/js/editor/tools/stroke.js +123 -0
  426. package/dist/web/static/js/editor/tools/transform-drag.js +174 -0
  427. package/dist/web/static/js/editor/tools/transform-handles.js +271 -0
  428. package/dist/web/static/js/editor/tools/transform-session.js +381 -0
  429. package/dist/web/static/js/editor/tools/wand.js +46 -0
  430. package/dist/web/static/js/editor/wire-import.js +148 -0
  431. package/dist/web/static/js/editor/wire-inpaint-controls.js +164 -0
  432. package/dist/web/static/js/editor/wire-merge-buttons.js +103 -0
  433. package/dist/web/static/js/editor/wire-selection-controls.js +170 -0
  434. package/dist/web/static/js/editor/wire-topbar-menus.js +174 -0
  435. package/dist/web/static/js/editor/wire-topbar-overflow.js +49 -0
  436. package/dist/web/static/js/editor/wire-topbar.js +188 -0
  437. package/dist/web/static/js/emailInbox.js +1245 -0
  438. package/dist/web/static/js/emailLibrary/replyRecipients.js +27 -0
  439. package/dist/web/static/js/emailLibrary/signatureFold.js +339 -0
  440. package/dist/web/static/js/emailLibrary/state.js +34 -0
  441. package/dist/web/static/js/emailLibrary/utils.js +202 -0
  442. package/dist/web/static/js/emailLibrary.js +5217 -0
  443. package/dist/web/static/js/emojiPicker.js +311 -0
  444. package/dist/web/static/js/escMenuStack.js +102 -0
  445. package/dist/web/static/js/fileHandler.js +295 -0
  446. package/dist/web/static/js/gallery.js +2835 -0
  447. package/dist/web/static/js/galleryEditor.js +3798 -0
  448. package/dist/web/static/js/group.js +955 -0
  449. package/dist/web/static/js/init.js +405 -0
  450. package/dist/web/static/js/keyboard-shortcuts.js +292 -0
  451. package/dist/web/static/js/langIcons.js +187 -0
  452. package/dist/web/static/js/markdown/tableRow.js +19 -0
  453. package/dist/web/static/js/markdown.js +806 -0
  454. package/dist/web/static/js/memory.js +1418 -0
  455. package/dist/web/static/js/modalManager.js +1552 -0
  456. package/dist/web/static/js/modalSnap.js +782 -0
  457. package/dist/web/static/js/model/matchKey.js +19 -0
  458. package/dist/web/static/js/modelPicker.js +695 -0
  459. package/dist/web/static/js/modelSort.js +33 -0
  460. package/dist/web/static/js/models.js +642 -0
  461. package/dist/web/static/js/notes.js +5054 -0
  462. package/dist/web/static/js/package.json +1 -0
  463. package/dist/web/static/js/platform.js +47 -0
  464. package/dist/web/static/js/presets.js +1110 -0
  465. package/dist/web/static/js/providers.js +93 -0
  466. package/dist/web/static/js/rag.js +177 -0
  467. package/dist/web/static/js/research/jobs.js +335 -0
  468. package/dist/web/static/js/research/panel.js +1233 -0
  469. package/dist/web/static/js/researchSynapse.js +225 -0
  470. package/dist/web/static/js/search-chat.js +201 -0
  471. package/dist/web/static/js/search.js +52 -0
  472. package/dist/web/static/js/section-management.js +260 -0
  473. package/dist/web/static/js/sessions.js +3108 -0
  474. package/dist/web/static/js/settings.js +4991 -0
  475. package/dist/web/static/js/sidebar-layout.js +573 -0
  476. package/dist/web/static/js/signature.js +504 -0
  477. package/dist/web/static/js/skills.js +1908 -0
  478. package/dist/web/static/js/slashAutocomplete.js +267 -0
  479. package/dist/web/static/js/slashCommands.js +6099 -0
  480. package/dist/web/static/js/spinner.js +406 -0
  481. package/dist/web/static/js/storage.js +123 -0
  482. package/dist/web/static/js/tasks.js +2699 -0
  483. package/dist/web/static/js/theme.js +2086 -0
  484. package/dist/web/static/js/tileManager.js +386 -0
  485. package/dist/web/static/js/tourAutoplay.js +133 -0
  486. package/dist/web/static/js/tourHints.js +179 -0
  487. package/dist/web/static/js/tts-ai.js +521 -0
  488. package/dist/web/static/js/ui.js +1288 -0
  489. package/dist/web/static/js/util/ordinal.js +13 -0
  490. package/dist/web/static/js/voiceRecorder.js +283 -0
  491. package/dist/web/static/js/windowDrag.js +326 -0
  492. package/dist/web/static/js/windowResize.js +233 -0
  493. package/dist/web/static/landing.html +824 -0
  494. package/dist/web/static/lib/docx.umd.min.js +20116 -0
  495. package/dist/web/static/lib/highlight.min.js +1213 -0
  496. package/dist/web/static/lib/html2pdf.bundle.min.js +3 -0
  497. package/dist/web/static/lib/mammoth.browser.min.js +21 -0
  498. package/dist/web/static/lib/qrcode.min.js +8 -0
  499. package/dist/web/static/lib/xlsx.full.min.js +24 -0
  500. package/dist/web/static/login.html +582 -0
  501. package/dist/web/static/manifest.json +15 -0
  502. package/dist/web/static/style.css +35733 -0
  503. package/dist/web/static/sw.js +144 -0
  504. package/dist/workflows/engine.d.ts +162 -0
  505. package/dist/workflows/engine.d.ts.map +1 -0
  506. package/dist/workflows/engine.js +625 -0
  507. package/dist/workflows/engine.js.map +1 -0
  508. package/dist/workflows/index.d.ts +8 -0
  509. package/dist/workflows/index.d.ts.map +1 -0
  510. package/dist/workflows/index.js +14 -0
  511. package/dist/workflows/index.js.map +1 -0
  512. package/package.json +112 -0
@@ -0,0 +1,677 @@
1
+ /**
2
+ * FX / adjustment-popup machinery — the per-layer Brightness/Contrast,
3
+ * Hue/Saturation, Levels, and Color-Balance editor.
4
+ *
5
+ * Self-contained subsystem with three external touchpoints:
6
+ *
7
+ * - `composite()` redraw the canvas after every staged change
8
+ * - `saveState(label)` push an undo entry on Apply
9
+ * - `renderLayerPanel()` refresh the layer panel after add/edit
10
+ *
11
+ * Lifecycle:
12
+ *
13
+ * FX button on layer row → openFxPopup(layer, anchor)
14
+ * → small chooser menu (B/C, H/S, Levels, Color Balance)
15
+ * → openAdjPopup(layer, type, anchor[, existingAdj])
16
+ * → buildAdjBody renders the type-specific sliders + histogram
17
+ * → sliders / histogram handles mutate `layer._stagedAdj.params`
18
+ * → composite() previews live via the adjLayers stack
19
+ * → Apply commits to layer.adjLayers + saveState() + renderLayerPanel()
20
+ * → Cancel / Esc drops the staged state
21
+ *
22
+ * Popups can be minimised → modalManager dock chip → click chip to
23
+ * restore. Re-opening a committed sub-layer (from the layer panel's
24
+ * adj-row click) calls `editAdjLayer` which re-opens openAdjPopup
25
+ * with the existing sub-layer's params staged for editing.
26
+ *
27
+ * @param {{
28
+ * composite: () => void,
29
+ * saveState: (label?: string) => void,
30
+ * renderLayerPanel: () => void,
31
+ * }} deps
32
+ *
33
+ * @returns {{
34
+ * openFxPopup, openAdjPopup, editAdjLayer,
35
+ * closeFxPopup, closeFxMenu, closeAdjPopup,
36
+ * ensureFxDock, ensureAdjustments,
37
+ * syncFxPanelToActiveLayerIfPresent,
38
+ * minimiseAdjPopup,
39
+ * }}
40
+ */
41
+ import { state } from '../state.js';
42
+ import modalManager from '../../modalManager.js';
43
+ import {
44
+ ADJ_ICONS,
45
+ adjLayerLabel,
46
+ defaultAdjParams,
47
+ } from '../layer-helpers.js';
48
+ import { drawHistogram } from './histogram.js';
49
+
50
+ export function createAdjPopupSystem({ composite, saveState, renderLayerPanel }) {
51
+ function suppressLayerGhostTap() {
52
+ window.__geSuppressLayerTapUntil = Date.now() + 650;
53
+ }
54
+
55
+ function closeFxPopup() {
56
+ if (state.fxPopupEl) {
57
+ state.fxPopupEl.remove();
58
+ state.fxPopupEl = null;
59
+ state.fxPopupLayerId = null;
60
+ }
61
+ }
62
+
63
+ function ensureAdjustments(layer) {
64
+ // Older layers (loaded from saved projects) may be missing the
65
+ // adjustments structure entirely. Pad with identity values.
66
+ if (!layer.adjustments) layer.adjustments = {};
67
+ const a = layer.adjustments;
68
+ if (a.brightness === undefined) a.brightness = 1;
69
+ if (a.contrast === undefined) a.contrast = 1;
70
+ if (a.saturation === undefined) a.saturation = 1;
71
+ if (a.hue === undefined) a.hue = 0;
72
+ if (!a.levels) a.levels = { inBlack: 0, inWhite: 255, gamma: 1.0, outBlack: 0, outWhite: 255 };
73
+ if (!a.colorBalance) a.colorBalance = {
74
+ shadows: { r: 0, g: 0, b: 0 },
75
+ midtones: { r: 0, g: 0, b: 0 },
76
+ highlights: { r: 0, g: 0, b: 0 },
77
+ };
78
+ return a;
79
+ }
80
+
81
+ // Floating dock for minimised FX popups — lives at bottom-right.
82
+ function ensureFxDock() {
83
+ let dock = document.getElementById('ge-fx-dock');
84
+ if (!dock) {
85
+ dock = document.createElement('div');
86
+ dock.id = 'ge-fx-dock';
87
+ document.body.appendChild(dock);
88
+ }
89
+ return dock;
90
+ }
91
+
92
+ function closeFxMenu() {
93
+ if (state.fxMenuEl) {
94
+ if (state.fxMenuEl._escHandler) {
95
+ document.removeEventListener('keydown', state.fxMenuEl._escHandler, true);
96
+ }
97
+ if (state.fxMenuEl._awayHandler) {
98
+ document.removeEventListener('pointerdown', state.fxMenuEl._awayHandler, true);
99
+ }
100
+ state.fxMenuEl.remove();
101
+ state.fxMenuEl = null;
102
+ }
103
+ document.getElementById('ge-fx-menu-backdrop')?.remove();
104
+ }
105
+
106
+ function openFxPopup(layer, anchorEl) {
107
+ // Toggle off ONLY if a menu for this layer is genuinely on-screen.
108
+ // `state` is a shared singleton that survives editor close/reopen,
109
+ // so a stale `fxMenuEl` from a previous session (whose detached
110
+ // element still carries a now-recycled `_layerId`) used to make
111
+ // this guard fire and silently swallow the first click. Verify the
112
+ // element is still in the document before treating it as "open".
113
+ if (state.fxMenuEl && document.body.contains(state.fxMenuEl) &&
114
+ state.fxMenuEl._layerId === layer.id) { closeFxMenu(); return; }
115
+ closeFxMenu();
116
+ if (!layer.adjLayers) layer.adjLayers = [];
117
+ const backdrop = document.createElement('div');
118
+ backdrop.id = 'ge-fx-menu-backdrop';
119
+ backdrop.style.cssText = 'position:fixed;inset:0;z-index:10001;background:transparent;pointer-events:auto;touch-action:none;';
120
+ document.body.appendChild(backdrop);
121
+ backdrop.addEventListener('pointerdown', (ev) => {
122
+ ev.preventDefault();
123
+ ev.stopPropagation();
124
+ closeFxMenu();
125
+ }, true);
126
+ backdrop.addEventListener('click', (ev) => {
127
+ ev.preventDefault();
128
+ ev.stopPropagation();
129
+ }, true);
130
+ const menu = document.createElement('div');
131
+ menu.className = 'ge-fx-menu ge-frosted';
132
+ menu._layerId = layer.id;
133
+ menu._ignoreActivationUntil = Date.now() + 350;
134
+ menu.style.zIndex = '10002';
135
+ menu.style.pointerEvents = 'auto';
136
+ const items = [
137
+ { type: 'brightness-contrast', label: 'Brightness / Contrast' },
138
+ { type: 'hue-saturation', label: 'Hue / Saturation' },
139
+ { type: 'levels', label: 'Levels' },
140
+ { type: 'color-balance', label: 'Color Balance' },
141
+ ];
142
+ menu.innerHTML = items.map(i =>
143
+ `<button class="ge-fx-menu-item" data-fx-type="${i.type}"><span class="ge-fx-menu-icon">${ADJ_ICONS[i.type] || ''}</span><span>${i.label}</span></button>`
144
+ ).join('');
145
+ document.body.appendChild(menu);
146
+ state.fxMenuEl = menu;
147
+ const activateMenuItem = (btn, ev) => {
148
+ ev?.preventDefault?.();
149
+ ev?.stopPropagation?.();
150
+ if (Date.now() < (menu._ignoreActivationUntil || 0)) return;
151
+ if (!btn || btn.dataset.opening === '1') return;
152
+ btn.dataset.opening = '1';
153
+ const type = btn.dataset.fxType;
154
+ closeFxMenu();
155
+ openAdjPopup(layer, type, anchorEl);
156
+ };
157
+ menu.addEventListener('pointerdown', (ev) => {
158
+ ev.stopPropagation();
159
+ }, true);
160
+ menu.addEventListener('pointerup', (ev) => {
161
+ const btn = ev.target.closest('.ge-fx-menu-item');
162
+ if (btn) activateMenuItem(btn, ev);
163
+ else ev.stopPropagation();
164
+ }, true);
165
+ menu.addEventListener('click', (ev) => {
166
+ const btn = ev.target.closest('.ge-fx-menu-item');
167
+ if (btn) activateMenuItem(btn, ev);
168
+ else ev.stopPropagation();
169
+ }, true);
170
+
171
+ const isMobile = window.matchMedia('(max-width: 820px)').matches;
172
+ const r = isMobile ? null : anchorEl?.getBoundingClientRect?.();
173
+ if (isMobile) {
174
+ menu.style.left = '';
175
+ menu.style.top = '';
176
+ menu.style.right = '';
177
+ menu.style.bottom = '';
178
+ } else if (r) {
179
+ const menuW = 220;
180
+ const menuH = menu.offsetHeight || 200;
181
+ const rightX = r.right + 4;
182
+ const leftX = r.left - menuW - 4;
183
+ const fitsRight = rightX + menuW <= window.innerWidth - 8;
184
+ let left = fitsRight ? rightX : Math.max(8, leftX);
185
+ left = Math.min(window.innerWidth - menuW - 8, Math.max(8, left));
186
+ menu.style.left = left + 'px';
187
+ let top = r.top;
188
+ if (top + menuH > window.innerHeight - 8) top = r.bottom - menuH;
189
+ top = Math.min(window.innerHeight - menuH - 8, Math.max(8, top));
190
+ menu.style.top = top + 'px';
191
+ }
192
+ menu.querySelectorAll('.ge-fx-menu-item').forEach(btn => {
193
+ const activate = (ev) => {
194
+ activateMenuItem(btn, ev);
195
+ };
196
+ btn.addEventListener('pointerup', activate);
197
+ btn.addEventListener('click', activate);
198
+ });
199
+ // Esc closes the menu, capture-phase + stopPropagation so the
200
+ // gallery modal's own Esc handler doesn't fire too.
201
+ const onKey = (ev) => {
202
+ if (ev.key === 'Escape') {
203
+ ev.preventDefault();
204
+ ev.stopPropagation();
205
+ closeFxMenu();
206
+ document.removeEventListener('keydown', onKey, true);
207
+ }
208
+ };
209
+ document.addEventListener('keydown', onKey, true);
210
+ menu._escHandler = onKey;
211
+ }
212
+
213
+ // Hide an adj popup and drop a chip into the FX dock. Click the chip
214
+ // to restore the popup in its previous position with staged state
215
+ // intact (we do NOT clear staged on minimise).
216
+ function minimiseAdjPopup(pop) {
217
+ if (!pop) return;
218
+ const type = pop._type;
219
+ const r = pop.getBoundingClientRect();
220
+ pop._stashLeft = r.left;
221
+ pop._stashTop = r.top;
222
+ pop.style.display = 'none';
223
+ if (state.adjPopupEl === pop) state.adjPopupEl = null;
224
+ const popupId = pop._modalId || `ge-fx-popup-${Math.random().toString(36).slice(2, 8)}`;
225
+ pop._modalId = popupId;
226
+ modalManager.register(popupId, {
227
+ label: adjLayerLabel(type),
228
+ icon: ADJ_ICONS[type] || '',
229
+ restoreFn: () => {
230
+ pop.style.left = pop._stashLeft + 'px';
231
+ pop.style.top = pop._stashTop + 'px';
232
+ pop.style.display = '';
233
+ if (state.adjPopupEl && state.adjPopupEl !== pop) {
234
+ const other = state.adjPopupEl;
235
+ state.adjPopupEl = other;
236
+ closeAdjPopup();
237
+ }
238
+ state.adjPopupEl = pop;
239
+ },
240
+ closeFn: () => {
241
+ state.adjPopupEl = pop;
242
+ closeAdjPopup();
243
+ modalManager.unregister(popupId);
244
+ },
245
+ });
246
+ modalManager.minimize(popupId);
247
+ }
248
+
249
+ // Re-open an existing committed adjustment sub-layer for editing.
250
+ // Pre-loads its params as the staged state; Apply updates in place.
251
+ function editAdjLayer(layer, adj, anchorEl) {
252
+ openAdjPopup(layer, adj.type, anchorEl, adj);
253
+ }
254
+
255
+ function closeAdjPopup() {
256
+ if (state.adjPopupEl) {
257
+ suppressLayerGhostTap();
258
+ const layer = state.adjPopupEl._layer;
259
+ if (layer) {
260
+ if (layer._stagedAdj) layer._stagedAdj = null;
261
+ if (layer._editingAdjId) layer._editingAdjId = null;
262
+ layer._adjFinalKey = null;
263
+ composite();
264
+ }
265
+ if (state.adjPopupEl._escHandler) {
266
+ document.removeEventListener('keydown', state.adjPopupEl._escHandler, true);
267
+ }
268
+ if (state.adjPopupEl._modalId) {
269
+ try { modalManager.unregister(state.adjPopupEl._modalId); } catch {}
270
+ }
271
+ state.adjPopupEl.remove();
272
+ state.adjPopupEl = null;
273
+ }
274
+ }
275
+
276
+ function openAdjPopup(layer, type, anchorEl, existingAdj) {
277
+ closeAdjPopup();
278
+ // Editing an existing sub-layer? Pre-load its params as the staged
279
+ // preview and mark the popup so Apply updates instead of appending.
280
+ const editing = !!existingAdj;
281
+ const startParams = editing
282
+ ? JSON.parse(JSON.stringify(existingAdj.params))
283
+ : defaultAdjParams(type);
284
+ layer._stagedAdj = { type, params: startParams };
285
+ if (editing) {
286
+ // Hide the existing sub-layer from the render stack so the
287
+ // staged preview shows correctly without doubling the effect.
288
+ layer._editingAdjId = existingAdj.id;
289
+ layer._adjFinalKey = null;
290
+ }
291
+ const pop = document.createElement('div');
292
+ pop.className = 'ge-adj-popup ge-frosted';
293
+ pop.style.zIndex = '10003';
294
+ pop._layer = layer;
295
+ pop._type = type;
296
+ pop._anchorEl = anchorEl;
297
+ pop._existingAdj = existingAdj || null;
298
+ pop.innerHTML = `
299
+ <div class="ge-adj-head" data-adj-drag>
300
+ <span class="ge-adj-icon">${ADJ_ICONS[type] || ''}</span>
301
+ <span class="ge-adj-title">${adjLayerLabel(type)}</span>
302
+ <span class="ge-head-btns">
303
+ <button class="ge-adj-min" type="button" title="Minimise">&minus;</button>
304
+ </span>
305
+ </div>
306
+ <div class="ge-adj-body" data-adj-body></div>
307
+ <div class="ge-adj-foot">
308
+ <button class="ge-btn ge-btn-sm ge-adj-cancel-btn" data-adj-action="cancel">Cancel</button>
309
+ <button class="ge-btn ge-btn-sm ge-btn-primary ge-adj-apply-btn" data-adj-action="ok">Apply</button>
310
+ </div>
311
+ `;
312
+ document.body.appendChild(pop);
313
+ state.adjPopupEl = pop;
314
+
315
+ const r = anchorEl?.getBoundingClientRect?.();
316
+ const pw = type === 'color-balance' ? 340 : 320;
317
+ // Prefer right of anchor; fall back to left if no room.
318
+ let left;
319
+ if (r) {
320
+ const rightX = r.right + 8;
321
+ const leftX = r.left - pw - 8;
322
+ const fitsRight = rightX + pw <= window.innerWidth - 8;
323
+ left = fitsRight ? rightX : Math.max(8, leftX);
324
+ } else {
325
+ left = (window.innerWidth - pw) / 2;
326
+ }
327
+ const top = r ? Math.max(8, r.top - 20) : 60;
328
+ pop.style.left = left + 'px';
329
+ pop.style.top = top + 'px';
330
+
331
+ const body = pop.querySelector('[data-adj-body]');
332
+ buildAdjBody(layer, type, body, pop);
333
+
334
+ pop.querySelector('.ge-adj-close')?.addEventListener('click', closeAdjPopup);
335
+ pop.querySelector('.ge-adj-min')?.addEventListener('click', () => minimiseAdjPopup(pop));
336
+ // Drag by head — anywhere except buttons. Mobile pins via !important
337
+ // rules; setProperty with 'important' lets inline styles win during drag.
338
+ const head = pop.querySelector('[data-adj-drag]');
339
+ if (head) {
340
+ const isMobile = window.matchMedia('(max-width: 820px)').matches;
341
+ const setPos = (x, y) => {
342
+ if (isMobile) {
343
+ pop.style.setProperty('left', x + 'px', 'important');
344
+ pop.style.setProperty('top', y + 'px', 'important');
345
+ pop.style.setProperty('right', 'auto', 'important');
346
+ pop.style.setProperty('bottom', 'auto', 'important');
347
+ pop.style.setProperty('width', 'auto', 'important');
348
+ pop.style.setProperty('max-width', 'calc(100vw - 16px)', 'important');
349
+ } else {
350
+ pop.style.left = x + 'px';
351
+ pop.style.top = y + 'px';
352
+ }
353
+ };
354
+ head.style.touchAction = 'none';
355
+ head.addEventListener('pointerdown', (e) => {
356
+ if (e.target.closest('button')) return;
357
+ e.preventDefault();
358
+ const startX = e.clientX, startY = e.clientY;
359
+ const r0 = pop.getBoundingClientRect();
360
+ head.setPointerCapture(e.pointerId);
361
+ head.style.cursor = 'grabbing';
362
+ const onMove = (ev) => {
363
+ const nx = Math.max(0, Math.min(window.innerWidth - 60, r0.left + (ev.clientX - startX)));
364
+ const ny = Math.max(0, Math.min(window.innerHeight - 30, r0.top + (ev.clientY - startY)));
365
+ setPos(nx, ny);
366
+ };
367
+ const onUp = () => {
368
+ head.releasePointerCapture(e.pointerId);
369
+ head.style.cursor = '';
370
+ head.removeEventListener('pointermove', onMove);
371
+ head.removeEventListener('pointerup', onUp);
372
+ };
373
+ head.addEventListener('pointermove', onMove);
374
+ head.addEventListener('pointerup', onUp);
375
+ });
376
+ }
377
+ // Esc closes; capture-phase + stopPropagation so the gallery modal's
378
+ // own Esc handler doesn't fire too.
379
+ const onKey = (ev) => {
380
+ if (ev.key === 'Escape') {
381
+ ev.preventDefault();
382
+ ev.stopPropagation();
383
+ closeAdjPopup();
384
+ document.removeEventListener('keydown', onKey, true);
385
+ }
386
+ };
387
+ document.addEventListener('keydown', onKey, true);
388
+ pop._escHandler = onKey;
389
+ pop.querySelector('[data-adj-action="cancel"]')?.addEventListener('click', (e) => {
390
+ e.preventDefault();
391
+ e.stopPropagation();
392
+ closeAdjPopup();
393
+ });
394
+ pop.querySelector('[data-adj-action="ok"]')?.addEventListener('click', (e) => {
395
+ e.preventDefault();
396
+ e.stopPropagation();
397
+ suppressLayerGhostTap();
398
+ saveState(editing ? `Edit ${adjLayerLabel(type)}` : `Add ${adjLayerLabel(type)}`);
399
+ const params = layer._stagedAdj.params;
400
+ layer._stagedAdj = null;
401
+ if (editing) {
402
+ const existing = (layer.adjLayers || []).find(a => a.id === existingAdj.id);
403
+ if (existing) existing.params = params;
404
+ layer._editingAdjId = null;
405
+ } else {
406
+ if (!layer.adjLayers) layer.adjLayers = [];
407
+ layer.adjLayers.push({
408
+ id: 'adj-' + Math.random().toString(36).slice(2, 9),
409
+ type,
410
+ name: adjLayerLabel(type),
411
+ visible: true,
412
+ opacity: 1,
413
+ params,
414
+ });
415
+ }
416
+ layer._adjFinalKey = null;
417
+ composite();
418
+ renderLayerPanel();
419
+ closeAdjPopup();
420
+ });
421
+ }
422
+
423
+ // rAF-throttled live preview while sliders are dragged.
424
+ function scheduleAdjRefresh(layer) {
425
+ if (state.adjRafPending) return;
426
+ state.adjRafPending = true;
427
+ requestAnimationFrame(() => {
428
+ state.adjRafPending = false;
429
+ layer._adjFinalKey = null;
430
+ composite();
431
+ });
432
+ }
433
+
434
+ function buildAdjBody(layer, type, body, popEl) {
435
+ const p = layer._stagedAdj.params;
436
+ const revertIcon = '<svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="1 4 1 10 7 10"/><path d="M3.51 15a9 9 0 1 0 2.13-9.36L1 10"/></svg>';
437
+ const sliderRow = (key, label, min, max, value, suffix) => `
438
+ <div class="ge-adj-row" data-adj-key="${key}">
439
+ <label>${label}</label>
440
+ <input type="range" min="${min}" max="${max}" value="${value}" data-key="${key}" />
441
+ <span class="ge-adj-value">${value}${suffix || ''}</span>
442
+ <button class="ge-adj-revert" type="button" title="Reset this slider" data-revert-key="${key}">${revertIcon}</button>
443
+ </div>
444
+ `;
445
+ if (type === 'brightness-contrast') {
446
+ const bSlider = Math.round((p.brightness - 1) * 100);
447
+ const cSlider = Math.round((p.contrast - 1) * 100);
448
+ body.innerHTML = `
449
+ ${sliderRow('brightness', 'Brightness', -100, 100, bSlider, '')}
450
+ ${sliderRow('contrast', 'Contrast', -100, 100, cSlider, '')}
451
+ `;
452
+ } else if (type === 'hue-saturation') {
453
+ const hSlider = Math.round(p.hue);
454
+ const sSlider = Math.round((p.saturation - 1) * 100);
455
+ body.innerHTML = `
456
+ ${sliderRow('hue', 'Hue', -180, 180, hSlider, ' °')}
457
+ ${sliderRow('saturation', 'Saturation', -100, 100, sSlider, '')}
458
+ `;
459
+ } else if (type === 'levels') {
460
+ // Histogram canvas + sliders. Histogram is computed from the
461
+ // layer's pixel data (after any adjLayers below this one) so
462
+ // the user is matching levels against what they're really seeing.
463
+ // <details> wrapper is collapsed by default on mobile to save
464
+ // vertical space; open by default on desktop.
465
+ const isMobile = window.matchMedia('(max-width: 820px)').matches;
466
+ body.innerHTML = `
467
+ <details class="ge-adj-hist-details"${isMobile ? '' : ' open'}>
468
+ <summary>Histogram</summary>
469
+ <div class="ge-adj-hist-wrap">
470
+ <canvas class="ge-adj-histogram" width="280" height="80"></canvas>
471
+ <div class="ge-adj-hist-handles">
472
+ <div class="ge-adj-hist-handle hist-h-black" data-handle="inBlack" title="Input black — drag"></div>
473
+ <div class="ge-adj-hist-handle hist-h-gamma" data-handle="gamma" title="Gamma — drag"></div>
474
+ <div class="ge-adj-hist-handle hist-h-white" data-handle="inWhite" title="Input white — drag"></div>
475
+ </div>
476
+ </div>
477
+ </details>
478
+ ${sliderRow('inBlack', 'Input black', 0, 254, p.inBlack, '')}
479
+ ${sliderRow('inWhite', 'Input white', 1, 255, p.inWhite, '')}
480
+ ${sliderRow('gamma', 'Gamma', 10, 990, Math.round((p.gamma || 1) * 100), 'γ')}
481
+ ${sliderRow('outBlack', 'Output black', 0, 255, p.outBlack, '')}
482
+ ${sliderRow('outWhite', 'Output white', 0, 255, p.outWhite, '')}
483
+ `;
484
+ const hist = body.querySelector('.ge-adj-histogram');
485
+ drawHistogram(hist, layer);
486
+ wireHistogramHandles(body, layer, type);
487
+ // Redraw histogram when the user opens the disclosure (canvas
488
+ // dimensions are layout-dependent).
489
+ body.querySelector('.ge-adj-hist-details')?.addEventListener('toggle', (e) => {
490
+ if (e.target.open) drawHistogram(hist, layer);
491
+ });
492
+ } else if (type === 'color-balance') {
493
+ // Color-tinted slider ends so the user sees what direction does what.
494
+ const cbRow = (key, leftCol, rightCol, label, value) => `
495
+ <div class="ge-adj-row ge-adj-cb-row" data-adj-key="${key}">
496
+ <span class="ge-adj-cb-dot" style="background:${leftCol}"></span>
497
+ <input type="range" min="-100" max="100" value="${value}" data-key="${key}" />
498
+ <span class="ge-adj-cb-dot" style="background:${rightCol}"></span>
499
+ <span class="ge-adj-value">${value}</span>
500
+ <button class="ge-adj-revert" type="button" title="Reset this slider" data-revert-key="${key}">${revertIcon}</button>
501
+ </div>
502
+ `;
503
+ // Tone picker: one tone group visible at a time. Remember the
504
+ // last picked tone on the popup so re-renders (revert button
505
+ // etc.) keep it.
506
+ const tone = popEl._cbTone || 'shadows';
507
+ popEl._cbTone = tone;
508
+ const toneSliders = (t) => `
509
+ ${cbRow(`${t}-r`, '#00d2d2', '#ff5555', 'Cyan ↔ Red', p[t].r)}
510
+ ${cbRow(`${t}-g`, '#d855d8', '#55d855', 'Magenta ↔ Green', p[t].g)}
511
+ ${cbRow(`${t}-b`, '#e6e64a', '#4a78ff', 'Yellow ↔ Blue', p[t].b)}
512
+ `;
513
+ body.innerHTML = `
514
+ <div class="ge-adj-cb-tone-picker">
515
+ <select class="ge-adj-cb-tone-select">
516
+ <option value="shadows"${tone === 'shadows' ? ' selected' : ''}>Shadows</option>
517
+ <option value="midtones"${tone === 'midtones' ? ' selected' : ''}>Midtones</option>
518
+ <option value="highlights"${tone === 'highlights' ? ' selected' : ''}>Highlights</option>
519
+ </select>
520
+ </div>
521
+ <div class="ge-adj-cb-sliders" data-cb-tone="${tone}">
522
+ ${toneSliders(tone)}
523
+ </div>
524
+ `;
525
+ body.querySelector('.ge-adj-cb-tone-select')?.addEventListener('change', (e) => {
526
+ popEl._cbTone = e.target.value;
527
+ body.innerHTML = '';
528
+ buildAdjBody(layer, type, body, popEl);
529
+ });
530
+ }
531
+ // Wire all sliders.
532
+ body.querySelectorAll('input[type="range"]').forEach(sl => {
533
+ sl.addEventListener('input', () => onAdjSliderInput(layer, type, sl));
534
+ });
535
+ // Per-slider revert buttons.
536
+ body.querySelectorAll('.ge-adj-revert').forEach(btn => {
537
+ btn.addEventListener('click', (e) => {
538
+ e.stopPropagation();
539
+ const key = btn.dataset.revertKey;
540
+ revertAdjKey(layer, type, key);
541
+ // Rebuild body so values + histogram refresh.
542
+ body.innerHTML = '';
543
+ buildAdjBody(layer, type, body, popEl);
544
+ });
545
+ });
546
+ }
547
+
548
+ // Reset a single slider key back to identity. Updates staged params
549
+ // and triggers a composite refresh.
550
+ function revertAdjKey(layer, type, key) {
551
+ const defaults = defaultAdjParams(type);
552
+ const p = layer._stagedAdj.params;
553
+ if (type === 'brightness-contrast' || type === 'hue-saturation') {
554
+ p[key] = defaults[key];
555
+ } else if (type === 'levels') {
556
+ p[key] = defaults[key];
557
+ } else if (type === 'color-balance') {
558
+ const [tone, ch] = key.split('-');
559
+ p[tone][ch] = defaults[tone][ch];
560
+ }
561
+ layer._adjFinalKey = null;
562
+ composite();
563
+ }
564
+
565
+ function onAdjSliderInput(layer, type, sl) {
566
+ const key = sl.dataset.key;
567
+ const raw = parseInt(sl.value, 10);
568
+ const valEl = sl.parentElement.querySelector('.ge-adj-value');
569
+ const p = layer._stagedAdj.params;
570
+ let display = String(raw);
571
+ if (type === 'brightness-contrast' || type === 'hue-saturation') {
572
+ if (key === 'brightness' || key === 'contrast' || key === 'saturation') {
573
+ p[key] = 1 + raw / 100;
574
+ } else if (key === 'hue') {
575
+ p.hue = raw; display = raw + ' °';
576
+ }
577
+ } else if (type === 'levels') {
578
+ if (key === 'gamma') {
579
+ p.gamma = raw / 100; display = (raw / 100).toFixed(2) + 'γ';
580
+ } else {
581
+ p[key] = raw;
582
+ }
583
+ } else if (type === 'color-balance') {
584
+ const [tone, ch] = key.split('-');
585
+ p[tone][ch] = raw;
586
+ }
587
+ if (valEl) valEl.textContent = display;
588
+ scheduleAdjRefresh(layer);
589
+ }
590
+
591
+ // Position the three histogram triangle handles by current staged
592
+ // values + wire pointer drags.
593
+ function wireHistogramHandles(bodyEl, layer, type) {
594
+ const wrap = bodyEl.querySelector('.ge-adj-hist-wrap');
595
+ const canvas = bodyEl.querySelector('.ge-adj-histogram');
596
+ if (!wrap || !canvas) return;
597
+ const handles = bodyEl.querySelectorAll('.ge-adj-hist-handle');
598
+ const placeHandles = () => {
599
+ const w = canvas.getBoundingClientRect().width;
600
+ const p = layer._stagedAdj.params;
601
+ const xB = (p.inBlack / 255) * w;
602
+ const xW = (p.inWhite / 255) * w;
603
+ // Gamma handle sits at a fraction of the (xB..xW) span, mapped
604
+ // from gamma's log scale (1 = midpoint, 0.1 = far right, 10 = far left).
605
+ const gammaT = 1 - (Math.log(p.gamma || 1) / Math.log(10) * 0.5 + 0.5);
606
+ const xG = xB + (xW - xB) * gammaT;
607
+ const set = (sel, x) => {
608
+ const el = bodyEl.querySelector(sel);
609
+ if (el) el.style.left = (x - 6) + 'px';
610
+ };
611
+ set('.hist-h-black', xB);
612
+ set('.hist-h-gamma', xG);
613
+ set('.hist-h-white', xW);
614
+ };
615
+ placeHandles();
616
+ handles.forEach(h => {
617
+ h.addEventListener('pointerdown', (e) => {
618
+ e.preventDefault();
619
+ e.stopPropagation();
620
+ h.setPointerCapture(e.pointerId);
621
+ const which = h.dataset.handle;
622
+ const rect = canvas.getBoundingClientRect();
623
+ const onMove = (ev) => {
624
+ const x = Math.max(0, Math.min(rect.width, ev.clientX - rect.left));
625
+ const v = Math.round((x / rect.width) * 255);
626
+ const p = layer._stagedAdj.params;
627
+ if (which === 'inBlack') {
628
+ p.inBlack = Math.min(p.inWhite - 1, v);
629
+ } else if (which === 'inWhite') {
630
+ p.inWhite = Math.max(p.inBlack + 1, v);
631
+ } else if (which === 'gamma') {
632
+ const xB = (p.inBlack / 255) * rect.width;
633
+ const xW = (p.inWhite / 255) * rect.width;
634
+ const span = Math.max(1, xW - xB);
635
+ let t = (x - xB) / span;
636
+ t = Math.max(0.01, Math.min(0.99, t));
637
+ // Invert the placeHandles mapping: t = 1 - (log10(g)*0.5+0.5).
638
+ const log10g = -((t - 0.5) * 2);
639
+ p.gamma = Math.pow(10, log10g);
640
+ }
641
+ placeHandles();
642
+ // Update visible slider rows + value labels.
643
+ const updateRow = (key, displayVal) => {
644
+ const sl = bodyEl.querySelector(`input[type="range"][data-key="${key}"]`);
645
+ if (sl) sl.value = String(key === 'gamma' ? Math.round(layer._stagedAdj.params.gamma * 100) : layer._stagedAdj.params[key]);
646
+ const val = sl?.parentElement.querySelector('.ge-adj-value');
647
+ if (val) val.textContent = displayVal;
648
+ };
649
+ if (which === 'inBlack') updateRow('inBlack', String(layer._stagedAdj.params.inBlack));
650
+ if (which === 'inWhite') updateRow('inWhite', String(layer._stagedAdj.params.inWhite));
651
+ if (which === 'gamma') updateRow('gamma', layer._stagedAdj.params.gamma.toFixed(2) + 'γ');
652
+ drawHistogram(canvas, layer);
653
+ scheduleAdjRefresh(layer);
654
+ };
655
+ const onUp = () => {
656
+ h.releasePointerCapture(e.pointerId);
657
+ h.removeEventListener('pointermove', onMove);
658
+ h.removeEventListener('pointerup', onUp);
659
+ };
660
+ h.addEventListener('pointermove', onMove);
661
+ h.addEventListener('pointerup', onUp);
662
+ });
663
+ });
664
+ }
665
+
666
+ // Legacy sidebar-FX panel sync — FX now lives in a per-layer popup;
667
+ // stubbed so any stale callers don't error.
668
+ function syncFxPanelToActiveLayerIfPresent() { /* no-op */ }
669
+
670
+ return {
671
+ openFxPopup, openAdjPopup, editAdjLayer,
672
+ closeFxPopup, closeFxMenu, closeAdjPopup,
673
+ ensureFxDock, ensureAdjustments,
674
+ syncFxPanelToActiveLayerIfPresent,
675
+ minimiseAdjPopup,
676
+ };
677
+ }