@almadar/ui 5.61.0 → 5.62.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 +3127 -1681
- package/dist/avl/index.js +1948 -502
- package/dist/components/core/molecules/GraphCanvas.d.ts +4 -0
- package/dist/components/core/templates/index.d.ts +4 -0
- package/dist/components/game/molecules/CardHand.d.ts +35 -0
- package/dist/components/game/molecules/DialogueBox.d.ts +8 -2
- package/dist/components/game/molecules/index.d.ts +1 -0
- package/dist/components/game/molecules/three/index.cjs +219 -115
- package/dist/components/game/molecules/three/index.js +219 -115
- package/dist/components/game/organisms/CardBattlerBoard.d.ts +46 -0
- package/dist/components/game/organisms/CityBuilderBoard.d.ts +63 -0
- package/dist/components/game/organisms/TopDownShooterBoard.d.ts +64 -0
- package/dist/components/game/organisms/TowerDefenseBoard.d.ts +10 -1
- package/dist/components/game/organisms/TraitSlot.d.ts +1 -3
- package/dist/components/game/organisms/VisualNovelBoard.d.ts +53 -0
- package/dist/components/game/organisms/index.d.ts +4 -0
- package/dist/components/game/templates/CardBattlerTemplate.d.ts +35 -0
- package/dist/components/game/templates/CityBuilderTemplate.d.ts +40 -0
- package/dist/components/game/templates/GameCanvas3DBattleTemplate.d.ts +5 -2
- package/dist/components/game/templates/GameCanvas3DCastleTemplate.d.ts +5 -2
- package/dist/components/game/templates/GameCanvas3DWorldMapTemplate.d.ts +5 -2
- package/dist/components/game/templates/TopDownShooterTemplate.d.ts +42 -0
- package/dist/components/game/templates/VisualNovelTemplate.d.ts +28 -0
- package/dist/components/game/templates/game3dAssetManifest.d.ts +50 -0
- package/dist/components/game/templates/index.d.ts +4 -0
- package/dist/components/index.cjs +2993 -1529
- package/dist/components/index.js +1961 -506
- package/dist/docs/index.cjs +105 -1
- package/dist/docs/index.js +105 -1
- package/dist/hooks/index.cjs +105 -1
- package/dist/hooks/index.js +105 -1
- package/dist/locales/index.cjs +315 -3
- package/dist/locales/index.js +315 -3
- package/dist/providers/index.cjs +2936 -1490
- package/dist/providers/index.js +1924 -478
- package/dist/runtime/index.cjs +2992 -1546
- package/dist/runtime/index.js +1928 -482
- package/locales/ar.json +105 -1
- package/locales/en.json +105 -1
- package/locales/sl.json +105 -1
- package/package.json +1 -1
package/dist/providers/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import * as
|
|
2
|
-
import
|
|
1
|
+
import * as React85 from 'react';
|
|
2
|
+
import React85__default, { createContext, useContext, useMemo, useRef, useEffect, useCallback, Suspense, useState, useLayoutEffect, lazy, useId, useSyncExternalStore, forwardRef, useImperativeHandle, Component } from 'react';
|
|
3
3
|
import { EventBusContext, useTraitScope, TraitScopeProvider } from '@almadar/ui/providers';
|
|
4
4
|
import { createLogger, isLogLevelEnabled } from '@almadar/logger';
|
|
5
5
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
@@ -354,7 +354,7 @@ var init_Box = __esm({
|
|
|
354
354
|
fixed: "fixed",
|
|
355
355
|
sticky: "sticky"
|
|
356
356
|
};
|
|
357
|
-
Box =
|
|
357
|
+
Box = React85__default.forwardRef(
|
|
358
358
|
({
|
|
359
359
|
padding,
|
|
360
360
|
paddingX,
|
|
@@ -404,7 +404,7 @@ var init_Box = __esm({
|
|
|
404
404
|
onMouseLeave?.(e);
|
|
405
405
|
}, [hoverEvent, eventBus, onMouseLeave]);
|
|
406
406
|
const isClickable = action || onClick;
|
|
407
|
-
return
|
|
407
|
+
return React85__default.createElement(
|
|
408
408
|
Component2,
|
|
409
409
|
{
|
|
410
410
|
ref,
|
|
@@ -499,7 +499,7 @@ function loadLib(key, importer) {
|
|
|
499
499
|
return p2;
|
|
500
500
|
}
|
|
501
501
|
function lazyFamilyIcon(libKey, importer, pick, fallbackName, family) {
|
|
502
|
-
const Lazy =
|
|
502
|
+
const Lazy = React85__default.lazy(async () => {
|
|
503
503
|
const lib = await loadLib(libKey, importer);
|
|
504
504
|
const Comp = pick(lib);
|
|
505
505
|
if (!Comp) {
|
|
@@ -509,7 +509,7 @@ function lazyFamilyIcon(libKey, importer, pick, fallbackName, family) {
|
|
|
509
509
|
return { default: Comp };
|
|
510
510
|
});
|
|
511
511
|
const Wrapped = (props) => /* @__PURE__ */ jsx(
|
|
512
|
-
|
|
512
|
+
React85__default.Suspense,
|
|
513
513
|
{
|
|
514
514
|
fallback: /* @__PURE__ */ jsx(
|
|
515
515
|
"span",
|
|
@@ -1235,7 +1235,7 @@ var init_Icon = __esm({
|
|
|
1235
1235
|
const directIcon = typeof icon === "string" ? void 0 : icon;
|
|
1236
1236
|
const effectiveName = typeof icon === "string" ? icon : name;
|
|
1237
1237
|
const family = useIconFamily();
|
|
1238
|
-
const RenderedComponent =
|
|
1238
|
+
const RenderedComponent = React85__default.useMemo(() => {
|
|
1239
1239
|
if (directIcon) return null;
|
|
1240
1240
|
return effectiveName ? resolveIconForFamily(effectiveName, family) : null;
|
|
1241
1241
|
}, [directIcon, effectiveName, family]);
|
|
@@ -1294,7 +1294,7 @@ function resolveIconProp(value, sizeClass) {
|
|
|
1294
1294
|
const IconComp = value;
|
|
1295
1295
|
return /* @__PURE__ */ jsx(IconComp, { className: sizeClass });
|
|
1296
1296
|
}
|
|
1297
|
-
if (
|
|
1297
|
+
if (React85__default.isValidElement(value)) {
|
|
1298
1298
|
return value;
|
|
1299
1299
|
}
|
|
1300
1300
|
if (typeof value === "object" && value !== null && "render" in value) {
|
|
@@ -1370,7 +1370,7 @@ var init_Button = __esm({
|
|
|
1370
1370
|
md: "h-icon-default w-icon-default",
|
|
1371
1371
|
lg: "h-icon-default w-icon-default"
|
|
1372
1372
|
};
|
|
1373
|
-
Button =
|
|
1373
|
+
Button = React85__default.forwardRef(
|
|
1374
1374
|
({
|
|
1375
1375
|
className,
|
|
1376
1376
|
variant = "primary",
|
|
@@ -1435,7 +1435,7 @@ var Dialog;
|
|
|
1435
1435
|
var init_Dialog = __esm({
|
|
1436
1436
|
"components/core/atoms/Dialog.tsx"() {
|
|
1437
1437
|
init_cn();
|
|
1438
|
-
Dialog =
|
|
1438
|
+
Dialog = React85__default.forwardRef(
|
|
1439
1439
|
({
|
|
1440
1440
|
role = "dialog",
|
|
1441
1441
|
"aria-modal": ariaModal = true,
|
|
@@ -2049,7 +2049,7 @@ var init_Badge = __esm({
|
|
|
2049
2049
|
md: "px-2.5 py-1 text-sm",
|
|
2050
2050
|
lg: "px-3 py-1.5 text-base"
|
|
2051
2051
|
};
|
|
2052
|
-
Badge =
|
|
2052
|
+
Badge = React85__default.forwardRef(
|
|
2053
2053
|
({ className, variant = "default", size = "sm", amount, label, icon, children, onRemove, removeLabel, ...props }, ref) => {
|
|
2054
2054
|
const iconSizes3 = {
|
|
2055
2055
|
sm: "h-icon-default w-icon-default",
|
|
@@ -2385,7 +2385,7 @@ var init_SvgFlow = __esm({
|
|
|
2385
2385
|
width = 100,
|
|
2386
2386
|
height = 100
|
|
2387
2387
|
}) => {
|
|
2388
|
-
const markerId =
|
|
2388
|
+
const markerId = React85__default.useMemo(() => {
|
|
2389
2389
|
flowIdCounter += 1;
|
|
2390
2390
|
return `almadar-flow-arrow-${flowIdCounter}`;
|
|
2391
2391
|
}, []);
|
|
@@ -2978,7 +2978,7 @@ var init_SvgRing = __esm({
|
|
|
2978
2978
|
width = 100,
|
|
2979
2979
|
height = 100
|
|
2980
2980
|
}) => {
|
|
2981
|
-
const gradientId =
|
|
2981
|
+
const gradientId = React85__default.useMemo(() => {
|
|
2982
2982
|
ringIdCounter += 1;
|
|
2983
2983
|
return `almadar-ring-glow-${ringIdCounter}`;
|
|
2984
2984
|
}, []);
|
|
@@ -3159,7 +3159,7 @@ var init_Input = __esm({
|
|
|
3159
3159
|
init_cn();
|
|
3160
3160
|
init_Icon();
|
|
3161
3161
|
init_useEventBus();
|
|
3162
|
-
Input =
|
|
3162
|
+
Input = React85__default.forwardRef(
|
|
3163
3163
|
({
|
|
3164
3164
|
className,
|
|
3165
3165
|
inputType,
|
|
@@ -3319,7 +3319,7 @@ var Label;
|
|
|
3319
3319
|
var init_Label = __esm({
|
|
3320
3320
|
"components/core/atoms/Label.tsx"() {
|
|
3321
3321
|
init_cn();
|
|
3322
|
-
Label =
|
|
3322
|
+
Label = React85__default.forwardRef(
|
|
3323
3323
|
({ className, required, children, ...props }, ref) => {
|
|
3324
3324
|
return /* @__PURE__ */ jsxs(
|
|
3325
3325
|
"label",
|
|
@@ -3346,7 +3346,7 @@ var init_Textarea = __esm({
|
|
|
3346
3346
|
"components/core/atoms/Textarea.tsx"() {
|
|
3347
3347
|
init_cn();
|
|
3348
3348
|
init_useEventBus();
|
|
3349
|
-
Textarea =
|
|
3349
|
+
Textarea = React85__default.forwardRef(
|
|
3350
3350
|
({ className, error, onChange, ...props }, ref) => {
|
|
3351
3351
|
const eventBus = useEventBus();
|
|
3352
3352
|
const handleChange = (e) => {
|
|
@@ -3585,7 +3585,7 @@ var init_Select = __esm({
|
|
|
3585
3585
|
init_cn();
|
|
3586
3586
|
init_Icon();
|
|
3587
3587
|
init_useEventBus();
|
|
3588
|
-
Select =
|
|
3588
|
+
Select = React85__default.forwardRef(
|
|
3589
3589
|
(props, _ref) => {
|
|
3590
3590
|
const { multiple, searchable, clearable } = props;
|
|
3591
3591
|
if (multiple || searchable || clearable) {
|
|
@@ -3602,7 +3602,7 @@ var init_Checkbox = __esm({
|
|
|
3602
3602
|
"components/core/atoms/Checkbox.tsx"() {
|
|
3603
3603
|
init_cn();
|
|
3604
3604
|
init_useEventBus();
|
|
3605
|
-
Checkbox =
|
|
3605
|
+
Checkbox = React85__default.forwardRef(
|
|
3606
3606
|
({ className, label, id, onChange, ...props }, ref) => {
|
|
3607
3607
|
const inputId = id || `checkbox-${Math.random().toString(36).substr(2, 9)}`;
|
|
3608
3608
|
const eventBus = useEventBus();
|
|
@@ -3656,7 +3656,7 @@ var init_Spinner = __esm({
|
|
|
3656
3656
|
md: "h-6 w-6",
|
|
3657
3657
|
lg: "h-8 w-8"
|
|
3658
3658
|
};
|
|
3659
|
-
Spinner =
|
|
3659
|
+
Spinner = React85__default.forwardRef(
|
|
3660
3660
|
({ className, size = "md", overlay, ...props }, ref) => {
|
|
3661
3661
|
if (overlay) {
|
|
3662
3662
|
return /* @__PURE__ */ jsx(
|
|
@@ -3746,7 +3746,7 @@ var init_Card = __esm({
|
|
|
3746
3746
|
chip: "shadow-none rounded-pill border-[length:var(--border-width)] border-border",
|
|
3747
3747
|
"tile-image-first": "p-0 overflow-hidden"
|
|
3748
3748
|
};
|
|
3749
|
-
Card =
|
|
3749
|
+
Card = React85__default.forwardRef(
|
|
3750
3750
|
({
|
|
3751
3751
|
className,
|
|
3752
3752
|
variant = "bordered",
|
|
@@ -3794,9 +3794,9 @@ var init_Card = __esm({
|
|
|
3794
3794
|
}
|
|
3795
3795
|
);
|
|
3796
3796
|
Card.displayName = "Card";
|
|
3797
|
-
CardHeader =
|
|
3797
|
+
CardHeader = React85__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("mb-4", className), ...props }));
|
|
3798
3798
|
CardHeader.displayName = "CardHeader";
|
|
3799
|
-
CardTitle =
|
|
3799
|
+
CardTitle = React85__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
3800
3800
|
"h3",
|
|
3801
3801
|
{
|
|
3802
3802
|
ref,
|
|
@@ -3809,11 +3809,11 @@ var init_Card = __esm({
|
|
|
3809
3809
|
}
|
|
3810
3810
|
));
|
|
3811
3811
|
CardTitle.displayName = "CardTitle";
|
|
3812
|
-
CardContent =
|
|
3812
|
+
CardContent = React85__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("", className), ...props }));
|
|
3813
3813
|
CardContent.displayName = "CardContent";
|
|
3814
3814
|
CardBody = CardContent;
|
|
3815
3815
|
CardBody.displayName = "CardBody";
|
|
3816
|
-
CardFooter =
|
|
3816
|
+
CardFooter = React85__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
3817
3817
|
"div",
|
|
3818
3818
|
{
|
|
3819
3819
|
ref,
|
|
@@ -3868,7 +3868,7 @@ var init_FilterPill = __esm({
|
|
|
3868
3868
|
md: "w-3.5 h-3.5",
|
|
3869
3869
|
lg: "w-4 h-4"
|
|
3870
3870
|
};
|
|
3871
|
-
FilterPill =
|
|
3871
|
+
FilterPill = React85__default.forwardRef(
|
|
3872
3872
|
({
|
|
3873
3873
|
className,
|
|
3874
3874
|
variant = "default",
|
|
@@ -3997,8 +3997,8 @@ var init_Avatar = __esm({
|
|
|
3997
3997
|
actionPayload
|
|
3998
3998
|
}) => {
|
|
3999
3999
|
const eventBus = useEventBus();
|
|
4000
|
-
const [imgFailed, setImgFailed] =
|
|
4001
|
-
|
|
4000
|
+
const [imgFailed, setImgFailed] = React85__default.useState(false);
|
|
4001
|
+
React85__default.useEffect(() => {
|
|
4002
4002
|
setImgFailed(false);
|
|
4003
4003
|
}, [src]);
|
|
4004
4004
|
const initials = providedInitials ?? (name ? generateInitials(name) : void 0);
|
|
@@ -4383,7 +4383,7 @@ var init_Radio = __esm({
|
|
|
4383
4383
|
md: "w-2.5 h-2.5",
|
|
4384
4384
|
lg: "w-3 h-3"
|
|
4385
4385
|
};
|
|
4386
|
-
Radio =
|
|
4386
|
+
Radio = React85__default.forwardRef(
|
|
4387
4387
|
({
|
|
4388
4388
|
label,
|
|
4389
4389
|
helperText,
|
|
@@ -4400,12 +4400,12 @@ var init_Radio = __esm({
|
|
|
4400
4400
|
onChange,
|
|
4401
4401
|
...props
|
|
4402
4402
|
}, ref) => {
|
|
4403
|
-
const reactId =
|
|
4403
|
+
const reactId = React85__default.useId();
|
|
4404
4404
|
const baseId = id || `radio-${reactId}`;
|
|
4405
4405
|
const hasError = !!error;
|
|
4406
4406
|
const eventBus = useEventBus();
|
|
4407
|
-
const [selected, setSelected] =
|
|
4408
|
-
|
|
4407
|
+
const [selected, setSelected] = React85__default.useState(value);
|
|
4408
|
+
React85__default.useEffect(() => {
|
|
4409
4409
|
if (value !== void 0) setSelected(value);
|
|
4410
4410
|
}, [value]);
|
|
4411
4411
|
const pick = (next, e) => {
|
|
@@ -4587,7 +4587,7 @@ var init_Switch = __esm({
|
|
|
4587
4587
|
"components/core/atoms/Switch.tsx"() {
|
|
4588
4588
|
"use client";
|
|
4589
4589
|
init_cn();
|
|
4590
|
-
Switch =
|
|
4590
|
+
Switch = React85.forwardRef(
|
|
4591
4591
|
({
|
|
4592
4592
|
checked,
|
|
4593
4593
|
defaultChecked = false,
|
|
@@ -4598,10 +4598,10 @@ var init_Switch = __esm({
|
|
|
4598
4598
|
name,
|
|
4599
4599
|
className
|
|
4600
4600
|
}, ref) => {
|
|
4601
|
-
const [isChecked, setIsChecked] =
|
|
4601
|
+
const [isChecked, setIsChecked] = React85.useState(
|
|
4602
4602
|
checked !== void 0 ? checked : defaultChecked
|
|
4603
4603
|
);
|
|
4604
|
-
|
|
4604
|
+
React85.useEffect(() => {
|
|
4605
4605
|
if (checked !== void 0) {
|
|
4606
4606
|
setIsChecked(checked);
|
|
4607
4607
|
}
|
|
@@ -4956,7 +4956,7 @@ var Aside;
|
|
|
4956
4956
|
var init_Aside = __esm({
|
|
4957
4957
|
"components/core/atoms/Aside.tsx"() {
|
|
4958
4958
|
init_cn();
|
|
4959
|
-
Aside =
|
|
4959
|
+
Aside = React85__default.forwardRef(
|
|
4960
4960
|
({ className, children, ...rest }, ref) => /* @__PURE__ */ jsx("aside", { ref, className: cn(className), ...rest, children })
|
|
4961
4961
|
);
|
|
4962
4962
|
Aside.displayName = "Aside";
|
|
@@ -5034,8 +5034,8 @@ var init_LawReferenceTooltip = __esm({
|
|
|
5034
5034
|
className
|
|
5035
5035
|
}) => {
|
|
5036
5036
|
const { t } = useTranslate();
|
|
5037
|
-
const [isVisible, setIsVisible] =
|
|
5038
|
-
const timeoutRef =
|
|
5037
|
+
const [isVisible, setIsVisible] = React85__default.useState(false);
|
|
5038
|
+
const timeoutRef = React85__default.useRef(null);
|
|
5039
5039
|
const handleMouseEnter = () => {
|
|
5040
5040
|
if (timeoutRef.current) clearTimeout(timeoutRef.current);
|
|
5041
5041
|
timeoutRef.current = setTimeout(() => setIsVisible(true), 200);
|
|
@@ -5044,7 +5044,7 @@ var init_LawReferenceTooltip = __esm({
|
|
|
5044
5044
|
if (timeoutRef.current) clearTimeout(timeoutRef.current);
|
|
5045
5045
|
setIsVisible(false);
|
|
5046
5046
|
};
|
|
5047
|
-
|
|
5047
|
+
React85__default.useEffect(() => {
|
|
5048
5048
|
return () => {
|
|
5049
5049
|
if (timeoutRef.current) clearTimeout(timeoutRef.current);
|
|
5050
5050
|
};
|
|
@@ -5254,7 +5254,7 @@ var init_StatusDot = __esm({
|
|
|
5254
5254
|
md: "w-2.5 h-2.5",
|
|
5255
5255
|
lg: "w-3 h-3"
|
|
5256
5256
|
};
|
|
5257
|
-
StatusDot =
|
|
5257
|
+
StatusDot = React85__default.forwardRef(
|
|
5258
5258
|
({ className, status = "offline", pulse = false, size = "md", label, ...props }, ref) => {
|
|
5259
5259
|
return /* @__PURE__ */ jsx(
|
|
5260
5260
|
"span",
|
|
@@ -5308,7 +5308,7 @@ var init_TrendIndicator = __esm({
|
|
|
5308
5308
|
down: "trending-down",
|
|
5309
5309
|
flat: "arrow-right"
|
|
5310
5310
|
};
|
|
5311
|
-
TrendIndicator =
|
|
5311
|
+
TrendIndicator = React85__default.forwardRef(
|
|
5312
5312
|
({
|
|
5313
5313
|
className,
|
|
5314
5314
|
value,
|
|
@@ -5375,7 +5375,7 @@ var init_RangeSlider = __esm({
|
|
|
5375
5375
|
md: "w-4 h-4",
|
|
5376
5376
|
lg: "w-5 h-5"
|
|
5377
5377
|
};
|
|
5378
|
-
RangeSlider =
|
|
5378
|
+
RangeSlider = React85__default.forwardRef(
|
|
5379
5379
|
({
|
|
5380
5380
|
className,
|
|
5381
5381
|
min = 0,
|
|
@@ -5883,7 +5883,7 @@ var init_ContentSection = __esm({
|
|
|
5883
5883
|
md: "py-16",
|
|
5884
5884
|
lg: "py-24"
|
|
5885
5885
|
};
|
|
5886
|
-
ContentSection =
|
|
5886
|
+
ContentSection = React85__default.forwardRef(
|
|
5887
5887
|
({ children, background = "default", padding = "lg", id, className }, ref) => {
|
|
5888
5888
|
return /* @__PURE__ */ jsx(
|
|
5889
5889
|
Box,
|
|
@@ -6417,7 +6417,7 @@ var init_AnimatedReveal = __esm({
|
|
|
6417
6417
|
"scale-up": { opacity: 1, transform: "scale(1) translateY(0)" },
|
|
6418
6418
|
"none": {}
|
|
6419
6419
|
};
|
|
6420
|
-
AnimatedReveal =
|
|
6420
|
+
AnimatedReveal = React85__default.forwardRef(
|
|
6421
6421
|
({
|
|
6422
6422
|
trigger = "scroll",
|
|
6423
6423
|
animation = "fade-up",
|
|
@@ -6577,7 +6577,7 @@ var init_AnimatedGraphic = __esm({
|
|
|
6577
6577
|
"components/marketing/atoms/AnimatedGraphic.tsx"() {
|
|
6578
6578
|
"use client";
|
|
6579
6579
|
init_cn();
|
|
6580
|
-
AnimatedGraphic =
|
|
6580
|
+
AnimatedGraphic = React85__default.forwardRef(
|
|
6581
6581
|
({
|
|
6582
6582
|
src,
|
|
6583
6583
|
svgContent,
|
|
@@ -6600,7 +6600,7 @@ var init_AnimatedGraphic = __esm({
|
|
|
6600
6600
|
const fetchedSvg = useFetchedSvg(svgContent ? void 0 : src);
|
|
6601
6601
|
const resolvedSvg = svgContent ?? fetchedSvg;
|
|
6602
6602
|
const prevAnimateRef = useRef(animate);
|
|
6603
|
-
const setRef =
|
|
6603
|
+
const setRef = React85__default.useCallback(
|
|
6604
6604
|
(node) => {
|
|
6605
6605
|
containerRef.current = node;
|
|
6606
6606
|
if (typeof ref === "function") ref(node);
|
|
@@ -6826,9 +6826,9 @@ function ScoreDisplay({
|
|
|
6826
6826
|
...rest
|
|
6827
6827
|
}) {
|
|
6828
6828
|
const resolvedValue = typeof value === "number" && !Number.isNaN(value) ? value : typeof rest.score === "number" && !Number.isNaN(rest.score) ? rest.score : 0;
|
|
6829
|
-
const [displayValue, setDisplayValue] =
|
|
6830
|
-
const [isAnimating, setIsAnimating] =
|
|
6831
|
-
|
|
6829
|
+
const [displayValue, setDisplayValue] = React85.useState(resolvedValue);
|
|
6830
|
+
const [isAnimating, setIsAnimating] = React85.useState(false);
|
|
6831
|
+
React85.useEffect(() => {
|
|
6832
6832
|
if (!animated || displayValue === resolvedValue) {
|
|
6833
6833
|
setDisplayValue(resolvedValue);
|
|
6834
6834
|
return;
|
|
@@ -6911,9 +6911,9 @@ function ControlButton({
|
|
|
6911
6911
|
className
|
|
6912
6912
|
}) {
|
|
6913
6913
|
const eventBus = useEventBus();
|
|
6914
|
-
const [isPressed, setIsPressed] =
|
|
6914
|
+
const [isPressed, setIsPressed] = React85.useState(false);
|
|
6915
6915
|
const actualPressed = pressed ?? isPressed;
|
|
6916
|
-
const handlePointerDown =
|
|
6916
|
+
const handlePointerDown = React85.useCallback(
|
|
6917
6917
|
(e) => {
|
|
6918
6918
|
e.preventDefault();
|
|
6919
6919
|
if (disabled) return;
|
|
@@ -6923,7 +6923,7 @@ function ControlButton({
|
|
|
6923
6923
|
},
|
|
6924
6924
|
[disabled, pressEvent, eventBus, onPress]
|
|
6925
6925
|
);
|
|
6926
|
-
const handlePointerUp =
|
|
6926
|
+
const handlePointerUp = React85.useCallback(
|
|
6927
6927
|
(e) => {
|
|
6928
6928
|
e.preventDefault();
|
|
6929
6929
|
if (disabled) return;
|
|
@@ -6933,7 +6933,7 @@ function ControlButton({
|
|
|
6933
6933
|
},
|
|
6934
6934
|
[disabled, releaseEvent, eventBus, onRelease]
|
|
6935
6935
|
);
|
|
6936
|
-
const handlePointerLeave =
|
|
6936
|
+
const handlePointerLeave = React85.useCallback(
|
|
6937
6937
|
(e) => {
|
|
6938
6938
|
if (isPressed) {
|
|
6939
6939
|
setIsPressed(false);
|
|
@@ -7554,8 +7554,8 @@ function XPBar({
|
|
|
7554
7554
|
}) {
|
|
7555
7555
|
const sizes = sizeMap9[size];
|
|
7556
7556
|
const percentage = max > 0 ? Math.max(0, Math.min(100, current / max * 100)) : 0;
|
|
7557
|
-
const [fillWidth, setFillWidth] =
|
|
7558
|
-
|
|
7557
|
+
const [fillWidth, setFillWidth] = React85.useState(animated ? 0 : percentage);
|
|
7558
|
+
React85.useEffect(() => {
|
|
7559
7559
|
if (!animated) {
|
|
7560
7560
|
setFillWidth(percentage);
|
|
7561
7561
|
return;
|
|
@@ -8043,9 +8043,9 @@ function MiniMap({
|
|
|
8043
8043
|
viewportRect = DEFAULT_VIEWPORT,
|
|
8044
8044
|
className
|
|
8045
8045
|
}) {
|
|
8046
|
-
const canvasRef =
|
|
8047
|
-
const frameRef =
|
|
8048
|
-
|
|
8046
|
+
const canvasRef = React85.useRef(null);
|
|
8047
|
+
const frameRef = React85.useRef(0);
|
|
8048
|
+
React85.useEffect(() => {
|
|
8049
8049
|
const canvas = canvasRef.current;
|
|
8050
8050
|
if (!canvas) return;
|
|
8051
8051
|
const ctx = canvas.getContext("2d");
|
|
@@ -8234,7 +8234,7 @@ var init_ErrorBoundary = __esm({
|
|
|
8234
8234
|
}
|
|
8235
8235
|
);
|
|
8236
8236
|
};
|
|
8237
|
-
ErrorBoundary = class extends
|
|
8237
|
+
ErrorBoundary = class extends React85__default.Component {
|
|
8238
8238
|
constructor(props) {
|
|
8239
8239
|
super(props);
|
|
8240
8240
|
__publicField(this, "reset", () => {
|
|
@@ -9625,8 +9625,8 @@ function ActionButtons({
|
|
|
9625
9625
|
disabled
|
|
9626
9626
|
}) {
|
|
9627
9627
|
const eventBus = useEventBus();
|
|
9628
|
-
const [activeButtons, setActiveButtons] =
|
|
9629
|
-
const handlePress =
|
|
9628
|
+
const [activeButtons, setActiveButtons] = React85.useState(/* @__PURE__ */ new Set());
|
|
9629
|
+
const handlePress = React85.useCallback(
|
|
9630
9630
|
(id) => {
|
|
9631
9631
|
setActiveButtons((prev) => new Set(prev).add(id));
|
|
9632
9632
|
if (actionEvent) eventBus.emit(`UI:${actionEvent}`, { id, pressed: true });
|
|
@@ -9634,7 +9634,7 @@ function ActionButtons({
|
|
|
9634
9634
|
},
|
|
9635
9635
|
[actionEvent, eventBus, onAction]
|
|
9636
9636
|
);
|
|
9637
|
-
const handleRelease =
|
|
9637
|
+
const handleRelease = React85.useCallback(
|
|
9638
9638
|
(id) => {
|
|
9639
9639
|
setActiveButtons((prev) => {
|
|
9640
9640
|
const next = new Set(prev);
|
|
@@ -10271,8 +10271,8 @@ var init_AnimatedCounter = __esm({
|
|
|
10271
10271
|
const [displayValue, setDisplayValue] = useState("0");
|
|
10272
10272
|
const [hasAnimated, setHasAnimated] = useState(false);
|
|
10273
10273
|
const animate = useCallback(() => {
|
|
10274
|
-
const { num:
|
|
10275
|
-
if (
|
|
10274
|
+
const { num: num3, prefix, suffix, decimals } = parseValue(value);
|
|
10275
|
+
if (num3 === 0) {
|
|
10276
10276
|
setDisplayValue(String(value));
|
|
10277
10277
|
return;
|
|
10278
10278
|
}
|
|
@@ -10281,7 +10281,7 @@ var init_AnimatedCounter = __esm({
|
|
|
10281
10281
|
const elapsed = now - startTime;
|
|
10282
10282
|
const progress = Math.min(elapsed / duration, 1);
|
|
10283
10283
|
const eased = 1 - Math.pow(1 - progress, 3);
|
|
10284
|
-
const current = eased *
|
|
10284
|
+
const current = eased * num3;
|
|
10285
10285
|
setDisplayValue(`${prefix}${current.toFixed(decimals)}${suffix}`);
|
|
10286
10286
|
if (progress < 1) {
|
|
10287
10287
|
requestAnimationFrame(tick);
|
|
@@ -11099,7 +11099,7 @@ function IsometricCanvas({
|
|
|
11099
11099
|
// Tuning
|
|
11100
11100
|
diamondTopY: diamondTopYProp,
|
|
11101
11101
|
// Remote asset loading
|
|
11102
|
-
assetBaseUrl
|
|
11102
|
+
assetBaseUrl,
|
|
11103
11103
|
assetManifest
|
|
11104
11104
|
}) {
|
|
11105
11105
|
const tilesProp = Array.isArray(_tilesPropRaw) ? _tilesPropRaw : [];
|
|
@@ -11178,7 +11178,7 @@ function IsometricCanvas({
|
|
|
11178
11178
|
const attackTargetSet = useMemo(() => {
|
|
11179
11179
|
return new Set(attackTargets.map((p2) => `${p2.x},${p2.y}`));
|
|
11180
11180
|
}, [attackTargets]);
|
|
11181
|
-
const
|
|
11181
|
+
const resolveManifestUrl7 = useCallback((relativePath) => {
|
|
11182
11182
|
if (!relativePath) return void 0;
|
|
11183
11183
|
if (assetBaseUrl) return `${assetBaseUrl.replace(/\/$/, "")}${relativePath.startsWith("/") ? "" : "/"}${relativePath}`;
|
|
11184
11184
|
return relativePath;
|
|
@@ -11191,7 +11191,7 @@ function IsometricCanvas({
|
|
|
11191
11191
|
const url = getTerrainSprite(tile.terrain ?? "");
|
|
11192
11192
|
if (url) urls.push(url);
|
|
11193
11193
|
} else {
|
|
11194
|
-
const url =
|
|
11194
|
+
const url = resolveManifestUrl7(assetManifest?.terrains?.[tile.terrain ?? ""]);
|
|
11195
11195
|
if (url) urls.push(url);
|
|
11196
11196
|
}
|
|
11197
11197
|
}
|
|
@@ -11201,7 +11201,7 @@ function IsometricCanvas({
|
|
|
11201
11201
|
const url = getFeatureSprite(feature.type);
|
|
11202
11202
|
if (url) urls.push(url);
|
|
11203
11203
|
} else {
|
|
11204
|
-
const url =
|
|
11204
|
+
const url = resolveManifestUrl7(assetManifest?.features?.[feature.type]);
|
|
11205
11205
|
if (url) urls.push(url);
|
|
11206
11206
|
}
|
|
11207
11207
|
}
|
|
@@ -11211,13 +11211,13 @@ function IsometricCanvas({
|
|
|
11211
11211
|
const url = getUnitSprite(unit);
|
|
11212
11212
|
if (url) urls.push(url);
|
|
11213
11213
|
} else if (unit.unitType) {
|
|
11214
|
-
const url =
|
|
11214
|
+
const url = resolveManifestUrl7(assetManifest?.units?.[unit.unitType]);
|
|
11215
11215
|
if (url) urls.push(url);
|
|
11216
11216
|
}
|
|
11217
11217
|
}
|
|
11218
11218
|
if (assetManifest?.effects) {
|
|
11219
11219
|
for (const path of Object.values(assetManifest.effects)) {
|
|
11220
|
-
const url =
|
|
11220
|
+
const url = resolveManifestUrl7(path);
|
|
11221
11221
|
if (url) urls.push(url);
|
|
11222
11222
|
}
|
|
11223
11223
|
}
|
|
@@ -11225,7 +11225,7 @@ function IsometricCanvas({
|
|
|
11225
11225
|
if (atlasSheetUrls.length) urls.push(...atlasSheetUrls);
|
|
11226
11226
|
if (backgroundImage) urls.push(backgroundImage);
|
|
11227
11227
|
return [...new Set(urls.filter(Boolean))];
|
|
11228
|
-
}, [sortedTiles, features, units, getTerrainSprite, getFeatureSprite, getUnitSprite, effectSpriteUrls, atlasSheetUrls, backgroundImage, assetManifest,
|
|
11228
|
+
}, [sortedTiles, features, units, getTerrainSprite, getFeatureSprite, getUnitSprite, effectSpriteUrls, atlasSheetUrls, backgroundImage, assetManifest, resolveManifestUrl7]);
|
|
11229
11229
|
const { getImage, pendingCount } = useImageCache(spriteUrls);
|
|
11230
11230
|
useEffect(() => {
|
|
11231
11231
|
if (typeof window === "undefined") return;
|
|
@@ -11249,14 +11249,14 @@ function IsometricCanvas({
|
|
|
11249
11249
|
lerpToTarget
|
|
11250
11250
|
} = useCamera();
|
|
11251
11251
|
const resolveTerrainSpriteUrl = useCallback((tile) => {
|
|
11252
|
-
return tile.terrainSprite || getTerrainSprite?.(tile.terrain ?? "") ||
|
|
11253
|
-
}, [getTerrainSprite, assetManifest,
|
|
11252
|
+
return tile.terrainSprite || getTerrainSprite?.(tile.terrain ?? "") || resolveManifestUrl7(assetManifest?.terrains?.[tile.terrain ?? ""]);
|
|
11253
|
+
}, [getTerrainSprite, assetManifest, resolveManifestUrl7]);
|
|
11254
11254
|
const resolveFeatureSpriteUrl = useCallback((featureType) => {
|
|
11255
|
-
return getFeatureSprite?.(featureType) ||
|
|
11256
|
-
}, [getFeatureSprite, assetManifest,
|
|
11255
|
+
return getFeatureSprite?.(featureType) || resolveManifestUrl7(assetManifest?.features?.[featureType]);
|
|
11256
|
+
}, [getFeatureSprite, assetManifest, resolveManifestUrl7]);
|
|
11257
11257
|
const resolveUnitSpriteUrl = useCallback((unit) => {
|
|
11258
|
-
return unit.sprite || getUnitSprite?.(unit) || (unit.unitType ?
|
|
11259
|
-
}, [getUnitSprite, assetManifest,
|
|
11258
|
+
return unit.sprite || getUnitSprite?.(unit) || (unit.unitType ? resolveManifestUrl7(assetManifest?.units?.[unit.unitType]) : void 0);
|
|
11259
|
+
}, [getUnitSprite, assetManifest, resolveManifestUrl7]);
|
|
11260
11260
|
const drawMinimap = useCallback(() => {
|
|
11261
11261
|
if (!showMinimap) return;
|
|
11262
11262
|
const miniCanvas = minimapRef.current;
|
|
@@ -11358,7 +11358,15 @@ function IsometricCanvas({
|
|
|
11358
11358
|
const spriteUrl = resolveTerrainSpriteUrl(tile);
|
|
11359
11359
|
const img = spriteUrl ? getImage(spriteUrl) : null;
|
|
11360
11360
|
if (img) {
|
|
11361
|
-
|
|
11361
|
+
if (img.naturalWidth === 0) {
|
|
11362
|
+
ctx.drawImage(img, pos.x, pos.y, scaledTileWidth, scaledTileHeight);
|
|
11363
|
+
} else {
|
|
11364
|
+
const drawW = scaledTileWidth;
|
|
11365
|
+
const drawH = scaledTileWidth * (img.naturalHeight / img.naturalWidth);
|
|
11366
|
+
const drawX = pos.x;
|
|
11367
|
+
const drawY = pos.y + scaledTileHeight - drawH;
|
|
11368
|
+
ctx.drawImage(img, drawX, drawY, drawW, drawH);
|
|
11369
|
+
}
|
|
11362
11370
|
} else {
|
|
11363
11371
|
const centerX = pos.x + scaledTileWidth / 2;
|
|
11364
11372
|
const topY = pos.y + scaledDiamondTopY;
|
|
@@ -13617,7 +13625,7 @@ var init_CodeBlock = __esm({
|
|
|
13617
13625
|
};
|
|
13618
13626
|
LINE_PROPS_FN = (n) => ({ "data-line": String(n - 1) });
|
|
13619
13627
|
HIDDEN_LINE_NUMBERS = { display: "none" };
|
|
13620
|
-
CodeBlock =
|
|
13628
|
+
CodeBlock = React85__default.memo(
|
|
13621
13629
|
({
|
|
13622
13630
|
code: rawCode,
|
|
13623
13631
|
language = "text",
|
|
@@ -13786,24 +13794,24 @@ var init_CodeBlock = __esm({
|
|
|
13786
13794
|
return;
|
|
13787
13795
|
}
|
|
13788
13796
|
lineEls.forEach((el) => {
|
|
13789
|
-
const
|
|
13790
|
-
if (hiddenLines.has(
|
|
13797
|
+
const num3 = parseInt(el.getAttribute("data-line") ?? "-1", 10);
|
|
13798
|
+
if (hiddenLines.has(num3)) {
|
|
13791
13799
|
el.style.display = "none";
|
|
13792
13800
|
return;
|
|
13793
13801
|
}
|
|
13794
13802
|
el.style.display = "";
|
|
13795
13803
|
el.style.position = "relative";
|
|
13796
13804
|
el.style.paddingLeft = "1.2em";
|
|
13797
|
-
const region = foldStartMap.get(
|
|
13805
|
+
const region = foldStartMap.get(num3);
|
|
13798
13806
|
if (!region) return;
|
|
13799
|
-
const isCollapsed = collapsed.has(
|
|
13807
|
+
const isCollapsed = collapsed.has(num3);
|
|
13800
13808
|
const toggle = document.createElement("span");
|
|
13801
13809
|
toggle.className = "fold-toggle";
|
|
13802
13810
|
toggle.textContent = isCollapsed ? "\u25B6" : "\u25BC";
|
|
13803
13811
|
toggle.style.cssText = "position:absolute;left:0;top:0;width:1.2em;text-align:center;cursor:pointer;color:#858585;font-size:10px;user-select:none;line-height:inherit;height:100%";
|
|
13804
13812
|
toggle.addEventListener("click", (e) => {
|
|
13805
13813
|
e.stopPropagation();
|
|
13806
|
-
toggleFoldRef.current(
|
|
13814
|
+
toggleFoldRef.current(num3);
|
|
13807
13815
|
});
|
|
13808
13816
|
el.insertBefore(toggle, el.firstChild);
|
|
13809
13817
|
if (isCollapsed) {
|
|
@@ -14204,7 +14212,7 @@ var init_MarkdownContent = __esm({
|
|
|
14204
14212
|
init_Box();
|
|
14205
14213
|
init_CodeBlock();
|
|
14206
14214
|
init_cn();
|
|
14207
|
-
MarkdownContent =
|
|
14215
|
+
MarkdownContent = React85__default.memo(
|
|
14208
14216
|
({ content, direction = "ltr", className }) => {
|
|
14209
14217
|
const { t: _t } = useTranslate();
|
|
14210
14218
|
const safeContent = typeof content === "string" ? content : String(content ?? "");
|
|
@@ -15521,7 +15529,7 @@ var init_StateMachineView = __esm({
|
|
|
15521
15529
|
style: { top: title ? 30 : 0 },
|
|
15522
15530
|
children: [
|
|
15523
15531
|
entity && /* @__PURE__ */ jsx(EntityBox, { entity, config }),
|
|
15524
|
-
states.map((state) => renderStateNode ? /* @__PURE__ */ jsx(
|
|
15532
|
+
states.map((state) => renderStateNode ? /* @__PURE__ */ jsx(React85__default.Fragment, { children: renderStateNode(state, config) }, state.id) : /* @__PURE__ */ jsx(
|
|
15525
15533
|
StateNode,
|
|
15526
15534
|
{
|
|
15527
15535
|
state,
|
|
@@ -19422,8 +19430,8 @@ function EmojiEffect({
|
|
|
19422
19430
|
);
|
|
19423
19431
|
}
|
|
19424
19432
|
function CanvasEffect({
|
|
19425
|
-
effectSpriteUrl
|
|
19426
|
-
assetBaseUrl
|
|
19433
|
+
effectSpriteUrl,
|
|
19434
|
+
assetBaseUrl,
|
|
19427
19435
|
...props
|
|
19428
19436
|
}) {
|
|
19429
19437
|
const eventBus = useEventBus();
|
|
@@ -19466,6 +19474,380 @@ var init_CanvasEffect = __esm({
|
|
|
19466
19474
|
CanvasEffect.displayName = "CanvasEffect";
|
|
19467
19475
|
}
|
|
19468
19476
|
});
|
|
19477
|
+
function CardHand({
|
|
19478
|
+
cards = DEFAULT_CARDS,
|
|
19479
|
+
selectedId = "",
|
|
19480
|
+
size = "md",
|
|
19481
|
+
onCardClick,
|
|
19482
|
+
cardClickEvent,
|
|
19483
|
+
emptyLabel = "No cards in hand",
|
|
19484
|
+
className
|
|
19485
|
+
}) {
|
|
19486
|
+
const eventBus = useEventBus();
|
|
19487
|
+
const handleClick = React85.useCallback(
|
|
19488
|
+
(card) => {
|
|
19489
|
+
if (card.disabled) return;
|
|
19490
|
+
onCardClick?.(card.id);
|
|
19491
|
+
if (cardClickEvent) {
|
|
19492
|
+
eventBus.emit(`UI:${cardClickEvent}`, { cardId: card.id });
|
|
19493
|
+
}
|
|
19494
|
+
},
|
|
19495
|
+
[onCardClick, cardClickEvent, eventBus]
|
|
19496
|
+
);
|
|
19497
|
+
if (cards.length === 0) {
|
|
19498
|
+
return /* @__PURE__ */ jsx(Box, { className: cn("flex items-center justify-center p-4", className), children: /* @__PURE__ */ jsx(Typography, { variant: "small", color: "muted", children: emptyLabel }) });
|
|
19499
|
+
}
|
|
19500
|
+
const art = artSizeMap[size];
|
|
19501
|
+
return /* @__PURE__ */ jsx(Box, { className: cn("flex flex-wrap gap-2 justify-center items-end", className), children: cards.map((card) => {
|
|
19502
|
+
const selected = selectedId === card.id;
|
|
19503
|
+
return /* @__PURE__ */ jsxs(
|
|
19504
|
+
"button",
|
|
19505
|
+
{
|
|
19506
|
+
type: "button",
|
|
19507
|
+
onClick: () => handleClick(card),
|
|
19508
|
+
disabled: card.disabled,
|
|
19509
|
+
title: card.title,
|
|
19510
|
+
className: cn(
|
|
19511
|
+
"card-hand-card relative flex flex-col items-center rounded-interactive border-2",
|
|
19512
|
+
"bg-card/90 px-1.5 pt-1.5 pb-1 transition-all duration-150",
|
|
19513
|
+
cardSizeMap[size],
|
|
19514
|
+
card.disabled ? "border-border opacity-50 cursor-not-allowed" : "border-accent hover:brightness-125 hover:-translate-y-1 cursor-pointer",
|
|
19515
|
+
selected && "ring-2 ring-foreground ring-offset-1 ring-offset-background -translate-y-1"
|
|
19516
|
+
),
|
|
19517
|
+
children: [
|
|
19518
|
+
card.cost != null && /* @__PURE__ */ jsx(
|
|
19519
|
+
"span",
|
|
19520
|
+
{
|
|
19521
|
+
className: cn(
|
|
19522
|
+
"absolute -top-2 -left-2 flex items-center justify-center",
|
|
19523
|
+
"min-w-[22px] h-[22px] rounded-full px-1",
|
|
19524
|
+
"bg-info text-foreground text-xs font-bold border border-background"
|
|
19525
|
+
),
|
|
19526
|
+
children: card.cost
|
|
19527
|
+
}
|
|
19528
|
+
),
|
|
19529
|
+
/* @__PURE__ */ jsx(Box, { className: "flex-1 flex items-center justify-center w-full", children: card.iconUrl ? /* @__PURE__ */ jsx(
|
|
19530
|
+
"img",
|
|
19531
|
+
{
|
|
19532
|
+
src: card.iconUrl,
|
|
19533
|
+
alt: card.title ?? card.id,
|
|
19534
|
+
width: art,
|
|
19535
|
+
height: art,
|
|
19536
|
+
style: { imageRendering: "pixelated", objectFit: "contain" },
|
|
19537
|
+
className: "flex-shrink-0"
|
|
19538
|
+
}
|
|
19539
|
+
) : /* @__PURE__ */ jsx(
|
|
19540
|
+
Box,
|
|
19541
|
+
{
|
|
19542
|
+
className: "rounded bg-muted/40",
|
|
19543
|
+
style: { width: art, height: art }
|
|
19544
|
+
}
|
|
19545
|
+
) }),
|
|
19546
|
+
card.title != null && /* @__PURE__ */ jsx(
|
|
19547
|
+
Typography,
|
|
19548
|
+
{
|
|
19549
|
+
variant: "small",
|
|
19550
|
+
className: "w-full truncate text-center text-[10px] leading-tight font-semibold",
|
|
19551
|
+
children: card.title
|
|
19552
|
+
}
|
|
19553
|
+
),
|
|
19554
|
+
(card.attack != null || card.defense != null) && /* @__PURE__ */ jsxs(Box, { className: "flex w-full items-center justify-between px-0.5 text-[10px] font-bold leading-none", children: [
|
|
19555
|
+
/* @__PURE__ */ jsx("span", { className: "text-error", children: card.attack != null ? `\u2694${card.attack}` : "" }),
|
|
19556
|
+
/* @__PURE__ */ jsx("span", { className: "text-info", children: card.defense != null ? `\u{1F6E1}${card.defense}` : "" })
|
|
19557
|
+
] })
|
|
19558
|
+
]
|
|
19559
|
+
},
|
|
19560
|
+
card.id
|
|
19561
|
+
);
|
|
19562
|
+
}) });
|
|
19563
|
+
}
|
|
19564
|
+
var cardSizeMap, artSizeMap, DEFAULT_CARDS;
|
|
19565
|
+
var init_CardHand = __esm({
|
|
19566
|
+
"components/game/molecules/CardHand.tsx"() {
|
|
19567
|
+
"use client";
|
|
19568
|
+
init_cn();
|
|
19569
|
+
init_useEventBus();
|
|
19570
|
+
init_Box();
|
|
19571
|
+
init_Typography();
|
|
19572
|
+
cardSizeMap = {
|
|
19573
|
+
sm: "w-16 h-24",
|
|
19574
|
+
md: "w-20 h-28",
|
|
19575
|
+
lg: "w-24 h-36"
|
|
19576
|
+
};
|
|
19577
|
+
artSizeMap = {
|
|
19578
|
+
sm: 40,
|
|
19579
|
+
md: 52,
|
|
19580
|
+
lg: 64
|
|
19581
|
+
};
|
|
19582
|
+
DEFAULT_CARDS = [
|
|
19583
|
+
{ id: "card-1", title: "Brawler", cost: 1, attack: 2, defense: 1 },
|
|
19584
|
+
{ id: "card-2", title: "Guardian", cost: 2, attack: 1, defense: 4 },
|
|
19585
|
+
{ id: "card-3", title: "Striker", cost: 3, attack: 5, defense: 2 }
|
|
19586
|
+
];
|
|
19587
|
+
CardHand.displayName = "CardHand";
|
|
19588
|
+
}
|
|
19589
|
+
});
|
|
19590
|
+
function resolveManifestUrl(manifest, relative) {
|
|
19591
|
+
if (relative == null) return void 0;
|
|
19592
|
+
if (/^https?:\/\//.test(relative)) return relative;
|
|
19593
|
+
const base = manifest?.baseUrl;
|
|
19594
|
+
if (base == null) return relative;
|
|
19595
|
+
const cleanBase = base.replace(/\/$/, "");
|
|
19596
|
+
const cleanRel = relative.replace(/^\//, "");
|
|
19597
|
+
return `${cleanBase}/${cleanRel}`;
|
|
19598
|
+
}
|
|
19599
|
+
function rowToCard(r) {
|
|
19600
|
+
return {
|
|
19601
|
+
id: str(r.id),
|
|
19602
|
+
iconKey: r.iconKey == null ? void 0 : str(r.iconKey),
|
|
19603
|
+
title: r.title == null ? void 0 : str(r.title),
|
|
19604
|
+
cost: r.cost == null ? void 0 : num(r.cost),
|
|
19605
|
+
attack: r.attack == null ? void 0 : num(r.attack),
|
|
19606
|
+
defense: r.defense == null ? void 0 : num(r.defense)
|
|
19607
|
+
};
|
|
19608
|
+
}
|
|
19609
|
+
function toHandCards(cards, manifest, mana) {
|
|
19610
|
+
return cards.map((c) => {
|
|
19611
|
+
const key = c.iconKey ?? c.id;
|
|
19612
|
+
const iconUrl = resolveManifestUrl(manifest, manifest?.cards?.[key]);
|
|
19613
|
+
return {
|
|
19614
|
+
id: c.id,
|
|
19615
|
+
iconUrl,
|
|
19616
|
+
title: c.title,
|
|
19617
|
+
cost: c.cost,
|
|
19618
|
+
attack: c.attack,
|
|
19619
|
+
defense: c.defense,
|
|
19620
|
+
disabled: c.cost != null && c.cost > mana
|
|
19621
|
+
};
|
|
19622
|
+
});
|
|
19623
|
+
}
|
|
19624
|
+
function CardBattlerBoard({
|
|
19625
|
+
entity,
|
|
19626
|
+
deck: propDeck,
|
|
19627
|
+
hand: propHand,
|
|
19628
|
+
board: propBoard,
|
|
19629
|
+
mana: propMana,
|
|
19630
|
+
maxMana: propMaxMana,
|
|
19631
|
+
turn: propTurn,
|
|
19632
|
+
result: propResult,
|
|
19633
|
+
assetManifest: propAssetManifest,
|
|
19634
|
+
playCardEvent,
|
|
19635
|
+
endTurnEvent,
|
|
19636
|
+
playAgainEvent,
|
|
19637
|
+
gameEndEvent,
|
|
19638
|
+
className
|
|
19639
|
+
}) {
|
|
19640
|
+
const board = boardEntity(entity) ?? {};
|
|
19641
|
+
const eventBus = useEventBus();
|
|
19642
|
+
const { t } = useTranslate();
|
|
19643
|
+
const assetManifest = propAssetManifest ?? board.assetManifest;
|
|
19644
|
+
const entityHand = useMemo(() => rows(board.hand).map(rowToCard), [board.hand]);
|
|
19645
|
+
const rawHand = propHand ?? entityHand;
|
|
19646
|
+
const hand = rawHand.length > 0 ? rawHand : DEFAULT_HAND;
|
|
19647
|
+
const entityBoard = useMemo(() => rows(board.board).map(rowToCard), [board.board]);
|
|
19648
|
+
const playedCards = propBoard ?? entityBoard;
|
|
19649
|
+
const entityDeck = useMemo(() => rows(board.deck).map(rowToCard), [board.deck]);
|
|
19650
|
+
const deck = propDeck ?? entityDeck;
|
|
19651
|
+
const mana = propMana ?? num(board.mana, 3);
|
|
19652
|
+
const maxMana = propMaxMana ?? num(board.maxMana, 3);
|
|
19653
|
+
const turn = propTurn ?? num(board.turn, 1);
|
|
19654
|
+
const result = propResult ?? (str(board.result) || "none");
|
|
19655
|
+
const handCards = useMemo(() => toHandCards(hand, assetManifest, mana), [hand, assetManifest, mana]);
|
|
19656
|
+
const boardCards = useMemo(() => toHandCards(playedCards, assetManifest, mana), [playedCards, assetManifest, mana]);
|
|
19657
|
+
const emittedGameEnd = useRef(false);
|
|
19658
|
+
if (result !== "none" && !emittedGameEnd.current) {
|
|
19659
|
+
emittedGameEnd.current = true;
|
|
19660
|
+
if (gameEndEvent) {
|
|
19661
|
+
eventBus.emit(`UI:${gameEndEvent}`, { result });
|
|
19662
|
+
}
|
|
19663
|
+
}
|
|
19664
|
+
if (result === "none") {
|
|
19665
|
+
emittedGameEnd.current = false;
|
|
19666
|
+
}
|
|
19667
|
+
const handlePlayCard = useCallback((cardId) => {
|
|
19668
|
+
if (result !== "none") return;
|
|
19669
|
+
if (playCardEvent) {
|
|
19670
|
+
eventBus.emit(`UI:${playCardEvent}`, { cardId });
|
|
19671
|
+
}
|
|
19672
|
+
}, [result, playCardEvent, eventBus]);
|
|
19673
|
+
const handleEndTurn = useCallback(() => {
|
|
19674
|
+
if (result !== "none") return;
|
|
19675
|
+
if (endTurnEvent) {
|
|
19676
|
+
eventBus.emit(`UI:${endTurnEvent}`, {});
|
|
19677
|
+
}
|
|
19678
|
+
}, [result, endTurnEvent, eventBus]);
|
|
19679
|
+
const handlePlayAgain = useCallback(() => {
|
|
19680
|
+
if (playAgainEvent) {
|
|
19681
|
+
eventBus.emit(`UI:${playAgainEvent}`, {});
|
|
19682
|
+
}
|
|
19683
|
+
}, [playAgainEvent, eventBus]);
|
|
19684
|
+
return /* @__PURE__ */ jsxs(VStack, { className: cn("card-battler-board relative min-h-[600px] bg-background", className), gap: "none", children: [
|
|
19685
|
+
/* @__PURE__ */ jsxs(
|
|
19686
|
+
HStack,
|
|
19687
|
+
{
|
|
19688
|
+
className: "px-4 py-2 border-b border-border bg-surface",
|
|
19689
|
+
gap: "lg",
|
|
19690
|
+
align: "center",
|
|
19691
|
+
children: [
|
|
19692
|
+
/* @__PURE__ */ jsxs(HStack, { gap: "xs", align: "center", children: [
|
|
19693
|
+
/* @__PURE__ */ jsx(Typography, { variant: "small", color: "muted", children: t("cb.mana") ?? "Mana" }),
|
|
19694
|
+
/* @__PURE__ */ jsxs(Typography, { variant: "body2", weight: "bold", className: "text-info", children: [
|
|
19695
|
+
mana,
|
|
19696
|
+
" / ",
|
|
19697
|
+
maxMana
|
|
19698
|
+
] })
|
|
19699
|
+
] }),
|
|
19700
|
+
/* @__PURE__ */ jsxs(HStack, { gap: "xs", align: "center", children: [
|
|
19701
|
+
/* @__PURE__ */ jsx(Typography, { variant: "small", color: "muted", children: t("cb.turn") ?? "Turn" }),
|
|
19702
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body2", weight: "bold", children: turn })
|
|
19703
|
+
] }),
|
|
19704
|
+
/* @__PURE__ */ jsxs(HStack, { gap: "xs", align: "center", children: [
|
|
19705
|
+
/* @__PURE__ */ jsx(Typography, { variant: "small", color: "muted", children: t("cb.deck") ?? "Deck" }),
|
|
19706
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body2", weight: "bold", children: deck.length })
|
|
19707
|
+
] }),
|
|
19708
|
+
/* @__PURE__ */ jsx(Box, { className: "ml-auto", children: result === "none" && /* @__PURE__ */ jsx(Button, { variant: "primary", size: "sm", onClick: handleEndTurn, children: t("cb.endTurn") ?? "End Turn" }) })
|
|
19709
|
+
]
|
|
19710
|
+
}
|
|
19711
|
+
),
|
|
19712
|
+
/* @__PURE__ */ jsxs(Box, { className: "flex-1 relative p-4 overflow-auto", children: [
|
|
19713
|
+
/* @__PURE__ */ jsx(Typography, { variant: "small", color: "muted", className: "mb-2 uppercase tracking-wide", children: t("cb.battlefield") ?? "Battlefield" }),
|
|
19714
|
+
boardCards.length > 0 ? /* @__PURE__ */ jsx(
|
|
19715
|
+
CardHand,
|
|
19716
|
+
{
|
|
19717
|
+
cards: boardCards,
|
|
19718
|
+
size: "md",
|
|
19719
|
+
className: "justify-start"
|
|
19720
|
+
}
|
|
19721
|
+
) : /* @__PURE__ */ jsx(Box, { className: "flex items-center justify-center h-32 rounded-interactive border-2 border-dashed border-border", children: /* @__PURE__ */ jsx(Typography, { variant: "small", color: "muted", children: t("cb.emptyBoard") ?? "Play a card to begin" }) })
|
|
19722
|
+
] }),
|
|
19723
|
+
/* @__PURE__ */ jsxs(Box, { className: "border-t border-border bg-surface px-4 py-3", children: [
|
|
19724
|
+
/* @__PURE__ */ jsx(Typography, { variant: "small", color: "muted", className: "mb-2 uppercase tracking-wide", children: t("cb.hand") ?? "Your Hand" }),
|
|
19725
|
+
/* @__PURE__ */ jsx(
|
|
19726
|
+
CardHand,
|
|
19727
|
+
{
|
|
19728
|
+
cards: handCards,
|
|
19729
|
+
size: "lg",
|
|
19730
|
+
onCardClick: handlePlayCard,
|
|
19731
|
+
emptyLabel: t("cb.emptyHand") ?? "No cards in hand"
|
|
19732
|
+
}
|
|
19733
|
+
)
|
|
19734
|
+
] }),
|
|
19735
|
+
result !== "none" && /* @__PURE__ */ jsx(Box, { className: "absolute inset-0 z-50 flex items-center justify-center bg-background/70 backdrop-blur-sm", children: /* @__PURE__ */ jsxs(VStack, { className: "text-center p-8", gap: "lg", children: [
|
|
19736
|
+
/* @__PURE__ */ jsx(
|
|
19737
|
+
Typography,
|
|
19738
|
+
{
|
|
19739
|
+
variant: "h2",
|
|
19740
|
+
className: cn(
|
|
19741
|
+
"text-4xl font-black tracking-widest uppercase",
|
|
19742
|
+
result === "won" ? "text-warning" : "text-error"
|
|
19743
|
+
),
|
|
19744
|
+
children: result === "won" ? t("cb.victory") ?? "Victory!" : t("cb.defeat") ?? "Defeat!"
|
|
19745
|
+
}
|
|
19746
|
+
),
|
|
19747
|
+
/* @__PURE__ */ jsx(
|
|
19748
|
+
Button,
|
|
19749
|
+
{
|
|
19750
|
+
variant: "primary",
|
|
19751
|
+
className: "px-8 py-3 font-semibold",
|
|
19752
|
+
onClick: handlePlayAgain,
|
|
19753
|
+
children: t("cb.playAgain") ?? "Play Again"
|
|
19754
|
+
}
|
|
19755
|
+
)
|
|
19756
|
+
] }) })
|
|
19757
|
+
] });
|
|
19758
|
+
}
|
|
19759
|
+
var DEFAULT_HAND;
|
|
19760
|
+
var init_CardBattlerBoard = __esm({
|
|
19761
|
+
"components/game/organisms/CardBattlerBoard.tsx"() {
|
|
19762
|
+
"use client";
|
|
19763
|
+
init_cn();
|
|
19764
|
+
init_useEventBus();
|
|
19765
|
+
init_Box();
|
|
19766
|
+
init_Button();
|
|
19767
|
+
init_Typography();
|
|
19768
|
+
init_Stack();
|
|
19769
|
+
init_CardHand();
|
|
19770
|
+
init_boardEntity();
|
|
19771
|
+
DEFAULT_HAND = [
|
|
19772
|
+
{ id: "c1", iconKey: "bear", title: "Bear", cost: 3, attack: 5, defense: 4 },
|
|
19773
|
+
{ id: "c2", iconKey: "owl", title: "Owl", cost: 1, attack: 2, defense: 1 },
|
|
19774
|
+
{ id: "c3", iconKey: "gorilla", title: "Gorilla", cost: 4, attack: 6, defense: 5 },
|
|
19775
|
+
{ id: "c4", iconKey: "frog", title: "Frog", cost: 1, attack: 1, defense: 2 },
|
|
19776
|
+
{ id: "c5", iconKey: "snake", title: "Snake", cost: 2, attack: 4, defense: 1 }
|
|
19777
|
+
];
|
|
19778
|
+
CardBattlerBoard.displayName = "CardBattlerBoard";
|
|
19779
|
+
}
|
|
19780
|
+
});
|
|
19781
|
+
function isEntityRow(value) {
|
|
19782
|
+
return value != null && typeof value === "object" && !Array.isArray(value);
|
|
19783
|
+
}
|
|
19784
|
+
function CardBattlerTemplate({
|
|
19785
|
+
entity,
|
|
19786
|
+
title = "Card Battler",
|
|
19787
|
+
deck,
|
|
19788
|
+
hand,
|
|
19789
|
+
board,
|
|
19790
|
+
mana,
|
|
19791
|
+
maxMana,
|
|
19792
|
+
turn,
|
|
19793
|
+
result,
|
|
19794
|
+
assetManifest,
|
|
19795
|
+
playCardEvent,
|
|
19796
|
+
endTurnEvent,
|
|
19797
|
+
playAgainEvent,
|
|
19798
|
+
gameEndEvent,
|
|
19799
|
+
className
|
|
19800
|
+
}) {
|
|
19801
|
+
const resolved = isEntityRow(entity) ? entity : void 0;
|
|
19802
|
+
return /* @__PURE__ */ jsxs(
|
|
19803
|
+
Box,
|
|
19804
|
+
{
|
|
19805
|
+
display: "flex",
|
|
19806
|
+
fullHeight: true,
|
|
19807
|
+
className: cn("card-battler-template flex-col", className),
|
|
19808
|
+
children: [
|
|
19809
|
+
/* @__PURE__ */ jsx(
|
|
19810
|
+
HStack,
|
|
19811
|
+
{
|
|
19812
|
+
gap: "sm",
|
|
19813
|
+
align: "center",
|
|
19814
|
+
className: "px-4 py-3 border-b-2 border-border bg-surface shrink-0",
|
|
19815
|
+
children: /* @__PURE__ */ jsx(Typography, { variant: "h4", children: title })
|
|
19816
|
+
}
|
|
19817
|
+
),
|
|
19818
|
+
/* @__PURE__ */ jsx(Box, { className: "flex-1 relative overflow-hidden", children: /* @__PURE__ */ jsx(
|
|
19819
|
+
CardBattlerBoard,
|
|
19820
|
+
{
|
|
19821
|
+
entity: resolved,
|
|
19822
|
+
deck,
|
|
19823
|
+
hand,
|
|
19824
|
+
board,
|
|
19825
|
+
mana,
|
|
19826
|
+
maxMana,
|
|
19827
|
+
turn,
|
|
19828
|
+
result,
|
|
19829
|
+
assetManifest,
|
|
19830
|
+
playCardEvent,
|
|
19831
|
+
endTurnEvent,
|
|
19832
|
+
playAgainEvent,
|
|
19833
|
+
gameEndEvent,
|
|
19834
|
+
className: "h-full"
|
|
19835
|
+
}
|
|
19836
|
+
) })
|
|
19837
|
+
]
|
|
19838
|
+
}
|
|
19839
|
+
);
|
|
19840
|
+
}
|
|
19841
|
+
var init_CardBattlerTemplate = __esm({
|
|
19842
|
+
"components/game/templates/CardBattlerTemplate.tsx"() {
|
|
19843
|
+
init_cn();
|
|
19844
|
+
init_Box();
|
|
19845
|
+
init_Stack();
|
|
19846
|
+
init_Typography();
|
|
19847
|
+
init_CardBattlerBoard();
|
|
19848
|
+
CardBattlerTemplate.displayName = "CardBattlerTemplate";
|
|
19849
|
+
}
|
|
19850
|
+
});
|
|
19469
19851
|
|
|
19470
19852
|
// lib/getNestedValue.ts
|
|
19471
19853
|
function getNestedValue(obj, path) {
|
|
@@ -21248,6 +21630,315 @@ var init_ChartLegend = __esm({
|
|
|
21248
21630
|
ChartLegend.displayName = "ChartLegend";
|
|
21249
21631
|
}
|
|
21250
21632
|
});
|
|
21633
|
+
function resolveManifestUrl2(manifest, relative) {
|
|
21634
|
+
if (relative == null) return void 0;
|
|
21635
|
+
if (/^https?:\/\//.test(relative)) return relative;
|
|
21636
|
+
const base = manifest?.baseUrl;
|
|
21637
|
+
if (base == null) return relative;
|
|
21638
|
+
const cleanBase = base.replace(/\/$/, "");
|
|
21639
|
+
const cleanRel = relative.replace(/^\//, "");
|
|
21640
|
+
return `${cleanBase}/${cleanRel}`;
|
|
21641
|
+
}
|
|
21642
|
+
function buildDefaultCBTiles() {
|
|
21643
|
+
const tiles = [];
|
|
21644
|
+
for (let y = 0; y < CB_GRID_H; y++) {
|
|
21645
|
+
for (let x = 0; x < CB_GRID_W; x++) {
|
|
21646
|
+
const variant = (x * 3 + y * 5 + (x ^ y)) % 3;
|
|
21647
|
+
const terrainKey = ["grass", "stone", "dirt"][variant];
|
|
21648
|
+
tiles.push({ x, y, terrain: terrainKey, passable: true });
|
|
21649
|
+
}
|
|
21650
|
+
}
|
|
21651
|
+
return tiles;
|
|
21652
|
+
}
|
|
21653
|
+
function tilesToIso(tiles, manifest) {
|
|
21654
|
+
return tiles.map((t) => {
|
|
21655
|
+
const key = t.terrain ?? "grass";
|
|
21656
|
+
const sprite = t.terrainSprite ?? resolveManifestUrl2(manifest, manifest?.terrains?.[key]) ?? resolveManifestUrl2(manifest, manifest?.terrains?.grass);
|
|
21657
|
+
return {
|
|
21658
|
+
x: t.x,
|
|
21659
|
+
y: t.y,
|
|
21660
|
+
terrain: t.terrain,
|
|
21661
|
+
terrainSprite: sprite,
|
|
21662
|
+
passable: t.passable
|
|
21663
|
+
};
|
|
21664
|
+
});
|
|
21665
|
+
}
|
|
21666
|
+
function buildingsToFeatures(buildings, manifest) {
|
|
21667
|
+
return buildings.map((b) => ({
|
|
21668
|
+
id: b.id,
|
|
21669
|
+
x: b.x,
|
|
21670
|
+
y: b.y,
|
|
21671
|
+
type: b.type,
|
|
21672
|
+
sprite: resolveManifestUrl2(manifest, manifest?.features?.[b.type])
|
|
21673
|
+
}));
|
|
21674
|
+
}
|
|
21675
|
+
function CityBuilderBoard({
|
|
21676
|
+
entity,
|
|
21677
|
+
tiles: propTiles,
|
|
21678
|
+
buildings: propBuildings,
|
|
21679
|
+
assetManifest: propAssetManifest,
|
|
21680
|
+
buildTypes: propBuildTypes,
|
|
21681
|
+
pendingBuildType: propPendingBuildType,
|
|
21682
|
+
gold: propGold,
|
|
21683
|
+
wood: propWood,
|
|
21684
|
+
population: propPopulation,
|
|
21685
|
+
result: propResult,
|
|
21686
|
+
scale = 0.3,
|
|
21687
|
+
unitScale = 0.6,
|
|
21688
|
+
spriteHeightRatio = 1.5,
|
|
21689
|
+
spriteMaxWidthRatio = 0.7,
|
|
21690
|
+
selectBuildTypeEvent,
|
|
21691
|
+
placeBuildingEvent,
|
|
21692
|
+
gameEndEvent,
|
|
21693
|
+
className
|
|
21694
|
+
}) {
|
|
21695
|
+
const board = boardEntity(entity) ?? {};
|
|
21696
|
+
const eventBus = useEventBus();
|
|
21697
|
+
const { t } = useTranslate();
|
|
21698
|
+
const assetManifest = propAssetManifest ?? board.assetManifest;
|
|
21699
|
+
const entityTiles = useMemo(
|
|
21700
|
+
() => rows(board.tiles).map((r) => ({
|
|
21701
|
+
x: num(r.x),
|
|
21702
|
+
y: num(r.y),
|
|
21703
|
+
terrain: r.terrain == null ? void 0 : str(r.terrain),
|
|
21704
|
+
terrainSprite: r.terrainSprite == null ? void 0 : str(r.terrainSprite),
|
|
21705
|
+
passable: r.passable !== false
|
|
21706
|
+
})),
|
|
21707
|
+
[board.tiles]
|
|
21708
|
+
);
|
|
21709
|
+
const rawTiles = propTiles ?? entityTiles;
|
|
21710
|
+
const tiles = rawTiles.length >= CB_GRID_W * CB_GRID_H ? rawTiles : DEFAULT_CB_TILES;
|
|
21711
|
+
const entityBuildings = useMemo(
|
|
21712
|
+
() => rows(board.buildings).map((r) => ({
|
|
21713
|
+
id: str(r.id),
|
|
21714
|
+
x: num(r.x),
|
|
21715
|
+
y: num(r.y),
|
|
21716
|
+
type: str(r.type)
|
|
21717
|
+
})),
|
|
21718
|
+
[board.buildings]
|
|
21719
|
+
);
|
|
21720
|
+
const buildings = propBuildings ?? entityBuildings;
|
|
21721
|
+
const buildTypes = propBuildTypes ?? DEFAULT_BUILD_TYPES;
|
|
21722
|
+
const gold = propGold ?? num(board.gold, 100);
|
|
21723
|
+
const wood = propWood ?? num(board.wood, 80);
|
|
21724
|
+
const population = propPopulation ?? num(board.population, 0);
|
|
21725
|
+
const pendingBuildType = propPendingBuildType ?? (str(board.pendingBuildType) || buildTypes[0]?.type || "");
|
|
21726
|
+
const result = propResult ?? (str(board.result) || "none");
|
|
21727
|
+
const [hoveredTile, setHoveredTile] = useState(null);
|
|
21728
|
+
const emittedGameEnd = useRef(false);
|
|
21729
|
+
if (result !== "none" && !emittedGameEnd.current) {
|
|
21730
|
+
emittedGameEnd.current = true;
|
|
21731
|
+
if (gameEndEvent) {
|
|
21732
|
+
eventBus.emit(`UI:${gameEndEvent}`, { result });
|
|
21733
|
+
}
|
|
21734
|
+
}
|
|
21735
|
+
if (result === "none") {
|
|
21736
|
+
emittedGameEnd.current = false;
|
|
21737
|
+
}
|
|
21738
|
+
const pendingCost = useMemo(
|
|
21739
|
+
() => buildTypes.find((b) => b.type === pendingBuildType)?.cost ?? 0,
|
|
21740
|
+
[buildTypes, pendingBuildType]
|
|
21741
|
+
);
|
|
21742
|
+
const buildingPositions = useMemo(
|
|
21743
|
+
() => new Set(buildings.map((b) => `${b.x},${b.y}`)),
|
|
21744
|
+
[buildings]
|
|
21745
|
+
);
|
|
21746
|
+
const validMoves = useMemo(() => {
|
|
21747
|
+
if (result !== "none" || gold < pendingCost) return [];
|
|
21748
|
+
return tiles.filter(
|
|
21749
|
+
(t2) => t2.passable !== false && !buildingPositions.has(`${t2.x},${t2.y}`)
|
|
21750
|
+
).map((t2) => ({ x: t2.x, y: t2.y }));
|
|
21751
|
+
}, [tiles, buildingPositions, result, gold, pendingCost]);
|
|
21752
|
+
const isoTiles = useMemo(() => tilesToIso(tiles, assetManifest), [tiles, assetManifest]);
|
|
21753
|
+
const buildingFeatures = useMemo(() => buildingsToFeatures(buildings, assetManifest), [buildings, assetManifest]);
|
|
21754
|
+
const handleTileClick = useCallback((x, y) => {
|
|
21755
|
+
if (result !== "none") return;
|
|
21756
|
+
if (buildingPositions.has(`${x},${y}`)) return;
|
|
21757
|
+
if (gold < pendingCost) return;
|
|
21758
|
+
if (placeBuildingEvent) {
|
|
21759
|
+
eventBus.emit(`UI:${placeBuildingEvent}`, { x, y });
|
|
21760
|
+
}
|
|
21761
|
+
}, [result, buildingPositions, gold, pendingCost, placeBuildingEvent, eventBus]);
|
|
21762
|
+
const handleSelectBuildType = useCallback((buildType) => {
|
|
21763
|
+
if (selectBuildTypeEvent) {
|
|
21764
|
+
eventBus.emit(`UI:${selectBuildTypeEvent}`, { buildType });
|
|
21765
|
+
}
|
|
21766
|
+
}, [selectBuildTypeEvent, eventBus]);
|
|
21767
|
+
const canBuild = gold >= pendingCost && result === "none";
|
|
21768
|
+
return /* @__PURE__ */ jsxs(VStack, { className: cn("city-builder-board relative min-h-[600px] bg-background", className), gap: "none", children: [
|
|
21769
|
+
/* @__PURE__ */ jsxs(
|
|
21770
|
+
HStack,
|
|
21771
|
+
{
|
|
21772
|
+
className: "px-4 py-2 border-b border-border bg-surface",
|
|
21773
|
+
gap: "lg",
|
|
21774
|
+
align: "center",
|
|
21775
|
+
children: [
|
|
21776
|
+
/* @__PURE__ */ jsxs(HStack, { gap: "xs", align: "center", children: [
|
|
21777
|
+
/* @__PURE__ */ jsx(Typography, { variant: "small", color: "muted", children: t("cb.gold") ?? "Gold" }),
|
|
21778
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body2", weight: "bold", className: "text-warning", children: gold })
|
|
21779
|
+
] }),
|
|
21780
|
+
/* @__PURE__ */ jsxs(HStack, { gap: "xs", align: "center", children: [
|
|
21781
|
+
/* @__PURE__ */ jsx(Typography, { variant: "small", color: "muted", children: t("cb.wood") ?? "Wood" }),
|
|
21782
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body2", weight: "bold", className: "text-success", children: wood })
|
|
21783
|
+
] }),
|
|
21784
|
+
/* @__PURE__ */ jsxs(HStack, { gap: "xs", align: "center", children: [
|
|
21785
|
+
/* @__PURE__ */ jsx(Typography, { variant: "small", color: "muted", children: t("cb.population") ?? "Population" }),
|
|
21786
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body2", weight: "bold", children: population })
|
|
21787
|
+
] }),
|
|
21788
|
+
/* @__PURE__ */ jsx(HStack, { gap: "xs", align: "center", className: "ml-auto", children: buildTypes.map((b) => /* @__PURE__ */ jsxs(
|
|
21789
|
+
Button,
|
|
21790
|
+
{
|
|
21791
|
+
variant: b.type === pendingBuildType ? "primary" : "secondary",
|
|
21792
|
+
size: "sm",
|
|
21793
|
+
disabled: gold < b.cost || result !== "none",
|
|
21794
|
+
onClick: () => handleSelectBuildType(b.type),
|
|
21795
|
+
children: [
|
|
21796
|
+
b.label,
|
|
21797
|
+
" (",
|
|
21798
|
+
b.cost,
|
|
21799
|
+
")"
|
|
21800
|
+
]
|
|
21801
|
+
},
|
|
21802
|
+
b.type
|
|
21803
|
+
)) })
|
|
21804
|
+
]
|
|
21805
|
+
}
|
|
21806
|
+
),
|
|
21807
|
+
/* @__PURE__ */ jsxs(Box, { className: "relative flex-1", children: [
|
|
21808
|
+
/* @__PURE__ */ jsx(
|
|
21809
|
+
IsometricCanvas_default,
|
|
21810
|
+
{
|
|
21811
|
+
tiles: isoTiles,
|
|
21812
|
+
features: buildingFeatures,
|
|
21813
|
+
assetBaseUrl: assetManifest?.baseUrl,
|
|
21814
|
+
assetManifest,
|
|
21815
|
+
validMoves,
|
|
21816
|
+
hoveredTile,
|
|
21817
|
+
onTileClick: handleTileClick,
|
|
21818
|
+
onTileHover: (x, y) => setHoveredTile({ x, y }),
|
|
21819
|
+
onTileLeave: () => setHoveredTile(null),
|
|
21820
|
+
scale,
|
|
21821
|
+
unitScale,
|
|
21822
|
+
spriteHeightRatio,
|
|
21823
|
+
spriteMaxWidthRatio
|
|
21824
|
+
}
|
|
21825
|
+
),
|
|
21826
|
+
hoveredTile && canBuild && validMoves.some((m) => m.x === hoveredTile.x && m.y === hoveredTile.y) && /* @__PURE__ */ jsx(Box, { className: "absolute bottom-4 left-1/2 -translate-x-1/2 z-10 bg-background/80 rounded px-3 py-1 backdrop-blur-sm pointer-events-none", children: /* @__PURE__ */ jsx(Typography, { variant: "small", children: t("cb.placeBuilding") ?? `Build ${pendingBuildType} (${pendingCost} gold)` }) })
|
|
21827
|
+
] }),
|
|
21828
|
+
result !== "none" && /* @__PURE__ */ jsx(Box, { className: "absolute inset-0 z-50 flex items-center justify-center bg-background/70 backdrop-blur-sm", children: /* @__PURE__ */ jsxs(VStack, { className: "text-center p-8", gap: "lg", children: [
|
|
21829
|
+
/* @__PURE__ */ jsx(
|
|
21830
|
+
Typography,
|
|
21831
|
+
{
|
|
21832
|
+
variant: "h2",
|
|
21833
|
+
className: cn(
|
|
21834
|
+
"text-4xl font-black tracking-widest uppercase",
|
|
21835
|
+
result === "won" ? "text-warning" : "text-error"
|
|
21836
|
+
),
|
|
21837
|
+
children: result === "won" ? t("cb.victory") ?? "City Thrives!" : t("cb.defeat") ?? "City Collapsed!"
|
|
21838
|
+
}
|
|
21839
|
+
),
|
|
21840
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body1", className: "text-muted-foreground", children: result === "won" ? t("cb.reachedGoal") ?? `Your city reached a population of ${population}.` : t("cb.bankrupt") ?? "Your city ran out of resources." })
|
|
21841
|
+
] }) })
|
|
21842
|
+
] });
|
|
21843
|
+
}
|
|
21844
|
+
var CB_GRID_W, CB_GRID_H, DEFAULT_BUILD_TYPES, DEFAULT_CB_TILES;
|
|
21845
|
+
var init_CityBuilderBoard = __esm({
|
|
21846
|
+
"components/game/organisms/CityBuilderBoard.tsx"() {
|
|
21847
|
+
"use client";
|
|
21848
|
+
init_cn();
|
|
21849
|
+
init_useEventBus();
|
|
21850
|
+
init_Box();
|
|
21851
|
+
init_Button();
|
|
21852
|
+
init_Typography();
|
|
21853
|
+
init_Stack();
|
|
21854
|
+
init_IsometricCanvas();
|
|
21855
|
+
init_boardEntity();
|
|
21856
|
+
CB_GRID_W = 12;
|
|
21857
|
+
CB_GRID_H = 12;
|
|
21858
|
+
DEFAULT_BUILD_TYPES = [
|
|
21859
|
+
{ type: "house", label: "House", cost: 20 },
|
|
21860
|
+
{ type: "farm", label: "Farm", cost: 15 },
|
|
21861
|
+
{ type: "mine", label: "Mine", cost: 25 },
|
|
21862
|
+
{ type: "barracks", label: "Barracks", cost: 40 }
|
|
21863
|
+
];
|
|
21864
|
+
DEFAULT_CB_TILES = buildDefaultCBTiles();
|
|
21865
|
+
CityBuilderBoard.displayName = "CityBuilderBoard";
|
|
21866
|
+
}
|
|
21867
|
+
});
|
|
21868
|
+
function isEntityRow2(value) {
|
|
21869
|
+
return value != null && typeof value === "object" && !Array.isArray(value);
|
|
21870
|
+
}
|
|
21871
|
+
function CityBuilderTemplate({
|
|
21872
|
+
entity,
|
|
21873
|
+
title = "City Builder",
|
|
21874
|
+
tiles,
|
|
21875
|
+
buildings,
|
|
21876
|
+
buildTypes,
|
|
21877
|
+
pendingBuildType,
|
|
21878
|
+
assetManifest,
|
|
21879
|
+
gold,
|
|
21880
|
+
wood,
|
|
21881
|
+
population,
|
|
21882
|
+
result,
|
|
21883
|
+
scale,
|
|
21884
|
+
unitScale,
|
|
21885
|
+
selectBuildTypeEvent,
|
|
21886
|
+
placeBuildingEvent,
|
|
21887
|
+
gameEndEvent,
|
|
21888
|
+
className
|
|
21889
|
+
}) {
|
|
21890
|
+
const resolved = isEntityRow2(entity) ? entity : void 0;
|
|
21891
|
+
return /* @__PURE__ */ jsxs(
|
|
21892
|
+
Box,
|
|
21893
|
+
{
|
|
21894
|
+
display: "flex",
|
|
21895
|
+
fullHeight: true,
|
|
21896
|
+
className: cn("city-builder-template flex-col", className),
|
|
21897
|
+
children: [
|
|
21898
|
+
/* @__PURE__ */ jsx(
|
|
21899
|
+
HStack,
|
|
21900
|
+
{
|
|
21901
|
+
gap: "sm",
|
|
21902
|
+
align: "center",
|
|
21903
|
+
className: "px-4 py-3 border-b-2 border-border bg-surface shrink-0",
|
|
21904
|
+
children: /* @__PURE__ */ jsx(Typography, { variant: "h4", children: title })
|
|
21905
|
+
}
|
|
21906
|
+
),
|
|
21907
|
+
/* @__PURE__ */ jsx(Box, { className: "flex-1 relative overflow-hidden", children: /* @__PURE__ */ jsx(
|
|
21908
|
+
CityBuilderBoard,
|
|
21909
|
+
{
|
|
21910
|
+
entity: resolved,
|
|
21911
|
+
tiles,
|
|
21912
|
+
buildings,
|
|
21913
|
+
buildTypes,
|
|
21914
|
+
pendingBuildType,
|
|
21915
|
+
assetManifest,
|
|
21916
|
+
gold,
|
|
21917
|
+
wood,
|
|
21918
|
+
population,
|
|
21919
|
+
result,
|
|
21920
|
+
scale,
|
|
21921
|
+
unitScale,
|
|
21922
|
+
selectBuildTypeEvent,
|
|
21923
|
+
placeBuildingEvent,
|
|
21924
|
+
gameEndEvent,
|
|
21925
|
+
className: "h-full"
|
|
21926
|
+
}
|
|
21927
|
+
) })
|
|
21928
|
+
]
|
|
21929
|
+
}
|
|
21930
|
+
);
|
|
21931
|
+
}
|
|
21932
|
+
var init_CityBuilderTemplate = __esm({
|
|
21933
|
+
"components/game/templates/CityBuilderTemplate.tsx"() {
|
|
21934
|
+
init_cn();
|
|
21935
|
+
init_Box();
|
|
21936
|
+
init_Stack();
|
|
21937
|
+
init_Typography();
|
|
21938
|
+
init_CityBuilderBoard();
|
|
21939
|
+
CityBuilderTemplate.displayName = "CityBuilderTemplate";
|
|
21940
|
+
}
|
|
21941
|
+
});
|
|
21251
21942
|
function ClassifierBoard({
|
|
21252
21943
|
entity,
|
|
21253
21944
|
completeEvent = "PUZZLE_COMPLETE",
|
|
@@ -22062,7 +22753,7 @@ function CraftingRecipe({
|
|
|
22062
22753
|
className
|
|
22063
22754
|
}) {
|
|
22064
22755
|
const eventBus = useEventBus();
|
|
22065
|
-
const handleCraft =
|
|
22756
|
+
const handleCraft = React85.useCallback(() => {
|
|
22066
22757
|
onCraft?.();
|
|
22067
22758
|
if (craftEvent) {
|
|
22068
22759
|
eventBus.emit(craftEvent, { output: output.label });
|
|
@@ -22079,7 +22770,7 @@ function CraftingRecipe({
|
|
|
22079
22770
|
children: [
|
|
22080
22771
|
/* @__PURE__ */ jsx(HStack, { gap: "xs", className: "flex-wrap items-center", children: inputs.map((ingredient, index) => {
|
|
22081
22772
|
const hasSufficient = ingredient.available >= ingredient.required;
|
|
22082
|
-
return /* @__PURE__ */ jsxs(
|
|
22773
|
+
return /* @__PURE__ */ jsxs(React85.Fragment, { children: [
|
|
22083
22774
|
/* @__PURE__ */ jsx(Box, { className: "relative", children: /* @__PURE__ */ jsx(
|
|
22084
22775
|
ItemSlot,
|
|
22085
22776
|
{
|
|
@@ -22151,8 +22842,8 @@ function DPad({
|
|
|
22151
22842
|
}) {
|
|
22152
22843
|
const eventBus = useEventBus();
|
|
22153
22844
|
const sizes = sizeMap15[size];
|
|
22154
|
-
const [activeDirections, setActiveDirections] =
|
|
22155
|
-
const handlePress =
|
|
22845
|
+
const [activeDirections, setActiveDirections] = React85.useState(/* @__PURE__ */ new Set());
|
|
22846
|
+
const handlePress = React85.useCallback(
|
|
22156
22847
|
(direction) => {
|
|
22157
22848
|
setActiveDirections((prev) => new Set(prev).add(direction));
|
|
22158
22849
|
if (directionEvent) eventBus.emit(`UI:${directionEvent}`, { direction, pressed: true });
|
|
@@ -22160,7 +22851,7 @@ function DPad({
|
|
|
22160
22851
|
},
|
|
22161
22852
|
[directionEvent, eventBus, onDirection]
|
|
22162
22853
|
);
|
|
22163
|
-
const handleRelease =
|
|
22854
|
+
const handleRelease = React85.useCallback(
|
|
22164
22855
|
(direction) => {
|
|
22165
22856
|
setActiveDirections((prev) => {
|
|
22166
22857
|
const next = new Set(prev);
|
|
@@ -22967,8 +23658,8 @@ var init_Menu = __esm({
|
|
|
22967
23658
|
"bottom-end": "bottom-start"
|
|
22968
23659
|
};
|
|
22969
23660
|
const effectivePosition = direction === "rtl" ? rtlMirror[position] ?? position : position;
|
|
22970
|
-
const triggerChild =
|
|
22971
|
-
const triggerElement =
|
|
23661
|
+
const triggerChild = React85__default.isValidElement(trigger) ? trigger : /* @__PURE__ */ jsx(Typography, { variant: "small", as: "span", children: trigger });
|
|
23662
|
+
const triggerElement = React85__default.cloneElement(
|
|
22972
23663
|
triggerChild,
|
|
22973
23664
|
{
|
|
22974
23665
|
ref: triggerRef,
|
|
@@ -23102,14 +23793,14 @@ function useDataDnd(args) {
|
|
|
23102
23793
|
const isZone = Boolean(dragGroup || accepts || sortable);
|
|
23103
23794
|
const enabled = isZone || Boolean(dndRoot);
|
|
23104
23795
|
const eventBus = useEventBus();
|
|
23105
|
-
const parentRoot =
|
|
23796
|
+
const parentRoot = React85__default.useContext(RootCtx);
|
|
23106
23797
|
const isRoot = enabled && parentRoot === null;
|
|
23107
|
-
const zoneId =
|
|
23798
|
+
const zoneId = React85__default.useId();
|
|
23108
23799
|
const ownGroup = dragGroup ?? accepts ?? zoneId;
|
|
23109
|
-
const [optimisticOrders, setOptimisticOrders] =
|
|
23110
|
-
const optimisticOrdersRef =
|
|
23800
|
+
const [optimisticOrders, setOptimisticOrders] = React85__default.useState(() => /* @__PURE__ */ new Map());
|
|
23801
|
+
const optimisticOrdersRef = React85__default.useRef(optimisticOrders);
|
|
23111
23802
|
optimisticOrdersRef.current = optimisticOrders;
|
|
23112
|
-
const clearOptimisticOrder =
|
|
23803
|
+
const clearOptimisticOrder = React85__default.useCallback((group) => {
|
|
23113
23804
|
setOptimisticOrders((prev) => {
|
|
23114
23805
|
if (!prev.has(group)) return prev;
|
|
23115
23806
|
const next = new Map(prev);
|
|
@@ -23134,7 +23825,7 @@ function useDataDnd(args) {
|
|
|
23134
23825
|
const raw = it[dndItemIdField];
|
|
23135
23826
|
return String(raw ?? `__idx_${idx}`);
|
|
23136
23827
|
}).join("|");
|
|
23137
|
-
const itemIds =
|
|
23828
|
+
const itemIds = React85__default.useMemo(
|
|
23138
23829
|
() => orderedItems.map((it, idx) => {
|
|
23139
23830
|
const raw = it[dndItemIdField];
|
|
23140
23831
|
return raw ?? `__idx_${idx}`;
|
|
@@ -23142,7 +23833,7 @@ function useDataDnd(args) {
|
|
|
23142
23833
|
[itemIdsSignature]
|
|
23143
23834
|
);
|
|
23144
23835
|
const itemsContentSig = items.map((it, idx) => String(it[dndItemIdField] ?? `__${idx}`)).join("|");
|
|
23145
|
-
|
|
23836
|
+
React85__default.useEffect(() => {
|
|
23146
23837
|
const root = isRoot ? null : parentRoot;
|
|
23147
23838
|
if (root) {
|
|
23148
23839
|
root.clearOptimisticOrder(ownGroup);
|
|
@@ -23150,20 +23841,20 @@ function useDataDnd(args) {
|
|
|
23150
23841
|
clearOptimisticOrder(ownGroup);
|
|
23151
23842
|
}
|
|
23152
23843
|
}, [itemsContentSig, ownGroup]);
|
|
23153
|
-
const zonesRef =
|
|
23154
|
-
const registerZone =
|
|
23844
|
+
const zonesRef = React85__default.useRef(/* @__PURE__ */ new Map());
|
|
23845
|
+
const registerZone = React85__default.useCallback((zoneId2, meta2) => {
|
|
23155
23846
|
zonesRef.current.set(zoneId2, meta2);
|
|
23156
23847
|
}, []);
|
|
23157
|
-
const unregisterZone =
|
|
23848
|
+
const unregisterZone = React85__default.useCallback((zoneId2) => {
|
|
23158
23849
|
zonesRef.current.delete(zoneId2);
|
|
23159
23850
|
}, []);
|
|
23160
|
-
const [activeDrag, setActiveDrag] =
|
|
23161
|
-
const [overZoneGroup, setOverZoneGroup] =
|
|
23162
|
-
const meta =
|
|
23851
|
+
const [activeDrag, setActiveDrag] = React85__default.useState(null);
|
|
23852
|
+
const [overZoneGroup, setOverZoneGroup] = React85__default.useState(null);
|
|
23853
|
+
const meta = React85__default.useMemo(
|
|
23163
23854
|
() => ({ group: ownGroup, dropEvent, reorderEvent, positionEvent, itemIds, rawItems: items, idField: dndItemIdField }),
|
|
23164
23855
|
[ownGroup, dropEvent, reorderEvent, positionEvent, itemIds, items, dndItemIdField]
|
|
23165
23856
|
);
|
|
23166
|
-
|
|
23857
|
+
React85__default.useEffect(() => {
|
|
23167
23858
|
const target = isRoot ? null : parentRoot;
|
|
23168
23859
|
if (!target) {
|
|
23169
23860
|
zonesRef.current.set(zoneId, meta);
|
|
@@ -23182,7 +23873,7 @@ function useDataDnd(args) {
|
|
|
23182
23873
|
}, [parentRoot, isRoot, zoneId, meta]);
|
|
23183
23874
|
const sensors = useAlmadarDndSensors(true);
|
|
23184
23875
|
const collisionDetection = almadarDndCollisionDetection;
|
|
23185
|
-
const findZoneByItem =
|
|
23876
|
+
const findZoneByItem = React85__default.useCallback(
|
|
23186
23877
|
(id) => {
|
|
23187
23878
|
for (const z of zonesRef.current.values()) {
|
|
23188
23879
|
if (z.itemIds.includes(id)) return z;
|
|
@@ -23191,7 +23882,7 @@ function useDataDnd(args) {
|
|
|
23191
23882
|
},
|
|
23192
23883
|
[]
|
|
23193
23884
|
);
|
|
23194
|
-
|
|
23885
|
+
React85__default.useCallback(
|
|
23195
23886
|
(group) => {
|
|
23196
23887
|
for (const z of zonesRef.current.values()) {
|
|
23197
23888
|
if (z.group === group) return z;
|
|
@@ -23200,7 +23891,7 @@ function useDataDnd(args) {
|
|
|
23200
23891
|
},
|
|
23201
23892
|
[]
|
|
23202
23893
|
);
|
|
23203
|
-
const handleDragEnd =
|
|
23894
|
+
const handleDragEnd = React85__default.useCallback(
|
|
23204
23895
|
(event) => {
|
|
23205
23896
|
const { active, over } = event;
|
|
23206
23897
|
const activeIdStr = String(active.id);
|
|
@@ -23291,8 +23982,8 @@ function useDataDnd(args) {
|
|
|
23291
23982
|
},
|
|
23292
23983
|
[eventBus]
|
|
23293
23984
|
);
|
|
23294
|
-
const sortableData =
|
|
23295
|
-
const SortableItem =
|
|
23985
|
+
const sortableData = React85__default.useMemo(() => ({ dndGroup: ownGroup }), [ownGroup]);
|
|
23986
|
+
const SortableItem = React85__default.useCallback(
|
|
23296
23987
|
({ id, children }) => {
|
|
23297
23988
|
const {
|
|
23298
23989
|
attributes,
|
|
@@ -23332,7 +24023,7 @@ function useDataDnd(args) {
|
|
|
23332
24023
|
id: droppableId,
|
|
23333
24024
|
data: sortableData
|
|
23334
24025
|
});
|
|
23335
|
-
const ctx =
|
|
24026
|
+
const ctx = React85__default.useContext(RootCtx);
|
|
23336
24027
|
const activeDrag2 = ctx?.activeDrag ?? null;
|
|
23337
24028
|
const overZoneGroup2 = ctx?.overZoneGroup ?? null;
|
|
23338
24029
|
const isThisZoneOver = overZoneGroup2 === ownGroup;
|
|
@@ -23347,7 +24038,7 @@ function useDataDnd(args) {
|
|
|
23347
24038
|
showForeignPlaceholder,
|
|
23348
24039
|
ctxAvailable: ctx != null
|
|
23349
24040
|
});
|
|
23350
|
-
|
|
24041
|
+
React85__default.useEffect(() => {
|
|
23351
24042
|
dndLog.info("dropzone:isOver:change", { droppableId, group: ownGroup, isOver, isThisZoneOver, showForeignPlaceholder, activeDragSourceGroup: activeDrag2?.sourceGroup ?? null });
|
|
23352
24043
|
}, [droppableId, isOver, isThisZoneOver, showForeignPlaceholder]);
|
|
23353
24044
|
return /* @__PURE__ */ jsx(
|
|
@@ -23361,11 +24052,11 @@ function useDataDnd(args) {
|
|
|
23361
24052
|
}
|
|
23362
24053
|
);
|
|
23363
24054
|
};
|
|
23364
|
-
const rootContextValue =
|
|
24055
|
+
const rootContextValue = React85__default.useMemo(
|
|
23365
24056
|
() => ({ registerZone, unregisterZone, activeDrag, overZoneGroup, optimisticOrders, clearOptimisticOrder }),
|
|
23366
24057
|
[registerZone, unregisterZone, activeDrag, overZoneGroup, optimisticOrders, clearOptimisticOrder]
|
|
23367
24058
|
);
|
|
23368
|
-
const handleDragStart =
|
|
24059
|
+
const handleDragStart = React85__default.useCallback((event) => {
|
|
23369
24060
|
const sourceZone = findZoneByItem(event.active.id);
|
|
23370
24061
|
const rect = event.active.rect.current.initial;
|
|
23371
24062
|
const height = rect?.height && rect.height > 0 ? rect.height : 64;
|
|
@@ -23384,7 +24075,7 @@ function useDataDnd(args) {
|
|
|
23384
24075
|
isRoot
|
|
23385
24076
|
});
|
|
23386
24077
|
}, [findZoneByItem, isRoot, zoneId]);
|
|
23387
|
-
const handleDragOver =
|
|
24078
|
+
const handleDragOver = React85__default.useCallback((event) => {
|
|
23388
24079
|
const { active, over } = event;
|
|
23389
24080
|
const overData = over?.data?.current;
|
|
23390
24081
|
const overGroup = overData?.dndGroup ?? null;
|
|
@@ -23454,7 +24145,7 @@ function useDataDnd(args) {
|
|
|
23454
24145
|
return next;
|
|
23455
24146
|
});
|
|
23456
24147
|
}, []);
|
|
23457
|
-
const handleDragCancel =
|
|
24148
|
+
const handleDragCancel = React85__default.useCallback((event) => {
|
|
23458
24149
|
setActiveDrag(null);
|
|
23459
24150
|
setOverZoneGroup(null);
|
|
23460
24151
|
dndLog.warn("dragCancel", {
|
|
@@ -23462,12 +24153,12 @@ function useDataDnd(args) {
|
|
|
23462
24153
|
reason: "dnd-kit cancelled the drag (escape key, pointer interrupted, or external)"
|
|
23463
24154
|
});
|
|
23464
24155
|
}, []);
|
|
23465
|
-
const handleDragEndWithCleanup =
|
|
24156
|
+
const handleDragEndWithCleanup = React85__default.useCallback((event) => {
|
|
23466
24157
|
handleDragEnd(event);
|
|
23467
24158
|
setActiveDrag(null);
|
|
23468
24159
|
setOverZoneGroup(null);
|
|
23469
24160
|
}, [handleDragEnd]);
|
|
23470
|
-
const wrapContainer =
|
|
24161
|
+
const wrapContainer = React85__default.useCallback(
|
|
23471
24162
|
(children) => {
|
|
23472
24163
|
if (!enabled) return children;
|
|
23473
24164
|
const strategy = layout === "grid" ? rectSortingStrategy : verticalListSortingStrategy;
|
|
@@ -23521,7 +24212,7 @@ var init_useDataDnd = __esm({
|
|
|
23521
24212
|
init_useAlmadarDndCollision();
|
|
23522
24213
|
init_Box();
|
|
23523
24214
|
dndLog = createLogger("almadar:ui:dnd");
|
|
23524
|
-
RootCtx =
|
|
24215
|
+
RootCtx = React85__default.createContext(null);
|
|
23525
24216
|
}
|
|
23526
24217
|
});
|
|
23527
24218
|
function renderIconInput(icon, props) {
|
|
@@ -24047,7 +24738,7 @@ function DataList({
|
|
|
24047
24738
|
}) {
|
|
24048
24739
|
const eventBus = useEventBus();
|
|
24049
24740
|
const { t } = useTranslate();
|
|
24050
|
-
const [visibleCount, setVisibleCount] =
|
|
24741
|
+
const [visibleCount, setVisibleCount] = React85__default.useState(pageSize || Infinity);
|
|
24051
24742
|
const fieldDefs = fields ?? columns ?? [];
|
|
24052
24743
|
const allDataRaw = Array.isArray(entity) ? entity : entity ? [entity] : [];
|
|
24053
24744
|
const dnd = useDataDnd({
|
|
@@ -24066,7 +24757,7 @@ function DataList({
|
|
|
24066
24757
|
const data = pageSize > 0 ? allData.slice(0, visibleCount) : allData;
|
|
24067
24758
|
const hasMoreLocal = pageSize > 0 && visibleCount < allData.length;
|
|
24068
24759
|
const hasRenderProp = typeof children === "function";
|
|
24069
|
-
|
|
24760
|
+
React85__default.useEffect(() => {
|
|
24070
24761
|
const renderItemTypeOf = typeof schemaRenderItem;
|
|
24071
24762
|
const childrenTypeOf = typeof children;
|
|
24072
24763
|
if (data.length > 0 && !hasRenderProp) {
|
|
@@ -24171,7 +24862,7 @@ function DataList({
|
|
|
24171
24862
|
const items2 = data.map((item) => item);
|
|
24172
24863
|
const groups2 = groupBy ? groupData(items2, groupBy) : [{ label: "", items: items2 }];
|
|
24173
24864
|
const contentField = titleField?.name ?? fieldDefs[0]?.name ?? "";
|
|
24174
|
-
return /* @__PURE__ */ jsx(VStack, { gap: "sm", className: cn("py-2", className), children: groups2.map((group, gi) => /* @__PURE__ */ jsxs(
|
|
24865
|
+
return /* @__PURE__ */ jsx(VStack, { gap: "sm", className: cn("py-2", className), children: groups2.map((group, gi) => /* @__PURE__ */ jsxs(React85__default.Fragment, { children: [
|
|
24175
24866
|
group.label && /* @__PURE__ */ jsx(Divider, { label: group.label, className: "my-2" }),
|
|
24176
24867
|
group.items.map((itemData, index) => {
|
|
24177
24868
|
const id = itemData.id || `${gi}-${index}`;
|
|
@@ -24312,7 +25003,7 @@ function DataList({
|
|
|
24312
25003
|
className
|
|
24313
25004
|
),
|
|
24314
25005
|
children: [
|
|
24315
|
-
groups.map((group, gi) => /* @__PURE__ */ jsxs(
|
|
25006
|
+
groups.map((group, gi) => /* @__PURE__ */ jsxs(React85__default.Fragment, { children: [
|
|
24316
25007
|
group.label && /* @__PURE__ */ jsx(Divider, { label: group.label, className: gi > 0 ? "mt-4" : "mt-0" }),
|
|
24317
25008
|
group.items.map(
|
|
24318
25009
|
(itemData, index) => renderItem(itemData, index, gi === groups.length - 1 && index === group.items.length - 1)
|
|
@@ -25228,7 +25919,7 @@ var init_Grid = __esm({
|
|
|
25228
25919
|
as: Component2 = "div"
|
|
25229
25920
|
}) => {
|
|
25230
25921
|
const mergedStyle = rows2 ? { gridTemplateRows: `repeat(${rows2}, minmax(0, 1fr))`, ...style } : style;
|
|
25231
|
-
return
|
|
25922
|
+
return React85__default.createElement(
|
|
25232
25923
|
Component2,
|
|
25233
25924
|
{
|
|
25234
25925
|
className: cn(
|
|
@@ -25416,8 +26107,8 @@ var init_Popover = __esm({
|
|
|
25416
26107
|
onMouseEnter: handleOpen,
|
|
25417
26108
|
onMouseLeave: handleClose
|
|
25418
26109
|
};
|
|
25419
|
-
const childElement =
|
|
25420
|
-
const triggerElement =
|
|
26110
|
+
const childElement = React85__default.isValidElement(children) ? children : /* @__PURE__ */ jsx("span", { children });
|
|
26111
|
+
const triggerElement = React85__default.cloneElement(
|
|
25421
26112
|
childElement,
|
|
25422
26113
|
{
|
|
25423
26114
|
ref: triggerRef,
|
|
@@ -26007,8 +26698,8 @@ var init_Tooltip = __esm({
|
|
|
26007
26698
|
if (hideTimeoutRef.current) clearTimeout(hideTimeoutRef.current);
|
|
26008
26699
|
};
|
|
26009
26700
|
}, []);
|
|
26010
|
-
const triggerElement =
|
|
26011
|
-
const trigger =
|
|
26701
|
+
const triggerElement = React85__default.isValidElement(children) ? children : /* @__PURE__ */ jsx("span", { children });
|
|
26702
|
+
const trigger = React85__default.cloneElement(triggerElement, {
|
|
26012
26703
|
ref: triggerRef,
|
|
26013
26704
|
onMouseEnter: handleMouseEnter,
|
|
26014
26705
|
onMouseLeave: handleMouseLeave,
|
|
@@ -26094,7 +26785,7 @@ var init_WizardProgress = __esm({
|
|
|
26094
26785
|
children: /* @__PURE__ */ jsx("div", { className: "flex items-center gap-2", children: normalizedSteps.map((step, index) => {
|
|
26095
26786
|
const isActive = index === currentStep;
|
|
26096
26787
|
const isCompleted = index < currentStep;
|
|
26097
|
-
return /* @__PURE__ */ jsxs(
|
|
26788
|
+
return /* @__PURE__ */ jsxs(React85__default.Fragment, { children: [
|
|
26098
26789
|
/* @__PURE__ */ jsx(
|
|
26099
26790
|
"button",
|
|
26100
26791
|
{
|
|
@@ -27055,7 +27746,7 @@ var init_ProgressDots = __esm({
|
|
|
27055
27746
|
}
|
|
27056
27747
|
});
|
|
27057
27748
|
function StatBadge({
|
|
27058
|
-
assetUrl
|
|
27749
|
+
assetUrl,
|
|
27059
27750
|
label,
|
|
27060
27751
|
value = 0,
|
|
27061
27752
|
max,
|
|
@@ -27122,7 +27813,7 @@ function StatBadge({
|
|
|
27122
27813
|
}
|
|
27123
27814
|
);
|
|
27124
27815
|
}
|
|
27125
|
-
var sizeMap17, variantMap2
|
|
27816
|
+
var sizeMap17, variantMap2;
|
|
27126
27817
|
var init_StatBadge = __esm({
|
|
27127
27818
|
"components/game/molecules/StatBadge.tsx"() {
|
|
27128
27819
|
init_cn();
|
|
@@ -27141,7 +27832,6 @@ var init_StatBadge = __esm({
|
|
|
27141
27832
|
warning: "bg-warning/15 border-warning/40 text-foreground",
|
|
27142
27833
|
danger: "bg-error/15 border-error/40 text-foreground"
|
|
27143
27834
|
};
|
|
27144
|
-
DEFAULT_ASSET_URL12 = "https://almadar-kflow-assets.web.app/shared/effects/particles/light_01.png";
|
|
27145
27835
|
StatBadge.displayName = "StatBadge";
|
|
27146
27836
|
}
|
|
27147
27837
|
});
|
|
@@ -27158,7 +27848,7 @@ function InventoryGrid({
|
|
|
27158
27848
|
const eventBus = useEventBus();
|
|
27159
27849
|
const slotCount = totalSlots ?? items.length;
|
|
27160
27850
|
const emptySlotCount = Math.max(0, slotCount - items.length);
|
|
27161
|
-
const handleSelect =
|
|
27851
|
+
const handleSelect = React85.useCallback(
|
|
27162
27852
|
(id) => {
|
|
27163
27853
|
onSelect?.(id);
|
|
27164
27854
|
if (selectEvent) {
|
|
@@ -27389,35 +28079,37 @@ function GameCanvas2D({
|
|
|
27389
28079
|
drawEvent,
|
|
27390
28080
|
fps = 60,
|
|
27391
28081
|
backgroundImage = "",
|
|
27392
|
-
assetBaseUrl
|
|
28082
|
+
assetBaseUrl,
|
|
27393
28083
|
className
|
|
27394
28084
|
}) {
|
|
27395
|
-
const canvasRef =
|
|
27396
|
-
const rafRef =
|
|
27397
|
-
const frameRef =
|
|
27398
|
-
const lastTimeRef =
|
|
27399
|
-
const imageCache =
|
|
28085
|
+
const canvasRef = React85.useRef(null);
|
|
28086
|
+
const rafRef = React85.useRef(0);
|
|
28087
|
+
const frameRef = React85.useRef(0);
|
|
28088
|
+
const lastTimeRef = React85.useRef(0);
|
|
28089
|
+
const imageCache = React85.useRef(/* @__PURE__ */ new Map());
|
|
27400
28090
|
const emit = useEmitEvent();
|
|
27401
|
-
const onDrawRef =
|
|
28091
|
+
const onDrawRef = React85.useRef(onDraw);
|
|
27402
28092
|
onDrawRef.current = onDraw;
|
|
27403
|
-
const onTickRef =
|
|
28093
|
+
const onTickRef = React85.useRef(onTick);
|
|
27404
28094
|
onTickRef.current = onTick;
|
|
27405
|
-
const tickEventRef =
|
|
28095
|
+
const tickEventRef = React85.useRef(tickEvent);
|
|
27406
28096
|
tickEventRef.current = tickEvent;
|
|
27407
|
-
const drawEventRef =
|
|
28097
|
+
const drawEventRef = React85.useRef(drawEvent);
|
|
27408
28098
|
drawEventRef.current = drawEvent;
|
|
27409
|
-
const emitRef =
|
|
28099
|
+
const emitRef = React85.useRef(emit);
|
|
27410
28100
|
emitRef.current = emit;
|
|
27411
|
-
const assetBaseUrlRef =
|
|
28101
|
+
const assetBaseUrlRef = React85.useRef(assetBaseUrl);
|
|
27412
28102
|
assetBaseUrlRef.current = assetBaseUrl;
|
|
27413
|
-
const backgroundImageRef =
|
|
28103
|
+
const backgroundImageRef = React85.useRef(backgroundImage);
|
|
27414
28104
|
backgroundImageRef.current = backgroundImage;
|
|
27415
|
-
const widthRef =
|
|
28105
|
+
const widthRef = React85.useRef(width);
|
|
27416
28106
|
widthRef.current = width;
|
|
27417
|
-
const heightRef =
|
|
28107
|
+
const heightRef = React85.useRef(height);
|
|
27418
28108
|
heightRef.current = height;
|
|
27419
|
-
const loadImage =
|
|
27420
|
-
const
|
|
28109
|
+
const loadImage = React85.useCallback((url) => {
|
|
28110
|
+
const base = assetBaseUrlRef.current;
|
|
28111
|
+
if (!url.startsWith("http") && !base) return null;
|
|
28112
|
+
const fullUrl = url.startsWith("http") ? url : `${base}${url}`;
|
|
27421
28113
|
const cached = imageCache.current.get(fullUrl);
|
|
27422
28114
|
if (cached?.complete && cached.naturalWidth > 0) return cached;
|
|
27423
28115
|
if (!cached) {
|
|
@@ -27428,7 +28120,7 @@ function GameCanvas2D({
|
|
|
27428
28120
|
}
|
|
27429
28121
|
return null;
|
|
27430
28122
|
}, []);
|
|
27431
|
-
|
|
28123
|
+
React85.useEffect(() => {
|
|
27432
28124
|
const canvas = canvasRef.current;
|
|
27433
28125
|
if (!canvas) return;
|
|
27434
28126
|
const ctx = canvas.getContext("2d");
|
|
@@ -27740,7 +28432,7 @@ function TurnPanel({
|
|
|
27740
28432
|
className
|
|
27741
28433
|
}) {
|
|
27742
28434
|
const eventBus = useEventBus();
|
|
27743
|
-
const handleAction =
|
|
28435
|
+
const handleAction = React85.useCallback(
|
|
27744
28436
|
(event) => {
|
|
27745
28437
|
if (event) {
|
|
27746
28438
|
eventBus.emit(event, { turn: currentTurn, phase, activeTeam });
|
|
@@ -27798,7 +28490,7 @@ var init_TurnPanel = __esm({
|
|
|
27798
28490
|
}
|
|
27799
28491
|
});
|
|
27800
28492
|
function EnemyPlate({
|
|
27801
|
-
assetUrl
|
|
28493
|
+
assetUrl,
|
|
27802
28494
|
name = "Shadow Guard",
|
|
27803
28495
|
health = 80,
|
|
27804
28496
|
maxHealth = 100,
|
|
@@ -27882,7 +28574,7 @@ function EnemyPlate({
|
|
|
27882
28574
|
}
|
|
27883
28575
|
);
|
|
27884
28576
|
}
|
|
27885
|
-
var effectVariantMap2, DEFAULT_ENEMY_EFFECTS
|
|
28577
|
+
var effectVariantMap2, DEFAULT_ENEMY_EFFECTS;
|
|
27886
28578
|
var init_EnemyPlate = __esm({
|
|
27887
28579
|
"components/game/molecules/EnemyPlate.tsx"() {
|
|
27888
28580
|
"use client";
|
|
@@ -27899,7 +28591,6 @@ var init_EnemyPlate = __esm({
|
|
|
27899
28591
|
DEFAULT_ENEMY_EFFECTS = [
|
|
27900
28592
|
{ icon: "flame", label: "Burn", variant: "debuff" }
|
|
27901
28593
|
];
|
|
27902
|
-
DEFAULT_ASSET_URL13 = "https://almadar-kflow-assets.web.app/shared/portraits/shadow-legion.png";
|
|
27903
28594
|
EnemyPlate.displayName = "EnemyPlate";
|
|
27904
28595
|
}
|
|
27905
28596
|
});
|
|
@@ -27909,7 +28600,7 @@ function UnitCommandBar({
|
|
|
27909
28600
|
className
|
|
27910
28601
|
}) {
|
|
27911
28602
|
const eventBus = useEventBus();
|
|
27912
|
-
const handleCommand =
|
|
28603
|
+
const handleCommand = React85.useCallback(
|
|
27913
28604
|
(event) => {
|
|
27914
28605
|
if (event) {
|
|
27915
28606
|
eventBus.emit(event, { unitId: selectedUnitId });
|
|
@@ -28050,6 +28741,9 @@ function DialogueBox({
|
|
|
28050
28741
|
completeEvent,
|
|
28051
28742
|
choiceEvent,
|
|
28052
28743
|
advanceEvent,
|
|
28744
|
+
backgroundImage,
|
|
28745
|
+
portraitUrl,
|
|
28746
|
+
portraitScale = 1,
|
|
28053
28747
|
className
|
|
28054
28748
|
}) {
|
|
28055
28749
|
const eventBus = useEventBus();
|
|
@@ -28165,64 +28859,98 @@ function DialogueBox({
|
|
|
28165
28859
|
}
|
|
28166
28860
|
}, [isTyping, skipTypewriter, dialogue.choices, selectedChoice, onChoice, onAdvance, choiceEvent, advanceEvent, eventBus]);
|
|
28167
28861
|
const enabledChoices = dialogue.choices?.filter((c) => !c.disabled) ?? [];
|
|
28168
|
-
return /* @__PURE__ */
|
|
28169
|
-
|
|
28170
|
-
|
|
28171
|
-
|
|
28172
|
-
"fixed
|
|
28173
|
-
|
|
28174
|
-
|
|
28175
|
-
|
|
28176
|
-
|
|
28177
|
-
|
|
28178
|
-
|
|
28179
|
-
|
|
28180
|
-
|
|
28181
|
-
|
|
28182
|
-
|
|
28862
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
28863
|
+
backgroundImage && /* @__PURE__ */ jsx(
|
|
28864
|
+
"div",
|
|
28865
|
+
{
|
|
28866
|
+
className: "fixed inset-0 z-20 bg-center bg-cover bg-no-repeat",
|
|
28867
|
+
style: { backgroundImage: `url(${backgroundImage})` },
|
|
28868
|
+
"aria-hidden": "true"
|
|
28869
|
+
}
|
|
28870
|
+
),
|
|
28871
|
+
portraitUrl && /* @__PURE__ */ jsx(
|
|
28872
|
+
"div",
|
|
28873
|
+
{
|
|
28874
|
+
className: cn(
|
|
28875
|
+
"fixed left-1/2 -translate-x-1/2 z-30 pointer-events-none flex items-end",
|
|
28876
|
+
position === "top" ? "top-0" : "bottom-0"
|
|
28877
|
+
),
|
|
28878
|
+
style: { height: `${60 * portraitScale}vh` },
|
|
28879
|
+
children: /* @__PURE__ */ jsx(
|
|
28183
28880
|
"img",
|
|
28184
28881
|
{
|
|
28185
|
-
src:
|
|
28882
|
+
src: portraitUrl,
|
|
28186
28883
|
alt: dialogue.speaker,
|
|
28187
|
-
className: "
|
|
28188
|
-
style: { imageRendering: "pixelated" }
|
|
28884
|
+
className: "h-full w-auto object-contain drop-shadow-2xl"
|
|
28189
28885
|
}
|
|
28190
|
-
)
|
|
28191
|
-
|
|
28192
|
-
|
|
28193
|
-
|
|
28194
|
-
|
|
28195
|
-
|
|
28196
|
-
|
|
28197
|
-
|
|
28198
|
-
|
|
28886
|
+
)
|
|
28887
|
+
}
|
|
28888
|
+
),
|
|
28889
|
+
/* @__PURE__ */ jsx(
|
|
28890
|
+
"div",
|
|
28891
|
+
{
|
|
28892
|
+
className: cn(
|
|
28893
|
+
"fixed left-0 right-0 z-40",
|
|
28894
|
+
position === "top" ? "top-0" : "bottom-0",
|
|
28895
|
+
className
|
|
28896
|
+
),
|
|
28897
|
+
onClick: handleClick,
|
|
28898
|
+
onKeyDown: handleKeyDown,
|
|
28899
|
+
tabIndex: 0,
|
|
28900
|
+
role: "dialog",
|
|
28901
|
+
"aria-label": "Dialogue",
|
|
28902
|
+
children: /* @__PURE__ */ jsx("div", { className: cn(
|
|
28903
|
+
"mx-4 my-4 border-2 rounded-container overflow-hidden",
|
|
28904
|
+
backgroundImage ? "bg-black/80 backdrop-blur-sm text-white border-white/20" : "bg-[var(--color-card)] bg-opacity-95 border-border"
|
|
28905
|
+
), children: /* @__PURE__ */ jsxs("div", { className: "flex", children: [
|
|
28906
|
+
dialogue.portrait && /* @__PURE__ */ jsx("div", { className: "flex-shrink-0 p-4 border-r border-border", children: /* @__PURE__ */ jsx(
|
|
28907
|
+
"img",
|
|
28199
28908
|
{
|
|
28200
|
-
|
|
28201
|
-
|
|
28202
|
-
|
|
28203
|
-
|
|
28204
|
-
|
|
28205
|
-
|
|
28206
|
-
|
|
28207
|
-
|
|
28208
|
-
|
|
28209
|
-
|
|
28909
|
+
src: dialogue.portrait,
|
|
28910
|
+
alt: dialogue.speaker,
|
|
28911
|
+
className: "w-24 h-24 object-contain",
|
|
28912
|
+
style: { imageRendering: "pixelated" }
|
|
28913
|
+
}
|
|
28914
|
+
) }),
|
|
28915
|
+
/* @__PURE__ */ jsxs("div", { className: "flex-1 p-4", children: [
|
|
28916
|
+
/* @__PURE__ */ jsx("div", { className: "text-warning font-bold mb-2", children: dialogue.speaker }),
|
|
28917
|
+
/* @__PURE__ */ jsxs("div", { className: cn(
|
|
28918
|
+
"text-lg leading-relaxed min-h-[60px]",
|
|
28919
|
+
backgroundImage ? "text-white" : "text-[var(--color-foreground)]"
|
|
28920
|
+
), children: [
|
|
28921
|
+
displayedText,
|
|
28922
|
+
isTyping && /* @__PURE__ */ jsx("span", { className: "animate-pulse", children: "\u258C" })
|
|
28923
|
+
] }),
|
|
28924
|
+
!isTyping && enabledChoices.length > 0 && /* @__PURE__ */ jsx("div", { className: "mt-4 space-y-2", children: enabledChoices.map((choice, index) => /* @__PURE__ */ jsxs(
|
|
28925
|
+
"button",
|
|
28926
|
+
{
|
|
28927
|
+
type: "button",
|
|
28928
|
+
className: cn(
|
|
28929
|
+
"block w-full text-left px-4 py-2 rounded-interactive transition-colors",
|
|
28930
|
+
"hover:bg-[var(--color-surface,#374151)] focus:outline-none focus:ring-2 focus:ring-warning",
|
|
28931
|
+
selectedChoice === index ? "bg-[var(--color-surface,#374151)] text-warning" : backgroundImage ? "bg-white/10 text-white hover:bg-white/20" : "bg-[var(--color-card)] text-[var(--color-foreground)]"
|
|
28932
|
+
),
|
|
28933
|
+
onClick: (e) => {
|
|
28934
|
+
e.stopPropagation();
|
|
28935
|
+
if (choiceEvent) eventBus.emit(`UI:${choiceEvent}`, { choice });
|
|
28936
|
+
onChoice?.(choice);
|
|
28937
|
+
},
|
|
28938
|
+
children: [
|
|
28939
|
+
/* @__PURE__ */ jsxs("span", { className: "text-muted-foreground mr-2", children: [
|
|
28940
|
+
index + 1,
|
|
28941
|
+
"."
|
|
28942
|
+
] }),
|
|
28943
|
+
choice.text
|
|
28944
|
+
]
|
|
28210
28945
|
},
|
|
28211
|
-
|
|
28212
|
-
|
|
28213
|
-
|
|
28214
|
-
|
|
28215
|
-
|
|
28216
|
-
|
|
28217
|
-
|
|
28218
|
-
|
|
28219
|
-
index
|
|
28220
|
-
)) }),
|
|
28221
|
-
!isTyping && !dialogue.choices?.length && /* @__PURE__ */ jsx("div", { className: "mt-4 text-muted-foreground text-sm animate-pulse", children: "Press SPACE or click to continue..." })
|
|
28222
|
-
] })
|
|
28223
|
-
] }) })
|
|
28224
|
-
}
|
|
28225
|
-
);
|
|
28946
|
+
index
|
|
28947
|
+
)) }),
|
|
28948
|
+
!isTyping && !dialogue.choices?.length && /* @__PURE__ */ jsx("div", { className: "mt-4 text-muted-foreground text-sm animate-pulse", children: "Press SPACE or click to continue..." })
|
|
28949
|
+
] })
|
|
28950
|
+
] }) })
|
|
28951
|
+
}
|
|
28952
|
+
)
|
|
28953
|
+
] });
|
|
28226
28954
|
}
|
|
28227
28955
|
var DEFAULT_DIALOGUE;
|
|
28228
28956
|
var init_DialogueBox = __esm({
|
|
@@ -28423,7 +29151,7 @@ function GameMenu({
|
|
|
28423
29151
|
} catch {
|
|
28424
29152
|
}
|
|
28425
29153
|
const eventBus = eventBusProp || eventBusFromHook;
|
|
28426
|
-
const handleOptionClick =
|
|
29154
|
+
const handleOptionClick = React85.useCallback(
|
|
28427
29155
|
(option) => {
|
|
28428
29156
|
if (option.event && eventBus) {
|
|
28429
29157
|
eventBus.emit(`UI:${option.event}`, { option });
|
|
@@ -28542,7 +29270,7 @@ function GameOverScreen({
|
|
|
28542
29270
|
} catch {
|
|
28543
29271
|
}
|
|
28544
29272
|
const eventBus = eventBusProp || eventBusFromHook;
|
|
28545
|
-
const handleActionClick =
|
|
29273
|
+
const handleActionClick = React85.useCallback(
|
|
28546
29274
|
(action) => {
|
|
28547
29275
|
if (action.event && eventBus) {
|
|
28548
29276
|
eventBus.emit(`UI:${action.event}`, { action });
|
|
@@ -28749,10 +29477,10 @@ function PlatformerCanvas({
|
|
|
28749
29477
|
canvasHeight = 400,
|
|
28750
29478
|
followCamera = true,
|
|
28751
29479
|
bgColor = "#5c94fc",
|
|
28752
|
-
playerSprite
|
|
29480
|
+
playerSprite,
|
|
28753
29481
|
tileSprites,
|
|
28754
29482
|
backgroundImage = "",
|
|
28755
|
-
assetBaseUrl
|
|
29483
|
+
assetBaseUrl,
|
|
28756
29484
|
leftEvent = "MOVE_LEFT",
|
|
28757
29485
|
rightEvent = "MOVE_RIGHT",
|
|
28758
29486
|
jumpEvent = "JUMP",
|
|
@@ -28766,6 +29494,7 @@ function PlatformerCanvas({
|
|
|
28766
29494
|
const imageCache = useRef(/* @__PURE__ */ new Map());
|
|
28767
29495
|
const [loadedImages, setLoadedImages] = useState(/* @__PURE__ */ new Set());
|
|
28768
29496
|
const loadImage = useCallback((url) => {
|
|
29497
|
+
if (!url.startsWith("http") && !assetBaseUrl) return null;
|
|
28769
29498
|
const fullUrl = url.startsWith("http") ? url : `${assetBaseUrl}${url}`;
|
|
28770
29499
|
const cached = imageCache.current.get(fullUrl);
|
|
28771
29500
|
if (cached?.complete && cached.naturalWidth > 0) {
|
|
@@ -29464,13 +30193,13 @@ var init_MapView = __esm({
|
|
|
29464
30193
|
shadowSize: [41, 41]
|
|
29465
30194
|
});
|
|
29466
30195
|
L.Marker.prototype.options.icon = defaultIcon;
|
|
29467
|
-
const { useEffect:
|
|
30196
|
+
const { useEffect: useEffect81, useRef: useRef78, useCallback: useCallback123, useState: useState110 } = React85__default;
|
|
29468
30197
|
const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
|
|
29469
30198
|
const { useEventBus: useEventBus3 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
|
|
29470
30199
|
function MapUpdater({ centerLat, centerLng, zoom }) {
|
|
29471
30200
|
const map = useMap();
|
|
29472
|
-
const prevRef =
|
|
29473
|
-
|
|
30201
|
+
const prevRef = useRef78({ centerLat, centerLng, zoom });
|
|
30202
|
+
useEffect81(() => {
|
|
29474
30203
|
const prev = prevRef.current;
|
|
29475
30204
|
if (prev.centerLat !== centerLat || prev.centerLng !== centerLng || prev.zoom !== zoom) {
|
|
29476
30205
|
map.setView([centerLat, centerLng], zoom);
|
|
@@ -29481,7 +30210,7 @@ var init_MapView = __esm({
|
|
|
29481
30210
|
}
|
|
29482
30211
|
function MapClickHandler({ onMapClick }) {
|
|
29483
30212
|
const map = useMap();
|
|
29484
|
-
|
|
30213
|
+
useEffect81(() => {
|
|
29485
30214
|
if (!onMapClick) return;
|
|
29486
30215
|
const handler = (e) => {
|
|
29487
30216
|
onMapClick(e.latlng.lat, e.latlng.lng);
|
|
@@ -29509,8 +30238,8 @@ var init_MapView = __esm({
|
|
|
29509
30238
|
showAttribution = true
|
|
29510
30239
|
}) {
|
|
29511
30240
|
const eventBus = useEventBus3();
|
|
29512
|
-
const [clickedPosition, setClickedPosition] =
|
|
29513
|
-
const handleMapClick =
|
|
30241
|
+
const [clickedPosition, setClickedPosition] = useState110(null);
|
|
30242
|
+
const handleMapClick = useCallback123((lat, lng) => {
|
|
29514
30243
|
if (showClickedPin) {
|
|
29515
30244
|
setClickedPosition({ lat, lng });
|
|
29516
30245
|
}
|
|
@@ -29519,7 +30248,7 @@ var init_MapView = __esm({
|
|
|
29519
30248
|
eventBus.emit(`UI:${mapClickEvent}`, { latitude: lat, longitude: lng });
|
|
29520
30249
|
}
|
|
29521
30250
|
}, [onMapClick, mapClickEvent, eventBus, showClickedPin]);
|
|
29522
|
-
const handleMarkerClick =
|
|
30251
|
+
const handleMarkerClick = useCallback123((marker) => {
|
|
29523
30252
|
onMarkerClick?.(marker);
|
|
29524
30253
|
if (markerClickEvent) {
|
|
29525
30254
|
eventBus.emit(`UI:${markerClickEvent}`, { ...marker });
|
|
@@ -30370,8 +31099,8 @@ function TableView({
|
|
|
30370
31099
|
}) {
|
|
30371
31100
|
const eventBus = useEventBus();
|
|
30372
31101
|
const { t } = useTranslate();
|
|
30373
|
-
const [visibleCount, setVisibleCount] =
|
|
30374
|
-
const [localSelected, setLocalSelected] =
|
|
31102
|
+
const [visibleCount, setVisibleCount] = React85__default.useState(pageSize > 0 ? pageSize : Infinity);
|
|
31103
|
+
const [localSelected, setLocalSelected] = React85__default.useState(/* @__PURE__ */ new Set());
|
|
30375
31104
|
const colDefs = columns ?? fields ?? [];
|
|
30376
31105
|
const allDataRaw = Array.isArray(entity) ? entity : entity ? [entity] : [];
|
|
30377
31106
|
const dnd = useDataDnd({
|
|
@@ -30566,12 +31295,12 @@ function TableView({
|
|
|
30566
31295
|
]
|
|
30567
31296
|
}
|
|
30568
31297
|
);
|
|
30569
|
-
return dnd.isZone ? /* @__PURE__ */ jsx(dnd.SortableItem, { id: row[idField] ?? id, children: rowInner }, id) : /* @__PURE__ */ jsx(
|
|
31298
|
+
return dnd.isZone ? /* @__PURE__ */ jsx(dnd.SortableItem, { id: row[idField] ?? id, children: rowInner }, id) : /* @__PURE__ */ jsx(React85__default.Fragment, { children: rowInner }, id);
|
|
30570
31299
|
};
|
|
30571
31300
|
const items = data.map((row) => row);
|
|
30572
31301
|
const groups = groupBy ? groupData2(items, groupBy) : [{ label: "", items }];
|
|
30573
31302
|
let runningIndex = 0;
|
|
30574
|
-
const body = /* @__PURE__ */ jsx(Box, { role: "rowgroup", children: groups.map((group, gi) => /* @__PURE__ */ jsxs(
|
|
31303
|
+
const body = /* @__PURE__ */ jsx(Box, { role: "rowgroup", children: groups.map((group, gi) => /* @__PURE__ */ jsxs(React85__default.Fragment, { children: [
|
|
30575
31304
|
group.label && /* @__PURE__ */ jsx(Divider, { label: group.label, className: gi > 0 ? "mt-3" : "mt-0" }),
|
|
30576
31305
|
group.items.map((row) => renderRow(row, runningIndex++))
|
|
30577
31306
|
] }, gi)) });
|
|
@@ -31928,7 +32657,7 @@ var init_StepFlow = __esm({
|
|
|
31928
32657
|
className
|
|
31929
32658
|
}) => {
|
|
31930
32659
|
if (orientation === "vertical") {
|
|
31931
|
-
return /* @__PURE__ */ jsx(VStack, { gap: "none", className: cn("w-full", className), children: steps.map((step, index) => /* @__PURE__ */ jsx(
|
|
32660
|
+
return /* @__PURE__ */ jsx(VStack, { gap: "none", className: cn("w-full", className), children: steps.map((step, index) => /* @__PURE__ */ jsx(React85__default.Fragment, { children: /* @__PURE__ */ jsxs(HStack, { gap: "md", align: "start", className: "w-full", children: [
|
|
31932
32661
|
/* @__PURE__ */ jsxs(VStack, { gap: "none", align: "center", children: [
|
|
31933
32662
|
/* @__PURE__ */ jsx(StepCircle, { step, index }),
|
|
31934
32663
|
showConnectors && index < steps.length - 1 && /* @__PURE__ */ jsx(Box, { className: "w-px h-8 bg-border" })
|
|
@@ -31939,7 +32668,7 @@ var init_StepFlow = __esm({
|
|
|
31939
32668
|
] })
|
|
31940
32669
|
] }) }, index)) });
|
|
31941
32670
|
}
|
|
31942
|
-
return /* @__PURE__ */ jsx(Box, { className: cn("w-full flex flex-col md:flex-row items-start gap-0", className), children: steps.map((step, index) => /* @__PURE__ */ jsxs(
|
|
32671
|
+
return /* @__PURE__ */ jsx(Box, { className: cn("w-full flex flex-col md:flex-row items-start gap-0", className), children: steps.map((step, index) => /* @__PURE__ */ jsxs(React85__default.Fragment, { children: [
|
|
31943
32672
|
/* @__PURE__ */ jsxs(VStack, { gap: "sm", align: "center", className: "flex-1 w-full md:w-auto", children: [
|
|
31944
32673
|
/* @__PURE__ */ jsx(StepCircle, { step, index }),
|
|
31945
32674
|
/* @__PURE__ */ jsx(Typography, { variant: "h4", className: "text-center", children: step.title }),
|
|
@@ -32924,7 +33653,7 @@ var init_LikertScale = __esm({
|
|
|
32924
33653
|
md: "text-base",
|
|
32925
33654
|
lg: "text-lg"
|
|
32926
33655
|
};
|
|
32927
|
-
LikertScale =
|
|
33656
|
+
LikertScale = React85__default.forwardRef(
|
|
32928
33657
|
({
|
|
32929
33658
|
question,
|
|
32930
33659
|
options = DEFAULT_LIKERT_OPTIONS,
|
|
@@ -32936,7 +33665,7 @@ var init_LikertScale = __esm({
|
|
|
32936
33665
|
variant = "radios",
|
|
32937
33666
|
className
|
|
32938
33667
|
}, ref) => {
|
|
32939
|
-
const groupId =
|
|
33668
|
+
const groupId = React85__default.useId();
|
|
32940
33669
|
const eventBus = useEventBus();
|
|
32941
33670
|
const handleSelect = useCallback(
|
|
32942
33671
|
(next) => {
|
|
@@ -35218,7 +35947,7 @@ var init_DocBreadcrumb = __esm({
|
|
|
35218
35947
|
"aria-label": t("aria.breadcrumb"),
|
|
35219
35948
|
children: /* @__PURE__ */ jsx(HStack, { gap: "xs", align: "center", wrap: true, children: items.map((item, idx) => {
|
|
35220
35949
|
const isLast = idx === items.length - 1;
|
|
35221
|
-
return /* @__PURE__ */ jsxs(
|
|
35950
|
+
return /* @__PURE__ */ jsxs(React85__default.Fragment, { children: [
|
|
35222
35951
|
idx > 0 && /* @__PURE__ */ jsx(
|
|
35223
35952
|
Icon,
|
|
35224
35953
|
{
|
|
@@ -36087,7 +36816,7 @@ var init_MiniStateMachine = __esm({
|
|
|
36087
36816
|
const x = 2 + i * (NODE_W + GAP + ARROW_W + GAP);
|
|
36088
36817
|
const tc = transitionCounts[s.name] ?? 0;
|
|
36089
36818
|
const role = getStateRole(s.name, s.isInitial, s.isTerminal, tc, maxTC);
|
|
36090
|
-
return /* @__PURE__ */ jsxs(
|
|
36819
|
+
return /* @__PURE__ */ jsxs(React85__default.Fragment, { children: [
|
|
36091
36820
|
/* @__PURE__ */ jsx(
|
|
36092
36821
|
AvlState,
|
|
36093
36822
|
{
|
|
@@ -36291,7 +37020,7 @@ var init_PageHeader = __esm({
|
|
|
36291
37020
|
info: "bg-info/10 text-info"
|
|
36292
37021
|
};
|
|
36293
37022
|
return /* @__PURE__ */ jsxs(Box, { className: cn("mb-6", className), children: [
|
|
36294
|
-
breadcrumbs && breadcrumbs.length > 0 && /* @__PURE__ */ jsx(Box, { as: "nav", className: "mb-4", children: /* @__PURE__ */ jsx(Box, { as: "ol", className: "flex items-center gap-2 text-sm", children: breadcrumbs.map((crumb, idx) => /* @__PURE__ */ jsxs(
|
|
37023
|
+
breadcrumbs && breadcrumbs.length > 0 && /* @__PURE__ */ jsx(Box, { as: "nav", className: "mb-4", children: /* @__PURE__ */ jsx(Box, { as: "ol", className: "flex items-center gap-2 text-sm", children: breadcrumbs.map((crumb, idx) => /* @__PURE__ */ jsxs(React85__default.Fragment, { children: [
|
|
36295
37024
|
idx > 0 && /* @__PURE__ */ jsx(Typography, { variant: "small", color: "muted", children: "/" }),
|
|
36296
37025
|
crumb.href ? /* @__PURE__ */ jsx(
|
|
36297
37026
|
"a",
|
|
@@ -36973,8 +37702,8 @@ var init_WizardContainer = __esm({
|
|
|
36973
37702
|
return void 0;
|
|
36974
37703
|
if (typeof controlledStep === "number") return controlledStep;
|
|
36975
37704
|
if (typeof controlledStep === "string") return parseInt(controlledStep, 10);
|
|
36976
|
-
const
|
|
36977
|
-
return isNaN(
|
|
37705
|
+
const num3 = Number(controlledStep);
|
|
37706
|
+
return isNaN(num3) ? void 0 : num3;
|
|
36978
37707
|
})();
|
|
36979
37708
|
const currentStep = normalizedControlledStep !== void 0 ? normalizedControlledStep : internalStep;
|
|
36980
37709
|
const totalSteps = steps.length;
|
|
@@ -37020,7 +37749,7 @@ var init_WizardContainer = __esm({
|
|
|
37020
37749
|
const isCompleted = index < currentStep;
|
|
37021
37750
|
const stepKey = step.id ?? step.tabId ?? `step-${index}`;
|
|
37022
37751
|
const stepTitle = step.title ?? step.name ?? `Step ${index + 1}`;
|
|
37023
|
-
return /* @__PURE__ */ jsxs(
|
|
37752
|
+
return /* @__PURE__ */ jsxs(React85__default.Fragment, { children: [
|
|
37024
37753
|
/* @__PURE__ */ jsx(
|
|
37025
37754
|
Button,
|
|
37026
37755
|
{
|
|
@@ -37952,6 +38681,8 @@ var init_GraphCanvas = __esm({
|
|
|
37952
38681
|
selectedNodeId,
|
|
37953
38682
|
repulsion = 800,
|
|
37954
38683
|
linkDistance = 100,
|
|
38684
|
+
nodeSpacing = 28,
|
|
38685
|
+
linkOpacity = 0.18,
|
|
37955
38686
|
layout = "force",
|
|
37956
38687
|
entity,
|
|
37957
38688
|
isLoading = false,
|
|
@@ -38111,6 +38842,25 @@ var init_GraphCanvas = __esm({
|
|
|
38111
38842
|
node.x = Math.max(30, Math.min(w - 30, node.x));
|
|
38112
38843
|
node.y = Math.max(30, Math.min(h - 30, node.y));
|
|
38113
38844
|
}
|
|
38845
|
+
for (let i = 0; i < nodes.length; i++) {
|
|
38846
|
+
for (let j = i + 1; j < nodes.length; j++) {
|
|
38847
|
+
const a = nodes[i];
|
|
38848
|
+
const b = nodes[j];
|
|
38849
|
+
const dx = b.x - a.x;
|
|
38850
|
+
const dy = b.y - a.y;
|
|
38851
|
+
const dist = Math.sqrt(dx * dx + dy * dy) || 1;
|
|
38852
|
+
const minDist = (a.size || 8) + (b.size || 8) + nodeSpacing;
|
|
38853
|
+
if (dist < minDist) {
|
|
38854
|
+
const push = (minDist - dist) / 2;
|
|
38855
|
+
const ux = dx / dist;
|
|
38856
|
+
const uy = dy / dist;
|
|
38857
|
+
a.x = Math.max(30, Math.min(w - 30, a.x - ux * push));
|
|
38858
|
+
a.y = Math.max(30, Math.min(h - 30, a.y - uy * push));
|
|
38859
|
+
b.x = Math.max(30, Math.min(w - 30, b.x + ux * push));
|
|
38860
|
+
b.y = Math.max(30, Math.min(h - 30, b.y + uy * push));
|
|
38861
|
+
}
|
|
38862
|
+
}
|
|
38863
|
+
}
|
|
38114
38864
|
iterations++;
|
|
38115
38865
|
forceUpdate((n) => n + 1);
|
|
38116
38866
|
if (iterations < maxIterations) {
|
|
@@ -38124,7 +38874,7 @@ var init_GraphCanvas = __esm({
|
|
|
38124
38874
|
return () => {
|
|
38125
38875
|
cancelAnimationFrame(animRef.current);
|
|
38126
38876
|
};
|
|
38127
|
-
}, [propNodes, propEdges, layout, repulsion, linkDistance, logicalW, height]);
|
|
38877
|
+
}, [propNodes, propEdges, layout, repulsion, linkDistance, nodeSpacing, logicalW, height]);
|
|
38128
38878
|
useEffect(() => {
|
|
38129
38879
|
const canvas = canvasRef.current;
|
|
38130
38880
|
if (!canvas) return;
|
|
@@ -38153,11 +38903,11 @@ var init_GraphCanvas = __esm({
|
|
|
38153
38903
|
const target = nodes.find((n) => n.id === edge.target);
|
|
38154
38904
|
if (!source || !target) continue;
|
|
38155
38905
|
const incident = !!hoveredNode && (edge.source === hoveredNode || edge.target === hoveredNode);
|
|
38156
|
-
ctx.globalAlpha = hoveredNode ? incident ? 1 : 0.
|
|
38906
|
+
ctx.globalAlpha = hoveredNode ? incident ? 1 : 0.05 : linkOpacity;
|
|
38157
38907
|
ctx.beginPath();
|
|
38158
38908
|
ctx.moveTo(source.x, source.y);
|
|
38159
38909
|
ctx.lineTo(target.x, target.y);
|
|
38160
|
-
ctx.strokeStyle = incident ? accentColor : edge.color || "#
|
|
38910
|
+
ctx.strokeStyle = incident ? accentColor : edge.color || "#888888";
|
|
38161
38911
|
ctx.lineWidth = incident ? 2 : edge.weight ? Math.max(1, edge.weight) : 1;
|
|
38162
38912
|
ctx.stroke();
|
|
38163
38913
|
if (edge.label && showLabels) {
|
|
@@ -39521,7 +40271,7 @@ var init_DetailPanel = __esm({
|
|
|
39521
40271
|
}
|
|
39522
40272
|
});
|
|
39523
40273
|
function extractTitle(children) {
|
|
39524
|
-
if (!
|
|
40274
|
+
if (!React85__default.isValidElement(children)) return void 0;
|
|
39525
40275
|
const props = children.props;
|
|
39526
40276
|
if (typeof props.title === "string") {
|
|
39527
40277
|
return props.title;
|
|
@@ -39576,7 +40326,7 @@ function LinearView({
|
|
|
39576
40326
|
/* @__PURE__ */ jsx(HStack, { className: "flex-wrap items-center", gap: "xs", children: trait.states.map((state, i) => {
|
|
39577
40327
|
const isDone = i < currentIdx;
|
|
39578
40328
|
const isCurrent = i === currentIdx;
|
|
39579
|
-
return /* @__PURE__ */ jsxs(
|
|
40329
|
+
return /* @__PURE__ */ jsxs(React85__default.Fragment, { children: [
|
|
39580
40330
|
i > 0 && /* @__PURE__ */ jsx(
|
|
39581
40331
|
Typography,
|
|
39582
40332
|
{
|
|
@@ -40526,12 +41276,12 @@ var init_Form = __esm({
|
|
|
40526
41276
|
const isSchemaEntity = isOrbitalEntitySchema(entity);
|
|
40527
41277
|
const resolvedEntity = isSchemaEntity ? entity : void 0;
|
|
40528
41278
|
const entityName = typeof entity === "string" ? entity : resolvedEntity?.name;
|
|
40529
|
-
const normalizedInitialData =
|
|
41279
|
+
const normalizedInitialData = React85__default.useMemo(() => {
|
|
40530
41280
|
const entityRowAsInitial = isPlainEntityRow(entity) ? entity : void 0;
|
|
40531
41281
|
const callerInitial = initialData !== null && typeof initialData === "object" && !Array.isArray(initialData) ? initialData : {};
|
|
40532
41282
|
return entityRowAsInitial !== void 0 ? { ...entityRowAsInitial, ...callerInitial } : callerInitial;
|
|
40533
41283
|
}, [entity, initialData]);
|
|
40534
|
-
const entityDerivedFields =
|
|
41284
|
+
const entityDerivedFields = React85__default.useMemo(() => {
|
|
40535
41285
|
if (fields && fields.length > 0) return void 0;
|
|
40536
41286
|
if (!resolvedEntity) return void 0;
|
|
40537
41287
|
return resolvedEntity.fields.map(
|
|
@@ -40551,16 +41301,16 @@ var init_Form = __esm({
|
|
|
40551
41301
|
const conditionalFields = typeof conditionalFieldsRaw === "boolean" ? {} : conditionalFieldsRaw;
|
|
40552
41302
|
const hiddenCalculations = typeof hiddenCalculationsRaw === "boolean" ? [] : hiddenCalculationsRaw;
|
|
40553
41303
|
const violationTriggers = typeof violationTriggersRaw === "boolean" ? [] : violationTriggersRaw;
|
|
40554
|
-
const [formData, setFormData] =
|
|
41304
|
+
const [formData, setFormData] = React85__default.useState(
|
|
40555
41305
|
normalizedInitialData
|
|
40556
41306
|
);
|
|
40557
|
-
const [collapsedSections, setCollapsedSections] =
|
|
41307
|
+
const [collapsedSections, setCollapsedSections] = React85__default.useState(
|
|
40558
41308
|
/* @__PURE__ */ new Set()
|
|
40559
41309
|
);
|
|
40560
|
-
const [submitError, setSubmitError] =
|
|
40561
|
-
const formRef =
|
|
41310
|
+
const [submitError, setSubmitError] = React85__default.useState(null);
|
|
41311
|
+
const formRef = React85__default.useRef(null);
|
|
40562
41312
|
const formMode = props.mode;
|
|
40563
|
-
const mountedRef =
|
|
41313
|
+
const mountedRef = React85__default.useRef(false);
|
|
40564
41314
|
if (!mountedRef.current) {
|
|
40565
41315
|
mountedRef.current = true;
|
|
40566
41316
|
debug("forms", "mount", {
|
|
@@ -40573,7 +41323,7 @@ var init_Form = __esm({
|
|
|
40573
41323
|
});
|
|
40574
41324
|
}
|
|
40575
41325
|
const shouldShowCancel = showCancel ?? (fields && fields.length > 0);
|
|
40576
|
-
const evalContext =
|
|
41326
|
+
const evalContext = React85__default.useMemo(
|
|
40577
41327
|
() => ({
|
|
40578
41328
|
formValues: formData,
|
|
40579
41329
|
globalVariables: externalContext?.globalVariables ?? {},
|
|
@@ -40582,7 +41332,7 @@ var init_Form = __esm({
|
|
|
40582
41332
|
}),
|
|
40583
41333
|
[formData, externalContext]
|
|
40584
41334
|
);
|
|
40585
|
-
|
|
41335
|
+
React85__default.useEffect(() => {
|
|
40586
41336
|
debug("forms", "initialData-sync", {
|
|
40587
41337
|
mode: formMode,
|
|
40588
41338
|
normalizedInitialData,
|
|
@@ -40593,7 +41343,7 @@ var init_Form = __esm({
|
|
|
40593
41343
|
setFormData(normalizedInitialData);
|
|
40594
41344
|
}
|
|
40595
41345
|
}, [normalizedInitialData]);
|
|
40596
|
-
const processCalculations =
|
|
41346
|
+
const processCalculations = React85__default.useCallback(
|
|
40597
41347
|
(changedFieldId, newFormData) => {
|
|
40598
41348
|
if (!hiddenCalculations.length) return;
|
|
40599
41349
|
const context = {
|
|
@@ -40618,7 +41368,7 @@ var init_Form = __esm({
|
|
|
40618
41368
|
},
|
|
40619
41369
|
[hiddenCalculations, externalContext, eventBus]
|
|
40620
41370
|
);
|
|
40621
|
-
const checkViolations =
|
|
41371
|
+
const checkViolations = React85__default.useCallback(
|
|
40622
41372
|
(changedFieldId, newFormData) => {
|
|
40623
41373
|
if (!violationTriggers.length) return;
|
|
40624
41374
|
const context = {
|
|
@@ -40656,7 +41406,7 @@ var init_Form = __esm({
|
|
|
40656
41406
|
processCalculations(name, newFormData);
|
|
40657
41407
|
checkViolations(name, newFormData);
|
|
40658
41408
|
};
|
|
40659
|
-
const isFieldVisible =
|
|
41409
|
+
const isFieldVisible = React85__default.useCallback(
|
|
40660
41410
|
(fieldName) => {
|
|
40661
41411
|
const condition = conditionalFields[fieldName];
|
|
40662
41412
|
if (!condition) return true;
|
|
@@ -40664,7 +41414,7 @@ var init_Form = __esm({
|
|
|
40664
41414
|
},
|
|
40665
41415
|
[conditionalFields, evalContext]
|
|
40666
41416
|
);
|
|
40667
|
-
const isSectionVisible =
|
|
41417
|
+
const isSectionVisible = React85__default.useCallback(
|
|
40668
41418
|
(section) => {
|
|
40669
41419
|
if (!section.condition) return true;
|
|
40670
41420
|
return Boolean(evaluateFormExpression(section.condition, evalContext));
|
|
@@ -40740,7 +41490,7 @@ var init_Form = __esm({
|
|
|
40740
41490
|
eventBus.emit(`UI:${onCancel}`);
|
|
40741
41491
|
}
|
|
40742
41492
|
};
|
|
40743
|
-
const renderField =
|
|
41493
|
+
const renderField = React85__default.useCallback(
|
|
40744
41494
|
(field) => {
|
|
40745
41495
|
const fieldName = field.name || field.field;
|
|
40746
41496
|
if (!fieldName) return null;
|
|
@@ -40761,7 +41511,7 @@ var init_Form = __esm({
|
|
|
40761
41511
|
[formData, isFieldVisible, relationsData, relationsLoading, isLoading]
|
|
40762
41512
|
);
|
|
40763
41513
|
const effectiveFields = entityDerivedFields ?? fields;
|
|
40764
|
-
const normalizedFields =
|
|
41514
|
+
const normalizedFields = React85__default.useMemo(() => {
|
|
40765
41515
|
if (!effectiveFields || effectiveFields.length === 0) return [];
|
|
40766
41516
|
return effectiveFields.map((field) => {
|
|
40767
41517
|
if (typeof field === "string") {
|
|
@@ -40784,7 +41534,7 @@ var init_Form = __esm({
|
|
|
40784
41534
|
return field;
|
|
40785
41535
|
});
|
|
40786
41536
|
}, [effectiveFields, resolvedEntity]);
|
|
40787
|
-
const schemaFields =
|
|
41537
|
+
const schemaFields = React85__default.useMemo(() => {
|
|
40788
41538
|
if (normalizedFields.length === 0) return null;
|
|
40789
41539
|
if (isDebugEnabled()) {
|
|
40790
41540
|
debugGroup(`Form: ${entityName || "unknown"}`);
|
|
@@ -40794,7 +41544,7 @@ var init_Form = __esm({
|
|
|
40794
41544
|
}
|
|
40795
41545
|
return normalizedFields.map(renderField).filter(Boolean);
|
|
40796
41546
|
}, [normalizedFields, renderField, entityName, conditionalFields]);
|
|
40797
|
-
const sectionElements =
|
|
41547
|
+
const sectionElements = React85__default.useMemo(() => {
|
|
40798
41548
|
if (!sections || sections.length === 0) return null;
|
|
40799
41549
|
return sections.map((section) => {
|
|
40800
41550
|
if (!isSectionVisible(section)) {
|
|
@@ -42114,12 +42864,18 @@ function ModelLoader({
|
|
|
42114
42864
|
});
|
|
42115
42865
|
return cloned;
|
|
42116
42866
|
}, [loadedModel, castShadow, receiveShadow]);
|
|
42867
|
+
const normFactor = useMemo(() => {
|
|
42868
|
+
if (!model) return 1;
|
|
42869
|
+
const box = new THREE3.Box3().setFromObject(model);
|
|
42870
|
+
const size = new THREE3.Vector3();
|
|
42871
|
+
box.getSize(size);
|
|
42872
|
+
const maxDim = Math.max(size.x, size.y, size.z);
|
|
42873
|
+
return maxDim > 0 && Number.isFinite(maxDim) ? 1 / maxDim : 1;
|
|
42874
|
+
}, [model]);
|
|
42117
42875
|
const scaleArray = useMemo(() => {
|
|
42118
|
-
|
|
42119
|
-
|
|
42120
|
-
|
|
42121
|
-
return scale;
|
|
42122
|
-
}, [scale]);
|
|
42876
|
+
const base = typeof scale === "number" ? [scale, scale, scale] : scale;
|
|
42877
|
+
return [base[0] * normFactor, base[1] * normFactor, base[2] * normFactor];
|
|
42878
|
+
}, [scale, normFactor]);
|
|
42123
42879
|
const rotationRad = useMemo(() => {
|
|
42124
42880
|
return [
|
|
42125
42881
|
rotation[0] * Math.PI / 180,
|
|
@@ -42330,6 +43086,29 @@ var init_GameCanvas3D2 = __esm({
|
|
|
42330
43086
|
const controlsRef = useRef(null);
|
|
42331
43087
|
const [hoveredTile, setHoveredTile] = useState(null);
|
|
42332
43088
|
const [internalError, setInternalError] = useState(null);
|
|
43089
|
+
useEffect(() => {
|
|
43090
|
+
const el = containerRef.current;
|
|
43091
|
+
if (!el) return;
|
|
43092
|
+
let node = el;
|
|
43093
|
+
let depth = 0;
|
|
43094
|
+
while (node && depth < 8) {
|
|
43095
|
+
const cs = window.getComputedStyle(node);
|
|
43096
|
+
const rect = node.getBoundingClientRect();
|
|
43097
|
+
console.log("[almadar:ui:game:3d-height]", {
|
|
43098
|
+
depth,
|
|
43099
|
+
tag: node.tagName,
|
|
43100
|
+
id: node.id || void 0,
|
|
43101
|
+
className: node.className?.slice?.(0, 60) || void 0,
|
|
43102
|
+
rectHeight: rect.height,
|
|
43103
|
+
computedHeight: cs.height,
|
|
43104
|
+
computedMinHeight: cs.minHeight,
|
|
43105
|
+
computedFlex: cs.flex,
|
|
43106
|
+
computedOverflow: cs.overflow
|
|
43107
|
+
});
|
|
43108
|
+
node = node.parentElement;
|
|
43109
|
+
depth++;
|
|
43110
|
+
}
|
|
43111
|
+
}, []);
|
|
42333
43112
|
const { sheetUrls: atlasSheetUrls, resolveUnitFrame } = useUnitSpriteAtlas(units);
|
|
42334
43113
|
const preloadUrls = useMemo(() => [...preloadAssets, ...atlasSheetUrls], [preloadAssets, atlasSheetUrls]);
|
|
42335
43114
|
const { isLoading: assetsLoading, progress, loaded, total } = useAssetLoader({
|
|
@@ -42719,7 +43498,7 @@ var init_GameCanvas3D2 = __esm({
|
|
|
42719
43498
|
{
|
|
42720
43499
|
ref: containerRef,
|
|
42721
43500
|
className: cn("game-canvas-3d relative w-full overflow-hidden", className),
|
|
42722
|
-
style: {
|
|
43501
|
+
style: { height: "85vh" },
|
|
42723
43502
|
"data-orientation": orientation,
|
|
42724
43503
|
"data-camera-mode": cameraMode,
|
|
42725
43504
|
"data-overlay": overlay,
|
|
@@ -42734,7 +43513,7 @@ var init_GameCanvas3D2 = __esm({
|
|
|
42734
43513
|
near: 0.1,
|
|
42735
43514
|
far: 1e3
|
|
42736
43515
|
},
|
|
42737
|
-
style: { background: backgroundColor,
|
|
43516
|
+
style: { background: backgroundColor, position: "absolute", inset: 0 },
|
|
42738
43517
|
onClick: (e) => {
|
|
42739
43518
|
if (e.target === e.currentTarget) {
|
|
42740
43519
|
eventHandlers.handleCanvasClick(e);
|
|
@@ -43705,7 +44484,7 @@ var init_List = __esm({
|
|
|
43705
44484
|
if (entity && typeof entity === "object" && "id" in entity) return [entity];
|
|
43706
44485
|
return [];
|
|
43707
44486
|
}, [entity]);
|
|
43708
|
-
const getItemActions =
|
|
44487
|
+
const getItemActions = React85__default.useCallback(
|
|
43709
44488
|
(item) => {
|
|
43710
44489
|
if (!itemActions) return [];
|
|
43711
44490
|
if (typeof itemActions === "function") {
|
|
@@ -44181,7 +44960,7 @@ var init_MediaGallery = __esm({
|
|
|
44181
44960
|
[selectable, selectedItems, selectionEvent, eventBus]
|
|
44182
44961
|
);
|
|
44183
44962
|
const entityData = Array.isArray(entity) ? entity : [];
|
|
44184
|
-
const items =
|
|
44963
|
+
const items = React85__default.useMemo(() => {
|
|
44185
44964
|
if (propItems) return propItems;
|
|
44186
44965
|
if (entityData.length === 0) return [];
|
|
44187
44966
|
return entityData.map((record, idx) => ({
|
|
@@ -44342,7 +45121,7 @@ var init_MediaGallery = __esm({
|
|
|
44342
45121
|
}
|
|
44343
45122
|
});
|
|
44344
45123
|
function extractTitle2(children) {
|
|
44345
|
-
if (!
|
|
45124
|
+
if (!React85__default.isValidElement(children)) return void 0;
|
|
44346
45125
|
const props = children.props;
|
|
44347
45126
|
if (typeof props.title === "string") {
|
|
44348
45127
|
return props.title;
|
|
@@ -44918,31 +45697,33 @@ var init_PricingPageTemplate = __esm({
|
|
|
44918
45697
|
PricingPageTemplate.displayName = "PricingPageTemplate";
|
|
44919
45698
|
}
|
|
44920
45699
|
});
|
|
44921
|
-
function
|
|
45700
|
+
function resolveManifestUrl3(manifest, relative) {
|
|
45701
|
+
if (relative == null) return void 0;
|
|
45702
|
+
if (/^https?:\/\//.test(relative)) return relative;
|
|
45703
|
+
const base = manifest?.baseUrl;
|
|
45704
|
+
if (base == null) return relative;
|
|
45705
|
+
const cleanBase = base.replace(/\/$/, "");
|
|
45706
|
+
const cleanRel = relative.replace(/^\//, "");
|
|
45707
|
+
return `${cleanBase}/${cleanRel}`;
|
|
45708
|
+
}
|
|
45709
|
+
function dungeonTerrain(x, y, stairsX, stairsY, manifest) {
|
|
44922
45710
|
const isBorder = x === 0 || y === 0 || x === DUNGEON_GRID_W - 1 || y === DUNGEON_GRID_H - 1;
|
|
44923
45711
|
const isPillar = x % 4 === 0 && y % 4 === 0 && !isBorder;
|
|
44924
45712
|
const isWall = isBorder || isPillar;
|
|
45713
|
+
const terrains = manifest?.terrains;
|
|
44925
45714
|
if (x === stairsX && y === stairsY) {
|
|
44926
|
-
return { terrain: "stairs", passable: true, terrainSprite:
|
|
45715
|
+
return { terrain: "stairs", passable: true, terrainSprite: resolveManifestUrl3(manifest, terrains?.stairs) };
|
|
44927
45716
|
}
|
|
44928
45717
|
if (isWall) {
|
|
44929
|
-
return { terrain: "wall", passable: false, terrainSprite:
|
|
44930
|
-
}
|
|
44931
|
-
|
|
44932
|
-
const sprites = [
|
|
44933
|
-
`${CDN4}/isometric-dungeon/Isometric/dirt_E.png`,
|
|
44934
|
-
`${CDN4}/isometric-dungeon/Isometric/dirtTiles_E.png`,
|
|
44935
|
-
`${CDN4}/isometric-dungeon/Isometric/planks_E.png`,
|
|
44936
|
-
`${CDN4}/isometric-dungeon/Isometric/stoneTile_E.png`,
|
|
44937
|
-
`${CDN4}/isometric-dungeon/Isometric/dirt_E.png`
|
|
44938
|
-
];
|
|
44939
|
-
return { terrain: "floor", passable: true, terrainSprite: sprites[variant] };
|
|
45718
|
+
return { terrain: "wall", passable: false, terrainSprite: resolveManifestUrl3(manifest, terrains?.wall) };
|
|
45719
|
+
}
|
|
45720
|
+
return { terrain: "floor", passable: true, terrainSprite: resolveManifestUrl3(manifest, terrains?.floor) };
|
|
44940
45721
|
}
|
|
44941
|
-
function buildDefaultDungeonTiles(stairsX, stairsY) {
|
|
45722
|
+
function buildDefaultDungeonTiles(stairsX, stairsY, manifest) {
|
|
44942
45723
|
const tiles = [];
|
|
44943
45724
|
for (let y = 0; y < DUNGEON_GRID_H; y++) {
|
|
44944
45725
|
for (let x = 0; x < DUNGEON_GRID_W; x++) {
|
|
44945
|
-
tiles.push({ x, y, ...dungeonTerrain(x, y, stairsX, stairsY) });
|
|
45726
|
+
tiles.push({ x, y, ...dungeonTerrain(x, y, stairsX, stairsY, manifest) });
|
|
44946
45727
|
}
|
|
44947
45728
|
}
|
|
44948
45729
|
return tiles;
|
|
@@ -44972,20 +45753,48 @@ function RoguelikeBoard({
|
|
|
44972
45753
|
className
|
|
44973
45754
|
}) {
|
|
44974
45755
|
const board = boardEntity(entity) ?? {};
|
|
44975
|
-
const
|
|
44976
|
-
const
|
|
44977
|
-
const
|
|
44978
|
-
const
|
|
44979
|
-
|
|
44980
|
-
|
|
45756
|
+
const assetManifest = propAssetManifest ?? board.assetManifest;
|
|
45757
|
+
const stairsX = propStairsX ?? num(board.stairsX, 14);
|
|
45758
|
+
const stairsY = propStairsY ?? num(board.stairsY, 14);
|
|
45759
|
+
const entityTiles = useMemo(
|
|
45760
|
+
() => rows(board.tiles).map((r) => ({
|
|
45761
|
+
x: num(r.x),
|
|
45762
|
+
y: num(r.y),
|
|
45763
|
+
terrain: r.terrain == null ? void 0 : str(r.terrain),
|
|
45764
|
+
terrainSprite: r.terrainSprite == null ? void 0 : str(r.terrainSprite),
|
|
45765
|
+
passable: r.passable !== false
|
|
45766
|
+
})),
|
|
45767
|
+
[board.tiles]
|
|
45768
|
+
);
|
|
45769
|
+
const tiles = propTiles ?? (entityTiles.length >= DUNGEON_GRID_W * DUNGEON_GRID_H ? entityTiles : buildDefaultDungeonTiles(stairsX, stairsY, assetManifest));
|
|
45770
|
+
const entityEnemies = useMemo(
|
|
45771
|
+
() => rows(board.enemies).map((r) => ({
|
|
45772
|
+
id: str(r.id),
|
|
45773
|
+
x: num(r.x),
|
|
45774
|
+
y: num(r.y),
|
|
45775
|
+
hp: num(r.hp),
|
|
45776
|
+
attack: num(r.attack)
|
|
45777
|
+
})),
|
|
45778
|
+
[board.enemies]
|
|
45779
|
+
);
|
|
45780
|
+
const enemies = propEnemies ?? (entityEnemies.length > 0 ? entityEnemies : DEFAULT_ENEMIES);
|
|
45781
|
+
const entityItems = useMemo(
|
|
45782
|
+
() => rows(board.items).map((r) => ({
|
|
45783
|
+
id: str(r.id),
|
|
45784
|
+
x: num(r.x),
|
|
45785
|
+
y: num(r.y),
|
|
45786
|
+
kind: str(r.kind) || "health_potion"
|
|
45787
|
+
})),
|
|
45788
|
+
[board.items]
|
|
45789
|
+
);
|
|
45790
|
+
const items = propItems ?? (entityItems.length > 0 ? entityItems : DEFAULT_ITEMS);
|
|
45791
|
+
const player = propPlayer ?? (board.player == null ? { x: 1, y: 1 } : vec2(board.player));
|
|
44981
45792
|
const playerHp = propPlayerHp ?? num(board.playerHp, 10);
|
|
44982
45793
|
const playerMaxHp = propPlayerMaxHp ?? num(board.playerMaxHp, 10);
|
|
44983
45794
|
const playerAttack = propPlayerAttack ?? num(board.playerAttack, 3);
|
|
44984
45795
|
const depth = propDepth ?? num(board.depth, 1);
|
|
44985
45796
|
const result = propResult ?? (str(board.result) || "none");
|
|
44986
45797
|
const phase = propPhase ?? (str(board.phase) || "player_turn");
|
|
44987
|
-
propStairsX ?? num(board.stairsX, 14);
|
|
44988
|
-
propStairsY ?? num(board.stairsY, 14);
|
|
44989
45798
|
const eventBus = useEventBus();
|
|
44990
45799
|
const { t } = useTranslate();
|
|
44991
45800
|
const [hoveredTile, setHoveredTile] = useState(null);
|
|
@@ -45032,7 +45841,7 @@ function RoguelikeBoard({
|
|
|
45032
45841
|
health: playerHp,
|
|
45033
45842
|
maxHealth: playerMaxHp,
|
|
45034
45843
|
unitType: "player",
|
|
45035
|
-
sprite:
|
|
45844
|
+
sprite: resolveManifestUrl3(assetManifest, assetManifest?.units?.player)
|
|
45036
45845
|
},
|
|
45037
45846
|
...liveEnemies.map((e) => ({
|
|
45038
45847
|
id: e.id,
|
|
@@ -45042,19 +45851,19 @@ function RoguelikeBoard({
|
|
|
45042
45851
|
health: e.hp,
|
|
45043
45852
|
maxHealth: 6,
|
|
45044
45853
|
unitType: "enemy",
|
|
45045
|
-
sprite:
|
|
45854
|
+
sprite: resolveManifestUrl3(assetManifest, assetManifest?.units?.enemy)
|
|
45046
45855
|
}))
|
|
45047
45856
|
];
|
|
45048
|
-
}, [player, enemies, playerHp, playerMaxHp, t]);
|
|
45857
|
+
}, [player, enemies, playerHp, playerMaxHp, assetManifest, t]);
|
|
45049
45858
|
const isoFeatures = useMemo(
|
|
45050
45859
|
() => items.map((it) => ({
|
|
45051
45860
|
id: it.id,
|
|
45052
45861
|
x: it.x,
|
|
45053
45862
|
y: it.y,
|
|
45054
45863
|
type: it.kind,
|
|
45055
|
-
sprite:
|
|
45864
|
+
sprite: resolveManifestUrl3(assetManifest, assetManifest?.features?.[it.kind])
|
|
45056
45865
|
})),
|
|
45057
|
-
[items]
|
|
45866
|
+
[items, assetManifest]
|
|
45058
45867
|
);
|
|
45059
45868
|
const validMoves = useMemo(() => {
|
|
45060
45869
|
if (result !== "none" || phase !== "player_turn") return [];
|
|
@@ -45113,8 +45922,8 @@ function RoguelikeBoard({
|
|
|
45113
45922
|
onTileHover: (x, y) => setHoveredTile({ x, y }),
|
|
45114
45923
|
onTileLeave: () => setHoveredTile(null),
|
|
45115
45924
|
scale,
|
|
45116
|
-
assetBaseUrl:
|
|
45117
|
-
assetManifest
|
|
45925
|
+
assetBaseUrl: assetManifest?.baseUrl,
|
|
45926
|
+
assetManifest,
|
|
45118
45927
|
unitScale,
|
|
45119
45928
|
spriteHeightRatio,
|
|
45120
45929
|
spriteMaxWidthRatio
|
|
@@ -45161,7 +45970,7 @@ function RoguelikeBoard({
|
|
|
45161
45970
|
] }) })
|
|
45162
45971
|
] });
|
|
45163
45972
|
}
|
|
45164
|
-
var
|
|
45973
|
+
var DUNGEON_GRID_W, DUNGEON_GRID_H, DEFAULT_ENEMIES, DEFAULT_ITEMS;
|
|
45165
45974
|
var init_RoguelikeBoard = __esm({
|
|
45166
45975
|
"components/game/organisms/RoguelikeBoard.tsx"() {
|
|
45167
45976
|
"use client";
|
|
@@ -45173,10 +45982,8 @@ var init_RoguelikeBoard = __esm({
|
|
|
45173
45982
|
init_Stack();
|
|
45174
45983
|
init_IsometricCanvas();
|
|
45175
45984
|
init_boardEntity();
|
|
45176
|
-
CDN4 = "https://almadar-kflow-assets.web.app/shared";
|
|
45177
45985
|
DUNGEON_GRID_W = 16;
|
|
45178
45986
|
DUNGEON_GRID_H = 16;
|
|
45179
|
-
buildDefaultDungeonTiles(14, 14);
|
|
45180
45987
|
DEFAULT_ENEMIES = [
|
|
45181
45988
|
{ id: "e1", x: 5, y: 2, hp: 5, attack: 2 },
|
|
45182
45989
|
{ id: "e2", x: 9, y: 6, hp: 4, attack: 1 },
|
|
@@ -45188,11 +45995,6 @@ var init_RoguelikeBoard = __esm({
|
|
|
45188
45995
|
{ id: "i2", x: 7, y: 9, kind: "sword" },
|
|
45189
45996
|
{ id: "i3", x: 11, y: 5, kind: "shield" }
|
|
45190
45997
|
];
|
|
45191
|
-
FEATURE_SPRITE = {
|
|
45192
|
-
health_potion: `${CDN4}/isometric-dungeon/Isometric/chestClosed_E.png`,
|
|
45193
|
-
sword: `${CDN4}/isometric-dungeon/Isometric/barrel_E.png`,
|
|
45194
|
-
shield: `${CDN4}/isometric-dungeon/Isometric/barrel_E.png`
|
|
45195
|
-
};
|
|
45196
45998
|
RoguelikeBoard.displayName = "RoguelikeBoard";
|
|
45197
45999
|
}
|
|
45198
46000
|
});
|
|
@@ -45230,40 +46032,40 @@ function RoguelikeTemplate({
|
|
|
45230
46032
|
}
|
|
45231
46033
|
);
|
|
45232
46034
|
}
|
|
45233
|
-
var
|
|
46035
|
+
var CDN4, DEFAULT_ROGUELIKE_TILES, DEFAULT_ROGUELIKE_MANIFEST;
|
|
45234
46036
|
var init_RoguelikeTemplate = __esm({
|
|
45235
46037
|
"components/game/templates/RoguelikeTemplate.tsx"() {
|
|
45236
46038
|
init_RoguelikeBoard();
|
|
45237
|
-
|
|
46039
|
+
CDN4 = "https://almadar-kflow-assets.web.app/shared";
|
|
45238
46040
|
DEFAULT_ROGUELIKE_TILES = [
|
|
45239
|
-
{ x: 0, y: 0, terrain: "wall", passable: false, terrainSprite: `${
|
|
45240
|
-
{ x: 1, y: 0, terrain: "wall", passable: false, terrainSprite: `${
|
|
45241
|
-
{ x: 2, y: 0, terrain: "wall", passable: false, terrainSprite: `${
|
|
45242
|
-
{ x: 3, y: 0, terrain: "wall", passable: false, terrainSprite: `${
|
|
45243
|
-
{ x: 4, y: 0, terrain: "wall", passable: false, terrainSprite: `${
|
|
45244
|
-
{ x: 0, y: 1, terrain: "wall", passable: false, terrainSprite: `${
|
|
45245
|
-
{ x: 1, y: 1, terrain: "floor", passable: true, terrainSprite: `${
|
|
45246
|
-
{ x: 2, y: 1, terrain: "floor", passable: true, terrainSprite: `${
|
|
45247
|
-
{ x: 3, y: 1, terrain: "floor", passable: true, terrainSprite: `${
|
|
45248
|
-
{ x: 4, y: 1, terrain: "wall", passable: false, terrainSprite: `${
|
|
45249
|
-
{ x: 0, y: 2, terrain: "wall", passable: false, terrainSprite: `${
|
|
45250
|
-
{ x: 1, y: 2, terrain: "floor", passable: true, terrainSprite: `${
|
|
45251
|
-
{ x: 2, y: 2, terrain: "floor", passable: true, terrainSprite: `${
|
|
45252
|
-
{ x: 3, y: 2, terrain: "floor", passable: true, terrainSprite: `${
|
|
45253
|
-
{ x: 4, y: 2, terrain: "wall", passable: false, terrainSprite: `${
|
|
45254
|
-
{ x: 0, y: 3, terrain: "wall", passable: false, terrainSprite: `${
|
|
45255
|
-
{ x: 1, y: 3, terrain: "floor", passable: true, terrainSprite: `${
|
|
45256
|
-
{ x: 2, y: 3, terrain: "floor", passable: true, terrainSprite: `${
|
|
45257
|
-
{ x: 3, y: 3, terrain: "stairs", passable: true, terrainSprite: `${
|
|
45258
|
-
{ x: 4, y: 3, terrain: "wall", passable: false, terrainSprite: `${
|
|
45259
|
-
{ x: 0, y: 4, terrain: "wall", passable: false, terrainSprite: `${
|
|
45260
|
-
{ x: 1, y: 4, terrain: "wall", passable: false, terrainSprite: `${
|
|
45261
|
-
{ x: 2, y: 4, terrain: "wall", passable: false, terrainSprite: `${
|
|
45262
|
-
{ x: 3, y: 4, terrain: "wall", passable: false, terrainSprite: `${
|
|
45263
|
-
{ x: 4, y: 4, terrain: "wall", passable: false, terrainSprite: `${
|
|
46041
|
+
{ x: 0, y: 0, terrain: "wall", passable: false, terrainSprite: `${CDN4}/isometric-dungeon/Isometric/stoneInset_E.png` },
|
|
46042
|
+
{ x: 1, y: 0, terrain: "wall", passable: false, terrainSprite: `${CDN4}/isometric-dungeon/Isometric/stoneInset_E.png` },
|
|
46043
|
+
{ x: 2, y: 0, terrain: "wall", passable: false, terrainSprite: `${CDN4}/isometric-dungeon/Isometric/stoneInset_E.png` },
|
|
46044
|
+
{ x: 3, y: 0, terrain: "wall", passable: false, terrainSprite: `${CDN4}/isometric-dungeon/Isometric/stoneInset_E.png` },
|
|
46045
|
+
{ x: 4, y: 0, terrain: "wall", passable: false, terrainSprite: `${CDN4}/isometric-dungeon/Isometric/stoneInset_E.png` },
|
|
46046
|
+
{ x: 0, y: 1, terrain: "wall", passable: false, terrainSprite: `${CDN4}/isometric-dungeon/Isometric/stoneInset_E.png` },
|
|
46047
|
+
{ x: 1, y: 1, terrain: "floor", passable: true, terrainSprite: `${CDN4}/isometric-dungeon/Isometric/dirt_E.png` },
|
|
46048
|
+
{ x: 2, y: 1, terrain: "floor", passable: true, terrainSprite: `${CDN4}/isometric-dungeon/Isometric/dirt_E.png` },
|
|
46049
|
+
{ x: 3, y: 1, terrain: "floor", passable: true, terrainSprite: `${CDN4}/isometric-dungeon/Isometric/dirt_E.png` },
|
|
46050
|
+
{ x: 4, y: 1, terrain: "wall", passable: false, terrainSprite: `${CDN4}/isometric-dungeon/Isometric/stoneInset_E.png` },
|
|
46051
|
+
{ x: 0, y: 2, terrain: "wall", passable: false, terrainSprite: `${CDN4}/isometric-dungeon/Isometric/stoneInset_E.png` },
|
|
46052
|
+
{ x: 1, y: 2, terrain: "floor", passable: true, terrainSprite: `${CDN4}/isometric-dungeon/Isometric/dirtTiles_E.png` },
|
|
46053
|
+
{ x: 2, y: 2, terrain: "floor", passable: true, terrainSprite: `${CDN4}/isometric-dungeon/Isometric/dirtTiles_E.png` },
|
|
46054
|
+
{ x: 3, y: 2, terrain: "floor", passable: true, terrainSprite: `${CDN4}/isometric-dungeon/Isometric/dirt_E.png` },
|
|
46055
|
+
{ x: 4, y: 2, terrain: "wall", passable: false, terrainSprite: `${CDN4}/isometric-dungeon/Isometric/stoneInset_E.png` },
|
|
46056
|
+
{ x: 0, y: 3, terrain: "wall", passable: false, terrainSprite: `${CDN4}/isometric-dungeon/Isometric/stoneInset_E.png` },
|
|
46057
|
+
{ x: 1, y: 3, terrain: "floor", passable: true, terrainSprite: `${CDN4}/isometric-dungeon/Isometric/dirt_E.png` },
|
|
46058
|
+
{ x: 2, y: 3, terrain: "floor", passable: true, terrainSprite: `${CDN4}/isometric-dungeon/Isometric/dirtTiles_E.png` },
|
|
46059
|
+
{ x: 3, y: 3, terrain: "stairs", passable: true, terrainSprite: `${CDN4}/isometric-dungeon/Isometric/stairs_E.png` },
|
|
46060
|
+
{ x: 4, y: 3, terrain: "wall", passable: false, terrainSprite: `${CDN4}/isometric-dungeon/Isometric/stoneInset_E.png` },
|
|
46061
|
+
{ x: 0, y: 4, terrain: "wall", passable: false, terrainSprite: `${CDN4}/isometric-dungeon/Isometric/stoneInset_E.png` },
|
|
46062
|
+
{ x: 1, y: 4, terrain: "wall", passable: false, terrainSprite: `${CDN4}/isometric-dungeon/Isometric/stoneInset_E.png` },
|
|
46063
|
+
{ x: 2, y: 4, terrain: "wall", passable: false, terrainSprite: `${CDN4}/isometric-dungeon/Isometric/stoneInset_E.png` },
|
|
46064
|
+
{ x: 3, y: 4, terrain: "wall", passable: false, terrainSprite: `${CDN4}/isometric-dungeon/Isometric/stoneInset_E.png` },
|
|
46065
|
+
{ x: 4, y: 4, terrain: "wall", passable: false, terrainSprite: `${CDN4}/isometric-dungeon/Isometric/stoneInset_E.png` }
|
|
45264
46066
|
];
|
|
45265
46067
|
DEFAULT_ROGUELIKE_MANIFEST = {
|
|
45266
|
-
baseUrl:
|
|
46068
|
+
baseUrl: CDN4,
|
|
45267
46069
|
terrains: {
|
|
45268
46070
|
floor: "/isometric-dungeon/Isometric/dirt_E.png",
|
|
45269
46071
|
wall: "/isometric-dungeon/Isometric/stoneInset_E.png",
|
|
@@ -45370,7 +46172,7 @@ var init_debugRegistry = __esm({
|
|
|
45370
46172
|
}
|
|
45371
46173
|
});
|
|
45372
46174
|
function useDebugData() {
|
|
45373
|
-
const [data, setData] =
|
|
46175
|
+
const [data, setData] = React85.useState(() => ({
|
|
45374
46176
|
traits: [],
|
|
45375
46177
|
ticks: [],
|
|
45376
46178
|
guards: [],
|
|
@@ -45384,7 +46186,7 @@ function useDebugData() {
|
|
|
45384
46186
|
},
|
|
45385
46187
|
lastUpdate: Date.now()
|
|
45386
46188
|
}));
|
|
45387
|
-
|
|
46189
|
+
React85.useEffect(() => {
|
|
45388
46190
|
const updateData = () => {
|
|
45389
46191
|
setData({
|
|
45390
46192
|
traits: getAllTraits(),
|
|
@@ -45493,12 +46295,12 @@ function layoutGraph(states, transitions, initialState, width, height) {
|
|
|
45493
46295
|
return positions;
|
|
45494
46296
|
}
|
|
45495
46297
|
function WalkMinimap() {
|
|
45496
|
-
const [walkStep, setWalkStep] =
|
|
45497
|
-
const [traits2, setTraits] =
|
|
45498
|
-
const [coveredEdges, setCoveredEdges] =
|
|
45499
|
-
const [completedTraits, setCompletedTraits] =
|
|
45500
|
-
const prevTraitRef =
|
|
45501
|
-
|
|
46298
|
+
const [walkStep, setWalkStep] = React85.useState(null);
|
|
46299
|
+
const [traits2, setTraits] = React85.useState([]);
|
|
46300
|
+
const [coveredEdges, setCoveredEdges] = React85.useState([]);
|
|
46301
|
+
const [completedTraits, setCompletedTraits] = React85.useState(/* @__PURE__ */ new Set());
|
|
46302
|
+
const prevTraitRef = React85.useRef(null);
|
|
46303
|
+
React85.useEffect(() => {
|
|
45502
46304
|
const interval = setInterval(() => {
|
|
45503
46305
|
const w = window;
|
|
45504
46306
|
const step = w.__orbitalWalkStep;
|
|
@@ -45934,15 +46736,15 @@ var init_EntitiesTab = __esm({
|
|
|
45934
46736
|
});
|
|
45935
46737
|
function EventFlowTab({ events: events2 }) {
|
|
45936
46738
|
const { t } = useTranslate();
|
|
45937
|
-
const [filter, setFilter] =
|
|
45938
|
-
const containerRef =
|
|
45939
|
-
const [autoScroll, setAutoScroll] =
|
|
45940
|
-
|
|
46739
|
+
const [filter, setFilter] = React85.useState("all");
|
|
46740
|
+
const containerRef = React85.useRef(null);
|
|
46741
|
+
const [autoScroll, setAutoScroll] = React85.useState(true);
|
|
46742
|
+
React85.useEffect(() => {
|
|
45941
46743
|
if (autoScroll && containerRef.current) {
|
|
45942
46744
|
containerRef.current.scrollTop = containerRef.current.scrollHeight;
|
|
45943
46745
|
}
|
|
45944
46746
|
}, [events2.length, autoScroll]);
|
|
45945
|
-
const filteredEvents =
|
|
46747
|
+
const filteredEvents = React85.useMemo(() => {
|
|
45946
46748
|
if (filter === "all") return events2;
|
|
45947
46749
|
return events2.filter((e) => e.type === filter);
|
|
45948
46750
|
}, [events2, filter]);
|
|
@@ -46058,7 +46860,7 @@ var init_EventFlowTab = __esm({
|
|
|
46058
46860
|
});
|
|
46059
46861
|
function GuardsPanel({ guards }) {
|
|
46060
46862
|
const { t } = useTranslate();
|
|
46061
|
-
const [filter, setFilter] =
|
|
46863
|
+
const [filter, setFilter] = React85.useState("all");
|
|
46062
46864
|
if (guards.length === 0) {
|
|
46063
46865
|
return /* @__PURE__ */ jsx(
|
|
46064
46866
|
EmptyState,
|
|
@@ -46071,7 +46873,7 @@ function GuardsPanel({ guards }) {
|
|
|
46071
46873
|
}
|
|
46072
46874
|
const passedCount = guards.filter((g) => g.result).length;
|
|
46073
46875
|
const failedCount = guards.length - passedCount;
|
|
46074
|
-
const filteredGuards =
|
|
46876
|
+
const filteredGuards = React85.useMemo(() => {
|
|
46075
46877
|
if (filter === "all") return guards;
|
|
46076
46878
|
if (filter === "passed") return guards.filter((g) => g.result);
|
|
46077
46879
|
return guards.filter((g) => !g.result);
|
|
@@ -46234,10 +47036,10 @@ function EffectBadge({ effect }) {
|
|
|
46234
47036
|
}
|
|
46235
47037
|
function TransitionTimeline({ transitions }) {
|
|
46236
47038
|
const { t } = useTranslate();
|
|
46237
|
-
const containerRef =
|
|
46238
|
-
const [autoScroll, setAutoScroll] =
|
|
46239
|
-
const [expandedId, setExpandedId] =
|
|
46240
|
-
|
|
47039
|
+
const containerRef = React85.useRef(null);
|
|
47040
|
+
const [autoScroll, setAutoScroll] = React85.useState(true);
|
|
47041
|
+
const [expandedId, setExpandedId] = React85.useState(null);
|
|
47042
|
+
React85.useEffect(() => {
|
|
46241
47043
|
if (autoScroll && containerRef.current) {
|
|
46242
47044
|
containerRef.current.scrollTop = containerRef.current.scrollHeight;
|
|
46243
47045
|
}
|
|
@@ -46517,9 +47319,9 @@ function getAllEvents(traits2) {
|
|
|
46517
47319
|
function EventDispatcherTab({ traits: traits2, schema }) {
|
|
46518
47320
|
const eventBus = useEventBus();
|
|
46519
47321
|
const { t } = useTranslate();
|
|
46520
|
-
const [log13, setLog] =
|
|
46521
|
-
const prevStatesRef =
|
|
46522
|
-
|
|
47322
|
+
const [log13, setLog] = React85.useState([]);
|
|
47323
|
+
const prevStatesRef = React85.useRef(/* @__PURE__ */ new Map());
|
|
47324
|
+
React85.useEffect(() => {
|
|
46523
47325
|
for (const trait of traits2) {
|
|
46524
47326
|
const prev = prevStatesRef.current.get(trait.id);
|
|
46525
47327
|
if (prev && prev !== trait.currentState) {
|
|
@@ -46688,10 +47490,10 @@ function VerifyModePanel({
|
|
|
46688
47490
|
localCount
|
|
46689
47491
|
}) {
|
|
46690
47492
|
const { t } = useTranslate();
|
|
46691
|
-
const [expanded, setExpanded] =
|
|
46692
|
-
const scrollRef =
|
|
46693
|
-
const prevCountRef =
|
|
46694
|
-
|
|
47493
|
+
const [expanded, setExpanded] = React85.useState(true);
|
|
47494
|
+
const scrollRef = React85.useRef(null);
|
|
47495
|
+
const prevCountRef = React85.useRef(0);
|
|
47496
|
+
React85.useEffect(() => {
|
|
46695
47497
|
if (expanded && transitions.length > prevCountRef.current && scrollRef.current) {
|
|
46696
47498
|
scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
|
|
46697
47499
|
}
|
|
@@ -46748,10 +47550,10 @@ function RuntimeDebugger({
|
|
|
46748
47550
|
schema
|
|
46749
47551
|
}) {
|
|
46750
47552
|
const { t } = useTranslate();
|
|
46751
|
-
const [isCollapsed, setIsCollapsed] =
|
|
46752
|
-
const [isVisible, setIsVisible] =
|
|
47553
|
+
const [isCollapsed, setIsCollapsed] = React85.useState(mode === "verify" ? true : defaultCollapsed);
|
|
47554
|
+
const [isVisible, setIsVisible] = React85.useState(mode === "inline" || mode === "verify" || isDebugEnabled2());
|
|
46753
47555
|
const debugData = useDebugData();
|
|
46754
|
-
|
|
47556
|
+
React85.useEffect(() => {
|
|
46755
47557
|
if (mode === "inline") return;
|
|
46756
47558
|
return onDebugToggle((enabled) => {
|
|
46757
47559
|
setIsVisible(enabled);
|
|
@@ -46760,7 +47562,7 @@ function RuntimeDebugger({
|
|
|
46760
47562
|
}
|
|
46761
47563
|
});
|
|
46762
47564
|
}, [mode]);
|
|
46763
|
-
|
|
47565
|
+
React85.useEffect(() => {
|
|
46764
47566
|
if (mode === "inline") return;
|
|
46765
47567
|
const handleKeyDown = (e) => {
|
|
46766
47568
|
if (e.key === "`" && isVisible) {
|
|
@@ -47320,7 +48122,7 @@ function SequenceBar({
|
|
|
47320
48122
|
onSlotRemove(index);
|
|
47321
48123
|
}, [onSlotRemove, playing]);
|
|
47322
48124
|
const paddedSlots = Array.from({ length: maxSlots }, (_, i) => slots[i]);
|
|
47323
|
-
return /* @__PURE__ */ jsx(HStack, { className: cn("items-center", className), gap: "sm", children: paddedSlots.map((slot, i) => /* @__PURE__ */ jsxs(
|
|
48125
|
+
return /* @__PURE__ */ jsx(HStack, { className: cn("items-center", className), gap: "sm", children: paddedSlots.map((slot, i) => /* @__PURE__ */ jsxs(React85__default.Fragment, { children: [
|
|
47324
48126
|
i > 0 && /* @__PURE__ */ jsx(
|
|
47325
48127
|
Typography,
|
|
47326
48128
|
{
|
|
@@ -48209,7 +49011,7 @@ var init_StatCard = __esm({
|
|
|
48209
49011
|
const labelToUse = propLabel ?? propTitle;
|
|
48210
49012
|
const eventBus = useEventBus();
|
|
48211
49013
|
const { t } = useTranslate();
|
|
48212
|
-
const handleActionClick =
|
|
49014
|
+
const handleActionClick = React85__default.useCallback(() => {
|
|
48213
49015
|
if (action?.event) {
|
|
48214
49016
|
eventBus.emit(`UI:${action.event}`, {});
|
|
48215
49017
|
}
|
|
@@ -48220,7 +49022,7 @@ var init_StatCard = __esm({
|
|
|
48220
49022
|
const data = Array.isArray(entity) ? entity : entity ? [entity] : [];
|
|
48221
49023
|
const isLoading = externalLoading ?? false;
|
|
48222
49024
|
const error = externalError;
|
|
48223
|
-
const computeMetricValue =
|
|
49025
|
+
const computeMetricValue = React85__default.useCallback(
|
|
48224
49026
|
(metric, items) => {
|
|
48225
49027
|
if (metric.value !== void 0) {
|
|
48226
49028
|
return metric.value;
|
|
@@ -48259,7 +49061,7 @@ var init_StatCard = __esm({
|
|
|
48259
49061
|
},
|
|
48260
49062
|
[]
|
|
48261
49063
|
);
|
|
48262
|
-
const schemaStats =
|
|
49064
|
+
const schemaStats = React85__default.useMemo(() => {
|
|
48263
49065
|
if (!metrics || metrics.length === 0) return null;
|
|
48264
49066
|
return metrics.map((metric) => ({
|
|
48265
49067
|
label: metric.label,
|
|
@@ -48267,7 +49069,7 @@ var init_StatCard = __esm({
|
|
|
48267
49069
|
format: metric.format
|
|
48268
49070
|
}));
|
|
48269
49071
|
}, [metrics, data, computeMetricValue]);
|
|
48270
|
-
const calculatedTrend =
|
|
49072
|
+
const calculatedTrend = React85__default.useMemo(() => {
|
|
48271
49073
|
if (manualTrend !== void 0) return manualTrend;
|
|
48272
49074
|
if (previousValue === void 0 || currentValue === void 0)
|
|
48273
49075
|
return void 0;
|
|
@@ -49233,7 +50035,7 @@ var init_Timeline = __esm({
|
|
|
49233
50035
|
}) => {
|
|
49234
50036
|
const { t } = useTranslate();
|
|
49235
50037
|
const entityData = Array.isArray(entity) ? entity : [];
|
|
49236
|
-
const items =
|
|
50038
|
+
const items = React85__default.useMemo(() => {
|
|
49237
50039
|
if (propItems) return propItems;
|
|
49238
50040
|
if (entityData.length === 0) return [];
|
|
49239
50041
|
return entityData.map((record, idx) => {
|
|
@@ -49340,7 +50142,7 @@ var init_Timeline = __esm({
|
|
|
49340
50142
|
}
|
|
49341
50143
|
});
|
|
49342
50144
|
function extractToastProps(children) {
|
|
49343
|
-
if (!
|
|
50145
|
+
if (!React85__default.isValidElement(children)) {
|
|
49344
50146
|
if (typeof children === "string") {
|
|
49345
50147
|
return { message: children };
|
|
49346
50148
|
}
|
|
@@ -49378,7 +50180,7 @@ var init_ToastSlot = __esm({
|
|
|
49378
50180
|
eventBus.emit("UI:CLOSE");
|
|
49379
50181
|
};
|
|
49380
50182
|
if (!isVisible) return null;
|
|
49381
|
-
const isCustomContent =
|
|
50183
|
+
const isCustomContent = React85__default.isValidElement(children) && !message;
|
|
49382
50184
|
return /* @__PURE__ */ jsx(Box, { className: "fixed bottom-4 right-4 z-50", children: isCustomContent ? children : /* @__PURE__ */ jsx(
|
|
49383
50185
|
Toast,
|
|
49384
50186
|
{
|
|
@@ -49394,82 +50196,442 @@ var init_ToastSlot = __esm({
|
|
|
49394
50196
|
ToastSlot.displayName = "ToastSlot";
|
|
49395
50197
|
}
|
|
49396
50198
|
});
|
|
50199
|
+
function resolveManifestUrl4(manifest, relative) {
|
|
50200
|
+
if (relative == null || relative === "") return void 0;
|
|
50201
|
+
if (/^https?:\/\//.test(relative)) return relative;
|
|
50202
|
+
const base = manifest?.baseUrl;
|
|
50203
|
+
if (base == null) return relative;
|
|
50204
|
+
const cleanBase = base.replace(/\/$/, "");
|
|
50205
|
+
const cleanRel = relative.replace(/^\//, "");
|
|
50206
|
+
return `${cleanBase}/${cleanRel}`;
|
|
50207
|
+
}
|
|
50208
|
+
function readPlayer(v) {
|
|
50209
|
+
if (v == null || typeof v !== "object") return void 0;
|
|
50210
|
+
const o = v;
|
|
50211
|
+
return { x: num(o.x), y: num(o.y) };
|
|
50212
|
+
}
|
|
50213
|
+
function TopDownShooterBoard({
|
|
50214
|
+
entity,
|
|
50215
|
+
player: propPlayer,
|
|
50216
|
+
enemies: propEnemies,
|
|
50217
|
+
projectiles: propProjectiles,
|
|
50218
|
+
score: propScore,
|
|
50219
|
+
wave: propWave,
|
|
50220
|
+
lives: propLives,
|
|
50221
|
+
result: propResult,
|
|
50222
|
+
assetManifest: propAssetManifest,
|
|
50223
|
+
width = DEFAULT_WIDTH,
|
|
50224
|
+
height = DEFAULT_HEIGHT,
|
|
50225
|
+
spriteSize = 32,
|
|
50226
|
+
moveEvent = "MOVE",
|
|
50227
|
+
fireEvent = "FIRE",
|
|
50228
|
+
playAgainEvent = "PLAY_AGAIN",
|
|
50229
|
+
gameEndEvent = "GAME_END",
|
|
50230
|
+
className
|
|
50231
|
+
}) {
|
|
50232
|
+
const board = boardEntity(entity) ?? {};
|
|
50233
|
+
const eventBus = useEventBus();
|
|
50234
|
+
const { t } = useTranslate();
|
|
50235
|
+
const assetManifest = propAssetManifest ?? board.assetManifest;
|
|
50236
|
+
const player = propPlayer ?? readPlayer(board.player) ?? { x: width / 2, y: height - spriteSize };
|
|
50237
|
+
const enemies = useMemo(
|
|
50238
|
+
() => propEnemies ?? rows(board.enemies).map((r) => ({
|
|
50239
|
+
id: str(r.id),
|
|
50240
|
+
x: num(r.x),
|
|
50241
|
+
y: num(r.y),
|
|
50242
|
+
hp: num(r.hp, 1)
|
|
50243
|
+
})),
|
|
50244
|
+
[propEnemies, board.enemies]
|
|
50245
|
+
);
|
|
50246
|
+
const projectiles = useMemo(
|
|
50247
|
+
() => propProjectiles ?? rows(board.projectiles).map((r) => ({
|
|
50248
|
+
id: str(r.id),
|
|
50249
|
+
x: num(r.x),
|
|
50250
|
+
y: num(r.y),
|
|
50251
|
+
vx: num(r.vx),
|
|
50252
|
+
vy: num(r.vy)
|
|
50253
|
+
})),
|
|
50254
|
+
[propProjectiles, board.projectiles]
|
|
50255
|
+
);
|
|
50256
|
+
const score = propScore ?? num(board.score, 0);
|
|
50257
|
+
const wave = propWave ?? num(board.wave, 1);
|
|
50258
|
+
const lives = propLives ?? num(board.lives, 3);
|
|
50259
|
+
const result = propResult ?? (str(board.result) || "none");
|
|
50260
|
+
const playerSprite = resolveManifestUrl4(assetManifest, assetManifest?.units?.player);
|
|
50261
|
+
const enemySprite = resolveManifestUrl4(assetManifest, assetManifest?.units?.enemy);
|
|
50262
|
+
const projectileSprite = resolveManifestUrl4(assetManifest, assetManifest?.features?.projectile);
|
|
50263
|
+
const backgroundSprite = resolveManifestUrl4(assetManifest, assetManifest?.background);
|
|
50264
|
+
const spriteUrls = useMemo(
|
|
50265
|
+
() => [playerSprite, enemySprite, projectileSprite].filter((u) => u != null),
|
|
50266
|
+
[playerSprite, enemySprite, projectileSprite]
|
|
50267
|
+
);
|
|
50268
|
+
const { getImage } = useImageCache(spriteUrls);
|
|
50269
|
+
const sceneRef = useRef({ player, enemies, projectiles, playerSprite, enemySprite, projectileSprite });
|
|
50270
|
+
sceneRef.current = { player, enemies, projectiles, playerSprite, enemySprite, projectileSprite };
|
|
50271
|
+
boardLog2.debug("shooter-resolve", {
|
|
50272
|
+
player: { x: player.x, y: player.y },
|
|
50273
|
+
enemyCount: enemies.length,
|
|
50274
|
+
projectileCount: projectiles.length,
|
|
50275
|
+
wave,
|
|
50276
|
+
lives,
|
|
50277
|
+
result,
|
|
50278
|
+
hasPlayerSprite: playerSprite != null
|
|
50279
|
+
});
|
|
50280
|
+
const onDraw = useCallback(
|
|
50281
|
+
(ctx, _frame) => {
|
|
50282
|
+
const scene = sceneRef.current;
|
|
50283
|
+
ctx.fillStyle = "#10141c";
|
|
50284
|
+
ctx.fillRect(0, 0, width, height);
|
|
50285
|
+
const half = spriteSize / 2;
|
|
50286
|
+
for (const p2 of scene.projectiles) {
|
|
50287
|
+
const img = scene.projectileSprite ? getImage(scene.projectileSprite) : void 0;
|
|
50288
|
+
if (img) {
|
|
50289
|
+
ctx.drawImage(img, p2.x - half / 2, p2.y - half / 2, spriteSize / 2, spriteSize / 2);
|
|
50290
|
+
} else {
|
|
50291
|
+
ctx.fillStyle = "#ffd34d";
|
|
50292
|
+
ctx.beginPath();
|
|
50293
|
+
ctx.arc(p2.x, p2.y, spriteSize / 6, 0, Math.PI * 2);
|
|
50294
|
+
ctx.fill();
|
|
50295
|
+
}
|
|
50296
|
+
}
|
|
50297
|
+
for (const e of scene.enemies) {
|
|
50298
|
+
const img = scene.enemySprite ? getImage(scene.enemySprite) : void 0;
|
|
50299
|
+
if (img) {
|
|
50300
|
+
ctx.drawImage(img, e.x - half, e.y - half, spriteSize, spriteSize);
|
|
50301
|
+
} else {
|
|
50302
|
+
ctx.fillStyle = "#e0524d";
|
|
50303
|
+
ctx.fillRect(e.x - half, e.y - half, spriteSize, spriteSize);
|
|
50304
|
+
}
|
|
50305
|
+
}
|
|
50306
|
+
const pImg = scene.playerSprite ? getImage(scene.playerSprite) : void 0;
|
|
50307
|
+
if (pImg) {
|
|
50308
|
+
ctx.drawImage(pImg, scene.player.x - half, scene.player.y - half, spriteSize, spriteSize);
|
|
50309
|
+
} else {
|
|
50310
|
+
ctx.fillStyle = "#4da3ff";
|
|
50311
|
+
ctx.beginPath();
|
|
50312
|
+
ctx.moveTo(scene.player.x, scene.player.y - half);
|
|
50313
|
+
ctx.lineTo(scene.player.x + half, scene.player.y + half);
|
|
50314
|
+
ctx.lineTo(scene.player.x - half, scene.player.y + half);
|
|
50315
|
+
ctx.closePath();
|
|
50316
|
+
ctx.fill();
|
|
50317
|
+
}
|
|
50318
|
+
},
|
|
50319
|
+
[getImage, width, height, spriteSize]
|
|
50320
|
+
);
|
|
50321
|
+
const moveEventRef = useRef(moveEvent);
|
|
50322
|
+
moveEventRef.current = moveEvent;
|
|
50323
|
+
const fireEventRef = useRef(fireEvent);
|
|
50324
|
+
fireEventRef.current = fireEvent;
|
|
50325
|
+
const resultRef = useRef(result);
|
|
50326
|
+
resultRef.current = result;
|
|
50327
|
+
const playerRef = useRef(player);
|
|
50328
|
+
playerRef.current = player;
|
|
50329
|
+
useEffect(() => {
|
|
50330
|
+
function onKeyDown(e) {
|
|
50331
|
+
if (resultRef.current !== "none") return;
|
|
50332
|
+
let dx = 0;
|
|
50333
|
+
let dy = 0;
|
|
50334
|
+
switch (e.key) {
|
|
50335
|
+
case "ArrowUp":
|
|
50336
|
+
case "w":
|
|
50337
|
+
dy = -1;
|
|
50338
|
+
break;
|
|
50339
|
+
case "ArrowDown":
|
|
50340
|
+
case "s":
|
|
50341
|
+
dy = 1;
|
|
50342
|
+
break;
|
|
50343
|
+
case "ArrowLeft":
|
|
50344
|
+
case "a":
|
|
50345
|
+
dx = -1;
|
|
50346
|
+
break;
|
|
50347
|
+
case "ArrowRight":
|
|
50348
|
+
case "d":
|
|
50349
|
+
dx = 1;
|
|
50350
|
+
break;
|
|
50351
|
+
case " ": {
|
|
50352
|
+
e.preventDefault();
|
|
50353
|
+
const evt = fireEventRef.current;
|
|
50354
|
+
if (evt) {
|
|
50355
|
+
eventBus.emit(`UI:${evt}`, { tx: playerRef.current.x, ty: 0 });
|
|
50356
|
+
}
|
|
50357
|
+
return;
|
|
50358
|
+
}
|
|
50359
|
+
default:
|
|
50360
|
+
return;
|
|
50361
|
+
}
|
|
50362
|
+
e.preventDefault();
|
|
50363
|
+
const moveEvt = moveEventRef.current;
|
|
50364
|
+
if (moveEvt) {
|
|
50365
|
+
eventBus.emit(`UI:${moveEvt}`, { dx, dy });
|
|
50366
|
+
}
|
|
50367
|
+
}
|
|
50368
|
+
window.addEventListener("keydown", onKeyDown);
|
|
50369
|
+
return () => window.removeEventListener("keydown", onKeyDown);
|
|
50370
|
+
}, [eventBus]);
|
|
50371
|
+
const handleFireClick = useCallback(
|
|
50372
|
+
(e) => {
|
|
50373
|
+
if (result !== "none") return;
|
|
50374
|
+
const evt = fireEventRef.current;
|
|
50375
|
+
if (!evt) return;
|
|
50376
|
+
const rect = e.currentTarget.getBoundingClientRect();
|
|
50377
|
+
const tx = e.clientX - rect.left;
|
|
50378
|
+
const ty = e.clientY - rect.top;
|
|
50379
|
+
eventBus.emit(`UI:${evt}`, { tx, ty });
|
|
50380
|
+
},
|
|
50381
|
+
[result, eventBus]
|
|
50382
|
+
);
|
|
50383
|
+
const handlePlayAgain = useCallback(() => {
|
|
50384
|
+
if (playAgainEvent) {
|
|
50385
|
+
eventBus.emit(`UI:${playAgainEvent}`, {});
|
|
50386
|
+
}
|
|
50387
|
+
}, [playAgainEvent, eventBus]);
|
|
50388
|
+
const gameEndEmittedRef = useRef(false);
|
|
50389
|
+
useEffect(() => {
|
|
50390
|
+
if ((result === "won" || result === "lost") && gameEndEvent) {
|
|
50391
|
+
if (!gameEndEmittedRef.current) {
|
|
50392
|
+
gameEndEmittedRef.current = true;
|
|
50393
|
+
eventBus.emit(`UI:${gameEndEvent}`, { result });
|
|
50394
|
+
}
|
|
50395
|
+
} else {
|
|
50396
|
+
gameEndEmittedRef.current = false;
|
|
50397
|
+
}
|
|
50398
|
+
}, [result, gameEndEvent, eventBus]);
|
|
50399
|
+
const isGameOver = result === "won" || result === "lost";
|
|
50400
|
+
return /* @__PURE__ */ jsxs(VStack, { className: cn("top-down-shooter-board relative bg-background", className), gap: "none", children: [
|
|
50401
|
+
/* @__PURE__ */ jsxs(HStack, { className: "px-4 py-2 border-b border-border bg-surface", gap: "lg", align: "center", children: [
|
|
50402
|
+
/* @__PURE__ */ jsxs(HStack, { gap: "xs", align: "center", children: [
|
|
50403
|
+
/* @__PURE__ */ jsx(Typography, { variant: "small", color: "muted", children: t("shooter.score") ?? "Score" }),
|
|
50404
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body2", weight: "bold", className: "text-warning", children: score })
|
|
50405
|
+
] }),
|
|
50406
|
+
/* @__PURE__ */ jsxs(HStack, { gap: "xs", align: "center", children: [
|
|
50407
|
+
/* @__PURE__ */ jsx(Typography, { variant: "small", color: "muted", children: t("shooter.wave") ?? "Wave" }),
|
|
50408
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body2", weight: "bold", children: wave })
|
|
50409
|
+
] }),
|
|
50410
|
+
/* @__PURE__ */ jsxs(HStack, { gap: "xs", align: "center", children: [
|
|
50411
|
+
/* @__PURE__ */ jsx(Typography, { variant: "small", color: "muted", children: t("shooter.lives") ?? "Lives" }),
|
|
50412
|
+
/* @__PURE__ */ jsx(
|
|
50413
|
+
Typography,
|
|
50414
|
+
{
|
|
50415
|
+
variant: "body2",
|
|
50416
|
+
weight: "bold",
|
|
50417
|
+
className: lives <= 1 ? "text-error" : "text-success",
|
|
50418
|
+
children: lives
|
|
50419
|
+
}
|
|
50420
|
+
)
|
|
50421
|
+
] })
|
|
50422
|
+
] }),
|
|
50423
|
+
/* @__PURE__ */ jsxs(Box, { className: "relative", onClick: handleFireClick, children: [
|
|
50424
|
+
/* @__PURE__ */ jsx(
|
|
50425
|
+
GameCanvas2D,
|
|
50426
|
+
{
|
|
50427
|
+
width,
|
|
50428
|
+
height,
|
|
50429
|
+
backgroundImage: backgroundSprite,
|
|
50430
|
+
assetBaseUrl: assetManifest?.baseUrl,
|
|
50431
|
+
onDraw
|
|
50432
|
+
}
|
|
50433
|
+
),
|
|
50434
|
+
isGameOver && /* @__PURE__ */ jsx(Box, { className: "absolute inset-0 z-50 flex items-center justify-center bg-background/70 backdrop-blur-sm rounded-container", children: /* @__PURE__ */ jsxs(VStack, { className: "text-center p-8", gap: "lg", children: [
|
|
50435
|
+
/* @__PURE__ */ jsx(
|
|
50436
|
+
Typography,
|
|
50437
|
+
{
|
|
50438
|
+
variant: "h2",
|
|
50439
|
+
className: cn(
|
|
50440
|
+
"text-4xl font-black tracking-widest uppercase",
|
|
50441
|
+
result === "won" ? "text-warning" : "text-error"
|
|
50442
|
+
),
|
|
50443
|
+
children: result === "won" ? t("shooter.victory") ?? "Victory!" : t("shooter.defeat") ?? "Defeat!"
|
|
50444
|
+
}
|
|
50445
|
+
),
|
|
50446
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body1", className: "text-muted-foreground", children: result === "won" ? t("shooter.cleared") ?? `Cleared wave ${wave} \u2014 score ${score}` : t("shooter.overrun") ?? "You were overrun." }),
|
|
50447
|
+
/* @__PURE__ */ jsx(
|
|
50448
|
+
Button,
|
|
50449
|
+
{
|
|
50450
|
+
variant: "primary",
|
|
50451
|
+
className: "px-8 py-3 font-semibold",
|
|
50452
|
+
onClick: handlePlayAgain,
|
|
50453
|
+
children: t("shooter.playAgain") ?? "Play Again"
|
|
50454
|
+
}
|
|
50455
|
+
)
|
|
50456
|
+
] }) })
|
|
50457
|
+
] })
|
|
50458
|
+
] });
|
|
50459
|
+
}
|
|
50460
|
+
var boardLog2, DEFAULT_WIDTH, DEFAULT_HEIGHT;
|
|
50461
|
+
var init_TopDownShooterBoard = __esm({
|
|
50462
|
+
"components/game/organisms/TopDownShooterBoard.tsx"() {
|
|
50463
|
+
"use client";
|
|
50464
|
+
init_cn();
|
|
50465
|
+
init_useEventBus();
|
|
50466
|
+
init_Box();
|
|
50467
|
+
init_Button();
|
|
50468
|
+
init_Typography();
|
|
50469
|
+
init_Stack();
|
|
50470
|
+
init_GameCanvas2D();
|
|
50471
|
+
init_useImageCache();
|
|
50472
|
+
init_boardEntity();
|
|
50473
|
+
boardLog2 = createLogger("almadar:ui:game:top-down-shooter-board");
|
|
50474
|
+
DEFAULT_WIDTH = 640;
|
|
50475
|
+
DEFAULT_HEIGHT = 480;
|
|
50476
|
+
TopDownShooterBoard.displayName = "TopDownShooterBoard";
|
|
50477
|
+
}
|
|
50478
|
+
});
|
|
50479
|
+
function isEntityRow3(value) {
|
|
50480
|
+
return value != null && typeof value === "object" && !Array.isArray(value);
|
|
50481
|
+
}
|
|
50482
|
+
function TopDownShooterTemplate({
|
|
50483
|
+
entity,
|
|
50484
|
+
title = "Arena Shooter",
|
|
50485
|
+
player,
|
|
50486
|
+
enemies,
|
|
50487
|
+
projectiles,
|
|
50488
|
+
score,
|
|
50489
|
+
wave,
|
|
50490
|
+
lives,
|
|
50491
|
+
result,
|
|
50492
|
+
assetManifest,
|
|
50493
|
+
width,
|
|
50494
|
+
height,
|
|
50495
|
+
spriteSize,
|
|
50496
|
+
moveEvent,
|
|
50497
|
+
fireEvent,
|
|
50498
|
+
playAgainEvent,
|
|
50499
|
+
gameEndEvent,
|
|
50500
|
+
className
|
|
50501
|
+
}) {
|
|
50502
|
+
const resolved = isEntityRow3(entity) ? entity : void 0;
|
|
50503
|
+
return /* @__PURE__ */ jsxs(
|
|
50504
|
+
Box,
|
|
50505
|
+
{
|
|
50506
|
+
display: "flex",
|
|
50507
|
+
fullHeight: true,
|
|
50508
|
+
className: cn("top-down-shooter-template flex-col", className),
|
|
50509
|
+
children: [
|
|
50510
|
+
/* @__PURE__ */ jsx(
|
|
50511
|
+
HStack,
|
|
50512
|
+
{
|
|
50513
|
+
gap: "sm",
|
|
50514
|
+
align: "center",
|
|
50515
|
+
className: "px-4 py-3 border-b-2 border-border bg-surface shrink-0",
|
|
50516
|
+
children: /* @__PURE__ */ jsx(Typography, { variant: "h4", children: title })
|
|
50517
|
+
}
|
|
50518
|
+
),
|
|
50519
|
+
/* @__PURE__ */ jsx(Box, { className: "flex-1 relative overflow-hidden", children: /* @__PURE__ */ jsx(
|
|
50520
|
+
TopDownShooterBoard,
|
|
50521
|
+
{
|
|
50522
|
+
entity: resolved,
|
|
50523
|
+
player,
|
|
50524
|
+
enemies,
|
|
50525
|
+
projectiles,
|
|
50526
|
+
score,
|
|
50527
|
+
wave,
|
|
50528
|
+
lives,
|
|
50529
|
+
result,
|
|
50530
|
+
assetManifest,
|
|
50531
|
+
width,
|
|
50532
|
+
height,
|
|
50533
|
+
spriteSize,
|
|
50534
|
+
moveEvent,
|
|
50535
|
+
fireEvent,
|
|
50536
|
+
playAgainEvent,
|
|
50537
|
+
gameEndEvent,
|
|
50538
|
+
className: "h-full"
|
|
50539
|
+
}
|
|
50540
|
+
) })
|
|
50541
|
+
]
|
|
50542
|
+
}
|
|
50543
|
+
);
|
|
50544
|
+
}
|
|
50545
|
+
var init_TopDownShooterTemplate = __esm({
|
|
50546
|
+
"components/game/templates/TopDownShooterTemplate.tsx"() {
|
|
50547
|
+
init_cn();
|
|
50548
|
+
init_Box();
|
|
50549
|
+
init_Stack();
|
|
50550
|
+
init_Typography();
|
|
50551
|
+
init_TopDownShooterBoard();
|
|
50552
|
+
TopDownShooterTemplate.displayName = "TopDownShooterTemplate";
|
|
50553
|
+
}
|
|
50554
|
+
});
|
|
50555
|
+
function resolveManifestUrl5(manifest, relative) {
|
|
50556
|
+
if (relative == null) return void 0;
|
|
50557
|
+
if (/^https?:\/\//.test(relative)) return relative;
|
|
50558
|
+
const base = manifest?.baseUrl;
|
|
50559
|
+
if (base == null) return relative;
|
|
50560
|
+
const cleanBase = base.replace(/\/$/, "");
|
|
50561
|
+
const cleanRel = relative.replace(/^\//, "");
|
|
50562
|
+
return `${cleanBase}/${cleanRel}`;
|
|
50563
|
+
}
|
|
49397
50564
|
function buildDefaultTDTiles() {
|
|
49398
50565
|
const pathSet = new Set(DEFAULT_TD_PATH.map((p2) => `${p2.x},${p2.y}`));
|
|
49399
50566
|
const tiles = [];
|
|
49400
50567
|
for (let y = 0; y < TD_GRID_H; y++) {
|
|
49401
50568
|
for (let x = 0; x < TD_GRID_W; x++) {
|
|
49402
50569
|
if (pathSet.has(`${x},${y}`)) {
|
|
49403
|
-
tiles.push({ x, y, terrain: "path", passable: false
|
|
50570
|
+
tiles.push({ x, y, terrain: "path", passable: false });
|
|
49404
50571
|
} else {
|
|
49405
50572
|
const variant = (x * 3 + y * 5 + (x ^ y)) % 3;
|
|
49406
|
-
const terrainKey = ["ground", "grass", "
|
|
49407
|
-
tiles.push({ x, y, terrain: terrainKey, passable: true
|
|
50573
|
+
const terrainKey = ["ground", "grass", "stone"][variant];
|
|
50574
|
+
tiles.push({ x, y, terrain: terrainKey, passable: true });
|
|
49408
50575
|
}
|
|
49409
50576
|
}
|
|
49410
50577
|
}
|
|
49411
50578
|
return tiles;
|
|
49412
50579
|
}
|
|
49413
|
-
function
|
|
49414
|
-
return tiles.map((t) =>
|
|
49415
|
-
|
|
49416
|
-
|
|
49417
|
-
|
|
49418
|
-
|
|
49419
|
-
|
|
49420
|
-
|
|
49421
|
-
|
|
49422
|
-
|
|
49423
|
-
|
|
49424
|
-
|
|
49425
|
-
position: { x: t.x, y: t.y },
|
|
49426
|
-
name: "Tower",
|
|
49427
|
-
team: "player",
|
|
49428
|
-
sprite: TOWER_SPRITE,
|
|
49429
|
-
unitType: "guardian",
|
|
49430
|
-
health: 1,
|
|
49431
|
-
maxHealth: 1
|
|
49432
|
-
}));
|
|
50580
|
+
function tilesToIso2(tiles, manifest) {
|
|
50581
|
+
return tiles.map((t) => {
|
|
50582
|
+
const key = t.terrain ?? "ground";
|
|
50583
|
+
const sprite = t.terrainSprite ?? resolveManifestUrl5(manifest, manifest?.terrains?.[key]) ?? resolveManifestUrl5(manifest, manifest?.terrains?.ground);
|
|
50584
|
+
return {
|
|
50585
|
+
x: t.x,
|
|
50586
|
+
y: t.y,
|
|
50587
|
+
terrain: t.terrain,
|
|
50588
|
+
terrainSprite: sprite,
|
|
50589
|
+
passable: t.passable
|
|
50590
|
+
};
|
|
50591
|
+
});
|
|
49433
50592
|
}
|
|
49434
|
-
function creepsToUnits(creeps) {
|
|
50593
|
+
function creepsToUnits(creeps, manifest) {
|
|
50594
|
+
const sprite = resolveManifestUrl5(manifest, manifest?.units?.creep);
|
|
49435
50595
|
return creeps.map((c) => ({
|
|
49436
50596
|
id: c.id,
|
|
49437
50597
|
position: { x: c.x, y: c.y },
|
|
49438
50598
|
name: "Creep",
|
|
49439
50599
|
team: "enemy",
|
|
49440
|
-
sprite
|
|
49441
|
-
unitType: "
|
|
50600
|
+
sprite,
|
|
50601
|
+
unitType: "creep",
|
|
49442
50602
|
health: c.hp,
|
|
49443
50603
|
maxHealth: c.maxHp
|
|
49444
50604
|
}));
|
|
49445
50605
|
}
|
|
49446
|
-
function
|
|
49447
|
-
return path.map((p2, i) => ({
|
|
49448
|
-
id: `path-${i}`,
|
|
49449
|
-
x: p2.x,
|
|
49450
|
-
y: p2.y,
|
|
49451
|
-
type: "path-marker",
|
|
49452
|
-
sprite: `${CDN6}world-map/road_straight.png`
|
|
49453
|
-
}));
|
|
49454
|
-
}
|
|
49455
|
-
function heroToUnit(hero) {
|
|
50606
|
+
function heroToUnit(hero, manifest) {
|
|
49456
50607
|
return {
|
|
49457
50608
|
id: hero.id,
|
|
49458
50609
|
position: { x: hero.x, y: hero.y },
|
|
49459
50610
|
name: "Hero",
|
|
49460
50611
|
team: "player",
|
|
49461
|
-
sprite:
|
|
49462
|
-
unitType: "
|
|
50612
|
+
sprite: resolveManifestUrl5(manifest, manifest?.units?.hero),
|
|
50613
|
+
unitType: "hero",
|
|
49463
50614
|
health: 1,
|
|
49464
50615
|
maxHealth: 1
|
|
49465
50616
|
};
|
|
49466
50617
|
}
|
|
50618
|
+
function towersToFeatures(towers, manifest) {
|
|
50619
|
+
const sprite = resolveManifestUrl5(manifest, manifest?.features?.tower);
|
|
50620
|
+
return towers.map((t) => ({
|
|
50621
|
+
id: t.id,
|
|
50622
|
+
x: t.x,
|
|
50623
|
+
y: t.y,
|
|
50624
|
+
type: "tower",
|
|
50625
|
+
sprite
|
|
50626
|
+
}));
|
|
50627
|
+
}
|
|
49467
50628
|
function TowerDefenseBoard({
|
|
49468
50629
|
entity,
|
|
49469
50630
|
tiles: propTiles,
|
|
49470
50631
|
path: propPath,
|
|
49471
50632
|
towers: propTowers,
|
|
49472
50633
|
creeps: propCreeps,
|
|
50634
|
+
assetManifest: propAssetManifest,
|
|
49473
50635
|
hero: propHero,
|
|
49474
50636
|
gold: propGold,
|
|
49475
50637
|
lives: propLives,
|
|
@@ -49492,12 +50654,51 @@ function TowerDefenseBoard({
|
|
|
49492
50654
|
const board = boardEntity(entity) ?? {};
|
|
49493
50655
|
const eventBus = useEventBus();
|
|
49494
50656
|
const { t } = useTranslate();
|
|
49495
|
-
const
|
|
50657
|
+
const assetManifest = propAssetManifest ?? board.assetManifest;
|
|
50658
|
+
const entityTiles = useMemo(
|
|
50659
|
+
() => rows(board.tiles).map((r) => ({
|
|
50660
|
+
x: num(r.x),
|
|
50661
|
+
y: num(r.y),
|
|
50662
|
+
terrain: r.terrain == null ? void 0 : str(r.terrain),
|
|
50663
|
+
terrainSprite: r.terrainSprite == null ? void 0 : str(r.terrainSprite),
|
|
50664
|
+
passable: r.passable !== false
|
|
50665
|
+
})),
|
|
50666
|
+
[board.tiles]
|
|
50667
|
+
);
|
|
50668
|
+
const rawTiles = propTiles ?? entityTiles;
|
|
49496
50669
|
const tiles = rawTiles.length >= TD_GRID_W * TD_GRID_H ? rawTiles : DEFAULT_TD_TILES;
|
|
49497
|
-
const
|
|
50670
|
+
const entityPath = useMemo(
|
|
50671
|
+
() => rows(board.path).map((r) => ({ x: num(r.x), y: num(r.y) })),
|
|
50672
|
+
[board.path]
|
|
50673
|
+
);
|
|
50674
|
+
const rawPath = propPath ?? entityPath;
|
|
49498
50675
|
const path = rawPath.length > 0 ? rawPath : DEFAULT_TD_PATH;
|
|
49499
|
-
const
|
|
49500
|
-
|
|
50676
|
+
const entityTowers = useMemo(
|
|
50677
|
+
() => rows(board.towers).map((r) => ({
|
|
50678
|
+
id: str(r.id),
|
|
50679
|
+
x: num(r.x),
|
|
50680
|
+
y: num(r.y),
|
|
50681
|
+
range: num(r.range),
|
|
50682
|
+
damage: num(r.damage),
|
|
50683
|
+
cooldown: num(r.cooldown),
|
|
50684
|
+
lastFiredAt: r.lastFiredAt == null ? void 0 : num(r.lastFiredAt)
|
|
50685
|
+
})),
|
|
50686
|
+
[board.towers]
|
|
50687
|
+
);
|
|
50688
|
+
const towers = propTowers ?? entityTowers;
|
|
50689
|
+
const entityCreeps = useMemo(
|
|
50690
|
+
() => rows(board.creeps).map((r) => ({
|
|
50691
|
+
id: str(r.id),
|
|
50692
|
+
x: num(r.x),
|
|
50693
|
+
y: num(r.y),
|
|
50694
|
+
hp: num(r.hp),
|
|
50695
|
+
maxHp: num(r.maxHp),
|
|
50696
|
+
pathIndex: num(r.pathIndex),
|
|
50697
|
+
speed: num(r.speed)
|
|
50698
|
+
})),
|
|
50699
|
+
[board.creeps]
|
|
50700
|
+
);
|
|
50701
|
+
const creeps = propCreeps ?? entityCreeps;
|
|
49501
50702
|
const hero = propHero ?? { id: "hero", x: 8, y: 8 };
|
|
49502
50703
|
const gold = propGold ?? num(board.gold, 100);
|
|
49503
50704
|
const lives = propLives ?? num(board.lives, 20);
|
|
@@ -49549,12 +50750,11 @@ function TowerDefenseBoard({
|
|
|
49549
50750
|
(t2) => t2.passable !== false && !towerPositions.has(`${t2.x},${t2.y}`) && !pathPositions.has(`${t2.x},${t2.y}`)
|
|
49550
50751
|
).map((t2) => ({ x: t2.x, y: t2.y }));
|
|
49551
50752
|
}, [tiles, towerPositions, pathPositions, result, gold, towerCost]);
|
|
49552
|
-
const isoTiles = useMemo(() =>
|
|
49553
|
-
const
|
|
49554
|
-
const
|
|
49555
|
-
const
|
|
49556
|
-
const
|
|
49557
|
-
const pathFeatures = useMemo(() => pathToFeatures(path), [path]);
|
|
50753
|
+
const isoTiles = useMemo(() => tilesToIso2(tiles, assetManifest), [tiles, assetManifest]);
|
|
50754
|
+
const creepUnits = useMemo(() => creepsToUnits(creeps, assetManifest), [creeps, assetManifest]);
|
|
50755
|
+
const heroUnit = useMemo(() => heroToUnit(hero, assetManifest), [hero, assetManifest]);
|
|
50756
|
+
const isoUnits = useMemo(() => [...creepUnits, heroUnit], [creepUnits, heroUnit]);
|
|
50757
|
+
const towerFeatures = useMemo(() => towersToFeatures(towers, assetManifest), [towers, assetManifest]);
|
|
49558
50758
|
const handleTileClick = useCallback((x, y) => {
|
|
49559
50759
|
if (result !== "none") return;
|
|
49560
50760
|
if (pathPositions.has(`${x},${y}`)) return;
|
|
@@ -49613,7 +50813,9 @@ function TowerDefenseBoard({
|
|
|
49613
50813
|
{
|
|
49614
50814
|
tiles: isoTiles,
|
|
49615
50815
|
units: isoUnits,
|
|
49616
|
-
features:
|
|
50816
|
+
features: towerFeatures,
|
|
50817
|
+
assetBaseUrl: assetManifest?.baseUrl,
|
|
50818
|
+
assetManifest,
|
|
49617
50819
|
validMoves,
|
|
49618
50820
|
hoveredTile,
|
|
49619
50821
|
onTileClick: handleTileClick,
|
|
@@ -49652,7 +50854,7 @@ function TowerDefenseBoard({
|
|
|
49652
50854
|
] }) })
|
|
49653
50855
|
] });
|
|
49654
50856
|
}
|
|
49655
|
-
var
|
|
50857
|
+
var TD_GRID_W, TD_GRID_H, DEFAULT_TD_PATH, DEFAULT_TD_TILES;
|
|
49656
50858
|
var init_TowerDefenseBoard = __esm({
|
|
49657
50859
|
"components/game/organisms/TowerDefenseBoard.tsx"() {
|
|
49658
50860
|
"use client";
|
|
@@ -49664,16 +50866,8 @@ var init_TowerDefenseBoard = __esm({
|
|
|
49664
50866
|
init_Stack();
|
|
49665
50867
|
init_IsometricCanvas();
|
|
49666
50868
|
init_boardEntity();
|
|
49667
|
-
CDN6 = "https://almadar-kflow-assets.web.app/shared/";
|
|
49668
50869
|
TD_GRID_W = 16;
|
|
49669
50870
|
TD_GRID_H = 16;
|
|
49670
|
-
TERRAIN_SPRITES = {
|
|
49671
|
-
ground: `${CDN6}isometric-blocks/PNG/Platformer tiles/platformerTile_01.png`,
|
|
49672
|
-
path: `${CDN6}isometric-blocks/PNG/Platformer tiles/platformerTile_09.png`,
|
|
49673
|
-
wall: `${CDN6}isometric-blocks/PNG/Platformer tiles/platformerTile_05.png`,
|
|
49674
|
-
grass: `${CDN6}isometric-dungeon/Isometric/dirt_E.png`,
|
|
49675
|
-
dirt: `${CDN6}isometric-dungeon/Isometric/dirtTiles_E.png`
|
|
49676
|
-
};
|
|
49677
50871
|
DEFAULT_TD_PATH = [
|
|
49678
50872
|
{ x: 2, y: 0 },
|
|
49679
50873
|
{ x: 2, y: 1 },
|
|
@@ -49726,9 +50920,6 @@ var init_TowerDefenseBoard = __esm({
|
|
|
49726
50920
|
{ x: 13, y: 15 }
|
|
49727
50921
|
];
|
|
49728
50922
|
DEFAULT_TD_TILES = buildDefaultTDTiles();
|
|
49729
|
-
TOWER_SPRITE = `${CDN6}sprite-sheets/guardian-sprite-sheet-se.png`;
|
|
49730
|
-
CREEP_SPRITE = `${CDN6}sprite-sheets/scrapper-sprite-sheet-se.png`;
|
|
49731
|
-
HERO_SPRITE = `${CDN6}sprite-sheets/amir-sprite-sheet-se.png`;
|
|
49732
50923
|
TowerDefenseBoard.displayName = "TowerDefenseBoard";
|
|
49733
50924
|
}
|
|
49734
50925
|
});
|
|
@@ -49996,6 +51187,214 @@ var init_UncontrolledBattleBoard = __esm({
|
|
|
49996
51187
|
UncontrolledBattleBoard.displayName = "UncontrolledBattleBoard";
|
|
49997
51188
|
}
|
|
49998
51189
|
});
|
|
51190
|
+
function resolveManifestUrl6(manifest, relative) {
|
|
51191
|
+
if (relative == null) return void 0;
|
|
51192
|
+
if (/^https?:\/\//.test(relative)) return relative;
|
|
51193
|
+
const base = manifest?.baseUrl;
|
|
51194
|
+
if (base == null) return relative;
|
|
51195
|
+
const cleanBase = base.replace(/\/$/, "");
|
|
51196
|
+
const cleanRel = relative.replace(/^\//, "");
|
|
51197
|
+
return `${cleanBase}/${cleanRel}`;
|
|
51198
|
+
}
|
|
51199
|
+
function VisualNovelBoard({
|
|
51200
|
+
entity,
|
|
51201
|
+
nodes: propNodes,
|
|
51202
|
+
currentNodeId: propCurrentNodeId,
|
|
51203
|
+
assetManifest: propAssetManifest,
|
|
51204
|
+
typewriterSpeed = 30,
|
|
51205
|
+
portraitScale = 1,
|
|
51206
|
+
chooseEvent,
|
|
51207
|
+
advanceEvent,
|
|
51208
|
+
restartEvent,
|
|
51209
|
+
className
|
|
51210
|
+
}) {
|
|
51211
|
+
const board = boardEntity(entity) ?? {};
|
|
51212
|
+
const eventBus = useEventBus();
|
|
51213
|
+
const assetManifest = propAssetManifest ?? board.assetManifest;
|
|
51214
|
+
const entityNodes = useMemo(
|
|
51215
|
+
() => rows(board.nodes).map((r) => ({
|
|
51216
|
+
id: str(r.id),
|
|
51217
|
+
speaker: str(r.speaker),
|
|
51218
|
+
text: str(r.text),
|
|
51219
|
+
backgroundKey: r.backgroundKey == null ? void 0 : str(r.backgroundKey),
|
|
51220
|
+
portraitKey: r.portraitKey == null ? void 0 : str(r.portraitKey),
|
|
51221
|
+
choices: rows(r.choices).map((c) => ({
|
|
51222
|
+
label: str(c.label),
|
|
51223
|
+
nextId: str(c.nextId)
|
|
51224
|
+
}))
|
|
51225
|
+
})),
|
|
51226
|
+
[board.nodes]
|
|
51227
|
+
);
|
|
51228
|
+
const rawNodes = propNodes ?? entityNodes;
|
|
51229
|
+
const nodes = rawNodes.length > 0 ? rawNodes : DEFAULT_NODES;
|
|
51230
|
+
const currentNodeId = propCurrentNodeId ?? (str(board.currentNodeId) || nodes[0]?.id);
|
|
51231
|
+
const currentNode = nodes.find((n) => n.id === currentNodeId) ?? nodes[0];
|
|
51232
|
+
const backgroundImage = useMemo(
|
|
51233
|
+
() => resolveManifestUrl6(assetManifest, assetManifest?.backgrounds?.[currentNode?.backgroundKey ?? ""]),
|
|
51234
|
+
[assetManifest, currentNode?.backgroundKey]
|
|
51235
|
+
);
|
|
51236
|
+
const portraitUrl = useMemo(
|
|
51237
|
+
() => resolveManifestUrl6(assetManifest, assetManifest?.portraits?.[currentNode?.portraitKey ?? ""]),
|
|
51238
|
+
[assetManifest, currentNode?.portraitKey]
|
|
51239
|
+
);
|
|
51240
|
+
const dialogueChoices = useMemo(
|
|
51241
|
+
() => (currentNode?.choices ?? []).map((c) => ({ text: c.label, next: c.nextId })),
|
|
51242
|
+
[currentNode?.choices]
|
|
51243
|
+
);
|
|
51244
|
+
const handleChoice = useCallback(
|
|
51245
|
+
(choice) => {
|
|
51246
|
+
const index = dialogueChoices.findIndex((c) => c.next === choice.next && c.text === choice.text);
|
|
51247
|
+
if (chooseEvent) {
|
|
51248
|
+
eventBus.emit(`UI:${chooseEvent}`, { choiceIndex: index });
|
|
51249
|
+
}
|
|
51250
|
+
},
|
|
51251
|
+
[dialogueChoices, chooseEvent, eventBus]
|
|
51252
|
+
);
|
|
51253
|
+
const handleAdvance = useCallback(() => {
|
|
51254
|
+
if (advanceEvent) {
|
|
51255
|
+
eventBus.emit(`UI:${advanceEvent}`, {});
|
|
51256
|
+
}
|
|
51257
|
+
}, [advanceEvent, eventBus]);
|
|
51258
|
+
const handleRestart = useCallback(() => {
|
|
51259
|
+
if (restartEvent) {
|
|
51260
|
+
eventBus.emit(`UI:${restartEvent}`, {});
|
|
51261
|
+
}
|
|
51262
|
+
}, [restartEvent, eventBus]);
|
|
51263
|
+
if (!currentNode) {
|
|
51264
|
+
return /* @__PURE__ */ jsxs(VStack, { className: cn("visual-novel-board relative min-h-[600px] bg-background items-center justify-center", className), gap: "lg", children: [
|
|
51265
|
+
/* @__PURE__ */ jsx(Typography, { variant: "h3", color: "muted", children: "No dialogue nodes" }),
|
|
51266
|
+
/* @__PURE__ */ jsx(Button, { variant: "primary", onClick: handleRestart, children: "Restart" })
|
|
51267
|
+
] });
|
|
51268
|
+
}
|
|
51269
|
+
return /* @__PURE__ */ jsx(Box, { className: cn("visual-novel-board relative min-h-[600px] bg-background overflow-hidden", className), children: /* @__PURE__ */ jsx(
|
|
51270
|
+
DialogueBox,
|
|
51271
|
+
{
|
|
51272
|
+
dialogue: {
|
|
51273
|
+
speaker: currentNode.speaker,
|
|
51274
|
+
text: currentNode.text,
|
|
51275
|
+
choices: dialogueChoices
|
|
51276
|
+
},
|
|
51277
|
+
typewriterSpeed,
|
|
51278
|
+
position: "bottom",
|
|
51279
|
+
backgroundImage,
|
|
51280
|
+
portraitUrl,
|
|
51281
|
+
portraitScale,
|
|
51282
|
+
onChoice: handleChoice,
|
|
51283
|
+
onAdvance: handleAdvance
|
|
51284
|
+
}
|
|
51285
|
+
) });
|
|
51286
|
+
}
|
|
51287
|
+
var DEFAULT_NODES;
|
|
51288
|
+
var init_VisualNovelBoard = __esm({
|
|
51289
|
+
"components/game/organisms/VisualNovelBoard.tsx"() {
|
|
51290
|
+
"use client";
|
|
51291
|
+
init_cn();
|
|
51292
|
+
init_useEventBus();
|
|
51293
|
+
init_Box();
|
|
51294
|
+
init_Typography();
|
|
51295
|
+
init_Stack();
|
|
51296
|
+
init_Button();
|
|
51297
|
+
init_DialogueBox();
|
|
51298
|
+
init_boardEntity();
|
|
51299
|
+
DEFAULT_NODES = [
|
|
51300
|
+
{
|
|
51301
|
+
id: "start",
|
|
51302
|
+
speaker: "Narrator",
|
|
51303
|
+
text: "The corridor stretches into shadow. A lone sentinel blocks your path.",
|
|
51304
|
+
backgroundKey: "corridor",
|
|
51305
|
+
portraitKey: "guide",
|
|
51306
|
+
choices: [
|
|
51307
|
+
{ label: "Approach the sentinel.", nextId: "meet" },
|
|
51308
|
+
{ label: "Turn back.", nextId: "retreat" }
|
|
51309
|
+
]
|
|
51310
|
+
},
|
|
51311
|
+
{
|
|
51312
|
+
id: "meet",
|
|
51313
|
+
speaker: "Sentinel",
|
|
51314
|
+
text: "You carry the old marks. Speak your purpose, traveler.",
|
|
51315
|
+
backgroundKey: "forge",
|
|
51316
|
+
portraitKey: "rival",
|
|
51317
|
+
choices: [
|
|
51318
|
+
{ label: "I seek the core.", nextId: "end" },
|
|
51319
|
+
{ label: "I am only passing through.", nextId: "retreat" }
|
|
51320
|
+
]
|
|
51321
|
+
},
|
|
51322
|
+
{
|
|
51323
|
+
id: "retreat",
|
|
51324
|
+
speaker: "Narrator",
|
|
51325
|
+
text: "You withdraw into the dark. The path will wait for braver feet.",
|
|
51326
|
+
backgroundKey: "corridor",
|
|
51327
|
+
choices: [{ label: "Begin again.", nextId: "start" }]
|
|
51328
|
+
},
|
|
51329
|
+
{
|
|
51330
|
+
id: "end",
|
|
51331
|
+
speaker: "Sentinel",
|
|
51332
|
+
text: "Then the way is open. Walk it well.",
|
|
51333
|
+
backgroundKey: "core",
|
|
51334
|
+
portraitKey: "rival",
|
|
51335
|
+
choices: [{ label: "Begin again.", nextId: "start" }]
|
|
51336
|
+
}
|
|
51337
|
+
];
|
|
51338
|
+
VisualNovelBoard.displayName = "VisualNovelBoard";
|
|
51339
|
+
}
|
|
51340
|
+
});
|
|
51341
|
+
function VisualNovelTemplate({
|
|
51342
|
+
entity,
|
|
51343
|
+
title = "Visual Novel",
|
|
51344
|
+
nodes,
|
|
51345
|
+
currentNodeId,
|
|
51346
|
+
typewriterSpeed,
|
|
51347
|
+
portraitScale,
|
|
51348
|
+
chooseEvent,
|
|
51349
|
+
advanceEvent,
|
|
51350
|
+
restartEvent,
|
|
51351
|
+
className
|
|
51352
|
+
}) {
|
|
51353
|
+
const resolved = entity && typeof entity === "object" && !Array.isArray(entity) ? entity : void 0;
|
|
51354
|
+
return /* @__PURE__ */ jsxs(
|
|
51355
|
+
Box,
|
|
51356
|
+
{
|
|
51357
|
+
display: "flex",
|
|
51358
|
+
fullHeight: true,
|
|
51359
|
+
className: cn("visual-novel-template flex-col", className),
|
|
51360
|
+
children: [
|
|
51361
|
+
/* @__PURE__ */ jsx(
|
|
51362
|
+
HStack,
|
|
51363
|
+
{
|
|
51364
|
+
gap: "sm",
|
|
51365
|
+
align: "center",
|
|
51366
|
+
className: "px-4 py-3 border-b-2 border-border bg-surface shrink-0",
|
|
51367
|
+
children: /* @__PURE__ */ jsx(Typography, { variant: "h4", children: title })
|
|
51368
|
+
}
|
|
51369
|
+
),
|
|
51370
|
+
/* @__PURE__ */ jsx(Box, { className: "flex-1 relative overflow-hidden", children: /* @__PURE__ */ jsx(
|
|
51371
|
+
VisualNovelBoard,
|
|
51372
|
+
{
|
|
51373
|
+
entity: resolved,
|
|
51374
|
+
nodes,
|
|
51375
|
+
currentNodeId,
|
|
51376
|
+
typewriterSpeed,
|
|
51377
|
+
portraitScale,
|
|
51378
|
+
chooseEvent,
|
|
51379
|
+
advanceEvent,
|
|
51380
|
+
restartEvent,
|
|
51381
|
+
className: "h-full"
|
|
51382
|
+
}
|
|
51383
|
+
) })
|
|
51384
|
+
]
|
|
51385
|
+
}
|
|
51386
|
+
);
|
|
51387
|
+
}
|
|
51388
|
+
var init_VisualNovelTemplate = __esm({
|
|
51389
|
+
"components/game/templates/VisualNovelTemplate.tsx"() {
|
|
51390
|
+
init_cn();
|
|
51391
|
+
init_Box();
|
|
51392
|
+
init_Stack();
|
|
51393
|
+
init_Typography();
|
|
51394
|
+
init_VisualNovelBoard();
|
|
51395
|
+
VisualNovelTemplate.displayName = "VisualNovelTemplate";
|
|
51396
|
+
}
|
|
51397
|
+
});
|
|
49999
51398
|
function heroPosition(h) {
|
|
50000
51399
|
if ("position" in h && h.position != null) return h.position;
|
|
50001
51400
|
return vec2(h.position);
|
|
@@ -50336,48 +51735,48 @@ function WorldMapTemplate({
|
|
|
50336
51735
|
}
|
|
50337
51736
|
);
|
|
50338
51737
|
}
|
|
50339
|
-
var
|
|
51738
|
+
var CDN5, DEFAULT_WORLDMAP_TILES, DEFAULT_WORLDMAP_UNITS, DEFAULT_WORLDMAP_FEATURES, DEFAULT_WORLDMAP_MANIFEST;
|
|
50340
51739
|
var init_WorldMapTemplate = __esm({
|
|
50341
51740
|
"components/game/templates/WorldMapTemplate.tsx"() {
|
|
50342
51741
|
init_WorldMapBoard();
|
|
50343
|
-
|
|
51742
|
+
CDN5 = "https://almadar-kflow-assets.web.app/shared";
|
|
50344
51743
|
DEFAULT_WORLDMAP_TILES = [
|
|
50345
|
-
{ x: 0, y: 0, terrain: "mountain", passable: false, terrainSprite: `${
|
|
50346
|
-
{ x: 1, y: 0, terrain: "mountain", passable: false, terrainSprite: `${
|
|
50347
|
-
{ x: 2, y: 0, terrain: "water", passable: false, terrainSprite: `${
|
|
50348
|
-
{ x: 3, y: 0, terrain: "mountain", passable: false, terrainSprite: `${
|
|
50349
|
-
{ x: 4, y: 0, terrain: "mountain", passable: false, terrainSprite: `${
|
|
50350
|
-
{ x: 0, y: 1, terrain: "mountain", passable: false, terrainSprite: `${
|
|
50351
|
-
{ x: 1, y: 1, terrain: "grass", passable: true, terrainSprite: `${
|
|
50352
|
-
{ x: 2, y: 1, terrain: "grass", passable: true, terrainSprite: `${
|
|
50353
|
-
{ x: 3, y: 1, terrain: "grass", passable: true, terrainSprite: `${
|
|
50354
|
-
{ x: 4, y: 1, terrain: "water", passable: false, terrainSprite: `${
|
|
50355
|
-
{ x: 0, y: 2, terrain: "water", passable: false, terrainSprite: `${
|
|
50356
|
-
{ x: 1, y: 2, terrain: "grass", passable: true, terrainSprite: `${
|
|
50357
|
-
{ x: 2, y: 2, terrain: "grass", passable: true, terrainSprite: `${
|
|
50358
|
-
{ x: 3, y: 2, terrain: "grass", passable: true, terrainSprite: `${
|
|
50359
|
-
{ x: 4, y: 2, terrain: "mountain", passable: false, terrainSprite: `${
|
|
50360
|
-
{ x: 0, y: 3, terrain: "mountain", passable: false, terrainSprite: `${
|
|
50361
|
-
{ x: 1, y: 3, terrain: "grass", passable: true, terrainSprite: `${
|
|
50362
|
-
{ x: 2, y: 3, terrain: "grass", passable: true, terrainSprite: `${
|
|
50363
|
-
{ x: 3, y: 3, terrain: "grass", passable: true, terrainSprite: `${
|
|
50364
|
-
{ x: 4, y: 3, terrain: "mountain", passable: false, terrainSprite: `${
|
|
50365
|
-
{ x: 0, y: 4, terrain: "mountain", passable: false, terrainSprite: `${
|
|
50366
|
-
{ x: 1, y: 4, terrain: "water", passable: false, terrainSprite: `${
|
|
50367
|
-
{ x: 2, y: 4, terrain: "grass", passable: true, terrainSprite: `${
|
|
50368
|
-
{ x: 3, y: 4, terrain: "mountain", passable: false, terrainSprite: `${
|
|
50369
|
-
{ x: 4, y: 4, terrain: "mountain", passable: false, terrainSprite: `${
|
|
51744
|
+
{ x: 0, y: 0, terrain: "mountain", passable: false, terrainSprite: `${CDN5}/isometric-blocks/PNG/Platformer tiles/platformerTile_13.png` },
|
|
51745
|
+
{ x: 1, y: 0, terrain: "mountain", passable: false, terrainSprite: `${CDN5}/isometric-blocks/PNG/Platformer tiles/platformerTile_13.png` },
|
|
51746
|
+
{ x: 2, y: 0, terrain: "water", passable: false, terrainSprite: `${CDN5}/isometric-blocks/PNG/Platformer tiles/platformerTile_11.png` },
|
|
51747
|
+
{ x: 3, y: 0, terrain: "mountain", passable: false, terrainSprite: `${CDN5}/isometric-blocks/PNG/Platformer tiles/platformerTile_13.png` },
|
|
51748
|
+
{ x: 4, y: 0, terrain: "mountain", passable: false, terrainSprite: `${CDN5}/isometric-blocks/PNG/Platformer tiles/platformerTile_13.png` },
|
|
51749
|
+
{ x: 0, y: 1, terrain: "mountain", passable: false, terrainSprite: `${CDN5}/isometric-blocks/PNG/Platformer tiles/platformerTile_13.png` },
|
|
51750
|
+
{ x: 1, y: 1, terrain: "grass", passable: true, terrainSprite: `${CDN5}/isometric-blocks/PNG/Platformer tiles/platformerTile_01.png` },
|
|
51751
|
+
{ x: 2, y: 1, terrain: "grass", passable: true, terrainSprite: `${CDN5}/isometric-blocks/PNG/Platformer tiles/platformerTile_01.png` },
|
|
51752
|
+
{ x: 3, y: 1, terrain: "grass", passable: true, terrainSprite: `${CDN5}/isometric-blocks/PNG/Platformer tiles/platformerTile_01.png` },
|
|
51753
|
+
{ x: 4, y: 1, terrain: "water", passable: false, terrainSprite: `${CDN5}/isometric-blocks/PNG/Platformer tiles/platformerTile_11.png` },
|
|
51754
|
+
{ x: 0, y: 2, terrain: "water", passable: false, terrainSprite: `${CDN5}/isometric-blocks/PNG/Platformer tiles/platformerTile_11.png` },
|
|
51755
|
+
{ x: 1, y: 2, terrain: "grass", passable: true, terrainSprite: `${CDN5}/isometric-blocks/PNG/Platformer tiles/platformerTile_01.png` },
|
|
51756
|
+
{ x: 2, y: 2, terrain: "grass", passable: true, terrainSprite: `${CDN5}/isometric-blocks/PNG/Platformer tiles/platformerTile_03.png` },
|
|
51757
|
+
{ x: 3, y: 2, terrain: "grass", passable: true, terrainSprite: `${CDN5}/isometric-blocks/PNG/Platformer tiles/platformerTile_01.png` },
|
|
51758
|
+
{ x: 4, y: 2, terrain: "mountain", passable: false, terrainSprite: `${CDN5}/isometric-blocks/PNG/Platformer tiles/platformerTile_13.png` },
|
|
51759
|
+
{ x: 0, y: 3, terrain: "mountain", passable: false, terrainSprite: `${CDN5}/isometric-blocks/PNG/Platformer tiles/platformerTile_13.png` },
|
|
51760
|
+
{ x: 1, y: 3, terrain: "grass", passable: true, terrainSprite: `${CDN5}/isometric-blocks/PNG/Platformer tiles/platformerTile_01.png` },
|
|
51761
|
+
{ x: 2, y: 3, terrain: "grass", passable: true, terrainSprite: `${CDN5}/isometric-blocks/PNG/Platformer tiles/platformerTile_01.png` },
|
|
51762
|
+
{ x: 3, y: 3, terrain: "grass", passable: true, terrainSprite: `${CDN5}/isometric-blocks/PNG/Platformer tiles/platformerTile_03.png` },
|
|
51763
|
+
{ x: 4, y: 3, terrain: "mountain", passable: false, terrainSprite: `${CDN5}/isometric-blocks/PNG/Platformer tiles/platformerTile_13.png` },
|
|
51764
|
+
{ x: 0, y: 4, terrain: "mountain", passable: false, terrainSprite: `${CDN5}/isometric-blocks/PNG/Platformer tiles/platformerTile_13.png` },
|
|
51765
|
+
{ x: 1, y: 4, terrain: "water", passable: false, terrainSprite: `${CDN5}/isometric-blocks/PNG/Platformer tiles/platformerTile_11.png` },
|
|
51766
|
+
{ x: 2, y: 4, terrain: "grass", passable: true, terrainSprite: `${CDN5}/isometric-blocks/PNG/Platformer tiles/platformerTile_01.png` },
|
|
51767
|
+
{ x: 3, y: 4, terrain: "mountain", passable: false, terrainSprite: `${CDN5}/isometric-blocks/PNG/Platformer tiles/platformerTile_13.png` },
|
|
51768
|
+
{ x: 4, y: 4, terrain: "mountain", passable: false, terrainSprite: `${CDN5}/isometric-blocks/PNG/Platformer tiles/platformerTile_13.png` }
|
|
50370
51769
|
];
|
|
50371
51770
|
DEFAULT_WORLDMAP_UNITS = [
|
|
50372
|
-
{ id: "h1", position: { x: 1, y: 1 }, unitType: "hero", name: "Amir", team: "player", health: 10, maxHealth: 10, sprite: `${
|
|
50373
|
-
{ id: "h2", position: { x: 3, y: 3 }, unitType: "scout", name: "Archivist", team: "player", health: 10, maxHealth: 10, sprite: `${
|
|
51771
|
+
{ id: "h1", position: { x: 1, y: 1 }, unitType: "hero", name: "Amir", team: "player", health: 10, maxHealth: 10, sprite: `${CDN5}/sprite-sheets/amir-sprite-sheet-se.png` },
|
|
51772
|
+
{ id: "h2", position: { x: 3, y: 3 }, unitType: "scout", name: "Archivist", team: "player", health: 10, maxHealth: 10, sprite: `${CDN5}/sprite-sheets/archivist-sprite-sheet-se.png` }
|
|
50374
51773
|
];
|
|
50375
51774
|
DEFAULT_WORLDMAP_FEATURES = [
|
|
50376
|
-
{ id: "f1", x: 2, y: 2, type: "capital", sprite: `${
|
|
50377
|
-
{ id: "f2", x: 4, y: 2, type: "power_node", sprite: `${
|
|
51775
|
+
{ id: "f1", x: 2, y: 2, type: "capital", sprite: `${CDN5}/scenes/world/capital.png` },
|
|
51776
|
+
{ id: "f2", x: 4, y: 2, type: "power_node", sprite: `${CDN5}/world-map/power_node.png` }
|
|
50378
51777
|
];
|
|
50379
51778
|
DEFAULT_WORLDMAP_MANIFEST = {
|
|
50380
|
-
baseUrl:
|
|
51779
|
+
baseUrl: CDN5,
|
|
50381
51780
|
terrains: {
|
|
50382
51781
|
grass: "/isometric-blocks/PNG/Platformer tiles/platformerTile_01.png",
|
|
50383
51782
|
water: "/isometric-blocks/PNG/Platformer tiles/platformerTile_11.png",
|
|
@@ -50397,7 +51796,7 @@ var init_WorldMapTemplate = __esm({
|
|
|
50397
51796
|
}
|
|
50398
51797
|
});
|
|
50399
51798
|
function lazyThree(name, loader) {
|
|
50400
|
-
const Lazy =
|
|
51799
|
+
const Lazy = React85__default.lazy(
|
|
50401
51800
|
() => loader().then((m) => {
|
|
50402
51801
|
const Resolved = m[name];
|
|
50403
51802
|
if (!Resolved) {
|
|
@@ -50409,13 +51808,13 @@ function lazyThree(name, loader) {
|
|
|
50409
51808
|
})
|
|
50410
51809
|
);
|
|
50411
51810
|
function ThreeWrapper(props) {
|
|
50412
|
-
return
|
|
51811
|
+
return React85__default.createElement(
|
|
50413
51812
|
ThreeBoundary,
|
|
50414
51813
|
{ name },
|
|
50415
|
-
|
|
50416
|
-
|
|
51814
|
+
React85__default.createElement(
|
|
51815
|
+
React85__default.Suspense,
|
|
50417
51816
|
{ fallback: null },
|
|
50418
|
-
|
|
51817
|
+
React85__default.createElement(Lazy, props)
|
|
50419
51818
|
)
|
|
50420
51819
|
);
|
|
50421
51820
|
}
|
|
@@ -50459,7 +51858,10 @@ var init_component_registry_generated = __esm({
|
|
|
50459
51858
|
init_CalendarGrid();
|
|
50460
51859
|
init_CanvasEffect();
|
|
50461
51860
|
init_Card();
|
|
51861
|
+
init_CardBattlerBoard();
|
|
51862
|
+
init_CardBattlerTemplate();
|
|
50462
51863
|
init_CardGrid();
|
|
51864
|
+
init_CardHand();
|
|
50463
51865
|
init_Carousel();
|
|
50464
51866
|
init_CaseStudyCard();
|
|
50465
51867
|
init_CaseStudyOrganism();
|
|
@@ -50470,6 +51872,8 @@ var init_component_registry_generated = __esm({
|
|
|
50470
51872
|
init_ChartLegend();
|
|
50471
51873
|
init_Checkbox();
|
|
50472
51874
|
init_ChoiceButton();
|
|
51875
|
+
init_CityBuilderBoard();
|
|
51876
|
+
init_CityBuilderTemplate();
|
|
50473
51877
|
init_ClassifierBoard();
|
|
50474
51878
|
init_CodeBlock();
|
|
50475
51879
|
init_CodeRunnerPanel();
|
|
@@ -50690,6 +52094,8 @@ var init_component_registry_generated = __esm({
|
|
|
50690
52094
|
init_Toast();
|
|
50691
52095
|
init_ToastSlot();
|
|
50692
52096
|
init_Tooltip();
|
|
52097
|
+
init_TopDownShooterBoard();
|
|
52098
|
+
init_TopDownShooterTemplate();
|
|
50693
52099
|
init_TowerDefenseBoard();
|
|
50694
52100
|
init_TowerDefenseTemplate();
|
|
50695
52101
|
init_TraitFrame();
|
|
@@ -50705,6 +52111,8 @@ var init_component_registry_generated = __esm({
|
|
|
50705
52111
|
init_UploadDropZone();
|
|
50706
52112
|
init_VersionDiff();
|
|
50707
52113
|
init_ViolationAlert();
|
|
52114
|
+
init_VisualNovelBoard();
|
|
52115
|
+
init_VisualNovelTemplate();
|
|
50708
52116
|
init_VoteStack();
|
|
50709
52117
|
init_WaypointMarker();
|
|
50710
52118
|
init_WizardContainer();
|
|
@@ -50713,7 +52121,7 @@ var init_component_registry_generated = __esm({
|
|
|
50713
52121
|
init_WorldMapBoard();
|
|
50714
52122
|
init_WorldMapTemplate();
|
|
50715
52123
|
init_XPBar();
|
|
50716
|
-
ThreeBoundary = class extends
|
|
52124
|
+
ThreeBoundary = class extends React85__default.Component {
|
|
50717
52125
|
constructor() {
|
|
50718
52126
|
super(...arguments);
|
|
50719
52127
|
__publicField(this, "state", { failed: false });
|
|
@@ -50723,7 +52131,7 @@ var init_component_registry_generated = __esm({
|
|
|
50723
52131
|
}
|
|
50724
52132
|
render() {
|
|
50725
52133
|
if (this.state.failed) {
|
|
50726
|
-
return
|
|
52134
|
+
return React85__default.createElement(
|
|
50727
52135
|
"div",
|
|
50728
52136
|
{
|
|
50729
52137
|
"data-testid": "three-unavailable",
|
|
@@ -50779,7 +52187,10 @@ var init_component_registry_generated = __esm({
|
|
|
50779
52187
|
"CalendarGrid": CalendarGrid,
|
|
50780
52188
|
"CanvasEffect": CanvasEffect,
|
|
50781
52189
|
"Card": Card,
|
|
52190
|
+
"CardBattlerBoard": CardBattlerBoard,
|
|
52191
|
+
"CardBattlerTemplate": CardBattlerTemplate,
|
|
50782
52192
|
"CardGrid": CardGrid,
|
|
52193
|
+
"CardHand": CardHand,
|
|
50783
52194
|
"Carousel": Carousel,
|
|
50784
52195
|
"CaseStudyCard": CaseStudyCard,
|
|
50785
52196
|
"CaseStudyOrganism": CaseStudyOrganism,
|
|
@@ -50790,6 +52201,8 @@ var init_component_registry_generated = __esm({
|
|
|
50790
52201
|
"ChartLegend": ChartLegend,
|
|
50791
52202
|
"Checkbox": Checkbox,
|
|
50792
52203
|
"ChoiceButton": ChoiceButton,
|
|
52204
|
+
"CityBuilderBoard": CityBuilderBoard,
|
|
52205
|
+
"CityBuilderTemplate": CityBuilderTemplate,
|
|
50793
52206
|
"ClassifierBoard": ClassifierBoard,
|
|
50794
52207
|
"CodeBlock": CodeBlock,
|
|
50795
52208
|
"CodeRunnerPanel": CodeRunnerPanel,
|
|
@@ -51022,6 +52435,8 @@ var init_component_registry_generated = __esm({
|
|
|
51022
52435
|
"Toast": Toast,
|
|
51023
52436
|
"ToastSlot": ToastSlot,
|
|
51024
52437
|
"Tooltip": Tooltip,
|
|
52438
|
+
"TopDownShooterBoard": TopDownShooterBoard,
|
|
52439
|
+
"TopDownShooterTemplate": TopDownShooterTemplate,
|
|
51025
52440
|
"TowerDefenseBoard": TowerDefenseBoard,
|
|
51026
52441
|
"TowerDefenseTemplate": TowerDefenseTemplate,
|
|
51027
52442
|
"TraitFrame": TraitFrame,
|
|
@@ -51038,6 +52453,8 @@ var init_component_registry_generated = __esm({
|
|
|
51038
52453
|
"VStack": VStack,
|
|
51039
52454
|
"VersionDiff": VersionDiff,
|
|
51040
52455
|
"ViolationAlert": ViolationAlert,
|
|
52456
|
+
"VisualNovelBoard": VisualNovelBoard,
|
|
52457
|
+
"VisualNovelTemplate": VisualNovelTemplate,
|
|
51041
52458
|
"VoteStack": VoteStack,
|
|
51042
52459
|
"WaypointMarker": WaypointMarker,
|
|
51043
52460
|
"WizardContainer": WizardContainer,
|
|
@@ -51064,7 +52481,7 @@ function SuspenseConfigProvider({
|
|
|
51064
52481
|
config,
|
|
51065
52482
|
children
|
|
51066
52483
|
}) {
|
|
51067
|
-
return
|
|
52484
|
+
return React85__default.createElement(
|
|
51068
52485
|
SuspenseConfigContext.Provider,
|
|
51069
52486
|
{ value: config },
|
|
51070
52487
|
children
|
|
@@ -51554,7 +52971,7 @@ function renderPatternChildren(children, onDismiss, parentId = "root", parentPat
|
|
|
51554
52971
|
const key = `${parentId}-${index}-trait:${traitName}`;
|
|
51555
52972
|
return /* @__PURE__ */ jsx(TraitFrame, { traitName }, key);
|
|
51556
52973
|
}
|
|
51557
|
-
return /* @__PURE__ */ jsx(
|
|
52974
|
+
return /* @__PURE__ */ jsx(React85__default.Fragment, { children: child }, `${parentId}-${index}`);
|
|
51558
52975
|
}
|
|
51559
52976
|
if (!child || typeof child !== "object") return null;
|
|
51560
52977
|
const childId = `${parentId}-${index}`;
|
|
@@ -51594,14 +53011,14 @@ function isPatternConfig(value) {
|
|
|
51594
53011
|
if (value === null || value === void 0) return false;
|
|
51595
53012
|
if (typeof value !== "object") return false;
|
|
51596
53013
|
if (Array.isArray(value)) return false;
|
|
51597
|
-
if (
|
|
53014
|
+
if (React85__default.isValidElement(value)) return false;
|
|
51598
53015
|
if (value instanceof Date) return false;
|
|
51599
53016
|
if (typeof value === "function") return false;
|
|
51600
53017
|
const record = value;
|
|
51601
53018
|
return "type" in record && typeof record.type === "string" && getComponentForPattern$1(record.type) !== null;
|
|
51602
53019
|
}
|
|
51603
53020
|
function isPlainConfigObject(value) {
|
|
51604
|
-
if (
|
|
53021
|
+
if (React85__default.isValidElement(value)) return false;
|
|
51605
53022
|
if (value instanceof Date) return false;
|
|
51606
53023
|
const proto = Object.getPrototypeOf(value);
|
|
51607
53024
|
return proto === Object.prototype || proto === null;
|
|
@@ -51722,6 +53139,22 @@ function SlotContentRenderer({
|
|
|
51722
53139
|
const childrenIsRenderFn = typeof incomingChildren === "function";
|
|
51723
53140
|
const { children: _childrenConfig, ...restPropsNoChildren } = content.props;
|
|
51724
53141
|
const restProps = childrenIsRenderFn ? { ...restPropsNoChildren, children: incomingChildren } : restPropsNoChildren;
|
|
53142
|
+
const nodeSlotOverrides = {};
|
|
53143
|
+
for (const slotKey of CONTENT_NODE_SLOTS) {
|
|
53144
|
+
const slotVal = restProps[slotKey];
|
|
53145
|
+
if (slotVal === void 0 || slotVal === null) continue;
|
|
53146
|
+
if (React85__default.isValidElement(slotVal) || typeof slotVal === "string" || typeof slotVal === "number" || typeof slotVal === "boolean") continue;
|
|
53147
|
+
if (Array.isArray(slotVal) || typeof slotVal === "object" && "type" in slotVal) {
|
|
53148
|
+
nodeSlotOverrides[slotKey] = renderPatternChildren(
|
|
53149
|
+
slotVal,
|
|
53150
|
+
onDismiss,
|
|
53151
|
+
`${content.id}-${slotKey}`,
|
|
53152
|
+
`${myPath}.${slotKey}`,
|
|
53153
|
+
content.sourceTrait,
|
|
53154
|
+
{ slot: content.slot, transitionEvent: content.transitionEvent, fromState: content.fromState, entity: content.entity }
|
|
53155
|
+
);
|
|
53156
|
+
}
|
|
53157
|
+
}
|
|
51725
53158
|
const renderedProps = renderPatternProps(restProps, onDismiss);
|
|
51726
53159
|
const patternDef = getPatternDefinition(content.pattern);
|
|
51727
53160
|
const propsSchema = patternDef?.propsSchema;
|
|
@@ -51752,6 +53185,9 @@ function SlotContentRenderer({
|
|
|
51752
53185
|
}
|
|
51753
53186
|
}
|
|
51754
53187
|
const finalProps = renderedProps;
|
|
53188
|
+
for (const [k, v] of Object.entries(nodeSlotOverrides)) {
|
|
53189
|
+
finalProps[k] = v;
|
|
53190
|
+
}
|
|
51755
53191
|
const resolvedItems = Array.isArray(
|
|
51756
53192
|
finalProps.entity
|
|
51757
53193
|
) ? finalProps.entity : null;
|
|
@@ -51872,7 +53308,7 @@ function UISlotRenderer({
|
|
|
51872
53308
|
}
|
|
51873
53309
|
return wrapped;
|
|
51874
53310
|
}
|
|
51875
|
-
var scopeWrapLog, TRAIT_BINDING_RE, SuspenseConfigContext, SlotContainedContext, SLOT_SKELETON_MAP, FORM_PATTERNS, SELF_OVERLAY_PATTERNS, PATTERNS_WITH_CHILDREN;
|
|
53311
|
+
var scopeWrapLog, TRAIT_BINDING_RE, SuspenseConfigContext, SlotContainedContext, SLOT_SKELETON_MAP, FORM_PATTERNS, SELF_OVERLAY_PATTERNS, CONTENT_NODE_SLOTS, PATTERNS_WITH_CHILDREN;
|
|
51876
53312
|
var init_UISlotRenderer = __esm({
|
|
51877
53313
|
"components/core/organisms/UISlotRenderer.tsx"() {
|
|
51878
53314
|
"use client";
|
|
@@ -51909,6 +53345,16 @@ var init_UISlotRenderer = __esm({
|
|
|
51909
53345
|
"wizard-step"
|
|
51910
53346
|
]);
|
|
51911
53347
|
SELF_OVERLAY_PATTERNS = /* @__PURE__ */ new Set(["modal", "confirm-dialog"]);
|
|
53348
|
+
CONTENT_NODE_SLOTS = /* @__PURE__ */ new Set([
|
|
53349
|
+
"logo",
|
|
53350
|
+
"master",
|
|
53351
|
+
"detail",
|
|
53352
|
+
"trigger",
|
|
53353
|
+
"content",
|
|
53354
|
+
"addons",
|
|
53355
|
+
"hud",
|
|
53356
|
+
"fallback"
|
|
53357
|
+
]);
|
|
51912
53358
|
PATTERNS_WITH_CHILDREN = /* @__PURE__ */ new Set([
|
|
51913
53359
|
"stack",
|
|
51914
53360
|
"vstack",
|