@almadar/ui 5.17.0 → 5.17.1
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 +181 -153
- package/dist/avl/index.js +181 -153
- 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 +181 -153
- package/dist/components/index.js +181 -153
- 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 +181 -153
- package/dist/providers/index.js +181 -153
- package/dist/runtime/index.cjs +181 -153
- package/dist/runtime/index.js +181 -153
- package/package.json +1 -1
package/dist/avl/index.cjs
CHANGED
|
@@ -6516,11 +6516,13 @@ var init_Icon = __esm({
|
|
|
6516
6516
|
strokeWidth,
|
|
6517
6517
|
style
|
|
6518
6518
|
}) => {
|
|
6519
|
+
const directIcon = typeof icon === "string" ? void 0 : icon;
|
|
6520
|
+
const effectiveName = typeof icon === "string" ? icon : name;
|
|
6519
6521
|
const family = useIconFamily();
|
|
6520
6522
|
const RenderedComponent = React98__namespace.default.useMemo(() => {
|
|
6521
|
-
if (
|
|
6522
|
-
return
|
|
6523
|
-
}, [
|
|
6523
|
+
if (directIcon) return null;
|
|
6524
|
+
return effectiveName ? resolveIconForFamily(effectiveName, family) : null;
|
|
6525
|
+
}, [directIcon, effectiveName, family]);
|
|
6524
6526
|
const effectiveStrokeWidth = strokeWidth ?? void 0;
|
|
6525
6527
|
const inlineStyle = {
|
|
6526
6528
|
...effectiveStrokeWidth === void 0 ? { strokeWidth: "var(--icon-stroke-width, 2)" } : {},
|
|
@@ -6532,8 +6534,8 @@ var init_Icon = __esm({
|
|
|
6532
6534
|
color ? color : "text-current",
|
|
6533
6535
|
className
|
|
6534
6536
|
);
|
|
6535
|
-
if (
|
|
6536
|
-
const Direct =
|
|
6537
|
+
if (directIcon) {
|
|
6538
|
+
const Direct = directIcon;
|
|
6537
6539
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
6538
6540
|
Direct,
|
|
6539
6541
|
{
|
|
@@ -8245,7 +8247,7 @@ var init_Input = __esm({
|
|
|
8245
8247
|
error,
|
|
8246
8248
|
leftIcon,
|
|
8247
8249
|
rightIcon,
|
|
8248
|
-
icon:
|
|
8250
|
+
icon: iconProp,
|
|
8249
8251
|
clearable,
|
|
8250
8252
|
onClear,
|
|
8251
8253
|
value,
|
|
@@ -8255,6 +8257,7 @@ var init_Input = __esm({
|
|
|
8255
8257
|
...props
|
|
8256
8258
|
}, ref) => {
|
|
8257
8259
|
const type = inputType || htmlType || "text";
|
|
8260
|
+
const IconComponent = typeof iconProp === "string" ? resolveIcon(iconProp) : iconProp;
|
|
8258
8261
|
const resolvedLeftIcon = leftIcon || IconComponent && /* @__PURE__ */ jsxRuntime.jsx(IconComponent, { className: "h-icon-default w-icon-default" });
|
|
8259
8262
|
const showClearButton = clearable && value && String(value).length > 0;
|
|
8260
8263
|
const isMultiline = type === "textarea";
|
|
@@ -8802,7 +8805,7 @@ var init_Avatar = __esm({
|
|
|
8802
8805
|
alt,
|
|
8803
8806
|
name,
|
|
8804
8807
|
initials: providedInitials,
|
|
8805
|
-
icon:
|
|
8808
|
+
icon: iconProp,
|
|
8806
8809
|
size = "md",
|
|
8807
8810
|
status,
|
|
8808
8811
|
badge,
|
|
@@ -8813,6 +8816,7 @@ var init_Avatar = __esm({
|
|
|
8813
8816
|
}) => {
|
|
8814
8817
|
const eventBus = useEventBus();
|
|
8815
8818
|
const initials = providedInitials ?? (name ? generateInitials(name) : void 0);
|
|
8819
|
+
const IconComponent = typeof iconProp === "string" ? resolveIcon(iconProp) : iconProp;
|
|
8816
8820
|
const hasImage = !!src;
|
|
8817
8821
|
const hasInitials = !!initials;
|
|
8818
8822
|
const hasIcon = !!IconComponent;
|
|
@@ -18800,6 +18804,7 @@ var init_StateMachineView = __esm({
|
|
|
18800
18804
|
setTooltip((prev) => ({ ...prev, pinned: false, visible: false }));
|
|
18801
18805
|
}, []);
|
|
18802
18806
|
useEventListener("UI:TOOLTIP_CLOSE", handleCloseTooltip);
|
|
18807
|
+
if (!layoutData) return null;
|
|
18803
18808
|
const { width, height, title, states, labels, entity, outputs, config } = layoutData;
|
|
18804
18809
|
const bundles = React98.useMemo(() => {
|
|
18805
18810
|
const bundleMap = {};
|
|
@@ -21144,13 +21149,14 @@ function BuilderBoard({
|
|
|
21144
21149
|
}) {
|
|
21145
21150
|
const { emit } = useEventBus();
|
|
21146
21151
|
const { t } = useTranslate();
|
|
21152
|
+
const resolved = Array.isArray(entity) ? entity[0] : entity;
|
|
21147
21153
|
const [placements, setPlacements] = React98.useState({});
|
|
21148
21154
|
const [headerError, setHeaderError] = React98.useState(false);
|
|
21149
21155
|
const [submitted, setSubmitted] = React98.useState(false);
|
|
21150
21156
|
const [attempts, setAttempts] = React98.useState(0);
|
|
21151
21157
|
const [showHint, setShowHint] = React98.useState(false);
|
|
21152
|
-
const components =
|
|
21153
|
-
const slots =
|
|
21158
|
+
const components = resolved?.components ?? [];
|
|
21159
|
+
const slots = resolved?.slots ?? [];
|
|
21154
21160
|
const usedComponentIds = new Set(Object.values(placements));
|
|
21155
21161
|
const availableComponents = components.filter((c) => !usedComponentIds.has(c.id));
|
|
21156
21162
|
const [selectedComponent, setSelectedComponent] = React98.useState(null);
|
|
@@ -21184,7 +21190,7 @@ function BuilderBoard({
|
|
|
21184
21190
|
}, [slots, placements, attempts, completeEvent, emit]);
|
|
21185
21191
|
const handleReset = () => {
|
|
21186
21192
|
setSubmitted(false);
|
|
21187
|
-
if (attempts >= 2 &&
|
|
21193
|
+
if (attempts >= 2 && resolved?.hint) {
|
|
21188
21194
|
setShowHint(true);
|
|
21189
21195
|
}
|
|
21190
21196
|
};
|
|
@@ -21196,20 +21202,21 @@ function BuilderBoard({
|
|
|
21196
21202
|
setShowHint(false);
|
|
21197
21203
|
};
|
|
21198
21204
|
const getComponentById = (id) => components.find((c) => c.id === id);
|
|
21205
|
+
if (!resolved) return null;
|
|
21199
21206
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
21200
21207
|
Box,
|
|
21201
21208
|
{
|
|
21202
21209
|
className,
|
|
21203
21210
|
style: {
|
|
21204
|
-
backgroundImage:
|
|
21211
|
+
backgroundImage: resolved.theme?.background ? `url(${resolved.theme.background})` : void 0,
|
|
21205
21212
|
backgroundSize: "cover",
|
|
21206
21213
|
backgroundPosition: "center"
|
|
21207
21214
|
},
|
|
21208
21215
|
children: /* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "lg", className: "p-4", children: [
|
|
21209
|
-
|
|
21216
|
+
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,
|
|
21210
21217
|
/* @__PURE__ */ jsxRuntime.jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "sm", children: [
|
|
21211
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "h4", weight: "bold", children:
|
|
21212
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", children:
|
|
21218
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "h4", weight: "bold", children: resolved.title }),
|
|
21219
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", children: resolved.description })
|
|
21213
21220
|
] }) }),
|
|
21214
21221
|
/* @__PURE__ */ jsxRuntime.jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "sm", children: [
|
|
21215
21222
|
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", weight: "bold", className: "uppercase tracking-wider text-muted-foreground", children: t("builder.components") }),
|
|
@@ -21269,9 +21276,9 @@ function BuilderBoard({
|
|
|
21269
21276
|
] }) }),
|
|
21270
21277
|
submitted && /* @__PURE__ */ jsxRuntime.jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "sm", align: "center", children: [
|
|
21271
21278
|
/* @__PURE__ */ jsxRuntime.jsx(Icon, { icon: allCorrect ? LucideIcons2.CheckCircle : LucideIcons2.XCircle, size: "lg", className: allCorrect ? "text-success" : "text-error" }),
|
|
21272
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", weight: "bold", children: allCorrect ?
|
|
21279
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", weight: "bold", children: allCorrect ? resolved.successMessage ?? t("builder.success") : resolved.failMessage ?? t("builder.incorrect") })
|
|
21273
21280
|
] }) }),
|
|
21274
|
-
showHint &&
|
|
21281
|
+
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 }) }),
|
|
21275
21282
|
/* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "sm", justify: "center", children: [
|
|
21276
21283
|
!submitted ? /* @__PURE__ */ jsxRuntime.jsxs(Button, { variant: "primary", onClick: handleSubmit, disabled: !allPlaced, children: [
|
|
21277
21284
|
/* @__PURE__ */ jsxRuntime.jsx(Icon, { icon: LucideIcons2.Wrench, size: "sm" }),
|
|
@@ -23812,11 +23819,12 @@ function CastleBoard({
|
|
|
23812
23819
|
className
|
|
23813
23820
|
}) {
|
|
23814
23821
|
const eventBus = useEventBus();
|
|
23815
|
-
const
|
|
23816
|
-
const
|
|
23817
|
-
const
|
|
23818
|
-
const
|
|
23819
|
-
const
|
|
23822
|
+
const resolved = Array.isArray(entity) ? entity[0] : entity;
|
|
23823
|
+
const tiles = resolved?.tiles ?? [];
|
|
23824
|
+
const features = resolved?.features ?? [];
|
|
23825
|
+
const units = resolved?.units ?? [];
|
|
23826
|
+
const assetManifest = resolved?.assetManifest;
|
|
23827
|
+
const backgroundImage = resolved?.backgroundImage;
|
|
23820
23828
|
const [hoveredTile, setHoveredTile] = React98.useState(null);
|
|
23821
23829
|
const [selectedFeature, setSelectedFeature] = React98.useState(null);
|
|
23822
23830
|
const hoveredFeature = React98.useMemo(() => {
|
|
@@ -24721,13 +24729,14 @@ function ClassifierBoard({
|
|
|
24721
24729
|
}) {
|
|
24722
24730
|
const { emit } = useEventBus();
|
|
24723
24731
|
const { t } = useTranslate();
|
|
24732
|
+
const resolved = Array.isArray(entity) ? entity[0] : entity;
|
|
24724
24733
|
const [assignments, setAssignments] = React98.useState({});
|
|
24725
24734
|
const [headerError, setHeaderError] = React98.useState(false);
|
|
24726
24735
|
const [submitted, setSubmitted] = React98.useState(false);
|
|
24727
24736
|
const [attempts, setAttempts] = React98.useState(0);
|
|
24728
24737
|
const [showHint, setShowHint] = React98.useState(false);
|
|
24729
|
-
const items =
|
|
24730
|
-
const categories =
|
|
24738
|
+
const items = resolved?.items ?? [];
|
|
24739
|
+
const categories = resolved?.categories ?? [];
|
|
24731
24740
|
const unassignedItems = items.filter((item) => !assignments[item.id]);
|
|
24732
24741
|
const allAssigned = Object.keys(assignments).length === items.length;
|
|
24733
24742
|
const results = submitted ? items.map((item) => ({
|
|
@@ -24759,7 +24768,7 @@ function ClassifierBoard({
|
|
|
24759
24768
|
}, [items, assignments, attempts, completeEvent, emit]);
|
|
24760
24769
|
const handleReset = () => {
|
|
24761
24770
|
setSubmitted(false);
|
|
24762
|
-
if (attempts >= 2 &&
|
|
24771
|
+
if (attempts >= 2 && resolved?.hint) {
|
|
24763
24772
|
setShowHint(true);
|
|
24764
24773
|
}
|
|
24765
24774
|
};
|
|
@@ -24769,20 +24778,21 @@ function ClassifierBoard({
|
|
|
24769
24778
|
setAttempts(0);
|
|
24770
24779
|
setShowHint(false);
|
|
24771
24780
|
};
|
|
24781
|
+
if (!resolved) return null;
|
|
24772
24782
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
24773
24783
|
Box,
|
|
24774
24784
|
{
|
|
24775
24785
|
className,
|
|
24776
24786
|
style: {
|
|
24777
|
-
backgroundImage:
|
|
24787
|
+
backgroundImage: resolved.theme?.background ? `url(${resolved.theme.background})` : void 0,
|
|
24778
24788
|
backgroundSize: "cover",
|
|
24779
24789
|
backgroundPosition: "center"
|
|
24780
24790
|
},
|
|
24781
24791
|
children: /* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "lg", className: "p-4", children: [
|
|
24782
|
-
|
|
24792
|
+
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,
|
|
24783
24793
|
/* @__PURE__ */ jsxRuntime.jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "sm", children: [
|
|
24784
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "h4", weight: "bold", children:
|
|
24785
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", children:
|
|
24794
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "h4", weight: "bold", children: resolved.title }),
|
|
24795
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", children: resolved.description })
|
|
24786
24796
|
] }) }),
|
|
24787
24797
|
unassignedItems.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "sm", children: [
|
|
24788
24798
|
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", weight: "bold", className: "uppercase tracking-wider text-muted-foreground", children: t("classifier.itemsToSort") }),
|
|
@@ -24834,10 +24844,10 @@ function ClassifierBoard({
|
|
|
24834
24844
|
}) }),
|
|
24835
24845
|
submitted && /* @__PURE__ */ jsxRuntime.jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "sm", align: "center", children: [
|
|
24836
24846
|
/* @__PURE__ */ jsxRuntime.jsx(Icon, { icon: allCorrect ? LucideIcons2.CheckCircle : LucideIcons2.XCircle, size: "lg", className: allCorrect ? "text-success" : "text-error" }),
|
|
24837
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", weight: "bold", children: allCorrect ?
|
|
24838
|
-
!allCorrect &&
|
|
24847
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", weight: "bold", children: allCorrect ? resolved.successMessage ?? t("classifier.allCorrect") : `${correctCount}/${items.length} ${t("classifier.correct")}` }),
|
|
24848
|
+
!allCorrect && resolved.failMessage && /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", className: "text-muted-foreground", children: resolved.failMessage })
|
|
24839
24849
|
] }) }),
|
|
24840
|
-
showHint &&
|
|
24850
|
+
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 }) }),
|
|
24841
24851
|
/* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "sm", justify: "center", children: [
|
|
24842
24852
|
!submitted ? /* @__PURE__ */ jsxRuntime.jsxs(Button, { variant: "primary", onClick: handleSubmit, disabled: !allAssigned, children: [
|
|
24843
24853
|
/* @__PURE__ */ jsxRuntime.jsx(Icon, { icon: LucideIcons2.Send, size: "sm" }),
|
|
@@ -36172,7 +36182,7 @@ var init_OptionConstraintGroup = __esm({
|
|
|
36172
36182
|
title,
|
|
36173
36183
|
description,
|
|
36174
36184
|
options,
|
|
36175
|
-
constraint,
|
|
36185
|
+
constraint = { type: "single" },
|
|
36176
36186
|
selected = [],
|
|
36177
36187
|
onChange,
|
|
36178
36188
|
changeEvent,
|
|
@@ -38907,7 +38917,7 @@ function DataTable({
|
|
|
38907
38917
|
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
38908
38918
|
EmptyState,
|
|
38909
38919
|
{
|
|
38910
|
-
icon: emptyIcon,
|
|
38920
|
+
icon: typeof emptyIcon === "string" ? resolveIcon(emptyIcon) : emptyIcon,
|
|
38911
38921
|
title: resolvedEmptyTitle,
|
|
38912
38922
|
description: resolvedEmptyDescription,
|
|
38913
38923
|
actionLabel: emptyAction?.label,
|
|
@@ -39036,6 +39046,7 @@ var init_DataTable = __esm({
|
|
|
39036
39046
|
init_Stack();
|
|
39037
39047
|
init_Typography();
|
|
39038
39048
|
init_molecules();
|
|
39049
|
+
init_Icon();
|
|
39039
39050
|
init_useEventBus();
|
|
39040
39051
|
init_useTranslate();
|
|
39041
39052
|
init_types3();
|
|
@@ -39056,6 +39067,7 @@ function DebuggerBoard({
|
|
|
39056
39067
|
}) {
|
|
39057
39068
|
const { emit } = useEventBus();
|
|
39058
39069
|
const { t } = useTranslate();
|
|
39070
|
+
const resolved = Array.isArray(entity) ? entity[0] : entity;
|
|
39059
39071
|
const [flaggedLines, setFlaggedLines] = React98.useState(/* @__PURE__ */ new Set());
|
|
39060
39072
|
const [headerError, setHeaderError] = React98.useState(false);
|
|
39061
39073
|
const [submitted, setSubmitted] = React98.useState(false);
|
|
@@ -39073,7 +39085,7 @@ function DebuggerBoard({
|
|
|
39073
39085
|
return next;
|
|
39074
39086
|
});
|
|
39075
39087
|
};
|
|
39076
|
-
const lines =
|
|
39088
|
+
const lines = resolved?.lines ?? [];
|
|
39077
39089
|
const bugLines = lines.filter((l) => l.isBug);
|
|
39078
39090
|
const correctFlags = lines.filter((l) => l.isBug && flaggedLines.has(l.id));
|
|
39079
39091
|
const falseFlags = lines.filter((l) => !l.isBug && flaggedLines.has(l.id));
|
|
@@ -39088,7 +39100,7 @@ function DebuggerBoard({
|
|
|
39088
39100
|
}, [correctFlags.length, bugLines.length, falseFlags.length, attempts, completeEvent, emit]);
|
|
39089
39101
|
const handleReset = () => {
|
|
39090
39102
|
setSubmitted(false);
|
|
39091
|
-
if (attempts >= 2 &&
|
|
39103
|
+
if (attempts >= 2 && resolved?.hint) {
|
|
39092
39104
|
setShowHint(true);
|
|
39093
39105
|
}
|
|
39094
39106
|
};
|
|
@@ -39098,24 +39110,25 @@ function DebuggerBoard({
|
|
|
39098
39110
|
setAttempts(0);
|
|
39099
39111
|
setShowHint(false);
|
|
39100
39112
|
};
|
|
39113
|
+
if (!resolved) return null;
|
|
39101
39114
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
39102
39115
|
Box,
|
|
39103
39116
|
{
|
|
39104
39117
|
className,
|
|
39105
39118
|
style: {
|
|
39106
|
-
backgroundImage:
|
|
39119
|
+
backgroundImage: resolved.theme?.background ? `url(${resolved.theme.background})` : void 0,
|
|
39107
39120
|
backgroundSize: "cover",
|
|
39108
39121
|
backgroundPosition: "center"
|
|
39109
39122
|
},
|
|
39110
39123
|
children: /* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "lg", className: "p-4", children: [
|
|
39111
|
-
|
|
39124
|
+
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,
|
|
39112
39125
|
/* @__PURE__ */ jsxRuntime.jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "sm", children: [
|
|
39113
39126
|
/* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "xs", align: "center", children: [
|
|
39114
39127
|
/* @__PURE__ */ jsxRuntime.jsx(Icon, { icon: LucideIcons2.Bug, size: "sm" }),
|
|
39115
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "h4", weight: "bold", children:
|
|
39128
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "h4", weight: "bold", children: resolved.title })
|
|
39116
39129
|
] }),
|
|
39117
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", children:
|
|
39118
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "caption", className: "text-muted-foreground", children: t("debugger.findBugs", { count: String(
|
|
39130
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", children: resolved.description }),
|
|
39131
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "caption", className: "text-muted-foreground", children: t("debugger.findBugs", { count: String(resolved.bugCount) }) })
|
|
39119
39132
|
] }) }),
|
|
39120
39133
|
/* @__PURE__ */ jsxRuntime.jsx(Card, { className: "p-0 overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx(VStack, { gap: "none", children: lines.map((line, i) => {
|
|
39121
39134
|
const isFlagged = flaggedLines.has(line.id);
|
|
@@ -39147,7 +39160,7 @@ function DebuggerBoard({
|
|
|
39147
39160
|
);
|
|
39148
39161
|
}) }) }),
|
|
39149
39162
|
submitted && /* @__PURE__ */ jsxRuntime.jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "sm", children: [
|
|
39150
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", weight: "bold", children: allCorrect ?
|
|
39163
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", weight: "bold", children: allCorrect ? resolved.successMessage ?? t("debugger.allFound") : `${correctFlags.length}/${bugLines.length} ${t("debugger.bugsFound")}` }),
|
|
39151
39164
|
bugLines.map((line) => /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "xs", align: "start", children: [
|
|
39152
39165
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
39153
39166
|
Icon,
|
|
@@ -39163,7 +39176,7 @@ function DebuggerBoard({
|
|
|
39163
39176
|
] })
|
|
39164
39177
|
] }, line.id))
|
|
39165
39178
|
] }) }),
|
|
39166
|
-
showHint &&
|
|
39179
|
+
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 }) }),
|
|
39167
39180
|
/* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "sm", justify: "center", children: [
|
|
39168
39181
|
!submitted ? /* @__PURE__ */ jsxRuntime.jsxs(Button, { variant: "primary", onClick: handleSubmit, disabled: flaggedLines.size === 0, children: [
|
|
39169
39182
|
/* @__PURE__ */ jsxRuntime.jsx(Icon, { icon: LucideIcons2.Send, size: "sm" }),
|
|
@@ -40295,7 +40308,8 @@ function EventHandlerBoard({
|
|
|
40295
40308
|
}) {
|
|
40296
40309
|
const { emit } = useEventBus();
|
|
40297
40310
|
const { t } = useTranslate();
|
|
40298
|
-
const
|
|
40311
|
+
const resolved = Array.isArray(entity) ? entity[0] : entity;
|
|
40312
|
+
const entityObjects = resolved?.objects ?? [];
|
|
40299
40313
|
const [objects, setObjects] = React98.useState(entityObjects);
|
|
40300
40314
|
const [selectedObjectId, setSelectedObjectId] = React98.useState(
|
|
40301
40315
|
entityObjects[0]?.id || null
|
|
@@ -40330,7 +40344,7 @@ function EventHandlerBoard({
|
|
|
40330
40344
|
allRules.push({ object: obj, rule });
|
|
40331
40345
|
});
|
|
40332
40346
|
});
|
|
40333
|
-
const triggers =
|
|
40347
|
+
const triggers = resolved?.triggerEvents || [];
|
|
40334
40348
|
const eventQueue = [...triggers];
|
|
40335
40349
|
const firedEvents = /* @__PURE__ */ new Set();
|
|
40336
40350
|
let stepIdx = 0;
|
|
@@ -40361,12 +40375,12 @@ function EventHandlerBoard({
|
|
|
40361
40375
|
matching.forEach(({ object, rule }) => {
|
|
40362
40376
|
addLogEntry(object.icon, t("eventHandler.heardEvent", { object: object.name, event: currentEvent, action: rule.thenAction }), "done");
|
|
40363
40377
|
eventQueue.push(rule.thenAction);
|
|
40364
|
-
if (rule.thenAction ===
|
|
40378
|
+
if (rule.thenAction === resolved?.goalEvent) {
|
|
40365
40379
|
goalReached = true;
|
|
40366
40380
|
}
|
|
40367
40381
|
});
|
|
40368
40382
|
}
|
|
40369
|
-
if (currentEvent ===
|
|
40383
|
+
if (currentEvent === resolved?.goalEvent) {
|
|
40370
40384
|
goalReached = true;
|
|
40371
40385
|
}
|
|
40372
40386
|
stepIdx++;
|
|
@@ -40376,7 +40390,7 @@ function EventHandlerBoard({
|
|
|
40376
40390
|
addLogEntry("\u{1F3AC}", t("eventHandler.simulationStarted", { events: triggers.join(", ") }), "active");
|
|
40377
40391
|
}
|
|
40378
40392
|
timerRef.current = setTimeout(processNext, stepDurationMs);
|
|
40379
|
-
}, [playState, objects,
|
|
40393
|
+
}, [playState, objects, resolved, stepDurationMs, playEvent, completeEvent, emit, addLogEntry, t]);
|
|
40380
40394
|
const handleTryAgain = React98.useCallback(() => {
|
|
40381
40395
|
if (timerRef.current) clearTimeout(timerRef.current);
|
|
40382
40396
|
setPlayState("editing");
|
|
@@ -40384,12 +40398,13 @@ function EventHandlerBoard({
|
|
|
40384
40398
|
}, []);
|
|
40385
40399
|
const handleReset = React98.useCallback(() => {
|
|
40386
40400
|
if (timerRef.current) clearTimeout(timerRef.current);
|
|
40387
|
-
setObjects(
|
|
40401
|
+
setObjects(resolved?.objects ?? []);
|
|
40388
40402
|
setPlayState("editing");
|
|
40389
40403
|
setEventLog([]);
|
|
40390
|
-
setSelectedObjectId((
|
|
40404
|
+
setSelectedObjectId((resolved?.objects ?? [])[0]?.id || null);
|
|
40391
40405
|
setAttempts(0);
|
|
40392
|
-
}, [
|
|
40406
|
+
}, [resolved?.objects]);
|
|
40407
|
+
if (!resolved) return null;
|
|
40393
40408
|
const objectViewers = objects.map((obj) => {
|
|
40394
40409
|
const machine = {
|
|
40395
40410
|
name: obj.name,
|
|
@@ -40403,25 +40418,25 @@ function EventHandlerBoard({
|
|
|
40403
40418
|
};
|
|
40404
40419
|
return { obj, machine };
|
|
40405
40420
|
});
|
|
40406
|
-
const showHint = attempts >= 3 &&
|
|
40421
|
+
const showHint = attempts >= 3 && resolved.hint;
|
|
40407
40422
|
const encourageKey = ENCOURAGEMENT_KEYS[Math.min(attempts - 1, ENCOURAGEMENT_KEYS.length - 1)] ?? ENCOURAGEMENT_KEYS[0];
|
|
40408
40423
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
40409
40424
|
VStack,
|
|
40410
40425
|
{
|
|
40411
40426
|
className: cn("p-4 gap-6", className),
|
|
40412
40427
|
style: {
|
|
40413
|
-
backgroundImage:
|
|
40428
|
+
backgroundImage: resolved.theme?.background ? `url(${resolved.theme.background})` : void 0,
|
|
40414
40429
|
backgroundSize: "cover",
|
|
40415
40430
|
backgroundPosition: "center"
|
|
40416
40431
|
},
|
|
40417
40432
|
children: [
|
|
40418
|
-
|
|
40433
|
+
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,
|
|
40419
40434
|
/* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "xs", children: [
|
|
40420
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "h4", className: "text-foreground", children:
|
|
40421
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body2", className: "text-muted-foreground", children:
|
|
40435
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "h4", className: "text-foreground", children: resolved.title }),
|
|
40436
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body2", className: "text-muted-foreground", children: resolved.description }),
|
|
40422
40437
|
/* @__PURE__ */ jsxRuntime.jsxs(HStack, { className: "items-center p-2 rounded bg-primary/10 border border-primary/30", gap: "xs", children: [
|
|
40423
40438
|
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "caption", className: "text-primary font-bold", children: t("game.goal") + ":" }),
|
|
40424
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "caption", className: "text-foreground", children:
|
|
40439
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "caption", className: "text-foreground", children: resolved.goalCondition })
|
|
40425
40440
|
] })
|
|
40426
40441
|
] }),
|
|
40427
40442
|
/* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "sm", children: [
|
|
@@ -40452,12 +40467,12 @@ function EventHandlerBoard({
|
|
|
40452
40467
|
}
|
|
40453
40468
|
),
|
|
40454
40469
|
eventLog.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(EventLog, { entries: eventLog }),
|
|
40455
|
-
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:
|
|
40470
|
+
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") }) }),
|
|
40456
40471
|
playState === "fail" && /* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "sm", children: [
|
|
40457
40472
|
/* @__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) }) }),
|
|
40458
40473
|
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: [
|
|
40459
40474
|
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body2", className: "text-accent font-bold shrink-0", children: "\u{1F4A1} " + t("game.hint") + ":" }),
|
|
40460
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body2", className: "text-foreground", children:
|
|
40475
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body2", className: "text-foreground", children: resolved.hint })
|
|
40461
40476
|
] }) })
|
|
40462
40477
|
] }),
|
|
40463
40478
|
/* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "sm", children: [
|
|
@@ -43578,19 +43593,20 @@ function NegotiatorBoard({
|
|
|
43578
43593
|
}) {
|
|
43579
43594
|
const { emit } = useEventBus();
|
|
43580
43595
|
const { t } = useTranslate();
|
|
43596
|
+
const resolved = Array.isArray(entity) ? entity[0] : entity;
|
|
43581
43597
|
const [history, setHistory] = React98.useState([]);
|
|
43582
43598
|
const [headerError, setHeaderError] = React98.useState(false);
|
|
43583
43599
|
const [showHint, setShowHint] = React98.useState(false);
|
|
43584
43600
|
const currentRound = history.length;
|
|
43585
|
-
const isComplete = currentRound >=
|
|
43601
|
+
const isComplete = currentRound >= (resolved?.totalRounds ?? 0);
|
|
43586
43602
|
const playerTotal = history.reduce((s, r2) => s + r2.playerPayoff, 0);
|
|
43587
43603
|
const opponentTotal = history.reduce((s, r2) => s + r2.opponentPayoff, 0);
|
|
43588
|
-
const won = isComplete && playerTotal >=
|
|
43589
|
-
const actions =
|
|
43590
|
-
const payoffMatrix =
|
|
43604
|
+
const won = isComplete && playerTotal >= (resolved?.targetScore ?? 0);
|
|
43605
|
+
const actions = resolved?.actions ?? [];
|
|
43606
|
+
const payoffMatrix = resolved?.payoffMatrix ?? [];
|
|
43591
43607
|
const handleAction = React98.useCallback((actionId) => {
|
|
43592
43608
|
if (isComplete) return;
|
|
43593
|
-
const opponentAction = getOpponentAction(
|
|
43609
|
+
const opponentAction = getOpponentAction(resolved?.opponentStrategy ?? "random", actions, history);
|
|
43594
43610
|
const payoff = payoffMatrix.find(
|
|
43595
43611
|
(p2) => p2.playerAction === actionId && p2.opponentAction === opponentAction
|
|
43596
43612
|
);
|
|
@@ -43603,41 +43619,42 @@ function NegotiatorBoard({
|
|
|
43603
43619
|
};
|
|
43604
43620
|
const newHistory = [...history, result];
|
|
43605
43621
|
setHistory(newHistory);
|
|
43606
|
-
if (newHistory.length >=
|
|
43622
|
+
if (newHistory.length >= (resolved?.totalRounds ?? 0)) {
|
|
43607
43623
|
const total = newHistory.reduce((s, r2) => s + r2.playerPayoff, 0);
|
|
43608
|
-
if (total >=
|
|
43624
|
+
if (total >= (resolved?.targetScore ?? 0)) {
|
|
43609
43625
|
emit(`UI:${completeEvent}`, { success: true, score: total });
|
|
43610
43626
|
}
|
|
43611
|
-
if (newHistory.length >= 3 &&
|
|
43627
|
+
if (newHistory.length >= 3 && resolved?.hint) {
|
|
43612
43628
|
setShowHint(true);
|
|
43613
43629
|
}
|
|
43614
43630
|
}
|
|
43615
|
-
}, [isComplete,
|
|
43631
|
+
}, [isComplete, resolved, actions, payoffMatrix, history, currentRound, completeEvent, emit]);
|
|
43616
43632
|
const handleReset = () => {
|
|
43617
43633
|
setHistory([]);
|
|
43618
43634
|
setShowHint(false);
|
|
43619
43635
|
};
|
|
43620
43636
|
const getActionLabel = (id) => actions.find((a) => a.id === id)?.label ?? id;
|
|
43637
|
+
if (!resolved) return null;
|
|
43621
43638
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
43622
43639
|
Box,
|
|
43623
43640
|
{
|
|
43624
43641
|
className,
|
|
43625
43642
|
style: {
|
|
43626
|
-
backgroundImage:
|
|
43643
|
+
backgroundImage: resolved.theme?.background ? `url(${resolved.theme.background})` : void 0,
|
|
43627
43644
|
backgroundSize: "cover",
|
|
43628
43645
|
backgroundPosition: "center"
|
|
43629
43646
|
},
|
|
43630
43647
|
children: /* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "lg", className: "p-4", children: [
|
|
43631
|
-
|
|
43648
|
+
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,
|
|
43632
43649
|
/* @__PURE__ */ jsxRuntime.jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "sm", children: [
|
|
43633
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "h4", weight: "bold", children:
|
|
43634
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", children:
|
|
43650
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "h4", weight: "bold", children: resolved.title }),
|
|
43651
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", children: resolved.description }),
|
|
43635
43652
|
/* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "md", children: [
|
|
43636
|
-
/* @__PURE__ */ jsxRuntime.jsx(Badge, { size: "sm", children: t("negotiator.round", { current: String(currentRound), total: String(
|
|
43653
|
+
/* @__PURE__ */ jsxRuntime.jsx(Badge, { size: "sm", children: t("negotiator.round", { current: String(currentRound), total: String(resolved.totalRounds) }) }),
|
|
43637
43654
|
/* @__PURE__ */ jsxRuntime.jsxs(Badge, { size: "sm", children: [
|
|
43638
43655
|
t("negotiator.target"),
|
|
43639
43656
|
": ",
|
|
43640
|
-
|
|
43657
|
+
resolved.targetScore
|
|
43641
43658
|
] })
|
|
43642
43659
|
] })
|
|
43643
43660
|
] }) }),
|
|
@@ -43686,16 +43703,16 @@ function NegotiatorBoard({
|
|
|
43686
43703
|
] }) }),
|
|
43687
43704
|
isComplete && /* @__PURE__ */ jsxRuntime.jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "sm", align: "center", children: [
|
|
43688
43705
|
/* @__PURE__ */ jsxRuntime.jsx(Icon, { icon: LucideIcons2.CheckCircle, size: "lg", className: won ? "text-success" : "text-error" }),
|
|
43689
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", weight: "bold", children: won ?
|
|
43706
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", weight: "bold", children: won ? resolved.successMessage ?? t("negotiator.success") : resolved.failMessage ?? t("negotiator.failed") }),
|
|
43690
43707
|
/* @__PURE__ */ jsxRuntime.jsxs(Typography, { variant: "caption", className: "text-muted-foreground", children: [
|
|
43691
43708
|
t("negotiator.finalScore"),
|
|
43692
43709
|
": ",
|
|
43693
43710
|
playerTotal,
|
|
43694
43711
|
"/",
|
|
43695
|
-
|
|
43712
|
+
resolved.targetScore
|
|
43696
43713
|
] })
|
|
43697
43714
|
] }) }),
|
|
43698
|
-
showHint &&
|
|
43715
|
+
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 }) }),
|
|
43699
43716
|
isComplete && !won && /* @__PURE__ */ jsxRuntime.jsx(HStack, { justify: "center", children: /* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "primary", onClick: handleReset, children: t("negotiator.playAgain") }) })
|
|
43700
43717
|
] })
|
|
43701
43718
|
}
|
|
@@ -46488,15 +46505,16 @@ function SequencerBoard({
|
|
|
46488
46505
|
}) {
|
|
46489
46506
|
const { emit } = useEventBus();
|
|
46490
46507
|
const { t } = useTranslate();
|
|
46508
|
+
const resolved = Array.isArray(entity) ? entity[0] : entity;
|
|
46491
46509
|
const [headerError, setHeaderError] = React98.useState(false);
|
|
46492
46510
|
const [slots, setSlots] = React98.useState(
|
|
46493
|
-
() => Array.from({ length:
|
|
46511
|
+
() => Array.from({ length: resolved?.maxSlots ?? 0 }, () => void 0)
|
|
46494
46512
|
);
|
|
46495
46513
|
const [playState, setPlayState] = React98.useState("idle");
|
|
46496
46514
|
const [currentStep, setCurrentStep] = React98.useState(-1);
|
|
46497
46515
|
const [attempts, setAttempts] = React98.useState(0);
|
|
46498
46516
|
const [slotFeedback, setSlotFeedback] = React98.useState(
|
|
46499
|
-
() => Array.from({ length:
|
|
46517
|
+
() => Array.from({ length: resolved?.maxSlots ?? 0 }, () => null)
|
|
46500
46518
|
);
|
|
46501
46519
|
const timerRef = React98.useRef(null);
|
|
46502
46520
|
React98.useEffect(() => () => {
|
|
@@ -46530,17 +46548,17 @@ function SequencerBoard({
|
|
|
46530
46548
|
}, [emit]);
|
|
46531
46549
|
const handleReset = React98.useCallback(() => {
|
|
46532
46550
|
if (timerRef.current) clearTimeout(timerRef.current);
|
|
46533
|
-
setSlots(Array.from({ length:
|
|
46551
|
+
setSlots(Array.from({ length: resolved?.maxSlots ?? 0 }, () => void 0));
|
|
46534
46552
|
setPlayState("idle");
|
|
46535
46553
|
setCurrentStep(-1);
|
|
46536
46554
|
setAttempts(0);
|
|
46537
|
-
setSlotFeedback(Array.from({ length:
|
|
46538
|
-
}, [
|
|
46555
|
+
setSlotFeedback(Array.from({ length: resolved?.maxSlots ?? 0 }, () => null));
|
|
46556
|
+
}, [resolved?.maxSlots]);
|
|
46539
46557
|
const filledSlots = slots.filter((s) => !!s);
|
|
46540
46558
|
const canPlay = filledSlots.length > 0 && playState === "idle";
|
|
46541
46559
|
const handlePlay = React98.useCallback(() => {
|
|
46542
46560
|
if (!canPlay) return;
|
|
46543
|
-
setSlotFeedback(Array.from({ length:
|
|
46561
|
+
setSlotFeedback(Array.from({ length: resolved?.maxSlots ?? 0 }, () => null));
|
|
46544
46562
|
emit("UI:PLAY_SOUND", { key: "confirm" });
|
|
46545
46563
|
const sequence = slots.map((s) => s?.id || "");
|
|
46546
46564
|
if (playEvent) {
|
|
@@ -46551,10 +46569,10 @@ function SequencerBoard({
|
|
|
46551
46569
|
let step = 0;
|
|
46552
46570
|
const advance = () => {
|
|
46553
46571
|
step++;
|
|
46554
|
-
if (step >=
|
|
46572
|
+
if (step >= (resolved?.maxSlots ?? 0)) {
|
|
46555
46573
|
const playerSeq = slots.map((s) => s?.id);
|
|
46556
46574
|
const playerIds = slots.filter(Boolean).map((s) => s?.id || "");
|
|
46557
|
-
const success =
|
|
46575
|
+
const success = (resolved?.solutions ?? []).some(
|
|
46558
46576
|
(sol) => sol.length === playerIds.length && sol.every((id, i) => id === playerIds[i])
|
|
46559
46577
|
);
|
|
46560
46578
|
if (success) {
|
|
@@ -46566,7 +46584,7 @@ function SequencerBoard({
|
|
|
46566
46584
|
}
|
|
46567
46585
|
} else {
|
|
46568
46586
|
setAttempts((prev) => prev + 1);
|
|
46569
|
-
const feedback = computeSlotFeedback(playerSeq,
|
|
46587
|
+
const feedback = computeSlotFeedback(playerSeq, resolved?.solutions ?? []);
|
|
46570
46588
|
setSlotFeedback(feedback);
|
|
46571
46589
|
setPlayState("idle");
|
|
46572
46590
|
setCurrentStep(-1);
|
|
@@ -46584,10 +46602,10 @@ function SequencerBoard({
|
|
|
46584
46602
|
}
|
|
46585
46603
|
};
|
|
46586
46604
|
timerRef.current = setTimeout(advance, stepDurationMs);
|
|
46587
|
-
}, [canPlay, slots,
|
|
46605
|
+
}, [canPlay, slots, resolved?.maxSlots, resolved?.solutions, stepDurationMs, playEvent, completeEvent, emit]);
|
|
46588
46606
|
const machine = {
|
|
46589
|
-
name:
|
|
46590
|
-
description:
|
|
46607
|
+
name: resolved?.title ?? "",
|
|
46608
|
+
description: resolved?.description ?? "",
|
|
46591
46609
|
states: slots.map((s, i) => stepLabel(s, i)),
|
|
46592
46610
|
currentState: currentStep >= 0 ? stepLabel(slots[currentStep], currentStep) : "__idle__",
|
|
46593
46611
|
transitions: slots.slice(0, -1).map((s, i) => ({
|
|
@@ -46596,36 +46614,37 @@ function SequencerBoard({
|
|
|
46596
46614
|
event: "NEXT"
|
|
46597
46615
|
}))
|
|
46598
46616
|
};
|
|
46599
|
-
const usedIds =
|
|
46600
|
-
const showHint = attempts >= 3 && !!
|
|
46617
|
+
const usedIds = resolved?.allowDuplicates === false ? slots.filter(Boolean).map((s) => s?.id || "") : [];
|
|
46618
|
+
const showHint = attempts >= 3 && !!resolved?.hint;
|
|
46601
46619
|
const hasFeedback = slotFeedback.some((f3) => f3 !== null);
|
|
46602
46620
|
const correctCount = slotFeedback.filter((f3) => f3 === "correct").length;
|
|
46603
46621
|
const encourageKey = ENCOURAGEMENT_KEYS2[Math.min(attempts - 1, ENCOURAGEMENT_KEYS2.length - 1)] ?? ENCOURAGEMENT_KEYS2[0];
|
|
46622
|
+
if (!resolved) return null;
|
|
46604
46623
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
46605
46624
|
VStack,
|
|
46606
46625
|
{
|
|
46607
46626
|
className: cn("p-4 gap-6", className),
|
|
46608
46627
|
style: {
|
|
46609
|
-
backgroundImage:
|
|
46628
|
+
backgroundImage: resolved.theme?.background ? `url(${resolved.theme.background})` : void 0,
|
|
46610
46629
|
backgroundSize: "cover",
|
|
46611
46630
|
backgroundPosition: "center"
|
|
46612
46631
|
},
|
|
46613
46632
|
children: [
|
|
46614
|
-
|
|
46633
|
+
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,
|
|
46615
46634
|
/* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "xs", children: [
|
|
46616
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "h4", className: "text-foreground", children:
|
|
46617
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body2", className: "text-muted-foreground", children:
|
|
46635
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "h4", className: "text-foreground", children: resolved.title }),
|
|
46636
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body2", className: "text-muted-foreground", children: resolved.description })
|
|
46618
46637
|
] }),
|
|
46619
46638
|
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: [
|
|
46620
46639
|
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body2", className: "text-accent font-bold shrink-0", children: "\u{1F4A1} " + t("game.hint") + ":" }),
|
|
46621
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body2", className: "text-foreground", children:
|
|
46640
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body2", className: "text-foreground", children: resolved.hint })
|
|
46622
46641
|
] }) }),
|
|
46623
46642
|
filledSlots.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(TraitStateViewer, { trait: machine, variant: "linear", size: "md" }),
|
|
46624
46643
|
/* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "xs", children: [
|
|
46625
46644
|
/* @__PURE__ */ jsxRuntime.jsxs(HStack, { className: "items-center justify-between", children: [
|
|
46626
46645
|
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body2", className: "text-muted-foreground font-medium", children: t("sequencer.yourSequence") + ":" }),
|
|
46627
46646
|
hasFeedback && playState === "idle" && /* @__PURE__ */ jsxRuntime.jsxs(Typography, { variant: "caption", className: "text-muted-foreground", children: [
|
|
46628
|
-
`${correctCount}/${
|
|
46647
|
+
`${correctCount}/${resolved.maxSlots} `,
|
|
46629
46648
|
"\u2705"
|
|
46630
46649
|
] })
|
|
46631
46650
|
] }),
|
|
@@ -46633,7 +46652,7 @@ function SequencerBoard({
|
|
|
46633
46652
|
SequenceBar,
|
|
46634
46653
|
{
|
|
46635
46654
|
slots,
|
|
46636
|
-
maxSlots:
|
|
46655
|
+
maxSlots: resolved.maxSlots,
|
|
46637
46656
|
onSlotDrop: handleSlotDrop,
|
|
46638
46657
|
onSlotRemove: handleSlotRemove,
|
|
46639
46658
|
playing: playState === "playing",
|
|
@@ -46647,15 +46666,15 @@ function SequencerBoard({
|
|
|
46647
46666
|
playState !== "playing" && /* @__PURE__ */ jsxRuntime.jsx(
|
|
46648
46667
|
ActionPalette,
|
|
46649
46668
|
{
|
|
46650
|
-
actions:
|
|
46669
|
+
actions: resolved.availableActions,
|
|
46651
46670
|
usedActionIds: usedIds,
|
|
46652
|
-
allowDuplicates:
|
|
46671
|
+
allowDuplicates: resolved.allowDuplicates !== false,
|
|
46653
46672
|
categoryColors,
|
|
46654
46673
|
label: t("sequencer.dragActions")
|
|
46655
46674
|
}
|
|
46656
46675
|
),
|
|
46657
46676
|
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) }) }),
|
|
46658
|
-
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:
|
|
46677
|
+
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") }) }),
|
|
46659
46678
|
/* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "sm", children: [
|
|
46660
46679
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
46661
46680
|
Button,
|
|
@@ -47478,7 +47497,8 @@ function SimulatorBoard({
|
|
|
47478
47497
|
}) {
|
|
47479
47498
|
const { emit } = useEventBus();
|
|
47480
47499
|
const { t } = useTranslate();
|
|
47481
|
-
const
|
|
47500
|
+
const resolved = Array.isArray(entity) ? entity[0] : entity;
|
|
47501
|
+
const parameters = resolved?.parameters ?? [];
|
|
47482
47502
|
const [values, setValues] = React98.useState(() => {
|
|
47483
47503
|
const init = {};
|
|
47484
47504
|
for (const p2 of parameters) {
|
|
@@ -47492,15 +47512,15 @@ function SimulatorBoard({
|
|
|
47492
47512
|
const [showHint, setShowHint] = React98.useState(false);
|
|
47493
47513
|
const computeOutput = React98.useCallback((params) => {
|
|
47494
47514
|
try {
|
|
47495
|
-
const fn = new Function("params", `return (${
|
|
47515
|
+
const fn = new Function("params", `return (${resolved?.computeExpression})`);
|
|
47496
47516
|
return fn(params);
|
|
47497
47517
|
} catch {
|
|
47498
47518
|
return 0;
|
|
47499
47519
|
}
|
|
47500
|
-
}, [
|
|
47520
|
+
}, [resolved?.computeExpression]);
|
|
47501
47521
|
const output = React98.useMemo(() => computeOutput(values) ?? 0, [computeOutput, values]);
|
|
47502
|
-
const targetValue =
|
|
47503
|
-
const targetTolerance =
|
|
47522
|
+
const targetValue = resolved?.targetValue ?? 0;
|
|
47523
|
+
const targetTolerance = resolved?.targetTolerance ?? 0;
|
|
47504
47524
|
const isCorrect = Math.abs(output - targetValue) <= targetTolerance;
|
|
47505
47525
|
const handleParameterChange = (id, value) => {
|
|
47506
47526
|
if (submitted) return;
|
|
@@ -47515,7 +47535,7 @@ function SimulatorBoard({
|
|
|
47515
47535
|
};
|
|
47516
47536
|
const handleReset = () => {
|
|
47517
47537
|
setSubmitted(false);
|
|
47518
|
-
if (attempts >= 2 &&
|
|
47538
|
+
if (attempts >= 2 && resolved?.hint) {
|
|
47519
47539
|
setShowHint(true);
|
|
47520
47540
|
}
|
|
47521
47541
|
};
|
|
@@ -47529,20 +47549,21 @@ function SimulatorBoard({
|
|
|
47529
47549
|
setAttempts(0);
|
|
47530
47550
|
setShowHint(false);
|
|
47531
47551
|
};
|
|
47552
|
+
if (!resolved) return null;
|
|
47532
47553
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
47533
47554
|
Box,
|
|
47534
47555
|
{
|
|
47535
47556
|
className,
|
|
47536
47557
|
style: {
|
|
47537
|
-
backgroundImage:
|
|
47558
|
+
backgroundImage: resolved.theme?.background ? `url(${resolved.theme.background})` : void 0,
|
|
47538
47559
|
backgroundSize: "cover",
|
|
47539
47560
|
backgroundPosition: "center"
|
|
47540
47561
|
},
|
|
47541
47562
|
children: /* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "lg", className: "p-4", children: [
|
|
47542
|
-
|
|
47563
|
+
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,
|
|
47543
47564
|
/* @__PURE__ */ jsxRuntime.jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "sm", children: [
|
|
47544
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "h4", weight: "bold", children:
|
|
47545
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", children:
|
|
47565
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "h4", weight: "bold", children: resolved.title }),
|
|
47566
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", children: resolved.description })
|
|
47546
47567
|
] }) }),
|
|
47547
47568
|
/* @__PURE__ */ jsxRuntime.jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "md", children: [
|
|
47548
47569
|
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", weight: "bold", className: "uppercase tracking-wider text-muted-foreground", children: t("simulator.parameters") }),
|
|
@@ -47583,28 +47604,28 @@ function SimulatorBoard({
|
|
|
47583
47604
|
] }, param.id))
|
|
47584
47605
|
] }) }),
|
|
47585
47606
|
/* @__PURE__ */ jsxRuntime.jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "sm", align: "center", children: [
|
|
47586
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", weight: "bold", className: "uppercase tracking-wider text-muted-foreground", children:
|
|
47607
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", weight: "bold", className: "uppercase tracking-wider text-muted-foreground", children: resolved.outputLabel }),
|
|
47587
47608
|
/* @__PURE__ */ jsxRuntime.jsxs(Typography, { variant: "h3", weight: "bold", children: [
|
|
47588
47609
|
output.toFixed(2),
|
|
47589
47610
|
" ",
|
|
47590
|
-
|
|
47611
|
+
resolved.outputUnit
|
|
47591
47612
|
] }),
|
|
47592
47613
|
submitted && /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "xs", align: "center", children: [
|
|
47593
47614
|
/* @__PURE__ */ jsxRuntime.jsx(Icon, { icon: isCorrect ? LucideIcons2.CheckCircle : LucideIcons2.XCircle, size: "sm", className: isCorrect ? "text-success" : "text-error" }),
|
|
47594
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", className: isCorrect ? "text-success" : "text-error", children: isCorrect ?
|
|
47615
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", className: isCorrect ? "text-success" : "text-error", children: isCorrect ? resolved.successMessage ?? t("simulator.correct") : resolved.failMessage ?? t("simulator.incorrect") })
|
|
47595
47616
|
] }),
|
|
47596
47617
|
/* @__PURE__ */ jsxRuntime.jsxs(Typography, { variant: "caption", className: "text-muted-foreground", children: [
|
|
47597
47618
|
t("simulator.target"),
|
|
47598
47619
|
": ",
|
|
47599
47620
|
targetValue,
|
|
47600
47621
|
" ",
|
|
47601
|
-
|
|
47622
|
+
resolved.outputUnit,
|
|
47602
47623
|
" (\xB1",
|
|
47603
47624
|
targetTolerance,
|
|
47604
47625
|
")"
|
|
47605
47626
|
] })
|
|
47606
47627
|
] }) }),
|
|
47607
|
-
showHint &&
|
|
47628
|
+
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 }) }),
|
|
47608
47629
|
/* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "sm", justify: "center", children: [
|
|
47609
47630
|
!submitted ? /* @__PURE__ */ jsxRuntime.jsxs(Button, { variant: "primary", onClick: handleSubmit, children: [
|
|
47610
47631
|
/* @__PURE__ */ jsxRuntime.jsx(Icon, { icon: LucideIcons2.Play, size: "sm" }),
|
|
@@ -48184,13 +48205,14 @@ function StateArchitectBoard({
|
|
|
48184
48205
|
}) {
|
|
48185
48206
|
const { emit } = useEventBus();
|
|
48186
48207
|
const { t } = useTranslate();
|
|
48187
|
-
const
|
|
48208
|
+
const resolved = Array.isArray(entity) ? entity[0] : entity;
|
|
48209
|
+
const [transitions, setTransitions] = React98.useState(resolved?.transitions ?? []);
|
|
48188
48210
|
const [headerError, setHeaderError] = React98.useState(false);
|
|
48189
48211
|
const [playState, setPlayState] = React98.useState("editing");
|
|
48190
|
-
const [currentState, setCurrentState] = React98.useState(
|
|
48212
|
+
const [currentState, setCurrentState] = React98.useState(resolved?.initialState ?? "");
|
|
48191
48213
|
const [selectedState, setSelectedState] = React98.useState(null);
|
|
48192
48214
|
const [testResults, setTestResults] = React98.useState([]);
|
|
48193
|
-
const [variables, setVariables] = React98.useState(
|
|
48215
|
+
const [variables, setVariables] = React98.useState(resolved?.variables ?? []);
|
|
48194
48216
|
const [attempts, setAttempts] = React98.useState(0);
|
|
48195
48217
|
const timerRef = React98.useRef(null);
|
|
48196
48218
|
const [addingFrom, setAddingFrom] = React98.useState(null);
|
|
@@ -48199,12 +48221,12 @@ function StateArchitectBoard({
|
|
|
48199
48221
|
}, []);
|
|
48200
48222
|
const GRAPH_W = 500;
|
|
48201
48223
|
const GRAPH_H = 400;
|
|
48202
|
-
const positions = React98.useMemo(() => layoutStates(
|
|
48224
|
+
const positions = React98.useMemo(() => layoutStates(resolved?.states ?? [], GRAPH_W, GRAPH_H), [resolved?.states]);
|
|
48203
48225
|
const handleStateClick = React98.useCallback((state) => {
|
|
48204
48226
|
if (playState !== "editing") return;
|
|
48205
48227
|
if (addingFrom) {
|
|
48206
48228
|
if (addingFrom !== state) {
|
|
48207
|
-
const event =
|
|
48229
|
+
const event = resolved?.availableEvents[0] || "EVENT";
|
|
48208
48230
|
const newTrans = {
|
|
48209
48231
|
id: `t-${nextTransId++}`,
|
|
48210
48232
|
from: addingFrom,
|
|
@@ -48217,7 +48239,7 @@ function StateArchitectBoard({
|
|
|
48217
48239
|
} else {
|
|
48218
48240
|
setSelectedState(state);
|
|
48219
48241
|
}
|
|
48220
|
-
}, [playState, addingFrom,
|
|
48242
|
+
}, [playState, addingFrom, resolved?.availableEvents]);
|
|
48221
48243
|
const handleStartAddTransition = React98.useCallback(() => {
|
|
48222
48244
|
if (!selectedState) return;
|
|
48223
48245
|
setAddingFrom(selectedState);
|
|
@@ -48226,9 +48248,9 @@ function StateArchitectBoard({
|
|
|
48226
48248
|
setTransitions((prev) => prev.filter((t2) => t2.id !== transId));
|
|
48227
48249
|
}, []);
|
|
48228
48250
|
const machine = React98.useMemo(() => ({
|
|
48229
|
-
name:
|
|
48230
|
-
description:
|
|
48231
|
-
states:
|
|
48251
|
+
name: resolved?.entityName ?? "",
|
|
48252
|
+
description: resolved?.description ?? "",
|
|
48253
|
+
states: resolved?.states ?? [],
|
|
48232
48254
|
currentState,
|
|
48233
48255
|
transitions: transitions.map((t2) => ({
|
|
48234
48256
|
from: t2.from,
|
|
@@ -48236,7 +48258,7 @@ function StateArchitectBoard({
|
|
|
48236
48258
|
event: t2.event,
|
|
48237
48259
|
guardHint: t2.guardHint
|
|
48238
48260
|
}))
|
|
48239
|
-
}), [
|
|
48261
|
+
}), [resolved, currentState, transitions]);
|
|
48240
48262
|
const handleTest = React98.useCallback(() => {
|
|
48241
48263
|
if (playState !== "editing") return;
|
|
48242
48264
|
if (testEvent) emit(`UI:${testEvent}`, {});
|
|
@@ -48245,7 +48267,7 @@ function StateArchitectBoard({
|
|
|
48245
48267
|
const results = [];
|
|
48246
48268
|
let testIdx = 0;
|
|
48247
48269
|
const runNextTest = () => {
|
|
48248
|
-
if (testIdx >=
|
|
48270
|
+
if (testIdx >= (resolved?.testCases.length ?? 0)) {
|
|
48249
48271
|
const allPassed = results.every((r2) => r2.passed);
|
|
48250
48272
|
setPlayState(allPassed ? "success" : "fail");
|
|
48251
48273
|
setTestResults(results);
|
|
@@ -48260,8 +48282,9 @@ function StateArchitectBoard({
|
|
|
48260
48282
|
}
|
|
48261
48283
|
return;
|
|
48262
48284
|
}
|
|
48263
|
-
const testCase =
|
|
48264
|
-
|
|
48285
|
+
const testCase = resolved?.testCases[testIdx];
|
|
48286
|
+
if (!testCase) return;
|
|
48287
|
+
let state = resolved.initialState;
|
|
48265
48288
|
for (const event of testCase.events) {
|
|
48266
48289
|
const trans = transitions.find((t2) => t2.from === state && t2.event === event);
|
|
48267
48290
|
if (trans) {
|
|
@@ -48279,52 +48302,53 @@ function StateArchitectBoard({
|
|
|
48279
48302
|
timerRef.current = setTimeout(runNextTest, stepDurationMs);
|
|
48280
48303
|
};
|
|
48281
48304
|
timerRef.current = setTimeout(runNextTest, stepDurationMs);
|
|
48282
|
-
}, [playState, transitions,
|
|
48305
|
+
}, [playState, transitions, resolved, stepDurationMs, testEvent, completeEvent, emit]);
|
|
48283
48306
|
const handleTryAgain = React98.useCallback(() => {
|
|
48284
48307
|
if (timerRef.current) clearTimeout(timerRef.current);
|
|
48285
48308
|
setPlayState("editing");
|
|
48286
|
-
setCurrentState(
|
|
48309
|
+
setCurrentState(resolved?.initialState ?? "");
|
|
48287
48310
|
setTestResults([]);
|
|
48288
|
-
}, [
|
|
48311
|
+
}, [resolved?.initialState]);
|
|
48289
48312
|
const handleReset = React98.useCallback(() => {
|
|
48290
48313
|
if (timerRef.current) clearTimeout(timerRef.current);
|
|
48291
|
-
setTransitions(
|
|
48314
|
+
setTransitions(resolved?.transitions ?? []);
|
|
48292
48315
|
setPlayState("editing");
|
|
48293
|
-
setCurrentState(
|
|
48316
|
+
setCurrentState(resolved?.initialState ?? "");
|
|
48294
48317
|
setTestResults([]);
|
|
48295
|
-
setVariables(
|
|
48318
|
+
setVariables(resolved?.variables ?? []);
|
|
48296
48319
|
setSelectedState(null);
|
|
48297
48320
|
setAddingFrom(null);
|
|
48298
48321
|
setAttempts(0);
|
|
48299
|
-
}, [
|
|
48322
|
+
}, [resolved]);
|
|
48300
48323
|
const codeData = React98.useMemo(() => ({
|
|
48301
|
-
name:
|
|
48302
|
-
states:
|
|
48303
|
-
initialState:
|
|
48324
|
+
name: resolved?.entityName ?? "",
|
|
48325
|
+
states: resolved?.states ?? [],
|
|
48326
|
+
initialState: resolved?.initialState ?? "",
|
|
48304
48327
|
transitions: transitions.map((t2) => ({
|
|
48305
48328
|
from: t2.from,
|
|
48306
48329
|
to: t2.to,
|
|
48307
48330
|
event: t2.event,
|
|
48308
48331
|
...t2.guardHint ? { guard: t2.guardHint } : {}
|
|
48309
48332
|
}))
|
|
48310
|
-
}), [
|
|
48333
|
+
}), [resolved, transitions]);
|
|
48334
|
+
if (!resolved) return null;
|
|
48311
48335
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
48312
48336
|
VStack,
|
|
48313
48337
|
{
|
|
48314
48338
|
className: cn("p-4 gap-6", className),
|
|
48315
48339
|
style: {
|
|
48316
|
-
backgroundImage:
|
|
48340
|
+
backgroundImage: resolved.theme?.background ? `url(${resolved.theme.background})` : void 0,
|
|
48317
48341
|
backgroundSize: "cover",
|
|
48318
48342
|
backgroundPosition: "center"
|
|
48319
48343
|
},
|
|
48320
48344
|
children: [
|
|
48321
|
-
|
|
48345
|
+
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,
|
|
48322
48346
|
/* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "xs", children: [
|
|
48323
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "h4", className: "text-foreground", children:
|
|
48324
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body2", className: "text-muted-foreground", children:
|
|
48347
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "h4", className: "text-foreground", children: resolved.title }),
|
|
48348
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body2", className: "text-muted-foreground", children: resolved.description }),
|
|
48325
48349
|
/* @__PURE__ */ jsxRuntime.jsxs(HStack, { className: "items-center p-2 rounded bg-warning/10 border border-warning/30", gap: "xs", children: [
|
|
48326
48350
|
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "caption", className: "text-warning font-bold", children: t("game.hint") + ":" }),
|
|
48327
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "caption", className: "text-foreground", children:
|
|
48351
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "caption", className: "text-foreground", children: resolved.hint })
|
|
48328
48352
|
] })
|
|
48329
48353
|
] }),
|
|
48330
48354
|
/* @__PURE__ */ jsxRuntime.jsxs(HStack, { className: "flex-wrap items-start", gap: "lg", children: [
|
|
@@ -48372,14 +48396,14 @@ function StateArchitectBoard({
|
|
|
48372
48396
|
]
|
|
48373
48397
|
}
|
|
48374
48398
|
),
|
|
48375
|
-
|
|
48399
|
+
resolved.states.map((state) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
48376
48400
|
StateNode2,
|
|
48377
48401
|
{
|
|
48378
48402
|
name: state,
|
|
48379
48403
|
position: positions[state],
|
|
48380
48404
|
isCurrent: state === currentState,
|
|
48381
48405
|
isSelected: state === selectedState,
|
|
48382
|
-
isInitial: state ===
|
|
48406
|
+
isInitial: state === resolved.initialState,
|
|
48383
48407
|
onClick: () => handleStateClick(state)
|
|
48384
48408
|
},
|
|
48385
48409
|
state
|
|
@@ -48426,7 +48450,7 @@ function StateArchitectBoard({
|
|
|
48426
48450
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
48427
48451
|
VariablePanel,
|
|
48428
48452
|
{
|
|
48429
|
-
entityName:
|
|
48453
|
+
entityName: resolved.entityName,
|
|
48430
48454
|
variables
|
|
48431
48455
|
}
|
|
48432
48456
|
),
|
|
@@ -48438,15 +48462,15 @@ function StateArchitectBoard({
|
|
|
48438
48462
|
!r2.passed && /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "caption", className: "text-error", children: t("stateArchitect.gotState", { state: r2.actualState }) })
|
|
48439
48463
|
] }, i))
|
|
48440
48464
|
] }),
|
|
48441
|
-
|
|
48465
|
+
resolved.showCodeView !== false && /* @__PURE__ */ jsxRuntime.jsx(CodeView, { data: codeData, label: "View Code" })
|
|
48442
48466
|
] })
|
|
48443
48467
|
] }),
|
|
48444
|
-
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:
|
|
48468
|
+
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") }) }),
|
|
48445
48469
|
playState === "fail" && /* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "sm", children: [
|
|
48446
48470
|
/* @__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]) }) }),
|
|
48447
|
-
attempts >= 3 &&
|
|
48471
|
+
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: [
|
|
48448
48472
|
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body2", className: "text-accent font-bold shrink-0", children: "\u{1F4A1} " + t("game.hint") + ":" }),
|
|
48449
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body2", className: "text-foreground", children:
|
|
48473
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body2", className: "text-foreground", children: resolved.hint })
|
|
48450
48474
|
] }) })
|
|
48451
48475
|
] }),
|
|
48452
48476
|
/* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "sm", children: [
|
|
@@ -49302,8 +49326,9 @@ var init_useBattleState = __esm({
|
|
|
49302
49326
|
}
|
|
49303
49327
|
});
|
|
49304
49328
|
function UncontrolledBattleBoard({ entity, ...rest }) {
|
|
49329
|
+
const resolved = Array.isArray(entity) ? entity[0] : entity;
|
|
49305
49330
|
const battleState = useBattleState(
|
|
49306
|
-
|
|
49331
|
+
resolved?.initialUnits ?? [],
|
|
49307
49332
|
{
|
|
49308
49333
|
tileClickEvent: rest.tileClickEvent,
|
|
49309
49334
|
unitClickEvent: rest.unitClickEvent,
|
|
@@ -49320,12 +49345,13 @@ function UncontrolledBattleBoard({ entity, ...rest }) {
|
|
|
49320
49345
|
calculateDamage: rest.calculateDamage
|
|
49321
49346
|
}
|
|
49322
49347
|
);
|
|
49348
|
+
if (!resolved) return null;
|
|
49323
49349
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
49324
49350
|
BattleBoard,
|
|
49325
49351
|
{
|
|
49326
49352
|
...rest,
|
|
49327
49353
|
entity: {
|
|
49328
|
-
...
|
|
49354
|
+
...resolved,
|
|
49329
49355
|
units: battleState.units,
|
|
49330
49356
|
phase: battleState.phase,
|
|
49331
49357
|
turn: battleState.turn,
|
|
@@ -55517,6 +55543,7 @@ var init_component_registry_generated = __esm({
|
|
|
55517
55543
|
init_StatsOrganism();
|
|
55518
55544
|
init_StatusDot();
|
|
55519
55545
|
init_StatusEffect();
|
|
55546
|
+
init_StepFlow();
|
|
55520
55547
|
init_StepFlowOrganism();
|
|
55521
55548
|
init_SvgBranch();
|
|
55522
55549
|
init_SvgConnection();
|
|
@@ -55835,6 +55862,7 @@ var init_component_registry_generated = __esm({
|
|
|
55835
55862
|
"StatsOrganism": StatsOrganism,
|
|
55836
55863
|
"StatusDot": StatusDot,
|
|
55837
55864
|
"StatusEffect": StatusEffect,
|
|
55865
|
+
"StepFlow": StepFlow,
|
|
55838
55866
|
"StepFlowOrganism": StepFlowOrganism,
|
|
55839
55867
|
"SvgBranch": SvgBranch,
|
|
55840
55868
|
"SvgConnection": SvgConnection,
|