@almadar/ui 2.15.7 → 2.15.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (127) hide show
  1. package/dist/components/atoms/ContentSection.d.ts +16 -0
  2. package/dist/components/atoms/SectionHeader.d.ts +14 -0
  3. package/dist/components/atoms/StatCard.d.ts +13 -0
  4. package/dist/components/atoms/index.d.ts +3 -0
  5. package/dist/components/atoms/svg/SvgBranch.d.ts +12 -0
  6. package/dist/components/atoms/svg/SvgConnection.d.ts +13 -0
  7. package/dist/components/atoms/svg/SvgFlow.d.ts +10 -0
  8. package/dist/components/atoms/svg/SvgGrid.d.ts +14 -0
  9. package/dist/components/atoms/svg/SvgLobe.d.ts +13 -0
  10. package/dist/components/atoms/svg/SvgMesh.d.ts +12 -0
  11. package/dist/components/atoms/svg/SvgMorph.d.ts +11 -0
  12. package/dist/components/atoms/svg/SvgNode.d.ts +12 -0
  13. package/dist/components/atoms/svg/SvgPulse.d.ts +12 -0
  14. package/dist/components/atoms/svg/SvgRing.d.ts +13 -0
  15. package/dist/components/atoms/svg/SvgShield.d.ts +11 -0
  16. package/dist/components/atoms/svg/SvgStack.d.ts +13 -0
  17. package/dist/components/atoms/svg/index.d.ts +12 -0
  18. package/dist/{chunk-K43H3ZDY.js → components/index.cjs} +24780 -16651
  19. package/dist/components/index.js +37757 -889
  20. package/dist/components/molecules/AnimatedCounter.d.ts +18 -0
  21. package/dist/components/molecules/ArticleSection.d.ts +18 -0
  22. package/dist/components/molecules/CTABanner.d.ts +31 -0
  23. package/dist/components/molecules/CaseStudyCard.d.ts +24 -0
  24. package/dist/components/molecules/CodeExample.d.ts +23 -0
  25. package/dist/components/molecules/CommunityLinks.d.ts +25 -0
  26. package/dist/components/molecules/DocBreadcrumb.d.ts +20 -0
  27. package/dist/components/molecules/DocCodeBlock.d.ts +13 -0
  28. package/dist/components/molecules/DocPagination.d.ts +14 -0
  29. package/dist/components/molecules/DocSearch.d.ts +15 -0
  30. package/dist/components/molecules/DocSidebar.d.ts +24 -0
  31. package/dist/components/molecules/DocTOC.d.ts +24 -0
  32. package/dist/components/molecules/FeatureCard.d.ts +26 -0
  33. package/dist/components/molecules/FeatureGrid.d.ts +19 -0
  34. package/dist/components/molecules/GradientDivider.d.ts +14 -0
  35. package/dist/components/molecules/HeroSection.d.ts +36 -0
  36. package/dist/components/molecules/InstallBox.d.ts +16 -0
  37. package/dist/components/molecules/MarketingFooter.d.ts +27 -0
  38. package/dist/components/molecules/PricingCard.d.ts +21 -0
  39. package/dist/components/molecules/PricingGrid.d.ts +13 -0
  40. package/dist/components/molecules/PullQuote.d.ts +14 -0
  41. package/dist/components/molecules/ServiceCatalog.d.ts +19 -0
  42. package/dist/components/molecules/ShowcaseCard.d.ts +20 -0
  43. package/dist/components/molecules/SocialProof.d.ts +25 -0
  44. package/dist/components/molecules/SplitSection.d.ts +21 -0
  45. package/dist/components/molecules/StatsGrid.d.ts +17 -0
  46. package/dist/components/molecules/StepFlow.d.ts +20 -0
  47. package/dist/components/molecules/TagCloud.d.ts +18 -0
  48. package/dist/components/molecules/TeamCard.d.ts +18 -0
  49. package/dist/components/molecules/index.d.ts +19 -0
  50. package/dist/components/molecules/svg/AIGenerates.d.ts +7 -0
  51. package/dist/components/molecules/svg/ClosedCircuit.d.ts +7 -0
  52. package/dist/components/molecules/svg/CommunityOwnership.d.ts +7 -0
  53. package/dist/components/molecules/svg/CompileAnywhere.d.ts +7 -0
  54. package/dist/components/molecules/svg/ComposableModels.d.ts +7 -0
  55. package/dist/components/molecules/svg/DescribeProveDeploy.d.ts +7 -0
  56. package/dist/components/molecules/svg/DomainGrid.d.ts +7 -0
  57. package/dist/components/molecules/svg/EventBus.d.ts +7 -0
  58. package/dist/components/molecules/svg/OrbitalUnit.d.ts +7 -0
  59. package/dist/components/molecules/svg/PlanVerifyRemember.d.ts +7 -0
  60. package/dist/components/molecules/svg/ProveCorrect.d.ts +7 -0
  61. package/dist/components/molecules/svg/ServiceLayers.d.ts +7 -0
  62. package/dist/components/molecules/svg/SharedReality.d.ts +7 -0
  63. package/dist/components/molecules/svg/StandardLibrary.d.ts +7 -0
  64. package/dist/components/molecules/svg/StateMachine.d.ts +7 -0
  65. package/dist/components/molecules/svg/WorldModel.d.ts +7 -0
  66. package/dist/components/molecules/svg/index.d.ts +16 -0
  67. package/dist/components/organisms/CaseStudyOrganism.d.ts +19 -0
  68. package/dist/components/organisms/FeatureGridOrganism.d.ts +20 -0
  69. package/dist/components/organisms/HeroOrganism.d.ts +18 -0
  70. package/dist/components/organisms/PricingOrganism.d.ts +19 -0
  71. package/dist/components/organisms/ShowcaseOrganism.d.ts +20 -0
  72. package/dist/components/organisms/StatsOrganism.d.ts +17 -0
  73. package/dist/components/organisms/StepFlowOrganism.d.ts +20 -0
  74. package/dist/components/organisms/TeamOrganism.d.ts +18 -0
  75. package/dist/components/organisms/UISlotRenderer.d.ts +1 -0
  76. package/dist/components/organisms/game/three/index.cjs +2525 -0
  77. package/dist/components/organisms/game/three/index.js +1795 -50
  78. package/dist/components/organisms/index.d.ts +9 -0
  79. package/dist/components/organisms/marketing-types.d.ts +87 -0
  80. package/dist/components/templates/AboutPageTemplate.d.ts +26 -0
  81. package/dist/components/templates/DashboardLayout.d.ts +2 -1
  82. package/dist/components/templates/FeatureDetailPageTemplate.d.ts +27 -0
  83. package/dist/components/templates/LandingPageTemplate.d.ts +31 -0
  84. package/dist/components/templates/PricingPageTemplate.d.ts +26 -0
  85. package/dist/components/templates/index.d.ts +4 -0
  86. package/dist/context/index.cjs +550 -0
  87. package/dist/context/index.js +420 -6
  88. package/dist/docs/index.cjs +4015 -0
  89. package/dist/docs/index.d.cts +412 -0
  90. package/dist/docs/index.d.ts +29 -0
  91. package/dist/docs/index.js +3977 -0
  92. package/dist/hooks/index.cjs +2606 -0
  93. package/dist/hooks/index.js +2535 -8
  94. package/dist/illustrations/index.cjs +3004 -0
  95. package/dist/illustrations/index.d.cts +261 -0
  96. package/dist/illustrations/index.d.ts +35 -0
  97. package/dist/illustrations/index.js +2971 -0
  98. package/dist/{chunk-XL7WB2O5.js → lib/index.cjs} +454 -274
  99. package/dist/lib/index.js +1407 -3
  100. package/dist/locales/index.cjs +340 -0
  101. package/dist/locales/index.js +105 -2
  102. package/dist/marketing/index.cjs +4683 -0
  103. package/dist/marketing/index.d.cts +831 -0
  104. package/dist/marketing/index.d.ts +62 -0
  105. package/dist/marketing/index.js +4626 -0
  106. package/dist/providers/index.cjs +4811 -0
  107. package/dist/providers/index.js +4765 -11
  108. package/dist/{chunk-K2D5D3WK.js → renderer/index.cjs} +101 -42
  109. package/dist/renderer/index.js +1036 -2
  110. package/dist/runtime/index.cjs +4400 -0
  111. package/dist/runtime/index.js +3615 -19
  112. package/dist/{chunk-N7MVUW4R.js → stores/index.cjs} +24 -1
  113. package/dist/stores/index.js +194 -2
  114. package/dist/tsup.config.d.ts +2 -1
  115. package/package.json +27 -12
  116. package/tailwind-preset.cjs +27 -2
  117. package/themes/index.css +22 -20
  118. package/dist/chunk-3HJHHULT.js +0 -93
  119. package/dist/chunk-3JGAROCW.js +0 -149
  120. package/dist/chunk-4N3BAPDB.js +0 -1667
  121. package/dist/chunk-CDIOHSKG.js +0 -661
  122. package/dist/chunk-DKQN5FVU.js +0 -279
  123. package/dist/chunk-GF6RQBO7.js +0 -375
  124. package/dist/chunk-PKBMQBKP.js +0 -5
  125. package/dist/chunk-QIABKRCN.js +0 -107
  126. package/dist/chunk-SD3KVCY6.js +0 -1465
  127. package/dist/chunk-YXZM3WCF.js +0 -222
@@ -0,0 +1,4400 @@
1
+ 'use strict';
2
+
3
+ var React113 = require('react');
4
+ var jsxRuntime = require('react/jsx-runtime');
5
+ require('@tanstack/react-query');
6
+ require('react-dom');
7
+ require('@almadar/ui/context');
8
+ var LucideIcons = require('lucide-react');
9
+ var clsx = require('clsx');
10
+ var tailwindMerge = require('tailwind-merge');
11
+ require('@almadar/evaluator');
12
+ var patterns = require('@almadar/patterns');
13
+ require('react-leaflet');
14
+ var L = require('leaflet');
15
+ require('leaflet/dist/leaflet.css');
16
+ require('react-router-dom');
17
+ var ReactMarkdown = require('react-markdown');
18
+ var remarkGfm = require('remark-gfm');
19
+ var remarkMath = require('remark-math');
20
+ var rehypeKatex = require('rehype-katex');
21
+ var SyntaxHighlighter = require('react-syntax-highlighter/dist/esm/prism');
22
+ var dark = require('react-syntax-highlighter/dist/esm/styles/prism/vsc-dark-plus');
23
+ var fiber = require('@react-three/fiber');
24
+ var drei = require('@react-three/drei');
25
+ var THREE = require('three');
26
+ var GLTFLoader = require('three/examples/jsm/loaders/GLTFLoader');
27
+ var GLTFLoader_js = require('three/examples/jsm/loaders/GLTFLoader.js');
28
+ var OBJLoader_js = require('three/examples/jsm/loaders/OBJLoader.js');
29
+ var core = require('@almadar/core');
30
+ var runtime = require('@almadar/runtime');
31
+
32
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
33
+
34
+ function _interopNamespace(e) {
35
+ if (e && e.__esModule) return e;
36
+ var n = Object.create(null);
37
+ if (e) {
38
+ Object.keys(e).forEach(function (k) {
39
+ if (k !== 'default') {
40
+ var d = Object.getOwnPropertyDescriptor(e, k);
41
+ Object.defineProperty(n, k, d.get ? d : {
42
+ enumerable: true,
43
+ get: function () { return e[k]; }
44
+ });
45
+ }
46
+ });
47
+ }
48
+ n.default = e;
49
+ return Object.freeze(n);
50
+ }
51
+
52
+ var React113__namespace = /*#__PURE__*/_interopNamespace(React113);
53
+ var LucideIcons__namespace = /*#__PURE__*/_interopNamespace(LucideIcons);
54
+ var L__default = /*#__PURE__*/_interopDefault(L);
55
+ var ReactMarkdown__default = /*#__PURE__*/_interopDefault(ReactMarkdown);
56
+ var remarkGfm__default = /*#__PURE__*/_interopDefault(remarkGfm);
57
+ var remarkMath__default = /*#__PURE__*/_interopDefault(remarkMath);
58
+ var rehypeKatex__default = /*#__PURE__*/_interopDefault(rehypeKatex);
59
+ var SyntaxHighlighter__default = /*#__PURE__*/_interopDefault(SyntaxHighlighter);
60
+ var dark__default = /*#__PURE__*/_interopDefault(dark);
61
+ var THREE__namespace = /*#__PURE__*/_interopNamespace(THREE);
62
+
63
+ var __defProp = Object.defineProperty;
64
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
65
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
66
+ var EventBusContext = React113.createContext(null);
67
+ function getGlobalEventBus() {
68
+ if (typeof window !== "undefined") {
69
+ return window.__kflowEventBus ?? null;
70
+ }
71
+ return null;
72
+ }
73
+ var fallbackListeners = /* @__PURE__ */ new Map();
74
+ var fallbackAnyListeners = /* @__PURE__ */ new Set();
75
+ var fallbackEventBus = {
76
+ emit: (type, payload) => {
77
+ const event = {
78
+ type,
79
+ payload,
80
+ timestamp: Date.now()
81
+ };
82
+ const handlers = fallbackListeners.get(type);
83
+ if (handlers) {
84
+ handlers.forEach((handler) => {
85
+ try {
86
+ handler(event);
87
+ } catch (error) {
88
+ console.error(`[EventBus] Error in listener for '${type}':`, error);
89
+ }
90
+ });
91
+ }
92
+ fallbackAnyListeners.forEach((handler) => {
93
+ try {
94
+ handler(event);
95
+ } catch (error) {
96
+ console.error(`[EventBus] Error in onAny listener for '${type}':`, error);
97
+ }
98
+ });
99
+ },
100
+ on: (type, listener) => {
101
+ if (!fallbackListeners.has(type)) {
102
+ fallbackListeners.set(type, /* @__PURE__ */ new Set());
103
+ }
104
+ fallbackListeners.get(type).add(listener);
105
+ return () => {
106
+ const handlers = fallbackListeners.get(type);
107
+ if (handlers) {
108
+ handlers.delete(listener);
109
+ if (handlers.size === 0) {
110
+ fallbackListeners.delete(type);
111
+ }
112
+ }
113
+ };
114
+ },
115
+ once: (type, listener) => {
116
+ const wrappedListener = (event) => {
117
+ fallbackListeners.get(type)?.delete(wrappedListener);
118
+ listener(event);
119
+ };
120
+ return fallbackEventBus.on(type, wrappedListener);
121
+ },
122
+ hasListeners: (type) => {
123
+ const handlers = fallbackListeners.get(type);
124
+ return handlers !== void 0 && handlers.size > 0;
125
+ },
126
+ onAny: (listener) => {
127
+ fallbackAnyListeners.add(listener);
128
+ return () => {
129
+ fallbackAnyListeners.delete(listener);
130
+ };
131
+ }
132
+ };
133
+ function useEventBus() {
134
+ const context = React113.useContext(EventBusContext);
135
+ return context ?? getGlobalEventBus() ?? fallbackEventBus;
136
+ }
137
+ function useEmitEvent() {
138
+ const eventBus = useEventBus();
139
+ return React113.useCallback(
140
+ (type, payload) => {
141
+ eventBus.emit(type, payload);
142
+ },
143
+ [eventBus]
144
+ );
145
+ }
146
+ React113.createContext(null);
147
+ React113.createContext(null);
148
+
149
+ // lib/api-client.ts
150
+ typeof process !== "undefined" && process.env?.VITE_API_URL ? process.env.VITE_API_URL : "/api";
151
+
152
+ // locales/en.json
153
+ var en_default = {
154
+ $meta: { locale: "en", direction: "ltr" },
155
+ "common.save": "Save",
156
+ "common.cancel": "Cancel",
157
+ "common.delete": "Delete",
158
+ "common.close": "Close",
159
+ "common.confirm": "Are you sure?",
160
+ "common.create": "Create",
161
+ "common.edit": "Edit",
162
+ "common.view": "View",
163
+ "common.add": "Add",
164
+ "common.remove": "Remove",
165
+ "common.search": "Search...",
166
+ "common.filter": "Filter",
167
+ "common.actions": "Actions",
168
+ "common.yes": "Yes",
169
+ "common.no": "No",
170
+ "common.selected": "selected",
171
+ "common.ok": "OK",
172
+ "common.done": "Done",
173
+ "common.apply": "Apply",
174
+ "common.reset": "Reset",
175
+ "common.refresh": "Refresh",
176
+ "common.export": "Export",
177
+ "common.import": "Import",
178
+ "common.copy": "Copy",
179
+ "common.settings": "Settings",
180
+ "nav.previous": "Previous",
181
+ "nav.next": "Next",
182
+ "nav.back": "Back",
183
+ "nav.home": "Home",
184
+ "form.submit": "Submit",
185
+ "form.saving": "Saving...",
186
+ "form.required": "This field is required",
187
+ "form.invalidEmail": "Enter a valid email address",
188
+ "form.selectPlaceholder": "Select {{label}}...",
189
+ "form.searchPlaceholder": "Search {{entity}}...",
190
+ "table.empty.title": "No items found",
191
+ "table.empty.description": "No items to display.",
192
+ "table.search.placeholder": "Search...",
193
+ "table.pagination.showing": "Showing {{start}} to {{end}} of {{total}} results",
194
+ "table.pagination.page": "Page {{page}} of {{totalPages}}",
195
+ "table.bulk.selected": "{{count}} selected",
196
+ "table.loading": "Loading...",
197
+ "status.loading": "Loading...",
198
+ "status.scheduled": "Scheduled",
199
+ "status.inProgress": "In Progress",
200
+ "status.completed": "Completed",
201
+ "status.cancelled": "Cancelled",
202
+ "status.pending": "Pending",
203
+ "status.active": "Active",
204
+ "status.inactive": "Inactive",
205
+ "status.draft": "Draft",
206
+ "status.archived": "Archived",
207
+ "error.generic": "Something went wrong",
208
+ "error.retry": "Try again",
209
+ "error.notFound": "Not found",
210
+ "error.loadFailed": "Failed to load: {{message}}",
211
+ "error.configMissing": "Configuration not found for: {{id}}",
212
+ "common.loading": "Loading...",
213
+ "common.showMore": "Show More",
214
+ "common.showLess": "Show Less",
215
+ "common.noResults": "No results found",
216
+ "common.saveChanges": "Save Changes",
217
+ "common.retry": "Retry",
218
+ "common.open": "Open",
219
+ "common.back": "Back",
220
+ "empty.noItems": "No items",
221
+ "empty.noData": "No data available",
222
+ "empty.noItemsYet": "No items yet",
223
+ "empty.noItemsAdded": "No items added yet",
224
+ "empty.noOptionsFound": "No options found",
225
+ "list.addItemPlaceholder": "Add new item...",
226
+ "error.occurred": "An error occurred",
227
+ "error.failedToLoad": "Failed to load data",
228
+ "wizard.back": "Back",
229
+ "wizard.next": "Next",
230
+ "wizard.complete": "Complete",
231
+ "wizard.stepOf": "Step {{current}} of {{total}}",
232
+ "pagination.previous": "Previous",
233
+ "pagination.next": "Next",
234
+ "pagination.total": "Total:",
235
+ "pagination.show": "Show:",
236
+ "pagination.goTo": "Go to:",
237
+ "pagination.go": "Go",
238
+ "auth.signIn": "Sign in",
239
+ "auth.signOut": "Sign out",
240
+ "dialog.confirm": "Confirm",
241
+ "dialog.cancel": "Cancel",
242
+ "dialog.loading": "Loading...",
243
+ "dialog.delete.title": "Delete {{item}}?",
244
+ "dialog.delete.message": "This action cannot be undone.",
245
+ "trait.availableActions": "Available Actions",
246
+ "trait.transitions": "Transitions",
247
+ "trait.availableNow": "Available now",
248
+ "book.startReading": "Start Reading",
249
+ "book.tableOfContents": "Table of Contents",
250
+ "book.partNumber": "Part {{number}}",
251
+ "book.print": "Print",
252
+ "book.previousPage": "Previous page",
253
+ "book.nextPage": "Next page",
254
+ "quiz.showAnswer": "Show answer",
255
+ "quiz.hideAnswer": "Hide answer"
256
+ };
257
+
258
+ // hooks/useTranslate.ts
259
+ var { $meta: _meta, ...coreMessages } = en_default;
260
+ var coreLocale = coreMessages;
261
+ var I18nContext = React113.createContext({
262
+ locale: "en",
263
+ direction: "ltr",
264
+ t: (key) => coreLocale[key] ?? key
265
+ // core locale fallback
266
+ });
267
+ I18nContext.displayName = "I18nContext";
268
+ I18nContext.Provider;
269
+ function useTranslate() {
270
+ return React113.useContext(I18nContext);
271
+ }
272
+ typeof process !== "undefined" && process.env?.VITE_API_URL ? process.env.VITE_API_URL : "http://localhost:3000";
273
+ React113.createContext(void 0);
274
+ var FetchedDataContext = React113.createContext(null);
275
+ function useFetchedDataContext() {
276
+ return React113.useContext(FetchedDataContext);
277
+ }
278
+ function cn(...inputs) {
279
+ return tailwindMerge.twMerge(clsx.clsx(inputs));
280
+ }
281
+ var iconAliases = {
282
+ "close": LucideIcons__namespace.X,
283
+ "trash": LucideIcons__namespace.Trash2,
284
+ "loader": LucideIcons__namespace.Loader2,
285
+ "stop": LucideIcons__namespace.Square,
286
+ "volume": LucideIcons__namespace.Volume2,
287
+ "volume-off": LucideIcons__namespace.VolumeX,
288
+ "refresh": LucideIcons__namespace.RefreshCw,
289
+ "share": LucideIcons__namespace.Share2,
290
+ "sort-asc": LucideIcons__namespace.ArrowUpNarrowWide,
291
+ "sort-desc": LucideIcons__namespace.ArrowDownNarrowWide
292
+ };
293
+ function kebabToPascal(name) {
294
+ return name.split("-").map((part) => {
295
+ if (/^\d+$/.test(part)) return part;
296
+ return part.charAt(0).toUpperCase() + part.slice(1);
297
+ }).join("");
298
+ }
299
+ var resolvedCache = /* @__PURE__ */ new Map();
300
+ function resolveIcon(name) {
301
+ const cached = resolvedCache.get(name);
302
+ if (cached) return cached;
303
+ const resolved = doResolve(name);
304
+ resolvedCache.set(name, resolved);
305
+ return resolved;
306
+ }
307
+ function doResolve(name) {
308
+ if (iconAliases[name]) return iconAliases[name];
309
+ const pascalName = kebabToPascal(name);
310
+ const directLookup = LucideIcons__namespace[pascalName];
311
+ if (directLookup && typeof directLookup === "object") return directLookup;
312
+ const asIs = LucideIcons__namespace[name];
313
+ if (asIs && typeof asIs === "object") return asIs;
314
+ return LucideIcons__namespace.HelpCircle;
315
+ }
316
+ var paddingStyles = {
317
+ none: "p-0",
318
+ xs: "p-1",
319
+ sm: "p-2",
320
+ md: "p-4",
321
+ lg: "p-6",
322
+ xl: "p-8",
323
+ "2xl": "p-12"
324
+ };
325
+ var paddingXStyles = {
326
+ none: "px-0",
327
+ xs: "px-1",
328
+ sm: "px-2",
329
+ md: "px-4",
330
+ lg: "px-6",
331
+ xl: "px-8",
332
+ "2xl": "px-12"
333
+ };
334
+ var paddingYStyles = {
335
+ none: "py-0",
336
+ xs: "py-1",
337
+ sm: "py-2",
338
+ md: "py-4",
339
+ lg: "py-6",
340
+ xl: "py-8",
341
+ "2xl": "py-12"
342
+ };
343
+ var marginStyles = {
344
+ none: "m-0",
345
+ xs: "m-1",
346
+ sm: "m-2",
347
+ md: "m-4",
348
+ lg: "m-6",
349
+ xl: "m-8",
350
+ "2xl": "m-12",
351
+ auto: "m-auto"
352
+ };
353
+ var marginXStyles = {
354
+ none: "mx-0",
355
+ xs: "mx-1",
356
+ sm: "mx-2",
357
+ md: "mx-4",
358
+ lg: "mx-6",
359
+ xl: "mx-8",
360
+ "2xl": "mx-12",
361
+ auto: "mx-auto"
362
+ };
363
+ var marginYStyles = {
364
+ none: "my-0",
365
+ xs: "my-1",
366
+ sm: "my-2",
367
+ md: "my-4",
368
+ lg: "my-6",
369
+ xl: "my-8",
370
+ "2xl": "my-12",
371
+ auto: "my-auto"
372
+ };
373
+ var bgStyles = {
374
+ transparent: "bg-transparent",
375
+ primary: "bg-[var(--color-primary)] text-[var(--color-primary-foreground)]",
376
+ secondary: "bg-[var(--color-secondary)] text-[var(--color-secondary-foreground)]",
377
+ muted: "bg-[var(--color-muted)] text-[var(--color-foreground)]",
378
+ accent: "bg-[var(--color-accent)] text-[var(--color-accent-foreground)]",
379
+ surface: "bg-[var(--color-card)]",
380
+ overlay: "bg-[var(--color-card)]/80 backdrop-blur-sm"
381
+ };
382
+ var roundedStyles = {
383
+ none: "rounded-none",
384
+ sm: "rounded-[var(--radius-sm)]",
385
+ md: "rounded-[var(--radius-md)]",
386
+ lg: "rounded-[var(--radius-lg)]",
387
+ xl: "rounded-[var(--radius-xl)]",
388
+ "2xl": "rounded-[var(--radius-xl)]",
389
+ full: "rounded-[var(--radius-full)]"
390
+ };
391
+ var shadowStyles = {
392
+ none: "shadow-none",
393
+ sm: "shadow-[var(--shadow-sm)]",
394
+ md: "shadow-[var(--shadow-main)]",
395
+ lg: "shadow-[var(--shadow-lg)]",
396
+ xl: "shadow-[var(--shadow-lg)]"
397
+ };
398
+ var displayStyles = {
399
+ block: "block",
400
+ inline: "inline",
401
+ "inline-block": "inline-block",
402
+ flex: "flex",
403
+ "inline-flex": "inline-flex",
404
+ grid: "grid"
405
+ };
406
+ var overflowStyles = {
407
+ auto: "overflow-auto",
408
+ hidden: "overflow-hidden",
409
+ visible: "overflow-visible",
410
+ scroll: "overflow-scroll"
411
+ };
412
+ var positionStyles = {
413
+ relative: "relative",
414
+ absolute: "absolute",
415
+ fixed: "fixed",
416
+ sticky: "sticky"
417
+ };
418
+ var Box = React113__namespace.default.forwardRef(
419
+ ({
420
+ padding,
421
+ paddingX,
422
+ paddingY,
423
+ margin,
424
+ marginX,
425
+ marginY,
426
+ bg = "transparent",
427
+ border = false,
428
+ rounded = "none",
429
+ shadow = "none",
430
+ display,
431
+ fullWidth = false,
432
+ fullHeight = false,
433
+ overflow,
434
+ position,
435
+ className,
436
+ children,
437
+ as: Component2 = "div",
438
+ action,
439
+ actionPayload,
440
+ hoverEvent,
441
+ onClick,
442
+ onMouseEnter,
443
+ onMouseLeave,
444
+ ...rest
445
+ }, ref) => {
446
+ const eventBus = useEventBus();
447
+ const handleClick = React113.useCallback((e) => {
448
+ if (action) {
449
+ e.stopPropagation();
450
+ eventBus.emit(`UI:${action}`, actionPayload ?? {});
451
+ }
452
+ onClick?.(e);
453
+ }, [action, actionPayload, eventBus, onClick]);
454
+ const handleMouseEnter = React113.useCallback((e) => {
455
+ if (hoverEvent) {
456
+ eventBus.emit(`UI:${hoverEvent}`, { hovered: true });
457
+ }
458
+ onMouseEnter?.(e);
459
+ }, [hoverEvent, eventBus, onMouseEnter]);
460
+ const handleMouseLeave = React113.useCallback((e) => {
461
+ if (hoverEvent) {
462
+ eventBus.emit(`UI:${hoverEvent}`, { hovered: false });
463
+ }
464
+ onMouseLeave?.(e);
465
+ }, [hoverEvent, eventBus, onMouseLeave]);
466
+ const isClickable = action || onClick;
467
+ const Comp = Component2;
468
+ return /* @__PURE__ */ jsxRuntime.jsx(
469
+ Comp,
470
+ {
471
+ ref,
472
+ className: cn(
473
+ // Padding
474
+ padding && paddingStyles[padding],
475
+ paddingX && paddingXStyles[paddingX],
476
+ paddingY && paddingYStyles[paddingY],
477
+ // Margin
478
+ margin && marginStyles[margin],
479
+ marginX && marginXStyles[marginX],
480
+ marginY && marginYStyles[marginY],
481
+ // Background
482
+ bgStyles[bg],
483
+ // Border - uses theme variables
484
+ border && "border-[length:var(--border-width)] border-[var(--color-border)]",
485
+ // Rounded
486
+ roundedStyles[rounded],
487
+ // Shadow
488
+ shadowStyles[shadow],
489
+ // Display
490
+ display && displayStyles[display],
491
+ // Dimensions
492
+ fullWidth && "w-full",
493
+ fullHeight && "h-full",
494
+ // Overflow
495
+ overflow && overflowStyles[overflow],
496
+ // Position
497
+ position && positionStyles[position],
498
+ // Cursor for clickable
499
+ isClickable && "cursor-pointer",
500
+ className
501
+ ),
502
+ onClick: isClickable ? handleClick : void 0,
503
+ onMouseEnter: hoverEvent || onMouseEnter ? handleMouseEnter : void 0,
504
+ onMouseLeave: hoverEvent || onMouseLeave ? handleMouseLeave : void 0,
505
+ ...rest,
506
+ children
507
+ }
508
+ );
509
+ }
510
+ );
511
+ Box.displayName = "Box";
512
+ var variantStyles = {
513
+ h1: "text-4xl font-bold tracking-tight text-[var(--color-foreground)]",
514
+ h2: "text-3xl font-bold tracking-tight text-[var(--color-foreground)]",
515
+ h3: "text-2xl font-bold text-[var(--color-foreground)]",
516
+ h4: "text-xl font-bold text-[var(--color-foreground)]",
517
+ h5: "text-lg font-bold text-[var(--color-foreground)]",
518
+ h6: "text-base font-bold text-[var(--color-foreground)]",
519
+ heading: "text-2xl font-bold text-[var(--color-foreground)]",
520
+ subheading: "text-lg font-semibold text-[var(--color-foreground)]",
521
+ body1: "text-base font-normal text-[var(--color-foreground)]",
522
+ body2: "text-sm font-normal text-[var(--color-foreground)]",
523
+ body: "text-base font-normal text-[var(--color-foreground)]",
524
+ caption: "text-xs font-normal text-[var(--color-muted-foreground)]",
525
+ overline: "text-xs uppercase tracking-wide font-bold text-[var(--color-muted-foreground)]",
526
+ small: "text-sm font-normal text-[var(--color-foreground)]",
527
+ large: "text-lg font-medium text-[var(--color-foreground)]",
528
+ label: "text-sm font-medium text-[var(--color-foreground)]"
529
+ };
530
+ var colorStyles = {
531
+ primary: "text-[var(--color-foreground)]",
532
+ secondary: "text-[var(--color-muted-foreground)]",
533
+ muted: "text-[var(--color-muted-foreground)]",
534
+ error: "text-[var(--color-error)]",
535
+ success: "text-[var(--color-success)]",
536
+ warning: "text-[var(--color-warning)]",
537
+ inherit: "text-inherit"
538
+ };
539
+ var weightStyles = {
540
+ light: "font-light",
541
+ normal: "font-normal",
542
+ medium: "font-medium",
543
+ semibold: "font-semibold",
544
+ bold: "font-bold"
545
+ };
546
+ var defaultElements = {
547
+ h1: "h1",
548
+ h2: "h2",
549
+ h3: "h3",
550
+ h4: "h4",
551
+ h5: "h5",
552
+ h6: "h6",
553
+ heading: "h2",
554
+ subheading: "h3",
555
+ body1: "p",
556
+ body2: "p",
557
+ body: "p",
558
+ caption: "span",
559
+ overline: "span",
560
+ small: "span",
561
+ large: "p",
562
+ label: "span"
563
+ };
564
+ var typographySizeStyles = {
565
+ xs: "text-xs",
566
+ sm: "text-sm",
567
+ md: "text-base",
568
+ lg: "text-lg",
569
+ xl: "text-xl",
570
+ "2xl": "text-2xl",
571
+ "3xl": "text-3xl"
572
+ };
573
+ var overflowStyles2 = {
574
+ visible: "overflow-visible",
575
+ hidden: "overflow-hidden",
576
+ wrap: "break-words overflow-hidden",
577
+ "clamp-2": "overflow-hidden line-clamp-2",
578
+ "clamp-3": "overflow-hidden line-clamp-3"
579
+ };
580
+ var Typography = ({
581
+ variant: variantProp,
582
+ level,
583
+ color = "primary",
584
+ align,
585
+ weight,
586
+ size,
587
+ truncate = false,
588
+ overflow,
589
+ as,
590
+ id,
591
+ className,
592
+ style,
593
+ content,
594
+ children
595
+ }) => {
596
+ const variant = variantProp ?? (level ? `h${level}` : "body1");
597
+ const Component2 = as || defaultElements[variant];
598
+ const Comp = Component2;
599
+ return /* @__PURE__ */ jsxRuntime.jsx(
600
+ Comp,
601
+ {
602
+ id,
603
+ className: cn(
604
+ variantStyles[variant],
605
+ colorStyles[color],
606
+ weight && weightStyles[weight],
607
+ size && typographySizeStyles[size],
608
+ align && `text-${align}`,
609
+ truncate && "truncate overflow-hidden text-ellipsis",
610
+ overflow && overflowStyles2[overflow],
611
+ className
612
+ ),
613
+ style,
614
+ children: children ?? content
615
+ }
616
+ );
617
+ };
618
+ Typography.displayName = "Typography";
619
+ var variantStyles2 = {
620
+ primary: [
621
+ "bg-[var(--color-primary)] text-[var(--color-primary-foreground)]",
622
+ "border-[length:var(--border-width)] border-[var(--color-border)]",
623
+ "shadow-[var(--shadow-sm)]",
624
+ "hover:bg-[var(--color-primary-hover)] hover:shadow-[var(--shadow-hover)]",
625
+ "active:scale-[var(--active-scale)] active:shadow-[var(--shadow-active)]"
626
+ ].join(" "),
627
+ secondary: [
628
+ "bg-[var(--color-secondary)] text-[var(--color-secondary-foreground)]",
629
+ "border-[length:var(--border-width-thin)] border-[var(--color-border)]",
630
+ "hover:bg-[var(--color-secondary-hover)]",
631
+ "active:scale-[var(--active-scale)]"
632
+ ].join(" "),
633
+ ghost: [
634
+ "bg-transparent text-[var(--color-muted-foreground)]",
635
+ "hover:text-[var(--color-foreground)] hover:bg-[var(--color-muted)]",
636
+ "active:scale-[var(--active-scale)]"
637
+ ].join(" "),
638
+ danger: [
639
+ "bg-[var(--color-surface)] text-[var(--color-error)]",
640
+ "border-[length:var(--border-width)] border-[var(--color-error)]",
641
+ "shadow-[var(--shadow-sm)]",
642
+ "hover:bg-[var(--color-error)] hover:text-[var(--color-error-foreground)] hover:shadow-[var(--shadow-hover)]",
643
+ "active:scale-[var(--active-scale)] active:shadow-[var(--shadow-active)]"
644
+ ].join(" "),
645
+ success: [
646
+ "bg-[var(--color-surface)] text-[var(--color-success)]",
647
+ "border-[length:var(--border-width)] border-[var(--color-success)]",
648
+ "shadow-[var(--shadow-sm)]",
649
+ "hover:bg-[var(--color-success)] hover:text-[var(--color-success-foreground)] hover:shadow-[var(--shadow-hover)]",
650
+ "active:scale-[var(--active-scale)] active:shadow-[var(--shadow-active)]"
651
+ ].join(" "),
652
+ warning: [
653
+ "bg-[var(--color-surface)] text-[var(--color-warning)]",
654
+ "border-[length:var(--border-width)] border-[var(--color-warning)]",
655
+ "shadow-[var(--shadow-sm)]",
656
+ "hover:bg-[var(--color-warning)] hover:text-[var(--color-warning-foreground)] hover:shadow-[var(--shadow-hover)]",
657
+ "active:scale-[var(--active-scale)] active:shadow-[var(--shadow-active)]"
658
+ ].join(" "),
659
+ // "default" is an alias for secondary
660
+ default: [
661
+ "bg-[var(--color-secondary)] text-[var(--color-secondary-foreground)]",
662
+ "border-[length:var(--border-width-thin)] border-[var(--color-border)]",
663
+ "hover:bg-[var(--color-secondary-hover)]",
664
+ "active:scale-[var(--active-scale)]"
665
+ ].join(" ")
666
+ };
667
+ variantStyles2.destructive = variantStyles2.danger;
668
+ var sizeStyles2 = {
669
+ sm: "px-3 py-1.5 text-sm",
670
+ md: "px-4 py-2 text-sm",
671
+ lg: "px-6 py-3 text-base"
672
+ };
673
+ var iconSizeStyles = {
674
+ sm: "h-3.5 w-3.5",
675
+ md: "h-4 w-4",
676
+ lg: "h-5 w-5"
677
+ };
678
+ function resolveIconProp(value, sizeClass) {
679
+ if (!value) return null;
680
+ if (typeof value === "string") {
681
+ const Resolved = resolveIcon(value);
682
+ return Resolved ? /* @__PURE__ */ jsxRuntime.jsx(Resolved, { className: sizeClass }) : null;
683
+ }
684
+ if (typeof value === "function") {
685
+ const IconComp = value;
686
+ return /* @__PURE__ */ jsxRuntime.jsx(IconComp, { className: sizeClass });
687
+ }
688
+ if (React113__namespace.default.isValidElement(value)) {
689
+ return value;
690
+ }
691
+ if (typeof value === "object" && value !== null && "render" in value) {
692
+ const IconComp = value;
693
+ return /* @__PURE__ */ jsxRuntime.jsx(IconComp, { className: sizeClass });
694
+ }
695
+ return value;
696
+ }
697
+ var Button = React113__namespace.default.forwardRef(
698
+ ({
699
+ className,
700
+ variant = "primary",
701
+ size = "md",
702
+ isLoading = false,
703
+ disabled,
704
+ leftIcon,
705
+ rightIcon,
706
+ icon: iconProp,
707
+ iconRight: iconRightProp,
708
+ action,
709
+ actionPayload,
710
+ label,
711
+ children,
712
+ onClick,
713
+ ...props
714
+ }, ref) => {
715
+ const eventBus = useEventBus();
716
+ const leftIconValue = leftIcon || iconProp;
717
+ const rightIconValue = rightIcon || iconRightProp;
718
+ const resolvedLeftIcon = resolveIconProp(leftIconValue, iconSizeStyles[size]);
719
+ const resolvedRightIcon = resolveIconProp(rightIconValue, iconSizeStyles[size]);
720
+ const handleClick = (e) => {
721
+ if (action) {
722
+ eventBus.emit(`UI:${action}`, actionPayload ?? {});
723
+ }
724
+ onClick?.(e);
725
+ };
726
+ return /* @__PURE__ */ jsxRuntime.jsxs(
727
+ "button",
728
+ {
729
+ ref,
730
+ disabled: disabled || isLoading,
731
+ className: cn(
732
+ "inline-flex items-center justify-center gap-2",
733
+ "font-[var(--font-weight-medium)]",
734
+ "rounded-[var(--radius-sm)]",
735
+ "transition-all duration-[var(--transition-normal)]",
736
+ "focus:outline-none focus:ring-[length:var(--focus-ring-width)] focus:ring-[var(--color-ring)] focus:ring-offset-[length:var(--focus-ring-offset)]",
737
+ "disabled:opacity-50 disabled:cursor-not-allowed",
738
+ variantStyles2[variant],
739
+ sizeStyles2[size],
740
+ className
741
+ ),
742
+ onClick: handleClick,
743
+ ...props,
744
+ "data-testid": props["data-testid"] ?? (action ? `action-${action}` : void 0),
745
+ children: [
746
+ isLoading ? /* @__PURE__ */ jsxRuntime.jsx(LucideIcons.Loader2, { className: "h-4 w-4 animate-spin" }) : resolvedLeftIcon && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-shrink-0", children: resolvedLeftIcon }),
747
+ children || label,
748
+ resolvedRightIcon && !isLoading && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-shrink-0", children: resolvedRightIcon })
749
+ ]
750
+ }
751
+ );
752
+ }
753
+ );
754
+ Button.displayName = "Button";
755
+ var variantStyles3 = {
756
+ default: [
757
+ "bg-[var(--color-muted)] text-[var(--color-foreground)]",
758
+ "border-[length:var(--border-width-thin)] border-[var(--color-border)]"
759
+ ].join(" "),
760
+ primary: "bg-[var(--color-primary)] text-[var(--color-primary-foreground)]",
761
+ secondary: "bg-[var(--color-secondary)] text-[var(--color-secondary-foreground)]",
762
+ success: [
763
+ "bg-[var(--color-surface)] text-[var(--color-success)]",
764
+ "border-[length:var(--border-width)] border-[var(--color-success)]"
765
+ ].join(" "),
766
+ warning: [
767
+ "bg-[var(--color-surface)] text-[var(--color-warning)]",
768
+ "border-[length:var(--border-width)] border-[var(--color-warning)]"
769
+ ].join(" "),
770
+ danger: [
771
+ "bg-[var(--color-surface)] text-[var(--color-error)]",
772
+ "border-[length:var(--border-width)] border-[var(--color-error)]"
773
+ ].join(" "),
774
+ error: [
775
+ "bg-[var(--color-surface)] text-[var(--color-error)]",
776
+ "border-[length:var(--border-width)] border-[var(--color-error)]"
777
+ ].join(" "),
778
+ info: [
779
+ "bg-[var(--color-surface)] text-[var(--color-info)]",
780
+ "border-[length:var(--border-width)] border-[var(--color-info)]"
781
+ ].join(" "),
782
+ neutral: [
783
+ "bg-[var(--color-muted)] text-[var(--color-muted-foreground)]",
784
+ "border-[length:var(--border-width-thin)] border-[var(--color-border)]"
785
+ ].join(" ")
786
+ };
787
+ var sizeStyles3 = {
788
+ sm: "px-2 py-0.5 text-xs",
789
+ md: "px-2.5 py-1 text-sm",
790
+ lg: "px-3 py-1.5 text-base"
791
+ };
792
+ var Badge = React113__namespace.default.forwardRef(
793
+ ({ className, variant = "default", size = "sm", amount, label, icon, children, ...props }, ref) => {
794
+ const iconSizes2 = { sm: "w-3 h-3", md: "w-3.5 h-3.5", lg: "w-4 h-4" };
795
+ const resolvedIcon = typeof icon === "string" ? (() => {
796
+ const I = resolveIcon(icon);
797
+ return I ? /* @__PURE__ */ jsxRuntime.jsx(I, { className: iconSizes2[size] }) : null;
798
+ })() : icon;
799
+ return /* @__PURE__ */ jsxRuntime.jsxs(
800
+ "span",
801
+ {
802
+ ref,
803
+ className: cn(
804
+ "inline-flex items-center gap-1 font-bold rounded-[var(--radius-sm)]",
805
+ variantStyles3[variant],
806
+ sizeStyles3[size],
807
+ className
808
+ ),
809
+ ...props,
810
+ children: [
811
+ resolvedIcon,
812
+ children || (amount != null ? `${label ? `${label} ` : ""}${amount}` : label)
813
+ ]
814
+ }
815
+ );
816
+ }
817
+ );
818
+ Badge.displayName = "Badge";
819
+ var Input = React113__namespace.default.forwardRef(
820
+ ({
821
+ className,
822
+ inputType,
823
+ type: htmlType,
824
+ error,
825
+ leftIcon,
826
+ rightIcon,
827
+ icon: IconComponent,
828
+ clearable,
829
+ onClear,
830
+ value,
831
+ options,
832
+ rows = 3,
833
+ onChange,
834
+ ...props
835
+ }, ref) => {
836
+ const type = inputType || htmlType || "text";
837
+ const resolvedLeftIcon = leftIcon || IconComponent && /* @__PURE__ */ jsxRuntime.jsx(IconComponent, { className: "h-4 w-4" });
838
+ const showClearButton = clearable && value && String(value).length > 0;
839
+ const baseClassName = cn(
840
+ "block w-full rounded-[var(--radius-sm)] transition-all duration-[var(--transition-fast)]",
841
+ "border-[length:var(--border-width-thin)] border-[var(--color-border)]",
842
+ "px-3 py-2 text-sm",
843
+ "bg-[var(--color-card)] hover:bg-[var(--color-muted)] focus:bg-[var(--color-card)]",
844
+ "text-[var(--color-foreground)] placeholder:text-[var(--color-muted-foreground)]",
845
+ "focus:outline-none focus:ring-1 focus:ring-[var(--color-ring)] focus:border-[var(--color-ring)]",
846
+ "disabled:opacity-50 disabled:cursor-not-allowed disabled:bg-[var(--color-muted)]",
847
+ error ? "border-[var(--color-error)] focus:border-[var(--color-error)] focus:ring-[var(--color-error)]" : "",
848
+ resolvedLeftIcon && "pl-10",
849
+ (rightIcon || showClearButton) && "pr-10",
850
+ className
851
+ );
852
+ if (type === "select") {
853
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
854
+ resolvedLeftIcon && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none text-[var(--color-muted-foreground)]", children: resolvedLeftIcon }),
855
+ /* @__PURE__ */ jsxRuntime.jsxs(
856
+ "select",
857
+ {
858
+ ref,
859
+ value,
860
+ onChange,
861
+ className: cn(baseClassName, "appearance-none pr-10", className),
862
+ ...props,
863
+ children: [
864
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "", children: "Select..." }),
865
+ options?.map((opt) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: opt.value, children: opt.label }, opt.value))
866
+ ]
867
+ }
868
+ ),
869
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-y-0 right-0 pr-3 flex items-center pointer-events-none text-[var(--color-muted-foreground)]", children: /* @__PURE__ */ jsxRuntime.jsx(LucideIcons.ChevronDown, { className: "h-4 w-4" }) })
870
+ ] });
871
+ }
872
+ if (type === "textarea") {
873
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative", children: /* @__PURE__ */ jsxRuntime.jsx(
874
+ "textarea",
875
+ {
876
+ ref,
877
+ value,
878
+ onChange,
879
+ rows,
880
+ className: baseClassName,
881
+ ...props
882
+ }
883
+ ) });
884
+ }
885
+ if (type === "checkbox") {
886
+ return /* @__PURE__ */ jsxRuntime.jsx(
887
+ "input",
888
+ {
889
+ ref,
890
+ type: "checkbox",
891
+ checked: props.checked,
892
+ onChange,
893
+ className: cn(
894
+ "h-4 w-4 rounded-[var(--radius-sm)]",
895
+ "border-[var(--color-border)]",
896
+ "text-[var(--color-primary)] focus:ring-[var(--color-ring)]",
897
+ "disabled:opacity-50 disabled:cursor-not-allowed",
898
+ className
899
+ ),
900
+ ...props
901
+ }
902
+ );
903
+ }
904
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
905
+ resolvedLeftIcon && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none text-[var(--color-muted-foreground)]", children: resolvedLeftIcon }),
906
+ /* @__PURE__ */ jsxRuntime.jsx(
907
+ "input",
908
+ {
909
+ ref,
910
+ type,
911
+ value,
912
+ onChange,
913
+ className: baseClassName,
914
+ ...props
915
+ }
916
+ ),
917
+ showClearButton && /* @__PURE__ */ jsxRuntime.jsx(
918
+ "button",
919
+ {
920
+ type: "button",
921
+ onClick: onClear,
922
+ className: "absolute inset-y-0 right-0 pr-3 flex items-center text-[var(--color-muted-foreground)] hover:text-[var(--color-foreground)]",
923
+ children: /* @__PURE__ */ jsxRuntime.jsx(LucideIcons.X, { className: "h-4 w-4" })
924
+ }
925
+ ),
926
+ rightIcon && !showClearButton && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-y-0 right-0 pr-3 flex items-center text-[var(--color-muted-foreground)]", children: rightIcon })
927
+ ] });
928
+ }
929
+ );
930
+ Input.displayName = "Input";
931
+ var Label = React113__namespace.default.forwardRef(
932
+ ({ className, required, children, ...props }, ref) => {
933
+ return /* @__PURE__ */ jsxRuntime.jsxs(
934
+ "label",
935
+ {
936
+ ref,
937
+ className: cn(
938
+ "block text-sm font-bold text-[var(--color-foreground)]",
939
+ className
940
+ ),
941
+ ...props,
942
+ children: [
943
+ children,
944
+ required && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[var(--color-error)] ml-1", children: "*" })
945
+ ]
946
+ }
947
+ );
948
+ }
949
+ );
950
+ Label.displayName = "Label";
951
+ var Textarea = React113__namespace.default.forwardRef(
952
+ ({ className, error, ...props }, ref) => {
953
+ return /* @__PURE__ */ jsxRuntime.jsx(
954
+ "textarea",
955
+ {
956
+ ref,
957
+ className: cn(
958
+ "block w-full border-[length:var(--border-width)] shadow-[var(--shadow-sm)]",
959
+ "px-3 py-2 text-sm text-[var(--color-foreground)]",
960
+ "bg-[var(--color-card)]",
961
+ "placeholder:text-[var(--color-placeholder)]",
962
+ "focus:outline-none focus:ring-2 focus:ring-offset-0 focus:ring-[var(--color-ring)]",
963
+ "disabled:bg-[var(--color-muted)] disabled:text-[var(--color-muted-foreground)] disabled:cursor-not-allowed",
964
+ "resize-y min-h-[80px]",
965
+ error ? "border-[var(--color-error)] focus:border-[var(--color-error)]" : "border-[var(--color-border)] focus:border-[var(--color-primary)]",
966
+ className
967
+ ),
968
+ ...props
969
+ }
970
+ );
971
+ }
972
+ );
973
+ Textarea.displayName = "Textarea";
974
+ var Select = React113__namespace.default.forwardRef(
975
+ ({ className, options, placeholder, error, ...props }, ref) => {
976
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
977
+ /* @__PURE__ */ jsxRuntime.jsxs(
978
+ "select",
979
+ {
980
+ ref,
981
+ className: cn(
982
+ "block w-full border-[length:var(--border-width)] shadow-[var(--shadow-sm)] appearance-none",
983
+ "px-3 py-2 pr-10 text-sm text-[var(--color-foreground)] font-medium",
984
+ "bg-[var(--color-card)]",
985
+ "focus:outline-none focus:ring-2 focus:ring-offset-0 focus:ring-[var(--color-ring)]",
986
+ "disabled:bg-[var(--color-muted)] disabled:text-[var(--color-muted-foreground)] disabled:cursor-not-allowed",
987
+ error ? "border-[var(--color-error)] focus:border-[var(--color-error)]" : "border-[var(--color-border)] focus:border-[var(--color-primary)]",
988
+ className
989
+ ),
990
+ ...props,
991
+ children: [
992
+ placeholder && /* @__PURE__ */ jsxRuntime.jsx("option", { value: "", disabled: true, children: placeholder }),
993
+ options.map((option) => /* @__PURE__ */ jsxRuntime.jsx(
994
+ "option",
995
+ {
996
+ value: option.value,
997
+ disabled: option.disabled,
998
+ children: option.label
999
+ },
1000
+ option.value
1001
+ ))
1002
+ ]
1003
+ }
1004
+ ),
1005
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-y-0 right-0 pr-3 flex items-center pointer-events-none", children: /* @__PURE__ */ jsxRuntime.jsx(LucideIcons.ChevronDown, { className: "h-4 w-4 text-[var(--color-foreground)]" }) })
1006
+ ] });
1007
+ }
1008
+ );
1009
+ Select.displayName = "Select";
1010
+ var Checkbox = React113__namespace.default.forwardRef(
1011
+ ({ className, label, id, ...props }, ref) => {
1012
+ const inputId = id || `checkbox-${Math.random().toString(36).substr(2, 9)}`;
1013
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center", children: [
1014
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative flex items-center", children: /* @__PURE__ */ jsxRuntime.jsx(
1015
+ "input",
1016
+ {
1017
+ ref,
1018
+ type: "checkbox",
1019
+ id: inputId,
1020
+ className: cn(
1021
+ "peer h-4 w-4 border-[length:var(--border-width)] border-[var(--color-border)]",
1022
+ "accent-[var(--color-primary)] focus:ring-[var(--color-ring)] focus:ring-offset-0",
1023
+ "bg-[var(--color-card)] checked:bg-[var(--color-primary)]",
1024
+ "disabled:opacity-50 disabled:cursor-not-allowed",
1025
+ className
1026
+ ),
1027
+ ...props
1028
+ }
1029
+ ) }),
1030
+ label && /* @__PURE__ */ jsxRuntime.jsx(
1031
+ "label",
1032
+ {
1033
+ htmlFor: inputId,
1034
+ className: "ml-2 text-sm text-[var(--color-foreground)] font-medium cursor-pointer select-none",
1035
+ children: label
1036
+ }
1037
+ )
1038
+ ] });
1039
+ }
1040
+ );
1041
+ Checkbox.displayName = "Checkbox";
1042
+ var variantStyles4 = {
1043
+ default: [
1044
+ "bg-[var(--color-card)] border-none",
1045
+ "transition-all duration-[var(--transition-normal)]",
1046
+ "hover:shadow-[var(--shadow-hover)] hover:-translate-y-0.5"
1047
+ ].join(" "),
1048
+ bordered: [
1049
+ "bg-[var(--color-card)]",
1050
+ "border-[length:var(--border-width)] border-[var(--color-border)]",
1051
+ "shadow-none",
1052
+ "transition-all duration-[var(--transition-normal)]",
1053
+ "hover:shadow-[var(--shadow-hover)] hover:-translate-y-0.5"
1054
+ ].join(" "),
1055
+ elevated: [
1056
+ "bg-[var(--color-card)]",
1057
+ "border-[length:var(--border-width)] border-[var(--color-border)]",
1058
+ "shadow-[var(--shadow-main)]",
1059
+ "transition-all duration-[var(--transition-normal)]",
1060
+ "hover:shadow-[var(--shadow-hover)] hover:-translate-y-0.5"
1061
+ ].join(" "),
1062
+ // Interactive variant with theme-specific hover effects
1063
+ interactive: [
1064
+ "bg-[var(--color-card)]",
1065
+ "border-[length:var(--border-width)] border-[var(--color-border)]",
1066
+ "shadow-[var(--shadow-main)]",
1067
+ "cursor-pointer",
1068
+ "transition-all duration-[var(--transition-normal)]",
1069
+ "hover:shadow-[var(--shadow-hover)]"
1070
+ ].join(" ")
1071
+ };
1072
+ var paddingStyles2 = {
1073
+ none: "",
1074
+ sm: "p-3",
1075
+ md: "p-4",
1076
+ lg: "p-6"
1077
+ };
1078
+ var shadowStyles2 = {
1079
+ none: "shadow-none",
1080
+ sm: "shadow-[var(--shadow-sm)]",
1081
+ md: "shadow-[var(--shadow-main)]",
1082
+ lg: "shadow-[var(--shadow-lg)]"
1083
+ };
1084
+ var Card = React113__namespace.default.forwardRef(
1085
+ ({
1086
+ className,
1087
+ variant = "bordered",
1088
+ padding = "md",
1089
+ title,
1090
+ subtitle,
1091
+ shadow,
1092
+ children,
1093
+ ...props
1094
+ }, ref) => {
1095
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1096
+ "div",
1097
+ {
1098
+ ref,
1099
+ className: cn(
1100
+ "rounded-[var(--radius-md)]",
1101
+ "transition-all duration-[var(--transition-normal)]",
1102
+ variantStyles4[variant],
1103
+ paddingStyles2[padding],
1104
+ shadow && shadowStyles2[shadow],
1105
+ className
1106
+ ),
1107
+ ...props,
1108
+ children: [
1109
+ (title || subtitle) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-4", children: [
1110
+ title && /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-lg text-[var(--color-card-foreground)] font-[var(--font-weight-bold)]", children: title }),
1111
+ subtitle && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-[var(--color-muted-foreground)] mt-1", children: subtitle })
1112
+ ] }),
1113
+ children
1114
+ ]
1115
+ }
1116
+ );
1117
+ }
1118
+ );
1119
+ Card.displayName = "Card";
1120
+ var CardHeader = React113__namespace.default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx("div", { ref, className: cn("mb-4", className), ...props }));
1121
+ CardHeader.displayName = "CardHeader";
1122
+ var CardTitle = React113__namespace.default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
1123
+ "h3",
1124
+ {
1125
+ ref,
1126
+ className: cn(
1127
+ "text-lg text-[var(--color-card-foreground)]",
1128
+ "font-[var(--font-weight-bold)]",
1129
+ className
1130
+ ),
1131
+ ...props
1132
+ }
1133
+ ));
1134
+ CardTitle.displayName = "CardTitle";
1135
+ var CardContent = React113__namespace.default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx("div", { ref, className: cn("", className), ...props }));
1136
+ CardContent.displayName = "CardContent";
1137
+ var CardBody = CardContent;
1138
+ CardBody.displayName = "CardBody";
1139
+ var CardFooter = React113__namespace.default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
1140
+ "div",
1141
+ {
1142
+ ref,
1143
+ className: cn("mt-4 flex items-center", className),
1144
+ ...props
1145
+ }
1146
+ ));
1147
+ CardFooter.displayName = "CardFooter";
1148
+ var sizeStyles4 = {
1149
+ xs: "h-3 w-3",
1150
+ sm: "h-4 w-4",
1151
+ md: "h-6 w-6",
1152
+ lg: "h-8 w-8"
1153
+ };
1154
+ var Spinner = React113__namespace.default.forwardRef(
1155
+ ({ className, size = "md", ...props }, ref) => {
1156
+ return /* @__PURE__ */ jsxRuntime.jsx(
1157
+ "div",
1158
+ {
1159
+ ref,
1160
+ className: cn("text-[var(--color-foreground)]", className),
1161
+ ...props,
1162
+ children: /* @__PURE__ */ jsxRuntime.jsx(LucideIcons.Loader2, { className: cn("animate-spin", sizeStyles4[size]) })
1163
+ }
1164
+ );
1165
+ }
1166
+ );
1167
+ Spinner.displayName = "Spinner";
1168
+ var Radio = React113__namespace.default.forwardRef(
1169
+ ({
1170
+ label,
1171
+ helperText,
1172
+ error,
1173
+ size = "md",
1174
+ className,
1175
+ id,
1176
+ checked,
1177
+ disabled,
1178
+ ...props
1179
+ }, ref) => {
1180
+ const radioId = id || `radio-${Math.random().toString(36).substr(2, 9)}`;
1181
+ const hasError = !!error;
1182
+ const sizeClasses6 = {
1183
+ sm: "w-4 h-4",
1184
+ md: "w-5 h-5",
1185
+ lg: "w-6 h-6"
1186
+ };
1187
+ const dotSizeClasses = {
1188
+ sm: "w-2 h-2",
1189
+ md: "w-2.5 h-2.5",
1190
+ lg: "w-3 h-3"
1191
+ };
1192
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1193
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start gap-3", children: [
1194
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative flex-shrink-0 mt-0.5", children: [
1195
+ /* @__PURE__ */ jsxRuntime.jsx(
1196
+ "input",
1197
+ {
1198
+ ref,
1199
+ type: "radio",
1200
+ id: radioId,
1201
+ checked,
1202
+ disabled,
1203
+ className: cn("sr-only peer", className),
1204
+ "aria-invalid": hasError,
1205
+ "aria-describedby": error ? `${radioId}-error` : helperText ? `${radioId}-helper` : void 0,
1206
+ ...props
1207
+ }
1208
+ ),
1209
+ /* @__PURE__ */ jsxRuntime.jsx(
1210
+ "label",
1211
+ {
1212
+ htmlFor: radioId,
1213
+ className: cn(
1214
+ "flex items-center justify-center",
1215
+ "border-[length:var(--border-width)] transition-all cursor-pointer",
1216
+ sizeClasses6[size],
1217
+ hasError ? "border-[var(--color-error)] peer-focus:ring-[var(--color-error)]/20" : "border-[var(--color-border)] peer-focus:ring-[var(--color-ring)]/20",
1218
+ checked ? hasError ? "border-[var(--color-error)]" : "border-[var(--color-primary)] bg-[var(--color-primary)]" : "",
1219
+ "peer-focus:outline-none peer-focus:ring-2 peer-focus:ring-offset-2",
1220
+ disabled && "opacity-50 cursor-not-allowed",
1221
+ !disabled && "hover:border-[var(--color-border-hover)]"
1222
+ ),
1223
+ children: checked && /* @__PURE__ */ jsxRuntime.jsx(
1224
+ "div",
1225
+ {
1226
+ className: cn(
1227
+ "transition-all",
1228
+ dotSizeClasses[size],
1229
+ hasError ? "bg-[var(--color-error)]" : "bg-[var(--color-primary-foreground)]"
1230
+ )
1231
+ }
1232
+ )
1233
+ }
1234
+ )
1235
+ ] }),
1236
+ label && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ jsxRuntime.jsx(
1237
+ "label",
1238
+ {
1239
+ htmlFor: radioId,
1240
+ className: cn(
1241
+ "block text-sm font-medium cursor-pointer select-none",
1242
+ hasError ? "text-[var(--color-error)]" : "text-[var(--color-foreground)]",
1243
+ disabled && "opacity-50 cursor-not-allowed"
1244
+ ),
1245
+ children: label
1246
+ }
1247
+ ) })
1248
+ ] }),
1249
+ (helperText || error) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-1.5 ml-8", children: [
1250
+ error && /* @__PURE__ */ jsxRuntime.jsx(
1251
+ "p",
1252
+ {
1253
+ id: `${radioId}-error`,
1254
+ className: "text-sm text-[var(--color-error)] font-medium",
1255
+ role: "alert",
1256
+ children: error
1257
+ }
1258
+ ),
1259
+ !error && helperText && /* @__PURE__ */ jsxRuntime.jsx(
1260
+ "p",
1261
+ {
1262
+ id: `${radioId}-helper`,
1263
+ className: "text-sm text-[var(--color-muted-foreground)]",
1264
+ children: helperText
1265
+ }
1266
+ )
1267
+ ] })
1268
+ ] });
1269
+ }
1270
+ );
1271
+ Radio.displayName = "Radio";
1272
+ var Switch = React113__namespace.forwardRef(
1273
+ ({
1274
+ checked,
1275
+ defaultChecked = false,
1276
+ onChange,
1277
+ disabled = false,
1278
+ label,
1279
+ id,
1280
+ name,
1281
+ className
1282
+ }, ref) => {
1283
+ const [isChecked, setIsChecked] = React113__namespace.useState(
1284
+ checked !== void 0 ? checked : defaultChecked
1285
+ );
1286
+ React113__namespace.useEffect(() => {
1287
+ if (checked !== void 0) {
1288
+ setIsChecked(checked);
1289
+ }
1290
+ }, [checked]);
1291
+ const handleClick = () => {
1292
+ if (disabled) return;
1293
+ const newValue = !isChecked;
1294
+ if (checked === void 0) {
1295
+ setIsChecked(newValue);
1296
+ }
1297
+ onChange?.(newValue);
1298
+ };
1299
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("inline-flex items-center gap-2", className), children: [
1300
+ /* @__PURE__ */ jsxRuntime.jsx(
1301
+ "button",
1302
+ {
1303
+ ref,
1304
+ type: "button",
1305
+ role: "switch",
1306
+ "aria-checked": isChecked,
1307
+ "aria-label": label,
1308
+ id,
1309
+ name,
1310
+ disabled,
1311
+ onClick: handleClick,
1312
+ className: cn(
1313
+ "relative inline-flex h-6 w-11 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors",
1314
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background",
1315
+ isChecked ? "bg-primary" : "bg-muted",
1316
+ disabled && "cursor-not-allowed opacity-50"
1317
+ ),
1318
+ children: /* @__PURE__ */ jsxRuntime.jsx(
1319
+ "span",
1320
+ {
1321
+ className: cn(
1322
+ "pointer-events-none block h-5 w-5 rounded-full bg-background shadow-lg ring-0 transition-transform",
1323
+ isChecked ? "translate-x-5" : "translate-x-0"
1324
+ )
1325
+ }
1326
+ )
1327
+ }
1328
+ ),
1329
+ label && /* @__PURE__ */ jsxRuntime.jsx(
1330
+ "label",
1331
+ {
1332
+ htmlFor: id,
1333
+ className: cn(
1334
+ "text-sm font-medium leading-none cursor-pointer",
1335
+ disabled && "cursor-not-allowed opacity-70"
1336
+ ),
1337
+ onClick: handleClick,
1338
+ children: label
1339
+ }
1340
+ )
1341
+ ] });
1342
+ }
1343
+ );
1344
+ Switch.displayName = "Switch";
1345
+ var gapStyles = {
1346
+ none: "gap-0",
1347
+ xs: "gap-1",
1348
+ sm: "gap-2",
1349
+ md: "gap-4",
1350
+ lg: "gap-6",
1351
+ xl: "gap-8",
1352
+ "2xl": "gap-12"
1353
+ };
1354
+ var alignStyles = {
1355
+ start: "items-start",
1356
+ center: "items-center",
1357
+ end: "items-end",
1358
+ stretch: "items-stretch",
1359
+ baseline: "items-baseline"
1360
+ };
1361
+ var justifyStyles = {
1362
+ start: "justify-start",
1363
+ center: "justify-center",
1364
+ end: "justify-end",
1365
+ between: "justify-between",
1366
+ around: "justify-around",
1367
+ evenly: "justify-evenly"
1368
+ };
1369
+ var Stack = ({
1370
+ direction = "vertical",
1371
+ gap = "md",
1372
+ align = "stretch",
1373
+ justify = "start",
1374
+ wrap = false,
1375
+ reverse = false,
1376
+ flex = false,
1377
+ className,
1378
+ style,
1379
+ children,
1380
+ as: Component2 = "div",
1381
+ onClick,
1382
+ onKeyDown,
1383
+ role,
1384
+ tabIndex,
1385
+ action,
1386
+ actionPayload,
1387
+ responsive = false
1388
+ }) => {
1389
+ const eventBus = useEventBus();
1390
+ const handleClick = (e) => {
1391
+ if (action) {
1392
+ eventBus.emit(`UI:${action}`, actionPayload ?? {});
1393
+ }
1394
+ onClick?.(e);
1395
+ };
1396
+ const isHorizontal = direction === "horizontal";
1397
+ const directionClass = responsive && isHorizontal ? reverse ? "flex-col-reverse md:flex-row-reverse" : "flex-col md:flex-row" : isHorizontal ? reverse ? "flex-row-reverse" : "flex-row" : reverse ? "flex-col-reverse" : "flex-col";
1398
+ const Comp = Component2;
1399
+ return /* @__PURE__ */ jsxRuntime.jsx(
1400
+ Comp,
1401
+ {
1402
+ className: cn(
1403
+ "flex",
1404
+ directionClass,
1405
+ gapStyles[gap],
1406
+ alignStyles[align],
1407
+ justifyStyles[justify],
1408
+ wrap && "flex-wrap",
1409
+ flex && "flex-1",
1410
+ className
1411
+ ),
1412
+ style,
1413
+ onClick: action || onClick ? handleClick : void 0,
1414
+ onKeyDown,
1415
+ role,
1416
+ tabIndex,
1417
+ children
1418
+ }
1419
+ );
1420
+ };
1421
+ var VStack = (props) => /* @__PURE__ */ jsxRuntime.jsx(Stack, { direction: "vertical", ...props });
1422
+ var HStack = (props) => /* @__PURE__ */ jsxRuntime.jsx(Stack, { direction: "horizontal", ...props });
1423
+ var statusColors = {
1424
+ online: "bg-[var(--color-success)]",
1425
+ offline: "bg-[var(--color-muted-foreground)]",
1426
+ away: "bg-[var(--color-warning)]",
1427
+ busy: "bg-[var(--color-error)]",
1428
+ warning: "bg-[var(--color-warning)]",
1429
+ critical: "bg-[var(--color-error)]"
1430
+ };
1431
+ var pulseRingColors = {
1432
+ online: "ring-[var(--color-success)]",
1433
+ offline: "ring-[var(--color-muted-foreground)]",
1434
+ away: "ring-[var(--color-warning)]",
1435
+ busy: "ring-[var(--color-error)]",
1436
+ warning: "ring-[var(--color-warning)]",
1437
+ critical: "ring-[var(--color-error)]"
1438
+ };
1439
+ var sizeStyles5 = {
1440
+ sm: "w-2 h-2",
1441
+ md: "w-2.5 h-2.5",
1442
+ lg: "w-3 h-3"
1443
+ };
1444
+ var StatusDot = React113__namespace.default.forwardRef(
1445
+ ({ className, status = "offline", pulse = false, size = "md", label, ...props }, ref) => {
1446
+ return /* @__PURE__ */ jsxRuntime.jsx(
1447
+ "span",
1448
+ {
1449
+ ref,
1450
+ className: cn(
1451
+ "inline-block rounded-full flex-shrink-0",
1452
+ statusColors[status],
1453
+ sizeStyles5[size],
1454
+ pulse && [
1455
+ "animate-pulse",
1456
+ "ring-2 ring-offset-1",
1457
+ pulseRingColors[status],
1458
+ "ring-opacity-40"
1459
+ ],
1460
+ className
1461
+ ),
1462
+ role: "status",
1463
+ "aria-label": label ?? status,
1464
+ ...props
1465
+ }
1466
+ );
1467
+ }
1468
+ );
1469
+ StatusDot.displayName = "StatusDot";
1470
+ var sizeStyles6 = {
1471
+ sm: { icon: "w-3 h-3", text: "text-xs" },
1472
+ md: { icon: "w-4 h-4", text: "text-sm" },
1473
+ lg: { icon: "w-5 h-5", text: "text-base" }
1474
+ };
1475
+ function resolveDirection(value, direction) {
1476
+ if (direction) return direction;
1477
+ if (value === void 0 || value === 0) return "flat";
1478
+ return value > 0 ? "up" : "down";
1479
+ }
1480
+ function resolveColor(dir, invert) {
1481
+ if (dir === "flat") return "text-[var(--color-muted-foreground)]";
1482
+ const isPositive = dir === "up";
1483
+ const isGood = invert ? !isPositive : isPositive;
1484
+ return isGood ? "text-[var(--color-success)]" : "text-[var(--color-error)]";
1485
+ }
1486
+ var iconMap2 = {
1487
+ up: LucideIcons.TrendingUp,
1488
+ down: LucideIcons.TrendingDown,
1489
+ flat: LucideIcons.ArrowRight
1490
+ };
1491
+ var TrendIndicator = React113__namespace.default.forwardRef(
1492
+ ({
1493
+ className,
1494
+ value,
1495
+ direction,
1496
+ showValue = true,
1497
+ invert = false,
1498
+ label,
1499
+ size = "md",
1500
+ ...props
1501
+ }, ref) => {
1502
+ const dir = resolveDirection(value, direction);
1503
+ const colorClass = resolveColor(dir, invert);
1504
+ const IconComponent = iconMap2[dir];
1505
+ const styles = sizeStyles6[size];
1506
+ const formattedValue = value !== void 0 ? `${value > 0 ? "+" : ""}${value}%` : void 0;
1507
+ const ariaLabel = label ?? (formattedValue ? `${dir} ${formattedValue}` : dir);
1508
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1509
+ "span",
1510
+ {
1511
+ ref,
1512
+ className: cn(
1513
+ "inline-flex items-center gap-1 font-medium",
1514
+ colorClass,
1515
+ styles.text,
1516
+ className
1517
+ ),
1518
+ role: "status",
1519
+ "aria-label": ariaLabel,
1520
+ ...props,
1521
+ children: [
1522
+ /* @__PURE__ */ jsxRuntime.jsx(IconComponent, { className: styles.icon }),
1523
+ showValue && formattedValue && /* @__PURE__ */ jsxRuntime.jsx("span", { children: formattedValue })
1524
+ ]
1525
+ }
1526
+ );
1527
+ }
1528
+ );
1529
+ TrendIndicator.displayName = "TrendIndicator";
1530
+ function useSafeEventBus() {
1531
+ try {
1532
+ return useEventBus();
1533
+ } catch {
1534
+ return { emit: () => {
1535
+ }, on: () => () => {
1536
+ }, once: () => {
1537
+ } };
1538
+ }
1539
+ }
1540
+ var trackSizes = {
1541
+ sm: "h-1",
1542
+ md: "h-1.5",
1543
+ lg: "h-2"
1544
+ };
1545
+ var thumbSizes = {
1546
+ sm: "w-3 h-3",
1547
+ md: "w-4 h-4",
1548
+ lg: "w-5 h-5"
1549
+ };
1550
+ var RangeSlider = React113__namespace.default.forwardRef(
1551
+ ({
1552
+ className,
1553
+ min = 0,
1554
+ max = 100,
1555
+ value = 0,
1556
+ step = 1,
1557
+ showTooltip = false,
1558
+ showTicks = false,
1559
+ buffered,
1560
+ size = "md",
1561
+ disabled = false,
1562
+ action,
1563
+ actionPayload,
1564
+ onChange,
1565
+ formatValue: formatValue5,
1566
+ ...props
1567
+ }, ref) => {
1568
+ const [isDragging, setIsDragging] = React113.useState(false);
1569
+ const [showTip, setShowTip] = React113.useState(false);
1570
+ const inputRef = React113.useRef(null);
1571
+ const eventBus = useSafeEventBus();
1572
+ const percentage = max !== min ? (value - min) / (max - min) * 100 : 0;
1573
+ const bufferedPercentage = buffered !== void 0 ? Math.min(buffered, 100) : void 0;
1574
+ const displayValue = formatValue5 ? formatValue5(value) : String(value);
1575
+ const handleChange = React113.useCallback(
1576
+ (e) => {
1577
+ const newValue = Number(e.target.value);
1578
+ onChange?.(newValue);
1579
+ if (action) {
1580
+ eventBus.emit(`UI:${action}`, { ...actionPayload, value: newValue });
1581
+ }
1582
+ },
1583
+ [onChange, action, actionPayload, eventBus]
1584
+ );
1585
+ const tickCount = showTicks ? Math.min(Math.floor((max - min) / step), 20) : 0;
1586
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1587
+ "div",
1588
+ {
1589
+ ref,
1590
+ className: cn(
1591
+ "relative w-full",
1592
+ disabled && "opacity-50 cursor-not-allowed",
1593
+ className
1594
+ ),
1595
+ ...props,
1596
+ children: [
1597
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative w-full py-2", children: [
1598
+ /* @__PURE__ */ jsxRuntime.jsx(
1599
+ "div",
1600
+ {
1601
+ className: cn(
1602
+ "absolute inset-x-0 rounded-full bg-[var(--color-muted)]",
1603
+ trackSizes[size]
1604
+ ),
1605
+ style: { top: "50%", transform: "translateY(-50%)" }
1606
+ }
1607
+ ),
1608
+ bufferedPercentage !== void 0 && /* @__PURE__ */ jsxRuntime.jsx(
1609
+ "div",
1610
+ {
1611
+ className: cn(
1612
+ "absolute rounded-full bg-[var(--color-muted-foreground)] opacity-30",
1613
+ trackSizes[size]
1614
+ ),
1615
+ style: {
1616
+ top: "50%",
1617
+ transform: "translateY(-50%)",
1618
+ left: 0,
1619
+ width: `${bufferedPercentage}%`
1620
+ }
1621
+ }
1622
+ ),
1623
+ /* @__PURE__ */ jsxRuntime.jsx(
1624
+ "div",
1625
+ {
1626
+ className: cn(
1627
+ "absolute rounded-full bg-[var(--color-primary)]",
1628
+ trackSizes[size]
1629
+ ),
1630
+ style: {
1631
+ top: "50%",
1632
+ transform: "translateY(-50%)",
1633
+ left: 0,
1634
+ width: `${percentage}%`
1635
+ }
1636
+ }
1637
+ ),
1638
+ /* @__PURE__ */ jsxRuntime.jsx(
1639
+ "input",
1640
+ {
1641
+ ref: inputRef,
1642
+ type: "range",
1643
+ min,
1644
+ max,
1645
+ step,
1646
+ value,
1647
+ disabled,
1648
+ onChange: handleChange,
1649
+ onMouseDown: () => {
1650
+ setIsDragging(true);
1651
+ setShowTip(true);
1652
+ },
1653
+ onMouseUp: () => {
1654
+ setIsDragging(false);
1655
+ setShowTip(false);
1656
+ },
1657
+ onTouchStart: () => {
1658
+ setIsDragging(true);
1659
+ setShowTip(true);
1660
+ },
1661
+ onTouchEnd: () => {
1662
+ setIsDragging(false);
1663
+ setShowTip(false);
1664
+ },
1665
+ onFocus: () => setShowTip(true),
1666
+ onBlur: () => {
1667
+ if (!isDragging) setShowTip(false);
1668
+ },
1669
+ className: cn(
1670
+ "absolute inset-0 w-full opacity-0 cursor-pointer",
1671
+ disabled && "cursor-not-allowed",
1672
+ // Thumb sizing via pseudo-element
1673
+ "[&::-webkit-slider-thumb]:appearance-none",
1674
+ "[&::-webkit-slider-thumb]:w-5 [&::-webkit-slider-thumb]:h-5",
1675
+ "[&::-moz-range-thumb]:w-5 [&::-moz-range-thumb]:h-5"
1676
+ ),
1677
+ style: { height: "100%", margin: 0 },
1678
+ "aria-label": props["aria-label"] ?? "Range slider",
1679
+ "aria-valuemin": min,
1680
+ "aria-valuemax": max,
1681
+ "aria-valuenow": value,
1682
+ "aria-valuetext": displayValue
1683
+ }
1684
+ ),
1685
+ /* @__PURE__ */ jsxRuntime.jsx(
1686
+ "div",
1687
+ {
1688
+ className: cn(
1689
+ "absolute rounded-full bg-[var(--color-primary-foreground)]",
1690
+ "border-2 border-[var(--color-primary)]",
1691
+ "shadow-[var(--shadow-sm)]",
1692
+ "pointer-events-none",
1693
+ "transition-transform duration-100",
1694
+ isDragging && "scale-110",
1695
+ thumbSizes[size]
1696
+ ),
1697
+ style: {
1698
+ top: "50%",
1699
+ transform: `translateY(-50%) translateX(-50%)${isDragging ? " scale(1.1)" : ""}`,
1700
+ left: `${percentage}%`
1701
+ }
1702
+ }
1703
+ ),
1704
+ showTooltip && showTip && /* @__PURE__ */ jsxRuntime.jsx(
1705
+ "div",
1706
+ {
1707
+ className: cn(
1708
+ "absolute -top-8 px-2 py-0.5 rounded",
1709
+ "bg-[var(--color-foreground)] text-[var(--color-background)]",
1710
+ "text-xs font-medium whitespace-nowrap",
1711
+ "pointer-events-none"
1712
+ ),
1713
+ style: {
1714
+ left: `${percentage}%`,
1715
+ transform: "translateX(-50%)"
1716
+ },
1717
+ children: displayValue
1718
+ }
1719
+ )
1720
+ ] }),
1721
+ showTicks && tickCount > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative w-full h-2 mt-1", children: Array.from({ length: tickCount + 1 }, (_, i) => {
1722
+ const tickPercent = i / tickCount * 100;
1723
+ return /* @__PURE__ */ jsxRuntime.jsx(
1724
+ "div",
1725
+ {
1726
+ className: "absolute w-px h-1.5 bg-[var(--color-muted-foreground)]",
1727
+ style: { left: `${tickPercent}%` }
1728
+ },
1729
+ i
1730
+ );
1731
+ }) })
1732
+ ]
1733
+ }
1734
+ );
1735
+ }
1736
+ );
1737
+ RangeSlider.displayName = "RangeSlider";
1738
+ var backgroundClasses = {
1739
+ default: "",
1740
+ alt: "bg-[var(--color-surface)]",
1741
+ dark: "bg-[var(--color-foreground)] text-[var(--color-background)]",
1742
+ gradient: [
1743
+ "bg-gradient-to-b",
1744
+ "from-[var(--color-primary)]/5",
1745
+ "to-[var(--color-secondary)]/5"
1746
+ ].join(" ")
1747
+ };
1748
+ var paddingClasses = {
1749
+ sm: "py-12",
1750
+ md: "py-16",
1751
+ lg: "py-24"
1752
+ };
1753
+ var ContentSection = React113__namespace.default.forwardRef(
1754
+ ({ children, background = "default", padding = "lg", id, className }, ref) => {
1755
+ return /* @__PURE__ */ jsxRuntime.jsx(
1756
+ Box,
1757
+ {
1758
+ ref,
1759
+ as: "section",
1760
+ id,
1761
+ className: cn(
1762
+ backgroundClasses[background],
1763
+ paddingClasses[padding],
1764
+ className
1765
+ ),
1766
+ children: /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "mx-auto max-w-7xl px-4 sm:px-6 lg:px-8", children })
1767
+ }
1768
+ );
1769
+ }
1770
+ );
1771
+ ContentSection.displayName = "ContentSection";
1772
+ var ErrorState = ({
1773
+ title,
1774
+ message,
1775
+ description,
1776
+ onRetry,
1777
+ className,
1778
+ retryEvent
1779
+ }) => {
1780
+ const eventBus = useEventBus();
1781
+ const { t } = useTranslate();
1782
+ const handleRetry = () => {
1783
+ if (retryEvent) eventBus.emit(`UI:${retryEvent}`, {});
1784
+ onRetry?.();
1785
+ };
1786
+ const resolvedTitle = title ?? t("error.generic");
1787
+ const resolvedMessage = message ?? description ?? t("error.occurred");
1788
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1789
+ VStack,
1790
+ {
1791
+ align: "center",
1792
+ className: cn(
1793
+ "justify-center py-12 text-center",
1794
+ className
1795
+ ),
1796
+ children: [
1797
+ /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "mb-4 rounded-[var(--radius-full)] bg-[var(--color-error)]/10 p-3", children: /* @__PURE__ */ jsxRuntime.jsx(LucideIcons.AlertCircle, { className: "h-8 w-8 text-[var(--color-error)]" }) }),
1798
+ /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "h3", className: "text-lg font-medium text-[var(--color-foreground)]", children: resolvedTitle }),
1799
+ /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", className: "mt-1 text-[var(--color-muted-foreground)] max-w-sm", children: resolvedMessage }),
1800
+ (onRetry || retryEvent) && /* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "secondary", className: "mt-4", onClick: handleRetry, children: t("error.retry") })
1801
+ ]
1802
+ }
1803
+ );
1804
+ };
1805
+ ErrorState.displayName = "ErrorState";
1806
+ var ErrorBoundary = class extends React113__namespace.default.Component {
1807
+ constructor(props) {
1808
+ super(props);
1809
+ __publicField(this, "reset", () => {
1810
+ this.setState({ error: null });
1811
+ });
1812
+ this.state = { error: null };
1813
+ }
1814
+ static getDerivedStateFromError(error) {
1815
+ return { error };
1816
+ }
1817
+ componentDidCatch(error, errorInfo) {
1818
+ this.props.onError?.(error, errorInfo);
1819
+ }
1820
+ render() {
1821
+ const { error } = this.state;
1822
+ const { children, fallback, className } = this.props;
1823
+ if (error) {
1824
+ const wrapper = className ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn(className), children: this.renderFallback(error, fallback) }) : this.renderFallback(error, fallback);
1825
+ return wrapper;
1826
+ }
1827
+ return children;
1828
+ }
1829
+ renderFallback(error, fallback) {
1830
+ if (typeof fallback === "function") {
1831
+ return fallback(error, this.reset);
1832
+ }
1833
+ if (fallback) {
1834
+ return fallback;
1835
+ }
1836
+ return /* @__PURE__ */ jsxRuntime.jsx(
1837
+ ErrorState,
1838
+ {
1839
+ title: "Something went wrong",
1840
+ message: error.message,
1841
+ onRetry: this.reset
1842
+ }
1843
+ );
1844
+ }
1845
+ };
1846
+ __publicField(ErrorBoundary, "displayName", "ErrorBoundary");
1847
+ var ClientEffectConfigContext = React113.createContext(null);
1848
+ ClientEffectConfigContext.Provider;
1849
+ React113.createContext(null);
1850
+ var defaultIcon = L__default.default.icon({
1851
+ iconUrl: "https://unpkg.com/leaflet@1.9.4/dist/images/marker-icon.png",
1852
+ iconRetinaUrl: "https://unpkg.com/leaflet@1.9.4/dist/images/marker-icon-2x.png",
1853
+ shadowUrl: "https://unpkg.com/leaflet@1.9.4/dist/images/marker-shadow.png",
1854
+ iconSize: [25, 41],
1855
+ iconAnchor: [12, 41],
1856
+ popupAnchor: [1, -34],
1857
+ shadowSize: [41, 41]
1858
+ });
1859
+ L__default.default.Marker.prototype.options.icon = defaultIcon;
1860
+
1861
+ // lib/verificationRegistry.ts
1862
+ var checks = /* @__PURE__ */ new Map();
1863
+ var transitions = [];
1864
+ var MAX_TRANSITIONS = 500;
1865
+ var listeners = /* @__PURE__ */ new Set();
1866
+ function notifyListeners() {
1867
+ listeners.forEach((l) => l());
1868
+ exposeOnWindow();
1869
+ }
1870
+ function registerCheck(id, label, status = "pending", details) {
1871
+ checks.set(id, { id, label, status, details, updatedAt: Date.now() });
1872
+ notifyListeners();
1873
+ }
1874
+ function getAllChecks() {
1875
+ return Array.from(checks.values());
1876
+ }
1877
+ function recordTransition(trace) {
1878
+ const entry = {
1879
+ ...trace,
1880
+ id: `t-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`
1881
+ };
1882
+ transitions.push(entry);
1883
+ if (transitions.length > MAX_TRANSITIONS) {
1884
+ transitions.shift();
1885
+ }
1886
+ if (entry.event === "INIT") {
1887
+ const hasFetch = entry.effects.some((e) => e.type === "fetch");
1888
+ const checkId = `init-fetch-${entry.traitName}`;
1889
+ if (hasFetch) {
1890
+ registerCheck(
1891
+ checkId,
1892
+ `INIT transition for "${entry.traitName}" has fetch effect`,
1893
+ "pass"
1894
+ );
1895
+ } else {
1896
+ const hasRenderUI = entry.effects.some((e) => e.type === "render-ui");
1897
+ if (hasRenderUI) {
1898
+ registerCheck(
1899
+ checkId,
1900
+ `INIT transition for "${entry.traitName}" missing fetch effect`,
1901
+ "fail",
1902
+ "Entity-bound render-ui without a fetch effect will show empty data"
1903
+ );
1904
+ }
1905
+ }
1906
+ }
1907
+ const failedEffects = entry.effects.filter((e) => e.status === "failed");
1908
+ if (failedEffects.length > 0) {
1909
+ registerCheck(
1910
+ `effects-${entry.id}`,
1911
+ `Effects failed in ${entry.traitName}: ${entry.from} -> ${entry.to}`,
1912
+ "fail",
1913
+ failedEffects.map((e) => `${e.type}: ${e.error}`).join("; ")
1914
+ );
1915
+ }
1916
+ notifyListeners();
1917
+ }
1918
+ function getTransitions() {
1919
+ return [...transitions];
1920
+ }
1921
+ function getBridgeHealth() {
1922
+ return null;
1923
+ }
1924
+ function getSummary() {
1925
+ const allChecks = getAllChecks();
1926
+ return {
1927
+ totalChecks: allChecks.length,
1928
+ passed: allChecks.filter((c) => c.status === "pass").length,
1929
+ failed: allChecks.filter((c) => c.status === "fail").length,
1930
+ warnings: allChecks.filter((c) => c.status === "warn").length,
1931
+ pending: allChecks.filter((c) => c.status === "pending").length
1932
+ };
1933
+ }
1934
+ function getSnapshot2() {
1935
+ return {
1936
+ checks: getAllChecks(),
1937
+ transitions: getTransitions(),
1938
+ bridge: getBridgeHealth(),
1939
+ summary: getSummary()
1940
+ };
1941
+ }
1942
+ function subscribeToVerification(listener) {
1943
+ listeners.add(listener);
1944
+ return () => listeners.delete(listener);
1945
+ }
1946
+ function exposeOnWindow() {
1947
+ if (typeof window === "undefined") return;
1948
+ if (!window.__orbitalVerification) {
1949
+ window.__orbitalVerification = {
1950
+ getSnapshot: getSnapshot2,
1951
+ getChecks: getAllChecks,
1952
+ getTransitions,
1953
+ getBridge: getBridgeHealth,
1954
+ getSummary,
1955
+ waitForTransition
1956
+ };
1957
+ }
1958
+ }
1959
+ function waitForTransition(event, timeoutMs = 1e4) {
1960
+ return new Promise((resolve) => {
1961
+ const existing = transitions.find((t) => t.event === event);
1962
+ if (existing) {
1963
+ resolve(existing);
1964
+ return;
1965
+ }
1966
+ const timeout = setTimeout(() => {
1967
+ unsub();
1968
+ resolve(null);
1969
+ }, timeoutMs);
1970
+ const unsub = subscribeToVerification(() => {
1971
+ const found = transitions.find((t) => t.event === event);
1972
+ if (found) {
1973
+ clearTimeout(timeout);
1974
+ unsub();
1975
+ resolve(found);
1976
+ }
1977
+ });
1978
+ });
1979
+ }
1980
+ exposeOnWindow();
1981
+ var MarkdownContent = React113__namespace.default.memo(
1982
+ ({ content, direction, className }) => {
1983
+ const { t: _t } = useTranslate();
1984
+ return /* @__PURE__ */ jsxRuntime.jsx(
1985
+ Box,
1986
+ {
1987
+ className: cn("prose prose-slate dark:prose-invert max-w-none", className),
1988
+ style: { direction },
1989
+ children: /* @__PURE__ */ jsxRuntime.jsx(
1990
+ ReactMarkdown__default.default,
1991
+ {
1992
+ remarkPlugins: [remarkMath__default.default, remarkGfm__default.default],
1993
+ rehypePlugins: [
1994
+ [rehypeKatex__default.default, { strict: false, throwOnError: false }]
1995
+ ],
1996
+ components: {
1997
+ // Handle inline code only — fenced code blocks are parsed out separately
1998
+ code({ className: codeClassName, children, ...props }) {
1999
+ return /* @__PURE__ */ jsxRuntime.jsx(
2000
+ "code",
2001
+ {
2002
+ ...props,
2003
+ className: codeClassName,
2004
+ style: {
2005
+ backgroundColor: "#1f2937",
2006
+ color: "#e5e7eb",
2007
+ padding: "0.125rem 0.375rem",
2008
+ borderRadius: "0.25rem",
2009
+ fontSize: "0.875em",
2010
+ fontFamily: "ui-monospace, monospace"
2011
+ },
2012
+ children
2013
+ }
2014
+ );
2015
+ },
2016
+ // Style links
2017
+ a({ href, children, ...props }) {
2018
+ return /* @__PURE__ */ jsxRuntime.jsx(
2019
+ "a",
2020
+ {
2021
+ href,
2022
+ ...props,
2023
+ className: "text-blue-600 dark:text-blue-400 hover:underline",
2024
+ target: href?.startsWith("http") ? "_blank" : void 0,
2025
+ rel: href?.startsWith("http") ? "noopener noreferrer" : void 0,
2026
+ children
2027
+ }
2028
+ );
2029
+ },
2030
+ // Style tables
2031
+ table({ children, ...props }) {
2032
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-x-auto my-4", children: /* @__PURE__ */ jsxRuntime.jsx(
2033
+ "table",
2034
+ {
2035
+ ...props,
2036
+ className: "min-w-full border-collapse border border-gray-300 dark:border-gray-600",
2037
+ children
2038
+ }
2039
+ ) });
2040
+ },
2041
+ th({ children, ...props }) {
2042
+ return /* @__PURE__ */ jsxRuntime.jsx(
2043
+ "th",
2044
+ {
2045
+ ...props,
2046
+ className: "border border-gray-300 dark:border-gray-600 bg-gray-100 dark:bg-gray-800 px-4 py-2 text-left font-semibold",
2047
+ children
2048
+ }
2049
+ );
2050
+ },
2051
+ td({ children, ...props }) {
2052
+ return /* @__PURE__ */ jsxRuntime.jsx(
2053
+ "td",
2054
+ {
2055
+ ...props,
2056
+ className: "border border-gray-300 dark:border-gray-600 px-4 py-2",
2057
+ children
2058
+ }
2059
+ );
2060
+ },
2061
+ // Style blockquotes
2062
+ blockquote({ children, ...props }) {
2063
+ return /* @__PURE__ */ jsxRuntime.jsx(
2064
+ "blockquote",
2065
+ {
2066
+ ...props,
2067
+ className: "border-l-4 border-blue-500 pl-4 italic text-[var(--color-foreground)] my-4",
2068
+ children
2069
+ }
2070
+ );
2071
+ }
2072
+ },
2073
+ children: content
2074
+ }
2075
+ )
2076
+ }
2077
+ );
2078
+ },
2079
+ (prev, next) => prev.content === next.content && prev.className === next.className && prev.direction === next.direction
2080
+ );
2081
+ MarkdownContent.displayName = "MarkdownContent";
2082
+ var CodeBlock = React113__namespace.default.memo(
2083
+ ({
2084
+ code,
2085
+ language = "text",
2086
+ showCopyButton = true,
2087
+ showLanguageBadge = true,
2088
+ maxHeight = "60vh",
2089
+ className
2090
+ }) => {
2091
+ const eventBus = useEventBus();
2092
+ const { t: _t } = useTranslate();
2093
+ const scrollRef = React113.useRef(null);
2094
+ const savedScrollLeftRef = React113.useRef(0);
2095
+ const [copied, setCopied] = React113.useState(false);
2096
+ React113.useLayoutEffect(() => {
2097
+ const el = scrollRef.current;
2098
+ return () => {
2099
+ if (el) savedScrollLeftRef.current = el.scrollLeft;
2100
+ };
2101
+ }, [language, code]);
2102
+ React113.useLayoutEffect(() => {
2103
+ const el = scrollRef.current;
2104
+ if (el) el.scrollLeft = savedScrollLeftRef.current;
2105
+ }, [language, code]);
2106
+ React113.useEffect(() => {
2107
+ const el = scrollRef.current;
2108
+ if (!el) return;
2109
+ const handle = () => {
2110
+ savedScrollLeftRef.current = el.scrollLeft;
2111
+ };
2112
+ el.addEventListener("scroll", handle, { passive: true });
2113
+ return () => el.removeEventListener("scroll", handle);
2114
+ }, [language, code]);
2115
+ const handleCopy = async () => {
2116
+ try {
2117
+ await navigator.clipboard.writeText(code);
2118
+ setCopied(true);
2119
+ eventBus.emit("UI:COPY_CODE", { language, success: true });
2120
+ setTimeout(() => setCopied(false), 2e3);
2121
+ } catch (err) {
2122
+ console.error("Failed to copy code:", err);
2123
+ eventBus.emit("UI:COPY_CODE", { language, success: false });
2124
+ }
2125
+ };
2126
+ return /* @__PURE__ */ jsxRuntime.jsxs(Box, { className: `relative group ${className || ""}`, children: [
2127
+ (showLanguageBadge || showCopyButton) && /* @__PURE__ */ jsxRuntime.jsxs(
2128
+ HStack,
2129
+ {
2130
+ justify: "between",
2131
+ align: "center",
2132
+ className: "px-3 py-2 bg-gray-800 rounded-t-lg border-b border-gray-700",
2133
+ children: [
2134
+ showLanguageBadge && /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: "default", size: "sm", children: language }),
2135
+ showCopyButton && /* @__PURE__ */ jsxRuntime.jsx(
2136
+ Button,
2137
+ {
2138
+ variant: "ghost",
2139
+ size: "sm",
2140
+ onClick: handleCopy,
2141
+ className: "opacity-0 group-hover:opacity-100 focus:opacity-100 transition-opacity text-[var(--color-muted-foreground)] hover:text-white",
2142
+ "aria-label": "Copy code",
2143
+ children: copied ? /* @__PURE__ */ jsxRuntime.jsx(LucideIcons.Check, { size: 16, className: "text-green-400" }) : /* @__PURE__ */ jsxRuntime.jsx(LucideIcons.Copy, { size: 16 })
2144
+ }
2145
+ )
2146
+ ]
2147
+ }
2148
+ ),
2149
+ /* @__PURE__ */ jsxRuntime.jsx(
2150
+ "div",
2151
+ {
2152
+ ref: scrollRef,
2153
+ style: {
2154
+ overflowX: "auto",
2155
+ overflowY: "auto",
2156
+ WebkitOverflowScrolling: "touch",
2157
+ maxHeight,
2158
+ overscrollBehavior: "auto",
2159
+ touchAction: "pan-x pan-y",
2160
+ contain: "paint",
2161
+ backgroundColor: "#1e1e1e",
2162
+ borderRadius: showLanguageBadge || showCopyButton ? "0 0 0.5rem 0.5rem" : "0.5rem",
2163
+ padding: "1rem"
2164
+ },
2165
+ children: /* @__PURE__ */ jsxRuntime.jsx(
2166
+ SyntaxHighlighter__default.default,
2167
+ {
2168
+ PreTag: "div",
2169
+ language,
2170
+ style: dark__default.default,
2171
+ customStyle: {
2172
+ backgroundColor: "transparent",
2173
+ borderRadius: 0,
2174
+ padding: 0,
2175
+ margin: 0,
2176
+ whiteSpace: "pre",
2177
+ minWidth: "100%"
2178
+ },
2179
+ children: code
2180
+ }
2181
+ )
2182
+ }
2183
+ )
2184
+ ] });
2185
+ },
2186
+ (prev, next) => prev.language === next.language && prev.code === next.code && prev.showCopyButton === next.showCopyButton && prev.maxHeight === next.maxHeight
2187
+ );
2188
+ CodeBlock.displayName = "CodeBlock";
2189
+ var Camera3D = React113.forwardRef(
2190
+ ({
2191
+ mode = "isometric",
2192
+ position = [10, 10, 10],
2193
+ target = [0, 0, 0],
2194
+ zoom = 1,
2195
+ fov = 45,
2196
+ enableOrbit = true,
2197
+ minDistance = 2,
2198
+ maxDistance = 100,
2199
+ onChange
2200
+ }, ref) => {
2201
+ const { camera, set, viewport } = fiber.useThree();
2202
+ const controlsRef = React113.useRef(null);
2203
+ const initialPosition = React113.useRef(new THREE__namespace.Vector3(...position));
2204
+ const initialTarget = React113.useRef(new THREE__namespace.Vector3(...target));
2205
+ React113.useEffect(() => {
2206
+ let newCamera;
2207
+ if (mode === "isometric") {
2208
+ const aspect = viewport.aspect;
2209
+ const size = 10 / zoom;
2210
+ newCamera = new THREE__namespace.OrthographicCamera(
2211
+ -size * aspect,
2212
+ size * aspect,
2213
+ size,
2214
+ -size,
2215
+ 0.1,
2216
+ 1e3
2217
+ );
2218
+ } else {
2219
+ newCamera = new THREE__namespace.PerspectiveCamera(fov, viewport.aspect, 0.1, 1e3);
2220
+ }
2221
+ newCamera.position.copy(initialPosition.current);
2222
+ newCamera.lookAt(initialTarget.current);
2223
+ set({ camera: newCamera });
2224
+ if (mode === "top-down") {
2225
+ newCamera.position.set(0, 20 / zoom, 0);
2226
+ newCamera.lookAt(0, 0, 0);
2227
+ }
2228
+ return () => {
2229
+ };
2230
+ }, [mode, fov, zoom, viewport.aspect, set]);
2231
+ fiber.useFrame(() => {
2232
+ if (onChange) {
2233
+ onChange(camera);
2234
+ }
2235
+ });
2236
+ React113.useImperativeHandle(ref, () => ({
2237
+ getCamera: () => camera,
2238
+ setPosition: (x, y, z) => {
2239
+ camera.position.set(x, y, z);
2240
+ if (controlsRef.current) {
2241
+ controlsRef.current.update();
2242
+ }
2243
+ },
2244
+ lookAt: (x, y, z) => {
2245
+ camera.lookAt(x, y, z);
2246
+ if (controlsRef.current) {
2247
+ controlsRef.current.target.set(x, y, z);
2248
+ controlsRef.current.update();
2249
+ }
2250
+ },
2251
+ reset: () => {
2252
+ camera.position.copy(initialPosition.current);
2253
+ camera.lookAt(initialTarget.current);
2254
+ if (controlsRef.current) {
2255
+ controlsRef.current.target.copy(initialTarget.current);
2256
+ controlsRef.current.update();
2257
+ }
2258
+ },
2259
+ getViewBounds: () => {
2260
+ const min = new THREE__namespace.Vector3(-10, -10, -10);
2261
+ const max = new THREE__namespace.Vector3(10, 10, 10);
2262
+ return { min, max };
2263
+ }
2264
+ }));
2265
+ const maxPolarAngle = mode === "top-down" ? 0.1 : Math.PI / 2 - 0.1;
2266
+ return /* @__PURE__ */ jsxRuntime.jsx(
2267
+ drei.OrbitControls,
2268
+ {
2269
+ ref: controlsRef,
2270
+ camera,
2271
+ enabled: enableOrbit,
2272
+ target: initialTarget.current,
2273
+ minDistance,
2274
+ maxDistance,
2275
+ maxPolarAngle,
2276
+ enableDamping: true,
2277
+ dampingFactor: 0.05
2278
+ }
2279
+ );
2280
+ }
2281
+ );
2282
+ Camera3D.displayName = "Camera3D";
2283
+ var Canvas3DErrorBoundary = class extends React113.Component {
2284
+ constructor(props) {
2285
+ super(props);
2286
+ __publicField(this, "handleReset", () => {
2287
+ this.setState({
2288
+ hasError: false,
2289
+ error: null,
2290
+ errorInfo: null
2291
+ });
2292
+ this.props.onReset?.();
2293
+ });
2294
+ this.state = {
2295
+ hasError: false,
2296
+ error: null,
2297
+ errorInfo: null
2298
+ };
2299
+ }
2300
+ static getDerivedStateFromError(error) {
2301
+ return {
2302
+ hasError: true,
2303
+ error,
2304
+ errorInfo: null
2305
+ };
2306
+ }
2307
+ componentDidCatch(error, errorInfo) {
2308
+ this.setState({ errorInfo });
2309
+ this.props.onError?.(error, errorInfo);
2310
+ console.error("[Canvas3DErrorBoundary] Error caught:", error);
2311
+ console.error("[Canvas3DErrorBoundary] Component stack:", errorInfo.componentStack);
2312
+ }
2313
+ render() {
2314
+ if (this.state.hasError) {
2315
+ if (this.props.fallback) {
2316
+ return this.props.fallback;
2317
+ }
2318
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "canvas-3d-error", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "canvas-3d-error__content", children: [
2319
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "canvas-3d-error__icon", children: "\u26A0\uFE0F" }),
2320
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "canvas-3d-error__title", children: "3D Scene Error" }),
2321
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "canvas-3d-error__message", children: "Something went wrong while rendering the 3D scene." }),
2322
+ this.state.error && /* @__PURE__ */ jsxRuntime.jsxs("details", { className: "canvas-3d-error__details", children: [
2323
+ /* @__PURE__ */ jsxRuntime.jsx("summary", { children: "Error Details" }),
2324
+ /* @__PURE__ */ jsxRuntime.jsxs("pre", { className: "error__stack", children: [
2325
+ this.state.error.message,
2326
+ "\n",
2327
+ this.state.error.stack
2328
+ ] }),
2329
+ this.state.errorInfo && /* @__PURE__ */ jsxRuntime.jsx("pre", { className: "error__component-stack", children: this.state.errorInfo.componentStack })
2330
+ ] }),
2331
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "canvas-3d-error__actions", children: [
2332
+ /* @__PURE__ */ jsxRuntime.jsx(
2333
+ "button",
2334
+ {
2335
+ className: "error__button error__button--primary",
2336
+ onClick: this.handleReset,
2337
+ children: "Try Again"
2338
+ }
2339
+ ),
2340
+ /* @__PURE__ */ jsxRuntime.jsx(
2341
+ "button",
2342
+ {
2343
+ className: "error__button error__button--secondary",
2344
+ onClick: () => window.location.reload(),
2345
+ children: "Reload Page"
2346
+ }
2347
+ )
2348
+ ] })
2349
+ ] }) });
2350
+ }
2351
+ return this.props.children;
2352
+ }
2353
+ };
2354
+ function Canvas3DLoadingState({
2355
+ progress = 0,
2356
+ loaded = 0,
2357
+ total = 0,
2358
+ message = "Loading 3D Scene...",
2359
+ details,
2360
+ showSpinner = true,
2361
+ className
2362
+ }) {
2363
+ const clampedProgress = Math.max(0, Math.min(100, progress));
2364
+ const hasProgress = total > 0;
2365
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `canvas-3d-loading ${className || ""}`, children: [
2366
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "canvas-3d-loading__content", children: [
2367
+ showSpinner && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "canvas-3d-loading__spinner", children: [
2368
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "spinner__ring" }),
2369
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "spinner__ring spinner__ring--secondary" })
2370
+ ] }),
2371
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "canvas-3d-loading__message", children: message }),
2372
+ details && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "canvas-3d-loading__details", children: details }),
2373
+ hasProgress && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "canvas-3d-loading__progress", children: [
2374
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "progress__bar", children: /* @__PURE__ */ jsxRuntime.jsx(
2375
+ "div",
2376
+ {
2377
+ className: "progress__fill",
2378
+ style: { width: `${clampedProgress}%` }
2379
+ }
2380
+ ) }),
2381
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "progress__text", children: [
2382
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "progress__percentage", children: [
2383
+ clampedProgress,
2384
+ "%"
2385
+ ] }),
2386
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "progress__count", children: [
2387
+ "(",
2388
+ loaded,
2389
+ "/",
2390
+ total,
2391
+ ")"
2392
+ ] })
2393
+ ] })
2394
+ ] })
2395
+ ] }),
2396
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "canvas-3d-loading__background", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "bg__grid" }) })
2397
+ ] });
2398
+ }
2399
+
2400
+ // lib/debug.ts
2401
+ typeof window !== "undefined" && (localStorage.getItem("debug") === "true" || process.env.NODE_ENV === "development");
2402
+ React113.lazy(() => import('react-markdown'));
2403
+ var GameAudioContext = React113.createContext(null);
2404
+ GameAudioContext.displayName = "GameAudioContext";
2405
+ function detectAssetRoot2(modelUrl) {
2406
+ const idx = modelUrl.indexOf("/3d/");
2407
+ if (idx !== -1) {
2408
+ return modelUrl.substring(0, idx + 4);
2409
+ }
2410
+ return modelUrl.substring(0, modelUrl.lastIndexOf("/") + 1);
2411
+ }
2412
+ function createGLTFLoaderForUrl(url) {
2413
+ const loader = new GLTFLoader_js.GLTFLoader();
2414
+ loader.setResourcePath(detectAssetRoot2(url));
2415
+ return loader;
2416
+ }
2417
+ var AssetLoader = class {
2418
+ constructor() {
2419
+ __publicField(this, "objLoader");
2420
+ __publicField(this, "textureLoader");
2421
+ __publicField(this, "modelCache");
2422
+ __publicField(this, "textureCache");
2423
+ __publicField(this, "loadingPromises");
2424
+ this.objLoader = new OBJLoader_js.OBJLoader();
2425
+ this.textureLoader = new THREE__namespace.TextureLoader();
2426
+ this.modelCache = /* @__PURE__ */ new Map();
2427
+ this.textureCache = /* @__PURE__ */ new Map();
2428
+ this.loadingPromises = /* @__PURE__ */ new Map();
2429
+ }
2430
+ /**
2431
+ * Load a GLB/GLTF model
2432
+ * @param url - URL to the .glb or .gltf file
2433
+ * @returns Promise with loaded model scene and animations
2434
+ */
2435
+ async loadModel(url) {
2436
+ if (this.modelCache.has(url)) {
2437
+ return this.modelCache.get(url);
2438
+ }
2439
+ if (this.loadingPromises.has(url)) {
2440
+ return this.loadingPromises.get(url);
2441
+ }
2442
+ const loader = createGLTFLoaderForUrl(url);
2443
+ const loadPromise = loader.loadAsync(url).then((gltf) => {
2444
+ const result = {
2445
+ scene: gltf.scene,
2446
+ animations: gltf.animations || []
2447
+ };
2448
+ this.modelCache.set(url, result);
2449
+ this.loadingPromises.delete(url);
2450
+ return result;
2451
+ }).catch((error) => {
2452
+ this.loadingPromises.delete(url);
2453
+ throw new Error(`Failed to load model ${url}: ${error.message}`);
2454
+ });
2455
+ this.loadingPromises.set(url, loadPromise);
2456
+ return loadPromise;
2457
+ }
2458
+ /**
2459
+ * Load an OBJ model (fallback for non-GLB assets)
2460
+ * @param url - URL to the .obj file
2461
+ * @returns Promise with loaded object group
2462
+ */
2463
+ async loadOBJ(url) {
2464
+ if (this.modelCache.has(url)) {
2465
+ return this.modelCache.get(url).scene;
2466
+ }
2467
+ if (this.loadingPromises.has(url)) {
2468
+ const result = await this.loadingPromises.get(url);
2469
+ return result.scene;
2470
+ }
2471
+ const loadPromise = this.objLoader.loadAsync(url).then((group) => {
2472
+ const result = {
2473
+ scene: group,
2474
+ animations: []
2475
+ };
2476
+ this.modelCache.set(url, result);
2477
+ this.loadingPromises.delete(url);
2478
+ return result;
2479
+ }).catch((error) => {
2480
+ this.loadingPromises.delete(url);
2481
+ throw new Error(`Failed to load OBJ ${url}: ${error.message}`);
2482
+ });
2483
+ this.loadingPromises.set(url, loadPromise);
2484
+ return (await loadPromise).scene;
2485
+ }
2486
+ /**
2487
+ * Load a texture
2488
+ * @param url - URL to the texture image
2489
+ * @returns Promise with loaded texture
2490
+ */
2491
+ async loadTexture(url) {
2492
+ if (this.textureCache.has(url)) {
2493
+ return this.textureCache.get(url);
2494
+ }
2495
+ if (this.loadingPromises.has(`texture:${url}`)) {
2496
+ return this.loadingPromises.get(`texture:${url}`);
2497
+ }
2498
+ const loadPromise = this.textureLoader.loadAsync(url).then((texture) => {
2499
+ texture.colorSpace = THREE__namespace.SRGBColorSpace;
2500
+ this.textureCache.set(url, texture);
2501
+ this.loadingPromises.delete(`texture:${url}`);
2502
+ return texture;
2503
+ }).catch((error) => {
2504
+ this.loadingPromises.delete(`texture:${url}`);
2505
+ throw new Error(`Failed to load texture ${url}: ${error.message}`);
2506
+ });
2507
+ this.loadingPromises.set(`texture:${url}`, loadPromise);
2508
+ return loadPromise;
2509
+ }
2510
+ /**
2511
+ * Preload multiple assets
2512
+ * @param urls - Array of asset URLs to preload
2513
+ * @returns Promise that resolves when all assets are loaded
2514
+ */
2515
+ async preload(urls) {
2516
+ const promises = urls.map((url) => {
2517
+ if (url.endsWith(".glb") || url.endsWith(".gltf")) {
2518
+ return this.loadModel(url).catch(() => null);
2519
+ } else if (url.endsWith(".obj")) {
2520
+ return this.loadOBJ(url).catch(() => null);
2521
+ } else if (/\.(png|jpg|jpeg|webp)$/i.test(url)) {
2522
+ return this.loadTexture(url).catch(() => null);
2523
+ }
2524
+ return Promise.resolve(null);
2525
+ });
2526
+ await Promise.all(promises);
2527
+ }
2528
+ /**
2529
+ * Check if a model is cached
2530
+ * @param url - Model URL
2531
+ */
2532
+ hasModel(url) {
2533
+ return this.modelCache.has(url);
2534
+ }
2535
+ /**
2536
+ * Check if a texture is cached
2537
+ * @param url - Texture URL
2538
+ */
2539
+ hasTexture(url) {
2540
+ return this.textureCache.has(url);
2541
+ }
2542
+ /**
2543
+ * Get cached model (throws if not cached)
2544
+ * @param url - Model URL
2545
+ */
2546
+ getModel(url) {
2547
+ const model = this.modelCache.get(url);
2548
+ if (!model) {
2549
+ throw new Error(`Model ${url} not in cache`);
2550
+ }
2551
+ return model;
2552
+ }
2553
+ /**
2554
+ * Get cached texture (throws if not cached)
2555
+ * @param url - Texture URL
2556
+ */
2557
+ getTexture(url) {
2558
+ const texture = this.textureCache.get(url);
2559
+ if (!texture) {
2560
+ throw new Error(`Texture ${url} not in cache`);
2561
+ }
2562
+ return texture;
2563
+ }
2564
+ /**
2565
+ * Clear all caches
2566
+ */
2567
+ clearCache() {
2568
+ this.textureCache.forEach((texture) => {
2569
+ texture.dispose();
2570
+ });
2571
+ this.modelCache.forEach((model) => {
2572
+ model.scene.traverse((child) => {
2573
+ if (child instanceof THREE__namespace.Mesh) {
2574
+ child.geometry.dispose();
2575
+ if (Array.isArray(child.material)) {
2576
+ child.material.forEach((m) => m.dispose());
2577
+ } else {
2578
+ child.material.dispose();
2579
+ }
2580
+ }
2581
+ });
2582
+ });
2583
+ this.modelCache.clear();
2584
+ this.textureCache.clear();
2585
+ this.loadingPromises.clear();
2586
+ }
2587
+ /**
2588
+ * Get cache statistics
2589
+ */
2590
+ getStats() {
2591
+ return {
2592
+ models: this.modelCache.size,
2593
+ textures: this.textureCache.size,
2594
+ loading: this.loadingPromises.size
2595
+ };
2596
+ }
2597
+ };
2598
+ new AssetLoader();
2599
+ function useAssetLoader(options = {}) {
2600
+ const { preloadUrls = [], loader: customLoader } = options;
2601
+ const loaderRef = React113.useRef(customLoader || new AssetLoader());
2602
+ const [state, setState] = React113.useState({
2603
+ isLoading: false,
2604
+ progress: 0,
2605
+ loaded: 0,
2606
+ total: 0,
2607
+ errors: []
2608
+ });
2609
+ React113.useEffect(() => {
2610
+ if (preloadUrls.length > 0) {
2611
+ preload(preloadUrls);
2612
+ }
2613
+ }, []);
2614
+ const updateProgress = React113.useCallback((loaded, total) => {
2615
+ setState((prev) => ({
2616
+ ...prev,
2617
+ loaded,
2618
+ total,
2619
+ progress: total > 0 ? Math.round(loaded / total * 100) : 0
2620
+ }));
2621
+ }, []);
2622
+ const loadModel = React113.useCallback(
2623
+ async (url) => {
2624
+ setState((prev) => ({ ...prev, isLoading: true }));
2625
+ try {
2626
+ const model = await loaderRef.current.loadModel(url);
2627
+ setState((prev) => ({
2628
+ ...prev,
2629
+ isLoading: false,
2630
+ loaded: prev.loaded + 1
2631
+ }));
2632
+ return model;
2633
+ } catch (error) {
2634
+ const errorMsg = error instanceof Error ? error.message : String(error);
2635
+ setState((prev) => ({
2636
+ ...prev,
2637
+ isLoading: false,
2638
+ errors: [...prev.errors, errorMsg]
2639
+ }));
2640
+ throw error;
2641
+ }
2642
+ },
2643
+ []
2644
+ );
2645
+ const loadOBJ = React113.useCallback(
2646
+ async (url) => {
2647
+ setState((prev) => ({ ...prev, isLoading: true }));
2648
+ try {
2649
+ const model = await loaderRef.current.loadOBJ(url);
2650
+ setState((prev) => ({
2651
+ ...prev,
2652
+ isLoading: false,
2653
+ loaded: prev.loaded + 1
2654
+ }));
2655
+ return model;
2656
+ } catch (error) {
2657
+ const errorMsg = error instanceof Error ? error.message : String(error);
2658
+ setState((prev) => ({
2659
+ ...prev,
2660
+ isLoading: false,
2661
+ errors: [...prev.errors, errorMsg]
2662
+ }));
2663
+ throw error;
2664
+ }
2665
+ },
2666
+ []
2667
+ );
2668
+ const loadTexture = React113.useCallback(
2669
+ async (url) => {
2670
+ setState((prev) => ({ ...prev, isLoading: true }));
2671
+ try {
2672
+ const texture = await loaderRef.current.loadTexture(url);
2673
+ setState((prev) => ({
2674
+ ...prev,
2675
+ isLoading: false,
2676
+ loaded: prev.loaded + 1
2677
+ }));
2678
+ return texture;
2679
+ } catch (error) {
2680
+ const errorMsg = error instanceof Error ? error.message : String(error);
2681
+ setState((prev) => ({
2682
+ ...prev,
2683
+ isLoading: false,
2684
+ errors: [...prev.errors, errorMsg]
2685
+ }));
2686
+ throw error;
2687
+ }
2688
+ },
2689
+ []
2690
+ );
2691
+ const preload = React113.useCallback(
2692
+ async (urls) => {
2693
+ setState((prev) => ({
2694
+ ...prev,
2695
+ isLoading: true,
2696
+ total: urls.length,
2697
+ loaded: 0,
2698
+ errors: []
2699
+ }));
2700
+ let completed = 0;
2701
+ const errors = [];
2702
+ await Promise.all(
2703
+ urls.map(async (url) => {
2704
+ try {
2705
+ if (url.endsWith(".glb") || url.endsWith(".gltf")) {
2706
+ await loaderRef.current.loadModel(url);
2707
+ } else if (url.endsWith(".obj")) {
2708
+ await loaderRef.current.loadOBJ(url);
2709
+ } else if (/\.(png|jpg|jpeg|webp)$/i.test(url)) {
2710
+ await loaderRef.current.loadTexture(url);
2711
+ }
2712
+ completed++;
2713
+ updateProgress(completed, urls.length);
2714
+ } catch (error) {
2715
+ const errorMsg = error instanceof Error ? error.message : String(error);
2716
+ errors.push(`${url}: ${errorMsg}`);
2717
+ completed++;
2718
+ updateProgress(completed, urls.length);
2719
+ }
2720
+ })
2721
+ );
2722
+ setState((prev) => ({
2723
+ ...prev,
2724
+ isLoading: false,
2725
+ errors
2726
+ }));
2727
+ },
2728
+ [updateProgress]
2729
+ );
2730
+ const hasModel = React113.useCallback((url) => {
2731
+ return loaderRef.current.hasModel(url);
2732
+ }, []);
2733
+ const hasTexture = React113.useCallback((url) => {
2734
+ return loaderRef.current.hasTexture(url);
2735
+ }, []);
2736
+ const getModel = React113.useCallback((url) => {
2737
+ try {
2738
+ return loaderRef.current.getModel(url);
2739
+ } catch {
2740
+ return void 0;
2741
+ }
2742
+ }, []);
2743
+ const getTexture = React113.useCallback((url) => {
2744
+ try {
2745
+ return loaderRef.current.getTexture(url);
2746
+ } catch {
2747
+ return void 0;
2748
+ }
2749
+ }, []);
2750
+ const clearCache = React113.useCallback(() => {
2751
+ loaderRef.current.clearCache();
2752
+ setState({
2753
+ isLoading: false,
2754
+ progress: 0,
2755
+ loaded: 0,
2756
+ total: 0,
2757
+ errors: []
2758
+ });
2759
+ }, []);
2760
+ return {
2761
+ ...state,
2762
+ loadModel,
2763
+ loadOBJ,
2764
+ loadTexture,
2765
+ preload,
2766
+ hasModel,
2767
+ hasTexture,
2768
+ getModel,
2769
+ getTexture,
2770
+ clearCache
2771
+ };
2772
+ }
2773
+ function useGameCanvas3DEvents(options) {
2774
+ const {
2775
+ tileClickEvent,
2776
+ unitClickEvent,
2777
+ featureClickEvent,
2778
+ canvasClickEvent,
2779
+ tileHoverEvent,
2780
+ tileLeaveEvent,
2781
+ unitAnimationEvent,
2782
+ cameraChangeEvent,
2783
+ onTileClick,
2784
+ onUnitClick,
2785
+ onFeatureClick,
2786
+ onCanvasClick,
2787
+ onTileHover,
2788
+ onUnitAnimation
2789
+ } = options;
2790
+ const emit = useEmitEvent();
2791
+ const optionsRef = React113.useRef(options);
2792
+ optionsRef.current = options;
2793
+ const handleTileClick = React113.useCallback(
2794
+ (tile, event) => {
2795
+ if (tileClickEvent) {
2796
+ emit(tileClickEvent, {
2797
+ tileId: tile.id,
2798
+ x: tile.x,
2799
+ z: tile.z ?? tile.y ?? 0,
2800
+ type: tile.type,
2801
+ terrain: tile.terrain,
2802
+ elevation: tile.elevation
2803
+ });
2804
+ }
2805
+ optionsRef.current.onTileClick?.(tile, event);
2806
+ },
2807
+ [tileClickEvent, emit]
2808
+ );
2809
+ const handleUnitClick = React113.useCallback(
2810
+ (unit, event) => {
2811
+ if (unitClickEvent) {
2812
+ emit(unitClickEvent, {
2813
+ unitId: unit.id,
2814
+ x: unit.x,
2815
+ z: unit.z ?? unit.y ?? 0,
2816
+ unitType: unit.unitType,
2817
+ name: unit.name,
2818
+ team: unit.team,
2819
+ faction: unit.faction,
2820
+ health: unit.health,
2821
+ maxHealth: unit.maxHealth
2822
+ });
2823
+ }
2824
+ optionsRef.current.onUnitClick?.(unit, event);
2825
+ },
2826
+ [unitClickEvent, emit]
2827
+ );
2828
+ const handleFeatureClick = React113.useCallback(
2829
+ (feature, event) => {
2830
+ if (featureClickEvent) {
2831
+ emit(featureClickEvent, {
2832
+ featureId: feature.id,
2833
+ x: feature.x,
2834
+ z: feature.z ?? feature.y ?? 0,
2835
+ type: feature.type,
2836
+ elevation: feature.elevation
2837
+ });
2838
+ }
2839
+ optionsRef.current.onFeatureClick?.(feature, event);
2840
+ },
2841
+ [featureClickEvent, emit]
2842
+ );
2843
+ const handleCanvasClick = React113.useCallback(
2844
+ (event) => {
2845
+ if (canvasClickEvent) {
2846
+ emit(canvasClickEvent, {
2847
+ clientX: event.clientX,
2848
+ clientY: event.clientY,
2849
+ button: event.button
2850
+ });
2851
+ }
2852
+ optionsRef.current.onCanvasClick?.(event);
2853
+ },
2854
+ [canvasClickEvent, emit]
2855
+ );
2856
+ const handleTileHover = React113.useCallback(
2857
+ (tile, event) => {
2858
+ if (tile) {
2859
+ if (tileHoverEvent) {
2860
+ emit(tileHoverEvent, {
2861
+ tileId: tile.id,
2862
+ x: tile.x,
2863
+ z: tile.z ?? tile.y ?? 0,
2864
+ type: tile.type
2865
+ });
2866
+ }
2867
+ } else {
2868
+ if (tileLeaveEvent) {
2869
+ emit(tileLeaveEvent, {});
2870
+ }
2871
+ }
2872
+ optionsRef.current.onTileHover?.(tile, event);
2873
+ },
2874
+ [tileHoverEvent, tileLeaveEvent, emit]
2875
+ );
2876
+ const handleUnitAnimation = React113.useCallback(
2877
+ (unitId, state) => {
2878
+ if (unitAnimationEvent) {
2879
+ emit(unitAnimationEvent, {
2880
+ unitId,
2881
+ state,
2882
+ timestamp: Date.now()
2883
+ });
2884
+ }
2885
+ optionsRef.current.onUnitAnimation?.(unitId, state);
2886
+ },
2887
+ [unitAnimationEvent, emit]
2888
+ );
2889
+ const handleCameraChange = React113.useCallback(
2890
+ (position) => {
2891
+ if (cameraChangeEvent) {
2892
+ emit(cameraChangeEvent, {
2893
+ position,
2894
+ timestamp: Date.now()
2895
+ });
2896
+ }
2897
+ },
2898
+ [cameraChangeEvent, emit]
2899
+ );
2900
+ return {
2901
+ handleTileClick,
2902
+ handleUnitClick,
2903
+ handleFeatureClick,
2904
+ handleCanvasClick,
2905
+ handleTileHover,
2906
+ handleUnitAnimation,
2907
+ handleCameraChange
2908
+ };
2909
+ }
2910
+ function detectAssetRoot3(modelUrl) {
2911
+ const idx = modelUrl.indexOf("/3d/");
2912
+ if (idx !== -1) {
2913
+ return modelUrl.substring(0, idx + 4);
2914
+ }
2915
+ return modelUrl.substring(0, modelUrl.lastIndexOf("/") + 1);
2916
+ }
2917
+ function useGLTFModel2(url, resourceBasePath) {
2918
+ const [state, setState] = React113.useState({
2919
+ model: null,
2920
+ isLoading: false,
2921
+ error: null
2922
+ });
2923
+ React113.useEffect(() => {
2924
+ if (!url) {
2925
+ setState({ model: null, isLoading: false, error: null });
2926
+ return;
2927
+ }
2928
+ console.log("[ModelLoader] Loading:", url);
2929
+ setState((prev) => ({ ...prev, isLoading: true, error: null }));
2930
+ const assetRoot = resourceBasePath || detectAssetRoot3(url);
2931
+ const loader = new GLTFLoader.GLTFLoader();
2932
+ loader.setResourcePath(assetRoot);
2933
+ loader.load(
2934
+ url,
2935
+ (gltf) => {
2936
+ console.log("[ModelLoader] Loaded:", url);
2937
+ setState({
2938
+ model: gltf.scene,
2939
+ isLoading: false,
2940
+ error: null
2941
+ });
2942
+ },
2943
+ void 0,
2944
+ (err) => {
2945
+ const errorMsg = err instanceof Error ? err.message : String(err);
2946
+ console.warn("[ModelLoader] Failed:", url, errorMsg);
2947
+ setState({
2948
+ model: null,
2949
+ isLoading: false,
2950
+ error: err instanceof Error ? err : new Error(String(err))
2951
+ });
2952
+ }
2953
+ );
2954
+ }, [url, resourceBasePath]);
2955
+ return state;
2956
+ }
2957
+ function ModelLoader({
2958
+ url,
2959
+ position = [0, 0, 0],
2960
+ scale = 1,
2961
+ rotation = [0, 0, 0],
2962
+ isSelected = false,
2963
+ isHovered = false,
2964
+ onClick,
2965
+ onHover,
2966
+ fallbackGeometry = "box",
2967
+ castShadow = true,
2968
+ receiveShadow = true,
2969
+ resourceBasePath
2970
+ }) {
2971
+ const { model: loadedModel, isLoading, error } = useGLTFModel2(url, resourceBasePath);
2972
+ const model = React113.useMemo(() => {
2973
+ if (!loadedModel) return null;
2974
+ const cloned = loadedModel.clone();
2975
+ cloned.traverse((child) => {
2976
+ if (child instanceof THREE__namespace.Mesh) {
2977
+ child.castShadow = castShadow;
2978
+ child.receiveShadow = receiveShadow;
2979
+ }
2980
+ });
2981
+ return cloned;
2982
+ }, [loadedModel, castShadow, receiveShadow]);
2983
+ const scaleArray = React113.useMemo(() => {
2984
+ if (typeof scale === "number") {
2985
+ return [scale, scale, scale];
2986
+ }
2987
+ return scale;
2988
+ }, [scale]);
2989
+ const rotationRad = React113.useMemo(() => {
2990
+ return [
2991
+ rotation[0] * Math.PI / 180,
2992
+ rotation[1] * Math.PI / 180,
2993
+ rotation[2] * Math.PI / 180
2994
+ ];
2995
+ }, [rotation]);
2996
+ if (isLoading) {
2997
+ return /* @__PURE__ */ jsxRuntime.jsx("group", { position, children: /* @__PURE__ */ jsxRuntime.jsxs("mesh", { rotation: [Math.PI / 2, 0, 0], children: [
2998
+ /* @__PURE__ */ jsxRuntime.jsx("ringGeometry", { args: [0.3, 0.35, 16] }),
2999
+ /* @__PURE__ */ jsxRuntime.jsx("meshBasicMaterial", { color: "#4a90d9", transparent: true, opacity: 0.8 })
3000
+ ] }) });
3001
+ }
3002
+ if (error || !model) {
3003
+ if (fallbackGeometry === "none") {
3004
+ return /* @__PURE__ */ jsxRuntime.jsx("group", { position });
3005
+ }
3006
+ const fallbackProps = {
3007
+ onClick,
3008
+ onPointerOver: () => onHover?.(true),
3009
+ onPointerOut: () => onHover?.(false)
3010
+ };
3011
+ return /* @__PURE__ */ jsxRuntime.jsxs("group", { position, children: [
3012
+ (isSelected || isHovered) && /* @__PURE__ */ jsxRuntime.jsxs("mesh", { position: [0, 0.02, 0], rotation: [-Math.PI / 2, 0, 0], children: [
3013
+ /* @__PURE__ */ jsxRuntime.jsx("ringGeometry", { args: [0.6, 0.7, 32] }),
3014
+ /* @__PURE__ */ jsxRuntime.jsx(
3015
+ "meshBasicMaterial",
3016
+ {
3017
+ color: isSelected ? 16755200 : 16777215,
3018
+ transparent: true,
3019
+ opacity: 0.5
3020
+ }
3021
+ )
3022
+ ] }),
3023
+ fallbackGeometry === "box" && /* @__PURE__ */ jsxRuntime.jsxs("mesh", { ...fallbackProps, position: [0, 0.5, 0], children: [
3024
+ /* @__PURE__ */ jsxRuntime.jsx("boxGeometry", { args: [0.8, 0.8, 0.8] }),
3025
+ /* @__PURE__ */ jsxRuntime.jsx("meshStandardMaterial", { color: error ? 16729156 : 8947848 })
3026
+ ] }),
3027
+ fallbackGeometry === "sphere" && /* @__PURE__ */ jsxRuntime.jsxs("mesh", { ...fallbackProps, position: [0, 0.5, 0], children: [
3028
+ /* @__PURE__ */ jsxRuntime.jsx("sphereGeometry", { args: [0.4, 16, 16] }),
3029
+ /* @__PURE__ */ jsxRuntime.jsx("meshStandardMaterial", { color: error ? 16729156 : 8947848 })
3030
+ ] }),
3031
+ fallbackGeometry === "cylinder" && /* @__PURE__ */ jsxRuntime.jsxs("mesh", { ...fallbackProps, position: [0, 0.5, 0], children: [
3032
+ /* @__PURE__ */ jsxRuntime.jsx("cylinderGeometry", { args: [0.3, 0.3, 0.8, 16] }),
3033
+ /* @__PURE__ */ jsxRuntime.jsx("meshStandardMaterial", { color: error ? 16729156 : 8947848 })
3034
+ ] })
3035
+ ] });
3036
+ }
3037
+ return /* @__PURE__ */ jsxRuntime.jsxs(
3038
+ "group",
3039
+ {
3040
+ position,
3041
+ rotation: rotationRad,
3042
+ onClick,
3043
+ onPointerOver: () => onHover?.(true),
3044
+ onPointerOut: () => onHover?.(false),
3045
+ children: [
3046
+ (isSelected || isHovered) && /* @__PURE__ */ jsxRuntime.jsxs("mesh", { position: [0, 0.02, 0], rotation: [-Math.PI / 2, 0, 0], children: [
3047
+ /* @__PURE__ */ jsxRuntime.jsx("ringGeometry", { args: [0.6, 0.7, 32] }),
3048
+ /* @__PURE__ */ jsxRuntime.jsx(
3049
+ "meshBasicMaterial",
3050
+ {
3051
+ color: isSelected ? 16755200 : 16777215,
3052
+ transparent: true,
3053
+ opacity: 0.5
3054
+ }
3055
+ )
3056
+ ] }),
3057
+ /* @__PURE__ */ jsxRuntime.jsx("primitive", { object: model, scale: scaleArray })
3058
+ ]
3059
+ }
3060
+ );
3061
+ }
3062
+ var DEFAULT_GRID_CONFIG = {
3063
+ cellSize: 1,
3064
+ offsetX: 0,
3065
+ offsetZ: 0
3066
+ };
3067
+ function CameraController({
3068
+ onCameraChange
3069
+ }) {
3070
+ const { camera } = fiber.useThree();
3071
+ React113.useEffect(() => {
3072
+ if (onCameraChange) {
3073
+ onCameraChange({
3074
+ x: camera.position.x,
3075
+ y: camera.position.y,
3076
+ z: camera.position.z
3077
+ });
3078
+ }
3079
+ }, [camera.position, onCameraChange]);
3080
+ return null;
3081
+ }
3082
+ var GameCanvas3D = React113.forwardRef(
3083
+ ({
3084
+ tiles = [],
3085
+ units = [],
3086
+ features = [],
3087
+ events: events2 = [],
3088
+ orientation = "standard",
3089
+ cameraMode = "isometric",
3090
+ showGrid = true,
3091
+ showCoordinates = false,
3092
+ showTileInfo = false,
3093
+ overlay = "default",
3094
+ shadows = true,
3095
+ backgroundColor = "#1a1a2e",
3096
+ onTileClick,
3097
+ onUnitClick,
3098
+ onFeatureClick,
3099
+ onCanvasClick,
3100
+ onTileHover,
3101
+ onUnitAnimation,
3102
+ assetLoader: customAssetLoader,
3103
+ tileRenderer: CustomTileRenderer,
3104
+ unitRenderer: CustomUnitRenderer,
3105
+ featureRenderer: CustomFeatureRenderer,
3106
+ className,
3107
+ isLoading: externalLoading,
3108
+ error: externalError,
3109
+ entity,
3110
+ preloadAssets = [],
3111
+ tileClickEvent,
3112
+ unitClickEvent,
3113
+ featureClickEvent,
3114
+ canvasClickEvent,
3115
+ tileHoverEvent,
3116
+ tileLeaveEvent,
3117
+ unitAnimationEvent,
3118
+ cameraChangeEvent,
3119
+ loadingMessage = "Loading 3D Scene...",
3120
+ useInstancing = true,
3121
+ validMoves = [],
3122
+ attackTargets = [],
3123
+ selectedTileIds = [],
3124
+ selectedUnitId = null,
3125
+ children
3126
+ }, ref) => {
3127
+ const containerRef = React113.useRef(null);
3128
+ const controlsRef = React113.useRef(null);
3129
+ const [hoveredTile, setHoveredTile] = React113.useState(null);
3130
+ const [internalError, setInternalError] = React113.useState(null);
3131
+ const { isLoading: assetsLoading, progress, loaded, total } = useAssetLoader({
3132
+ preloadUrls: preloadAssets,
3133
+ loader: customAssetLoader
3134
+ });
3135
+ const eventHandlers = useGameCanvas3DEvents({
3136
+ tileClickEvent,
3137
+ unitClickEvent,
3138
+ featureClickEvent,
3139
+ canvasClickEvent,
3140
+ tileHoverEvent,
3141
+ tileLeaveEvent,
3142
+ unitAnimationEvent,
3143
+ cameraChangeEvent,
3144
+ onTileClick,
3145
+ onUnitClick,
3146
+ onFeatureClick,
3147
+ onCanvasClick,
3148
+ onTileHover,
3149
+ onUnitAnimation
3150
+ });
3151
+ const gridBounds = React113.useMemo(() => {
3152
+ if (tiles.length === 0) {
3153
+ return { minX: 0, maxX: 10, minZ: 0, maxZ: 10 };
3154
+ }
3155
+ const xs = tiles.map((t) => t.x);
3156
+ const zs = tiles.map((t) => t.z || t.y || 0);
3157
+ return {
3158
+ minX: Math.min(...xs),
3159
+ maxX: Math.max(...xs),
3160
+ minZ: Math.min(...zs),
3161
+ maxZ: Math.max(...zs)
3162
+ };
3163
+ }, [tiles]);
3164
+ const cameraTarget = React113.useMemo(() => {
3165
+ return [
3166
+ (gridBounds.minX + gridBounds.maxX) / 2,
3167
+ 0,
3168
+ (gridBounds.minZ + gridBounds.maxZ) / 2
3169
+ ];
3170
+ }, [gridBounds]);
3171
+ const gridConfig = React113.useMemo(
3172
+ () => ({
3173
+ ...DEFAULT_GRID_CONFIG,
3174
+ offsetX: -(gridBounds.maxX - gridBounds.minX) / 2,
3175
+ offsetZ: -(gridBounds.maxZ - gridBounds.minZ) / 2
3176
+ }),
3177
+ [gridBounds]
3178
+ );
3179
+ const gridToWorld = React113.useCallback(
3180
+ (x, z, y = 0) => {
3181
+ const worldX = (x - gridBounds.minX) * gridConfig.cellSize;
3182
+ const worldZ = (z - gridBounds.minZ) * gridConfig.cellSize;
3183
+ return [worldX, y * gridConfig.cellSize, worldZ];
3184
+ },
3185
+ [gridBounds, gridConfig]
3186
+ );
3187
+ React113.useImperativeHandle(ref, () => ({
3188
+ getCameraPosition: () => {
3189
+ if (controlsRef.current) {
3190
+ const pos = controlsRef.current.object.position;
3191
+ return new THREE__namespace.Vector3(pos.x, pos.y, pos.z);
3192
+ }
3193
+ return null;
3194
+ },
3195
+ setCameraPosition: (x, y, z) => {
3196
+ if (controlsRef.current) {
3197
+ controlsRef.current.object.position.set(x, y, z);
3198
+ controlsRef.current.update();
3199
+ }
3200
+ },
3201
+ lookAt: (x, y, z) => {
3202
+ if (controlsRef.current) {
3203
+ controlsRef.current.target.set(x, y, z);
3204
+ controlsRef.current.update();
3205
+ }
3206
+ },
3207
+ resetCamera: () => {
3208
+ if (controlsRef.current) {
3209
+ controlsRef.current.reset();
3210
+ }
3211
+ },
3212
+ screenshot: () => {
3213
+ const canvas = containerRef.current?.querySelector("canvas");
3214
+ if (canvas) {
3215
+ return canvas.toDataURL("image/png");
3216
+ }
3217
+ return null;
3218
+ },
3219
+ export: () => ({
3220
+ tiles,
3221
+ units,
3222
+ features
3223
+ })
3224
+ }));
3225
+ const handleTileClick = React113.useCallback(
3226
+ (tile, event) => {
3227
+ eventHandlers.handleTileClick(tile, event);
3228
+ },
3229
+ [eventHandlers]
3230
+ );
3231
+ const handleUnitClick = React113.useCallback(
3232
+ (unit, event) => {
3233
+ eventHandlers.handleUnitClick(unit, event);
3234
+ },
3235
+ [eventHandlers]
3236
+ );
3237
+ const handleFeatureClick = React113.useCallback(
3238
+ (feature, event) => {
3239
+ if (event) {
3240
+ eventHandlers.handleFeatureClick(feature, event);
3241
+ }
3242
+ },
3243
+ [eventHandlers]
3244
+ );
3245
+ const handleTileHover = React113.useCallback(
3246
+ (tile, event) => {
3247
+ setHoveredTile(tile);
3248
+ if (event) {
3249
+ eventHandlers.handleTileHover(tile, event);
3250
+ }
3251
+ },
3252
+ [eventHandlers]
3253
+ );
3254
+ const cameraConfig = React113.useMemo(() => {
3255
+ const size = Math.max(
3256
+ gridBounds.maxX - gridBounds.minX,
3257
+ gridBounds.maxZ - gridBounds.minZ
3258
+ );
3259
+ const distance = size * 1.5;
3260
+ switch (cameraMode) {
3261
+ case "isometric":
3262
+ return {
3263
+ position: [distance, distance * 0.8, distance],
3264
+ fov: 45
3265
+ };
3266
+ case "top-down":
3267
+ return {
3268
+ position: [0, distance * 2, 0],
3269
+ fov: 45
3270
+ };
3271
+ case "perspective":
3272
+ default:
3273
+ return {
3274
+ position: [distance, distance, distance],
3275
+ fov: 45
3276
+ };
3277
+ }
3278
+ }, [cameraMode, gridBounds]);
3279
+ const DefaultTileRenderer = React113.useCallback(
3280
+ ({ tile, position }) => {
3281
+ const isSelected = tile.id ? selectedTileIds.includes(tile.id) : false;
3282
+ const isHovered = hoveredTile?.id === tile.id;
3283
+ const isValidMove = validMoves.some(
3284
+ (m) => m.x === tile.x && m.z === (tile.z ?? tile.y ?? 0)
3285
+ );
3286
+ const isAttackTarget = attackTargets.some(
3287
+ (m) => m.x === tile.x && m.z === (tile.z ?? tile.y ?? 0)
3288
+ );
3289
+ let color = 8421504;
3290
+ if (tile.type === "water") color = 4491468;
3291
+ else if (tile.type === "grass") color = 4500036;
3292
+ else if (tile.type === "sand") color = 14535816;
3293
+ else if (tile.type === "rock") color = 8947848;
3294
+ else if (tile.type === "snow") color = 15658734;
3295
+ let emissive = 0;
3296
+ if (isSelected) emissive = 4473924;
3297
+ else if (isAttackTarget) emissive = 4456448;
3298
+ else if (isValidMove) emissive = 17408;
3299
+ else if (isHovered) emissive = 2236962;
3300
+ return /* @__PURE__ */ jsxRuntime.jsxs(
3301
+ "mesh",
3302
+ {
3303
+ position,
3304
+ onClick: (e) => handleTileClick(tile, e),
3305
+ onPointerEnter: (e) => handleTileHover(tile, e),
3306
+ onPointerLeave: (e) => handleTileHover(null, e),
3307
+ userData: { type: "tile", tileId: tile.id, gridX: tile.x, gridZ: tile.z ?? tile.y },
3308
+ children: [
3309
+ /* @__PURE__ */ jsxRuntime.jsx("boxGeometry", { args: [0.95, 0.2, 0.95] }),
3310
+ /* @__PURE__ */ jsxRuntime.jsx("meshStandardMaterial", { color, emissive })
3311
+ ]
3312
+ }
3313
+ );
3314
+ },
3315
+ [selectedTileIds, hoveredTile, validMoves, attackTargets, handleTileClick, handleTileHover]
3316
+ );
3317
+ const DefaultUnitRenderer = React113.useCallback(
3318
+ ({ unit, position }) => {
3319
+ const isSelected = selectedUnitId === unit.id;
3320
+ const color = unit.faction === "player" ? 4491519 : unit.faction === "enemy" ? 16729156 : 16777028;
3321
+ return /* @__PURE__ */ jsxRuntime.jsxs(
3322
+ "group",
3323
+ {
3324
+ position,
3325
+ onClick: (e) => handleUnitClick(unit, e),
3326
+ userData: { type: "unit", unitId: unit.id },
3327
+ children: [
3328
+ isSelected && /* @__PURE__ */ jsxRuntime.jsxs("mesh", { position: [0, 0.05, 0], rotation: [-Math.PI / 2, 0, 0], children: [
3329
+ /* @__PURE__ */ jsxRuntime.jsx("ringGeometry", { args: [0.4, 0.5, 32] }),
3330
+ /* @__PURE__ */ jsxRuntime.jsx("meshBasicMaterial", { color: "#ffff00", transparent: true, opacity: 0.8 })
3331
+ ] }),
3332
+ /* @__PURE__ */ jsxRuntime.jsxs("mesh", { position: [0, 0.3, 0], children: [
3333
+ /* @__PURE__ */ jsxRuntime.jsx("cylinderGeometry", { args: [0.3, 0.3, 0.1, 8] }),
3334
+ /* @__PURE__ */ jsxRuntime.jsx("meshStandardMaterial", { color })
3335
+ ] }),
3336
+ /* @__PURE__ */ jsxRuntime.jsxs("mesh", { position: [0, 0.6, 0], children: [
3337
+ /* @__PURE__ */ jsxRuntime.jsx("capsuleGeometry", { args: [0.2, 0.4, 4, 8] }),
3338
+ /* @__PURE__ */ jsxRuntime.jsx("meshStandardMaterial", { color })
3339
+ ] }),
3340
+ /* @__PURE__ */ jsxRuntime.jsxs("mesh", { position: [0, 0.9, 0], children: [
3341
+ /* @__PURE__ */ jsxRuntime.jsx("sphereGeometry", { args: [0.12, 8, 8] }),
3342
+ /* @__PURE__ */ jsxRuntime.jsx("meshStandardMaterial", { color })
3343
+ ] }),
3344
+ unit.health !== void 0 && unit.maxHealth !== void 0 && /* @__PURE__ */ jsxRuntime.jsxs("group", { position: [0, 1.2, 0], children: [
3345
+ /* @__PURE__ */ jsxRuntime.jsxs("mesh", { position: [-0.25, 0, 0], children: [
3346
+ /* @__PURE__ */ jsxRuntime.jsx("planeGeometry", { args: [0.5, 0.05] }),
3347
+ /* @__PURE__ */ jsxRuntime.jsx("meshBasicMaterial", { color: 3355443 })
3348
+ ] }),
3349
+ /* @__PURE__ */ jsxRuntime.jsxs(
3350
+ "mesh",
3351
+ {
3352
+ position: [
3353
+ -0.25 + 0.5 * (unit.health / unit.maxHealth) / 2,
3354
+ 0,
3355
+ 0.01
3356
+ ],
3357
+ children: [
3358
+ /* @__PURE__ */ jsxRuntime.jsx("planeGeometry", { args: [0.5 * (unit.health / unit.maxHealth), 0.05] }),
3359
+ /* @__PURE__ */ jsxRuntime.jsx(
3360
+ "meshBasicMaterial",
3361
+ {
3362
+ color: unit.health / unit.maxHealth > 0.5 ? 4500036 : unit.health / unit.maxHealth > 0.25 ? 11184708 : 16729156
3363
+ }
3364
+ )
3365
+ ]
3366
+ }
3367
+ )
3368
+ ] })
3369
+ ]
3370
+ }
3371
+ );
3372
+ },
3373
+ [selectedUnitId, handleUnitClick]
3374
+ );
3375
+ const DefaultFeatureRenderer = React113.useCallback(
3376
+ ({
3377
+ feature,
3378
+ position
3379
+ }) => {
3380
+ if (feature.assetUrl) {
3381
+ return /* @__PURE__ */ jsxRuntime.jsx(
3382
+ ModelLoader,
3383
+ {
3384
+ url: feature.assetUrl,
3385
+ position,
3386
+ scale: 0.5,
3387
+ rotation: [0, feature.rotation ?? 0, 0],
3388
+ onClick: () => handleFeatureClick(feature, null),
3389
+ fallbackGeometry: "box"
3390
+ },
3391
+ feature.id
3392
+ );
3393
+ }
3394
+ if (feature.type === "tree") {
3395
+ return /* @__PURE__ */ jsxRuntime.jsxs(
3396
+ "group",
3397
+ {
3398
+ position,
3399
+ onClick: (e) => handleFeatureClick(feature, e),
3400
+ userData: { type: "feature", featureId: feature.id },
3401
+ children: [
3402
+ /* @__PURE__ */ jsxRuntime.jsxs("mesh", { position: [0, 0.4, 0], children: [
3403
+ /* @__PURE__ */ jsxRuntime.jsx("cylinderGeometry", { args: [0.1, 0.15, 0.8, 6] }),
3404
+ /* @__PURE__ */ jsxRuntime.jsx("meshStandardMaterial", { color: 9127187 })
3405
+ ] }),
3406
+ /* @__PURE__ */ jsxRuntime.jsxs("mesh", { position: [0, 0.9, 0], children: [
3407
+ /* @__PURE__ */ jsxRuntime.jsx("coneGeometry", { args: [0.5, 0.8, 8] }),
3408
+ /* @__PURE__ */ jsxRuntime.jsx("meshStandardMaterial", { color: 2263842 })
3409
+ ] })
3410
+ ]
3411
+ }
3412
+ );
3413
+ }
3414
+ if (feature.type === "rock") {
3415
+ return /* @__PURE__ */ jsxRuntime.jsxs(
3416
+ "mesh",
3417
+ {
3418
+ position: [position[0], position[1] + 0.3, position[2]],
3419
+ onClick: (e) => handleFeatureClick(feature, e),
3420
+ userData: { type: "feature", featureId: feature.id },
3421
+ children: [
3422
+ /* @__PURE__ */ jsxRuntime.jsx("dodecahedronGeometry", { args: [0.3, 0] }),
3423
+ /* @__PURE__ */ jsxRuntime.jsx("meshStandardMaterial", { color: 8421504 })
3424
+ ]
3425
+ }
3426
+ );
3427
+ }
3428
+ return null;
3429
+ },
3430
+ [handleFeatureClick]
3431
+ );
3432
+ if (externalLoading || assetsLoading && preloadAssets.length > 0) {
3433
+ return /* @__PURE__ */ jsxRuntime.jsx(
3434
+ Canvas3DLoadingState,
3435
+ {
3436
+ progress,
3437
+ loaded,
3438
+ total,
3439
+ message: loadingMessage,
3440
+ className
3441
+ }
3442
+ );
3443
+ }
3444
+ const displayError = externalError || internalError;
3445
+ if (displayError) {
3446
+ return /* @__PURE__ */ jsxRuntime.jsx(Canvas3DErrorBoundary, { children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "game-canvas-3d game-canvas-3d--error", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "game-canvas-3d__error", children: [
3447
+ "Error: ",
3448
+ displayError
3449
+ ] }) }) });
3450
+ }
3451
+ return /* @__PURE__ */ jsxRuntime.jsx(
3452
+ Canvas3DErrorBoundary,
3453
+ {
3454
+ onError: (err) => setInternalError(err.message),
3455
+ onReset: () => setInternalError(null),
3456
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
3457
+ "div",
3458
+ {
3459
+ ref: containerRef,
3460
+ className: `game-canvas-3d ${className || ""}`,
3461
+ "data-orientation": orientation,
3462
+ "data-camera-mode": cameraMode,
3463
+ "data-overlay": overlay,
3464
+ children: [
3465
+ /* @__PURE__ */ jsxRuntime.jsxs(
3466
+ fiber.Canvas,
3467
+ {
3468
+ shadows,
3469
+ camera: {
3470
+ position: cameraConfig.position,
3471
+ fov: cameraConfig.fov,
3472
+ near: 0.1,
3473
+ far: 1e3
3474
+ },
3475
+ style: { background: backgroundColor },
3476
+ onClick: (e) => {
3477
+ if (e.target === e.currentTarget) {
3478
+ eventHandlers.handleCanvasClick(e);
3479
+ }
3480
+ },
3481
+ children: [
3482
+ /* @__PURE__ */ jsxRuntime.jsx(CameraController, { onCameraChange: eventHandlers.handleCameraChange }),
3483
+ /* @__PURE__ */ jsxRuntime.jsx("ambientLight", { intensity: 0.6 }),
3484
+ /* @__PURE__ */ jsxRuntime.jsx(
3485
+ "directionalLight",
3486
+ {
3487
+ position: [10, 20, 10],
3488
+ intensity: 0.8,
3489
+ castShadow: shadows,
3490
+ "shadow-mapSize": [2048, 2048]
3491
+ }
3492
+ ),
3493
+ /* @__PURE__ */ jsxRuntime.jsx("hemisphereLight", { intensity: 0.3, color: "#87ceeb", groundColor: "#362d1d" }),
3494
+ showGrid && /* @__PURE__ */ jsxRuntime.jsx(
3495
+ drei.Grid,
3496
+ {
3497
+ args: [
3498
+ Math.max(gridBounds.maxX - gridBounds.minX + 2, 10),
3499
+ Math.max(gridBounds.maxZ - gridBounds.minZ + 2, 10)
3500
+ ],
3501
+ position: [
3502
+ (gridBounds.maxX - gridBounds.minX) / 2 - 0.5,
3503
+ 0,
3504
+ (gridBounds.maxZ - gridBounds.minZ) / 2 - 0.5
3505
+ ],
3506
+ cellSize: 1,
3507
+ cellThickness: 1,
3508
+ cellColor: "#444444",
3509
+ sectionSize: 5,
3510
+ sectionThickness: 1.5,
3511
+ sectionColor: "#666666",
3512
+ fadeDistance: 50,
3513
+ fadeStrength: 1
3514
+ }
3515
+ ),
3516
+ tiles.map((tile, index) => {
3517
+ const position = gridToWorld(
3518
+ tile.x,
3519
+ tile.z ?? tile.y ?? 0,
3520
+ tile.elevation ?? 0
3521
+ );
3522
+ const Renderer = CustomTileRenderer || DefaultTileRenderer;
3523
+ return /* @__PURE__ */ jsxRuntime.jsx(Renderer, { tile, position }, tile.id ?? `tile-${index}`);
3524
+ }),
3525
+ features.map((feature, index) => {
3526
+ const position = gridToWorld(
3527
+ feature.x,
3528
+ feature.z ?? feature.y ?? 0,
3529
+ (feature.elevation ?? 0) + 0.5
3530
+ );
3531
+ const Renderer = CustomFeatureRenderer || DefaultFeatureRenderer;
3532
+ return /* @__PURE__ */ jsxRuntime.jsx(Renderer, { feature, position }, feature.id ?? `feature-${index}`);
3533
+ }),
3534
+ units.map((unit) => {
3535
+ const position = gridToWorld(
3536
+ unit.x ?? 0,
3537
+ unit.z ?? unit.y ?? 0,
3538
+ (unit.elevation ?? 0) + 0.5
3539
+ );
3540
+ const Renderer = CustomUnitRenderer || DefaultUnitRenderer;
3541
+ return /* @__PURE__ */ jsxRuntime.jsx(Renderer, { unit, position }, unit.id);
3542
+ }),
3543
+ children,
3544
+ /* @__PURE__ */ jsxRuntime.jsx(
3545
+ drei.OrbitControls,
3546
+ {
3547
+ ref: controlsRef,
3548
+ target: cameraTarget,
3549
+ enableDamping: true,
3550
+ dampingFactor: 0.05,
3551
+ minDistance: 2,
3552
+ maxDistance: 100,
3553
+ maxPolarAngle: Math.PI / 2 - 0.1
3554
+ }
3555
+ )
3556
+ ]
3557
+ }
3558
+ ),
3559
+ showCoordinates && hoveredTile && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "game-canvas-3d__coordinates", children: [
3560
+ "X: ",
3561
+ hoveredTile.x,
3562
+ ", Z: ",
3563
+ hoveredTile.z ?? hoveredTile.y ?? 0
3564
+ ] }),
3565
+ showTileInfo && hoveredTile && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "game-canvas-3d__tile-info", children: [
3566
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "tile-info__type", children: hoveredTile.type }),
3567
+ hoveredTile.terrain && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "tile-info__terrain", children: hoveredTile.terrain })
3568
+ ] })
3569
+ ]
3570
+ }
3571
+ )
3572
+ }
3573
+ );
3574
+ }
3575
+ );
3576
+ GameCanvas3D.displayName = "GameCanvas3D";
3577
+
3578
+ // lib/traitRegistry.ts
3579
+ var traits = /* @__PURE__ */ new Map();
3580
+ var listeners2 = /* @__PURE__ */ new Set();
3581
+ function notifyListeners2() {
3582
+ listeners2.forEach((listener) => listener());
3583
+ }
3584
+ function registerTrait(info) {
3585
+ traits.set(info.id, info);
3586
+ notifyListeners2();
3587
+ }
3588
+ function updateTraitState(id, newState) {
3589
+ const trait = traits.get(id);
3590
+ if (trait) {
3591
+ trait.currentState = newState;
3592
+ trait.transitionCount++;
3593
+ notifyListeners2();
3594
+ }
3595
+ }
3596
+ function unregisterTrait(id) {
3597
+ traits.delete(id);
3598
+ notifyListeners2();
3599
+ }
3600
+ React113.createContext({ enabled: false });
3601
+ React113.createContext(false);
3602
+ React113.createContext(null);
3603
+
3604
+ // runtime/createClientEffectHandlers.ts
3605
+ function createClientEffectHandlers(options) {
3606
+ const { eventBus, slotSetter, navigate, notify, enrichPattern } = options;
3607
+ return {
3608
+ emit: (event, payload) => {
3609
+ const prefixedEvent = event.startsWith("UI:") ? event : `UI:${event}`;
3610
+ eventBus.emit(prefixedEvent, { payload });
3611
+ },
3612
+ persist: async () => {
3613
+ console.warn("[ClientEffectHandlers] persist is server-side only, ignored on client");
3614
+ },
3615
+ set: () => {
3616
+ console.warn("[ClientEffectHandlers] set is server-side only, ignored on client");
3617
+ },
3618
+ callService: async () => {
3619
+ console.warn("[ClientEffectHandlers] callService is server-side only, ignored on client");
3620
+ return {};
3621
+ },
3622
+ renderUI: (slot, pattern, props) => {
3623
+ if (pattern === null) {
3624
+ slotSetter.clearSlot(slot);
3625
+ return;
3626
+ }
3627
+ const enriched = enrichPattern ? enrichPattern(pattern) : pattern;
3628
+ slotSetter.addPattern(slot, enriched, props);
3629
+ },
3630
+ navigate: navigate ?? ((path) => {
3631
+ console.warn("[ClientEffectHandlers] No navigate handler, ignoring:", path);
3632
+ }),
3633
+ notify: notify ?? ((msg, type) => {
3634
+ console.log(`[ClientEffectHandlers] notify (${type}):`, msg);
3635
+ })
3636
+ };
3637
+ }
3638
+ var EntitySchemaContext = React113.createContext(null);
3639
+ function EntitySchemaProvider({
3640
+ entities,
3641
+ children
3642
+ }) {
3643
+ const entitiesMap = React113.useMemo(() => {
3644
+ const map = /* @__PURE__ */ new Map();
3645
+ for (const entity of entities) {
3646
+ map.set(entity.name, entity);
3647
+ }
3648
+ return map;
3649
+ }, [entities]);
3650
+ const contextValue = React113.useMemo(
3651
+ () => ({
3652
+ entities: entitiesMap
3653
+ }),
3654
+ [entitiesMap]
3655
+ );
3656
+ return /* @__PURE__ */ jsxRuntime.jsx(EntitySchemaContext.Provider, { value: contextValue, children });
3657
+ }
3658
+ function useEntitySchema() {
3659
+ const context = React113.useContext(EntitySchemaContext);
3660
+ if (!context) {
3661
+ throw new Error("useEntitySchema must be used within an EntitySchemaProvider");
3662
+ }
3663
+ return context;
3664
+ }
3665
+ function useEntityDefinition(entityName) {
3666
+ const { entities } = useEntitySchema();
3667
+ return entities.get(entityName);
3668
+ }
3669
+
3670
+ // runtime/useTraitStateMachine.ts
3671
+ function toTraitDefinition(binding) {
3672
+ return {
3673
+ name: binding.trait.name,
3674
+ states: binding.trait.states,
3675
+ transitions: binding.trait.transitions,
3676
+ listens: binding.trait.listens
3677
+ };
3678
+ }
3679
+ function normalizeEventKey(eventKey) {
3680
+ return eventKey.startsWith("UI:") ? eventKey.slice(3) : eventKey;
3681
+ }
3682
+ function useTraitStateMachine(traitBindings, slotsActions, options) {
3683
+ const eventBus = useEventBus();
3684
+ const { entities } = useEntitySchema();
3685
+ const fetchedDataContext = useFetchedDataContext();
3686
+ const manager = React113.useMemo(() => {
3687
+ const traitDefs = traitBindings.map(toTraitDefinition);
3688
+ return new runtime.StateMachineManager(traitDefs);
3689
+ }, [traitBindings]);
3690
+ const [traitStates, setTraitStates] = React113.useState(() => {
3691
+ return manager.getAllStates();
3692
+ });
3693
+ const eventQueueRef = React113.useRef([]);
3694
+ const processingRef = React113.useRef(false);
3695
+ const traitBindingsRef = React113.useRef(traitBindings);
3696
+ const managerRef = React113.useRef(manager);
3697
+ const slotsActionsRef = React113.useRef(slotsActions);
3698
+ const optionsRef = React113.useRef(options);
3699
+ React113.useEffect(() => {
3700
+ traitBindingsRef.current = traitBindings;
3701
+ }, [traitBindings]);
3702
+ React113.useEffect(() => {
3703
+ managerRef.current = manager;
3704
+ setTraitStates(manager.getAllStates());
3705
+ }, [manager]);
3706
+ React113.useEffect(() => {
3707
+ slotsActionsRef.current = slotsActions;
3708
+ }, [slotsActions]);
3709
+ React113.useEffect(() => {
3710
+ optionsRef.current = options;
3711
+ }, [options]);
3712
+ const traitStatesRef = React113.useRef(traitStates);
3713
+ const fetchedDataContextRef = React113.useRef(fetchedDataContext);
3714
+ React113.useEffect(() => {
3715
+ traitStatesRef.current = traitStates;
3716
+ }, [traitStates]);
3717
+ React113.useEffect(() => {
3718
+ fetchedDataContextRef.current = fetchedDataContext;
3719
+ }, [fetchedDataContext]);
3720
+ React113.useEffect(() => {
3721
+ const mgr = managerRef.current;
3722
+ const bindings = traitBindingsRef.current;
3723
+ const ids = [];
3724
+ for (const binding of bindings) {
3725
+ const trait = binding.trait;
3726
+ const state = mgr.getState(trait.name);
3727
+ const info = {
3728
+ id: trait.name,
3729
+ name: trait.name,
3730
+ currentState: state?.currentState ?? trait.states[0]?.name ?? "unknown",
3731
+ states: trait.states.map((s) => s.name),
3732
+ transitions: trait.transitions.flatMap((t) => {
3733
+ const froms = Array.isArray(t.from) ? t.from : [t.from];
3734
+ return froms.map((f) => ({
3735
+ from: f,
3736
+ to: t.to,
3737
+ event: t.event,
3738
+ guard: t.guard ? String(t.guard) : void 0
3739
+ }));
3740
+ }),
3741
+ guards: trait.transitions.filter((t) => t.guard).map((t) => ({ name: String(t.guard) })),
3742
+ transitionCount: 0
3743
+ };
3744
+ registerTrait(info);
3745
+ ids.push(trait.name);
3746
+ }
3747
+ return () => {
3748
+ for (const id of ids) {
3749
+ unregisterTrait(id);
3750
+ }
3751
+ };
3752
+ }, [traitBindings]);
3753
+ React113.useEffect(() => {
3754
+ const newManager = managerRef.current;
3755
+ newManager.resetAll();
3756
+ setTraitStates(newManager.getAllStates());
3757
+ console.log(
3758
+ "[TraitStateMachine] Reset states for page navigation:",
3759
+ Array.from(newManager.getAllStates().keys()).join(", ")
3760
+ );
3761
+ }, [traitBindings]);
3762
+ const runTickEffects = React113.useCallback((tick, binding) => {
3763
+ const fdc = fetchedDataContextRef.current;
3764
+ const actions = slotsActionsRef.current;
3765
+ const linkedEntity = binding.linkedEntity ?? "";
3766
+ const currentState = traitStatesRef.current.get(binding.trait.name)?.currentState ?? "";
3767
+ if (tick.appliesTo.length > 0 && !tick.appliesTo.includes(currentState)) return;
3768
+ const records = linkedEntity && fdc ? fdc.getData(linkedEntity) : [];
3769
+ const entityData = records.length > 0 ? Object.assign([...records], records[0]) : {};
3770
+ const bindingCtx = { entity: entityData, payload: {}, state: currentState };
3771
+ const evalCtx = runtime.createContextFromBindings(bindingCtx);
3772
+ if (tick.guard !== void 0) {
3773
+ const passed = runtime.interpolateValue(tick.guard, evalCtx);
3774
+ if (!passed) return;
3775
+ }
3776
+ const entityMutations = /* @__PURE__ */ new Map();
3777
+ const pendingSlots = /* @__PURE__ */ new Map();
3778
+ const slotSource = {
3779
+ trait: binding.trait.name,
3780
+ state: currentState,
3781
+ transition: `${currentState}->tick:${tick.name}`,
3782
+ effects: tick.effects,
3783
+ traitDefinition: binding.trait
3784
+ };
3785
+ const enrichTickNode = (node) => {
3786
+ if (!node || typeof node !== "object") return node;
3787
+ const rec = node;
3788
+ const nodeType = rec.type;
3789
+ let enriched = rec;
3790
+ if (Array.isArray(rec.children)) {
3791
+ enriched = { ...rec, children: rec.children.map(enrichTickNode) };
3792
+ }
3793
+ if (nodeType && patterns.isEntityAwarePattern(nodeType) && fdc) {
3794
+ let injected = false;
3795
+ if (typeof enriched.entity === "string") {
3796
+ const entityRecords = fdc.getData(enriched.entity);
3797
+ if (entityRecords.length > 0) {
3798
+ enriched = { ...enriched, entity: entityRecords };
3799
+ injected = true;
3800
+ }
3801
+ } else if (!enriched.entity && linkedEntity) {
3802
+ const entityRecords = fdc.getData(linkedEntity);
3803
+ if (entityRecords.length > 0) {
3804
+ enriched = { ...enriched, entity: entityRecords };
3805
+ injected = true;
3806
+ }
3807
+ }
3808
+ if (injected && !enriched.fields && !enriched.columns) {
3809
+ const sample = enriched.entity[0];
3810
+ if (sample && typeof sample === "object") {
3811
+ const keys = Object.keys(sample).filter((k) => k !== "id" && k !== "_id");
3812
+ enriched = { ...enriched, fields: keys.map((k, i) => ({ name: k, variant: i === 0 ? "h4" : "body" })), children: void 0 };
3813
+ }
3814
+ }
3815
+ }
3816
+ return enriched;
3817
+ };
3818
+ for (const effect of tick.effects) {
3819
+ if (!Array.isArray(effect)) continue;
3820
+ const op = effect[0];
3821
+ if (op === "set") {
3822
+ const path = effect[1];
3823
+ if (typeof path !== "string" || !path.startsWith("@entity.")) continue;
3824
+ const field = path.slice("@entity.".length);
3825
+ const updatedCtx = runtime.createContextFromBindings(bindingCtx);
3826
+ const value = runtime.interpolateValue(effect[2], updatedCtx);
3827
+ bindingCtx.entity[field] = value;
3828
+ entityMutations.set(field, value);
3829
+ } else if (op === "render-ui" || op === "render") {
3830
+ const slot = effect[1];
3831
+ const rawPattern = effect[2];
3832
+ if (rawPattern === null || rawPattern === void 0) {
3833
+ pendingSlots.set(slot, []);
3834
+ continue;
3835
+ }
3836
+ const updatedCtx = runtime.createContextFromBindings(bindingCtx);
3837
+ const resolved = runtime.interpolateValue(rawPattern, updatedCtx);
3838
+ const enriched = enrichTickNode(resolved);
3839
+ const existing = pendingSlots.get(slot) ?? [];
3840
+ existing.push({ pattern: enriched, props: {} });
3841
+ pendingSlots.set(slot, existing);
3842
+ }
3843
+ }
3844
+ for (const [slot, patterns] of pendingSlots) {
3845
+ if (patterns.length === 0) {
3846
+ actions.clearSlot(slot);
3847
+ } else {
3848
+ actions.setSlotPatterns(slot, patterns, slotSource);
3849
+ }
3850
+ }
3851
+ if (linkedEntity && entityMutations.size > 0 && fdc) {
3852
+ const latestRecords = fdc.getData(linkedEntity);
3853
+ if (latestRecords.length > 0) {
3854
+ const updated = latestRecords.map(
3855
+ (r, i) => i === 0 ? { ...r, ...Object.fromEntries(entityMutations) } : r
3856
+ );
3857
+ fdc.setData({ [linkedEntity]: updated });
3858
+ }
3859
+ }
3860
+ }, []);
3861
+ React113.useEffect(() => {
3862
+ const hasFrameTicks = traitBindingsRef.current.some(
3863
+ (b) => b.trait.ticks?.some((t) => t.interval === "frame")
3864
+ );
3865
+ if (!hasFrameTicks) return;
3866
+ let running = true;
3867
+ let rafId = 0;
3868
+ const frame = () => {
3869
+ if (!running) return;
3870
+ for (const binding of traitBindingsRef.current) {
3871
+ for (const tick of binding.trait.ticks ?? []) {
3872
+ if (tick.interval !== "frame") continue;
3873
+ runTickEffects(tick, binding);
3874
+ }
3875
+ }
3876
+ rafId = requestAnimationFrame(frame);
3877
+ };
3878
+ rafId = requestAnimationFrame(frame);
3879
+ return () => {
3880
+ running = false;
3881
+ cancelAnimationFrame(rafId);
3882
+ };
3883
+ }, [traitBindings, runTickEffects]);
3884
+ React113.useEffect(() => {
3885
+ const intervals = [];
3886
+ for (const binding of traitBindings) {
3887
+ for (const tick of binding.trait.ticks ?? []) {
3888
+ if (tick.interval === "frame") continue;
3889
+ const ms = tick.interval;
3890
+ intervals.push(setInterval(() => {
3891
+ runTickEffects(tick, binding);
3892
+ }, ms));
3893
+ }
3894
+ }
3895
+ return () => {
3896
+ for (const id of intervals) clearInterval(id);
3897
+ };
3898
+ }, [traitBindings, runTickEffects]);
3899
+ const processEventQueued = React113.useCallback(async (eventKey, payload) => {
3900
+ const normalizedEvent = normalizeEventKey(eventKey);
3901
+ const bindings = traitBindingsRef.current;
3902
+ const currentManager = managerRef.current;
3903
+ const actions = slotsActionsRef.current;
3904
+ console.log("[TraitStateMachine] Processing event:", normalizedEvent, "payload:", payload);
3905
+ const bindingMap = new Map(bindings.map((b) => [b.trait.name, b]));
3906
+ const results = currentManager.sendEvent(normalizedEvent, payload);
3907
+ for (const { traitName, result } of results) {
3908
+ const binding = bindingMap.get(traitName);
3909
+ const traitState = currentManager.getState(traitName);
3910
+ if (!binding || !traitState) continue;
3911
+ if (result.executed && result.effects.length > 0) {
3912
+ console.log(
3913
+ "[TraitStateMachine] Executing",
3914
+ result.effects.length,
3915
+ "effects for",
3916
+ traitName,
3917
+ "| linkedEntity:",
3918
+ binding.linkedEntity,
3919
+ "| transition:",
3920
+ `${result.previousState} -> ${result.newState}`,
3921
+ "| effects:",
3922
+ JSON.stringify(result.effects)
3923
+ );
3924
+ const linkedEntity = binding.linkedEntity || "";
3925
+ const entityId = payload?.entityId;
3926
+ const entityData = (() => {
3927
+ if (!linkedEntity || !fetchedDataContext) return payload || {};
3928
+ if (entityId) {
3929
+ return fetchedDataContext.getById(linkedEntity, entityId) || {};
3930
+ }
3931
+ const records = fetchedDataContext.getData(linkedEntity);
3932
+ if (records.length === 0) return payload || {};
3933
+ const firstRecord = records[0];
3934
+ return Object.assign([...records], firstRecord);
3935
+ })();
3936
+ const pendingSlots = /* @__PURE__ */ new Map();
3937
+ const slotSource = {
3938
+ trait: binding.trait.name,
3939
+ state: result.previousState,
3940
+ transition: `${result.previousState}->${result.newState}`,
3941
+ effects: result.effects,
3942
+ traitDefinition: binding.trait
3943
+ };
3944
+ const handlers = createClientEffectHandlers({
3945
+ eventBus,
3946
+ slotSetter: {
3947
+ addPattern: (slot, pattern, props) => {
3948
+ const existing = pendingSlots.get(slot) || [];
3949
+ existing.push({ pattern, props: props || {} });
3950
+ pendingSlots.set(slot, existing);
3951
+ },
3952
+ clearSlot: (slot) => {
3953
+ pendingSlots.set(slot, []);
3954
+ }
3955
+ },
3956
+ navigate: optionsRef.current?.navigate,
3957
+ notify: optionsRef.current?.notify,
3958
+ enrichPattern: (pattern) => {
3959
+ const enrichNode = (node) => {
3960
+ if (!node || typeof node !== "object") return node;
3961
+ const rec = node;
3962
+ const nodeType = rec.type;
3963
+ let enriched = rec;
3964
+ if (Array.isArray(rec.children)) {
3965
+ const enrichedChildren = rec.children.map(enrichNode);
3966
+ enriched = { ...rec, children: enrichedChildren };
3967
+ }
3968
+ if (nodeType && patterns.isEntityAwarePattern(nodeType) && fetchedDataContext) {
3969
+ let injected = false;
3970
+ if (typeof enriched.entity === "string") {
3971
+ const records = fetchedDataContext.getData(enriched.entity);
3972
+ if (records.length > 0) {
3973
+ enriched = { ...enriched, entity: records };
3974
+ injected = true;
3975
+ }
3976
+ } else if (!enriched.entity && linkedEntity) {
3977
+ const records = fetchedDataContext.getData(linkedEntity);
3978
+ if (records.length > 0) {
3979
+ enriched = { ...enriched, entity: records };
3980
+ injected = true;
3981
+ }
3982
+ }
3983
+ if (injected && !enriched.fields && !enriched.columns) {
3984
+ const sample = enriched.entity[0];
3985
+ if (sample && typeof sample === "object") {
3986
+ const keys = Object.keys(sample).filter((k) => k !== "id" && k !== "_id");
3987
+ enriched = {
3988
+ ...enriched,
3989
+ fields: keys.map((k, i) => ({
3990
+ name: k,
3991
+ variant: i === 0 ? "h4" : "body"
3992
+ })),
3993
+ // Remove pattern-config children that components
3994
+ // can't render (they expect a function or nothing)
3995
+ children: void 0
3996
+ };
3997
+ }
3998
+ }
3999
+ }
4000
+ return enriched;
4001
+ };
4002
+ return enrichNode(pattern);
4003
+ }
4004
+ });
4005
+ const bindingCtx = {
4006
+ entity: entityData,
4007
+ payload: payload || {},
4008
+ state: result.previousState
4009
+ };
4010
+ const entityMutations = /* @__PURE__ */ new Map();
4011
+ for (const effect of result.effects) {
4012
+ if (!Array.isArray(effect) || effect[0] !== "set") continue;
4013
+ const path = effect[1];
4014
+ if (typeof path !== "string" || !path.startsWith("@entity.")) continue;
4015
+ const field = path.slice("@entity.".length);
4016
+ const evalCtx = runtime.createContextFromBindings(bindingCtx);
4017
+ const value = runtime.interpolateValue(effect[2], evalCtx);
4018
+ if (bindingCtx.entity !== null && typeof bindingCtx.entity === "object") {
4019
+ bindingCtx.entity[field] = value;
4020
+ }
4021
+ entityMutations.set(field, value);
4022
+ }
4023
+ const effectContext = {
4024
+ traitName: binding.trait.name,
4025
+ state: result.previousState,
4026
+ transition: `${result.previousState}->${result.newState}`,
4027
+ linkedEntity,
4028
+ entityId
4029
+ };
4030
+ const executor = new runtime.EffectExecutor({ handlers, bindings: bindingCtx, context: effectContext });
4031
+ try {
4032
+ await executor.executeAll(result.effects);
4033
+ console.log(
4034
+ "[TraitStateMachine] After executeAll, pendingSlots:",
4035
+ Object.fromEntries(pendingSlots.entries())
4036
+ );
4037
+ for (const [slot, patterns] of pendingSlots) {
4038
+ if (patterns.length === 0) {
4039
+ actions.clearSlot(slot);
4040
+ } else {
4041
+ actions.setSlotPatterns(slot, patterns, slotSource);
4042
+ }
4043
+ }
4044
+ if (linkedEntity && entityMutations.size > 0 && fetchedDataContext) {
4045
+ const records = fetchedDataContext.getData(linkedEntity);
4046
+ if (records.length > 0) {
4047
+ const updated = records.map(
4048
+ (r, i) => i === 0 ? { ...r, ...Object.fromEntries(entityMutations) } : r
4049
+ );
4050
+ fetchedDataContext.setData({ [linkedEntity]: updated });
4051
+ }
4052
+ }
4053
+ if (fetchedDataContext) {
4054
+ for (const effect of result.effects) {
4055
+ if (!Array.isArray(effect) || effect[0] !== "persist") continue;
4056
+ const action = effect[1];
4057
+ const entityType = effect[2] || linkedEntity;
4058
+ if (!entityType) continue;
4059
+ const records = fetchedDataContext.getData(entityType);
4060
+ if (action === "create") {
4061
+ const evalCtx = runtime.createContextFromBindings(bindingCtx);
4062
+ const rawData = effect[3];
4063
+ const newRecord = { id: `${entityType}-${Date.now()}` };
4064
+ if (rawData) {
4065
+ for (const [k, v] of Object.entries(rawData)) {
4066
+ newRecord[k] = runtime.interpolateValue(v, evalCtx);
4067
+ }
4068
+ }
4069
+ for (const [k, v] of entityMutations) {
4070
+ newRecord[k] = v;
4071
+ }
4072
+ fetchedDataContext.setData({ [entityType]: [...records, newRecord] });
4073
+ } else if (action === "delete") {
4074
+ const deleteId = effect[3];
4075
+ if (deleteId) {
4076
+ const filtered = records.filter((r) => r.id !== deleteId);
4077
+ fetchedDataContext.setData({ [entityType]: filtered });
4078
+ }
4079
+ } else if (action === "update") {
4080
+ const updateId = effect[3];
4081
+ const updateData = effect[4];
4082
+ if (updateId && updateData) {
4083
+ const evalCtx = runtime.createContextFromBindings(bindingCtx);
4084
+ const updated = records.map((r) => {
4085
+ if (r.id !== updateId) return r;
4086
+ const patched = { ...r };
4087
+ for (const [k, v] of Object.entries(updateData)) {
4088
+ patched[k] = runtime.interpolateValue(v, evalCtx);
4089
+ }
4090
+ return patched;
4091
+ });
4092
+ fetchedDataContext.setData({ [entityType]: updated });
4093
+ }
4094
+ }
4095
+ }
4096
+ }
4097
+ } catch (error) {
4098
+ console.error(
4099
+ "[TraitStateMachine] Effect execution error:",
4100
+ error,
4101
+ "| effects:",
4102
+ JSON.stringify(result.effects)
4103
+ );
4104
+ }
4105
+ } else if (!result.executed) {
4106
+ if (result.guardResult === false) {
4107
+ console.log(
4108
+ "[TraitStateMachine] Guard blocked transition:",
4109
+ traitName,
4110
+ result.previousState,
4111
+ "->",
4112
+ result.transition?.to
4113
+ );
4114
+ } else if (!result.transition) {
4115
+ if (core.isCircuitEvent(normalizedEvent)) {
4116
+ console.warn(
4117
+ `[CLOSED CIRCUIT VIOLATION] Trait "${traitName}" in state "${traitState.currentState}" received event "${normalizedEvent}" but has no transition to handle it.
4118
+ This is likely a schema issue. To fix, add a transition:
4119
+ { from: "${traitState.currentState}", to: "<target_state>", event: "${normalizedEvent}", effects: [...] }
4120
+ Or ensure the previous action (that opened this UI) properly transitions back before emitting this event.`
4121
+ );
4122
+ } else {
4123
+ console.log(
4124
+ "[TraitStateMachine] No transition for",
4125
+ traitName,
4126
+ "from state:",
4127
+ traitState.currentState,
4128
+ "on event:",
4129
+ normalizedEvent
4130
+ );
4131
+ }
4132
+ }
4133
+ }
4134
+ }
4135
+ for (const { traitName, result } of results) {
4136
+ if (result.executed) {
4137
+ updateTraitState(traitName, result.newState);
4138
+ const effectTraces = result.effects.map(
4139
+ (e) => {
4140
+ const eff = e;
4141
+ return {
4142
+ type: String(eff.type ?? "unknown"),
4143
+ args: Array.isArray(eff.args) ? eff.args : [],
4144
+ status: "executed"
4145
+ };
4146
+ }
4147
+ );
4148
+ recordTransition({
4149
+ traitName,
4150
+ from: result.previousState,
4151
+ to: result.newState,
4152
+ event: normalizedEvent,
4153
+ effects: effectTraces,
4154
+ timestamp: Date.now()
4155
+ });
4156
+ }
4157
+ }
4158
+ if (results.length > 0) {
4159
+ setTraitStates(currentManager.getAllStates());
4160
+ }
4161
+ const onEventProcessed = optionsRef.current?.onEventProcessed;
4162
+ if (onEventProcessed) {
4163
+ onEventProcessed(normalizedEvent, payload);
4164
+ }
4165
+ }, [entities, fetchedDataContext, eventBus]);
4166
+ const drainEventQueue = React113.useCallback(async () => {
4167
+ if (processingRef.current) return;
4168
+ processingRef.current = true;
4169
+ try {
4170
+ while (eventQueueRef.current.length > 0) {
4171
+ const entry = eventQueueRef.current.shift();
4172
+ await processEventQueued(entry.eventKey, entry.payload);
4173
+ }
4174
+ } finally {
4175
+ processingRef.current = false;
4176
+ }
4177
+ }, [processEventQueued]);
4178
+ const enqueueAndDrain = React113.useCallback((eventKey, payload) => {
4179
+ eventQueueRef.current.push({ eventKey, payload });
4180
+ void drainEventQueue();
4181
+ }, [drainEventQueue]);
4182
+ React113.useCallback((eventKey, payload) => {
4183
+ enqueueAndDrain(eventKey, payload);
4184
+ }, [enqueueAndDrain]);
4185
+ const sendEvent = React113.useCallback((eventKey, payload) => {
4186
+ enqueueAndDrain(eventKey, payload);
4187
+ }, [enqueueAndDrain]);
4188
+ const getTraitState = React113.useCallback((traitName) => {
4189
+ return managerRef.current.getState(traitName);
4190
+ }, []);
4191
+ const canHandleEvent = React113.useCallback((traitName, eventKey) => {
4192
+ const normalizedEvent = normalizeEventKey(eventKey);
4193
+ return managerRef.current.canHandleEvent(traitName, normalizedEvent);
4194
+ }, []);
4195
+ React113.useEffect(() => {
4196
+ const allEvents = /* @__PURE__ */ new Set();
4197
+ for (const binding of traitBindings) {
4198
+ for (const event of binding.trait.events) {
4199
+ allEvents.add(event.key);
4200
+ }
4201
+ for (const transition of binding.trait.transitions) {
4202
+ allEvents.add(transition.event);
4203
+ }
4204
+ }
4205
+ console.log("[TraitStateMachine] Subscribing to events:", Array.from(allEvents));
4206
+ const unsubscribes = [];
4207
+ for (const eventKey of allEvents) {
4208
+ if (eventKey === "INIT" || eventKey === "LOAD" || eventKey === "$MOUNT") {
4209
+ continue;
4210
+ }
4211
+ const unsub = eventBus.on(`UI:${eventKey}`, (event) => {
4212
+ console.log("[TraitStateMachine] Received event:", `UI:${eventKey}`, event);
4213
+ enqueueAndDrain(eventKey, event.payload);
4214
+ });
4215
+ unsubscribes.push(unsub);
4216
+ }
4217
+ return () => {
4218
+ for (const unsub of unsubscribes) {
4219
+ unsub();
4220
+ }
4221
+ };
4222
+ }, [traitBindings, eventBus, enqueueAndDrain]);
4223
+ return {
4224
+ traitStates,
4225
+ sendEvent,
4226
+ getTraitState,
4227
+ canHandleEvent
4228
+ };
4229
+ }
4230
+ function useResolvedSchema(schema, pageName) {
4231
+ const [loading, setLoading] = React113.useState(true);
4232
+ const [error, setError] = React113.useState(null);
4233
+ const ir = React113.useMemo(() => {
4234
+ if (!schema) return null;
4235
+ try {
4236
+ return core.schemaToIR(schema);
4237
+ } catch (err) {
4238
+ setError(err instanceof Error ? err.message : "Schema resolution failed");
4239
+ return null;
4240
+ }
4241
+ }, [schema]);
4242
+ React113.useEffect(() => {
4243
+ setLoading(false);
4244
+ }, [ir]);
4245
+ const result = React113.useMemo(() => {
4246
+ if (!ir) {
4247
+ return {
4248
+ page: void 0,
4249
+ traits: [],
4250
+ entities: /* @__PURE__ */ new Map(),
4251
+ allEntities: /* @__PURE__ */ new Map(),
4252
+ allTraits: /* @__PURE__ */ new Map(),
4253
+ loading,
4254
+ error: error || (schema ? null : "No schema provided"),
4255
+ ir: null
4256
+ };
4257
+ }
4258
+ const page = core.getPage(ir, pageName);
4259
+ console.log("[useResolvedSchema] Resolved page:", page?.name, "| path:", page?.path, "| traits:", page?.traits.length);
4260
+ const traits2 = page?.traits || [];
4261
+ const entities = /* @__PURE__ */ new Map();
4262
+ if (page) {
4263
+ for (const binding of page.entityBindings) {
4264
+ entities.set(binding.entity.name, binding.entity);
4265
+ }
4266
+ }
4267
+ return {
4268
+ page,
4269
+ traits: traits2,
4270
+ entities,
4271
+ allEntities: ir.entities,
4272
+ allTraits: ir.traits,
4273
+ loading,
4274
+ error,
4275
+ ir
4276
+ };
4277
+ }, [ir, pageName, loading, error, schema]);
4278
+ return result;
4279
+ }
4280
+ function clearSchemaCache() {
4281
+ core.clearSchemaCache();
4282
+ }
4283
+ var TraitContext = React113.createContext(null);
4284
+ function TraitProvider({
4285
+ traits: traitBindings,
4286
+ children
4287
+ }) {
4288
+ const traitInstances = React113.useMemo(() => {
4289
+ const map = /* @__PURE__ */ new Map();
4290
+ for (const binding of traitBindings) {
4291
+ const trait = binding.trait;
4292
+ const initialState = trait.states.find((s) => s.isInitial);
4293
+ const stateName = initialState?.name || trait.states[0]?.name || "idle";
4294
+ const instance = {
4295
+ name: trait.name,
4296
+ currentState: stateName,
4297
+ availableEvents: trait.transitions.filter((t) => t.from === stateName).map((t) => t.event),
4298
+ dispatch: (eventKey, payload) => {
4299
+ console.log(`[TraitProvider] Dispatch to ${trait.name}: ${eventKey}`, payload);
4300
+ },
4301
+ canDispatch: (eventKey) => {
4302
+ return trait.transitions.some(
4303
+ (t) => t.from === stateName && t.event === eventKey
4304
+ );
4305
+ },
4306
+ trait
4307
+ };
4308
+ map.set(trait.name, instance);
4309
+ }
4310
+ return map;
4311
+ }, [traitBindings]);
4312
+ const contextValue = React113.useMemo(() => {
4313
+ return {
4314
+ traits: traitInstances,
4315
+ getTrait: (name) => traitInstances.get(name),
4316
+ dispatchToTrait: (traitName, eventKey, payload) => {
4317
+ const instance = traitInstances.get(traitName);
4318
+ if (instance) {
4319
+ instance.dispatch(eventKey, payload);
4320
+ }
4321
+ },
4322
+ canDispatch: (traitName, eventKey) => {
4323
+ const instance = traitInstances.get(traitName);
4324
+ return instance?.canDispatch(eventKey) || false;
4325
+ }
4326
+ };
4327
+ }, [traitInstances]);
4328
+ return /* @__PURE__ */ jsxRuntime.jsx(TraitContext.Provider, { value: contextValue, children });
4329
+ }
4330
+ function useTraitContext() {
4331
+ const context = React113.useContext(TraitContext);
4332
+ if (!context) {
4333
+ throw new Error("useTraitContext must be used within a TraitProvider");
4334
+ }
4335
+ return context;
4336
+ }
4337
+ function useTrait(traitName) {
4338
+ const context = useTraitContext();
4339
+ return context.getTrait(traitName);
4340
+ }
4341
+ var SlotsStateContext = React113.createContext({});
4342
+ var SlotsActionsContext = React113.createContext(null);
4343
+ function SlotsProvider({ children }) {
4344
+ const [slots, setSlots] = React113.useState({});
4345
+ const setSlotPatterns = React113.useCallback((slot, patterns, source) => {
4346
+ setSlots((prev) => ({
4347
+ ...prev,
4348
+ [slot]: { patterns, source }
4349
+ }));
4350
+ }, []);
4351
+ const clearSlot = React113.useCallback((slot) => {
4352
+ setSlots((prev) => {
4353
+ if (!(slot in prev)) return prev;
4354
+ const next = { ...prev };
4355
+ delete next[slot];
4356
+ return next;
4357
+ });
4358
+ }, []);
4359
+ const clearAllSlots = React113.useCallback(() => {
4360
+ setSlots({});
4361
+ }, []);
4362
+ const actionsRef = React113.useRef({ setSlotPatterns, clearSlot, clearAllSlots });
4363
+ actionsRef.current = { setSlotPatterns, clearSlot, clearAllSlots };
4364
+ const [stableActions] = React113.useState(() => ({
4365
+ setSlotPatterns: (...args) => actionsRef.current.setSlotPatterns(...args),
4366
+ clearSlot: (...args) => actionsRef.current.clearSlot(...args),
4367
+ clearAllSlots: () => actionsRef.current.clearAllSlots()
4368
+ }));
4369
+ return /* @__PURE__ */ jsxRuntime.jsx(SlotsActionsContext.Provider, { value: stableActions, children: /* @__PURE__ */ jsxRuntime.jsx(SlotsStateContext.Provider, { value: slots, children }) });
4370
+ }
4371
+ function useSlots() {
4372
+ return React113.useContext(SlotsStateContext);
4373
+ }
4374
+ function useSlotContent(slotName) {
4375
+ const slots = React113.useContext(SlotsStateContext);
4376
+ return slots[slotName] || null;
4377
+ }
4378
+ function useSlotsActions() {
4379
+ const actions = React113.useContext(SlotsActionsContext);
4380
+ if (!actions) {
4381
+ throw new Error("useSlotsActions must be used within a SlotsProvider");
4382
+ }
4383
+ return actions;
4384
+ }
4385
+
4386
+ exports.EntitySchemaProvider = EntitySchemaProvider;
4387
+ exports.SlotsProvider = SlotsProvider;
4388
+ exports.TraitContext = TraitContext;
4389
+ exports.TraitProvider = TraitProvider;
4390
+ exports.clearSchemaCache = clearSchemaCache;
4391
+ exports.createClientEffectHandlers = createClientEffectHandlers;
4392
+ exports.useEntityDefinition = useEntityDefinition;
4393
+ exports.useEntitySchema = useEntitySchema;
4394
+ exports.useResolvedSchema = useResolvedSchema;
4395
+ exports.useSlotContent = useSlotContent;
4396
+ exports.useSlots = useSlots;
4397
+ exports.useSlotsActions = useSlotsActions;
4398
+ exports.useTrait = useTrait;
4399
+ exports.useTraitContext = useTraitContext;
4400
+ exports.useTraitStateMachine = useTraitStateMachine;