@almadar/ui 5.34.0 → 5.36.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 +228 -206
- package/dist/avl/index.js +228 -206
- package/dist/components/game/organisms/puzzles/builder/BuilderBoard.d.ts +18 -5
- package/dist/components/game/organisms/puzzles/classifier/ClassifierBoard.d.ts +21 -3
- package/dist/components/game/organisms/puzzles/debugger/DebuggerBoard.d.ts +12 -2
- package/dist/components/game/organisms/puzzles/negotiator/NegotiatorBoard.d.ts +13 -3
- package/dist/components/game/organisms/puzzles/simulator/SimulatorBoard.d.ts +22 -7
- package/dist/components/index.cjs +228 -206
- package/dist/components/index.js +228 -206
- package/dist/providers/index.cjs +228 -206
- package/dist/providers/index.js +228 -206
- package/dist/runtime/index.cjs +228 -206
- package/dist/runtime/index.js +228 -206
- package/package.json +1 -1
package/dist/providers/index.js
CHANGED
|
@@ -9490,7 +9490,7 @@ var init_AboutPageTemplate = __esm({
|
|
|
9490
9490
|
const resolved = entity && typeof entity === "object" && !Array.isArray(entity) ? entity : void 0;
|
|
9491
9491
|
if (!resolved) return null;
|
|
9492
9492
|
return /* @__PURE__ */ jsxs(VStack, { gap: "none", className: cn("w-full", className), children: [
|
|
9493
|
-
/* @__PURE__ */ jsx(
|
|
9493
|
+
resolved.hero && /* @__PURE__ */ jsx(
|
|
9494
9494
|
HeroSection,
|
|
9495
9495
|
{
|
|
9496
9496
|
tag: resolved.hero.tag,
|
|
@@ -17372,61 +17372,53 @@ var init_Breadcrumb = __esm({
|
|
|
17372
17372
|
function BuilderBoard({
|
|
17373
17373
|
entity,
|
|
17374
17374
|
completeEvent = "PUZZLE_COMPLETE",
|
|
17375
|
+
placeEvent,
|
|
17376
|
+
checkEvent,
|
|
17377
|
+
playAgainEvent,
|
|
17375
17378
|
className
|
|
17376
17379
|
}) {
|
|
17377
17380
|
const { emit } = useEventBus();
|
|
17378
17381
|
const { t } = useTranslate();
|
|
17379
17382
|
const resolved = boardEntity(entity);
|
|
17380
|
-
const [placements, setPlacements] = useState({});
|
|
17381
17383
|
const [headerError, setHeaderError] = useState(false);
|
|
17382
|
-
const [
|
|
17383
|
-
const [attempts, setAttempts] = useState(0);
|
|
17384
|
-
const [showHint, setShowHint] = useState(false);
|
|
17384
|
+
const [selectedComponent, setSelectedComponent] = useState(null);
|
|
17385
17385
|
const components = Array.isArray(resolved?.components) ? resolved.components : [];
|
|
17386
17386
|
const slots = Array.isArray(resolved?.slots) ? resolved.slots : [];
|
|
17387
|
+
const placements = {};
|
|
17388
|
+
for (const slot of slots) {
|
|
17389
|
+
if (slot.placedComponentId) placements[slot.id] = slot.placedComponentId;
|
|
17390
|
+
}
|
|
17391
|
+
const attempts = num(resolved?.attempts);
|
|
17392
|
+
const result = str(resolved?.result) || "none";
|
|
17393
|
+
const submitted = result === "win";
|
|
17387
17394
|
const usedComponentIds = new Set(Object.values(placements));
|
|
17388
17395
|
const availableComponents = components.filter((c) => !usedComponentIds.has(c.id));
|
|
17389
|
-
const
|
|
17390
|
-
const allPlaced = Object.keys(placements).length === slots.length;
|
|
17396
|
+
const allPlaced = slots.length > 0 && slots.every((s) => Boolean(placements[s.id]));
|
|
17391
17397
|
const results = submitted ? slots.map((slot) => ({
|
|
17392
17398
|
slot,
|
|
17393
17399
|
placed: placements[slot.id],
|
|
17394
|
-
correct: placements[slot.id] === slot.
|
|
17400
|
+
correct: placements[slot.id] === slot.requiredComponentId
|
|
17395
17401
|
})) : [];
|
|
17396
|
-
const
|
|
17402
|
+
const showHint = attempts >= 2 && Boolean(str(resolved?.hint));
|
|
17397
17403
|
const handlePlaceComponent = (slotId) => {
|
|
17398
17404
|
if (submitted || !selectedComponent) return;
|
|
17399
|
-
|
|
17405
|
+
if (placeEvent) emit(`UI:${placeEvent}`, { slotId, componentId: selectedComponent });
|
|
17400
17406
|
setSelectedComponent(null);
|
|
17401
17407
|
};
|
|
17402
17408
|
const handleRemoveFromSlot = (slotId) => {
|
|
17403
17409
|
if (submitted) return;
|
|
17404
|
-
|
|
17405
|
-
const next = { ...prev };
|
|
17406
|
-
delete next[slotId];
|
|
17407
|
-
return next;
|
|
17408
|
-
});
|
|
17410
|
+
if (placeEvent) emit(`UI:${placeEvent}`, { slotId, componentId: "" });
|
|
17409
17411
|
};
|
|
17410
|
-
const handleSubmit =
|
|
17411
|
-
|
|
17412
|
-
|
|
17413
|
-
|
|
17414
|
-
if (correct) {
|
|
17412
|
+
const handleSubmit = () => {
|
|
17413
|
+
if (checkEvent) emit(`UI:${checkEvent}`, {});
|
|
17414
|
+
const solved = slots.length > 0 && slots.every((s) => placements[s.id] === s.requiredComponentId);
|
|
17415
|
+
if (solved && completeEvent) {
|
|
17415
17416
|
emit(`UI:${completeEvent}`, { success: true, attempts: attempts + 1 });
|
|
17416
17417
|
}
|
|
17417
|
-
}, [slots, placements, attempts, completeEvent, emit]);
|
|
17418
|
-
const handleReset = () => {
|
|
17419
|
-
setSubmitted(false);
|
|
17420
|
-
if (attempts >= 2 && str(resolved?.hint)) {
|
|
17421
|
-
setShowHint(true);
|
|
17422
|
-
}
|
|
17423
17418
|
};
|
|
17424
|
-
const
|
|
17425
|
-
setPlacements({});
|
|
17426
|
-
setSubmitted(false);
|
|
17419
|
+
const handlePlayAgain = () => {
|
|
17427
17420
|
setSelectedComponent(null);
|
|
17428
|
-
|
|
17429
|
-
setShowHint(false);
|
|
17421
|
+
if (playAgainEvent) emit(`UI:${playAgainEvent}`, {});
|
|
17430
17422
|
};
|
|
17431
17423
|
const getComponentById = (id) => components.find((c) => c.id === id);
|
|
17432
17424
|
if (!resolved) return null;
|
|
@@ -17476,13 +17468,13 @@ function BuilderBoard({
|
|
|
17476
17468
|
/* @__PURE__ */ jsx(Typography, { variant: "small", weight: "bold", className: "uppercase tracking-wider text-muted-foreground", children: t("builder.blueprint") }),
|
|
17477
17469
|
/* @__PURE__ */ jsx(VStack, { gap: "sm", children: slots.map((slot) => {
|
|
17478
17470
|
const placedComp = placements[slot.id] ? getComponentById(placements[slot.id]) : null;
|
|
17479
|
-
const
|
|
17471
|
+
const result2 = results.find((r) => r.slot.id === slot.id);
|
|
17480
17472
|
return /* @__PURE__ */ jsxs(
|
|
17481
17473
|
HStack,
|
|
17482
17474
|
{
|
|
17483
17475
|
gap: "sm",
|
|
17484
17476
|
align: "center",
|
|
17485
|
-
className: `p-3 border-2 rounded ${
|
|
17477
|
+
className: `p-3 border-2 rounded ${result2 ? result2.correct ? "border-success" : "border-error" : selectedComponent ? "border-dashed border-foreground cursor-pointer" : "border-border"}`,
|
|
17486
17478
|
onClick: () => handlePlaceComponent(slot.id),
|
|
17487
17479
|
children: [
|
|
17488
17480
|
/* @__PURE__ */ jsxs(VStack, { gap: "none", className: "flex-1", children: [
|
|
@@ -17497,7 +17489,7 @@ function BuilderBoard({
|
|
|
17497
17489
|
] }) : null,
|
|
17498
17490
|
placedComp.label
|
|
17499
17491
|
] }),
|
|
17500
|
-
|
|
17492
|
+
result2 && /* @__PURE__ */ jsx(Icon, { icon: result2.correct ? CheckCircle : XCircle, size: "sm", className: result2.correct ? "text-success" : "text-error" })
|
|
17501
17493
|
] }) : /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-muted-foreground", children: t("builder.empty") })
|
|
17502
17494
|
]
|
|
17503
17495
|
},
|
|
@@ -17506,16 +17498,16 @@ function BuilderBoard({
|
|
|
17506
17498
|
}) })
|
|
17507
17499
|
] }) }),
|
|
17508
17500
|
submitted && /* @__PURE__ */ jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxs(VStack, { gap: "sm", align: "center", children: [
|
|
17509
|
-
/* @__PURE__ */ jsx(Icon, { icon:
|
|
17510
|
-
/* @__PURE__ */ jsx(Typography, { variant: "body", weight: "bold", children:
|
|
17501
|
+
/* @__PURE__ */ jsx(Icon, { icon: CheckCircle, size: "lg", className: "text-success" }),
|
|
17502
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body", weight: "bold", children: str(resolved.successMessage) || t("builder.success") })
|
|
17511
17503
|
] }) }),
|
|
17512
17504
|
showHint && hint && /* @__PURE__ */ jsx(Card, { className: "p-4 border-l-4 border-l-warning", children: /* @__PURE__ */ jsx(Typography, { variant: "body", children: hint }) }),
|
|
17513
17505
|
/* @__PURE__ */ jsxs(HStack, { gap: "sm", justify: "center", children: [
|
|
17514
|
-
!submitted
|
|
17506
|
+
!submitted && /* @__PURE__ */ jsxs(Button, { variant: "primary", onClick: handleSubmit, disabled: !allPlaced, children: [
|
|
17515
17507
|
/* @__PURE__ */ jsx(Icon, { icon: Wrench, size: "sm" }),
|
|
17516
17508
|
t("builder.build")
|
|
17517
|
-
] })
|
|
17518
|
-
/* @__PURE__ */ jsxs(Button, { variant: "secondary", onClick:
|
|
17509
|
+
] }),
|
|
17510
|
+
/* @__PURE__ */ jsxs(Button, { variant: "secondary", onClick: handlePlayAgain, children: [
|
|
17519
17511
|
/* @__PURE__ */ jsx(Icon, { icon: RotateCcw, size: "sm" }),
|
|
17520
17512
|
t("builder.reset")
|
|
17521
17513
|
] })
|
|
@@ -20971,57 +20963,84 @@ var init_ChartLegend = __esm({
|
|
|
20971
20963
|
function ClassifierBoard({
|
|
20972
20964
|
entity,
|
|
20973
20965
|
completeEvent = "PUZZLE_COMPLETE",
|
|
20966
|
+
assignEvent,
|
|
20967
|
+
checkEvent,
|
|
20968
|
+
playAgainEvent,
|
|
20974
20969
|
className
|
|
20975
20970
|
}) {
|
|
20976
20971
|
const { emit } = useEventBus();
|
|
20977
20972
|
const { t } = useTranslate();
|
|
20978
20973
|
const resolved = boardEntity(entity);
|
|
20979
|
-
const [
|
|
20974
|
+
const [localAssignments, setLocalAssignments] = useState({});
|
|
20980
20975
|
const [headerError, setHeaderError] = useState(false);
|
|
20981
|
-
const [
|
|
20982
|
-
const [
|
|
20976
|
+
const [localSubmitted, setLocalSubmitted] = useState(false);
|
|
20977
|
+
const [localAttempts, setLocalAttempts] = useState(0);
|
|
20983
20978
|
const [showHint, setShowHint] = useState(false);
|
|
20984
20979
|
const items = Array.isArray(resolved?.items) ? resolved.items : [];
|
|
20985
20980
|
const categories = Array.isArray(resolved?.categories) ? resolved.categories : [];
|
|
20981
|
+
const entityResult = str(resolved?.result);
|
|
20982
|
+
const entityDrivesResult = entityResult.length > 0;
|
|
20983
|
+
const entityHasAssignments = items.some((item) => item.assignedCategory != null);
|
|
20984
|
+
const assignments = entityHasAssignments ? items.reduce((acc, item) => {
|
|
20985
|
+
if (item.assignedCategory != null) acc[item.id] = item.assignedCategory;
|
|
20986
|
+
return acc;
|
|
20987
|
+
}, {}) : localAssignments;
|
|
20988
|
+
const attempts = entityDrivesResult ? num(resolved?.attempts) : localAttempts;
|
|
20989
|
+
const submitted = entityDrivesResult || localSubmitted;
|
|
20986
20990
|
const unassignedItems = items.filter((item) => !assignments[item.id]);
|
|
20987
|
-
const allAssigned = Object.keys(assignments).length === items.length;
|
|
20991
|
+
const allAssigned = items.length > 0 && Object.keys(assignments).length === items.length;
|
|
20988
20992
|
const results = submitted ? items.map((item) => ({
|
|
20989
20993
|
item,
|
|
20990
20994
|
assigned: assignments[item.id],
|
|
20991
20995
|
correct: assignments[item.id] === item.correctCategory
|
|
20992
20996
|
})) : [];
|
|
20993
|
-
const allCorrect = results.length > 0 && results.every((r) => r.correct);
|
|
20997
|
+
const allCorrect = entityDrivesResult ? entityResult === "success" : results.length > 0 && results.every((r) => r.correct);
|
|
20994
20998
|
const correctCount = results.filter((r) => r.correct).length;
|
|
20995
20999
|
const handleAssign = (itemId, categoryId) => {
|
|
20996
21000
|
if (submitted) return;
|
|
20997
|
-
|
|
21001
|
+
if (assignEvent) {
|
|
21002
|
+
emit(`UI:${assignEvent}`, { itemId, categoryId });
|
|
21003
|
+
}
|
|
21004
|
+
if (!entityHasAssignments) {
|
|
21005
|
+
setLocalAssignments((prev) => ({ ...prev, [itemId]: categoryId }));
|
|
21006
|
+
}
|
|
20998
21007
|
};
|
|
20999
21008
|
const handleUnassign = (itemId) => {
|
|
21000
21009
|
if (submitted) return;
|
|
21001
|
-
|
|
21002
|
-
|
|
21003
|
-
|
|
21004
|
-
|
|
21005
|
-
|
|
21010
|
+
if (!entityHasAssignments) {
|
|
21011
|
+
setLocalAssignments((prev) => {
|
|
21012
|
+
const next = { ...prev };
|
|
21013
|
+
delete next[itemId];
|
|
21014
|
+
return next;
|
|
21015
|
+
});
|
|
21016
|
+
}
|
|
21006
21017
|
};
|
|
21007
21018
|
const handleSubmit = useCallback(() => {
|
|
21008
|
-
|
|
21009
|
-
|
|
21010
|
-
|
|
21011
|
-
if (
|
|
21012
|
-
|
|
21019
|
+
if (checkEvent) {
|
|
21020
|
+
emit(`UI:${checkEvent}`, {});
|
|
21021
|
+
}
|
|
21022
|
+
if (!entityDrivesResult) {
|
|
21023
|
+
setLocalSubmitted(true);
|
|
21024
|
+
setLocalAttempts((a) => a + 1);
|
|
21025
|
+
const correct = items.every((item) => assignments[item.id] === item.correctCategory);
|
|
21026
|
+
if (correct) {
|
|
21027
|
+
emit(`UI:${completeEvent}`, { success: true, attempts: attempts + 1 });
|
|
21028
|
+
}
|
|
21013
21029
|
}
|
|
21014
|
-
}, [items, assignments, attempts, completeEvent, emit]);
|
|
21030
|
+
}, [checkEvent, entityDrivesResult, items, assignments, attempts, completeEvent, emit]);
|
|
21015
21031
|
const handleReset = () => {
|
|
21016
|
-
|
|
21032
|
+
if (!entityDrivesResult) setLocalSubmitted(false);
|
|
21017
21033
|
if (attempts >= 2 && str(resolved?.hint)) {
|
|
21018
21034
|
setShowHint(true);
|
|
21019
21035
|
}
|
|
21020
21036
|
};
|
|
21021
21037
|
const handleFullReset = () => {
|
|
21022
|
-
|
|
21023
|
-
|
|
21024
|
-
|
|
21038
|
+
if (playAgainEvent) {
|
|
21039
|
+
emit(`UI:${playAgainEvent}`, {});
|
|
21040
|
+
}
|
|
21041
|
+
setLocalAssignments({});
|
|
21042
|
+
setLocalSubmitted(false);
|
|
21043
|
+
setLocalAttempts(0);
|
|
21025
21044
|
setShowHint(false);
|
|
21026
21045
|
};
|
|
21027
21046
|
if (!resolved) return null;
|
|
@@ -28904,13 +28923,13 @@ var init_MapView = __esm({
|
|
|
28904
28923
|
shadowSize: [41, 41]
|
|
28905
28924
|
});
|
|
28906
28925
|
L.Marker.prototype.options.icon = defaultIcon;
|
|
28907
|
-
const { useEffect:
|
|
28926
|
+
const { useEffect: useEffect73, useRef: useRef68, useCallback: useCallback111, useState: useState104 } = React83__default;
|
|
28908
28927
|
const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
|
|
28909
28928
|
const { useEventBus: useEventBus2 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
|
|
28910
28929
|
function MapUpdater({ centerLat, centerLng, zoom }) {
|
|
28911
28930
|
const map = useMap();
|
|
28912
|
-
const prevRef =
|
|
28913
|
-
|
|
28931
|
+
const prevRef = useRef68({ centerLat, centerLng, zoom });
|
|
28932
|
+
useEffect73(() => {
|
|
28914
28933
|
const prev = prevRef.current;
|
|
28915
28934
|
if (prev.centerLat !== centerLat || prev.centerLng !== centerLng || prev.zoom !== zoom) {
|
|
28916
28935
|
map.setView([centerLat, centerLng], zoom);
|
|
@@ -28921,7 +28940,7 @@ var init_MapView = __esm({
|
|
|
28921
28940
|
}
|
|
28922
28941
|
function MapClickHandler({ onMapClick }) {
|
|
28923
28942
|
const map = useMap();
|
|
28924
|
-
|
|
28943
|
+
useEffect73(() => {
|
|
28925
28944
|
if (!onMapClick) return;
|
|
28926
28945
|
const handler = (e) => {
|
|
28927
28946
|
onMapClick(e.latlng.lat, e.latlng.lng);
|
|
@@ -28950,7 +28969,7 @@ var init_MapView = __esm({
|
|
|
28950
28969
|
}) {
|
|
28951
28970
|
const eventBus = useEventBus2();
|
|
28952
28971
|
const [clickedPosition, setClickedPosition] = useState104(null);
|
|
28953
|
-
const handleMapClick =
|
|
28972
|
+
const handleMapClick = useCallback111((lat, lng) => {
|
|
28954
28973
|
if (showClickedPin) {
|
|
28955
28974
|
setClickedPosition({ lat, lng });
|
|
28956
28975
|
}
|
|
@@ -28959,7 +28978,7 @@ var init_MapView = __esm({
|
|
|
28959
28978
|
eventBus.emit(`UI:${mapClickEvent}`, { latitude: lat, longitude: lng });
|
|
28960
28979
|
}
|
|
28961
28980
|
}, [onMapClick, mapClickEvent, eventBus, showClickedPin]);
|
|
28962
|
-
const handleMarkerClick =
|
|
28981
|
+
const handleMarkerClick = useCallback111((marker) => {
|
|
28963
28982
|
onMarkerClick?.(marker);
|
|
28964
28983
|
if (markerClickEvent) {
|
|
28965
28984
|
eventBus.emit(`UI:${markerClickEvent}`, { ...marker });
|
|
@@ -38181,51 +38200,52 @@ var init_DataTable = __esm({
|
|
|
38181
38200
|
function DebuggerBoard({
|
|
38182
38201
|
entity,
|
|
38183
38202
|
completeEvent = "PUZZLE_COMPLETE",
|
|
38203
|
+
toggleFlagEvent,
|
|
38204
|
+
checkEvent,
|
|
38205
|
+
playAgainEvent,
|
|
38184
38206
|
className
|
|
38185
38207
|
}) {
|
|
38186
38208
|
const { emit } = useEventBus();
|
|
38187
38209
|
const { t } = useTranslate();
|
|
38188
38210
|
const resolved = boardEntity(entity);
|
|
38189
|
-
const [flaggedLines, setFlaggedLines] = useState(/* @__PURE__ */ new Set());
|
|
38190
38211
|
const [headerError, setHeaderError] = useState(false);
|
|
38191
|
-
const [submitted, setSubmitted] = useState(false);
|
|
38192
|
-
const [attempts, setAttempts] = useState(0);
|
|
38193
38212
|
const [showHint, setShowHint] = useState(false);
|
|
38213
|
+
const lines = Array.isArray(resolved?.lines) ? resolved.lines : [];
|
|
38214
|
+
const result = resolved?.result ?? null;
|
|
38215
|
+
const attempts = num(resolved?.attempts);
|
|
38216
|
+
const submitted = result != null;
|
|
38217
|
+
const bugLines = lines.filter((l) => l.isBug);
|
|
38218
|
+
const flaggedLines = lines.filter((l) => l.isFlagged);
|
|
38219
|
+
const correctFlags = lines.filter((l) => l.isBug && l.isFlagged);
|
|
38220
|
+
const falseFlags = lines.filter((l) => !l.isBug && l.isFlagged);
|
|
38221
|
+
const allCorrect = result === "win";
|
|
38194
38222
|
const toggleLine = (lineId) => {
|
|
38195
38223
|
if (submitted) return;
|
|
38196
|
-
|
|
38197
|
-
|
|
38198
|
-
|
|
38199
|
-
next.delete(lineId);
|
|
38200
|
-
} else {
|
|
38201
|
-
next.add(lineId);
|
|
38202
|
-
}
|
|
38203
|
-
return next;
|
|
38204
|
-
});
|
|
38224
|
+
if (toggleFlagEvent) {
|
|
38225
|
+
emit(`UI:${toggleFlagEvent}`, { lineId });
|
|
38226
|
+
}
|
|
38205
38227
|
};
|
|
38206
|
-
const lines = Array.isArray(resolved?.lines) ? resolved.lines : [];
|
|
38207
|
-
const bugLines = lines.filter((l) => l.isBug);
|
|
38208
|
-
const correctFlags = lines.filter((l) => l.isBug && flaggedLines.has(l.id));
|
|
38209
|
-
const falseFlags = lines.filter((l) => !l.isBug && flaggedLines.has(l.id));
|
|
38210
|
-
const allCorrect = submitted && correctFlags.length === bugLines.length && falseFlags.length === 0;
|
|
38211
38228
|
const handleSubmit = useCallback(() => {
|
|
38212
|
-
|
|
38213
|
-
|
|
38229
|
+
if (checkEvent) {
|
|
38230
|
+
emit(`UI:${checkEvent}`, {});
|
|
38231
|
+
}
|
|
38214
38232
|
const correct = correctFlags.length === bugLines.length && falseFlags.length === 0;
|
|
38215
38233
|
if (correct) {
|
|
38216
38234
|
emit(`UI:${completeEvent}`, { success: true, attempts: attempts + 1 });
|
|
38217
38235
|
}
|
|
38218
|
-
}, [correctFlags.length, bugLines.length, falseFlags.length, attempts, completeEvent, emit]);
|
|
38236
|
+
}, [checkEvent, correctFlags.length, bugLines.length, falseFlags.length, attempts, completeEvent, emit]);
|
|
38219
38237
|
const handleReset = () => {
|
|
38220
|
-
|
|
38238
|
+
if (playAgainEvent) {
|
|
38239
|
+
emit(`UI:${playAgainEvent}`, {});
|
|
38240
|
+
}
|
|
38221
38241
|
if (attempts >= 2 && str(resolved?.hint)) {
|
|
38222
38242
|
setShowHint(true);
|
|
38223
38243
|
}
|
|
38224
38244
|
};
|
|
38225
38245
|
const handleFullReset = () => {
|
|
38226
|
-
|
|
38227
|
-
|
|
38228
|
-
|
|
38246
|
+
if (playAgainEvent) {
|
|
38247
|
+
emit(`UI:${playAgainEvent}`, {});
|
|
38248
|
+
}
|
|
38229
38249
|
setShowHint(false);
|
|
38230
38250
|
};
|
|
38231
38251
|
if (!resolved) return null;
|
|
@@ -38253,7 +38273,7 @@ function DebuggerBoard({
|
|
|
38253
38273
|
/* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-muted-foreground", children: t("debugger.findBugs", { count: String(num(resolved.bugCount)) }) })
|
|
38254
38274
|
] }) }),
|
|
38255
38275
|
/* @__PURE__ */ jsx(Card, { className: "p-0 overflow-hidden", children: /* @__PURE__ */ jsx(VStack, { gap: "none", children: lines.map((line, i) => {
|
|
38256
|
-
const isFlagged =
|
|
38276
|
+
const isFlagged = !!line.isFlagged;
|
|
38257
38277
|
let lineStyle = "";
|
|
38258
38278
|
if (submitted) {
|
|
38259
38279
|
if (line.isBug && isFlagged) lineStyle = "bg-success/10";
|
|
@@ -38287,9 +38307,9 @@ function DebuggerBoard({
|
|
|
38287
38307
|
/* @__PURE__ */ jsx(
|
|
38288
38308
|
Icon,
|
|
38289
38309
|
{
|
|
38290
|
-
icon:
|
|
38310
|
+
icon: line.isFlagged ? CheckCircle : XCircle,
|
|
38291
38311
|
size: "xs",
|
|
38292
|
-
className:
|
|
38312
|
+
className: line.isFlagged ? "text-success mt-0.5" : "text-warning mt-0.5"
|
|
38293
38313
|
}
|
|
38294
38314
|
),
|
|
38295
38315
|
/* @__PURE__ */ jsxs(VStack, { gap: "none", children: [
|
|
@@ -38300,7 +38320,7 @@ function DebuggerBoard({
|
|
|
38300
38320
|
] }) }),
|
|
38301
38321
|
showHint && hint && /* @__PURE__ */ jsx(Card, { className: "p-4 border-l-4 border-l-warning", children: /* @__PURE__ */ jsx(Typography, { variant: "body", children: hint }) }),
|
|
38302
38322
|
/* @__PURE__ */ jsxs(HStack, { gap: "sm", justify: "center", children: [
|
|
38303
|
-
!submitted ? /* @__PURE__ */ jsxs(Button, { variant: "primary", onClick: handleSubmit, disabled: flaggedLines.
|
|
38323
|
+
!submitted ? /* @__PURE__ */ jsxs(Button, { variant: "primary", onClick: handleSubmit, disabled: flaggedLines.length === 0, children: [
|
|
38304
38324
|
/* @__PURE__ */ jsx(Icon, { icon: Send, size: "sm" }),
|
|
38305
38325
|
t("debugger.submit")
|
|
38306
38326
|
] }) : !allCorrect ? /* @__PURE__ */ jsx(Button, { variant: "primary", onClick: handleReset, children: t("debugger.tryAgain") }) : null,
|
|
@@ -39537,7 +39557,7 @@ var init_FeatureDetailPageTemplate = __esm({
|
|
|
39537
39557
|
const resolved = entity && typeof entity === "object" && !Array.isArray(entity) ? entity : void 0;
|
|
39538
39558
|
if (!resolved) return null;
|
|
39539
39559
|
return /* @__PURE__ */ jsxs(VStack, { gap: "none", className: cn("w-full", className), children: [
|
|
39540
|
-
/* @__PURE__ */ jsx(
|
|
39560
|
+
resolved.hero && /* @__PURE__ */ jsx(
|
|
39541
39561
|
HeroSection,
|
|
39542
39562
|
{
|
|
39543
39563
|
tag: resolved.hero.tag,
|
|
@@ -41057,7 +41077,7 @@ var init_LandingPageTemplate = __esm({
|
|
|
41057
41077
|
const resolved = entity && typeof entity === "object" && !Array.isArray(entity) ? entity : void 0;
|
|
41058
41078
|
if (!resolved) return null;
|
|
41059
41079
|
return /* @__PURE__ */ jsxs(VStack, { gap: "none", className: cn("w-full", className), children: [
|
|
41060
|
-
/* @__PURE__ */ jsx(
|
|
41080
|
+
resolved.hero && /* @__PURE__ */ jsx(
|
|
41061
41081
|
HeroSection,
|
|
41062
41082
|
{
|
|
41063
41083
|
tag: resolved.hero.tag,
|
|
@@ -42064,6 +42084,9 @@ function getOpponentAction(strategy, actions, history) {
|
|
|
42064
42084
|
function NegotiatorBoard({
|
|
42065
42085
|
entity,
|
|
42066
42086
|
completeEvent = "PUZZLE_COMPLETE",
|
|
42087
|
+
playRoundEvent,
|
|
42088
|
+
finishEvent,
|
|
42089
|
+
playAgainEvent,
|
|
42067
42090
|
className
|
|
42068
42091
|
}) {
|
|
42069
42092
|
const { emit } = useEventBus();
|
|
@@ -42072,13 +42095,14 @@ function NegotiatorBoard({
|
|
|
42072
42095
|
const [history, setHistory] = useState([]);
|
|
42073
42096
|
const [headerError, setHeaderError] = useState(false);
|
|
42074
42097
|
const [showHint, setShowHint] = useState(false);
|
|
42075
|
-
const totalRounds = num(resolved?.
|
|
42098
|
+
const totalRounds = num(resolved?.maxRounds);
|
|
42076
42099
|
const targetScore = num(resolved?.targetScore);
|
|
42077
|
-
const currentRound =
|
|
42078
|
-
const
|
|
42079
|
-
const playerTotal =
|
|
42100
|
+
const currentRound = num(resolved?.round);
|
|
42101
|
+
const result = str(resolved?.result) || "none";
|
|
42102
|
+
const playerTotal = num(resolved?.score);
|
|
42103
|
+
const isComplete = result !== "none" || totalRounds > 0 && currentRound >= totalRounds;
|
|
42104
|
+
const won = result === "win";
|
|
42080
42105
|
const opponentTotal = history.reduce((s, r) => s + r.opponentPayoff, 0);
|
|
42081
|
-
const won = isComplete && playerTotal >= targetScore;
|
|
42082
42106
|
const actions = Array.isArray(resolved?.actions) ? resolved.actions : [];
|
|
42083
42107
|
const payoffMatrix = Array.isArray(resolved?.payoffMatrix) ? resolved.payoffMatrix : [];
|
|
42084
42108
|
const handleAction = useCallback((actionId) => {
|
|
@@ -42087,29 +42111,45 @@ function NegotiatorBoard({
|
|
|
42087
42111
|
const payoff = payoffMatrix.find(
|
|
42088
42112
|
(p2) => p2.playerAction === actionId && p2.opponentAction === opponentAction
|
|
42089
42113
|
);
|
|
42090
|
-
const
|
|
42091
|
-
|
|
42092
|
-
|
|
42093
|
-
|
|
42094
|
-
|
|
42095
|
-
|
|
42096
|
-
|
|
42097
|
-
|
|
42098
|
-
|
|
42099
|
-
|
|
42100
|
-
|
|
42101
|
-
|
|
42102
|
-
|
|
42103
|
-
|
|
42104
|
-
|
|
42114
|
+
const playerPayoff = payoff?.playerPayoff ?? 0;
|
|
42115
|
+
setHistory((prev) => [
|
|
42116
|
+
...prev,
|
|
42117
|
+
{
|
|
42118
|
+
round: prev.length + 1,
|
|
42119
|
+
playerAction: actionId,
|
|
42120
|
+
opponentAction,
|
|
42121
|
+
playerPayoff,
|
|
42122
|
+
opponentPayoff: payoff?.opponentPayoff ?? 0
|
|
42123
|
+
}
|
|
42124
|
+
]);
|
|
42125
|
+
if (playRoundEvent) {
|
|
42126
|
+
emit(`UI:${playRoundEvent}`, { playerAction: actionId, payoff: playerPayoff });
|
|
42127
|
+
}
|
|
42128
|
+
if (totalRounds > 0 && currentRound + 1 >= totalRounds) {
|
|
42129
|
+
if (finishEvent) {
|
|
42130
|
+
emit(`UI:${finishEvent}`, {});
|
|
42131
|
+
}
|
|
42132
|
+
if (str(resolved?.hint)) {
|
|
42105
42133
|
setShowHint(true);
|
|
42106
42134
|
}
|
|
42107
42135
|
}
|
|
42108
|
-
}, [isComplete, resolved, totalRounds,
|
|
42109
|
-
const handleReset = () => {
|
|
42136
|
+
}, [isComplete, resolved, totalRounds, currentRound, actions, payoffMatrix, history, playRoundEvent, finishEvent, emit]);
|
|
42137
|
+
const handleReset = useCallback(() => {
|
|
42110
42138
|
setHistory([]);
|
|
42111
42139
|
setShowHint(false);
|
|
42112
|
-
|
|
42140
|
+
if (playAgainEvent) {
|
|
42141
|
+
emit(`UI:${playAgainEvent}`, {});
|
|
42142
|
+
}
|
|
42143
|
+
}, [playAgainEvent, emit]);
|
|
42144
|
+
const completedRef = useRef(false);
|
|
42145
|
+
useEffect(() => {
|
|
42146
|
+
if (result === "win" && !completedRef.current) {
|
|
42147
|
+
completedRef.current = true;
|
|
42148
|
+
emit(`UI:${completeEvent}`, { success: true, score: playerTotal });
|
|
42149
|
+
} else if (result === "none") {
|
|
42150
|
+
completedRef.current = false;
|
|
42151
|
+
}
|
|
42152
|
+
}, [result, playerTotal, completeEvent, emit]);
|
|
42113
42153
|
const getActionLabel = (id) => actions.find((a) => a.id === id)?.label ?? id;
|
|
42114
42154
|
if (!resolved) return null;
|
|
42115
42155
|
const theme = resolved.theme ?? void 0;
|
|
@@ -42278,7 +42318,7 @@ var init_PricingPageTemplate = __esm({
|
|
|
42278
42318
|
const resolved = entity && typeof entity === "object" && !Array.isArray(entity) ? entity : void 0;
|
|
42279
42319
|
if (!resolved) return null;
|
|
42280
42320
|
return /* @__PURE__ */ jsxs(VStack, { gap: "none", className: cn("w-full", className), children: [
|
|
42281
|
-
/* @__PURE__ */ jsx(
|
|
42321
|
+
resolved.hero && /* @__PURE__ */ jsx(
|
|
42282
42322
|
HeroSection,
|
|
42283
42323
|
{
|
|
42284
42324
|
tag: resolved.hero.tag,
|
|
@@ -45056,67 +45096,47 @@ var init_SimulationGraph = __esm({
|
|
|
45056
45096
|
function SimulatorBoard({
|
|
45057
45097
|
entity,
|
|
45058
45098
|
completeEvent = "PUZZLE_COMPLETE",
|
|
45099
|
+
setAEvent,
|
|
45100
|
+
setBEvent,
|
|
45101
|
+
checkEvent,
|
|
45102
|
+
playAgainEvent,
|
|
45059
45103
|
className
|
|
45060
45104
|
}) {
|
|
45061
45105
|
const { emit } = useEventBus();
|
|
45062
45106
|
const { t } = useTranslate();
|
|
45063
45107
|
const resolved = boardEntity(entity);
|
|
45064
45108
|
const parameters = Array.isArray(resolved?.parameters) ? resolved.parameters : [];
|
|
45065
|
-
const [values, setValues] = useState(() => {
|
|
45066
|
-
const init = {};
|
|
45067
|
-
for (const p2 of parameters) {
|
|
45068
|
-
init[p2.id] = p2.initial;
|
|
45069
|
-
}
|
|
45070
|
-
return init;
|
|
45071
|
-
});
|
|
45072
45109
|
const [headerError, setHeaderError] = useState(false);
|
|
45073
|
-
|
|
45074
|
-
const
|
|
45075
|
-
const
|
|
45076
|
-
const
|
|
45077
|
-
|
|
45078
|
-
|
|
45079
|
-
|
|
45080
|
-
|
|
45081
|
-
|
|
45082
|
-
|
|
45083
|
-
|
|
45084
|
-
const
|
|
45085
|
-
const
|
|
45086
|
-
const
|
|
45087
|
-
const
|
|
45088
|
-
|
|
45089
|
-
|
|
45090
|
-
|
|
45110
|
+
if (!resolved) return null;
|
|
45111
|
+
const paramA = num(resolved.paramA);
|
|
45112
|
+
const paramB = num(resolved.paramB);
|
|
45113
|
+
const output = num(resolved.output);
|
|
45114
|
+
const targetValue = num(resolved.target);
|
|
45115
|
+
const targetTolerance = num(resolved.tolerance);
|
|
45116
|
+
const attempts = num(resolved.attempts);
|
|
45117
|
+
const result = str(resolved.result);
|
|
45118
|
+
const isWin = result === "win";
|
|
45119
|
+
const isComplete = result !== "none" && result !== "";
|
|
45120
|
+
const paramAValue = parameters[0];
|
|
45121
|
+
const paramBValue = parameters[1];
|
|
45122
|
+
const sliderValues = [paramA, paramB];
|
|
45123
|
+
const sliderEvents = [setAEvent, setBEvent];
|
|
45124
|
+
const handleParameterChange = (index, value) => {
|
|
45125
|
+
if (isComplete) return;
|
|
45126
|
+
const ev = sliderEvents[index];
|
|
45127
|
+
if (ev) emit(`UI:${ev}`, { value });
|
|
45091
45128
|
};
|
|
45092
|
-
const
|
|
45093
|
-
|
|
45094
|
-
setAttempts((a) => a + 1);
|
|
45095
|
-
if (isCorrect) {
|
|
45096
|
-
emit(`UI:${completeEvent}`, { success: true, attempts: attempts + 1 });
|
|
45097
|
-
}
|
|
45129
|
+
const handleCheck = () => {
|
|
45130
|
+
if (checkEvent) emit(`UI:${checkEvent}`, {});
|
|
45098
45131
|
};
|
|
45099
|
-
const
|
|
45100
|
-
|
|
45101
|
-
if (attempts >= 2 && str(resolved?.hint)) {
|
|
45102
|
-
setShowHint(true);
|
|
45103
|
-
}
|
|
45132
|
+
const handlePlayAgain = () => {
|
|
45133
|
+
if (playAgainEvent) emit(`UI:${playAgainEvent}`, {});
|
|
45104
45134
|
};
|
|
45105
|
-
const handleFullReset = () => {
|
|
45106
|
-
const init = {};
|
|
45107
|
-
for (const p2 of parameters) {
|
|
45108
|
-
init[p2.id] = p2.initial;
|
|
45109
|
-
}
|
|
45110
|
-
setValues(init);
|
|
45111
|
-
setSubmitted(false);
|
|
45112
|
-
setAttempts(0);
|
|
45113
|
-
setShowHint(false);
|
|
45114
|
-
};
|
|
45115
|
-
if (!resolved) return null;
|
|
45116
45135
|
const theme = resolved.theme ?? void 0;
|
|
45117
45136
|
const themeBackground = theme?.background;
|
|
45118
45137
|
const headerImage = str(resolved.headerImage);
|
|
45119
45138
|
const hint = str(resolved.hint);
|
|
45139
|
+
const showHint = isComplete && !isWin && attempts >= 2 && Boolean(hint);
|
|
45120
45140
|
const outputLabel = str(resolved.outputLabel);
|
|
45121
45141
|
const outputUnit = str(resolved.outputUnit);
|
|
45122
45142
|
return /* @__PURE__ */ jsx(
|
|
@@ -45136,41 +45156,43 @@ function SimulatorBoard({
|
|
|
45136
45156
|
] }) }),
|
|
45137
45157
|
/* @__PURE__ */ jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxs(VStack, { gap: "md", children: [
|
|
45138
45158
|
/* @__PURE__ */ jsx(Typography, { variant: "small", weight: "bold", className: "uppercase tracking-wider text-muted-foreground", children: t("simulator.parameters") }),
|
|
45139
|
-
|
|
45140
|
-
/* @__PURE__ */ jsxs(
|
|
45141
|
-
/* @__PURE__ */
|
|
45142
|
-
|
|
45143
|
-
|
|
45144
|
-
|
|
45145
|
-
|
|
45146
|
-
|
|
45147
|
-
|
|
45148
|
-
/* @__PURE__ */ jsx(
|
|
45149
|
-
"input",
|
|
45150
|
-
{
|
|
45151
|
-
type: "range",
|
|
45152
|
-
min: param.min,
|
|
45153
|
-
max: param.max,
|
|
45154
|
-
step: param.step,
|
|
45155
|
-
value: values[param.id],
|
|
45156
|
-
onChange: (e) => handleParameterChange(param.id, Number(e.target.value)),
|
|
45157
|
-
disabled: submitted,
|
|
45158
|
-
className: "w-full accent-foreground"
|
|
45159
|
-
}
|
|
45160
|
-
),
|
|
45161
|
-
/* @__PURE__ */ jsxs(HStack, { justify: "between", children: [
|
|
45162
|
-
/* @__PURE__ */ jsxs(Typography, { variant: "caption", className: "text-muted-foreground", children: [
|
|
45163
|
-
param.min,
|
|
45164
|
-
" ",
|
|
45165
|
-
param.unit
|
|
45159
|
+
[paramAValue, paramBValue].map(
|
|
45160
|
+
(param, index) => param ? /* @__PURE__ */ jsxs(VStack, { gap: "xs", children: [
|
|
45161
|
+
/* @__PURE__ */ jsxs(HStack, { justify: "between", align: "center", children: [
|
|
45162
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body", weight: "medium", children: param.label }),
|
|
45163
|
+
/* @__PURE__ */ jsxs(Badge, { size: "sm", children: [
|
|
45164
|
+
sliderValues[index],
|
|
45165
|
+
" ",
|
|
45166
|
+
param.unit
|
|
45167
|
+
] })
|
|
45166
45168
|
] }),
|
|
45167
|
-
/* @__PURE__ */
|
|
45168
|
-
|
|
45169
|
-
|
|
45170
|
-
|
|
45169
|
+
/* @__PURE__ */ jsx(
|
|
45170
|
+
"input",
|
|
45171
|
+
{
|
|
45172
|
+
type: "range",
|
|
45173
|
+
min: param.min,
|
|
45174
|
+
max: param.max,
|
|
45175
|
+
step: param.step,
|
|
45176
|
+
value: sliderValues[index],
|
|
45177
|
+
onChange: (e) => handleParameterChange(index, Number(e.target.value)),
|
|
45178
|
+
disabled: isComplete,
|
|
45179
|
+
className: "w-full accent-foreground"
|
|
45180
|
+
}
|
|
45181
|
+
),
|
|
45182
|
+
/* @__PURE__ */ jsxs(HStack, { justify: "between", children: [
|
|
45183
|
+
/* @__PURE__ */ jsxs(Typography, { variant: "caption", className: "text-muted-foreground", children: [
|
|
45184
|
+
param.min,
|
|
45185
|
+
" ",
|
|
45186
|
+
param.unit
|
|
45187
|
+
] }),
|
|
45188
|
+
/* @__PURE__ */ jsxs(Typography, { variant: "caption", className: "text-muted-foreground", children: [
|
|
45189
|
+
param.max,
|
|
45190
|
+
" ",
|
|
45191
|
+
param.unit
|
|
45192
|
+
] })
|
|
45171
45193
|
] })
|
|
45172
|
-
] })
|
|
45173
|
-
|
|
45194
|
+
] }, param.id ?? index) : null
|
|
45195
|
+
)
|
|
45174
45196
|
] }) }),
|
|
45175
45197
|
/* @__PURE__ */ jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxs(VStack, { gap: "sm", align: "center", children: [
|
|
45176
45198
|
/* @__PURE__ */ jsx(Typography, { variant: "small", weight: "bold", className: "uppercase tracking-wider text-muted-foreground", children: outputLabel }),
|
|
@@ -45179,9 +45201,9 @@ function SimulatorBoard({
|
|
|
45179
45201
|
" ",
|
|
45180
45202
|
outputUnit
|
|
45181
45203
|
] }),
|
|
45182
|
-
|
|
45183
|
-
/* @__PURE__ */ jsx(Icon, { icon:
|
|
45184
|
-
/* @__PURE__ */ jsx(Typography, { variant: "body", className:
|
|
45204
|
+
isComplete && /* @__PURE__ */ jsxs(HStack, { gap: "xs", align: "center", children: [
|
|
45205
|
+
/* @__PURE__ */ jsx(Icon, { icon: isWin ? CheckCircle : XCircle, size: "sm", className: isWin ? "text-success" : "text-error" }),
|
|
45206
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body", className: isWin ? "text-success" : "text-error", children: isWin ? str(resolved.successMessage) || t("simulator.correct") : str(resolved.failMessage) || t("simulator.incorrect") })
|
|
45185
45207
|
] }),
|
|
45186
45208
|
/* @__PURE__ */ jsxs(Typography, { variant: "caption", className: "text-muted-foreground", children: [
|
|
45187
45209
|
t("simulator.target"),
|
|
@@ -45196,11 +45218,11 @@ function SimulatorBoard({
|
|
|
45196
45218
|
] }) }),
|
|
45197
45219
|
showHint && hint && /* @__PURE__ */ jsx(Card, { className: "p-4 border-l-4 border-l-warning", children: /* @__PURE__ */ jsx(Typography, { variant: "body", children: hint }) }),
|
|
45198
45220
|
/* @__PURE__ */ jsxs(HStack, { gap: "sm", justify: "center", children: [
|
|
45199
|
-
!
|
|
45221
|
+
!isComplete ? /* @__PURE__ */ jsxs(Button, { variant: "primary", onClick: handleCheck, children: [
|
|
45200
45222
|
/* @__PURE__ */ jsx(Icon, { icon: Play, size: "sm" }),
|
|
45201
45223
|
t("simulator.simulate")
|
|
45202
|
-
] }) :
|
|
45203
|
-
/* @__PURE__ */ jsxs(Button, { variant: "secondary", onClick:
|
|
45224
|
+
] }) : null,
|
|
45225
|
+
/* @__PURE__ */ jsxs(Button, { variant: "secondary", onClick: handlePlayAgain, children: [
|
|
45204
45226
|
/* @__PURE__ */ jsx(Icon, { icon: RotateCcw, size: "sm" }),
|
|
45205
45227
|
t("simulator.reset")
|
|
45206
45228
|
] })
|