cyberia 3.1.3 → 3.2.9

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 (377) hide show
  1. package/.env.example +0 -2
  2. package/.github/workflows/engine-cyberia.cd.yml +10 -8
  3. package/.github/workflows/engine-cyberia.ci.yml +12 -29
  4. package/.github/workflows/ghpkg.ci.yml +4 -4
  5. package/.github/workflows/npmpkg.ci.yml +28 -11
  6. package/.github/workflows/publish.ci.yml +21 -2
  7. package/.github/workflows/pwa-microservices-template-page.cd.yml +4 -5
  8. package/.github/workflows/pwa-microservices-template-test.ci.yml +3 -3
  9. package/.github/workflows/release.cd.yml +14 -10
  10. package/CHANGELOG.md +783 -1
  11. package/CLI-HELP.md +95 -18
  12. package/Dockerfile +0 -2
  13. package/README.md +290 -220
  14. package/bin/build.js +24 -7
  15. package/bin/cyberia.js +2838 -252
  16. package/bin/deploy.js +747 -125
  17. package/bin/file.js +9 -0
  18. package/bin/index.js +2838 -252
  19. package/bin/vs.js +1 -1
  20. package/conf.js +99 -65
  21. package/deployment.yaml +18 -164
  22. package/hardhat/hardhat.config.js +13 -13
  23. package/hardhat/ignition/modules/ObjectLayerToken.js +1 -1
  24. package/hardhat/package-lock.json +2559 -5864
  25. package/hardhat/package.json +14 -23
  26. package/hardhat/scripts/deployObjectLayerToken.js +1 -1
  27. package/hardhat/test/ObjectLayerToken.js +4 -2
  28. package/hardhat/types/ethers-contracts/ObjectLayerToken.ts +690 -0
  29. package/hardhat/types/ethers-contracts/common.ts +92 -0
  30. package/hardhat/types/ethers-contracts/factories/ObjectLayerToken__factory.ts +1055 -0
  31. package/hardhat/types/ethers-contracts/factories/index.ts +4 -0
  32. package/hardhat/types/ethers-contracts/hardhat.d.ts +47 -0
  33. package/hardhat/types/ethers-contracts/index.ts +6 -0
  34. package/jsconfig.json +1 -1
  35. package/manifests/cronjobs/dd-cron/dd-cron-backup.yaml +6 -5
  36. package/manifests/cronjobs/dd-cron/dd-cron-dns.yaml +6 -5
  37. package/manifests/deployment/dd-cyberia-development/deployment.yaml +18 -164
  38. package/manifests/deployment/dd-cyberia-development/proxy.yaml +7 -79
  39. package/manifests/deployment/dd-default-development/deployment.yaml +2 -6
  40. package/manifests/deployment/dd-test-development/deployment.yaml +112 -28
  41. package/manifests/deployment/dd-test-development/proxy.yaml +46 -1
  42. package/manifests/deployment/playwright/deployment.yaml +1 -1
  43. package/nodemon.json +1 -1
  44. package/package.json +39 -24
  45. package/proxy.yaml +7 -79
  46. package/scripts/k3s-node-setup.sh +2 -2
  47. package/scripts/nat-iptables.sh +103 -18
  48. package/scripts/rhel-grpc-setup.sh +56 -0
  49. package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.controller.js +58 -14
  50. package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.model.js +23 -14
  51. package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.router.js +5 -0
  52. package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.service.js +148 -20
  53. package/src/api/core/core.controller.js +10 -10
  54. package/src/api/core/core.service.js +10 -10
  55. package/src/api/crypto/crypto.controller.js +8 -8
  56. package/src/api/crypto/crypto.service.js +8 -8
  57. package/src/api/cyberia-action/cyberia-action.controller.js +74 -0
  58. package/src/api/cyberia-action/cyberia-action.model.js +87 -0
  59. package/src/api/cyberia-action/cyberia-action.router.js +27 -0
  60. package/src/api/cyberia-action/cyberia-action.service.js +42 -0
  61. package/src/api/cyberia-dialogue/cyberia-dialogue.controller.js +93 -0
  62. package/src/api/cyberia-dialogue/cyberia-dialogue.model.js +36 -0
  63. package/src/api/cyberia-dialogue/cyberia-dialogue.router.js +29 -0
  64. package/src/api/cyberia-dialogue/cyberia-dialogue.service.js +51 -0
  65. package/src/api/cyberia-entity/cyberia-entity.controller.js +74 -0
  66. package/src/api/cyberia-entity/cyberia-entity.model.js +24 -0
  67. package/src/api/cyberia-entity/cyberia-entity.router.js +27 -0
  68. package/src/api/cyberia-entity/cyberia-entity.service.js +42 -0
  69. package/src/api/cyberia-instance/cyberia-fallback-world.js +178 -0
  70. package/src/api/cyberia-instance/cyberia-instance.controller.js +92 -0
  71. package/src/api/cyberia-instance/cyberia-instance.model.js +87 -0
  72. package/src/api/cyberia-instance/cyberia-instance.router.js +63 -0
  73. package/src/api/cyberia-instance/cyberia-instance.service.js +156 -0
  74. package/src/api/cyberia-instance/cyberia-portal-connector.js +260 -0
  75. package/src/api/cyberia-instance/cyberia-world-generator.js +505 -0
  76. package/src/api/cyberia-instance-conf/cyberia-instance-conf.controller.js +74 -0
  77. package/src/api/cyberia-instance-conf/cyberia-instance-conf.defaults.js +574 -0
  78. package/src/api/cyberia-instance-conf/cyberia-instance-conf.model.js +231 -0
  79. package/src/api/cyberia-instance-conf/cyberia-instance-conf.router.js +27 -0
  80. package/src/api/cyberia-instance-conf/cyberia-instance-conf.service.js +46 -0
  81. package/src/api/cyberia-map/cyberia-map.controller.js +79 -0
  82. package/src/api/cyberia-map/cyberia-map.model.js +30 -0
  83. package/src/api/cyberia-map/cyberia-map.router.js +40 -0
  84. package/src/api/cyberia-map/cyberia-map.service.js +74 -0
  85. package/src/api/cyberia-quest/cyberia-quest.controller.js +74 -0
  86. package/src/api/cyberia-quest/cyberia-quest.model.js +67 -0
  87. package/src/api/cyberia-quest/cyberia-quest.router.js +27 -0
  88. package/src/api/cyberia-quest/cyberia-quest.service.js +42 -0
  89. package/src/api/cyberia-quest-progress/cyberia-quest-progress.controller.js +74 -0
  90. package/src/api/cyberia-quest-progress/cyberia-quest-progress.model.js +49 -0
  91. package/src/api/cyberia-quest-progress/cyberia-quest-progress.router.js +27 -0
  92. package/src/api/cyberia-quest-progress/cyberia-quest-progress.service.js +42 -0
  93. package/src/api/default/default.controller.js +10 -10
  94. package/src/api/default/default.service.js +10 -10
  95. package/src/api/document/document.controller.js +12 -12
  96. package/src/api/document/document.model.js +10 -16
  97. package/src/api/file/file.controller.js +8 -8
  98. package/src/api/file/file.model.js +10 -10
  99. package/src/api/file/file.ref.json +18 -0
  100. package/src/api/file/file.service.js +36 -36
  101. package/src/api/instance/instance.controller.js +10 -10
  102. package/src/api/instance/instance.model.js +4 -10
  103. package/src/api/instance/instance.service.js +10 -10
  104. package/src/api/ipfs/ipfs.controller.js +15 -36
  105. package/src/api/ipfs/ipfs.model.js +47 -47
  106. package/src/api/ipfs/ipfs.router.js +8 -13
  107. package/src/api/ipfs/ipfs.service.js +67 -129
  108. package/src/api/object-layer/object-layer.controller.js +12 -12
  109. package/src/api/object-layer/object-layer.model.js +4 -17
  110. package/src/api/object-layer/object-layer.router.js +30 -0
  111. package/src/api/object-layer/object-layer.service.js +126 -43
  112. package/src/api/object-layer-render-frames/object-layer-render-frames.controller.js +10 -10
  113. package/src/api/object-layer-render-frames/object-layer-render-frames.model.js +6 -16
  114. package/src/api/object-layer-render-frames/object-layer-render-frames.service.js +18 -14
  115. package/src/api/test/test.controller.js +8 -8
  116. package/src/api/test/test.service.js +8 -8
  117. package/src/api/user/guest.service.js +99 -0
  118. package/src/api/user/user.controller.js +6 -6
  119. package/src/api/user/user.model.js +8 -13
  120. package/src/api/user/user.service.js +11 -27
  121. package/src/cli/cluster.js +68 -21
  122. package/src/cli/db.js +753 -825
  123. package/src/cli/deploy.js +215 -125
  124. package/src/cli/env.js +29 -0
  125. package/src/cli/fs.js +82 -8
  126. package/src/cli/image.js +43 -1
  127. package/src/cli/index.js +74 -3
  128. package/src/cli/kubectl.js +211 -0
  129. package/src/cli/release.js +340 -0
  130. package/src/cli/repository.js +475 -74
  131. package/src/cli/run.js +582 -43
  132. package/src/cli/secrets.js +73 -0
  133. package/src/cli/ssh.js +1 -1
  134. package/src/cli/static.js +43 -115
  135. package/src/cli/test.js +3 -3
  136. package/src/client/Cryptokoyn.index.js +18 -22
  137. package/src/client/CyberiaPortal.index.js +19 -24
  138. package/src/client/Default.index.js +21 -34
  139. package/src/client/Itemledger.index.js +20 -27
  140. package/src/client/Underpost.index.js +19 -24
  141. package/src/client/components/core/404.js +4 -4
  142. package/src/client/components/core/500.js +4 -4
  143. package/src/client/components/core/Account.js +73 -60
  144. package/src/client/components/core/AgGrid.js +23 -33
  145. package/src/client/components/core/Alert.js +12 -13
  146. package/src/client/components/core/AppStore.js +69 -0
  147. package/src/client/components/core/Auth.js +35 -37
  148. package/src/client/components/core/Badge.js +7 -13
  149. package/src/client/components/core/BtnIcon.js +15 -17
  150. package/src/client/components/core/CalendarCore.js +43 -64
  151. package/src/client/components/core/Chat.js +13 -15
  152. package/src/client/components/core/ClientEvents.js +87 -0
  153. package/src/client/components/core/ColorPaletteElement.js +309 -0
  154. package/src/client/components/core/Content.js +17 -14
  155. package/src/client/components/core/Css.js +15 -71
  156. package/src/client/components/core/CssCore.js +12 -16
  157. package/src/client/components/core/D3Chart.js +4 -4
  158. package/src/client/components/core/Docs.js +64 -91
  159. package/src/client/components/core/DropDown.js +194 -96
  160. package/src/client/components/core/EventBus.js +92 -0
  161. package/src/client/components/core/EventsUI.js +14 -17
  162. package/src/client/components/core/FileExplorer.js +96 -228
  163. package/src/client/components/core/FullScreen.js +47 -75
  164. package/src/client/components/core/Input.js +24 -69
  165. package/src/client/components/core/Keyboard.js +26 -19
  166. package/src/client/components/core/KeyboardAvoidance.js +145 -0
  167. package/src/client/components/core/LoadingAnimation.js +25 -31
  168. package/src/client/components/core/LogIn.js +43 -43
  169. package/src/client/components/core/LogOut.js +25 -16
  170. package/src/client/components/core/Modal.js +462 -179
  171. package/src/client/components/core/NotificationManager.js +14 -18
  172. package/src/client/components/core/Panel.js +54 -51
  173. package/src/client/components/core/PanelForm.js +44 -144
  174. package/src/client/components/core/Polyhedron.js +110 -214
  175. package/src/client/components/core/PublicProfile.js +39 -32
  176. package/src/client/components/core/Recover.js +48 -44
  177. package/src/client/components/core/Responsive.js +88 -32
  178. package/src/client/components/core/RichText.js +9 -18
  179. package/src/client/components/core/Router.js +24 -3
  180. package/src/client/components/core/SearchBox.js +37 -37
  181. package/src/client/components/core/SignUp.js +39 -30
  182. package/src/client/components/core/SocketIo.js +112 -30
  183. package/src/client/components/core/SocketIoHandler.js +75 -0
  184. package/src/client/components/core/Stream.js +143 -95
  185. package/src/client/components/core/ToggleSwitch.js +8 -20
  186. package/src/client/components/core/ToolTip.js +5 -17
  187. package/src/client/components/core/Translate.js +56 -59
  188. package/src/client/components/core/Validator.js +26 -16
  189. package/src/client/components/core/Wallet.js +15 -26
  190. package/src/client/components/core/Webhook.js +40 -7
  191. package/src/client/components/core/Worker.js +163 -27
  192. package/src/client/components/core/windowGetDimensions.js +7 -7
  193. package/src/client/components/cryptokoyn/{MenuCryptokoyn.js → AppShellCryptokoyn.js} +59 -59
  194. package/src/client/components/cryptokoyn/AppStoreCryptokoyn.js +5 -0
  195. package/src/client/components/cryptokoyn/CssCryptokoyn.js +15 -15
  196. package/src/client/components/cryptokoyn/LogInCryptokoyn.js +9 -7
  197. package/src/client/components/cryptokoyn/LogOutCryptokoyn.js +8 -6
  198. package/src/client/components/cryptokoyn/RouterCryptokoyn.js +37 -0
  199. package/src/client/components/cryptokoyn/SettingsCryptokoyn.js +4 -4
  200. package/src/client/components/cryptokoyn/SignUpCryptokoyn.js +6 -4
  201. package/src/client/components/cryptokoyn/SocketIoCryptokoyn.js +3 -51
  202. package/src/client/components/cyberia/InstanceEngineCyberia.js +781 -0
  203. package/src/client/components/cyberia/MapEngineCyberia.js +1836 -2
  204. package/src/client/components/cyberia/ObjectLayerEngine.js +19 -0
  205. package/src/client/components/cyberia/ObjectLayerEngineModal.js +1220 -99
  206. package/src/client/components/cyberia/ObjectLayerEngineViewer.js +252 -316
  207. package/src/client/components/cyberia-portal/{MenuCyberiaPortal.js → AppShellCyberiaPortal.js} +136 -103
  208. package/src/client/components/cyberia-portal/AppStoreCyberiaPortal.js +5 -0
  209. package/src/client/components/cyberia-portal/CommonCyberiaPortal.js +462 -32
  210. package/src/client/components/cyberia-portal/CssCyberiaPortal.js +15 -15
  211. package/src/client/components/cyberia-portal/LogInCyberiaPortal.js +9 -7
  212. package/src/client/components/cyberia-portal/LogOutCyberiaPortal.js +8 -6
  213. package/src/client/components/cyberia-portal/MainBodyCyberiaPortal.js +4 -4
  214. package/src/client/components/cyberia-portal/RouterCyberiaPortal.js +60 -0
  215. package/src/client/components/cyberia-portal/SettingsCyberiaPortal.js +4 -4
  216. package/src/client/components/cyberia-portal/SignUpCyberiaPortal.js +6 -4
  217. package/src/client/components/cyberia-portal/SocketIoCyberiaPortal.js +3 -49
  218. package/src/client/components/cyberia-portal/TranslateCyberiaPortal.js +8 -4
  219. package/src/client/components/default/{MenuDefault.js → AppShellDefault.js} +91 -91
  220. package/src/client/components/default/AppStoreDefault.js +5 -0
  221. package/src/client/components/default/CssDefault.js +12 -12
  222. package/src/client/components/default/LogInDefault.js +9 -7
  223. package/src/client/components/default/LogOutDefault.js +8 -6
  224. package/src/client/components/default/RouterDefault.js +47 -0
  225. package/src/client/components/default/SettingsDefault.js +4 -4
  226. package/src/client/components/default/SignUpDefault.js +6 -4
  227. package/src/client/components/default/SocketIoDefault.js +3 -51
  228. package/src/client/components/default/TranslateDefault.js +3 -3
  229. package/src/client/components/itemledger/{MenuItemledger.js → AppShellItemledger.js} +59 -59
  230. package/src/client/components/itemledger/AppStoreItemledger.js +5 -0
  231. package/src/client/components/itemledger/CssItemledger.js +15 -15
  232. package/src/client/components/itemledger/LogInItemledger.js +9 -7
  233. package/src/client/components/itemledger/LogOutItemledger.js +8 -6
  234. package/src/client/components/itemledger/RouterItemledger.js +38 -0
  235. package/src/client/components/itemledger/SettingsItemledger.js +4 -4
  236. package/src/client/components/itemledger/SignUpItemledger.js +6 -4
  237. package/src/client/components/itemledger/SocketIoItemledger.js +3 -51
  238. package/src/client/components/itemledger/TranslateItemledger.js +3 -3
  239. package/src/client/components/underpost/{MenuUnderpost.js → AppShellUnderpost.js} +92 -92
  240. package/src/client/components/underpost/AppStoreUnderpost.js +5 -0
  241. package/src/client/components/underpost/CssUnderpost.js +14 -14
  242. package/src/client/components/underpost/CyberpunkBloggerUnderpost.js +4 -4
  243. package/src/client/components/underpost/DocumentSearchProvider.js +1 -1
  244. package/src/client/components/underpost/LabGalleryUnderpost.js +12 -15
  245. package/src/client/components/underpost/LogInUnderpost.js +9 -7
  246. package/src/client/components/underpost/LogOutUnderpost.js +8 -6
  247. package/src/client/components/underpost/RouterUnderpost.js +45 -0
  248. package/src/client/components/underpost/SettingsUnderpost.js +4 -4
  249. package/src/client/components/underpost/SignUpUnderpost.js +6 -4
  250. package/src/client/components/underpost/SocketIoUnderpost.js +3 -51
  251. package/src/client/components/underpost/TranslateUnderpost.js +4 -4
  252. package/src/client/public/cyberia-docs/ACTION-SYSTEM.md +235 -0
  253. package/src/client/public/cyberia-docs/ARCHITECTURE.md +443 -0
  254. package/src/client/public/cyberia-docs/CYBERIA-CLI.md +417 -0
  255. package/src/client/public/cyberia-docs/CYBERIA-CLIENT.md +313 -0
  256. package/src/client/public/cyberia-docs/CYBERIA-SERVER.md +260 -0
  257. package/src/client/public/cyberia-docs/ENTITY-PROFILE.md +241 -0
  258. package/src/client/public/cyberia-docs/HARDHAT-MODULE.md +300 -0
  259. package/src/client/public/cyberia-docs/OFF-CHAIN-ECONOMY.md +279 -0
  260. package/src/client/public/cyberia-docs/QUEST-SYSTEM.md +206 -0
  261. package/src/client/public/cyberia-docs/ROADMAP.md +240 -0
  262. package/src/client/public/cyberia-docs/WHITE-PAPER.md +732 -0
  263. package/src/client/services/atlas-sprite-sheet/atlas-sprite-sheet.service.js +14 -20
  264. package/src/client/services/core/core.service.js +35 -55
  265. package/src/client/services/crypto/crypto.service.js +8 -13
  266. package/src/client/services/cyberia-action/cyberia-action.service.js +99 -0
  267. package/src/client/services/cyberia-dialogue/cyberia-dialogue.service.js +99 -0
  268. package/src/client/services/cyberia-entity/cyberia-entity.management.js +57 -0
  269. package/src/client/services/cyberia-entity/cyberia-entity.service.js +99 -0
  270. package/src/client/services/cyberia-instance/cyberia-instance.management.js +194 -0
  271. package/src/client/services/cyberia-instance/cyberia-instance.service.js +116 -0
  272. package/src/client/services/cyberia-instance-conf/cyberia-instance-conf.service.js +99 -0
  273. package/src/client/services/cyberia-map/cyberia-map.management.js +193 -0
  274. package/src/client/services/cyberia-map/cyberia-map.service.js +120 -0
  275. package/src/client/services/cyberia-quest/cyberia-quest.service.js +99 -0
  276. package/src/client/services/cyberia-quest-progress/cyberia-quest-progress.service.js +99 -0
  277. package/src/client/services/default/default.management.js +159 -267
  278. package/src/client/services/default/default.service.js +10 -16
  279. package/src/client/services/document/document.service.js +14 -19
  280. package/src/client/services/file/file.service.js +8 -13
  281. package/src/client/services/instance/instance.management.js +6 -6
  282. package/src/client/services/instance/instance.service.js +10 -15
  283. package/src/client/services/ipfs/ipfs.service.js +14 -40
  284. package/src/client/services/object-layer/object-layer.management.js +14 -14
  285. package/src/client/services/object-layer/object-layer.service.js +39 -24
  286. package/src/client/services/object-layer-render-frames/object-layer-render-frames.service.js +10 -16
  287. package/src/client/services/test/test.service.js +8 -13
  288. package/src/client/services/user/guest.service.js +86 -0
  289. package/src/client/services/user/user.management.js +6 -6
  290. package/src/client/services/user/user.service.js +14 -20
  291. package/src/client/ssr/body/404.js +3 -3
  292. package/src/client/ssr/body/500.js +3 -3
  293. package/src/client/ssr/body/CacheControl.js +5 -2
  294. package/src/client/ssr/body/DefaultSplashScreen.js +19 -12
  295. package/src/client/ssr/body/UnderpostDefaultSplashScreen.js +13 -6
  296. package/src/client/ssr/head/PwaItemledger.js +197 -60
  297. package/src/client/ssr/mailer/DefaultRecoverEmail.js +19 -20
  298. package/src/client/ssr/mailer/DefaultVerifyEmail.js +15 -16
  299. package/src/client/ssr/offline/Maintenance.js +12 -11
  300. package/src/client/ssr/offline/NoNetworkConnection.js +3 -3
  301. package/src/client/ssr/pages/CyberiaServerMetrics.js +1 -1
  302. package/src/client/ssr/pages/Test.js +2 -2
  303. package/src/client/sw/core.sw.js +212 -0
  304. package/src/grpc/cyberia/grpc-server.js +642 -0
  305. package/src/index.js +24 -1
  306. package/src/runtime/cyberia-client/Dockerfile +80 -0
  307. package/src/runtime/cyberia-server/Dockerfile +37 -0
  308. package/src/runtime/express/Dockerfile +5 -1
  309. package/src/runtime/express/Express.js +18 -1
  310. package/src/runtime/lampp/Dockerfile +17 -5
  311. package/src/runtime/lampp/Lampp.js +27 -4
  312. package/src/runtime/wp/Dockerfile +62 -0
  313. package/src/runtime/wp/Wp.js +639 -0
  314. package/src/server/atlas-sprite-sheet-generator.js +4 -2
  315. package/src/server/auth.js +24 -1
  316. package/src/server/backup.js +37 -9
  317. package/src/server/client-build-docs.js +52 -46
  318. package/src/server/client-build.js +356 -82
  319. package/src/server/client-formatted.js +140 -57
  320. package/src/server/conf.js +29 -13
  321. package/src/server/cron.js +25 -23
  322. package/src/server/data-query.js +32 -20
  323. package/src/server/dns.js +24 -1
  324. package/src/server/ipfs-client.js +253 -89
  325. package/src/server/object-layer.js +150 -114
  326. package/src/server/peer.js +8 -0
  327. package/src/server/process.js +13 -27
  328. package/src/server/runtime.js +25 -1
  329. package/src/server/semantic-layer-generator-floor.js +319 -0
  330. package/src/server/semantic-layer-generator-resource.js +259 -0
  331. package/src/server/semantic-layer-generator-skin.js +1164 -0
  332. package/src/server/semantic-layer-generator.js +211 -542
  333. package/src/server/shape-generator.js +108 -0
  334. package/src/server/start.js +19 -5
  335. package/src/server/valkey.js +141 -235
  336. package/src/ws/IoInterface.js +1 -10
  337. package/src/ws/IoServer.js +14 -33
  338. package/src/ws/core/channels/core.ws.chat.js +65 -20
  339. package/src/ws/core/channels/core.ws.mailer.js +113 -32
  340. package/src/ws/core/channels/core.ws.stream.js +90 -31
  341. package/src/ws/core/core.ws.connection.js +12 -33
  342. package/src/ws/core/core.ws.emit.js +10 -26
  343. package/src/ws/core/core.ws.server.js +25 -58
  344. package/src/ws/default/channels/default.ws.main.js +53 -12
  345. package/src/ws/default/default.ws.connection.js +26 -13
  346. package/src/ws/default/default.ws.server.js +30 -12
  347. package/tsconfig.docs.json +15 -0
  348. package/typedoc.dd-cyberia.json +29 -0
  349. package/typedoc.json +29 -0
  350. package/WHITE-PAPER.md +0 -1540
  351. package/hardhat/README.md +0 -531
  352. package/hardhat/WHITE-PAPER.md +0 -1540
  353. package/jsdoc.dd-cyberia.json +0 -59
  354. package/jsdoc.json +0 -59
  355. package/src/api/object-layer/README.md +0 -347
  356. package/src/client/components/core/ColorPalette.js +0 -5267
  357. package/src/client/components/core/JoyStick.js +0 -80
  358. package/src/client/components/cryptokoyn/CommonCryptokoyn.js +0 -29
  359. package/src/client/components/cryptokoyn/ElementsCryptokoyn.js +0 -38
  360. package/src/client/components/cryptokoyn/RoutesCryptokoyn.js +0 -39
  361. package/src/client/components/cyberia-portal/ElementsCyberiaPortal.js +0 -38
  362. package/src/client/components/cyberia-portal/RoutesCyberiaPortal.js +0 -58
  363. package/src/client/components/cyberia-portal/ServerCyberiaPortal.js +0 -136
  364. package/src/client/components/default/ElementsDefault.js +0 -38
  365. package/src/client/components/default/RoutesDefault.js +0 -49
  366. package/src/client/components/itemledger/CommonItemledger.js +0 -29
  367. package/src/client/components/itemledger/ElementsItemledger.js +0 -38
  368. package/src/client/components/itemledger/RoutesItemledger.js +0 -40
  369. package/src/client/components/underpost/CommonUnderpost.js +0 -29
  370. package/src/client/components/underpost/ElementsUnderpost.js +0 -38
  371. package/src/client/components/underpost/RoutesUnderpost.js +0 -47
  372. package/src/client/sw/default.sw.js +0 -127
  373. package/src/client/sw/template.sw.js +0 -84
  374. package/src/ws/core/management/core.ws.chat.js +0 -8
  375. package/src/ws/core/management/core.ws.mailer.js +0 -16
  376. package/src/ws/core/management/core.ws.stream.js +0 -8
  377. package/src/ws/default/management/default.ws.main.js +0 -8
@@ -0,0 +1,781 @@
1
+ import { BtnIcon } from '../core/BtnIcon.js';
2
+ import { Input, InputFile, getFileFromBlobEndpoint } from '../core/Input.js';
3
+ import { htmls, s } from '../core/VanillaJs.js';
4
+ import { NotificationManager } from '../core/NotificationManager.js';
5
+ import { Translate } from '../core/Translate.js';
6
+ import { dynamicCol, darkTheme, ThemeEvents } from '../core/Css.js';
7
+ import { DropDown } from '../core/DropDown.js';
8
+ import { CyberiaInstanceManagement } from '../../services/cyberia-instance/cyberia-instance.management.js';
9
+ import { CyberiaInstanceService } from '../../services/cyberia-instance/cyberia-instance.service.js';
10
+ import { CyberiaMapService } from '../../services/cyberia-map/cyberia-map.service.js';
11
+ import { FileService } from '../../services/file/file.service.js';
12
+ import { DefaultManagement } from '../../services/default/default.management.js';
13
+ import { getApiBaseUrl } from '../../services/core/core.service.js';
14
+ import { ObjectLayerService } from '../../services/object-layer/object-layer.service.js';
15
+
16
+ const dropdownValueKey = (value = '') => String(value).trim().replaceAll(' ', '-');
17
+ const createDropdownOption = (value, onClick = () => {}, display = value, data = value) => ({
18
+ value,
19
+ display,
20
+ data,
21
+ onClick,
22
+ });
23
+
24
+ class InstanceEngineCyberia {
25
+ static currentInstanceId = null;
26
+ static currentThumbnailId = null;
27
+ static thumbnailDirty = false;
28
+ static portals = [];
29
+ static itemIdsDropdownId = 'instance-engine-item-ids-dropdown';
30
+
31
+ static syncItemIdsDropdownSelection(itemIds = []) {
32
+ const dropdownId = InstanceEngineCyberia.itemIdsDropdownId;
33
+ if (!DropDown.Tokens[dropdownId]) return;
34
+
35
+ DropDown.Tokens[dropdownId].value = [];
36
+ if (s(`.${dropdownId}`)) s(`.${dropdownId}`).value = [];
37
+ DropDown.Tokens[dropdownId].oncheckvalues = {};
38
+ htmls(`.dropdown-current-${dropdownId}`, '');
39
+ htmls(`.${dropdownId}-render-container`, '');
40
+
41
+ for (const itemId of itemIds) {
42
+ const key = dropdownValueKey(itemId);
43
+ DropDown.Tokens[dropdownId].oncheckvalues[key] = {
44
+ data: itemId,
45
+ display: itemId,
46
+ value: itemId,
47
+ };
48
+ }
49
+ DropDown.Tokens[dropdownId].value = [...itemIds];
50
+ if (s(`.${dropdownId}`)) s(`.${dropdownId}`).value = [...itemIds];
51
+ DropDown.Tokens[dropdownId]._renderSelectedBadges?.();
52
+ }
53
+
54
+ static async buildItemIdsDropdown() {
55
+ return await DropDown.instance({
56
+ id: InstanceEngineCyberia.itemIdsDropdownId,
57
+ label: html`Object Layer Item IDs`,
58
+ data: [],
59
+ type: 'checkbox',
60
+ containerClass: 'inl',
61
+ excludeSelected: true,
62
+ serviceProvider: async (q) => {
63
+ const result = await ObjectLayerService.searchItemIds({ q });
64
+ if (result.status === 'success' && result.data?.itemIds) {
65
+ return result.data.itemIds.map((itemId) => createDropdownOption(itemId));
66
+ }
67
+ return [];
68
+ },
69
+ });
70
+ }
71
+
72
+ static renderPortalList(containerId) {
73
+ const container = s(`.${containerId}`);
74
+ if (!container) return;
75
+
76
+ const filterSource = s('.instance-engine-filter-source')?.value?.trim().toLowerCase() || '';
77
+ const filterTarget = s('.instance-engine-filter-target')?.value?.trim().toLowerCase() || '';
78
+
79
+ const filtered = [];
80
+ InstanceEngineCyberia.portals.forEach((portal, i) => {
81
+ if (filterSource && !(portal.sourceMapCode || '').toLowerCase().includes(filterSource)) return;
82
+ if (filterTarget && !(portal.targetMapCode || '').toLowerCase().includes(filterTarget)) return;
83
+ filtered.push({ portal, i });
84
+ });
85
+
86
+ let listHtml = '';
87
+ filtered.forEach(({ portal, i }) => {
88
+ listHtml += html`<div class="fl" style="border-bottom:1px solid #444; padding:4px 0; align-items:center;">
89
+ <div class="in fll" style="flex:1;font-size:12px;font-family:monospace;">
90
+ <span style="color:${darkTheme ? '#8cf' : '#246'};">${portal.sourceMapCode}</span>
91
+ (${portal.sourceCellX}, ${portal.sourceCellY})
92
+ <span style="margin:0 4px;">&rarr;</span>
93
+ <span style="color:${darkTheme ? '#fc8' : '#842'};">${portal.targetMapCode}</span>
94
+ ${portal.targetCellX < 0 || portal.targetCellY < 0
95
+ ? '<span style="color:#aaa;">(random)</span>'
96
+ : `(${portal.targetCellX}, ${portal.targetCellY})`}
97
+ <span style="color:${darkTheme ? '#9e9' : '#383'};margin-left:4px;font-size:11px;"
98
+ >[${portal.portalMode || 'inter-portal'}]</span
99
+ >
100
+ </div>
101
+ <div class="in fll" style="display:flex;gap:3px;">
102
+ <button
103
+ class="btn-instance-engine-load-portal"
104
+ data-index="${i}"
105
+ style="cursor:pointer;background:#36a;color:#fff;border:none;padding:2px 8px;font-size:12px;"
106
+ >
107
+ <i class="fa-solid fa-clone"></i>
108
+ </button>
109
+ <button
110
+ class="btn-instance-engine-remove-portal"
111
+ data-index="${i}"
112
+ style="cursor:pointer;background:#a00;color:#fff;border:none;padding:2px 8px;font-size:12px;"
113
+ >
114
+ <i class="fa-solid fa-trash"></i>
115
+ </button>
116
+ </div>
117
+ </div>`;
118
+ });
119
+
120
+ if (!listHtml)
121
+ listHtml = `<div style="color:#888;font-size:13px;">${
122
+ InstanceEngineCyberia.portals.length > 0 ? 'No matching portals.' : 'No portals added yet.'
123
+ }</div>`;
124
+
125
+ htmls(`.${containerId}`, listHtml);
126
+
127
+ container.querySelectorAll('.btn-instance-engine-remove-portal').forEach((btn) => {
128
+ btn.onclick = () => {
129
+ const idx = parseInt(btn.dataset.index);
130
+ InstanceEngineCyberia.portals.splice(idx, 1);
131
+ InstanceEngineCyberia.renderPortalList(containerId);
132
+ };
133
+ });
134
+
135
+ container.querySelectorAll('.btn-instance-engine-load-portal').forEach((btn) => {
136
+ btn.onclick = () => {
137
+ const idx = parseInt(btn.dataset.index);
138
+ const portal = InstanceEngineCyberia.portals[idx];
139
+ if (!portal) return;
140
+ if (s('.instance-engine-source-map-code'))
141
+ s('.instance-engine-source-map-code').value = portal.sourceMapCode || '';
142
+ if (s('.instance-engine-source-cell-x')) s('.instance-engine-source-cell-x').value = portal.sourceCellX || 0;
143
+ if (s('.instance-engine-source-cell-y')) s('.instance-engine-source-cell-y').value = portal.sourceCellY || 0;
144
+ if (s('.instance-engine-target-map-code'))
145
+ s('.instance-engine-target-map-code').value = portal.targetMapCode || '';
146
+ if (s('.instance-engine-target-cell-x')) s('.instance-engine-target-cell-x').value = portal.targetCellX || 0;
147
+ if (s('.instance-engine-target-cell-y')) s('.instance-engine-target-cell-y').value = portal.targetCellY || 0;
148
+ };
149
+ });
150
+ }
151
+
152
+ static async render(options = {}) {
153
+ const { appStore } = options;
154
+ const idCode = 'instance-engine-input-code';
155
+ const idName = 'instance-engine-input-name';
156
+ const idDescription = 'instance-engine-input-description';
157
+ const idTags = 'instance-engine-input-tags';
158
+ const idStatus = 'instance-engine-input-status';
159
+ const idThumbnail = 'instance-engine-input-thumbnail';
160
+ const idMapCodesDropdown = 'instance-engine-map-codes-dropdown';
161
+ const idItemIdsDropdown = InstanceEngineCyberia.itemIdsDropdownId;
162
+ const managementId = 'modal-cyberia-instance-engine';
163
+ const portalListId = 'instance-engine-portal-list';
164
+ const idSourceMapCode = 'instance-engine-source-map-code';
165
+ const idSourceCellX = 'instance-engine-source-cell-x';
166
+ const idSourceCellY = 'instance-engine-source-cell-y';
167
+ const idTargetMapCode = 'instance-engine-target-map-code';
168
+ const idTargetCellX = 'instance-engine-target-cell-x';
169
+ const idTargetCellY = 'instance-engine-target-cell-y';
170
+ const idFilterSource = 'instance-engine-filter-source';
171
+ const idFilterTarget = 'instance-engine-filter-target';
172
+
173
+ InstanceEngineCyberia.currentInstanceId = null;
174
+ InstanceEngineCyberia.currentThumbnailId = null;
175
+ InstanceEngineCyberia.thumbnailDirty = false;
176
+ InstanceEngineCyberia.portals = [];
177
+
178
+ const getInstancePayload = () => {
179
+ const tagsRaw = s(`.${idTags}`)?.value || '';
180
+ const tags = tagsRaw
181
+ .split(',')
182
+ .map((t) => t.trim())
183
+ .filter((t) => t);
184
+ const cyberiaMapCodes = DropDown.Tokens[idMapCodesDropdown]?.value
185
+ ? [...DropDown.Tokens[idMapCodesDropdown].value]
186
+ : [];
187
+ const itemIds = DropDown.Tokens[idItemIdsDropdown]?.value ? [...DropDown.Tokens[idItemIdsDropdown].value] : [];
188
+ const payload = {
189
+ code: s(`.${idCode}`)?.value || '',
190
+ name: s(`.${idName}`)?.value || '',
191
+ description: s(`.${idDescription}`)?.value || '',
192
+ tags,
193
+ status: DropDown.Tokens[idStatus]?.value || 'unlisted',
194
+ cyberiaMapCodes,
195
+ itemIds,
196
+ portals: InstanceEngineCyberia.portals,
197
+ };
198
+ if (InstanceEngineCyberia.currentThumbnailId) payload.thumbnail = InstanceEngineCyberia.currentThumbnailId;
199
+ return payload;
200
+ };
201
+
202
+ const persistInstance = async ({ notify = true } = {}) => {
203
+ // Upload thumbnail file only if user selected a new one
204
+ const thumbnailInput = s(`.${idThumbnail}`);
205
+ if (
206
+ InstanceEngineCyberia.thumbnailDirty &&
207
+ thumbnailInput &&
208
+ thumbnailInput.files &&
209
+ thumbnailInput.files.length > 0
210
+ ) {
211
+ const formData = new FormData();
212
+ formData.append('file', thumbnailInput.files[0]);
213
+ const uploadResult = await FileService.post({ body: formData });
214
+ if (uploadResult.status === 'success' && uploadResult.data && uploadResult.data.length > 0) {
215
+ InstanceEngineCyberia.currentThumbnailId = uploadResult.data[0]._id;
216
+ } else {
217
+ if (notify) {
218
+ NotificationManager.Push({
219
+ html: uploadResult.message || 'Failed to upload thumbnail',
220
+ status: 'error',
221
+ });
222
+ }
223
+ return uploadResult;
224
+ }
225
+ }
226
+
227
+ const body = getInstancePayload();
228
+ const isUpdate = !!InstanceEngineCyberia.currentInstanceId;
229
+ let result;
230
+ if (isUpdate) {
231
+ result = await CyberiaInstanceService.put({ id: InstanceEngineCyberia.currentInstanceId, body });
232
+ } else {
233
+ result = await CyberiaInstanceService.post({ body });
234
+ }
235
+ if (notify) {
236
+ NotificationManager.Push({
237
+ html:
238
+ result.status === 'error'
239
+ ? result.message
240
+ : isUpdate
241
+ ? Translate.instance('success-update-item')
242
+ : Translate.instance('success-create-item'),
243
+ status: result.status,
244
+ });
245
+ }
246
+ if (result.status === 'success') {
247
+ if (result.data?._id) InstanceEngineCyberia.currentInstanceId = result.data._id;
248
+ await DefaultManagement.loadTable(managementId, { force: true, reload: true });
249
+ }
250
+ return result;
251
+ };
252
+
253
+ const saveInstance = async () => {
254
+ await persistInstance({ notify: true });
255
+ };
256
+
257
+ const loadInstance = async (instanceData) => {
258
+ InstanceEngineCyberia.currentInstanceId = instanceData._id || null;
259
+ if (s(`.${idCode}`)) s(`.${idCode}`).value = instanceData.code || '';
260
+ if (s(`.${idName}`)) s(`.${idName}`).value = instanceData.name || '';
261
+ if (s(`.${idDescription}`)) s(`.${idDescription}`).value = instanceData.description || '';
262
+ if (s(`.${idTags}`)) s(`.${idTags}`).value = (instanceData.tags || []).join(', ');
263
+ const statusValue = instanceData.status || 'unlisted';
264
+ if (DropDown.Tokens[idStatus]) {
265
+ const statusIndex = statusOptions.findIndex((opt) => opt.value === statusValue);
266
+ if (statusIndex > -1) s(`.dropdown-option-${idStatus}-${statusIndex}`).click();
267
+ }
268
+
269
+ // Thumbnail
270
+ InstanceEngineCyberia.currentThumbnailId = instanceData.thumbnail || null;
271
+ const thumbnailPreview = s(`.instance-engine-thumbnail-preview`);
272
+ if (InstanceEngineCyberia.currentThumbnailId) {
273
+ const thumbId =
274
+ typeof InstanceEngineCyberia.currentThumbnailId === 'object'
275
+ ? InstanceEngineCyberia.currentThumbnailId._id
276
+ : InstanceEngineCyberia.currentThumbnailId;
277
+
278
+ // Set preview image
279
+ if (thumbnailPreview) {
280
+ thumbnailPreview.innerHTML = html`<img
281
+ src="${getApiBaseUrl({ id: thumbId, endpoint: 'file/blob' })}"
282
+ style="max-width:120px;max-height:120px;border:1px solid #555;"
283
+ onerror="this.style.display='none';"
284
+ />`;
285
+ }
286
+
287
+ // Populate InputFile with the actual file from server
288
+ if (s(`.${idThumbnail}`)) {
289
+ const fileData = await getFileFromBlobEndpoint({ _id: thumbId, mimetype: 'image/png' });
290
+ if (fileData) {
291
+ const dataTransfer = new DataTransfer();
292
+ dataTransfer.items.add(fileData);
293
+ s(`.${idThumbnail}`).files = dataTransfer.files;
294
+ s(`.${idThumbnail}`).onchange({ target: s(`.${idThumbnail}`) });
295
+ }
296
+ }
297
+ InstanceEngineCyberia.thumbnailDirty = false;
298
+ } else {
299
+ if (thumbnailPreview) thumbnailPreview.innerHTML = '';
300
+ if (s(`.${idThumbnail}`)) {
301
+ s(`.${idThumbnail}`).value = '';
302
+ s(`.${idThumbnail}`).onchange({ target: s(`.${idThumbnail}`) });
303
+ }
304
+ }
305
+
306
+ // Creator display
307
+ const creatorDisplay = s(`.instance-engine-creator-display`);
308
+ if (creatorDisplay) {
309
+ if (instanceData.creator) {
310
+ const creatorUsername =
311
+ typeof instanceData.creator === 'object'
312
+ ? instanceData.creator.username || instanceData.creator._id
313
+ : instanceData.creator;
314
+ creatorDisplay.innerHTML = html`<span style="font-family:monospace;font-size:12px;"
315
+ >${creatorUsername}</span
316
+ >`;
317
+ } else {
318
+ creatorDisplay.innerHTML = html`<span style="color:#888;font-size:12px;">—</span>`;
319
+ }
320
+ }
321
+
322
+ // Load cyberiaMapCodes into the dropdown
323
+ if (DropDown.Tokens[idMapCodesDropdown]) {
324
+ DropDown.Tokens[idMapCodesDropdown].oncheckvalues = {};
325
+ const mapCodes = instanceData.cyberiaMapCodes || [];
326
+ for (const code of mapCodes) {
327
+ const key = code.trim().replaceAll(' ', '-');
328
+ DropDown.Tokens[idMapCodesDropdown].oncheckvalues[key] = { data: code, display: code, value: code };
329
+ }
330
+ DropDown.Tokens[idMapCodesDropdown].value = mapCodes;
331
+ if (s(`.${idMapCodesDropdown}`)) s(`.${idMapCodesDropdown}`).value = mapCodes;
332
+ if (s(`.dropdown-current-${idMapCodesDropdown}`)) {
333
+ DropDown.Tokens[idMapCodesDropdown]._renderSelectedBadges?.();
334
+ }
335
+ }
336
+
337
+ InstanceEngineCyberia.syncItemIdsDropdownSelection(instanceData.itemIds || instanceData.itemsId || []);
338
+
339
+ // Load portals
340
+ InstanceEngineCyberia.portals = (instanceData.portals || []).map((p) => ({
341
+ sourceMapCode: p.sourceMapCode || '',
342
+ sourceCellX: p.sourceCellX || 0,
343
+ sourceCellY: p.sourceCellY || 0,
344
+ targetMapCode: p.targetMapCode || '',
345
+ targetCellX: p.targetCellX || 0,
346
+ targetCellY: p.targetCellY || 0,
347
+ portalMode: p.portalMode || 'inter-portal',
348
+ }));
349
+ InstanceEngineCyberia.renderPortalList(portalListId);
350
+ };
351
+
352
+ const resetForm = () => {
353
+ InstanceEngineCyberia.currentInstanceId = null;
354
+ InstanceEngineCyberia.currentThumbnailId = null;
355
+ InstanceEngineCyberia.thumbnailDirty = false;
356
+ if (s(`.${idCode}`)) s(`.${idCode}`).value = '';
357
+ if (s(`.${idName}`)) s(`.${idName}`).value = '';
358
+ if (s(`.${idDescription}`)) s(`.${idDescription}`).value = '';
359
+ if (s(`.${idTags}`)) s(`.${idTags}`).value = '';
360
+ if (DropDown.Tokens[idStatus]) {
361
+ const resetIndex = statusOptions.findIndex((opt) => opt.value === 'unlisted');
362
+ if (resetIndex > -1) s(`.dropdown-option-${idStatus}-${resetIndex}`).click();
363
+ }
364
+ const thumbnailPreview = s(`.instance-engine-thumbnail-preview`);
365
+ if (thumbnailPreview) thumbnailPreview.innerHTML = '';
366
+ if (s(`.${idThumbnail}`)) {
367
+ s(`.${idThumbnail}`).value = '';
368
+ s(`.${idThumbnail}`).onchange({ target: s(`.${idThumbnail}`) });
369
+ }
370
+ const creatorDisplay = s(`.instance-engine-creator-display`);
371
+ if (creatorDisplay) creatorDisplay.innerHTML = '<span style="color:#888;font-size:12px;">—</span>';
372
+ if (DropDown.Tokens[idMapCodesDropdown]) {
373
+ DropDown.Tokens[idMapCodesDropdown].oncheckvalues = {};
374
+ DropDown.Tokens[idMapCodesDropdown].value = [];
375
+ htmls(`.dropdown-current-${idMapCodesDropdown}`, '');
376
+ htmls(`.${idMapCodesDropdown}-render-container`, '');
377
+ }
378
+ if (DropDown.Tokens[idItemIdsDropdown]) {
379
+ DropDown.Tokens[idItemIdsDropdown].oncheckvalues = {};
380
+ DropDown.Tokens[idItemIdsDropdown].value = [];
381
+ htmls(`.dropdown-current-${idItemIdsDropdown}`, '');
382
+ htmls(`.${idItemIdsDropdown}-render-container`, '');
383
+ }
384
+ InstanceEngineCyberia.portals = [];
385
+ InstanceEngineCyberia.renderPortalList(portalListId);
386
+ };
387
+
388
+ setTimeout(() => {
389
+ if (s(`.btn-instance-engine-save`)) s(`.btn-instance-engine-save`).onclick = () => saveInstance();
390
+ if (s(`.btn-instance-engine-new`)) s(`.btn-instance-engine-new`).onclick = () => resetForm();
391
+
392
+ if (s(`.btn-instance-engine-toggle-thumbnail`))
393
+ s(`.btn-instance-engine-toggle-thumbnail`).onclick = () => {
394
+ const body = s(`.instance-engine-thumbnail-body`);
395
+ const caret = s(`.instance-engine-thumbnail-caret`);
396
+ if (body) body.classList.toggle('hide');
397
+ if (caret) {
398
+ caret.classList.toggle('fa-caret-right');
399
+ caret.classList.toggle('fa-caret-down');
400
+ }
401
+ };
402
+
403
+ // Portal management
404
+ if (s(`.btn-instance-engine-portal-connect`))
405
+ s(`.btn-instance-engine-portal-connect`).onclick = async () => {
406
+ const btn = s(`.btn-instance-engine-portal-connect`);
407
+ if (btn) btn.disabled = true;
408
+ try {
409
+ const persistResult = await persistInstance({ notify: false });
410
+ if (!persistResult || persistResult.status !== 'success' || !InstanceEngineCyberia.currentInstanceId) {
411
+ NotificationManager.Push({
412
+ html: persistResult?.message || Translate.instance('save-instance-first') || 'Save the instance first.',
413
+ status: persistResult?.status === 'error' ? 'error' : 'warning',
414
+ });
415
+ return;
416
+ }
417
+ const result = await CyberiaInstanceService.portalConnect({ id: InstanceEngineCyberia.currentInstanceId });
418
+ if (result.status === 'error') {
419
+ NotificationManager.Push({ html: result.message, status: 'error' });
420
+ return;
421
+ }
422
+ const { portals: generated, topology, message } = result.data || {};
423
+ if (!generated || generated.length === 0) {
424
+ NotificationManager.Push({
425
+ html: message || 'No portals could be generated.',
426
+ status: 'warning',
427
+ });
428
+ return;
429
+ }
430
+ // Replace all portals with the centralized topology output
431
+ // (ring + random behavior for remaining unassigned portals)
432
+ InstanceEngineCyberia.portals = generated.map((p) => ({
433
+ sourceMapCode: p.sourceMapCode || '',
434
+ sourceCellX: p.sourceCellX || 0,
435
+ sourceCellY: p.sourceCellY || 0,
436
+ targetMapCode: p.targetMapCode || '',
437
+ targetCellX: p.targetCellX || 0,
438
+ targetCellY: p.targetCellY || 0,
439
+ portalMode: p.portalMode || 'inter-portal',
440
+ }));
441
+ InstanceEngineCyberia.renderPortalList(portalListId);
442
+ NotificationManager.Push({
443
+ html: `${topology} — ${generated.length} portal(s) generated.`,
444
+ status: 'success',
445
+ });
446
+ } catch (e) {
447
+ NotificationManager.Push({ html: e.message, status: 'error' });
448
+ } finally {
449
+ if (btn) btn.disabled = false;
450
+ }
451
+ };
452
+
453
+ if (s(`.btn-instance-engine-add-portal`))
454
+ s(`.btn-instance-engine-add-portal`).onclick = () => {
455
+ const portal = {
456
+ sourceMapCode: s(`.${idSourceMapCode}`)?.value || '',
457
+ sourceCellX: parseInt(s(`.${idSourceCellX}`)?.value) || 0,
458
+ sourceCellY: parseInt(s(`.${idSourceCellY}`)?.value) || 0,
459
+ targetMapCode: s(`.${idTargetMapCode}`)?.value || '',
460
+ targetCellX: parseInt(s(`.${idTargetCellX}`)?.value) || 0,
461
+ targetCellY: parseInt(s(`.${idTargetCellY}`)?.value) || 0,
462
+ portalMode: 'inter-portal',
463
+ };
464
+ InstanceEngineCyberia.portals.push(portal);
465
+ InstanceEngineCyberia.renderPortalList(portalListId);
466
+ };
467
+
468
+ if (s('.btn-instance-engine-toggle-portal-filter'))
469
+ s('.btn-instance-engine-toggle-portal-filter').onclick = () => {
470
+ const body = s('.instance-engine-portal-filter-body');
471
+ const caret = s('.instance-engine-portal-filter-caret');
472
+ if (body) body.classList.toggle('hide');
473
+ if (caret) {
474
+ caret.classList.toggle('fa-caret-right');
475
+ caret.classList.toggle('fa-caret-down');
476
+ }
477
+ };
478
+
479
+ let portalFilterTimeout = null;
480
+ const applyPortalFilter = () => {
481
+ clearTimeout(portalFilterTimeout);
482
+ portalFilterTimeout = setTimeout(() => {
483
+ InstanceEngineCyberia.renderPortalList(portalListId);
484
+ }, 300);
485
+ };
486
+ [idFilterSource, idFilterTarget].forEach((cls) => {
487
+ if (s(`.${cls}`)) s(`.${cls}`).addEventListener('input', applyPortalFilter);
488
+ });
489
+
490
+ if (s('.btn-instance-engine-clear-portal-filter'))
491
+ s('.btn-instance-engine-clear-portal-filter').onclick = () => {
492
+ [idFilterSource, idFilterTarget].forEach((cls) => {
493
+ if (s(`.${cls}`)) s(`.${cls}`).value = '';
494
+ });
495
+ InstanceEngineCyberia.renderPortalList(portalListId);
496
+ };
497
+
498
+ ThemeEvents['instance-engine-theme'] = () => {
499
+ InstanceEngineCyberia.renderPortalList(portalListId);
500
+ };
501
+ });
502
+
503
+ const statusOptions = [
504
+ { value: 'unlisted', display: 'unlisted', data: 'unlisted', onClick: () => {} },
505
+ { value: 'draft', display: 'draft', data: 'draft', onClick: () => {} },
506
+ { value: 'published', display: 'published', data: 'published', onClick: () => {} },
507
+ { value: 'archived', display: 'archived', data: 'archived', onClick: () => {} },
508
+ ];
509
+
510
+ const managementTableHtml = await CyberiaInstanceManagement.instance({
511
+ idModal: managementId,
512
+ loadInstanceCallback: loadInstance,
513
+ appStore,
514
+ readyRowDataEvent: {
515
+ 'instance-engine-check-deleted': (rowData) => {
516
+ if (InstanceEngineCyberia.currentInstanceId) {
517
+ const stillExists = rowData.some((row) => row._id === InstanceEngineCyberia.currentInstanceId);
518
+ if (!stillExists) InstanceEngineCyberia.currentInstanceId = null;
519
+ }
520
+ },
521
+ },
522
+ });
523
+
524
+ const dcFields = 'instance-engine-dc-fields';
525
+ const dcMetaFields = 'instance-engine-dc-meta';
526
+ const dcSaveNew = 'instance-engine-dc-save-new';
527
+ const dcPortalSource = 'instance-engine-dc-portal-source';
528
+ const dcPortalTarget = 'instance-engine-dc-portal-target';
529
+ const dcPortalFilter = 'instance-engine-dc-portal-filter';
530
+
531
+ return html`<div class="in section-mp instance-engine-container">
532
+ ${dynamicCol({ containerSelector: 'instance-engine-container', id: dcFields, type: 'search-inputs' })}
533
+ <div class="fl">
534
+ <div class="in fll ${dcFields}-col-a">
535
+ ${await Input.instance({
536
+ id: idCode,
537
+ label: html`Code`,
538
+ containerClass: 'inl',
539
+ type: 'text',
540
+ })}
541
+ </div>
542
+ <div class="in fll ${dcFields}-col-b">
543
+ ${await Input.instance({
544
+ id: idName,
545
+ label: html`Name`,
546
+ containerClass: 'inl',
547
+ type: 'text',
548
+ })}
549
+ </div>
550
+ <div class="in fll ${dcFields}-col-c">
551
+ ${await Input.instance({
552
+ id: idDescription,
553
+ label: html`Description`,
554
+ containerClass: 'inl',
555
+ type: 'text',
556
+ })}
557
+ </div>
558
+ </div>
559
+ ${dynamicCol({ containerSelector: 'instance-engine-container', id: dcMetaFields, type: 'search-inputs' })}
560
+ <div class="fl">
561
+ <div class="in fll ${dcMetaFields}-col-a">
562
+ ${await Input.instance({
563
+ id: idTags,
564
+ label: html`Tags (comma separated)`,
565
+ containerClass: 'inl',
566
+ type: 'text',
567
+ })}
568
+ </div>
569
+ <div class="in fll ${dcMetaFields}-col-b">
570
+ ${await DropDown.instance({
571
+ id: idStatus,
572
+ label: html`Status`,
573
+ data: statusOptions.map((opt) => ({ ...opt })),
574
+ value: 'unlisted',
575
+ containerClass: 'inl',
576
+ })}
577
+ </div>
578
+ <div class="in fll ${dcMetaFields}-col-c">
579
+ <div class="inl">
580
+ <div class="in input-label">Creator</div>
581
+ <div class="in instance-engine-creator-display">
582
+ <span style="color:#888;font-size:12px;">—</span>
583
+ </div>
584
+ </div>
585
+ </div>
586
+ </div>
587
+ <div class="in section-mp" style="margin-top: 5px;">
588
+ <div class="in instance-engine-thumbnail-preview" style="margin-bottom: 5px;"></div>
589
+ ${await BtnIcon.instance({
590
+ class: 'wfa btn-instance-engine-toggle-thumbnail',
591
+ label: html`<i class="fa-solid fa-caret-right instance-engine-thumbnail-caret"></i> Thumbnail`,
592
+ })}
593
+ <div class="in instance-engine-thumbnail-body hide">
594
+ ${await InputFile.instance(
595
+ {
596
+ id: idThumbnail,
597
+ multiple: false,
598
+ extensionsAccept: ['image/png', 'image/jpeg'],
599
+ },
600
+ {
601
+ change: (e) => {
602
+ const file = e.target.files[0];
603
+ if (file) {
604
+ InstanceEngineCyberia.thumbnailDirty = true;
605
+ const url = URL.createObjectURL(file);
606
+ const preview = s('.instance-engine-thumbnail-preview');
607
+ if (preview)
608
+ preview.innerHTML = html`<img
609
+ src="${url}"
610
+ class="in"
611
+ style="max-width:300px;height:auto;border:1px solid #555;margin:auto"
612
+ />`;
613
+ }
614
+ },
615
+ clear: () => {
616
+ InstanceEngineCyberia.thumbnailDirty = true;
617
+ InstanceEngineCyberia.currentThumbnailId = null;
618
+ const preview = s('.instance-engine-thumbnail-preview');
619
+ if (preview) preview.innerHTML = '';
620
+ },
621
+ },
622
+ )}
623
+ </div>
624
+ </div>
625
+ <div class="in section-mp" style="margin-top: 10px;">
626
+ ${await DropDown.instance({
627
+ id: idMapCodesDropdown,
628
+ label: html`Cyberia Map Codes`,
629
+ data: [],
630
+ type: 'checkbox',
631
+ containerClass: 'inl',
632
+ excludeSelected: true,
633
+ serviceProvider: async (q) => {
634
+ const result = await CyberiaMapService.searchCodes({ q });
635
+ if (result.status === 'success' && result.data?.codes) {
636
+ return result.data.codes.map((code) => ({
637
+ value: code,
638
+ display: code,
639
+ data: code,
640
+ onClick: () => {},
641
+ }));
642
+ }
643
+ return [];
644
+ },
645
+ })}
646
+ </div>
647
+ <div class="in section-mp" style="margin-top: 10px;">${await InstanceEngineCyberia.buildItemIdsDropdown()}</div>
648
+ <div class="in section-mp" style="margin-top: 10px;">
649
+ <div class="in input-label" style="font-size:14px;margin-bottom:5px;">Portals</div>
650
+ ${dynamicCol({ containerSelector: 'instance-engine-container', id: dcPortalSource, type: 'search-inputs' })}
651
+ <div class="fl">
652
+ <div class="in fll ${dcPortalSource}-col-a">
653
+ ${await Input.instance({
654
+ id: idSourceMapCode,
655
+ label: html`Source Map Code`,
656
+ containerClass: 'inl',
657
+ type: 'text',
658
+ })}
659
+ </div>
660
+ <div class="in fll ${dcPortalSource}-col-b">
661
+ ${await Input.instance({
662
+ id: idSourceCellX,
663
+ label: html`Source Cell X`,
664
+ containerClass: 'inl',
665
+ type: 'number',
666
+ min: 0,
667
+ value: 0,
668
+ })}
669
+ </div>
670
+ <div class="in fll ${dcPortalSource}-col-c">
671
+ ${await Input.instance({
672
+ id: idSourceCellY,
673
+ label: html`Source Cell Y`,
674
+ containerClass: 'inl',
675
+ type: 'number',
676
+ min: 0,
677
+ value: 0,
678
+ })}
679
+ </div>
680
+ </div>
681
+ ${dynamicCol({ containerSelector: 'instance-engine-container', id: dcPortalTarget, type: 'search-inputs' })}
682
+ <div class="fl">
683
+ <div class="in fll ${dcPortalTarget}-col-a">
684
+ ${await Input.instance({
685
+ id: idTargetMapCode,
686
+ label: html`Target Map Code`,
687
+ containerClass: 'inl',
688
+ type: 'text',
689
+ })}
690
+ </div>
691
+ <div class="in fll ${dcPortalTarget}-col-b">
692
+ ${await Input.instance({
693
+ id: idTargetCellX,
694
+ label: html`Target Cell X`,
695
+ containerClass: 'inl',
696
+ type: 'number',
697
+ min: 0,
698
+ value: 0,
699
+ })}
700
+ </div>
701
+ <div class="in fll ${dcPortalTarget}-col-c">
702
+ ${await Input.instance({
703
+ id: idTargetCellY,
704
+ label: html`Target Cell Y`,
705
+ containerClass: 'inl',
706
+ type: 'number',
707
+ min: 0,
708
+ value: 0,
709
+ })}
710
+ </div>
711
+ </div>
712
+ <div class="in" style="display:flex;gap:5px;flex-wrap:wrap;">
713
+ ${await BtnIcon.instance({
714
+ class: 'wfa btn-instance-engine-add-portal',
715
+ label: html`<i class="fa-solid fa-plus"></i> Add Portal`,
716
+ })}
717
+ ${await BtnIcon.instance({
718
+ class: 'wfa btn-instance-engine-portal-connect',
719
+ label: html`<i class="fa-solid fa-circle-nodes"></i> Portal Connector`,
720
+ })}
721
+ </div>
722
+ <div class="in" style="margin-top: 10px;">
723
+ ${await BtnIcon.instance({
724
+ class: 'wfa btn-instance-engine-toggle-portal-filter',
725
+ label: html`<i class="fa-solid fa-caret-right instance-engine-portal-filter-caret"></i> Filters`,
726
+ })}
727
+ <div class="in instance-engine-portal-filter-body hide">
728
+ ${dynamicCol({ containerSelector: 'instance-engine-container', id: dcPortalFilter, type: 'a-50-b-50' })}
729
+ <div class="fl">
730
+ <div class="in fll ${dcPortalFilter}-col-a">
731
+ ${await Input.instance({
732
+ id: idFilterSource,
733
+ label: html`Source Map Code`,
734
+ containerClass: 'inl',
735
+ type: 'text',
736
+ placeholder: true,
737
+ })}
738
+ </div>
739
+ <div class="in fll ${dcPortalFilter}-col-b">
740
+ ${await Input.instance({
741
+ id: idFilterTarget,
742
+ label: html`Target Map Code`,
743
+ containerClass: 'inl',
744
+ type: 'text',
745
+ placeholder: true,
746
+ })}
747
+ </div>
748
+ </div>
749
+ <div class="in" style="margin-top:5px;">
750
+ ${await BtnIcon.instance({
751
+ class: 'wfa btn-instance-engine-clear-portal-filter',
752
+ label: html`<i class="fa-solid fa-broom"></i> Clear Filters`,
753
+ })}
754
+ </div>
755
+ </div>
756
+ </div>
757
+ <div class="in ${portalListId}" style="margin-top: 10px; max-height: 200px; overflow-y: auto;"></div>
758
+ </div>
759
+ <div class="in section-mp" style="margin-top: 10px;">
760
+ ${dynamicCol({ containerSelector: 'instance-engine-container', id: dcSaveNew, type: 'a-50-b-50' })}
761
+ <div class="fl">
762
+ <div class="in fll ${dcSaveNew}-col-a" style="padding: 5px;">
763
+ ${await BtnIcon.instance({
764
+ class: 'wfa btn-instance-engine-save',
765
+ label: html`<i class="fa-solid fa-floppy-disk"></i> Save Instance`,
766
+ })}
767
+ </div>
768
+ <div class="in fll ${dcSaveNew}-col-b" style="padding: 5px;">
769
+ ${await BtnIcon.instance({
770
+ class: 'wfa btn-instance-engine-new',
771
+ label: html`<i class="fa-solid fa-file"></i> New Instance`,
772
+ })}
773
+ </div>
774
+ </div>
775
+ <div class="in" style="margin-top: 10px;">${managementTableHtml}</div>
776
+ </div>
777
+ </div>`;
778
+ }
779
+ }
780
+
781
+ export { InstanceEngineCyberia };