@almadar/ui 2.16.0 → 2.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/avl/index.cjs +91 -1
- package/dist/avl/index.d.cts +7 -5
- package/dist/avl/index.js +91 -1
- package/dist/components/index.cjs +131 -2411
- package/dist/components/index.css +0 -508
- package/dist/components/index.js +132 -2411
- package/dist/components/molecules/avl/AvlSlotMap.d.ts +5 -4
- package/dist/components/molecules/avl/avl-layout.d.ts +2 -1
- package/dist/components/organisms/component-registry.generated.d.ts +1 -1
- package/dist/components/organisms/game/three/index.cjs +1067 -0
- package/dist/components/organisms/game/three/index.css +192 -0
- package/dist/components/organisms/game/three/index.d.ts +4 -0
- package/dist/components/organisms/game/three/index.js +1068 -5
- package/dist/illustrations/index.cjs +91 -1
- package/dist/illustrations/index.d.cts +5 -4
- package/dist/illustrations/index.js +91 -1
- package/dist/providers/index.cjs +152 -1521
- package/dist/providers/index.css +0 -508
- package/dist/providers/index.js +62 -1430
- package/dist/runtime/index.cjs +145 -1514
- package/dist/runtime/index.css +0 -508
- package/dist/runtime/index.js +63 -1431
- package/package.json +1 -1
package/dist/providers/index.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var React110 = require('react');
|
|
4
4
|
var jsxRuntime = require('react/jsx-runtime');
|
|
5
5
|
require('react-dom');
|
|
6
6
|
require('@almadar/ui/context');
|
|
@@ -19,12 +19,6 @@ var remarkMath = require('remark-math');
|
|
|
19
19
|
var rehypeKatex = require('rehype-katex');
|
|
20
20
|
var SyntaxHighlighter = require('react-syntax-highlighter/dist/esm/prism');
|
|
21
21
|
var dark = require('react-syntax-highlighter/dist/esm/styles/prism/vsc-dark-plus');
|
|
22
|
-
var fiber = require('@react-three/fiber');
|
|
23
|
-
var drei = require('@react-three/drei');
|
|
24
|
-
var THREE = require('three');
|
|
25
|
-
var GLTFLoader = require('three/examples/jsm/loaders/GLTFLoader');
|
|
26
|
-
var GLTFLoader_js = require('three/examples/jsm/loaders/GLTFLoader.js');
|
|
27
|
-
var OBJLoader_js = require('three/examples/jsm/loaders/OBJLoader.js');
|
|
28
22
|
|
|
29
23
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
30
24
|
|
|
@@ -46,7 +40,7 @@ function _interopNamespace(e) {
|
|
|
46
40
|
return Object.freeze(n);
|
|
47
41
|
}
|
|
48
42
|
|
|
49
|
-
var
|
|
43
|
+
var React110__namespace = /*#__PURE__*/_interopNamespace(React110);
|
|
50
44
|
var LucideIcons__namespace = /*#__PURE__*/_interopNamespace(LucideIcons);
|
|
51
45
|
var L__default = /*#__PURE__*/_interopDefault(L);
|
|
52
46
|
var ReactMarkdown__default = /*#__PURE__*/_interopDefault(ReactMarkdown);
|
|
@@ -55,7 +49,6 @@ var remarkMath__default = /*#__PURE__*/_interopDefault(remarkMath);
|
|
|
55
49
|
var rehypeKatex__default = /*#__PURE__*/_interopDefault(rehypeKatex);
|
|
56
50
|
var SyntaxHighlighter__default = /*#__PURE__*/_interopDefault(SyntaxHighlighter);
|
|
57
51
|
var dark__default = /*#__PURE__*/_interopDefault(dark);
|
|
58
|
-
var THREE__namespace = /*#__PURE__*/_interopNamespace(THREE);
|
|
59
52
|
|
|
60
53
|
var __defProp = Object.defineProperty;
|
|
61
54
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
@@ -159,7 +152,7 @@ var BUILT_IN_THEMES = [
|
|
|
159
152
|
hasDarkMode: true
|
|
160
153
|
}
|
|
161
154
|
];
|
|
162
|
-
var ThemeContext =
|
|
155
|
+
var ThemeContext = React110.createContext(void 0);
|
|
163
156
|
var THEME_STORAGE_KEY = "theme";
|
|
164
157
|
var MODE_STORAGE_KEY = "theme-mode";
|
|
165
158
|
function getSystemMode() {
|
|
@@ -179,14 +172,14 @@ var ThemeProvider = ({
|
|
|
179
172
|
defaultMode = "system",
|
|
180
173
|
targetRef
|
|
181
174
|
}) => {
|
|
182
|
-
const availableThemes =
|
|
175
|
+
const availableThemes = React110.useMemo(() => {
|
|
183
176
|
const themeMap = /* @__PURE__ */ new Map();
|
|
184
177
|
BUILT_IN_THEMES.forEach((t) => themeMap.set(t.name, t));
|
|
185
178
|
themes.forEach((t) => themeMap.set(t.name, t));
|
|
186
179
|
return Array.from(themeMap.values());
|
|
187
180
|
}, [themes]);
|
|
188
181
|
const isScoped = !!targetRef;
|
|
189
|
-
const [theme, setThemeState] =
|
|
182
|
+
const [theme, setThemeState] = React110.useState(() => {
|
|
190
183
|
if (isScoped || typeof window === "undefined") return defaultTheme;
|
|
191
184
|
const stored = localStorage.getItem(THEME_STORAGE_KEY);
|
|
192
185
|
const validThemes = [
|
|
@@ -198,7 +191,7 @@ var ThemeProvider = ({
|
|
|
198
191
|
}
|
|
199
192
|
return defaultTheme;
|
|
200
193
|
});
|
|
201
|
-
const [mode, setModeState] =
|
|
194
|
+
const [mode, setModeState] = React110.useState(() => {
|
|
202
195
|
if (isScoped || typeof window === "undefined") return defaultMode;
|
|
203
196
|
const stored = localStorage.getItem(MODE_STORAGE_KEY);
|
|
204
197
|
if (stored === "light" || stored === "dark" || stored === "system") {
|
|
@@ -206,14 +199,14 @@ var ThemeProvider = ({
|
|
|
206
199
|
}
|
|
207
200
|
return defaultMode;
|
|
208
201
|
});
|
|
209
|
-
const [resolvedMode, setResolvedMode] =
|
|
202
|
+
const [resolvedMode, setResolvedMode] = React110.useState(
|
|
210
203
|
() => resolveMode(mode)
|
|
211
204
|
);
|
|
212
|
-
const appliedTheme =
|
|
205
|
+
const appliedTheme = React110.useMemo(
|
|
213
206
|
() => `${theme}-${resolvedMode}`,
|
|
214
207
|
[theme, resolvedMode]
|
|
215
208
|
);
|
|
216
|
-
|
|
209
|
+
React110.useEffect(() => {
|
|
217
210
|
const updateResolved = () => {
|
|
218
211
|
setResolvedMode(resolveMode(mode));
|
|
219
212
|
};
|
|
@@ -226,7 +219,7 @@ var ThemeProvider = ({
|
|
|
226
219
|
}
|
|
227
220
|
return void 0;
|
|
228
221
|
}, [mode]);
|
|
229
|
-
|
|
222
|
+
React110.useEffect(() => {
|
|
230
223
|
if (isScoped) {
|
|
231
224
|
if (targetRef?.current) {
|
|
232
225
|
targetRef.current.setAttribute("data-theme", appliedTheme);
|
|
@@ -240,7 +233,7 @@ var ThemeProvider = ({
|
|
|
240
233
|
root.classList.remove("light", "dark");
|
|
241
234
|
root.classList.add(resolvedMode);
|
|
242
235
|
}, [appliedTheme, resolvedMode, targetRef, isScoped]);
|
|
243
|
-
const setTheme =
|
|
236
|
+
const setTheme = React110.useCallback(
|
|
244
237
|
(newTheme) => {
|
|
245
238
|
const validTheme = availableThemes.find((t) => t.name === newTheme);
|
|
246
239
|
if (validTheme) {
|
|
@@ -256,17 +249,17 @@ var ThemeProvider = ({
|
|
|
256
249
|
},
|
|
257
250
|
[availableThemes]
|
|
258
251
|
);
|
|
259
|
-
const setMode =
|
|
252
|
+
const setMode = React110.useCallback((newMode) => {
|
|
260
253
|
setModeState(newMode);
|
|
261
254
|
if (!isScoped && typeof window !== "undefined") {
|
|
262
255
|
localStorage.setItem(MODE_STORAGE_KEY, newMode);
|
|
263
256
|
}
|
|
264
257
|
}, []);
|
|
265
|
-
const toggleMode =
|
|
258
|
+
const toggleMode = React110.useCallback(() => {
|
|
266
259
|
const newMode = resolvedMode === "dark" ? "light" : "dark";
|
|
267
260
|
setMode(newMode);
|
|
268
261
|
}, [resolvedMode, setMode]);
|
|
269
|
-
const contextValue =
|
|
262
|
+
const contextValue = React110.useMemo(
|
|
270
263
|
() => ({
|
|
271
264
|
theme,
|
|
272
265
|
mode,
|
|
@@ -362,24 +355,15 @@ var fallbackEventBus = {
|
|
|
362
355
|
}
|
|
363
356
|
};
|
|
364
357
|
function useEventBus() {
|
|
365
|
-
const context =
|
|
358
|
+
const context = React110.useContext(EventBusContext);
|
|
366
359
|
return context ?? getGlobalEventBus() ?? fallbackEventBus;
|
|
367
360
|
}
|
|
368
|
-
|
|
369
|
-
const eventBus = useEventBus();
|
|
370
|
-
return React113.useCallback(
|
|
371
|
-
(type, payload) => {
|
|
372
|
-
eventBus.emit(type, payload);
|
|
373
|
-
},
|
|
374
|
-
[eventBus]
|
|
375
|
-
);
|
|
376
|
-
}
|
|
377
|
-
var EventBusContext = React113.createContext(null);
|
|
361
|
+
var EventBusContext = React110.createContext(null);
|
|
378
362
|
function EventBusProvider({ children, debug: debug2 = false }) {
|
|
379
|
-
const listenersRef =
|
|
380
|
-
const anyListenersRef =
|
|
381
|
-
const deprecationWarningShown =
|
|
382
|
-
const getSelectedEntity =
|
|
363
|
+
const listenersRef = React110.useRef(/* @__PURE__ */ new Map());
|
|
364
|
+
const anyListenersRef = React110.useRef(/* @__PURE__ */ new Set());
|
|
365
|
+
const deprecationWarningShown = React110.useRef(false);
|
|
366
|
+
const getSelectedEntity = React110.useCallback(() => {
|
|
383
367
|
if (!deprecationWarningShown.current) {
|
|
384
368
|
console.warn(
|
|
385
369
|
"[EventBus] getSelectedEntity is deprecated. Use SelectionProvider and useSelection hook instead. See SelectionProvider.tsx for migration guide."
|
|
@@ -388,7 +372,7 @@ function EventBusProvider({ children, debug: debug2 = false }) {
|
|
|
388
372
|
}
|
|
389
373
|
return null;
|
|
390
374
|
}, []);
|
|
391
|
-
const clearSelectedEntity =
|
|
375
|
+
const clearSelectedEntity = React110.useCallback(() => {
|
|
392
376
|
if (!deprecationWarningShown.current) {
|
|
393
377
|
console.warn(
|
|
394
378
|
"[EventBus] clearSelectedEntity is deprecated. Use SelectionProvider and useSelection hook instead. See SelectionProvider.tsx for migration guide."
|
|
@@ -396,7 +380,7 @@ function EventBusProvider({ children, debug: debug2 = false }) {
|
|
|
396
380
|
deprecationWarningShown.current = true;
|
|
397
381
|
}
|
|
398
382
|
}, []);
|
|
399
|
-
const emit =
|
|
383
|
+
const emit = React110.useCallback((type, payload) => {
|
|
400
384
|
const event = {
|
|
401
385
|
type,
|
|
402
386
|
payload,
|
|
@@ -430,7 +414,7 @@ function EventBusProvider({ children, debug: debug2 = false }) {
|
|
|
430
414
|
}
|
|
431
415
|
}
|
|
432
416
|
}, [debug2]);
|
|
433
|
-
const on =
|
|
417
|
+
const on = React110.useCallback((type, listener) => {
|
|
434
418
|
if (!listenersRef.current.has(type)) {
|
|
435
419
|
listenersRef.current.set(type, /* @__PURE__ */ new Set());
|
|
436
420
|
}
|
|
@@ -449,18 +433,18 @@ function EventBusProvider({ children, debug: debug2 = false }) {
|
|
|
449
433
|
}
|
|
450
434
|
};
|
|
451
435
|
}, [debug2]);
|
|
452
|
-
const once =
|
|
436
|
+
const once = React110.useCallback((type, listener) => {
|
|
453
437
|
const wrappedListener = (event) => {
|
|
454
438
|
listenersRef.current.get(type)?.delete(wrappedListener);
|
|
455
439
|
listener(event);
|
|
456
440
|
};
|
|
457
441
|
return on(type, wrappedListener);
|
|
458
442
|
}, [on]);
|
|
459
|
-
const hasListeners =
|
|
443
|
+
const hasListeners = React110.useCallback((type) => {
|
|
460
444
|
const listeners7 = listenersRef.current.get(type);
|
|
461
445
|
return listeners7 !== void 0 && listeners7.size > 0;
|
|
462
446
|
}, []);
|
|
463
|
-
const onAny =
|
|
447
|
+
const onAny = React110.useCallback((listener) => {
|
|
464
448
|
anyListenersRef.current.add(listener);
|
|
465
449
|
if (debug2) {
|
|
466
450
|
console.log(`[EventBus] onAny subscribed, total: ${anyListenersRef.current.size}`);
|
|
@@ -472,7 +456,7 @@ function EventBusProvider({ children, debug: debug2 = false }) {
|
|
|
472
456
|
}
|
|
473
457
|
};
|
|
474
458
|
}, [debug2]);
|
|
475
|
-
const contextValue =
|
|
459
|
+
const contextValue = React110.useMemo(
|
|
476
460
|
() => ({
|
|
477
461
|
emit,
|
|
478
462
|
on,
|
|
@@ -484,7 +468,7 @@ function EventBusProvider({ children, debug: debug2 = false }) {
|
|
|
484
468
|
}),
|
|
485
469
|
[emit, on, once, hasListeners, onAny, getSelectedEntity, clearSelectedEntity]
|
|
486
470
|
);
|
|
487
|
-
|
|
471
|
+
React110.useEffect(() => {
|
|
488
472
|
setGlobalEventBus(contextValue);
|
|
489
473
|
return () => {
|
|
490
474
|
setGlobalEventBus(null);
|
|
@@ -492,7 +476,7 @@ function EventBusProvider({ children, debug: debug2 = false }) {
|
|
|
492
476
|
}, [contextValue]);
|
|
493
477
|
return /* @__PURE__ */ jsxRuntime.jsx(EventBusContext.Provider, { value: contextValue, children });
|
|
494
478
|
}
|
|
495
|
-
var SelectionContext =
|
|
479
|
+
var SelectionContext = React110.createContext(null);
|
|
496
480
|
var defaultCompareEntities = (a, b) => {
|
|
497
481
|
if (a === b) return true;
|
|
498
482
|
if (!a || !b) return false;
|
|
@@ -509,8 +493,8 @@ function SelectionProvider({
|
|
|
509
493
|
compareEntities = defaultCompareEntities
|
|
510
494
|
}) {
|
|
511
495
|
const eventBus = useEventBus();
|
|
512
|
-
const [selected, setSelectedState] =
|
|
513
|
-
const setSelected =
|
|
496
|
+
const [selected, setSelectedState] = React110.useState(null);
|
|
497
|
+
const setSelected = React110.useCallback(
|
|
514
498
|
(entity) => {
|
|
515
499
|
setSelectedState(entity);
|
|
516
500
|
if (debug2) {
|
|
@@ -519,19 +503,19 @@ function SelectionProvider({
|
|
|
519
503
|
},
|
|
520
504
|
[debug2]
|
|
521
505
|
);
|
|
522
|
-
const clearSelection =
|
|
506
|
+
const clearSelection = React110.useCallback(() => {
|
|
523
507
|
setSelectedState(null);
|
|
524
508
|
if (debug2) {
|
|
525
509
|
console.log("[SelectionProvider] Selection cleared");
|
|
526
510
|
}
|
|
527
511
|
}, [debug2]);
|
|
528
|
-
const isSelected =
|
|
512
|
+
const isSelected = React110.useCallback(
|
|
529
513
|
(entity) => {
|
|
530
514
|
return compareEntities(selected, entity);
|
|
531
515
|
},
|
|
532
516
|
[selected, compareEntities]
|
|
533
517
|
);
|
|
534
|
-
|
|
518
|
+
React110.useEffect(() => {
|
|
535
519
|
const handleSelect = (event) => {
|
|
536
520
|
const row = event.payload?.row;
|
|
537
521
|
if (row) {
|
|
@@ -569,53 +553,53 @@ function SelectionProvider({
|
|
|
569
553
|
return /* @__PURE__ */ jsxRuntime.jsx(SelectionContext.Provider, { value: contextValue, children });
|
|
570
554
|
}
|
|
571
555
|
function useSelection() {
|
|
572
|
-
const context =
|
|
556
|
+
const context = React110.useContext(SelectionContext);
|
|
573
557
|
if (!context) {
|
|
574
558
|
throw new Error("useSelection must be used within a SelectionProvider");
|
|
575
559
|
}
|
|
576
560
|
return context;
|
|
577
561
|
}
|
|
578
562
|
function useSelectionOptional() {
|
|
579
|
-
const context =
|
|
563
|
+
const context = React110.useContext(SelectionContext);
|
|
580
564
|
return context;
|
|
581
565
|
}
|
|
582
|
-
var FetchedDataContext =
|
|
566
|
+
var FetchedDataContext = React110.createContext(null);
|
|
583
567
|
function FetchedDataProvider({
|
|
584
568
|
initialData,
|
|
585
569
|
children
|
|
586
570
|
}) {
|
|
587
|
-
const [state, setState] =
|
|
571
|
+
const [state, setState] = React110.useState(() => ({
|
|
588
572
|
data: initialData || {},
|
|
589
573
|
fetchedAt: {},
|
|
590
574
|
loading: false,
|
|
591
575
|
error: null
|
|
592
576
|
}));
|
|
593
|
-
const getData =
|
|
577
|
+
const getData = React110.useCallback(
|
|
594
578
|
(entityName) => {
|
|
595
579
|
return state.data[entityName] || [];
|
|
596
580
|
},
|
|
597
581
|
[state.data]
|
|
598
582
|
);
|
|
599
|
-
const getById =
|
|
583
|
+
const getById = React110.useCallback(
|
|
600
584
|
(entityName, id) => {
|
|
601
585
|
const records = state.data[entityName];
|
|
602
586
|
return records?.find((r) => r.id === id);
|
|
603
587
|
},
|
|
604
588
|
[state.data]
|
|
605
589
|
);
|
|
606
|
-
const hasData =
|
|
590
|
+
const hasData = React110.useCallback(
|
|
607
591
|
(entityName) => {
|
|
608
592
|
return entityName in state.data && state.data[entityName].length > 0;
|
|
609
593
|
},
|
|
610
594
|
[state.data]
|
|
611
595
|
);
|
|
612
|
-
const getFetchedAt =
|
|
596
|
+
const getFetchedAt = React110.useCallback(
|
|
613
597
|
(entityName) => {
|
|
614
598
|
return state.fetchedAt[entityName];
|
|
615
599
|
},
|
|
616
600
|
[state.fetchedAt]
|
|
617
601
|
);
|
|
618
|
-
const setData =
|
|
602
|
+
const setData = React110.useCallback((data) => {
|
|
619
603
|
const now = Date.now();
|
|
620
604
|
setState((prev) => ({
|
|
621
605
|
...prev,
|
|
@@ -634,14 +618,14 @@ function FetchedDataProvider({
|
|
|
634
618
|
error: null
|
|
635
619
|
}));
|
|
636
620
|
}, []);
|
|
637
|
-
const clearData =
|
|
621
|
+
const clearData = React110.useCallback(() => {
|
|
638
622
|
setState((prev) => ({
|
|
639
623
|
...prev,
|
|
640
624
|
data: {},
|
|
641
625
|
fetchedAt: {}
|
|
642
626
|
}));
|
|
643
627
|
}, []);
|
|
644
|
-
const clearEntity =
|
|
628
|
+
const clearEntity = React110.useCallback((entityName) => {
|
|
645
629
|
setState((prev) => {
|
|
646
630
|
const newData = { ...prev.data };
|
|
647
631
|
const newFetchedAt = { ...prev.fetchedAt };
|
|
@@ -654,13 +638,13 @@ function FetchedDataProvider({
|
|
|
654
638
|
};
|
|
655
639
|
});
|
|
656
640
|
}, []);
|
|
657
|
-
const setLoading =
|
|
641
|
+
const setLoading = React110.useCallback((loading) => {
|
|
658
642
|
setState((prev) => ({ ...prev, loading }));
|
|
659
643
|
}, []);
|
|
660
|
-
const setError =
|
|
644
|
+
const setError = React110.useCallback((error) => {
|
|
661
645
|
setState((prev) => ({ ...prev, error, loading: false }));
|
|
662
646
|
}, []);
|
|
663
|
-
const contextValue =
|
|
647
|
+
const contextValue = React110.useMemo(
|
|
664
648
|
() => ({
|
|
665
649
|
getData,
|
|
666
650
|
getById,
|
|
@@ -691,10 +675,10 @@ function FetchedDataProvider({
|
|
|
691
675
|
return /* @__PURE__ */ jsxRuntime.jsx(FetchedDataContext.Provider, { value: contextValue, children });
|
|
692
676
|
}
|
|
693
677
|
function useFetchedDataContext() {
|
|
694
|
-
return
|
|
678
|
+
return React110.useContext(FetchedDataContext);
|
|
695
679
|
}
|
|
696
680
|
function useFetchedData() {
|
|
697
|
-
const context =
|
|
681
|
+
const context = React110.useContext(FetchedDataContext);
|
|
698
682
|
if (!context) {
|
|
699
683
|
return {
|
|
700
684
|
getData: () => [],
|
|
@@ -734,12 +718,12 @@ function useFetchedEntity(entityName) {
|
|
|
734
718
|
error: context.error
|
|
735
719
|
};
|
|
736
720
|
}
|
|
737
|
-
var EntityDataContext =
|
|
721
|
+
var EntityDataContext = React110.createContext(null);
|
|
738
722
|
function EntityDataProvider({
|
|
739
723
|
adapter,
|
|
740
724
|
children
|
|
741
725
|
}) {
|
|
742
|
-
return
|
|
726
|
+
return React110__namespace.default.createElement(
|
|
743
727
|
EntityDataContext.Provider,
|
|
744
728
|
{ value: adapter },
|
|
745
729
|
children
|
|
@@ -885,7 +869,7 @@ var positionStyles = {
|
|
|
885
869
|
fixed: "fixed",
|
|
886
870
|
sticky: "sticky"
|
|
887
871
|
};
|
|
888
|
-
var Box =
|
|
872
|
+
var Box = React110__namespace.default.forwardRef(
|
|
889
873
|
({
|
|
890
874
|
padding,
|
|
891
875
|
paddingX,
|
|
@@ -904,7 +888,7 @@ var Box = React113__namespace.default.forwardRef(
|
|
|
904
888
|
position,
|
|
905
889
|
className,
|
|
906
890
|
children,
|
|
907
|
-
as:
|
|
891
|
+
as: Component = "div",
|
|
908
892
|
action,
|
|
909
893
|
actionPayload,
|
|
910
894
|
hoverEvent,
|
|
@@ -914,27 +898,27 @@ var Box = React113__namespace.default.forwardRef(
|
|
|
914
898
|
...rest
|
|
915
899
|
}, ref) => {
|
|
916
900
|
const eventBus = useEventBus();
|
|
917
|
-
const handleClick =
|
|
901
|
+
const handleClick = React110.useCallback((e) => {
|
|
918
902
|
if (action) {
|
|
919
903
|
e.stopPropagation();
|
|
920
904
|
eventBus.emit(`UI:${action}`, actionPayload ?? {});
|
|
921
905
|
}
|
|
922
906
|
onClick?.(e);
|
|
923
907
|
}, [action, actionPayload, eventBus, onClick]);
|
|
924
|
-
const handleMouseEnter =
|
|
908
|
+
const handleMouseEnter = React110.useCallback((e) => {
|
|
925
909
|
if (hoverEvent) {
|
|
926
910
|
eventBus.emit(`UI:${hoverEvent}`, { hovered: true });
|
|
927
911
|
}
|
|
928
912
|
onMouseEnter?.(e);
|
|
929
913
|
}, [hoverEvent, eventBus, onMouseEnter]);
|
|
930
|
-
const handleMouseLeave =
|
|
914
|
+
const handleMouseLeave = React110.useCallback((e) => {
|
|
931
915
|
if (hoverEvent) {
|
|
932
916
|
eventBus.emit(`UI:${hoverEvent}`, { hovered: false });
|
|
933
917
|
}
|
|
934
918
|
onMouseLeave?.(e);
|
|
935
919
|
}, [hoverEvent, eventBus, onMouseLeave]);
|
|
936
920
|
const isClickable = action || onClick;
|
|
937
|
-
const Comp =
|
|
921
|
+
const Comp = Component;
|
|
938
922
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
939
923
|
Comp,
|
|
940
924
|
{
|
|
@@ -1064,8 +1048,8 @@ var Typography = ({
|
|
|
1064
1048
|
children
|
|
1065
1049
|
}) => {
|
|
1066
1050
|
const variant = variantProp ?? (level ? `h${level}` : "body1");
|
|
1067
|
-
const
|
|
1068
|
-
const Comp =
|
|
1051
|
+
const Component = as || defaultElements[variant];
|
|
1052
|
+
const Comp = Component;
|
|
1069
1053
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1070
1054
|
Comp,
|
|
1071
1055
|
{
|
|
@@ -1155,7 +1139,7 @@ function resolveIconProp(value, sizeClass) {
|
|
|
1155
1139
|
const IconComp = value;
|
|
1156
1140
|
return /* @__PURE__ */ jsxRuntime.jsx(IconComp, { className: sizeClass });
|
|
1157
1141
|
}
|
|
1158
|
-
if (
|
|
1142
|
+
if (React110__namespace.default.isValidElement(value)) {
|
|
1159
1143
|
return value;
|
|
1160
1144
|
}
|
|
1161
1145
|
if (typeof value === "object" && value !== null && "render" in value) {
|
|
@@ -1164,7 +1148,7 @@ function resolveIconProp(value, sizeClass) {
|
|
|
1164
1148
|
}
|
|
1165
1149
|
return value;
|
|
1166
1150
|
}
|
|
1167
|
-
var Button =
|
|
1151
|
+
var Button = React110__namespace.default.forwardRef(
|
|
1168
1152
|
({
|
|
1169
1153
|
className,
|
|
1170
1154
|
variant = "primary",
|
|
@@ -1259,7 +1243,7 @@ var sizeStyles3 = {
|
|
|
1259
1243
|
md: "px-2.5 py-1 text-sm",
|
|
1260
1244
|
lg: "px-3 py-1.5 text-base"
|
|
1261
1245
|
};
|
|
1262
|
-
var Badge =
|
|
1246
|
+
var Badge = React110__namespace.default.forwardRef(
|
|
1263
1247
|
({ className, variant = "default", size = "sm", amount, label, icon, children, ...props }, ref) => {
|
|
1264
1248
|
const iconSizes2 = { sm: "w-3 h-3", md: "w-3.5 h-3.5", lg: "w-4 h-4" };
|
|
1265
1249
|
const resolvedIcon = typeof icon === "string" ? (() => {
|
|
@@ -1286,7 +1270,7 @@ var Badge = React113__namespace.default.forwardRef(
|
|
|
1286
1270
|
}
|
|
1287
1271
|
);
|
|
1288
1272
|
Badge.displayName = "Badge";
|
|
1289
|
-
var Input =
|
|
1273
|
+
var Input = React110__namespace.default.forwardRef(
|
|
1290
1274
|
({
|
|
1291
1275
|
className,
|
|
1292
1276
|
inputType,
|
|
@@ -1398,7 +1382,7 @@ var Input = React113__namespace.default.forwardRef(
|
|
|
1398
1382
|
}
|
|
1399
1383
|
);
|
|
1400
1384
|
Input.displayName = "Input";
|
|
1401
|
-
var Label =
|
|
1385
|
+
var Label = React110__namespace.default.forwardRef(
|
|
1402
1386
|
({ className, required, children, ...props }, ref) => {
|
|
1403
1387
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1404
1388
|
"label",
|
|
@@ -1418,7 +1402,7 @@ var Label = React113__namespace.default.forwardRef(
|
|
|
1418
1402
|
}
|
|
1419
1403
|
);
|
|
1420
1404
|
Label.displayName = "Label";
|
|
1421
|
-
var Textarea =
|
|
1405
|
+
var Textarea = React110__namespace.default.forwardRef(
|
|
1422
1406
|
({ className, error, ...props }, ref) => {
|
|
1423
1407
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1424
1408
|
"textarea",
|
|
@@ -1441,7 +1425,7 @@ var Textarea = React113__namespace.default.forwardRef(
|
|
|
1441
1425
|
}
|
|
1442
1426
|
);
|
|
1443
1427
|
Textarea.displayName = "Textarea";
|
|
1444
|
-
var Select =
|
|
1428
|
+
var Select = React110__namespace.default.forwardRef(
|
|
1445
1429
|
({ className, options, placeholder, error, ...props }, ref) => {
|
|
1446
1430
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
|
|
1447
1431
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -1477,7 +1461,7 @@ var Select = React113__namespace.default.forwardRef(
|
|
|
1477
1461
|
}
|
|
1478
1462
|
);
|
|
1479
1463
|
Select.displayName = "Select";
|
|
1480
|
-
var Checkbox =
|
|
1464
|
+
var Checkbox = React110__namespace.default.forwardRef(
|
|
1481
1465
|
({ className, label, id, ...props }, ref) => {
|
|
1482
1466
|
const inputId = id || `checkbox-${Math.random().toString(36).substr(2, 9)}`;
|
|
1483
1467
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center", children: [
|
|
@@ -1551,7 +1535,7 @@ var shadowStyles2 = {
|
|
|
1551
1535
|
md: "shadow-[var(--shadow-main)]",
|
|
1552
1536
|
lg: "shadow-[var(--shadow-lg)]"
|
|
1553
1537
|
};
|
|
1554
|
-
var Card =
|
|
1538
|
+
var Card = React110__namespace.default.forwardRef(
|
|
1555
1539
|
({
|
|
1556
1540
|
className,
|
|
1557
1541
|
variant = "bordered",
|
|
@@ -1587,9 +1571,9 @@ var Card = React113__namespace.default.forwardRef(
|
|
|
1587
1571
|
}
|
|
1588
1572
|
);
|
|
1589
1573
|
Card.displayName = "Card";
|
|
1590
|
-
var CardHeader =
|
|
1574
|
+
var CardHeader = React110__namespace.default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx("div", { ref, className: cn("mb-4", className), ...props }));
|
|
1591
1575
|
CardHeader.displayName = "CardHeader";
|
|
1592
|
-
var CardTitle =
|
|
1576
|
+
var CardTitle = React110__namespace.default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
1593
1577
|
"h3",
|
|
1594
1578
|
{
|
|
1595
1579
|
ref,
|
|
@@ -1602,11 +1586,11 @@ var CardTitle = React113__namespace.default.forwardRef(({ className, ...props },
|
|
|
1602
1586
|
}
|
|
1603
1587
|
));
|
|
1604
1588
|
CardTitle.displayName = "CardTitle";
|
|
1605
|
-
var CardContent =
|
|
1589
|
+
var CardContent = React110__namespace.default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx("div", { ref, className: cn("", className), ...props }));
|
|
1606
1590
|
CardContent.displayName = "CardContent";
|
|
1607
1591
|
var CardBody = CardContent;
|
|
1608
1592
|
CardBody.displayName = "CardBody";
|
|
1609
|
-
var CardFooter =
|
|
1593
|
+
var CardFooter = React110__namespace.default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
1610
1594
|
"div",
|
|
1611
1595
|
{
|
|
1612
1596
|
ref,
|
|
@@ -1621,7 +1605,7 @@ var sizeStyles4 = {
|
|
|
1621
1605
|
md: "h-6 w-6",
|
|
1622
1606
|
lg: "h-8 w-8"
|
|
1623
1607
|
};
|
|
1624
|
-
var Spinner =
|
|
1608
|
+
var Spinner = React110__namespace.default.forwardRef(
|
|
1625
1609
|
({ className, size = "md", ...props }, ref) => {
|
|
1626
1610
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1627
1611
|
"div",
|
|
@@ -1635,7 +1619,7 @@ var Spinner = React113__namespace.default.forwardRef(
|
|
|
1635
1619
|
}
|
|
1636
1620
|
);
|
|
1637
1621
|
Spinner.displayName = "Spinner";
|
|
1638
|
-
var Radio =
|
|
1622
|
+
var Radio = React110__namespace.default.forwardRef(
|
|
1639
1623
|
({
|
|
1640
1624
|
label,
|
|
1641
1625
|
helperText,
|
|
@@ -1739,7 +1723,7 @@ var Radio = React113__namespace.default.forwardRef(
|
|
|
1739
1723
|
}
|
|
1740
1724
|
);
|
|
1741
1725
|
Radio.displayName = "Radio";
|
|
1742
|
-
var Switch =
|
|
1726
|
+
var Switch = React110__namespace.forwardRef(
|
|
1743
1727
|
({
|
|
1744
1728
|
checked,
|
|
1745
1729
|
defaultChecked = false,
|
|
@@ -1750,10 +1734,10 @@ var Switch = React113__namespace.forwardRef(
|
|
|
1750
1734
|
name,
|
|
1751
1735
|
className
|
|
1752
1736
|
}, ref) => {
|
|
1753
|
-
const [isChecked, setIsChecked] =
|
|
1737
|
+
const [isChecked, setIsChecked] = React110__namespace.useState(
|
|
1754
1738
|
checked !== void 0 ? checked : defaultChecked
|
|
1755
1739
|
);
|
|
1756
|
-
|
|
1740
|
+
React110__namespace.useEffect(() => {
|
|
1757
1741
|
if (checked !== void 0) {
|
|
1758
1742
|
setIsChecked(checked);
|
|
1759
1743
|
}
|
|
@@ -1847,7 +1831,7 @@ var Stack = ({
|
|
|
1847
1831
|
className,
|
|
1848
1832
|
style,
|
|
1849
1833
|
children,
|
|
1850
|
-
as:
|
|
1834
|
+
as: Component = "div",
|
|
1851
1835
|
onClick,
|
|
1852
1836
|
onKeyDown,
|
|
1853
1837
|
role,
|
|
@@ -1865,7 +1849,7 @@ var Stack = ({
|
|
|
1865
1849
|
};
|
|
1866
1850
|
const isHorizontal = direction === "horizontal";
|
|
1867
1851
|
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";
|
|
1868
|
-
const Comp =
|
|
1852
|
+
const Comp = Component;
|
|
1869
1853
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1870
1854
|
Comp,
|
|
1871
1855
|
{
|
|
@@ -1911,7 +1895,7 @@ var sizeStyles5 = {
|
|
|
1911
1895
|
md: "w-2.5 h-2.5",
|
|
1912
1896
|
lg: "w-3 h-3"
|
|
1913
1897
|
};
|
|
1914
|
-
var StatusDot =
|
|
1898
|
+
var StatusDot = React110__namespace.default.forwardRef(
|
|
1915
1899
|
({ className, status = "offline", pulse = false, size = "md", label, ...props }, ref) => {
|
|
1916
1900
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1917
1901
|
"span",
|
|
@@ -1958,7 +1942,7 @@ var iconMap2 = {
|
|
|
1958
1942
|
down: LucideIcons.TrendingDown,
|
|
1959
1943
|
flat: LucideIcons.ArrowRight
|
|
1960
1944
|
};
|
|
1961
|
-
var TrendIndicator =
|
|
1945
|
+
var TrendIndicator = React110__namespace.default.forwardRef(
|
|
1962
1946
|
({
|
|
1963
1947
|
className,
|
|
1964
1948
|
value,
|
|
@@ -2017,7 +2001,7 @@ var thumbSizes = {
|
|
|
2017
2001
|
md: "w-4 h-4",
|
|
2018
2002
|
lg: "w-5 h-5"
|
|
2019
2003
|
};
|
|
2020
|
-
var RangeSlider =
|
|
2004
|
+
var RangeSlider = React110__namespace.default.forwardRef(
|
|
2021
2005
|
({
|
|
2022
2006
|
className,
|
|
2023
2007
|
min = 0,
|
|
@@ -2035,14 +2019,14 @@ var RangeSlider = React113__namespace.default.forwardRef(
|
|
|
2035
2019
|
formatValue: formatValue5,
|
|
2036
2020
|
...props
|
|
2037
2021
|
}, ref) => {
|
|
2038
|
-
const [isDragging, setIsDragging] =
|
|
2039
|
-
const [showTip, setShowTip] =
|
|
2040
|
-
const inputRef =
|
|
2022
|
+
const [isDragging, setIsDragging] = React110.useState(false);
|
|
2023
|
+
const [showTip, setShowTip] = React110.useState(false);
|
|
2024
|
+
const inputRef = React110.useRef(null);
|
|
2041
2025
|
const eventBus = useSafeEventBus();
|
|
2042
2026
|
const percentage = max !== min ? (value - min) / (max - min) * 100 : 0;
|
|
2043
2027
|
const bufferedPercentage = buffered !== void 0 ? Math.min(buffered, 100) : void 0;
|
|
2044
2028
|
const displayValue = formatValue5 ? formatValue5(value) : String(value);
|
|
2045
|
-
const handleChange =
|
|
2029
|
+
const handleChange = React110.useCallback(
|
|
2046
2030
|
(e) => {
|
|
2047
2031
|
const newValue = Number(e.target.value);
|
|
2048
2032
|
onChange?.(newValue);
|
|
@@ -2220,7 +2204,7 @@ var paddingClasses = {
|
|
|
2220
2204
|
md: "py-16",
|
|
2221
2205
|
lg: "py-24"
|
|
2222
2206
|
};
|
|
2223
|
-
var ContentSection =
|
|
2207
|
+
var ContentSection = React110__namespace.default.forwardRef(
|
|
2224
2208
|
({ children, background = "default", padding = "lg", id, className }, ref) => {
|
|
2225
2209
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2226
2210
|
Box,
|
|
@@ -2349,7 +2333,7 @@ var en_default = {
|
|
|
2349
2333
|
// hooks/useTranslate.ts
|
|
2350
2334
|
var { $meta: _meta, ...coreMessages } = en_default;
|
|
2351
2335
|
var coreLocale = coreMessages;
|
|
2352
|
-
var I18nContext =
|
|
2336
|
+
var I18nContext = React110.createContext({
|
|
2353
2337
|
locale: "en",
|
|
2354
2338
|
direction: "ltr",
|
|
2355
2339
|
t: (key) => coreLocale[key] ?? key
|
|
@@ -2358,7 +2342,7 @@ var I18nContext = React113.createContext({
|
|
|
2358
2342
|
I18nContext.displayName = "I18nContext";
|
|
2359
2343
|
I18nContext.Provider;
|
|
2360
2344
|
function useTranslate() {
|
|
2361
|
-
return
|
|
2345
|
+
return React110.useContext(I18nContext);
|
|
2362
2346
|
}
|
|
2363
2347
|
var ErrorState = ({
|
|
2364
2348
|
title,
|
|
@@ -2394,7 +2378,7 @@ var ErrorState = ({
|
|
|
2394
2378
|
);
|
|
2395
2379
|
};
|
|
2396
2380
|
ErrorState.displayName = "ErrorState";
|
|
2397
|
-
var ErrorBoundary = class extends
|
|
2381
|
+
var ErrorBoundary = class extends React110__namespace.default.Component {
|
|
2398
2382
|
constructor(props) {
|
|
2399
2383
|
super(props);
|
|
2400
2384
|
__publicField(this, "reset", () => {
|
|
@@ -2493,7 +2477,7 @@ function executeNotify(message, options, config) {
|
|
|
2493
2477
|
function executeEmit(event, payload, config) {
|
|
2494
2478
|
config.eventBus.emit(event, payload);
|
|
2495
2479
|
}
|
|
2496
|
-
var ClientEffectConfigContext =
|
|
2480
|
+
var ClientEffectConfigContext = React110.createContext(null);
|
|
2497
2481
|
ClientEffectConfigContext.Provider;
|
|
2498
2482
|
var effectIdCounter = 0;
|
|
2499
2483
|
function generateEffectId() {
|
|
@@ -2732,14 +2716,14 @@ var OfflineExecutor = class {
|
|
|
2732
2716
|
}
|
|
2733
2717
|
};
|
|
2734
2718
|
function useOfflineExecutor(options) {
|
|
2735
|
-
const executorRef =
|
|
2736
|
-
const [state, setState] =
|
|
2719
|
+
const executorRef = React110.useRef(null);
|
|
2720
|
+
const [state, setState] = React110.useState({
|
|
2737
2721
|
isOffline: false,
|
|
2738
2722
|
syncQueue: [],
|
|
2739
2723
|
localEffectsProcessed: 0,
|
|
2740
2724
|
effectsSynced: 0
|
|
2741
2725
|
});
|
|
2742
|
-
|
|
2726
|
+
React110.useEffect(() => {
|
|
2743
2727
|
const executor = new OfflineExecutor({
|
|
2744
2728
|
...options,
|
|
2745
2729
|
onQueueChange: (queue) => {
|
|
@@ -2754,7 +2738,7 @@ function useOfflineExecutor(options) {
|
|
|
2754
2738
|
executorRef.current = null;
|
|
2755
2739
|
};
|
|
2756
2740
|
}, []);
|
|
2757
|
-
|
|
2741
|
+
React110.useEffect(() => {
|
|
2758
2742
|
if (!options.autoSync || !options.serverUrl) return;
|
|
2759
2743
|
const handleOnline = async () => {
|
|
2760
2744
|
if (executorRef.current) {
|
|
@@ -2768,13 +2752,13 @@ function useOfflineExecutor(options) {
|
|
|
2768
2752
|
window.addEventListener("online", handleOnline);
|
|
2769
2753
|
return () => window.removeEventListener("online", handleOnline);
|
|
2770
2754
|
}, [options.autoSync, options.serverUrl, options.authToken]);
|
|
2771
|
-
const executeEffects =
|
|
2755
|
+
const executeEffects = React110.useCallback((effects) => {
|
|
2772
2756
|
executorRef.current?.executeClientEffects(effects);
|
|
2773
2757
|
if (executorRef.current) {
|
|
2774
2758
|
setState(executorRef.current.getState());
|
|
2775
2759
|
}
|
|
2776
2760
|
}, []);
|
|
2777
|
-
const processEventOffline =
|
|
2761
|
+
const processEventOffline = React110.useCallback(
|
|
2778
2762
|
(event, payload, effects) => {
|
|
2779
2763
|
const result = executorRef.current?.processEventOffline(event, payload, effects);
|
|
2780
2764
|
if (executorRef.current) {
|
|
@@ -2784,7 +2768,7 @@ function useOfflineExecutor(options) {
|
|
|
2784
2768
|
},
|
|
2785
2769
|
[]
|
|
2786
2770
|
);
|
|
2787
|
-
const sync =
|
|
2771
|
+
const sync = React110.useCallback(async () => {
|
|
2788
2772
|
if (!executorRef.current || !options.serverUrl) return 0;
|
|
2789
2773
|
const count = await executorRef.current.syncPendingEffects(
|
|
2790
2774
|
options.serverUrl,
|
|
@@ -2793,7 +2777,7 @@ function useOfflineExecutor(options) {
|
|
|
2793
2777
|
setState(executorRef.current.getState());
|
|
2794
2778
|
return count;
|
|
2795
2779
|
}, [options.serverUrl, options.authToken]);
|
|
2796
|
-
const clearQueue =
|
|
2780
|
+
const clearQueue = React110.useCallback(() => {
|
|
2797
2781
|
executorRef.current?.clearQueue();
|
|
2798
2782
|
if (executorRef.current) {
|
|
2799
2783
|
setState(executorRef.current.getState());
|
|
@@ -2809,7 +2793,7 @@ function useOfflineExecutor(options) {
|
|
|
2809
2793
|
clearQueue
|
|
2810
2794
|
};
|
|
2811
2795
|
}
|
|
2812
|
-
|
|
2796
|
+
React110.createContext(null);
|
|
2813
2797
|
var defaultIcon = L__default.default.icon({
|
|
2814
2798
|
iconUrl: "https://unpkg.com/leaflet@1.9.4/dist/images/marker-icon.png",
|
|
2815
2799
|
iconRetinaUrl: "https://unpkg.com/leaflet@1.9.4/dist/images/marker-icon-2x.png",
|
|
@@ -2974,7 +2958,7 @@ function bindTraitStateGetter(getter) {
|
|
|
2974
2958
|
}
|
|
2975
2959
|
}
|
|
2976
2960
|
exposeOnWindow();
|
|
2977
|
-
var MarkdownContent =
|
|
2961
|
+
var MarkdownContent = React110__namespace.default.memo(
|
|
2978
2962
|
({ content, direction, className }) => {
|
|
2979
2963
|
const { t: _t } = useTranslate();
|
|
2980
2964
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -3075,7 +3059,7 @@ var MarkdownContent = React113__namespace.default.memo(
|
|
|
3075
3059
|
(prev, next) => prev.content === next.content && prev.className === next.className && prev.direction === next.direction
|
|
3076
3060
|
);
|
|
3077
3061
|
MarkdownContent.displayName = "MarkdownContent";
|
|
3078
|
-
var CodeBlock =
|
|
3062
|
+
var CodeBlock = React110__namespace.default.memo(
|
|
3079
3063
|
({
|
|
3080
3064
|
code,
|
|
3081
3065
|
language = "text",
|
|
@@ -3086,20 +3070,20 @@ var CodeBlock = React113__namespace.default.memo(
|
|
|
3086
3070
|
}) => {
|
|
3087
3071
|
const eventBus = useEventBus();
|
|
3088
3072
|
const { t: _t } = useTranslate();
|
|
3089
|
-
const scrollRef =
|
|
3090
|
-
const savedScrollLeftRef =
|
|
3091
|
-
const [copied, setCopied] =
|
|
3092
|
-
|
|
3073
|
+
const scrollRef = React110.useRef(null);
|
|
3074
|
+
const savedScrollLeftRef = React110.useRef(0);
|
|
3075
|
+
const [copied, setCopied] = React110.useState(false);
|
|
3076
|
+
React110.useLayoutEffect(() => {
|
|
3093
3077
|
const el = scrollRef.current;
|
|
3094
3078
|
return () => {
|
|
3095
3079
|
if (el) savedScrollLeftRef.current = el.scrollLeft;
|
|
3096
3080
|
};
|
|
3097
3081
|
}, [language, code]);
|
|
3098
|
-
|
|
3082
|
+
React110.useLayoutEffect(() => {
|
|
3099
3083
|
const el = scrollRef.current;
|
|
3100
3084
|
if (el) el.scrollLeft = savedScrollLeftRef.current;
|
|
3101
3085
|
}, [language, code]);
|
|
3102
|
-
|
|
3086
|
+
React110.useEffect(() => {
|
|
3103
3087
|
const el = scrollRef.current;
|
|
3104
3088
|
if (!el) return;
|
|
3105
3089
|
const handle = () => {
|
|
@@ -3182,1401 +3166,48 @@ var CodeBlock = React113__namespace.default.memo(
|
|
|
3182
3166
|
(prev, next) => prev.language === next.language && prev.code === next.code && prev.showCopyButton === next.showCopyButton && prev.maxHeight === next.maxHeight
|
|
3183
3167
|
);
|
|
3184
3168
|
CodeBlock.displayName = "CodeBlock";
|
|
3185
|
-
var Camera3D = React113.forwardRef(
|
|
3186
|
-
({
|
|
3187
|
-
mode = "isometric",
|
|
3188
|
-
position = [10, 10, 10],
|
|
3189
|
-
target = [0, 0, 0],
|
|
3190
|
-
zoom = 1,
|
|
3191
|
-
fov = 45,
|
|
3192
|
-
enableOrbit = true,
|
|
3193
|
-
minDistance = 2,
|
|
3194
|
-
maxDistance = 100,
|
|
3195
|
-
onChange
|
|
3196
|
-
}, ref) => {
|
|
3197
|
-
const { camera, set, viewport } = fiber.useThree();
|
|
3198
|
-
const controlsRef = React113.useRef(null);
|
|
3199
|
-
const initialPosition = React113.useRef(new THREE__namespace.Vector3(...position));
|
|
3200
|
-
const initialTarget = React113.useRef(new THREE__namespace.Vector3(...target));
|
|
3201
|
-
React113.useEffect(() => {
|
|
3202
|
-
let newCamera;
|
|
3203
|
-
if (mode === "isometric") {
|
|
3204
|
-
const aspect = viewport.aspect;
|
|
3205
|
-
const size = 10 / zoom;
|
|
3206
|
-
newCamera = new THREE__namespace.OrthographicCamera(
|
|
3207
|
-
-size * aspect,
|
|
3208
|
-
size * aspect,
|
|
3209
|
-
size,
|
|
3210
|
-
-size,
|
|
3211
|
-
0.1,
|
|
3212
|
-
1e3
|
|
3213
|
-
);
|
|
3214
|
-
} else {
|
|
3215
|
-
newCamera = new THREE__namespace.PerspectiveCamera(fov, viewport.aspect, 0.1, 1e3);
|
|
3216
|
-
}
|
|
3217
|
-
newCamera.position.copy(initialPosition.current);
|
|
3218
|
-
newCamera.lookAt(initialTarget.current);
|
|
3219
|
-
set({ camera: newCamera });
|
|
3220
|
-
if (mode === "top-down") {
|
|
3221
|
-
newCamera.position.set(0, 20 / zoom, 0);
|
|
3222
|
-
newCamera.lookAt(0, 0, 0);
|
|
3223
|
-
}
|
|
3224
|
-
return () => {
|
|
3225
|
-
};
|
|
3226
|
-
}, [mode, fov, zoom, viewport.aspect, set]);
|
|
3227
|
-
fiber.useFrame(() => {
|
|
3228
|
-
if (onChange) {
|
|
3229
|
-
onChange(camera);
|
|
3230
|
-
}
|
|
3231
|
-
});
|
|
3232
|
-
React113.useImperativeHandle(ref, () => ({
|
|
3233
|
-
getCamera: () => camera,
|
|
3234
|
-
setPosition: (x, y, z) => {
|
|
3235
|
-
camera.position.set(x, y, z);
|
|
3236
|
-
if (controlsRef.current) {
|
|
3237
|
-
controlsRef.current.update();
|
|
3238
|
-
}
|
|
3239
|
-
},
|
|
3240
|
-
lookAt: (x, y, z) => {
|
|
3241
|
-
camera.lookAt(x, y, z);
|
|
3242
|
-
if (controlsRef.current) {
|
|
3243
|
-
controlsRef.current.target.set(x, y, z);
|
|
3244
|
-
controlsRef.current.update();
|
|
3245
|
-
}
|
|
3246
|
-
},
|
|
3247
|
-
reset: () => {
|
|
3248
|
-
camera.position.copy(initialPosition.current);
|
|
3249
|
-
camera.lookAt(initialTarget.current);
|
|
3250
|
-
if (controlsRef.current) {
|
|
3251
|
-
controlsRef.current.target.copy(initialTarget.current);
|
|
3252
|
-
controlsRef.current.update();
|
|
3253
|
-
}
|
|
3254
|
-
},
|
|
3255
|
-
getViewBounds: () => {
|
|
3256
|
-
const min = new THREE__namespace.Vector3(-10, -10, -10);
|
|
3257
|
-
const max = new THREE__namespace.Vector3(10, 10, 10);
|
|
3258
|
-
return { min, max };
|
|
3259
|
-
}
|
|
3260
|
-
}));
|
|
3261
|
-
const maxPolarAngle = mode === "top-down" ? 0.1 : Math.PI / 2 - 0.1;
|
|
3262
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
3263
|
-
drei.OrbitControls,
|
|
3264
|
-
{
|
|
3265
|
-
ref: controlsRef,
|
|
3266
|
-
camera,
|
|
3267
|
-
enabled: enableOrbit,
|
|
3268
|
-
target: initialTarget.current,
|
|
3269
|
-
minDistance,
|
|
3270
|
-
maxDistance,
|
|
3271
|
-
maxPolarAngle,
|
|
3272
|
-
enableDamping: true,
|
|
3273
|
-
dampingFactor: 0.05
|
|
3274
|
-
}
|
|
3275
|
-
);
|
|
3276
|
-
}
|
|
3277
|
-
);
|
|
3278
|
-
Camera3D.displayName = "Camera3D";
|
|
3279
|
-
var Canvas3DErrorBoundary = class extends React113.Component {
|
|
3280
|
-
constructor(props) {
|
|
3281
|
-
super(props);
|
|
3282
|
-
__publicField(this, "handleReset", () => {
|
|
3283
|
-
this.setState({
|
|
3284
|
-
hasError: false,
|
|
3285
|
-
error: null,
|
|
3286
|
-
errorInfo: null
|
|
3287
|
-
});
|
|
3288
|
-
this.props.onReset?.();
|
|
3289
|
-
});
|
|
3290
|
-
this.state = {
|
|
3291
|
-
hasError: false,
|
|
3292
|
-
error: null,
|
|
3293
|
-
errorInfo: null
|
|
3294
|
-
};
|
|
3295
|
-
}
|
|
3296
|
-
static getDerivedStateFromError(error) {
|
|
3297
|
-
return {
|
|
3298
|
-
hasError: true,
|
|
3299
|
-
error,
|
|
3300
|
-
errorInfo: null
|
|
3301
|
-
};
|
|
3302
|
-
}
|
|
3303
|
-
componentDidCatch(error, errorInfo) {
|
|
3304
|
-
this.setState({ errorInfo });
|
|
3305
|
-
this.props.onError?.(error, errorInfo);
|
|
3306
|
-
console.error("[Canvas3DErrorBoundary] Error caught:", error);
|
|
3307
|
-
console.error("[Canvas3DErrorBoundary] Component stack:", errorInfo.componentStack);
|
|
3308
|
-
}
|
|
3309
|
-
render() {
|
|
3310
|
-
if (this.state.hasError) {
|
|
3311
|
-
if (this.props.fallback) {
|
|
3312
|
-
return this.props.fallback;
|
|
3313
|
-
}
|
|
3314
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "canvas-3d-error", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "canvas-3d-error__content", children: [
|
|
3315
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "canvas-3d-error__icon", children: "\u26A0\uFE0F" }),
|
|
3316
|
-
/* @__PURE__ */ jsxRuntime.jsx("h2", { className: "canvas-3d-error__title", children: "3D Scene Error" }),
|
|
3317
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "canvas-3d-error__message", children: "Something went wrong while rendering the 3D scene." }),
|
|
3318
|
-
this.state.error && /* @__PURE__ */ jsxRuntime.jsxs("details", { className: "canvas-3d-error__details", children: [
|
|
3319
|
-
/* @__PURE__ */ jsxRuntime.jsx("summary", { children: "Error Details" }),
|
|
3320
|
-
/* @__PURE__ */ jsxRuntime.jsxs("pre", { className: "error__stack", children: [
|
|
3321
|
-
this.state.error.message,
|
|
3322
|
-
"\n",
|
|
3323
|
-
this.state.error.stack
|
|
3324
|
-
] }),
|
|
3325
|
-
this.state.errorInfo && /* @__PURE__ */ jsxRuntime.jsx("pre", { className: "error__component-stack", children: this.state.errorInfo.componentStack })
|
|
3326
|
-
] }),
|
|
3327
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "canvas-3d-error__actions", children: [
|
|
3328
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3329
|
-
"button",
|
|
3330
|
-
{
|
|
3331
|
-
className: "error__button error__button--primary",
|
|
3332
|
-
onClick: this.handleReset,
|
|
3333
|
-
children: "Try Again"
|
|
3334
|
-
}
|
|
3335
|
-
),
|
|
3336
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3337
|
-
"button",
|
|
3338
|
-
{
|
|
3339
|
-
className: "error__button error__button--secondary",
|
|
3340
|
-
onClick: () => window.location.reload(),
|
|
3341
|
-
children: "Reload Page"
|
|
3342
|
-
}
|
|
3343
|
-
)
|
|
3344
|
-
] })
|
|
3345
|
-
] }) });
|
|
3346
|
-
}
|
|
3347
|
-
return this.props.children;
|
|
3348
|
-
}
|
|
3349
|
-
};
|
|
3350
|
-
function Canvas3DLoadingState({
|
|
3351
|
-
progress = 0,
|
|
3352
|
-
loaded = 0,
|
|
3353
|
-
total = 0,
|
|
3354
|
-
message = "Loading 3D Scene...",
|
|
3355
|
-
details,
|
|
3356
|
-
showSpinner = true,
|
|
3357
|
-
className
|
|
3358
|
-
}) {
|
|
3359
|
-
const clampedProgress = Math.max(0, Math.min(100, progress));
|
|
3360
|
-
const hasProgress = total > 0;
|
|
3361
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `canvas-3d-loading ${className || ""}`, children: [
|
|
3362
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "canvas-3d-loading__content", children: [
|
|
3363
|
-
showSpinner && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "canvas-3d-loading__spinner", children: [
|
|
3364
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "spinner__ring" }),
|
|
3365
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "spinner__ring spinner__ring--secondary" })
|
|
3366
|
-
] }),
|
|
3367
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "canvas-3d-loading__message", children: message }),
|
|
3368
|
-
details && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "canvas-3d-loading__details", children: details }),
|
|
3369
|
-
hasProgress && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "canvas-3d-loading__progress", children: [
|
|
3370
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "progress__bar", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3371
|
-
"div",
|
|
3372
|
-
{
|
|
3373
|
-
className: "progress__fill",
|
|
3374
|
-
style: { width: `${clampedProgress}%` }
|
|
3375
|
-
}
|
|
3376
|
-
) }),
|
|
3377
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "progress__text", children: [
|
|
3378
|
-
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "progress__percentage", children: [
|
|
3379
|
-
clampedProgress,
|
|
3380
|
-
"%"
|
|
3381
|
-
] }),
|
|
3382
|
-
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "progress__count", children: [
|
|
3383
|
-
"(",
|
|
3384
|
-
loaded,
|
|
3385
|
-
"/",
|
|
3386
|
-
total,
|
|
3387
|
-
")"
|
|
3388
|
-
] })
|
|
3389
|
-
] })
|
|
3390
|
-
] })
|
|
3391
|
-
] }),
|
|
3392
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "canvas-3d-loading__background", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "bg__grid" }) })
|
|
3393
|
-
] });
|
|
3394
|
-
}
|
|
3395
3169
|
|
|
3396
3170
|
// lib/debug.ts
|
|
3397
3171
|
typeof window !== "undefined" && (localStorage.getItem("debug") === "true" || process.env.NODE_ENV === "development");
|
|
3398
|
-
|
|
3399
|
-
var GameAudioContext =
|
|
3172
|
+
React110.lazy(() => import('react-markdown'));
|
|
3173
|
+
var GameAudioContext = React110.createContext(null);
|
|
3400
3174
|
GameAudioContext.displayName = "GameAudioContext";
|
|
3401
|
-
|
|
3402
|
-
|
|
3403
|
-
|
|
3404
|
-
|
|
3405
|
-
|
|
3406
|
-
|
|
3407
|
-
|
|
3408
|
-
|
|
3409
|
-
|
|
3410
|
-
loader.setResourcePath(detectAssetRoot2(url));
|
|
3411
|
-
return loader;
|
|
3412
|
-
}
|
|
3413
|
-
var AssetLoader = class {
|
|
3414
|
-
constructor() {
|
|
3415
|
-
__publicField(this, "objLoader");
|
|
3416
|
-
__publicField(this, "textureLoader");
|
|
3417
|
-
__publicField(this, "modelCache");
|
|
3418
|
-
__publicField(this, "textureCache");
|
|
3419
|
-
__publicField(this, "loadingPromises");
|
|
3420
|
-
this.objLoader = new OBJLoader_js.OBJLoader();
|
|
3421
|
-
this.textureLoader = new THREE__namespace.TextureLoader();
|
|
3422
|
-
this.modelCache = /* @__PURE__ */ new Map();
|
|
3423
|
-
this.textureCache = /* @__PURE__ */ new Map();
|
|
3424
|
-
this.loadingPromises = /* @__PURE__ */ new Map();
|
|
3425
|
-
}
|
|
3426
|
-
/**
|
|
3427
|
-
* Load a GLB/GLTF model
|
|
3428
|
-
* @param url - URL to the .glb or .gltf file
|
|
3429
|
-
* @returns Promise with loaded model scene and animations
|
|
3430
|
-
*/
|
|
3431
|
-
async loadModel(url) {
|
|
3432
|
-
if (this.modelCache.has(url)) {
|
|
3433
|
-
return this.modelCache.get(url);
|
|
3434
|
-
}
|
|
3435
|
-
if (this.loadingPromises.has(url)) {
|
|
3436
|
-
return this.loadingPromises.get(url);
|
|
3437
|
-
}
|
|
3438
|
-
const loader = createGLTFLoaderForUrl(url);
|
|
3439
|
-
const loadPromise = loader.loadAsync(url).then((gltf) => {
|
|
3440
|
-
const result = {
|
|
3441
|
-
scene: gltf.scene,
|
|
3442
|
-
animations: gltf.animations || []
|
|
3443
|
-
};
|
|
3444
|
-
this.modelCache.set(url, result);
|
|
3445
|
-
this.loadingPromises.delete(url);
|
|
3446
|
-
return result;
|
|
3447
|
-
}).catch((error) => {
|
|
3448
|
-
this.loadingPromises.delete(url);
|
|
3449
|
-
throw new Error(`Failed to load model ${url}: ${error.message}`);
|
|
3450
|
-
});
|
|
3451
|
-
this.loadingPromises.set(url, loadPromise);
|
|
3452
|
-
return loadPromise;
|
|
3453
|
-
}
|
|
3454
|
-
/**
|
|
3455
|
-
* Load an OBJ model (fallback for non-GLB assets)
|
|
3456
|
-
* @param url - URL to the .obj file
|
|
3457
|
-
* @returns Promise with loaded object group
|
|
3458
|
-
*/
|
|
3459
|
-
async loadOBJ(url) {
|
|
3460
|
-
if (this.modelCache.has(url)) {
|
|
3461
|
-
return this.modelCache.get(url).scene;
|
|
3462
|
-
}
|
|
3463
|
-
if (this.loadingPromises.has(url)) {
|
|
3464
|
-
const result = await this.loadingPromises.get(url);
|
|
3465
|
-
return result.scene;
|
|
3466
|
-
}
|
|
3467
|
-
const loadPromise = this.objLoader.loadAsync(url).then((group) => {
|
|
3468
|
-
const result = {
|
|
3469
|
-
scene: group,
|
|
3470
|
-
animations: []
|
|
3471
|
-
};
|
|
3472
|
-
this.modelCache.set(url, result);
|
|
3473
|
-
this.loadingPromises.delete(url);
|
|
3474
|
-
return result;
|
|
3475
|
-
}).catch((error) => {
|
|
3476
|
-
this.loadingPromises.delete(url);
|
|
3477
|
-
throw new Error(`Failed to load OBJ ${url}: ${error.message}`);
|
|
3478
|
-
});
|
|
3479
|
-
this.loadingPromises.set(url, loadPromise);
|
|
3480
|
-
return (await loadPromise).scene;
|
|
3481
|
-
}
|
|
3482
|
-
/**
|
|
3483
|
-
* Load a texture
|
|
3484
|
-
* @param url - URL to the texture image
|
|
3485
|
-
* @returns Promise with loaded texture
|
|
3486
|
-
*/
|
|
3487
|
-
async loadTexture(url) {
|
|
3488
|
-
if (this.textureCache.has(url)) {
|
|
3489
|
-
return this.textureCache.get(url);
|
|
3490
|
-
}
|
|
3491
|
-
if (this.loadingPromises.has(`texture:${url}`)) {
|
|
3492
|
-
return this.loadingPromises.get(`texture:${url}`);
|
|
3493
|
-
}
|
|
3494
|
-
const loadPromise = this.textureLoader.loadAsync(url).then((texture) => {
|
|
3495
|
-
texture.colorSpace = THREE__namespace.SRGBColorSpace;
|
|
3496
|
-
this.textureCache.set(url, texture);
|
|
3497
|
-
this.loadingPromises.delete(`texture:${url}`);
|
|
3498
|
-
return texture;
|
|
3499
|
-
}).catch((error) => {
|
|
3500
|
-
this.loadingPromises.delete(`texture:${url}`);
|
|
3501
|
-
throw new Error(`Failed to load texture ${url}: ${error.message}`);
|
|
3502
|
-
});
|
|
3503
|
-
this.loadingPromises.set(`texture:${url}`, loadPromise);
|
|
3504
|
-
return loadPromise;
|
|
3505
|
-
}
|
|
3506
|
-
/**
|
|
3507
|
-
* Preload multiple assets
|
|
3508
|
-
* @param urls - Array of asset URLs to preload
|
|
3509
|
-
* @returns Promise that resolves when all assets are loaded
|
|
3510
|
-
*/
|
|
3511
|
-
async preload(urls) {
|
|
3512
|
-
const promises = urls.map((url) => {
|
|
3513
|
-
if (url.endsWith(".glb") || url.endsWith(".gltf")) {
|
|
3514
|
-
return this.loadModel(url).catch(() => null);
|
|
3515
|
-
} else if (url.endsWith(".obj")) {
|
|
3516
|
-
return this.loadOBJ(url).catch(() => null);
|
|
3517
|
-
} else if (/\.(png|jpg|jpeg|webp)$/i.test(url)) {
|
|
3518
|
-
return this.loadTexture(url).catch(() => null);
|
|
3519
|
-
}
|
|
3520
|
-
return Promise.resolve(null);
|
|
3521
|
-
});
|
|
3522
|
-
await Promise.all(promises);
|
|
3523
|
-
}
|
|
3524
|
-
/**
|
|
3525
|
-
* Check if a model is cached
|
|
3526
|
-
* @param url - Model URL
|
|
3527
|
-
*/
|
|
3528
|
-
hasModel(url) {
|
|
3529
|
-
return this.modelCache.has(url);
|
|
3530
|
-
}
|
|
3531
|
-
/**
|
|
3532
|
-
* Check if a texture is cached
|
|
3533
|
-
* @param url - Texture URL
|
|
3534
|
-
*/
|
|
3535
|
-
hasTexture(url) {
|
|
3536
|
-
return this.textureCache.has(url);
|
|
3537
|
-
}
|
|
3538
|
-
/**
|
|
3539
|
-
* Get cached model (throws if not cached)
|
|
3540
|
-
* @param url - Model URL
|
|
3541
|
-
*/
|
|
3542
|
-
getModel(url) {
|
|
3543
|
-
const model = this.modelCache.get(url);
|
|
3544
|
-
if (!model) {
|
|
3545
|
-
throw new Error(`Model ${url} not in cache`);
|
|
3546
|
-
}
|
|
3547
|
-
return model;
|
|
3548
|
-
}
|
|
3549
|
-
/**
|
|
3550
|
-
* Get cached texture (throws if not cached)
|
|
3551
|
-
* @param url - Texture URL
|
|
3552
|
-
*/
|
|
3553
|
-
getTexture(url) {
|
|
3554
|
-
const texture = this.textureCache.get(url);
|
|
3555
|
-
if (!texture) {
|
|
3556
|
-
throw new Error(`Texture ${url} not in cache`);
|
|
3557
|
-
}
|
|
3558
|
-
return texture;
|
|
3559
|
-
}
|
|
3560
|
-
/**
|
|
3561
|
-
* Clear all caches
|
|
3562
|
-
*/
|
|
3563
|
-
clearCache() {
|
|
3564
|
-
this.textureCache.forEach((texture) => {
|
|
3565
|
-
texture.dispose();
|
|
3566
|
-
});
|
|
3567
|
-
this.modelCache.forEach((model) => {
|
|
3568
|
-
model.scene.traverse((child) => {
|
|
3569
|
-
if (child instanceof THREE__namespace.Mesh) {
|
|
3570
|
-
child.geometry.dispose();
|
|
3571
|
-
if (Array.isArray(child.material)) {
|
|
3572
|
-
child.material.forEach((m) => m.dispose());
|
|
3573
|
-
} else {
|
|
3574
|
-
child.material.dispose();
|
|
3575
|
-
}
|
|
3576
|
-
}
|
|
3577
|
-
});
|
|
3578
|
-
});
|
|
3579
|
-
this.modelCache.clear();
|
|
3580
|
-
this.textureCache.clear();
|
|
3581
|
-
this.loadingPromises.clear();
|
|
3582
|
-
}
|
|
3583
|
-
/**
|
|
3584
|
-
* Get cache statistics
|
|
3585
|
-
*/
|
|
3586
|
-
getStats() {
|
|
3587
|
-
return {
|
|
3588
|
-
models: this.modelCache.size,
|
|
3589
|
-
textures: this.textureCache.size,
|
|
3590
|
-
loading: this.loadingPromises.size
|
|
3591
|
-
};
|
|
3592
|
-
}
|
|
3593
|
-
};
|
|
3594
|
-
new AssetLoader();
|
|
3595
|
-
function useAssetLoader(options = {}) {
|
|
3596
|
-
const { preloadUrls = [], loader: customLoader } = options;
|
|
3597
|
-
const loaderRef = React113.useRef(customLoader || new AssetLoader());
|
|
3598
|
-
const [state, setState] = React113.useState({
|
|
3599
|
-
isLoading: false,
|
|
3600
|
-
progress: 0,
|
|
3601
|
-
loaded: 0,
|
|
3602
|
-
total: 0,
|
|
3603
|
-
errors: []
|
|
3604
|
-
});
|
|
3605
|
-
React113.useEffect(() => {
|
|
3606
|
-
if (preloadUrls.length > 0) {
|
|
3607
|
-
preload(preloadUrls);
|
|
3608
|
-
}
|
|
3609
|
-
}, []);
|
|
3610
|
-
const updateProgress = React113.useCallback((loaded, total) => {
|
|
3611
|
-
setState((prev) => ({
|
|
3612
|
-
...prev,
|
|
3613
|
-
loaded,
|
|
3614
|
-
total,
|
|
3615
|
-
progress: total > 0 ? Math.round(loaded / total * 100) : 0
|
|
3616
|
-
}));
|
|
3617
|
-
}, []);
|
|
3618
|
-
const loadModel = React113.useCallback(
|
|
3619
|
-
async (url) => {
|
|
3620
|
-
setState((prev) => ({ ...prev, isLoading: true }));
|
|
3621
|
-
try {
|
|
3622
|
-
const model = await loaderRef.current.loadModel(url);
|
|
3623
|
-
setState((prev) => ({
|
|
3624
|
-
...prev,
|
|
3625
|
-
isLoading: false,
|
|
3626
|
-
loaded: prev.loaded + 1
|
|
3627
|
-
}));
|
|
3628
|
-
return model;
|
|
3629
|
-
} catch (error) {
|
|
3630
|
-
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
3631
|
-
setState((prev) => ({
|
|
3632
|
-
...prev,
|
|
3633
|
-
isLoading: false,
|
|
3634
|
-
errors: [...prev.errors, errorMsg]
|
|
3635
|
-
}));
|
|
3636
|
-
throw error;
|
|
3637
|
-
}
|
|
3638
|
-
},
|
|
3639
|
-
[]
|
|
3640
|
-
);
|
|
3641
|
-
const loadOBJ = React113.useCallback(
|
|
3642
|
-
async (url) => {
|
|
3643
|
-
setState((prev) => ({ ...prev, isLoading: true }));
|
|
3644
|
-
try {
|
|
3645
|
-
const model = await loaderRef.current.loadOBJ(url);
|
|
3646
|
-
setState((prev) => ({
|
|
3647
|
-
...prev,
|
|
3648
|
-
isLoading: false,
|
|
3649
|
-
loaded: prev.loaded + 1
|
|
3650
|
-
}));
|
|
3651
|
-
return model;
|
|
3652
|
-
} catch (error) {
|
|
3653
|
-
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
3654
|
-
setState((prev) => ({
|
|
3655
|
-
...prev,
|
|
3656
|
-
isLoading: false,
|
|
3657
|
-
errors: [...prev.errors, errorMsg]
|
|
3658
|
-
}));
|
|
3659
|
-
throw error;
|
|
3660
|
-
}
|
|
3661
|
-
},
|
|
3662
|
-
[]
|
|
3663
|
-
);
|
|
3664
|
-
const loadTexture = React113.useCallback(
|
|
3665
|
-
async (url) => {
|
|
3666
|
-
setState((prev) => ({ ...prev, isLoading: true }));
|
|
3667
|
-
try {
|
|
3668
|
-
const texture = await loaderRef.current.loadTexture(url);
|
|
3669
|
-
setState((prev) => ({
|
|
3670
|
-
...prev,
|
|
3671
|
-
isLoading: false,
|
|
3672
|
-
loaded: prev.loaded + 1
|
|
3673
|
-
}));
|
|
3674
|
-
return texture;
|
|
3675
|
-
} catch (error) {
|
|
3676
|
-
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
3677
|
-
setState((prev) => ({
|
|
3678
|
-
...prev,
|
|
3679
|
-
isLoading: false,
|
|
3680
|
-
errors: [...prev.errors, errorMsg]
|
|
3681
|
-
}));
|
|
3682
|
-
throw error;
|
|
3683
|
-
}
|
|
3684
|
-
},
|
|
3685
|
-
[]
|
|
3686
|
-
);
|
|
3687
|
-
const preload = React113.useCallback(
|
|
3688
|
-
async (urls) => {
|
|
3689
|
-
setState((prev) => ({
|
|
3690
|
-
...prev,
|
|
3691
|
-
isLoading: true,
|
|
3692
|
-
total: urls.length,
|
|
3693
|
-
loaded: 0,
|
|
3694
|
-
errors: []
|
|
3695
|
-
}));
|
|
3696
|
-
let completed = 0;
|
|
3697
|
-
const errors = [];
|
|
3698
|
-
await Promise.all(
|
|
3699
|
-
urls.map(async (url) => {
|
|
3700
|
-
try {
|
|
3701
|
-
if (url.endsWith(".glb") || url.endsWith(".gltf")) {
|
|
3702
|
-
await loaderRef.current.loadModel(url);
|
|
3703
|
-
} else if (url.endsWith(".obj")) {
|
|
3704
|
-
await loaderRef.current.loadOBJ(url);
|
|
3705
|
-
} else if (/\.(png|jpg|jpeg|webp)$/i.test(url)) {
|
|
3706
|
-
await loaderRef.current.loadTexture(url);
|
|
3707
|
-
}
|
|
3708
|
-
completed++;
|
|
3709
|
-
updateProgress(completed, urls.length);
|
|
3710
|
-
} catch (error) {
|
|
3711
|
-
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
3712
|
-
errors.push(`${url}: ${errorMsg}`);
|
|
3713
|
-
completed++;
|
|
3714
|
-
updateProgress(completed, urls.length);
|
|
3715
|
-
}
|
|
3716
|
-
})
|
|
3717
|
-
);
|
|
3718
|
-
setState((prev) => ({
|
|
3719
|
-
...prev,
|
|
3720
|
-
isLoading: false,
|
|
3721
|
-
errors
|
|
3722
|
-
}));
|
|
3723
|
-
},
|
|
3724
|
-
[updateProgress]
|
|
3725
|
-
);
|
|
3726
|
-
const hasModel = React113.useCallback((url) => {
|
|
3727
|
-
return loaderRef.current.hasModel(url);
|
|
3728
|
-
}, []);
|
|
3729
|
-
const hasTexture = React113.useCallback((url) => {
|
|
3730
|
-
return loaderRef.current.hasTexture(url);
|
|
3731
|
-
}, []);
|
|
3732
|
-
const getModel = React113.useCallback((url) => {
|
|
3733
|
-
try {
|
|
3734
|
-
return loaderRef.current.getModel(url);
|
|
3735
|
-
} catch {
|
|
3736
|
-
return void 0;
|
|
3737
|
-
}
|
|
3738
|
-
}, []);
|
|
3739
|
-
const getTexture = React113.useCallback((url) => {
|
|
3740
|
-
try {
|
|
3741
|
-
return loaderRef.current.getTexture(url);
|
|
3742
|
-
} catch {
|
|
3743
|
-
return void 0;
|
|
3744
|
-
}
|
|
3745
|
-
}, []);
|
|
3746
|
-
const clearCache = React113.useCallback(() => {
|
|
3747
|
-
loaderRef.current.clearCache();
|
|
3748
|
-
setState({
|
|
3749
|
-
isLoading: false,
|
|
3750
|
-
progress: 0,
|
|
3751
|
-
loaded: 0,
|
|
3752
|
-
total: 0,
|
|
3753
|
-
errors: []
|
|
3754
|
-
});
|
|
3755
|
-
}, []);
|
|
3756
|
-
return {
|
|
3757
|
-
...state,
|
|
3758
|
-
loadModel,
|
|
3759
|
-
loadOBJ,
|
|
3760
|
-
loadTexture,
|
|
3761
|
-
preload,
|
|
3762
|
-
hasModel,
|
|
3763
|
-
hasTexture,
|
|
3764
|
-
getModel,
|
|
3765
|
-
getTexture,
|
|
3766
|
-
clearCache
|
|
3767
|
-
};
|
|
3768
|
-
}
|
|
3769
|
-
function useGameCanvas3DEvents(options) {
|
|
3770
|
-
const {
|
|
3771
|
-
tileClickEvent,
|
|
3772
|
-
unitClickEvent,
|
|
3773
|
-
featureClickEvent,
|
|
3774
|
-
canvasClickEvent,
|
|
3775
|
-
tileHoverEvent,
|
|
3776
|
-
tileLeaveEvent,
|
|
3777
|
-
unitAnimationEvent,
|
|
3778
|
-
cameraChangeEvent,
|
|
3779
|
-
onTileClick,
|
|
3780
|
-
onUnitClick,
|
|
3781
|
-
onFeatureClick,
|
|
3782
|
-
onCanvasClick,
|
|
3783
|
-
onTileHover,
|
|
3784
|
-
onUnitAnimation
|
|
3785
|
-
} = options;
|
|
3786
|
-
const emit = useEmitEvent();
|
|
3787
|
-
const optionsRef = React113.useRef(options);
|
|
3788
|
-
optionsRef.current = options;
|
|
3789
|
-
const handleTileClick = React113.useCallback(
|
|
3790
|
-
(tile, event) => {
|
|
3791
|
-
if (tileClickEvent) {
|
|
3792
|
-
emit(tileClickEvent, {
|
|
3793
|
-
tileId: tile.id,
|
|
3794
|
-
x: tile.x,
|
|
3795
|
-
z: tile.z ?? tile.y ?? 0,
|
|
3796
|
-
type: tile.type,
|
|
3797
|
-
terrain: tile.terrain,
|
|
3798
|
-
elevation: tile.elevation
|
|
3799
|
-
});
|
|
3800
|
-
}
|
|
3801
|
-
optionsRef.current.onTileClick?.(tile, event);
|
|
3802
|
-
},
|
|
3803
|
-
[tileClickEvent, emit]
|
|
3804
|
-
);
|
|
3805
|
-
const handleUnitClick = React113.useCallback(
|
|
3806
|
-
(unit, event) => {
|
|
3807
|
-
if (unitClickEvent) {
|
|
3808
|
-
emit(unitClickEvent, {
|
|
3809
|
-
unitId: unit.id,
|
|
3810
|
-
x: unit.x,
|
|
3811
|
-
z: unit.z ?? unit.y ?? 0,
|
|
3812
|
-
unitType: unit.unitType,
|
|
3813
|
-
name: unit.name,
|
|
3814
|
-
team: unit.team,
|
|
3815
|
-
faction: unit.faction,
|
|
3816
|
-
health: unit.health,
|
|
3817
|
-
maxHealth: unit.maxHealth
|
|
3818
|
-
});
|
|
3819
|
-
}
|
|
3820
|
-
optionsRef.current.onUnitClick?.(unit, event);
|
|
3821
|
-
},
|
|
3822
|
-
[unitClickEvent, emit]
|
|
3823
|
-
);
|
|
3824
|
-
const handleFeatureClick = React113.useCallback(
|
|
3825
|
-
(feature, event) => {
|
|
3826
|
-
if (featureClickEvent) {
|
|
3827
|
-
emit(featureClickEvent, {
|
|
3828
|
-
featureId: feature.id,
|
|
3829
|
-
x: feature.x,
|
|
3830
|
-
z: feature.z ?? feature.y ?? 0,
|
|
3831
|
-
type: feature.type,
|
|
3832
|
-
elevation: feature.elevation
|
|
3833
|
-
});
|
|
3834
|
-
}
|
|
3835
|
-
optionsRef.current.onFeatureClick?.(feature, event);
|
|
3836
|
-
},
|
|
3837
|
-
[featureClickEvent, emit]
|
|
3838
|
-
);
|
|
3839
|
-
const handleCanvasClick = React113.useCallback(
|
|
3840
|
-
(event) => {
|
|
3841
|
-
if (canvasClickEvent) {
|
|
3842
|
-
emit(canvasClickEvent, {
|
|
3843
|
-
clientX: event.clientX,
|
|
3844
|
-
clientY: event.clientY,
|
|
3845
|
-
button: event.button
|
|
3846
|
-
});
|
|
3847
|
-
}
|
|
3848
|
-
optionsRef.current.onCanvasClick?.(event);
|
|
3849
|
-
},
|
|
3850
|
-
[canvasClickEvent, emit]
|
|
3851
|
-
);
|
|
3852
|
-
const handleTileHover = React113.useCallback(
|
|
3853
|
-
(tile, event) => {
|
|
3854
|
-
if (tile) {
|
|
3855
|
-
if (tileHoverEvent) {
|
|
3856
|
-
emit(tileHoverEvent, {
|
|
3857
|
-
tileId: tile.id,
|
|
3858
|
-
x: tile.x,
|
|
3859
|
-
z: tile.z ?? tile.y ?? 0,
|
|
3860
|
-
type: tile.type
|
|
3861
|
-
});
|
|
3862
|
-
}
|
|
3863
|
-
} else {
|
|
3864
|
-
if (tileLeaveEvent) {
|
|
3865
|
-
emit(tileLeaveEvent, {});
|
|
3866
|
-
}
|
|
3867
|
-
}
|
|
3868
|
-
optionsRef.current.onTileHover?.(tile, event);
|
|
3869
|
-
},
|
|
3870
|
-
[tileHoverEvent, tileLeaveEvent, emit]
|
|
3871
|
-
);
|
|
3872
|
-
const handleUnitAnimation = React113.useCallback(
|
|
3873
|
-
(unitId, state) => {
|
|
3874
|
-
if (unitAnimationEvent) {
|
|
3875
|
-
emit(unitAnimationEvent, {
|
|
3876
|
-
unitId,
|
|
3877
|
-
state,
|
|
3878
|
-
timestamp: Date.now()
|
|
3879
|
-
});
|
|
3880
|
-
}
|
|
3881
|
-
optionsRef.current.onUnitAnimation?.(unitId, state);
|
|
3882
|
-
},
|
|
3883
|
-
[unitAnimationEvent, emit]
|
|
3884
|
-
);
|
|
3885
|
-
const handleCameraChange = React113.useCallback(
|
|
3886
|
-
(position) => {
|
|
3887
|
-
if (cameraChangeEvent) {
|
|
3888
|
-
emit(cameraChangeEvent, {
|
|
3889
|
-
position,
|
|
3890
|
-
timestamp: Date.now()
|
|
3891
|
-
});
|
|
3892
|
-
}
|
|
3893
|
-
},
|
|
3894
|
-
[cameraChangeEvent, emit]
|
|
3895
|
-
);
|
|
3896
|
-
return {
|
|
3897
|
-
handleTileClick,
|
|
3898
|
-
handleUnitClick,
|
|
3899
|
-
handleFeatureClick,
|
|
3900
|
-
handleCanvasClick,
|
|
3901
|
-
handleTileHover,
|
|
3902
|
-
handleUnitAnimation,
|
|
3903
|
-
handleCameraChange
|
|
3904
|
-
};
|
|
3905
|
-
}
|
|
3906
|
-
function detectAssetRoot3(modelUrl) {
|
|
3907
|
-
const idx = modelUrl.indexOf("/3d/");
|
|
3908
|
-
if (idx !== -1) {
|
|
3909
|
-
return modelUrl.substring(0, idx + 4);
|
|
3910
|
-
}
|
|
3911
|
-
return modelUrl.substring(0, modelUrl.lastIndexOf("/") + 1);
|
|
3912
|
-
}
|
|
3913
|
-
function useGLTFModel2(url, resourceBasePath) {
|
|
3914
|
-
const [state, setState] = React113.useState({
|
|
3915
|
-
model: null,
|
|
3916
|
-
isLoading: false,
|
|
3917
|
-
error: null
|
|
3918
|
-
});
|
|
3919
|
-
React113.useEffect(() => {
|
|
3920
|
-
if (!url) {
|
|
3921
|
-
setState({ model: null, isLoading: false, error: null });
|
|
3922
|
-
return;
|
|
3923
|
-
}
|
|
3924
|
-
console.log("[ModelLoader] Loading:", url);
|
|
3925
|
-
setState((prev) => ({ ...prev, isLoading: true, error: null }));
|
|
3926
|
-
const assetRoot = resourceBasePath || detectAssetRoot3(url);
|
|
3927
|
-
const loader = new GLTFLoader.GLTFLoader();
|
|
3928
|
-
loader.setResourcePath(assetRoot);
|
|
3929
|
-
loader.load(
|
|
3930
|
-
url,
|
|
3931
|
-
(gltf) => {
|
|
3932
|
-
console.log("[ModelLoader] Loaded:", url);
|
|
3933
|
-
setState({
|
|
3934
|
-
model: gltf.scene,
|
|
3935
|
-
isLoading: false,
|
|
3936
|
-
error: null
|
|
3937
|
-
});
|
|
3938
|
-
},
|
|
3939
|
-
void 0,
|
|
3940
|
-
(err) => {
|
|
3941
|
-
const errorMsg = err instanceof Error ? err.message : String(err);
|
|
3942
|
-
console.warn("[ModelLoader] Failed:", url, errorMsg);
|
|
3943
|
-
setState({
|
|
3944
|
-
model: null,
|
|
3945
|
-
isLoading: false,
|
|
3946
|
-
error: err instanceof Error ? err : new Error(String(err))
|
|
3947
|
-
});
|
|
3948
|
-
}
|
|
3175
|
+
|
|
3176
|
+
// components/organisms/component-registry.generated.ts
|
|
3177
|
+
function lazyThree(name, loader) {
|
|
3178
|
+
const Lazy = React110__namespace.default.lazy(() => loader().then((m) => ({ default: m[name] })));
|
|
3179
|
+
function ThreeWrapper(props) {
|
|
3180
|
+
return React110__namespace.default.createElement(
|
|
3181
|
+
React110__namespace.default.Suspense,
|
|
3182
|
+
{ fallback: null },
|
|
3183
|
+
React110__namespace.default.createElement(Lazy, props)
|
|
3949
3184
|
);
|
|
3950
|
-
}, [url, resourceBasePath]);
|
|
3951
|
-
return state;
|
|
3952
|
-
}
|
|
3953
|
-
function ModelLoader({
|
|
3954
|
-
url,
|
|
3955
|
-
position = [0, 0, 0],
|
|
3956
|
-
scale = 1,
|
|
3957
|
-
rotation = [0, 0, 0],
|
|
3958
|
-
isSelected = false,
|
|
3959
|
-
isHovered = false,
|
|
3960
|
-
onClick,
|
|
3961
|
-
onHover,
|
|
3962
|
-
fallbackGeometry = "box",
|
|
3963
|
-
castShadow = true,
|
|
3964
|
-
receiveShadow = true,
|
|
3965
|
-
resourceBasePath
|
|
3966
|
-
}) {
|
|
3967
|
-
const { model: loadedModel, isLoading, error } = useGLTFModel2(url, resourceBasePath);
|
|
3968
|
-
const model = React113.useMemo(() => {
|
|
3969
|
-
if (!loadedModel) return null;
|
|
3970
|
-
const cloned = loadedModel.clone();
|
|
3971
|
-
cloned.traverse((child) => {
|
|
3972
|
-
if (child instanceof THREE__namespace.Mesh) {
|
|
3973
|
-
child.castShadow = castShadow;
|
|
3974
|
-
child.receiveShadow = receiveShadow;
|
|
3975
|
-
}
|
|
3976
|
-
});
|
|
3977
|
-
return cloned;
|
|
3978
|
-
}, [loadedModel, castShadow, receiveShadow]);
|
|
3979
|
-
const scaleArray = React113.useMemo(() => {
|
|
3980
|
-
if (typeof scale === "number") {
|
|
3981
|
-
return [scale, scale, scale];
|
|
3982
|
-
}
|
|
3983
|
-
return scale;
|
|
3984
|
-
}, [scale]);
|
|
3985
|
-
const rotationRad = React113.useMemo(() => {
|
|
3986
|
-
return [
|
|
3987
|
-
rotation[0] * Math.PI / 180,
|
|
3988
|
-
rotation[1] * Math.PI / 180,
|
|
3989
|
-
rotation[2] * Math.PI / 180
|
|
3990
|
-
];
|
|
3991
|
-
}, [rotation]);
|
|
3992
|
-
if (isLoading) {
|
|
3993
|
-
return /* @__PURE__ */ jsxRuntime.jsx("group", { position, children: /* @__PURE__ */ jsxRuntime.jsxs("mesh", { rotation: [Math.PI / 2, 0, 0], children: [
|
|
3994
|
-
/* @__PURE__ */ jsxRuntime.jsx("ringGeometry", { args: [0.3, 0.35, 16] }),
|
|
3995
|
-
/* @__PURE__ */ jsxRuntime.jsx("meshBasicMaterial", { color: "#4a90d9", transparent: true, opacity: 0.8 })
|
|
3996
|
-
] }) });
|
|
3997
|
-
}
|
|
3998
|
-
if (error || !model) {
|
|
3999
|
-
if (fallbackGeometry === "none") {
|
|
4000
|
-
return /* @__PURE__ */ jsxRuntime.jsx("group", { position });
|
|
4001
|
-
}
|
|
4002
|
-
const fallbackProps = {
|
|
4003
|
-
onClick,
|
|
4004
|
-
onPointerOver: () => onHover?.(true),
|
|
4005
|
-
onPointerOut: () => onHover?.(false)
|
|
4006
|
-
};
|
|
4007
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("group", { position, children: [
|
|
4008
|
-
(isSelected || isHovered) && /* @__PURE__ */ jsxRuntime.jsxs("mesh", { position: [0, 0.02, 0], rotation: [-Math.PI / 2, 0, 0], children: [
|
|
4009
|
-
/* @__PURE__ */ jsxRuntime.jsx("ringGeometry", { args: [0.6, 0.7, 32] }),
|
|
4010
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4011
|
-
"meshBasicMaterial",
|
|
4012
|
-
{
|
|
4013
|
-
color: isSelected ? 16755200 : 16777215,
|
|
4014
|
-
transparent: true,
|
|
4015
|
-
opacity: 0.5
|
|
4016
|
-
}
|
|
4017
|
-
)
|
|
4018
|
-
] }),
|
|
4019
|
-
fallbackGeometry === "box" && /* @__PURE__ */ jsxRuntime.jsxs("mesh", { ...fallbackProps, position: [0, 0.5, 0], children: [
|
|
4020
|
-
/* @__PURE__ */ jsxRuntime.jsx("boxGeometry", { args: [0.8, 0.8, 0.8] }),
|
|
4021
|
-
/* @__PURE__ */ jsxRuntime.jsx("meshStandardMaterial", { color: error ? 16729156 : 8947848 })
|
|
4022
|
-
] }),
|
|
4023
|
-
fallbackGeometry === "sphere" && /* @__PURE__ */ jsxRuntime.jsxs("mesh", { ...fallbackProps, position: [0, 0.5, 0], children: [
|
|
4024
|
-
/* @__PURE__ */ jsxRuntime.jsx("sphereGeometry", { args: [0.4, 16, 16] }),
|
|
4025
|
-
/* @__PURE__ */ jsxRuntime.jsx("meshStandardMaterial", { color: error ? 16729156 : 8947848 })
|
|
4026
|
-
] }),
|
|
4027
|
-
fallbackGeometry === "cylinder" && /* @__PURE__ */ jsxRuntime.jsxs("mesh", { ...fallbackProps, position: [0, 0.5, 0], children: [
|
|
4028
|
-
/* @__PURE__ */ jsxRuntime.jsx("cylinderGeometry", { args: [0.3, 0.3, 0.8, 16] }),
|
|
4029
|
-
/* @__PURE__ */ jsxRuntime.jsx("meshStandardMaterial", { color: error ? 16729156 : 8947848 })
|
|
4030
|
-
] })
|
|
4031
|
-
] });
|
|
4032
3185
|
}
|
|
4033
|
-
|
|
4034
|
-
|
|
4035
|
-
{
|
|
4036
|
-
position,
|
|
4037
|
-
rotation: rotationRad,
|
|
4038
|
-
onClick,
|
|
4039
|
-
onPointerOver: () => onHover?.(true),
|
|
4040
|
-
onPointerOut: () => onHover?.(false),
|
|
4041
|
-
children: [
|
|
4042
|
-
(isSelected || isHovered) && /* @__PURE__ */ jsxRuntime.jsxs("mesh", { position: [0, 0.02, 0], rotation: [-Math.PI / 2, 0, 0], children: [
|
|
4043
|
-
/* @__PURE__ */ jsxRuntime.jsx("ringGeometry", { args: [0.6, 0.7, 32] }),
|
|
4044
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4045
|
-
"meshBasicMaterial",
|
|
4046
|
-
{
|
|
4047
|
-
color: isSelected ? 16755200 : 16777215,
|
|
4048
|
-
transparent: true,
|
|
4049
|
-
opacity: 0.5
|
|
4050
|
-
}
|
|
4051
|
-
)
|
|
4052
|
-
] }),
|
|
4053
|
-
/* @__PURE__ */ jsxRuntime.jsx("primitive", { object: model, scale: scaleArray })
|
|
4054
|
-
]
|
|
4055
|
-
}
|
|
4056
|
-
);
|
|
4057
|
-
}
|
|
4058
|
-
var DEFAULT_GRID_CONFIG = {
|
|
4059
|
-
cellSize: 1,
|
|
4060
|
-
offsetX: 0,
|
|
4061
|
-
offsetZ: 0
|
|
4062
|
-
};
|
|
4063
|
-
function CameraController({
|
|
4064
|
-
onCameraChange
|
|
4065
|
-
}) {
|
|
4066
|
-
const { camera } = fiber.useThree();
|
|
4067
|
-
React113.useEffect(() => {
|
|
4068
|
-
if (onCameraChange) {
|
|
4069
|
-
onCameraChange({
|
|
4070
|
-
x: camera.position.x,
|
|
4071
|
-
y: camera.position.y,
|
|
4072
|
-
z: camera.position.z
|
|
4073
|
-
});
|
|
4074
|
-
}
|
|
4075
|
-
}, [camera.position, onCameraChange]);
|
|
4076
|
-
return null;
|
|
3186
|
+
ThreeWrapper.displayName = `Lazy(${name})`;
|
|
3187
|
+
return ThreeWrapper;
|
|
4077
3188
|
}
|
|
4078
|
-
|
|
4079
|
-
|
|
4080
|
-
|
|
4081
|
-
|
|
4082
|
-
|
|
4083
|
-
|
|
4084
|
-
|
|
4085
|
-
|
|
4086
|
-
|
|
4087
|
-
|
|
4088
|
-
|
|
4089
|
-
|
|
4090
|
-
|
|
4091
|
-
|
|
4092
|
-
|
|
4093
|
-
|
|
4094
|
-
|
|
4095
|
-
onCanvasClick,
|
|
4096
|
-
onTileHover,
|
|
4097
|
-
onUnitAnimation,
|
|
4098
|
-
assetLoader: customAssetLoader,
|
|
4099
|
-
tileRenderer: CustomTileRenderer,
|
|
4100
|
-
unitRenderer: CustomUnitRenderer,
|
|
4101
|
-
featureRenderer: CustomFeatureRenderer,
|
|
4102
|
-
className,
|
|
4103
|
-
isLoading: externalLoading,
|
|
4104
|
-
error: externalError,
|
|
4105
|
-
entity,
|
|
4106
|
-
preloadAssets = [],
|
|
4107
|
-
tileClickEvent,
|
|
4108
|
-
unitClickEvent,
|
|
4109
|
-
featureClickEvent,
|
|
4110
|
-
canvasClickEvent,
|
|
4111
|
-
tileHoverEvent,
|
|
4112
|
-
tileLeaveEvent,
|
|
4113
|
-
unitAnimationEvent,
|
|
4114
|
-
cameraChangeEvent,
|
|
4115
|
-
loadingMessage = "Loading 3D Scene...",
|
|
4116
|
-
useInstancing = true,
|
|
4117
|
-
validMoves = [],
|
|
4118
|
-
attackTargets = [],
|
|
4119
|
-
selectedTileIds = [],
|
|
4120
|
-
selectedUnitId = null,
|
|
4121
|
-
children
|
|
4122
|
-
}, ref) => {
|
|
4123
|
-
const containerRef = React113.useRef(null);
|
|
4124
|
-
const controlsRef = React113.useRef(null);
|
|
4125
|
-
const [hoveredTile, setHoveredTile] = React113.useState(null);
|
|
4126
|
-
const [internalError, setInternalError] = React113.useState(null);
|
|
4127
|
-
const { isLoading: assetsLoading, progress, loaded, total } = useAssetLoader({
|
|
4128
|
-
preloadUrls: preloadAssets,
|
|
4129
|
-
loader: customAssetLoader
|
|
4130
|
-
});
|
|
4131
|
-
const eventHandlers = useGameCanvas3DEvents({
|
|
4132
|
-
tileClickEvent,
|
|
4133
|
-
unitClickEvent,
|
|
4134
|
-
featureClickEvent,
|
|
4135
|
-
canvasClickEvent,
|
|
4136
|
-
tileHoverEvent,
|
|
4137
|
-
tileLeaveEvent,
|
|
4138
|
-
unitAnimationEvent,
|
|
4139
|
-
cameraChangeEvent,
|
|
4140
|
-
onTileClick,
|
|
4141
|
-
onUnitClick,
|
|
4142
|
-
onFeatureClick,
|
|
4143
|
-
onCanvasClick,
|
|
4144
|
-
onTileHover,
|
|
4145
|
-
onUnitAnimation
|
|
4146
|
-
});
|
|
4147
|
-
const gridBounds = React113.useMemo(() => {
|
|
4148
|
-
if (tiles.length === 0) {
|
|
4149
|
-
return { minX: 0, maxX: 10, minZ: 0, maxZ: 10 };
|
|
4150
|
-
}
|
|
4151
|
-
const xs = tiles.map((t) => t.x);
|
|
4152
|
-
const zs = tiles.map((t) => t.z || t.y || 0);
|
|
4153
|
-
return {
|
|
4154
|
-
minX: Math.min(...xs),
|
|
4155
|
-
maxX: Math.max(...xs),
|
|
4156
|
-
minZ: Math.min(...zs),
|
|
4157
|
-
maxZ: Math.max(...zs)
|
|
4158
|
-
};
|
|
4159
|
-
}, [tiles]);
|
|
4160
|
-
const cameraTarget = React113.useMemo(() => {
|
|
4161
|
-
return [
|
|
4162
|
-
(gridBounds.minX + gridBounds.maxX) / 2,
|
|
4163
|
-
0,
|
|
4164
|
-
(gridBounds.minZ + gridBounds.maxZ) / 2
|
|
4165
|
-
];
|
|
4166
|
-
}, [gridBounds]);
|
|
4167
|
-
const gridConfig = React113.useMemo(
|
|
4168
|
-
() => ({
|
|
4169
|
-
...DEFAULT_GRID_CONFIG,
|
|
4170
|
-
offsetX: -(gridBounds.maxX - gridBounds.minX) / 2,
|
|
4171
|
-
offsetZ: -(gridBounds.maxZ - gridBounds.minZ) / 2
|
|
4172
|
-
}),
|
|
4173
|
-
[gridBounds]
|
|
4174
|
-
);
|
|
4175
|
-
const gridToWorld = React113.useCallback(
|
|
4176
|
-
(x, z, y = 0) => {
|
|
4177
|
-
const worldX = (x - gridBounds.minX) * gridConfig.cellSize;
|
|
4178
|
-
const worldZ = (z - gridBounds.minZ) * gridConfig.cellSize;
|
|
4179
|
-
return [worldX, y * gridConfig.cellSize, worldZ];
|
|
4180
|
-
},
|
|
4181
|
-
[gridBounds, gridConfig]
|
|
4182
|
-
);
|
|
4183
|
-
React113.useImperativeHandle(ref, () => ({
|
|
4184
|
-
getCameraPosition: () => {
|
|
4185
|
-
if (controlsRef.current) {
|
|
4186
|
-
const pos = controlsRef.current.object.position;
|
|
4187
|
-
return new THREE__namespace.Vector3(pos.x, pos.y, pos.z);
|
|
4188
|
-
}
|
|
4189
|
-
return null;
|
|
4190
|
-
},
|
|
4191
|
-
setCameraPosition: (x, y, z) => {
|
|
4192
|
-
if (controlsRef.current) {
|
|
4193
|
-
controlsRef.current.object.position.set(x, y, z);
|
|
4194
|
-
controlsRef.current.update();
|
|
4195
|
-
}
|
|
4196
|
-
},
|
|
4197
|
-
lookAt: (x, y, z) => {
|
|
4198
|
-
if (controlsRef.current) {
|
|
4199
|
-
controlsRef.current.target.set(x, y, z);
|
|
4200
|
-
controlsRef.current.update();
|
|
4201
|
-
}
|
|
4202
|
-
},
|
|
4203
|
-
resetCamera: () => {
|
|
4204
|
-
if (controlsRef.current) {
|
|
4205
|
-
controlsRef.current.reset();
|
|
4206
|
-
}
|
|
4207
|
-
},
|
|
4208
|
-
screenshot: () => {
|
|
4209
|
-
const canvas = containerRef.current?.querySelector("canvas");
|
|
4210
|
-
if (canvas) {
|
|
4211
|
-
return canvas.toDataURL("image/png");
|
|
4212
|
-
}
|
|
4213
|
-
return null;
|
|
4214
|
-
},
|
|
4215
|
-
export: () => ({
|
|
4216
|
-
tiles,
|
|
4217
|
-
units,
|
|
4218
|
-
features
|
|
4219
|
-
})
|
|
4220
|
-
}));
|
|
4221
|
-
const handleTileClick = React113.useCallback(
|
|
4222
|
-
(tile, event) => {
|
|
4223
|
-
eventHandlers.handleTileClick(tile, event);
|
|
4224
|
-
},
|
|
4225
|
-
[eventHandlers]
|
|
4226
|
-
);
|
|
4227
|
-
const handleUnitClick = React113.useCallback(
|
|
4228
|
-
(unit, event) => {
|
|
4229
|
-
eventHandlers.handleUnitClick(unit, event);
|
|
4230
|
-
},
|
|
4231
|
-
[eventHandlers]
|
|
4232
|
-
);
|
|
4233
|
-
const handleFeatureClick = React113.useCallback(
|
|
4234
|
-
(feature, event) => {
|
|
4235
|
-
if (event) {
|
|
4236
|
-
eventHandlers.handleFeatureClick(feature, event);
|
|
4237
|
-
}
|
|
4238
|
-
},
|
|
4239
|
-
[eventHandlers]
|
|
4240
|
-
);
|
|
4241
|
-
const handleTileHover = React113.useCallback(
|
|
4242
|
-
(tile, event) => {
|
|
4243
|
-
setHoveredTile(tile);
|
|
4244
|
-
if (event) {
|
|
4245
|
-
eventHandlers.handleTileHover(tile, event);
|
|
4246
|
-
}
|
|
4247
|
-
},
|
|
4248
|
-
[eventHandlers]
|
|
4249
|
-
);
|
|
4250
|
-
const cameraConfig = React113.useMemo(() => {
|
|
4251
|
-
const size = Math.max(
|
|
4252
|
-
gridBounds.maxX - gridBounds.minX,
|
|
4253
|
-
gridBounds.maxZ - gridBounds.minZ
|
|
4254
|
-
);
|
|
4255
|
-
const distance = size * 1.5;
|
|
4256
|
-
switch (cameraMode) {
|
|
4257
|
-
case "isometric":
|
|
4258
|
-
return {
|
|
4259
|
-
position: [distance, distance * 0.8, distance],
|
|
4260
|
-
fov: 45
|
|
4261
|
-
};
|
|
4262
|
-
case "top-down":
|
|
4263
|
-
return {
|
|
4264
|
-
position: [0, distance * 2, 0],
|
|
4265
|
-
fov: 45
|
|
4266
|
-
};
|
|
4267
|
-
case "perspective":
|
|
4268
|
-
default:
|
|
4269
|
-
return {
|
|
4270
|
-
position: [distance, distance, distance],
|
|
4271
|
-
fov: 45
|
|
4272
|
-
};
|
|
4273
|
-
}
|
|
4274
|
-
}, [cameraMode, gridBounds]);
|
|
4275
|
-
const DefaultTileRenderer = React113.useCallback(
|
|
4276
|
-
({ tile, position }) => {
|
|
4277
|
-
const isSelected = tile.id ? selectedTileIds.includes(tile.id) : false;
|
|
4278
|
-
const isHovered = hoveredTile?.id === tile.id;
|
|
4279
|
-
const isValidMove = validMoves.some(
|
|
4280
|
-
(m) => m.x === tile.x && m.z === (tile.z ?? tile.y ?? 0)
|
|
4281
|
-
);
|
|
4282
|
-
const isAttackTarget = attackTargets.some(
|
|
4283
|
-
(m) => m.x === tile.x && m.z === (tile.z ?? tile.y ?? 0)
|
|
4284
|
-
);
|
|
4285
|
-
let color = 8421504;
|
|
4286
|
-
if (tile.type === "water") color = 4491468;
|
|
4287
|
-
else if (tile.type === "grass") color = 4500036;
|
|
4288
|
-
else if (tile.type === "sand") color = 14535816;
|
|
4289
|
-
else if (tile.type === "rock") color = 8947848;
|
|
4290
|
-
else if (tile.type === "snow") color = 15658734;
|
|
4291
|
-
let emissive = 0;
|
|
4292
|
-
if (isSelected) emissive = 4473924;
|
|
4293
|
-
else if (isAttackTarget) emissive = 4456448;
|
|
4294
|
-
else if (isValidMove) emissive = 17408;
|
|
4295
|
-
else if (isHovered) emissive = 2236962;
|
|
4296
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4297
|
-
"mesh",
|
|
4298
|
-
{
|
|
4299
|
-
position,
|
|
4300
|
-
onClick: (e) => handleTileClick(tile, e),
|
|
4301
|
-
onPointerEnter: (e) => handleTileHover(tile, e),
|
|
4302
|
-
onPointerLeave: (e) => handleTileHover(null, e),
|
|
4303
|
-
userData: { type: "tile", tileId: tile.id, gridX: tile.x, gridZ: tile.z ?? tile.y },
|
|
4304
|
-
children: [
|
|
4305
|
-
/* @__PURE__ */ jsxRuntime.jsx("boxGeometry", { args: [0.95, 0.2, 0.95] }),
|
|
4306
|
-
/* @__PURE__ */ jsxRuntime.jsx("meshStandardMaterial", { color, emissive })
|
|
4307
|
-
]
|
|
4308
|
-
}
|
|
4309
|
-
);
|
|
4310
|
-
},
|
|
4311
|
-
[selectedTileIds, hoveredTile, validMoves, attackTargets, handleTileClick, handleTileHover]
|
|
4312
|
-
);
|
|
4313
|
-
const DefaultUnitRenderer = React113.useCallback(
|
|
4314
|
-
({ unit, position }) => {
|
|
4315
|
-
const isSelected = selectedUnitId === unit.id;
|
|
4316
|
-
const color = unit.faction === "player" ? 4491519 : unit.faction === "enemy" ? 16729156 : 16777028;
|
|
4317
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4318
|
-
"group",
|
|
4319
|
-
{
|
|
4320
|
-
position,
|
|
4321
|
-
onClick: (e) => handleUnitClick(unit, e),
|
|
4322
|
-
userData: { type: "unit", unitId: unit.id },
|
|
4323
|
-
children: [
|
|
4324
|
-
isSelected && /* @__PURE__ */ jsxRuntime.jsxs("mesh", { position: [0, 0.05, 0], rotation: [-Math.PI / 2, 0, 0], children: [
|
|
4325
|
-
/* @__PURE__ */ jsxRuntime.jsx("ringGeometry", { args: [0.4, 0.5, 32] }),
|
|
4326
|
-
/* @__PURE__ */ jsxRuntime.jsx("meshBasicMaterial", { color: "#ffff00", transparent: true, opacity: 0.8 })
|
|
4327
|
-
] }),
|
|
4328
|
-
/* @__PURE__ */ jsxRuntime.jsxs("mesh", { position: [0, 0.3, 0], children: [
|
|
4329
|
-
/* @__PURE__ */ jsxRuntime.jsx("cylinderGeometry", { args: [0.3, 0.3, 0.1, 8] }),
|
|
4330
|
-
/* @__PURE__ */ jsxRuntime.jsx("meshStandardMaterial", { color })
|
|
4331
|
-
] }),
|
|
4332
|
-
/* @__PURE__ */ jsxRuntime.jsxs("mesh", { position: [0, 0.6, 0], children: [
|
|
4333
|
-
/* @__PURE__ */ jsxRuntime.jsx("capsuleGeometry", { args: [0.2, 0.4, 4, 8] }),
|
|
4334
|
-
/* @__PURE__ */ jsxRuntime.jsx("meshStandardMaterial", { color })
|
|
4335
|
-
] }),
|
|
4336
|
-
/* @__PURE__ */ jsxRuntime.jsxs("mesh", { position: [0, 0.9, 0], children: [
|
|
4337
|
-
/* @__PURE__ */ jsxRuntime.jsx("sphereGeometry", { args: [0.12, 8, 8] }),
|
|
4338
|
-
/* @__PURE__ */ jsxRuntime.jsx("meshStandardMaterial", { color })
|
|
4339
|
-
] }),
|
|
4340
|
-
unit.health !== void 0 && unit.maxHealth !== void 0 && /* @__PURE__ */ jsxRuntime.jsxs("group", { position: [0, 1.2, 0], children: [
|
|
4341
|
-
/* @__PURE__ */ jsxRuntime.jsxs("mesh", { position: [-0.25, 0, 0], children: [
|
|
4342
|
-
/* @__PURE__ */ jsxRuntime.jsx("planeGeometry", { args: [0.5, 0.05] }),
|
|
4343
|
-
/* @__PURE__ */ jsxRuntime.jsx("meshBasicMaterial", { color: 3355443 })
|
|
4344
|
-
] }),
|
|
4345
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
4346
|
-
"mesh",
|
|
4347
|
-
{
|
|
4348
|
-
position: [
|
|
4349
|
-
-0.25 + 0.5 * (unit.health / unit.maxHealth) / 2,
|
|
4350
|
-
0,
|
|
4351
|
-
0.01
|
|
4352
|
-
],
|
|
4353
|
-
children: [
|
|
4354
|
-
/* @__PURE__ */ jsxRuntime.jsx("planeGeometry", { args: [0.5 * (unit.health / unit.maxHealth), 0.05] }),
|
|
4355
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4356
|
-
"meshBasicMaterial",
|
|
4357
|
-
{
|
|
4358
|
-
color: unit.health / unit.maxHealth > 0.5 ? 4500036 : unit.health / unit.maxHealth > 0.25 ? 11184708 : 16729156
|
|
4359
|
-
}
|
|
4360
|
-
)
|
|
4361
|
-
]
|
|
4362
|
-
}
|
|
4363
|
-
)
|
|
4364
|
-
] })
|
|
4365
|
-
]
|
|
4366
|
-
}
|
|
4367
|
-
);
|
|
4368
|
-
},
|
|
4369
|
-
[selectedUnitId, handleUnitClick]
|
|
4370
|
-
);
|
|
4371
|
-
const DefaultFeatureRenderer = React113.useCallback(
|
|
4372
|
-
({
|
|
4373
|
-
feature,
|
|
4374
|
-
position
|
|
4375
|
-
}) => {
|
|
4376
|
-
if (feature.assetUrl) {
|
|
4377
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4378
|
-
ModelLoader,
|
|
4379
|
-
{
|
|
4380
|
-
url: feature.assetUrl,
|
|
4381
|
-
position,
|
|
4382
|
-
scale: 0.5,
|
|
4383
|
-
rotation: [0, feature.rotation ?? 0, 0],
|
|
4384
|
-
onClick: () => handleFeatureClick(feature, null),
|
|
4385
|
-
fallbackGeometry: "box"
|
|
4386
|
-
},
|
|
4387
|
-
feature.id
|
|
4388
|
-
);
|
|
4389
|
-
}
|
|
4390
|
-
if (feature.type === "tree") {
|
|
4391
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4392
|
-
"group",
|
|
4393
|
-
{
|
|
4394
|
-
position,
|
|
4395
|
-
onClick: (e) => handleFeatureClick(feature, e),
|
|
4396
|
-
userData: { type: "feature", featureId: feature.id },
|
|
4397
|
-
children: [
|
|
4398
|
-
/* @__PURE__ */ jsxRuntime.jsxs("mesh", { position: [0, 0.4, 0], children: [
|
|
4399
|
-
/* @__PURE__ */ jsxRuntime.jsx("cylinderGeometry", { args: [0.1, 0.15, 0.8, 6] }),
|
|
4400
|
-
/* @__PURE__ */ jsxRuntime.jsx("meshStandardMaterial", { color: 9127187 })
|
|
4401
|
-
] }),
|
|
4402
|
-
/* @__PURE__ */ jsxRuntime.jsxs("mesh", { position: [0, 0.9, 0], children: [
|
|
4403
|
-
/* @__PURE__ */ jsxRuntime.jsx("coneGeometry", { args: [0.5, 0.8, 8] }),
|
|
4404
|
-
/* @__PURE__ */ jsxRuntime.jsx("meshStandardMaterial", { color: 2263842 })
|
|
4405
|
-
] })
|
|
4406
|
-
]
|
|
4407
|
-
}
|
|
4408
|
-
);
|
|
4409
|
-
}
|
|
4410
|
-
if (feature.type === "rock") {
|
|
4411
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4412
|
-
"mesh",
|
|
4413
|
-
{
|
|
4414
|
-
position: [position[0], position[1] + 0.3, position[2]],
|
|
4415
|
-
onClick: (e) => handleFeatureClick(feature, e),
|
|
4416
|
-
userData: { type: "feature", featureId: feature.id },
|
|
4417
|
-
children: [
|
|
4418
|
-
/* @__PURE__ */ jsxRuntime.jsx("dodecahedronGeometry", { args: [0.3, 0] }),
|
|
4419
|
-
/* @__PURE__ */ jsxRuntime.jsx("meshStandardMaterial", { color: 8421504 })
|
|
4420
|
-
]
|
|
4421
|
-
}
|
|
4422
|
-
);
|
|
4423
|
-
}
|
|
4424
|
-
return null;
|
|
4425
|
-
},
|
|
4426
|
-
[handleFeatureClick]
|
|
4427
|
-
);
|
|
4428
|
-
if (externalLoading || assetsLoading && preloadAssets.length > 0) {
|
|
4429
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4430
|
-
Canvas3DLoadingState,
|
|
4431
|
-
{
|
|
4432
|
-
progress,
|
|
4433
|
-
loaded,
|
|
4434
|
-
total,
|
|
4435
|
-
message: loadingMessage,
|
|
4436
|
-
className
|
|
4437
|
-
}
|
|
4438
|
-
);
|
|
4439
|
-
}
|
|
4440
|
-
const displayError = externalError || internalError;
|
|
4441
|
-
if (displayError) {
|
|
4442
|
-
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: [
|
|
4443
|
-
"Error: ",
|
|
4444
|
-
displayError
|
|
4445
|
-
] }) }) });
|
|
4446
|
-
}
|
|
4447
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4448
|
-
Canvas3DErrorBoundary,
|
|
4449
|
-
{
|
|
4450
|
-
onError: (err) => setInternalError(err.message),
|
|
4451
|
-
onReset: () => setInternalError(null),
|
|
4452
|
-
children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4453
|
-
"div",
|
|
4454
|
-
{
|
|
4455
|
-
ref: containerRef,
|
|
4456
|
-
className: `game-canvas-3d ${className || ""}`,
|
|
4457
|
-
"data-orientation": orientation,
|
|
4458
|
-
"data-camera-mode": cameraMode,
|
|
4459
|
-
"data-overlay": overlay,
|
|
4460
|
-
children: [
|
|
4461
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
4462
|
-
fiber.Canvas,
|
|
4463
|
-
{
|
|
4464
|
-
shadows,
|
|
4465
|
-
camera: {
|
|
4466
|
-
position: cameraConfig.position,
|
|
4467
|
-
fov: cameraConfig.fov,
|
|
4468
|
-
near: 0.1,
|
|
4469
|
-
far: 1e3
|
|
4470
|
-
},
|
|
4471
|
-
style: { background: backgroundColor },
|
|
4472
|
-
onClick: (e) => {
|
|
4473
|
-
if (e.target === e.currentTarget) {
|
|
4474
|
-
eventHandlers.handleCanvasClick(e);
|
|
4475
|
-
}
|
|
4476
|
-
},
|
|
4477
|
-
children: [
|
|
4478
|
-
/* @__PURE__ */ jsxRuntime.jsx(CameraController, { onCameraChange: eventHandlers.handleCameraChange }),
|
|
4479
|
-
/* @__PURE__ */ jsxRuntime.jsx("ambientLight", { intensity: 0.6 }),
|
|
4480
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4481
|
-
"directionalLight",
|
|
4482
|
-
{
|
|
4483
|
-
position: [10, 20, 10],
|
|
4484
|
-
intensity: 0.8,
|
|
4485
|
-
castShadow: shadows,
|
|
4486
|
-
"shadow-mapSize": [2048, 2048]
|
|
4487
|
-
}
|
|
4488
|
-
),
|
|
4489
|
-
/* @__PURE__ */ jsxRuntime.jsx("hemisphereLight", { intensity: 0.3, color: "#87ceeb", groundColor: "#362d1d" }),
|
|
4490
|
-
showGrid && /* @__PURE__ */ jsxRuntime.jsx(
|
|
4491
|
-
drei.Grid,
|
|
4492
|
-
{
|
|
4493
|
-
args: [
|
|
4494
|
-
Math.max(gridBounds.maxX - gridBounds.minX + 2, 10),
|
|
4495
|
-
Math.max(gridBounds.maxZ - gridBounds.minZ + 2, 10)
|
|
4496
|
-
],
|
|
4497
|
-
position: [
|
|
4498
|
-
(gridBounds.maxX - gridBounds.minX) / 2 - 0.5,
|
|
4499
|
-
0,
|
|
4500
|
-
(gridBounds.maxZ - gridBounds.minZ) / 2 - 0.5
|
|
4501
|
-
],
|
|
4502
|
-
cellSize: 1,
|
|
4503
|
-
cellThickness: 1,
|
|
4504
|
-
cellColor: "#444444",
|
|
4505
|
-
sectionSize: 5,
|
|
4506
|
-
sectionThickness: 1.5,
|
|
4507
|
-
sectionColor: "#666666",
|
|
4508
|
-
fadeDistance: 50,
|
|
4509
|
-
fadeStrength: 1
|
|
4510
|
-
}
|
|
4511
|
-
),
|
|
4512
|
-
tiles.map((tile, index) => {
|
|
4513
|
-
const position = gridToWorld(
|
|
4514
|
-
tile.x,
|
|
4515
|
-
tile.z ?? tile.y ?? 0,
|
|
4516
|
-
tile.elevation ?? 0
|
|
4517
|
-
);
|
|
4518
|
-
const Renderer = CustomTileRenderer || DefaultTileRenderer;
|
|
4519
|
-
return /* @__PURE__ */ jsxRuntime.jsx(Renderer, { tile, position }, tile.id ?? `tile-${index}`);
|
|
4520
|
-
}),
|
|
4521
|
-
features.map((feature, index) => {
|
|
4522
|
-
const position = gridToWorld(
|
|
4523
|
-
feature.x,
|
|
4524
|
-
feature.z ?? feature.y ?? 0,
|
|
4525
|
-
(feature.elevation ?? 0) + 0.5
|
|
4526
|
-
);
|
|
4527
|
-
const Renderer = CustomFeatureRenderer || DefaultFeatureRenderer;
|
|
4528
|
-
return /* @__PURE__ */ jsxRuntime.jsx(Renderer, { feature, position }, feature.id ?? `feature-${index}`);
|
|
4529
|
-
}),
|
|
4530
|
-
units.map((unit) => {
|
|
4531
|
-
const position = gridToWorld(
|
|
4532
|
-
unit.x ?? 0,
|
|
4533
|
-
unit.z ?? unit.y ?? 0,
|
|
4534
|
-
(unit.elevation ?? 0) + 0.5
|
|
4535
|
-
);
|
|
4536
|
-
const Renderer = CustomUnitRenderer || DefaultUnitRenderer;
|
|
4537
|
-
return /* @__PURE__ */ jsxRuntime.jsx(Renderer, { unit, position }, unit.id);
|
|
4538
|
-
}),
|
|
4539
|
-
children,
|
|
4540
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4541
|
-
drei.OrbitControls,
|
|
4542
|
-
{
|
|
4543
|
-
ref: controlsRef,
|
|
4544
|
-
target: cameraTarget,
|
|
4545
|
-
enableDamping: true,
|
|
4546
|
-
dampingFactor: 0.05,
|
|
4547
|
-
minDistance: 2,
|
|
4548
|
-
maxDistance: 100,
|
|
4549
|
-
maxPolarAngle: Math.PI / 2 - 0.1
|
|
4550
|
-
}
|
|
4551
|
-
)
|
|
4552
|
-
]
|
|
4553
|
-
}
|
|
4554
|
-
),
|
|
4555
|
-
showCoordinates && hoveredTile && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "game-canvas-3d__coordinates", children: [
|
|
4556
|
-
"X: ",
|
|
4557
|
-
hoveredTile.x,
|
|
4558
|
-
", Z: ",
|
|
4559
|
-
hoveredTile.z ?? hoveredTile.y ?? 0
|
|
4560
|
-
] }),
|
|
4561
|
-
showTileInfo && hoveredTile && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "game-canvas-3d__tile-info", children: [
|
|
4562
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "tile-info__type", children: hoveredTile.type }),
|
|
4563
|
-
hoveredTile.terrain && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "tile-info__terrain", children: hoveredTile.terrain })
|
|
4564
|
-
] })
|
|
4565
|
-
]
|
|
4566
|
-
}
|
|
4567
|
-
)
|
|
4568
|
-
}
|
|
4569
|
-
);
|
|
4570
|
-
}
|
|
4571
|
-
);
|
|
4572
|
-
GameCanvas3D.displayName = "GameCanvas3D";
|
|
4573
|
-
var SuspenseConfigContext = React113.createContext({ enabled: false });
|
|
4574
|
-
React113.createContext(false);
|
|
3189
|
+
lazyThree("Camera3D", () => import('@almadar/ui/components/organisms/game/three'));
|
|
3190
|
+
lazyThree("Canvas3DErrorBoundary", () => import('@almadar/ui/components/organisms/game/three'));
|
|
3191
|
+
lazyThree("Canvas3DLoadingState", () => import('@almadar/ui/components/organisms/game/three'));
|
|
3192
|
+
lazyThree("FeatureRenderer", () => import('@almadar/ui/components/organisms/game/three'));
|
|
3193
|
+
lazyThree("FeatureRenderer3D", () => import('@almadar/ui/components/organisms/game/three'));
|
|
3194
|
+
lazyThree("GameCanvas3D", () => import('@almadar/ui/components/organisms/game/three'));
|
|
3195
|
+
lazyThree("GameCanvas3DBattleTemplate", () => import('@almadar/ui/components/organisms/game/three'));
|
|
3196
|
+
lazyThree("GameCanvas3DCastleTemplate", () => import('@almadar/ui/components/organisms/game/three'));
|
|
3197
|
+
lazyThree("GameCanvas3DWorldMapTemplate", () => import('@almadar/ui/components/organisms/game/three'));
|
|
3198
|
+
lazyThree("Lighting3D", () => import('@almadar/ui/components/organisms/game/three'));
|
|
3199
|
+
lazyThree("ModelLoader", () => import('@almadar/ui/components/organisms/game/three'));
|
|
3200
|
+
lazyThree("PhysicsObject3D", () => import('@almadar/ui/components/organisms/game/three'));
|
|
3201
|
+
lazyThree("Scene3D", () => import('@almadar/ui/components/organisms/game/three'));
|
|
3202
|
+
lazyThree("TileRenderer", () => import('@almadar/ui/components/organisms/game/three'));
|
|
3203
|
+
lazyThree("UnitRenderer", () => import('@almadar/ui/components/organisms/game/three'));
|
|
3204
|
+
var SuspenseConfigContext = React110.createContext({ enabled: false });
|
|
3205
|
+
React110.createContext(false);
|
|
4575
3206
|
function SuspenseConfigProvider({
|
|
4576
3207
|
config,
|
|
4577
3208
|
children
|
|
4578
3209
|
}) {
|
|
4579
|
-
return
|
|
3210
|
+
return React110__namespace.default.createElement(
|
|
4580
3211
|
SuspenseConfigContext.Provider,
|
|
4581
3212
|
{ value: config },
|
|
4582
3213
|
children
|
|
@@ -4621,8 +3252,8 @@ function VerificationProvider({
|
|
|
4621
3252
|
}) {
|
|
4622
3253
|
const isEnabled = enabled ?? (typeof process !== "undefined" && process.env?.NODE_ENV !== "production");
|
|
4623
3254
|
const eventBus = useEventBus();
|
|
4624
|
-
const pendingRef =
|
|
4625
|
-
|
|
3255
|
+
const pendingRef = React110.useRef(/* @__PURE__ */ new Map());
|
|
3256
|
+
React110.useEffect(() => {
|
|
4626
3257
|
if (!isEnabled) return;
|
|
4627
3258
|
if (!eventBus.onAny) return;
|
|
4628
3259
|
const unsub = eventBus.onAny((evt) => {
|
|
@@ -4683,7 +3314,7 @@ function VerificationProvider({
|
|
|
4683
3314
|
);
|
|
4684
3315
|
return unsub;
|
|
4685
3316
|
}, [isEnabled, eventBus]);
|
|
4686
|
-
|
|
3317
|
+
React110.useEffect(() => {
|
|
4687
3318
|
if (!isEnabled) return;
|
|
4688
3319
|
if (!runtimeManager) return;
|
|
4689
3320
|
runtimeManager.setObserver({
|
|
@@ -4705,11 +3336,11 @@ function VerificationProvider({
|
|
|
4705
3336
|
"pass"
|
|
4706
3337
|
);
|
|
4707
3338
|
}, [isEnabled, runtimeManager]);
|
|
4708
|
-
|
|
3339
|
+
React110.useEffect(() => {
|
|
4709
3340
|
if (!isEnabled) return;
|
|
4710
3341
|
bindEventBus(eventBus);
|
|
4711
3342
|
}, [isEnabled, eventBus]);
|
|
4712
|
-
|
|
3343
|
+
React110.useEffect(() => {
|
|
4713
3344
|
if (!isEnabled) return;
|
|
4714
3345
|
if (traitStateGetter) {
|
|
4715
3346
|
bindTraitStateGetter(traitStateGetter);
|
|
@@ -4723,7 +3354,7 @@ function VerificationProvider({
|
|
|
4723
3354
|
VerificationProvider.displayName = "VerificationProvider";
|
|
4724
3355
|
function FetchedDataBridge({ children }) {
|
|
4725
3356
|
const fetchedData = useFetchedData();
|
|
4726
|
-
const adapter =
|
|
3357
|
+
const adapter = React110.useMemo(() => ({
|
|
4727
3358
|
getData: (entity) => fetchedData.getData(entity),
|
|
4728
3359
|
getById: (entity, id) => fetchedData.getById(entity, id),
|
|
4729
3360
|
isLoading: fetchedData.loading,
|
|
@@ -4743,7 +3374,7 @@ function OrbitalProvider({
|
|
|
4743
3374
|
suspense = false,
|
|
4744
3375
|
verification
|
|
4745
3376
|
}) {
|
|
4746
|
-
const suspenseConfig =
|
|
3377
|
+
const suspenseConfig = React110.useMemo(
|
|
4747
3378
|
() => ({ enabled: suspense }),
|
|
4748
3379
|
[suspense]
|
|
4749
3380
|
);
|
|
@@ -4763,15 +3394,15 @@ function OrbitalProvider({
|
|
|
4763
3394
|
);
|
|
4764
3395
|
}
|
|
4765
3396
|
OrbitalProvider.displayName = "OrbitalProvider";
|
|
4766
|
-
var OfflineModeContext =
|
|
3397
|
+
var OfflineModeContext = React110.createContext(null);
|
|
4767
3398
|
function OfflineModeProvider({
|
|
4768
3399
|
children,
|
|
4769
3400
|
...executorOptions
|
|
4770
3401
|
}) {
|
|
4771
|
-
const [forceOffline, setForceOffline] =
|
|
3402
|
+
const [forceOffline, setForceOffline] = React110.useState(false);
|
|
4772
3403
|
const executor = useOfflineExecutor(executorOptions);
|
|
4773
3404
|
const effectivelyOffline = executor.isOffline || forceOffline;
|
|
4774
|
-
const contextValue =
|
|
3405
|
+
const contextValue = React110.useMemo(
|
|
4775
3406
|
() => ({
|
|
4776
3407
|
...executor,
|
|
4777
3408
|
forceOffline,
|
|
@@ -4783,14 +3414,14 @@ function OfflineModeProvider({
|
|
|
4783
3414
|
return /* @__PURE__ */ jsxRuntime.jsx(OfflineModeContext.Provider, { value: contextValue, children });
|
|
4784
3415
|
}
|
|
4785
3416
|
function useOfflineMode() {
|
|
4786
|
-
const context =
|
|
3417
|
+
const context = React110.useContext(OfflineModeContext);
|
|
4787
3418
|
if (!context) {
|
|
4788
3419
|
throw new Error("useOfflineMode must be used within OfflineModeProvider");
|
|
4789
3420
|
}
|
|
4790
3421
|
return context;
|
|
4791
3422
|
}
|
|
4792
3423
|
function useOptionalOfflineMode() {
|
|
4793
|
-
return
|
|
3424
|
+
return React110.useContext(OfflineModeContext);
|
|
4794
3425
|
}
|
|
4795
3426
|
|
|
4796
3427
|
exports.EventBusContext = EventBusContext;
|