@mindexec/cli 0.2.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 (232) hide show
  1. package/README.md +275 -0
  2. package/codex-runtime.js +960 -0
  3. package/launch-bridge.cjs +162 -0
  4. package/package.json +61 -0
  5. package/port-guard.cjs +232 -0
  6. package/scripts/setup-tree-sitter-grammars.mjs +59 -0
  7. package/server.js +8422 -0
  8. package/start-bridge.bat +32 -0
  9. package/start-bridge.sh +81 -0
  10. package/tree-sitter-grammars/README.md +18 -0
  11. package/tree-sitter-grammars/tree-sitter-c_sharp.wasm +0 -0
  12. package/tree-sitter-grammars/tree-sitter-go.wasm +0 -0
  13. package/tree-sitter-grammars/tree-sitter-java.wasm +0 -0
  14. package/tree-sitter-grammars/tree-sitter-javascript.wasm +0 -0
  15. package/tree-sitter-grammars/tree-sitter-python.wasm +0 -0
  16. package/tree-sitter-grammars/tree-sitter-rust.wasm +0 -0
  17. package/tree-sitter-grammars/tree-sitter-tsx.wasm +0 -0
  18. package/tree-sitter-grammars/tree-sitter-typescript.wasm +0 -0
  19. package/wwwroot/MindExecution.Web.styles.css +3 -0
  20. package/wwwroot/_content/MindExecution.Plugins.Admin/css/admin-dashboard.css +546 -0
  21. package/wwwroot/_content/MindExecution.Plugins.Directory/MindExecution.Plugins.Directory.u7utcng611.bundle.scp.css +7 -0
  22. package/wwwroot/_content/MindExecution.Plugins.Directory/background.png +0 -0
  23. package/wwwroot/_content/MindExecution.Plugins.Directory/directory-manager.js +202 -0
  24. package/wwwroot/_content/MindExecution.Plugins.Directory/exampleJsInterop.js +6 -0
  25. package/wwwroot/_content/MindExecution.Plugins.YouTube/css/youtube-search.css +251 -0
  26. package/wwwroot/_content/MindExecution.Shared/MindExecution.Shared.wsano1j4wp.bundle.scp.css +4 -0
  27. package/wwwroot/_content/MindExecution.Shared/css/admin-dashboard.css +559 -0
  28. package/wwwroot/_content/MindExecution.Shared/css/app.css +1 -0
  29. package/wwwroot/_content/MindExecution.Shared/css/mind-map-overrides.css +2936 -0
  30. package/wwwroot/_content/MindExecution.Shared/fonts/NotoSansKR-Bold.ttf +0 -0
  31. package/wwwroot/_content/MindExecution.Shared/fonts/NotoSansKR-Regular.ttf +0 -0
  32. package/wwwroot/_content/MindExecution.Shared/js/agent-visualization.js +359 -0
  33. package/wwwroot/_content/MindExecution.Shared/js/background-themes.js +1721 -0
  34. package/wwwroot/_content/MindExecution.Shared/js/code-master.js +8316 -0
  35. package/wwwroot/_content/MindExecution.Shared/js/file-system-helper.js +639 -0
  36. package/wwwroot/_content/MindExecution.Shared/js/helpers/InfiniteGridHelper.js +109 -0
  37. package/wwwroot/_content/MindExecution.Shared/js/marked.min.js +69 -0
  38. package/wwwroot/_content/MindExecution.Shared/js/mind-map-core.js +7982 -0
  39. package/wwwroot/_content/MindExecution.Shared/js/mind-map-core.js.backup +1059 -0
  40. package/wwwroot/_content/MindExecution.Shared/js/mind-map-css3d-manager.js +15803 -0
  41. package/wwwroot/_content/MindExecution.Shared/js/mind-map-dev-guards.js +325 -0
  42. package/wwwroot/_content/MindExecution.Shared/js/mind-map-dnd.js +1430 -0
  43. package/wwwroot/_content/MindExecution.Shared/js/mind-map-dnd.js.bak +434 -0
  44. package/wwwroot/_content/MindExecution.Shared/js/mind-map-glow-shader.js +260 -0
  45. package/wwwroot/_content/MindExecution.Shared/js/mind-map-interactions.js +7640 -0
  46. package/wwwroot/_content/MindExecution.Shared/js/mind-map-lod-plan-worker.js +160 -0
  47. package/wwwroot/_content/MindExecution.Shared/js/mind-map-lod-renderer.js +9923 -0
  48. package/wwwroot/_content/MindExecution.Shared/js/mind-map-logic-workers.js +977 -0
  49. package/wwwroot/_content/MindExecution.Shared/js/mind-map-menu-manager.js +1431 -0
  50. package/wwwroot/_content/MindExecution.Shared/js/mind-map-multi-select.js +1716 -0
  51. package/wwwroot/_content/MindExecution.Shared/js/mind-map-node-search-worker.js +553 -0
  52. package/wwwroot/_content/MindExecution.Shared/js/mind-map-nodes.js +4541 -0
  53. package/wwwroot/_content/MindExecution.Shared/js/mind-map-object-manager.js +489 -0
  54. package/wwwroot/_content/MindExecution.Shared/js/mind-map-object-manager.js.backup +372 -0
  55. package/wwwroot/_content/MindExecution.Shared/js/mind-map-pipeline.js +2075 -0
  56. package/wwwroot/_content/MindExecution.Shared/js/mind-map-text-lod-system.js +646 -0
  57. package/wwwroot/_content/MindExecution.Shared/js/mind-map-text-overlay-v2.js +4323 -0
  58. package/wwwroot/_content/MindExecution.Shared/js/mind-map-texture-factory.js +2260 -0
  59. package/wwwroot/_content/MindExecution.Shared/js/mind-map-texture-factory.js.backup +1258 -0
  60. package/wwwroot/_content/MindExecution.Shared/js/mind-map-visibility-worker.js +890 -0
  61. package/wwwroot/_content/MindExecution.Shared/js/mindmap-toolbar.js +594 -0
  62. package/wwwroot/_content/MindExecution.Shared/js/native-drop-handler.js +170 -0
  63. package/wwwroot/_content/MindExecution.Shared/js/plan-master.js +788 -0
  64. package/wwwroot/_content/MindExecution.Shared/js/renderers/CSS3DRenderer.js +50 -0
  65. package/wwwroot/_content/MindExecution.Shared/js/texture-worker-manager.js +188 -0
  66. package/wwwroot/_content/MindExecution.Shared/js/texture-worker.js +208 -0
  67. package/wwwroot/_content/MindExecution.Shared/js/three.min.js +6 -0
  68. package/wwwroot/_content/MindExecution.Shared/js/titlebar-handler.js +191 -0
  69. package/wwwroot/_content/MindExecution.Shared/js/token-manager.js +37 -0
  70. package/wwwroot/_content/MindExecution.Shared/js/token-worker.js +28 -0
  71. package/wwwroot/_content/MindExecution.Shared/js/troika-bundle.js +5626 -0
  72. package/wwwroot/_content/MindExecution.Shared/js/troika-bundle.js.map +7 -0
  73. package/wwwroot/_content/MindExecution.Shared/lib/font-awesome/css/all.min.css +9 -0
  74. package/wwwroot/_content/MindExecution.Shared/lib/font-awesome/webfonts/fa-brands-400.ttf +0 -0
  75. package/wwwroot/_content/MindExecution.Shared/lib/font-awesome/webfonts/fa-brands-400.woff2 +0 -0
  76. package/wwwroot/_content/MindExecution.Shared/lib/font-awesome/webfonts/fa-regular-400.ttf +0 -0
  77. package/wwwroot/_content/MindExecution.Shared/lib/font-awesome/webfonts/fa-regular-400.woff2 +0 -0
  78. package/wwwroot/_content/MindExecution.Shared/lib/font-awesome/webfonts/fa-solid-900.ttf +0 -0
  79. package/wwwroot/_content/MindExecution.Shared/lib/font-awesome/webfonts/fa-solid-900.woff2 +0 -0
  80. package/wwwroot/_content/MindExecution.Shared/models/all-MiniLM-L6-v2-quantized.onnx +0 -0
  81. package/wwwroot/_content/MindExecution.Shared/models/vocab.txt +30522 -0
  82. package/wwwroot/_framework/Google.Protobuf.9h59ukbel7.dll +0 -0
  83. package/wwwroot/_framework/Markdig.d1j7v41cl1.dll +0 -0
  84. package/wwwroot/_framework/MessagePack.Annotations.l6qv48kgpt.dll +0 -0
  85. package/wwwroot/_framework/MessagePack.eqoptzx9d5.dll +0 -0
  86. package/wwwroot/_framework/Microsoft.AspNetCore.Authorization.k7dsih5y5g.dll +0 -0
  87. package/wwwroot/_framework/Microsoft.AspNetCore.Components.6nyje9sa0g.dll +0 -0
  88. package/wwwroot/_framework/Microsoft.AspNetCore.Components.Authorization.iycd6unprw.dll +0 -0
  89. package/wwwroot/_framework/Microsoft.AspNetCore.Components.Web.487u3twia4.dll +0 -0
  90. package/wwwroot/_framework/Microsoft.AspNetCore.Components.WebAssembly.d0gcnmlxxz.dll +0 -0
  91. package/wwwroot/_framework/Microsoft.AspNetCore.Metadata.h4yevl9adi.dll +0 -0
  92. package/wwwroot/_framework/Microsoft.CSharp.qrvp77qmhs.dll +0 -0
  93. package/wwwroot/_framework/Microsoft.Data.Sqlite.jdlxgv2jtg.dll +0 -0
  94. package/wwwroot/_framework/Microsoft.EntityFrameworkCore.4gjazp7kjf.dll +0 -0
  95. package/wwwroot/_framework/Microsoft.EntityFrameworkCore.Abstractions.gocudnvz7b.dll +0 -0
  96. package/wwwroot/_framework/Microsoft.EntityFrameworkCore.Relational.lt4rsvinuo.dll +0 -0
  97. package/wwwroot/_framework/Microsoft.EntityFrameworkCore.Sqlite.69luj0fa9r.dll +0 -0
  98. package/wwwroot/_framework/Microsoft.Extensions.Caching.Abstractions.364t4jh3zz.dll +0 -0
  99. package/wwwroot/_framework/Microsoft.Extensions.Caching.Memory.izlxhpzosu.dll +0 -0
  100. package/wwwroot/_framework/Microsoft.Extensions.Configuration.8zq7hh41o7.dll +0 -0
  101. package/wwwroot/_framework/Microsoft.Extensions.Configuration.Abstractions.8if74zs6ea.dll +0 -0
  102. package/wwwroot/_framework/Microsoft.Extensions.Configuration.Json.duvlngw8i0.dll +0 -0
  103. package/wwwroot/_framework/Microsoft.Extensions.DependencyInjection.Abstractions.t2hh9kvx0o.dll +0 -0
  104. package/wwwroot/_framework/Microsoft.Extensions.DependencyInjection.n4tg99oy8l.dll +0 -0
  105. package/wwwroot/_framework/Microsoft.Extensions.DependencyModel.h0d06ixk3e.dll +0 -0
  106. package/wwwroot/_framework/Microsoft.Extensions.Logging.Abstractions.rl32bkx2sd.dll +0 -0
  107. package/wwwroot/_framework/Microsoft.Extensions.Logging.dlht1xei0t.dll +0 -0
  108. package/wwwroot/_framework/Microsoft.Extensions.Options.qeunebioml.dll +0 -0
  109. package/wwwroot/_framework/Microsoft.Extensions.Primitives.18cr6vnuuz.dll +0 -0
  110. package/wwwroot/_framework/Microsoft.IO.RecyclableMemoryStream.r915vovvw4.dll +0 -0
  111. package/wwwroot/_framework/Microsoft.IdentityModel.Abstractions.1ejljk3erv.dll +0 -0
  112. package/wwwroot/_framework/Microsoft.IdentityModel.JsonWebTokens.1596zr8gne.dll +0 -0
  113. package/wwwroot/_framework/Microsoft.IdentityModel.Logging.229uyvpgio.dll +0 -0
  114. package/wwwroot/_framework/Microsoft.IdentityModel.Tokens.9sibtajc9f.dll +0 -0
  115. package/wwwroot/_framework/Microsoft.JSInterop.17lq4j1j7g.dll +0 -0
  116. package/wwwroot/_framework/Microsoft.JSInterop.WebAssembly.ryia5gxiad.dll +0 -0
  117. package/wwwroot/_framework/Microsoft.ML.OnnxRuntime.w9deo1m5ss.dll +0 -0
  118. package/wwwroot/_framework/Microsoft.ML.Tokenizers.cm2vuv2z61.dll +0 -0
  119. package/wwwroot/_framework/Microsoft.NET.StringTools.3qbrf4v2ki.dll +0 -0
  120. package/wwwroot/_framework/MimeMapping.og9ys58ylm.dll +0 -0
  121. package/wwwroot/_framework/MindExecution.Core.1q1trifbuu.dll +0 -0
  122. package/wwwroot/_framework/MindExecution.Kernel.gwwc40sc45.dll +0 -0
  123. package/wwwroot/_framework/MindExecution.Plugins.Admin.0jgrn1sckv.dll +0 -0
  124. package/wwwroot/_framework/MindExecution.Plugins.Business.13mme2qcag.dll +0 -0
  125. package/wwwroot/_framework/MindExecution.Plugins.Concept.dfp2mdt45q.dll +0 -0
  126. package/wwwroot/_framework/MindExecution.Plugins.Directory.3w4t6n3se0.dll +0 -0
  127. package/wwwroot/_framework/MindExecution.Plugins.PlanMaster.s0qpntz420.dll +0 -0
  128. package/wwwroot/_framework/MindExecution.Plugins.YouTube.iu11fq8d16.dll +0 -0
  129. package/wwwroot/_framework/MindExecution.Shared.7j27dcqnrc.dll +0 -0
  130. package/wwwroot/_framework/MindExecution.Web.pq1ty8ov2v.dll +0 -0
  131. package/wwwroot/_framework/Newtonsoft.Json.a56zs13vug.dll +0 -0
  132. package/wwwroot/_framework/SQLitePCLRaw.batteries_v2.rrd1nzawpp.dll +0 -0
  133. package/wwwroot/_framework/SQLitePCLRaw.core.1dxloztpfz.dll +0 -0
  134. package/wwwroot/_framework/SQLitePCLRaw.provider.e_sqlite3.oekyzl53i1.dll +0 -0
  135. package/wwwroot/_framework/Supabase.Core.s1pkj4aj0l.dll +0 -0
  136. package/wwwroot/_framework/Supabase.Functions.qz4nu782sg.dll +0 -0
  137. package/wwwroot/_framework/Supabase.Gotrue.twah27pkik.dll +0 -0
  138. package/wwwroot/_framework/Supabase.Postgrest.gmuuv369ih.dll +0 -0
  139. package/wwwroot/_framework/Supabase.Realtime.ox3kchdy3w.dll +0 -0
  140. package/wwwroot/_framework/Supabase.Storage.fnjnepaowr.dll +0 -0
  141. package/wwwroot/_framework/Supabase.azmaw5pgcz.dll +0 -0
  142. package/wwwroot/_framework/System.Collections.Concurrent.y1zmvuyipi.dll +0 -0
  143. package/wwwroot/_framework/System.Collections.Immutable.ug3j698qms.dll +0 -0
  144. package/wwwroot/_framework/System.Collections.NonGeneric.h66hj3863h.dll +0 -0
  145. package/wwwroot/_framework/System.Collections.Specialized.umr3y27ntj.dll +0 -0
  146. package/wwwroot/_framework/System.Collections.x53e19vfsj.dll +0 -0
  147. package/wwwroot/_framework/System.ComponentModel.Annotations.tz6gnt4ebt.dll +0 -0
  148. package/wwwroot/_framework/System.ComponentModel.Primitives.j7tiphu4rg.dll +0 -0
  149. package/wwwroot/_framework/System.ComponentModel.TypeConverter.ujlztox1gx.dll +0 -0
  150. package/wwwroot/_framework/System.ComponentModel.x9xz0ojfb6.dll +0 -0
  151. package/wwwroot/_framework/System.Console.ijzpqmj7ne.dll +0 -0
  152. package/wwwroot/_framework/System.Data.Common.1r0sqffq1p.dll +0 -0
  153. package/wwwroot/_framework/System.Diagnostics.DiagnosticSource.9upoqwq09o.dll +0 -0
  154. package/wwwroot/_framework/System.Diagnostics.Process.m99azzntjm.dll +0 -0
  155. package/wwwroot/_framework/System.Diagnostics.TraceSource.pl7wv26myr.dll +0 -0
  156. package/wwwroot/_framework/System.Diagnostics.Tracing.crlhfx6tut.dll +0 -0
  157. package/wwwroot/_framework/System.Drawing.Primitives.22e4y9ikq9.dll +0 -0
  158. package/wwwroot/_framework/System.Drawing.mi7d8hwowb.dll +0 -0
  159. package/wwwroot/_framework/System.Formats.Asn1.jx23sjiqnn.dll +0 -0
  160. package/wwwroot/_framework/System.IO.Compression.6fyoii3uej.dll +0 -0
  161. package/wwwroot/_framework/System.IO.Pipelines.vg77t4cd4d.dll +0 -0
  162. package/wwwroot/_framework/System.IdentityModel.Tokens.Jwt.t67es60z5b.dll +0 -0
  163. package/wwwroot/_framework/System.Linq.1bkoxlqgmq.dll +0 -0
  164. package/wwwroot/_framework/System.Linq.Expressions.24xqiypwdt.dll +0 -0
  165. package/wwwroot/_framework/System.Linq.Queryable.hvd01d6rsa.dll +0 -0
  166. package/wwwroot/_framework/System.Memory.8dx3lwgym4.dll +0 -0
  167. package/wwwroot/_framework/System.Net.Http.Json.3mhdm9l1rf.dll +0 -0
  168. package/wwwroot/_framework/System.Net.Http.eitrz660my.dll +0 -0
  169. package/wwwroot/_framework/System.Net.NetworkInformation.3pkuofcv9r.dll +0 -0
  170. package/wwwroot/_framework/System.Net.Ping.8clj5pklrp.dll +0 -0
  171. package/wwwroot/_framework/System.Net.Primitives.qrp4wcjz1p.dll +0 -0
  172. package/wwwroot/_framework/System.Net.WebSockets.Client.2u6pv01g69.dll +0 -0
  173. package/wwwroot/_framework/System.Net.WebSockets.qp6u31zvm5.dll +0 -0
  174. package/wwwroot/_framework/System.Numerics.Tensors.0c7z4mt3on.dll +0 -0
  175. package/wwwroot/_framework/System.Numerics.Vectors.kc7ufp2j4l.dll +0 -0
  176. package/wwwroot/_framework/System.ObjectModel.qv82fot1ib.dll +0 -0
  177. package/wwwroot/_framework/System.Private.CoreLib.rkafq04oma.dll +0 -0
  178. package/wwwroot/_framework/System.Private.Uri.t9542hmr6j.dll +0 -0
  179. package/wwwroot/_framework/System.Private.Xml.Linq.n8n3ptrbwu.dll +0 -0
  180. package/wwwroot/_framework/System.Private.Xml.rxd3tytisn.dll +0 -0
  181. package/wwwroot/_framework/System.Reactive.t3fuon548l.dll +0 -0
  182. package/wwwroot/_framework/System.Reflection.Emit.9tjhp6y0j3.dll +0 -0
  183. package/wwwroot/_framework/System.Reflection.Emit.ILGeneration.stxyk8zoo1.dll +0 -0
  184. package/wwwroot/_framework/System.Reflection.Emit.Lightweight.6xrd5v8vg0.dll +0 -0
  185. package/wwwroot/_framework/System.Reflection.Primitives.wgn8fpwwvv.dll +0 -0
  186. package/wwwroot/_framework/System.Runtime.InteropServices.JavaScript.sliym526xh.dll +0 -0
  187. package/wwwroot/_framework/System.Runtime.InteropServices.RuntimeInformation.oji7zut14z.dll +0 -0
  188. package/wwwroot/_framework/System.Runtime.InteropServices.te07xr2we9.dll +0 -0
  189. package/wwwroot/_framework/System.Runtime.Intrinsics.507y4h8nzq.dll +0 -0
  190. package/wwwroot/_framework/System.Runtime.Loader.v7gk4bse0k.dll +0 -0
  191. package/wwwroot/_framework/System.Runtime.Numerics.eqy5xjv3nd.dll +0 -0
  192. package/wwwroot/_framework/System.Runtime.Serialization.Formatters.zpkrub8lab.dll +0 -0
  193. package/wwwroot/_framework/System.Runtime.Serialization.Primitives.vhkpnbxjip.dll +0 -0
  194. package/wwwroot/_framework/System.Runtime.jn319d5nyg.dll +0 -0
  195. package/wwwroot/_framework/System.Security.Claims.0ztig1q9vo.dll +0 -0
  196. package/wwwroot/_framework/System.Security.Cryptography.vttizqc9ho.dll +0 -0
  197. package/wwwroot/_framework/System.Text.Encoding.Extensions.utdd47ny8f.dll +0 -0
  198. package/wwwroot/_framework/System.Text.Encodings.Web.wah8r1zoe0.dll +0 -0
  199. package/wwwroot/_framework/System.Text.Json.kxlfxj0wrs.dll +0 -0
  200. package/wwwroot/_framework/System.Text.RegularExpressions.dbqn58klox.dll +0 -0
  201. package/wwwroot/_framework/System.Threading.42ao9vi047.dll +0 -0
  202. package/wwwroot/_framework/System.Threading.Channels.hfa7j0uv2w.dll +0 -0
  203. package/wwwroot/_framework/System.Threading.Thread.caul0pdqul.dll +0 -0
  204. package/wwwroot/_framework/System.Transactions.Local.fimi2hamzo.dll +0 -0
  205. package/wwwroot/_framework/System.Web.HttpUtility.gq8yz50p2e.dll +0 -0
  206. package/wwwroot/_framework/System.Xml.Linq.kitin4zjoj.dll +0 -0
  207. package/wwwroot/_framework/System.Xml.ReaderWriter.kzvw3qgxb0.dll +0 -0
  208. package/wwwroot/_framework/System.Xml.XDocument.c539ki6cuq.dll +0 -0
  209. package/wwwroot/_framework/System.m05i39uvk9.dll +0 -0
  210. package/wwwroot/_framework/Websocket.Client.vapounvmnl.dll +0 -0
  211. package/wwwroot/_framework/blazor.boot.json +305 -0
  212. package/wwwroot/_framework/blazor.webassembly.js +1 -0
  213. package/wwwroot/_framework/dotnet.js +4 -0
  214. package/wwwroot/_framework/dotnet.native.vz0adxojrz.wasm +0 -0
  215. package/wwwroot/_framework/dotnet.native.xsn1d6x2kd.js +16 -0
  216. package/wwwroot/_framework/dotnet.runtime.dstopyvqzi.js +4 -0
  217. package/wwwroot/_framework/icudt_CJK.tjcz0u77k5.dat +0 -0
  218. package/wwwroot/_framework/icudt_EFIGS.tptq2av103.dat +0 -0
  219. package/wwwroot/_framework/icudt_no_CJK.lfu7j35m59.dat +0 -0
  220. package/wwwroot/_framework/netstandard.0xet7jg7ky.dll +0 -0
  221. package/wwwroot/_headers +40 -0
  222. package/wwwroot/_redirects +1 -0
  223. package/wwwroot/appsettings.json +71 -0
  224. package/wwwroot/icon-192.png +0 -0
  225. package/wwwroot/icon-512.png +0 -0
  226. package/wwwroot/index.html +710 -0
  227. package/wwwroot/js/marketing-tool.js +180 -0
  228. package/wwwroot/manifest.webmanifest +22 -0
  229. package/wwwroot/robots.txt +4 -0
  230. package/wwwroot/service-worker-assets.js +857 -0
  231. package/wwwroot/service-worker.js +33 -0
  232. package/wwwroot/sitemap.xml +27 -0
@@ -0,0 +1,489 @@
1
+ // File: mind-map-object-manager.js
2
+ // [Refactor] Creates and updates WebGL node groups (THREE.Group / THREE.Mesh).
3
+ (function () {
4
+ 'use strict';
5
+ // Keep glow purely in CSS layers; avoid spending WebGL budget on halo effects.
6
+ const ENABLE_WEBGL_GLOW = false;
7
+ const MEMO_WEBGL_THEMES = {
8
+ coral: { fill: 0xfff1eb, border: 0xf7b08d, accent: 0xff8052 },
9
+ amber: { fill: 0xfff7df, border: 0xf4d06f, accent: 0xf59e0b },
10
+ sun: { fill: 0xfff9d7, border: 0xe7d668, accent: 0xca8a04 },
11
+ sage: { fill: 0xeef6e7, border: 0xbed79f, accent: 0x65a30d },
12
+ mint: { fill: 0xe8faf4, border: 0x8fd8c1, accent: 0x10b981 },
13
+ sky: { fill: 0xe8f4ff, border: 0x9dc7f7, accent: 0x3b82f6 },
14
+ indigo: { fill: 0xeef0ff, border: 0xbcc2ff, accent: 0x6366f1 },
15
+ violet: { fill: 0xf5ecff, border: 0xd6b8ff, accent: 0x8b5cf6 },
16
+ rose: { fill: 0xffeef2, border: 0xf5b2c2, accent: 0xf43f5e },
17
+ gray: { fill: 0xf3f4f6, border: 0xd1d5db, accent: 0x6b7280 },
18
+ slate: { fill: 0xf3f5f7, border: 0xcbd5e1, accent: 0x64748b }
19
+ };
20
+
21
+ function getNodeMetadata(nodeModel) {
22
+ return nodeModel?.metadata || nodeModel?.Metadata || null;
23
+ }
24
+
25
+ function isAgentStyledMemoNode(nodeModel) {
26
+ const metadata = getNodeMetadata(nodeModel);
27
+ const semanticType = String(metadata?.SemanticType || metadata?.semanticType || '').trim();
28
+ return semanticType === 'MindCanvasAgent' || semanticType === 'AgentCommand';
29
+ }
30
+
31
+ function getMemoWebglTheme(nodeModel) {
32
+ const fallbackKey = 'coral';
33
+ const key = String(getNodeMetadata(nodeModel)?.memoColor || fallbackKey).toLowerCase();
34
+ return MEMO_WEBGL_THEMES[key] || MEMO_WEBGL_THEMES[fallbackKey];
35
+ }
36
+
37
+ function createRoundedRectGeometry(width, height, radius) {
38
+ const shape = new THREE.Shape();
39
+ const x = -width / 2;
40
+ const y = -height / 2;
41
+
42
+ // Start at bottom-left, go clockwise
43
+ shape.moveTo(x, y + radius);
44
+ shape.quadraticCurveTo(x, y, x + radius, y);
45
+
46
+ shape.lineTo(x + width - radius, y);
47
+ shape.quadraticCurveTo(x + width, y, x + width, y + radius);
48
+
49
+ shape.lineTo(x + width, y + height - radius);
50
+ shape.quadraticCurveTo(x + width, y + height, x + width - radius, y + height);
51
+
52
+ shape.lineTo(x + radius, y + height);
53
+ shape.quadraticCurveTo(x, y + height, x, y + height - radius);
54
+
55
+ shape.lineTo(x, y + radius);
56
+
57
+ const points = shape.getPoints();
58
+ return new THREE.BufferGeometry().setFromPoints(points);
59
+ }
60
+
61
+ // ▼▼▼ [New] Create FILLED rounded rectangle for scrollbar ▼▼▼
62
+ // Note: This draws DOWNWARD (negative Y) to match node coordinate system
63
+ function createRoundedRectFilledGeometry(width, height, radius) {
64
+ const shape = new THREE.Shape();
65
+ const x = 0;
66
+ const y = 0;
67
+ const r = Math.min(radius, width / 2, height / 2);
68
+ const h = -height; // Draw downward (negative Y direction)
69
+
70
+ // Start at top-left corner, draw clockwise (going down)
71
+ shape.moveTo(x + r, y);
72
+ shape.lineTo(x + width - r, y);
73
+ shape.quadraticCurveTo(x + width, y, x + width, y - r);
74
+ shape.lineTo(x + width, y + h + r);
75
+ shape.quadraticCurveTo(x + width, y + h, x + width - r, y + h);
76
+ shape.lineTo(x + r, y + h);
77
+ shape.quadraticCurveTo(x, y + h, x, y + h + r);
78
+ shape.lineTo(x, y - r);
79
+ shape.quadraticCurveTo(x, y, x + r, y);
80
+
81
+ return new THREE.ShapeGeometry(shape);
82
+ }
83
+ // ▲▲▲ [New] ▲▲▲
84
+
85
+ const IMAGE_SELECTION_GLOW_PAD = 18;
86
+ const IMAGE_SELECTION_GLOW_COLOR = 0x1e3a8a;
87
+ const IMAGE_SELECTION_GLOW_OPACITY = 0.18;
88
+
89
+ function syncImageSelectionGlow(group, width, height, baseRenderOrder, isSelected) {
90
+ if (!group) return null;
91
+
92
+ let outline = group.getObjectByName('outline');
93
+ if (!outline) {
94
+ outline = new THREE.Mesh(
95
+ createRoundedRectFilledGeometry(
96
+ width + IMAGE_SELECTION_GLOW_PAD,
97
+ height + IMAGE_SELECTION_GLOW_PAD,
98
+ 20 + (IMAGE_SELECTION_GLOW_PAD * 0.5)
99
+ ),
100
+ new THREE.MeshBasicMaterial({
101
+ color: IMAGE_SELECTION_GLOW_COLOR,
102
+ transparent: true,
103
+ opacity: 0,
104
+ depthWrite: false,
105
+ depthTest: false
106
+ })
107
+ );
108
+ outline.name = 'outline';
109
+ outline.userData = { ...(outline.userData || {}), isImageSelectionGlow: true };
110
+ group.add(outline);
111
+ }
112
+
113
+ if (outline.geometry) {
114
+ outline.geometry.dispose?.();
115
+ }
116
+ outline.geometry = createRoundedRectFilledGeometry(
117
+ width + IMAGE_SELECTION_GLOW_PAD,
118
+ height + IMAGE_SELECTION_GLOW_PAD,
119
+ 20 + (IMAGE_SELECTION_GLOW_PAD * 0.5)
120
+ );
121
+ outline.position.set(-(IMAGE_SELECTION_GLOW_PAD / 2), IMAGE_SELECTION_GLOW_PAD / 2, 0);
122
+ outline.renderOrder = baseRenderOrder - 1;
123
+ outline.visible = !!isSelected;
124
+
125
+ if (outline.material) {
126
+ outline.material.color.setHex(IMAGE_SELECTION_GLOW_COLOR);
127
+ outline.material.opacity = isSelected ? IMAGE_SELECTION_GLOW_OPACITY : 0;
128
+ outline.material.transparent = true;
129
+ outline.material.depthWrite = false;
130
+ outline.material.depthTest = false;
131
+ outline.material.needsUpdate = true;
132
+ }
133
+
134
+ return outline;
135
+ }
136
+
137
+ // ▲▲▲ [Change] ▲▲▲
138
+
139
+ async function createOrUpdateCanvasTextureNode(module, nodeModel, existingGroup = null, zPos = 0, textures, width, height) {
140
+ // ▼▼▼ [Changed] Identify nodes handled by CSS3D (Text, Note, Code) ▼▼▼
141
+ // These nodes render as simple background meshes in WebGL (Mesh), content is in DOM.
142
+ const isCss3dNode = ['text', 'note', 'memo', 'code', 'markdown'].includes(nodeModel.contentType);
143
+ // ▲▲▲ [Changed] ▲▲▲
144
+
145
+ // For non-CSS3D nodes, validate textures
146
+ if (!isCss3dNode && (!textures || !textures.default || !textures.selected)) {
147
+ console.error(`[MindMapObjectManager] Cannot create node ${nodeModel.id}: Invalid textures object provided.`);
148
+ return null;
149
+ }
150
+
151
+ const TAIL_HEIGHT = 12;
152
+ const HANDLE_SIZE = 16; // Changed from 36 to 16 to match CSS handles and prevent ghost touches
153
+ const CORNER_RADIUS = 20;
154
+ const DEFAULT_OUTLINE_COLOR = 0x374151;
155
+ const SELECTED_OUTLINE_COLOR = 0x7b7ff2;
156
+ const memoTheme = String(nodeModel?.contentType ?? '').toLowerCase() === 'memo' ? getMemoWebglTheme(nodeModel) : null;
157
+ const defaultBorderHex = memoTheme ? memoTheme.border : DEFAULT_OUTLINE_COLOR;
158
+ const bodyFillHex = memoTheme ? memoTheme.fill : 0xfefefe;
159
+ const isSelected = module.multiSelectedNodeIds.has(nodeModel.id);
160
+ const selectedBorderHex = isCss3dNode
161
+ ? SELECTED_OUTLINE_COLOR
162
+ : (memoTheme ? memoTheme.accent : SELECTED_OUTLINE_COLOR);
163
+ const outlineColor = isSelected ? selectedBorderHex : defaultBorderHex;
164
+ const OUTLINE_SHRINK = 2;
165
+ const OUTLINE_RADIUS = Math.max(1, CORNER_RADIUS - 1);
166
+
167
+ if (existingGroup) {
168
+ const active = isSelected ? (textures?.selected || {}) : (textures?.default || {});
169
+ const bodyMesh = existingGroup.getObjectByName('body');
170
+ const tailMesh = existingGroup.getObjectByName('tail');
171
+ const glowMesh = existingGroup.getObjectByName('glow');
172
+ let outline = existingGroup.getObjectByName('outline');
173
+ let baseRenderOrder = existingGroup.userData?.baseRenderOrder;
174
+ if (baseRenderOrder === undefined) {
175
+ baseRenderOrder = bodyMesh?.renderOrder ?? module.nodeZCounter++;
176
+ existingGroup.userData = {
177
+ ...(existingGroup.userData || {}),
178
+ baseRenderOrder
179
+ };
180
+ }
181
+
182
+ if (bodyMesh) {
183
+ const gp = bodyMesh.geometry && bodyMesh.geometry.parameters;
184
+ if (!gp || gp.width !== width || gp.height !== height) {
185
+ bodyMesh.geometry.dispose();
186
+ bodyMesh.geometry = new THREE.PlaneGeometry(width, height);
187
+
188
+ if (outline) {
189
+ outline.geometry.dispose();
190
+ outline.geometry = createRoundedRectGeometry(
191
+ width - OUTLINE_SHRINK,
192
+ height - OUTLINE_SHRINK,
193
+ OUTLINE_RADIUS
194
+ );
195
+ }
196
+ }
197
+ bodyMesh.position.set(width / 2, -height / 2, 0);
198
+ if (nodeModel.contentType === 'image') {
199
+ syncImageSelectionGlow(existingGroup, width, height, baseRenderOrder, isSelected);
200
+ window.MindMapNodes?.syncImageMidLodDecorations?.(existingGroup, width, height, baseRenderOrder, isSelected);
201
+ } else if (outline) {
202
+ outline.position.copy(bodyMesh.position);
203
+ outline.position.z = 0; // [Fix] Z=0 for parallax elimination
204
+ outline.visible = false;
205
+ if (outline.material) {
206
+ outline.material.color.setHex(isSelected ? selectedBorderHex : defaultBorderHex);
207
+ outline.material.opacity = isSelected ? 1.0 : 0.5;
208
+ }
209
+ }
210
+
211
+ if (bodyMesh.material?.uniforms) {
212
+ if (bodyMesh.material.uniforms.bgColor) {
213
+ bodyMesh.material.uniforms.bgColor.value.setHex(bodyFillHex);
214
+ }
215
+ if (bodyMesh.material.uniforms.borderColor) {
216
+ bodyMesh.material.uniforms.borderColor.value.setHex(isSelected ? selectedBorderHex : defaultBorderHex);
217
+ }
218
+ }
219
+ }
220
+ if (tailMesh) {
221
+ tailMesh.position.set(width / 2, -height - (TAIL_HEIGHT / 2), 0);
222
+ if (active?.tail && tailMesh.material) {
223
+ tailMesh.material.map = active.tail;
224
+ tailMesh.material.needsUpdate = true;
225
+ }
226
+ }
227
+ // Update resize handles (omitted for brevity, handled by existing code flow if not changed)
228
+ if (nodeModel.contentType !== 'pdf') {
229
+ const edgeWidthLength = Math.max(10, width - HANDLE_SIZE * 2);
230
+ const edgeHeightLength = Math.max(10, height - HANDLE_SIZE * 2);
231
+ const handleConfigs = {
232
+ // ▼▼▼ [Fix] Z값을 0으로 통일하여 시차(Parallax) 완전 제거 ▼▼▼
233
+ 'resizeHandle_TL': { x: HANDLE_SIZE / 2, y: -HANDLE_SIZE / 2, w: HANDLE_SIZE, h: HANDLE_SIZE, z: 0 },
234
+ 'resizeHandle_TR': { x: width - HANDLE_SIZE / 2, y: -HANDLE_SIZE / 2, w: HANDLE_SIZE, h: HANDLE_SIZE, z: 0 },
235
+ 'resizeHandle_BL': { x: HANDLE_SIZE / 2, y: -height + HANDLE_SIZE / 2, w: HANDLE_SIZE, h: HANDLE_SIZE, z: 0 },
236
+ 'resizeHandle_BR': { x: width - HANDLE_SIZE / 2, y: -height + HANDLE_SIZE / 2, w: HANDLE_SIZE, h: HANDLE_SIZE, z: 0 }
237
+ // ▲▲▲ [Fix] ▲▲▲
238
+ };
239
+ if (nodeModel.contentType !== 'image') {
240
+ Object.assign(handleConfigs, {
241
+ 'resizeHandle_T': { x: width / 2, y: -HANDLE_SIZE / 2, w: edgeWidthLength, h: HANDLE_SIZE, z: 0 },
242
+ 'resizeHandle_B': { x: width / 2, y: -height + HANDLE_SIZE / 2, w: edgeWidthLength, h: HANDLE_SIZE, z: 0 },
243
+ 'resizeHandle_L': { x: HANDLE_SIZE / 2, y: -height / 2, w: HANDLE_SIZE, h: edgeHeightLength, z: 0 },
244
+ 'resizeHandle_R': { x: width - HANDLE_SIZE / 2, y: -height / 2, w: HANDLE_SIZE, h: edgeHeightLength, z: 0 }
245
+ });
246
+ }
247
+ Object.entries(handleConfigs).forEach(([name, cfg]) => {
248
+ const handle = existingGroup.getObjectByName(name);
249
+ if (handle) {
250
+ handle.position.set(cfg.x, cfg.y, cfg.z);
251
+ const gp = handle.geometry?.parameters;
252
+ if (gp && (gp.width !== cfg.w || gp.height !== cfg.h)) {
253
+ handle.geometry.dispose();
254
+ handle.geometry = new THREE.PlaneGeometry(cfg.w, cfg.h);
255
+ }
256
+ if (nodeModel.contentType === 'image' && handle.material) {
257
+ handle.material.opacity = 0.0;
258
+ handle.material.colorWrite = false;
259
+ handle.material.needsUpdate = true;
260
+ }
261
+ }
262
+ });
263
+ if (nodeModel.contentType === 'image') {
264
+ ['resizeHandle_T', 'resizeHandle_B', 'resizeHandle_L', 'resizeHandle_R'].forEach(name => {
265
+ const handle = existingGroup.getObjectByName(name);
266
+ if (handle) {
267
+ handle.visible = false;
268
+ }
269
+ });
270
+ }
271
+ }
272
+
273
+ // ▼▼▼ [Changed] CSS3D nodes: keep simplified material (or shader), skip texture update ▼▼▼
274
+ if (!isCss3dNode) {
275
+ const active = isSelected ? textures.selected : textures.default;
276
+ if (bodyMesh && bodyMesh.material) { bodyMesh.material.map = active.body; bodyMesh.material.needsUpdate = true; }
277
+ if (tailMesh && tailMesh.material) { tailMesh.material.map = active.tail; tailMesh.material.needsUpdate = true; }
278
+ }
279
+ // ▲▲▲ [Changed] ▲▲▲
280
+
281
+ if (!ENABLE_WEBGL_GLOW && glowMesh) {
282
+ existingGroup.remove(glowMesh);
283
+ try { glowMesh.geometry?.dispose?.(); } catch { }
284
+ try { glowMesh.material?.dispose?.(); } catch { }
285
+ } else if (ENABLE_WEBGL_GLOW && window.MindMapGlowShader) {
286
+ const contentType = nodeModel.contentType || 'text';
287
+ if (!glowMesh) {
288
+ const glow = window.MindMapGlowShader.createSDFGlowMesh(width, height, isSelected, contentType);
289
+ glow.position.set(width / 2, -height / 2, 0.0);
290
+ glow.renderOrder = baseRenderOrder - 5;
291
+ const cameraZ = module.camera?.position?.z ?? Infinity;
292
+ const threshold = 4000;
293
+ glow.visible = cameraZ < threshold;
294
+ existingGroup.add(glow);
295
+ } else {
296
+ window.MindMapGlowShader.updateGlowSize(glowMesh, width, height, contentType);
297
+ window.MindMapGlowShader.updateGlowSelection(glowMesh, isSelected);
298
+ glowMesh.position.set(width / 2, -height / 2, 0.0);
299
+ glowMesh.renderOrder = baseRenderOrder - 5;
300
+ }
301
+ }
302
+
303
+ existingGroup.userData.worldWidth = width;
304
+ existingGroup.userData.worldHeight = height;
305
+ existingGroup.userData.baseRenderOrder = baseRenderOrder;
306
+
307
+ return existingGroup;
308
+
309
+ } else {
310
+ // --- Create new group ---
311
+ const group = new THREE.Group();
312
+ const baseRenderOrder = module.nodeZCounter++;
313
+ const active = isSelected ? (textures?.selected || {}) : (textures?.default || {});
314
+
315
+ // SDF Glow (disabled by default; use CSS selected states instead)
316
+ if (ENABLE_WEBGL_GLOW && window.MindMapGlowShader) {
317
+ const contentType = nodeModel.contentType || 'text';
318
+ const glowMesh = window.MindMapGlowShader.createSDFGlowMesh(width, height, isSelected, contentType);
319
+ glowMesh.position.set(width / 2, -height / 2, 0.0);
320
+ glowMesh.renderOrder = baseRenderOrder - 5;
321
+ const cameraZ = module.camera?.position?.z ?? Infinity;
322
+ const threshold = 4000;
323
+ glowMesh.visible = cameraZ < threshold;
324
+ group.add(glowMesh);
325
+ }
326
+
327
+ // Body
328
+ const bodyGeometry = new THREE.PlaneGeometry(width, height);
329
+ let bodyMaterial;
330
+
331
+ if (isCss3dNode) {
332
+ // ▼▼▼ [Optimized] CSS3D nodes: use SDF shader for border (no texture = saves memory) ▼▼▼
333
+ // This replaces the textured material for text/note/code
334
+ bodyMaterial = new THREE.ShaderMaterial({
335
+ transparent: false, // ★ 불투명하게 변경 - 그리드가 비치지 않도록
336
+ depthWrite: true,
337
+ depthTest: true,
338
+ uniforms: {
339
+ bgColor: { value: new THREE.Color(bodyFillHex) },
340
+ borderColor: { value: new THREE.Color(isSelected ? selectedBorderHex : defaultBorderHex) },
341
+ borderWidth: { value: 3.0 },
342
+ meshSize: { value: new THREE.Vector2(width, height) }
343
+ },
344
+ vertexShader: `
345
+ varying vec2 vUv;
346
+ void main() {
347
+ vUv = uv;
348
+ gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
349
+ }
350
+ `,
351
+ fragmentShader: `
352
+ precision highp float;
353
+ varying vec2 vUv;
354
+ uniform vec3 bgColor;
355
+ uniform vec3 borderColor;
356
+ uniform float borderWidth;
357
+ uniform vec2 meshSize;
358
+
359
+ void main() {
360
+ vec2 pixelCoord = vUv * meshSize;
361
+ bool inBorder = pixelCoord.x < borderWidth ||
362
+ pixelCoord.x > meshSize.x - borderWidth ||
363
+ pixelCoord.y < borderWidth ||
364
+ pixelCoord.y > meshSize.y - borderWidth;
365
+ vec3 finalColor = inBorder ? borderColor : bgColor;
366
+ gl_FragColor = vec4(finalColor, 1.0); // ★ 항상 불투명
367
+ }
368
+ `
369
+ });
370
+ // ▲▲▲ [Optimized] ▲▲▲
371
+ } else {
372
+ // Standard mode (Image nodes): use individual texture
373
+ // ★ [Fix] Image nodes: use fallback color if texture is missing (0xaaaaaa), otherwise white
374
+ const isImage = nodeModel.contentType === 'image';
375
+ const hasTexture = !!active.body;
376
+
377
+ bodyMaterial = new THREE.MeshBasicMaterial({
378
+ map: active.body,
379
+ transparent: false, // ★ 불투명하게 변경 - 그리드가 비치지 않도록
380
+ depthWrite: true,
381
+ depthTest: true,
382
+ color: 0xffffff
383
+ // [Fix] polygonOffset 제거 - Z=0 평면에서 renderOrder로만 제어
384
+ });
385
+ }
386
+
387
+ const bodyMesh = new THREE.Mesh(bodyGeometry, bodyMaterial);
388
+ bodyMesh.renderOrder = baseRenderOrder;
389
+ bodyMesh.name = 'body';
390
+ bodyMesh.position.set(width / 2, -height / 2, 0.0); // ★ z=0.0: 그리드(z=0)와 밀착
391
+ bodyMesh.userData.nodeId = nodeModel.id;
392
+ group.add(bodyMesh);
393
+
394
+ if (nodeModel.contentType === 'image') {
395
+ syncImageSelectionGlow(group, width, height, baseRenderOrder, isSelected);
396
+ window.MindMapNodes?.syncImageMidLodDecorations?.(group, width, height, baseRenderOrder, isSelected);
397
+ }
398
+
399
+ // Tail
400
+ const tailGeometry = new THREE.PlaneGeometry(TAIL_HEIGHT * 2, TAIL_HEIGHT);
401
+ let tailMaterial;
402
+ if (isCss3dNode && !active?.tail) {
403
+ tailMaterial = new THREE.MeshBasicMaterial({ color: 0xfefefe, transparent: true, opacity: 0.9, depthWrite: false, depthTest: false });
404
+ } else {
405
+ tailMaterial = new THREE.MeshBasicMaterial({ map: active?.tail, transparent: true, depthWrite: false, depthTest: false });
406
+ }
407
+ const tailMesh = new THREE.Mesh(tailGeometry, tailMaterial);
408
+ tailMesh.renderOrder = baseRenderOrder;
409
+ tailMesh.name = 'tail';
410
+ tailMesh.position.set(width / 2, -height - (TAIL_HEIGHT / 2), 0.0); // ★ z=0.0
411
+ tailMesh.userData = { nodeId: nodeModel.id, isTailHandle: true };
412
+ group.add(tailMesh);
413
+
414
+ // ▼▼▼ [Removed] Scrollbar creation for CSS3D nodes (DOM handles it) ▼▼▼
415
+ // (Original code had special logic for code nodes, now removed/skipped)
416
+ // ▲▲▲ [Removed] ▲▲▲
417
+
418
+ // ▼▼▼ [Changed] Add eight resize handles (4 corners + 4 edges spanning full length) ▼▼▼
419
+ if (nodeModel.contentType !== 'pdf') {
420
+ // Edge handles span from corner to corner (minus corner handle size)
421
+ const edgeWidthLength = Math.max(10, width - HANDLE_SIZE * 2); // horizontal edge length
422
+ const edgeHeightLength = Math.max(10, height - HANDLE_SIZE * 2); // vertical edge length
423
+
424
+ const handles = [];
425
+
426
+ // Add edges only if NOT an image node
427
+ if (nodeModel.contentType !== 'image') {
428
+ handles.push(
429
+ { name: 'resizeHandle_T', corner: 'T', x: width / 2, y: -HANDLE_SIZE / 2, w: edgeWidthLength, h: HANDLE_SIZE, order: 0 },
430
+ { name: 'resizeHandle_B', corner: 'B', x: width / 2, y: -height + HANDLE_SIZE / 2, w: edgeWidthLength, h: HANDLE_SIZE, order: 0 },
431
+ { name: 'resizeHandle_L', corner: 'L', x: HANDLE_SIZE / 2, y: -height / 2, w: HANDLE_SIZE, h: edgeHeightLength, order: 0 },
432
+ { name: 'resizeHandle_R', corner: 'R', x: width - HANDLE_SIZE / 2, y: -height / 2, w: HANDLE_SIZE, h: edgeHeightLength, order: 0 }
433
+ );
434
+ }
435
+
436
+ // Corners always present
437
+ handles.push(
438
+ { name: 'resizeHandle_TL', corner: 'TL', x: HANDLE_SIZE / 2, y: -HANDLE_SIZE / 2, w: HANDLE_SIZE, h: HANDLE_SIZE, order: 1 },
439
+ { name: 'resizeHandle_TR', corner: 'TR', x: width - HANDLE_SIZE / 2, y: -HANDLE_SIZE / 2, w: HANDLE_SIZE, h: HANDLE_SIZE, order: 1 },
440
+ { name: 'resizeHandle_BL', corner: 'BL', x: HANDLE_SIZE / 2, y: -height + HANDLE_SIZE / 2, w: HANDLE_SIZE, h: HANDLE_SIZE, order: 1 },
441
+ { name: 'resizeHandle_BR', corner: 'BR', x: width - HANDLE_SIZE / 2, y: -height + HANDLE_SIZE / 2, w: HANDLE_SIZE, h: HANDLE_SIZE, order: 1 }
442
+ );
443
+
444
+ handles.forEach(c => {
445
+ const handleGeom = new THREE.PlaneGeometry(c.w, c.h);
446
+ // Use opacity 0.01 instead of 0.0 to ensure Raycaster hits it (some implementations optimize out 0.0)
447
+ const handleMat = new THREE.MeshBasicMaterial({ color: 0xff0000, transparent: true, opacity: 0.01, depthWrite: false, depthTest: false });
448
+ const handleMesh = new THREE.Mesh(handleGeom, handleMat);
449
+ handleMesh.name = c.name;
450
+ handleMesh.userData = { nodeId: nodeModel.id, isResizeHandle: true, corner: c.corner };
451
+ handleMesh.renderOrder = baseRenderOrder + 10 + c.order; // Boost renderOrder significantly
452
+ // ▼▼▼ [Fix] Z값을 0으로 설정 (그리드와 평탄화하여 시차 제거) ▼▼▼
453
+ handleMesh.position.set(c.x, c.y, 0);
454
+ // ▲▲▲ [Fix] ▲▲▲
455
+ group.add(handleMesh);
456
+ });
457
+ }
458
+ // ▲▲▲ [Changed] ▲▲▲
459
+
460
+ group.position.set(nodeModel.positionX, nodeModel.positionY, zPos);
461
+ group.userData = { worldWidth: width, worldHeight: height, nodeId: nodeModel.id, baseRenderOrder };
462
+ return group;
463
+ }
464
+ }
465
+
466
+ function createDeferredNodeShell(nodeModel, width, height, zPos = 0, baseRenderOrder = 0) {
467
+ const group = new THREE.Group();
468
+ group.position.set(nodeModel.positionX || 0, nodeModel.positionY || 0, zPos);
469
+ group.visible = false;
470
+ group.userData = {
471
+ worldWidth: width,
472
+ worldHeight: height,
473
+ nodeId: nodeModel.id,
474
+ baseRenderOrder,
475
+ isDeferredShell: true,
476
+ spatialGridKeys: new Set()
477
+ };
478
+ return group;
479
+ }
480
+
481
+ // Expose MindMapObjectManager globally
482
+ window.MindMapObjectManager = {
483
+ createOrUpdateCanvasTextureNode: createOrUpdateCanvasTextureNode,
484
+ createDeferredNodeShell: createDeferredNodeShell,
485
+ createRoundedRectFilledGeometry: createRoundedRectFilledGeometry // For scrollbar resize in pipeline
486
+ };
487
+
488
+ console.log('✅ mind-map-object-manager.js loaded (Rounded Outline)');
489
+ })();