@almadar/ui 5.86.0 → 5.89.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 +3435 -1250
- package/dist/avl/index.js +2485 -300
- package/dist/components/game/2d/molecules/StateGraph.d.ts +38 -0
- package/dist/components/game/2d/molecules/index.d.ts +24 -15
- package/dist/components/game/2d/organisms/BuilderBoard.d.ts +60 -0
- package/dist/components/game/2d/organisms/ClassifierBoard.d.ts +66 -0
- package/dist/components/game/2d/organisms/DebuggerBoard.d.ts +61 -0
- package/dist/components/game/2d/organisms/EventHandlerBoard.d.ts +42 -0
- package/dist/components/game/2d/organisms/NegotiatorBoard.d.ts +56 -0
- package/dist/components/game/2d/{molecules → organisms}/SequenceBar.d.ts +3 -8
- package/dist/components/game/2d/organisms/SequencerBoard.d.ts +69 -0
- package/dist/components/game/2d/organisms/SimulatorBoard.d.ts +58 -0
- package/dist/components/game/2d/organisms/StateArchitectBoard.d.ts +61 -0
- package/dist/components/game/shared/lib/puzzleObject.d.ts +1 -1
- package/dist/components/index.cjs +3168 -1351
- package/dist/components/index.js +2199 -391
- package/dist/providers/index.cjs +3295 -1110
- package/dist/providers/index.js +2454 -269
- package/dist/runtime/index.cjs +3291 -1106
- package/dist/runtime/index.js +2460 -275
- package/package.json +1 -1
- /package/dist/components/game/2d/{molecules → organisms}/ActionPalette.d.ts +0 -0
- /package/dist/components/game/2d/{molecules → organisms}/ActionTile.d.ts +0 -0
- /package/dist/components/game/2d/{molecules → organisms}/EventLog.d.ts +0 -0
- /package/dist/components/game/2d/{molecules → organisms}/ObjectRulePanel.d.ts +0 -0
- /package/dist/components/game/2d/{molecules → organisms}/RuleEditor.d.ts +0 -0
- /package/dist/components/game/2d/{molecules → organisms}/SimulationCanvas.d.ts +0 -0
- /package/dist/components/game/2d/{molecules → organisms}/SimulationControls.d.ts +0 -0
- /package/dist/components/game/2d/{molecules → organisms}/SimulationGraph.d.ts +0 -0
- /package/dist/components/game/2d/{molecules → organisms}/StateJsonView.d.ts +0 -0
- /package/dist/components/game/2d/{molecules → organisms}/StateNode.d.ts +0 -0
- /package/dist/components/game/2d/{molecules → organisms}/TraitSlot.d.ts +0 -0
- /package/dist/components/game/2d/{molecules → organisms}/TraitStateViewer.d.ts +0 -0
- /package/dist/components/game/2d/{molecules → organisms}/TransitionArrow.d.ts +0 -0
- /package/dist/components/game/2d/{molecules → organisms}/VariablePanel.d.ts +0 -0
package/dist/providers/index.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import * as
|
|
2
|
-
import
|
|
1
|
+
import * as React98 from 'react';
|
|
2
|
+
import React98__default, { createContext, useContext, useMemo, useRef, useEffect, useCallback, Suspense, useState, useLayoutEffect, lazy, useId, useSyncExternalStore } from 'react';
|
|
3
3
|
import { EventBusContext, useTraitScope, useEntitySchemaOptional, TraitScopeProvider, useCurrentPagePath } from '@almadar/ui/providers';
|
|
4
4
|
import { createLogger, isLogLevelEnabled } from '@almadar/logger';
|
|
5
5
|
import { clsx } from 'clsx';
|
|
6
6
|
import { twMerge } from 'tailwind-merge';
|
|
7
7
|
import * as LucideIcons2 from 'lucide-react';
|
|
8
|
-
import { Loader2, X, Lightbulb, CheckCircle, List, Printer, ChevronRight, ChevronLeft, GitBranch, Pencil, Eye, Plus, ArrowRight, Trash, Code, FileText, WrapText, Check, Copy, RotateCcw, Play, Terminal, XCircle, AlertTriangle, Trash2, Link2, ZoomOut, ZoomIn, Download, ChevronDown, Menu as Menu$1, Package, Calendar, MoreHorizontal, Image as Image$1, Upload, ArrowLeft, HelpCircle, PauseCircle, Search, Type, Heading1, Heading2, Heading3, ListOrdered, Quote, Minus, Eraser, TrendingUp, TrendingDown, AlertCircle, Circle, Clock, CheckCircle2, ChevronUp, Tag, User, DollarSign } from 'lucide-react';
|
|
8
|
+
import { Loader2, X, Lightbulb, CheckCircle, List, Printer, ChevronRight, ChevronLeft, GitBranch, Pencil, Eye, Plus, ArrowRight, Trash, Code, FileText, WrapText, Check, Copy, RotateCcw, Play, Terminal, XCircle, AlertTriangle, Trash2, Link2, ZoomOut, ZoomIn, Download, ChevronDown, Menu as Menu$1, Package, Calendar, MoreHorizontal, Image as Image$1, Upload, ArrowLeft, HelpCircle, PauseCircle, Search, Type, Heading1, Heading2, Heading3, ListOrdered, Quote, Minus, Eraser, TrendingUp, TrendingDown, AlertCircle, Circle, Clock, CheckCircle2, Bug, Send, ChevronUp, Wrench, Tag, User, DollarSign } from 'lucide-react';
|
|
9
9
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
10
10
|
import { createPortal } from 'react-dom';
|
|
11
11
|
import { useTranslate } from '@almadar/ui/hooks';
|
|
@@ -388,7 +388,7 @@ var init_Box = __esm({
|
|
|
388
388
|
fixed: "fixed",
|
|
389
389
|
sticky: "sticky"
|
|
390
390
|
};
|
|
391
|
-
Box =
|
|
391
|
+
Box = React98__default.forwardRef(
|
|
392
392
|
({
|
|
393
393
|
padding,
|
|
394
394
|
paddingX,
|
|
@@ -453,7 +453,7 @@ var init_Box = __esm({
|
|
|
453
453
|
onPointerDown?.(e);
|
|
454
454
|
}, [hoverEvent, tapReveal, triggerProps, onPointerDown]);
|
|
455
455
|
const isClickable = action || onClick;
|
|
456
|
-
return
|
|
456
|
+
return React98__default.createElement(
|
|
457
457
|
Component,
|
|
458
458
|
{
|
|
459
459
|
ref,
|
|
@@ -549,7 +549,7 @@ function loadLib(key, importer) {
|
|
|
549
549
|
return p;
|
|
550
550
|
}
|
|
551
551
|
function lazyFamilyIcon(libKey, importer, pick, fallbackName, family) {
|
|
552
|
-
const Lazy =
|
|
552
|
+
const Lazy = React98__default.lazy(async () => {
|
|
553
553
|
const lib = await loadLib(libKey, importer);
|
|
554
554
|
const Comp = pick(lib);
|
|
555
555
|
if (!Comp) {
|
|
@@ -559,7 +559,7 @@ function lazyFamilyIcon(libKey, importer, pick, fallbackName, family) {
|
|
|
559
559
|
return { default: Comp };
|
|
560
560
|
});
|
|
561
561
|
const Wrapped = (props) => /* @__PURE__ */ jsx(
|
|
562
|
-
|
|
562
|
+
React98__default.Suspense,
|
|
563
563
|
{
|
|
564
564
|
fallback: /* @__PURE__ */ jsx(
|
|
565
565
|
"span",
|
|
@@ -1290,7 +1290,7 @@ var init_Icon = __esm({
|
|
|
1290
1290
|
const directIcon = typeof icon === "string" ? void 0 : icon;
|
|
1291
1291
|
const effectiveName = typeof icon === "string" ? icon : name;
|
|
1292
1292
|
const family = useIconFamily();
|
|
1293
|
-
const RenderedComponent =
|
|
1293
|
+
const RenderedComponent = React98__default.useMemo(() => {
|
|
1294
1294
|
if (directIcon) return null;
|
|
1295
1295
|
return effectiveName ? resolveIconForFamily(effectiveName, family) : null;
|
|
1296
1296
|
}, [directIcon, effectiveName, family]);
|
|
@@ -1352,7 +1352,7 @@ function resolveIconProp(value, sizeClass) {
|
|
|
1352
1352
|
const IconComp = value;
|
|
1353
1353
|
return /* @__PURE__ */ jsx(IconComp, { className: sizeClass });
|
|
1354
1354
|
}
|
|
1355
|
-
if (
|
|
1355
|
+
if (React98__default.isValidElement(value)) {
|
|
1356
1356
|
return value;
|
|
1357
1357
|
}
|
|
1358
1358
|
if (typeof value === "object" && value !== null && isIconLike(value)) {
|
|
@@ -1428,7 +1428,7 @@ var init_Button = __esm({
|
|
|
1428
1428
|
md: "h-icon-default w-icon-default",
|
|
1429
1429
|
lg: "h-icon-default w-icon-default"
|
|
1430
1430
|
};
|
|
1431
|
-
Button =
|
|
1431
|
+
Button = React98__default.forwardRef(
|
|
1432
1432
|
({
|
|
1433
1433
|
className,
|
|
1434
1434
|
variant = "primary",
|
|
@@ -1496,7 +1496,7 @@ var Dialog;
|
|
|
1496
1496
|
var init_Dialog = __esm({
|
|
1497
1497
|
"components/core/atoms/Dialog.tsx"() {
|
|
1498
1498
|
init_cn();
|
|
1499
|
-
Dialog =
|
|
1499
|
+
Dialog = React98__default.forwardRef(
|
|
1500
1500
|
({
|
|
1501
1501
|
role = "dialog",
|
|
1502
1502
|
"aria-modal": ariaModal = true,
|
|
@@ -1614,7 +1614,7 @@ var init_Typography = __esm({
|
|
|
1614
1614
|
}) => {
|
|
1615
1615
|
const variant = variantProp ?? (level ? `h${level}` : "body1");
|
|
1616
1616
|
const Component = as || defaultElements[variant];
|
|
1617
|
-
return
|
|
1617
|
+
return React98__default.createElement(
|
|
1618
1618
|
Component,
|
|
1619
1619
|
{
|
|
1620
1620
|
id,
|
|
@@ -2109,7 +2109,7 @@ var init_Badge = __esm({
|
|
|
2109
2109
|
md: "px-2.5 py-1 text-sm",
|
|
2110
2110
|
lg: "px-3 py-1.5 text-base"
|
|
2111
2111
|
};
|
|
2112
|
-
Badge =
|
|
2112
|
+
Badge = React98__default.forwardRef(
|
|
2113
2113
|
({ className, variant = "default", size = "sm", amount, label, icon, iconAsset, children, onRemove, removeLabel, ...props }, ref) => {
|
|
2114
2114
|
const iconSizes3 = {
|
|
2115
2115
|
sm: "h-icon-default w-icon-default",
|
|
@@ -2446,7 +2446,7 @@ var init_SvgFlow = __esm({
|
|
|
2446
2446
|
width = 100,
|
|
2447
2447
|
height = 100
|
|
2448
2448
|
}) => {
|
|
2449
|
-
const markerId =
|
|
2449
|
+
const markerId = React98__default.useMemo(() => {
|
|
2450
2450
|
flowIdCounter += 1;
|
|
2451
2451
|
return `almadar-flow-arrow-${flowIdCounter}`;
|
|
2452
2452
|
}, []);
|
|
@@ -2499,7 +2499,7 @@ var init_SvgGrid = __esm({
|
|
|
2499
2499
|
x = 10,
|
|
2500
2500
|
y = 10,
|
|
2501
2501
|
cols = 4,
|
|
2502
|
-
rows = 3,
|
|
2502
|
+
rows: rows2 = 3,
|
|
2503
2503
|
spacing = 20,
|
|
2504
2504
|
nodeRadius = 3,
|
|
2505
2505
|
color = "var(--color-primary)",
|
|
@@ -2511,7 +2511,7 @@ var init_SvgGrid = __esm({
|
|
|
2511
2511
|
height = 100
|
|
2512
2512
|
}) => {
|
|
2513
2513
|
const highlightSet = new Set(highlights);
|
|
2514
|
-
const inner = /* @__PURE__ */ jsx("g", { className, opacity, children: Array.from({ length:
|
|
2514
|
+
const inner = /* @__PURE__ */ jsx("g", { className, opacity, children: Array.from({ length: rows2 }).map(
|
|
2515
2515
|
(_, row) => Array.from({ length: cols }).map((_2, col) => {
|
|
2516
2516
|
const index = row * cols + col;
|
|
2517
2517
|
const isHighlighted = highlightSet.has(index);
|
|
@@ -3039,7 +3039,7 @@ var init_SvgRing = __esm({
|
|
|
3039
3039
|
width = 100,
|
|
3040
3040
|
height = 100
|
|
3041
3041
|
}) => {
|
|
3042
|
-
const gradientId =
|
|
3042
|
+
const gradientId = React98__default.useMemo(() => {
|
|
3043
3043
|
ringIdCounter += 1;
|
|
3044
3044
|
return `almadar-ring-glow-${ringIdCounter}`;
|
|
3045
3045
|
}, []);
|
|
@@ -3220,7 +3220,7 @@ var init_Input = __esm({
|
|
|
3220
3220
|
init_cn();
|
|
3221
3221
|
init_Icon();
|
|
3222
3222
|
init_useEventBus();
|
|
3223
|
-
Input =
|
|
3223
|
+
Input = React98__default.forwardRef(
|
|
3224
3224
|
({
|
|
3225
3225
|
className,
|
|
3226
3226
|
inputType,
|
|
@@ -3235,7 +3235,7 @@ var init_Input = __esm({
|
|
|
3235
3235
|
onClear,
|
|
3236
3236
|
value,
|
|
3237
3237
|
options,
|
|
3238
|
-
rows = 3,
|
|
3238
|
+
rows: rows2 = 3,
|
|
3239
3239
|
onChange,
|
|
3240
3240
|
...props
|
|
3241
3241
|
}, ref) => {
|
|
@@ -3317,7 +3317,7 @@ var init_Input = __esm({
|
|
|
3317
3317
|
ref,
|
|
3318
3318
|
value,
|
|
3319
3319
|
onChange: handleChange,
|
|
3320
|
-
rows,
|
|
3320
|
+
rows: rows2,
|
|
3321
3321
|
className: baseClassName,
|
|
3322
3322
|
...props
|
|
3323
3323
|
}
|
|
@@ -3380,7 +3380,7 @@ var Label;
|
|
|
3380
3380
|
var init_Label = __esm({
|
|
3381
3381
|
"components/core/atoms/Label.tsx"() {
|
|
3382
3382
|
init_cn();
|
|
3383
|
-
Label =
|
|
3383
|
+
Label = React98__default.forwardRef(
|
|
3384
3384
|
({ className, required, children, ...props }, ref) => {
|
|
3385
3385
|
return /* @__PURE__ */ jsxs(
|
|
3386
3386
|
"label",
|
|
@@ -3407,7 +3407,7 @@ var init_Textarea = __esm({
|
|
|
3407
3407
|
"components/core/atoms/Textarea.tsx"() {
|
|
3408
3408
|
init_cn();
|
|
3409
3409
|
init_useEventBus();
|
|
3410
|
-
Textarea =
|
|
3410
|
+
Textarea = React98__default.forwardRef(
|
|
3411
3411
|
({ className, error, onChange, ...props }, ref) => {
|
|
3412
3412
|
const eventBus = useEventBus();
|
|
3413
3413
|
const handleChange = (e) => {
|
|
@@ -3646,7 +3646,7 @@ var init_Select = __esm({
|
|
|
3646
3646
|
init_cn();
|
|
3647
3647
|
init_Icon();
|
|
3648
3648
|
init_useEventBus();
|
|
3649
|
-
Select =
|
|
3649
|
+
Select = React98__default.forwardRef(
|
|
3650
3650
|
(props, _ref) => {
|
|
3651
3651
|
const { multiple, searchable, clearable } = props;
|
|
3652
3652
|
if (multiple || searchable || clearable) {
|
|
@@ -3663,7 +3663,7 @@ var init_Checkbox = __esm({
|
|
|
3663
3663
|
"components/core/atoms/Checkbox.tsx"() {
|
|
3664
3664
|
init_cn();
|
|
3665
3665
|
init_useEventBus();
|
|
3666
|
-
Checkbox =
|
|
3666
|
+
Checkbox = React98__default.forwardRef(
|
|
3667
3667
|
({ className, label, id, onChange, ...props }, ref) => {
|
|
3668
3668
|
const inputId = id || `checkbox-${Math.random().toString(36).substr(2, 9)}`;
|
|
3669
3669
|
const eventBus = useEventBus();
|
|
@@ -3717,7 +3717,7 @@ var init_Spinner = __esm({
|
|
|
3717
3717
|
md: "h-6 w-6",
|
|
3718
3718
|
lg: "h-8 w-8"
|
|
3719
3719
|
};
|
|
3720
|
-
Spinner =
|
|
3720
|
+
Spinner = React98__default.forwardRef(
|
|
3721
3721
|
({ className, size = "md", overlay, ...props }, ref) => {
|
|
3722
3722
|
if (overlay) {
|
|
3723
3723
|
return /* @__PURE__ */ jsx(
|
|
@@ -3807,7 +3807,7 @@ var init_Card = __esm({
|
|
|
3807
3807
|
chip: "shadow-none rounded-pill border-[length:var(--border-width)] border-border",
|
|
3808
3808
|
"tile-image-first": "p-0 overflow-hidden"
|
|
3809
3809
|
};
|
|
3810
|
-
Card =
|
|
3810
|
+
Card = React98__default.forwardRef(
|
|
3811
3811
|
({
|
|
3812
3812
|
className,
|
|
3813
3813
|
variant = "bordered",
|
|
@@ -3855,9 +3855,9 @@ var init_Card = __esm({
|
|
|
3855
3855
|
}
|
|
3856
3856
|
);
|
|
3857
3857
|
Card.displayName = "Card";
|
|
3858
|
-
CardHeader =
|
|
3858
|
+
CardHeader = React98__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("mb-4", className), ...props }));
|
|
3859
3859
|
CardHeader.displayName = "CardHeader";
|
|
3860
|
-
CardTitle =
|
|
3860
|
+
CardTitle = React98__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
3861
3861
|
"h3",
|
|
3862
3862
|
{
|
|
3863
3863
|
ref,
|
|
@@ -3870,11 +3870,11 @@ var init_Card = __esm({
|
|
|
3870
3870
|
}
|
|
3871
3871
|
));
|
|
3872
3872
|
CardTitle.displayName = "CardTitle";
|
|
3873
|
-
CardContent =
|
|
3873
|
+
CardContent = React98__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("", className), ...props }));
|
|
3874
3874
|
CardContent.displayName = "CardContent";
|
|
3875
3875
|
CardBody = CardContent;
|
|
3876
3876
|
CardBody.displayName = "CardBody";
|
|
3877
|
-
CardFooter =
|
|
3877
|
+
CardFooter = React98__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
3878
3878
|
"div",
|
|
3879
3879
|
{
|
|
3880
3880
|
ref,
|
|
@@ -3929,7 +3929,7 @@ var init_FilterPill = __esm({
|
|
|
3929
3929
|
md: "w-3.5 h-3.5",
|
|
3930
3930
|
lg: "w-4 h-4"
|
|
3931
3931
|
};
|
|
3932
|
-
FilterPill =
|
|
3932
|
+
FilterPill = React98__default.forwardRef(
|
|
3933
3933
|
({
|
|
3934
3934
|
className,
|
|
3935
3935
|
variant = "default",
|
|
@@ -4058,8 +4058,8 @@ var init_Avatar = __esm({
|
|
|
4058
4058
|
actionPayload
|
|
4059
4059
|
}) => {
|
|
4060
4060
|
const eventBus = useEventBus();
|
|
4061
|
-
const [imgFailed, setImgFailed] =
|
|
4062
|
-
|
|
4061
|
+
const [imgFailed, setImgFailed] = React98__default.useState(false);
|
|
4062
|
+
React98__default.useEffect(() => {
|
|
4063
4063
|
setImgFailed(false);
|
|
4064
4064
|
}, [src]);
|
|
4065
4065
|
const initials = providedInitials ?? (name ? generateInitials(name) : void 0);
|
|
@@ -4172,7 +4172,7 @@ var init_Center = __esm({
|
|
|
4172
4172
|
as: Component = "div"
|
|
4173
4173
|
}) => {
|
|
4174
4174
|
const mergedStyle = minHeight ? { minHeight, ...style } : style;
|
|
4175
|
-
return
|
|
4175
|
+
return React98__default.createElement(Component, {
|
|
4176
4176
|
className: cn(
|
|
4177
4177
|
inline ? "inline-flex" : "flex",
|
|
4178
4178
|
horizontal && "justify-center",
|
|
@@ -4440,7 +4440,7 @@ var init_Radio = __esm({
|
|
|
4440
4440
|
md: "w-2.5 h-2.5",
|
|
4441
4441
|
lg: "w-3 h-3"
|
|
4442
4442
|
};
|
|
4443
|
-
Radio =
|
|
4443
|
+
Radio = React98__default.forwardRef(
|
|
4444
4444
|
({
|
|
4445
4445
|
label,
|
|
4446
4446
|
helperText,
|
|
@@ -4457,12 +4457,12 @@ var init_Radio = __esm({
|
|
|
4457
4457
|
onChange,
|
|
4458
4458
|
...props
|
|
4459
4459
|
}, ref) => {
|
|
4460
|
-
const reactId =
|
|
4460
|
+
const reactId = React98__default.useId();
|
|
4461
4461
|
const baseId = id || `radio-${reactId}`;
|
|
4462
4462
|
const hasError = !!error;
|
|
4463
4463
|
const eventBus = useEventBus();
|
|
4464
|
-
const [selected, setSelected] =
|
|
4465
|
-
|
|
4464
|
+
const [selected, setSelected] = React98__default.useState(value);
|
|
4465
|
+
React98__default.useEffect(() => {
|
|
4466
4466
|
if (value !== void 0) setSelected(value);
|
|
4467
4467
|
}, [value]);
|
|
4468
4468
|
const pick = (next, e) => {
|
|
@@ -4644,7 +4644,7 @@ var init_Switch = __esm({
|
|
|
4644
4644
|
"components/core/atoms/Switch.tsx"() {
|
|
4645
4645
|
"use client";
|
|
4646
4646
|
init_cn();
|
|
4647
|
-
Switch =
|
|
4647
|
+
Switch = React98.forwardRef(
|
|
4648
4648
|
({
|
|
4649
4649
|
checked,
|
|
4650
4650
|
defaultChecked = false,
|
|
@@ -4655,10 +4655,10 @@ var init_Switch = __esm({
|
|
|
4655
4655
|
name,
|
|
4656
4656
|
className
|
|
4657
4657
|
}, ref) => {
|
|
4658
|
-
const [isChecked, setIsChecked] =
|
|
4658
|
+
const [isChecked, setIsChecked] = React98.useState(
|
|
4659
4659
|
checked !== void 0 ? checked : defaultChecked
|
|
4660
4660
|
);
|
|
4661
|
-
|
|
4661
|
+
React98.useEffect(() => {
|
|
4662
4662
|
if (checked !== void 0) {
|
|
4663
4663
|
setIsChecked(checked);
|
|
4664
4664
|
}
|
|
@@ -4821,7 +4821,7 @@ var init_Stack = __esm({
|
|
|
4821
4821
|
};
|
|
4822
4822
|
const isHorizontal = direction === "horizontal";
|
|
4823
4823
|
const directionClass = responsive && isHorizontal ? reverse ? "flex-col-reverse md:flex-row-reverse" : "flex-col md:flex-row" : isHorizontal ? reverse ? "flex-row-reverse" : "flex-row" : reverse ? "flex-col-reverse" : "flex-col";
|
|
4824
|
-
return
|
|
4824
|
+
return React98__default.createElement(
|
|
4825
4825
|
Component,
|
|
4826
4826
|
{
|
|
4827
4827
|
className: cn(
|
|
@@ -5021,7 +5021,7 @@ var Aside;
|
|
|
5021
5021
|
var init_Aside = __esm({
|
|
5022
5022
|
"components/core/atoms/Aside.tsx"() {
|
|
5023
5023
|
init_cn();
|
|
5024
|
-
Aside =
|
|
5024
|
+
Aside = React98__default.forwardRef(
|
|
5025
5025
|
({ className, children, ...rest }, ref) => /* @__PURE__ */ jsx("aside", { ref, className: cn(className), ...rest, children })
|
|
5026
5026
|
);
|
|
5027
5027
|
Aside.displayName = "Aside";
|
|
@@ -5100,9 +5100,9 @@ var init_LawReferenceTooltip = __esm({
|
|
|
5100
5100
|
className
|
|
5101
5101
|
}) => {
|
|
5102
5102
|
const { t } = useTranslate();
|
|
5103
|
-
const [isVisible, setIsVisible] =
|
|
5104
|
-
const timeoutRef =
|
|
5105
|
-
const triggerRef =
|
|
5103
|
+
const [isVisible, setIsVisible] = React98__default.useState(false);
|
|
5104
|
+
const timeoutRef = React98__default.useRef(null);
|
|
5105
|
+
const triggerRef = React98__default.useRef(null);
|
|
5106
5106
|
const handleMouseEnter = () => {
|
|
5107
5107
|
if (timeoutRef.current) clearTimeout(timeoutRef.current);
|
|
5108
5108
|
timeoutRef.current = setTimeout(() => setIsVisible(true), 200);
|
|
@@ -5113,7 +5113,7 @@ var init_LawReferenceTooltip = __esm({
|
|
|
5113
5113
|
};
|
|
5114
5114
|
const { revealed, triggerProps } = useTapReveal({ refs: [triggerRef] });
|
|
5115
5115
|
const open = isVisible || revealed;
|
|
5116
|
-
|
|
5116
|
+
React98__default.useEffect(() => {
|
|
5117
5117
|
return () => {
|
|
5118
5118
|
if (timeoutRef.current) clearTimeout(timeoutRef.current);
|
|
5119
5119
|
};
|
|
@@ -5323,7 +5323,7 @@ var init_StatusDot = __esm({
|
|
|
5323
5323
|
md: "w-2.5 h-2.5",
|
|
5324
5324
|
lg: "w-3 h-3"
|
|
5325
5325
|
};
|
|
5326
|
-
StatusDot =
|
|
5326
|
+
StatusDot = React98__default.forwardRef(
|
|
5327
5327
|
({ className, status = "offline", pulse = false, size = "md", label, ...props }, ref) => {
|
|
5328
5328
|
return /* @__PURE__ */ jsx(
|
|
5329
5329
|
"span",
|
|
@@ -5377,7 +5377,7 @@ var init_TrendIndicator = __esm({
|
|
|
5377
5377
|
down: "trending-down",
|
|
5378
5378
|
flat: "arrow-right"
|
|
5379
5379
|
};
|
|
5380
|
-
TrendIndicator =
|
|
5380
|
+
TrendIndicator = React98__default.forwardRef(
|
|
5381
5381
|
({
|
|
5382
5382
|
className,
|
|
5383
5383
|
value,
|
|
@@ -5444,7 +5444,7 @@ var init_RangeSlider = __esm({
|
|
|
5444
5444
|
md: "w-4 h-4",
|
|
5445
5445
|
lg: "w-5 h-5"
|
|
5446
5446
|
};
|
|
5447
|
-
RangeSlider =
|
|
5447
|
+
RangeSlider = React98__default.forwardRef(
|
|
5448
5448
|
({
|
|
5449
5449
|
className,
|
|
5450
5450
|
min = 0,
|
|
@@ -6038,7 +6038,7 @@ var init_ContentSection = __esm({
|
|
|
6038
6038
|
md: "py-16",
|
|
6039
6039
|
lg: "py-24"
|
|
6040
6040
|
};
|
|
6041
|
-
ContentSection =
|
|
6041
|
+
ContentSection = React98__default.forwardRef(
|
|
6042
6042
|
({ children, background = "default", padding = "lg", id, className }, ref) => {
|
|
6043
6043
|
return /* @__PURE__ */ jsx(
|
|
6044
6044
|
Box,
|
|
@@ -6572,7 +6572,7 @@ var init_AnimatedReveal = __esm({
|
|
|
6572
6572
|
"scale-up": { opacity: 1, transform: "scale(1) translateY(0)" },
|
|
6573
6573
|
"none": {}
|
|
6574
6574
|
};
|
|
6575
|
-
AnimatedReveal =
|
|
6575
|
+
AnimatedReveal = React98__default.forwardRef(
|
|
6576
6576
|
({
|
|
6577
6577
|
trigger = "scroll",
|
|
6578
6578
|
animation = "fade-up",
|
|
@@ -6732,7 +6732,7 @@ var init_AnimatedGraphic = __esm({
|
|
|
6732
6732
|
"components/marketing/atoms/AnimatedGraphic.tsx"() {
|
|
6733
6733
|
"use client";
|
|
6734
6734
|
init_cn();
|
|
6735
|
-
AnimatedGraphic =
|
|
6735
|
+
AnimatedGraphic = React98__default.forwardRef(
|
|
6736
6736
|
({
|
|
6737
6737
|
src,
|
|
6738
6738
|
svgContent,
|
|
@@ -6755,7 +6755,7 @@ var init_AnimatedGraphic = __esm({
|
|
|
6755
6755
|
const fetchedSvg = useFetchedSvg(svgContent ? void 0 : src);
|
|
6756
6756
|
const resolvedSvg = svgContent ?? fetchedSvg;
|
|
6757
6757
|
const prevAnimateRef = useRef(animate);
|
|
6758
|
-
const setRef =
|
|
6758
|
+
const setRef = React98__default.useCallback(
|
|
6759
6759
|
(node) => {
|
|
6760
6760
|
containerRef.current = node;
|
|
6761
6761
|
if (typeof ref === "function") ref(node);
|
|
@@ -6903,6 +6903,20 @@ var init_effects = __esm({
|
|
|
6903
6903
|
});
|
|
6904
6904
|
|
|
6905
6905
|
// components/game/shared/boardEntity.ts
|
|
6906
|
+
function boardEntity(entity) {
|
|
6907
|
+
if (!entity) return void 0;
|
|
6908
|
+
return Array.isArray(entity) ? entity[0] : entity;
|
|
6909
|
+
}
|
|
6910
|
+
function str(v) {
|
|
6911
|
+
return v == null ? "" : String(v);
|
|
6912
|
+
}
|
|
6913
|
+
function num(v, fallback = 0) {
|
|
6914
|
+
const n = Number(v);
|
|
6915
|
+
return Number.isFinite(n) ? n : fallback;
|
|
6916
|
+
}
|
|
6917
|
+
function rows(v) {
|
|
6918
|
+
return Array.isArray(v) ? v : [];
|
|
6919
|
+
}
|
|
6906
6920
|
var init_boardEntity = __esm({
|
|
6907
6921
|
"components/game/shared/boardEntity.ts"() {
|
|
6908
6922
|
}
|
|
@@ -7336,7 +7350,7 @@ function GameCard({
|
|
|
7336
7350
|
className
|
|
7337
7351
|
}) {
|
|
7338
7352
|
const eventBus = useEventBus();
|
|
7339
|
-
const handleClick =
|
|
7353
|
+
const handleClick = React98.useCallback(() => {
|
|
7340
7354
|
if (disabled) return;
|
|
7341
7355
|
onClick?.(id);
|
|
7342
7356
|
if (clickEvent) eventBus.emit(`UI:${clickEvent}`, { cardId: id });
|
|
@@ -7618,9 +7632,9 @@ function ControlButton({
|
|
|
7618
7632
|
className
|
|
7619
7633
|
}) {
|
|
7620
7634
|
const eventBus = useEventBus();
|
|
7621
|
-
const [isPressed, setIsPressed] =
|
|
7635
|
+
const [isPressed, setIsPressed] = React98.useState(false);
|
|
7622
7636
|
const actualPressed = pressed ?? isPressed;
|
|
7623
|
-
const handlePointerDown =
|
|
7637
|
+
const handlePointerDown = React98.useCallback(
|
|
7624
7638
|
(e) => {
|
|
7625
7639
|
e.preventDefault();
|
|
7626
7640
|
if (disabled) return;
|
|
@@ -7630,7 +7644,7 @@ function ControlButton({
|
|
|
7630
7644
|
},
|
|
7631
7645
|
[disabled, pressEvent, eventBus, onPress]
|
|
7632
7646
|
);
|
|
7633
|
-
const handlePointerUp =
|
|
7647
|
+
const handlePointerUp = React98.useCallback(
|
|
7634
7648
|
(e) => {
|
|
7635
7649
|
e.preventDefault();
|
|
7636
7650
|
if (disabled) return;
|
|
@@ -7640,7 +7654,7 @@ function ControlButton({
|
|
|
7640
7654
|
},
|
|
7641
7655
|
[disabled, releaseEvent, eventBus, onRelease]
|
|
7642
7656
|
);
|
|
7643
|
-
const handlePointerLeave =
|
|
7657
|
+
const handlePointerLeave = React98.useCallback(
|
|
7644
7658
|
(e) => {
|
|
7645
7659
|
if (isPressed) {
|
|
7646
7660
|
setIsPressed(false);
|
|
@@ -8659,8 +8673,8 @@ function MiniMap({
|
|
|
8659
8673
|
tileAssets,
|
|
8660
8674
|
unitAssets
|
|
8661
8675
|
}) {
|
|
8662
|
-
const canvasRef =
|
|
8663
|
-
const imgCacheRef =
|
|
8676
|
+
const canvasRef = React98.useRef(null);
|
|
8677
|
+
const imgCacheRef = React98.useRef(/* @__PURE__ */ new Map());
|
|
8664
8678
|
function loadImg(url) {
|
|
8665
8679
|
const cached = imgCacheRef.current.get(url);
|
|
8666
8680
|
if (cached) return cached.complete ? cached : null;
|
|
@@ -8675,7 +8689,7 @@ function MiniMap({
|
|
|
8675
8689
|
imgCacheRef.current.set(url, img);
|
|
8676
8690
|
return null;
|
|
8677
8691
|
}
|
|
8678
|
-
|
|
8692
|
+
React98.useEffect(() => {
|
|
8679
8693
|
const canvas = canvasRef.current;
|
|
8680
8694
|
if (!canvas) return;
|
|
8681
8695
|
const ctx = canvas.getContext("2d");
|
|
@@ -8810,8 +8824,8 @@ function ControlGrid({
|
|
|
8810
8824
|
className
|
|
8811
8825
|
}) {
|
|
8812
8826
|
const eventBus = useEventBus();
|
|
8813
|
-
const [active, setActive] =
|
|
8814
|
-
const handlePress =
|
|
8827
|
+
const [active, setActive] = React98.useState(/* @__PURE__ */ new Set());
|
|
8828
|
+
const handlePress = React98.useCallback(
|
|
8815
8829
|
(id) => {
|
|
8816
8830
|
setActive((prev) => new Set(prev).add(id));
|
|
8817
8831
|
if (actionEvent) eventBus.emit(`UI:${actionEvent}`, { id, pressed: true });
|
|
@@ -8825,7 +8839,7 @@ function ControlGrid({
|
|
|
8825
8839
|
},
|
|
8826
8840
|
[kind, actionEvent, directionEvent, directionEvents, eventBus, onAction, onDirection]
|
|
8827
8841
|
);
|
|
8828
|
-
const handleRelease =
|
|
8842
|
+
const handleRelease = React98.useCallback(
|
|
8829
8843
|
(id) => {
|
|
8830
8844
|
setActive((prev) => {
|
|
8831
8845
|
const next = new Set(prev);
|
|
@@ -9083,7 +9097,7 @@ function InventoryGrid({
|
|
|
9083
9097
|
const eventBus = useEventBus();
|
|
9084
9098
|
const slotCount = totalSlots ?? items.length;
|
|
9085
9099
|
const emptySlotCount = Math.max(0, slotCount - items.length);
|
|
9086
|
-
const handleSelect =
|
|
9100
|
+
const handleSelect = React98.useCallback(
|
|
9087
9101
|
(id) => {
|
|
9088
9102
|
onSelect?.(id);
|
|
9089
9103
|
if (selectEvent) {
|
|
@@ -9300,7 +9314,7 @@ function GameMenu({
|
|
|
9300
9314
|
}) {
|
|
9301
9315
|
const resolvedOptions = options ?? menuItems ?? DEFAULT_MENU_OPTIONS;
|
|
9302
9316
|
const eventBus = useEventBus();
|
|
9303
|
-
const handleOptionClick =
|
|
9317
|
+
const handleOptionClick = React98.useCallback(
|
|
9304
9318
|
(option) => {
|
|
9305
9319
|
if (option.event) {
|
|
9306
9320
|
eventBus.emit(`UI:${option.event}`, { option });
|
|
@@ -9377,6 +9391,214 @@ var init_GameMenu = __esm({
|
|
|
9377
9391
|
GameMenu.displayName = "GameMenu";
|
|
9378
9392
|
}
|
|
9379
9393
|
});
|
|
9394
|
+
function StateNode({
|
|
9395
|
+
name,
|
|
9396
|
+
isCurrent = false,
|
|
9397
|
+
isSelected = false,
|
|
9398
|
+
isInitial = false,
|
|
9399
|
+
position,
|
|
9400
|
+
onClick,
|
|
9401
|
+
className
|
|
9402
|
+
}) {
|
|
9403
|
+
return /* @__PURE__ */ jsx(
|
|
9404
|
+
Box,
|
|
9405
|
+
{
|
|
9406
|
+
position: "absolute",
|
|
9407
|
+
display: "flex",
|
|
9408
|
+
className: cn(
|
|
9409
|
+
"items-center justify-center rounded-pill border-3 transition-all cursor-pointer select-none",
|
|
9410
|
+
"min-w-[80px] h-[80px] px-3",
|
|
9411
|
+
isCurrent && "bg-primary/20 border-primary shadow-lg shadow-primary/30 scale-110",
|
|
9412
|
+
isSelected && !isCurrent && "bg-accent/20 border-accent ring-2 ring-accent/50",
|
|
9413
|
+
!isCurrent && !isSelected && "bg-card border-border hover:border-muted-foreground hover:scale-105",
|
|
9414
|
+
className
|
|
9415
|
+
),
|
|
9416
|
+
style: {
|
|
9417
|
+
left: position.x,
|
|
9418
|
+
top: position.y,
|
|
9419
|
+
transform: "translate(-50%, -50%)"
|
|
9420
|
+
},
|
|
9421
|
+
onClick,
|
|
9422
|
+
children: /* @__PURE__ */ jsxs(Box, { className: "text-center", children: [
|
|
9423
|
+
isInitial && /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-muted-foreground text-xs block", children: "\u25B6 start" }),
|
|
9424
|
+
/* @__PURE__ */ jsx(
|
|
9425
|
+
Typography,
|
|
9426
|
+
{
|
|
9427
|
+
variant: "body2",
|
|
9428
|
+
className: cn(
|
|
9429
|
+
"font-bold whitespace-nowrap",
|
|
9430
|
+
isCurrent ? "text-primary" : "text-foreground"
|
|
9431
|
+
),
|
|
9432
|
+
children: name
|
|
9433
|
+
}
|
|
9434
|
+
)
|
|
9435
|
+
] })
|
|
9436
|
+
}
|
|
9437
|
+
);
|
|
9438
|
+
}
|
|
9439
|
+
var init_StateNode = __esm({
|
|
9440
|
+
"components/game/2d/organisms/StateNode.tsx"() {
|
|
9441
|
+
init_atoms();
|
|
9442
|
+
init_cn();
|
|
9443
|
+
StateNode.displayName = "StateNode";
|
|
9444
|
+
}
|
|
9445
|
+
});
|
|
9446
|
+
function TransitionArrow({
|
|
9447
|
+
from,
|
|
9448
|
+
to,
|
|
9449
|
+
eventLabel,
|
|
9450
|
+
guardHint,
|
|
9451
|
+
isActive = false,
|
|
9452
|
+
onClick,
|
|
9453
|
+
className
|
|
9454
|
+
}) {
|
|
9455
|
+
const dx = to.x - from.x;
|
|
9456
|
+
const dy = to.y - from.y;
|
|
9457
|
+
const dist = Math.sqrt(dx * dx + dy * dy);
|
|
9458
|
+
if (dist === 0) return /* @__PURE__ */ jsx(Fragment, {});
|
|
9459
|
+
const nx = dx / dist;
|
|
9460
|
+
const ny = dy / dist;
|
|
9461
|
+
const startX = from.x + nx * NODE_RADIUS;
|
|
9462
|
+
const startY = from.y + ny * NODE_RADIUS;
|
|
9463
|
+
const endX = to.x - nx * NODE_RADIUS;
|
|
9464
|
+
const endY = to.y - ny * NODE_RADIUS;
|
|
9465
|
+
const midX = (startX + endX) / 2;
|
|
9466
|
+
const midY = (startY + endY) / 2;
|
|
9467
|
+
const perpX = -ny * 20;
|
|
9468
|
+
const perpY = nx * 20;
|
|
9469
|
+
const ctrlX = midX + perpX;
|
|
9470
|
+
const ctrlY = midY + perpY;
|
|
9471
|
+
const path = `M ${startX} ${startY} Q ${ctrlX} ${ctrlY} ${endX} ${endY}`;
|
|
9472
|
+
return /* @__PURE__ */ jsxs("g", { className: cn("cursor-pointer", className), onClick, children: [
|
|
9473
|
+
/* @__PURE__ */ jsx(
|
|
9474
|
+
"path",
|
|
9475
|
+
{
|
|
9476
|
+
d: path,
|
|
9477
|
+
fill: "none",
|
|
9478
|
+
stroke: isActive ? "var(--color-primary)" : "var(--color-border)",
|
|
9479
|
+
strokeWidth: isActive ? 3 : 2,
|
|
9480
|
+
markerEnd: isActive ? "url(#arrowhead-active)" : "url(#arrowhead)"
|
|
9481
|
+
}
|
|
9482
|
+
),
|
|
9483
|
+
/* @__PURE__ */ jsx(
|
|
9484
|
+
"text",
|
|
9485
|
+
{
|
|
9486
|
+
x: ctrlX,
|
|
9487
|
+
y: ctrlY - 8,
|
|
9488
|
+
textAnchor: "middle",
|
|
9489
|
+
fill: isActive ? "var(--color-primary)" : "var(--color-foreground)",
|
|
9490
|
+
fontSize: 12,
|
|
9491
|
+
fontWeight: isActive ? "bold" : "normal",
|
|
9492
|
+
className: "select-none",
|
|
9493
|
+
children: eventLabel
|
|
9494
|
+
}
|
|
9495
|
+
),
|
|
9496
|
+
guardHint && /* @__PURE__ */ jsx(
|
|
9497
|
+
"text",
|
|
9498
|
+
{
|
|
9499
|
+
x: ctrlX,
|
|
9500
|
+
y: ctrlY + 6,
|
|
9501
|
+
textAnchor: "middle",
|
|
9502
|
+
fill: "var(--color-warning)",
|
|
9503
|
+
fontSize: 10,
|
|
9504
|
+
className: "select-none",
|
|
9505
|
+
children: "\u26A0 " + guardHint
|
|
9506
|
+
}
|
|
9507
|
+
)
|
|
9508
|
+
] });
|
|
9509
|
+
}
|
|
9510
|
+
var NODE_RADIUS;
|
|
9511
|
+
var init_TransitionArrow = __esm({
|
|
9512
|
+
"components/game/2d/organisms/TransitionArrow.tsx"() {
|
|
9513
|
+
init_cn();
|
|
9514
|
+
NODE_RADIUS = 40;
|
|
9515
|
+
TransitionArrow.displayName = "TransitionArrow";
|
|
9516
|
+
}
|
|
9517
|
+
});
|
|
9518
|
+
function layoutStates(states, width, height) {
|
|
9519
|
+
const cx = width / 2;
|
|
9520
|
+
const cy = height / 2;
|
|
9521
|
+
const radius = Math.min(cx, cy) - 60;
|
|
9522
|
+
const positions = {};
|
|
9523
|
+
states.forEach((state, i) => {
|
|
9524
|
+
const angle = 2 * Math.PI * i / Math.max(states.length, 1) - Math.PI / 2;
|
|
9525
|
+
positions[state] = { x: cx + radius * Math.cos(angle), y: cy + radius * Math.sin(angle) };
|
|
9526
|
+
});
|
|
9527
|
+
return positions;
|
|
9528
|
+
}
|
|
9529
|
+
function StateGraph({
|
|
9530
|
+
states,
|
|
9531
|
+
transitions = [],
|
|
9532
|
+
currentState,
|
|
9533
|
+
selectedState,
|
|
9534
|
+
addingFrom,
|
|
9535
|
+
initialState,
|
|
9536
|
+
width = 500,
|
|
9537
|
+
height = 400,
|
|
9538
|
+
nodeClickEvent,
|
|
9539
|
+
className
|
|
9540
|
+
}) {
|
|
9541
|
+
const eventBus = useEventBus();
|
|
9542
|
+
const nodes = states ?? [];
|
|
9543
|
+
const positions = React98.useMemo(() => layoutStates(nodes, width, height), [nodes, width, height]);
|
|
9544
|
+
return /* @__PURE__ */ jsxs(
|
|
9545
|
+
Box,
|
|
9546
|
+
{
|
|
9547
|
+
position: "relative",
|
|
9548
|
+
className: cn("rounded-container border border-border bg-background overflow-hidden", className),
|
|
9549
|
+
style: { width, height },
|
|
9550
|
+
children: [
|
|
9551
|
+
/* @__PURE__ */ jsxs("svg", { width, height, className: "absolute inset-0", style: { pointerEvents: "none" }, children: [
|
|
9552
|
+
/* @__PURE__ */ jsxs("defs", { children: [
|
|
9553
|
+
/* @__PURE__ */ jsx("marker", { id: "arrowhead", markerWidth: "10", markerHeight: "7", refX: "10", refY: "3.5", orient: "auto", children: /* @__PURE__ */ jsx("polygon", { points: "0 0, 10 3.5, 0 7", fill: "var(--color-border)" }) }),
|
|
9554
|
+
/* @__PURE__ */ jsx("marker", { id: "arrowhead-active", markerWidth: "10", markerHeight: "7", refX: "10", refY: "3.5", orient: "auto", children: /* @__PURE__ */ jsx("polygon", { points: "0 0, 10 3.5, 0 7", fill: "var(--color-primary)" }) })
|
|
9555
|
+
] }),
|
|
9556
|
+
transitions.map((tr, i) => {
|
|
9557
|
+
const fromPos = positions[tr.from];
|
|
9558
|
+
const toPos = positions[tr.to];
|
|
9559
|
+
if (!fromPos || !toPos) return null;
|
|
9560
|
+
return /* @__PURE__ */ jsx(
|
|
9561
|
+
TransitionArrow,
|
|
9562
|
+
{
|
|
9563
|
+
from: fromPos,
|
|
9564
|
+
to: toPos,
|
|
9565
|
+
eventLabel: tr.event,
|
|
9566
|
+
guardHint: tr.guardHint,
|
|
9567
|
+
isActive: tr.from === currentState
|
|
9568
|
+
},
|
|
9569
|
+
`${tr.from}-${tr.event}-${tr.to}-${i}`
|
|
9570
|
+
);
|
|
9571
|
+
})
|
|
9572
|
+
] }),
|
|
9573
|
+
nodes.map((state) => {
|
|
9574
|
+
const pos = positions[state];
|
|
9575
|
+
if (!pos) return null;
|
|
9576
|
+
return /* @__PURE__ */ jsx(
|
|
9577
|
+
StateNode,
|
|
9578
|
+
{
|
|
9579
|
+
name: state,
|
|
9580
|
+
position: pos,
|
|
9581
|
+
isCurrent: state === currentState,
|
|
9582
|
+
isSelected: state === selectedState || state === addingFrom,
|
|
9583
|
+
isInitial: state === initialState,
|
|
9584
|
+
onClick: nodeClickEvent ? () => eventBus.emit(`UI:${nodeClickEvent}`, { stateId: state }) : void 0
|
|
9585
|
+
},
|
|
9586
|
+
state
|
|
9587
|
+
);
|
|
9588
|
+
})
|
|
9589
|
+
]
|
|
9590
|
+
}
|
|
9591
|
+
);
|
|
9592
|
+
}
|
|
9593
|
+
var init_StateGraph = __esm({
|
|
9594
|
+
"components/game/2d/molecules/StateGraph.tsx"() {
|
|
9595
|
+
init_atoms();
|
|
9596
|
+
init_cn();
|
|
9597
|
+
init_useEventBus();
|
|
9598
|
+
init_StateNode();
|
|
9599
|
+
init_TransitionArrow();
|
|
9600
|
+
}
|
|
9601
|
+
});
|
|
9380
9602
|
function useCamera() {
|
|
9381
9603
|
const cameraRef = useRef({ x: 0, y: 0, zoom: 1 });
|
|
9382
9604
|
const targetCameraRef = useRef(null);
|
|
@@ -10974,7 +11196,7 @@ function LinearView({
|
|
|
10974
11196
|
/* @__PURE__ */ jsx(HStack, { className: "flex-wrap items-center", gap: "xs", children: trait.states.map((state, i) => {
|
|
10975
11197
|
const isDone = i < currentIdx;
|
|
10976
11198
|
const isCurrent = i === currentIdx;
|
|
10977
|
-
return /* @__PURE__ */ jsxs(
|
|
11199
|
+
return /* @__PURE__ */ jsxs(React98__default.Fragment, { children: [
|
|
10978
11200
|
i > 0 && /* @__PURE__ */ jsx(
|
|
10979
11201
|
Typography,
|
|
10980
11202
|
{
|
|
@@ -11171,7 +11393,7 @@ function TraitStateViewer({
|
|
|
11171
11393
|
}
|
|
11172
11394
|
var SIZE_CONFIG;
|
|
11173
11395
|
var init_TraitStateViewer = __esm({
|
|
11174
|
-
"components/game/2d/
|
|
11396
|
+
"components/game/2d/organisms/TraitStateViewer.tsx"() {
|
|
11175
11397
|
"use client";
|
|
11176
11398
|
init_cn();
|
|
11177
11399
|
init_Box();
|
|
@@ -11378,7 +11600,7 @@ function TraitSlot({
|
|
|
11378
11600
|
}
|
|
11379
11601
|
var SIZE_CONFIG2, DRAG_MIME;
|
|
11380
11602
|
var init_TraitSlot = __esm({
|
|
11381
|
-
"components/game/2d/
|
|
11603
|
+
"components/game/2d/organisms/TraitSlot.tsx"() {
|
|
11382
11604
|
"use client";
|
|
11383
11605
|
init_cn();
|
|
11384
11606
|
init_useEventBus();
|
|
@@ -11437,7 +11659,7 @@ function ActionTile({
|
|
|
11437
11659
|
}
|
|
11438
11660
|
var DRAG_MIME2, SIZE_CONFIG3;
|
|
11439
11661
|
var init_ActionTile = __esm({
|
|
11440
|
-
"components/game/2d/
|
|
11662
|
+
"components/game/2d/organisms/ActionTile.tsx"() {
|
|
11441
11663
|
init_atoms();
|
|
11442
11664
|
init_cn();
|
|
11443
11665
|
DRAG_MIME2 = "application/x-almadar-slot-item";
|
|
@@ -11474,7 +11696,7 @@ function ActionPalette({
|
|
|
11474
11696
|
] });
|
|
11475
11697
|
}
|
|
11476
11698
|
var init_ActionPalette = __esm({
|
|
11477
|
-
"components/game/2d/
|
|
11699
|
+
"components/game/2d/organisms/ActionPalette.tsx"() {
|
|
11478
11700
|
init_atoms();
|
|
11479
11701
|
init_cn();
|
|
11480
11702
|
init_ActionTile();
|
|
@@ -11486,8 +11708,6 @@ function SequenceBar({
|
|
|
11486
11708
|
maxSlots,
|
|
11487
11709
|
onSlotDrop,
|
|
11488
11710
|
onSlotRemove,
|
|
11489
|
-
slotDropEvent,
|
|
11490
|
-
slotRemoveEvent,
|
|
11491
11711
|
playing = false,
|
|
11492
11712
|
currentStep = -1,
|
|
11493
11713
|
categoryColors,
|
|
@@ -11495,19 +11715,16 @@ function SequenceBar({
|
|
|
11495
11715
|
size = "lg",
|
|
11496
11716
|
className
|
|
11497
11717
|
}) {
|
|
11498
|
-
const { emit } = useEventBus();
|
|
11499
11718
|
const handleDrop = useCallback((index) => (item) => {
|
|
11500
11719
|
if (playing) return;
|
|
11501
|
-
|
|
11502
|
-
|
|
11503
|
-
}, [onSlotDrop, slotDropEvent, emit, playing]);
|
|
11720
|
+
onSlotDrop(index, item);
|
|
11721
|
+
}, [onSlotDrop, playing]);
|
|
11504
11722
|
const handleRemove = useCallback((index) => () => {
|
|
11505
11723
|
if (playing) return;
|
|
11506
|
-
|
|
11507
|
-
|
|
11508
|
-
}, [onSlotRemove, slotRemoveEvent, emit, playing]);
|
|
11724
|
+
onSlotRemove(index);
|
|
11725
|
+
}, [onSlotRemove, playing]);
|
|
11509
11726
|
const paddedSlots = Array.from({ length: maxSlots }, (_, i) => slots[i]);
|
|
11510
|
-
return /* @__PURE__ */ jsx(HStack, { className: cn("items-center", className), gap: "sm", children: paddedSlots.map((slot, i) => /* @__PURE__ */ jsxs(
|
|
11727
|
+
return /* @__PURE__ */ jsx(HStack, { className: cn("items-center", className), gap: "sm", children: paddedSlots.map((slot, i) => /* @__PURE__ */ jsxs(React98__default.Fragment, { children: [
|
|
11511
11728
|
i > 0 && /* @__PURE__ */ jsx(
|
|
11512
11729
|
Typography,
|
|
11513
11730
|
{
|
|
@@ -11537,14 +11754,330 @@ function SequenceBar({
|
|
|
11537
11754
|
] }, i)) });
|
|
11538
11755
|
}
|
|
11539
11756
|
var init_SequenceBar = __esm({
|
|
11540
|
-
"components/game/2d/
|
|
11757
|
+
"components/game/2d/organisms/SequenceBar.tsx"() {
|
|
11541
11758
|
init_atoms();
|
|
11542
11759
|
init_cn();
|
|
11543
|
-
init_useEventBus();
|
|
11544
11760
|
init_TraitSlot();
|
|
11545
11761
|
SequenceBar.displayName = "SequenceBar";
|
|
11546
11762
|
}
|
|
11547
11763
|
});
|
|
11764
|
+
function computeSlotFeedback(playerSeq, solutions) {
|
|
11765
|
+
let bestSolution = solutions[0];
|
|
11766
|
+
let bestMatches = -1;
|
|
11767
|
+
for (const sol of solutions) {
|
|
11768
|
+
const matches = sol.filter((id, i) => id === playerSeq[i]).length;
|
|
11769
|
+
if (matches > bestMatches) {
|
|
11770
|
+
bestMatches = matches;
|
|
11771
|
+
bestSolution = sol;
|
|
11772
|
+
}
|
|
11773
|
+
}
|
|
11774
|
+
return playerSeq.map(
|
|
11775
|
+
(id, i) => id !== void 0 && id === bestSolution[i] ? "correct" : "wrong"
|
|
11776
|
+
);
|
|
11777
|
+
}
|
|
11778
|
+
function isFieldRecord(v) {
|
|
11779
|
+
return typeof v === "object" && v !== null && !Array.isArray(v) && !(v instanceof Date);
|
|
11780
|
+
}
|
|
11781
|
+
function assetFromField(v) {
|
|
11782
|
+
if (!isFieldRecord(v)) return void 0;
|
|
11783
|
+
const url = typeof v.url === "string" ? v.url : void 0;
|
|
11784
|
+
const role = typeof v.role === "string" ? v.role : void 0;
|
|
11785
|
+
const category = typeof v.category === "string" ? v.category : "";
|
|
11786
|
+
if (!url || !role) return void 0;
|
|
11787
|
+
return {
|
|
11788
|
+
url,
|
|
11789
|
+
role,
|
|
11790
|
+
category,
|
|
11791
|
+
name: typeof v.name === "string" ? v.name : void 0,
|
|
11792
|
+
thumbnailUrl: typeof v.thumbnailUrl === "string" ? v.thumbnailUrl : void 0,
|
|
11793
|
+
style: typeof v.style === "string" ? v.style : void 0,
|
|
11794
|
+
variant: typeof v.variant === "string" ? v.variant : void 0,
|
|
11795
|
+
dimension: typeof v.dimension === "string" ? v.dimension : void 0,
|
|
11796
|
+
aspect: typeof v.aspect === "string" ? v.aspect : void 0
|
|
11797
|
+
};
|
|
11798
|
+
}
|
|
11799
|
+
function slotItemFromField(fv) {
|
|
11800
|
+
if (!isFieldRecord(fv)) return void 0;
|
|
11801
|
+
const id = typeof fv.id === "string" ? fv.id : void 0;
|
|
11802
|
+
const name = typeof fv.name === "string" ? fv.name : void 0;
|
|
11803
|
+
const category = typeof fv.category === "string" ? fv.category : void 0;
|
|
11804
|
+
if (!id || !name || !category) return void 0;
|
|
11805
|
+
return {
|
|
11806
|
+
id,
|
|
11807
|
+
name,
|
|
11808
|
+
category,
|
|
11809
|
+
description: typeof fv.description === "string" ? fv.description : void 0,
|
|
11810
|
+
iconEmoji: typeof fv.iconEmoji === "string" ? fv.iconEmoji : void 0,
|
|
11811
|
+
iconUrl: assetFromField(fv.iconUrl)
|
|
11812
|
+
};
|
|
11813
|
+
}
|
|
11814
|
+
function SequencerBoard({
|
|
11815
|
+
entity,
|
|
11816
|
+
categoryColors,
|
|
11817
|
+
stepDurationMs = 1e3,
|
|
11818
|
+
playEvent,
|
|
11819
|
+
completeEvent,
|
|
11820
|
+
placeEvent,
|
|
11821
|
+
removeEvent,
|
|
11822
|
+
checkEvent,
|
|
11823
|
+
playAgainEvent,
|
|
11824
|
+
stepEvent,
|
|
11825
|
+
className
|
|
11826
|
+
}) {
|
|
11827
|
+
const { emit } = useEventBus();
|
|
11828
|
+
const { t } = useTranslate();
|
|
11829
|
+
const resolved = boardEntity(entity);
|
|
11830
|
+
const maxSlots = num(resolved?.maxSlots) || 3;
|
|
11831
|
+
const solutions = Array.isArray(resolved?.solutions) ? resolved.solutions : [];
|
|
11832
|
+
const availableActions = (Array.isArray(resolved?.availableActions) ? resolved.availableActions : []).reduce((acc, fv) => {
|
|
11833
|
+
const item = slotItemFromField(fv);
|
|
11834
|
+
if (item) acc.push(item);
|
|
11835
|
+
return acc;
|
|
11836
|
+
}, []);
|
|
11837
|
+
const allowDuplicates = resolved?.allowDuplicates !== false;
|
|
11838
|
+
const entitySlots = Array.isArray(resolved?.slots) ? resolved.slots : [];
|
|
11839
|
+
const entityResult = str(resolved?.result);
|
|
11840
|
+
const entityAttempts = num(resolved?.attempts);
|
|
11841
|
+
const entityCurrentStep = typeof resolved?.currentStep === "number" ? resolved.currentStep : -1;
|
|
11842
|
+
const slots = Array.from({ length: maxSlots }, (_, i) => {
|
|
11843
|
+
const entitySlot = entitySlots.find((s) => s.index === i);
|
|
11844
|
+
if (!entitySlot?.placedActionId) return void 0;
|
|
11845
|
+
return availableActions.find((a) => a.id === entitySlot.placedActionId);
|
|
11846
|
+
});
|
|
11847
|
+
const isSuccess = entityResult === "win";
|
|
11848
|
+
const attempts = entityAttempts;
|
|
11849
|
+
const isPlayingBack = entityCurrentStep >= 0 && !isSuccess;
|
|
11850
|
+
const currentStep = entityCurrentStep;
|
|
11851
|
+
const [headerError, setHeaderError] = useState(false);
|
|
11852
|
+
const [slotFeedback, setSlotFeedback] = useState(
|
|
11853
|
+
() => Array.from({ length: maxSlots }, () => null)
|
|
11854
|
+
);
|
|
11855
|
+
const timerRef = useRef(null);
|
|
11856
|
+
useEffect(() => () => {
|
|
11857
|
+
if (timerRef.current) clearTimeout(timerRef.current);
|
|
11858
|
+
}, []);
|
|
11859
|
+
const handleSlotDrop = useCallback((index, item) => {
|
|
11860
|
+
setSlotFeedback((prev) => {
|
|
11861
|
+
const next = [...prev];
|
|
11862
|
+
next[index] = null;
|
|
11863
|
+
return next;
|
|
11864
|
+
});
|
|
11865
|
+
emit("UI:PLAY_SOUND", { key: "drop_slot" });
|
|
11866
|
+
if (placeEvent) emit(`UI:${placeEvent}`, { slotIndex: index, actionId: item.id });
|
|
11867
|
+
}, [emit, placeEvent]);
|
|
11868
|
+
const handleSlotRemove = useCallback((index) => {
|
|
11869
|
+
setSlotFeedback((prev) => {
|
|
11870
|
+
const next = [...prev];
|
|
11871
|
+
next[index] = null;
|
|
11872
|
+
return next;
|
|
11873
|
+
});
|
|
11874
|
+
emit("UI:PLAY_SOUND", { key: "back" });
|
|
11875
|
+
if (removeEvent) emit(`UI:${removeEvent}`, { slotIndex: index });
|
|
11876
|
+
}, [emit, removeEvent]);
|
|
11877
|
+
const handleReset = useCallback(() => {
|
|
11878
|
+
if (timerRef.current) clearTimeout(timerRef.current);
|
|
11879
|
+
setSlotFeedback(Array.from({ length: maxSlots }, () => null));
|
|
11880
|
+
if (playAgainEvent) emit(`UI:${playAgainEvent}`, {});
|
|
11881
|
+
}, [maxSlots, playAgainEvent, emit]);
|
|
11882
|
+
const filledSlots = slots.filter((s) => !!s);
|
|
11883
|
+
const canPlay = filledSlots.length > 0 && !isPlayingBack && !isSuccess;
|
|
11884
|
+
const handlePlay = useCallback(() => {
|
|
11885
|
+
if (!canPlay) return;
|
|
11886
|
+
setSlotFeedback(Array.from({ length: maxSlots }, () => null));
|
|
11887
|
+
emit("UI:PLAY_SOUND", { key: "confirm" });
|
|
11888
|
+
const sequence = slots.map((s) => s?.id || "");
|
|
11889
|
+
const playerIds = slots.filter(Boolean).map((s) => s?.id || "");
|
|
11890
|
+
if (playEvent) emit(`UI:${playEvent}`, { sequence });
|
|
11891
|
+
let step = 0;
|
|
11892
|
+
const advance = () => {
|
|
11893
|
+
step++;
|
|
11894
|
+
if (stepEvent) emit(`UI:${stepEvent}`, { step });
|
|
11895
|
+
if (step >= maxSlots) {
|
|
11896
|
+
if (checkEvent) emit(`UI:${checkEvent}`, { sequence: playerIds });
|
|
11897
|
+
const playerSeq = slots.map((s) => s?.id);
|
|
11898
|
+
const success = solutions.some(
|
|
11899
|
+
(sol) => sol.length === playerIds.length && sol.every((id, i) => id === playerIds[i])
|
|
11900
|
+
);
|
|
11901
|
+
if (success) {
|
|
11902
|
+
emit("UI:PLAY_SOUND", { key: "levelComplete" });
|
|
11903
|
+
if (completeEvent) emit(`UI:${completeEvent}`, { success: true, sequence: playerIds });
|
|
11904
|
+
} else {
|
|
11905
|
+
const feedback = computeSlotFeedback(playerSeq, solutions);
|
|
11906
|
+
setSlotFeedback(feedback);
|
|
11907
|
+
emit("UI:PLAY_SOUND", { key: "fail" });
|
|
11908
|
+
const correctCount2 = feedback.filter((f3) => f3 === "correct").length;
|
|
11909
|
+
for (let ci = 0; ci < correctCount2; ci++) {
|
|
11910
|
+
setTimeout(() => {
|
|
11911
|
+
emit("UI:PLAY_SOUND", { key: "correctSlot" });
|
|
11912
|
+
}, 300 + ci * 150);
|
|
11913
|
+
}
|
|
11914
|
+
}
|
|
11915
|
+
} else {
|
|
11916
|
+
timerRef.current = setTimeout(advance, stepDurationMs);
|
|
11917
|
+
}
|
|
11918
|
+
};
|
|
11919
|
+
timerRef.current = setTimeout(advance, stepDurationMs);
|
|
11920
|
+
}, [canPlay, slots, maxSlots, solutions, stepDurationMs, playEvent, completeEvent, checkEvent, emit]);
|
|
11921
|
+
const machine = {
|
|
11922
|
+
name: str(resolved?.title),
|
|
11923
|
+
description: str(resolved?.description),
|
|
11924
|
+
states: slots.map((s, i) => stepLabel(s, i)),
|
|
11925
|
+
currentState: currentStep >= 0 ? stepLabel(slots[currentStep], currentStep) : "__idle__",
|
|
11926
|
+
transitions: slots.slice(0, -1).map((s, i) => ({
|
|
11927
|
+
from: stepLabel(s, i),
|
|
11928
|
+
to: stepLabel(slots[i + 1], i + 1),
|
|
11929
|
+
event: "NEXT"
|
|
11930
|
+
}))
|
|
11931
|
+
};
|
|
11932
|
+
const usedIds = !allowDuplicates ? slots.filter(Boolean).map((s) => s?.id || "") : [];
|
|
11933
|
+
const hint = str(resolved?.hint);
|
|
11934
|
+
const showHint = attempts >= 3 && !!hint;
|
|
11935
|
+
const hasFeedback = slotFeedback.some((f3) => f3 !== null);
|
|
11936
|
+
const correctCount = slotFeedback.filter((f3) => f3 === "correct").length;
|
|
11937
|
+
const encourageKey = ENCOURAGEMENT_KEYS[Math.min(attempts - 1, ENCOURAGEMENT_KEYS.length - 1)] ?? ENCOURAGEMENT_KEYS[0];
|
|
11938
|
+
if (!resolved) return null;
|
|
11939
|
+
const theme = resolved.theme ?? void 0;
|
|
11940
|
+
const themeBackground = theme?.background;
|
|
11941
|
+
const headerImage = str(resolved.headerImage);
|
|
11942
|
+
return /* @__PURE__ */ jsxs(
|
|
11943
|
+
VStack,
|
|
11944
|
+
{
|
|
11945
|
+
className: cn("p-4 gap-6", className),
|
|
11946
|
+
style: {
|
|
11947
|
+
backgroundImage: themeBackground ? `url(${themeBackground})` : void 0,
|
|
11948
|
+
backgroundSize: "cover",
|
|
11949
|
+
backgroundPosition: "center"
|
|
11950
|
+
},
|
|
11951
|
+
children: [
|
|
11952
|
+
headerImage && !headerError ? /* @__PURE__ */ jsx(Box, { className: "w-full h-32 overflow-hidden rounded-container", children: /* @__PURE__ */ jsx("img", { src: headerImage, alt: "", onError: () => setHeaderError(true), className: "w-full h-full object-cover" }) }) : headerImage && headerError ? /* @__PURE__ */ jsx(Box, { className: "w-full h-32 rounded-container bg-gradient-to-br from-muted to-accent opacity-60" }) : null,
|
|
11953
|
+
/* @__PURE__ */ jsxs(VStack, { gap: "xs", children: [
|
|
11954
|
+
/* @__PURE__ */ jsx(Typography, { variant: "h4", className: "text-foreground", children: str(resolved.title) }),
|
|
11955
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-muted-foreground", children: str(resolved.description) })
|
|
11956
|
+
] }),
|
|
11957
|
+
showHint && /* @__PURE__ */ jsx(Box, { className: "p-3 rounded-container bg-accent/10 border border-accent/30", children: /* @__PURE__ */ jsxs(HStack, { className: "items-start", gap: "xs", children: [
|
|
11958
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-accent font-bold shrink-0", children: "\u{1F4A1} " + t("game.hint") + ":" }),
|
|
11959
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-foreground", children: hint })
|
|
11960
|
+
] }) }),
|
|
11961
|
+
filledSlots.length > 0 && /* @__PURE__ */ jsx(TraitStateViewer, { trait: machine, variant: "linear", size: "md" }),
|
|
11962
|
+
/* @__PURE__ */ jsxs(VStack, { gap: "xs", children: [
|
|
11963
|
+
/* @__PURE__ */ jsxs(HStack, { className: "items-center justify-between", children: [
|
|
11964
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-muted-foreground font-medium", children: t("sequencer.yourSequence") + ":" }),
|
|
11965
|
+
hasFeedback && !isPlayingBack && !isSuccess && /* @__PURE__ */ jsxs(Typography, { variant: "caption", className: "text-muted-foreground", children: [
|
|
11966
|
+
`${correctCount}/${maxSlots} `,
|
|
11967
|
+
"\u2705"
|
|
11968
|
+
] })
|
|
11969
|
+
] }),
|
|
11970
|
+
/* @__PURE__ */ jsx(
|
|
11971
|
+
SequenceBar,
|
|
11972
|
+
{
|
|
11973
|
+
slots,
|
|
11974
|
+
maxSlots,
|
|
11975
|
+
onSlotDrop: handleSlotDrop,
|
|
11976
|
+
onSlotRemove: handleSlotRemove,
|
|
11977
|
+
playing: isPlayingBack,
|
|
11978
|
+
currentStep,
|
|
11979
|
+
categoryColors,
|
|
11980
|
+
slotFeedback,
|
|
11981
|
+
size: "lg"
|
|
11982
|
+
}
|
|
11983
|
+
)
|
|
11984
|
+
] }),
|
|
11985
|
+
!isPlayingBack && /* @__PURE__ */ jsx(
|
|
11986
|
+
ActionPalette,
|
|
11987
|
+
{
|
|
11988
|
+
actions: availableActions,
|
|
11989
|
+
usedActionIds: usedIds,
|
|
11990
|
+
allowDuplicates,
|
|
11991
|
+
categoryColors,
|
|
11992
|
+
label: t("sequencer.dragActions")
|
|
11993
|
+
}
|
|
11994
|
+
),
|
|
11995
|
+
hasFeedback && !isPlayingBack && !isSuccess && attempts > 0 && /* @__PURE__ */ jsx(Box, { className: "p-3 rounded-container bg-warning/10 border border-warning/30 text-center", children: /* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-foreground", children: t(encourageKey) }) }),
|
|
11996
|
+
isSuccess && /* @__PURE__ */ jsx(Box, { className: "p-4 rounded-container bg-success/20 border border-success text-center", children: /* @__PURE__ */ jsx(Typography, { variant: "h5", className: "text-success", children: str(resolved.successMessage) || t("sequencer.levelComplete") }) }),
|
|
11997
|
+
/* @__PURE__ */ jsxs(HStack, { gap: "sm", children: [
|
|
11998
|
+
/* @__PURE__ */ jsx(
|
|
11999
|
+
Button,
|
|
12000
|
+
{
|
|
12001
|
+
variant: "primary",
|
|
12002
|
+
onClick: handlePlay,
|
|
12003
|
+
disabled: !canPlay,
|
|
12004
|
+
children: "\u25B6 " + t("game.play")
|
|
12005
|
+
}
|
|
12006
|
+
),
|
|
12007
|
+
/* @__PURE__ */ jsx(Button, { variant: "ghost", onClick: handleReset, children: "\u21BA " + t("game.reset") })
|
|
12008
|
+
] })
|
|
12009
|
+
]
|
|
12010
|
+
}
|
|
12011
|
+
);
|
|
12012
|
+
}
|
|
12013
|
+
var ENCOURAGEMENT_KEYS, stepLabel;
|
|
12014
|
+
var init_SequencerBoard = __esm({
|
|
12015
|
+
"components/game/2d/organisms/SequencerBoard.tsx"() {
|
|
12016
|
+
init_atoms();
|
|
12017
|
+
init_cn();
|
|
12018
|
+
init_useEventBus();
|
|
12019
|
+
init_TraitStateViewer();
|
|
12020
|
+
init_boardEntity();
|
|
12021
|
+
init_SequenceBar();
|
|
12022
|
+
init_ActionPalette();
|
|
12023
|
+
ENCOURAGEMENT_KEYS = [
|
|
12024
|
+
"puzzle.tryAgain1",
|
|
12025
|
+
"puzzle.tryAgain2",
|
|
12026
|
+
"puzzle.tryAgain3"
|
|
12027
|
+
];
|
|
12028
|
+
stepLabel = (slot, i) => slot ? `${i + 1}. ${slot.name}` : `Step ${i + 1}`;
|
|
12029
|
+
SequencerBoard.displayName = "SequencerBoard";
|
|
12030
|
+
}
|
|
12031
|
+
});
|
|
12032
|
+
function RuleEditor({
|
|
12033
|
+
rule,
|
|
12034
|
+
availableEvents,
|
|
12035
|
+
availableActions,
|
|
12036
|
+
onChange,
|
|
12037
|
+
onRemove,
|
|
12038
|
+
disabled = false,
|
|
12039
|
+
className
|
|
12040
|
+
}) {
|
|
12041
|
+
const { t } = useTranslate();
|
|
12042
|
+
const handleWhenChange = useCallback((v) => {
|
|
12043
|
+
onChange({ ...rule, whenEvent: v });
|
|
12044
|
+
}, [rule, onChange]);
|
|
12045
|
+
const handleThenChange = useCallback((v) => {
|
|
12046
|
+
onChange({ ...rule, thenAction: v });
|
|
12047
|
+
}, [rule, onChange]);
|
|
12048
|
+
return /* @__PURE__ */ jsxs(HStack, { className: cn("items-center p-2 rounded-lg bg-muted/50 border border-border", className), gap: "sm", children: [
|
|
12049
|
+
/* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-primary font-bold whitespace-nowrap", children: t("eventHandler.when") }),
|
|
12050
|
+
/* @__PURE__ */ jsx(
|
|
12051
|
+
Select,
|
|
12052
|
+
{
|
|
12053
|
+
value: rule.whenEvent,
|
|
12054
|
+
onValueChange: handleWhenChange,
|
|
12055
|
+
options: availableEvents,
|
|
12056
|
+
disabled,
|
|
12057
|
+
className: "flex-1 min-w-0"
|
|
12058
|
+
}
|
|
12059
|
+
),
|
|
12060
|
+
/* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-accent font-bold whitespace-nowrap", children: "\u2192 " + t("eventHandler.then") }),
|
|
12061
|
+
/* @__PURE__ */ jsx(
|
|
12062
|
+
Select,
|
|
12063
|
+
{
|
|
12064
|
+
value: rule.thenAction,
|
|
12065
|
+
onValueChange: handleThenChange,
|
|
12066
|
+
options: availableActions,
|
|
12067
|
+
disabled,
|
|
12068
|
+
className: "flex-1 min-w-0"
|
|
12069
|
+
}
|
|
12070
|
+
),
|
|
12071
|
+
onRemove && /* @__PURE__ */ jsx(Button, { variant: "ghost", onClick: onRemove, disabled, className: "shrink-0", children: "\xD7" })
|
|
12072
|
+
] });
|
|
12073
|
+
}
|
|
12074
|
+
var init_RuleEditor = __esm({
|
|
12075
|
+
"components/game/2d/organisms/RuleEditor.tsx"() {
|
|
12076
|
+
init_atoms();
|
|
12077
|
+
init_cn();
|
|
12078
|
+
RuleEditor.displayName = "RuleEditor";
|
|
12079
|
+
}
|
|
12080
|
+
});
|
|
11548
12081
|
function EventLog({
|
|
11549
12082
|
entries,
|
|
11550
12083
|
maxHeight = 200,
|
|
@@ -11580,7 +12113,7 @@ function EventLog({
|
|
|
11580
12113
|
}
|
|
11581
12114
|
var STATUS_STYLES, STATUS_DOTS;
|
|
11582
12115
|
var init_EventLog = __esm({
|
|
11583
|
-
"components/game/2d/
|
|
12116
|
+
"components/game/2d/organisms/EventLog.tsx"() {
|
|
11584
12117
|
init_atoms();
|
|
11585
12118
|
init_cn();
|
|
11586
12119
|
STATUS_STYLES = {
|
|
@@ -11600,10 +12133,1644 @@ var init_EventLog = __esm({
|
|
|
11600
12133
|
});
|
|
11601
12134
|
|
|
11602
12135
|
// components/game/shared/lib/puzzleObject.ts
|
|
12136
|
+
function objId(o) {
|
|
12137
|
+
return o.id == null ? "" : String(o.id);
|
|
12138
|
+
}
|
|
12139
|
+
function objName(o) {
|
|
12140
|
+
return o.name == null ? "" : String(o.name);
|
|
12141
|
+
}
|
|
12142
|
+
function objIcon(o) {
|
|
12143
|
+
return o.icon == null ? "" : String(o.icon);
|
|
12144
|
+
}
|
|
12145
|
+
function objStates(o) {
|
|
12146
|
+
return Array.isArray(o.states) ? o.states : [];
|
|
12147
|
+
}
|
|
12148
|
+
function objCurrentState(o) {
|
|
12149
|
+
return o.currentState == null ? "" : String(o.currentState);
|
|
12150
|
+
}
|
|
12151
|
+
function objAvailableEvents(o) {
|
|
12152
|
+
return Array.isArray(o.availableEvents) ? o.availableEvents : [];
|
|
12153
|
+
}
|
|
12154
|
+
function objAvailableActions(o) {
|
|
12155
|
+
return Array.isArray(o.availableActions) ? o.availableActions : [];
|
|
12156
|
+
}
|
|
12157
|
+
function objRules(o) {
|
|
12158
|
+
return Array.isArray(o.rules) ? o.rules : [];
|
|
12159
|
+
}
|
|
12160
|
+
function objMaxRules(o) {
|
|
12161
|
+
const n = Number(o.maxRules);
|
|
12162
|
+
return Number.isFinite(n) && n > 0 ? n : 3;
|
|
12163
|
+
}
|
|
11603
12164
|
var init_puzzleObject = __esm({
|
|
11604
12165
|
"components/game/shared/lib/puzzleObject.ts"() {
|
|
11605
12166
|
}
|
|
11606
12167
|
});
|
|
12168
|
+
function ObjectRulePanel({
|
|
12169
|
+
object,
|
|
12170
|
+
onRulesChange,
|
|
12171
|
+
disabled = false,
|
|
12172
|
+
className
|
|
12173
|
+
}) {
|
|
12174
|
+
const { t } = useTranslate();
|
|
12175
|
+
const id = objId(object);
|
|
12176
|
+
const name = objName(object);
|
|
12177
|
+
const icon = objIcon(object);
|
|
12178
|
+
const states = objStates(object);
|
|
12179
|
+
const currentState = objCurrentState(object);
|
|
12180
|
+
const availableEvents = objAvailableEvents(object);
|
|
12181
|
+
const availableActions = objAvailableActions(object);
|
|
12182
|
+
const rules = objRules(object);
|
|
12183
|
+
const maxRules = objMaxRules(object);
|
|
12184
|
+
const canAdd = rules.length < maxRules;
|
|
12185
|
+
const handleRuleChange = useCallback((index, updatedRule) => {
|
|
12186
|
+
const newRules = [...rules];
|
|
12187
|
+
newRules[index] = updatedRule;
|
|
12188
|
+
onRulesChange(id, newRules);
|
|
12189
|
+
}, [id, rules, onRulesChange]);
|
|
12190
|
+
const handleRuleRemove = useCallback((index) => {
|
|
12191
|
+
const newRules = rules.filter((_, i) => i !== index);
|
|
12192
|
+
onRulesChange(id, newRules);
|
|
12193
|
+
}, [id, rules, onRulesChange]);
|
|
12194
|
+
const handleAddRule = useCallback(() => {
|
|
12195
|
+
if (!canAdd || disabled) return;
|
|
12196
|
+
const firstEvent = availableEvents[0]?.value || "";
|
|
12197
|
+
const firstAction = availableActions[0]?.value || "";
|
|
12198
|
+
const newRule = {
|
|
12199
|
+
id: `rule-${nextRuleId++}`,
|
|
12200
|
+
whenEvent: firstEvent,
|
|
12201
|
+
thenAction: firstAction
|
|
12202
|
+
};
|
|
12203
|
+
onRulesChange(id, [...rules, newRule]);
|
|
12204
|
+
}, [canAdd, disabled, id, rules, availableEvents, availableActions, onRulesChange]);
|
|
12205
|
+
const machine = {
|
|
12206
|
+
name,
|
|
12207
|
+
states,
|
|
12208
|
+
currentState,
|
|
12209
|
+
transitions: rules.map((r) => ({
|
|
12210
|
+
from: currentState,
|
|
12211
|
+
to: states.find((s) => s !== currentState) || currentState,
|
|
12212
|
+
event: r.whenEvent
|
|
12213
|
+
}))
|
|
12214
|
+
};
|
|
12215
|
+
return /* @__PURE__ */ jsxs(VStack, { className: cn("p-4 rounded-lg bg-card border border-border", className), gap: "sm", children: [
|
|
12216
|
+
/* @__PURE__ */ jsxs(HStack, { className: "items-center", gap: "sm", children: [
|
|
12217
|
+
/* @__PURE__ */ jsx(Typography, { variant: "h5", children: icon }),
|
|
12218
|
+
/* @__PURE__ */ jsxs(VStack, { gap: "none", children: [
|
|
12219
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body1", className: "text-foreground font-bold", children: name }),
|
|
12220
|
+
/* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-muted-foreground", children: t("eventHandler.state") + ": " + currentState })
|
|
12221
|
+
] })
|
|
12222
|
+
] }),
|
|
12223
|
+
/* @__PURE__ */ jsx(TraitStateViewer, { trait: machine, variant: "compact", size: "sm" }),
|
|
12224
|
+
/* @__PURE__ */ jsxs(VStack, { gap: "xs", children: [
|
|
12225
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-muted-foreground font-medium", children: t("eventHandler.rules", { count: rules.length, max: maxRules }) + ":" }),
|
|
12226
|
+
rules.map((rule, i) => /* @__PURE__ */ jsx(
|
|
12227
|
+
RuleEditor,
|
|
12228
|
+
{
|
|
12229
|
+
rule,
|
|
12230
|
+
availableEvents,
|
|
12231
|
+
availableActions,
|
|
12232
|
+
onChange: (r) => handleRuleChange(i, r),
|
|
12233
|
+
onRemove: () => handleRuleRemove(i),
|
|
12234
|
+
disabled
|
|
12235
|
+
},
|
|
12236
|
+
rule.id
|
|
12237
|
+
)),
|
|
12238
|
+
canAdd && !disabled && /* @__PURE__ */ jsx(Button, { variant: "ghost", onClick: handleAddRule, className: "self-start", children: t("eventHandler.addRule") })
|
|
12239
|
+
] })
|
|
12240
|
+
] });
|
|
12241
|
+
}
|
|
12242
|
+
var nextRuleId;
|
|
12243
|
+
var init_ObjectRulePanel = __esm({
|
|
12244
|
+
"components/game/2d/organisms/ObjectRulePanel.tsx"() {
|
|
12245
|
+
init_atoms();
|
|
12246
|
+
init_cn();
|
|
12247
|
+
init_TraitStateViewer();
|
|
12248
|
+
init_RuleEditor();
|
|
12249
|
+
init_puzzleObject();
|
|
12250
|
+
nextRuleId = 1;
|
|
12251
|
+
ObjectRulePanel.displayName = "ObjectRulePanel";
|
|
12252
|
+
}
|
|
12253
|
+
});
|
|
12254
|
+
function EventHandlerBoard({
|
|
12255
|
+
entity,
|
|
12256
|
+
stepDurationMs = 800,
|
|
12257
|
+
playEvent,
|
|
12258
|
+
completeEvent,
|
|
12259
|
+
editRuleEvent,
|
|
12260
|
+
playAgainEvent,
|
|
12261
|
+
className
|
|
12262
|
+
}) {
|
|
12263
|
+
const { emit } = useEventBus();
|
|
12264
|
+
const { t } = useTranslate();
|
|
12265
|
+
const resolved = boardEntity(entity);
|
|
12266
|
+
const objects = rows(resolved?.objects);
|
|
12267
|
+
const entityResult = str(resolved?.result) || "none";
|
|
12268
|
+
const isSuccess = entityResult === "win";
|
|
12269
|
+
const attempts = typeof resolved?.attempts === "number" ? resolved.attempts : 0;
|
|
12270
|
+
const [selectedObjectId, setSelectedObjectId] = useState(
|
|
12271
|
+
objects[0] ? objId(objects[0]) : null
|
|
12272
|
+
);
|
|
12273
|
+
const [headerError, setHeaderError] = useState(false);
|
|
12274
|
+
const [isPlaying, setIsPlaying] = useState(false);
|
|
12275
|
+
const [eventLog, setEventLog] = useState([]);
|
|
12276
|
+
const timerRef = useRef(null);
|
|
12277
|
+
const logIdCounter = useRef(0);
|
|
12278
|
+
useEffect(() => () => {
|
|
12279
|
+
if (timerRef.current) clearTimeout(timerRef.current);
|
|
12280
|
+
}, []);
|
|
12281
|
+
const selectedObject = objects.find((o) => objId(o) === selectedObjectId) ?? null;
|
|
12282
|
+
const handleRulesChange = useCallback((objectId, rules) => {
|
|
12283
|
+
if (editRuleEvent) emit(`UI:${editRuleEvent}`, { objectId, rules });
|
|
12284
|
+
}, [editRuleEvent, emit]);
|
|
12285
|
+
const addLogEntry = useCallback((icon, message, status = "done") => {
|
|
12286
|
+
const id = `log-${logIdCounter.current++}`;
|
|
12287
|
+
setEventLog((prev) => [...prev, { id, timestamp: Date.now(), icon, message, status }]);
|
|
12288
|
+
}, []);
|
|
12289
|
+
const handlePlay = useCallback(() => {
|
|
12290
|
+
if (isPlaying || isSuccess) return;
|
|
12291
|
+
if (playEvent) emit(`UI:${playEvent}`, {});
|
|
12292
|
+
setIsPlaying(true);
|
|
12293
|
+
setEventLog([]);
|
|
12294
|
+
const allRules = [];
|
|
12295
|
+
objects.forEach((obj) => {
|
|
12296
|
+
objRules(obj).forEach((rule) => {
|
|
12297
|
+
allRules.push({ object: obj, rule });
|
|
12298
|
+
});
|
|
12299
|
+
});
|
|
12300
|
+
const triggers = Array.isArray(resolved?.triggerEvents) ? resolved.triggerEvents : [];
|
|
12301
|
+
const goalEvent = str(resolved?.goalEvent);
|
|
12302
|
+
const eventQueue = [...triggers];
|
|
12303
|
+
const firedEvents = /* @__PURE__ */ new Set();
|
|
12304
|
+
let stepIdx = 0;
|
|
12305
|
+
let goalReached = false;
|
|
12306
|
+
const processNext = () => {
|
|
12307
|
+
if (eventQueue.length === 0 || stepIdx > 20) {
|
|
12308
|
+
setIsPlaying(false);
|
|
12309
|
+
if (goalReached && completeEvent) emit(`UI:${completeEvent}`, { success: true });
|
|
12310
|
+
return;
|
|
12311
|
+
}
|
|
12312
|
+
const currentEvent = eventQueue.shift();
|
|
12313
|
+
if (firedEvents.has(currentEvent)) {
|
|
12314
|
+
timerRef.current = setTimeout(processNext, 100);
|
|
12315
|
+
return;
|
|
12316
|
+
}
|
|
12317
|
+
firedEvents.add(currentEvent);
|
|
12318
|
+
const matching = allRules.filter((r) => r.rule.whenEvent === currentEvent);
|
|
12319
|
+
if (matching.length === 0) {
|
|
12320
|
+
addLogEntry("\u26A1", t("eventHandler.noListeners", { event: currentEvent }), "done");
|
|
12321
|
+
} else {
|
|
12322
|
+
matching.forEach(({ object, rule }) => {
|
|
12323
|
+
addLogEntry(objIcon(object), t("eventHandler.heardEvent", { object: objName(object), event: currentEvent, action: rule.thenAction }), "done");
|
|
12324
|
+
eventQueue.push(rule.thenAction);
|
|
12325
|
+
if (rule.thenAction === goalEvent) {
|
|
12326
|
+
goalReached = true;
|
|
12327
|
+
}
|
|
12328
|
+
});
|
|
12329
|
+
}
|
|
12330
|
+
if (currentEvent === goalEvent) {
|
|
12331
|
+
goalReached = true;
|
|
12332
|
+
}
|
|
12333
|
+
stepIdx++;
|
|
12334
|
+
timerRef.current = setTimeout(processNext, stepDurationMs);
|
|
12335
|
+
};
|
|
12336
|
+
if (triggers.length > 0) {
|
|
12337
|
+
addLogEntry("\u{1F3AC}", t("eventHandler.simulationStarted", { events: triggers.join(", ") }), "active");
|
|
12338
|
+
}
|
|
12339
|
+
timerRef.current = setTimeout(processNext, stepDurationMs);
|
|
12340
|
+
}, [isPlaying, isSuccess, objects, resolved, stepDurationMs, playEvent, completeEvent, emit, addLogEntry, t]);
|
|
12341
|
+
const handleTryAgain = useCallback(() => {
|
|
12342
|
+
if (timerRef.current) clearTimeout(timerRef.current);
|
|
12343
|
+
setIsPlaying(false);
|
|
12344
|
+
setEventLog([]);
|
|
12345
|
+
}, []);
|
|
12346
|
+
const handleReset = useCallback(() => {
|
|
12347
|
+
if (timerRef.current) clearTimeout(timerRef.current);
|
|
12348
|
+
setIsPlaying(false);
|
|
12349
|
+
setEventLog([]);
|
|
12350
|
+
setSelectedObjectId(objects[0] ? objId(objects[0]) : null);
|
|
12351
|
+
if (playAgainEvent) emit(`UI:${playAgainEvent}`, {});
|
|
12352
|
+
}, [objects, playAgainEvent, emit]);
|
|
12353
|
+
if (!resolved) return null;
|
|
12354
|
+
const objectViewers = objects.map((obj) => {
|
|
12355
|
+
const states = objStates(obj);
|
|
12356
|
+
const currentState = objCurrentState(obj);
|
|
12357
|
+
const machine = {
|
|
12358
|
+
name: objName(obj),
|
|
12359
|
+
states,
|
|
12360
|
+
currentState,
|
|
12361
|
+
transitions: objRules(obj).map((r) => ({
|
|
12362
|
+
from: currentState,
|
|
12363
|
+
to: states.find((s) => s !== currentState) || currentState,
|
|
12364
|
+
event: r.whenEvent
|
|
12365
|
+
}))
|
|
12366
|
+
};
|
|
12367
|
+
return { obj, machine };
|
|
12368
|
+
});
|
|
12369
|
+
const hint = str(resolved.hint);
|
|
12370
|
+
const showHint = attempts >= 3 && hint;
|
|
12371
|
+
const theme = resolved.theme ?? void 0;
|
|
12372
|
+
const themeBackground = theme?.background;
|
|
12373
|
+
const headerImage = str(resolved.headerImage);
|
|
12374
|
+
const encourageKey = ENCOURAGEMENT_KEYS2[Math.min(attempts - 1, ENCOURAGEMENT_KEYS2.length - 1)] ?? ENCOURAGEMENT_KEYS2[0];
|
|
12375
|
+
return /* @__PURE__ */ jsxs(
|
|
12376
|
+
VStack,
|
|
12377
|
+
{
|
|
12378
|
+
className: cn("p-4 gap-6", className),
|
|
12379
|
+
style: {
|
|
12380
|
+
backgroundImage: themeBackground ? `url(${themeBackground})` : void 0,
|
|
12381
|
+
backgroundSize: "cover",
|
|
12382
|
+
backgroundPosition: "center"
|
|
12383
|
+
},
|
|
12384
|
+
children: [
|
|
12385
|
+
headerImage && !headerError ? /* @__PURE__ */ jsx(Box, { className: "w-full h-32 overflow-hidden rounded-container", children: /* @__PURE__ */ jsx("img", { src: headerImage, alt: "", onError: () => setHeaderError(true), className: "w-full h-full object-cover" }) }) : headerImage && headerError ? /* @__PURE__ */ jsx(Box, { className: "w-full h-32 rounded-container bg-gradient-to-br from-muted to-accent opacity-60" }) : null,
|
|
12386
|
+
/* @__PURE__ */ jsxs(VStack, { gap: "xs", children: [
|
|
12387
|
+
/* @__PURE__ */ jsx(Typography, { variant: "h4", className: "text-foreground", children: str(resolved.title) }),
|
|
12388
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-muted-foreground", children: str(resolved.description) }),
|
|
12389
|
+
/* @__PURE__ */ jsxs(HStack, { className: "items-center p-2 rounded bg-primary/10 border border-primary/30", gap: "xs", children: [
|
|
12390
|
+
/* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-primary font-bold", children: t("game.goal") + ":" }),
|
|
12391
|
+
/* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-foreground", children: str(resolved.goalCondition) })
|
|
12392
|
+
] })
|
|
12393
|
+
] }),
|
|
12394
|
+
/* @__PURE__ */ jsxs(VStack, { gap: "sm", children: [
|
|
12395
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-muted-foreground font-medium", children: t("eventHandler.clickObject") + ":" }),
|
|
12396
|
+
/* @__PURE__ */ jsx(HStack, { className: "flex-wrap", gap: "sm", children: objectViewers.map(({ obj, machine }) => {
|
|
12397
|
+
const oid = objId(obj);
|
|
12398
|
+
return /* @__PURE__ */ jsx(
|
|
12399
|
+
Box,
|
|
12400
|
+
{
|
|
12401
|
+
className: cn(
|
|
12402
|
+
"p-3 rounded-container border-2 cursor-pointer transition-all hover:scale-105",
|
|
12403
|
+
selectedObjectId === oid ? "border-primary bg-primary/10" : "border-border bg-card hover:border-muted-foreground"
|
|
12404
|
+
),
|
|
12405
|
+
onClick: () => setSelectedObjectId(oid),
|
|
12406
|
+
children: /* @__PURE__ */ jsxs(VStack, { gap: "xs", className: "items-center min-w-[120px]", children: [
|
|
12407
|
+
/* @__PURE__ */ jsx(Typography, { variant: "h5", children: objIcon(obj) }),
|
|
12408
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-foreground font-medium", children: objName(obj) }),
|
|
12409
|
+
/* @__PURE__ */ jsx(TraitStateViewer, { trait: machine, variant: "compact", size: "sm" })
|
|
12410
|
+
] })
|
|
12411
|
+
},
|
|
12412
|
+
oid
|
|
12413
|
+
);
|
|
12414
|
+
}) })
|
|
12415
|
+
] }),
|
|
12416
|
+
selectedObject && /* @__PURE__ */ jsx(
|
|
12417
|
+
ObjectRulePanel,
|
|
12418
|
+
{
|
|
12419
|
+
object: selectedObject,
|
|
12420
|
+
onRulesChange: handleRulesChange,
|
|
12421
|
+
disabled: isPlaying
|
|
12422
|
+
}
|
|
12423
|
+
),
|
|
12424
|
+
eventLog.length > 0 && /* @__PURE__ */ jsx(EventLog, { entries: eventLog }),
|
|
12425
|
+
isSuccess && /* @__PURE__ */ jsx(Box, { className: "p-4 rounded-container bg-success/20 border border-success text-center", children: /* @__PURE__ */ jsx(Typography, { variant: "h5", className: "text-success", children: str(resolved.successMessage) || t("eventHandler.chainComplete") }) }),
|
|
12426
|
+
!isPlaying && !isSuccess && attempts > 0 && /* @__PURE__ */ jsxs(VStack, { gap: "sm", children: [
|
|
12427
|
+
/* @__PURE__ */ jsx(Box, { className: "p-4 rounded-container bg-warning/10 border border-warning/30 text-center", children: /* @__PURE__ */ jsx(Typography, { variant: "body1", className: "text-foreground font-medium", children: t(encourageKey) }) }),
|
|
12428
|
+
showHint && /* @__PURE__ */ jsx(Box, { className: "p-3 rounded-container bg-accent/10 border border-accent/30", children: /* @__PURE__ */ jsxs(HStack, { className: "items-start", gap: "xs", children: [
|
|
12429
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-accent font-bold shrink-0", children: "\u{1F4A1} " + t("game.hint") + ":" }),
|
|
12430
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-foreground", children: hint })
|
|
12431
|
+
] }) })
|
|
12432
|
+
] }),
|
|
12433
|
+
/* @__PURE__ */ jsxs(HStack, { gap: "sm", children: [
|
|
12434
|
+
!isPlaying && !isSuccess && attempts > 0 ? /* @__PURE__ */ jsx(Button, { variant: "primary", onClick: handleTryAgain, children: "\u{1F504} " + t("puzzle.tryAgainButton") }) : /* @__PURE__ */ jsx(
|
|
12435
|
+
Button,
|
|
12436
|
+
{
|
|
12437
|
+
variant: "primary",
|
|
12438
|
+
onClick: handlePlay,
|
|
12439
|
+
disabled: isPlaying || isSuccess,
|
|
12440
|
+
children: "\u25B6 " + t("game.play")
|
|
12441
|
+
}
|
|
12442
|
+
),
|
|
12443
|
+
/* @__PURE__ */ jsx(Button, { variant: "ghost", onClick: handleReset, children: "\u21BA " + t("game.reset") })
|
|
12444
|
+
] })
|
|
12445
|
+
]
|
|
12446
|
+
}
|
|
12447
|
+
);
|
|
12448
|
+
}
|
|
12449
|
+
var ENCOURAGEMENT_KEYS2;
|
|
12450
|
+
var init_EventHandlerBoard = __esm({
|
|
12451
|
+
"components/game/2d/organisms/EventHandlerBoard.tsx"() {
|
|
12452
|
+
init_atoms();
|
|
12453
|
+
init_cn();
|
|
12454
|
+
init_useEventBus();
|
|
12455
|
+
init_TraitStateViewer();
|
|
12456
|
+
init_ObjectRulePanel();
|
|
12457
|
+
init_EventLog();
|
|
12458
|
+
init_puzzleObject();
|
|
12459
|
+
init_boardEntity();
|
|
12460
|
+
ENCOURAGEMENT_KEYS2 = [
|
|
12461
|
+
"puzzle.tryAgain1",
|
|
12462
|
+
"puzzle.tryAgain2",
|
|
12463
|
+
"puzzle.tryAgain3"
|
|
12464
|
+
];
|
|
12465
|
+
EventHandlerBoard.displayName = "EventHandlerBoard";
|
|
12466
|
+
}
|
|
12467
|
+
});
|
|
12468
|
+
function VariablePanel({
|
|
12469
|
+
entityName,
|
|
12470
|
+
variables,
|
|
12471
|
+
className
|
|
12472
|
+
}) {
|
|
12473
|
+
const { t } = useTranslate();
|
|
12474
|
+
return /* @__PURE__ */ jsxs(VStack, { className: cn("p-3 rounded-lg bg-card border border-border", className), gap: "sm", children: [
|
|
12475
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-muted-foreground font-medium", children: t("stateArchitect.variables", { name: entityName }) }),
|
|
12476
|
+
variables.map((v) => {
|
|
12477
|
+
const name = v.name == null ? "" : String(v.name);
|
|
12478
|
+
const value = numField(v.value);
|
|
12479
|
+
const max = numField(v.max, 100);
|
|
12480
|
+
const min = numField(v.min, 0);
|
|
12481
|
+
const unit = v.unit == null ? "" : String(v.unit);
|
|
12482
|
+
const pct = Math.round((value - min) / (max - min) * 100);
|
|
12483
|
+
const isHigh = pct > 80;
|
|
12484
|
+
const isLow = pct < 20;
|
|
12485
|
+
return /* @__PURE__ */ jsxs(VStack, { gap: "none", children: [
|
|
12486
|
+
/* @__PURE__ */ jsxs(HStack, { className: "items-center justify-between", children: [
|
|
12487
|
+
/* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-foreground font-medium", children: name }),
|
|
12488
|
+
/* @__PURE__ */ jsxs(Typography, { variant: "caption", className: cn(
|
|
12489
|
+
isHigh ? "text-error" : isLow ? "text-warning" : "text-foreground"
|
|
12490
|
+
), children: [
|
|
12491
|
+
value,
|
|
12492
|
+
unit,
|
|
12493
|
+
" / ",
|
|
12494
|
+
max,
|
|
12495
|
+
unit
|
|
12496
|
+
] })
|
|
12497
|
+
] }),
|
|
12498
|
+
/* @__PURE__ */ jsx(
|
|
12499
|
+
ProgressBar,
|
|
12500
|
+
{
|
|
12501
|
+
value: pct,
|
|
12502
|
+
color: isHigh ? "danger" : isLow ? "warning" : "primary",
|
|
12503
|
+
size: "sm"
|
|
12504
|
+
}
|
|
12505
|
+
)
|
|
12506
|
+
] }, name);
|
|
12507
|
+
})
|
|
12508
|
+
] });
|
|
12509
|
+
}
|
|
12510
|
+
var numField;
|
|
12511
|
+
var init_VariablePanel = __esm({
|
|
12512
|
+
"components/game/2d/organisms/VariablePanel.tsx"() {
|
|
12513
|
+
init_atoms();
|
|
12514
|
+
init_cn();
|
|
12515
|
+
numField = (v, fallback = 0) => {
|
|
12516
|
+
const n = Number(v);
|
|
12517
|
+
return Number.isFinite(n) ? n : fallback;
|
|
12518
|
+
};
|
|
12519
|
+
VariablePanel.displayName = "VariablePanel";
|
|
12520
|
+
}
|
|
12521
|
+
});
|
|
12522
|
+
function StateJsonView({
|
|
12523
|
+
data,
|
|
12524
|
+
label,
|
|
12525
|
+
defaultExpanded = false,
|
|
12526
|
+
className
|
|
12527
|
+
}) {
|
|
12528
|
+
const { t } = useTranslate();
|
|
12529
|
+
const [expanded, setExpanded] = useState(defaultExpanded);
|
|
12530
|
+
const jsonString = JSON.stringify(data, null, 2);
|
|
12531
|
+
return /* @__PURE__ */ jsxs(VStack, { className: cn("rounded-lg border border-border overflow-hidden", className), gap: "none", children: [
|
|
12532
|
+
/* @__PURE__ */ jsxs(HStack, { className: "items-center justify-between p-2 bg-muted", gap: "sm", children: [
|
|
12533
|
+
/* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-muted-foreground font-medium", children: label ?? t("stateArchitect.viewCode") }),
|
|
12534
|
+
/* @__PURE__ */ jsx(Button, { variant: "ghost", onClick: () => setExpanded(!expanded), className: "text-xs", children: expanded ? t("stateArchitect.hideJson") : t("stateArchitect.showJson") })
|
|
12535
|
+
] }),
|
|
12536
|
+
expanded && /* @__PURE__ */ jsx(Box, { className: "p-3 bg-background overflow-x-auto", children: /* @__PURE__ */ jsx(
|
|
12537
|
+
Typography,
|
|
12538
|
+
{
|
|
12539
|
+
variant: "caption",
|
|
12540
|
+
className: "text-foreground font-mono whitespace-pre text-xs leading-relaxed block",
|
|
12541
|
+
children: jsonString
|
|
12542
|
+
}
|
|
12543
|
+
) })
|
|
12544
|
+
] });
|
|
12545
|
+
}
|
|
12546
|
+
var init_StateJsonView = __esm({
|
|
12547
|
+
"components/game/2d/organisms/StateJsonView.tsx"() {
|
|
12548
|
+
init_atoms();
|
|
12549
|
+
init_cn();
|
|
12550
|
+
StateJsonView.displayName = "StateJsonView";
|
|
12551
|
+
}
|
|
12552
|
+
});
|
|
12553
|
+
function layoutStates2(states, width, height) {
|
|
12554
|
+
const cx = width / 2;
|
|
12555
|
+
const cy = height / 2;
|
|
12556
|
+
const radius = Math.min(cx, cy) - 60;
|
|
12557
|
+
const positions = {};
|
|
12558
|
+
states.forEach((state, i) => {
|
|
12559
|
+
const angle = 2 * Math.PI * i / states.length - Math.PI / 2;
|
|
12560
|
+
positions[state] = {
|
|
12561
|
+
x: cx + radius * Math.cos(angle),
|
|
12562
|
+
y: cy + radius * Math.sin(angle)
|
|
12563
|
+
};
|
|
12564
|
+
});
|
|
12565
|
+
return positions;
|
|
12566
|
+
}
|
|
12567
|
+
function StateArchitectBoard({
|
|
12568
|
+
entity,
|
|
12569
|
+
stepDurationMs = 600,
|
|
12570
|
+
testEvent,
|
|
12571
|
+
completeEvent,
|
|
12572
|
+
addTransitionEvent,
|
|
12573
|
+
removeTransitionEvent,
|
|
12574
|
+
playAgainEvent,
|
|
12575
|
+
className
|
|
12576
|
+
}) {
|
|
12577
|
+
const { emit } = useEventBus();
|
|
12578
|
+
const { t } = useTranslate();
|
|
12579
|
+
const resolved = boardEntity(entity);
|
|
12580
|
+
const entityStates = Array.isArray(resolved?.states) ? resolved.states : [];
|
|
12581
|
+
const initialState = str(resolved?.initialState);
|
|
12582
|
+
const entityName = str(resolved?.entityName);
|
|
12583
|
+
const availableEvents = Array.isArray(resolved?.availableEvents) ? resolved.availableEvents : [];
|
|
12584
|
+
const testCases = (Array.isArray(resolved?.testCases) ? resolved.testCases : []).map((item) => {
|
|
12585
|
+
const o = typeof item === "object" && item !== null && !Array.isArray(item) ? item : {};
|
|
12586
|
+
const eventsField = o["events"];
|
|
12587
|
+
return {
|
|
12588
|
+
events: Array.isArray(eventsField) ? eventsField : [],
|
|
12589
|
+
expectedState: str(o["expectedState"]),
|
|
12590
|
+
label: str(o["label"])
|
|
12591
|
+
};
|
|
12592
|
+
});
|
|
12593
|
+
const entityTransitions = (Array.isArray(resolved?.transitions) ? resolved.transitions : []).map((item) => {
|
|
12594
|
+
const o = typeof item === "object" && item !== null && !Array.isArray(item) ? item : {};
|
|
12595
|
+
return {
|
|
12596
|
+
id: str(o["id"]),
|
|
12597
|
+
from: str(o["from"]),
|
|
12598
|
+
to: str(o["to"]),
|
|
12599
|
+
event: str(o["event"]),
|
|
12600
|
+
...o["guardHint"] ? { guardHint: str(o["guardHint"]) } : {}
|
|
12601
|
+
};
|
|
12602
|
+
});
|
|
12603
|
+
const entityVariables = rows(resolved?.variables);
|
|
12604
|
+
const transitions = entityTransitions;
|
|
12605
|
+
const attempts = typeof resolved?.attempts === "number" ? resolved.attempts : 0;
|
|
12606
|
+
const entityResult = str(resolved?.result) || "none";
|
|
12607
|
+
const isSuccess = entityResult === "win";
|
|
12608
|
+
const [isTesting, setIsTesting] = useState(false);
|
|
12609
|
+
const [headerError, setHeaderError] = useState(false);
|
|
12610
|
+
const [currentState, setCurrentState] = useState(initialState);
|
|
12611
|
+
const [selectedState, setSelectedState] = useState(null);
|
|
12612
|
+
const [testResults, setTestResults] = useState([]);
|
|
12613
|
+
const [variables, setVariables] = useState(() => [...entityVariables]);
|
|
12614
|
+
const timerRef = useRef(null);
|
|
12615
|
+
const [addingFrom, setAddingFrom] = useState(null);
|
|
12616
|
+
useEffect(() => () => {
|
|
12617
|
+
if (timerRef.current) clearTimeout(timerRef.current);
|
|
12618
|
+
}, []);
|
|
12619
|
+
const GRAPH_W = 500;
|
|
12620
|
+
const GRAPH_H = 400;
|
|
12621
|
+
const positions = useMemo(() => layoutStates2(entityStates, GRAPH_W, GRAPH_H), [entityStates]);
|
|
12622
|
+
const handleStateClick = useCallback((state) => {
|
|
12623
|
+
if (isTesting) return;
|
|
12624
|
+
if (addingFrom) {
|
|
12625
|
+
if (addingFrom !== state) {
|
|
12626
|
+
const event = availableEvents[0] || "EVENT";
|
|
12627
|
+
const newTrans = {
|
|
12628
|
+
id: `t-${nextTransId++}`,
|
|
12629
|
+
from: addingFrom,
|
|
12630
|
+
to: state,
|
|
12631
|
+
event
|
|
12632
|
+
};
|
|
12633
|
+
if (addTransitionEvent) emit(`UI:${addTransitionEvent}`, { id: newTrans.id, from: newTrans.from, to: newTrans.to, event: newTrans.event });
|
|
12634
|
+
}
|
|
12635
|
+
setAddingFrom(null);
|
|
12636
|
+
} else {
|
|
12637
|
+
setSelectedState(state);
|
|
12638
|
+
}
|
|
12639
|
+
}, [isTesting, addingFrom, availableEvents, addTransitionEvent, emit]);
|
|
12640
|
+
const handleStartAddTransition = useCallback(() => {
|
|
12641
|
+
if (!selectedState) return;
|
|
12642
|
+
setAddingFrom(selectedState);
|
|
12643
|
+
}, [selectedState]);
|
|
12644
|
+
const handleRemoveTransition = useCallback((transId) => {
|
|
12645
|
+
if (removeTransitionEvent) emit(`UI:${removeTransitionEvent}`, { id: transId });
|
|
12646
|
+
}, [removeTransitionEvent, emit]);
|
|
12647
|
+
const machine = useMemo(() => ({
|
|
12648
|
+
name: entityName,
|
|
12649
|
+
description: str(resolved?.description),
|
|
12650
|
+
states: entityStates,
|
|
12651
|
+
currentState,
|
|
12652
|
+
transitions: transitions.map((t2) => ({
|
|
12653
|
+
from: t2.from,
|
|
12654
|
+
to: t2.to,
|
|
12655
|
+
event: t2.event,
|
|
12656
|
+
guardHint: t2.guardHint
|
|
12657
|
+
}))
|
|
12658
|
+
}), [entityName, resolved, entityStates, currentState, transitions]);
|
|
12659
|
+
const handleTest = useCallback(() => {
|
|
12660
|
+
if (isTesting) return;
|
|
12661
|
+
if (testEvent) emit(`UI:${testEvent}`, {});
|
|
12662
|
+
setIsTesting(true);
|
|
12663
|
+
setTestResults([]);
|
|
12664
|
+
const results = [];
|
|
12665
|
+
let testIdx = 0;
|
|
12666
|
+
const runNextTest = () => {
|
|
12667
|
+
if (testIdx >= testCases.length) {
|
|
12668
|
+
const allPassed = results.every((r) => r.passed);
|
|
12669
|
+
setIsTesting(false);
|
|
12670
|
+
setTestResults(results);
|
|
12671
|
+
if (allPassed && completeEvent) {
|
|
12672
|
+
emit(`UI:${completeEvent}`, {
|
|
12673
|
+
success: true,
|
|
12674
|
+
passedTests: results.filter((r) => r.passed).length
|
|
12675
|
+
});
|
|
12676
|
+
}
|
|
12677
|
+
return;
|
|
12678
|
+
}
|
|
12679
|
+
const testCase = testCases[testIdx];
|
|
12680
|
+
if (!testCase) return;
|
|
12681
|
+
let state = initialState;
|
|
12682
|
+
for (const event of testCase.events) {
|
|
12683
|
+
const trans = transitions.find((t2) => t2.from === state && t2.event === event);
|
|
12684
|
+
if (trans) {
|
|
12685
|
+
state = trans.to;
|
|
12686
|
+
}
|
|
12687
|
+
}
|
|
12688
|
+
setCurrentState(state);
|
|
12689
|
+
results.push({
|
|
12690
|
+
label: testCase.label,
|
|
12691
|
+
passed: state === testCase.expectedState,
|
|
12692
|
+
actualState: state,
|
|
12693
|
+
expectedState: testCase.expectedState
|
|
12694
|
+
});
|
|
12695
|
+
testIdx++;
|
|
12696
|
+
timerRef.current = setTimeout(runNextTest, stepDurationMs);
|
|
12697
|
+
};
|
|
12698
|
+
timerRef.current = setTimeout(runNextTest, stepDurationMs);
|
|
12699
|
+
}, [isTesting, transitions, testCases, initialState, stepDurationMs, testEvent, completeEvent, emit]);
|
|
12700
|
+
const handleTryAgain = useCallback(() => {
|
|
12701
|
+
if (timerRef.current) clearTimeout(timerRef.current);
|
|
12702
|
+
setIsTesting(false);
|
|
12703
|
+
setCurrentState(initialState);
|
|
12704
|
+
setTestResults([]);
|
|
12705
|
+
}, [initialState]);
|
|
12706
|
+
const handleReset = useCallback(() => {
|
|
12707
|
+
if (timerRef.current) clearTimeout(timerRef.current);
|
|
12708
|
+
setIsTesting(false);
|
|
12709
|
+
setCurrentState(initialState);
|
|
12710
|
+
setTestResults([]);
|
|
12711
|
+
setVariables([...entityVariables]);
|
|
12712
|
+
setSelectedState(null);
|
|
12713
|
+
setAddingFrom(null);
|
|
12714
|
+
if (playAgainEvent) emit(`UI:${playAgainEvent}`, {});
|
|
12715
|
+
}, [initialState, entityVariables, playAgainEvent, emit]);
|
|
12716
|
+
const codeData = useMemo(() => ({
|
|
12717
|
+
name: entityName,
|
|
12718
|
+
states: entityStates,
|
|
12719
|
+
initialState,
|
|
12720
|
+
transitions: transitions.map((t2) => ({
|
|
12721
|
+
from: t2.from,
|
|
12722
|
+
to: t2.to,
|
|
12723
|
+
event: t2.event,
|
|
12724
|
+
...t2.guardHint ? { guard: t2.guardHint } : {}
|
|
12725
|
+
}))
|
|
12726
|
+
}), [entityName, entityStates, initialState, transitions]);
|
|
12727
|
+
if (!resolved) return null;
|
|
12728
|
+
const theme = resolved.theme ?? void 0;
|
|
12729
|
+
const themeBackground = theme?.background;
|
|
12730
|
+
const headerImage = str(resolved.headerImage);
|
|
12731
|
+
const hint = str(resolved.hint);
|
|
12732
|
+
return /* @__PURE__ */ jsxs(
|
|
12733
|
+
VStack,
|
|
12734
|
+
{
|
|
12735
|
+
className: cn("p-4 gap-6", className),
|
|
12736
|
+
style: {
|
|
12737
|
+
backgroundImage: themeBackground ? `url(${themeBackground})` : void 0,
|
|
12738
|
+
backgroundSize: "cover",
|
|
12739
|
+
backgroundPosition: "center"
|
|
12740
|
+
},
|
|
12741
|
+
children: [
|
|
12742
|
+
headerImage && !headerError ? /* @__PURE__ */ jsx(Box, { className: "w-full h-32 overflow-hidden rounded-container", children: /* @__PURE__ */ jsx("img", { src: headerImage, alt: "", onError: () => setHeaderError(true), className: "w-full h-full object-cover" }) }) : headerImage && headerError ? /* @__PURE__ */ jsx(Box, { className: "w-full h-32 rounded-container bg-gradient-to-br from-muted to-accent opacity-60" }) : null,
|
|
12743
|
+
/* @__PURE__ */ jsxs(VStack, { gap: "xs", children: [
|
|
12744
|
+
/* @__PURE__ */ jsx(Typography, { variant: "h4", className: "text-foreground", children: str(resolved.title) }),
|
|
12745
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-muted-foreground", children: str(resolved.description) }),
|
|
12746
|
+
/* @__PURE__ */ jsxs(HStack, { className: "items-center p-2 rounded bg-warning/10 border border-warning/30", gap: "xs", children: [
|
|
12747
|
+
/* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-warning font-bold", children: t("game.hint") + ":" }),
|
|
12748
|
+
/* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-foreground", children: hint })
|
|
12749
|
+
] })
|
|
12750
|
+
] }),
|
|
12751
|
+
/* @__PURE__ */ jsxs(HStack, { className: "flex-wrap items-start", gap: "lg", children: [
|
|
12752
|
+
/* @__PURE__ */ jsxs(VStack, { gap: "sm", className: "flex-1 min-w-[300px]", children: [
|
|
12753
|
+
/* @__PURE__ */ jsxs(HStack, { className: "items-center justify-between", children: [
|
|
12754
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-muted-foreground font-medium", children: t("stateArchitect.graph") }),
|
|
12755
|
+
addingFrom && /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-accent animate-pulse", children: t("stateArchitect.clickTarget", { state: addingFrom || "" }) })
|
|
12756
|
+
] }),
|
|
12757
|
+
/* @__PURE__ */ jsxs(
|
|
12758
|
+
Box,
|
|
12759
|
+
{
|
|
12760
|
+
position: "relative",
|
|
12761
|
+
className: "rounded-container border border-border bg-background overflow-hidden",
|
|
12762
|
+
style: { width: GRAPH_W, height: GRAPH_H },
|
|
12763
|
+
children: [
|
|
12764
|
+
/* @__PURE__ */ jsxs(
|
|
12765
|
+
"svg",
|
|
12766
|
+
{
|
|
12767
|
+
width: GRAPH_W,
|
|
12768
|
+
height: GRAPH_H,
|
|
12769
|
+
className: "absolute inset-0",
|
|
12770
|
+
style: { pointerEvents: "none" },
|
|
12771
|
+
children: [
|
|
12772
|
+
/* @__PURE__ */ jsxs("defs", { children: [
|
|
12773
|
+
/* @__PURE__ */ jsx("marker", { id: "arrowhead", markerWidth: "10", markerHeight: "7", refX: "10", refY: "3.5", orient: "auto", children: /* @__PURE__ */ jsx("polygon", { points: "0 0, 10 3.5, 0 7", fill: "var(--color-border)" }) }),
|
|
12774
|
+
/* @__PURE__ */ jsx("marker", { id: "arrowhead-active", markerWidth: "10", markerHeight: "7", refX: "10", refY: "3.5", orient: "auto", children: /* @__PURE__ */ jsx("polygon", { points: "0 0, 10 3.5, 0 7", fill: "var(--color-primary)" }) })
|
|
12775
|
+
] }),
|
|
12776
|
+
transitions.map((t2) => {
|
|
12777
|
+
const fromPos = positions[t2.from];
|
|
12778
|
+
const toPos = positions[t2.to];
|
|
12779
|
+
if (!fromPos || !toPos) return null;
|
|
12780
|
+
const isActive = t2.from === currentState;
|
|
12781
|
+
return /* @__PURE__ */ jsx(
|
|
12782
|
+
TransitionArrow,
|
|
12783
|
+
{
|
|
12784
|
+
from: fromPos,
|
|
12785
|
+
to: toPos,
|
|
12786
|
+
eventLabel: t2.event,
|
|
12787
|
+
guardHint: t2.guardHint,
|
|
12788
|
+
isActive
|
|
12789
|
+
},
|
|
12790
|
+
t2.id
|
|
12791
|
+
);
|
|
12792
|
+
})
|
|
12793
|
+
]
|
|
12794
|
+
}
|
|
12795
|
+
),
|
|
12796
|
+
entityStates.map((state) => /* @__PURE__ */ jsx(
|
|
12797
|
+
StateNode,
|
|
12798
|
+
{
|
|
12799
|
+
name: state,
|
|
12800
|
+
position: positions[state],
|
|
12801
|
+
isCurrent: state === currentState,
|
|
12802
|
+
isSelected: state === selectedState,
|
|
12803
|
+
isInitial: state === initialState,
|
|
12804
|
+
onClick: () => handleStateClick(state)
|
|
12805
|
+
},
|
|
12806
|
+
state
|
|
12807
|
+
))
|
|
12808
|
+
]
|
|
12809
|
+
}
|
|
12810
|
+
),
|
|
12811
|
+
!isTesting && /* @__PURE__ */ jsx(HStack, { gap: "sm", children: /* @__PURE__ */ jsx(
|
|
12812
|
+
Button,
|
|
12813
|
+
{
|
|
12814
|
+
variant: "ghost",
|
|
12815
|
+
onClick: handleStartAddTransition,
|
|
12816
|
+
disabled: !selectedState,
|
|
12817
|
+
children: selectedState ? t("stateArchitect.addTransition", { state: selectedState }) : t("stateArchitect.addTransitionPrompt")
|
|
12818
|
+
}
|
|
12819
|
+
) }),
|
|
12820
|
+
transitions.length > 0 && /* @__PURE__ */ jsxs(VStack, { gap: "xs", className: "p-3 rounded-container bg-muted/50 border border-border", children: [
|
|
12821
|
+
/* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-muted-foreground font-medium", children: t("stateArchitect.transitions", { count: transitions.length }) + ":" }),
|
|
12822
|
+
transitions.map((t2) => /* @__PURE__ */ jsxs(HStack, { className: "items-center text-xs", gap: "xs", children: [
|
|
12823
|
+
/* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-foreground", children: t2.from }),
|
|
12824
|
+
/* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-muted-foreground", children: "\u2014[" }),
|
|
12825
|
+
/* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-accent font-medium", children: t2.event }),
|
|
12826
|
+
/* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-muted-foreground", children: "]\u2192" }),
|
|
12827
|
+
/* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-success", children: t2.to }),
|
|
12828
|
+
t2.guardHint && /* @__PURE__ */ jsxs(Typography, { variant: "caption", className: "text-warning", children: [
|
|
12829
|
+
"(",
|
|
12830
|
+
t2.guardHint,
|
|
12831
|
+
")"
|
|
12832
|
+
] }),
|
|
12833
|
+
!isTesting && /* @__PURE__ */ jsx(
|
|
12834
|
+
Button,
|
|
12835
|
+
{
|
|
12836
|
+
variant: "ghost",
|
|
12837
|
+
onClick: () => handleRemoveTransition(t2.id),
|
|
12838
|
+
className: "text-xs ml-auto",
|
|
12839
|
+
children: "\xD7"
|
|
12840
|
+
}
|
|
12841
|
+
)
|
|
12842
|
+
] }, t2.id))
|
|
12843
|
+
] })
|
|
12844
|
+
] }),
|
|
12845
|
+
/* @__PURE__ */ jsxs(VStack, { gap: "sm", className: "w-[280px] shrink-0", children: [
|
|
12846
|
+
/* @__PURE__ */ jsx(TraitStateViewer, { trait: machine, variant: "full", size: "sm" }),
|
|
12847
|
+
/* @__PURE__ */ jsx(
|
|
12848
|
+
VariablePanel,
|
|
12849
|
+
{
|
|
12850
|
+
entityName,
|
|
12851
|
+
variables
|
|
12852
|
+
}
|
|
12853
|
+
),
|
|
12854
|
+
testResults.length > 0 && /* @__PURE__ */ jsxs(VStack, { className: "p-3 rounded-container bg-card border border-border", gap: "xs", children: [
|
|
12855
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-muted-foreground font-medium", children: t("stateArchitect.testResults") + ":" }),
|
|
12856
|
+
testResults.map((r, i) => /* @__PURE__ */ jsxs(HStack, { className: "items-center text-xs", gap: "xs", children: [
|
|
12857
|
+
/* @__PURE__ */ jsx(Typography, { variant: "caption", className: r.passed ? "text-success" : "text-error", children: r.passed ? "\u2714" : "\u2717" }),
|
|
12858
|
+
/* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-foreground flex-1", children: r.label }),
|
|
12859
|
+
!r.passed && /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-error", children: t("stateArchitect.gotState", { state: r.actualState }) })
|
|
12860
|
+
] }, i))
|
|
12861
|
+
] }),
|
|
12862
|
+
resolved.showCodeView !== false && /* @__PURE__ */ jsx(StateJsonView, { data: codeData, label: "View Code" })
|
|
12863
|
+
] })
|
|
12864
|
+
] }),
|
|
12865
|
+
isSuccess && /* @__PURE__ */ jsx(Box, { className: "p-4 rounded-container bg-success/20 border border-success text-center", children: /* @__PURE__ */ jsx(Typography, { variant: "h5", className: "text-success", children: str(resolved.successMessage) || t("stateArchitect.allPassed") }) }),
|
|
12866
|
+
!isTesting && !isSuccess && testResults.some((r) => !r.passed) && /* @__PURE__ */ jsxs(VStack, { gap: "sm", children: [
|
|
12867
|
+
/* @__PURE__ */ jsx(Box, { className: "p-4 rounded-container bg-warning/10 border border-warning/30 text-center", children: /* @__PURE__ */ jsx(Typography, { variant: "body1", className: "text-foreground font-medium", children: t(ENCOURAGEMENT_KEYS3[Math.min(attempts - 1, ENCOURAGEMENT_KEYS3.length - 1)] ?? ENCOURAGEMENT_KEYS3[0]) }) }),
|
|
12868
|
+
!isSuccess && attempts >= 2 && Boolean(str(resolved?.hint)) && /* @__PURE__ */ jsx(Box, { className: "p-3 rounded-container bg-accent/10 border border-accent/30", children: /* @__PURE__ */ jsxs(HStack, { className: "items-start", gap: "xs", children: [
|
|
12869
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-accent font-bold shrink-0", children: "\u{1F4A1} " + t("game.hint") + ":" }),
|
|
12870
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-foreground", children: hint })
|
|
12871
|
+
] }) })
|
|
12872
|
+
] }),
|
|
12873
|
+
/* @__PURE__ */ jsxs(HStack, { gap: "sm", children: [
|
|
12874
|
+
!isTesting && !isSuccess && testResults.some((r) => !r.passed) ? /* @__PURE__ */ jsx(Button, { variant: "primary", onClick: handleTryAgain, children: "\u{1F504} " + t("puzzle.tryAgainButton") }) : /* @__PURE__ */ jsx(
|
|
12875
|
+
Button,
|
|
12876
|
+
{
|
|
12877
|
+
variant: "primary",
|
|
12878
|
+
onClick: handleTest,
|
|
12879
|
+
disabled: isTesting,
|
|
12880
|
+
children: "\u25B6 " + t("game.runTests")
|
|
12881
|
+
}
|
|
12882
|
+
),
|
|
12883
|
+
/* @__PURE__ */ jsx(Button, { variant: "ghost", onClick: handleReset, children: "\u21BA " + t("game.reset") })
|
|
12884
|
+
] })
|
|
12885
|
+
]
|
|
12886
|
+
}
|
|
12887
|
+
);
|
|
12888
|
+
}
|
|
12889
|
+
var ENCOURAGEMENT_KEYS3, nextTransId;
|
|
12890
|
+
var init_StateArchitectBoard = __esm({
|
|
12891
|
+
"components/game/2d/organisms/StateArchitectBoard.tsx"() {
|
|
12892
|
+
init_atoms();
|
|
12893
|
+
init_cn();
|
|
12894
|
+
init_useEventBus();
|
|
12895
|
+
init_TraitStateViewer();
|
|
12896
|
+
init_StateNode();
|
|
12897
|
+
init_TransitionArrow();
|
|
12898
|
+
init_VariablePanel();
|
|
12899
|
+
init_StateJsonView();
|
|
12900
|
+
init_boardEntity();
|
|
12901
|
+
ENCOURAGEMENT_KEYS3 = [
|
|
12902
|
+
"puzzle.tryAgain1",
|
|
12903
|
+
"puzzle.tryAgain2",
|
|
12904
|
+
"puzzle.tryAgain3"
|
|
12905
|
+
];
|
|
12906
|
+
nextTransId = 100;
|
|
12907
|
+
StateArchitectBoard.displayName = "StateArchitectBoard";
|
|
12908
|
+
}
|
|
12909
|
+
});
|
|
12910
|
+
function readSimulatorParameters(v) {
|
|
12911
|
+
if (!Array.isArray(v)) return [];
|
|
12912
|
+
const result = [];
|
|
12913
|
+
for (const item of v) {
|
|
12914
|
+
if (typeof item === "object" && item !== null && !Array.isArray(item) && !(item instanceof Date)) {
|
|
12915
|
+
const param = item;
|
|
12916
|
+
if ("id" in item && "label" in item && "unit" in item && "min" in item && "max" in item && "step" in item) {
|
|
12917
|
+
result.push({
|
|
12918
|
+
id: str(param.id),
|
|
12919
|
+
label: str(param.label),
|
|
12920
|
+
unit: str(param.unit),
|
|
12921
|
+
min: num(param.min),
|
|
12922
|
+
max: num(param.max),
|
|
12923
|
+
step: num(param.step),
|
|
12924
|
+
initial: num(param.initial),
|
|
12925
|
+
correct: num(param.correct),
|
|
12926
|
+
tolerance: num(param.tolerance)
|
|
12927
|
+
});
|
|
12928
|
+
}
|
|
12929
|
+
}
|
|
12930
|
+
}
|
|
12931
|
+
return result;
|
|
12932
|
+
}
|
|
12933
|
+
function SimulatorBoard({
|
|
12934
|
+
entity,
|
|
12935
|
+
completeEvent = "PUZZLE_COMPLETE",
|
|
12936
|
+
setAEvent,
|
|
12937
|
+
setBEvent,
|
|
12938
|
+
checkEvent,
|
|
12939
|
+
playAgainEvent,
|
|
12940
|
+
assetManifest,
|
|
12941
|
+
className
|
|
12942
|
+
}) {
|
|
12943
|
+
const ui = assetManifest?.ui;
|
|
12944
|
+
const { emit } = useEventBus();
|
|
12945
|
+
const { t } = useTranslate();
|
|
12946
|
+
const resolved = boardEntity(entity);
|
|
12947
|
+
const parameters = readSimulatorParameters(resolved?.parameters);
|
|
12948
|
+
const [headerError, setHeaderError] = useState(false);
|
|
12949
|
+
if (!resolved) return null;
|
|
12950
|
+
const paramA = num(resolved.paramA);
|
|
12951
|
+
const paramB = num(resolved.paramB);
|
|
12952
|
+
const output = num(resolved.output);
|
|
12953
|
+
const targetValue = num(resolved.target);
|
|
12954
|
+
const targetTolerance = num(resolved.tolerance);
|
|
12955
|
+
const attempts = num(resolved.attempts);
|
|
12956
|
+
const result = str(resolved.result);
|
|
12957
|
+
const isWin = result === "win";
|
|
12958
|
+
const isComplete = result !== "none" && result !== "";
|
|
12959
|
+
const paramAValue = parameters[0];
|
|
12960
|
+
const paramBValue = parameters[1];
|
|
12961
|
+
const sliderValues = [paramA, paramB];
|
|
12962
|
+
const sliderEvents = [setAEvent, setBEvent];
|
|
12963
|
+
const handleParameterChange = (index, value) => {
|
|
12964
|
+
if (isComplete) return;
|
|
12965
|
+
const ev = sliderEvents[index];
|
|
12966
|
+
if (ev) emit(`UI:${ev}`, { value });
|
|
12967
|
+
};
|
|
12968
|
+
const handleCheck = () => {
|
|
12969
|
+
if (checkEvent) emit(`UI:${checkEvent}`, {});
|
|
12970
|
+
};
|
|
12971
|
+
const handlePlayAgain = () => {
|
|
12972
|
+
if (playAgainEvent) emit(`UI:${playAgainEvent}`, {});
|
|
12973
|
+
};
|
|
12974
|
+
const themeBackground = (() => {
|
|
12975
|
+
const t2 = resolved.theme;
|
|
12976
|
+
if (typeof t2 === "object" && t2 !== null && !Array.isArray(t2) && !(t2 instanceof Date)) {
|
|
12977
|
+
const bg = t2.background;
|
|
12978
|
+
return str(bg);
|
|
12979
|
+
}
|
|
12980
|
+
return "";
|
|
12981
|
+
})();
|
|
12982
|
+
const headerImage = str(resolved.headerImage);
|
|
12983
|
+
const hint = str(resolved.hint);
|
|
12984
|
+
const showHint = isComplete && !isWin && attempts >= 2 && Boolean(hint);
|
|
12985
|
+
const outputLabel = str(resolved.outputLabel);
|
|
12986
|
+
const outputUnit = str(resolved.outputUnit);
|
|
12987
|
+
return /* @__PURE__ */ jsx(
|
|
12988
|
+
Box,
|
|
12989
|
+
{
|
|
12990
|
+
className,
|
|
12991
|
+
style: {
|
|
12992
|
+
backgroundImage: themeBackground ? `url(${themeBackground})` : void 0,
|
|
12993
|
+
backgroundSize: "cover",
|
|
12994
|
+
backgroundPosition: "center"
|
|
12995
|
+
},
|
|
12996
|
+
children: /* @__PURE__ */ jsxs(VStack, { gap: "lg", className: "p-4", children: [
|
|
12997
|
+
headerImage && !headerError ? /* @__PURE__ */ jsx(Box, { className: "w-full h-32 overflow-hidden rounded-container", children: /* @__PURE__ */ jsx("img", { src: headerImage, alt: "", onError: () => setHeaderError(true), className: "w-full h-full object-cover" }) }) : headerImage && headerError ? /* @__PURE__ */ jsx(Box, { className: "w-full h-32 rounded-container bg-gradient-to-br from-muted to-accent opacity-60" }) : null,
|
|
12998
|
+
/* @__PURE__ */ jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxs(VStack, { gap: "sm", children: [
|
|
12999
|
+
/* @__PURE__ */ jsx(Typography, { variant: "h4", weight: "bold", children: str(resolved.title) }),
|
|
13000
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body", children: str(resolved.description) })
|
|
13001
|
+
] }) }),
|
|
13002
|
+
/* @__PURE__ */ jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxs(VStack, { gap: "md", children: [
|
|
13003
|
+
/* @__PURE__ */ jsx(Typography, { variant: "small", weight: "bold", className: "uppercase tracking-wider text-muted-foreground", children: t("simulator.parameters") }),
|
|
13004
|
+
[paramAValue, paramBValue].map(
|
|
13005
|
+
(param, index) => param ? /* @__PURE__ */ jsxs(VStack, { gap: "xs", children: [
|
|
13006
|
+
/* @__PURE__ */ jsxs(HStack, { justify: "between", align: "center", children: [
|
|
13007
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body", weight: "medium", children: param.label }),
|
|
13008
|
+
/* @__PURE__ */ jsxs(Badge, { size: "sm", children: [
|
|
13009
|
+
sliderValues[index],
|
|
13010
|
+
" ",
|
|
13011
|
+
param.unit
|
|
13012
|
+
] })
|
|
13013
|
+
] }),
|
|
13014
|
+
/* @__PURE__ */ jsx(
|
|
13015
|
+
"input",
|
|
13016
|
+
{
|
|
13017
|
+
type: "range",
|
|
13018
|
+
min: param.min,
|
|
13019
|
+
max: param.max,
|
|
13020
|
+
step: param.step,
|
|
13021
|
+
value: sliderValues[index],
|
|
13022
|
+
onChange: (e) => handleParameterChange(index, Number(e.target.value)),
|
|
13023
|
+
disabled: isComplete,
|
|
13024
|
+
className: "w-full accent-foreground"
|
|
13025
|
+
}
|
|
13026
|
+
),
|
|
13027
|
+
/* @__PURE__ */ jsxs(HStack, { justify: "between", children: [
|
|
13028
|
+
/* @__PURE__ */ jsxs(Typography, { variant: "caption", className: "text-muted-foreground", children: [
|
|
13029
|
+
param.min,
|
|
13030
|
+
" ",
|
|
13031
|
+
param.unit
|
|
13032
|
+
] }),
|
|
13033
|
+
/* @__PURE__ */ jsxs(Typography, { variant: "caption", className: "text-muted-foreground", children: [
|
|
13034
|
+
param.max,
|
|
13035
|
+
" ",
|
|
13036
|
+
param.unit
|
|
13037
|
+
] })
|
|
13038
|
+
] })
|
|
13039
|
+
] }, param.id ?? index) : null
|
|
13040
|
+
)
|
|
13041
|
+
] }) }),
|
|
13042
|
+
/* @__PURE__ */ jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxs(VStack, { gap: "sm", align: "center", children: [
|
|
13043
|
+
/* @__PURE__ */ jsx(Typography, { variant: "small", weight: "bold", className: "uppercase tracking-wider text-muted-foreground", children: outputLabel }),
|
|
13044
|
+
/* @__PURE__ */ jsxs(Typography, { variant: "h3", weight: "bold", children: [
|
|
13045
|
+
output.toFixed(2),
|
|
13046
|
+
" ",
|
|
13047
|
+
outputUnit
|
|
13048
|
+
] }),
|
|
13049
|
+
isComplete && /* @__PURE__ */ jsxs(HStack, { gap: "xs", align: "center", children: [
|
|
13050
|
+
/* @__PURE__ */ jsx(
|
|
13051
|
+
GameIcon,
|
|
13052
|
+
{
|
|
13053
|
+
icon: isWin ? CheckCircle : XCircle,
|
|
13054
|
+
assetUrl: isWin ? ui?.["correct"] : ui?.["incorrect"],
|
|
13055
|
+
size: "sm",
|
|
13056
|
+
className: isWin ? "text-success" : "text-error"
|
|
13057
|
+
}
|
|
13058
|
+
),
|
|
13059
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body", className: isWin ? "text-success" : "text-error", children: isWin ? str(resolved.successMessage) || t("simulator.correct") : str(resolved.failMessage) || t("simulator.incorrect") })
|
|
13060
|
+
] }),
|
|
13061
|
+
/* @__PURE__ */ jsxs(Typography, { variant: "caption", className: "text-muted-foreground", children: [
|
|
13062
|
+
t("simulator.target"),
|
|
13063
|
+
": ",
|
|
13064
|
+
targetValue,
|
|
13065
|
+
" ",
|
|
13066
|
+
outputUnit,
|
|
13067
|
+
" (\xB1",
|
|
13068
|
+
targetTolerance,
|
|
13069
|
+
")"
|
|
13070
|
+
] })
|
|
13071
|
+
] }) }),
|
|
13072
|
+
showHint && hint && /* @__PURE__ */ jsx(Card, { className: "p-4 border-l-4 border-l-warning", children: /* @__PURE__ */ jsx(Typography, { variant: "body", children: hint }) }),
|
|
13073
|
+
/* @__PURE__ */ jsxs(HStack, { gap: "sm", justify: "center", children: [
|
|
13074
|
+
!isComplete ? /* @__PURE__ */ jsxs(Button, { variant: "primary", onClick: handleCheck, children: [
|
|
13075
|
+
/* @__PURE__ */ jsx(GameIcon, { icon: Play, assetUrl: ui?.["play"], size: "sm" }),
|
|
13076
|
+
t("simulator.simulate")
|
|
13077
|
+
] }) : null,
|
|
13078
|
+
/* @__PURE__ */ jsxs(Button, { variant: "secondary", onClick: handlePlayAgain, children: [
|
|
13079
|
+
/* @__PURE__ */ jsx(GameIcon, { icon: RotateCcw, assetUrl: ui?.["reset"], size: "sm" }),
|
|
13080
|
+
t("simulator.reset")
|
|
13081
|
+
] })
|
|
13082
|
+
] })
|
|
13083
|
+
] })
|
|
13084
|
+
}
|
|
13085
|
+
);
|
|
13086
|
+
}
|
|
13087
|
+
var init_SimulatorBoard = __esm({
|
|
13088
|
+
"components/game/2d/organisms/SimulatorBoard.tsx"() {
|
|
13089
|
+
init_atoms();
|
|
13090
|
+
init_useEventBus();
|
|
13091
|
+
init_boardEntity();
|
|
13092
|
+
init_GameIcon();
|
|
13093
|
+
SimulatorBoard.displayName = "SimulatorBoard";
|
|
13094
|
+
}
|
|
13095
|
+
});
|
|
13096
|
+
function ClassifierBoard({
|
|
13097
|
+
entity,
|
|
13098
|
+
completeEvent = "PUZZLE_COMPLETE",
|
|
13099
|
+
assignEvent,
|
|
13100
|
+
checkEvent,
|
|
13101
|
+
playAgainEvent,
|
|
13102
|
+
assetManifest,
|
|
13103
|
+
className
|
|
13104
|
+
}) {
|
|
13105
|
+
const ui = assetManifest?.ui;
|
|
13106
|
+
const { emit } = useEventBus();
|
|
13107
|
+
const { t } = useTranslate();
|
|
13108
|
+
const resolved = boardEntity(entity);
|
|
13109
|
+
const [headerError, setHeaderError] = useState(false);
|
|
13110
|
+
const items = rows(resolved?.items);
|
|
13111
|
+
const categories = rows(resolved?.categories);
|
|
13112
|
+
const result = str(resolved?.result);
|
|
13113
|
+
const submitted = result === "win";
|
|
13114
|
+
const attempts = num(resolved?.attempts);
|
|
13115
|
+
const assignments = items.reduce((acc, item) => {
|
|
13116
|
+
if (item.assignedCategory != null && item.assignedCategory !== "") acc[item.id] = item.assignedCategory;
|
|
13117
|
+
return acc;
|
|
13118
|
+
}, {});
|
|
13119
|
+
const unassignedItems = items.filter((item) => !assignments[item.id]);
|
|
13120
|
+
const allAssigned = items.length > 0 && Object.keys(assignments).length === items.length;
|
|
13121
|
+
const results = submitted ? items.map((item) => ({
|
|
13122
|
+
item,
|
|
13123
|
+
assigned: assignments[item.id],
|
|
13124
|
+
correct: assignments[item.id] === item.correctCategory
|
|
13125
|
+
})) : [];
|
|
13126
|
+
const allCorrect = result === "win";
|
|
13127
|
+
const correctCount = results.filter((r) => r.correct).length;
|
|
13128
|
+
const showHint = attempts >= 2 && Boolean(str(resolved?.hint));
|
|
13129
|
+
const handleAssign = (itemId, categoryId) => {
|
|
13130
|
+
if (submitted) return;
|
|
13131
|
+
if (assignEvent) emit(`UI:${assignEvent}`, { itemId, categoryId });
|
|
13132
|
+
};
|
|
13133
|
+
const handleUnassign = (itemId) => {
|
|
13134
|
+
if (submitted) return;
|
|
13135
|
+
if (assignEvent) emit(`UI:${assignEvent}`, { itemId, categoryId: "" });
|
|
13136
|
+
};
|
|
13137
|
+
const handleSubmit = () => {
|
|
13138
|
+
if (checkEvent) emit(`UI:${checkEvent}`, {});
|
|
13139
|
+
if (allAssigned && items.every((item) => assignments[item.id] === item.correctCategory)) {
|
|
13140
|
+
emit(`UI:${completeEvent}`, { success: true, attempts: attempts + 1 });
|
|
13141
|
+
}
|
|
13142
|
+
};
|
|
13143
|
+
const handleFullReset = () => {
|
|
13144
|
+
if (playAgainEvent) emit(`UI:${playAgainEvent}`, {});
|
|
13145
|
+
};
|
|
13146
|
+
if (!resolved) return null;
|
|
13147
|
+
const theme = resolved.theme ?? void 0;
|
|
13148
|
+
const themeBackground = theme?.background;
|
|
13149
|
+
const headerImage = str(resolved.headerImage);
|
|
13150
|
+
const hint = str(resolved.hint);
|
|
13151
|
+
const failMessage = str(resolved.failMessage);
|
|
13152
|
+
return /* @__PURE__ */ jsx(
|
|
13153
|
+
Box,
|
|
13154
|
+
{
|
|
13155
|
+
className,
|
|
13156
|
+
style: {
|
|
13157
|
+
backgroundImage: themeBackground ? `url(${themeBackground})` : void 0,
|
|
13158
|
+
backgroundSize: "cover",
|
|
13159
|
+
backgroundPosition: "center"
|
|
13160
|
+
},
|
|
13161
|
+
children: /* @__PURE__ */ jsxs(VStack, { gap: "lg", className: "p-4", children: [
|
|
13162
|
+
headerImage && !headerError ? /* @__PURE__ */ jsx(Box, { className: "w-full h-32 overflow-hidden rounded-container", children: /* @__PURE__ */ jsx("img", { src: headerImage, alt: "", onError: () => setHeaderError(true), className: "w-full h-full object-cover" }) }) : headerImage && headerError ? /* @__PURE__ */ jsx(Box, { className: "w-full h-32 rounded-container bg-gradient-to-br from-muted to-accent opacity-60" }) : null,
|
|
13163
|
+
/* @__PURE__ */ jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxs(VStack, { gap: "sm", children: [
|
|
13164
|
+
/* @__PURE__ */ jsx(Typography, { variant: "h4", weight: "bold", children: str(resolved.title) }),
|
|
13165
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body", children: str(resolved.description) })
|
|
13166
|
+
] }) }),
|
|
13167
|
+
unassignedItems.length > 0 && /* @__PURE__ */ jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxs(VStack, { gap: "sm", children: [
|
|
13168
|
+
/* @__PURE__ */ jsx(Typography, { variant: "small", weight: "bold", className: "uppercase tracking-wider text-muted-foreground", children: t("classifier.itemsToSort") }),
|
|
13169
|
+
/* @__PURE__ */ jsx(HStack, { gap: "sm", className: "flex-wrap", children: unassignedItems.map((item) => /* @__PURE__ */ jsxs(Badge, { size: "md", className: "cursor-pointer", children: [
|
|
13170
|
+
item.iconUrl && /* @__PURE__ */ jsx("img", { src: item.iconUrl, alt: "", className: "w-4 h-4 object-contain inline-block" }),
|
|
13171
|
+
item.label
|
|
13172
|
+
] }, item.id)) })
|
|
13173
|
+
] }) }),
|
|
13174
|
+
/* @__PURE__ */ jsx(VStack, { gap: "md", children: categories.map((cat) => {
|
|
13175
|
+
const catItems = items.filter((item) => assignments[item.id] === cat.id);
|
|
13176
|
+
return /* @__PURE__ */ jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxs(VStack, { gap: "sm", children: [
|
|
13177
|
+
cat.imageUrl && /* @__PURE__ */ jsx(Box, { className: "w-full h-16 overflow-hidden rounded-container", children: /* @__PURE__ */ jsx("img", { src: cat.imageUrl, alt: "", className: "w-full h-full object-cover" }) }),
|
|
13178
|
+
/* @__PURE__ */ jsxs(HStack, { justify: "between", align: "center", children: [
|
|
13179
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body", weight: "bold", children: cat.label }),
|
|
13180
|
+
/* @__PURE__ */ jsx(Badge, { size: "sm", children: catItems.length })
|
|
13181
|
+
] }),
|
|
13182
|
+
/* @__PURE__ */ jsx(HStack, { gap: "xs", className: "flex-wrap min-h-[2rem]", children: catItems.map((item) => {
|
|
13183
|
+
const result2 = results.find((r) => r.item.id === item.id);
|
|
13184
|
+
return /* @__PURE__ */ jsxs(
|
|
13185
|
+
Badge,
|
|
13186
|
+
{
|
|
13187
|
+
size: "sm",
|
|
13188
|
+
className: `cursor-pointer ${result2 ? result2.correct ? "border-success bg-success/10" : "border-error bg-error/10" : ""}`,
|
|
13189
|
+
onClick: () => handleUnassign(item.id),
|
|
13190
|
+
children: [
|
|
13191
|
+
item.iconUrl && /* @__PURE__ */ jsx("img", { src: item.iconUrl, alt: "", className: "w-3 h-3 object-contain inline-block" }),
|
|
13192
|
+
item.label,
|
|
13193
|
+
result2 && /* @__PURE__ */ jsx(
|
|
13194
|
+
GameIcon,
|
|
13195
|
+
{
|
|
13196
|
+
icon: result2.correct ? CheckCircle : XCircle,
|
|
13197
|
+
assetUrl: result2.correct ? ui?.["correct"] : ui?.["incorrect"],
|
|
13198
|
+
size: "sm",
|
|
13199
|
+
className: result2.correct ? "text-success" : "text-error"
|
|
13200
|
+
}
|
|
13201
|
+
)
|
|
13202
|
+
]
|
|
13203
|
+
},
|
|
13204
|
+
item.id
|
|
13205
|
+
);
|
|
13206
|
+
}) }),
|
|
13207
|
+
!submitted && unassignedItems.length > 0 && /* @__PURE__ */ jsx(HStack, { gap: "xs", className: "flex-wrap", children: unassignedItems.map((item) => /* @__PURE__ */ jsxs(
|
|
13208
|
+
Button,
|
|
13209
|
+
{
|
|
13210
|
+
size: "sm",
|
|
13211
|
+
variant: "ghost",
|
|
13212
|
+
onClick: () => handleAssign(item.id, cat.id),
|
|
13213
|
+
className: "text-xs opacity-50 hover:opacity-100",
|
|
13214
|
+
children: [
|
|
13215
|
+
"+ ",
|
|
13216
|
+
item.label
|
|
13217
|
+
]
|
|
13218
|
+
},
|
|
13219
|
+
item.id
|
|
13220
|
+
)) })
|
|
13221
|
+
] }) }, cat.id);
|
|
13222
|
+
}) }),
|
|
13223
|
+
submitted && /* @__PURE__ */ jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxs(VStack, { gap: "sm", align: "center", children: [
|
|
13224
|
+
/* @__PURE__ */ jsx(
|
|
13225
|
+
GameIcon,
|
|
13226
|
+
{
|
|
13227
|
+
icon: allCorrect ? CheckCircle : XCircle,
|
|
13228
|
+
assetUrl: allCorrect ? ui?.["correct"] : ui?.["incorrect"],
|
|
13229
|
+
size: "lg",
|
|
13230
|
+
className: allCorrect ? "text-success" : "text-error"
|
|
13231
|
+
}
|
|
13232
|
+
),
|
|
13233
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body", weight: "bold", children: allCorrect ? str(resolved.successMessage) || t("classifier.allCorrect") : `${correctCount}/${items.length} ${t("classifier.correct")}` }),
|
|
13234
|
+
!allCorrect && failMessage && /* @__PURE__ */ jsx(Typography, { variant: "body", className: "text-muted-foreground", children: failMessage })
|
|
13235
|
+
] }) }),
|
|
13236
|
+
showHint && hint && /* @__PURE__ */ jsx(Card, { className: "p-4 border-l-4 border-l-warning", children: /* @__PURE__ */ jsx(Typography, { variant: "body", children: hint }) }),
|
|
13237
|
+
/* @__PURE__ */ jsxs(HStack, { gap: "sm", justify: "center", children: [
|
|
13238
|
+
!submitted && /* @__PURE__ */ jsxs(Button, { variant: "primary", onClick: handleSubmit, disabled: !allAssigned, children: [
|
|
13239
|
+
/* @__PURE__ */ jsx(GameIcon, { icon: Send, assetUrl: ui?.["send"], size: "sm" }),
|
|
13240
|
+
t("classifier.check")
|
|
13241
|
+
] }),
|
|
13242
|
+
/* @__PURE__ */ jsxs(Button, { variant: "secondary", onClick: handleFullReset, children: [
|
|
13243
|
+
/* @__PURE__ */ jsx(GameIcon, { icon: RotateCcw, assetUrl: ui?.["reset"], size: "sm" }),
|
|
13244
|
+
t("classifier.reset")
|
|
13245
|
+
] })
|
|
13246
|
+
] })
|
|
13247
|
+
] })
|
|
13248
|
+
}
|
|
13249
|
+
);
|
|
13250
|
+
}
|
|
13251
|
+
var init_ClassifierBoard = __esm({
|
|
13252
|
+
"components/game/2d/organisms/ClassifierBoard.tsx"() {
|
|
13253
|
+
init_atoms();
|
|
13254
|
+
init_useEventBus();
|
|
13255
|
+
init_boardEntity();
|
|
13256
|
+
init_GameIcon();
|
|
13257
|
+
ClassifierBoard.displayName = "ClassifierBoard";
|
|
13258
|
+
}
|
|
13259
|
+
});
|
|
13260
|
+
function BuilderBoard({
|
|
13261
|
+
entity,
|
|
13262
|
+
completeEvent = "PUZZLE_COMPLETE",
|
|
13263
|
+
placeEvent,
|
|
13264
|
+
checkEvent,
|
|
13265
|
+
playAgainEvent,
|
|
13266
|
+
assetManifest,
|
|
13267
|
+
className
|
|
13268
|
+
}) {
|
|
13269
|
+
const ui = assetManifest?.ui;
|
|
13270
|
+
const { emit } = useEventBus();
|
|
13271
|
+
const { t } = useTranslate();
|
|
13272
|
+
const resolved = boardEntity(entity);
|
|
13273
|
+
const [headerError, setHeaderError] = useState(false);
|
|
13274
|
+
const [selectedComponent, setSelectedComponent] = useState(null);
|
|
13275
|
+
const components = rows(resolved?.components).map((r) => ({
|
|
13276
|
+
id: str(r.id),
|
|
13277
|
+
label: str(r.label),
|
|
13278
|
+
description: str(r.description) || void 0,
|
|
13279
|
+
iconEmoji: str(r.iconEmoji) || void 0,
|
|
13280
|
+
iconUrl: str(r.iconUrl) || void 0,
|
|
13281
|
+
category: str(r.category) || void 0
|
|
13282
|
+
}));
|
|
13283
|
+
const slots = rows(resolved?.slots).map((r) => ({
|
|
13284
|
+
id: str(r.id),
|
|
13285
|
+
label: str(r.label) || void 0,
|
|
13286
|
+
description: str(r.description) || void 0,
|
|
13287
|
+
requiredComponentId: str(r.requiredComponentId),
|
|
13288
|
+
placedComponentId: str(r.placedComponentId) || void 0
|
|
13289
|
+
}));
|
|
13290
|
+
const placements = {};
|
|
13291
|
+
for (const slot of slots) {
|
|
13292
|
+
if (slot.placedComponentId) placements[slot.id] = slot.placedComponentId;
|
|
13293
|
+
}
|
|
13294
|
+
const attempts = num(resolved?.attempts);
|
|
13295
|
+
const result = str(resolved?.result) || "none";
|
|
13296
|
+
const submitted = result === "win";
|
|
13297
|
+
const usedComponentIds = new Set(Object.values(placements));
|
|
13298
|
+
const availableComponents = components.filter((c) => !usedComponentIds.has(c.id));
|
|
13299
|
+
const allPlaced = slots.length > 0 && slots.every((s) => Boolean(placements[s.id]));
|
|
13300
|
+
const results = submitted ? slots.map((slot) => ({
|
|
13301
|
+
slot,
|
|
13302
|
+
placed: placements[slot.id],
|
|
13303
|
+
correct: placements[slot.id] === slot.requiredComponentId
|
|
13304
|
+
})) : [];
|
|
13305
|
+
const showHint = attempts >= 2 && Boolean(str(resolved?.hint));
|
|
13306
|
+
const handlePlaceComponent = (slotId) => {
|
|
13307
|
+
if (submitted || !selectedComponent) return;
|
|
13308
|
+
if (placeEvent) emit(`UI:${placeEvent}`, { slotId, componentId: selectedComponent });
|
|
13309
|
+
setSelectedComponent(null);
|
|
13310
|
+
};
|
|
13311
|
+
const handleRemoveFromSlot = (slotId) => {
|
|
13312
|
+
if (submitted) return;
|
|
13313
|
+
if (placeEvent) emit(`UI:${placeEvent}`, { slotId, componentId: "" });
|
|
13314
|
+
};
|
|
13315
|
+
const handleSubmit = () => {
|
|
13316
|
+
if (checkEvent) emit(`UI:${checkEvent}`, {});
|
|
13317
|
+
const solved = slots.length > 0 && slots.every((s) => placements[s.id] === s.requiredComponentId);
|
|
13318
|
+
if (solved && completeEvent) {
|
|
13319
|
+
emit(`UI:${completeEvent}`, { success: true, attempts: attempts + 1 });
|
|
13320
|
+
}
|
|
13321
|
+
};
|
|
13322
|
+
const handlePlayAgain = () => {
|
|
13323
|
+
setSelectedComponent(null);
|
|
13324
|
+
if (playAgainEvent) emit(`UI:${playAgainEvent}`, {});
|
|
13325
|
+
};
|
|
13326
|
+
const getComponentById = (id) => components.find((c) => c.id === id);
|
|
13327
|
+
if (!resolved) return null;
|
|
13328
|
+
const theme = resolved.theme ?? void 0;
|
|
13329
|
+
const themeBackground = theme?.background;
|
|
13330
|
+
const headerImage = str(resolved.headerImage);
|
|
13331
|
+
const hint = str(resolved.hint);
|
|
13332
|
+
return /* @__PURE__ */ jsx(
|
|
13333
|
+
Box,
|
|
13334
|
+
{
|
|
13335
|
+
className,
|
|
13336
|
+
style: {
|
|
13337
|
+
backgroundImage: themeBackground ? `url(${themeBackground})` : void 0,
|
|
13338
|
+
backgroundSize: "cover",
|
|
13339
|
+
backgroundPosition: "center"
|
|
13340
|
+
},
|
|
13341
|
+
children: /* @__PURE__ */ jsxs(VStack, { gap: "lg", className: "p-4", children: [
|
|
13342
|
+
headerImage && !headerError ? /* @__PURE__ */ jsx(Box, { className: "w-full h-32 overflow-hidden rounded-container", children: /* @__PURE__ */ jsx("img", { src: headerImage, alt: "", onError: () => setHeaderError(true), className: "w-full h-full object-cover" }) }) : headerImage && headerError ? /* @__PURE__ */ jsx(Box, { className: "w-full h-32 rounded-container bg-gradient-to-br from-muted to-accent opacity-60" }) : null,
|
|
13343
|
+
/* @__PURE__ */ jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxs(VStack, { gap: "sm", children: [
|
|
13344
|
+
/* @__PURE__ */ jsx(Typography, { variant: "h4", weight: "bold", children: str(resolved.title) }),
|
|
13345
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body", children: str(resolved.description) })
|
|
13346
|
+
] }) }),
|
|
13347
|
+
/* @__PURE__ */ jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxs(VStack, { gap: "sm", children: [
|
|
13348
|
+
/* @__PURE__ */ jsx(Typography, { variant: "small", weight: "bold", className: "uppercase tracking-wider text-muted-foreground", children: t("builder.components") }),
|
|
13349
|
+
/* @__PURE__ */ jsxs(HStack, { gap: "sm", className: "flex-wrap", children: [
|
|
13350
|
+
availableComponents.map((comp) => /* @__PURE__ */ jsxs(
|
|
13351
|
+
Button,
|
|
13352
|
+
{
|
|
13353
|
+
size: "sm",
|
|
13354
|
+
variant: selectedComponent === comp.id ? "primary" : "secondary",
|
|
13355
|
+
onClick: () => setSelectedComponent(selectedComponent === comp.id ? null : comp.id),
|
|
13356
|
+
disabled: submitted,
|
|
13357
|
+
children: [
|
|
13358
|
+
comp.iconUrl ? /* @__PURE__ */ jsx("img", { src: comp.iconUrl, alt: "", className: "w-5 h-5 object-contain inline-block mr-1" }) : comp.iconEmoji ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
13359
|
+
comp.iconEmoji,
|
|
13360
|
+
" "
|
|
13361
|
+
] }) : null,
|
|
13362
|
+
comp.label
|
|
13363
|
+
]
|
|
13364
|
+
},
|
|
13365
|
+
comp.id
|
|
13366
|
+
)),
|
|
13367
|
+
availableComponents.length === 0 && !submitted && /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-muted-foreground", children: t("builder.allPlaced") })
|
|
13368
|
+
] })
|
|
13369
|
+
] }) }),
|
|
13370
|
+
/* @__PURE__ */ jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxs(VStack, { gap: "sm", children: [
|
|
13371
|
+
/* @__PURE__ */ jsx(Typography, { variant: "small", weight: "bold", className: "uppercase tracking-wider text-muted-foreground", children: t("builder.blueprint") }),
|
|
13372
|
+
/* @__PURE__ */ jsx(VStack, { gap: "sm", children: slots.map((slot) => {
|
|
13373
|
+
const placedComp = placements[slot.id] ? getComponentById(placements[slot.id]) : null;
|
|
13374
|
+
const result2 = results.find((r) => r.slot.id === slot.id);
|
|
13375
|
+
return /* @__PURE__ */ jsxs(
|
|
13376
|
+
HStack,
|
|
13377
|
+
{
|
|
13378
|
+
gap: "sm",
|
|
13379
|
+
align: "center",
|
|
13380
|
+
className: `p-3 border-2 rounded ${result2 ? result2.correct ? "border-success" : "border-error" : selectedComponent ? "border-dashed border-foreground cursor-pointer" : "border-border"}`,
|
|
13381
|
+
onClick: () => handlePlaceComponent(slot.id),
|
|
13382
|
+
children: [
|
|
13383
|
+
/* @__PURE__ */ jsxs(VStack, { gap: "none", className: "flex-1", children: [
|
|
13384
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body", weight: "medium", children: slot.label }),
|
|
13385
|
+
slot.description && /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-muted-foreground", children: slot.description })
|
|
13386
|
+
] }),
|
|
13387
|
+
placedComp ? /* @__PURE__ */ jsxs(HStack, { gap: "xs", align: "center", children: [
|
|
13388
|
+
/* @__PURE__ */ jsxs(Badge, { size: "sm", onClick: () => handleRemoveFromSlot(slot.id), children: [
|
|
13389
|
+
placedComp.iconUrl ? /* @__PURE__ */ jsx("img", { src: placedComp.iconUrl, alt: "", className: "w-4 h-4 object-contain inline-block mr-1" }) : placedComp.iconEmoji ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
13390
|
+
placedComp.iconEmoji,
|
|
13391
|
+
" "
|
|
13392
|
+
] }) : null,
|
|
13393
|
+
placedComp.label
|
|
13394
|
+
] }),
|
|
13395
|
+
result2 && /* @__PURE__ */ jsx(
|
|
13396
|
+
GameIcon,
|
|
13397
|
+
{
|
|
13398
|
+
icon: result2.correct ? CheckCircle : XCircle,
|
|
13399
|
+
assetUrl: result2.correct ? ui?.["correct"] : ui?.["incorrect"],
|
|
13400
|
+
size: "sm",
|
|
13401
|
+
className: result2.correct ? "text-success" : "text-error"
|
|
13402
|
+
}
|
|
13403
|
+
)
|
|
13404
|
+
] }) : /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-muted-foreground", children: t("builder.empty") })
|
|
13405
|
+
]
|
|
13406
|
+
},
|
|
13407
|
+
slot.id
|
|
13408
|
+
);
|
|
13409
|
+
}) })
|
|
13410
|
+
] }) }),
|
|
13411
|
+
submitted && /* @__PURE__ */ jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxs(VStack, { gap: "sm", align: "center", children: [
|
|
13412
|
+
/* @__PURE__ */ jsx(GameIcon, { icon: CheckCircle, assetUrl: ui?.["correct"], size: "lg", className: "text-success" }),
|
|
13413
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body", weight: "bold", children: str(resolved.successMessage) || t("builder.success") })
|
|
13414
|
+
] }) }),
|
|
13415
|
+
showHint && hint && /* @__PURE__ */ jsx(Card, { className: "p-4 border-l-4 border-l-warning", children: /* @__PURE__ */ jsx(Typography, { variant: "body", children: hint }) }),
|
|
13416
|
+
/* @__PURE__ */ jsxs(HStack, { gap: "sm", justify: "center", children: [
|
|
13417
|
+
!submitted && /* @__PURE__ */ jsxs(Button, { variant: "primary", onClick: handleSubmit, disabled: !allPlaced, children: [
|
|
13418
|
+
/* @__PURE__ */ jsx(GameIcon, { icon: Wrench, assetUrl: ui?.["build"], size: "sm" }),
|
|
13419
|
+
t("builder.build")
|
|
13420
|
+
] }),
|
|
13421
|
+
/* @__PURE__ */ jsxs(Button, { variant: "secondary", onClick: handlePlayAgain, children: [
|
|
13422
|
+
/* @__PURE__ */ jsx(GameIcon, { icon: RotateCcw, assetUrl: ui?.["reset"], size: "sm" }),
|
|
13423
|
+
t("builder.reset")
|
|
13424
|
+
] })
|
|
13425
|
+
] })
|
|
13426
|
+
] })
|
|
13427
|
+
}
|
|
13428
|
+
);
|
|
13429
|
+
}
|
|
13430
|
+
var init_BuilderBoard = __esm({
|
|
13431
|
+
"components/game/2d/organisms/BuilderBoard.tsx"() {
|
|
13432
|
+
init_atoms();
|
|
13433
|
+
init_useEventBus();
|
|
13434
|
+
init_boardEntity();
|
|
13435
|
+
init_GameIcon();
|
|
13436
|
+
BuilderBoard.displayName = "BuilderBoard";
|
|
13437
|
+
}
|
|
13438
|
+
});
|
|
13439
|
+
function toDebuggerLine(v) {
|
|
13440
|
+
if (v === null || typeof v !== "object" || Array.isArray(v) || v instanceof Date) return null;
|
|
13441
|
+
const id = v["id"];
|
|
13442
|
+
const content = v["content"];
|
|
13443
|
+
const isBug = v["isBug"];
|
|
13444
|
+
if (typeof id !== "string" || typeof content !== "string" || typeof isBug !== "boolean") return null;
|
|
13445
|
+
const isFlagged = v["isFlagged"];
|
|
13446
|
+
const explanation = v["explanation"];
|
|
13447
|
+
return {
|
|
13448
|
+
id,
|
|
13449
|
+
content,
|
|
13450
|
+
isBug,
|
|
13451
|
+
isFlagged: typeof isFlagged === "boolean" ? isFlagged : void 0,
|
|
13452
|
+
explanation: typeof explanation === "string" ? explanation : void 0
|
|
13453
|
+
};
|
|
13454
|
+
}
|
|
13455
|
+
function DebuggerBoard({
|
|
13456
|
+
entity,
|
|
13457
|
+
completeEvent = "PUZZLE_COMPLETE",
|
|
13458
|
+
toggleFlagEvent,
|
|
13459
|
+
checkEvent,
|
|
13460
|
+
playAgainEvent,
|
|
13461
|
+
assetManifest,
|
|
13462
|
+
className
|
|
13463
|
+
}) {
|
|
13464
|
+
const ui = assetManifest?.ui;
|
|
13465
|
+
const { emit } = useEventBus();
|
|
13466
|
+
const { t } = useTranslate();
|
|
13467
|
+
const resolved = boardEntity(entity);
|
|
13468
|
+
const [headerError, setHeaderError] = useState(false);
|
|
13469
|
+
const lines = Array.isArray(resolved?.lines) ? resolved.lines.flatMap((v) => {
|
|
13470
|
+
const l = toDebuggerLine(v);
|
|
13471
|
+
return l ? [l] : [];
|
|
13472
|
+
}) : [];
|
|
13473
|
+
const result = str(resolved?.result) || "none";
|
|
13474
|
+
const attempts = num(resolved?.attempts);
|
|
13475
|
+
const submitted = result === "win";
|
|
13476
|
+
const showHint = !submitted && attempts >= 2 && Boolean(str(resolved?.hint));
|
|
13477
|
+
const bugLines = lines.filter((l) => l.isBug);
|
|
13478
|
+
const flaggedLines = lines.filter((l) => l.isFlagged);
|
|
13479
|
+
const correctFlags = lines.filter((l) => l.isBug && l.isFlagged);
|
|
13480
|
+
const falseFlags = lines.filter((l) => !l.isBug && l.isFlagged);
|
|
13481
|
+
const allCorrect = submitted;
|
|
13482
|
+
const toggleLine = (lineId) => {
|
|
13483
|
+
if (submitted) return;
|
|
13484
|
+
if (toggleFlagEvent) emit(`UI:${toggleFlagEvent}`, { lineId });
|
|
13485
|
+
};
|
|
13486
|
+
const handleSubmit = useCallback(() => {
|
|
13487
|
+
if (checkEvent) emit(`UI:${checkEvent}`, {});
|
|
13488
|
+
const correct = correctFlags.length === bugLines.length && falseFlags.length === 0;
|
|
13489
|
+
if (correct) emit(`UI:${completeEvent}`, { success: true, attempts: attempts + 1 });
|
|
13490
|
+
}, [checkEvent, correctFlags.length, bugLines.length, falseFlags.length, attempts, completeEvent, emit]);
|
|
13491
|
+
const handleReset = () => {
|
|
13492
|
+
if (playAgainEvent) emit(`UI:${playAgainEvent}`, {});
|
|
13493
|
+
};
|
|
13494
|
+
if (!resolved) return null;
|
|
13495
|
+
const theme = resolved.theme ?? void 0;
|
|
13496
|
+
const themeBackground = theme?.background;
|
|
13497
|
+
const headerImage = str(resolved.headerImage);
|
|
13498
|
+
const hint = str(resolved.hint);
|
|
13499
|
+
return /* @__PURE__ */ jsx(
|
|
13500
|
+
Box,
|
|
13501
|
+
{
|
|
13502
|
+
className,
|
|
13503
|
+
style: {
|
|
13504
|
+
backgroundImage: themeBackground ? `url(${themeBackground})` : void 0,
|
|
13505
|
+
backgroundSize: "cover",
|
|
13506
|
+
backgroundPosition: "center"
|
|
13507
|
+
},
|
|
13508
|
+
children: /* @__PURE__ */ jsxs(VStack, { gap: "lg", className: "p-4", children: [
|
|
13509
|
+
headerImage && !headerError ? /* @__PURE__ */ jsx(Box, { className: "w-full h-32 overflow-hidden rounded-container", children: /* @__PURE__ */ jsx("img", { src: headerImage, alt: "", onError: () => setHeaderError(true), className: "w-full h-full object-cover" }) }) : headerImage && headerError ? /* @__PURE__ */ jsx(Box, { className: "w-full h-32 rounded-container bg-gradient-to-br from-muted to-accent opacity-60" }) : null,
|
|
13510
|
+
/* @__PURE__ */ jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxs(VStack, { gap: "sm", children: [
|
|
13511
|
+
/* @__PURE__ */ jsxs(HStack, { gap: "xs", align: "center", children: [
|
|
13512
|
+
/* @__PURE__ */ jsx(GameIcon, { icon: Bug, assetUrl: ui?.["bug"], size: "sm" }),
|
|
13513
|
+
/* @__PURE__ */ jsx(Typography, { variant: "h4", weight: "bold", children: str(resolved.title) })
|
|
13514
|
+
] }),
|
|
13515
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body", children: str(resolved.description) }),
|
|
13516
|
+
/* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-muted-foreground", children: t("debugger.findBugs", { count: String(lines.filter((l) => l.isBug).length) }) })
|
|
13517
|
+
] }) }),
|
|
13518
|
+
/* @__PURE__ */ jsx(Card, { className: "p-0 overflow-hidden", children: /* @__PURE__ */ jsx(VStack, { gap: "none", children: lines.map((line, i) => {
|
|
13519
|
+
const isFlagged = !!line.isFlagged;
|
|
13520
|
+
let lineStyle = "";
|
|
13521
|
+
if (submitted) {
|
|
13522
|
+
if (line.isBug && isFlagged) lineStyle = "bg-success/10";
|
|
13523
|
+
else if (line.isBug && !isFlagged) lineStyle = "bg-warning/10";
|
|
13524
|
+
else if (!line.isBug && isFlagged) lineStyle = "bg-error/10";
|
|
13525
|
+
} else if (isFlagged) {
|
|
13526
|
+
lineStyle = "bg-error/10";
|
|
13527
|
+
}
|
|
13528
|
+
return /* @__PURE__ */ jsxs(
|
|
13529
|
+
HStack,
|
|
13530
|
+
{
|
|
13531
|
+
gap: "none",
|
|
13532
|
+
align: "stretch",
|
|
13533
|
+
className: `border-b border-border cursor-pointer hover:bg-muted ${lineStyle}`,
|
|
13534
|
+
onClick: () => toggleLine(line.id),
|
|
13535
|
+
children: [
|
|
13536
|
+
/* @__PURE__ */ jsx(Box, { className: "w-10 flex-shrink-0 flex items-center justify-center border-r border-border text-muted-foreground", children: /* @__PURE__ */ jsx(Typography, { variant: "caption", children: i + 1 }) }),
|
|
13537
|
+
/* @__PURE__ */ jsx(Box, { className: "flex-1 px-3 py-1.5 font-mono text-sm whitespace-pre", children: /* @__PURE__ */ jsx(Typography, { variant: "body", className: "font-mono text-sm", children: line.content }) }),
|
|
13538
|
+
/* @__PURE__ */ jsxs(Box, { className: "w-8 flex-shrink-0 flex items-center justify-center", children: [
|
|
13539
|
+
isFlagged && /* @__PURE__ */ jsx(GameIcon, { icon: Bug, assetUrl: ui?.["bug"], size: "sm", className: "text-error" }),
|
|
13540
|
+
submitted && line.isBug && !isFlagged && /* @__PURE__ */ jsx(GameIcon, { icon: Bug, assetUrl: ui?.["bug"], size: "sm", className: "text-warning" })
|
|
13541
|
+
] })
|
|
13542
|
+
]
|
|
13543
|
+
},
|
|
13544
|
+
line.id
|
|
13545
|
+
);
|
|
13546
|
+
}) }) }),
|
|
13547
|
+
submitted && /* @__PURE__ */ jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxs(VStack, { gap: "sm", children: [
|
|
13548
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body", weight: "bold", children: allCorrect ? str(resolved.successMessage) || t("debugger.allFound") : `${correctFlags.length}/${bugLines.length} ${t("debugger.bugsFound")}` }),
|
|
13549
|
+
bugLines.map((line) => /* @__PURE__ */ jsxs(HStack, { gap: "xs", align: "start", children: [
|
|
13550
|
+
/* @__PURE__ */ jsx(
|
|
13551
|
+
GameIcon,
|
|
13552
|
+
{
|
|
13553
|
+
icon: line.isFlagged ? CheckCircle : XCircle,
|
|
13554
|
+
assetUrl: line.isFlagged ? ui?.["correct"] : ui?.["incorrect"],
|
|
13555
|
+
size: "sm",
|
|
13556
|
+
className: line.isFlagged ? "text-success mt-0.5" : "text-warning mt-0.5"
|
|
13557
|
+
}
|
|
13558
|
+
),
|
|
13559
|
+
/* @__PURE__ */ jsxs(VStack, { gap: "none", children: [
|
|
13560
|
+
/* @__PURE__ */ jsx(Typography, { variant: "caption", weight: "bold", className: "font-mono", children: line.content.trim() }),
|
|
13561
|
+
line.explanation && /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-muted-foreground", children: line.explanation })
|
|
13562
|
+
] })
|
|
13563
|
+
] }, line.id))
|
|
13564
|
+
] }) }),
|
|
13565
|
+
showHint && hint && /* @__PURE__ */ jsx(Card, { className: "p-4 border-l-4 border-l-warning", children: /* @__PURE__ */ jsx(Typography, { variant: "body", children: hint }) }),
|
|
13566
|
+
/* @__PURE__ */ jsxs(HStack, { gap: "sm", justify: "center", children: [
|
|
13567
|
+
!submitted && /* @__PURE__ */ jsxs(Button, { variant: "primary", onClick: handleSubmit, disabled: flaggedLines.length === 0, children: [
|
|
13568
|
+
/* @__PURE__ */ jsx(GameIcon, { icon: Send, assetUrl: ui?.["send"], size: "sm" }),
|
|
13569
|
+
t("debugger.submit")
|
|
13570
|
+
] }),
|
|
13571
|
+
/* @__PURE__ */ jsxs(Button, { variant: "secondary", onClick: handleReset, children: [
|
|
13572
|
+
/* @__PURE__ */ jsx(GameIcon, { icon: RotateCcw, assetUrl: ui?.["reset"], size: "sm" }),
|
|
13573
|
+
t("debugger.reset")
|
|
13574
|
+
] })
|
|
13575
|
+
] })
|
|
13576
|
+
] })
|
|
13577
|
+
}
|
|
13578
|
+
);
|
|
13579
|
+
}
|
|
13580
|
+
var init_DebuggerBoard = __esm({
|
|
13581
|
+
"components/game/2d/organisms/DebuggerBoard.tsx"() {
|
|
13582
|
+
init_atoms();
|
|
13583
|
+
init_useEventBus();
|
|
13584
|
+
init_boardEntity();
|
|
13585
|
+
init_GameIcon();
|
|
13586
|
+
DebuggerBoard.displayName = "DebuggerBoard";
|
|
13587
|
+
}
|
|
13588
|
+
});
|
|
13589
|
+
function NegotiatorBoard({
|
|
13590
|
+
entity,
|
|
13591
|
+
completeEvent = "PUZZLE_COMPLETE",
|
|
13592
|
+
playRoundEvent,
|
|
13593
|
+
finishEvent,
|
|
13594
|
+
playAgainEvent,
|
|
13595
|
+
assetManifest,
|
|
13596
|
+
className
|
|
13597
|
+
}) {
|
|
13598
|
+
const ui = assetManifest?.ui;
|
|
13599
|
+
const { emit } = useEventBus();
|
|
13600
|
+
const { t } = useTranslate();
|
|
13601
|
+
const resolved = boardEntity(entity);
|
|
13602
|
+
const [history, setHistory] = useState([]);
|
|
13603
|
+
const [headerError, setHeaderError] = useState(false);
|
|
13604
|
+
const [showHint, setShowHint] = useState(false);
|
|
13605
|
+
const totalRounds = num(resolved?.maxRounds);
|
|
13606
|
+
const targetScore = num(resolved?.targetScore);
|
|
13607
|
+
const currentRound = num(resolved?.round);
|
|
13608
|
+
const result = str(resolved?.result) || "none";
|
|
13609
|
+
const playerTotal = num(resolved?.score);
|
|
13610
|
+
const isComplete = result !== "none" || totalRounds > 0 && currentRound >= totalRounds;
|
|
13611
|
+
const won = result === "win";
|
|
13612
|
+
const lastPlayerAction = str(resolved?.lastPlayerAction);
|
|
13613
|
+
const lastOpponentAction = str(resolved?.lastOpponentAction);
|
|
13614
|
+
const lastPayoff = num(resolved?.lastPayoff);
|
|
13615
|
+
const actions = Array.isArray(resolved?.actions) ? resolved.actions.flatMap((item) => {
|
|
13616
|
+
if (item !== null && typeof item === "object" && !Array.isArray(item) && !(item instanceof Date) && typeof item.id === "string" && typeof item.label === "string")
|
|
13617
|
+
return [{ id: item.id, label: item.label, description: typeof item.description === "string" ? item.description : void 0 }];
|
|
13618
|
+
return [];
|
|
13619
|
+
}) : [];
|
|
13620
|
+
const payoffMatrix = Array.isArray(resolved?.payoffMatrix) ? resolved.payoffMatrix.flatMap((item) => {
|
|
13621
|
+
if (item !== null && typeof item === "object" && !Array.isArray(item) && !(item instanceof Date) && typeof item.playerAction === "string" && typeof item.opponentAction === "string")
|
|
13622
|
+
return [{ playerAction: item.playerAction, opponentAction: item.opponentAction, playerPayoff: typeof item.playerPayoff === "number" ? item.playerPayoff : 0, opponentPayoff: typeof item.opponentPayoff === "number" ? item.opponentPayoff : 0 }];
|
|
13623
|
+
return [];
|
|
13624
|
+
}) : [];
|
|
13625
|
+
const prevRoundRef = useRef(currentRound);
|
|
13626
|
+
useEffect(() => {
|
|
13627
|
+
if (currentRound > prevRoundRef.current && lastPlayerAction) {
|
|
13628
|
+
const opponentPayoffEntry = payoffMatrix.find(
|
|
13629
|
+
(p) => p.playerAction === lastPlayerAction && p.opponentAction === lastOpponentAction
|
|
13630
|
+
);
|
|
13631
|
+
setHistory((prev) => [
|
|
13632
|
+
...prev,
|
|
13633
|
+
{
|
|
13634
|
+
round: currentRound,
|
|
13635
|
+
playerAction: lastPlayerAction,
|
|
13636
|
+
opponentAction: lastOpponentAction,
|
|
13637
|
+
playerPayoff: lastPayoff,
|
|
13638
|
+
opponentPayoff: opponentPayoffEntry?.opponentPayoff ?? 0
|
|
13639
|
+
}
|
|
13640
|
+
]);
|
|
13641
|
+
}
|
|
13642
|
+
prevRoundRef.current = currentRound;
|
|
13643
|
+
}, [currentRound, lastPlayerAction, lastOpponentAction, lastPayoff, payoffMatrix]);
|
|
13644
|
+
const opponentTotal = useMemo(() => history.reduce((s, r) => s + r.opponentPayoff, 0), [history]);
|
|
13645
|
+
const handleAction = useCallback((actionId) => {
|
|
13646
|
+
if (isComplete) return;
|
|
13647
|
+
if (playRoundEvent) {
|
|
13648
|
+
emit(`UI:${playRoundEvent}`, { playerAction: actionId, payoff: 0 });
|
|
13649
|
+
}
|
|
13650
|
+
if (totalRounds > 0 && currentRound + 1 >= totalRounds) {
|
|
13651
|
+
if (finishEvent) {
|
|
13652
|
+
emit(`UI:${finishEvent}`, {});
|
|
13653
|
+
}
|
|
13654
|
+
if (str(resolved?.hint)) {
|
|
13655
|
+
setShowHint(true);
|
|
13656
|
+
}
|
|
13657
|
+
}
|
|
13658
|
+
}, [isComplete, resolved, totalRounds, currentRound, playRoundEvent, finishEvent, emit]);
|
|
13659
|
+
const handleReset = useCallback(() => {
|
|
13660
|
+
setHistory([]);
|
|
13661
|
+
setShowHint(false);
|
|
13662
|
+
prevRoundRef.current = 0;
|
|
13663
|
+
if (playAgainEvent) {
|
|
13664
|
+
emit(`UI:${playAgainEvent}`, {});
|
|
13665
|
+
}
|
|
13666
|
+
}, [playAgainEvent, emit]);
|
|
13667
|
+
const completedRef = useRef(false);
|
|
13668
|
+
useEffect(() => {
|
|
13669
|
+
if (result === "win" && !completedRef.current) {
|
|
13670
|
+
completedRef.current = true;
|
|
13671
|
+
emit(`UI:${completeEvent}`, { success: true, score: playerTotal });
|
|
13672
|
+
} else if (result === "none") {
|
|
13673
|
+
completedRef.current = false;
|
|
13674
|
+
}
|
|
13675
|
+
}, [result, playerTotal, completeEvent, emit]);
|
|
13676
|
+
const getActionLabel = (id) => actions.find((a) => a.id === id)?.label ?? id;
|
|
13677
|
+
if (!resolved) return null;
|
|
13678
|
+
const theme = resolved.theme ?? void 0;
|
|
13679
|
+
const themeBackground = theme?.background;
|
|
13680
|
+
const headerImage = str(resolved.headerImage);
|
|
13681
|
+
const hint = str(resolved.hint);
|
|
13682
|
+
return /* @__PURE__ */ jsx(
|
|
13683
|
+
Box,
|
|
13684
|
+
{
|
|
13685
|
+
className,
|
|
13686
|
+
style: {
|
|
13687
|
+
backgroundImage: themeBackground ? `url(${themeBackground})` : void 0,
|
|
13688
|
+
backgroundSize: "cover",
|
|
13689
|
+
backgroundPosition: "center"
|
|
13690
|
+
},
|
|
13691
|
+
children: /* @__PURE__ */ jsxs(VStack, { gap: "lg", className: "p-4", children: [
|
|
13692
|
+
headerImage && !headerError ? /* @__PURE__ */ jsx(Box, { className: "w-full h-32 overflow-hidden rounded-container", children: /* @__PURE__ */ jsx("img", { src: headerImage, alt: "", onError: () => setHeaderError(true), className: "w-full h-full object-cover" }) }) : headerImage && headerError ? /* @__PURE__ */ jsx(Box, { className: "w-full h-32 rounded-container bg-gradient-to-br from-muted to-accent opacity-60" }) : null,
|
|
13693
|
+
/* @__PURE__ */ jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxs(VStack, { gap: "sm", children: [
|
|
13694
|
+
/* @__PURE__ */ jsx(Typography, { variant: "h4", weight: "bold", children: str(resolved.title) }),
|
|
13695
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body", children: str(resolved.description) }),
|
|
13696
|
+
/* @__PURE__ */ jsxs(HStack, { gap: "md", children: [
|
|
13697
|
+
/* @__PURE__ */ jsx(Badge, { size: "sm", children: t("negotiator.round", { current: String(currentRound), total: String(totalRounds) }) }),
|
|
13698
|
+
/* @__PURE__ */ jsxs(Badge, { size: "sm", children: [
|
|
13699
|
+
t("negotiator.target"),
|
|
13700
|
+
": ",
|
|
13701
|
+
targetScore
|
|
13702
|
+
] })
|
|
13703
|
+
] })
|
|
13704
|
+
] }) }),
|
|
13705
|
+
/* @__PURE__ */ jsxs(HStack, { gap: "md", justify: "center", children: [
|
|
13706
|
+
/* @__PURE__ */ jsx(Card, { className: "p-4 flex-1 text-center", children: /* @__PURE__ */ jsxs(VStack, { gap: "xs", align: "center", children: [
|
|
13707
|
+
/* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-muted-foreground", children: t("negotiator.you") }),
|
|
13708
|
+
/* @__PURE__ */ jsx(Typography, { variant: "h3", weight: "bold", children: playerTotal })
|
|
13709
|
+
] }) }),
|
|
13710
|
+
/* @__PURE__ */ jsx(Card, { className: "p-4 flex-1 text-center", children: /* @__PURE__ */ jsxs(VStack, { gap: "xs", align: "center", children: [
|
|
13711
|
+
/* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-muted-foreground", children: t("negotiator.opponent") }),
|
|
13712
|
+
/* @__PURE__ */ jsx(Typography, { variant: "h3", weight: "bold", children: opponentTotal })
|
|
13713
|
+
] }) })
|
|
13714
|
+
] }),
|
|
13715
|
+
!isComplete && /* @__PURE__ */ jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxs(VStack, { gap: "sm", children: [
|
|
13716
|
+
/* @__PURE__ */ jsx(Typography, { variant: "small", weight: "bold", className: "uppercase tracking-wider text-muted-foreground", children: t("negotiator.chooseAction") }),
|
|
13717
|
+
/* @__PURE__ */ jsx(HStack, { gap: "sm", justify: "center", className: "flex-wrap", children: actions.map((action) => /* @__PURE__ */ jsx(
|
|
13718
|
+
Button,
|
|
13719
|
+
{
|
|
13720
|
+
variant: "primary",
|
|
13721
|
+
onClick: () => handleAction(action.id),
|
|
13722
|
+
children: action.label
|
|
13723
|
+
},
|
|
13724
|
+
action.id
|
|
13725
|
+
)) })
|
|
13726
|
+
] }) }),
|
|
13727
|
+
history.length > 0 && /* @__PURE__ */ jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxs(VStack, { gap: "sm", children: [
|
|
13728
|
+
/* @__PURE__ */ jsx(Typography, { variant: "small", weight: "bold", className: "uppercase tracking-wider text-muted-foreground", children: t("negotiator.history") }),
|
|
13729
|
+
history.map((round) => /* @__PURE__ */ jsxs(HStack, { gap: "sm", align: "center", className: "text-sm", children: [
|
|
13730
|
+
/* @__PURE__ */ jsxs(Badge, { size: "sm", children: [
|
|
13731
|
+
"R",
|
|
13732
|
+
round.round
|
|
13733
|
+
] }),
|
|
13734
|
+
/* @__PURE__ */ jsx(Typography, { variant: "caption", children: getActionLabel(round.playerAction) }),
|
|
13735
|
+
/* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-muted-foreground", children: "vs" }),
|
|
13736
|
+
/* @__PURE__ */ jsx(Typography, { variant: "caption", children: getActionLabel(round.opponentAction) }),
|
|
13737
|
+
/* @__PURE__ */ jsx(GameIcon, { icon: ArrowRight, assetUrl: ui?.["arrow"], size: "sm" }),
|
|
13738
|
+
/* @__PURE__ */ jsxs(Typography, { variant: "caption", weight: "bold", className: "text-success", children: [
|
|
13739
|
+
"+",
|
|
13740
|
+
round.playerPayoff
|
|
13741
|
+
] }),
|
|
13742
|
+
/* @__PURE__ */ jsxs(Typography, { variant: "caption", className: "text-muted-foreground", children: [
|
|
13743
|
+
"/ +",
|
|
13744
|
+
round.opponentPayoff
|
|
13745
|
+
] })
|
|
13746
|
+
] }, round.round))
|
|
13747
|
+
] }) }),
|
|
13748
|
+
isComplete && /* @__PURE__ */ jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxs(VStack, { gap: "sm", align: "center", children: [
|
|
13749
|
+
/* @__PURE__ */ jsx(GameIcon, { icon: CheckCircle, assetUrl: ui?.["correct"], size: "lg", className: won ? "text-success" : "text-error" }),
|
|
13750
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body", weight: "bold", children: won ? str(resolved.successMessage) || t("negotiator.success") : str(resolved.failMessage) || t("negotiator.failed") }),
|
|
13751
|
+
/* @__PURE__ */ jsxs(Typography, { variant: "caption", className: "text-muted-foreground", children: [
|
|
13752
|
+
t("negotiator.finalScore"),
|
|
13753
|
+
": ",
|
|
13754
|
+
playerTotal,
|
|
13755
|
+
"/",
|
|
13756
|
+
targetScore
|
|
13757
|
+
] })
|
|
13758
|
+
] }) }),
|
|
13759
|
+
showHint && hint && !won && /* @__PURE__ */ jsx(Card, { className: "p-4 border-l-4 border-l-warning", children: /* @__PURE__ */ jsx(Typography, { variant: "body", children: hint }) }),
|
|
13760
|
+
isComplete && !won && /* @__PURE__ */ jsx(HStack, { justify: "center", children: /* @__PURE__ */ jsx(Button, { variant: "primary", onClick: handleReset, children: t("negotiator.playAgain") }) })
|
|
13761
|
+
] })
|
|
13762
|
+
}
|
|
13763
|
+
);
|
|
13764
|
+
}
|
|
13765
|
+
var init_NegotiatorBoard = __esm({
|
|
13766
|
+
"components/game/2d/organisms/NegotiatorBoard.tsx"() {
|
|
13767
|
+
init_atoms();
|
|
13768
|
+
init_useEventBus();
|
|
13769
|
+
init_boardEntity();
|
|
13770
|
+
init_GameIcon();
|
|
13771
|
+
NegotiatorBoard.displayName = "NegotiatorBoard";
|
|
13772
|
+
}
|
|
13773
|
+
});
|
|
11607
13774
|
|
|
11608
13775
|
// components/game/shared/lib/mechanics.ts
|
|
11609
13776
|
var projectileMotion, pendulum, springOscillator;
|
|
@@ -11811,7 +13978,7 @@ function SimulationCanvas({
|
|
|
11811
13978
|
}
|
|
11812
13979
|
var PRESET_BY_ID;
|
|
11813
13980
|
var init_SimulationCanvas = __esm({
|
|
11814
|
-
"components/game/2d/
|
|
13981
|
+
"components/game/2d/organisms/SimulationCanvas.tsx"() {
|
|
11815
13982
|
init_cn();
|
|
11816
13983
|
init_atoms();
|
|
11817
13984
|
init_verificationRegistry();
|
|
@@ -12433,7 +14600,7 @@ var init_ErrorBoundary = __esm({
|
|
|
12433
14600
|
}
|
|
12434
14601
|
);
|
|
12435
14602
|
};
|
|
12436
|
-
ErrorBoundary = class extends
|
|
14603
|
+
ErrorBoundary = class extends React98__default.Component {
|
|
12437
14604
|
constructor(props) {
|
|
12438
14605
|
super(props);
|
|
12439
14606
|
__publicField(this, "reset", () => {
|
|
@@ -12478,15 +14645,15 @@ function HeaderSkeleton({ className }) {
|
|
|
12478
14645
|
] })
|
|
12479
14646
|
] });
|
|
12480
14647
|
}
|
|
12481
|
-
function TableSkeleton({ rows = 5, columns = 4, className }) {
|
|
14648
|
+
function TableSkeleton({ rows: rows2 = 5, columns = 4, className }) {
|
|
12482
14649
|
return /* @__PURE__ */ jsxs(VStack, { gap: "none", className: cn("border border-border rounded-lg overflow-hidden", className), children: [
|
|
12483
14650
|
/* @__PURE__ */ jsx(HStack, { className: "px-4 py-3 bg-muted/30 border-b border-border", children: Array.from({ length: columns }).map((_, i) => /* @__PURE__ */ jsx(SkeletonBlock, { className: "h-4 flex-1 mx-2" }, i)) }),
|
|
12484
|
-
Array.from({ length:
|
|
14651
|
+
Array.from({ length: rows2 }).map((_, rowIdx) => /* @__PURE__ */ jsx(
|
|
12485
14652
|
HStack,
|
|
12486
14653
|
{
|
|
12487
14654
|
className: cn(
|
|
12488
14655
|
"px-4 py-3",
|
|
12489
|
-
rowIdx <
|
|
14656
|
+
rowIdx < rows2 - 1 && "border-b border-border"
|
|
12490
14657
|
),
|
|
12491
14658
|
children: Array.from({ length: columns }).map((_2, colIdx) => /* @__PURE__ */ jsx(SkeletonLine, { className: "flex-1 mx-2" }, colIdx))
|
|
12492
14659
|
},
|
|
@@ -12534,18 +14701,18 @@ function CardSkeleton({ className }) {
|
|
|
12534
14701
|
}
|
|
12535
14702
|
);
|
|
12536
14703
|
}
|
|
12537
|
-
function TextSkeleton({ rows = 3, className }) {
|
|
12538
|
-
return /* @__PURE__ */ jsx(VStack, { gap: "sm", className, children: Array.from({ length:
|
|
14704
|
+
function TextSkeleton({ rows: rows2 = 3, className }) {
|
|
14705
|
+
return /* @__PURE__ */ jsx(VStack, { gap: "sm", className, children: Array.from({ length: rows2 }).map((_, i) => /* @__PURE__ */ jsx(
|
|
12539
14706
|
SkeletonLine,
|
|
12540
14707
|
{
|
|
12541
|
-
className: i ===
|
|
14708
|
+
className: i === rows2 - 1 ? "w-2/3" : "w-full"
|
|
12542
14709
|
},
|
|
12543
14710
|
i
|
|
12544
14711
|
)) });
|
|
12545
14712
|
}
|
|
12546
14713
|
function Skeleton({
|
|
12547
14714
|
variant = "text",
|
|
12548
|
-
rows,
|
|
14715
|
+
rows: rows2,
|
|
12549
14716
|
columns,
|
|
12550
14717
|
fields,
|
|
12551
14718
|
className
|
|
@@ -12555,15 +14722,15 @@ function Skeleton({
|
|
|
12555
14722
|
case "header":
|
|
12556
14723
|
return /* @__PURE__ */ jsx(HeaderSkeleton, { className });
|
|
12557
14724
|
case "table":
|
|
12558
|
-
return /* @__PURE__ */ jsx(TableSkeleton, { rows, columns, className });
|
|
14725
|
+
return /* @__PURE__ */ jsx(TableSkeleton, { rows: rows2, columns, className });
|
|
12559
14726
|
case "form":
|
|
12560
14727
|
return /* @__PURE__ */ jsx(FormSkeleton, { fields, className });
|
|
12561
14728
|
case "card":
|
|
12562
14729
|
return /* @__PURE__ */ jsx(CardSkeleton, { className });
|
|
12563
14730
|
case "text":
|
|
12564
|
-
return /* @__PURE__ */ jsx(TextSkeleton, { rows, className });
|
|
14731
|
+
return /* @__PURE__ */ jsx(TextSkeleton, { rows: rows2, className });
|
|
12565
14732
|
default:
|
|
12566
|
-
return /* @__PURE__ */ jsx(TextSkeleton, { rows, className });
|
|
14733
|
+
return /* @__PURE__ */ jsx(TextSkeleton, { rows: rows2, className });
|
|
12567
14734
|
}
|
|
12568
14735
|
}
|
|
12569
14736
|
var pulseClass;
|
|
@@ -13098,7 +15265,7 @@ var init_Container = __esm({
|
|
|
13098
15265
|
as: Component = "div"
|
|
13099
15266
|
}) => {
|
|
13100
15267
|
const resolvedSize = maxWidth ?? size ?? "lg";
|
|
13101
|
-
return
|
|
15268
|
+
return React98__default.createElement(
|
|
13102
15269
|
Component,
|
|
13103
15270
|
{
|
|
13104
15271
|
className: cn(
|
|
@@ -15766,7 +17933,7 @@ var init_CodeBlock = __esm({
|
|
|
15766
17933
|
DIFF_STYLE_FALLBACK = { bg: "", prefix: " ", text: "text-foreground" };
|
|
15767
17934
|
LINE_PROPS_FN = (n) => ({ "data-line": String(n - 1) });
|
|
15768
17935
|
HIDDEN_LINE_NUMBERS = { display: "none" };
|
|
15769
|
-
CodeBlock =
|
|
17936
|
+
CodeBlock = React98__default.memo(
|
|
15770
17937
|
({
|
|
15771
17938
|
code: rawCode,
|
|
15772
17939
|
language = "text",
|
|
@@ -15935,24 +18102,24 @@ var init_CodeBlock = __esm({
|
|
|
15935
18102
|
return;
|
|
15936
18103
|
}
|
|
15937
18104
|
lineEls.forEach((el) => {
|
|
15938
|
-
const
|
|
15939
|
-
if (hiddenLines.has(
|
|
18105
|
+
const num2 = parseInt(el.getAttribute("data-line") ?? "-1", 10);
|
|
18106
|
+
if (hiddenLines.has(num2)) {
|
|
15940
18107
|
el.style.display = "none";
|
|
15941
18108
|
return;
|
|
15942
18109
|
}
|
|
15943
18110
|
el.style.display = "";
|
|
15944
18111
|
el.style.position = "relative";
|
|
15945
18112
|
el.style.paddingLeft = "1.2em";
|
|
15946
|
-
const region = foldStartMap.get(
|
|
18113
|
+
const region = foldStartMap.get(num2);
|
|
15947
18114
|
if (!region) return;
|
|
15948
|
-
const isCollapsed = collapsed.has(
|
|
18115
|
+
const isCollapsed = collapsed.has(num2);
|
|
15949
18116
|
const toggle = document.createElement("span");
|
|
15950
18117
|
toggle.className = "fold-toggle";
|
|
15951
18118
|
toggle.textContent = isCollapsed ? "\u25B6" : "\u25BC";
|
|
15952
18119
|
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%";
|
|
15953
18120
|
toggle.addEventListener("click", (e) => {
|
|
15954
18121
|
e.stopPropagation();
|
|
15955
|
-
toggleFoldRef.current(
|
|
18122
|
+
toggleFoldRef.current(num2);
|
|
15956
18123
|
});
|
|
15957
18124
|
el.insertBefore(toggle, el.firstChild);
|
|
15958
18125
|
if (isCollapsed) {
|
|
@@ -16353,7 +18520,7 @@ var init_MarkdownContent = __esm({
|
|
|
16353
18520
|
init_Box();
|
|
16354
18521
|
init_CodeBlock();
|
|
16355
18522
|
init_cn();
|
|
16356
|
-
MarkdownContent =
|
|
18523
|
+
MarkdownContent = React98__default.memo(
|
|
16357
18524
|
({ content, direction = "ltr", className }) => {
|
|
16358
18525
|
const { t: _t } = useTranslate();
|
|
16359
18526
|
const safeContent = typeof content === "string" ? content : String(content ?? "");
|
|
@@ -16922,7 +19089,7 @@ var init_QuizBlock = __esm({
|
|
|
16922
19089
|
QuizBlock.displayName = "QuizBlock";
|
|
16923
19090
|
}
|
|
16924
19091
|
});
|
|
16925
|
-
var
|
|
19092
|
+
var StateNode2, TransitionBundleArrow, BundleTooltip, EntityBox, OutputsBox, Legend, StateMachineView;
|
|
16926
19093
|
var init_StateMachineView = __esm({
|
|
16927
19094
|
"components/core/organisms/StateMachineView.tsx"() {
|
|
16928
19095
|
"use client";
|
|
@@ -16934,7 +19101,7 @@ var init_StateMachineView = __esm({
|
|
|
16934
19101
|
init_Icon();
|
|
16935
19102
|
init_useEventBus();
|
|
16936
19103
|
init_cn();
|
|
16937
|
-
|
|
19104
|
+
StateNode2 = ({ state, config }) => {
|
|
16938
19105
|
const { t } = useTranslate();
|
|
16939
19106
|
const size = state.radius * 2;
|
|
16940
19107
|
let borderColor = config.colors.nodeBorder;
|
|
@@ -17680,8 +19847,8 @@ var init_StateMachineView = __esm({
|
|
|
17680
19847
|
style: { top: title ? 30 : 0 },
|
|
17681
19848
|
children: [
|
|
17682
19849
|
entity && /* @__PURE__ */ jsx(EntityBox, { entity, config }),
|
|
17683
|
-
states.map((state) => renderStateNode ? /* @__PURE__ */ jsx(
|
|
17684
|
-
|
|
19850
|
+
states.map((state) => renderStateNode ? /* @__PURE__ */ jsx(React98__default.Fragment, { children: renderStateNode(state, config) }, state.id) : /* @__PURE__ */ jsx(
|
|
19851
|
+
StateNode2,
|
|
17685
19852
|
{
|
|
17686
19853
|
state,
|
|
17687
19854
|
config
|
|
@@ -23318,8 +25485,8 @@ var init_Menu = __esm({
|
|
|
23318
25485
|
"bottom-end": "bottom-start"
|
|
23319
25486
|
};
|
|
23320
25487
|
const effectivePosition = direction === "rtl" ? rtlMirror[position] ?? position : position;
|
|
23321
|
-
const triggerChild =
|
|
23322
|
-
const triggerElement =
|
|
25488
|
+
const triggerChild = React98__default.isValidElement(trigger) ? trigger : /* @__PURE__ */ jsx(Typography, { variant: "small", as: "span", children: trigger });
|
|
25489
|
+
const triggerElement = React98__default.cloneElement(
|
|
23323
25490
|
triggerChild,
|
|
23324
25491
|
{
|
|
23325
25492
|
ref: triggerRef,
|
|
@@ -23414,14 +25581,14 @@ function useDataDnd(args) {
|
|
|
23414
25581
|
const isZone = Boolean(dragGroup || accepts || sortable);
|
|
23415
25582
|
const enabled = isZone || Boolean(dndRoot);
|
|
23416
25583
|
const eventBus = useEventBus();
|
|
23417
|
-
const parentRoot =
|
|
25584
|
+
const parentRoot = React98__default.useContext(RootCtx);
|
|
23418
25585
|
const isRoot = enabled && parentRoot === null;
|
|
23419
|
-
const zoneId =
|
|
25586
|
+
const zoneId = React98__default.useId();
|
|
23420
25587
|
const ownGroup = dragGroup ?? accepts ?? zoneId;
|
|
23421
|
-
const [optimisticOrders, setOptimisticOrders] =
|
|
23422
|
-
const optimisticOrdersRef =
|
|
25588
|
+
const [optimisticOrders, setOptimisticOrders] = React98__default.useState(() => /* @__PURE__ */ new Map());
|
|
25589
|
+
const optimisticOrdersRef = React98__default.useRef(optimisticOrders);
|
|
23423
25590
|
optimisticOrdersRef.current = optimisticOrders;
|
|
23424
|
-
const clearOptimisticOrder =
|
|
25591
|
+
const clearOptimisticOrder = React98__default.useCallback((group) => {
|
|
23425
25592
|
setOptimisticOrders((prev) => {
|
|
23426
25593
|
if (!prev.has(group)) return prev;
|
|
23427
25594
|
const next = new Map(prev);
|
|
@@ -23446,7 +25613,7 @@ function useDataDnd(args) {
|
|
|
23446
25613
|
const raw = it[dndItemIdField];
|
|
23447
25614
|
return raw != null ? String(raw) : `__idx_${idx}`;
|
|
23448
25615
|
}).join("|");
|
|
23449
|
-
const itemIds =
|
|
25616
|
+
const itemIds = React98__default.useMemo(
|
|
23450
25617
|
() => orderedItems.map((it, idx) => {
|
|
23451
25618
|
const raw = it[dndItemIdField];
|
|
23452
25619
|
return raw != null ? String(raw) : `__idx_${idx}`;
|
|
@@ -23457,7 +25624,7 @@ function useDataDnd(args) {
|
|
|
23457
25624
|
const raw = it[dndItemIdField];
|
|
23458
25625
|
return raw != null ? String(raw) : `__${idx}`;
|
|
23459
25626
|
}).join("|");
|
|
23460
|
-
|
|
25627
|
+
React98__default.useEffect(() => {
|
|
23461
25628
|
const root = isRoot ? null : parentRoot;
|
|
23462
25629
|
if (root) {
|
|
23463
25630
|
root.clearOptimisticOrder(ownGroup);
|
|
@@ -23465,20 +25632,20 @@ function useDataDnd(args) {
|
|
|
23465
25632
|
clearOptimisticOrder(ownGroup);
|
|
23466
25633
|
}
|
|
23467
25634
|
}, [itemsContentSig, ownGroup]);
|
|
23468
|
-
const zonesRef =
|
|
23469
|
-
const registerZone =
|
|
25635
|
+
const zonesRef = React98__default.useRef(/* @__PURE__ */ new Map());
|
|
25636
|
+
const registerZone = React98__default.useCallback((zoneId2, meta2) => {
|
|
23470
25637
|
zonesRef.current.set(zoneId2, meta2);
|
|
23471
25638
|
}, []);
|
|
23472
|
-
const unregisterZone =
|
|
25639
|
+
const unregisterZone = React98__default.useCallback((zoneId2) => {
|
|
23473
25640
|
zonesRef.current.delete(zoneId2);
|
|
23474
25641
|
}, []);
|
|
23475
|
-
const [activeDrag, setActiveDrag] =
|
|
23476
|
-
const [overZoneGroup, setOverZoneGroup] =
|
|
23477
|
-
const meta =
|
|
25642
|
+
const [activeDrag, setActiveDrag] = React98__default.useState(null);
|
|
25643
|
+
const [overZoneGroup, setOverZoneGroup] = React98__default.useState(null);
|
|
25644
|
+
const meta = React98__default.useMemo(
|
|
23478
25645
|
() => ({ group: ownGroup, dropEvent, reorderEvent, positionEvent, itemIds, rawItems: items, idField: dndItemIdField }),
|
|
23479
25646
|
[ownGroup, dropEvent, reorderEvent, positionEvent, itemIds, items, dndItemIdField]
|
|
23480
25647
|
);
|
|
23481
|
-
|
|
25648
|
+
React98__default.useEffect(() => {
|
|
23482
25649
|
const target = isRoot ? null : parentRoot;
|
|
23483
25650
|
if (!target) {
|
|
23484
25651
|
zonesRef.current.set(zoneId, meta);
|
|
@@ -23497,7 +25664,7 @@ function useDataDnd(args) {
|
|
|
23497
25664
|
}, [parentRoot, isRoot, zoneId, meta]);
|
|
23498
25665
|
const sensors = useAlmadarDndSensors(true);
|
|
23499
25666
|
const collisionDetection = almadarDndCollisionDetection;
|
|
23500
|
-
const findZoneByItem =
|
|
25667
|
+
const findZoneByItem = React98__default.useCallback(
|
|
23501
25668
|
(id) => {
|
|
23502
25669
|
for (const z of zonesRef.current.values()) {
|
|
23503
25670
|
if (z.itemIds.includes(id)) return z;
|
|
@@ -23506,7 +25673,7 @@ function useDataDnd(args) {
|
|
|
23506
25673
|
},
|
|
23507
25674
|
[]
|
|
23508
25675
|
);
|
|
23509
|
-
|
|
25676
|
+
React98__default.useCallback(
|
|
23510
25677
|
(group) => {
|
|
23511
25678
|
for (const z of zonesRef.current.values()) {
|
|
23512
25679
|
if (z.group === group) return z;
|
|
@@ -23515,7 +25682,7 @@ function useDataDnd(args) {
|
|
|
23515
25682
|
},
|
|
23516
25683
|
[]
|
|
23517
25684
|
);
|
|
23518
|
-
const handleDragEnd =
|
|
25685
|
+
const handleDragEnd = React98__default.useCallback(
|
|
23519
25686
|
(event) => {
|
|
23520
25687
|
const { active, over } = event;
|
|
23521
25688
|
const activeIdStr = String(active.id);
|
|
@@ -23606,8 +25773,8 @@ function useDataDnd(args) {
|
|
|
23606
25773
|
},
|
|
23607
25774
|
[eventBus]
|
|
23608
25775
|
);
|
|
23609
|
-
const sortableData =
|
|
23610
|
-
const SortableItem =
|
|
25776
|
+
const sortableData = React98__default.useMemo(() => ({ dndGroup: ownGroup }), [ownGroup]);
|
|
25777
|
+
const SortableItem = React98__default.useCallback(
|
|
23611
25778
|
({ id, children }) => {
|
|
23612
25779
|
const {
|
|
23613
25780
|
attributes,
|
|
@@ -23647,7 +25814,7 @@ function useDataDnd(args) {
|
|
|
23647
25814
|
id: droppableId,
|
|
23648
25815
|
data: sortableData
|
|
23649
25816
|
});
|
|
23650
|
-
const ctx =
|
|
25817
|
+
const ctx = React98__default.useContext(RootCtx);
|
|
23651
25818
|
const activeDrag2 = ctx?.activeDrag ?? null;
|
|
23652
25819
|
const overZoneGroup2 = ctx?.overZoneGroup ?? null;
|
|
23653
25820
|
const isThisZoneOver = overZoneGroup2 === ownGroup;
|
|
@@ -23662,7 +25829,7 @@ function useDataDnd(args) {
|
|
|
23662
25829
|
showForeignPlaceholder,
|
|
23663
25830
|
ctxAvailable: ctx != null
|
|
23664
25831
|
});
|
|
23665
|
-
|
|
25832
|
+
React98__default.useEffect(() => {
|
|
23666
25833
|
dndLog.info("dropzone:isOver:change", { droppableId, group: ownGroup, isOver, isThisZoneOver, showForeignPlaceholder, activeDragSourceGroup: activeDrag2?.sourceGroup ?? null });
|
|
23667
25834
|
}, [droppableId, isOver, isThisZoneOver, showForeignPlaceholder]);
|
|
23668
25835
|
return /* @__PURE__ */ jsx(
|
|
@@ -23676,11 +25843,11 @@ function useDataDnd(args) {
|
|
|
23676
25843
|
}
|
|
23677
25844
|
);
|
|
23678
25845
|
};
|
|
23679
|
-
const rootContextValue =
|
|
25846
|
+
const rootContextValue = React98__default.useMemo(
|
|
23680
25847
|
() => ({ registerZone, unregisterZone, activeDrag, overZoneGroup, optimisticOrders, clearOptimisticOrder }),
|
|
23681
25848
|
[registerZone, unregisterZone, activeDrag, overZoneGroup, optimisticOrders, clearOptimisticOrder]
|
|
23682
25849
|
);
|
|
23683
|
-
const handleDragStart =
|
|
25850
|
+
const handleDragStart = React98__default.useCallback((event) => {
|
|
23684
25851
|
const sourceZone = findZoneByItem(event.active.id);
|
|
23685
25852
|
const rect = event.active.rect.current.initial;
|
|
23686
25853
|
const height = rect?.height && rect.height > 0 ? rect.height : 64;
|
|
@@ -23699,7 +25866,7 @@ function useDataDnd(args) {
|
|
|
23699
25866
|
isRoot
|
|
23700
25867
|
});
|
|
23701
25868
|
}, [findZoneByItem, isRoot, zoneId]);
|
|
23702
|
-
const handleDragOver =
|
|
25869
|
+
const handleDragOver = React98__default.useCallback((event) => {
|
|
23703
25870
|
const { active, over } = event;
|
|
23704
25871
|
const overData = over?.data?.current;
|
|
23705
25872
|
const overGroup = overData?.dndGroup ?? null;
|
|
@@ -23769,7 +25936,7 @@ function useDataDnd(args) {
|
|
|
23769
25936
|
return next;
|
|
23770
25937
|
});
|
|
23771
25938
|
}, []);
|
|
23772
|
-
const handleDragCancel =
|
|
25939
|
+
const handleDragCancel = React98__default.useCallback((event) => {
|
|
23773
25940
|
setActiveDrag(null);
|
|
23774
25941
|
setOverZoneGroup(null);
|
|
23775
25942
|
dndLog.warn("dragCancel", {
|
|
@@ -23777,12 +25944,12 @@ function useDataDnd(args) {
|
|
|
23777
25944
|
reason: "dnd-kit cancelled the drag (escape key, pointer interrupted, or external)"
|
|
23778
25945
|
});
|
|
23779
25946
|
}, []);
|
|
23780
|
-
const handleDragEndWithCleanup =
|
|
25947
|
+
const handleDragEndWithCleanup = React98__default.useCallback((event) => {
|
|
23781
25948
|
handleDragEnd(event);
|
|
23782
25949
|
setActiveDrag(null);
|
|
23783
25950
|
setOverZoneGroup(null);
|
|
23784
25951
|
}, [handleDragEnd]);
|
|
23785
|
-
const wrapContainer =
|
|
25952
|
+
const wrapContainer = React98__default.useCallback(
|
|
23786
25953
|
(children) => {
|
|
23787
25954
|
if (!enabled) return children;
|
|
23788
25955
|
const strategy = layout === "grid" ? rectSortingStrategy : verticalListSortingStrategy;
|
|
@@ -23836,7 +26003,7 @@ var init_useDataDnd = __esm({
|
|
|
23836
26003
|
init_useAlmadarDndCollision();
|
|
23837
26004
|
init_Box();
|
|
23838
26005
|
dndLog = createLogger("almadar:ui:dnd");
|
|
23839
|
-
RootCtx =
|
|
26006
|
+
RootCtx = React98__default.createContext(null);
|
|
23840
26007
|
}
|
|
23841
26008
|
});
|
|
23842
26009
|
function renderIconInput(icon, props) {
|
|
@@ -24362,7 +26529,7 @@ function DataList({
|
|
|
24362
26529
|
}) {
|
|
24363
26530
|
const eventBus = useEventBus();
|
|
24364
26531
|
const { t } = useTranslate();
|
|
24365
|
-
const [visibleCount, setVisibleCount] =
|
|
26532
|
+
const [visibleCount, setVisibleCount] = React98__default.useState(pageSize || Infinity);
|
|
24366
26533
|
const fieldDefs = fields ?? columns ?? [];
|
|
24367
26534
|
const allDataRaw = Array.isArray(entity) ? entity : entity ? [entity] : [];
|
|
24368
26535
|
const dnd = useDataDnd({
|
|
@@ -24381,7 +26548,7 @@ function DataList({
|
|
|
24381
26548
|
const data = pageSize > 0 ? allData.slice(0, visibleCount) : allData;
|
|
24382
26549
|
const hasMoreLocal = pageSize > 0 && visibleCount < allData.length;
|
|
24383
26550
|
const hasRenderProp = typeof children === "function";
|
|
24384
|
-
|
|
26551
|
+
React98__default.useEffect(() => {
|
|
24385
26552
|
const renderItemTypeOf = typeof schemaRenderItem;
|
|
24386
26553
|
const childrenTypeOf = typeof children;
|
|
24387
26554
|
if (data.length > 0 && !hasRenderProp) {
|
|
@@ -24485,7 +26652,7 @@ function DataList({
|
|
|
24485
26652
|
const items2 = [...data];
|
|
24486
26653
|
const groups2 = groupBy ? groupData(items2, groupBy) : [{ label: "", items: items2 }];
|
|
24487
26654
|
const contentField = titleField?.name ?? fieldDefs[0]?.name ?? "";
|
|
24488
|
-
return /* @__PURE__ */ jsx(VStack, { gap: "sm", className: cn("py-2", className), children: groups2.map((group, gi) => /* @__PURE__ */ jsxs(
|
|
26655
|
+
return /* @__PURE__ */ jsx(VStack, { gap: "sm", className: cn("py-2", className), children: groups2.map((group, gi) => /* @__PURE__ */ jsxs(React98__default.Fragment, { children: [
|
|
24489
26656
|
group.label && /* @__PURE__ */ jsx(Divider, { label: group.label, className: "my-2" }),
|
|
24490
26657
|
group.items.map((itemData, index) => {
|
|
24491
26658
|
const id = itemData.id || `${gi}-${index}`;
|
|
@@ -24626,7 +26793,7 @@ function DataList({
|
|
|
24626
26793
|
className
|
|
24627
26794
|
),
|
|
24628
26795
|
children: [
|
|
24629
|
-
groups.map((group, gi) => /* @__PURE__ */ jsxs(
|
|
26796
|
+
groups.map((group, gi) => /* @__PURE__ */ jsxs(React98__default.Fragment, { children: [
|
|
24630
26797
|
group.label && /* @__PURE__ */ jsx(Divider, { label: group.label, className: gi > 0 ? "mt-4" : "mt-0" }),
|
|
24631
26798
|
group.items.map(
|
|
24632
26799
|
(itemData, index) => renderItem(itemData, index, gi === groups.length - 1 && index === group.items.length - 1)
|
|
@@ -24711,7 +26878,7 @@ var init_FormSection = __esm({
|
|
|
24711
26878
|
columns = 1,
|
|
24712
26879
|
className
|
|
24713
26880
|
}) => {
|
|
24714
|
-
const [collapsed, setCollapsed] =
|
|
26881
|
+
const [collapsed, setCollapsed] = React98__default.useState(defaultCollapsed);
|
|
24715
26882
|
const { t } = useTranslate();
|
|
24716
26883
|
const eventBus = useEventBus();
|
|
24717
26884
|
const gridClass = {
|
|
@@ -24719,7 +26886,7 @@ var init_FormSection = __esm({
|
|
|
24719
26886
|
2: "grid-cols-1 md:grid-cols-2",
|
|
24720
26887
|
3: "grid-cols-1 md:grid-cols-2 lg:grid-cols-3"
|
|
24721
26888
|
}[columns];
|
|
24722
|
-
|
|
26889
|
+
React98__default.useCallback(() => {
|
|
24723
26890
|
if (collapsible) {
|
|
24724
26891
|
setCollapsed((prev) => !prev);
|
|
24725
26892
|
eventBus.emit("UI:TOGGLE_COLLAPSE", { collapsed: !collapsed });
|
|
@@ -25669,7 +27836,7 @@ var init_Flex = __esm({
|
|
|
25669
27836
|
flexStyle.flexBasis = typeof basis === "number" ? `${basis}px` : basis;
|
|
25670
27837
|
}
|
|
25671
27838
|
}
|
|
25672
|
-
return
|
|
27839
|
+
return React98__default.createElement(Component, {
|
|
25673
27840
|
className: cn(
|
|
25674
27841
|
inline ? "inline-flex" : "flex",
|
|
25675
27842
|
directionStyles[direction],
|
|
@@ -25775,7 +27942,7 @@ var init_Grid = __esm({
|
|
|
25775
27942
|
};
|
|
25776
27943
|
Grid = ({
|
|
25777
27944
|
cols = 1,
|
|
25778
|
-
rows,
|
|
27945
|
+
rows: rows2,
|
|
25779
27946
|
gap = "md",
|
|
25780
27947
|
rowGap,
|
|
25781
27948
|
colGap,
|
|
@@ -25787,8 +27954,8 @@ var init_Grid = __esm({
|
|
|
25787
27954
|
children,
|
|
25788
27955
|
as: Component = "div"
|
|
25789
27956
|
}) => {
|
|
25790
|
-
const mergedStyle =
|
|
25791
|
-
return
|
|
27957
|
+
const mergedStyle = rows2 ? { gridTemplateRows: `repeat(${rows2}, minmax(0, 1fr))`, ...style } : style;
|
|
27958
|
+
return React98__default.createElement(
|
|
25792
27959
|
Component,
|
|
25793
27960
|
{
|
|
25794
27961
|
className: cn(
|
|
@@ -25984,9 +28151,9 @@ var init_Popover = __esm({
|
|
|
25984
28151
|
onMouseLeave: handleClose,
|
|
25985
28152
|
onPointerDown: tapTriggerProps.onPointerDown
|
|
25986
28153
|
};
|
|
25987
|
-
const childElement =
|
|
28154
|
+
const childElement = React98__default.isValidElement(children) ? children : /* @__PURE__ */ jsx("span", { children });
|
|
25988
28155
|
const childPointerDown = childElement.props.onPointerDown;
|
|
25989
|
-
const triggerElement =
|
|
28156
|
+
const triggerElement = React98__default.cloneElement(
|
|
25990
28157
|
childElement,
|
|
25991
28158
|
{
|
|
25992
28159
|
ref: triggerRef,
|
|
@@ -26588,9 +28755,9 @@ var init_Tooltip = __esm({
|
|
|
26588
28755
|
if (hideTimeoutRef.current) clearTimeout(hideTimeoutRef.current);
|
|
26589
28756
|
};
|
|
26590
28757
|
}, []);
|
|
26591
|
-
const triggerElement =
|
|
28758
|
+
const triggerElement = React98__default.isValidElement(children) ? children : /* @__PURE__ */ jsx("span", { children });
|
|
26592
28759
|
const childPointerDown = triggerElement.props.onPointerDown;
|
|
26593
|
-
const trigger =
|
|
28760
|
+
const trigger = React98__default.cloneElement(triggerElement, {
|
|
26594
28761
|
ref: triggerRef,
|
|
26595
28762
|
onMouseEnter: handleMouseEnter,
|
|
26596
28763
|
onMouseLeave: handleMouseLeave,
|
|
@@ -26680,7 +28847,7 @@ var init_WizardProgress = __esm({
|
|
|
26680
28847
|
children: /* @__PURE__ */ jsx("div", { className: "flex items-center gap-2", children: normalizedSteps.map((step, index) => {
|
|
26681
28848
|
const isActive = index === currentStep;
|
|
26682
28849
|
const isCompleted = index < currentStep;
|
|
26683
|
-
return /* @__PURE__ */ jsxs(
|
|
28850
|
+
return /* @__PURE__ */ jsxs(React98__default.Fragment, { children: [
|
|
26684
28851
|
/* @__PURE__ */ jsx(
|
|
26685
28852
|
"button",
|
|
26686
28853
|
{
|
|
@@ -28240,13 +30407,13 @@ var init_MapView = __esm({
|
|
|
28240
30407
|
shadowSize: [41, 41]
|
|
28241
30408
|
});
|
|
28242
30409
|
L.Marker.prototype.options.icon = defaultIcon;
|
|
28243
|
-
const { useEffect:
|
|
30410
|
+
const { useEffect: useEffect68, useRef: useRef65, useCallback: useCallback104, useState: useState98 } = React98__default;
|
|
28244
30411
|
const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
|
|
28245
30412
|
const { useEventBus: useEventBus2 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
|
|
28246
30413
|
function MapUpdater({ centerLat, centerLng, zoom }) {
|
|
28247
30414
|
const map = useMap();
|
|
28248
|
-
const prevRef =
|
|
28249
|
-
|
|
30415
|
+
const prevRef = useRef65({ centerLat, centerLng, zoom });
|
|
30416
|
+
useEffect68(() => {
|
|
28250
30417
|
const prev = prevRef.current;
|
|
28251
30418
|
if (prev.centerLat !== centerLat || prev.centerLng !== centerLng || prev.zoom !== zoom) {
|
|
28252
30419
|
map.setView([centerLat, centerLng], zoom);
|
|
@@ -28257,7 +30424,7 @@ var init_MapView = __esm({
|
|
|
28257
30424
|
}
|
|
28258
30425
|
function MapClickHandler({ onMapClick }) {
|
|
28259
30426
|
const map = useMap();
|
|
28260
|
-
|
|
30427
|
+
useEffect68(() => {
|
|
28261
30428
|
if (!onMapClick) return;
|
|
28262
30429
|
const handler = (e) => {
|
|
28263
30430
|
onMapClick(e.latlng.lat, e.latlng.lng);
|
|
@@ -28285,8 +30452,8 @@ var init_MapView = __esm({
|
|
|
28285
30452
|
showAttribution = true
|
|
28286
30453
|
}) {
|
|
28287
30454
|
const eventBus = useEventBus2();
|
|
28288
|
-
const [clickedPosition, setClickedPosition] =
|
|
28289
|
-
const handleMapClick =
|
|
30455
|
+
const [clickedPosition, setClickedPosition] = useState98(null);
|
|
30456
|
+
const handleMapClick = useCallback104((lat, lng) => {
|
|
28290
30457
|
if (showClickedPin) {
|
|
28291
30458
|
setClickedPosition({ lat, lng });
|
|
28292
30459
|
}
|
|
@@ -28295,7 +30462,7 @@ var init_MapView = __esm({
|
|
|
28295
30462
|
eventBus.emit(`UI:${mapClickEvent}`, { latitude: lat, longitude: lng });
|
|
28296
30463
|
}
|
|
28297
30464
|
}, [onMapClick, mapClickEvent, eventBus, showClickedPin]);
|
|
28298
|
-
const handleMarkerClick =
|
|
30465
|
+
const handleMarkerClick = useCallback104((marker) => {
|
|
28299
30466
|
onMarkerClick?.(marker);
|
|
28300
30467
|
if (markerClickEvent) {
|
|
28301
30468
|
eventBus.emit(`UI:${markerClickEvent}`, { ...marker });
|
|
@@ -29155,8 +31322,8 @@ function TableView({
|
|
|
29155
31322
|
}) {
|
|
29156
31323
|
const eventBus = useEventBus();
|
|
29157
31324
|
const { t } = useTranslate();
|
|
29158
|
-
const [visibleCount, setVisibleCount] =
|
|
29159
|
-
const [localSelected, setLocalSelected] =
|
|
31325
|
+
const [visibleCount, setVisibleCount] = React98__default.useState(pageSize > 0 ? pageSize : Infinity);
|
|
31326
|
+
const [localSelected, setLocalSelected] = React98__default.useState(/* @__PURE__ */ new Set());
|
|
29160
31327
|
const colDefs = columns ?? fields ?? [];
|
|
29161
31328
|
const allDataRaw = Array.isArray(entity) ? entity : entity ? [entity] : [];
|
|
29162
31329
|
const dnd = useDataDnd({
|
|
@@ -29351,12 +31518,12 @@ function TableView({
|
|
|
29351
31518
|
]
|
|
29352
31519
|
}
|
|
29353
31520
|
);
|
|
29354
|
-
return dnd.isZone ? /* @__PURE__ */ jsx(dnd.SortableItem, { id: row[idField] ?? id, children: rowInner }, id) : /* @__PURE__ */ jsx(
|
|
31521
|
+
return dnd.isZone ? /* @__PURE__ */ jsx(dnd.SortableItem, { id: row[idField] ?? id, children: rowInner }, id) : /* @__PURE__ */ jsx(React98__default.Fragment, { children: rowInner }, id);
|
|
29355
31522
|
};
|
|
29356
31523
|
const items = Array.from(data);
|
|
29357
31524
|
const groups = groupBy ? groupData2(items, groupBy) : [{ label: "", items }];
|
|
29358
31525
|
let runningIndex = 0;
|
|
29359
|
-
const body = /* @__PURE__ */ jsx(Box, { role: "rowgroup", children: groups.map((group, gi) => /* @__PURE__ */ jsxs(
|
|
31526
|
+
const body = /* @__PURE__ */ jsx(Box, { role: "rowgroup", children: groups.map((group, gi) => /* @__PURE__ */ jsxs(React98__default.Fragment, { children: [
|
|
29360
31527
|
group.label && /* @__PURE__ */ jsx(Divider, { label: group.label, className: gi > 0 ? "mt-3" : "mt-0" }),
|
|
29361
31528
|
group.items.map((row) => renderRow(row, runningIndex++))
|
|
29362
31529
|
] }, gi)) });
|
|
@@ -30713,7 +32880,7 @@ var init_StepFlow = __esm({
|
|
|
30713
32880
|
className
|
|
30714
32881
|
}) => {
|
|
30715
32882
|
if (orientation === "vertical") {
|
|
30716
|
-
return /* @__PURE__ */ jsx(VStack, { gap: "none", className: cn("w-full", className), children: steps.map((step, index) => /* @__PURE__ */ jsx(
|
|
32883
|
+
return /* @__PURE__ */ jsx(VStack, { gap: "none", className: cn("w-full", className), children: steps.map((step, index) => /* @__PURE__ */ jsx(React98__default.Fragment, { children: /* @__PURE__ */ jsxs(HStack, { gap: "md", align: "start", className: "w-full", children: [
|
|
30717
32884
|
/* @__PURE__ */ jsxs(VStack, { gap: "none", align: "center", children: [
|
|
30718
32885
|
/* @__PURE__ */ jsx(StepCircle, { step, index }),
|
|
30719
32886
|
showConnectors && index < steps.length - 1 && /* @__PURE__ */ jsx(Box, { className: "w-px h-8 bg-border" })
|
|
@@ -30724,7 +32891,7 @@ var init_StepFlow = __esm({
|
|
|
30724
32891
|
] })
|
|
30725
32892
|
] }) }, index)) });
|
|
30726
32893
|
}
|
|
30727
|
-
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(
|
|
32894
|
+
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(React98__default.Fragment, { children: [
|
|
30728
32895
|
/* @__PURE__ */ jsxs(VStack, { gap: "sm", align: "center", className: "flex-1 w-full md:w-auto", children: [
|
|
30729
32896
|
/* @__PURE__ */ jsx(StepCircle, { step, index }),
|
|
30730
32897
|
/* @__PURE__ */ jsx(Typography, { variant: "h4", className: "text-center", children: step.title }),
|
|
@@ -31450,11 +33617,11 @@ function LatticeSVG({
|
|
|
31450
33617
|
}) {
|
|
31451
33618
|
const paths = [];
|
|
31452
33619
|
const cols = 5;
|
|
31453
|
-
const
|
|
33620
|
+
const rows2 = Math.ceil(h / (w / cols));
|
|
31454
33621
|
const cellW = w / cols;
|
|
31455
33622
|
const cellH = cellW;
|
|
31456
33623
|
const bulge = cellW * 0.3;
|
|
31457
|
-
for (let row = 0; row <
|
|
33624
|
+
for (let row = 0; row < rows2; row++) {
|
|
31458
33625
|
for (let col = 0; col < cols; col++) {
|
|
31459
33626
|
const cx = col * cellW + cellW / 2;
|
|
31460
33627
|
const cy = row * cellH + cellH / 2;
|
|
@@ -31709,7 +33876,7 @@ var init_LikertScale = __esm({
|
|
|
31709
33876
|
md: "text-base",
|
|
31710
33877
|
lg: "text-lg"
|
|
31711
33878
|
};
|
|
31712
|
-
LikertScale =
|
|
33879
|
+
LikertScale = React98__default.forwardRef(
|
|
31713
33880
|
({
|
|
31714
33881
|
question,
|
|
31715
33882
|
options = DEFAULT_LIKERT_OPTIONS,
|
|
@@ -31721,7 +33888,7 @@ var init_LikertScale = __esm({
|
|
|
31721
33888
|
variant = "radios",
|
|
31722
33889
|
className
|
|
31723
33890
|
}, ref) => {
|
|
31724
|
-
const groupId =
|
|
33891
|
+
const groupId = React98__default.useId();
|
|
31725
33892
|
const eventBus = useEventBus();
|
|
31726
33893
|
const handleSelect = useCallback(
|
|
31727
33894
|
(next) => {
|
|
@@ -31875,7 +34042,7 @@ var init_MatrixQuestion = __esm({
|
|
|
31875
34042
|
};
|
|
31876
34043
|
MatrixQuestion = ({
|
|
31877
34044
|
title,
|
|
31878
|
-
rows,
|
|
34045
|
+
rows: rows2,
|
|
31879
34046
|
columns = DEFAULT_MATRIX_COLUMNS,
|
|
31880
34047
|
values,
|
|
31881
34048
|
onChange,
|
|
@@ -31885,7 +34052,7 @@ var init_MatrixQuestion = __esm({
|
|
|
31885
34052
|
className
|
|
31886
34053
|
}) => {
|
|
31887
34054
|
const styles = sizeStyles12[size];
|
|
31888
|
-
const safeRows =
|
|
34055
|
+
const safeRows = rows2 ?? [];
|
|
31889
34056
|
const safeValues = values ?? {};
|
|
31890
34057
|
const eventBus = useEventBus();
|
|
31891
34058
|
const handleChange = useCallback(
|
|
@@ -34003,7 +36170,7 @@ var init_DocBreadcrumb = __esm({
|
|
|
34003
36170
|
"aria-label": t("aria.breadcrumb"),
|
|
34004
36171
|
children: /* @__PURE__ */ jsx(HStack, { gap: "xs", align: "center", wrap: true, children: items.map((item, idx) => {
|
|
34005
36172
|
const isLast = idx === items.length - 1;
|
|
34006
|
-
return /* @__PURE__ */ jsxs(
|
|
36173
|
+
return /* @__PURE__ */ jsxs(React98__default.Fragment, { children: [
|
|
34007
36174
|
idx > 0 && /* @__PURE__ */ jsx(
|
|
34008
36175
|
Icon,
|
|
34009
36176
|
{
|
|
@@ -34872,7 +37039,7 @@ var init_MiniStateMachine = __esm({
|
|
|
34872
37039
|
const x = 2 + i * (NODE_W + GAP + ARROW_W + GAP);
|
|
34873
37040
|
const tc = transitionCounts[s.name] ?? 0;
|
|
34874
37041
|
const role = getStateRole(s.name, s.isInitial ?? void 0, s.isTerminal ?? void 0, tc, maxTC);
|
|
34875
|
-
return /* @__PURE__ */ jsxs(
|
|
37042
|
+
return /* @__PURE__ */ jsxs(React98__default.Fragment, { children: [
|
|
34876
37043
|
/* @__PURE__ */ jsx(
|
|
34877
37044
|
AvlState,
|
|
34878
37045
|
{
|
|
@@ -35076,7 +37243,7 @@ var init_PageHeader = __esm({
|
|
|
35076
37243
|
info: "bg-info/10 text-info"
|
|
35077
37244
|
};
|
|
35078
37245
|
return /* @__PURE__ */ jsxs(Box, { className: cn("mb-6", className), children: [
|
|
35079
|
-
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(
|
|
37246
|
+
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(React98__default.Fragment, { children: [
|
|
35080
37247
|
idx > 0 && /* @__PURE__ */ jsx(Typography, { variant: "small", color: "muted", children: "/" }),
|
|
35081
37248
|
crumb.href ? /* @__PURE__ */ jsx(
|
|
35082
37249
|
"a",
|
|
@@ -35434,7 +37601,7 @@ var init_Section = __esm({
|
|
|
35434
37601
|
as: Component = "section"
|
|
35435
37602
|
}) => {
|
|
35436
37603
|
const hasHeader = title || description || action;
|
|
35437
|
-
return
|
|
37604
|
+
return React98__default.createElement(
|
|
35438
37605
|
Component,
|
|
35439
37606
|
{
|
|
35440
37607
|
className: cn(
|
|
@@ -35758,8 +37925,8 @@ var init_WizardContainer = __esm({
|
|
|
35758
37925
|
return void 0;
|
|
35759
37926
|
if (typeof controlledStep === "number") return controlledStep;
|
|
35760
37927
|
if (typeof controlledStep === "string") return parseInt(controlledStep, 10);
|
|
35761
|
-
const
|
|
35762
|
-
return isNaN(
|
|
37928
|
+
const num2 = Number(controlledStep);
|
|
37929
|
+
return isNaN(num2) ? void 0 : num2;
|
|
35763
37930
|
})();
|
|
35764
37931
|
const currentStep = normalizedControlledStep !== void 0 ? normalizedControlledStep : internalStep;
|
|
35765
37932
|
const totalSteps = steps.length;
|
|
@@ -35808,7 +37975,7 @@ var init_WizardContainer = __esm({
|
|
|
35808
37975
|
const isCompleted = index < currentStep;
|
|
35809
37976
|
const stepKey = step.id ?? step.tabId ?? `step-${index}`;
|
|
35810
37977
|
const stepTitle = step.title ?? step.name ?? `Step ${index + 1}`;
|
|
35811
|
-
return /* @__PURE__ */ jsxs(
|
|
37978
|
+
return /* @__PURE__ */ jsxs(React98__default.Fragment, { children: [
|
|
35812
37979
|
/* @__PURE__ */ jsx(
|
|
35813
37980
|
Button,
|
|
35814
37981
|
{
|
|
@@ -37785,7 +39952,7 @@ function getBadgeVariant(fieldName, value) {
|
|
|
37785
39952
|
return "default";
|
|
37786
39953
|
}
|
|
37787
39954
|
function formatFieldLabel(fieldName) {
|
|
37788
|
-
return fieldName.replace(/([A-Z])/g, " $1").replace(/^./, (
|
|
39955
|
+
return fieldName.replace(/([A-Z])/g, " $1").replace(/^./, (str2) => str2.toUpperCase());
|
|
37789
39956
|
}
|
|
37790
39957
|
function formatFieldValue(value, fieldName) {
|
|
37791
39958
|
if (typeof value === "number") {
|
|
@@ -37804,26 +39971,26 @@ function formatFieldValue(value, fieldName) {
|
|
|
37804
39971
|
}
|
|
37805
39972
|
function renderRichFieldValue(value, fieldName, fieldType) {
|
|
37806
39973
|
if (value === void 0 || value === null) return "\u2014";
|
|
37807
|
-
const
|
|
39974
|
+
const str2 = String(value);
|
|
37808
39975
|
switch (fieldType) {
|
|
37809
39976
|
case "image":
|
|
37810
39977
|
case "url": {
|
|
37811
|
-
if (
|
|
39978
|
+
if (str2.match(/\.(png|jpe?g|gif|svg|webp|avif)(\?|$)/i) || str2.startsWith("data:image/")) {
|
|
37812
39979
|
return /* @__PURE__ */ jsx(Box, { className: "mt-1 max-w-full", children: /* @__PURE__ */ jsx(
|
|
37813
39980
|
"img",
|
|
37814
39981
|
{
|
|
37815
|
-
src:
|
|
39982
|
+
src: str2,
|
|
37816
39983
|
alt: formatFieldLabel(fieldName),
|
|
37817
39984
|
className: "max-w-full max-h-64 rounded-md object-contain",
|
|
37818
39985
|
loading: "lazy"
|
|
37819
39986
|
}
|
|
37820
39987
|
) });
|
|
37821
39988
|
}
|
|
37822
|
-
return
|
|
39989
|
+
return str2;
|
|
37823
39990
|
}
|
|
37824
39991
|
case "markdown":
|
|
37825
39992
|
case "richtext":
|
|
37826
|
-
return /* @__PURE__ */ jsx(Suspense, { fallback: /* @__PURE__ */ jsx(Typography, { variant: "body", className: "break-words", children:
|
|
39993
|
+
return /* @__PURE__ */ jsx(Suspense, { fallback: /* @__PURE__ */ jsx(Typography, { variant: "body", className: "break-words", children: str2 }), children: /* @__PURE__ */ jsx(
|
|
37827
39994
|
Box,
|
|
37828
39995
|
{
|
|
37829
39996
|
className: "prose prose-sm max-w-none",
|
|
@@ -37841,11 +40008,11 @@ function renderRichFieldValue(value, fieldName, fieldType) {
|
|
|
37841
40008
|
"--tw-prose-th-borders": "var(--color-border)",
|
|
37842
40009
|
"--tw-prose-td-borders": "var(--color-border)"
|
|
37843
40010
|
},
|
|
37844
|
-
children: /* @__PURE__ */ jsx(ReactMarkdown2, { children:
|
|
40011
|
+
children: /* @__PURE__ */ jsx(ReactMarkdown2, { children: str2 })
|
|
37845
40012
|
}
|
|
37846
40013
|
) });
|
|
37847
40014
|
case "code":
|
|
37848
|
-
return /* @__PURE__ */ jsx(Box, { className: "mt-1 rounded-md bg-muted p-3 overflow-x-auto", children: /* @__PURE__ */ jsx("pre", { className: "text-sm font-mono whitespace-pre-wrap break-words m-0", children: /* @__PURE__ */ jsx("code", { children:
|
|
40015
|
+
return /* @__PURE__ */ jsx(Box, { className: "mt-1 rounded-md bg-muted p-3 overflow-x-auto", children: /* @__PURE__ */ jsx("pre", { className: "text-sm font-mono whitespace-pre-wrap break-words m-0", children: /* @__PURE__ */ jsx("code", { children: str2 }) }) });
|
|
37849
40016
|
case "html":
|
|
37850
40017
|
return /* @__PURE__ */ jsx(
|
|
37851
40018
|
Box,
|
|
@@ -37865,12 +40032,12 @@ function renderRichFieldValue(value, fieldName, fieldType) {
|
|
|
37865
40032
|
"--tw-prose-th-borders": "var(--color-border)",
|
|
37866
40033
|
"--tw-prose-td-borders": "var(--color-border)"
|
|
37867
40034
|
},
|
|
37868
|
-
children: /* @__PURE__ */ jsx(Typography, { variant: "body", children:
|
|
40035
|
+
children: /* @__PURE__ */ jsx(Typography, { variant: "body", children: str2 })
|
|
37869
40036
|
}
|
|
37870
40037
|
);
|
|
37871
40038
|
case "date":
|
|
37872
40039
|
case "datetime": {
|
|
37873
|
-
const d = new Date(
|
|
40040
|
+
const d = new Date(str2);
|
|
37874
40041
|
if (!isNaN(d.getTime())) {
|
|
37875
40042
|
return d.toLocaleDateString(void 0, {
|
|
37876
40043
|
year: "numeric",
|
|
@@ -37879,7 +40046,7 @@ function renderRichFieldValue(value, fieldName, fieldType) {
|
|
|
37879
40046
|
...fieldType === "datetime" ? { hour: "2-digit", minute: "2-digit" } : {}
|
|
37880
40047
|
});
|
|
37881
40048
|
}
|
|
37882
|
-
return
|
|
40049
|
+
return str2;
|
|
37883
40050
|
}
|
|
37884
40051
|
default:
|
|
37885
40052
|
return formatFieldValue(value, fieldName);
|
|
@@ -38241,7 +40408,7 @@ var init_DetailPanel = __esm({
|
|
|
38241
40408
|
}
|
|
38242
40409
|
});
|
|
38243
40410
|
function extractTitle(children) {
|
|
38244
|
-
if (!
|
|
40411
|
+
if (!React98__default.isValidElement(children)) return void 0;
|
|
38245
40412
|
const props = children.props;
|
|
38246
40413
|
if (typeof props.title === "string") {
|
|
38247
40414
|
return props.title;
|
|
@@ -38591,12 +40758,12 @@ var init_Form = __esm({
|
|
|
38591
40758
|
const isSchemaEntity = isOrbitalEntitySchema(entity);
|
|
38592
40759
|
const resolvedEntity = isSchemaEntity ? entity : void 0;
|
|
38593
40760
|
const entityName = typeof entity === "string" ? entity : resolvedEntity?.name;
|
|
38594
|
-
const normalizedInitialData =
|
|
40761
|
+
const normalizedInitialData = React98__default.useMemo(() => {
|
|
38595
40762
|
const entityRowAsInitial = isPlainEntityRow(entity) ? entity : void 0;
|
|
38596
40763
|
const callerInitial = initialData !== null && typeof initialData === "object" && !Array.isArray(initialData) ? initialData : {};
|
|
38597
40764
|
return entityRowAsInitial !== void 0 ? { ...entityRowAsInitial, ...callerInitial } : callerInitial;
|
|
38598
40765
|
}, [entity, initialData]);
|
|
38599
|
-
const entityDerivedFields =
|
|
40766
|
+
const entityDerivedFields = React98__default.useMemo(() => {
|
|
38600
40767
|
if (fields && fields.length > 0) return void 0;
|
|
38601
40768
|
if (!resolvedEntity) return void 0;
|
|
38602
40769
|
return resolvedEntity.fields.map(
|
|
@@ -38617,16 +40784,16 @@ var init_Form = __esm({
|
|
|
38617
40784
|
const conditionalFields = typeof conditionalFieldsRaw === "boolean" ? {} : conditionalFieldsRaw;
|
|
38618
40785
|
const hiddenCalculations = typeof hiddenCalculationsRaw === "boolean" ? [] : hiddenCalculationsRaw;
|
|
38619
40786
|
const violationTriggers = typeof violationTriggersRaw === "boolean" ? [] : violationTriggersRaw;
|
|
38620
|
-
const [formData, setFormData] =
|
|
40787
|
+
const [formData, setFormData] = React98__default.useState(
|
|
38621
40788
|
normalizedInitialData
|
|
38622
40789
|
);
|
|
38623
|
-
const [collapsedSections, setCollapsedSections] =
|
|
40790
|
+
const [collapsedSections, setCollapsedSections] = React98__default.useState(
|
|
38624
40791
|
/* @__PURE__ */ new Set()
|
|
38625
40792
|
);
|
|
38626
|
-
const [submitError, setSubmitError] =
|
|
38627
|
-
const formRef =
|
|
40793
|
+
const [submitError, setSubmitError] = React98__default.useState(null);
|
|
40794
|
+
const formRef = React98__default.useRef(null);
|
|
38628
40795
|
const formMode = props.mode;
|
|
38629
|
-
const mountedRef =
|
|
40796
|
+
const mountedRef = React98__default.useRef(false);
|
|
38630
40797
|
if (!mountedRef.current) {
|
|
38631
40798
|
mountedRef.current = true;
|
|
38632
40799
|
debug("forms", "mount", {
|
|
@@ -38639,7 +40806,7 @@ var init_Form = __esm({
|
|
|
38639
40806
|
});
|
|
38640
40807
|
}
|
|
38641
40808
|
const shouldShowCancel = showCancel ?? (fields && fields.length > 0);
|
|
38642
|
-
const evalContext =
|
|
40809
|
+
const evalContext = React98__default.useMemo(
|
|
38643
40810
|
() => ({
|
|
38644
40811
|
formValues: formData,
|
|
38645
40812
|
globalVariables: externalContext?.globalVariables ?? {},
|
|
@@ -38648,7 +40815,7 @@ var init_Form = __esm({
|
|
|
38648
40815
|
}),
|
|
38649
40816
|
[formData, externalContext]
|
|
38650
40817
|
);
|
|
38651
|
-
|
|
40818
|
+
React98__default.useEffect(() => {
|
|
38652
40819
|
debug("forms", "initialData-sync", {
|
|
38653
40820
|
mode: formMode,
|
|
38654
40821
|
normalizedInitialData,
|
|
@@ -38659,7 +40826,7 @@ var init_Form = __esm({
|
|
|
38659
40826
|
setFormData(normalizedInitialData);
|
|
38660
40827
|
}
|
|
38661
40828
|
}, [normalizedInitialData]);
|
|
38662
|
-
const processCalculations =
|
|
40829
|
+
const processCalculations = React98__default.useCallback(
|
|
38663
40830
|
(changedFieldId, newFormData) => {
|
|
38664
40831
|
if (!hiddenCalculations.length) return;
|
|
38665
40832
|
const context = {
|
|
@@ -38684,7 +40851,7 @@ var init_Form = __esm({
|
|
|
38684
40851
|
},
|
|
38685
40852
|
[hiddenCalculations, externalContext, eventBus]
|
|
38686
40853
|
);
|
|
38687
|
-
const checkViolations =
|
|
40854
|
+
const checkViolations = React98__default.useCallback(
|
|
38688
40855
|
(changedFieldId, newFormData) => {
|
|
38689
40856
|
if (!violationTriggers.length) return;
|
|
38690
40857
|
const context = {
|
|
@@ -38722,7 +40889,7 @@ var init_Form = __esm({
|
|
|
38722
40889
|
processCalculations(name, newFormData);
|
|
38723
40890
|
checkViolations(name, newFormData);
|
|
38724
40891
|
};
|
|
38725
|
-
const isFieldVisible =
|
|
40892
|
+
const isFieldVisible = React98__default.useCallback(
|
|
38726
40893
|
(fieldName) => {
|
|
38727
40894
|
const condition = conditionalFields[fieldName];
|
|
38728
40895
|
if (!condition) return true;
|
|
@@ -38730,7 +40897,7 @@ var init_Form = __esm({
|
|
|
38730
40897
|
},
|
|
38731
40898
|
[conditionalFields, evalContext]
|
|
38732
40899
|
);
|
|
38733
|
-
const isSectionVisible =
|
|
40900
|
+
const isSectionVisible = React98__default.useCallback(
|
|
38734
40901
|
(section) => {
|
|
38735
40902
|
if (!section.condition) return true;
|
|
38736
40903
|
return Boolean(evaluateFormExpression(section.condition, evalContext));
|
|
@@ -38806,7 +40973,7 @@ var init_Form = __esm({
|
|
|
38806
40973
|
eventBus.emit(`UI:${onCancel}`);
|
|
38807
40974
|
}
|
|
38808
40975
|
};
|
|
38809
|
-
const renderField =
|
|
40976
|
+
const renderField = React98__default.useCallback(
|
|
38810
40977
|
(field) => {
|
|
38811
40978
|
const fieldName = field.name || field.field;
|
|
38812
40979
|
if (!fieldName) return null;
|
|
@@ -38827,7 +40994,7 @@ var init_Form = __esm({
|
|
|
38827
40994
|
[formData, isFieldVisible, relationsData, relationsLoading, isLoading]
|
|
38828
40995
|
);
|
|
38829
40996
|
const effectiveFields = entityDerivedFields ?? fields;
|
|
38830
|
-
const normalizedFields =
|
|
40997
|
+
const normalizedFields = React98__default.useMemo(() => {
|
|
38831
40998
|
if (!effectiveFields || effectiveFields.length === 0) return [];
|
|
38832
40999
|
return effectiveFields.map((field) => {
|
|
38833
41000
|
if (typeof field === "string") {
|
|
@@ -38851,7 +41018,7 @@ var init_Form = __esm({
|
|
|
38851
41018
|
return field;
|
|
38852
41019
|
});
|
|
38853
41020
|
}, [effectiveFields, resolvedEntity]);
|
|
38854
|
-
const schemaFields =
|
|
41021
|
+
const schemaFields = React98__default.useMemo(() => {
|
|
38855
41022
|
if (normalizedFields.length === 0) return null;
|
|
38856
41023
|
if (isDebugEnabled()) {
|
|
38857
41024
|
debugGroup(`Form: ${entityName || "unknown"}`);
|
|
@@ -38861,7 +41028,7 @@ var init_Form = __esm({
|
|
|
38861
41028
|
}
|
|
38862
41029
|
return normalizedFields.map(renderField).filter(Boolean);
|
|
38863
41030
|
}, [normalizedFields, renderField, entityName, conditionalFields]);
|
|
38864
|
-
const sectionElements =
|
|
41031
|
+
const sectionElements = React98__default.useMemo(() => {
|
|
38865
41032
|
if (!sections || sections.length === 0) return null;
|
|
38866
41033
|
return sections.map((section) => {
|
|
38867
41034
|
if (!isSectionVisible(section)) {
|
|
@@ -39440,7 +41607,7 @@ function formatValue3(value, fieldName) {
|
|
|
39440
41607
|
return String(value);
|
|
39441
41608
|
}
|
|
39442
41609
|
function formatFieldLabel2(fieldName) {
|
|
39443
|
-
return fieldName.replace(/([A-Z])/g, " $1").replace(/^./, (
|
|
41610
|
+
return fieldName.replace(/([A-Z])/g, " $1").replace(/^./, (str2) => str2.toUpperCase()).replace(/Id$/, "").trim();
|
|
39444
41611
|
}
|
|
39445
41612
|
var STATUS_STYLES2, StatusBadge, ProgressIndicator, List3;
|
|
39446
41613
|
var init_List = __esm({
|
|
@@ -39586,7 +41753,7 @@ var init_List = __esm({
|
|
|
39586
41753
|
if (entity && typeof entity === "object" && "id" in entity) return [entity];
|
|
39587
41754
|
return [];
|
|
39588
41755
|
}, [entity]);
|
|
39589
|
-
const getItemActions =
|
|
41756
|
+
const getItemActions = React98__default.useCallback(
|
|
39590
41757
|
(item) => {
|
|
39591
41758
|
if (!itemActions) return [];
|
|
39592
41759
|
if (typeof itemActions === "function") {
|
|
@@ -40061,7 +42228,7 @@ var init_MediaGallery = __esm({
|
|
|
40061
42228
|
[selectable, selectedItems, selectionEvent, eventBus]
|
|
40062
42229
|
);
|
|
40063
42230
|
const entityData = Array.isArray(entity) ? entity : [];
|
|
40064
|
-
const items =
|
|
42231
|
+
const items = React98__default.useMemo(() => {
|
|
40065
42232
|
if (propItems) return propItems;
|
|
40066
42233
|
if (entityData.length === 0) return [];
|
|
40067
42234
|
return entityData.map((record, idx) => {
|
|
@@ -40224,7 +42391,7 @@ var init_MediaGallery = __esm({
|
|
|
40224
42391
|
}
|
|
40225
42392
|
});
|
|
40226
42393
|
function extractTitle2(children) {
|
|
40227
|
-
if (!
|
|
42394
|
+
if (!React98__default.isValidElement(children)) return void 0;
|
|
40228
42395
|
const props = children.props;
|
|
40229
42396
|
if (typeof props.title === "string") {
|
|
40230
42397
|
return props.title;
|
|
@@ -40479,7 +42646,7 @@ var init_debugRegistry = __esm({
|
|
|
40479
42646
|
}
|
|
40480
42647
|
});
|
|
40481
42648
|
function useDebugData() {
|
|
40482
|
-
const [data, setData] =
|
|
42649
|
+
const [data, setData] = React98.useState(() => ({
|
|
40483
42650
|
traits: [],
|
|
40484
42651
|
ticks: [],
|
|
40485
42652
|
guards: [],
|
|
@@ -40493,7 +42660,7 @@ function useDebugData() {
|
|
|
40493
42660
|
},
|
|
40494
42661
|
lastUpdate: Date.now()
|
|
40495
42662
|
}));
|
|
40496
|
-
|
|
42663
|
+
React98.useEffect(() => {
|
|
40497
42664
|
const updateData = () => {
|
|
40498
42665
|
setData({
|
|
40499
42666
|
traits: getAllTraits(),
|
|
@@ -40602,12 +42769,12 @@ function layoutGraph(states, transitions, initialState, width, height) {
|
|
|
40602
42769
|
return positions;
|
|
40603
42770
|
}
|
|
40604
42771
|
function WalkMinimap() {
|
|
40605
|
-
const [walkStep, setWalkStep] =
|
|
40606
|
-
const [traits2, setTraits] =
|
|
40607
|
-
const [coveredEdges, setCoveredEdges] =
|
|
40608
|
-
const [completedTraits, setCompletedTraits] =
|
|
40609
|
-
const prevTraitRef =
|
|
40610
|
-
|
|
42772
|
+
const [walkStep, setWalkStep] = React98.useState(null);
|
|
42773
|
+
const [traits2, setTraits] = React98.useState([]);
|
|
42774
|
+
const [coveredEdges, setCoveredEdges] = React98.useState([]);
|
|
42775
|
+
const [completedTraits, setCompletedTraits] = React98.useState(/* @__PURE__ */ new Set());
|
|
42776
|
+
const prevTraitRef = React98.useRef(null);
|
|
42777
|
+
React98.useEffect(() => {
|
|
40611
42778
|
const interval = setInterval(() => {
|
|
40612
42779
|
const w = window;
|
|
40613
42780
|
const step = w.__orbitalWalkStep;
|
|
@@ -41043,15 +43210,15 @@ var init_EntitiesTab = __esm({
|
|
|
41043
43210
|
});
|
|
41044
43211
|
function EventFlowTab({ events: events2 }) {
|
|
41045
43212
|
const { t } = useTranslate();
|
|
41046
|
-
const [filter, setFilter] =
|
|
41047
|
-
const containerRef =
|
|
41048
|
-
const [autoScroll, setAutoScroll] =
|
|
41049
|
-
|
|
43213
|
+
const [filter, setFilter] = React98.useState("all");
|
|
43214
|
+
const containerRef = React98.useRef(null);
|
|
43215
|
+
const [autoScroll, setAutoScroll] = React98.useState(true);
|
|
43216
|
+
React98.useEffect(() => {
|
|
41050
43217
|
if (autoScroll && containerRef.current) {
|
|
41051
43218
|
containerRef.current.scrollTop = containerRef.current.scrollHeight;
|
|
41052
43219
|
}
|
|
41053
43220
|
}, [events2.length, autoScroll]);
|
|
41054
|
-
const filteredEvents =
|
|
43221
|
+
const filteredEvents = React98.useMemo(() => {
|
|
41055
43222
|
if (filter === "all") return events2;
|
|
41056
43223
|
return events2.filter((e) => e.type === filter);
|
|
41057
43224
|
}, [events2, filter]);
|
|
@@ -41167,7 +43334,7 @@ var init_EventFlowTab = __esm({
|
|
|
41167
43334
|
});
|
|
41168
43335
|
function GuardsPanel({ guards }) {
|
|
41169
43336
|
const { t } = useTranslate();
|
|
41170
|
-
const [filter, setFilter] =
|
|
43337
|
+
const [filter, setFilter] = React98.useState("all");
|
|
41171
43338
|
if (guards.length === 0) {
|
|
41172
43339
|
return /* @__PURE__ */ jsx(
|
|
41173
43340
|
EmptyState,
|
|
@@ -41180,7 +43347,7 @@ function GuardsPanel({ guards }) {
|
|
|
41180
43347
|
}
|
|
41181
43348
|
const passedCount = guards.filter((g) => g.result).length;
|
|
41182
43349
|
const failedCount = guards.length - passedCount;
|
|
41183
|
-
const filteredGuards =
|
|
43350
|
+
const filteredGuards = React98.useMemo(() => {
|
|
41184
43351
|
if (filter === "all") return guards;
|
|
41185
43352
|
if (filter === "passed") return guards.filter((g) => g.result);
|
|
41186
43353
|
return guards.filter((g) => !g.result);
|
|
@@ -41343,10 +43510,10 @@ function EffectBadge({ effect }) {
|
|
|
41343
43510
|
}
|
|
41344
43511
|
function TransitionTimeline({ transitions }) {
|
|
41345
43512
|
const { t } = useTranslate();
|
|
41346
|
-
const containerRef =
|
|
41347
|
-
const [autoScroll, setAutoScroll] =
|
|
41348
|
-
const [expandedId, setExpandedId] =
|
|
41349
|
-
|
|
43513
|
+
const containerRef = React98.useRef(null);
|
|
43514
|
+
const [autoScroll, setAutoScroll] = React98.useState(true);
|
|
43515
|
+
const [expandedId, setExpandedId] = React98.useState(null);
|
|
43516
|
+
React98.useEffect(() => {
|
|
41350
43517
|
if (autoScroll && containerRef.current) {
|
|
41351
43518
|
containerRef.current.scrollTop = containerRef.current.scrollHeight;
|
|
41352
43519
|
}
|
|
@@ -41626,9 +43793,9 @@ function getAllEvents(traits2) {
|
|
|
41626
43793
|
function EventDispatcherTab({ traits: traits2, schema }) {
|
|
41627
43794
|
const eventBus = useEventBus();
|
|
41628
43795
|
const { t } = useTranslate();
|
|
41629
|
-
const [log13, setLog] =
|
|
41630
|
-
const prevStatesRef =
|
|
41631
|
-
|
|
43796
|
+
const [log13, setLog] = React98.useState([]);
|
|
43797
|
+
const prevStatesRef = React98.useRef(/* @__PURE__ */ new Map());
|
|
43798
|
+
React98.useEffect(() => {
|
|
41632
43799
|
for (const trait of traits2) {
|
|
41633
43800
|
const prev = prevStatesRef.current.get(trait.id);
|
|
41634
43801
|
if (prev && prev !== trait.currentState) {
|
|
@@ -41797,10 +43964,10 @@ function VerifyModePanel({
|
|
|
41797
43964
|
localCount
|
|
41798
43965
|
}) {
|
|
41799
43966
|
const { t } = useTranslate();
|
|
41800
|
-
const [expanded, setExpanded] =
|
|
41801
|
-
const scrollRef =
|
|
41802
|
-
const prevCountRef =
|
|
41803
|
-
|
|
43967
|
+
const [expanded, setExpanded] = React98.useState(true);
|
|
43968
|
+
const scrollRef = React98.useRef(null);
|
|
43969
|
+
const prevCountRef = React98.useRef(0);
|
|
43970
|
+
React98.useEffect(() => {
|
|
41804
43971
|
if (expanded && transitions.length > prevCountRef.current && scrollRef.current) {
|
|
41805
43972
|
scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
|
|
41806
43973
|
}
|
|
@@ -41857,10 +44024,10 @@ function RuntimeDebugger({
|
|
|
41857
44024
|
schema
|
|
41858
44025
|
}) {
|
|
41859
44026
|
const { t } = useTranslate();
|
|
41860
|
-
const [isCollapsed, setIsCollapsed] =
|
|
41861
|
-
const [isVisible, setIsVisible] =
|
|
44027
|
+
const [isCollapsed, setIsCollapsed] = React98.useState(mode === "verify" ? true : defaultCollapsed);
|
|
44028
|
+
const [isVisible, setIsVisible] = React98.useState(mode === "inline" || mode === "verify" || isDebugEnabled2());
|
|
41862
44029
|
const debugData = useDebugData();
|
|
41863
|
-
|
|
44030
|
+
React98.useEffect(() => {
|
|
41864
44031
|
if (mode === "inline") return;
|
|
41865
44032
|
return onDebugToggle((enabled) => {
|
|
41866
44033
|
setIsVisible(enabled);
|
|
@@ -41869,7 +44036,7 @@ function RuntimeDebugger({
|
|
|
41869
44036
|
}
|
|
41870
44037
|
});
|
|
41871
44038
|
}, [mode]);
|
|
41872
|
-
|
|
44039
|
+
React98.useEffect(() => {
|
|
41873
44040
|
if (mode === "inline") return;
|
|
41874
44041
|
const handleKeyDown = (e) => {
|
|
41875
44042
|
if (e.key === "`" && isVisible) {
|
|
@@ -42389,7 +44556,7 @@ var init_StatCard = __esm({
|
|
|
42389
44556
|
const labelToUse = propLabel ?? propTitle;
|
|
42390
44557
|
const eventBus = useEventBus();
|
|
42391
44558
|
const { t } = useTranslate();
|
|
42392
|
-
const handleActionClick =
|
|
44559
|
+
const handleActionClick = React98__default.useCallback(() => {
|
|
42393
44560
|
if (action?.event) {
|
|
42394
44561
|
eventBus.emit(`UI:${action.event}`, {});
|
|
42395
44562
|
}
|
|
@@ -42400,7 +44567,7 @@ var init_StatCard = __esm({
|
|
|
42400
44567
|
const data = Array.isArray(entity) ? entity : entity ? [entity] : [];
|
|
42401
44568
|
const isLoading = externalLoading ?? false;
|
|
42402
44569
|
const error = externalError;
|
|
42403
|
-
const computeMetricValue =
|
|
44570
|
+
const computeMetricValue = React98__default.useCallback(
|
|
42404
44571
|
(metric, items) => {
|
|
42405
44572
|
if (metric.value !== void 0) {
|
|
42406
44573
|
return metric.value;
|
|
@@ -42439,7 +44606,7 @@ var init_StatCard = __esm({
|
|
|
42439
44606
|
},
|
|
42440
44607
|
[]
|
|
42441
44608
|
);
|
|
42442
|
-
const schemaStats =
|
|
44609
|
+
const schemaStats = React98__default.useMemo(() => {
|
|
42443
44610
|
if (!metrics || metrics.length === 0) return null;
|
|
42444
44611
|
return metrics.map((metric) => ({
|
|
42445
44612
|
label: metric.label,
|
|
@@ -42447,7 +44614,7 @@ var init_StatCard = __esm({
|
|
|
42447
44614
|
format: metric.format
|
|
42448
44615
|
}));
|
|
42449
44616
|
}, [metrics, data, computeMetricValue]);
|
|
42450
|
-
const calculatedTrend =
|
|
44617
|
+
const calculatedTrend = React98__default.useMemo(() => {
|
|
42451
44618
|
if (manualTrend !== void 0) return manualTrend;
|
|
42452
44619
|
if (previousValue === void 0 || currentValue === void 0)
|
|
42453
44620
|
return void 0;
|
|
@@ -43087,8 +45254,8 @@ var init_SubagentTracePanel = __esm({
|
|
|
43087
45254
|
] });
|
|
43088
45255
|
};
|
|
43089
45256
|
InlineActivityStream = ({ activities, autoScroll = true, className }) => {
|
|
43090
|
-
const endRef =
|
|
43091
|
-
|
|
45257
|
+
const endRef = React98__default.useRef(null);
|
|
45258
|
+
React98__default.useEffect(() => {
|
|
43092
45259
|
if (!autoScroll) return;
|
|
43093
45260
|
endRef.current?.scrollIntoView({ behavior: "smooth", block: "end" });
|
|
43094
45261
|
}, [activities.length, autoScroll]);
|
|
@@ -43182,7 +45349,7 @@ var init_SubagentTracePanel = __esm({
|
|
|
43182
45349
|
};
|
|
43183
45350
|
SubagentRichCard = ({ subagent }) => {
|
|
43184
45351
|
const { t } = useTranslate();
|
|
43185
|
-
const activities =
|
|
45352
|
+
const activities = React98__default.useMemo(
|
|
43186
45353
|
() => subagentMessagesToActivities(subagent.messages),
|
|
43187
45354
|
[subagent.messages]
|
|
43188
45355
|
);
|
|
@@ -43259,8 +45426,8 @@ var init_SubagentTracePanel = __esm({
|
|
|
43259
45426
|
] });
|
|
43260
45427
|
};
|
|
43261
45428
|
CoordinatorConversation = ({ messages, autoScroll = true, className }) => {
|
|
43262
|
-
const endRef =
|
|
43263
|
-
|
|
45429
|
+
const endRef = React98__default.useRef(null);
|
|
45430
|
+
React98__default.useEffect(() => {
|
|
43264
45431
|
if (!autoScroll) return;
|
|
43265
45432
|
endRef.current?.scrollIntoView({ behavior: "smooth", block: "end" });
|
|
43266
45433
|
}, [messages.length, autoScroll]);
|
|
@@ -43690,7 +45857,7 @@ var init_Timeline = __esm({
|
|
|
43690
45857
|
}) => {
|
|
43691
45858
|
const { t } = useTranslate();
|
|
43692
45859
|
const entityData = entity ?? [];
|
|
43693
|
-
const items =
|
|
45860
|
+
const items = React98__default.useMemo(() => {
|
|
43694
45861
|
if (propItems) return propItems;
|
|
43695
45862
|
if (entityData.length === 0) return [];
|
|
43696
45863
|
return entityData.map((record, idx) => {
|
|
@@ -43792,7 +45959,7 @@ var init_Timeline = __esm({
|
|
|
43792
45959
|
}
|
|
43793
45960
|
});
|
|
43794
45961
|
function extractToastProps(children) {
|
|
43795
|
-
if (!
|
|
45962
|
+
if (!React98__default.isValidElement(children)) {
|
|
43796
45963
|
if (typeof children === "string") {
|
|
43797
45964
|
return { message: children };
|
|
43798
45965
|
}
|
|
@@ -43834,7 +46001,7 @@ var init_ToastSlot = __esm({
|
|
|
43834
46001
|
eventBus.emit(`${prefix}CLOSE`);
|
|
43835
46002
|
};
|
|
43836
46003
|
if (!isVisible) return null;
|
|
43837
|
-
const isCustomContent =
|
|
46004
|
+
const isCustomContent = React98__default.isValidElement(children) && !message;
|
|
43838
46005
|
return /* @__PURE__ */ jsx(Box, { className: "fixed bottom-4 right-4 z-50", children: isCustomContent ? children : /* @__PURE__ */ jsx(
|
|
43839
46006
|
Toast,
|
|
43840
46007
|
{
|
|
@@ -43851,7 +46018,7 @@ var init_ToastSlot = __esm({
|
|
|
43851
46018
|
}
|
|
43852
46019
|
});
|
|
43853
46020
|
function lazyThree(name, loader) {
|
|
43854
|
-
const Lazy =
|
|
46021
|
+
const Lazy = React98__default.lazy(
|
|
43855
46022
|
() => loader().then((m) => {
|
|
43856
46023
|
const Resolved = m[name];
|
|
43857
46024
|
if (!Resolved) {
|
|
@@ -43863,13 +46030,13 @@ function lazyThree(name, loader) {
|
|
|
43863
46030
|
})
|
|
43864
46031
|
);
|
|
43865
46032
|
function ThreeWrapper(props) {
|
|
43866
|
-
return
|
|
46033
|
+
return React98__default.createElement(
|
|
43867
46034
|
ThreeBoundary,
|
|
43868
46035
|
{ name },
|
|
43869
|
-
|
|
43870
|
-
|
|
46036
|
+
React98__default.createElement(
|
|
46037
|
+
React98__default.Suspense,
|
|
43871
46038
|
{ fallback: null },
|
|
43872
|
-
|
|
46039
|
+
React98__default.createElement(Lazy, props)
|
|
43873
46040
|
)
|
|
43874
46041
|
);
|
|
43875
46042
|
}
|
|
@@ -43905,6 +46072,7 @@ var init_component_registry_generated = __esm({
|
|
|
43905
46072
|
init_LayoutPatterns();
|
|
43906
46073
|
init_BranchingLogicBuilder();
|
|
43907
46074
|
init_Breadcrumb();
|
|
46075
|
+
init_BuilderBoard();
|
|
43908
46076
|
init_CTABanner();
|
|
43909
46077
|
init_CalendarGrid();
|
|
43910
46078
|
init_Canvas2D();
|
|
@@ -43920,6 +46088,7 @@ var init_component_registry_generated = __esm({
|
|
|
43920
46088
|
init_Checkbox();
|
|
43921
46089
|
init_ChemistryCanvas();
|
|
43922
46090
|
init_ChoiceButton();
|
|
46091
|
+
init_ClassifierBoard();
|
|
43923
46092
|
init_CodeBlock();
|
|
43924
46093
|
init_CodeRunnerPanel();
|
|
43925
46094
|
init_ComboCounter();
|
|
@@ -43943,6 +46112,7 @@ var init_component_registry_generated = __esm({
|
|
|
43943
46112
|
init_DateRangePicker();
|
|
43944
46113
|
init_DateRangeSelector();
|
|
43945
46114
|
init_DayCell();
|
|
46115
|
+
init_DebuggerBoard();
|
|
43946
46116
|
init_DetailPanel();
|
|
43947
46117
|
init_Dialog();
|
|
43948
46118
|
init_DialogueBubble();
|
|
@@ -43958,6 +46128,7 @@ var init_component_registry_generated = __esm({
|
|
|
43958
46128
|
init_EmptyState();
|
|
43959
46129
|
init_ErrorBoundary();
|
|
43960
46130
|
init_ErrorState();
|
|
46131
|
+
init_EventHandlerBoard();
|
|
43961
46132
|
init_EventLog();
|
|
43962
46133
|
init_FeatureCard();
|
|
43963
46134
|
init_FeatureDetailPageTemplate();
|
|
@@ -44024,6 +46195,7 @@ var init_component_registry_generated = __esm({
|
|
|
44024
46195
|
init_ModalSlot();
|
|
44025
46196
|
init_ModuleCard();
|
|
44026
46197
|
init_Navigation();
|
|
46198
|
+
init_NegotiatorBoard();
|
|
44027
46199
|
init_NumberStepper();
|
|
44028
46200
|
init_OptionConstraintGroup();
|
|
44029
46201
|
init_OrbitalVisualization();
|
|
@@ -44062,6 +46234,7 @@ var init_component_registry_generated = __esm({
|
|
|
44062
46234
|
init_SegmentRenderer();
|
|
44063
46235
|
init_Select();
|
|
44064
46236
|
init_SequenceBar();
|
|
46237
|
+
init_SequencerBoard();
|
|
44065
46238
|
init_ServiceCatalog();
|
|
44066
46239
|
init_ShowcaseCard();
|
|
44067
46240
|
init_ShowcaseOrganism();
|
|
@@ -44070,6 +46243,7 @@ var init_component_registry_generated = __esm({
|
|
|
44070
46243
|
init_SignaturePad();
|
|
44071
46244
|
init_SimpleGrid();
|
|
44072
46245
|
init_SimulationCanvas();
|
|
46246
|
+
init_SimulatorBoard();
|
|
44073
46247
|
init_Skeleton();
|
|
44074
46248
|
init_SocialProof();
|
|
44075
46249
|
init_SortableList();
|
|
@@ -44083,6 +46257,8 @@ var init_component_registry_generated = __esm({
|
|
|
44083
46257
|
init_StatBadge();
|
|
44084
46258
|
init_StatCard();
|
|
44085
46259
|
init_StatDisplay();
|
|
46260
|
+
init_StateArchitectBoard();
|
|
46261
|
+
init_StateGraph();
|
|
44086
46262
|
init_StateIndicator();
|
|
44087
46263
|
init_StateMachineView();
|
|
44088
46264
|
init_StatsGrid();
|
|
@@ -44137,7 +46313,7 @@ var init_component_registry_generated = __esm({
|
|
|
44137
46313
|
init_WizardContainer();
|
|
44138
46314
|
init_WizardNavigation();
|
|
44139
46315
|
init_WizardProgress();
|
|
44140
|
-
ThreeBoundary = class extends
|
|
46316
|
+
ThreeBoundary = class extends React98__default.Component {
|
|
44141
46317
|
constructor() {
|
|
44142
46318
|
super(...arguments);
|
|
44143
46319
|
__publicField(this, "state", { failed: false });
|
|
@@ -44147,7 +46323,7 @@ var init_component_registry_generated = __esm({
|
|
|
44147
46323
|
}
|
|
44148
46324
|
render() {
|
|
44149
46325
|
if (this.state.failed) {
|
|
44150
|
-
return
|
|
46326
|
+
return React98__default.createElement(
|
|
44151
46327
|
"div",
|
|
44152
46328
|
{
|
|
44153
46329
|
"data-testid": "three-unavailable",
|
|
@@ -44193,6 +46369,7 @@ var init_component_registry_generated = __esm({
|
|
|
44193
46369
|
"BoxPattern": BoxPattern,
|
|
44194
46370
|
"BranchingLogicBuilder": BranchingLogicBuilder,
|
|
44195
46371
|
"Breadcrumb": Breadcrumb,
|
|
46372
|
+
"BuilderBoard": BuilderBoard,
|
|
44196
46373
|
"Button": ButtonPattern,
|
|
44197
46374
|
"ButtonPattern": ButtonPattern,
|
|
44198
46375
|
"CTABanner": CTABanner,
|
|
@@ -44210,6 +46387,7 @@ var init_component_registry_generated = __esm({
|
|
|
44210
46387
|
"Checkbox": Checkbox,
|
|
44211
46388
|
"ChemistryCanvas": ChemistryCanvas,
|
|
44212
46389
|
"ChoiceButton": ChoiceButton,
|
|
46390
|
+
"ClassifierBoard": ClassifierBoard,
|
|
44213
46391
|
"CodeBlock": CodeBlock,
|
|
44214
46392
|
"CodeRunnerPanel": CodeRunnerPanel,
|
|
44215
46393
|
"ComboCounter": ComboCounter,
|
|
@@ -44233,6 +46411,7 @@ var init_component_registry_generated = __esm({
|
|
|
44233
46411
|
"DateRangePicker": DateRangePicker,
|
|
44234
46412
|
"DateRangeSelector": DateRangeSelector,
|
|
44235
46413
|
"DayCell": DayCell,
|
|
46414
|
+
"DebuggerBoard": DebuggerBoard,
|
|
44236
46415
|
"DetailPanel": DetailPanel,
|
|
44237
46416
|
"Dialog": Dialog,
|
|
44238
46417
|
"DialogueBubble": DialogueBubble,
|
|
@@ -44250,6 +46429,7 @@ var init_component_registry_generated = __esm({
|
|
|
44250
46429
|
"EmptyState": EmptyState,
|
|
44251
46430
|
"ErrorBoundary": ErrorBoundary,
|
|
44252
46431
|
"ErrorState": ErrorState,
|
|
46432
|
+
"EventHandlerBoard": EventHandlerBoard,
|
|
44253
46433
|
"EventLog": EventLog,
|
|
44254
46434
|
"FeatureCard": FeatureCard,
|
|
44255
46435
|
"FeatureDetailPageTemplate": FeatureDetailPageTemplate,
|
|
@@ -44324,6 +46504,7 @@ var init_component_registry_generated = __esm({
|
|
|
44324
46504
|
"ModalSlot": ModalSlot,
|
|
44325
46505
|
"ModuleCard": ModuleCard,
|
|
44326
46506
|
"Navigation": Navigation,
|
|
46507
|
+
"NegotiatorBoard": NegotiatorBoard,
|
|
44327
46508
|
"NumberStepper": NumberStepper,
|
|
44328
46509
|
"OptionConstraintGroup": OptionConstraintGroup,
|
|
44329
46510
|
"OrbitalVisualization": OrbitalVisualization,
|
|
@@ -44362,6 +46543,7 @@ var init_component_registry_generated = __esm({
|
|
|
44362
46543
|
"SegmentRenderer": SegmentRenderer,
|
|
44363
46544
|
"Select": Select,
|
|
44364
46545
|
"SequenceBar": SequenceBar,
|
|
46546
|
+
"SequencerBoard": SequencerBoard,
|
|
44365
46547
|
"ServiceCatalog": ServiceCatalog,
|
|
44366
46548
|
"ShowcaseCard": ShowcaseCard,
|
|
44367
46549
|
"ShowcaseOrganism": ShowcaseOrganism,
|
|
@@ -44370,6 +46552,7 @@ var init_component_registry_generated = __esm({
|
|
|
44370
46552
|
"SignaturePad": SignaturePad,
|
|
44371
46553
|
"SimpleGrid": SimpleGrid,
|
|
44372
46554
|
"SimulationCanvas": SimulationCanvas,
|
|
46555
|
+
"SimulatorBoard": SimulatorBoard,
|
|
44373
46556
|
"Skeleton": Skeleton,
|
|
44374
46557
|
"SocialProof": SocialProof,
|
|
44375
46558
|
"SortableList": SortableList,
|
|
@@ -44386,6 +46569,8 @@ var init_component_registry_generated = __esm({
|
|
|
44386
46569
|
"StatBadge": StatBadge,
|
|
44387
46570
|
"StatCard": StatCard,
|
|
44388
46571
|
"StatDisplay": StatDisplay,
|
|
46572
|
+
"StateArchitectBoard": StateArchitectBoard,
|
|
46573
|
+
"StateGraph": StateGraph,
|
|
44389
46574
|
"StateIndicator": StateIndicator,
|
|
44390
46575
|
"StateMachineView": StateMachineView,
|
|
44391
46576
|
"StatsGrid": StatsGrid,
|
|
@@ -44459,7 +46644,7 @@ function SuspenseConfigProvider({
|
|
|
44459
46644
|
config,
|
|
44460
46645
|
children
|
|
44461
46646
|
}) {
|
|
44462
|
-
return
|
|
46647
|
+
return React98__default.createElement(
|
|
44463
46648
|
SuspenseConfigContext.Provider,
|
|
44464
46649
|
{ value: config },
|
|
44465
46650
|
children
|
|
@@ -44501,7 +46686,7 @@ function enrichFormFields(fields, entityDef) {
|
|
|
44501
46686
|
}
|
|
44502
46687
|
return { name: field, label: field.replace(/([a-z])([A-Z])/g, "$1 $2").replace(/\b\w/g, (c) => c.toUpperCase()) };
|
|
44503
46688
|
}
|
|
44504
|
-
if (field && typeof field === "object" && !Array.isArray(field) && !
|
|
46689
|
+
if (field && typeof field === "object" && !Array.isArray(field) && !React98__default.isValidElement(field) && !(field instanceof Date)) {
|
|
44505
46690
|
const obj = field;
|
|
44506
46691
|
const fieldName = typeof obj.name === "string" ? obj.name : typeof obj.field === "string" ? obj.field : void 0;
|
|
44507
46692
|
if (!fieldName) return field;
|
|
@@ -44954,7 +47139,7 @@ function renderPatternChildren(children, onDismiss, parentId = "root", parentPat
|
|
|
44954
47139
|
const key = `${parentId}-${index}-trait:${traitName}`;
|
|
44955
47140
|
return /* @__PURE__ */ jsx(TraitFrame, { traitName }, key);
|
|
44956
47141
|
}
|
|
44957
|
-
return /* @__PURE__ */ jsx(
|
|
47142
|
+
return /* @__PURE__ */ jsx(React98__default.Fragment, { children: child }, `${parentId}-${index}`);
|
|
44958
47143
|
}
|
|
44959
47144
|
if (!child || typeof child !== "object") return null;
|
|
44960
47145
|
const childId = `${parentId}-${index}`;
|
|
@@ -44994,14 +47179,14 @@ function isPatternConfig(value) {
|
|
|
44994
47179
|
if (value === null || value === void 0) return false;
|
|
44995
47180
|
if (typeof value !== "object") return false;
|
|
44996
47181
|
if (Array.isArray(value)) return false;
|
|
44997
|
-
if (
|
|
47182
|
+
if (React98__default.isValidElement(value)) return false;
|
|
44998
47183
|
if (value instanceof Date) return false;
|
|
44999
47184
|
if (typeof value === "function") return false;
|
|
45000
47185
|
const record = value;
|
|
45001
47186
|
return "type" in record && typeof record.type === "string" && getComponentForPattern$1(record.type) !== null;
|
|
45002
47187
|
}
|
|
45003
47188
|
function isPlainConfigObject(value) {
|
|
45004
|
-
if (
|
|
47189
|
+
if (React98__default.isValidElement(value)) return false;
|
|
45005
47190
|
if (value instanceof Date) return false;
|
|
45006
47191
|
const proto = Object.getPrototypeOf(value);
|
|
45007
47192
|
return proto === Object.prototype || proto === null;
|
|
@@ -45127,7 +47312,7 @@ function SlotContentRenderer({
|
|
|
45127
47312
|
for (const slotKey of CONTENT_NODE_SLOTS) {
|
|
45128
47313
|
const slotVal = restProps[slotKey];
|
|
45129
47314
|
if (slotVal === void 0 || slotVal === null) continue;
|
|
45130
|
-
if (
|
|
47315
|
+
if (React98__default.isValidElement(slotVal) || typeof slotVal === "string" || typeof slotVal === "number" || typeof slotVal === "boolean") continue;
|
|
45131
47316
|
if (Array.isArray(slotVal) || typeof slotVal === "object" && "type" in slotVal) {
|
|
45132
47317
|
nodeSlotOverrides[slotKey] = renderPatternChildren(
|
|
45133
47318
|
slotVal,
|
|
@@ -45176,7 +47361,7 @@ function SlotContentRenderer({
|
|
|
45176
47361
|
const resolvedItems = Array.isArray(entityVal) && entityVal[0] !== "fn" ? entityVal : null;
|
|
45177
47362
|
if (resolvedItems && resolvedItems.length > 0 && !finalProps.fields && !finalProps.columns) {
|
|
45178
47363
|
const sample = resolvedItems[0];
|
|
45179
|
-
if (sample && typeof sample === "object" && !Array.isArray(sample) && !
|
|
47364
|
+
if (sample && typeof sample === "object" && !Array.isArray(sample) && !React98__default.isValidElement(sample) && !(sample instanceof Date)) {
|
|
45180
47365
|
const keys = Object.keys(sample).filter((k) => k !== "id" && k !== "_id");
|
|
45181
47366
|
finalProps.fields = keys.map((k, i) => ({ name: k, variant: i === 0 ? "h4" : "body" }));
|
|
45182
47367
|
}
|