@almadar/ui 5.17.0 → 5.18.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 +219 -171
- package/dist/avl/index.js +219 -171
- package/dist/components/atoms/Avatar.d.ts +4 -2
- package/dist/components/atoms/ConditionalWrapper.d.ts +2 -2
- package/dist/components/atoms/Icon.d.ts +6 -2
- package/dist/components/atoms/Input.d.ts +3 -2
- package/dist/components/atoms/LawReferenceTooltip.d.ts +2 -2
- package/dist/components/atoms/types.d.ts +10 -10
- package/dist/components/index.cjs +188 -156
- package/dist/components/index.js +188 -156
- package/dist/components/molecules/OptionConstraintGroup.d.ts +5 -3
- package/dist/components/molecules/ViolationAlert.d.ts +2 -2
- package/dist/components/molecules/game/CraftingRecipe.d.ts +4 -4
- package/dist/components/molecules/game/DialogueBox.d.ts +2 -2
- package/dist/components/organisms/ComponentPatterns.d.ts +2 -1
- package/dist/components/organisms/CustomPattern.d.ts +2 -1
- package/dist/components/organisms/DataTable.d.ts +1 -1
- package/dist/components/organisms/Form.d.ts +3 -3
- package/dist/components/organisms/LayoutPatterns.d.ts +4 -3
- package/dist/components/organisms/StateMachineView.d.ts +6 -3
- package/dist/components/organisms/book/types.d.ts +2 -2
- package/dist/components/organisms/game/CastleBoard.d.ts +4 -3
- package/dist/components/organisms/game/TraitStateViewer.d.ts +4 -4
- package/dist/components/organisms/game/UncontrolledBattleBoard.d.ts +9 -4
- package/dist/components/organisms/game/WorldMapBoard.d.ts +5 -4
- package/dist/components/organisms/game/puzzles/builder/BuilderBoard.d.ts +3 -3
- package/dist/components/organisms/game/puzzles/classifier/ClassifierBoard.d.ts +3 -3
- package/dist/components/organisms/game/puzzles/debugger/DebuggerBoard.d.ts +3 -3
- package/dist/components/organisms/game/puzzles/event-handler/EventHandlerBoard.d.ts +7 -4
- package/dist/components/organisms/game/puzzles/event-handler/ObjectRulePanel.d.ts +2 -2
- package/dist/components/organisms/game/puzzles/negotiator/NegotiatorBoard.d.ts +3 -3
- package/dist/components/organisms/game/puzzles/sequencer/SequencerBoard.d.ts +5 -4
- package/dist/components/organisms/game/puzzles/simulator/SimulatorBoard.d.ts +3 -3
- package/dist/components/organisms/game/puzzles/state-architect/StateArchitectBoard.d.ts +5 -4
- package/dist/components/templates/GenericAppTemplate.d.ts +1 -7
- package/dist/components/templates/types.d.ts +14 -6
- package/dist/docs/index.cjs +60 -22
- package/dist/docs/index.d.cts +9 -4
- package/dist/docs/index.js +58 -20
- package/dist/marketing/index.cjs +61 -23
- package/dist/marketing/index.d.cts +10 -6
- package/dist/marketing/index.js +58 -20
- package/dist/providers/index.cjs +188 -156
- package/dist/providers/index.js +188 -156
- package/dist/runtime/fn-form-lambda.d.ts +1 -1
- package/dist/runtime/index.cjs +219 -171
- package/dist/runtime/index.js +219 -171
- package/package.json +1 -1
package/dist/providers/index.cjs
CHANGED
|
@@ -1535,11 +1535,13 @@ var init_Icon = __esm({
|
|
|
1535
1535
|
strokeWidth,
|
|
1536
1536
|
style
|
|
1537
1537
|
}) => {
|
|
1538
|
+
const directIcon = typeof icon === "string" ? void 0 : icon;
|
|
1539
|
+
const effectiveName = typeof icon === "string" ? icon : name;
|
|
1538
1540
|
const family = useIconFamily();
|
|
1539
1541
|
const RenderedComponent = React86__namespace.default.useMemo(() => {
|
|
1540
|
-
if (
|
|
1541
|
-
return
|
|
1542
|
-
}, [
|
|
1542
|
+
if (directIcon) return null;
|
|
1543
|
+
return effectiveName ? resolveIconForFamily(effectiveName, family) : null;
|
|
1544
|
+
}, [directIcon, effectiveName, family]);
|
|
1543
1545
|
const effectiveStrokeWidth = strokeWidth ?? void 0;
|
|
1544
1546
|
const inlineStyle = {
|
|
1545
1547
|
...effectiveStrokeWidth === void 0 ? { strokeWidth: "var(--icon-stroke-width, 2)" } : {},
|
|
@@ -1551,8 +1553,8 @@ var init_Icon = __esm({
|
|
|
1551
1553
|
color ? color : "text-current",
|
|
1552
1554
|
className
|
|
1553
1555
|
);
|
|
1554
|
-
if (
|
|
1555
|
-
const Direct =
|
|
1556
|
+
if (directIcon) {
|
|
1557
|
+
const Direct = directIcon;
|
|
1556
1558
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1557
1559
|
Direct,
|
|
1558
1560
|
{
|
|
@@ -3425,7 +3427,7 @@ var init_Input = __esm({
|
|
|
3425
3427
|
error,
|
|
3426
3428
|
leftIcon,
|
|
3427
3429
|
rightIcon,
|
|
3428
|
-
icon:
|
|
3430
|
+
icon: iconProp,
|
|
3429
3431
|
clearable,
|
|
3430
3432
|
onClear,
|
|
3431
3433
|
value,
|
|
@@ -3435,6 +3437,7 @@ var init_Input = __esm({
|
|
|
3435
3437
|
...props
|
|
3436
3438
|
}, ref) => {
|
|
3437
3439
|
const type = inputType || htmlType || "text";
|
|
3440
|
+
const IconComponent = typeof iconProp === "string" ? resolveIcon(iconProp) : iconProp;
|
|
3438
3441
|
const resolvedLeftIcon = leftIcon || IconComponent && /* @__PURE__ */ jsxRuntime.jsx(IconComponent, { className: "h-icon-default w-icon-default" });
|
|
3439
3442
|
const showClearButton = clearable && value && String(value).length > 0;
|
|
3440
3443
|
const isMultiline = type === "textarea";
|
|
@@ -3982,7 +3985,7 @@ var init_Avatar = __esm({
|
|
|
3982
3985
|
alt,
|
|
3983
3986
|
name,
|
|
3984
3987
|
initials: providedInitials,
|
|
3985
|
-
icon:
|
|
3988
|
+
icon: iconProp,
|
|
3986
3989
|
size = "md",
|
|
3987
3990
|
status,
|
|
3988
3991
|
badge,
|
|
@@ -3993,6 +3996,7 @@ var init_Avatar = __esm({
|
|
|
3993
3996
|
}) => {
|
|
3994
3997
|
const eventBus = useEventBus();
|
|
3995
3998
|
const initials = providedInitials ?? (name ? generateInitials(name) : void 0);
|
|
3999
|
+
const IconComponent = typeof iconProp === "string" ? resolveIcon(iconProp) : iconProp;
|
|
3996
4000
|
const hasImage = !!src;
|
|
3997
4001
|
const hasInitials = !!initials;
|
|
3998
4002
|
const hasIcon = !!IconComponent;
|
|
@@ -15207,6 +15211,7 @@ var init_StateMachineView = __esm({
|
|
|
15207
15211
|
setTooltip((prev) => ({ ...prev, pinned: false, visible: false }));
|
|
15208
15212
|
}, []);
|
|
15209
15213
|
useEventListener("UI:TOOLTIP_CLOSE", handleCloseTooltip);
|
|
15214
|
+
if (!layoutData) return null;
|
|
15210
15215
|
const { width, height, title, states, labels, entity, outputs, config } = layoutData;
|
|
15211
15216
|
const bundles = React86.useMemo(() => {
|
|
15212
15217
|
const bundleMap = {};
|
|
@@ -17551,13 +17556,14 @@ function BuilderBoard({
|
|
|
17551
17556
|
}) {
|
|
17552
17557
|
const { emit } = useEventBus();
|
|
17553
17558
|
const { t } = useTranslate();
|
|
17559
|
+
const resolved = Array.isArray(entity) ? entity[0] : entity;
|
|
17554
17560
|
const [placements, setPlacements] = React86.useState({});
|
|
17555
17561
|
const [headerError, setHeaderError] = React86.useState(false);
|
|
17556
17562
|
const [submitted, setSubmitted] = React86.useState(false);
|
|
17557
17563
|
const [attempts, setAttempts] = React86.useState(0);
|
|
17558
17564
|
const [showHint, setShowHint] = React86.useState(false);
|
|
17559
|
-
const components =
|
|
17560
|
-
const slots =
|
|
17565
|
+
const components = resolved?.components ?? [];
|
|
17566
|
+
const slots = resolved?.slots ?? [];
|
|
17561
17567
|
const usedComponentIds = new Set(Object.values(placements));
|
|
17562
17568
|
const availableComponents = components.filter((c) => !usedComponentIds.has(c.id));
|
|
17563
17569
|
const [selectedComponent, setSelectedComponent] = React86.useState(null);
|
|
@@ -17591,7 +17597,7 @@ function BuilderBoard({
|
|
|
17591
17597
|
}, [slots, placements, attempts, completeEvent, emit]);
|
|
17592
17598
|
const handleReset = () => {
|
|
17593
17599
|
setSubmitted(false);
|
|
17594
|
-
if (attempts >= 2 &&
|
|
17600
|
+
if (attempts >= 2 && resolved?.hint) {
|
|
17595
17601
|
setShowHint(true);
|
|
17596
17602
|
}
|
|
17597
17603
|
};
|
|
@@ -17603,20 +17609,21 @@ function BuilderBoard({
|
|
|
17603
17609
|
setShowHint(false);
|
|
17604
17610
|
};
|
|
17605
17611
|
const getComponentById = (id) => components.find((c) => c.id === id);
|
|
17612
|
+
if (!resolved) return null;
|
|
17606
17613
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
17607
17614
|
Box,
|
|
17608
17615
|
{
|
|
17609
17616
|
className,
|
|
17610
17617
|
style: {
|
|
17611
|
-
backgroundImage:
|
|
17618
|
+
backgroundImage: resolved.theme?.background ? `url(${resolved.theme.background})` : void 0,
|
|
17612
17619
|
backgroundSize: "cover",
|
|
17613
17620
|
backgroundPosition: "center"
|
|
17614
17621
|
},
|
|
17615
17622
|
children: /* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "lg", className: "p-4", children: [
|
|
17616
|
-
|
|
17623
|
+
resolved.headerImage && !headerError ? /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "w-full h-32 overflow-hidden rounded-container", children: /* @__PURE__ */ jsxRuntime.jsx("img", { src: resolved.headerImage, alt: "", onError: () => setHeaderError(true), className: "w-full h-full object-cover" }) }) : resolved.headerImage && headerError ? /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "w-full h-32 rounded-container bg-gradient-to-br from-muted to-accent opacity-60" }) : null,
|
|
17617
17624
|
/* @__PURE__ */ jsxRuntime.jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "sm", children: [
|
|
17618
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "h4", weight: "bold", children:
|
|
17619
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", children:
|
|
17625
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "h4", weight: "bold", children: resolved.title }),
|
|
17626
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", children: resolved.description })
|
|
17620
17627
|
] }) }),
|
|
17621
17628
|
/* @__PURE__ */ jsxRuntime.jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "sm", children: [
|
|
17622
17629
|
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", weight: "bold", className: "uppercase tracking-wider text-muted-foreground", children: t("builder.components") }),
|
|
@@ -17676,9 +17683,9 @@ function BuilderBoard({
|
|
|
17676
17683
|
] }) }),
|
|
17677
17684
|
submitted && /* @__PURE__ */ jsxRuntime.jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "sm", align: "center", children: [
|
|
17678
17685
|
/* @__PURE__ */ jsxRuntime.jsx(Icon, { icon: allCorrect ? LucideIcons2.CheckCircle : LucideIcons2.XCircle, size: "lg", className: allCorrect ? "text-success" : "text-error" }),
|
|
17679
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", weight: "bold", children: allCorrect ?
|
|
17686
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", weight: "bold", children: allCorrect ? resolved.successMessage ?? t("builder.success") : resolved.failMessage ?? t("builder.incorrect") })
|
|
17680
17687
|
] }) }),
|
|
17681
|
-
showHint &&
|
|
17688
|
+
showHint && resolved.hint && /* @__PURE__ */ jsxRuntime.jsx(Card, { className: "p-4 border-l-4 border-l-warning", children: /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", children: resolved.hint }) }),
|
|
17682
17689
|
/* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "sm", justify: "center", children: [
|
|
17683
17690
|
!submitted ? /* @__PURE__ */ jsxRuntime.jsxs(Button, { variant: "primary", onClick: handleSubmit, disabled: !allPlaced, children: [
|
|
17684
17691
|
/* @__PURE__ */ jsxRuntime.jsx(Icon, { icon: LucideIcons2.Wrench, size: "sm" }),
|
|
@@ -20219,11 +20226,12 @@ function CastleBoard({
|
|
|
20219
20226
|
className
|
|
20220
20227
|
}) {
|
|
20221
20228
|
const eventBus = useEventBus();
|
|
20222
|
-
const
|
|
20223
|
-
const
|
|
20224
|
-
const
|
|
20225
|
-
const
|
|
20226
|
-
const
|
|
20229
|
+
const resolved = Array.isArray(entity) ? entity[0] : entity;
|
|
20230
|
+
const tiles = resolved?.tiles ?? [];
|
|
20231
|
+
const features = resolved?.features ?? [];
|
|
20232
|
+
const units = resolved?.units ?? [];
|
|
20233
|
+
const assetManifest = resolved?.assetManifest;
|
|
20234
|
+
const backgroundImage = resolved?.backgroundImage;
|
|
20227
20235
|
const [hoveredTile, setHoveredTile] = React86.useState(null);
|
|
20228
20236
|
const [selectedFeature, setSelectedFeature] = React86.useState(null);
|
|
20229
20237
|
const hoveredFeature = React86.useMemo(() => {
|
|
@@ -21128,13 +21136,14 @@ function ClassifierBoard({
|
|
|
21128
21136
|
}) {
|
|
21129
21137
|
const { emit } = useEventBus();
|
|
21130
21138
|
const { t } = useTranslate();
|
|
21139
|
+
const resolved = Array.isArray(entity) ? entity[0] : entity;
|
|
21131
21140
|
const [assignments, setAssignments] = React86.useState({});
|
|
21132
21141
|
const [headerError, setHeaderError] = React86.useState(false);
|
|
21133
21142
|
const [submitted, setSubmitted] = React86.useState(false);
|
|
21134
21143
|
const [attempts, setAttempts] = React86.useState(0);
|
|
21135
21144
|
const [showHint, setShowHint] = React86.useState(false);
|
|
21136
|
-
const items =
|
|
21137
|
-
const categories =
|
|
21145
|
+
const items = resolved?.items ?? [];
|
|
21146
|
+
const categories = resolved?.categories ?? [];
|
|
21138
21147
|
const unassignedItems = items.filter((item) => !assignments[item.id]);
|
|
21139
21148
|
const allAssigned = Object.keys(assignments).length === items.length;
|
|
21140
21149
|
const results = submitted ? items.map((item) => ({
|
|
@@ -21166,7 +21175,7 @@ function ClassifierBoard({
|
|
|
21166
21175
|
}, [items, assignments, attempts, completeEvent, emit]);
|
|
21167
21176
|
const handleReset = () => {
|
|
21168
21177
|
setSubmitted(false);
|
|
21169
|
-
if (attempts >= 2 &&
|
|
21178
|
+
if (attempts >= 2 && resolved?.hint) {
|
|
21170
21179
|
setShowHint(true);
|
|
21171
21180
|
}
|
|
21172
21181
|
};
|
|
@@ -21176,20 +21185,21 @@ function ClassifierBoard({
|
|
|
21176
21185
|
setAttempts(0);
|
|
21177
21186
|
setShowHint(false);
|
|
21178
21187
|
};
|
|
21188
|
+
if (!resolved) return null;
|
|
21179
21189
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
21180
21190
|
Box,
|
|
21181
21191
|
{
|
|
21182
21192
|
className,
|
|
21183
21193
|
style: {
|
|
21184
|
-
backgroundImage:
|
|
21194
|
+
backgroundImage: resolved.theme?.background ? `url(${resolved.theme.background})` : void 0,
|
|
21185
21195
|
backgroundSize: "cover",
|
|
21186
21196
|
backgroundPosition: "center"
|
|
21187
21197
|
},
|
|
21188
21198
|
children: /* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "lg", className: "p-4", children: [
|
|
21189
|
-
|
|
21199
|
+
resolved.headerImage && !headerError ? /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "w-full h-32 overflow-hidden rounded-container", children: /* @__PURE__ */ jsxRuntime.jsx("img", { src: resolved.headerImage, alt: "", onError: () => setHeaderError(true), className: "w-full h-full object-cover" }) }) : resolved.headerImage && headerError ? /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "w-full h-32 rounded-container bg-gradient-to-br from-muted to-accent opacity-60" }) : null,
|
|
21190
21200
|
/* @__PURE__ */ jsxRuntime.jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "sm", children: [
|
|
21191
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "h4", weight: "bold", children:
|
|
21192
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", children:
|
|
21201
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "h4", weight: "bold", children: resolved.title }),
|
|
21202
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", children: resolved.description })
|
|
21193
21203
|
] }) }),
|
|
21194
21204
|
unassignedItems.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "sm", children: [
|
|
21195
21205
|
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", weight: "bold", className: "uppercase tracking-wider text-muted-foreground", children: t("classifier.itemsToSort") }),
|
|
@@ -21241,10 +21251,10 @@ function ClassifierBoard({
|
|
|
21241
21251
|
}) }),
|
|
21242
21252
|
submitted && /* @__PURE__ */ jsxRuntime.jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "sm", align: "center", children: [
|
|
21243
21253
|
/* @__PURE__ */ jsxRuntime.jsx(Icon, { icon: allCorrect ? LucideIcons2.CheckCircle : LucideIcons2.XCircle, size: "lg", className: allCorrect ? "text-success" : "text-error" }),
|
|
21244
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", weight: "bold", children: allCorrect ?
|
|
21245
|
-
!allCorrect &&
|
|
21254
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", weight: "bold", children: allCorrect ? resolved.successMessage ?? t("classifier.allCorrect") : `${correctCount}/${items.length} ${t("classifier.correct")}` }),
|
|
21255
|
+
!allCorrect && resolved.failMessage && /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", className: "text-muted-foreground", children: resolved.failMessage })
|
|
21246
21256
|
] }) }),
|
|
21247
|
-
showHint &&
|
|
21257
|
+
showHint && resolved.hint && /* @__PURE__ */ jsxRuntime.jsx(Card, { className: "p-4 border-l-4 border-l-warning", children: /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", children: resolved.hint }) }),
|
|
21248
21258
|
/* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "sm", justify: "center", children: [
|
|
21249
21259
|
!submitted ? /* @__PURE__ */ jsxRuntime.jsxs(Button, { variant: "primary", onClick: handleSubmit, disabled: !allAssigned, children: [
|
|
21250
21260
|
/* @__PURE__ */ jsxRuntime.jsx(Icon, { icon: LucideIcons2.Send, size: "sm" }),
|
|
@@ -32579,7 +32589,7 @@ var init_OptionConstraintGroup = __esm({
|
|
|
32579
32589
|
title,
|
|
32580
32590
|
description,
|
|
32581
32591
|
options,
|
|
32582
|
-
constraint,
|
|
32592
|
+
constraint = { type: "single" },
|
|
32583
32593
|
selected = [],
|
|
32584
32594
|
onChange,
|
|
32585
32595
|
changeEvent,
|
|
@@ -35717,7 +35727,7 @@ function DataTable({
|
|
|
35717
35727
|
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
35718
35728
|
EmptyState,
|
|
35719
35729
|
{
|
|
35720
|
-
icon: emptyIcon,
|
|
35730
|
+
icon: typeof emptyIcon === "string" ? resolveIcon(emptyIcon) : emptyIcon,
|
|
35721
35731
|
title: resolvedEmptyTitle,
|
|
35722
35732
|
description: resolvedEmptyDescription,
|
|
35723
35733
|
actionLabel: emptyAction?.label,
|
|
@@ -35846,6 +35856,7 @@ var init_DataTable = __esm({
|
|
|
35846
35856
|
init_Stack();
|
|
35847
35857
|
init_Typography();
|
|
35848
35858
|
init_molecules();
|
|
35859
|
+
init_Icon();
|
|
35849
35860
|
init_useEventBus();
|
|
35850
35861
|
init_useTranslate();
|
|
35851
35862
|
init_types3();
|
|
@@ -35866,6 +35877,7 @@ function DebuggerBoard({
|
|
|
35866
35877
|
}) {
|
|
35867
35878
|
const { emit } = useEventBus();
|
|
35868
35879
|
const { t } = useTranslate();
|
|
35880
|
+
const resolved = Array.isArray(entity) ? entity[0] : entity;
|
|
35869
35881
|
const [flaggedLines, setFlaggedLines] = React86.useState(/* @__PURE__ */ new Set());
|
|
35870
35882
|
const [headerError, setHeaderError] = React86.useState(false);
|
|
35871
35883
|
const [submitted, setSubmitted] = React86.useState(false);
|
|
@@ -35883,7 +35895,7 @@ function DebuggerBoard({
|
|
|
35883
35895
|
return next;
|
|
35884
35896
|
});
|
|
35885
35897
|
};
|
|
35886
|
-
const lines =
|
|
35898
|
+
const lines = resolved?.lines ?? [];
|
|
35887
35899
|
const bugLines = lines.filter((l) => l.isBug);
|
|
35888
35900
|
const correctFlags = lines.filter((l) => l.isBug && flaggedLines.has(l.id));
|
|
35889
35901
|
const falseFlags = lines.filter((l) => !l.isBug && flaggedLines.has(l.id));
|
|
@@ -35898,7 +35910,7 @@ function DebuggerBoard({
|
|
|
35898
35910
|
}, [correctFlags.length, bugLines.length, falseFlags.length, attempts, completeEvent, emit]);
|
|
35899
35911
|
const handleReset = () => {
|
|
35900
35912
|
setSubmitted(false);
|
|
35901
|
-
if (attempts >= 2 &&
|
|
35913
|
+
if (attempts >= 2 && resolved?.hint) {
|
|
35902
35914
|
setShowHint(true);
|
|
35903
35915
|
}
|
|
35904
35916
|
};
|
|
@@ -35908,24 +35920,25 @@ function DebuggerBoard({
|
|
|
35908
35920
|
setAttempts(0);
|
|
35909
35921
|
setShowHint(false);
|
|
35910
35922
|
};
|
|
35923
|
+
if (!resolved) return null;
|
|
35911
35924
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
35912
35925
|
Box,
|
|
35913
35926
|
{
|
|
35914
35927
|
className,
|
|
35915
35928
|
style: {
|
|
35916
|
-
backgroundImage:
|
|
35929
|
+
backgroundImage: resolved.theme?.background ? `url(${resolved.theme.background})` : void 0,
|
|
35917
35930
|
backgroundSize: "cover",
|
|
35918
35931
|
backgroundPosition: "center"
|
|
35919
35932
|
},
|
|
35920
35933
|
children: /* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "lg", className: "p-4", children: [
|
|
35921
|
-
|
|
35934
|
+
resolved.headerImage && !headerError ? /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "w-full h-32 overflow-hidden rounded-container", children: /* @__PURE__ */ jsxRuntime.jsx("img", { src: resolved.headerImage, alt: "", onError: () => setHeaderError(true), className: "w-full h-full object-cover" }) }) : resolved.headerImage && headerError ? /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "w-full h-32 rounded-container bg-gradient-to-br from-muted to-accent opacity-60" }) : null,
|
|
35922
35935
|
/* @__PURE__ */ jsxRuntime.jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "sm", children: [
|
|
35923
35936
|
/* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "xs", align: "center", children: [
|
|
35924
35937
|
/* @__PURE__ */ jsxRuntime.jsx(Icon, { icon: LucideIcons2.Bug, size: "sm" }),
|
|
35925
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "h4", weight: "bold", children:
|
|
35938
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "h4", weight: "bold", children: resolved.title })
|
|
35926
35939
|
] }),
|
|
35927
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", children:
|
|
35928
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "caption", className: "text-muted-foreground", children: t("debugger.findBugs", { count: String(
|
|
35940
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", children: resolved.description }),
|
|
35941
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "caption", className: "text-muted-foreground", children: t("debugger.findBugs", { count: String(resolved.bugCount) }) })
|
|
35929
35942
|
] }) }),
|
|
35930
35943
|
/* @__PURE__ */ jsxRuntime.jsx(Card, { className: "p-0 overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx(VStack, { gap: "none", children: lines.map((line, i) => {
|
|
35931
35944
|
const isFlagged = flaggedLines.has(line.id);
|
|
@@ -35957,7 +35970,7 @@ function DebuggerBoard({
|
|
|
35957
35970
|
);
|
|
35958
35971
|
}) }) }),
|
|
35959
35972
|
submitted && /* @__PURE__ */ jsxRuntime.jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "sm", children: [
|
|
35960
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", weight: "bold", children: allCorrect ?
|
|
35973
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", weight: "bold", children: allCorrect ? resolved.successMessage ?? t("debugger.allFound") : `${correctFlags.length}/${bugLines.length} ${t("debugger.bugsFound")}` }),
|
|
35961
35974
|
bugLines.map((line) => /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "xs", align: "start", children: [
|
|
35962
35975
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
35963
35976
|
Icon,
|
|
@@ -35973,7 +35986,7 @@ function DebuggerBoard({
|
|
|
35973
35986
|
] })
|
|
35974
35987
|
] }, line.id))
|
|
35975
35988
|
] }) }),
|
|
35976
|
-
showHint &&
|
|
35989
|
+
showHint && resolved.hint && /* @__PURE__ */ jsxRuntime.jsx(Card, { className: "p-4 border-l-4 border-l-warning", children: /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", children: resolved.hint }) }),
|
|
35977
35990
|
/* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "sm", justify: "center", children: [
|
|
35978
35991
|
!submitted ? /* @__PURE__ */ jsxRuntime.jsxs(Button, { variant: "primary", onClick: handleSubmit, disabled: flaggedLines.size === 0, children: [
|
|
35979
35992
|
/* @__PURE__ */ jsxRuntime.jsx(Icon, { icon: LucideIcons2.Send, size: "sm" }),
|
|
@@ -37105,7 +37118,8 @@ function EventHandlerBoard({
|
|
|
37105
37118
|
}) {
|
|
37106
37119
|
const { emit } = useEventBus();
|
|
37107
37120
|
const { t } = useTranslate();
|
|
37108
|
-
const
|
|
37121
|
+
const resolved = Array.isArray(entity) ? entity[0] : entity;
|
|
37122
|
+
const entityObjects = resolved?.objects ?? [];
|
|
37109
37123
|
const [objects, setObjects] = React86.useState(entityObjects);
|
|
37110
37124
|
const [selectedObjectId, setSelectedObjectId] = React86.useState(
|
|
37111
37125
|
entityObjects[0]?.id || null
|
|
@@ -37140,7 +37154,7 @@ function EventHandlerBoard({
|
|
|
37140
37154
|
allRules.push({ object: obj, rule });
|
|
37141
37155
|
});
|
|
37142
37156
|
});
|
|
37143
|
-
const triggers =
|
|
37157
|
+
const triggers = resolved?.triggerEvents || [];
|
|
37144
37158
|
const eventQueue = [...triggers];
|
|
37145
37159
|
const firedEvents = /* @__PURE__ */ new Set();
|
|
37146
37160
|
let stepIdx = 0;
|
|
@@ -37171,12 +37185,12 @@ function EventHandlerBoard({
|
|
|
37171
37185
|
matching.forEach(({ object, rule }) => {
|
|
37172
37186
|
addLogEntry(object.icon, t("eventHandler.heardEvent", { object: object.name, event: currentEvent, action: rule.thenAction }), "done");
|
|
37173
37187
|
eventQueue.push(rule.thenAction);
|
|
37174
|
-
if (rule.thenAction ===
|
|
37188
|
+
if (rule.thenAction === resolved?.goalEvent) {
|
|
37175
37189
|
goalReached = true;
|
|
37176
37190
|
}
|
|
37177
37191
|
});
|
|
37178
37192
|
}
|
|
37179
|
-
if (currentEvent ===
|
|
37193
|
+
if (currentEvent === resolved?.goalEvent) {
|
|
37180
37194
|
goalReached = true;
|
|
37181
37195
|
}
|
|
37182
37196
|
stepIdx++;
|
|
@@ -37186,7 +37200,7 @@ function EventHandlerBoard({
|
|
|
37186
37200
|
addLogEntry("\u{1F3AC}", t("eventHandler.simulationStarted", { events: triggers.join(", ") }), "active");
|
|
37187
37201
|
}
|
|
37188
37202
|
timerRef.current = setTimeout(processNext, stepDurationMs);
|
|
37189
|
-
}, [playState, objects,
|
|
37203
|
+
}, [playState, objects, resolved, stepDurationMs, playEvent, completeEvent, emit, addLogEntry, t]);
|
|
37190
37204
|
const handleTryAgain = React86.useCallback(() => {
|
|
37191
37205
|
if (timerRef.current) clearTimeout(timerRef.current);
|
|
37192
37206
|
setPlayState("editing");
|
|
@@ -37194,12 +37208,13 @@ function EventHandlerBoard({
|
|
|
37194
37208
|
}, []);
|
|
37195
37209
|
const handleReset = React86.useCallback(() => {
|
|
37196
37210
|
if (timerRef.current) clearTimeout(timerRef.current);
|
|
37197
|
-
setObjects(
|
|
37211
|
+
setObjects(resolved?.objects ?? []);
|
|
37198
37212
|
setPlayState("editing");
|
|
37199
37213
|
setEventLog([]);
|
|
37200
|
-
setSelectedObjectId((
|
|
37214
|
+
setSelectedObjectId((resolved?.objects ?? [])[0]?.id || null);
|
|
37201
37215
|
setAttempts(0);
|
|
37202
|
-
}, [
|
|
37216
|
+
}, [resolved?.objects]);
|
|
37217
|
+
if (!resolved) return null;
|
|
37203
37218
|
const objectViewers = objects.map((obj) => {
|
|
37204
37219
|
const machine = {
|
|
37205
37220
|
name: obj.name,
|
|
@@ -37213,25 +37228,25 @@ function EventHandlerBoard({
|
|
|
37213
37228
|
};
|
|
37214
37229
|
return { obj, machine };
|
|
37215
37230
|
});
|
|
37216
|
-
const showHint = attempts >= 3 &&
|
|
37231
|
+
const showHint = attempts >= 3 && resolved.hint;
|
|
37217
37232
|
const encourageKey = ENCOURAGEMENT_KEYS[Math.min(attempts - 1, ENCOURAGEMENT_KEYS.length - 1)] ?? ENCOURAGEMENT_KEYS[0];
|
|
37218
37233
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
37219
37234
|
VStack,
|
|
37220
37235
|
{
|
|
37221
37236
|
className: cn("p-4 gap-6", className),
|
|
37222
37237
|
style: {
|
|
37223
|
-
backgroundImage:
|
|
37238
|
+
backgroundImage: resolved.theme?.background ? `url(${resolved.theme.background})` : void 0,
|
|
37224
37239
|
backgroundSize: "cover",
|
|
37225
37240
|
backgroundPosition: "center"
|
|
37226
37241
|
},
|
|
37227
37242
|
children: [
|
|
37228
|
-
|
|
37243
|
+
resolved.headerImage && !headerError ? /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "w-full h-32 overflow-hidden rounded-container", children: /* @__PURE__ */ jsxRuntime.jsx("img", { src: resolved.headerImage, alt: "", onError: () => setHeaderError(true), className: "w-full h-full object-cover" }) }) : resolved.headerImage && headerError ? /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "w-full h-32 rounded-container bg-gradient-to-br from-muted to-accent opacity-60" }) : null,
|
|
37229
37244
|
/* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "xs", children: [
|
|
37230
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "h4", className: "text-foreground", children:
|
|
37231
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body2", className: "text-muted-foreground", children:
|
|
37245
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "h4", className: "text-foreground", children: resolved.title }),
|
|
37246
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body2", className: "text-muted-foreground", children: resolved.description }),
|
|
37232
37247
|
/* @__PURE__ */ jsxRuntime.jsxs(HStack, { className: "items-center p-2 rounded bg-primary/10 border border-primary/30", gap: "xs", children: [
|
|
37233
37248
|
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "caption", className: "text-primary font-bold", children: t("game.goal") + ":" }),
|
|
37234
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "caption", className: "text-foreground", children:
|
|
37249
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "caption", className: "text-foreground", children: resolved.goalCondition })
|
|
37235
37250
|
] })
|
|
37236
37251
|
] }),
|
|
37237
37252
|
/* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "sm", children: [
|
|
@@ -37262,12 +37277,12 @@ function EventHandlerBoard({
|
|
|
37262
37277
|
}
|
|
37263
37278
|
),
|
|
37264
37279
|
eventLog.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(EventLog, { entries: eventLog }),
|
|
37265
|
-
playState === "success" && /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "p-4 rounded-container bg-success/20 border border-success text-center", children: /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "h5", className: "text-success", children:
|
|
37280
|
+
playState === "success" && /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "p-4 rounded-container bg-success/20 border border-success text-center", children: /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "h5", className: "text-success", children: resolved.successMessage || t("eventHandler.chainComplete") }) }),
|
|
37266
37281
|
playState === "fail" && /* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "sm", children: [
|
|
37267
37282
|
/* @__PURE__ */ jsxRuntime.jsx(Box, { className: "p-4 rounded-container bg-warning/10 border border-warning/30 text-center", children: /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body1", className: "text-foreground font-medium", children: t(encourageKey) }) }),
|
|
37268
37283
|
showHint && /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "p-3 rounded-container bg-accent/10 border border-accent/30", children: /* @__PURE__ */ jsxRuntime.jsxs(HStack, { className: "items-start", gap: "xs", children: [
|
|
37269
37284
|
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body2", className: "text-accent font-bold shrink-0", children: "\u{1F4A1} " + t("game.hint") + ":" }),
|
|
37270
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body2", className: "text-foreground", children:
|
|
37285
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body2", className: "text-foreground", children: resolved.hint })
|
|
37271
37286
|
] }) })
|
|
37272
37287
|
] }),
|
|
37273
37288
|
/* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "sm", children: [
|
|
@@ -40388,19 +40403,20 @@ function NegotiatorBoard({
|
|
|
40388
40403
|
}) {
|
|
40389
40404
|
const { emit } = useEventBus();
|
|
40390
40405
|
const { t } = useTranslate();
|
|
40406
|
+
const resolved = Array.isArray(entity) ? entity[0] : entity;
|
|
40391
40407
|
const [history, setHistory] = React86.useState([]);
|
|
40392
40408
|
const [headerError, setHeaderError] = React86.useState(false);
|
|
40393
40409
|
const [showHint, setShowHint] = React86.useState(false);
|
|
40394
40410
|
const currentRound = history.length;
|
|
40395
|
-
const isComplete = currentRound >=
|
|
40411
|
+
const isComplete = currentRound >= (resolved?.totalRounds ?? 0);
|
|
40396
40412
|
const playerTotal = history.reduce((s, r) => s + r.playerPayoff, 0);
|
|
40397
40413
|
const opponentTotal = history.reduce((s, r) => s + r.opponentPayoff, 0);
|
|
40398
|
-
const won = isComplete && playerTotal >=
|
|
40399
|
-
const actions =
|
|
40400
|
-
const payoffMatrix =
|
|
40414
|
+
const won = isComplete && playerTotal >= (resolved?.targetScore ?? 0);
|
|
40415
|
+
const actions = resolved?.actions ?? [];
|
|
40416
|
+
const payoffMatrix = resolved?.payoffMatrix ?? [];
|
|
40401
40417
|
const handleAction = React86.useCallback((actionId) => {
|
|
40402
40418
|
if (isComplete) return;
|
|
40403
|
-
const opponentAction = getOpponentAction(
|
|
40419
|
+
const opponentAction = getOpponentAction(resolved?.opponentStrategy ?? "random", actions, history);
|
|
40404
40420
|
const payoff = payoffMatrix.find(
|
|
40405
40421
|
(p2) => p2.playerAction === actionId && p2.opponentAction === opponentAction
|
|
40406
40422
|
);
|
|
@@ -40413,41 +40429,42 @@ function NegotiatorBoard({
|
|
|
40413
40429
|
};
|
|
40414
40430
|
const newHistory = [...history, result];
|
|
40415
40431
|
setHistory(newHistory);
|
|
40416
|
-
if (newHistory.length >=
|
|
40432
|
+
if (newHistory.length >= (resolved?.totalRounds ?? 0)) {
|
|
40417
40433
|
const total = newHistory.reduce((s, r) => s + r.playerPayoff, 0);
|
|
40418
|
-
if (total >=
|
|
40434
|
+
if (total >= (resolved?.targetScore ?? 0)) {
|
|
40419
40435
|
emit(`UI:${completeEvent}`, { success: true, score: total });
|
|
40420
40436
|
}
|
|
40421
|
-
if (newHistory.length >= 3 &&
|
|
40437
|
+
if (newHistory.length >= 3 && resolved?.hint) {
|
|
40422
40438
|
setShowHint(true);
|
|
40423
40439
|
}
|
|
40424
40440
|
}
|
|
40425
|
-
}, [isComplete,
|
|
40441
|
+
}, [isComplete, resolved, actions, payoffMatrix, history, currentRound, completeEvent, emit]);
|
|
40426
40442
|
const handleReset = () => {
|
|
40427
40443
|
setHistory([]);
|
|
40428
40444
|
setShowHint(false);
|
|
40429
40445
|
};
|
|
40430
40446
|
const getActionLabel = (id) => actions.find((a) => a.id === id)?.label ?? id;
|
|
40447
|
+
if (!resolved) return null;
|
|
40431
40448
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
40432
40449
|
Box,
|
|
40433
40450
|
{
|
|
40434
40451
|
className,
|
|
40435
40452
|
style: {
|
|
40436
|
-
backgroundImage:
|
|
40453
|
+
backgroundImage: resolved.theme?.background ? `url(${resolved.theme.background})` : void 0,
|
|
40437
40454
|
backgroundSize: "cover",
|
|
40438
40455
|
backgroundPosition: "center"
|
|
40439
40456
|
},
|
|
40440
40457
|
children: /* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "lg", className: "p-4", children: [
|
|
40441
|
-
|
|
40458
|
+
resolved.headerImage && !headerError ? /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "w-full h-32 overflow-hidden rounded-container", children: /* @__PURE__ */ jsxRuntime.jsx("img", { src: resolved.headerImage, alt: "", onError: () => setHeaderError(true), className: "w-full h-full object-cover" }) }) : resolved.headerImage && headerError ? /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "w-full h-32 rounded-container bg-gradient-to-br from-muted to-accent opacity-60" }) : null,
|
|
40442
40459
|
/* @__PURE__ */ jsxRuntime.jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "sm", children: [
|
|
40443
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "h4", weight: "bold", children:
|
|
40444
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", children:
|
|
40460
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "h4", weight: "bold", children: resolved.title }),
|
|
40461
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", children: resolved.description }),
|
|
40445
40462
|
/* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "md", children: [
|
|
40446
|
-
/* @__PURE__ */ jsxRuntime.jsx(Badge, { size: "sm", children: t("negotiator.round", { current: String(currentRound), total: String(
|
|
40463
|
+
/* @__PURE__ */ jsxRuntime.jsx(Badge, { size: "sm", children: t("negotiator.round", { current: String(currentRound), total: String(resolved.totalRounds) }) }),
|
|
40447
40464
|
/* @__PURE__ */ jsxRuntime.jsxs(Badge, { size: "sm", children: [
|
|
40448
40465
|
t("negotiator.target"),
|
|
40449
40466
|
": ",
|
|
40450
|
-
|
|
40467
|
+
resolved.targetScore
|
|
40451
40468
|
] })
|
|
40452
40469
|
] })
|
|
40453
40470
|
] }) }),
|
|
@@ -40496,16 +40513,16 @@ function NegotiatorBoard({
|
|
|
40496
40513
|
] }) }),
|
|
40497
40514
|
isComplete && /* @__PURE__ */ jsxRuntime.jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "sm", align: "center", children: [
|
|
40498
40515
|
/* @__PURE__ */ jsxRuntime.jsx(Icon, { icon: LucideIcons2.CheckCircle, size: "lg", className: won ? "text-success" : "text-error" }),
|
|
40499
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", weight: "bold", children: won ?
|
|
40516
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", weight: "bold", children: won ? resolved.successMessage ?? t("negotiator.success") : resolved.failMessage ?? t("negotiator.failed") }),
|
|
40500
40517
|
/* @__PURE__ */ jsxRuntime.jsxs(Typography, { variant: "caption", className: "text-muted-foreground", children: [
|
|
40501
40518
|
t("negotiator.finalScore"),
|
|
40502
40519
|
": ",
|
|
40503
40520
|
playerTotal,
|
|
40504
40521
|
"/",
|
|
40505
|
-
|
|
40522
|
+
resolved.targetScore
|
|
40506
40523
|
] })
|
|
40507
40524
|
] }) }),
|
|
40508
|
-
showHint &&
|
|
40525
|
+
showHint && resolved.hint && !won && /* @__PURE__ */ jsxRuntime.jsx(Card, { className: "p-4 border-l-4 border-l-warning", children: /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", children: resolved.hint }) }),
|
|
40509
40526
|
isComplete && !won && /* @__PURE__ */ jsxRuntime.jsx(HStack, { justify: "center", children: /* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "primary", onClick: handleReset, children: t("negotiator.playAgain") }) })
|
|
40510
40527
|
] })
|
|
40511
40528
|
}
|
|
@@ -43279,15 +43296,16 @@ function SequencerBoard({
|
|
|
43279
43296
|
}) {
|
|
43280
43297
|
const { emit } = useEventBus();
|
|
43281
43298
|
const { t } = useTranslate();
|
|
43299
|
+
const resolved = Array.isArray(entity) ? entity[0] : entity;
|
|
43282
43300
|
const [headerError, setHeaderError] = React86.useState(false);
|
|
43283
43301
|
const [slots, setSlots] = React86.useState(
|
|
43284
|
-
() => Array.from({ length:
|
|
43302
|
+
() => Array.from({ length: resolved?.maxSlots ?? 0 }, () => void 0)
|
|
43285
43303
|
);
|
|
43286
43304
|
const [playState, setPlayState] = React86.useState("idle");
|
|
43287
43305
|
const [currentStep, setCurrentStep] = React86.useState(-1);
|
|
43288
43306
|
const [attempts, setAttempts] = React86.useState(0);
|
|
43289
43307
|
const [slotFeedback, setSlotFeedback] = React86.useState(
|
|
43290
|
-
() => Array.from({ length:
|
|
43308
|
+
() => Array.from({ length: resolved?.maxSlots ?? 0 }, () => null)
|
|
43291
43309
|
);
|
|
43292
43310
|
const timerRef = React86.useRef(null);
|
|
43293
43311
|
React86.useEffect(() => () => {
|
|
@@ -43321,17 +43339,17 @@ function SequencerBoard({
|
|
|
43321
43339
|
}, [emit]);
|
|
43322
43340
|
const handleReset = React86.useCallback(() => {
|
|
43323
43341
|
if (timerRef.current) clearTimeout(timerRef.current);
|
|
43324
|
-
setSlots(Array.from({ length:
|
|
43342
|
+
setSlots(Array.from({ length: resolved?.maxSlots ?? 0 }, () => void 0));
|
|
43325
43343
|
setPlayState("idle");
|
|
43326
43344
|
setCurrentStep(-1);
|
|
43327
43345
|
setAttempts(0);
|
|
43328
|
-
setSlotFeedback(Array.from({ length:
|
|
43329
|
-
}, [
|
|
43346
|
+
setSlotFeedback(Array.from({ length: resolved?.maxSlots ?? 0 }, () => null));
|
|
43347
|
+
}, [resolved?.maxSlots]);
|
|
43330
43348
|
const filledSlots = slots.filter((s) => !!s);
|
|
43331
43349
|
const canPlay = filledSlots.length > 0 && playState === "idle";
|
|
43332
43350
|
const handlePlay = React86.useCallback(() => {
|
|
43333
43351
|
if (!canPlay) return;
|
|
43334
|
-
setSlotFeedback(Array.from({ length:
|
|
43352
|
+
setSlotFeedback(Array.from({ length: resolved?.maxSlots ?? 0 }, () => null));
|
|
43335
43353
|
emit("UI:PLAY_SOUND", { key: "confirm" });
|
|
43336
43354
|
const sequence = slots.map((s) => s?.id || "");
|
|
43337
43355
|
if (playEvent) {
|
|
@@ -43342,10 +43360,10 @@ function SequencerBoard({
|
|
|
43342
43360
|
let step = 0;
|
|
43343
43361
|
const advance = () => {
|
|
43344
43362
|
step++;
|
|
43345
|
-
if (step >=
|
|
43363
|
+
if (step >= (resolved?.maxSlots ?? 0)) {
|
|
43346
43364
|
const playerSeq = slots.map((s) => s?.id);
|
|
43347
43365
|
const playerIds = slots.filter(Boolean).map((s) => s?.id || "");
|
|
43348
|
-
const success =
|
|
43366
|
+
const success = (resolved?.solutions ?? []).some(
|
|
43349
43367
|
(sol) => sol.length === playerIds.length && sol.every((id, i) => id === playerIds[i])
|
|
43350
43368
|
);
|
|
43351
43369
|
if (success) {
|
|
@@ -43357,7 +43375,7 @@ function SequencerBoard({
|
|
|
43357
43375
|
}
|
|
43358
43376
|
} else {
|
|
43359
43377
|
setAttempts((prev) => prev + 1);
|
|
43360
|
-
const feedback = computeSlotFeedback(playerSeq,
|
|
43378
|
+
const feedback = computeSlotFeedback(playerSeq, resolved?.solutions ?? []);
|
|
43361
43379
|
setSlotFeedback(feedback);
|
|
43362
43380
|
setPlayState("idle");
|
|
43363
43381
|
setCurrentStep(-1);
|
|
@@ -43375,10 +43393,10 @@ function SequencerBoard({
|
|
|
43375
43393
|
}
|
|
43376
43394
|
};
|
|
43377
43395
|
timerRef.current = setTimeout(advance, stepDurationMs);
|
|
43378
|
-
}, [canPlay, slots,
|
|
43396
|
+
}, [canPlay, slots, resolved?.maxSlots, resolved?.solutions, stepDurationMs, playEvent, completeEvent, emit]);
|
|
43379
43397
|
const machine = {
|
|
43380
|
-
name:
|
|
43381
|
-
description:
|
|
43398
|
+
name: resolved?.title ?? "",
|
|
43399
|
+
description: resolved?.description ?? "",
|
|
43382
43400
|
states: slots.map((s, i) => stepLabel(s, i)),
|
|
43383
43401
|
currentState: currentStep >= 0 ? stepLabel(slots[currentStep], currentStep) : "__idle__",
|
|
43384
43402
|
transitions: slots.slice(0, -1).map((s, i) => ({
|
|
@@ -43387,36 +43405,37 @@ function SequencerBoard({
|
|
|
43387
43405
|
event: "NEXT"
|
|
43388
43406
|
}))
|
|
43389
43407
|
};
|
|
43390
|
-
const usedIds =
|
|
43391
|
-
const showHint = attempts >= 3 && !!
|
|
43408
|
+
const usedIds = resolved?.allowDuplicates === false ? slots.filter(Boolean).map((s) => s?.id || "") : [];
|
|
43409
|
+
const showHint = attempts >= 3 && !!resolved?.hint;
|
|
43392
43410
|
const hasFeedback = slotFeedback.some((f3) => f3 !== null);
|
|
43393
43411
|
const correctCount = slotFeedback.filter((f3) => f3 === "correct").length;
|
|
43394
43412
|
const encourageKey = ENCOURAGEMENT_KEYS2[Math.min(attempts - 1, ENCOURAGEMENT_KEYS2.length - 1)] ?? ENCOURAGEMENT_KEYS2[0];
|
|
43413
|
+
if (!resolved) return null;
|
|
43395
43414
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
43396
43415
|
VStack,
|
|
43397
43416
|
{
|
|
43398
43417
|
className: cn("p-4 gap-6", className),
|
|
43399
43418
|
style: {
|
|
43400
|
-
backgroundImage:
|
|
43419
|
+
backgroundImage: resolved.theme?.background ? `url(${resolved.theme.background})` : void 0,
|
|
43401
43420
|
backgroundSize: "cover",
|
|
43402
43421
|
backgroundPosition: "center"
|
|
43403
43422
|
},
|
|
43404
43423
|
children: [
|
|
43405
|
-
|
|
43424
|
+
resolved.headerImage && !headerError ? /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "w-full h-32 overflow-hidden rounded-container", children: /* @__PURE__ */ jsxRuntime.jsx("img", { src: resolved.headerImage, alt: "", onError: () => setHeaderError(true), className: "w-full h-full object-cover" }) }) : resolved.headerImage && headerError ? /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "w-full h-32 rounded-container bg-gradient-to-br from-muted to-accent opacity-60" }) : null,
|
|
43406
43425
|
/* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "xs", children: [
|
|
43407
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "h4", className: "text-foreground", children:
|
|
43408
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body2", className: "text-muted-foreground", children:
|
|
43426
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "h4", className: "text-foreground", children: resolved.title }),
|
|
43427
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body2", className: "text-muted-foreground", children: resolved.description })
|
|
43409
43428
|
] }),
|
|
43410
43429
|
showHint && /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "p-3 rounded-container bg-accent/10 border border-accent/30", children: /* @__PURE__ */ jsxRuntime.jsxs(HStack, { className: "items-start", gap: "xs", children: [
|
|
43411
43430
|
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body2", className: "text-accent font-bold shrink-0", children: "\u{1F4A1} " + t("game.hint") + ":" }),
|
|
43412
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body2", className: "text-foreground", children:
|
|
43431
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body2", className: "text-foreground", children: resolved.hint })
|
|
43413
43432
|
] }) }),
|
|
43414
43433
|
filledSlots.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(TraitStateViewer, { trait: machine, variant: "linear", size: "md" }),
|
|
43415
43434
|
/* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "xs", children: [
|
|
43416
43435
|
/* @__PURE__ */ jsxRuntime.jsxs(HStack, { className: "items-center justify-between", children: [
|
|
43417
43436
|
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body2", className: "text-muted-foreground font-medium", children: t("sequencer.yourSequence") + ":" }),
|
|
43418
43437
|
hasFeedback && playState === "idle" && /* @__PURE__ */ jsxRuntime.jsxs(Typography, { variant: "caption", className: "text-muted-foreground", children: [
|
|
43419
|
-
`${correctCount}/${
|
|
43438
|
+
`${correctCount}/${resolved.maxSlots} `,
|
|
43420
43439
|
"\u2705"
|
|
43421
43440
|
] })
|
|
43422
43441
|
] }),
|
|
@@ -43424,7 +43443,7 @@ function SequencerBoard({
|
|
|
43424
43443
|
SequenceBar,
|
|
43425
43444
|
{
|
|
43426
43445
|
slots,
|
|
43427
|
-
maxSlots:
|
|
43446
|
+
maxSlots: resolved.maxSlots,
|
|
43428
43447
|
onSlotDrop: handleSlotDrop,
|
|
43429
43448
|
onSlotRemove: handleSlotRemove,
|
|
43430
43449
|
playing: playState === "playing",
|
|
@@ -43438,15 +43457,15 @@ function SequencerBoard({
|
|
|
43438
43457
|
playState !== "playing" && /* @__PURE__ */ jsxRuntime.jsx(
|
|
43439
43458
|
ActionPalette,
|
|
43440
43459
|
{
|
|
43441
|
-
actions:
|
|
43460
|
+
actions: resolved.availableActions,
|
|
43442
43461
|
usedActionIds: usedIds,
|
|
43443
|
-
allowDuplicates:
|
|
43462
|
+
allowDuplicates: resolved.allowDuplicates !== false,
|
|
43444
43463
|
categoryColors,
|
|
43445
43464
|
label: t("sequencer.dragActions")
|
|
43446
43465
|
}
|
|
43447
43466
|
),
|
|
43448
43467
|
hasFeedback && playState === "idle" && attempts > 0 && /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "p-3 rounded-container bg-warning/10 border border-warning/30 text-center", children: /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body2", className: "text-foreground", children: t(encourageKey) }) }),
|
|
43449
|
-
playState === "success" && /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "p-4 rounded-container bg-success/20 border border-success text-center", children: /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "h5", className: "text-success", children:
|
|
43468
|
+
playState === "success" && /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "p-4 rounded-container bg-success/20 border border-success text-center", children: /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "h5", className: "text-success", children: resolved.successMessage || t("sequencer.levelComplete") }) }),
|
|
43450
43469
|
/* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "sm", children: [
|
|
43451
43470
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
43452
43471
|
Button,
|
|
@@ -44269,7 +44288,8 @@ function SimulatorBoard({
|
|
|
44269
44288
|
}) {
|
|
44270
44289
|
const { emit } = useEventBus();
|
|
44271
44290
|
const { t } = useTranslate();
|
|
44272
|
-
const
|
|
44291
|
+
const resolved = Array.isArray(entity) ? entity[0] : entity;
|
|
44292
|
+
const parameters = resolved?.parameters ?? [];
|
|
44273
44293
|
const [values, setValues] = React86.useState(() => {
|
|
44274
44294
|
const init = {};
|
|
44275
44295
|
for (const p2 of parameters) {
|
|
@@ -44283,15 +44303,15 @@ function SimulatorBoard({
|
|
|
44283
44303
|
const [showHint, setShowHint] = React86.useState(false);
|
|
44284
44304
|
const computeOutput = React86.useCallback((params) => {
|
|
44285
44305
|
try {
|
|
44286
|
-
const fn = new Function("params", `return (${
|
|
44306
|
+
const fn = new Function("params", `return (${resolved?.computeExpression})`);
|
|
44287
44307
|
return fn(params);
|
|
44288
44308
|
} catch {
|
|
44289
44309
|
return 0;
|
|
44290
44310
|
}
|
|
44291
|
-
}, [
|
|
44311
|
+
}, [resolved?.computeExpression]);
|
|
44292
44312
|
const output = React86.useMemo(() => computeOutput(values) ?? 0, [computeOutput, values]);
|
|
44293
|
-
const targetValue =
|
|
44294
|
-
const targetTolerance =
|
|
44313
|
+
const targetValue = resolved?.targetValue ?? 0;
|
|
44314
|
+
const targetTolerance = resolved?.targetTolerance ?? 0;
|
|
44295
44315
|
const isCorrect = Math.abs(output - targetValue) <= targetTolerance;
|
|
44296
44316
|
const handleParameterChange = (id, value) => {
|
|
44297
44317
|
if (submitted) return;
|
|
@@ -44306,7 +44326,7 @@ function SimulatorBoard({
|
|
|
44306
44326
|
};
|
|
44307
44327
|
const handleReset = () => {
|
|
44308
44328
|
setSubmitted(false);
|
|
44309
|
-
if (attempts >= 2 &&
|
|
44329
|
+
if (attempts >= 2 && resolved?.hint) {
|
|
44310
44330
|
setShowHint(true);
|
|
44311
44331
|
}
|
|
44312
44332
|
};
|
|
@@ -44320,20 +44340,21 @@ function SimulatorBoard({
|
|
|
44320
44340
|
setAttempts(0);
|
|
44321
44341
|
setShowHint(false);
|
|
44322
44342
|
};
|
|
44343
|
+
if (!resolved) return null;
|
|
44323
44344
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
44324
44345
|
Box,
|
|
44325
44346
|
{
|
|
44326
44347
|
className,
|
|
44327
44348
|
style: {
|
|
44328
|
-
backgroundImage:
|
|
44349
|
+
backgroundImage: resolved.theme?.background ? `url(${resolved.theme.background})` : void 0,
|
|
44329
44350
|
backgroundSize: "cover",
|
|
44330
44351
|
backgroundPosition: "center"
|
|
44331
44352
|
},
|
|
44332
44353
|
children: /* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "lg", className: "p-4", children: [
|
|
44333
|
-
|
|
44354
|
+
resolved.headerImage && !headerError ? /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "w-full h-32 overflow-hidden rounded-container", children: /* @__PURE__ */ jsxRuntime.jsx("img", { src: resolved.headerImage, alt: "", onError: () => setHeaderError(true), className: "w-full h-full object-cover" }) }) : resolved.headerImage && headerError ? /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "w-full h-32 rounded-container bg-gradient-to-br from-muted to-accent opacity-60" }) : null,
|
|
44334
44355
|
/* @__PURE__ */ jsxRuntime.jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "sm", children: [
|
|
44335
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "h4", weight: "bold", children:
|
|
44336
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", children:
|
|
44356
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "h4", weight: "bold", children: resolved.title }),
|
|
44357
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", children: resolved.description })
|
|
44337
44358
|
] }) }),
|
|
44338
44359
|
/* @__PURE__ */ jsxRuntime.jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "md", children: [
|
|
44339
44360
|
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", weight: "bold", className: "uppercase tracking-wider text-muted-foreground", children: t("simulator.parameters") }),
|
|
@@ -44374,28 +44395,28 @@ function SimulatorBoard({
|
|
|
44374
44395
|
] }, param.id))
|
|
44375
44396
|
] }) }),
|
|
44376
44397
|
/* @__PURE__ */ jsxRuntime.jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "sm", align: "center", children: [
|
|
44377
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", weight: "bold", className: "uppercase tracking-wider text-muted-foreground", children:
|
|
44398
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", weight: "bold", className: "uppercase tracking-wider text-muted-foreground", children: resolved.outputLabel }),
|
|
44378
44399
|
/* @__PURE__ */ jsxRuntime.jsxs(Typography, { variant: "h3", weight: "bold", children: [
|
|
44379
44400
|
output.toFixed(2),
|
|
44380
44401
|
" ",
|
|
44381
|
-
|
|
44402
|
+
resolved.outputUnit
|
|
44382
44403
|
] }),
|
|
44383
44404
|
submitted && /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "xs", align: "center", children: [
|
|
44384
44405
|
/* @__PURE__ */ jsxRuntime.jsx(Icon, { icon: isCorrect ? LucideIcons2.CheckCircle : LucideIcons2.XCircle, size: "sm", className: isCorrect ? "text-success" : "text-error" }),
|
|
44385
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", className: isCorrect ? "text-success" : "text-error", children: isCorrect ?
|
|
44406
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", className: isCorrect ? "text-success" : "text-error", children: isCorrect ? resolved.successMessage ?? t("simulator.correct") : resolved.failMessage ?? t("simulator.incorrect") })
|
|
44386
44407
|
] }),
|
|
44387
44408
|
/* @__PURE__ */ jsxRuntime.jsxs(Typography, { variant: "caption", className: "text-muted-foreground", children: [
|
|
44388
44409
|
t("simulator.target"),
|
|
44389
44410
|
": ",
|
|
44390
44411
|
targetValue,
|
|
44391
44412
|
" ",
|
|
44392
|
-
|
|
44413
|
+
resolved.outputUnit,
|
|
44393
44414
|
" (\xB1",
|
|
44394
44415
|
targetTolerance,
|
|
44395
44416
|
")"
|
|
44396
44417
|
] })
|
|
44397
44418
|
] }) }),
|
|
44398
|
-
showHint &&
|
|
44419
|
+
showHint && resolved.hint && /* @__PURE__ */ jsxRuntime.jsx(Card, { className: "p-4 border-l-4 border-l-warning", children: /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", children: resolved.hint }) }),
|
|
44399
44420
|
/* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "sm", justify: "center", children: [
|
|
44400
44421
|
!submitted ? /* @__PURE__ */ jsxRuntime.jsxs(Button, { variant: "primary", onClick: handleSubmit, children: [
|
|
44401
44422
|
/* @__PURE__ */ jsxRuntime.jsx(Icon, { icon: LucideIcons2.Play, size: "sm" }),
|
|
@@ -44975,13 +44996,14 @@ function StateArchitectBoard({
|
|
|
44975
44996
|
}) {
|
|
44976
44997
|
const { emit } = useEventBus();
|
|
44977
44998
|
const { t } = useTranslate();
|
|
44978
|
-
const
|
|
44999
|
+
const resolved = Array.isArray(entity) ? entity[0] : entity;
|
|
45000
|
+
const [transitions, setTransitions] = React86.useState(resolved?.transitions ?? []);
|
|
44979
45001
|
const [headerError, setHeaderError] = React86.useState(false);
|
|
44980
45002
|
const [playState, setPlayState] = React86.useState("editing");
|
|
44981
|
-
const [currentState, setCurrentState] = React86.useState(
|
|
45003
|
+
const [currentState, setCurrentState] = React86.useState(resolved?.initialState ?? "");
|
|
44982
45004
|
const [selectedState, setSelectedState] = React86.useState(null);
|
|
44983
45005
|
const [testResults, setTestResults] = React86.useState([]);
|
|
44984
|
-
const [variables, setVariables] = React86.useState(
|
|
45006
|
+
const [variables, setVariables] = React86.useState(resolved?.variables ?? []);
|
|
44985
45007
|
const [attempts, setAttempts] = React86.useState(0);
|
|
44986
45008
|
const timerRef = React86.useRef(null);
|
|
44987
45009
|
const [addingFrom, setAddingFrom] = React86.useState(null);
|
|
@@ -44990,12 +45012,12 @@ function StateArchitectBoard({
|
|
|
44990
45012
|
}, []);
|
|
44991
45013
|
const GRAPH_W = 500;
|
|
44992
45014
|
const GRAPH_H = 400;
|
|
44993
|
-
const positions = React86.useMemo(() => layoutStates(
|
|
45015
|
+
const positions = React86.useMemo(() => layoutStates(resolved?.states ?? [], GRAPH_W, GRAPH_H), [resolved?.states]);
|
|
44994
45016
|
const handleStateClick = React86.useCallback((state) => {
|
|
44995
45017
|
if (playState !== "editing") return;
|
|
44996
45018
|
if (addingFrom) {
|
|
44997
45019
|
if (addingFrom !== state) {
|
|
44998
|
-
const event =
|
|
45020
|
+
const event = resolved?.availableEvents[0] || "EVENT";
|
|
44999
45021
|
const newTrans = {
|
|
45000
45022
|
id: `t-${nextTransId++}`,
|
|
45001
45023
|
from: addingFrom,
|
|
@@ -45008,7 +45030,7 @@ function StateArchitectBoard({
|
|
|
45008
45030
|
} else {
|
|
45009
45031
|
setSelectedState(state);
|
|
45010
45032
|
}
|
|
45011
|
-
}, [playState, addingFrom,
|
|
45033
|
+
}, [playState, addingFrom, resolved?.availableEvents]);
|
|
45012
45034
|
const handleStartAddTransition = React86.useCallback(() => {
|
|
45013
45035
|
if (!selectedState) return;
|
|
45014
45036
|
setAddingFrom(selectedState);
|
|
@@ -45017,9 +45039,9 @@ function StateArchitectBoard({
|
|
|
45017
45039
|
setTransitions((prev) => prev.filter((t2) => t2.id !== transId));
|
|
45018
45040
|
}, []);
|
|
45019
45041
|
const machine = React86.useMemo(() => ({
|
|
45020
|
-
name:
|
|
45021
|
-
description:
|
|
45022
|
-
states:
|
|
45042
|
+
name: resolved?.entityName ?? "",
|
|
45043
|
+
description: resolved?.description ?? "",
|
|
45044
|
+
states: resolved?.states ?? [],
|
|
45023
45045
|
currentState,
|
|
45024
45046
|
transitions: transitions.map((t2) => ({
|
|
45025
45047
|
from: t2.from,
|
|
@@ -45027,7 +45049,7 @@ function StateArchitectBoard({
|
|
|
45027
45049
|
event: t2.event,
|
|
45028
45050
|
guardHint: t2.guardHint
|
|
45029
45051
|
}))
|
|
45030
|
-
}), [
|
|
45052
|
+
}), [resolved, currentState, transitions]);
|
|
45031
45053
|
const handleTest = React86.useCallback(() => {
|
|
45032
45054
|
if (playState !== "editing") return;
|
|
45033
45055
|
if (testEvent) emit(`UI:${testEvent}`, {});
|
|
@@ -45036,7 +45058,7 @@ function StateArchitectBoard({
|
|
|
45036
45058
|
const results = [];
|
|
45037
45059
|
let testIdx = 0;
|
|
45038
45060
|
const runNextTest = () => {
|
|
45039
|
-
if (testIdx >=
|
|
45061
|
+
if (testIdx >= (resolved?.testCases.length ?? 0)) {
|
|
45040
45062
|
const allPassed = results.every((r) => r.passed);
|
|
45041
45063
|
setPlayState(allPassed ? "success" : "fail");
|
|
45042
45064
|
setTestResults(results);
|
|
@@ -45051,8 +45073,9 @@ function StateArchitectBoard({
|
|
|
45051
45073
|
}
|
|
45052
45074
|
return;
|
|
45053
45075
|
}
|
|
45054
|
-
const testCase =
|
|
45055
|
-
|
|
45076
|
+
const testCase = resolved?.testCases[testIdx];
|
|
45077
|
+
if (!testCase) return;
|
|
45078
|
+
let state = resolved.initialState;
|
|
45056
45079
|
for (const event of testCase.events) {
|
|
45057
45080
|
const trans = transitions.find((t2) => t2.from === state && t2.event === event);
|
|
45058
45081
|
if (trans) {
|
|
@@ -45070,52 +45093,53 @@ function StateArchitectBoard({
|
|
|
45070
45093
|
timerRef.current = setTimeout(runNextTest, stepDurationMs);
|
|
45071
45094
|
};
|
|
45072
45095
|
timerRef.current = setTimeout(runNextTest, stepDurationMs);
|
|
45073
|
-
}, [playState, transitions,
|
|
45096
|
+
}, [playState, transitions, resolved, stepDurationMs, testEvent, completeEvent, emit]);
|
|
45074
45097
|
const handleTryAgain = React86.useCallback(() => {
|
|
45075
45098
|
if (timerRef.current) clearTimeout(timerRef.current);
|
|
45076
45099
|
setPlayState("editing");
|
|
45077
|
-
setCurrentState(
|
|
45100
|
+
setCurrentState(resolved?.initialState ?? "");
|
|
45078
45101
|
setTestResults([]);
|
|
45079
|
-
}, [
|
|
45102
|
+
}, [resolved?.initialState]);
|
|
45080
45103
|
const handleReset = React86.useCallback(() => {
|
|
45081
45104
|
if (timerRef.current) clearTimeout(timerRef.current);
|
|
45082
|
-
setTransitions(
|
|
45105
|
+
setTransitions(resolved?.transitions ?? []);
|
|
45083
45106
|
setPlayState("editing");
|
|
45084
|
-
setCurrentState(
|
|
45107
|
+
setCurrentState(resolved?.initialState ?? "");
|
|
45085
45108
|
setTestResults([]);
|
|
45086
|
-
setVariables(
|
|
45109
|
+
setVariables(resolved?.variables ?? []);
|
|
45087
45110
|
setSelectedState(null);
|
|
45088
45111
|
setAddingFrom(null);
|
|
45089
45112
|
setAttempts(0);
|
|
45090
|
-
}, [
|
|
45113
|
+
}, [resolved]);
|
|
45091
45114
|
const codeData = React86.useMemo(() => ({
|
|
45092
|
-
name:
|
|
45093
|
-
states:
|
|
45094
|
-
initialState:
|
|
45115
|
+
name: resolved?.entityName ?? "",
|
|
45116
|
+
states: resolved?.states ?? [],
|
|
45117
|
+
initialState: resolved?.initialState ?? "",
|
|
45095
45118
|
transitions: transitions.map((t2) => ({
|
|
45096
45119
|
from: t2.from,
|
|
45097
45120
|
to: t2.to,
|
|
45098
45121
|
event: t2.event,
|
|
45099
45122
|
...t2.guardHint ? { guard: t2.guardHint } : {}
|
|
45100
45123
|
}))
|
|
45101
|
-
}), [
|
|
45124
|
+
}), [resolved, transitions]);
|
|
45125
|
+
if (!resolved) return null;
|
|
45102
45126
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
45103
45127
|
VStack,
|
|
45104
45128
|
{
|
|
45105
45129
|
className: cn("p-4 gap-6", className),
|
|
45106
45130
|
style: {
|
|
45107
|
-
backgroundImage:
|
|
45131
|
+
backgroundImage: resolved.theme?.background ? `url(${resolved.theme.background})` : void 0,
|
|
45108
45132
|
backgroundSize: "cover",
|
|
45109
45133
|
backgroundPosition: "center"
|
|
45110
45134
|
},
|
|
45111
45135
|
children: [
|
|
45112
|
-
|
|
45136
|
+
resolved.headerImage && !headerError ? /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "w-full h-32 overflow-hidden rounded-container", children: /* @__PURE__ */ jsxRuntime.jsx("img", { src: resolved.headerImage, alt: "", onError: () => setHeaderError(true), className: "w-full h-full object-cover" }) }) : resolved.headerImage && headerError ? /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "w-full h-32 rounded-container bg-gradient-to-br from-muted to-accent opacity-60" }) : null,
|
|
45113
45137
|
/* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "xs", children: [
|
|
45114
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "h4", className: "text-foreground", children:
|
|
45115
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body2", className: "text-muted-foreground", children:
|
|
45138
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "h4", className: "text-foreground", children: resolved.title }),
|
|
45139
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body2", className: "text-muted-foreground", children: resolved.description }),
|
|
45116
45140
|
/* @__PURE__ */ jsxRuntime.jsxs(HStack, { className: "items-center p-2 rounded bg-warning/10 border border-warning/30", gap: "xs", children: [
|
|
45117
45141
|
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "caption", className: "text-warning font-bold", children: t("game.hint") + ":" }),
|
|
45118
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "caption", className: "text-foreground", children:
|
|
45142
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "caption", className: "text-foreground", children: resolved.hint })
|
|
45119
45143
|
] })
|
|
45120
45144
|
] }),
|
|
45121
45145
|
/* @__PURE__ */ jsxRuntime.jsxs(HStack, { className: "flex-wrap items-start", gap: "lg", children: [
|
|
@@ -45163,14 +45187,14 @@ function StateArchitectBoard({
|
|
|
45163
45187
|
]
|
|
45164
45188
|
}
|
|
45165
45189
|
),
|
|
45166
|
-
|
|
45190
|
+
resolved.states.map((state) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
45167
45191
|
StateNode2,
|
|
45168
45192
|
{
|
|
45169
45193
|
name: state,
|
|
45170
45194
|
position: positions[state],
|
|
45171
45195
|
isCurrent: state === currentState,
|
|
45172
45196
|
isSelected: state === selectedState,
|
|
45173
|
-
isInitial: state ===
|
|
45197
|
+
isInitial: state === resolved.initialState,
|
|
45174
45198
|
onClick: () => handleStateClick(state)
|
|
45175
45199
|
},
|
|
45176
45200
|
state
|
|
@@ -45217,7 +45241,7 @@ function StateArchitectBoard({
|
|
|
45217
45241
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
45218
45242
|
VariablePanel,
|
|
45219
45243
|
{
|
|
45220
|
-
entityName:
|
|
45244
|
+
entityName: resolved.entityName,
|
|
45221
45245
|
variables
|
|
45222
45246
|
}
|
|
45223
45247
|
),
|
|
@@ -45229,15 +45253,15 @@ function StateArchitectBoard({
|
|
|
45229
45253
|
!r.passed && /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "caption", className: "text-error", children: t("stateArchitect.gotState", { state: r.actualState }) })
|
|
45230
45254
|
] }, i))
|
|
45231
45255
|
] }),
|
|
45232
|
-
|
|
45256
|
+
resolved.showCodeView !== false && /* @__PURE__ */ jsxRuntime.jsx(CodeView, { data: codeData, label: "View Code" })
|
|
45233
45257
|
] })
|
|
45234
45258
|
] }),
|
|
45235
|
-
playState === "success" && /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "p-4 rounded-container bg-success/20 border border-success text-center", children: /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "h5", className: "text-success", children:
|
|
45259
|
+
playState === "success" && /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "p-4 rounded-container bg-success/20 border border-success text-center", children: /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "h5", className: "text-success", children: resolved.successMessage || t("stateArchitect.allPassed") }) }),
|
|
45236
45260
|
playState === "fail" && /* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "sm", children: [
|
|
45237
45261
|
/* @__PURE__ */ jsxRuntime.jsx(Box, { className: "p-4 rounded-container bg-warning/10 border border-warning/30 text-center", children: /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body1", className: "text-foreground font-medium", children: t(ENCOURAGEMENT_KEYS3[Math.min(attempts - 1, ENCOURAGEMENT_KEYS3.length - 1)] ?? ENCOURAGEMENT_KEYS3[0]) }) }),
|
|
45238
|
-
attempts >= 3 &&
|
|
45262
|
+
attempts >= 3 && resolved.hint && /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "p-3 rounded-container bg-accent/10 border border-accent/30", children: /* @__PURE__ */ jsxRuntime.jsxs(HStack, { className: "items-start", gap: "xs", children: [
|
|
45239
45263
|
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body2", className: "text-accent font-bold shrink-0", children: "\u{1F4A1} " + t("game.hint") + ":" }),
|
|
45240
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body2", className: "text-foreground", children:
|
|
45264
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body2", className: "text-foreground", children: resolved.hint })
|
|
45241
45265
|
] }) })
|
|
45242
45266
|
] }),
|
|
45243
45267
|
/* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "sm", children: [
|
|
@@ -46093,8 +46117,9 @@ var init_useBattleState = __esm({
|
|
|
46093
46117
|
}
|
|
46094
46118
|
});
|
|
46095
46119
|
function UncontrolledBattleBoard({ entity, ...rest }) {
|
|
46120
|
+
const resolved = Array.isArray(entity) ? entity[0] : entity;
|
|
46096
46121
|
const battleState = useBattleState(
|
|
46097
|
-
|
|
46122
|
+
resolved?.initialUnits ?? [],
|
|
46098
46123
|
{
|
|
46099
46124
|
tileClickEvent: rest.tileClickEvent,
|
|
46100
46125
|
unitClickEvent: rest.unitClickEvent,
|
|
@@ -46111,12 +46136,13 @@ function UncontrolledBattleBoard({ entity, ...rest }) {
|
|
|
46111
46136
|
calculateDamage: rest.calculateDamage
|
|
46112
46137
|
}
|
|
46113
46138
|
);
|
|
46139
|
+
if (!resolved) return null;
|
|
46114
46140
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
46115
46141
|
BattleBoard,
|
|
46116
46142
|
{
|
|
46117
46143
|
...rest,
|
|
46118
46144
|
entity: {
|
|
46119
|
-
...
|
|
46145
|
+
...resolved,
|
|
46120
46146
|
units: battleState.units,
|
|
46121
46147
|
phase: battleState.phase,
|
|
46122
46148
|
turn: battleState.turn,
|
|
@@ -46819,6 +46845,7 @@ var init_component_registry_generated = __esm({
|
|
|
46819
46845
|
init_StatsOrganism();
|
|
46820
46846
|
init_StatusDot();
|
|
46821
46847
|
init_StatusEffect();
|
|
46848
|
+
init_StepFlow();
|
|
46822
46849
|
init_StepFlowOrganism();
|
|
46823
46850
|
init_SvgBranch();
|
|
46824
46851
|
init_SvgConnection();
|
|
@@ -47137,6 +47164,7 @@ var init_component_registry_generated = __esm({
|
|
|
47137
47164
|
"StatsOrganism": StatsOrganism,
|
|
47138
47165
|
"StatusDot": StatusDot,
|
|
47139
47166
|
"StatusEffect": StatusEffect,
|
|
47167
|
+
"StepFlow": StepFlow,
|
|
47140
47168
|
"StepFlowOrganism": StepFlowOrganism,
|
|
47141
47169
|
"SvgBranch": SvgBranch,
|
|
47142
47170
|
"SvgConnection": SvgConnection,
|
|
@@ -47864,11 +47892,15 @@ function SlotContentRenderer({
|
|
|
47864
47892
|
}
|
|
47865
47893
|
if (propsSchema) {
|
|
47866
47894
|
for (const [propKey, propDef] of Object.entries(propsSchema)) {
|
|
47867
|
-
const
|
|
47868
|
-
if ((typeof v === "string" || typeof v === "number") && propDef.types?.some(
|
|
47895
|
+
const isDate = propDef.types?.some(
|
|
47869
47896
|
(t) => t === "date" || t === "datetime" || t === "timestamp"
|
|
47870
|
-
)
|
|
47897
|
+
);
|
|
47898
|
+
if (!isDate) continue;
|
|
47899
|
+
const v = renderedProps[propKey];
|
|
47900
|
+
if (typeof v === "string" || typeof v === "number") {
|
|
47871
47901
|
renderedProps[propKey] = new Date(v);
|
|
47902
|
+
} else if (v == null && propDef.required) {
|
|
47903
|
+
renderedProps[propKey] = /* @__PURE__ */ new Date();
|
|
47872
47904
|
}
|
|
47873
47905
|
}
|
|
47874
47906
|
}
|