agmon 0.2.0 → 0.2.2
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.
- package/.next/BUILD_ID +1 -1
- package/.next/build-manifest.json +3 -3
- package/.next/fallback-build-manifest.json +3 -3
- package/.next/prerender-manifest.json +8 -8
- package/.next/server/app/_global-error.html +1 -1
- package/.next/server/app/_global-error.rsc +1 -1
- package/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/server/app/_not-found.html +1 -1
- package/.next/server/app/_not-found.rsc +15 -13
- package/.next/server/app/_not-found.segments/_full.segment.rsc +15 -13
- package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +8 -6
- package/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/api/media/route.js.nft.json +1 -1
- package/.next/server/app/api/reports/tokens/route.js.nft.json +1 -1
- package/.next/server/app/api/sessions/[id]/transcript/route.js +1 -1
- package/.next/server/app/api/sessions/[id]/transcript/route.js.nft.json +1 -1
- package/.next/server/app/api/traces/stream/route.js +1 -1
- package/.next/server/app/api/traces/stream/route.js.nft.json +1 -1
- package/.next/server/app/api/version/route.js.nft.json +1 -1
- package/.next/server/app/api/workspace/file-content/route.js.nft.json +1 -1
- package/.next/server/app/api/workspace/files/route.js.nft.json +1 -1
- package/.next/server/app/chat/page.js.nft.json +1 -1
- package/.next/server/app/chat/page_client-reference-manifest.js +1 -1
- package/.next/server/app/chat.html +1 -1
- package/.next/server/app/chat.rsc +20 -19
- package/.next/server/app/chat.segments/_full.segment.rsc +20 -19
- package/.next/server/app/chat.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/chat.segments/chat/__PAGE__.segment.rsc +22 -20
- package/.next/server/app/index.html +1 -1
- package/.next/server/app/index.rsc +20 -18
- package/.next/server/app/index.segments/__PAGE__.segment.rsc +10 -9
- package/.next/server/app/index.segments/_full.segment.rsc +20 -18
- package/.next/server/app/index.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/page.js.nft.json +1 -1
- package/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/server/app/reports/page.js.nft.json +1 -1
- package/.next/server/app/reports/page_client-reference-manifest.js +1 -1
- package/.next/server/app/reports.html +1 -1
- package/.next/server/app/reports.rsc +4 -4
- package/.next/server/app/reports.segments/_full.segment.rsc +4 -4
- package/.next/server/app/reports.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/reports.segments/reports/__PAGE__.segment.rsc +6 -5
- package/.next/server/app/store/page.js.nft.json +1 -1
- package/.next/server/app/store/page_client-reference-manifest.js +1 -1
- package/.next/server/app/store.html +1 -1
- package/.next/server/app/store.rsc +5 -5
- package/.next/server/app/store.segments/_full.segment.rsc +5 -5
- package/.next/server/app/store.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/store.segments/store/__PAGE__.segment.rsc +7 -6
- package/.next/server/chunks/[root-of-the-server]__0dw97_pahi8uf._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__0dw97_pahi8uf._.js.map +1 -0
- package/.next/server/chunks/_0ao-_t4jkb46h._.js +2 -2
- package/.next/server/chunks/_0ao-_t4jkb46h._.js.map +1 -1
- package/.next/server/chunks/_1-8ipqazoyrrk._.js +1 -1
- package/.next/server/chunks/_1-8ipqazoyrrk._.js.map +1 -1
- package/.next/server/chunks/ssr/[root-of-the-server]__0i2rbwbkxbdog._.js +3 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__0i2rbwbkxbdog._.js.map +1 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__0qzscpxebh28_._.js +3 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__0qzscpxebh28_._.js.map +1 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__1jwplflwix8wi._.js +427 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__1jwplflwix8wi._.js.map +1 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__1kt7h7bz59mdn._.js +1 -1
- package/.next/server/chunks/ssr/[root-of-the-server]__1kt7h7bz59mdn._.js.map +1 -1
- package/.next/server/chunks/ssr/[root-of-the-server]__1otsvjy81s8my._.js +427 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__1otsvjy81s8my._.js.map +1 -0
- package/.next/server/chunks/ssr/_0e3frtjrk-wi9._.js +3 -0
- package/.next/server/chunks/ssr/_0e3frtjrk-wi9._.js.map +1 -0
- package/.next/server/chunks/ssr/_0h29jdf4relbq._.js +3 -0
- package/.next/server/chunks/ssr/_0h29jdf4relbq._.js.map +1 -0
- package/.next/server/chunks/ssr/_0zel-n0h--cnl._.js +3 -0
- package/.next/server/chunks/ssr/_0zel-n0h--cnl._.js.map +1 -0
- package/.next/server/chunks/ssr/_1487-zi23c5eb._.js +1 -1
- package/.next/server/chunks/ssr/_1487-zi23c5eb._.js.map +1 -1
- package/.next/server/chunks/ssr/_1vgwoe-shb9z7._.js +3 -0
- package/.next/server/chunks/ssr/_1vgwoe-shb9z7._.js.map +1 -0
- package/.next/server/chunks/ssr/_1zm4m-s8k7oe3._.js +3 -0
- package/.next/server/chunks/ssr/_1zm4m-s8k7oe3._.js.map +1 -0
- package/.next/server/chunks/ssr/_202tntue-jj6s._.js +3 -0
- package/.next/server/chunks/ssr/_202tntue-jj6s._.js.map +1 -0
- package/.next/server/chunks/ssr/{node_modules_1wlwrgnt65zus._.js → node_modules_00ebs67b4u61w._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0f773uqgzj7y7._.js → node_modules_01avo0bde3tpo._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0z3elum1675ve._.js → node_modules_01l0208e5kqic._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1c8i3jrmo4393._.js → node_modules_033x29yqle_sj._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1kr1c-ncf8q9t._.js → node_modules_03wbg__aslvui._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_02jwra-d9iqim._.js → node_modules_06mgkab1v5iox._.js} +2 -2
- package/.next/server/chunks/ssr/{node_modules_0z7rdbaf13024._.js → node_modules_08-bqkrz7sh0l._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_13nsmuhey_ti_._.js → node_modules_089w9jm7s2qa3._.js} +2 -2
- package/.next/server/chunks/ssr/{node_modules_0m3ihe65818y_._.js → node_modules_08q6a-f2itxyo._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0__m9_odts7_e._.js → node_modules_0cy47-s63xjzh._.js} +2 -2
- package/.next/server/chunks/ssr/{node_modules_0b8ndnuql44z1._.js → node_modules_0czh0jcnsm5e6._.js} +2 -2
- package/.next/server/chunks/ssr/{node_modules_0fs8mckuwk2tj._.js → node_modules_0e6qoh__e4a69._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_05w7qhtrzvnk6._.js → node_modules_0fv321j1nslkb._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_061uaylfjwqk7._.js → node_modules_0g-wb7h-hsdwc._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1ll-58c1c-qab._.js → node_modules_0hb0q0epwvp--._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0dq0dsblt-q0g._.js → node_modules_0l-y0kqtu_r3o._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1zs2nou5uogby._.js → node_modules_0l814qpw677vm._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1xyxigbqzb8vs._.js → node_modules_0o63z1gd17rhb._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1-sz_-qddwilq._.js → node_modules_0oz_zzlh8exwx._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0oukyh0iq21ow._.js → node_modules_0so2agzqd9p8l._.js} +2 -2
- package/.next/server/chunks/ssr/{node_modules_12qw2ucebdvol._.js → node_modules_0w2w61b8bh769._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1dff7b_kvngr-._.js → node_modules_0wd6szix_zku7._.js} +2 -2
- package/.next/server/chunks/ssr/{node_modules_0fd1swhk15cx3._.js → node_modules_0wp7omf0xblv8._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0nde84kzuwv2n._.js → node_modules_0yayrqhzfk8wy._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0f4xh33v3iltc._.js → node_modules_0zb0i39mnjdf3._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1iovyom0-y7o_._.js → node_modules_10c51o2qv6mbi._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_02nv3yff2pqh8._.js → node_modules_10g1mmrf63d8a._.js} +2 -2
- package/.next/server/chunks/ssr/{node_modules_0-6sb1gkbjo93._.js → node_modules_152txg4c7ose3._.js} +2 -2
- package/.next/server/chunks/ssr/{node_modules_12qn4bepdou5v._.js → node_modules_185fuy4cv7loa._.js} +2 -2
- package/.next/server/chunks/ssr/{node_modules_1-iyhsn_1p9nx._.js → node_modules_19vqq7rvf-_ar._.js} +2 -2
- package/.next/server/chunks/ssr/{node_modules_0hqa9oxz17hip._.js → node_modules_1hd7j-tdb8drq._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1rlnehdn16ay-._.js → node_modules_1hu83gui7_nj2._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_07maxxr-t28ql._.js → node_modules_1i3x2csuq_-jt._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0kovk4b6czb22._.js → node_modules_1j8hpoiygrs5e._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0zc49fdcopqu9._.js → node_modules_1l2g7btuh3e4s._.js} +2 -2
- package/.next/server/chunks/ssr/{node_modules_0t4h1rucl35hl._.js → node_modules_1n4kig4mj6n4s._.js} +2 -2
- package/.next/server/chunks/ssr/{node_modules_0vn0kjn_84lmn._.js → node_modules_1nz3ckv6tu_66._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0-nvg0c4pgfb8._.js → node_modules_1qnypguag6s_l._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1v4lexrfhnlhs._.js → node_modules_1r6w-jlme6d10._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1f4geuvkvlxj1._.js → node_modules_1s8oxeqa5_i3k._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1216007ogd5om._.js → node_modules_1tskcaktx6ods._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_02vtgweceovke._.js → node_modules_1xz1dstlo5ri-._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1kv6lsckqs-m0._.js → node_modules_1zii7uk468cay._.js} +2 -2
- package/.next/server/chunks/ssr/{node_modules_katex_dist_katex_mjs_0bmuudv_6eypr._.js → node_modules_katex_dist_katex_mjs_067omoj5szuys._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_katex_dist_katex_mjs_0qyy6pq9uzpk0._.js → node_modules_katex_dist_katex_mjs_1604s1ky8db8u._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_lucide-react_dist_esm_1d8fezw1qsiob._.js → node_modules_lucide-react_dist_esm_0-5bcc79665lq._.js} +2 -2
- package/.next/server/chunks/ssr/node_modules_lucide-react_dist_esm_0-5bcc79665lq._.js.map +1 -0
- package/.next/server/chunks/ssr/{node_modules_lucide-react_dist_esm_0pezg1352q13j._.js → node_modules_lucide-react_dist_esm_0axoa1eg51x1-._.js} +2 -2
- package/.next/server/chunks/ssr/node_modules_lucide-react_dist_esm_0axoa1eg51x1-._.js.map +1 -0
- package/.next/server/chunks/ssr/{node_modules_lucide-react_dist_esm_131i-tjzse3ye._.js → node_modules_lucide-react_dist_esm_18ei1-na3kusb._.js} +2 -2
- package/.next/server/chunks/ssr/node_modules_lucide-react_dist_esm_18ei1-na3kusb._.js.map +1 -0
- package/.next/server/chunks/ssr/{node_modules_lucide-react_dist_esm_1to-9cv1ysvs6._.js → node_modules_lucide-react_dist_esm_1tx493x2_auzs._.js} +2 -2
- package/.next/server/chunks/ssr/node_modules_lucide-react_dist_esm_1tx493x2_auzs._.js.map +1 -0
- package/.next/server/chunks/ssr/node_modules_mermaid_dist_mermaid_core_mjs_06it7ktosm1dr._.js +3 -0
- package/.next/server/chunks/ssr/node_modules_mermaid_dist_mermaid_core_mjs_06it7ktosm1dr._.js.map +1 -0
- package/.next/server/chunks/ssr/src_app_page_1vqfk0-j72fp6.js +1 -1
- package/.next/server/chunks/ssr/src_app_page_1vqfk0-j72fp6.js.map +1 -1
- package/.next/server/chunks/ssr/src_components_reports_TokenReportView_jsx_1g3p_enbbsadt._.js +1 -1
- package/.next/server/chunks/ssr/src_components_reports_TokenReportView_jsx_1g3p_enbbsadt._.js.map +1 -1
- package/.next/server/middleware-build-manifest.js +3 -3
- package/.next/server/pages/404.html +1 -1
- package/.next/server/pages/500.html +1 -1
- package/.next/server/preview-props.json +3 -3
- package/.next/server/server-reference-manifest.js +1 -1
- package/.next/server/server-reference-manifest.json +1 -1
- package/.next/static/chunks/0jo6fy2c_gmqn.js +1 -0
- package/.next/static/chunks/0r9apkv3exqv-.js +1 -0
- package/.next/static/chunks/1n_lb7wmn81jj.js +1 -0
- package/.next/static/chunks/2-w116ewoshm1.js +1 -0
- package/.next/static/chunks/23uup1e8841av.js +1 -0
- package/.next/static/chunks/2q9cwykv6ox1t.css +1 -0
- package/.next/static/chunks/2rx7xvi55ohln.js +1 -0
- package/.next/static/chunks/2zf44j8sjo0w0.js +425 -0
- package/.next/static/chunks/3rtpnpqd981z9.js +1 -0
- package/.next/trace +1 -1
- package/.next/trace-build +1 -1
- package/bin/cli.js +12 -0
- package/package.json +1 -1
- package/src/app/api/traces/stream/route.js +41 -5
- package/src/app/chat/page.js +14 -14
- package/src/app/globals.css +128 -0
- package/src/app/layout.js +8 -2
- package/src/app/page.js +18 -2
- package/src/components/chat/ChatMessageItem.js +12 -12
- package/src/components/chat/CodeBlock.js +5 -5
- package/src/components/chat/DiffViewer.js +27 -27
- package/src/components/chat/MarkdownRenderer.js +19 -19
- package/src/components/chat/SessionChatView.js +42 -42
- package/src/components/chat/SessionSearch.js +8 -8
- package/src/components/chat/ThinkingAccordion.js +3 -3
- package/src/components/chat/ToolCallCard.js +6 -6
- package/src/components/chat/ToolOutputView.js +19 -19
- package/src/components/factory/office-canvas.js +165 -3
- package/src/components/factory/scene/characters.js +267 -32
- package/src/components/layout/BottomPanel.jsx +6 -6
- package/src/components/layout/CommandPalette.jsx +12 -0
- package/src/components/layout/EditorTabs.jsx +17 -0
- package/src/components/layout/LayoutToggles.jsx +31 -2
- package/src/components/layout/LeftSidebar.jsx +88 -6
- package/src/components/layout/RightSidebar.jsx +8 -8
- package/src/components/layout/StatusBar.jsx +1 -1
- package/src/components/layout/TitleBar.jsx +76 -2
- package/src/components/layout/VSCodeWorkbench.jsx +99 -14
- package/src/components/store/Item3DRenderer.jsx +602 -48
- package/src/components/store/LiveFittingRoom.jsx +55 -791
- package/src/components/store/LiveReactAgent.jsx +1637 -0
- package/src/components/store/SupporterStoreModal.jsx +3 -2
- package/src/components/store/SupporterStoreView.jsx +94 -34
- package/src/components/theme/ThemeSettingsModal.jsx +40 -40
- package/src/components/ui/Button.jsx +4 -4
- package/src/components/ui/Input.jsx +1 -1
- package/src/components/ui/Modal.jsx +6 -6
- package/src/components/ui/Select.jsx +3 -3
- package/src/lib/catalog/auras.js +226 -1199
- package/src/lib/catalog/index.js +60 -1
- package/src/lib/catalog/pets.js +291 -2398
- package/src/lib/catalog/props.js +488 -4199
- package/src/lib/catalog/skins.js +773 -3249
- package/src/lib/catalog/trophies.js +226 -1199
- package/src/lib/mockTraces.js +28 -26
- package/src/lib/parsers/codexParser.js +373 -0
- package/src/lib/parsers/transcriptParser.js +35 -3
- package/src/lib/supporterStore.js +1 -1
- package/src/lib/traceContract.js +1 -1
- package/src/lib/useFactoryTraces.js +70 -5
- package/src/lib/watchers/antigravityWatcher.js +15 -1
- package/src/lib/watchers/claudeWatcher.js +86 -70
- package/src/lib/watchers/codexWatcher.js +482 -0
- package/src/lib/watchers/watcherManager.js +46 -30
- package/.next/server/chunks/src_lib_watchers_antigravityWatcher_0w1-atg39y__p.js +0 -3
- package/.next/server/chunks/src_lib_watchers_antigravityWatcher_0w1-atg39y__p.js.map +0 -1
- package/.next/server/chunks/ssr/[root-of-the-server]__19s2v5rryc14o._.js +0 -3
- package/.next/server/chunks/ssr/[root-of-the-server]__19s2v5rryc14o._.js.map +0 -1
- package/.next/server/chunks/ssr/[root-of-the-server]__1_jerxrctq6ev._.js +0 -427
- package/.next/server/chunks/ssr/[root-of-the-server]__1_jerxrctq6ev._.js.map +0 -1
- package/.next/server/chunks/ssr/[root-of-the-server]__1pvso-uyf--97._.js +0 -427
- package/.next/server/chunks/ssr/[root-of-the-server]__1pvso-uyf--97._.js.map +0 -1
- package/.next/server/chunks/ssr/[root-of-the-server]__1y78dc7oiz7ks._.js +0 -3
- package/.next/server/chunks/ssr/[root-of-the-server]__1y78dc7oiz7ks._.js.map +0 -1
- package/.next/server/chunks/ssr/_0ozao7omdwbvd._.js +0 -3
- package/.next/server/chunks/ssr/_0ozao7omdwbvd._.js.map +0 -1
- package/.next/server/chunks/ssr/_0rcmpdyxc1qwj._.js +0 -3
- package/.next/server/chunks/ssr/_0rcmpdyxc1qwj._.js.map +0 -1
- package/.next/server/chunks/ssr/_0wv0xnhun3mk7._.js +0 -3
- package/.next/server/chunks/ssr/_0wv0xnhun3mk7._.js.map +0 -1
- package/.next/server/chunks/ssr/_17rmaft1zusua._.js +0 -3
- package/.next/server/chunks/ssr/_17rmaft1zusua._.js.map +0 -1
- package/.next/server/chunks/ssr/_1e-d4pcj59a7a._.js +0 -3
- package/.next/server/chunks/ssr/_1e-d4pcj59a7a._.js.map +0 -1
- package/.next/server/chunks/ssr/_1qr5gnh64z8pg._.js +0 -3
- package/.next/server/chunks/ssr/_1qr5gnh64z8pg._.js.map +0 -1
- package/.next/server/chunks/ssr/node_modules_lucide-react_dist_esm_0pezg1352q13j._.js.map +0 -1
- package/.next/server/chunks/ssr/node_modules_lucide-react_dist_esm_131i-tjzse3ye._.js.map +0 -1
- package/.next/server/chunks/ssr/node_modules_lucide-react_dist_esm_1d8fezw1qsiob._.js.map +0 -1
- package/.next/server/chunks/ssr/node_modules_lucide-react_dist_esm_1to-9cv1ysvs6._.js.map +0 -1
- package/.next/static/chunks/0_3s_e4gd9xl0.js +0 -1
- package/.next/static/chunks/0i4kx4yl-dwfg.js +0 -425
- package/.next/static/chunks/0z0jbobmmvqoc.js +0 -1
- package/.next/static/chunks/1_a_gmob5qzho.js +0 -1
- package/.next/static/chunks/1ifqr4qo4697b.js +0 -1
- package/.next/static/chunks/2ccq9i8ev4dsx.js +0 -1
- package/.next/static/chunks/2mif7onk_9jy-.css +0 -1
- package/.next/static/chunks/40wyf-mv0tiu3.js +0 -1
- /package/.next/server/chunks/ssr/{node_modules_1c8i3jrmo4393._.js.map → node_modules_00ebs67b4u61w._.js.map} +0 -0
- /package/.next/server/chunks/ssr/{node_modules_0f773uqgzj7y7._.js.map → node_modules_01avo0bde3tpo._.js.map} +0 -0
- /package/.next/server/chunks/ssr/{node_modules_0z3elum1675ve._.js.map → node_modules_01l0208e5kqic._.js.map} +0 -0
- /package/.next/server/chunks/ssr/{node_modules_1wlwrgnt65zus._.js.map → node_modules_033x29yqle_sj._.js.map} +0 -0
- /package/.next/server/chunks/ssr/{node_modules_1kr1c-ncf8q9t._.js.map → node_modules_03wbg__aslvui._.js.map} +0 -0
- /package/.next/server/chunks/ssr/{node_modules_02jwra-d9iqim._.js.map → node_modules_06mgkab1v5iox._.js.map} +0 -0
- /package/.next/server/chunks/ssr/{node_modules_0fs8mckuwk2tj._.js.map → node_modules_08-bqkrz7sh0l._.js.map} +0 -0
- /package/.next/server/chunks/ssr/{node_modules_0-6sb1gkbjo93._.js.map → node_modules_089w9jm7s2qa3._.js.map} +0 -0
- /package/.next/server/chunks/ssr/{node_modules_02vtgweceovke._.js.map → node_modules_08q6a-f2itxyo._.js.map} +0 -0
- /package/.next/server/chunks/ssr/{node_modules_0__m9_odts7_e._.js.map → node_modules_0cy47-s63xjzh._.js.map} +0 -0
- /package/.next/server/chunks/ssr/{node_modules_02nv3yff2pqh8._.js.map → node_modules_0czh0jcnsm5e6._.js.map} +0 -0
- /package/.next/server/chunks/ssr/{node_modules_0z7rdbaf13024._.js.map → node_modules_0e6qoh__e4a69._.js.map} +0 -0
- /package/.next/server/chunks/ssr/{node_modules_0-nvg0c4pgfb8._.js.map → node_modules_0fv321j1nslkb._.js.map} +0 -0
- /package/.next/server/chunks/ssr/{node_modules_061uaylfjwqk7._.js.map → node_modules_0g-wb7h-hsdwc._.js.map} +0 -0
- /package/.next/server/chunks/ssr/{node_modules_0t4h1rucl35hl._.js.map → node_modules_0hb0q0epwvp--._.js.map} +0 -0
- /package/.next/server/chunks/ssr/{node_modules_0dq0dsblt-q0g._.js.map → node_modules_0l-y0kqtu_r3o._.js.map} +0 -0
- /package/.next/server/chunks/ssr/{node_modules_0zc49fdcopqu9._.js.map → node_modules_0l814qpw677vm._.js.map} +0 -0
- /package/.next/server/chunks/ssr/{node_modules_1xyxigbqzb8vs._.js.map → node_modules_0o63z1gd17rhb._.js.map} +0 -0
- /package/.next/server/chunks/ssr/{node_modules_1-iyhsn_1p9nx._.js.map → node_modules_0oz_zzlh8exwx._.js.map} +0 -0
- /package/.next/server/chunks/ssr/{node_modules_0oukyh0iq21ow._.js.map → node_modules_0so2agzqd9p8l._.js.map} +0 -0
- /package/.next/server/chunks/ssr/{node_modules_07maxxr-t28ql._.js.map → node_modules_0w2w61b8bh769._.js.map} +0 -0
- /package/.next/server/chunks/ssr/{node_modules_1dff7b_kvngr-._.js.map → node_modules_0wd6szix_zku7._.js.map} +0 -0
- /package/.next/server/chunks/ssr/{node_modules_0fd1swhk15cx3._.js.map → node_modules_0wp7omf0xblv8._.js.map} +0 -0
- /package/.next/server/chunks/ssr/{node_modules_0nde84kzuwv2n._.js.map → node_modules_0yayrqhzfk8wy._.js.map} +0 -0
- /package/.next/server/chunks/ssr/{node_modules_0f4xh33v3iltc._.js.map → node_modules_0zb0i39mnjdf3._.js.map} +0 -0
- /package/.next/server/chunks/ssr/{node_modules_1-sz_-qddwilq._.js.map → node_modules_10c51o2qv6mbi._.js.map} +0 -0
- /package/.next/server/chunks/ssr/{node_modules_0b8ndnuql44z1._.js.map → node_modules_10g1mmrf63d8a._.js.map} +0 -0
- /package/.next/server/chunks/ssr/{node_modules_13nsmuhey_ti_._.js.map → node_modules_152txg4c7ose3._.js.map} +0 -0
- /package/.next/server/chunks/ssr/{node_modules_12qn4bepdou5v._.js.map → node_modules_185fuy4cv7loa._.js.map} +0 -0
- /package/.next/server/chunks/ssr/{node_modules_1iovyom0-y7o_._.js.map → node_modules_19vqq7rvf-_ar._.js.map} +0 -0
- /package/.next/server/chunks/ssr/{node_modules_0hqa9oxz17hip._.js.map → node_modules_1hd7j-tdb8drq._.js.map} +0 -0
- /package/.next/server/chunks/ssr/{node_modules_1rlnehdn16ay-._.js.map → node_modules_1hu83gui7_nj2._.js.map} +0 -0
- /package/.next/server/chunks/ssr/{node_modules_12qw2ucebdvol._.js.map → node_modules_1i3x2csuq_-jt._.js.map} +0 -0
- /package/.next/server/chunks/ssr/{node_modules_0kovk4b6czb22._.js.map → node_modules_1j8hpoiygrs5e._.js.map} +0 -0
- /package/.next/server/chunks/ssr/{node_modules_1ll-58c1c-qab._.js.map → node_modules_1l2g7btuh3e4s._.js.map} +0 -0
- /package/.next/server/chunks/ssr/{node_modules_1zs2nou5uogby._.js.map → node_modules_1n4kig4mj6n4s._.js.map} +0 -0
- /package/.next/server/chunks/ssr/{node_modules_0vn0kjn_84lmn._.js.map → node_modules_1nz3ckv6tu_66._.js.map} +0 -0
- /package/.next/server/chunks/ssr/{node_modules_05w7qhtrzvnk6._.js.map → node_modules_1qnypguag6s_l._.js.map} +0 -0
- /package/.next/server/chunks/ssr/{node_modules_1v4lexrfhnlhs._.js.map → node_modules_1r6w-jlme6d10._.js.map} +0 -0
- /package/.next/server/chunks/ssr/{node_modules_1f4geuvkvlxj1._.js.map → node_modules_1s8oxeqa5_i3k._.js.map} +0 -0
- /package/.next/server/chunks/ssr/{node_modules_1216007ogd5om._.js.map → node_modules_1tskcaktx6ods._.js.map} +0 -0
- /package/.next/server/chunks/ssr/{node_modules_0m3ihe65818y_._.js.map → node_modules_1xz1dstlo5ri-._.js.map} +0 -0
- /package/.next/server/chunks/ssr/{node_modules_1kv6lsckqs-m0._.js.map → node_modules_1zii7uk468cay._.js.map} +0 -0
- /package/.next/server/chunks/ssr/{node_modules_katex_dist_katex_mjs_0bmuudv_6eypr._.js.map → node_modules_katex_dist_katex_mjs_067omoj5szuys._.js.map} +0 -0
- /package/.next/server/chunks/ssr/{node_modules_katex_dist_katex_mjs_0qyy6pq9uzpk0._.js.map → node_modules_katex_dist_katex_mjs_1604s1ky8db8u._.js.map} +0 -0
- /package/.next/static/{sQnXeiP8rV6y2v0az_xw3 → dGN2VKPk5TJgezxS3JvRc}/_buildManifest.js +0 -0
- /package/.next/static/{sQnXeiP8rV6y2v0az_xw3 → dGN2VKPk5TJgezxS3JvRc}/_clientMiddlewareManifest.js +0 -0
- /package/.next/static/{sQnXeiP8rV6y2v0az_xw3 → dGN2VKPk5TJgezxS3JvRc}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,1637 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import React, { useRef, useEffect, useMemo } from "react";
|
|
4
|
+
import { getItemById, COSMETIC_CATALOG } from "@/lib/catalog/index.js";
|
|
5
|
+
|
|
6
|
+
// Floor theme color palettes
|
|
7
|
+
const THEME_STYLES = {
|
|
8
|
+
theme_default: { name: "Classic Charcoal Slate", base: "#14161a", tile: "#1e222b", grid: "#2d3548", glow: "#38bdf8" },
|
|
9
|
+
theme_cyberpunk: { name: "Cyberpunk Neon Night", base: "#0d0819", tile: "#1c0d33", grid: "#ff2a85", glow: "#00f0ff" },
|
|
10
|
+
theme_matrix: { name: "Phosphor Matrix Terminal", base: "#020d05", tile: "#051f0b", grid: "#00ff66", glow: "#10b981" },
|
|
11
|
+
theme_wood: { name: "Cozy Scandinavian Loft", base: "#1f1610", tile: "#2c2017", grid: "#451a03", glow: "#f59e0b" },
|
|
12
|
+
theme_space: { name: "Deep Space Void", base: "#030712", tile: "#0b1329", grid: "#1e1b4b", glow: "#6366f1" },
|
|
13
|
+
theme_blueprint: { name: "Blueprint CAD Grid", base: "#0b1a30", tile: "#1e3a8a", grid: "#1d4ed8", glow: "#38bdf8" },
|
|
14
|
+
theme_synthwave: { name: "Retro Synthwave 80s", base: "#1a052e", tile: "#3b0764", grid: "#d946ef", glow: "#ec4899" },
|
|
15
|
+
theme_sakura_cyber: { name: "Sakura Cyber Garden", base: "#1c0e18", tile: "#2e1022", grid: "#f43f5e", glow: "#fb7185" },
|
|
16
|
+
theme_nordic_ice: { name: "Minimalist Nordic Ice", base: "#0f172a", tile: "#1e293b", grid: "#38bdf8", glow: "#e2e8f0" },
|
|
17
|
+
theme_industrial: { name: "High-Voltage Industrial", base: "#18181b", tile: "#27272a", grid: "#eab308", glow: "#f59e0b" },
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* 50 Curated High-Fidelity Silhouette & Accessory Variations
|
|
22
|
+
*/
|
|
23
|
+
function RenderSkinAccessories({ variant, archetype, color, secondaryColor, accentColor }) {
|
|
24
|
+
// 1. CYBER SUIT VARIANTS (10)
|
|
25
|
+
if (variant === "tactical_visor") {
|
|
26
|
+
return (
|
|
27
|
+
<g>
|
|
28
|
+
<polygon points="-26,-66 -34,-76 -26,-72" fill={color} />
|
|
29
|
+
<polygon points="26,-66 34,-76 26,-72" fill={color} />
|
|
30
|
+
<rect x="-24" y="-66" width="48" height="6" rx="2" fill={color} />
|
|
31
|
+
<circle cx="0" cy="-63" r="2.5" fill={accentColor} />
|
|
32
|
+
</g>
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
if (variant === "laser_scout") {
|
|
36
|
+
return (
|
|
37
|
+
<g>
|
|
38
|
+
<circle cx="8" cy="-57" r="7" fill="none" stroke={color} strokeWidth="1.8" />
|
|
39
|
+
<line x1="8" y1="-66" x2="8" y2="-48" stroke={color} strokeWidth="1" strokeDasharray="1 2" />
|
|
40
|
+
<line x1="-1" y1="-57" x2="17" y2="-57" stroke={color} strokeWidth="1" strokeDasharray="1 2" />
|
|
41
|
+
<circle cx="8" cy="-57" r="2" fill="#ff0000" />
|
|
42
|
+
</g>
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
if (variant === "riot_shield") {
|
|
46
|
+
return (
|
|
47
|
+
<g>
|
|
48
|
+
<rect x="-25" y="-68" width="50" height="9" rx="3" fill="#1e2430" stroke={color} strokeWidth="1.8" />
|
|
49
|
+
<rect x="-20" y="-34" width="40" height="6" rx="2" fill={color} />
|
|
50
|
+
<circle cx="-16" cy="-64" r="2.5" fill={accentColor} />
|
|
51
|
+
<circle cx="16" cy="-64" r="2.5" fill={accentColor} />
|
|
52
|
+
</g>
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
if (variant === "cyber_horns") {
|
|
56
|
+
return (
|
|
57
|
+
<g>
|
|
58
|
+
<polygon points="-20,-70 -30,-88 -14,-76" fill={color} stroke={secondaryColor} strokeWidth="1" />
|
|
59
|
+
<polygon points="20,-70 30,-88 14,-76" fill={color} stroke={secondaryColor} strokeWidth="1" />
|
|
60
|
+
<line x1="-17" y1="-73" x2="-25" y2="-82" stroke={accentColor} strokeWidth="1.5" />
|
|
61
|
+
<line x1="17" y1="-73" x2="25" y2="-82" stroke={accentColor} strokeWidth="1.5" />
|
|
62
|
+
</g>
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
if (variant === "crown_radiator") {
|
|
66
|
+
return (
|
|
67
|
+
<g fill={color}>
|
|
68
|
+
<polygon points="-16,-72 -14,-86 -8,-74" />
|
|
69
|
+
<polygon points="-4,-74 0,-92 4,-74" />
|
|
70
|
+
<polygon points="8,-74 14,-86 16,-72" />
|
|
71
|
+
<circle cx="0" cy="-70" r="3" fill={accentColor} />
|
|
72
|
+
</g>
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
if (variant === "gas_respirator") {
|
|
76
|
+
return (
|
|
77
|
+
<g>
|
|
78
|
+
<circle cx="-14" cy="-44" r="6" fill="#1e2430" stroke={color} strokeWidth="1.5" />
|
|
79
|
+
<circle cx="14" cy="-44" r="6" fill="#1e2430" stroke={color} strokeWidth="1.5" />
|
|
80
|
+
<circle cx="-14" cy="-44" r="3" fill={color} />
|
|
81
|
+
<circle cx="14" cy="-44" r="3" fill={color} />
|
|
82
|
+
<rect x="-8" y="-46" width="16" height="5" fill="#111827" stroke={color} strokeWidth="1" />
|
|
83
|
+
</g>
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
if (variant === "prism_goggles") {
|
|
87
|
+
return (
|
|
88
|
+
<g>
|
|
89
|
+
<polygon points="-16,-62 -8,-66 -2,-62 -2,-52 -8,-48 -16,-52" fill="#0c4a6e" stroke={color} strokeWidth="1.6" />
|
|
90
|
+
<polygon points="2,-62 8,-66 16,-62 16,-52 8,-48 2,-52" fill="#0c4a6e" stroke={color} strokeWidth="1.6" />
|
|
91
|
+
<circle cx="-9" cy="-57" r="2.5" fill={accentColor} />
|
|
92
|
+
<circle cx="9" cy="-57" r="2.5" fill={accentColor} />
|
|
93
|
+
</g>
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
if (variant === "samurai_crest") {
|
|
97
|
+
return (
|
|
98
|
+
<g>
|
|
99
|
+
<path d="M -22 -72 Q 0 -92 22 -72 Q 0 -84 -22 -72 Z" fill={color} stroke={secondaryColor} strokeWidth="1" />
|
|
100
|
+
<circle cx="0" cy="-78" r="3" fill={accentColor} />
|
|
101
|
+
</g>
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
if (variant === "overdrive_vents") {
|
|
105
|
+
return (
|
|
106
|
+
<g strokeLinecap="round">
|
|
107
|
+
<line x1="-18" y1="-72" x2="-28" y2="-90" stroke={color} strokeWidth="3" />
|
|
108
|
+
<line x1="18" y1="-72" x2="28" y2="-90" stroke={color} strokeWidth="3" />
|
|
109
|
+
<line x1="-12" y1="-70" x2="-20" y2="-84" stroke={accentColor} strokeWidth="2" />
|
|
110
|
+
<line x1="12" y1="-70" x2="20" y2="-84" stroke={accentColor} strokeWidth="2" />
|
|
111
|
+
</g>
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
if (variant === "holo_shroud") {
|
|
115
|
+
return (
|
|
116
|
+
<g>
|
|
117
|
+
<ellipse cx="0" cy="-66" rx="28" ry="12" fill="none" stroke={color} strokeWidth="1.8" strokeDasharray="4 2" />
|
|
118
|
+
<circle cx="0" cy="-78" r="4" fill={accentColor} />
|
|
119
|
+
</g>
|
|
120
|
+
);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// 2. MECHA PILOT VARIANTS (10)
|
|
124
|
+
if (variant === "v_fin") {
|
|
125
|
+
return (
|
|
126
|
+
<g>
|
|
127
|
+
<polygon points="-24,-88 -18,-92 0,-76 18,-92 24,-88 0,-72" fill={color} stroke={secondaryColor} strokeWidth="1" />
|
|
128
|
+
<polygon points="-4,-72 0,-78 4,-72 0,-68" fill="#ef4444" />
|
|
129
|
+
</g>
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
if (variant === "blast_shield") {
|
|
133
|
+
return (
|
|
134
|
+
<g>
|
|
135
|
+
<rect x="-24" y="-68" width="48" height="14" rx="3" fill="#0f172a" stroke={color} strokeWidth="2" />
|
|
136
|
+
<circle cx="-18" cy="-80" r="3.5" fill="#fde047" stroke={color} strokeWidth="1" />
|
|
137
|
+
<circle cx="18" cy="-80" r="3.5" fill="#fde047" stroke={color} strokeWidth="1" />
|
|
138
|
+
</g>
|
|
139
|
+
);
|
|
140
|
+
}
|
|
141
|
+
if (variant === "eva_horn") {
|
|
142
|
+
return (
|
|
143
|
+
<g>
|
|
144
|
+
<polygon points="-3,-74 0,-98 3,-74" fill={color} stroke={secondaryColor} strokeWidth="1" />
|
|
145
|
+
<rect x="-28" y="-48" width="5" height="18" rx="2" fill={color} stroke={secondaryColor} strokeWidth="1" />
|
|
146
|
+
<rect x="23" y="-48" width="5" height="18" rx="2" fill={color} stroke={secondaryColor} strokeWidth="1" />
|
|
147
|
+
</g>
|
|
148
|
+
);
|
|
149
|
+
}
|
|
150
|
+
if (variant === "cage_grille") {
|
|
151
|
+
return (
|
|
152
|
+
<g>
|
|
153
|
+
<rect x="-16" y="-52" width="32" height="14" rx="2" fill="#18181b" stroke={color} strokeWidth="1.6" />
|
|
154
|
+
<line x1="-10" y1="-52" x2="-10" y2="-38" stroke={color} strokeWidth="1.2" />
|
|
155
|
+
<line x1="-4" y1="-52" x2="-4" y2="-38" stroke={color} strokeWidth="1.2" />
|
|
156
|
+
<line x1="4" y1="-52" x2="4" y2="-38" stroke={color} strokeWidth="1.2" />
|
|
157
|
+
<line x1="10" y1="-52" x2="10" y2="-38" stroke={color} strokeWidth="1.2" />
|
|
158
|
+
<rect x="-22" y="-86" width="4" height="16" fill="#27272a" stroke={color} strokeWidth="1" />
|
|
159
|
+
<rect x="18" y="-86" width="4" height="16" fill="#27272a" stroke={color} strokeWidth="1" />
|
|
160
|
+
</g>
|
|
161
|
+
);
|
|
162
|
+
}
|
|
163
|
+
if (variant === "missile_pod") {
|
|
164
|
+
return (
|
|
165
|
+
<g>
|
|
166
|
+
<rect x="-30" y="-42" width="8" height="12" rx="2" fill="#1c1917" stroke={color} strokeWidth="1.5" />
|
|
167
|
+
<circle cx="-26" cy="-38" r="1.5" fill="#ef4444" />
|
|
168
|
+
<circle cx="-26" cy="-34" r="1.5" fill="#ef4444" />
|
|
169
|
+
<rect x="22" y="-42" width="8" height="12" rx="2" fill="#1c1917" stroke={color} strokeWidth="1.5" />
|
|
170
|
+
<circle cx="26" cy="-38" r="1.5" fill="#ef4444" />
|
|
171
|
+
<circle cx="26" cy="-34" r="1.5" fill="#ef4444" />
|
|
172
|
+
</g>
|
|
173
|
+
);
|
|
174
|
+
}
|
|
175
|
+
if (variant === "quad_array") {
|
|
176
|
+
return (
|
|
177
|
+
<g stroke={color} strokeWidth="1.8">
|
|
178
|
+
<line x1="-22" y1="-72" x2="-26" y2="-90" />
|
|
179
|
+
<line x1="-12" y1="-76" x2="-14" y2="-94" />
|
|
180
|
+
<line x1="12" y1="-76" x2="14" y2="-94" />
|
|
181
|
+
<line x1="22" y1="-72" x2="26" y2="-90" />
|
|
182
|
+
<circle cx="-26" cy="-90" r="2" fill={accentColor} stroke="none" />
|
|
183
|
+
<circle cx="-14" cy="-94" r="2" fill={accentColor} stroke="none" />
|
|
184
|
+
<circle cx="14" cy="-94" r="2" fill={accentColor} stroke="none" />
|
|
185
|
+
<circle cx="26" cy="-90" r="2" fill={accentColor} stroke="none" />
|
|
186
|
+
</g>
|
|
187
|
+
);
|
|
188
|
+
}
|
|
189
|
+
if (variant === "halo_shield") {
|
|
190
|
+
return (
|
|
191
|
+
<g>
|
|
192
|
+
<polygon points="-32,-42 -26,-46 -20,-42 -20,-34 -26,-30 -32,-34" fill="#064e3b" stroke={color} strokeWidth="1.5" />
|
|
193
|
+
<polygon points="20,-42 26,-46 32,-42 32,-34 26,-30 20,-34" fill="#064e3b" stroke={color} strokeWidth="1.5" />
|
|
194
|
+
</g>
|
|
195
|
+
);
|
|
196
|
+
}
|
|
197
|
+
if (variant === "ram_horns") {
|
|
198
|
+
return (
|
|
199
|
+
<g>
|
|
200
|
+
<path d="M -18 -72 C -34 -82, -32 -96, -18 -92 C -24 -88, -24 -78, -14 -72 Z" fill={color} stroke={secondaryColor} strokeWidth="1" />
|
|
201
|
+
<path d="M 18 -72 C 34 -82, 32 -96, 18 -92 C 24 -88, 24 -78, 14 -72 Z" fill={color} stroke={secondaryColor} strokeWidth="1" />
|
|
202
|
+
</g>
|
|
203
|
+
);
|
|
204
|
+
}
|
|
205
|
+
if (variant === "radar_dish") {
|
|
206
|
+
return (
|
|
207
|
+
<g>
|
|
208
|
+
<ellipse cx="-24" cy="-84" rx="7" ry="12" fill="#18181b" stroke={color} strokeWidth="1.5" transform="rotate(-25 -24 -84)" />
|
|
209
|
+
<circle cx="-24" cy="-84" r="2" fill={accentColor} />
|
|
210
|
+
</g>
|
|
211
|
+
);
|
|
212
|
+
}
|
|
213
|
+
if (variant === "hyper_wings") {
|
|
214
|
+
return (
|
|
215
|
+
<g>
|
|
216
|
+
<polygon points="-26,-46 -44,-64 -34,-40" fill={color} stroke={secondaryColor} strokeWidth="1.2" />
|
|
217
|
+
<polygon points="26,-46 44,-64 34,-40" fill={color} stroke={secondaryColor} strokeWidth="1.2" />
|
|
218
|
+
</g>
|
|
219
|
+
);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// 3. STEALTH NINJA VARIANTS (10)
|
|
223
|
+
if (variant === "flowing_headband") {
|
|
224
|
+
return (
|
|
225
|
+
<g>
|
|
226
|
+
<rect x="-24" y="-66" width="48" height="8" rx="2" fill="#1e1b4b" stroke={color} strokeWidth="1.5" />
|
|
227
|
+
<circle cx="0" cy="-62" r="3" fill="#38bdf8" />
|
|
228
|
+
<path d="M 24 -62 Q 38 -56 46 -46 Q 36 -48 24 -56" fill={color} />
|
|
229
|
+
</g>
|
|
230
|
+
);
|
|
231
|
+
}
|
|
232
|
+
if (variant === "tactical_cowl") {
|
|
233
|
+
return (
|
|
234
|
+
<g>
|
|
235
|
+
<path d="M -24 -68 Q 0 -76 24 -68 L 22 -44 Q 0 -38 -22 -44 Z" fill="#0f172a" stroke={color} strokeWidth="1.4" opacity="0.8" />
|
|
236
|
+
<circle cx="6" cy="-57" r="4.5" fill="none" stroke="#22c55e" strokeWidth="1.8" />
|
|
237
|
+
<circle cx="6" cy="-57" r="1.5" fill="#22c55e" />
|
|
238
|
+
</g>
|
|
239
|
+
);
|
|
240
|
+
}
|
|
241
|
+
if (variant === "oni_mask") {
|
|
242
|
+
return (
|
|
243
|
+
<g>
|
|
244
|
+
<polygon points="-16,-72 -24,-88 -12,-76" fill="#ef4444" stroke="#450a0a" strokeWidth="1" />
|
|
245
|
+
<polygon points="16,-72 24,-88 12,-76" fill="#ef4444" stroke="#450a0a" strokeWidth="1" />
|
|
246
|
+
<path d="M -16 -46 L -10 -40 L -6 -46 L 0 -42 L 6 -46 L 10 -40 L 16 -46 L 12 -36 L -12 -36 Z" fill="#ffffff" stroke={color} strokeWidth="1" />
|
|
247
|
+
</g>
|
|
248
|
+
);
|
|
249
|
+
}
|
|
250
|
+
if (variant === "kitsune_ears") {
|
|
251
|
+
return (
|
|
252
|
+
<g>
|
|
253
|
+
<polygon points="-22,-72 -14,-88 -6,-76" fill="#1e2430" />
|
|
254
|
+
<polygon points="-20,-73 -14,-85 -8,-76" fill={color} />
|
|
255
|
+
<polygon points="6,-76 14,-88 22,-72" fill="#1e2430" />
|
|
256
|
+
<polygon points="8,-76 14,-85 20,-73" fill={color} />
|
|
257
|
+
<line x1="-12" y1="-46" x2="-22" y2="-48" stroke={color} strokeWidth="1.2" />
|
|
258
|
+
<line x1="12" y1="-46" x2="22" y2="-48" stroke={color} strokeWidth="1.2" />
|
|
259
|
+
</g>
|
|
260
|
+
);
|
|
261
|
+
}
|
|
262
|
+
if (variant === "conical_kasa") {
|
|
263
|
+
return (
|
|
264
|
+
<g>
|
|
265
|
+
<polygon points="-36,-72 0,-92 36,-72" fill="#18181b" stroke={color} strokeWidth="1.6" />
|
|
266
|
+
<line x1="-36" y1="-72" x2="36" y2="-72" stroke={accentColor} strokeWidth="2.4" />
|
|
267
|
+
</g>
|
|
268
|
+
);
|
|
269
|
+
}
|
|
270
|
+
if (variant === "twin_katanas") {
|
|
271
|
+
return (
|
|
272
|
+
<g strokeLinecap="round">
|
|
273
|
+
<line x1="-24" y1="-32" x2="28" y2="-88" stroke="#475569" strokeWidth="3" />
|
|
274
|
+
<line x1="-22" y1="-34" x2="26" y2="-86" stroke={color} strokeWidth="1.6" />
|
|
275
|
+
<line x1="24" y1="-32" x2="-28" y2="-88" stroke="#475569" strokeWidth="3" />
|
|
276
|
+
<line x1="22" y1="-34" x2="-26" y2="-86" stroke={color} strokeWidth="1.6" />
|
|
277
|
+
</g>
|
|
278
|
+
);
|
|
279
|
+
}
|
|
280
|
+
if (variant === "tengu_beak") {
|
|
281
|
+
return (
|
|
282
|
+
<g>
|
|
283
|
+
<polygon points="-12,-48 0,-34 12,-48 0,-44" fill="#0f172a" stroke={color} strokeWidth="1.5" />
|
|
284
|
+
</g>
|
|
285
|
+
);
|
|
286
|
+
}
|
|
287
|
+
if (variant === "veil_shroud") {
|
|
288
|
+
return (
|
|
289
|
+
<g>
|
|
290
|
+
<path d="M -22 -62 Q 0 -70 22 -62 L 20 -36 Q 0 -30 -20 -36 Z" fill="#0f172a" opacity="0.85" stroke={color} strokeWidth="1.2" strokeDasharray="3 2" />
|
|
291
|
+
</g>
|
|
292
|
+
);
|
|
293
|
+
}
|
|
294
|
+
if (variant === "scythe_crest") {
|
|
295
|
+
return (
|
|
296
|
+
<g>
|
|
297
|
+
<path d="M 0 -88 C -14 -88, -20 -76, -14 -66 C -20 -72, -14 -84, 0 -84 C 14 -84, 20 -72, 14 -66 C 20 -76, 14 -88, 0 -88 Z" fill={color} stroke={secondaryColor} strokeWidth="1" />
|
|
298
|
+
</g>
|
|
299
|
+
);
|
|
300
|
+
}
|
|
301
|
+
if (variant === "void_mask") {
|
|
302
|
+
return (
|
|
303
|
+
<g>
|
|
304
|
+
<rect x="-18" y="-62" width="36" height="20" rx="4" fill="#000000" stroke={color} strokeWidth="1.8" />
|
|
305
|
+
<text x="0" y="-48" fill={color} fontSize="10" fontFamily="monospace" textAnchor="middle" fontWeight="bold">零</text>
|
|
306
|
+
</g>
|
|
307
|
+
);
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
// 4. MATRIX HACKER VARIANTS (10)
|
|
311
|
+
if (variant === "hoodie_cowl") {
|
|
312
|
+
return (
|
|
313
|
+
<g>
|
|
314
|
+
<path d="M -28 -74 Q 0 -92 28 -74 Q 28 -34 20 -32 Q 0 -28 -20 -32 Q -28 -34 -28 -74 Z" fill="#051f0b" stroke={color} strokeWidth="1.8" opacity="0.9" />
|
|
315
|
+
<text x="-12" y="-72" fill={color} fontSize="6" fontFamily="monospace" opacity="0.7">101</text>
|
|
316
|
+
<text x="4" y="-72" fill={color} fontSize="6" fontFamily="monospace" opacity="0.7">010</text>
|
|
317
|
+
</g>
|
|
318
|
+
);
|
|
319
|
+
}
|
|
320
|
+
if (variant === "vr_goggles") {
|
|
321
|
+
return (
|
|
322
|
+
<g>
|
|
323
|
+
<rect x="-22" y="-64" width="44" height="15" rx="3" fill="#083344" stroke={color} strokeWidth="1.8" />
|
|
324
|
+
<line x1="-12" y1="-64" x2="-16" y2="-82" stroke={color} strokeWidth="1.6" />
|
|
325
|
+
<circle cx="-16" cy="-82" r="2.5" fill={accentColor} />
|
|
326
|
+
<line x1="-14" y1="-56" x2="14" y2="-56" stroke={accentColor} strokeWidth="1.4" />
|
|
327
|
+
</g>
|
|
328
|
+
);
|
|
329
|
+
}
|
|
330
|
+
if (variant === "daemon_horns") {
|
|
331
|
+
return (
|
|
332
|
+
<g>
|
|
333
|
+
<path d="M -24 -70 Q 0 -82 24 -70" stroke={color} strokeWidth="3" fill="none" />
|
|
334
|
+
<polygon points="-16,-70 -22,-86 -10,-74" fill={color} stroke={secondaryColor} strokeWidth="1" />
|
|
335
|
+
<polygon points="16,-70 22,-86 10,-74" fill={color} stroke={secondaryColor} strokeWidth="1" />
|
|
336
|
+
</g>
|
|
337
|
+
);
|
|
338
|
+
}
|
|
339
|
+
if (variant === "glitch_halo") {
|
|
340
|
+
return (
|
|
341
|
+
<g>
|
|
342
|
+
<rect x="-28" y="-76" width="56" height="42" fill="none" stroke={color} strokeWidth="1.5" strokeDasharray="6 3 2 4" />
|
|
343
|
+
<rect x="-18" y="-82" width="12" height="6" fill={color} opacity="0.7" />
|
|
344
|
+
<rect x="12" y="-50" width="10" height="4" fill={color} opacity="0.7" />
|
|
345
|
+
</g>
|
|
346
|
+
);
|
|
347
|
+
}
|
|
348
|
+
if (variant === "floating_hud") {
|
|
349
|
+
return (
|
|
350
|
+
<g>
|
|
351
|
+
<rect x="24" y="-78" width="34" height="18" rx="2" fill="#09090b" stroke={color} strokeWidth="1" />
|
|
352
|
+
<text x="27" y="-66" fill={color} fontSize="6" fontFamily="monospace">root#_</text>
|
|
353
|
+
</g>
|
|
354
|
+
);
|
|
355
|
+
}
|
|
356
|
+
if (variant === "respirator_eq") {
|
|
357
|
+
return (
|
|
358
|
+
<g strokeWidth="2">
|
|
359
|
+
<rect x="-18" y="-46" width="36" height="10" rx="3" fill="#0f172a" stroke={color} strokeWidth="1.2" />
|
|
360
|
+
<line x1="-12" y1="-40" x2="-12" y2="-45" stroke="#22c55e" />
|
|
361
|
+
<line x1="-6" y1="-38" x2="-6" y2="-45" stroke="#eab308" />
|
|
362
|
+
<line x1="0" y1="-37" x2="0" y2="-45" stroke="#ef4444" />
|
|
363
|
+
<line x1="6" y1="-39" x2="6" y2="-45" stroke="#eab308" />
|
|
364
|
+
<line x1="12" y1="-41" x2="12" y2="-45" stroke="#22c55e" />
|
|
365
|
+
</g>
|
|
366
|
+
);
|
|
367
|
+
}
|
|
368
|
+
if (variant === "heatsink_fins") {
|
|
369
|
+
return (
|
|
370
|
+
<g fill="#ea580c" stroke="#fed7aa" strokeWidth="1">
|
|
371
|
+
<rect x="-18" y="-84" width="4" height="14" rx="1" />
|
|
372
|
+
<rect x="-10" y="-88" width="4" height="18" rx="1" />
|
|
373
|
+
<rect x="-2" y="-90" width="4" height="20" rx="1" />
|
|
374
|
+
<rect x="6" y="-88" width="4" height="18" rx="1" />
|
|
375
|
+
<rect x="14" y="-84" width="4" height="14" rx="1" />
|
|
376
|
+
</g>
|
|
377
|
+
);
|
|
378
|
+
}
|
|
379
|
+
if (variant === "cable_dreads") {
|
|
380
|
+
return (
|
|
381
|
+
<g fill="none" strokeLinecap="round">
|
|
382
|
+
<path d="M -22 -62 C -32 -48, -30 -24, -28 -12" stroke={color} strokeWidth="2.5" />
|
|
383
|
+
<path d="M -16 -64 C -22 -44, -20 -20, -18 -8" stroke={accentColor} strokeWidth="2" />
|
|
384
|
+
<path d="M 16 -64 C 22 -44, 20 -20, 18 -8" stroke={accentColor} strokeWidth="2" />
|
|
385
|
+
<path d="M 22 -62 C 32 -48, 30 -24, 28 -12" stroke={color} strokeWidth="2.5" />
|
|
386
|
+
</g>
|
|
387
|
+
);
|
|
388
|
+
}
|
|
389
|
+
if (variant === "cyber_skull") {
|
|
390
|
+
return (
|
|
391
|
+
<g>
|
|
392
|
+
<ellipse cx="-7" cy="-55" rx="5" ry="4" fill="#000000" stroke={color} strokeWidth="1.5" />
|
|
393
|
+
<ellipse cx="7" cy="-55" rx="5" ry="4" fill="#000000" stroke={color} strokeWidth="1.5" />
|
|
394
|
+
<polygon points="-2,-46 0,-43 2,-46" fill={color} />
|
|
395
|
+
<line x1="-8" y1="-40" x2="8" y2="-40" stroke={color} strokeWidth="1.8" />
|
|
396
|
+
<line x1="-6" y1="-43" x2="-6" y2="-37" stroke={color} strokeWidth="1.4" />
|
|
397
|
+
<line x1="0" y1="-43" x2="0" y2="-37" stroke={color} strokeWidth="1.4" />
|
|
398
|
+
<line x1="6" y1="-43" x2="6" y2="-37" stroke={color} strokeWidth="1.4" />
|
|
399
|
+
</g>
|
|
400
|
+
);
|
|
401
|
+
}
|
|
402
|
+
if (variant === "wireframe_cube") {
|
|
403
|
+
return (
|
|
404
|
+
<g stroke={color}>
|
|
405
|
+
<rect x="-24" y="-76" width="48" height="42" rx="4" fill="none" strokeWidth="1.6" />
|
|
406
|
+
<rect x="-16" y="-68" width="32" height="26" rx="2" fill="none" stroke={accentColor} strokeWidth="1.2" strokeDasharray="3 2" />
|
|
407
|
+
<line x1="-24" y1="-76" x2="-16" y2="-68" strokeWidth="1.2" />
|
|
408
|
+
<line x1="24" y1="-76" x2="16" y2="-68" strokeWidth="1.2" />
|
|
409
|
+
<line x1="-24" y1="-34" x2="-16" y2="-42" strokeWidth="1.2" />
|
|
410
|
+
<line x1="24" y1="-34" x2="16" y2="-42" strokeWidth="1.2" />
|
|
411
|
+
</g>
|
|
412
|
+
);
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
// 5. CELESTIAL ASTRO VARIANTS (10)
|
|
416
|
+
if (variant === "bubble_dome") {
|
|
417
|
+
return (
|
|
418
|
+
<g>
|
|
419
|
+
<circle cx="0" cy="-56" r="28" fill="none" stroke={color} strokeWidth="2.5" opacity="0.9" />
|
|
420
|
+
<circle cx="0" cy="-84" r="3.5" fill="#fef08a" stroke={color} strokeWidth="1.2" />
|
|
421
|
+
<path d="M -14 -72 Q 0 -80 14 -72" stroke="#ffffff" strokeWidth="2" fill="none" opacity="0.6" strokeLinecap="round" />
|
|
422
|
+
</g>
|
|
423
|
+
);
|
|
424
|
+
}
|
|
425
|
+
if (variant === "lunar_pack") {
|
|
426
|
+
return (
|
|
427
|
+
<g>
|
|
428
|
+
<rect x="-20" y="-86" width="2" height="18" fill={color} />
|
|
429
|
+
<circle cx="-19" cy="-86" r="2" fill="#ffffff" />
|
|
430
|
+
<ellipse cx="0" cy="-54" rx="24" ry="18" fill="none" stroke="#e2e8f0" strokeWidth="2" />
|
|
431
|
+
</g>
|
|
432
|
+
);
|
|
433
|
+
}
|
|
434
|
+
if (variant === "sunburst_halo") {
|
|
435
|
+
return (
|
|
436
|
+
<g stroke={color} strokeWidth="1.8" opacity="0.85">
|
|
437
|
+
<line x1="0" y1="-86" x2="0" y2="-98" />
|
|
438
|
+
<line x1="22" y1="-78" x2="32" y2="-88" />
|
|
439
|
+
<line x1="30" y1="-56" x2="42" y2="-56" />
|
|
440
|
+
<line x1="22" y1="-34" x2="32" y2="-24" />
|
|
441
|
+
<line x1="0" y1="-26" x2="0" y2="-14" />
|
|
442
|
+
<line x1="-22" y1="-34" x2="-32" y2="-24" />
|
|
443
|
+
<line x1="-30" y1="-56" x2="-42" y2="-56" />
|
|
444
|
+
<line x1="-22" y1="-78" x2="-32" y2="-88" />
|
|
445
|
+
</g>
|
|
446
|
+
);
|
|
447
|
+
}
|
|
448
|
+
if (variant === "saturn_ring") {
|
|
449
|
+
return (
|
|
450
|
+
<g>
|
|
451
|
+
<ellipse cx="0" cy="-56" rx="36" ry="10" fill="none" stroke={color} strokeWidth="2.2" transform="rotate(-15 0 -56)" />
|
|
452
|
+
<circle cx="28" cy="-62" r="3" fill={accentColor} />
|
|
453
|
+
</g>
|
|
454
|
+
);
|
|
455
|
+
}
|
|
456
|
+
if (variant === "star_crown") {
|
|
457
|
+
return (
|
|
458
|
+
<g fill={color}>
|
|
459
|
+
<polygon points="-16,-74 -12,-86 -8,-76" />
|
|
460
|
+
<polygon points="-6,-76 0,-92 6,-76" />
|
|
461
|
+
<polygon points="8,-76 12,-86 16,-74" />
|
|
462
|
+
<circle cx="0" cy="-74" r="2.5" fill="#ffffff" />
|
|
463
|
+
</g>
|
|
464
|
+
);
|
|
465
|
+
}
|
|
466
|
+
if (variant === "eclipse_corona") {
|
|
467
|
+
return (
|
|
468
|
+
<g>
|
|
469
|
+
<ellipse cx="0" cy="-56" rx="32" ry="18" fill="none" stroke={color} strokeWidth="3" opacity="0.6" strokeDasharray="8 4" />
|
|
470
|
+
<circle cx="0" cy="-56" r="22" fill="#000000" stroke={color} strokeWidth="1.5" />
|
|
471
|
+
</g>
|
|
472
|
+
);
|
|
473
|
+
}
|
|
474
|
+
if (variant === "pulsar_spires") {
|
|
475
|
+
return (
|
|
476
|
+
<g stroke={color} strokeWidth="2.8" strokeLinecap="round">
|
|
477
|
+
<line x1="0" y1="-78" x2="0" y2="-98" />
|
|
478
|
+
<circle cx="0" cy="-98" r="3" fill="#ffffff" stroke="none" />
|
|
479
|
+
<line x1="0" y1="-34" x2="0" y2="-18" />
|
|
480
|
+
<circle cx="0" cy="-18" r="3" fill="#ffffff" stroke="none" />
|
|
481
|
+
</g>
|
|
482
|
+
);
|
|
483
|
+
}
|
|
484
|
+
if (variant === "aurora_ribbons") {
|
|
485
|
+
return (
|
|
486
|
+
<g fill="none" strokeLinecap="round">
|
|
487
|
+
<path d="M -30 -82 Q -15 -96 0 -84 T 30 -88" stroke={color} strokeWidth="3" opacity="0.75" />
|
|
488
|
+
<path d="M -26 -88 Q -10 -100 6 -88 T 26 -92" stroke={accentColor} strokeWidth="2" opacity="0.6" />
|
|
489
|
+
</g>
|
|
490
|
+
);
|
|
491
|
+
}
|
|
492
|
+
if (variant === "angel_wings") {
|
|
493
|
+
return (
|
|
494
|
+
<g>
|
|
495
|
+
<polygon points="-26,-46 -48,-78 -32,-38" fill={color} stroke={secondaryColor} strokeWidth="1.2" opacity="0.85" />
|
|
496
|
+
<polygon points="26,-46 48,-78 32,-38" fill={color} stroke={secondaryColor} strokeWidth="1.2" opacity="0.85" />
|
|
497
|
+
<ellipse cx="0" cy="-80" rx="16" ry="5" fill="none" stroke={accentColor} strokeWidth="1.6" />
|
|
498
|
+
</g>
|
|
499
|
+
);
|
|
500
|
+
}
|
|
501
|
+
if (variant === "singularity_core") {
|
|
502
|
+
return (
|
|
503
|
+
<g>
|
|
504
|
+
<ellipse cx="0" cy="-56" rx="30" ry="26" fill="none" stroke="#ffffff" strokeWidth="2" opacity="0.9" />
|
|
505
|
+
<circle cx="-22" cy="-70" r="2.5" fill={accentColor} />
|
|
506
|
+
<circle cx="22" cy="-42" r="2.5" fill={accentColor} />
|
|
507
|
+
</g>
|
|
508
|
+
);
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
// Archetype Fallbacks
|
|
512
|
+
if (archetype === "stealth_ninja") {
|
|
513
|
+
return (
|
|
514
|
+
<g>
|
|
515
|
+
<rect x="-24" y="-66" width="48" height="8" rx="2" fill="#1e1b4b" stroke={color} strokeWidth="1.5" />
|
|
516
|
+
<circle cx="0" cy="-62" r="3" fill="#38bdf8" />
|
|
517
|
+
</g>
|
|
518
|
+
);
|
|
519
|
+
}
|
|
520
|
+
if (archetype === "mecha_pilot") {
|
|
521
|
+
return (
|
|
522
|
+
<g fill={color}>
|
|
523
|
+
<rect x="-20" y="-88" width="3" height="20" rx="1" />
|
|
524
|
+
<rect x="17" y="-88" width="3" height="20" rx="1" />
|
|
525
|
+
<circle cx="-18.5" cy="-88" r="3" fill="#ffffff" />
|
|
526
|
+
<circle cx="18.5" cy="-88" r="3" fill="#ffffff" />
|
|
527
|
+
</g>
|
|
528
|
+
);
|
|
529
|
+
}
|
|
530
|
+
if (archetype === "celestial_astro") {
|
|
531
|
+
return (
|
|
532
|
+
<ellipse cx="0" cy="-64" rx="30" ry="8" fill="none" stroke={color} strokeWidth="2" opacity="0.9" />
|
|
533
|
+
);
|
|
534
|
+
}
|
|
535
|
+
if (archetype === "matrix_hacker") {
|
|
536
|
+
return (
|
|
537
|
+
<rect x="-26" y="-76" width="52" height="44" rx="12" fill="none" stroke={color} strokeWidth="1.8" />
|
|
538
|
+
);
|
|
539
|
+
}
|
|
540
|
+
// Default Cyber Suit
|
|
541
|
+
return (
|
|
542
|
+
<rect x="-24" y="-66" width="48" height="6" rx="2" fill={color} />
|
|
543
|
+
);
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
/**
|
|
547
|
+
* 5 Distinct Staff Uniform & Torso Silhouettes for Employee Roles:
|
|
548
|
+
* - cyber_suit: Corporate Tech Field Ops / Executive blazer with security ID badge lanyard & lapels
|
|
549
|
+
* - mecha_pilot: Heavy Industrial DevOps / Hardware engineer with hazard chevrons, shoulder pauldrons & harness
|
|
550
|
+
* - stealth_ninja: Security Auditor Shinobi with crossed gi collar, diagonal tactical sash, kunai strap & obi
|
|
551
|
+
* - matrix_hacker: Streetwear Netrunner with oversized slouchy techwear cowl-hoodie, drawstrings & kangaroo pocket
|
|
552
|
+
* - celestial_astro: Aerospace Scientist flight uniform with gold command epaulets, hermetic neck seal & pressure dials
|
|
553
|
+
*/
|
|
554
|
+
export function RenderStaffTorso({ archetype, color, secondaryColor, accentColor, idPrefix, trimColor }) {
|
|
555
|
+
if (archetype === "cyber_suit") {
|
|
556
|
+
return (
|
|
557
|
+
<g id="staff-torso-cyber-suit">
|
|
558
|
+
{/* Tailored Corporate Blazer / Suit Jacket */}
|
|
559
|
+
<polygon points="-18,-30 18,-30 15,-6 -15,-6" fill={`url(#${idPrefix}_bodyGradient)`} stroke={color} strokeWidth="1.2" />
|
|
560
|
+
{/* Crisp Dark Lapels */}
|
|
561
|
+
<polygon points="-17,-30 -7,-14 -13,-14" fill="#0d1117" stroke={color} strokeWidth="0.8" />
|
|
562
|
+
<polygon points="17,-30 7,-14 13,-14" fill="#0d1117" stroke={color} strokeWidth="0.8" />
|
|
563
|
+
{/* Center Zipper / Placket */}
|
|
564
|
+
<line x1="0" y1="-30" x2="0" y2="-10" stroke={color} strokeWidth="1.4" />
|
|
565
|
+
{/* Dual Chest Pocket Slits */}
|
|
566
|
+
<rect x="-14" y="-22" width="5" height="3" rx="1" fill="#1f2937" stroke={color} strokeWidth="0.6" />
|
|
567
|
+
<rect x="9" y="-22" width="5" height="3" rx="1" fill="#1f2937" stroke={color} strokeWidth="0.6" />
|
|
568
|
+
{/* Executive Security ID Lanyard & Hanging Badge */}
|
|
569
|
+
<path d="M -5 -30 Q 0 -18 5 -30" stroke={accentColor} strokeWidth="1.2" fill="none" opacity="0.85" />
|
|
570
|
+
<rect x="-4.5" y="-19" width="9" height="12" rx="1.5" fill="#090d16" stroke={color} strokeWidth="1" />
|
|
571
|
+
<rect x="-3" y="-17.5" width="6" height="4.5" rx="0.5" fill={color} />
|
|
572
|
+
<line x1="-3" y1="-11" x2="3" y2="-11" stroke="#ffffff" strokeWidth="0.8" />
|
|
573
|
+
<line x1="-3" y1="-9" x2="1" y2="-9" stroke="#ffffff" strokeWidth="0.8" />
|
|
574
|
+
{/* Polished Belt & Buckle */}
|
|
575
|
+
<rect x="-15" y="-10" width="30" height="4" fill="#020617" />
|
|
576
|
+
<rect x="-3.5" y="-11" width="7" height="6" rx="1" fill="#1e293b" stroke={color} strokeWidth="1" />
|
|
577
|
+
</g>
|
|
578
|
+
);
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
if (archetype === "mecha_pilot") {
|
|
582
|
+
return (
|
|
583
|
+
<g id="staff-torso-mecha-pilot">
|
|
584
|
+
{/* Broad Reinforced Heavy Armored Chest Rig */}
|
|
585
|
+
<polygon points="-22,-30 22,-30 18,-6 -18,-6" fill="#18181b" stroke={color} strokeWidth="1.6" />
|
|
586
|
+
{/* Armored Shoulder Pauldrons */}
|
|
587
|
+
<polygon points="-27,-29 -20,-33 -17,-25 -25,-20" fill="#27272a" stroke={color} strokeWidth="1.2" />
|
|
588
|
+
<polygon points="27,-29 20,-33 17,-25 25,-20" fill="#27272a" stroke={color} strokeWidth="1.2" />
|
|
589
|
+
{/* Heavy Industrial Hazard Chevrons (Yellow/Black) */}
|
|
590
|
+
<polygon points="-12,-26 -7,-26 -3,-20 -8,-20" fill="#eab308" />
|
|
591
|
+
<polygon points="-5,-26 0,-26 4,-20 -1,-20" fill="#18181b" />
|
|
592
|
+
<polygon points="2,-26 7,-26 11,-20 6,-20" fill="#eab308" />
|
|
593
|
+
<polygon points="9,-26 13,-26 17,-20 13,-20" fill="#18181b" />
|
|
594
|
+
{/* Heavy Duty Tactical Harness Straps with Carabiners */}
|
|
595
|
+
<line x1="-13" y1="-30" x2="-11" y2="-6" stroke={color} strokeWidth="1.8" />
|
|
596
|
+
<line x1="13" y1="-30" x2="11" y2="-6" stroke={color} strokeWidth="1.8" />
|
|
597
|
+
<circle cx="-12" cy="-10" r="1.8" fill="none" stroke="#e2e8f0" strokeWidth="1" />
|
|
598
|
+
<circle cx="12" cy="-10" r="1.8" fill="none" stroke="#e2e8f0" strokeWidth="1" />
|
|
599
|
+
{/* Central Reinforced Fusion Reactor with Protective Cage */}
|
|
600
|
+
<circle cx="0" cy="-14" r="5.5" fill="#09090b" stroke={color} strokeWidth="1.5" />
|
|
601
|
+
<circle cx="0" cy="-14" r="3.2" fill={color} />
|
|
602
|
+
<line x1="-5" y1="-14" x2="5" y2="-14" stroke="#ffffff" strokeWidth="1" />
|
|
603
|
+
<line x1="0" y1="-19" x2="0" y2="-9" stroke="#ffffff" strokeWidth="1" />
|
|
604
|
+
{/* Tool Carabiner Pouch */}
|
|
605
|
+
<rect x="-16" y="-9" width="7" height="4" rx="1" fill="#3f3f46" stroke="#71717a" strokeWidth="0.8" />
|
|
606
|
+
<rect x="9" y="-9" width="7" height="4" rx="1" fill="#3f3f46" stroke="#71717a" strokeWidth="0.8" />
|
|
607
|
+
</g>
|
|
608
|
+
);
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
if (archetype === "stealth_ninja") {
|
|
612
|
+
return (
|
|
613
|
+
<g id="staff-torso-stealth-ninja">
|
|
614
|
+
{/* Sleek Form-Fitting Shinobi Gi / Wrapped Tunic */}
|
|
615
|
+
<polygon points="-16,-30 16,-30 13,-6 -13,-6" fill="#090d16" stroke={color} strokeWidth="1.4" />
|
|
616
|
+
{/* Crossed Kimono / Gi Lapels */}
|
|
617
|
+
<line x1="-16" y1="-30" x2="5" y2="-14" stroke={color} strokeWidth="2.2" strokeLinecap="round" />
|
|
618
|
+
<line x1="16" y1="-30" x2="-3" y2="-14" stroke={color} strokeWidth="1.6" strokeLinecap="round" opacity="0.6" />
|
|
619
|
+
{/* Prominent Diagonal Tactical Sash (Torso cross-strap) */}
|
|
620
|
+
<polygon points="-16,-28 -11,-30 14,-9 9,-7" fill={color} opacity="0.9" />
|
|
621
|
+
{/* Attached Stealth Kunai / Scroll Sheath */}
|
|
622
|
+
<rect x="-3" y="-21" width="11" height="4" rx="1.5" fill="#1e293b" stroke="#ffffff" strokeWidth="0.8" transform="rotate(-35 2 -19)" />
|
|
623
|
+
{/* Tied Fabric Obi Waist Sash with Hanging Knot Tails */}
|
|
624
|
+
<rect x="-14" y="-12" width="28" height="6" rx="2" fill="#1e1b4b" stroke={color} strokeWidth="1.2" />
|
|
625
|
+
<path d="M 3 -7 Q 6 1 4 6 Q 1 1 3 -7" fill={color} />
|
|
626
|
+
<path d="M 5 -7 Q 9 0 8 5 Q 4 0 5 -7" fill={accentColor} opacity="0.85" />
|
|
627
|
+
{/* Forearm Binding Accents */}
|
|
628
|
+
<line x1="-24" y1="-22" x2="-18" y2="-20" stroke={color} strokeWidth="1.2" />
|
|
629
|
+
<line x1="24" y1="-22" x2="18" y2="-20" stroke={color} strokeWidth="1.2" />
|
|
630
|
+
</g>
|
|
631
|
+
);
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
if (archetype === "matrix_hacker") {
|
|
635
|
+
return (
|
|
636
|
+
<g id="staff-torso-matrix-hacker">
|
|
637
|
+
{/* Loose Oversized Slouchy Techwear Hoodie Body */}
|
|
638
|
+
<rect x="-21" y="-30" width="42" height="25" rx="8" fill="#121217" stroke={color} strokeWidth="1.6" />
|
|
639
|
+
{/* Crumpled Fabric Cowl Collar draped around neck */}
|
|
640
|
+
<path d="M -18 -32 Q 0 -26 18 -32 Q 13 -22 0 -22 Q -13 -22 -18 -32 Z" fill="#1f1f28" stroke={color} strokeWidth="1.2" />
|
|
641
|
+
{/* Hanging Dual Drawstring Cords with Metal Aglets */}
|
|
642
|
+
<path d="M -7 -23 Q -9 -14 -6 -7" stroke="#ffffff" strokeWidth="1.4" fill="none" strokeLinecap="round" />
|
|
643
|
+
<rect x="-7.5" y="-7" width="3" height="4" rx="0.8" fill={color} />
|
|
644
|
+
<path d="M 7 -23 Q 9 -13 6 -6" stroke="#ffffff" strokeWidth="1.4" fill="none" strokeLinecap="round" />
|
|
645
|
+
<rect x="4.5" y="-6" width="3" height="4" rx="0.8" fill={color} />
|
|
646
|
+
{/* Front Kangaroo Pouch Pocket */}
|
|
647
|
+
<path d="M -15 -14 L 15 -14 L 13 -6 L -13 -6 Z" fill="#09090d" stroke="#27272a" strokeWidth="1" />
|
|
648
|
+
<line x1="-14" y1="-14" x2="-11" y2="-8" stroke={color} strokeWidth="1.2" />
|
|
649
|
+
<line x1="14" y1="-14" x2="11" y2="-8" stroke={color} strokeWidth="1.2" />
|
|
650
|
+
{/* Cyber Holographic Glitch Patch on Chest */}
|
|
651
|
+
<g transform="translate(6, -21)">
|
|
652
|
+
<rect x="0" y="0" width="9" height="5" fill="#000000" stroke={accentColor} strokeWidth="0.8" />
|
|
653
|
+
<line x1="2" y1="1" x2="2" y2="4" stroke={color} strokeWidth="0.8" />
|
|
654
|
+
<line x1="4" y1="1" x2="4" y2="4" stroke={color} strokeWidth="1.2" />
|
|
655
|
+
<line x1="6.5" y1="1" x2="6.5" y2="4" stroke={color} strokeWidth="0.8" />
|
|
656
|
+
</g>
|
|
657
|
+
</g>
|
|
658
|
+
);
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
if (archetype === "celestial_astro") {
|
|
662
|
+
return (
|
|
663
|
+
<g id="staff-torso-celestial-astro">
|
|
664
|
+
{/* Pressurized Flight Suit Body */}
|
|
665
|
+
<polygon points="-18,-30 18,-30 16,-6 -16,-6" fill="#f1f5f9" stroke={color} strokeWidth="1.4" />
|
|
666
|
+
{/* Hermetic Helmet Seal Ring */}
|
|
667
|
+
<rect x="-14" y="-33" width="28" height="5" rx="2" fill="#334155" stroke={color} strokeWidth="1.2" />
|
|
668
|
+
{/* Gold Command Rank Epaulets on Shoulders */}
|
|
669
|
+
<rect x="-24" y="-31" width="8" height="4.5" rx="1" fill="#f59e0b" stroke="#78350f" strokeWidth="0.8" />
|
|
670
|
+
<line x1="-22" y1="-30" x2="-22" y2="-28" stroke="#ffffff" strokeWidth="0.8" />
|
|
671
|
+
<line x1="-19" y1="-30" x2="-19" y2="-28" stroke="#ffffff" strokeWidth="0.8" />
|
|
672
|
+
<rect x="16" y="-31" width="8" height="4.5" rx="1" fill="#f59e0b" stroke="#78350f" strokeWidth="0.8" />
|
|
673
|
+
<line x1="19" y1="-30" x2="19" y2="-28" stroke="#ffffff" strokeWidth="0.8" />
|
|
674
|
+
<line x1="22" y1="-30" x2="22" y2="-28" stroke="#ffffff" strokeWidth="0.8" />
|
|
675
|
+
{/* Dual Atmospheric Pressure Regulator Dials with Connecting Glowing Tubing */}
|
|
676
|
+
<circle cx="-7" cy="-17" r="3.5" fill="#0f172a" stroke={color} strokeWidth="1.2" />
|
|
677
|
+
<circle cx="-7" cy="-17" r="1.5" fill="#22c55e" />
|
|
678
|
+
<circle cx="7" cy="-17" r="3.5" fill="#0f172a" stroke={color} strokeWidth="1.2" />
|
|
679
|
+
<circle cx="7" cy="-17" r="1.5" fill="#38bdf8" />
|
|
680
|
+
<path d="M -3.5 -17 Q 0 -13 3.5 -17" fill="none" stroke={color} strokeWidth="1.6" />
|
|
681
|
+
{/* Planetary Mission Patch Insignia on Left Chest */}
|
|
682
|
+
<polygon points="-12,-26 -6,-26 -9,-21" fill={color} stroke="#ffffff" strokeWidth="0.8" />
|
|
683
|
+
<ellipse cx="-9" cy="-24" rx="4" ry="1.5" fill="none" stroke="#f59e0b" strokeWidth="0.8" transform="rotate(-20 -9 -24)" />
|
|
684
|
+
{/* Aerodynamic Thermal Seams */}
|
|
685
|
+
<line x1="-12" y1="-14" x2="-10" y2="-6" stroke="#94a3b8" strokeWidth="1" />
|
|
686
|
+
<line x1="12" y1="-14" x2="10" y2="-6" stroke="#94a3b8" strokeWidth="1" />
|
|
687
|
+
</g>
|
|
688
|
+
);
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
// Fallback default
|
|
692
|
+
return (
|
|
693
|
+
<g>
|
|
694
|
+
<rect x="-17" y="-30" width="34" height="22" rx="11" fill={`url(#${idPrefix}_bodyGradient)`} />
|
|
695
|
+
<rect x="-14" y="-12" width="28" height="6" fill={trimColor} />
|
|
696
|
+
<circle cx="0" cy="-18" r="4.5" fill="#0f172a" stroke={color} strokeWidth="1.4" />
|
|
697
|
+
<circle cx="0" cy="-18" r="2.2" fill={color} />
|
|
698
|
+
</g>
|
|
699
|
+
);
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
export function RenderStaffArms({ archetype, color, armLRef, armRRef }) {
|
|
703
|
+
let sleeveL = null;
|
|
704
|
+
let sleeveR = null;
|
|
705
|
+
|
|
706
|
+
if (archetype === "mecha_pilot") {
|
|
707
|
+
sleeveL = (
|
|
708
|
+
<>
|
|
709
|
+
<rect x="-27" y="-26" width="9" height="24" rx="3" fill="#27272a" stroke={color} strokeWidth="1" />
|
|
710
|
+
<rect x="-28" y="-16" width="11" height="8" rx="2" fill="#3f3f46" stroke="#eab308" strokeWidth="1" />
|
|
711
|
+
</>
|
|
712
|
+
);
|
|
713
|
+
sleeveR = (
|
|
714
|
+
<>
|
|
715
|
+
<rect x="18" y="-26" width="9" height="24" rx="3" fill="#27272a" stroke={color} strokeWidth="1" />
|
|
716
|
+
<rect x="17" y="-16" width="11" height="8" rx="2" fill="#3f3f46" stroke="#eab308" strokeWidth="1" />
|
|
717
|
+
</>
|
|
718
|
+
);
|
|
719
|
+
} else if (archetype === "stealth_ninja") {
|
|
720
|
+
sleeveL = (
|
|
721
|
+
<>
|
|
722
|
+
<rect x="-26" y="-26" width="8" height="24" rx="4" fill="#0f172a" />
|
|
723
|
+
<line x1="-26" y1="-18" x2="-18" y2="-16" stroke={color} strokeWidth="1.2" />
|
|
724
|
+
<line x1="-26" y1="-12" x2="-18" y2="-10" stroke={color} strokeWidth="1.2" />
|
|
725
|
+
</>
|
|
726
|
+
);
|
|
727
|
+
sleeveR = (
|
|
728
|
+
<>
|
|
729
|
+
<rect x="18" y="-26" width="8" height="24" rx="4" fill="#0f172a" />
|
|
730
|
+
<line x1="18" y1="-18" x2="26" y2="-16" stroke={color} strokeWidth="1.2" />
|
|
731
|
+
<line x1="18" y1="-12" x2="26" y2="-10" stroke={color} strokeWidth="1.2" />
|
|
732
|
+
</>
|
|
733
|
+
);
|
|
734
|
+
} else if (archetype === "matrix_hacker") {
|
|
735
|
+
sleeveL = (
|
|
736
|
+
<>
|
|
737
|
+
<rect x="-28" y="-26" width="11" height="24" rx="5" fill="#18181b" stroke={color} strokeWidth="1" />
|
|
738
|
+
<rect x="-27" y="-5" width="9" height="3" rx="1" fill="#27272a" />
|
|
739
|
+
</>
|
|
740
|
+
);
|
|
741
|
+
sleeveR = (
|
|
742
|
+
<>
|
|
743
|
+
<rect x="17" y="-26" width="11" height="24" rx="5" fill="#18181b" stroke={color} strokeWidth="1" />
|
|
744
|
+
<rect x="18" y="-5" width="9" height="3" rx="1" fill="#27272a" />
|
|
745
|
+
</>
|
|
746
|
+
);
|
|
747
|
+
} else if (archetype === "celestial_astro") {
|
|
748
|
+
sleeveL = (
|
|
749
|
+
<>
|
|
750
|
+
<rect x="-26" y="-26" width="8" height="24" rx="4" fill="#f1f5f9" stroke="#94a3b8" strokeWidth="0.8" />
|
|
751
|
+
<polygon points="-26,-15 -18,-15 -22,-11" fill={color} />
|
|
752
|
+
</>
|
|
753
|
+
);
|
|
754
|
+
sleeveR = (
|
|
755
|
+
<>
|
|
756
|
+
<rect x="18" y="-26" width="8" height="24" rx="4" fill="#f1f5f9" stroke="#94a3b8" strokeWidth="0.8" />
|
|
757
|
+
<polygon points="18,-15 26,-15 22,-11" fill={color} />
|
|
758
|
+
</>
|
|
759
|
+
);
|
|
760
|
+
} else {
|
|
761
|
+
// Default cyber suit tailored sleeve
|
|
762
|
+
sleeveL = (
|
|
763
|
+
<>
|
|
764
|
+
<rect x="-26" y="-26" width="8" height="24" rx="4" fill="#1e2430" stroke={color} strokeWidth="0.8" />
|
|
765
|
+
<line x1="-25" y1="-6" x2="-19" y2="-6" stroke={color} strokeWidth="1" />
|
|
766
|
+
</>
|
|
767
|
+
);
|
|
768
|
+
sleeveR = (
|
|
769
|
+
<>
|
|
770
|
+
<rect x="18" y="-26" width="8" height="24" rx="4" fill="#1e2430" stroke={color} strokeWidth="0.8" />
|
|
771
|
+
<line x1="19" y1="-6" x2="25" y2="-6" stroke={color} strokeWidth="1" />
|
|
772
|
+
</>
|
|
773
|
+
);
|
|
774
|
+
}
|
|
775
|
+
|
|
776
|
+
return (
|
|
777
|
+
<>
|
|
778
|
+
<g ref={armLRef}>{sleeveL}</g>
|
|
779
|
+
<g ref={armRRef}>{sleeveR}</g>
|
|
780
|
+
</>
|
|
781
|
+
);
|
|
782
|
+
}
|
|
783
|
+
|
|
784
|
+
/**
|
|
785
|
+
* Pure Declarative React SVG Animated Character & Workstation Engine.
|
|
786
|
+
* Supports:
|
|
787
|
+
* - 6 Actions: streaming, happy, sleeping, error, looping, pending
|
|
788
|
+
* - Live mixing of 810 catalog items (Skins, Props, Pets, Auras, Themes)
|
|
789
|
+
* - Pure SVG rendering (zero canvas dependency) with 60 FPS hardware-accelerated transforms
|
|
790
|
+
* - Zero raw emojis, 100% vector scalability
|
|
791
|
+
*/
|
|
792
|
+
export function LiveReactAgent({
|
|
793
|
+
mode = "streaming",
|
|
794
|
+
intensity = 0.75,
|
|
795
|
+
skinId = "skin_0",
|
|
796
|
+
skinItem: propSkinItem = null,
|
|
797
|
+
petId = "pet_0",
|
|
798
|
+
petItem: propPetItem = null,
|
|
799
|
+
propsList = [],
|
|
800
|
+
auraId = "aura_0",
|
|
801
|
+
auraItem: propAuraItem = null,
|
|
802
|
+
themeId = "theme_default",
|
|
803
|
+
themeItem: propThemeItem = null,
|
|
804
|
+
clientType = "cli",
|
|
805
|
+
interactive = true,
|
|
806
|
+
isPlaying = true,
|
|
807
|
+
showDesk = true,
|
|
808
|
+
showFloor = true,
|
|
809
|
+
className = "",
|
|
810
|
+
style = {},
|
|
811
|
+
onTelemetry = null,
|
|
812
|
+
}) {
|
|
813
|
+
const rawId = React.useId();
|
|
814
|
+
const idPrefix = useMemo(() => "lra_" + rawId.replace(/[^a-zA-Z0-9]/g, "_"), [rawId]);
|
|
815
|
+
// Resolve item objects from catalog or props
|
|
816
|
+
const skin = useMemo(() => {
|
|
817
|
+
return propSkinItem || getItemById(skinId) || (COSMETIC_CATALOG.skins || [])[0];
|
|
818
|
+
}, [propSkinItem, skinId]);
|
|
819
|
+
|
|
820
|
+
const pet = useMemo(() => {
|
|
821
|
+
return propPetItem || getItemById(petId) || (COSMETIC_CATALOG.pets || [])[0];
|
|
822
|
+
}, [propPetItem, petId]);
|
|
823
|
+
|
|
824
|
+
const aura = useMemo(() => {
|
|
825
|
+
return propAuraItem || getItemById(auraId) || (COSMETIC_CATALOG.auras || [])[0];
|
|
826
|
+
}, [propAuraItem, auraId]);
|
|
827
|
+
|
|
828
|
+
const theme = useMemo(() => {
|
|
829
|
+
return propThemeItem || getItemById(themeId) || (COSMETIC_CATALOG.officeThemes || [])[0];
|
|
830
|
+
}, [propThemeItem, themeId]);
|
|
831
|
+
|
|
832
|
+
const themeStyle = THEME_STYLES[theme?.id] || THEME_STYLES.theme_default;
|
|
833
|
+
const skinColor = skin?.color || "#00f0ff";
|
|
834
|
+
const skinSecColor = skin?.secondaryColor || "#111827";
|
|
835
|
+
const skinAccColor = skin?.accentColor || "#ffffff";
|
|
836
|
+
const skinVariant = skin?.variant || "tactical_visor";
|
|
837
|
+
const skinArch = skin?.archetype || "cyber_suit";
|
|
838
|
+
const petColor = pet?.color || "#00f0ff";
|
|
839
|
+
const petArch = pet?.archetype || "none";
|
|
840
|
+
const auraColor = aura?.color || "#00f0ff";
|
|
841
|
+
const auraArch = aura?.archetype || "none";
|
|
842
|
+
const trimColor = clientType === "app" ? "#8b5cf6" : "#10b981";
|
|
843
|
+
|
|
844
|
+
// SVG Animation Refs for zero-rerender 60 FPS animation
|
|
845
|
+
const rootGRef = useRef(null);
|
|
846
|
+
const bodyGRef = useRef(null);
|
|
847
|
+
const armLRef = useRef(null);
|
|
848
|
+
const armRRef = useRef(null);
|
|
849
|
+
const eyeLRef = useRef(null);
|
|
850
|
+
const eyeRRef = useRef(null);
|
|
851
|
+
const mouthRef = useRef(null);
|
|
852
|
+
const auraRef = useRef(null);
|
|
853
|
+
const petGRef = useRef(null);
|
|
854
|
+
const holoCubeRef = useRef(null);
|
|
855
|
+
const steamRef = useRef(null);
|
|
856
|
+
const serverLedsRef = useRef([]);
|
|
857
|
+
const oscWaveRef = useRef(null);
|
|
858
|
+
const fxGroupRef = useRef(null);
|
|
859
|
+
const auraParticlesRef = useRef(null);
|
|
860
|
+
const monitorScanlineRef = useRef(null);
|
|
861
|
+
|
|
862
|
+
// Animation Loop Effect
|
|
863
|
+
useEffect(() => {
|
|
864
|
+
if (!interactive) return;
|
|
865
|
+
|
|
866
|
+
let animId;
|
|
867
|
+
let lastTime = performance.now();
|
|
868
|
+
let frameCount = 0;
|
|
869
|
+
let fpsTimer = 0;
|
|
870
|
+
|
|
871
|
+
const tick = (now) => {
|
|
872
|
+
const dt = now - lastTime;
|
|
873
|
+
lastTime = now;
|
|
874
|
+
const t = isPlaying ? now : 0;
|
|
875
|
+
|
|
876
|
+
frameCount++;
|
|
877
|
+
fpsTimer += dt;
|
|
878
|
+
|
|
879
|
+
// 1. Body Bob, Shake & Tilt
|
|
880
|
+
let bob = Math.sin(t * 0.004) * (0.8 + intensity * 1.4);
|
|
881
|
+
let shake = 0;
|
|
882
|
+
let tilt = 0;
|
|
883
|
+
|
|
884
|
+
if (mode === "happy") bob = -Math.abs(Math.sin(t * 0.005)) * 4.2;
|
|
885
|
+
if (mode === "sleeping") {
|
|
886
|
+
bob = Math.sin(t * 0.0016) * 1.1 + 2.2;
|
|
887
|
+
tilt = (0.12 + Math.sin(t * 0.0016) * 0.02) * (180 / Math.PI);
|
|
888
|
+
}
|
|
889
|
+
if (mode === "error") shake = Math.sin(t * 0.09) * 2.2;
|
|
890
|
+
if (mode === "looping") {
|
|
891
|
+
shake = Math.sin(t * 0.08) * 2.5;
|
|
892
|
+
bob = Math.sin(t * 0.015) * 1.8;
|
|
893
|
+
tilt = Math.sin(t * 0.02) * 10;
|
|
894
|
+
}
|
|
895
|
+
|
|
896
|
+
if (bodyGRef.current) {
|
|
897
|
+
bodyGRef.current.setAttribute("transform", `translate(${shake.toFixed(2)}, ${bob.toFixed(2)}) rotate(${tilt.toFixed(2)})`);
|
|
898
|
+
}
|
|
899
|
+
|
|
900
|
+
// 2. Arms (Shoulder Pivot at (-22, -26) and (22, -26))
|
|
901
|
+
const phase = t * 0.012;
|
|
902
|
+
let rotL = 0;
|
|
903
|
+
let rotR = 0;
|
|
904
|
+
|
|
905
|
+
if (mode === "streaming") {
|
|
906
|
+
rotL = Math.sin(phase) * 0.14 * (0.3 + intensity) * (180 / Math.PI);
|
|
907
|
+
rotR = -Math.sin(phase + 1.3) * 0.14 * (0.3 + intensity) * (180 / Math.PI);
|
|
908
|
+
} else if (mode === "pending") {
|
|
909
|
+
rotL = (2.5 + Math.sin(t * 0.012) * 0.35) * (180 / Math.PI);
|
|
910
|
+
rotR = -Math.sin(phase + 1.3) * 0.06 * (180 / Math.PI);
|
|
911
|
+
} else if (mode === "happy") {
|
|
912
|
+
rotL = (2.2 + Math.sin(t * 0.01) * 0.2) * (180 / Math.PI);
|
|
913
|
+
rotR = (-2.2 - Math.sin(t * 0.01 + 1) * 0.2) * (180 / Math.PI);
|
|
914
|
+
} else if (mode === "error") {
|
|
915
|
+
rotL = (2.7 + Math.sin(t * 0.08) * 0.1) * (180 / Math.PI);
|
|
916
|
+
rotR = (-2.7 - Math.sin(t * 0.08) * 0.1) * (180 / Math.PI);
|
|
917
|
+
} else if (mode === "looping") {
|
|
918
|
+
rotL = (2.4 + Math.sin(t * 0.02) * 0.4) * (180 / Math.PI);
|
|
919
|
+
rotR = (-2.4 - Math.sin(t * 0.02 + 1) * 0.4) * (180 / Math.PI);
|
|
920
|
+
}
|
|
921
|
+
|
|
922
|
+
if (armLRef.current) armLRef.current.setAttribute("transform", `rotate(${rotL.toFixed(2)}, -22, -26)`);
|
|
923
|
+
if (armRRef.current) armRRef.current.setAttribute("transform", `rotate(${rotR.toFixed(2)}, 22, -26)`);
|
|
924
|
+
|
|
925
|
+
// 3. Eyes (Blink & CRT Flicker)
|
|
926
|
+
const blinking = Math.sin(t * 0.0013) > 0.985;
|
|
927
|
+
const flicker = (0.85 + Math.sin(t * 0.01) * 0.15).toFixed(2);
|
|
928
|
+
|
|
929
|
+
if (eyeLRef.current) {
|
|
930
|
+
eyeLRef.current.setAttribute("opacity", flicker);
|
|
931
|
+
if (mode === "streaming") {
|
|
932
|
+
eyeLRef.current.setAttribute("ry", blinking ? "0.8" : "4.4");
|
|
933
|
+
}
|
|
934
|
+
}
|
|
935
|
+
if (eyeRRef.current) {
|
|
936
|
+
eyeRRef.current.setAttribute("opacity", flicker);
|
|
937
|
+
if (mode === "streaming") {
|
|
938
|
+
eyeRRef.current.setAttribute("ry", blinking ? "0.8" : "4.4");
|
|
939
|
+
}
|
|
940
|
+
}
|
|
941
|
+
|
|
942
|
+
// Telemetry callback
|
|
943
|
+
if (fpsTimer >= 400 && onTelemetry) {
|
|
944
|
+
onTelemetry({
|
|
945
|
+
fps: Math.round((frameCount * 1000) / fpsTimer),
|
|
946
|
+
bob,
|
|
947
|
+
shake,
|
|
948
|
+
rotL,
|
|
949
|
+
rotR,
|
|
950
|
+
blink: blinking,
|
|
951
|
+
});
|
|
952
|
+
frameCount = 0;
|
|
953
|
+
fpsTimer = 0;
|
|
954
|
+
}
|
|
955
|
+
|
|
956
|
+
// 4. Aura & Ambient VFX Animation
|
|
957
|
+
if (auraRef.current && auraArch !== "none") {
|
|
958
|
+
const pulse = 1 + Math.sin(t * 0.006) * 0.12;
|
|
959
|
+
auraRef.current.setAttribute("transform", `scale(${pulse.toFixed(3)})`);
|
|
960
|
+
|
|
961
|
+
if (auraParticlesRef.current) {
|
|
962
|
+
if (auraArch === "matrix_rain") {
|
|
963
|
+
let mHtml = "";
|
|
964
|
+
const cols = [-40, -28, -16, -4, 8, 20, 32, 44];
|
|
965
|
+
const glyphs = ["0", "1", "λ", "§", "#", "*", ">", "Ψ", "Δ", "01"];
|
|
966
|
+
cols.forEach((colX, cIdx) => {
|
|
967
|
+
const speed = 0.05 + (cIdx % 3) * 0.02;
|
|
968
|
+
const dropY = -45 + ((t * speed + cIdx * 18) % 75);
|
|
969
|
+
mHtml += `<line x1="${colX}" y1="-45" x2="${colX}" y2="${dropY.toFixed(1)}" stroke="${auraColor}" stroke-width="1.2" stroke-dasharray="2 3" opacity="0.35" />`;
|
|
970
|
+
const glyph = glyphs[(Math.floor(t * 0.003 + cIdx * 3)) % glyphs.length];
|
|
971
|
+
mHtml += `<text x="${colX - 3}" y="${dropY.toFixed(1)}" fill="${auraColor}" font-size="7" font-family="monospace" font-weight="bold" opacity="0.9">${glyph}</text>`;
|
|
972
|
+
mHtml += `<circle cx="${colX}" cy="${(dropY + 2).toFixed(1)}" r="1.6" fill="#ffffff" />`;
|
|
973
|
+
});
|
|
974
|
+
auraParticlesRef.current.innerHTML = mHtml;
|
|
975
|
+
} else if (auraArch === "quantum_mist") {
|
|
976
|
+
let qHtml = "";
|
|
977
|
+
const rAng = (t * 0.02) % 360;
|
|
978
|
+
qHtml += `<ellipse cx="0" cy="0" rx="46" ry="18" fill="none" stroke="${auraColor}" stroke-width="1.4" opacity="0.5" transform="rotate(${rAng.toFixed(1)})" />`;
|
|
979
|
+
qHtml += `<ellipse cx="0" cy="0" rx="40" ry="15" fill="none" stroke="#ffffff" stroke-width="1" opacity="0.4" transform="rotate(${(-rAng * 0.7).toFixed(1)})" />`;
|
|
980
|
+
for (let i = 0; i < 6; i++) {
|
|
981
|
+
const orbAng = t * 0.0025 + (i * Math.PI * 2) / 6;
|
|
982
|
+
const ox = Math.cos(orbAng) * 44;
|
|
983
|
+
const oy = Math.sin(orbAng) * 18;
|
|
984
|
+
const zScale = 0.7 + Math.sin(orbAng) * 0.3;
|
|
985
|
+
const alpha = (0.4 + Math.sin(orbAng) * 0.5).toFixed(2);
|
|
986
|
+
qHtml += `<circle cx="${ox.toFixed(1)}" cy="${oy.toFixed(1)}" r="${(2.5 * zScale).toFixed(1)}" fill="${auraColor}" opacity="${alpha}" />`;
|
|
987
|
+
qHtml += `<circle cx="${ox.toFixed(1)}" cy="${oy.toFixed(1)}" r="${(1.2 * zScale).toFixed(1)}" fill="#ffffff" opacity="${alpha}" />`;
|
|
988
|
+
}
|
|
989
|
+
auraParticlesRef.current.innerHTML = qHtml;
|
|
990
|
+
} else if (auraArch === "glitch_halo") {
|
|
991
|
+
let gHtml = "";
|
|
992
|
+
const isGlitch = Math.sin(t * 0.04) > 0.65;
|
|
993
|
+
const jitterX = isGlitch ? Math.sin(t * 0.3) * 6 : 0;
|
|
994
|
+
const jitterY = isGlitch ? Math.cos(t * 0.4) * 3 : 0;
|
|
995
|
+
gHtml += `<rect x="${(-38 + jitterX).toFixed(1)}" y="${(-26 + jitterY).toFixed(1)}" width="76" height="34" rx="4" fill="none" stroke="#00f0ff" stroke-width="1.8" opacity="0.75" />`;
|
|
996
|
+
gHtml += `<rect x="${(-38 - jitterX * 0.8).toFixed(1)}" y="${(-26 - jitterY * 0.8).toFixed(1)}" width="76" height="34" rx="4" fill="none" stroke="#ff007f" stroke-width="1.8" opacity="0.75" />`;
|
|
997
|
+
gHtml += `<rect x="-38" y="-26" width="76" height="34" rx="4" fill="none" stroke="${auraColor}" stroke-width="2.2" opacity="0.9" />`;
|
|
998
|
+
for (let sl = -20; sl <= 20; sl += 10) {
|
|
999
|
+
const sOff = isGlitch ? Math.sin(t * 0.2 + sl) * 8 : 0;
|
|
1000
|
+
gHtml += `<line x1="${(-38 + sOff).toFixed(1)}" y1="${sl}" x2="${(38 + sOff).toFixed(1)}" y2="${sl}" stroke="#ffffff" stroke-width="0.8" opacity="0.5" />`;
|
|
1001
|
+
}
|
|
1002
|
+
auraParticlesRef.current.innerHTML = gHtml;
|
|
1003
|
+
} else {
|
|
1004
|
+
// Plasma Ring & Other Auras
|
|
1005
|
+
let pHtml = "";
|
|
1006
|
+
const rot1 = (t * 0.03) % 360;
|
|
1007
|
+
const rot2 = (-t * 0.045) % 360;
|
|
1008
|
+
pHtml += `<ellipse cx="0" cy="0" rx="46" ry="18" fill="none" stroke="${auraColor}" stroke-width="2.5" opacity="0.8" transform="rotate(${rot1.toFixed(1)})" />`;
|
|
1009
|
+
pHtml += `<ellipse cx="0" cy="0" rx="42" ry="14" fill="none" stroke="#ffffff" stroke-width="1.2" opacity="0.6" transform="rotate(${rot2.toFixed(1)})" />`;
|
|
1010
|
+
for (let i = 0; i < 8; i++) {
|
|
1011
|
+
const fAng = (t * 0.002 + (i * Math.PI * 2) / 8);
|
|
1012
|
+
const fx = Math.cos(fAng) * 44;
|
|
1013
|
+
const fy = Math.sin(fAng) * 16;
|
|
1014
|
+
pHtml += `<circle cx="${fx.toFixed(1)}" cy="${fy.toFixed(1)}" r="2" fill="${auraColor}" opacity="0.8" />`;
|
|
1015
|
+
}
|
|
1016
|
+
auraParticlesRef.current.innerHTML = pHtml;
|
|
1017
|
+
}
|
|
1018
|
+
}
|
|
1019
|
+
}
|
|
1020
|
+
|
|
1021
|
+
// 5. Props & Desk Animation
|
|
1022
|
+
if (holoCubeRef.current) {
|
|
1023
|
+
const ang = (t * 0.1) % 360;
|
|
1024
|
+
holoCubeRef.current.setAttribute("transform", `translate(65, -15) rotate(${ang.toFixed(1)})`);
|
|
1025
|
+
}
|
|
1026
|
+
|
|
1027
|
+
if (serverLedsRef.current.length > 0) {
|
|
1028
|
+
const ledCols = ["#22c55e", "#00f0ff", "#f59e0b", "#ec4899"];
|
|
1029
|
+
serverLedsRef.current.forEach((led, idx) => {
|
|
1030
|
+
if (!led) return;
|
|
1031
|
+
const on = Math.sin(t * 0.008 + idx * 1.6) > 0;
|
|
1032
|
+
led.setAttribute("fill", on ? ledCols[idx] : "#0f172a");
|
|
1033
|
+
});
|
|
1034
|
+
}
|
|
1035
|
+
|
|
1036
|
+
if (oscWaveRef.current) {
|
|
1037
|
+
let d = "M 57 21";
|
|
1038
|
+
for (let ox = 57; ox <= 85; ox += 3) {
|
|
1039
|
+
const oy = 21 + Math.sin(t * 0.01 + ox * 0.8) * 4;
|
|
1040
|
+
d += ` L ${ox} ${oy.toFixed(1)}`;
|
|
1041
|
+
}
|
|
1042
|
+
oscWaveRef.current.setAttribute("d", d);
|
|
1043
|
+
}
|
|
1044
|
+
|
|
1045
|
+
if (steamRef.current) {
|
|
1046
|
+
let sHtml = "";
|
|
1047
|
+
for (let i = 0; i < 3; i++) {
|
|
1048
|
+
const p = ((t * 0.0008 + i / 3) % 1);
|
|
1049
|
+
const sy = 8 - p * 22;
|
|
1050
|
+
const sx = -73 + Math.sin(p * 5 + i * 2) * 4;
|
|
1051
|
+
const alpha = (0.55 * (1 - p)).toFixed(2);
|
|
1052
|
+
const r = 1 + p * 2.5;
|
|
1053
|
+
sHtml += `<circle cx="${sx.toFixed(1)}" cy="${sy.toFixed(1)}" r="${r.toFixed(1)}" fill="#ffffff" opacity="${alpha}" />`;
|
|
1054
|
+
}
|
|
1055
|
+
steamRef.current.innerHTML = sHtml;
|
|
1056
|
+
}
|
|
1057
|
+
|
|
1058
|
+
if (monitorScanlineRef.current) {
|
|
1059
|
+
const sY = -42 + ((t * 0.035) % 42);
|
|
1060
|
+
monitorScanlineRef.current.setAttribute("y1", sY.toFixed(1));
|
|
1061
|
+
monitorScanlineRef.current.setAttribute("y2", sY.toFixed(1));
|
|
1062
|
+
}
|
|
1063
|
+
|
|
1064
|
+
// 6. Pet Animation
|
|
1065
|
+
if (petGRef.current && petArch !== "none") {
|
|
1066
|
+
if (petArch === "hover_drone") {
|
|
1067
|
+
const droneY = -25 + Math.sin(t * 0.005) * 5;
|
|
1068
|
+
petGRef.current.setAttribute("transform", `translate(80, ${droneY.toFixed(2)})`);
|
|
1069
|
+
} else if (mode === "happy") {
|
|
1070
|
+
const jumpY = -Math.abs(Math.sin(t * 0.008)) * 8;
|
|
1071
|
+
const squash = 1 + Math.abs(Math.sin(t * 0.008)) * 0.15;
|
|
1072
|
+
petGRef.current.setAttribute("transform", `translate(80, ${jumpY.toFixed(2)}) scale(1, ${squash.toFixed(2)})`);
|
|
1073
|
+
} else if (mode === "sleeping") {
|
|
1074
|
+
const breathe = 1 + Math.sin(t * 0.0016) * 0.04;
|
|
1075
|
+
petGRef.current.setAttribute("transform", `translate(80, 0) scale(1, ${breathe.toFixed(2)})`);
|
|
1076
|
+
} else if (mode === "error") {
|
|
1077
|
+
const petShake = Math.sin(t * 0.08) * 2;
|
|
1078
|
+
petGRef.current.setAttribute("transform", `translate(${(80 + petShake).toFixed(2)}, 0)`);
|
|
1079
|
+
} else if (mode === "looping") {
|
|
1080
|
+
const petTilt = Math.sin(t * 0.04) * 8;
|
|
1081
|
+
petGRef.current.setAttribute("transform", `translate(80, 0) rotate(${petTilt.toFixed(1)})`);
|
|
1082
|
+
} else {
|
|
1083
|
+
petGRef.current.setAttribute("transform", "translate(80, 0)");
|
|
1084
|
+
}
|
|
1085
|
+
}
|
|
1086
|
+
|
|
1087
|
+
// 7. Dynamic Workstation & Action Particle Effects
|
|
1088
|
+
if (fxGroupRef.current) {
|
|
1089
|
+
if (mode === "streaming" || mode === "pending") {
|
|
1090
|
+
// Keystroke sparks & floating code bits shooting up from keyboard
|
|
1091
|
+
let inner = "";
|
|
1092
|
+
const numParticles = Math.min(8, Math.round(3 + intensity * 6));
|
|
1093
|
+
const codeTokens = ["✦", "01", "</>", "{ }", "++", "=>", "•", "λ", "=="];
|
|
1094
|
+
for (let k = 0; k < numParticles; k++) {
|
|
1095
|
+
const p = ((t * (0.0006 + intensity * 0.0006) + k / numParticles) % 1);
|
|
1096
|
+
const sx = 20 - p * 30 + Math.sin(p * 6 + k) * 6;
|
|
1097
|
+
const sy = 25 - p * 42;
|
|
1098
|
+
const alpha = (Math.sin(p * Math.PI) * (0.4 + intensity * 0.6)).toFixed(2);
|
|
1099
|
+
const token = codeTokens[k % codeTokens.length];
|
|
1100
|
+
if (k % 2 === 0) {
|
|
1101
|
+
inner += `<text x="${sx.toFixed(1)}" y="${sy.toFixed(1)}" fill="${skinColor}" font-size="5.5" font-family="monospace" font-weight="bold" opacity="${alpha}">${token}</text>`;
|
|
1102
|
+
} else {
|
|
1103
|
+
inner += `<circle cx="${sx.toFixed(1)}" cy="${sy.toFixed(1)}" r="${(1 + p * 1.5).toFixed(1)}" fill="#00f0ff" opacity="${alpha}" />`;
|
|
1104
|
+
}
|
|
1105
|
+
}
|
|
1106
|
+
fxGroupRef.current.innerHTML = inner;
|
|
1107
|
+
} else if (mode === "happy") {
|
|
1108
|
+
// Celebration Confetti & Sparkles
|
|
1109
|
+
let inner = "";
|
|
1110
|
+
const colors = ["#fbbf24", "#00f0ff", "#f43f5e", "#10b981", "#a855f7", "#ffffff"];
|
|
1111
|
+
const shapes = ["✦", "★", "✧", "•"];
|
|
1112
|
+
for (let k = 0; k < 10; k++) {
|
|
1113
|
+
const p = ((t * 0.0007 + k / 10) % 1);
|
|
1114
|
+
const ang = (k / 10) * Math.PI * 2;
|
|
1115
|
+
const dist = 18 + p * 45;
|
|
1116
|
+
const cx = Math.cos(ang) * dist;
|
|
1117
|
+
const cy = -50 + Math.sin(ang) * (dist * 0.7) - p * 15;
|
|
1118
|
+
const alpha = ((1 - p) * 0.9).toFixed(2);
|
|
1119
|
+
const col = colors[k % colors.length];
|
|
1120
|
+
const sym = shapes[k % shapes.length];
|
|
1121
|
+
inner += `<text x="${cx.toFixed(1)}" y="${cy.toFixed(1)}" fill="${col}" font-size="7" font-weight="bold" opacity="${alpha}">${sym}</text>`;
|
|
1122
|
+
}
|
|
1123
|
+
fxGroupRef.current.innerHTML = inner;
|
|
1124
|
+
} else if (mode === "sleeping") {
|
|
1125
|
+
// Floating Sleep Z Letters & Bubbles
|
|
1126
|
+
let inner = "";
|
|
1127
|
+
for (let k = 0; k < 4; k++) {
|
|
1128
|
+
const p = ((t * 0.0004 + k / 4) % 1);
|
|
1129
|
+
const zx = 18 + p * 20;
|
|
1130
|
+
const zy = -78 - p * 34;
|
|
1131
|
+
const s = 3 + p * 4;
|
|
1132
|
+
const alpha = (1 - p).toFixed(2);
|
|
1133
|
+
inner += `<path d="M ${zx} ${zy} L ${zx + s} ${zy} L ${zx} ${zy + s} L ${zx + s} ${zy + s}" stroke="#93c5fd" stroke-width="1.8" fill="none" opacity="${alpha}" />`;
|
|
1134
|
+
inner += `<circle cx="${(zx - 6).toFixed(1)}" cy="${(zy + 8).toFixed(1)}" r="${(1.5 + p * 3).toFixed(1)}" fill="none" stroke="#60a5fa" stroke-width="0.8" opacity="${(alpha * 0.6).toFixed(2)}" />`;
|
|
1135
|
+
}
|
|
1136
|
+
fxGroupRef.current.innerHTML = inner;
|
|
1137
|
+
} else if (mode === "error" || mode === "looping") {
|
|
1138
|
+
// Billowing Smoke & Electric Arc Sparks
|
|
1139
|
+
let inner = "";
|
|
1140
|
+
for (let k = 0; k < 5; k++) {
|
|
1141
|
+
const p = ((t * 0.0008 + k / 5) % 1);
|
|
1142
|
+
const sx = Math.sin(p * 8 + k * 1.3) * 8 + (k - 2) * 4;
|
|
1143
|
+
const sy = -76 - p * 42;
|
|
1144
|
+
const r = 2.5 + p * 8;
|
|
1145
|
+
const alpha = (0.65 * (1 - p)).toFixed(2);
|
|
1146
|
+
inner += `<circle cx="${sx.toFixed(1)}" cy="${sy.toFixed(1)}" r="${r.toFixed(1)}" fill="#4b5563" opacity="${alpha}" />`;
|
|
1147
|
+
}
|
|
1148
|
+
if (Math.sin(t * 0.05) > 0.6) {
|
|
1149
|
+
inner += `<path d="M -26 -65 L -34 -72 L -28 -74 L -36 -82" stroke="#f43f5e" stroke-width="1.5" fill="none" />`;
|
|
1150
|
+
inner += `<path d="M 26 -65 L 34 -72 L 28 -74 L 36 -82" stroke="#facc15" stroke-width="1.5" fill="none" />`;
|
|
1151
|
+
}
|
|
1152
|
+
fxGroupRef.current.innerHTML = inner;
|
|
1153
|
+
} else {
|
|
1154
|
+
fxGroupRef.current.innerHTML = "";
|
|
1155
|
+
}
|
|
1156
|
+
}
|
|
1157
|
+
|
|
1158
|
+
if (isPlaying) {
|
|
1159
|
+
animId = requestAnimationFrame(tick);
|
|
1160
|
+
}
|
|
1161
|
+
};
|
|
1162
|
+
|
|
1163
|
+
animId = requestAnimationFrame(tick);
|
|
1164
|
+
return () => cancelAnimationFrame(animId);
|
|
1165
|
+
}, [interactive, mode, intensity, petArch, isPlaying]);
|
|
1166
|
+
|
|
1167
|
+
// Prop helpers & resolved list
|
|
1168
|
+
const resolvedProps = useMemo(() => {
|
|
1169
|
+
if (!propsList || propsList.length === 0) return [];
|
|
1170
|
+
return propsList
|
|
1171
|
+
.map((p) => (typeof p === "object" && p !== null ? p : getItemById(p) || null))
|
|
1172
|
+
.filter(Boolean);
|
|
1173
|
+
}, [propsList]);
|
|
1174
|
+
|
|
1175
|
+
const hasProp = (keyword) => {
|
|
1176
|
+
const kw = String(keyword).toLowerCase();
|
|
1177
|
+
return (
|
|
1178
|
+
(propsList || []).some((p) => String(p).toLowerCase().includes(kw)) ||
|
|
1179
|
+
resolvedProps.some((p) => (p.archetype && p.archetype.includes(kw)) || (p.name && p.name.toLowerCase().includes(kw)))
|
|
1180
|
+
);
|
|
1181
|
+
};
|
|
1182
|
+
|
|
1183
|
+
const getProp = (arch) => {
|
|
1184
|
+
const kw = String(arch).toLowerCase();
|
|
1185
|
+
return resolvedProps.find((p) => (p.archetype && p.archetype.includes(kw)) || (p.name && p.name.toLowerCase().includes(kw)) || String(p.id).includes(kw));
|
|
1186
|
+
};
|
|
1187
|
+
|
|
1188
|
+
return (
|
|
1189
|
+
<div
|
|
1190
|
+
className={`relative select-none flex items-center justify-center overflow-hidden ${className}`}
|
|
1191
|
+
style={style}
|
|
1192
|
+
>
|
|
1193
|
+
<svg
|
|
1194
|
+
ref={rootGRef}
|
|
1195
|
+
viewBox={showDesk || showFloor ? "-170 -160 340 300" : "-65 -95 130 130"}
|
|
1196
|
+
className="w-full h-full block"
|
|
1197
|
+
style={{ filter: "drop-shadow(0 12px 24px rgba(0,0,0,0.5))" }}
|
|
1198
|
+
>
|
|
1199
|
+
<defs>
|
|
1200
|
+
{/* Radial Ambient Glow */}
|
|
1201
|
+
<radialGradient id={`${idPrefix}_ambientGlow`} cx="50%" cy="50%" r="50%">
|
|
1202
|
+
<stop offset="0%" stopColor={themeStyle.glow} stopOpacity="0.25" />
|
|
1203
|
+
<stop offset="70%" stopColor={themeStyle.base} stopOpacity="0.05" />
|
|
1204
|
+
<stop offset="100%" stopColor="transparent" stopOpacity="0" />
|
|
1205
|
+
</radialGradient>
|
|
1206
|
+
|
|
1207
|
+
{/* Torso & Head Shading Gradients */}
|
|
1208
|
+
<linearGradient id={`${idPrefix}_bodyGradient`} x1="0" y1="0" x2="0" y2="1">
|
|
1209
|
+
<stop offset="0%" stopColor="#ffffff" />
|
|
1210
|
+
<stop offset="50%" stopColor="#1e2430" />
|
|
1211
|
+
<stop offset="100%" stopColor="#111622" />
|
|
1212
|
+
</linearGradient>
|
|
1213
|
+
|
|
1214
|
+
<linearGradient id={`${idPrefix}_headGradient`} x1="0" y1="0" x2="0" y2="1">
|
|
1215
|
+
<stop offset="0%" stopColor="#2d3748" />
|
|
1216
|
+
<stop offset="60%" stopColor="#1e2430" />
|
|
1217
|
+
<stop offset="100%" stopColor="#111622" />
|
|
1218
|
+
</linearGradient>
|
|
1219
|
+
|
|
1220
|
+
<linearGradient id={`${idPrefix}_deskGradient`} x1="0" y1="0" x2="0" y2="1">
|
|
1221
|
+
<stop offset="0%" stopColor="#2b3443" />
|
|
1222
|
+
<stop offset="100%" stopColor="#181d26" />
|
|
1223
|
+
</linearGradient>
|
|
1224
|
+
|
|
1225
|
+
<linearGradient id={`${idPrefix}_floorGradient`} x1="0" y1="0" x2="0" y2="1">
|
|
1226
|
+
<stop offset="0%" stopColor={themeStyle.tile} />
|
|
1227
|
+
<stop offset="100%" stopColor={themeStyle.base} />
|
|
1228
|
+
</linearGradient>
|
|
1229
|
+
</defs>
|
|
1230
|
+
|
|
1231
|
+
{/* 1. FLOOR THEME ISOMETRIC ENVIRONMENT */}
|
|
1232
|
+
{showFloor && (
|
|
1233
|
+
<g transform="translate(0, 50)">
|
|
1234
|
+
{/* Ambient Radial Spotlight */}
|
|
1235
|
+
<circle cx="0" cy="-30" r="140" fill={`url(#${idPrefix}_ambientGlow)`} />
|
|
1236
|
+
|
|
1237
|
+
{/* Floor Cast Shadow */}
|
|
1238
|
+
<ellipse cx="0" cy="18" rx="145" ry="46" fill="#000000" opacity="0.55" />
|
|
1239
|
+
|
|
1240
|
+
{/* Isometric Floor Rhombus */}
|
|
1241
|
+
<polygon
|
|
1242
|
+
points="0,-68 150,0 0,68 -150,0"
|
|
1243
|
+
fill={`url(#${idPrefix}_floorGradient)`}
|
|
1244
|
+
stroke={themeStyle.grid}
|
|
1245
|
+
strokeWidth="1.8"
|
|
1246
|
+
/>
|
|
1247
|
+
|
|
1248
|
+
{/* Floor Bevel Extrusion Rim */}
|
|
1249
|
+
<polygon points="-150,0 0,68 0,76 -150,8" fill="#090a0f" opacity="0.6" />
|
|
1250
|
+
<polygon points="150,0 0,68 0,76 150,8" fill="#050608" opacity="0.8" />
|
|
1251
|
+
|
|
1252
|
+
{/* Floor Gridlines */}
|
|
1253
|
+
<g stroke={themeStyle.grid} strokeWidth="1" opacity="0.45">
|
|
1254
|
+
<line x1="-75" y1="-34" x2="75" y2="34" />
|
|
1255
|
+
<line x1="-112" y1="-17" x2="38" y2="51" />
|
|
1256
|
+
<line x1="-38" y1="-51" x2="112" y2="17" />
|
|
1257
|
+
<line x1="75" y1="-34" x2="-75" y2="34" />
|
|
1258
|
+
<line x1="112" y1="-17" x2="-38" y2="51" />
|
|
1259
|
+
<line x1="38" y1="-51" x2="-112" y2="17" />
|
|
1260
|
+
</g>
|
|
1261
|
+
|
|
1262
|
+
{/* Neon Corner Brackets */}
|
|
1263
|
+
<g stroke={themeStyle.glow} strokeWidth="2" fill="none">
|
|
1264
|
+
<path d="M -130,-4 L -145,0 L -130,4" />
|
|
1265
|
+
<path d="M 130,-4 L 145,0 L 130,4" />
|
|
1266
|
+
</g>
|
|
1267
|
+
</g>
|
|
1268
|
+
)}
|
|
1269
|
+
|
|
1270
|
+
{/* 2. DYNAMIC AURA & ATMOSPHERE EFFECTS LAYER (Behind Character) */}
|
|
1271
|
+
{auraArch !== "none" && (
|
|
1272
|
+
<g transform="translate(0, -42)">
|
|
1273
|
+
<g ref={auraRef}>
|
|
1274
|
+
<g ref={auraParticlesRef} />
|
|
1275
|
+
</g>
|
|
1276
|
+
</g>
|
|
1277
|
+
)}
|
|
1278
|
+
|
|
1279
|
+
{/* 3. AGENT BODY & HEAD (Positioned behind desk) */}
|
|
1280
|
+
<g id="agent-root" transform="translate(0, -50)">
|
|
1281
|
+
<g ref={bodyGRef}>
|
|
1282
|
+
{/* Distinct Staff Torso & Uniform Silhouette */}
|
|
1283
|
+
<RenderStaffTorso
|
|
1284
|
+
archetype={skinArch}
|
|
1285
|
+
color={skinColor}
|
|
1286
|
+
secondaryColor={skinSecColor}
|
|
1287
|
+
accentColor={skinAccColor}
|
|
1288
|
+
idPrefix={idPrefix}
|
|
1289
|
+
trimColor={trimColor}
|
|
1290
|
+
/>
|
|
1291
|
+
|
|
1292
|
+
{/* Distinct Staff Arms with Archetype Sleeves */}
|
|
1293
|
+
<RenderStaffArms
|
|
1294
|
+
archetype={skinArch}
|
|
1295
|
+
color={skinColor}
|
|
1296
|
+
armLRef={armLRef}
|
|
1297
|
+
armRRef={armRRef}
|
|
1298
|
+
/>
|
|
1299
|
+
|
|
1300
|
+
{/* Comm Pods */}
|
|
1301
|
+
<circle cx="-27" cy="-56" r="8" fill={skinColor} />
|
|
1302
|
+
<circle cx="27" cy="-56" r="8" fill={skinColor} />
|
|
1303
|
+
|
|
1304
|
+
{/* Helmet Sphere */}
|
|
1305
|
+
<ellipse
|
|
1306
|
+
cx="0"
|
|
1307
|
+
cy="-56"
|
|
1308
|
+
rx="26"
|
|
1309
|
+
ry="24"
|
|
1310
|
+
fill={`url(#${idPrefix}_headGradient)`}
|
|
1311
|
+
stroke={skinColor}
|
|
1312
|
+
strokeWidth="2.2"
|
|
1313
|
+
/>
|
|
1314
|
+
|
|
1315
|
+
{/* Visor Cavity */}
|
|
1316
|
+
<ellipse cx="0" cy="-53" rx="20" ry="15.5" fill="#0f141c" />
|
|
1317
|
+
|
|
1318
|
+
{/* Custom 50 Curated Skin Accessories */}
|
|
1319
|
+
<RenderSkinAccessories
|
|
1320
|
+
variant={skinVariant}
|
|
1321
|
+
archetype={skinArch}
|
|
1322
|
+
color={skinColor}
|
|
1323
|
+
secondaryColor={skinSecColor}
|
|
1324
|
+
accentColor={skinAccColor}
|
|
1325
|
+
/>
|
|
1326
|
+
|
|
1327
|
+
{/* CRT Visor Eyes */}
|
|
1328
|
+
{mode === "happy" ? (
|
|
1329
|
+
<g stroke={skinColor} strokeWidth="2.2" fill="none">
|
|
1330
|
+
<path d="M -12.6 -55 A 4.6 4.6 0 0 1 -3.4 -55" />
|
|
1331
|
+
<path d="M 3.4 -55 A 4.6 4.6 0 0 1 12.6 -55" />
|
|
1332
|
+
</g>
|
|
1333
|
+
) : mode === "sleeping" ? (
|
|
1334
|
+
<g stroke={skinColor} strokeWidth="2.2" fill="none">
|
|
1335
|
+
<path d="M -12.6 -57 A 4.6 4.6 0 0 0 -3.4 -57" />
|
|
1336
|
+
<path d="M 3.4 -57 A 4.6 4.6 0 0 0 12.6 -57" />
|
|
1337
|
+
</g>
|
|
1338
|
+
) : mode === "error" ? (
|
|
1339
|
+
<g stroke={skinColor} strokeWidth="2.2">
|
|
1340
|
+
<line x1="-12" y1="-61" x2="-4" y2="-53" />
|
|
1341
|
+
<line x1="-4" y1="-61" x2="-12" y2="-53" />
|
|
1342
|
+
<line x1="4" y1="-61" x2="12" y2="-53" />
|
|
1343
|
+
<line x1="12" y1="-61" x2="4" y2="-53" />
|
|
1344
|
+
</g>
|
|
1345
|
+
) : mode === "looping" ? (
|
|
1346
|
+
<g stroke={skinColor} strokeWidth="1.6" fill="none">
|
|
1347
|
+
<circle cx="-8" cy="-57" r="4.2" />
|
|
1348
|
+
<circle cx="-8" cy="-57" r="2.0" />
|
|
1349
|
+
<circle cx="8" cy="-57" r="4.2" />
|
|
1350
|
+
<circle cx="8" cy="-57" r="2.0" />
|
|
1351
|
+
</g>
|
|
1352
|
+
) : (
|
|
1353
|
+
<g>
|
|
1354
|
+
<ellipse ref={eyeLRef} cx="-8" cy="-57" rx="4.8" ry="4.4" fill={skinColor} />
|
|
1355
|
+
<ellipse ref={eyeRRef} cx="8" cy="-57" rx="4.8" ry="4.4" fill={skinColor} />
|
|
1356
|
+
</g>
|
|
1357
|
+
)}
|
|
1358
|
+
|
|
1359
|
+
{/* Mouth */}
|
|
1360
|
+
{mode === "happy" ? (
|
|
1361
|
+
<path d="M -6 -48 A 6 6 0 0 0 6 -48" stroke={skinColor} strokeWidth="2.2" fill="none" />
|
|
1362
|
+
) : mode === "sleeping" ? (
|
|
1363
|
+
<circle cx="0" cy="-45" r="1.8" fill="none" stroke={skinColor} strokeWidth="1.6" />
|
|
1364
|
+
) : mode === "error" ? (
|
|
1365
|
+
<path d="M -7 -45 L -3.5 -48 L 0 -45 L 3.5 -48 L 7 -45" stroke={skinColor} strokeWidth="2" fill="none" />
|
|
1366
|
+
) : mode === "looping" ? (
|
|
1367
|
+
<circle cx="0" cy="-46" r="3.2" fill="none" stroke={skinColor} strokeWidth="2" />
|
|
1368
|
+
) : (
|
|
1369
|
+
<ellipse ref={mouthRef} cx="0" cy="-46" rx={5 + intensity * 3} ry={2.4 + intensity * 1.2} fill={skinColor} />
|
|
1370
|
+
)}
|
|
1371
|
+
|
|
1372
|
+
{/* Particle Effects Group (Z's or Smoke) */}
|
|
1373
|
+
<g ref={fxGroupRef} />
|
|
1374
|
+
</g>
|
|
1375
|
+
</g>
|
|
1376
|
+
|
|
1377
|
+
{/* 4. WORKSTATION DESK & PROPS (In front of Character) */}
|
|
1378
|
+
{showDesk && (
|
|
1379
|
+
<g id="desk-root" transform="translate(0, 0)">
|
|
1380
|
+
{/* Ground Contact Shadow */}
|
|
1381
|
+
<ellipse cx="0" cy="65" rx="110" ry="14" fill="#000000" opacity="0.4" />
|
|
1382
|
+
|
|
1383
|
+
{/* Desk Surface & Base */}
|
|
1384
|
+
<rect x="-105" y="0" width="210" height="120" rx="10" fill={`url(#${idPrefix}_deskGradient)`} stroke="#475569" strokeWidth="1.5" />
|
|
1385
|
+
|
|
1386
|
+
{/* Desk Lip Highlight */}
|
|
1387
|
+
<rect x="-105" y="0" width="210" height="4" fill="#ffffff" opacity="0.15" />
|
|
1388
|
+
|
|
1389
|
+
{/* Latency / Elapsed Progress Bar */}
|
|
1390
|
+
<rect x="-85" y="106" width="170" height="6" rx="3" fill="#0f141c" />
|
|
1391
|
+
<rect
|
|
1392
|
+
x="-85"
|
|
1393
|
+
y="106"
|
|
1394
|
+
width={170 * (0.3 + intensity * 0.7)}
|
|
1395
|
+
height="6"
|
|
1396
|
+
rx="3"
|
|
1397
|
+
fill={mode === "error" ? "#f43f5e" : intensity > 0.8 ? "#f59e0b" : "#10b981"}
|
|
1398
|
+
/>
|
|
1399
|
+
|
|
1400
|
+
{/* Center Monitor Screen */}
|
|
1401
|
+
<rect x="-45" y="-45" width="90" height="48" rx="4" fill="#0b0e13" />
|
|
1402
|
+
<rect
|
|
1403
|
+
x="-42"
|
|
1404
|
+
y="-42"
|
|
1405
|
+
width="84"
|
|
1406
|
+
height="42"
|
|
1407
|
+
rx="3"
|
|
1408
|
+
fill={mode === "error" ? "rgba(244,63,94,0.3)" : "rgba(0,240,255,0.25)"}
|
|
1409
|
+
/>
|
|
1410
|
+
|
|
1411
|
+
{/* CRT Active Scanline Beam */}
|
|
1412
|
+
<line
|
|
1413
|
+
ref={monitorScanlineRef}
|
|
1414
|
+
x1="-42"
|
|
1415
|
+
y1="-42"
|
|
1416
|
+
x2="42"
|
|
1417
|
+
y2="-42"
|
|
1418
|
+
stroke={mode === "error" ? "#f43f5e" : "#00f0ff"}
|
|
1419
|
+
strokeWidth="1.6"
|
|
1420
|
+
opacity="0.65"
|
|
1421
|
+
/>
|
|
1422
|
+
|
|
1423
|
+
{/* Screen Code Lines */}
|
|
1424
|
+
<g fill="#ffffff" opacity="0.5">
|
|
1425
|
+
<rect x="-38" y="-38" width="24" height="3" rx="1" />
|
|
1426
|
+
<rect x="-38" y="-29" width="42" height="3" rx="1" />
|
|
1427
|
+
<rect x="-38" y="-20" width="30" height="3" rx="1" />
|
|
1428
|
+
<rect x="-38" y="-11" width="36" height="3" rx="1" />
|
|
1429
|
+
</g>
|
|
1430
|
+
|
|
1431
|
+
{/* Monitor Client Badge */}
|
|
1432
|
+
<rect x="-42" y="-42" width="28" height="12" rx="2" fill={clientType === "app" ? "#3b0764" : "#064e3b"} />
|
|
1433
|
+
<text x="-38" y="-33" fontFamily="monospace" fontSize="8" fontWeight="bold" fill={clientType === "app" ? "#d8b4fe" : "#6ee7b7"}>
|
|
1434
|
+
{clientType.toUpperCase()}
|
|
1435
|
+
</text>
|
|
1436
|
+
|
|
1437
|
+
{/* ----------------- EQUIPPED PROPS (7 DISTINCT ARCHETYPES) ----------------- */}
|
|
1438
|
+
|
|
1439
|
+
{/* 1. SUPERCOMPUTER / SERVER TOWER */}
|
|
1440
|
+
{(hasProp("supercomputer") || hasProp("server") || hasProp("tower") || (resolvedProps.length === 0 && hasProp("prop_1"))) && (() => {
|
|
1441
|
+
const p = getProp("supercomputer") || { color: "#00f0ff", secondaryColor: "#003b46" };
|
|
1442
|
+
return (
|
|
1443
|
+
<g id="prop-supercomputer" transform="translate(-98, -26)">
|
|
1444
|
+
<rect x="0" y="0" width="16" height="42" rx="3" fill="#121824" stroke={p.color} strokeWidth="1.2" />
|
|
1445
|
+
{/* Drive bays */}
|
|
1446
|
+
<line x1="3" y1="8" x2="13" y2="8" stroke="#334155" strokeWidth="1.5" />
|
|
1447
|
+
<line x1="3" y1="14" x2="13" y2="14" stroke="#334155" strokeWidth="1.5" />
|
|
1448
|
+
<line x1="3" y1="20" x2="13" y2="20" stroke="#334155" strokeWidth="1.5" />
|
|
1449
|
+
{/* Blinking LEDs */}
|
|
1450
|
+
{[0, 1, 2, 3].map((idx) => (
|
|
1451
|
+
<circle
|
|
1452
|
+
key={`server-led-${idx}`}
|
|
1453
|
+
ref={(el) => (serverLedsRef.current[idx] = el)}
|
|
1454
|
+
cx="5"
|
|
1455
|
+
cy={26 + idx * 4}
|
|
1456
|
+
r="1.4"
|
|
1457
|
+
fill={p.color}
|
|
1458
|
+
/>
|
|
1459
|
+
))}
|
|
1460
|
+
{/* Ventilation Grill */}
|
|
1461
|
+
<line x1="9" y1="26" x2="13" y2="26" stroke={p.color} strokeWidth="0.8" opacity="0.6" />
|
|
1462
|
+
<line x1="9" y1="30" x2="13" y2="30" stroke={p.color} strokeWidth="0.8" opacity="0.6" />
|
|
1463
|
+
<line x1="9" y1="34" x2="13" y2="34" stroke={p.color} strokeWidth="0.8" opacity="0.6" />
|
|
1464
|
+
<line x1="9" y1="38" x2="13" y2="38" stroke={p.color} strokeWidth="0.8" opacity="0.6" />
|
|
1465
|
+
</g>
|
|
1466
|
+
);
|
|
1467
|
+
})()}
|
|
1468
|
+
|
|
1469
|
+
{/* 2. ESPRESSO STATION */}
|
|
1470
|
+
{(hasProp("espresso_station") || hasProp("espresso") || hasProp("coffee") || (resolvedProps.length === 0)) && (() => {
|
|
1471
|
+
const p = getProp("espresso_station") || { color: "#e2e8f0", secondaryColor: "#1e293b" };
|
|
1472
|
+
return (
|
|
1473
|
+
<g id="prop-espresso">
|
|
1474
|
+
{/* Steaming Coffee Cup */}
|
|
1475
|
+
<rect x="-80" y="10" width="14" height="16" rx="2" fill={p.color || "#e2e8f0"} stroke="#475569" strokeWidth="1" />
|
|
1476
|
+
<path d="M -66 14 C -62 14, -62 22, -66 22" stroke={p.color || "#e2e8f0"} strokeWidth="2" fill="none" />
|
|
1477
|
+
<g ref={steamRef} />
|
|
1478
|
+
{/* Machine Body (if explicitly an espresso station) */}
|
|
1479
|
+
{(hasProp("espresso_station") || hasProp("espresso")) && (
|
|
1480
|
+
<g transform="translate(-84, -14)">
|
|
1481
|
+
<rect x="0" y="0" width="18" height="24" rx="2" fill="#1e293b" stroke={p.color} strokeWidth="1" />
|
|
1482
|
+
<circle cx="9" cy="8" r="4" fill="#0f172a" stroke={p.color} strokeWidth="0.8" />
|
|
1483
|
+
<line x1="9" y1="8" x2="11" y2="6" stroke="#ef4444" strokeWidth="0.8" />
|
|
1484
|
+
<rect x="6" y="14" width="6" height="3" fill="#64748b" />
|
|
1485
|
+
</g>
|
|
1486
|
+
)}
|
|
1487
|
+
</g>
|
|
1488
|
+
);
|
|
1489
|
+
})()}
|
|
1490
|
+
|
|
1491
|
+
{/* 3. ARCADE CABINET */}
|
|
1492
|
+
{(hasProp("arcade_cabinet") || hasProp("arcade")) && (() => {
|
|
1493
|
+
const p = getProp("arcade_cabinet") || { color: "#f43f5e", secondaryColor: "#881337" };
|
|
1494
|
+
return (
|
|
1495
|
+
<g id="prop-arcade" transform="translate(-96, -24)">
|
|
1496
|
+
{/* Cabinet Body */}
|
|
1497
|
+
<polygon points="0,42 0,6 4,0 16,0 18,6 18,42" fill="#18181b" stroke={p.color} strokeWidth="1.2" />
|
|
1498
|
+
{/* Marquee Banner */}
|
|
1499
|
+
<rect x="3" y="2" width="12" height="6" rx="1" fill={p.color} />
|
|
1500
|
+
<text x="9" y="7" fill="#ffffff" fontSize="4" fontWeight="bold" textAnchor="middle" fontFamily="monospace">PLAY</text>
|
|
1501
|
+
{/* Screen Bezel & Screen */}
|
|
1502
|
+
<polygon points="2,11 16,11 15,24 3,24" fill="#09090b" stroke="#27272a" strokeWidth="0.8" />
|
|
1503
|
+
<polygon points="3,12 15,12 14,23 4,23" fill={p.secondaryColor || "#09090b"} />
|
|
1504
|
+
{/* 8-bit Pixel Sprite on Screen */}
|
|
1505
|
+
<rect x="7" y="15" width="4" height="4" fill={p.color} />
|
|
1506
|
+
{/* Control Panel: Joystick & Buttons */}
|
|
1507
|
+
<polygon points="2,25 16,25 17,31 1,31" fill="#27272a" stroke={p.color} strokeWidth="0.8" />
|
|
1508
|
+
<circle cx="5" cy="27.5" r="1.6" fill="#ef4444" />
|
|
1509
|
+
<line x1="5" y1="27.5" x2="5" y2="30" stroke="#ffffff" strokeWidth="0.8" />
|
|
1510
|
+
<circle cx="11" cy="28" r="1.2" fill={p.color} />
|
|
1511
|
+
<circle cx="14" cy="27" r="1.2" fill="#eab308" />
|
|
1512
|
+
{/* Coin Door */}
|
|
1513
|
+
<rect x="6" y="34" width="6" height="6" rx="1" fill="#09090b" stroke="#3f3f46" strokeWidth="0.6" />
|
|
1514
|
+
<rect x="8.5" y="35" width="1" height="3" fill="#eab308" />
|
|
1515
|
+
</g>
|
|
1516
|
+
);
|
|
1517
|
+
})()}
|
|
1518
|
+
|
|
1519
|
+
{/* 4. TERRARIUM BONSAI */}
|
|
1520
|
+
{(hasProp("terrarium_bonsai") || hasProp("bonsai") || hasProp("plant")) && (() => {
|
|
1521
|
+
const p = getProp("terrarium_bonsai") || { color: "#10b981", secondaryColor: "#064e3b" };
|
|
1522
|
+
return (
|
|
1523
|
+
<g id="prop-bonsai" transform="translate(-84, 4)">
|
|
1524
|
+
{/* Hexagonal Ceramic Planter */}
|
|
1525
|
+
<polygon points="2,14 16,14 14,20 4,20" fill="#78350f" stroke="#b45309" strokeWidth="1" />
|
|
1526
|
+
{/* Gnarled Bonsai Trunk */}
|
|
1527
|
+
<path d="M 9 14 Q 8 8 5 5 Q 12 2 10 -4" stroke="#92400e" strokeWidth="2.4" fill="none" strokeLinecap="round" />
|
|
1528
|
+
{/* Glowing Foliage / Sakura Clouds */}
|
|
1529
|
+
<ellipse cx="5" cy="2" rx="6.5" ry="4" fill={p.color} opacity="0.9" />
|
|
1530
|
+
<ellipse cx="12" cy="-2" rx="6" ry="3.8" fill={p.color} opacity="0.95" />
|
|
1531
|
+
<ellipse cx="8" cy="6" rx="4.5" ry="3" fill={p.secondaryColor || "#059669"} opacity="0.85" />
|
|
1532
|
+
<circle cx="5" cy="2" r="1.2" fill="#ffffff" />
|
|
1533
|
+
<circle cx="12" cy="-2" r="1.2" fill="#ffffff" />
|
|
1534
|
+
</g>
|
|
1535
|
+
);
|
|
1536
|
+
})()}
|
|
1537
|
+
|
|
1538
|
+
{/* 5. DUAL MONITOR */}
|
|
1539
|
+
{(hasProp("dual_monitor") || hasProp("monitor") || hasProp("screen")) && (() => {
|
|
1540
|
+
const p = getProp("dual_monitor") || { color: "#06b6d4", secondaryColor: "#083344" };
|
|
1541
|
+
return (
|
|
1542
|
+
<g id="prop-dual-monitor" transform="translate(50, -36)">
|
|
1543
|
+
{/* Articulated Gas-Spring Mount Arm */}
|
|
1544
|
+
<line x1="22" y1="28" x2="22" y2="46" stroke="#475569" strokeWidth="2.4" />
|
|
1545
|
+
<ellipse cx="22" cy="46" rx="7" ry="2.5" fill="#334155" />
|
|
1546
|
+
{/* Secondary Angled Screen */}
|
|
1547
|
+
<rect x="2" y="0" width="40" height="30" rx="3" fill="#090d16" stroke={p.color} strokeWidth="1.2" />
|
|
1548
|
+
{/* Screen Content: Mini Syntax Code Lines & Status Bar */}
|
|
1549
|
+
<rect x="5" y="4" width="22" height="2" rx="0.5" fill={p.color} opacity="0.8" />
|
|
1550
|
+
<rect x="5" y="8" width="16" height="2" rx="0.5" fill="#ffffff" opacity="0.5" />
|
|
1551
|
+
<rect x="5" y="12" width="28" height="2" rx="0.5" fill="#ffffff" opacity="0.4" />
|
|
1552
|
+
<rect x="5" y="16" width="20" height="2" rx="0.5" fill={p.color} opacity="0.7" />
|
|
1553
|
+
{/* Telemetry Bar Chart on Right */}
|
|
1554
|
+
<rect x="30" y="20" width="2" height="6" fill="#10b981" />
|
|
1555
|
+
<rect x="33" y="16" width="2" height="10" fill={p.color} />
|
|
1556
|
+
<rect x="36" y="12" width="2" height="14" fill="#f59e0b" />
|
|
1557
|
+
</g>
|
|
1558
|
+
);
|
|
1559
|
+
})()}
|
|
1560
|
+
|
|
1561
|
+
{/* 6. HOLOGRAM EMITTER */}
|
|
1562
|
+
{(hasProp("hologram_emitter") || hasProp("holo") || hasProp("cube")) && (() => {
|
|
1563
|
+
const p = getProp("hologram_emitter") || { color: skinColor, secondaryColor: "#1e1b4b" };
|
|
1564
|
+
return (
|
|
1565
|
+
<g id="prop-hologram">
|
|
1566
|
+
{/* Hexagonal Emitter Pad */}
|
|
1567
|
+
<ellipse cx="65" cy="14" rx="14" ry="5" fill="#1e293b" stroke={p.color} strokeWidth="1.2" />
|
|
1568
|
+
<ellipse cx="65" cy="13" rx="9" ry="3" fill="#0f172a" stroke={p.color} strokeWidth="0.8" />
|
|
1569
|
+
{/* Upward Volumetric Hologram Cone */}
|
|
1570
|
+
<polygon points="65,13 46,-16 84,-16" fill={p.color} opacity="0.16" />
|
|
1571
|
+
<line x1="46" y1="-16" x2="84" y2="-16" stroke={p.color} strokeWidth="1" opacity="0.4" strokeDasharray="2 2" />
|
|
1572
|
+
{/* Floating Rotating Hologram Core */}
|
|
1573
|
+
<g ref={holoCubeRef}>
|
|
1574
|
+
<rect x="-10" y="-10" width="20" height="20" fill="none" stroke={p.color} strokeWidth="1.4" opacity="0.9" />
|
|
1575
|
+
<line x1="-10" y1="-10" x2="10" y2="10" stroke={p.color} strokeWidth="0.8" opacity="0.5" />
|
|
1576
|
+
<circle cx="0" cy="0" r="2.5" fill={p.color} />
|
|
1577
|
+
</g>
|
|
1578
|
+
</g>
|
|
1579
|
+
);
|
|
1580
|
+
})()}
|
|
1581
|
+
|
|
1582
|
+
{/* 7. LAB OSCILLOSCOPE */}
|
|
1583
|
+
{(hasProp("lab_oscilloscope") || hasProp("osc") || hasProp("scope") || hasProp("wave")) && (() => {
|
|
1584
|
+
const p = getProp("lab_oscilloscope") || { color: "#10b981", secondaryColor: "#064e3b" };
|
|
1585
|
+
return (
|
|
1586
|
+
<g id="prop-oscilloscope" transform="translate(56, 8)">
|
|
1587
|
+
{/* Instrument Enclosure */}
|
|
1588
|
+
<rect x="0" y="0" width="34" height="24" rx="3" fill="#111827" stroke="#374151" strokeWidth="1.2" />
|
|
1589
|
+
{/* Phosphor CRT Display */}
|
|
1590
|
+
<rect x="3" y="3" width="20" height="18" rx="2" fill="#051b14" stroke={p.color} strokeWidth="0.8" />
|
|
1591
|
+
{/* Screen Grid Reticle */}
|
|
1592
|
+
<line x1="13" y1="3" x2="13" y2="21" stroke={p.color} strokeWidth="0.4" opacity="0.4" strokeDasharray="1 1" />
|
|
1593
|
+
<line x1="3" y1="12" x2="23" y2="12" stroke={p.color} strokeWidth="0.4" opacity="0.4" strokeDasharray="1 1" />
|
|
1594
|
+
{/* Live Animated Waveform */}
|
|
1595
|
+
<path ref={oscWaveRef} d="M 4 12 L 22 12" stroke={p.color} strokeWidth="1.4" fill="none" />
|
|
1596
|
+
{/* Control Knobs & BNC Jacks */}
|
|
1597
|
+
<circle cx="28" cy="7" r="2.4" fill="#374151" stroke="#9ca3af" strokeWidth="0.6" />
|
|
1598
|
+
<circle cx="28" cy="14" r="2.4" fill="#374151" stroke="#9ca3af" strokeWidth="0.6" />
|
|
1599
|
+
<circle cx="28" cy="19.5" r="1.5" fill={p.color} />
|
|
1600
|
+
</g>
|
|
1601
|
+
);
|
|
1602
|
+
})()}
|
|
1603
|
+
|
|
1604
|
+
{/* Mechanical Keyboard */}
|
|
1605
|
+
<g id="prop-keyboard">
|
|
1606
|
+
<rect x="15" y="27" width="34" height="8" rx="2" fill="#232a35" stroke="#3b4554" strokeWidth="1" />
|
|
1607
|
+
</g>
|
|
1608
|
+
|
|
1609
|
+
{/* ----------------- COMPANION PET ----------------- */}
|
|
1610
|
+
{petArch !== "none" && (
|
|
1611
|
+
<g ref={petGRef} id="companion-pet">
|
|
1612
|
+
{petArch === "hover_drone" ? (
|
|
1613
|
+
<g>
|
|
1614
|
+
<ellipse cx="0" cy="0" rx="14" ry="8" fill="#0f172a" stroke={petColor} strokeWidth="1.5" />
|
|
1615
|
+
<ellipse cx="0" cy="-6" rx="16" ry="3" fill="none" stroke="#ffffff" strokeWidth="1" />
|
|
1616
|
+
<circle cx="0" cy="0" r="2.5" fill={petColor} />
|
|
1617
|
+
</g>
|
|
1618
|
+
) : (
|
|
1619
|
+
<g>
|
|
1620
|
+
<rect x="-10" y="-14" width="20" height="16" rx="5" fill="#1e293b" stroke={petColor} strokeWidth="1.4" />
|
|
1621
|
+
{/* Ears */}
|
|
1622
|
+
<polygon points="-8,-14 -4,-20 -1,-14" fill={petColor} />
|
|
1623
|
+
<polygon points="1,-14 4,-20 8,-14" fill={petColor} />
|
|
1624
|
+
{/* Eyes */}
|
|
1625
|
+
<circle cx="-4" cy="-8" r="1.5" fill="#ffffff" />
|
|
1626
|
+
<circle cx="4" cy="-8" r="1.5" fill="#ffffff" />
|
|
1627
|
+
</g>
|
|
1628
|
+
)}
|
|
1629
|
+
</g>
|
|
1630
|
+
)}
|
|
1631
|
+
</g>
|
|
1632
|
+
)}
|
|
1633
|
+
</svg>
|
|
1634
|
+
</div>
|
|
1635
|
+
);
|
|
1636
|
+
}
|
|
1637
|
+
export default LiveReactAgent;
|