@almadar/ui 5.21.12 → 5.22.2
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 +919 -631
- package/dist/avl/index.js +919 -631
- package/dist/components/core/molecules/CalendarGrid.d.ts +3 -10
- package/dist/components/core/molecules/ContentRenderer.d.ts +2 -2
- package/dist/components/core/molecules/DataGrid.d.ts +11 -20
- package/dist/components/core/molecules/DataList.d.ts +9 -15
- package/dist/components/core/molecules/FormSection.d.ts +4 -4
- package/dist/components/core/molecules/PositionedCanvas.d.ts +4 -17
- package/dist/components/core/molecules/ReplyTree.d.ts +2 -13
- package/dist/components/core/molecules/RichBlockEditor.d.ts +3 -6
- package/dist/components/core/molecules/SortableList.d.ts +7 -5
- package/dist/components/core/molecules/TableView.d.ts +7 -7
- package/dist/components/core/molecules/index.d.ts +3 -3
- package/dist/components/core/molecules/useDataDnd.d.ts +5 -5
- package/dist/components/core/organisms/CardGrid.d.ts +5 -2
- package/dist/components/core/organisms/CaseStudyOrganism.d.ts +4 -3
- package/dist/components/core/organisms/DataTable.d.ts +4 -2
- package/dist/components/core/organisms/DetailPanel.d.ts +6 -6
- package/dist/components/core/organisms/FeatureGridOrganism.d.ts +4 -3
- package/dist/components/core/organisms/HeroOrganism.d.ts +4 -5
- package/dist/components/core/organisms/List.d.ts +5 -2
- package/dist/components/core/organisms/MasterDetail.d.ts +4 -2
- package/dist/components/core/organisms/MediaGallery.d.ts +4 -2
- package/dist/components/core/organisms/ShowcaseOrganism.d.ts +4 -3
- package/dist/components/core/organisms/StatCard.d.ts +5 -2
- package/dist/components/core/organisms/StepFlowOrganism.d.ts +4 -3
- package/dist/components/core/organisms/Timeline.d.ts +2 -2
- package/dist/components/core/organisms/book/index.d.ts +1 -1
- package/dist/components/core/organisms/book/types.d.ts +28 -48
- package/dist/components/core/organisms/index.d.ts +1 -2
- package/dist/components/core/organisms/layout/DashboardGrid.d.ts +2 -2
- package/dist/components/core/organisms/marketing-types.d.ts +5 -94
- package/dist/components/core/organisms/types.d.ts +9 -27
- package/dist/components/core/templates/index.d.ts +6 -6
- package/dist/components/game/organisms/BattleBoard.d.ts +14 -90
- package/dist/components/game/organisms/CastleBoard.d.ts +7 -21
- package/dist/components/game/organisms/UncontrolledBattleBoard.d.ts +2 -7
- package/dist/components/game/organisms/WorldMapBoard.d.ts +13 -59
- package/dist/components/game/organisms/boardEntity.d.ts +44 -0
- package/dist/components/game/organisms/hooks/useBattleState.d.ts +7 -7
- package/dist/components/game/organisms/index.d.ts +3 -3
- package/dist/components/game/organisms/puzzles/builder/BuilderBoard.d.ts +7 -20
- package/dist/components/game/organisms/puzzles/builder/index.d.ts +1 -1
- package/dist/components/game/organisms/puzzles/classifier/ClassifierBoard.d.ts +7 -20
- package/dist/components/game/organisms/puzzles/classifier/index.d.ts +1 -1
- package/dist/components/game/organisms/puzzles/debugger/DebuggerBoard.d.ts +6 -22
- package/dist/components/game/organisms/puzzles/debugger/index.d.ts +1 -1
- package/dist/components/game/organisms/puzzles/event-handler/EventHandlerBoard.d.ts +6 -33
- package/dist/components/game/organisms/puzzles/event-handler/ObjectRulePanel.d.ts +3 -21
- package/dist/components/game/organisms/puzzles/event-handler/index.d.ts +2 -2
- package/dist/components/game/organisms/puzzles/event-handler/puzzleObject.d.ts +21 -0
- package/dist/components/game/organisms/puzzles/negotiator/NegotiatorBoard.d.ts +8 -24
- package/dist/components/game/organisms/puzzles/negotiator/index.d.ts +1 -1
- package/dist/components/game/organisms/puzzles/sequencer/ActionTile.d.ts +2 -2
- package/dist/components/game/organisms/puzzles/sequencer/SequencerBoard.d.ts +7 -36
- package/dist/components/game/organisms/puzzles/sequencer/index.d.ts +1 -1
- package/dist/components/game/organisms/puzzles/simulator/SimulatorBoard.d.ts +6 -25
- package/dist/components/game/organisms/puzzles/simulator/index.d.ts +1 -1
- package/dist/components/game/organisms/puzzles/state-architect/StateArchitectBoard.d.ts +7 -40
- package/dist/components/game/organisms/puzzles/state-architect/VariablePanel.d.ts +3 -9
- package/dist/components/game/organisms/puzzles/state-architect/index.d.ts +2 -2
- package/dist/components/game/organisms/three/index.cjs +35 -21
- package/dist/components/game/organisms/three/index.js +35 -21
- package/dist/components/game/templates/BattleTemplate.d.ts +2 -3
- package/dist/components/game/templates/CastleTemplate.d.ts +2 -3
- package/dist/components/game/templates/GameCanvas3DBattleTemplate.d.ts +1 -16
- package/dist/components/game/templates/GameCanvas3DCastleTemplate.d.ts +1 -18
- package/dist/components/game/templates/GameCanvas3DWorldMapTemplate.d.ts +1 -14
- package/dist/components/game/templates/GameTemplate.d.ts +1 -6
- package/dist/components/game/templates/WorldMapTemplate.d.ts +2 -3
- package/dist/components/index.cjs +2016 -1668
- package/dist/components/index.js +1128 -780
- package/dist/components/marketing/organisms/PricingOrganism.d.ts +4 -3
- package/dist/components/marketing/organisms/StatsOrganism.d.ts +4 -3
- package/dist/components/marketing/organisms/TeamOrganism.d.ts +4 -3
- package/dist/components/marketing/organisms/book/BookChapterView.d.ts +5 -2
- package/dist/components/marketing/organisms/book/BookTableOfContents.d.ts +3 -2
- package/dist/components/marketing/organisms/book/BookViewer.d.ts +4 -4
- package/dist/components/marketing/templates/AboutPageTemplate.d.ts +32 -6
- package/dist/components/marketing/templates/FeatureDetailPageTemplate.d.ts +14 -4
- package/dist/components/marketing/templates/LandingPageTemplate.d.ts +47 -9
- package/dist/components/marketing/templates/PricingPageTemplate.d.ts +23 -5
- package/dist/providers/index.cjs +912 -624
- package/dist/providers/index.js +912 -624
- package/dist/runtime/index.cjs +914 -626
- package/dist/runtime/index.js +914 -626
- package/package.json +2 -2
package/dist/components/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
2
|
-
import * as
|
|
3
|
-
import
|
|
2
|
+
import * as React80 from 'react';
|
|
3
|
+
import React80__default, { useContext, useMemo, useRef, useEffect, useCallback, Suspense, useState, lazy, createContext, useLayoutEffect, useId, useSyncExternalStore } from 'react';
|
|
4
4
|
import { clsx } from 'clsx';
|
|
5
5
|
import { twMerge } from 'tailwind-merge';
|
|
6
6
|
import { EventBusContext, useTraitScope, TraitScopeProvider } from '@almadar/ui/providers';
|
|
@@ -211,7 +211,7 @@ var init_SvgFlow = __esm({
|
|
|
211
211
|
opacity = 1,
|
|
212
212
|
className
|
|
213
213
|
}) => {
|
|
214
|
-
const markerId =
|
|
214
|
+
const markerId = React80__default.useMemo(() => {
|
|
215
215
|
flowIdCounter += 1;
|
|
216
216
|
return `almadar-flow-arrow-${flowIdCounter}`;
|
|
217
217
|
}, []);
|
|
@@ -260,7 +260,7 @@ var init_SvgGrid = __esm({
|
|
|
260
260
|
x,
|
|
261
261
|
y,
|
|
262
262
|
cols = 4,
|
|
263
|
-
rows = 3,
|
|
263
|
+
rows: rows2 = 3,
|
|
264
264
|
spacing = 20,
|
|
265
265
|
nodeRadius = 3,
|
|
266
266
|
color = "var(--color-primary)",
|
|
@@ -269,7 +269,7 @@ var init_SvgGrid = __esm({
|
|
|
269
269
|
highlights = []
|
|
270
270
|
}) => {
|
|
271
271
|
const highlightSet = new Set(highlights);
|
|
272
|
-
return /* @__PURE__ */ jsx("g", { className, opacity, children: Array.from({ length:
|
|
272
|
+
return /* @__PURE__ */ jsx("g", { className, opacity, children: Array.from({ length: rows2 }).map(
|
|
273
273
|
(_, row) => Array.from({ length: cols }).map((_2, col) => {
|
|
274
274
|
const index = row * cols + col;
|
|
275
275
|
const isHighlighted = highlightSet.has(index);
|
|
@@ -754,7 +754,7 @@ var init_SvgRing = __esm({
|
|
|
754
754
|
className,
|
|
755
755
|
label
|
|
756
756
|
}) => {
|
|
757
|
-
const gradientId =
|
|
757
|
+
const gradientId = React80__default.useMemo(() => {
|
|
758
758
|
ringIdCounter += 1;
|
|
759
759
|
return `almadar-ring-glow-${ringIdCounter}`;
|
|
760
760
|
}, []);
|
|
@@ -1836,7 +1836,7 @@ var init_Icon = __esm({
|
|
|
1836
1836
|
const directIcon = typeof icon === "string" ? void 0 : icon;
|
|
1837
1837
|
const effectiveName = typeof icon === "string" ? icon : name;
|
|
1838
1838
|
const family = useIconFamily();
|
|
1839
|
-
const RenderedComponent =
|
|
1839
|
+
const RenderedComponent = React80__default.useMemo(() => {
|
|
1840
1840
|
if (directIcon) return null;
|
|
1841
1841
|
return effectiveName ? resolveIconForFamily(effectiveName, family) : null;
|
|
1842
1842
|
}, [directIcon, effectiveName, family]);
|
|
@@ -1894,7 +1894,7 @@ function resolveIconProp(value, sizeClass) {
|
|
|
1894
1894
|
const IconComp = value;
|
|
1895
1895
|
return /* @__PURE__ */ jsx(IconComp, { className: sizeClass });
|
|
1896
1896
|
}
|
|
1897
|
-
if (
|
|
1897
|
+
if (React80__default.isValidElement(value)) {
|
|
1898
1898
|
return value;
|
|
1899
1899
|
}
|
|
1900
1900
|
if (typeof value === "object" && value !== null && "render" in value) {
|
|
@@ -1970,7 +1970,7 @@ var init_Button = __esm({
|
|
|
1970
1970
|
md: "h-icon-default w-icon-default",
|
|
1971
1971
|
lg: "h-icon-default w-icon-default"
|
|
1972
1972
|
};
|
|
1973
|
-
Button =
|
|
1973
|
+
Button = React80__default.forwardRef(
|
|
1974
1974
|
({
|
|
1975
1975
|
className,
|
|
1976
1976
|
variant = "primary",
|
|
@@ -2036,7 +2036,7 @@ var init_Input = __esm({
|
|
|
2036
2036
|
"components/core/atoms/Input.tsx"() {
|
|
2037
2037
|
init_cn();
|
|
2038
2038
|
init_Icon();
|
|
2039
|
-
Input =
|
|
2039
|
+
Input = React80__default.forwardRef(
|
|
2040
2040
|
({
|
|
2041
2041
|
className,
|
|
2042
2042
|
inputType,
|
|
@@ -2049,7 +2049,7 @@ var init_Input = __esm({
|
|
|
2049
2049
|
onClear,
|
|
2050
2050
|
value,
|
|
2051
2051
|
options,
|
|
2052
|
-
rows = 3,
|
|
2052
|
+
rows: rows2 = 3,
|
|
2053
2053
|
onChange,
|
|
2054
2054
|
...props
|
|
2055
2055
|
}, ref) => {
|
|
@@ -2099,7 +2099,7 @@ var init_Input = __esm({
|
|
|
2099
2099
|
ref,
|
|
2100
2100
|
value,
|
|
2101
2101
|
onChange,
|
|
2102
|
-
rows,
|
|
2102
|
+
rows: rows2,
|
|
2103
2103
|
className: baseClassName,
|
|
2104
2104
|
...props
|
|
2105
2105
|
}
|
|
@@ -2157,7 +2157,7 @@ var Label;
|
|
|
2157
2157
|
var init_Label = __esm({
|
|
2158
2158
|
"components/core/atoms/Label.tsx"() {
|
|
2159
2159
|
init_cn();
|
|
2160
|
-
Label =
|
|
2160
|
+
Label = React80__default.forwardRef(
|
|
2161
2161
|
({ className, required, children, ...props }, ref) => {
|
|
2162
2162
|
return /* @__PURE__ */ jsxs(
|
|
2163
2163
|
"label",
|
|
@@ -2183,7 +2183,7 @@ var Textarea;
|
|
|
2183
2183
|
var init_Textarea = __esm({
|
|
2184
2184
|
"components/core/atoms/Textarea.tsx"() {
|
|
2185
2185
|
init_cn();
|
|
2186
|
-
Textarea =
|
|
2186
|
+
Textarea = React80__default.forwardRef(
|
|
2187
2187
|
({ className, error, ...props }, ref) => {
|
|
2188
2188
|
return /* @__PURE__ */ jsx(
|
|
2189
2189
|
"textarea",
|
|
@@ -2213,7 +2213,7 @@ var init_Select = __esm({
|
|
|
2213
2213
|
"components/core/atoms/Select.tsx"() {
|
|
2214
2214
|
init_cn();
|
|
2215
2215
|
init_Icon();
|
|
2216
|
-
Select =
|
|
2216
|
+
Select = React80__default.forwardRef(
|
|
2217
2217
|
({ className, options, placeholder, error, ...props }, ref) => {
|
|
2218
2218
|
return /* @__PURE__ */ jsxs("div", { className: "relative", children: [
|
|
2219
2219
|
/* @__PURE__ */ jsxs(
|
|
@@ -2255,7 +2255,7 @@ var Checkbox;
|
|
|
2255
2255
|
var init_Checkbox = __esm({
|
|
2256
2256
|
"components/core/atoms/Checkbox.tsx"() {
|
|
2257
2257
|
init_cn();
|
|
2258
|
-
Checkbox =
|
|
2258
|
+
Checkbox = React80__default.forwardRef(
|
|
2259
2259
|
({ className, label, id, ...props }, ref) => {
|
|
2260
2260
|
const inputId = id || `checkbox-${Math.random().toString(36).substr(2, 9)}`;
|
|
2261
2261
|
return /* @__PURE__ */ jsxs("div", { className: "flex items-center", children: [
|
|
@@ -2346,7 +2346,7 @@ var init_Card = __esm({
|
|
|
2346
2346
|
chip: "shadow-none rounded-pill border-[length:var(--border-width)] border-border",
|
|
2347
2347
|
"tile-image-first": "p-0 overflow-hidden"
|
|
2348
2348
|
};
|
|
2349
|
-
Card =
|
|
2349
|
+
Card = React80__default.forwardRef(
|
|
2350
2350
|
({
|
|
2351
2351
|
className,
|
|
2352
2352
|
variant = "bordered",
|
|
@@ -2384,9 +2384,9 @@ var init_Card = __esm({
|
|
|
2384
2384
|
}
|
|
2385
2385
|
);
|
|
2386
2386
|
Card.displayName = "Card";
|
|
2387
|
-
CardHeader =
|
|
2387
|
+
CardHeader = React80__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("mb-4", className), ...props }));
|
|
2388
2388
|
CardHeader.displayName = "CardHeader";
|
|
2389
|
-
CardTitle =
|
|
2389
|
+
CardTitle = React80__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
2390
2390
|
"h3",
|
|
2391
2391
|
{
|
|
2392
2392
|
ref,
|
|
@@ -2399,11 +2399,11 @@ var init_Card = __esm({
|
|
|
2399
2399
|
}
|
|
2400
2400
|
));
|
|
2401
2401
|
CardTitle.displayName = "CardTitle";
|
|
2402
|
-
CardContent =
|
|
2402
|
+
CardContent = React80__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("", className), ...props }));
|
|
2403
2403
|
CardContent.displayName = "CardContent";
|
|
2404
2404
|
CardBody = CardContent;
|
|
2405
2405
|
CardBody.displayName = "CardBody";
|
|
2406
|
-
CardFooter =
|
|
2406
|
+
CardFooter = React80__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
2407
2407
|
"div",
|
|
2408
2408
|
{
|
|
2409
2409
|
ref,
|
|
@@ -2456,7 +2456,7 @@ var init_Badge = __esm({
|
|
|
2456
2456
|
md: "px-2.5 py-1 text-sm",
|
|
2457
2457
|
lg: "px-3 py-1.5 text-base"
|
|
2458
2458
|
};
|
|
2459
|
-
Badge =
|
|
2459
|
+
Badge = React80__default.forwardRef(
|
|
2460
2460
|
({ className, variant = "default", size = "sm", amount, label, icon, children, onRemove, removeLabel, ...props }, ref) => {
|
|
2461
2461
|
const iconSizes3 = {
|
|
2462
2462
|
sm: "h-icon-default w-icon-default",
|
|
@@ -2549,7 +2549,7 @@ var init_FilterPill = __esm({
|
|
|
2549
2549
|
md: "w-3.5 h-3.5",
|
|
2550
2550
|
lg: "w-4 h-4"
|
|
2551
2551
|
};
|
|
2552
|
-
FilterPill =
|
|
2552
|
+
FilterPill = React80__default.forwardRef(
|
|
2553
2553
|
({
|
|
2554
2554
|
className,
|
|
2555
2555
|
variant = "default",
|
|
@@ -2626,7 +2626,7 @@ var init_Spinner = __esm({
|
|
|
2626
2626
|
md: "h-6 w-6",
|
|
2627
2627
|
lg: "h-8 w-8"
|
|
2628
2628
|
};
|
|
2629
|
-
Spinner =
|
|
2629
|
+
Spinner = React80__default.forwardRef(
|
|
2630
2630
|
({ className, size = "md", ...props }, ref) => {
|
|
2631
2631
|
return /* @__PURE__ */ jsx(
|
|
2632
2632
|
"div",
|
|
@@ -2910,7 +2910,7 @@ var init_Box = __esm({
|
|
|
2910
2910
|
fixed: "fixed",
|
|
2911
2911
|
sticky: "sticky"
|
|
2912
2912
|
};
|
|
2913
|
-
Box =
|
|
2913
|
+
Box = React80__default.forwardRef(
|
|
2914
2914
|
({
|
|
2915
2915
|
padding,
|
|
2916
2916
|
paddingX,
|
|
@@ -2960,7 +2960,7 @@ var init_Box = __esm({
|
|
|
2960
2960
|
onMouseLeave?.(e);
|
|
2961
2961
|
}, [hoverEvent, eventBus, onMouseLeave]);
|
|
2962
2962
|
const isClickable = action || onClick;
|
|
2963
|
-
return
|
|
2963
|
+
return React80__default.createElement(
|
|
2964
2964
|
Component,
|
|
2965
2965
|
{
|
|
2966
2966
|
ref,
|
|
@@ -3282,7 +3282,7 @@ var init_Radio = __esm({
|
|
|
3282
3282
|
md: "w-2.5 h-2.5",
|
|
3283
3283
|
lg: "w-3 h-3"
|
|
3284
3284
|
};
|
|
3285
|
-
Radio =
|
|
3285
|
+
Radio = React80__default.forwardRef(
|
|
3286
3286
|
({
|
|
3287
3287
|
label,
|
|
3288
3288
|
helperText,
|
|
@@ -3299,12 +3299,12 @@ var init_Radio = __esm({
|
|
|
3299
3299
|
onChange,
|
|
3300
3300
|
...props
|
|
3301
3301
|
}, ref) => {
|
|
3302
|
-
const reactId =
|
|
3302
|
+
const reactId = React80__default.useId();
|
|
3303
3303
|
const baseId = id || `radio-${reactId}`;
|
|
3304
3304
|
const hasError = !!error;
|
|
3305
3305
|
const eventBus = useEventBus();
|
|
3306
|
-
const [selected, setSelected] =
|
|
3307
|
-
|
|
3306
|
+
const [selected, setSelected] = React80__default.useState(value);
|
|
3307
|
+
React80__default.useEffect(() => {
|
|
3308
3308
|
if (value !== void 0) setSelected(value);
|
|
3309
3309
|
}, [value]);
|
|
3310
3310
|
const pick = (next, e) => {
|
|
@@ -3486,7 +3486,7 @@ var init_Switch = __esm({
|
|
|
3486
3486
|
"components/core/atoms/Switch.tsx"() {
|
|
3487
3487
|
"use client";
|
|
3488
3488
|
init_cn();
|
|
3489
|
-
Switch =
|
|
3489
|
+
Switch = React80.forwardRef(
|
|
3490
3490
|
({
|
|
3491
3491
|
checked,
|
|
3492
3492
|
defaultChecked = false,
|
|
@@ -3497,10 +3497,10 @@ var init_Switch = __esm({
|
|
|
3497
3497
|
name,
|
|
3498
3498
|
className
|
|
3499
3499
|
}, ref) => {
|
|
3500
|
-
const [isChecked, setIsChecked] =
|
|
3500
|
+
const [isChecked, setIsChecked] = React80.useState(
|
|
3501
3501
|
checked !== void 0 ? checked : defaultChecked
|
|
3502
3502
|
);
|
|
3503
|
-
|
|
3503
|
+
React80.useEffect(() => {
|
|
3504
3504
|
if (checked !== void 0) {
|
|
3505
3505
|
setIsChecked(checked);
|
|
3506
3506
|
}
|
|
@@ -4371,7 +4371,7 @@ var Dialog;
|
|
|
4371
4371
|
var init_Dialog = __esm({
|
|
4372
4372
|
"components/core/atoms/Dialog.tsx"() {
|
|
4373
4373
|
init_cn();
|
|
4374
|
-
Dialog =
|
|
4374
|
+
Dialog = React80__default.forwardRef(
|
|
4375
4375
|
({
|
|
4376
4376
|
role = "dialog",
|
|
4377
4377
|
"aria-modal": ariaModal = true,
|
|
@@ -4397,7 +4397,7 @@ var Aside;
|
|
|
4397
4397
|
var init_Aside = __esm({
|
|
4398
4398
|
"components/core/atoms/Aside.tsx"() {
|
|
4399
4399
|
init_cn();
|
|
4400
|
-
Aside =
|
|
4400
|
+
Aside = React80__default.forwardRef(
|
|
4401
4401
|
({ className, children, ...rest }, ref) => /* @__PURE__ */ jsx("aside", { ref, className: cn(className), ...rest, children })
|
|
4402
4402
|
);
|
|
4403
4403
|
Aside.displayName = "Aside";
|
|
@@ -4475,8 +4475,8 @@ var init_LawReferenceTooltip = __esm({
|
|
|
4475
4475
|
className
|
|
4476
4476
|
}) => {
|
|
4477
4477
|
const { t } = useTranslate();
|
|
4478
|
-
const [isVisible, setIsVisible] =
|
|
4479
|
-
const timeoutRef =
|
|
4478
|
+
const [isVisible, setIsVisible] = React80__default.useState(false);
|
|
4479
|
+
const timeoutRef = React80__default.useRef(null);
|
|
4480
4480
|
const handleMouseEnter = () => {
|
|
4481
4481
|
if (timeoutRef.current) clearTimeout(timeoutRef.current);
|
|
4482
4482
|
timeoutRef.current = setTimeout(() => setIsVisible(true), 200);
|
|
@@ -4485,7 +4485,7 @@ var init_LawReferenceTooltip = __esm({
|
|
|
4485
4485
|
if (timeoutRef.current) clearTimeout(timeoutRef.current);
|
|
4486
4486
|
setIsVisible(false);
|
|
4487
4487
|
};
|
|
4488
|
-
|
|
4488
|
+
React80__default.useEffect(() => {
|
|
4489
4489
|
return () => {
|
|
4490
4490
|
if (timeoutRef.current) clearTimeout(timeoutRef.current);
|
|
4491
4491
|
};
|
|
@@ -4695,7 +4695,7 @@ var init_StatusDot = __esm({
|
|
|
4695
4695
|
md: "w-2.5 h-2.5",
|
|
4696
4696
|
lg: "w-3 h-3"
|
|
4697
4697
|
};
|
|
4698
|
-
StatusDot =
|
|
4698
|
+
StatusDot = React80__default.forwardRef(
|
|
4699
4699
|
({ className, status = "offline", pulse = false, size = "md", label, ...props }, ref) => {
|
|
4700
4700
|
return /* @__PURE__ */ jsx(
|
|
4701
4701
|
"span",
|
|
@@ -4749,7 +4749,7 @@ var init_TrendIndicator = __esm({
|
|
|
4749
4749
|
down: "trending-down",
|
|
4750
4750
|
flat: "arrow-right"
|
|
4751
4751
|
};
|
|
4752
|
-
TrendIndicator =
|
|
4752
|
+
TrendIndicator = React80__default.forwardRef(
|
|
4753
4753
|
({
|
|
4754
4754
|
className,
|
|
4755
4755
|
value,
|
|
@@ -4816,7 +4816,7 @@ var init_RangeSlider = __esm({
|
|
|
4816
4816
|
md: "w-4 h-4",
|
|
4817
4817
|
lg: "w-5 h-5"
|
|
4818
4818
|
};
|
|
4819
|
-
RangeSlider =
|
|
4819
|
+
RangeSlider = React80__default.forwardRef(
|
|
4820
4820
|
({
|
|
4821
4821
|
className,
|
|
4822
4822
|
min = 0,
|
|
@@ -5412,7 +5412,7 @@ var init_ContentSection = __esm({
|
|
|
5412
5412
|
md: "py-16",
|
|
5413
5413
|
lg: "py-24"
|
|
5414
5414
|
};
|
|
5415
|
-
ContentSection =
|
|
5415
|
+
ContentSection = React80__default.forwardRef(
|
|
5416
5416
|
({ children, background = "default", padding = "lg", id, className }, ref) => {
|
|
5417
5417
|
return /* @__PURE__ */ jsx(
|
|
5418
5418
|
Box,
|
|
@@ -5946,7 +5946,7 @@ var init_AnimatedReveal = __esm({
|
|
|
5946
5946
|
"scale-up": { opacity: 1, transform: "scale(1) translateY(0)" },
|
|
5947
5947
|
"none": {}
|
|
5948
5948
|
};
|
|
5949
|
-
AnimatedReveal =
|
|
5949
|
+
AnimatedReveal = React80__default.forwardRef(
|
|
5950
5950
|
({
|
|
5951
5951
|
trigger = "scroll",
|
|
5952
5952
|
animation = "fade-up",
|
|
@@ -6106,7 +6106,7 @@ var init_AnimatedGraphic = __esm({
|
|
|
6106
6106
|
"components/marketing/atoms/AnimatedGraphic.tsx"() {
|
|
6107
6107
|
"use client";
|
|
6108
6108
|
init_cn();
|
|
6109
|
-
AnimatedGraphic =
|
|
6109
|
+
AnimatedGraphic = React80__default.forwardRef(
|
|
6110
6110
|
({
|
|
6111
6111
|
src,
|
|
6112
6112
|
svgContent,
|
|
@@ -6129,7 +6129,7 @@ var init_AnimatedGraphic = __esm({
|
|
|
6129
6129
|
const fetchedSvg = useFetchedSvg(svgContent ? void 0 : src);
|
|
6130
6130
|
const resolvedSvg = svgContent ?? fetchedSvg;
|
|
6131
6131
|
const prevAnimateRef = useRef(animate);
|
|
6132
|
-
const setRef =
|
|
6132
|
+
const setRef = React80__default.useCallback(
|
|
6133
6133
|
(node) => {
|
|
6134
6134
|
containerRef.current = node;
|
|
6135
6135
|
if (typeof ref === "function") ref(node);
|
|
@@ -6819,7 +6819,7 @@ var init_ErrorBoundary = __esm({
|
|
|
6819
6819
|
}
|
|
6820
6820
|
);
|
|
6821
6821
|
};
|
|
6822
|
-
ErrorBoundary = class extends
|
|
6822
|
+
ErrorBoundary = class extends React80__default.Component {
|
|
6823
6823
|
constructor(props) {
|
|
6824
6824
|
super(props);
|
|
6825
6825
|
__publicField(this, "reset", () => {
|
|
@@ -6864,15 +6864,15 @@ function HeaderSkeleton({ className }) {
|
|
|
6864
6864
|
] })
|
|
6865
6865
|
] });
|
|
6866
6866
|
}
|
|
6867
|
-
function TableSkeleton({ rows = 5, columns = 4, className }) {
|
|
6867
|
+
function TableSkeleton({ rows: rows2 = 5, columns = 4, className }) {
|
|
6868
6868
|
return /* @__PURE__ */ jsxs(VStack, { gap: "none", className: cn("border border-border rounded-lg overflow-hidden", className), children: [
|
|
6869
6869
|
/* @__PURE__ */ jsx(HStack, { className: "px-4 py-3 bg-muted/30 border-b border-border", children: Array.from({ length: columns }).map((_, i) => /* @__PURE__ */ jsx(SkeletonBlock, { className: "h-4 flex-1 mx-2" }, i)) }),
|
|
6870
|
-
Array.from({ length:
|
|
6870
|
+
Array.from({ length: rows2 }).map((_, rowIdx) => /* @__PURE__ */ jsx(
|
|
6871
6871
|
HStack,
|
|
6872
6872
|
{
|
|
6873
6873
|
className: cn(
|
|
6874
6874
|
"px-4 py-3",
|
|
6875
|
-
rowIdx <
|
|
6875
|
+
rowIdx < rows2 - 1 && "border-b border-border"
|
|
6876
6876
|
),
|
|
6877
6877
|
children: Array.from({ length: columns }).map((_2, colIdx) => /* @__PURE__ */ jsx(SkeletonLine, { className: "flex-1 mx-2" }, colIdx))
|
|
6878
6878
|
},
|
|
@@ -6920,18 +6920,18 @@ function CardSkeleton({ className }) {
|
|
|
6920
6920
|
}
|
|
6921
6921
|
);
|
|
6922
6922
|
}
|
|
6923
|
-
function TextSkeleton({ rows = 3, className }) {
|
|
6924
|
-
return /* @__PURE__ */ jsx(VStack, { gap: "sm", className, children: Array.from({ length:
|
|
6923
|
+
function TextSkeleton({ rows: rows2 = 3, className }) {
|
|
6924
|
+
return /* @__PURE__ */ jsx(VStack, { gap: "sm", className, children: Array.from({ length: rows2 }).map((_, i) => /* @__PURE__ */ jsx(
|
|
6925
6925
|
SkeletonLine,
|
|
6926
6926
|
{
|
|
6927
|
-
className: i ===
|
|
6927
|
+
className: i === rows2 - 1 ? "w-2/3" : "w-full"
|
|
6928
6928
|
},
|
|
6929
6929
|
i
|
|
6930
6930
|
)) });
|
|
6931
6931
|
}
|
|
6932
6932
|
function Skeleton({
|
|
6933
6933
|
variant = "text",
|
|
6934
|
-
rows,
|
|
6934
|
+
rows: rows2,
|
|
6935
6935
|
columns,
|
|
6936
6936
|
fields,
|
|
6937
6937
|
className
|
|
@@ -6941,15 +6941,15 @@ function Skeleton({
|
|
|
6941
6941
|
case "header":
|
|
6942
6942
|
return /* @__PURE__ */ jsx(HeaderSkeleton, { className });
|
|
6943
6943
|
case "table":
|
|
6944
|
-
return /* @__PURE__ */ jsx(TableSkeleton, { rows, columns, className });
|
|
6944
|
+
return /* @__PURE__ */ jsx(TableSkeleton, { rows: rows2, columns, className });
|
|
6945
6945
|
case "form":
|
|
6946
6946
|
return /* @__PURE__ */ jsx(FormSkeleton, { fields, className });
|
|
6947
6947
|
case "card":
|
|
6948
6948
|
return /* @__PURE__ */ jsx(CardSkeleton, { className });
|
|
6949
6949
|
case "text":
|
|
6950
|
-
return /* @__PURE__ */ jsx(TextSkeleton, { rows, className });
|
|
6950
|
+
return /* @__PURE__ */ jsx(TextSkeleton, { rows: rows2, className });
|
|
6951
6951
|
default:
|
|
6952
|
-
return /* @__PURE__ */ jsx(TextSkeleton, { rows, className });
|
|
6952
|
+
return /* @__PURE__ */ jsx(TextSkeleton, { rows: rows2, className });
|
|
6953
6953
|
}
|
|
6954
6954
|
}
|
|
6955
6955
|
var pulseClass;
|
|
@@ -7858,8 +7858,8 @@ var init_Tooltip = __esm({
|
|
|
7858
7858
|
if (hideTimeoutRef.current) clearTimeout(hideTimeoutRef.current);
|
|
7859
7859
|
};
|
|
7860
7860
|
}, []);
|
|
7861
|
-
const triggerElement =
|
|
7862
|
-
const trigger =
|
|
7861
|
+
const triggerElement = React80__default.isValidElement(children) ? children : /* @__PURE__ */ jsx("span", { children });
|
|
7862
|
+
const trigger = React80__default.cloneElement(triggerElement, {
|
|
7863
7863
|
ref: triggerRef,
|
|
7864
7864
|
onMouseEnter: handleMouseEnter,
|
|
7865
7865
|
onMouseLeave: handleMouseLeave,
|
|
@@ -8014,8 +8014,8 @@ var init_Popover = __esm({
|
|
|
8014
8014
|
onMouseEnter: handleOpen,
|
|
8015
8015
|
onMouseLeave: handleClose
|
|
8016
8016
|
};
|
|
8017
|
-
const childElement =
|
|
8018
|
-
const triggerElement =
|
|
8017
|
+
const childElement = React80__default.isValidElement(children) ? children : /* @__PURE__ */ jsx("span", { children });
|
|
8018
|
+
const triggerElement = React80__default.cloneElement(
|
|
8019
8019
|
childElement,
|
|
8020
8020
|
{
|
|
8021
8021
|
ref: triggerRef,
|
|
@@ -8142,8 +8142,8 @@ var init_Menu = __esm({
|
|
|
8142
8142
|
};
|
|
8143
8143
|
const effectivePosition = direction === "rtl" ? rtlMirror[position] ?? position : position;
|
|
8144
8144
|
const subMenuSideClass = direction === "rtl" ? "right-full mr-2" : "left-full ml-2";
|
|
8145
|
-
const triggerChild =
|
|
8146
|
-
const triggerElement =
|
|
8145
|
+
const triggerChild = React80__default.isValidElement(trigger) ? trigger : /* @__PURE__ */ jsx(Typography, { variant: "small", as: "span", children: trigger });
|
|
8146
|
+
const triggerElement = React80__default.cloneElement(
|
|
8147
8147
|
triggerChild,
|
|
8148
8148
|
{
|
|
8149
8149
|
ref: triggerRef,
|
|
@@ -8550,13 +8550,13 @@ var init_MapView = __esm({
|
|
|
8550
8550
|
shadowSize: [41, 41]
|
|
8551
8551
|
});
|
|
8552
8552
|
L.Marker.prototype.options.icon = defaultIcon;
|
|
8553
|
-
const { useEffect:
|
|
8553
|
+
const { useEffect: useEffect70, useRef: useRef67, useCallback: useCallback114, useState: useState100 } = React80__default;
|
|
8554
8554
|
const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
|
|
8555
8555
|
const { useEventBus: useEventBus2 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
|
|
8556
8556
|
function MapUpdater({ centerLat, centerLng, zoom }) {
|
|
8557
8557
|
const map = useMap();
|
|
8558
|
-
const prevRef =
|
|
8559
|
-
|
|
8558
|
+
const prevRef = useRef67({ centerLat, centerLng, zoom });
|
|
8559
|
+
useEffect70(() => {
|
|
8560
8560
|
const prev = prevRef.current;
|
|
8561
8561
|
if (prev.centerLat !== centerLat || prev.centerLng !== centerLng || prev.zoom !== zoom) {
|
|
8562
8562
|
map.setView([centerLat, centerLng], zoom);
|
|
@@ -8567,7 +8567,7 @@ var init_MapView = __esm({
|
|
|
8567
8567
|
}
|
|
8568
8568
|
function MapClickHandler({ onMapClick }) {
|
|
8569
8569
|
const map = useMap();
|
|
8570
|
-
|
|
8570
|
+
useEffect70(() => {
|
|
8571
8571
|
if (!onMapClick) return;
|
|
8572
8572
|
const handler = (e) => {
|
|
8573
8573
|
onMapClick(e.latlng.lat, e.latlng.lng);
|
|
@@ -8595,8 +8595,8 @@ var init_MapView = __esm({
|
|
|
8595
8595
|
showAttribution = true
|
|
8596
8596
|
}) {
|
|
8597
8597
|
const eventBus = useEventBus2();
|
|
8598
|
-
const [clickedPosition, setClickedPosition] =
|
|
8599
|
-
const handleMapClick =
|
|
8598
|
+
const [clickedPosition, setClickedPosition] = useState100(null);
|
|
8599
|
+
const handleMapClick = useCallback114((lat, lng) => {
|
|
8600
8600
|
if (showClickedPin) {
|
|
8601
8601
|
setClickedPosition({ lat, lng });
|
|
8602
8602
|
}
|
|
@@ -8605,7 +8605,7 @@ var init_MapView = __esm({
|
|
|
8605
8605
|
eventBus.emit(`UI:${mapClickEvent}`, { latitude: lat, longitude: lng });
|
|
8606
8606
|
}
|
|
8607
8607
|
}, [onMapClick, mapClickEvent, eventBus, showClickedPin]);
|
|
8608
|
-
const handleMarkerClick =
|
|
8608
|
+
const handleMarkerClick = useCallback114((marker) => {
|
|
8609
8609
|
onMarkerClick?.(marker);
|
|
8610
8610
|
if (markerClickEvent) {
|
|
8611
8611
|
eventBus.emit(`UI:${markerClickEvent}`, { ...marker });
|
|
@@ -8796,7 +8796,7 @@ function InputPattern({
|
|
|
8796
8796
|
fieldName
|
|
8797
8797
|
}) {
|
|
8798
8798
|
const { emit } = useEventBus();
|
|
8799
|
-
const [localValue, setLocalValue] =
|
|
8799
|
+
const [localValue, setLocalValue] = React80__default.useState(value);
|
|
8800
8800
|
const handleChange = (e) => {
|
|
8801
8801
|
setLocalValue(e.target.value);
|
|
8802
8802
|
if (onChange) {
|
|
@@ -8826,7 +8826,7 @@ function InputPattern({
|
|
|
8826
8826
|
function TextareaPattern({
|
|
8827
8827
|
value = "",
|
|
8828
8828
|
placeholder,
|
|
8829
|
-
rows = 4,
|
|
8829
|
+
rows: rows2 = 4,
|
|
8830
8830
|
disabled = false,
|
|
8831
8831
|
fieldError,
|
|
8832
8832
|
onChange,
|
|
@@ -8834,7 +8834,7 @@ function TextareaPattern({
|
|
|
8834
8834
|
fieldName
|
|
8835
8835
|
}) {
|
|
8836
8836
|
const { emit } = useEventBus();
|
|
8837
|
-
const [localValue, setLocalValue] =
|
|
8837
|
+
const [localValue, setLocalValue] = React80__default.useState(value);
|
|
8838
8838
|
const handleChange = (e) => {
|
|
8839
8839
|
setLocalValue(e.target.value);
|
|
8840
8840
|
if (onChange) {
|
|
@@ -8846,7 +8846,7 @@ function TextareaPattern({
|
|
|
8846
8846
|
{
|
|
8847
8847
|
value: localValue,
|
|
8848
8848
|
placeholder,
|
|
8849
|
-
rows,
|
|
8849
|
+
rows: rows2,
|
|
8850
8850
|
disabled,
|
|
8851
8851
|
error: fieldError,
|
|
8852
8852
|
onChange: handleChange,
|
|
@@ -8866,7 +8866,7 @@ function SelectPattern({
|
|
|
8866
8866
|
fieldName
|
|
8867
8867
|
}) {
|
|
8868
8868
|
const { emit } = useEventBus();
|
|
8869
|
-
const [localValue, setLocalValue] =
|
|
8869
|
+
const [localValue, setLocalValue] = React80__default.useState(value);
|
|
8870
8870
|
const handleChange = (e) => {
|
|
8871
8871
|
setLocalValue(e.target.value);
|
|
8872
8872
|
if (onChange) {
|
|
@@ -8895,7 +8895,7 @@ function CheckboxPattern({
|
|
|
8895
8895
|
className
|
|
8896
8896
|
}) {
|
|
8897
8897
|
const { emit } = useEventBus();
|
|
8898
|
-
const [localChecked, setLocalChecked] =
|
|
8898
|
+
const [localChecked, setLocalChecked] = React80__default.useState(checked);
|
|
8899
8899
|
const handleChange = (e) => {
|
|
8900
8900
|
setLocalChecked(e.target.checked);
|
|
8901
8901
|
if (onChange) {
|
|
@@ -9208,9 +9208,9 @@ function ControlButton({
|
|
|
9208
9208
|
className
|
|
9209
9209
|
}) {
|
|
9210
9210
|
const eventBus = useEventBus();
|
|
9211
|
-
const [isPressed, setIsPressed] =
|
|
9211
|
+
const [isPressed, setIsPressed] = React80.useState(false);
|
|
9212
9212
|
const actualPressed = pressed ?? isPressed;
|
|
9213
|
-
const handlePointerDown =
|
|
9213
|
+
const handlePointerDown = React80.useCallback(
|
|
9214
9214
|
(e) => {
|
|
9215
9215
|
e.preventDefault();
|
|
9216
9216
|
if (disabled) return;
|
|
@@ -9220,7 +9220,7 @@ function ControlButton({
|
|
|
9220
9220
|
},
|
|
9221
9221
|
[disabled, pressEvent, eventBus, onPress]
|
|
9222
9222
|
);
|
|
9223
|
-
const handlePointerUp =
|
|
9223
|
+
const handlePointerUp = React80.useCallback(
|
|
9224
9224
|
(e) => {
|
|
9225
9225
|
e.preventDefault();
|
|
9226
9226
|
if (disabled) return;
|
|
@@ -9230,7 +9230,7 @@ function ControlButton({
|
|
|
9230
9230
|
},
|
|
9231
9231
|
[disabled, releaseEvent, eventBus, onRelease]
|
|
9232
9232
|
);
|
|
9233
|
-
const handlePointerLeave =
|
|
9233
|
+
const handlePointerLeave = React80.useCallback(
|
|
9234
9234
|
(e) => {
|
|
9235
9235
|
if (isPressed) {
|
|
9236
9236
|
setIsPressed(false);
|
|
@@ -9307,8 +9307,8 @@ function ActionButtons({
|
|
|
9307
9307
|
disabled
|
|
9308
9308
|
}) {
|
|
9309
9309
|
const eventBus = useEventBus();
|
|
9310
|
-
const [activeButtons, setActiveButtons] =
|
|
9311
|
-
const handlePress =
|
|
9310
|
+
const [activeButtons, setActiveButtons] = React80.useState(/* @__PURE__ */ new Set());
|
|
9311
|
+
const handlePress = React80.useCallback(
|
|
9312
9312
|
(id) => {
|
|
9313
9313
|
setActiveButtons((prev) => new Set(prev).add(id));
|
|
9314
9314
|
if (actionEvent) eventBus.emit(`UI:${actionEvent}`, { id, pressed: true });
|
|
@@ -9316,7 +9316,7 @@ function ActionButtons({
|
|
|
9316
9316
|
},
|
|
9317
9317
|
[actionEvent, eventBus, onAction]
|
|
9318
9318
|
);
|
|
9319
|
-
const handleRelease =
|
|
9319
|
+
const handleRelease = React80.useCallback(
|
|
9320
9320
|
(id) => {
|
|
9321
9321
|
setActiveButtons((prev) => {
|
|
9322
9322
|
const next = new Set(prev);
|
|
@@ -9512,6 +9512,91 @@ var init_ActionPalette = __esm({
|
|
|
9512
9512
|
ActionPalette.displayName = "ActionPalette";
|
|
9513
9513
|
}
|
|
9514
9514
|
});
|
|
9515
|
+
function parseValue(value) {
|
|
9516
|
+
if (value === "" || value == null) return { num: 0, prefix: "", suffix: "", decimals: 0 };
|
|
9517
|
+
const match = String(value).match(/^([^0-9]*)([0-9]+(?:\.[0-9]+)?)(.*)$/);
|
|
9518
|
+
if (!match) {
|
|
9519
|
+
return { num: 0, prefix: "", suffix: String(value), decimals: 0 };
|
|
9520
|
+
}
|
|
9521
|
+
const numStr = match[2];
|
|
9522
|
+
const decimalIdx = numStr.indexOf(".");
|
|
9523
|
+
const decimals = decimalIdx >= 0 ? numStr.length - decimalIdx - 1 : 0;
|
|
9524
|
+
return {
|
|
9525
|
+
prefix: match[1],
|
|
9526
|
+
num: parseFloat(numStr),
|
|
9527
|
+
suffix: match[3],
|
|
9528
|
+
decimals
|
|
9529
|
+
};
|
|
9530
|
+
}
|
|
9531
|
+
var AnimatedCounter2;
|
|
9532
|
+
var init_AnimatedCounter2 = __esm({
|
|
9533
|
+
"components/core/molecules/AnimatedCounter.tsx"() {
|
|
9534
|
+
"use client";
|
|
9535
|
+
init_cn();
|
|
9536
|
+
init_Box();
|
|
9537
|
+
init_Typography();
|
|
9538
|
+
AnimatedCounter2 = ({
|
|
9539
|
+
value,
|
|
9540
|
+
label,
|
|
9541
|
+
duration = 1500,
|
|
9542
|
+
className
|
|
9543
|
+
}) => {
|
|
9544
|
+
const ref = useRef(null);
|
|
9545
|
+
const [displayValue, setDisplayValue] = useState("0");
|
|
9546
|
+
const [hasAnimated, setHasAnimated] = useState(false);
|
|
9547
|
+
const animate = useCallback(() => {
|
|
9548
|
+
const { num: num2, prefix, suffix, decimals } = parseValue(value);
|
|
9549
|
+
if (num2 === 0) {
|
|
9550
|
+
setDisplayValue(String(value));
|
|
9551
|
+
return;
|
|
9552
|
+
}
|
|
9553
|
+
const startTime = performance.now();
|
|
9554
|
+
const tick = (now) => {
|
|
9555
|
+
const elapsed = now - startTime;
|
|
9556
|
+
const progress = Math.min(elapsed / duration, 1);
|
|
9557
|
+
const eased = 1 - Math.pow(1 - progress, 3);
|
|
9558
|
+
const current = eased * num2;
|
|
9559
|
+
setDisplayValue(`${prefix}${current.toFixed(decimals)}${suffix}`);
|
|
9560
|
+
if (progress < 1) {
|
|
9561
|
+
requestAnimationFrame(tick);
|
|
9562
|
+
} else {
|
|
9563
|
+
setDisplayValue(String(value));
|
|
9564
|
+
}
|
|
9565
|
+
};
|
|
9566
|
+
requestAnimationFrame(tick);
|
|
9567
|
+
}, [value, duration]);
|
|
9568
|
+
useEffect(() => {
|
|
9569
|
+
if (hasAnimated) return;
|
|
9570
|
+
const el = ref.current;
|
|
9571
|
+
if (!el) return;
|
|
9572
|
+
const observer2 = new IntersectionObserver(
|
|
9573
|
+
(entries) => {
|
|
9574
|
+
if (entries[0].isIntersecting) {
|
|
9575
|
+
setHasAnimated(true);
|
|
9576
|
+
animate();
|
|
9577
|
+
observer2.disconnect();
|
|
9578
|
+
}
|
|
9579
|
+
},
|
|
9580
|
+
{ threshold: 0.3 }
|
|
9581
|
+
);
|
|
9582
|
+
observer2.observe(el);
|
|
9583
|
+
return () => observer2.disconnect();
|
|
9584
|
+
}, [hasAnimated, animate]);
|
|
9585
|
+
return /* @__PURE__ */ jsxs(Box, { ref, className: cn("flex flex-col items-center gap-1 p-4", className), children: [
|
|
9586
|
+
/* @__PURE__ */ jsx(
|
|
9587
|
+
Typography,
|
|
9588
|
+
{
|
|
9589
|
+
variant: "h2",
|
|
9590
|
+
className: "text-primary font-bold tabular-nums",
|
|
9591
|
+
children: hasAnimated ? displayValue : "0"
|
|
9592
|
+
}
|
|
9593
|
+
),
|
|
9594
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body2", color: "muted", className: "text-center", children: label })
|
|
9595
|
+
] });
|
|
9596
|
+
};
|
|
9597
|
+
AnimatedCounter2.displayName = "AnimatedCounter";
|
|
9598
|
+
}
|
|
9599
|
+
});
|
|
9515
9600
|
var AuthLayout;
|
|
9516
9601
|
var init_AuthLayout = __esm({
|
|
9517
9602
|
"components/core/templates/AuthLayout.tsx"() {
|
|
@@ -10764,6 +10849,39 @@ var init_IsometricCanvas2 = __esm({
|
|
|
10764
10849
|
init_IsometricCanvas();
|
|
10765
10850
|
}
|
|
10766
10851
|
});
|
|
10852
|
+
|
|
10853
|
+
// components/game/organisms/boardEntity.ts
|
|
10854
|
+
function boardEntity(entity) {
|
|
10855
|
+
if (!entity) return void 0;
|
|
10856
|
+
return Array.isArray(entity) ? entity[0] : entity;
|
|
10857
|
+
}
|
|
10858
|
+
function str(v) {
|
|
10859
|
+
return v == null ? "" : String(v);
|
|
10860
|
+
}
|
|
10861
|
+
function num(v, fallback = 0) {
|
|
10862
|
+
const n = Number(v);
|
|
10863
|
+
return Number.isFinite(n) ? n : fallback;
|
|
10864
|
+
}
|
|
10865
|
+
function rows(v) {
|
|
10866
|
+
return Array.isArray(v) ? v : [];
|
|
10867
|
+
}
|
|
10868
|
+
function vec2(v) {
|
|
10869
|
+
const o = v ?? {};
|
|
10870
|
+
return { x: num(o.x), y: num(o.y) };
|
|
10871
|
+
}
|
|
10872
|
+
function unitPosition(u) {
|
|
10873
|
+
return vec2(u.position);
|
|
10874
|
+
}
|
|
10875
|
+
function unitTeam(u) {
|
|
10876
|
+
return str(u.team);
|
|
10877
|
+
}
|
|
10878
|
+
function unitHealth(u) {
|
|
10879
|
+
return num(u.health);
|
|
10880
|
+
}
|
|
10881
|
+
var init_boardEntity = __esm({
|
|
10882
|
+
"components/game/organisms/boardEntity.ts"() {
|
|
10883
|
+
}
|
|
10884
|
+
});
|
|
10767
10885
|
function BattleBoard({
|
|
10768
10886
|
entity,
|
|
10769
10887
|
scale = 0.45,
|
|
@@ -10790,43 +10908,49 @@ function BattleBoard({
|
|
|
10790
10908
|
attackEvent,
|
|
10791
10909
|
className
|
|
10792
10910
|
}) {
|
|
10793
|
-
const
|
|
10794
|
-
const
|
|
10795
|
-
const
|
|
10796
|
-
const
|
|
10797
|
-
const
|
|
10798
|
-
const
|
|
10799
|
-
const
|
|
10800
|
-
const
|
|
10801
|
-
const
|
|
10802
|
-
const
|
|
10803
|
-
const
|
|
10911
|
+
const board = boardEntity(entity) ?? {};
|
|
10912
|
+
const tiles = Array.isArray(board.tiles) ? board.tiles : [];
|
|
10913
|
+
const features = Array.isArray(board.features) ? board.features : [];
|
|
10914
|
+
const boardWidth = num(board.boardWidth, 8);
|
|
10915
|
+
const boardHeight = num(board.boardHeight, 6);
|
|
10916
|
+
const assetManifest = board.assetManifest;
|
|
10917
|
+
const backgroundImage = board.backgroundImage;
|
|
10918
|
+
const units = rows(board.units);
|
|
10919
|
+
const selectedUnitId = board.selectedUnitId ?? null;
|
|
10920
|
+
const currentPhase = str(board.phase) || "observation";
|
|
10921
|
+
const currentTurn = num(board.turn, 1);
|
|
10922
|
+
const gameResult = board.gameResult ?? null;
|
|
10804
10923
|
const eventBus = useEventBus();
|
|
10805
10924
|
const { t } = useTranslate();
|
|
10806
10925
|
const [hoveredTile, setHoveredTile] = useState(null);
|
|
10807
10926
|
const [isShaking, setIsShaking] = useState(false);
|
|
10808
10927
|
const selectedUnit = useMemo(
|
|
10809
|
-
() => units.find((u) => u.id === selectedUnitId) ?? null,
|
|
10928
|
+
() => units.find((u) => str(u.id) === selectedUnitId) ?? null,
|
|
10810
10929
|
[units, selectedUnitId]
|
|
10811
10930
|
);
|
|
10812
10931
|
const hoveredUnit = useMemo(() => {
|
|
10813
10932
|
if (!hoveredTile) return null;
|
|
10814
|
-
return units.find(
|
|
10815
|
-
|
|
10816
|
-
|
|
10933
|
+
return units.find((u) => {
|
|
10934
|
+
const p2 = unitPosition(u);
|
|
10935
|
+
return p2.x === hoveredTile.x && p2.y === hoveredTile.y && unitHealth(u) > 0;
|
|
10936
|
+
}) ?? null;
|
|
10817
10937
|
}, [hoveredTile, units]);
|
|
10818
|
-
const playerUnits = useMemo(() => units.filter((u) => u
|
|
10819
|
-
const enemyUnits = useMemo(() => units.filter((u) => u
|
|
10938
|
+
const playerUnits = useMemo(() => units.filter((u) => unitTeam(u) === "player" && unitHealth(u) > 0), [units]);
|
|
10939
|
+
const enemyUnits = useMemo(() => units.filter((u) => unitTeam(u) === "enemy" && unitHealth(u) > 0), [units]);
|
|
10820
10940
|
const validMoves = useMemo(() => {
|
|
10821
10941
|
if (!selectedUnit || currentPhase !== "movement") return [];
|
|
10822
10942
|
const moves = [];
|
|
10823
|
-
const range = selectedUnit.movement;
|
|
10943
|
+
const range = num(selectedUnit.movement);
|
|
10944
|
+
const origin = unitPosition(selectedUnit);
|
|
10824
10945
|
for (let dy = -range; dy <= range; dy++) {
|
|
10825
10946
|
for (let dx = -range; dx <= range; dx++) {
|
|
10826
|
-
const nx =
|
|
10827
|
-
const ny =
|
|
10947
|
+
const nx = origin.x + dx;
|
|
10948
|
+
const ny = origin.y + dy;
|
|
10828
10949
|
const dist = Math.abs(dx) + Math.abs(dy);
|
|
10829
|
-
if (dist > 0 && dist <= range && nx >= 0 && nx < boardWidth && ny >= 0 && ny < boardHeight && !units.some((u) =>
|
|
10950
|
+
if (dist > 0 && dist <= range && nx >= 0 && nx < boardWidth && ny >= 0 && ny < boardHeight && !units.some((u) => {
|
|
10951
|
+
const p2 = unitPosition(u);
|
|
10952
|
+
return p2.x === nx && p2.y === ny && unitHealth(u) > 0;
|
|
10953
|
+
})) {
|
|
10830
10954
|
moves.push({ x: nx, y: ny });
|
|
10831
10955
|
}
|
|
10832
10956
|
}
|
|
@@ -10835,11 +10959,14 @@ function BattleBoard({
|
|
|
10835
10959
|
}, [selectedUnit, currentPhase, units, boardWidth, boardHeight]);
|
|
10836
10960
|
const attackTargets = useMemo(() => {
|
|
10837
10961
|
if (!selectedUnit || currentPhase !== "action") return [];
|
|
10838
|
-
|
|
10839
|
-
|
|
10840
|
-
|
|
10962
|
+
const sp = unitPosition(selectedUnit);
|
|
10963
|
+
const sTeam = unitTeam(selectedUnit);
|
|
10964
|
+
return units.filter((u) => unitTeam(u) !== sTeam && unitHealth(u) > 0).filter((u) => {
|
|
10965
|
+
const p2 = unitPosition(u);
|
|
10966
|
+
const dx = Math.abs(p2.x - sp.x);
|
|
10967
|
+
const dy = Math.abs(p2.y - sp.y);
|
|
10841
10968
|
return dx <= 1 && dy <= 1 && dx + dy > 0;
|
|
10842
|
-
}).map((u) => u
|
|
10969
|
+
}).map((u) => unitPosition(u));
|
|
10843
10970
|
}, [selectedUnit, currentPhase, units]);
|
|
10844
10971
|
const MOVE_SPEED_MS_PER_TILE = 300;
|
|
10845
10972
|
const movementAnimRef = useRef(null);
|
|
@@ -10879,23 +11006,25 @@ function BattleBoard({
|
|
|
10879
11006
|
return () => clearInterval(interval);
|
|
10880
11007
|
}, []);
|
|
10881
11008
|
const isoUnits = useMemo(() => {
|
|
10882
|
-
return units.filter((u) => u
|
|
10883
|
-
const
|
|
11009
|
+
return units.filter((u) => unitHealth(u) > 0).map((unit) => {
|
|
11010
|
+
const id = str(unit.id);
|
|
11011
|
+
const pos = movingPositions.get(id) ?? unitPosition(unit);
|
|
11012
|
+
const unitTraits = Array.isArray(unit.traits) ? unit.traits : void 0;
|
|
10884
11013
|
return {
|
|
10885
|
-
id
|
|
11014
|
+
id,
|
|
10886
11015
|
position: pos,
|
|
10887
|
-
name: unit.name,
|
|
10888
|
-
team: unit
|
|
10889
|
-
health: unit
|
|
10890
|
-
maxHealth: unit.maxHealth,
|
|
10891
|
-
unitType: unit.unitType,
|
|
10892
|
-
heroId: unit.heroId,
|
|
10893
|
-
sprite: unit.sprite,
|
|
10894
|
-
traits:
|
|
10895
|
-
name:
|
|
10896
|
-
currentState:
|
|
10897
|
-
states:
|
|
10898
|
-
cooldown:
|
|
11016
|
+
name: str(unit.name),
|
|
11017
|
+
team: unitTeam(unit),
|
|
11018
|
+
health: unitHealth(unit),
|
|
11019
|
+
maxHealth: num(unit.maxHealth),
|
|
11020
|
+
unitType: unit.unitType == null ? void 0 : str(unit.unitType),
|
|
11021
|
+
heroId: unit.heroId == null ? void 0 : str(unit.heroId),
|
|
11022
|
+
sprite: unit.sprite == null ? void 0 : str(unit.sprite),
|
|
11023
|
+
traits: unitTraits?.map((tr) => ({
|
|
11024
|
+
name: tr.name,
|
|
11025
|
+
currentState: tr.currentState,
|
|
11026
|
+
states: tr.states,
|
|
11027
|
+
cooldown: tr.cooldown ?? 0
|
|
10899
11028
|
}))
|
|
10900
11029
|
};
|
|
10901
11030
|
});
|
|
@@ -10907,8 +11036,8 @@ function BattleBoard({
|
|
|
10907
11036
|
[scale, baseOffsetX]
|
|
10908
11037
|
);
|
|
10909
11038
|
const checkGameEnd = useCallback(() => {
|
|
10910
|
-
const pa = units.filter((u) => u
|
|
10911
|
-
const ea = units.filter((u) => u
|
|
11039
|
+
const pa = units.filter((u) => unitTeam(u) === "player" && unitHealth(u) > 0);
|
|
11040
|
+
const ea = units.filter((u) => unitTeam(u) === "enemy" && unitHealth(u) > 0);
|
|
10912
11041
|
if (pa.length === 0) {
|
|
10913
11042
|
onGameEnd?.("defeat");
|
|
10914
11043
|
if (gameEndEvent) {
|
|
@@ -10922,21 +11051,22 @@ function BattleBoard({
|
|
|
10922
11051
|
}
|
|
10923
11052
|
}, [units, onGameEnd, gameEndEvent, eventBus]);
|
|
10924
11053
|
const handleUnitClick = useCallback((unitId) => {
|
|
10925
|
-
const unit = units.find((u) => u.id === unitId);
|
|
11054
|
+
const unit = units.find((u) => str(u.id) === unitId);
|
|
10926
11055
|
if (!unit) return;
|
|
10927
11056
|
if (unitClickEvent) {
|
|
10928
11057
|
eventBus.emit(`UI:${unitClickEvent}`, { unitId });
|
|
10929
11058
|
}
|
|
10930
11059
|
if (currentPhase === "action" && selectedUnit) {
|
|
10931
|
-
|
|
10932
|
-
|
|
11060
|
+
const up = unitPosition(unit);
|
|
11061
|
+
if (unitTeam(unit) === "enemy" && attackTargets.some((t2) => t2.x === up.x && t2.y === up.y)) {
|
|
11062
|
+
const damage = calculateDamage2 ? calculateDamage2(selectedUnit, unit) : Math.max(1, num(selectedUnit.attack) - num(unit.defense));
|
|
10933
11063
|
setIsShaking(true);
|
|
10934
11064
|
setTimeout(() => setIsShaking(false), 300);
|
|
10935
11065
|
onAttack?.(selectedUnit, unit, damage);
|
|
10936
11066
|
if (attackEvent) {
|
|
10937
11067
|
eventBus.emit(`UI:${attackEvent}`, {
|
|
10938
|
-
attackerId: selectedUnit.id,
|
|
10939
|
-
targetId: unit.id,
|
|
11068
|
+
attackerId: str(selectedUnit.id),
|
|
11069
|
+
targetId: str(unit.id),
|
|
10940
11070
|
damage
|
|
10941
11071
|
});
|
|
10942
11072
|
}
|
|
@@ -10951,9 +11081,9 @@ function BattleBoard({
|
|
|
10951
11081
|
if (currentPhase === "movement" && selectedUnit) {
|
|
10952
11082
|
if (movementAnimRef.current) return;
|
|
10953
11083
|
if (validMoves.some((m) => m.x === x && m.y === y)) {
|
|
10954
|
-
const from = { ...selectedUnit
|
|
11084
|
+
const from = { ...unitPosition(selectedUnit) };
|
|
10955
11085
|
const to = { x, y };
|
|
10956
|
-
startMoveAnimation(selectedUnit.id, from, to, () => {
|
|
11086
|
+
startMoveAnimation(str(selectedUnit.id), from, to, () => {
|
|
10957
11087
|
onUnitMove?.(selectedUnit, to);
|
|
10958
11088
|
});
|
|
10959
11089
|
}
|
|
@@ -11111,6 +11241,7 @@ var init_BattleBoard = __esm({
|
|
|
11111
11241
|
init_Typography();
|
|
11112
11242
|
init_Stack();
|
|
11113
11243
|
init_IsometricCanvas2();
|
|
11244
|
+
init_boardEntity();
|
|
11114
11245
|
init_isometric();
|
|
11115
11246
|
BattleBoard.displayName = "BattleBoard";
|
|
11116
11247
|
}
|
|
@@ -12191,7 +12322,7 @@ var init_CodeBlock = __esm({
|
|
|
12191
12322
|
log5 = createLogger("almadar:ui:markdown-code");
|
|
12192
12323
|
LINE_PROPS_FN = (n) => ({ "data-line": String(n - 1) });
|
|
12193
12324
|
HIDDEN_LINE_NUMBERS = { display: "none" };
|
|
12194
|
-
CodeBlock =
|
|
12325
|
+
CodeBlock = React80__default.memo(
|
|
12195
12326
|
({
|
|
12196
12327
|
code: rawCode,
|
|
12197
12328
|
language = "text",
|
|
@@ -12333,24 +12464,24 @@ var init_CodeBlock = __esm({
|
|
|
12333
12464
|
return;
|
|
12334
12465
|
}
|
|
12335
12466
|
lineEls.forEach((el) => {
|
|
12336
|
-
const
|
|
12337
|
-
if (hiddenLines.has(
|
|
12467
|
+
const num2 = parseInt(el.getAttribute("data-line") ?? "-1", 10);
|
|
12468
|
+
if (hiddenLines.has(num2)) {
|
|
12338
12469
|
el.style.display = "none";
|
|
12339
12470
|
return;
|
|
12340
12471
|
}
|
|
12341
12472
|
el.style.display = "";
|
|
12342
12473
|
el.style.position = "relative";
|
|
12343
12474
|
el.style.paddingLeft = "1.2em";
|
|
12344
|
-
const region = foldStartMap.get(
|
|
12475
|
+
const region = foldStartMap.get(num2);
|
|
12345
12476
|
if (!region) return;
|
|
12346
|
-
const isCollapsed = collapsed.has(
|
|
12477
|
+
const isCollapsed = collapsed.has(num2);
|
|
12347
12478
|
const toggle = document.createElement("span");
|
|
12348
12479
|
toggle.className = "fold-toggle";
|
|
12349
12480
|
toggle.textContent = isCollapsed ? "\u25B6" : "\u25BC";
|
|
12350
12481
|
toggle.style.cssText = "position:absolute;left:0;top:0;width:1.2em;text-align:center;cursor:pointer;color:#858585;font-size:10px;user-select:none;line-height:inherit;height:100%";
|
|
12351
12482
|
toggle.addEventListener("click", (e) => {
|
|
12352
12483
|
e.stopPropagation();
|
|
12353
|
-
toggleFoldRef.current(
|
|
12484
|
+
toggleFoldRef.current(num2);
|
|
12354
12485
|
});
|
|
12355
12486
|
el.insertBefore(toggle, el.firstChild);
|
|
12356
12487
|
if (isCollapsed) {
|
|
@@ -12628,7 +12759,7 @@ var init_MarkdownContent = __esm({
|
|
|
12628
12759
|
init_Box();
|
|
12629
12760
|
init_CodeBlock();
|
|
12630
12761
|
init_cn();
|
|
12631
|
-
MarkdownContent =
|
|
12762
|
+
MarkdownContent = React80__default.memo(
|
|
12632
12763
|
({ content, direction, className }) => {
|
|
12633
12764
|
const { t: _t } = useTranslate();
|
|
12634
12765
|
const safeContent = typeof content === "string" ? content : String(content ?? "");
|
|
@@ -13724,7 +13855,7 @@ var init_StateMachineView = __esm({
|
|
|
13724
13855
|
style: { top: title ? 30 : 0 },
|
|
13725
13856
|
children: [
|
|
13726
13857
|
entity && /* @__PURE__ */ jsx(EntityBox, { entity, config }),
|
|
13727
|
-
states.map((state) => renderStateNode ? /* @__PURE__ */ jsx(
|
|
13858
|
+
states.map((state) => renderStateNode ? /* @__PURE__ */ jsx(React80__default.Fragment, { children: renderStateNode(state, config) }, state.id) : /* @__PURE__ */ jsx(
|
|
13728
13859
|
StateNode,
|
|
13729
13860
|
{
|
|
13730
13861
|
state,
|
|
@@ -14603,10 +14734,13 @@ var init_BookChapterView = __esm({
|
|
|
14603
14734
|
init_cn();
|
|
14604
14735
|
BookChapterView = ({
|
|
14605
14736
|
chapter,
|
|
14737
|
+
orbitalSchema,
|
|
14606
14738
|
direction,
|
|
14607
14739
|
className
|
|
14608
14740
|
}) => {
|
|
14609
14741
|
const { t: _t } = useTranslate();
|
|
14742
|
+
const title = String(chapter.title ?? "");
|
|
14743
|
+
const content = String(chapter.content ?? "");
|
|
14610
14744
|
return /* @__PURE__ */ jsxs(
|
|
14611
14745
|
VStack,
|
|
14612
14746
|
{
|
|
@@ -14614,16 +14748,16 @@ var init_BookChapterView = __esm({
|
|
|
14614
14748
|
className: cn("px-6 py-8 max-w-4xl mx-auto w-full", className),
|
|
14615
14749
|
style: { direction },
|
|
14616
14750
|
children: [
|
|
14617
|
-
/* @__PURE__ */ jsx(Typography, { variant: "h1", className: "text-3xl font-bold", children:
|
|
14751
|
+
/* @__PURE__ */ jsx(Typography, { variant: "h1", className: "text-3xl font-bold", children: title }),
|
|
14618
14752
|
/* @__PURE__ */ jsx(Divider, {}),
|
|
14619
|
-
!!
|
|
14753
|
+
!!orbitalSchema && /* @__PURE__ */ jsx(ScaledDiagram, { children: /* @__PURE__ */ jsx(
|
|
14620
14754
|
JazariStateMachine,
|
|
14621
14755
|
{
|
|
14622
|
-
schema:
|
|
14756
|
+
schema: orbitalSchema,
|
|
14623
14757
|
direction
|
|
14624
14758
|
}
|
|
14625
14759
|
) }),
|
|
14626
|
-
/* @__PURE__ */ jsx(ContentRenderer, { content
|
|
14760
|
+
/* @__PURE__ */ jsx(ContentRenderer, { content, direction })
|
|
14627
14761
|
]
|
|
14628
14762
|
}
|
|
14629
14763
|
);
|
|
@@ -14721,7 +14855,7 @@ var init_BookNavBar = __esm({
|
|
|
14721
14855
|
BookNavBar = ({
|
|
14722
14856
|
currentPage,
|
|
14723
14857
|
totalPages,
|
|
14724
|
-
chapterTitle,
|
|
14858
|
+
chapterTitle: chapterTitle2,
|
|
14725
14859
|
direction,
|
|
14726
14860
|
className
|
|
14727
14861
|
}) => {
|
|
@@ -14762,12 +14896,12 @@ var init_BookNavBar = __esm({
|
|
|
14762
14896
|
)
|
|
14763
14897
|
] }),
|
|
14764
14898
|
/* @__PURE__ */ jsxs(Box, { className: "flex-1 mx-4 max-w-md", children: [
|
|
14765
|
-
|
|
14899
|
+
chapterTitle2 && /* @__PURE__ */ jsx(
|
|
14766
14900
|
Typography,
|
|
14767
14901
|
{
|
|
14768
14902
|
variant: "caption",
|
|
14769
14903
|
className: "text-center block truncate text-muted-foreground",
|
|
14770
|
-
children:
|
|
14904
|
+
children: chapterTitle2
|
|
14771
14905
|
}
|
|
14772
14906
|
),
|
|
14773
14907
|
/* @__PURE__ */ jsx(ProgressBar, { value: progress, size: "sm", variant: "primary" })
|
|
@@ -14834,31 +14968,35 @@ var init_BookTableOfContents = __esm({
|
|
|
14834
14968
|
style: { direction },
|
|
14835
14969
|
children: [
|
|
14836
14970
|
/* @__PURE__ */ jsx(Typography, { variant: "h1", className: "text-3xl font-bold text-center mb-4", children: t("book.tableOfContents") }),
|
|
14837
|
-
parts.map((part, partIdx) =>
|
|
14838
|
-
|
|
14839
|
-
|
|
14840
|
-
/* @__PURE__ */
|
|
14841
|
-
|
|
14842
|
-
|
|
14843
|
-
|
|
14844
|
-
|
|
14845
|
-
|
|
14846
|
-
|
|
14847
|
-
|
|
14848
|
-
|
|
14849
|
-
|
|
14850
|
-
|
|
14851
|
-
|
|
14852
|
-
|
|
14853
|
-
|
|
14854
|
-
|
|
14855
|
-
|
|
14856
|
-
|
|
14857
|
-
|
|
14858
|
-
|
|
14859
|
-
|
|
14860
|
-
|
|
14861
|
-
|
|
14971
|
+
parts.map((part, partIdx) => {
|
|
14972
|
+
const chapters = Array.isArray(part.chapters) ? part.chapters : [];
|
|
14973
|
+
return /* @__PURE__ */ jsxs(VStack, { gap: "sm", children: [
|
|
14974
|
+
/* @__PURE__ */ jsxs(HStack, { gap: "sm", align: "center", children: [
|
|
14975
|
+
/* @__PURE__ */ jsx(Badge, { variant: "default", size: "sm", children: t("book.partNumber", { number: String(partIdx + 1) }) }),
|
|
14976
|
+
/* @__PURE__ */ jsx(Typography, { variant: "h3", className: "font-semibold", children: String(part.title ?? "") })
|
|
14977
|
+
] }),
|
|
14978
|
+
/* @__PURE__ */ jsx(VStack, { gap: "xs", className: direction === "rtl" ? "pr-6" : "pl-6", children: chapters.map((chapter) => {
|
|
14979
|
+
const id = chapter.id == null ? "" : String(chapter.id);
|
|
14980
|
+
const isCurrent = id === currentChapterId;
|
|
14981
|
+
return /* @__PURE__ */ jsx(
|
|
14982
|
+
Button,
|
|
14983
|
+
{
|
|
14984
|
+
variant: "ghost",
|
|
14985
|
+
size: "sm",
|
|
14986
|
+
action: "BOOK_NAVIGATE",
|
|
14987
|
+
actionPayload: { chapterId: id },
|
|
14988
|
+
className: cn(
|
|
14989
|
+
"justify-start text-left w-full",
|
|
14990
|
+
direction === "rtl" && "text-right",
|
|
14991
|
+
isCurrent && "bg-blue-50 dark:bg-blue-950 text-blue-600 dark:text-blue-400"
|
|
14992
|
+
),
|
|
14993
|
+
children: /* @__PURE__ */ jsx(Box, { className: "truncate", children: /* @__PURE__ */ jsx(Typography, { variant: "body", children: String(chapter.title ?? "") }) })
|
|
14994
|
+
},
|
|
14995
|
+
id
|
|
14996
|
+
);
|
|
14997
|
+
}) })
|
|
14998
|
+
] }, partIdx);
|
|
14999
|
+
})
|
|
14862
15000
|
]
|
|
14863
15001
|
}
|
|
14864
15002
|
);
|
|
@@ -14980,27 +15118,41 @@ function resolveFieldMap(fieldMap) {
|
|
|
14980
15118
|
function get(obj, key) {
|
|
14981
15119
|
return obj[key];
|
|
14982
15120
|
}
|
|
15121
|
+
function asStr(v) {
|
|
15122
|
+
return v == null ? "" : String(v);
|
|
15123
|
+
}
|
|
14983
15124
|
function mapBookData(raw, fields = IDENTITY_BOOK_FIELDS) {
|
|
14984
15125
|
const rawParts = get(raw, fields.parts) ?? [];
|
|
14985
|
-
|
|
14986
|
-
|
|
14987
|
-
|
|
14988
|
-
|
|
14989
|
-
|
|
14990
|
-
|
|
14991
|
-
|
|
14992
|
-
const rawChapters = get(part, fields.chapters) ?? [];
|
|
14993
|
-
return {
|
|
14994
|
-
title: get(part, fields.partTitle) ?? "",
|
|
14995
|
-
chapters: rawChapters.map((ch) => ({
|
|
14996
|
-
id: get(ch, fields.chapterId) ?? "",
|
|
14997
|
-
title: get(ch, fields.chapterTitle) ?? "",
|
|
14998
|
-
content: get(ch, fields.chapterContent) ?? "",
|
|
14999
|
-
orbitalSchema: get(ch, fields.chapterOrbitalSchema)
|
|
15000
|
-
}))
|
|
15001
|
-
};
|
|
15002
|
-
})
|
|
15126
|
+
const direction = get(raw, fields.direction) ?? "ltr";
|
|
15127
|
+
const cover = {
|
|
15128
|
+
title: asStr(get(raw, fields.title)),
|
|
15129
|
+
subtitle: asStr(get(raw, fields.subtitle)),
|
|
15130
|
+
author: asStr(get(raw, fields.author)),
|
|
15131
|
+
coverImageUrl: asStr(get(raw, fields.coverImageUrl)),
|
|
15132
|
+
direction
|
|
15003
15133
|
};
|
|
15134
|
+
const schemaByChapterId = {};
|
|
15135
|
+
const chapters = [];
|
|
15136
|
+
const parts = rawParts.map((part) => {
|
|
15137
|
+
const rawChapters = get(part, fields.chapters) ?? [];
|
|
15138
|
+
const chapterRows = rawChapters.map((ch) => {
|
|
15139
|
+
const id = asStr(get(ch, fields.chapterId));
|
|
15140
|
+
const schema = get(ch, fields.chapterOrbitalSchema);
|
|
15141
|
+
if (schema) schemaByChapterId[id] = schema;
|
|
15142
|
+
const row = {
|
|
15143
|
+
id,
|
|
15144
|
+
title: asStr(get(ch, fields.chapterTitle)),
|
|
15145
|
+
content: asStr(get(ch, fields.chapterContent))
|
|
15146
|
+
};
|
|
15147
|
+
chapters.push(row);
|
|
15148
|
+
return row;
|
|
15149
|
+
});
|
|
15150
|
+
return {
|
|
15151
|
+
title: asStr(get(part, fields.partTitle)),
|
|
15152
|
+
chapters: chapterRows
|
|
15153
|
+
};
|
|
15154
|
+
});
|
|
15155
|
+
return { cover, direction, parts, chapters, schemaByChapterId };
|
|
15004
15156
|
}
|
|
15005
15157
|
var IDENTITY_BOOK_FIELDS, AR_BOOK_FIELDS, FIELD_MAP_REGISTRY;
|
|
15006
15158
|
var init_types2 = __esm({
|
|
@@ -15038,10 +15190,7 @@ var init_types2 = __esm({
|
|
|
15038
15190
|
};
|
|
15039
15191
|
}
|
|
15040
15192
|
});
|
|
15041
|
-
|
|
15042
|
-
return book.parts.flatMap((part) => part.chapters);
|
|
15043
|
-
}
|
|
15044
|
-
var PRINT_STYLES, BookViewer;
|
|
15193
|
+
var chapterId, chapterTitle, PRINT_STYLES, BookViewer;
|
|
15045
15194
|
var init_BookViewer = __esm({
|
|
15046
15195
|
"components/marketing/organisms/book/BookViewer.tsx"() {
|
|
15047
15196
|
init_Box();
|
|
@@ -15054,6 +15203,8 @@ var init_BookViewer = __esm({
|
|
|
15054
15203
|
init_BookNavBar();
|
|
15055
15204
|
init_EmptyState();
|
|
15056
15205
|
init_types2();
|
|
15206
|
+
chapterId = (ch) => ch?.id == null ? void 0 : String(ch.id);
|
|
15207
|
+
chapterTitle = (ch) => ch?.title == null ? void 0 : String(ch.title);
|
|
15057
15208
|
PRINT_STYLES = `
|
|
15058
15209
|
@media print {
|
|
15059
15210
|
.book-viewer-page {
|
|
@@ -15082,14 +15233,14 @@ var init_BookViewer = __esm({
|
|
|
15082
15233
|
return mapBookData(raw, resolvedFieldMap);
|
|
15083
15234
|
}, [entity, resolvedFieldMap]);
|
|
15084
15235
|
const direction = book?.direction ?? "ltr";
|
|
15085
|
-
const chapters = useMemo(() => book ?
|
|
15236
|
+
const chapters = useMemo(() => book ? book.chapters : [], [book]);
|
|
15086
15237
|
const totalPages = 2 + chapters.length;
|
|
15087
15238
|
const navigateTo = useCallback(
|
|
15088
15239
|
(page) => {
|
|
15089
15240
|
const clamped = Math.max(0, Math.min(page, totalPages - 1));
|
|
15090
15241
|
setCurrentPage(clamped);
|
|
15091
|
-
const
|
|
15092
|
-
eventBus.emit("UI:BOOK_PAGE_CHANGE", { pageIndex: clamped, chapterId });
|
|
15242
|
+
const id = clamped >= 2 ? chapterId(chapters[clamped - 2]) : void 0;
|
|
15243
|
+
eventBus.emit("UI:BOOK_PAGE_CHANGE", { pageIndex: clamped, chapterId: id });
|
|
15093
15244
|
},
|
|
15094
15245
|
[totalPages, chapters, eventBus]
|
|
15095
15246
|
);
|
|
@@ -15101,8 +15252,8 @@ var init_BookViewer = __esm({
|
|
|
15101
15252
|
eventBus.on("UI:BOOK_PAGE_NEXT", () => navigateTo(currentPage + 1)),
|
|
15102
15253
|
eventBus.on("UI:BOOK_PRINT", () => window.print()),
|
|
15103
15254
|
eventBus.on("UI:BOOK_NAVIGATE", (event) => {
|
|
15104
|
-
const
|
|
15105
|
-
const idx = chapters.findIndex((ch) => ch
|
|
15255
|
+
const targetId = event.payload?.chapterId;
|
|
15256
|
+
const idx = chapters.findIndex((ch) => chapterId(ch) === targetId);
|
|
15106
15257
|
if (idx >= 0) navigateTo(idx + 2);
|
|
15107
15258
|
})
|
|
15108
15259
|
];
|
|
@@ -15119,9 +15270,11 @@ var init_BookViewer = __esm({
|
|
|
15119
15270
|
style.remove();
|
|
15120
15271
|
};
|
|
15121
15272
|
}, []);
|
|
15122
|
-
const currentChapterId = currentPage >= 2 ? chapters[currentPage - 2]
|
|
15123
|
-
const currentChapterTitle = currentPage >= 2 ? chapters[currentPage - 2]
|
|
15273
|
+
const currentChapterId = currentPage >= 2 ? chapterId(chapters[currentPage - 2]) : void 0;
|
|
15274
|
+
const currentChapterTitle = currentPage >= 2 ? chapterTitle(chapters[currentPage - 2]) : void 0;
|
|
15124
15275
|
if (!book) return /* @__PURE__ */ jsx(EmptyState, { message: t("book.noData") });
|
|
15276
|
+
const cover = book.cover;
|
|
15277
|
+
const coverTitle = String(cover.title ?? "");
|
|
15125
15278
|
return /* @__PURE__ */ jsxs(VStack, { className: cn("relative h-full overflow-hidden bg-background", className), children: [
|
|
15126
15279
|
/* @__PURE__ */ jsxs(
|
|
15127
15280
|
Box,
|
|
@@ -15133,10 +15286,10 @@ var init_BookViewer = __esm({
|
|
|
15133
15286
|
/* @__PURE__ */ jsx(
|
|
15134
15287
|
BookCoverPage,
|
|
15135
15288
|
{
|
|
15136
|
-
title:
|
|
15137
|
-
subtitle:
|
|
15138
|
-
author:
|
|
15139
|
-
coverImageUrl:
|
|
15289
|
+
title: coverTitle,
|
|
15290
|
+
subtitle: String(cover.subtitle ?? "") || void 0,
|
|
15291
|
+
author: String(cover.author ?? "") || void 0,
|
|
15292
|
+
coverImageUrl: String(cover.coverImageUrl ?? "") || void 0,
|
|
15140
15293
|
direction
|
|
15141
15294
|
}
|
|
15142
15295
|
),
|
|
@@ -15147,23 +15300,27 @@ var init_BookViewer = __esm({
|
|
|
15147
15300
|
direction
|
|
15148
15301
|
}
|
|
15149
15302
|
),
|
|
15150
|
-
chapters.map((chapter) =>
|
|
15151
|
-
|
|
15152
|
-
|
|
15153
|
-
|
|
15154
|
-
|
|
15155
|
-
|
|
15156
|
-
|
|
15157
|
-
|
|
15303
|
+
chapters.map((chapter) => {
|
|
15304
|
+
const id = chapterId(chapter);
|
|
15305
|
+
return /* @__PURE__ */ jsx(
|
|
15306
|
+
BookChapterView,
|
|
15307
|
+
{
|
|
15308
|
+
chapter,
|
|
15309
|
+
orbitalSchema: id ? book.schemaByChapterId[id] : void 0,
|
|
15310
|
+
direction
|
|
15311
|
+
},
|
|
15312
|
+
id
|
|
15313
|
+
);
|
|
15314
|
+
})
|
|
15158
15315
|
] }),
|
|
15159
15316
|
/* @__PURE__ */ jsxs(Box, { className: "print:hidden", children: [
|
|
15160
15317
|
currentPage === 0 && /* @__PURE__ */ jsx(
|
|
15161
15318
|
BookCoverPage,
|
|
15162
15319
|
{
|
|
15163
|
-
title:
|
|
15164
|
-
subtitle:
|
|
15165
|
-
author:
|
|
15166
|
-
coverImageUrl:
|
|
15320
|
+
title: coverTitle,
|
|
15321
|
+
subtitle: String(cover.subtitle ?? "") || void 0,
|
|
15322
|
+
author: String(cover.author ?? "") || void 0,
|
|
15323
|
+
coverImageUrl: String(cover.coverImageUrl ?? "") || void 0,
|
|
15167
15324
|
direction
|
|
15168
15325
|
}
|
|
15169
15326
|
),
|
|
@@ -15179,6 +15336,7 @@ var init_BookViewer = __esm({
|
|
|
15179
15336
|
BookChapterView,
|
|
15180
15337
|
{
|
|
15181
15338
|
chapter: chapters[currentPage - 2],
|
|
15339
|
+
orbitalSchema: currentChapterId ? book.schemaByChapterId[currentChapterId] : void 0,
|
|
15182
15340
|
direction
|
|
15183
15341
|
}
|
|
15184
15342
|
)
|
|
@@ -15191,7 +15349,7 @@ var init_BookViewer = __esm({
|
|
|
15191
15349
|
{
|
|
15192
15350
|
currentPage,
|
|
15193
15351
|
totalPages,
|
|
15194
|
-
chapterTitle: currentPage === 0 ?
|
|
15352
|
+
chapterTitle: currentPage === 0 ? coverTitle : currentPage === 1 ? t("book.tableOfContents") : currentChapterTitle,
|
|
15195
15353
|
direction
|
|
15196
15354
|
}
|
|
15197
15355
|
)
|
|
@@ -15289,7 +15447,7 @@ var init_Grid = __esm({
|
|
|
15289
15447
|
};
|
|
15290
15448
|
Grid = ({
|
|
15291
15449
|
cols = 1,
|
|
15292
|
-
rows,
|
|
15450
|
+
rows: rows2,
|
|
15293
15451
|
gap = "md",
|
|
15294
15452
|
rowGap,
|
|
15295
15453
|
colGap,
|
|
@@ -15301,8 +15459,8 @@ var init_Grid = __esm({
|
|
|
15301
15459
|
children,
|
|
15302
15460
|
as: Component = "div"
|
|
15303
15461
|
}) => {
|
|
15304
|
-
const mergedStyle =
|
|
15305
|
-
return
|
|
15462
|
+
const mergedStyle = rows2 ? { gridTemplateRows: `repeat(${rows2}, minmax(0, 1fr))`, ...style } : style;
|
|
15463
|
+
return React80__default.createElement(
|
|
15306
15464
|
Component,
|
|
15307
15465
|
{
|
|
15308
15466
|
className: cn(
|
|
@@ -16017,14 +16175,14 @@ function BuilderBoard({
|
|
|
16017
16175
|
}) {
|
|
16018
16176
|
const { emit } = useEventBus();
|
|
16019
16177
|
const { t } = useTranslate();
|
|
16020
|
-
const resolved =
|
|
16178
|
+
const resolved = boardEntity(entity);
|
|
16021
16179
|
const [placements, setPlacements] = useState({});
|
|
16022
16180
|
const [headerError, setHeaderError] = useState(false);
|
|
16023
16181
|
const [submitted, setSubmitted] = useState(false);
|
|
16024
16182
|
const [attempts, setAttempts] = useState(0);
|
|
16025
16183
|
const [showHint, setShowHint] = useState(false);
|
|
16026
|
-
const components = resolved?.components
|
|
16027
|
-
const slots = resolved?.slots
|
|
16184
|
+
const components = Array.isArray(resolved?.components) ? resolved.components : [];
|
|
16185
|
+
const slots = Array.isArray(resolved?.slots) ? resolved.slots : [];
|
|
16028
16186
|
const usedComponentIds = new Set(Object.values(placements));
|
|
16029
16187
|
const availableComponents = components.filter((c) => !usedComponentIds.has(c.id));
|
|
16030
16188
|
const [selectedComponent, setSelectedComponent] = useState(null);
|
|
@@ -16058,7 +16216,7 @@ function BuilderBoard({
|
|
|
16058
16216
|
}, [slots, placements, attempts, completeEvent, emit]);
|
|
16059
16217
|
const handleReset = () => {
|
|
16060
16218
|
setSubmitted(false);
|
|
16061
|
-
if (attempts >= 2 && resolved?.hint) {
|
|
16219
|
+
if (attempts >= 2 && str(resolved?.hint)) {
|
|
16062
16220
|
setShowHint(true);
|
|
16063
16221
|
}
|
|
16064
16222
|
};
|
|
@@ -16071,20 +16229,24 @@ function BuilderBoard({
|
|
|
16071
16229
|
};
|
|
16072
16230
|
const getComponentById = (id) => components.find((c) => c.id === id);
|
|
16073
16231
|
if (!resolved) return null;
|
|
16232
|
+
const theme = resolved.theme ?? void 0;
|
|
16233
|
+
const themeBackground = theme?.background;
|
|
16234
|
+
const headerImage = str(resolved.headerImage);
|
|
16235
|
+
const hint = str(resolved.hint);
|
|
16074
16236
|
return /* @__PURE__ */ jsx(
|
|
16075
16237
|
Box,
|
|
16076
16238
|
{
|
|
16077
16239
|
className,
|
|
16078
16240
|
style: {
|
|
16079
|
-
backgroundImage:
|
|
16241
|
+
backgroundImage: themeBackground ? `url(${themeBackground})` : void 0,
|
|
16080
16242
|
backgroundSize: "cover",
|
|
16081
16243
|
backgroundPosition: "center"
|
|
16082
16244
|
},
|
|
16083
16245
|
children: /* @__PURE__ */ jsxs(VStack, { gap: "lg", className: "p-4", children: [
|
|
16084
|
-
|
|
16246
|
+
headerImage && !headerError ? /* @__PURE__ */ jsx(Box, { className: "w-full h-32 overflow-hidden rounded-container", children: /* @__PURE__ */ jsx("img", { src: headerImage, alt: "", onError: () => setHeaderError(true), className: "w-full h-full object-cover" }) }) : headerImage && headerError ? /* @__PURE__ */ jsx(Box, { className: "w-full h-32 rounded-container bg-gradient-to-br from-muted to-accent opacity-60" }) : null,
|
|
16085
16247
|
/* @__PURE__ */ jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxs(VStack, { gap: "sm", children: [
|
|
16086
|
-
/* @__PURE__ */ jsx(Typography, { variant: "h4", weight: "bold", children: resolved.title }),
|
|
16087
|
-
/* @__PURE__ */ jsx(Typography, { variant: "body", children: resolved.description })
|
|
16248
|
+
/* @__PURE__ */ jsx(Typography, { variant: "h4", weight: "bold", children: str(resolved.title) }),
|
|
16249
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body", children: str(resolved.description) })
|
|
16088
16250
|
] }) }),
|
|
16089
16251
|
/* @__PURE__ */ jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxs(VStack, { gap: "sm", children: [
|
|
16090
16252
|
/* @__PURE__ */ jsx(Typography, { variant: "small", weight: "bold", className: "uppercase tracking-wider text-muted-foreground", children: t("builder.components") }),
|
|
@@ -16144,9 +16306,9 @@ function BuilderBoard({
|
|
|
16144
16306
|
] }) }),
|
|
16145
16307
|
submitted && /* @__PURE__ */ jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxs(VStack, { gap: "sm", align: "center", children: [
|
|
16146
16308
|
/* @__PURE__ */ jsx(Icon, { icon: allCorrect ? CheckCircle : XCircle, size: "lg", className: allCorrect ? "text-success" : "text-error" }),
|
|
16147
|
-
/* @__PURE__ */ jsx(Typography, { variant: "body", weight: "bold", children: allCorrect ? resolved.successMessage
|
|
16309
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body", weight: "bold", children: allCorrect ? str(resolved.successMessage) || t("builder.success") : str(resolved.failMessage) || t("builder.incorrect") })
|
|
16148
16310
|
] }) }),
|
|
16149
|
-
showHint &&
|
|
16311
|
+
showHint && hint && /* @__PURE__ */ jsx(Card, { className: "p-4 border-l-4 border-l-warning", children: /* @__PURE__ */ jsx(Typography, { variant: "body", children: hint }) }),
|
|
16150
16312
|
/* @__PURE__ */ jsxs(HStack, { gap: "sm", justify: "center", children: [
|
|
16151
16313
|
!submitted ? /* @__PURE__ */ jsxs(Button, { variant: "primary", onClick: handleSubmit, disabled: !allPlaced, children: [
|
|
16152
16314
|
/* @__PURE__ */ jsx(Icon, { icon: Wrench, size: "sm" }),
|
|
@@ -16165,6 +16327,7 @@ var init_BuilderBoard = __esm({
|
|
|
16165
16327
|
"components/game/organisms/puzzles/builder/BuilderBoard.tsx"() {
|
|
16166
16328
|
init_atoms2();
|
|
16167
16329
|
init_useEventBus();
|
|
16330
|
+
init_boardEntity();
|
|
16168
16331
|
BuilderBoard.displayName = "BuilderBoard";
|
|
16169
16332
|
}
|
|
16170
16333
|
});
|
|
@@ -16502,21 +16665,24 @@ function CalendarGrid({
|
|
|
16502
16665
|
eventBus.emit(`UI:${longPressEvent}`, { date: day.toISOString(), time, ...longPressPayload });
|
|
16503
16666
|
}, 500);
|
|
16504
16667
|
}, [longPressEvent, longPressPayload, eventBus]);
|
|
16505
|
-
const renderEvent = (event) =>
|
|
16506
|
-
|
|
16507
|
-
|
|
16508
|
-
|
|
16509
|
-
|
|
16510
|
-
|
|
16511
|
-
|
|
16512
|
-
|
|
16513
|
-
|
|
16514
|
-
|
|
16515
|
-
|
|
16516
|
-
|
|
16517
|
-
|
|
16518
|
-
|
|
16519
|
-
|
|
16668
|
+
const renderEvent = (event) => {
|
|
16669
|
+
const color = event.color;
|
|
16670
|
+
return /* @__PURE__ */ jsx(
|
|
16671
|
+
Box,
|
|
16672
|
+
{
|
|
16673
|
+
rounded: "md",
|
|
16674
|
+
padding: "xs",
|
|
16675
|
+
border: true,
|
|
16676
|
+
className: cn(
|
|
16677
|
+
"cursor-pointer hover:shadow-sm transition-shadow text-xs truncate",
|
|
16678
|
+
color ? color : "bg-blue-500/15 border-blue-500/30 text-blue-600"
|
|
16679
|
+
),
|
|
16680
|
+
onClick: (e) => handleEventClick(event, e),
|
|
16681
|
+
children: /* @__PURE__ */ jsx(Typography, { variant: "small", className: "truncate font-medium", children: event.title })
|
|
16682
|
+
},
|
|
16683
|
+
event.id
|
|
16684
|
+
);
|
|
16685
|
+
};
|
|
16520
16686
|
return /* @__PURE__ */ jsxs(
|
|
16521
16687
|
Box,
|
|
16522
16688
|
{
|
|
@@ -18180,7 +18346,6 @@ var init_CardGrid = __esm({
|
|
|
18180
18346
|
alignItems = "stretch",
|
|
18181
18347
|
className,
|
|
18182
18348
|
children,
|
|
18183
|
-
// EntityDisplayProps
|
|
18184
18349
|
entity,
|
|
18185
18350
|
isLoading = false,
|
|
18186
18351
|
error = null,
|
|
@@ -18652,14 +18817,14 @@ var init_CaseStudyOrganism = __esm({
|
|
|
18652
18817
|
/* @__PURE__ */ jsx(SimpleGrid, { cols: cols > 0 ? cols : 1, gap: "lg", children: items.map((study) => /* @__PURE__ */ jsx(
|
|
18653
18818
|
CaseStudyCard,
|
|
18654
18819
|
{
|
|
18655
|
-
title: study.title,
|
|
18656
|
-
description: study.description,
|
|
18657
|
-
category: study.category,
|
|
18658
|
-
categoryColor: study.categoryColor,
|
|
18659
|
-
href: study.href,
|
|
18660
|
-
linkLabel: study.linkLabel
|
|
18820
|
+
title: String(study.title ?? ""),
|
|
18821
|
+
description: String(study.description ?? ""),
|
|
18822
|
+
category: String(study.category ?? ""),
|
|
18823
|
+
categoryColor: study.categoryColor != null ? String(study.categoryColor) : void 0,
|
|
18824
|
+
href: String(study.href ?? ""),
|
|
18825
|
+
linkLabel: study.linkLabel != null ? String(study.linkLabel) : void 0
|
|
18661
18826
|
},
|
|
18662
|
-
study.id
|
|
18827
|
+
String(study.id ?? "")
|
|
18663
18828
|
)) })
|
|
18664
18829
|
] });
|
|
18665
18830
|
};
|
|
@@ -18682,10 +18847,10 @@ function CastleBoard({
|
|
|
18682
18847
|
className
|
|
18683
18848
|
}) {
|
|
18684
18849
|
const eventBus = useEventBus();
|
|
18685
|
-
const resolved =
|
|
18686
|
-
const tiles = resolved?.tiles
|
|
18687
|
-
const features = resolved?.features
|
|
18688
|
-
const units = resolved?.units
|
|
18850
|
+
const resolved = boardEntity(entity);
|
|
18851
|
+
const tiles = Array.isArray(resolved?.tiles) ? resolved.tiles : [];
|
|
18852
|
+
const features = Array.isArray(resolved?.features) ? resolved.features : [];
|
|
18853
|
+
const units = Array.isArray(resolved?.units) ? resolved.units : [];
|
|
18689
18854
|
const assetManifest = resolved?.assetManifest;
|
|
18690
18855
|
const backgroundImage = resolved?.backgroundImage;
|
|
18691
18856
|
const [hoveredTile, setHoveredTile] = useState(null);
|
|
@@ -18713,7 +18878,7 @@ function CastleBoard({
|
|
|
18713
18878
|
onFeatureClick?.(feature);
|
|
18714
18879
|
if (featureClickEvent) {
|
|
18715
18880
|
eventBus.emit(`UI:${featureClickEvent}`, {
|
|
18716
|
-
featureId: feature.id,
|
|
18881
|
+
featureId: feature.id ?? "",
|
|
18717
18882
|
featureType: feature.type,
|
|
18718
18883
|
x: feature.x,
|
|
18719
18884
|
y: feature.y
|
|
@@ -18781,6 +18946,7 @@ var init_CastleBoard = __esm({
|
|
|
18781
18946
|
init_cn();
|
|
18782
18947
|
init_useEventBus();
|
|
18783
18948
|
init_IsometricCanvas2();
|
|
18949
|
+
init_boardEntity();
|
|
18784
18950
|
init_isometric();
|
|
18785
18951
|
CastleBoard.displayName = "CastleBoard";
|
|
18786
18952
|
}
|
|
@@ -19637,14 +19803,14 @@ function ClassifierBoard({
|
|
|
19637
19803
|
}) {
|
|
19638
19804
|
const { emit } = useEventBus();
|
|
19639
19805
|
const { t } = useTranslate();
|
|
19640
|
-
const resolved =
|
|
19806
|
+
const resolved = boardEntity(entity);
|
|
19641
19807
|
const [assignments, setAssignments] = useState({});
|
|
19642
19808
|
const [headerError, setHeaderError] = useState(false);
|
|
19643
19809
|
const [submitted, setSubmitted] = useState(false);
|
|
19644
19810
|
const [attempts, setAttempts] = useState(0);
|
|
19645
19811
|
const [showHint, setShowHint] = useState(false);
|
|
19646
|
-
const items = resolved?.items
|
|
19647
|
-
const categories = resolved?.categories
|
|
19812
|
+
const items = Array.isArray(resolved?.items) ? resolved.items : [];
|
|
19813
|
+
const categories = Array.isArray(resolved?.categories) ? resolved.categories : [];
|
|
19648
19814
|
const unassignedItems = items.filter((item) => !assignments[item.id]);
|
|
19649
19815
|
const allAssigned = Object.keys(assignments).length === items.length;
|
|
19650
19816
|
const results = submitted ? items.map((item) => ({
|
|
@@ -19676,7 +19842,7 @@ function ClassifierBoard({
|
|
|
19676
19842
|
}, [items, assignments, attempts, completeEvent, emit]);
|
|
19677
19843
|
const handleReset = () => {
|
|
19678
19844
|
setSubmitted(false);
|
|
19679
|
-
if (attempts >= 2 && resolved?.hint) {
|
|
19845
|
+
if (attempts >= 2 && str(resolved?.hint)) {
|
|
19680
19846
|
setShowHint(true);
|
|
19681
19847
|
}
|
|
19682
19848
|
};
|
|
@@ -19687,20 +19853,25 @@ function ClassifierBoard({
|
|
|
19687
19853
|
setShowHint(false);
|
|
19688
19854
|
};
|
|
19689
19855
|
if (!resolved) return null;
|
|
19856
|
+
const theme = resolved.theme ?? void 0;
|
|
19857
|
+
const themeBackground = theme?.background;
|
|
19858
|
+
const headerImage = str(resolved.headerImage);
|
|
19859
|
+
const hint = str(resolved.hint);
|
|
19860
|
+
const failMessage = str(resolved.failMessage);
|
|
19690
19861
|
return /* @__PURE__ */ jsx(
|
|
19691
19862
|
Box,
|
|
19692
19863
|
{
|
|
19693
19864
|
className,
|
|
19694
19865
|
style: {
|
|
19695
|
-
backgroundImage:
|
|
19866
|
+
backgroundImage: themeBackground ? `url(${themeBackground})` : void 0,
|
|
19696
19867
|
backgroundSize: "cover",
|
|
19697
19868
|
backgroundPosition: "center"
|
|
19698
19869
|
},
|
|
19699
19870
|
children: /* @__PURE__ */ jsxs(VStack, { gap: "lg", className: "p-4", children: [
|
|
19700
|
-
|
|
19871
|
+
headerImage && !headerError ? /* @__PURE__ */ jsx(Box, { className: "w-full h-32 overflow-hidden rounded-container", children: /* @__PURE__ */ jsx("img", { src: headerImage, alt: "", onError: () => setHeaderError(true), className: "w-full h-full object-cover" }) }) : headerImage && headerError ? /* @__PURE__ */ jsx(Box, { className: "w-full h-32 rounded-container bg-gradient-to-br from-muted to-accent opacity-60" }) : null,
|
|
19701
19872
|
/* @__PURE__ */ jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxs(VStack, { gap: "sm", children: [
|
|
19702
|
-
/* @__PURE__ */ jsx(Typography, { variant: "h4", weight: "bold", children: resolved.title }),
|
|
19703
|
-
/* @__PURE__ */ jsx(Typography, { variant: "body", children: resolved.description })
|
|
19873
|
+
/* @__PURE__ */ jsx(Typography, { variant: "h4", weight: "bold", children: str(resolved.title) }),
|
|
19874
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body", children: str(resolved.description) })
|
|
19704
19875
|
] }) }),
|
|
19705
19876
|
unassignedItems.length > 0 && /* @__PURE__ */ jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxs(VStack, { gap: "sm", children: [
|
|
19706
19877
|
/* @__PURE__ */ jsx(Typography, { variant: "small", weight: "bold", className: "uppercase tracking-wider text-muted-foreground", children: t("classifier.itemsToSort") }),
|
|
@@ -19752,10 +19923,10 @@ function ClassifierBoard({
|
|
|
19752
19923
|
}) }),
|
|
19753
19924
|
submitted && /* @__PURE__ */ jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxs(VStack, { gap: "sm", align: "center", children: [
|
|
19754
19925
|
/* @__PURE__ */ jsx(Icon, { icon: allCorrect ? CheckCircle : XCircle, size: "lg", className: allCorrect ? "text-success" : "text-error" }),
|
|
19755
|
-
/* @__PURE__ */ jsx(Typography, { variant: "body", weight: "bold", children: allCorrect ? resolved.successMessage
|
|
19756
|
-
!allCorrect &&
|
|
19926
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body", weight: "bold", children: allCorrect ? str(resolved.successMessage) || t("classifier.allCorrect") : `${correctCount}/${items.length} ${t("classifier.correct")}` }),
|
|
19927
|
+
!allCorrect && failMessage && /* @__PURE__ */ jsx(Typography, { variant: "body", className: "text-muted-foreground", children: failMessage })
|
|
19757
19928
|
] }) }),
|
|
19758
|
-
showHint &&
|
|
19929
|
+
showHint && hint && /* @__PURE__ */ jsx(Card, { className: "p-4 border-l-4 border-l-warning", children: /* @__PURE__ */ jsx(Typography, { variant: "body", children: hint }) }),
|
|
19759
19930
|
/* @__PURE__ */ jsxs(HStack, { gap: "sm", justify: "center", children: [
|
|
19760
19931
|
!submitted ? /* @__PURE__ */ jsxs(Button, { variant: "primary", onClick: handleSubmit, disabled: !allAssigned, children: [
|
|
19761
19932
|
/* @__PURE__ */ jsx(Icon, { icon: Send, size: "sm" }),
|
|
@@ -19774,6 +19945,7 @@ var init_ClassifierBoard = __esm({
|
|
|
19774
19945
|
"components/game/organisms/puzzles/classifier/ClassifierBoard.tsx"() {
|
|
19775
19946
|
init_atoms2();
|
|
19776
19947
|
init_useEventBus();
|
|
19948
|
+
init_boardEntity();
|
|
19777
19949
|
ClassifierBoard.displayName = "ClassifierBoard";
|
|
19778
19950
|
}
|
|
19779
19951
|
});
|
|
@@ -20826,7 +20998,7 @@ function CraftingRecipe({
|
|
|
20826
20998
|
className
|
|
20827
20999
|
}) {
|
|
20828
21000
|
const eventBus = useEventBus();
|
|
20829
|
-
const handleCraft =
|
|
21001
|
+
const handleCraft = React80.useCallback(() => {
|
|
20830
21002
|
onCraft?.();
|
|
20831
21003
|
if (craftEvent) {
|
|
20832
21004
|
eventBus.emit(craftEvent, { output: output.label });
|
|
@@ -20843,7 +21015,7 @@ function CraftingRecipe({
|
|
|
20843
21015
|
children: [
|
|
20844
21016
|
/* @__PURE__ */ jsx(HStack, { gap: "xs", className: "flex-wrap items-center", children: inputs.map((ingredient, index) => {
|
|
20845
21017
|
const hasSufficient = ingredient.available >= ingredient.required;
|
|
20846
|
-
return /* @__PURE__ */ jsxs(
|
|
21018
|
+
return /* @__PURE__ */ jsxs(React80.Fragment, { children: [
|
|
20847
21019
|
/* @__PURE__ */ jsx(Box, { className: "relative", children: /* @__PURE__ */ jsx(
|
|
20848
21020
|
ItemSlot,
|
|
20849
21021
|
{
|
|
@@ -20906,8 +21078,8 @@ function DPad({
|
|
|
20906
21078
|
}) {
|
|
20907
21079
|
const eventBus = useEventBus();
|
|
20908
21080
|
const sizes = sizeMap6[size];
|
|
20909
|
-
const [activeDirections, setActiveDirections] =
|
|
20910
|
-
const handlePress =
|
|
21081
|
+
const [activeDirections, setActiveDirections] = React80.useState(/* @__PURE__ */ new Set());
|
|
21082
|
+
const handlePress = React80.useCallback(
|
|
20911
21083
|
(direction) => {
|
|
20912
21084
|
setActiveDirections((prev) => new Set(prev).add(direction));
|
|
20913
21085
|
if (directionEvent) eventBus.emit(`UI:${directionEvent}`, { direction, pressed: true });
|
|
@@ -20915,7 +21087,7 @@ function DPad({
|
|
|
20915
21087
|
},
|
|
20916
21088
|
[directionEvent, eventBus, onDirection]
|
|
20917
21089
|
);
|
|
20918
|
-
const handleRelease =
|
|
21090
|
+
const handleRelease = React80.useCallback(
|
|
20919
21091
|
(direction) => {
|
|
20920
21092
|
setActiveDirections((prev) => {
|
|
20921
21093
|
const next = new Set(prev);
|
|
@@ -21650,14 +21822,14 @@ function useDataDnd(args) {
|
|
|
21650
21822
|
const isZone = Boolean(dragGroup || accepts || sortable);
|
|
21651
21823
|
const enabled = isZone || Boolean(dndRoot);
|
|
21652
21824
|
const eventBus = useEventBus();
|
|
21653
|
-
const parentRoot =
|
|
21825
|
+
const parentRoot = React80__default.useContext(RootCtx);
|
|
21654
21826
|
const isRoot = enabled && parentRoot === null;
|
|
21655
|
-
const zoneId =
|
|
21827
|
+
const zoneId = React80__default.useId();
|
|
21656
21828
|
const ownGroup = dragGroup ?? accepts ?? zoneId;
|
|
21657
|
-
const [optimisticOrders, setOptimisticOrders] =
|
|
21658
|
-
const optimisticOrdersRef =
|
|
21829
|
+
const [optimisticOrders, setOptimisticOrders] = React80__default.useState(() => /* @__PURE__ */ new Map());
|
|
21830
|
+
const optimisticOrdersRef = React80__default.useRef(optimisticOrders);
|
|
21659
21831
|
optimisticOrdersRef.current = optimisticOrders;
|
|
21660
|
-
const clearOptimisticOrder =
|
|
21832
|
+
const clearOptimisticOrder = React80__default.useCallback((group) => {
|
|
21661
21833
|
setOptimisticOrders((prev) => {
|
|
21662
21834
|
if (!prev.has(group)) return prev;
|
|
21663
21835
|
const next = new Map(prev);
|
|
@@ -21682,7 +21854,7 @@ function useDataDnd(args) {
|
|
|
21682
21854
|
const raw = it[dndItemIdField];
|
|
21683
21855
|
return String(raw ?? `__idx_${idx}`);
|
|
21684
21856
|
}).join("|");
|
|
21685
|
-
const itemIds =
|
|
21857
|
+
const itemIds = React80__default.useMemo(
|
|
21686
21858
|
() => orderedItems.map((it, idx) => {
|
|
21687
21859
|
const raw = it[dndItemIdField];
|
|
21688
21860
|
return raw ?? `__idx_${idx}`;
|
|
@@ -21690,7 +21862,7 @@ function useDataDnd(args) {
|
|
|
21690
21862
|
[itemIdsSignature]
|
|
21691
21863
|
);
|
|
21692
21864
|
const itemsContentSig = items.map((it, idx) => String(it[dndItemIdField] ?? `__${idx}`)).join("|");
|
|
21693
|
-
|
|
21865
|
+
React80__default.useEffect(() => {
|
|
21694
21866
|
const root = isRoot ? null : parentRoot;
|
|
21695
21867
|
if (root) {
|
|
21696
21868
|
root.clearOptimisticOrder(ownGroup);
|
|
@@ -21698,20 +21870,20 @@ function useDataDnd(args) {
|
|
|
21698
21870
|
clearOptimisticOrder(ownGroup);
|
|
21699
21871
|
}
|
|
21700
21872
|
}, [itemsContentSig, ownGroup]);
|
|
21701
|
-
const zonesRef =
|
|
21702
|
-
const registerZone =
|
|
21873
|
+
const zonesRef = React80__default.useRef(/* @__PURE__ */ new Map());
|
|
21874
|
+
const registerZone = React80__default.useCallback((zoneId2, meta2) => {
|
|
21703
21875
|
zonesRef.current.set(zoneId2, meta2);
|
|
21704
21876
|
}, []);
|
|
21705
|
-
const unregisterZone =
|
|
21877
|
+
const unregisterZone = React80__default.useCallback((zoneId2) => {
|
|
21706
21878
|
zonesRef.current.delete(zoneId2);
|
|
21707
21879
|
}, []);
|
|
21708
|
-
const [activeDrag, setActiveDrag] =
|
|
21709
|
-
const [overZoneGroup, setOverZoneGroup] =
|
|
21710
|
-
const meta =
|
|
21880
|
+
const [activeDrag, setActiveDrag] = React80__default.useState(null);
|
|
21881
|
+
const [overZoneGroup, setOverZoneGroup] = React80__default.useState(null);
|
|
21882
|
+
const meta = React80__default.useMemo(
|
|
21711
21883
|
() => ({ group: ownGroup, dropEvent, reorderEvent, positionEvent, itemIds, rawItems: items, idField: dndItemIdField }),
|
|
21712
21884
|
[ownGroup, dropEvent, reorderEvent, positionEvent, itemIds, items, dndItemIdField]
|
|
21713
21885
|
);
|
|
21714
|
-
|
|
21886
|
+
React80__default.useEffect(() => {
|
|
21715
21887
|
const target = isRoot ? null : parentRoot;
|
|
21716
21888
|
if (!target) {
|
|
21717
21889
|
zonesRef.current.set(zoneId, meta);
|
|
@@ -21730,7 +21902,7 @@ function useDataDnd(args) {
|
|
|
21730
21902
|
}, [parentRoot, isRoot, zoneId, meta]);
|
|
21731
21903
|
const sensors = useAlmadarDndSensors(true);
|
|
21732
21904
|
const collisionDetection = almadarDndCollisionDetection;
|
|
21733
|
-
const findZoneByItem =
|
|
21905
|
+
const findZoneByItem = React80__default.useCallback(
|
|
21734
21906
|
(id) => {
|
|
21735
21907
|
for (const z of zonesRef.current.values()) {
|
|
21736
21908
|
if (z.itemIds.includes(id)) return z;
|
|
@@ -21739,7 +21911,7 @@ function useDataDnd(args) {
|
|
|
21739
21911
|
},
|
|
21740
21912
|
[]
|
|
21741
21913
|
);
|
|
21742
|
-
|
|
21914
|
+
React80__default.useCallback(
|
|
21743
21915
|
(group) => {
|
|
21744
21916
|
for (const z of zonesRef.current.values()) {
|
|
21745
21917
|
if (z.group === group) return z;
|
|
@@ -21748,7 +21920,7 @@ function useDataDnd(args) {
|
|
|
21748
21920
|
},
|
|
21749
21921
|
[]
|
|
21750
21922
|
);
|
|
21751
|
-
const handleDragEnd =
|
|
21923
|
+
const handleDragEnd = React80__default.useCallback(
|
|
21752
21924
|
(event) => {
|
|
21753
21925
|
const { active, over } = event;
|
|
21754
21926
|
const activeIdStr = String(active.id);
|
|
@@ -21839,8 +22011,8 @@ function useDataDnd(args) {
|
|
|
21839
22011
|
},
|
|
21840
22012
|
[eventBus]
|
|
21841
22013
|
);
|
|
21842
|
-
const sortableData =
|
|
21843
|
-
const SortableItem =
|
|
22014
|
+
const sortableData = React80__default.useMemo(() => ({ dndGroup: ownGroup }), [ownGroup]);
|
|
22015
|
+
const SortableItem = React80__default.useCallback(
|
|
21844
22016
|
({ id, children }) => {
|
|
21845
22017
|
const {
|
|
21846
22018
|
attributes,
|
|
@@ -21880,7 +22052,7 @@ function useDataDnd(args) {
|
|
|
21880
22052
|
id: droppableId,
|
|
21881
22053
|
data: sortableData
|
|
21882
22054
|
});
|
|
21883
|
-
const ctx =
|
|
22055
|
+
const ctx = React80__default.useContext(RootCtx);
|
|
21884
22056
|
const activeDrag2 = ctx?.activeDrag ?? null;
|
|
21885
22057
|
const overZoneGroup2 = ctx?.overZoneGroup ?? null;
|
|
21886
22058
|
const isThisZoneOver = overZoneGroup2 === ownGroup;
|
|
@@ -21895,7 +22067,7 @@ function useDataDnd(args) {
|
|
|
21895
22067
|
showForeignPlaceholder,
|
|
21896
22068
|
ctxAvailable: ctx != null
|
|
21897
22069
|
});
|
|
21898
|
-
|
|
22070
|
+
React80__default.useEffect(() => {
|
|
21899
22071
|
dndLog.info("dropzone:isOver:change", { droppableId, group: ownGroup, isOver, isThisZoneOver, showForeignPlaceholder, activeDragSourceGroup: activeDrag2?.sourceGroup ?? null });
|
|
21900
22072
|
}, [droppableId, isOver, isThisZoneOver, showForeignPlaceholder]);
|
|
21901
22073
|
return /* @__PURE__ */ jsx(
|
|
@@ -21909,11 +22081,11 @@ function useDataDnd(args) {
|
|
|
21909
22081
|
}
|
|
21910
22082
|
);
|
|
21911
22083
|
};
|
|
21912
|
-
const rootContextValue =
|
|
22084
|
+
const rootContextValue = React80__default.useMemo(
|
|
21913
22085
|
() => ({ registerZone, unregisterZone, activeDrag, overZoneGroup, optimisticOrders, clearOptimisticOrder }),
|
|
21914
22086
|
[registerZone, unregisterZone, activeDrag, overZoneGroup, optimisticOrders, clearOptimisticOrder]
|
|
21915
22087
|
);
|
|
21916
|
-
const handleDragStart =
|
|
22088
|
+
const handleDragStart = React80__default.useCallback((event) => {
|
|
21917
22089
|
const sourceZone = findZoneByItem(event.active.id);
|
|
21918
22090
|
const rect = event.active.rect.current.initial;
|
|
21919
22091
|
const height = rect?.height && rect.height > 0 ? rect.height : 64;
|
|
@@ -21932,7 +22104,7 @@ function useDataDnd(args) {
|
|
|
21932
22104
|
isRoot
|
|
21933
22105
|
});
|
|
21934
22106
|
}, [findZoneByItem, isRoot, zoneId]);
|
|
21935
|
-
const handleDragOver =
|
|
22107
|
+
const handleDragOver = React80__default.useCallback((event) => {
|
|
21936
22108
|
const { active, over } = event;
|
|
21937
22109
|
const overData = over?.data?.current;
|
|
21938
22110
|
const overGroup = overData?.dndGroup ?? null;
|
|
@@ -22002,7 +22174,7 @@ function useDataDnd(args) {
|
|
|
22002
22174
|
return next;
|
|
22003
22175
|
});
|
|
22004
22176
|
}, []);
|
|
22005
|
-
const handleDragCancel =
|
|
22177
|
+
const handleDragCancel = React80__default.useCallback((event) => {
|
|
22006
22178
|
setActiveDrag(null);
|
|
22007
22179
|
setOverZoneGroup(null);
|
|
22008
22180
|
dndLog.warn("dragCancel", {
|
|
@@ -22010,12 +22182,12 @@ function useDataDnd(args) {
|
|
|
22010
22182
|
reason: "dnd-kit cancelled the drag (escape key, pointer interrupted, or external)"
|
|
22011
22183
|
});
|
|
22012
22184
|
}, []);
|
|
22013
|
-
const handleDragEndWithCleanup =
|
|
22185
|
+
const handleDragEndWithCleanup = React80__default.useCallback((event) => {
|
|
22014
22186
|
handleDragEnd(event);
|
|
22015
22187
|
setActiveDrag(null);
|
|
22016
22188
|
setOverZoneGroup(null);
|
|
22017
22189
|
}, [handleDragEnd]);
|
|
22018
|
-
const wrapContainer =
|
|
22190
|
+
const wrapContainer = React80__default.useCallback(
|
|
22019
22191
|
(children) => {
|
|
22020
22192
|
if (!enabled) return children;
|
|
22021
22193
|
const strategy = layout === "grid" ? rectSortingStrategy : verticalListSortingStrategy;
|
|
@@ -22069,7 +22241,7 @@ var init_useDataDnd = __esm({
|
|
|
22069
22241
|
init_useAlmadarDndCollision();
|
|
22070
22242
|
init_Box();
|
|
22071
22243
|
dndLog = createLogger("almadar:ui:dnd");
|
|
22072
|
-
RootCtx =
|
|
22244
|
+
RootCtx = React80__default.createContext(null);
|
|
22073
22245
|
}
|
|
22074
22246
|
});
|
|
22075
22247
|
function fieldLabel2(key) {
|
|
@@ -22589,7 +22761,7 @@ function DataList({
|
|
|
22589
22761
|
}) {
|
|
22590
22762
|
const eventBus = useEventBus();
|
|
22591
22763
|
const { t } = useTranslate();
|
|
22592
|
-
const [visibleCount, setVisibleCount] =
|
|
22764
|
+
const [visibleCount, setVisibleCount] = React80__default.useState(pageSize || Infinity);
|
|
22593
22765
|
const fieldDefs = fields ?? columns ?? [];
|
|
22594
22766
|
const allDataRaw = Array.isArray(entity) ? entity : entity ? [entity] : [];
|
|
22595
22767
|
const dnd = useDataDnd({
|
|
@@ -22608,7 +22780,7 @@ function DataList({
|
|
|
22608
22780
|
const data = pageSize > 0 ? allData.slice(0, visibleCount) : allData;
|
|
22609
22781
|
const hasMoreLocal = pageSize > 0 && visibleCount < allData.length;
|
|
22610
22782
|
const hasRenderProp = typeof children === "function";
|
|
22611
|
-
|
|
22783
|
+
React80__default.useEffect(() => {
|
|
22612
22784
|
const renderItemTypeOf = typeof schemaRenderItem;
|
|
22613
22785
|
const childrenTypeOf = typeof children;
|
|
22614
22786
|
if (data.length > 0 && !hasRenderProp) {
|
|
@@ -22713,7 +22885,7 @@ function DataList({
|
|
|
22713
22885
|
const items2 = data.map((item) => item);
|
|
22714
22886
|
const groups2 = groupBy ? groupData(items2, groupBy) : [{ label: "", items: items2 }];
|
|
22715
22887
|
const contentField = titleField?.name ?? fieldDefs[0]?.name ?? "";
|
|
22716
|
-
return /* @__PURE__ */ jsx(VStack, { gap: "sm", className: cn("py-2", className), children: groups2.map((group, gi) => /* @__PURE__ */ jsxs(
|
|
22888
|
+
return /* @__PURE__ */ jsx(VStack, { gap: "sm", className: cn("py-2", className), children: groups2.map((group, gi) => /* @__PURE__ */ jsxs(React80__default.Fragment, { children: [
|
|
22717
22889
|
group.label && /* @__PURE__ */ jsx(Divider, { label: group.label, className: "my-2" }),
|
|
22718
22890
|
group.items.map((itemData, index) => {
|
|
22719
22891
|
const id = itemData.id || `${gi}-${index}`;
|
|
@@ -22861,7 +23033,7 @@ function DataList({
|
|
|
22861
23033
|
className
|
|
22862
23034
|
),
|
|
22863
23035
|
children: [
|
|
22864
|
-
groups.map((group, gi) => /* @__PURE__ */ jsxs(
|
|
23036
|
+
groups.map((group, gi) => /* @__PURE__ */ jsxs(React80__default.Fragment, { children: [
|
|
22865
23037
|
group.label && /* @__PURE__ */ jsx(Divider, { label: group.label, className: gi > 0 ? "mt-4" : "mt-0" }),
|
|
22866
23038
|
group.items.map(
|
|
22867
23039
|
(itemData, index) => renderItem(itemData, index, gi === groups.length - 1 && index === group.items.length - 1)
|
|
@@ -24485,7 +24657,7 @@ var init_WizardProgress = __esm({
|
|
|
24485
24657
|
children: /* @__PURE__ */ jsx("div", { className: "flex items-center gap-2", children: normalizedSteps.map((step, index) => {
|
|
24486
24658
|
const isActive = index === currentStep;
|
|
24487
24659
|
const isCompleted = index < currentStep;
|
|
24488
|
-
return /* @__PURE__ */ jsxs(
|
|
24660
|
+
return /* @__PURE__ */ jsxs(React80__default.Fragment, { children: [
|
|
24489
24661
|
/* @__PURE__ */ jsx(
|
|
24490
24662
|
"button",
|
|
24491
24663
|
{
|
|
@@ -25532,9 +25704,9 @@ function ScoreDisplay({
|
|
|
25532
25704
|
...rest
|
|
25533
25705
|
}) {
|
|
25534
25706
|
const resolvedValue = typeof value === "number" && !Number.isNaN(value) ? value : typeof rest.score === "number" && !Number.isNaN(rest.score) ? rest.score : 0;
|
|
25535
|
-
const [displayValue, setDisplayValue] =
|
|
25536
|
-
const [isAnimating, setIsAnimating] =
|
|
25537
|
-
|
|
25707
|
+
const [displayValue, setDisplayValue] = React80.useState(resolvedValue);
|
|
25708
|
+
const [isAnimating, setIsAnimating] = React80.useState(false);
|
|
25709
|
+
React80.useEffect(() => {
|
|
25538
25710
|
if (!animated || displayValue === resolvedValue) {
|
|
25539
25711
|
setDisplayValue(resolvedValue);
|
|
25540
25712
|
return;
|
|
@@ -25681,7 +25853,7 @@ function InventoryGrid({
|
|
|
25681
25853
|
const eventBus = useEventBus();
|
|
25682
25854
|
const slotCount = totalSlots ?? items.length;
|
|
25683
25855
|
const emptySlotCount = Math.max(0, slotCount - items.length);
|
|
25684
|
-
const handleSelect =
|
|
25856
|
+
const handleSelect = React80.useCallback(
|
|
25685
25857
|
(id) => {
|
|
25686
25858
|
onSelect?.(id);
|
|
25687
25859
|
if (selectEvent) {
|
|
@@ -25967,31 +26139,31 @@ function GameCanvas2D({
|
|
|
25967
26139
|
assetBaseUrl = "",
|
|
25968
26140
|
className
|
|
25969
26141
|
}) {
|
|
25970
|
-
const canvasRef =
|
|
25971
|
-
const rafRef =
|
|
25972
|
-
const frameRef =
|
|
25973
|
-
const lastTimeRef =
|
|
25974
|
-
const imageCache =
|
|
26142
|
+
const canvasRef = React80.useRef(null);
|
|
26143
|
+
const rafRef = React80.useRef(0);
|
|
26144
|
+
const frameRef = React80.useRef(0);
|
|
26145
|
+
const lastTimeRef = React80.useRef(0);
|
|
26146
|
+
const imageCache = React80.useRef(/* @__PURE__ */ new Map());
|
|
25975
26147
|
const emit = useEmitEvent();
|
|
25976
|
-
const onDrawRef =
|
|
26148
|
+
const onDrawRef = React80.useRef(onDraw);
|
|
25977
26149
|
onDrawRef.current = onDraw;
|
|
25978
|
-
const onTickRef =
|
|
26150
|
+
const onTickRef = React80.useRef(onTick);
|
|
25979
26151
|
onTickRef.current = onTick;
|
|
25980
|
-
const tickEventRef =
|
|
26152
|
+
const tickEventRef = React80.useRef(tickEvent);
|
|
25981
26153
|
tickEventRef.current = tickEvent;
|
|
25982
|
-
const drawEventRef =
|
|
26154
|
+
const drawEventRef = React80.useRef(drawEvent);
|
|
25983
26155
|
drawEventRef.current = drawEvent;
|
|
25984
|
-
const emitRef =
|
|
26156
|
+
const emitRef = React80.useRef(emit);
|
|
25985
26157
|
emitRef.current = emit;
|
|
25986
|
-
const assetBaseUrlRef =
|
|
26158
|
+
const assetBaseUrlRef = React80.useRef(assetBaseUrl);
|
|
25987
26159
|
assetBaseUrlRef.current = assetBaseUrl;
|
|
25988
|
-
const backgroundImageRef =
|
|
26160
|
+
const backgroundImageRef = React80.useRef(backgroundImage);
|
|
25989
26161
|
backgroundImageRef.current = backgroundImage;
|
|
25990
|
-
const widthRef =
|
|
26162
|
+
const widthRef = React80.useRef(width);
|
|
25991
26163
|
widthRef.current = width;
|
|
25992
|
-
const heightRef =
|
|
26164
|
+
const heightRef = React80.useRef(height);
|
|
25993
26165
|
heightRef.current = height;
|
|
25994
|
-
const loadImage =
|
|
26166
|
+
const loadImage = React80.useCallback((url) => {
|
|
25995
26167
|
const fullUrl = url.startsWith("http") ? url : `${assetBaseUrlRef.current}${url}`;
|
|
25996
26168
|
const cached = imageCache.current.get(fullUrl);
|
|
25997
26169
|
if (cached?.complete && cached.naturalWidth > 0) return cached;
|
|
@@ -26003,7 +26175,7 @@ function GameCanvas2D({
|
|
|
26003
26175
|
}
|
|
26004
26176
|
return null;
|
|
26005
26177
|
}, []);
|
|
26006
|
-
|
|
26178
|
+
React80.useEffect(() => {
|
|
26007
26179
|
const canvas = canvasRef.current;
|
|
26008
26180
|
if (!canvas) return;
|
|
26009
26181
|
const ctx = canvas.getContext("2d");
|
|
@@ -26358,7 +26530,7 @@ function TurnPanel({
|
|
|
26358
26530
|
className
|
|
26359
26531
|
}) {
|
|
26360
26532
|
const eventBus = useEventBus();
|
|
26361
|
-
const handleAction =
|
|
26533
|
+
const handleAction = React80.useCallback(
|
|
26362
26534
|
(event) => {
|
|
26363
26535
|
if (event) {
|
|
26364
26536
|
eventBus.emit(event, { turn: currentTurn, phase, activeTeam });
|
|
@@ -26504,7 +26676,7 @@ function UnitCommandBar({
|
|
|
26504
26676
|
className
|
|
26505
26677
|
}) {
|
|
26506
26678
|
const eventBus = useEventBus();
|
|
26507
|
-
const handleCommand =
|
|
26679
|
+
const handleCommand = React80.useCallback(
|
|
26508
26680
|
(event) => {
|
|
26509
26681
|
if (event) {
|
|
26510
26682
|
eventBus.emit(event, { unitId: selectedUnitId });
|
|
@@ -26837,7 +27009,7 @@ function InventoryPanel({
|
|
|
26837
27009
|
const slotArray = Array.from({ length: safeSlots }, (_, index) => {
|
|
26838
27010
|
return safeItems[index] ?? null;
|
|
26839
27011
|
});
|
|
26840
|
-
const
|
|
27012
|
+
const rows2 = Math.ceil(safeSlots / safeColumns);
|
|
26841
27013
|
const handleSlotClick = useCallback((index) => {
|
|
26842
27014
|
if (selectSlotEvent) eventBus.emit(`UI:${selectSlotEvent}`, { index });
|
|
26843
27015
|
onSelectSlot?.(index);
|
|
@@ -26906,7 +27078,7 @@ function InventoryPanel({
|
|
|
26906
27078
|
className: "grid gap-1 bg-[var(--color-card)] p-2 rounded-container border border-border",
|
|
26907
27079
|
style: {
|
|
26908
27080
|
gridTemplateColumns: `repeat(${safeColumns}, ${slotSize}px)`,
|
|
26909
|
-
gridTemplateRows: `repeat(${
|
|
27081
|
+
gridTemplateRows: `repeat(${rows2}, ${slotSize}px)`
|
|
26910
27082
|
},
|
|
26911
27083
|
children: slotArray.map((item, index) => /* @__PURE__ */ jsx(
|
|
26912
27084
|
"button",
|
|
@@ -26989,7 +27161,7 @@ function GameMenu({
|
|
|
26989
27161
|
} catch {
|
|
26990
27162
|
}
|
|
26991
27163
|
const eventBus = eventBusProp || eventBusFromHook;
|
|
26992
|
-
const handleOptionClick =
|
|
27164
|
+
const handleOptionClick = React80.useCallback(
|
|
26993
27165
|
(option) => {
|
|
26994
27166
|
if (option.event && eventBus) {
|
|
26995
27167
|
eventBus.emit(`UI:${option.event}`, { option });
|
|
@@ -27103,7 +27275,7 @@ function GameOverScreen({
|
|
|
27103
27275
|
} catch {
|
|
27104
27276
|
}
|
|
27105
27277
|
const eventBus = eventBusProp || eventBusFromHook;
|
|
27106
|
-
const handleActionClick =
|
|
27278
|
+
const handleActionClick = React80.useCallback(
|
|
27107
27279
|
(action) => {
|
|
27108
27280
|
if (action.event && eventBus) {
|
|
27109
27281
|
eventBus.emit(`UI:${action.event}`, { action });
|
|
@@ -28602,8 +28774,8 @@ function TableView({
|
|
|
28602
28774
|
}) {
|
|
28603
28775
|
const eventBus = useEventBus();
|
|
28604
28776
|
const { t } = useTranslate();
|
|
28605
|
-
const [visibleCount, setVisibleCount] =
|
|
28606
|
-
const [localSelected, setLocalSelected] =
|
|
28777
|
+
const [visibleCount, setVisibleCount] = React80__default.useState(pageSize > 0 ? pageSize : Infinity);
|
|
28778
|
+
const [localSelected, setLocalSelected] = React80__default.useState(/* @__PURE__ */ new Set());
|
|
28607
28779
|
const colDefs = columns ?? fields ?? [];
|
|
28608
28780
|
const allDataRaw = Array.isArray(entity) ? entity : entity ? [entity] : [];
|
|
28609
28781
|
const dnd = useDataDnd({
|
|
@@ -28798,12 +28970,12 @@ function TableView({
|
|
|
28798
28970
|
]
|
|
28799
28971
|
}
|
|
28800
28972
|
);
|
|
28801
|
-
return dnd.isZone ? /* @__PURE__ */ jsx(dnd.SortableItem, { id: row[idField] ?? id, children: rowInner }, id) : /* @__PURE__ */ jsx(
|
|
28973
|
+
return dnd.isZone ? /* @__PURE__ */ jsx(dnd.SortableItem, { id: row[idField] ?? id, children: rowInner }, id) : /* @__PURE__ */ jsx(React80__default.Fragment, { children: rowInner }, id);
|
|
28802
28974
|
};
|
|
28803
28975
|
const items = data.map((row) => row);
|
|
28804
28976
|
const groups = groupBy ? groupData2(items, groupBy) : [{ label: "", items }];
|
|
28805
28977
|
let runningIndex = 0;
|
|
28806
|
-
const body = /* @__PURE__ */ jsx(Box, { role: "rowgroup", children: groups.map((group, gi) => /* @__PURE__ */ jsxs(
|
|
28978
|
+
const body = /* @__PURE__ */ jsx(Box, { role: "rowgroup", children: groups.map((group, gi) => /* @__PURE__ */ jsxs(React80__default.Fragment, { children: [
|
|
28807
28979
|
group.label && /* @__PURE__ */ jsx(Divider, { label: group.label, className: gi > 0 ? "mt-3" : "mt-0" }),
|
|
28808
28980
|
group.items.map((row) => renderRow(row, runningIndex++))
|
|
28809
28981
|
] }, gi)) });
|
|
@@ -30155,7 +30327,7 @@ var init_StepFlow = __esm({
|
|
|
30155
30327
|
className
|
|
30156
30328
|
}) => {
|
|
30157
30329
|
if (orientation === "vertical") {
|
|
30158
|
-
return /* @__PURE__ */ jsx(VStack, { gap: "none", className: cn("w-full", className), children: steps.map((step, index) => /* @__PURE__ */ jsx(
|
|
30330
|
+
return /* @__PURE__ */ jsx(VStack, { gap: "none", className: cn("w-full", className), children: steps.map((step, index) => /* @__PURE__ */ jsx(React80__default.Fragment, { children: /* @__PURE__ */ jsxs(HStack, { gap: "md", align: "start", className: "w-full", children: [
|
|
30159
30331
|
/* @__PURE__ */ jsxs(VStack, { gap: "none", align: "center", children: [
|
|
30160
30332
|
/* @__PURE__ */ jsx(StepCircle, { step, index }),
|
|
30161
30333
|
showConnectors && index < steps.length - 1 && /* @__PURE__ */ jsx(Box, { className: "w-px h-8 bg-border" })
|
|
@@ -30166,7 +30338,7 @@ var init_StepFlow = __esm({
|
|
|
30166
30338
|
] })
|
|
30167
30339
|
] }) }, index)) });
|
|
30168
30340
|
}
|
|
30169
|
-
return /* @__PURE__ */ jsx(Box, { className: cn("w-full flex flex-col md:flex-row items-start gap-0", className), children: steps.map((step, index) => /* @__PURE__ */ jsxs(
|
|
30341
|
+
return /* @__PURE__ */ jsx(Box, { className: cn("w-full flex flex-col md:flex-row items-start gap-0", className), children: steps.map((step, index) => /* @__PURE__ */ jsxs(React80__default.Fragment, { children: [
|
|
30170
30342
|
/* @__PURE__ */ jsxs(VStack, { gap: "sm", align: "center", className: "flex-1 w-full md:w-auto", children: [
|
|
30171
30343
|
/* @__PURE__ */ jsx(StepCircle, { step, index }),
|
|
30172
30344
|
/* @__PURE__ */ jsx(Typography, { variant: "h4", className: "text-center", children: step.title }),
|
|
@@ -30892,11 +31064,11 @@ function LatticeSVG({
|
|
|
30892
31064
|
}) {
|
|
30893
31065
|
const paths = [];
|
|
30894
31066
|
const cols = 5;
|
|
30895
|
-
const
|
|
31067
|
+
const rows2 = Math.ceil(h / (w / cols));
|
|
30896
31068
|
const cellW = w / cols;
|
|
30897
31069
|
const cellH = cellW;
|
|
30898
31070
|
const bulge = cellW * 0.3;
|
|
30899
|
-
for (let row = 0; row <
|
|
31071
|
+
for (let row = 0; row < rows2; row++) {
|
|
30900
31072
|
for (let col = 0; col < cols; col++) {
|
|
30901
31073
|
const cx = col * cellW + cellW / 2;
|
|
30902
31074
|
const cy = row * cellH + cellH / 2;
|
|
@@ -31142,7 +31314,7 @@ var init_LikertScale = __esm({
|
|
|
31142
31314
|
md: "text-base",
|
|
31143
31315
|
lg: "text-lg"
|
|
31144
31316
|
};
|
|
31145
|
-
LikertScale =
|
|
31317
|
+
LikertScale = React80__default.forwardRef(
|
|
31146
31318
|
({
|
|
31147
31319
|
question,
|
|
31148
31320
|
options = DEFAULT_LIKERT_OPTIONS,
|
|
@@ -31154,7 +31326,7 @@ var init_LikertScale = __esm({
|
|
|
31154
31326
|
variant = "radios",
|
|
31155
31327
|
className
|
|
31156
31328
|
}, ref) => {
|
|
31157
|
-
const groupId =
|
|
31329
|
+
const groupId = React80__default.useId();
|
|
31158
31330
|
const eventBus = useEventBus();
|
|
31159
31331
|
const handleSelect = useCallback(
|
|
31160
31332
|
(next) => {
|
|
@@ -31308,7 +31480,7 @@ var init_MatrixQuestion = __esm({
|
|
|
31308
31480
|
};
|
|
31309
31481
|
MatrixQuestion = ({
|
|
31310
31482
|
title,
|
|
31311
|
-
rows,
|
|
31483
|
+
rows: rows2,
|
|
31312
31484
|
columns = DEFAULT_MATRIX_COLUMNS,
|
|
31313
31485
|
values,
|
|
31314
31486
|
onChange,
|
|
@@ -31318,7 +31490,7 @@ var init_MatrixQuestion = __esm({
|
|
|
31318
31490
|
className
|
|
31319
31491
|
}) => {
|
|
31320
31492
|
const styles = sizeStyles13[size];
|
|
31321
|
-
const safeRows =
|
|
31493
|
+
const safeRows = rows2 ?? [];
|
|
31322
31494
|
const safeValues = values ?? {};
|
|
31323
31495
|
const eventBus = useEventBus();
|
|
31324
31496
|
const handleChange = useCallback(
|
|
@@ -31946,7 +32118,8 @@ var init_PositionedCanvas = __esm({
|
|
|
31946
32118
|
dragRef.current = null;
|
|
31947
32119
|
setDraggingId(null);
|
|
31948
32120
|
if (!wasDrag) {
|
|
31949
|
-
const
|
|
32121
|
+
const itemId = item.id;
|
|
32122
|
+
const next = selectedId === itemId ? null : itemId;
|
|
31950
32123
|
onSelect?.(next);
|
|
31951
32124
|
if (selectEvent) {
|
|
31952
32125
|
eventBus.emit(`UI:${selectEvent}`, { id: next });
|
|
@@ -31981,15 +32154,22 @@ var init_PositionedCanvas = __esm({
|
|
|
31981
32154
|
style: { width, height },
|
|
31982
32155
|
onClick: handleContainerClick,
|
|
31983
32156
|
children: items.map((item) => {
|
|
32157
|
+
const itemId = item.id;
|
|
32158
|
+
const label = item.label;
|
|
32159
|
+
const x = item.x;
|
|
32160
|
+
const y = item.y;
|
|
32161
|
+
const capacity = item.capacity;
|
|
32162
|
+
const partySize = item.partySize;
|
|
32163
|
+
const serverName = item.serverName;
|
|
31984
32164
|
const status = item.status ?? "empty";
|
|
31985
32165
|
const shape = item.shape ?? "round";
|
|
31986
|
-
const isSelected = selectedId ===
|
|
31987
|
-
const isDragging = draggingId ===
|
|
32166
|
+
const isSelected = selectedId === itemId;
|
|
32167
|
+
const isDragging = draggingId === itemId;
|
|
31988
32168
|
const statusBadge = STATUS_BADGE[status];
|
|
31989
32169
|
return /* @__PURE__ */ jsxs(
|
|
31990
32170
|
Box,
|
|
31991
32171
|
{
|
|
31992
|
-
"data-testid": `item-node-${
|
|
32172
|
+
"data-testid": `item-node-${itemId}`,
|
|
31993
32173
|
"data-status": status,
|
|
31994
32174
|
className: cn(
|
|
31995
32175
|
"absolute flex flex-col items-center justify-center gap-1 border-2 select-none",
|
|
@@ -32000,7 +32180,7 @@ var init_PositionedCanvas = __esm({
|
|
|
32000
32180
|
isSelected && "outline outline-2 outline-offset-2 outline-primary shadow-md",
|
|
32001
32181
|
isDragging && "shadow-lg z-10"
|
|
32002
32182
|
),
|
|
32003
|
-
style: { left:
|
|
32183
|
+
style: { left: x, top: y, touchAction: "none" },
|
|
32004
32184
|
onPointerDown: (e) => handlePointerDown(e, item),
|
|
32005
32185
|
onPointerMove: handlePointerMove,
|
|
32006
32186
|
onPointerUp: (e) => handlePointerUp(e, item),
|
|
@@ -32008,10 +32188,10 @@ var init_PositionedCanvas = __esm({
|
|
|
32008
32188
|
children: [
|
|
32009
32189
|
/* @__PURE__ */ jsxs(Box, { className: "flex items-center gap-1", children: [
|
|
32010
32190
|
getStatusIcon(status),
|
|
32011
|
-
/* @__PURE__ */ jsx(Typography, { variant: "body2", weight: "semibold", children:
|
|
32191
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body2", weight: "semibold", children: label })
|
|
32012
32192
|
] }),
|
|
32013
|
-
/* @__PURE__ */ jsx(Typography, { variant: "caption", color: "secondary", children:
|
|
32014
|
-
status === "seated" &&
|
|
32193
|
+
/* @__PURE__ */ jsx(Typography, { variant: "caption", color: "secondary", children: partySize !== void 0 && status === "seated" ? `${partySize}/${capacity}` : `Cap ${capacity}` }),
|
|
32194
|
+
status === "seated" && serverName && /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "secondary", className: "truncate max-w-[80%]", children: serverName }),
|
|
32015
32195
|
isSelected && /* @__PURE__ */ jsx(
|
|
32016
32196
|
Badge,
|
|
32017
32197
|
{
|
|
@@ -32023,7 +32203,7 @@ var init_PositionedCanvas = __esm({
|
|
|
32023
32203
|
)
|
|
32024
32204
|
]
|
|
32025
32205
|
},
|
|
32026
|
-
|
|
32206
|
+
itemId
|
|
32027
32207
|
);
|
|
32028
32208
|
})
|
|
32029
32209
|
}
|
|
@@ -32795,9 +32975,10 @@ var init_RichBlockEditor = __esm({
|
|
|
32795
32975
|
});
|
|
32796
32976
|
function collectInitiallyCollapsed(nodes, acc) {
|
|
32797
32977
|
for (const n of nodes) {
|
|
32978
|
+
const replies = n.replies;
|
|
32798
32979
|
if (n.collapsed) acc.add(n.id);
|
|
32799
|
-
if (
|
|
32800
|
-
collectInitiallyCollapsed(
|
|
32980
|
+
if (replies && replies.length > 0) {
|
|
32981
|
+
collectInitiallyCollapsed(replies, acc);
|
|
32801
32982
|
}
|
|
32802
32983
|
}
|
|
32803
32984
|
}
|
|
@@ -32827,44 +33008,52 @@ var init_ReplyTree = __esm({
|
|
|
32827
33008
|
}) => {
|
|
32828
33009
|
const eventBus = useEventBus();
|
|
32829
33010
|
const { t } = useTranslate();
|
|
32830
|
-
const
|
|
32831
|
-
const
|
|
33011
|
+
const nodeId = node.id;
|
|
33012
|
+
const authorName = node.authorName;
|
|
33013
|
+
const authorAvatarUrl = node.authorAvatarUrl;
|
|
33014
|
+
const content = node.content;
|
|
33015
|
+
const postedAt = node.postedAt;
|
|
33016
|
+
const voteCount = node.voteCount;
|
|
33017
|
+
const userVote = node.userVote;
|
|
33018
|
+
const replies = node.replies;
|
|
33019
|
+
const hasReplies = !!replies && replies.length > 0;
|
|
33020
|
+
const isCollapsed = collapsedSet.has(nodeId);
|
|
32832
33021
|
const atMaxDepth = depth >= maxDepth;
|
|
32833
33022
|
const [replyOpen, setReplyOpen] = useState(false);
|
|
32834
33023
|
const [draft, setDraft] = useState("");
|
|
32835
33024
|
const handleVote = useCallback(
|
|
32836
33025
|
(next) => {
|
|
32837
|
-
onVote?.(
|
|
32838
|
-
if (voteEvent) eventBus.emit(`UI:${voteEvent}`, { nodeId
|
|
33026
|
+
onVote?.(nodeId, next);
|
|
33027
|
+
if (voteEvent) eventBus.emit(`UI:${voteEvent}`, { nodeId, vote: next });
|
|
32839
33028
|
},
|
|
32840
|
-
[
|
|
33029
|
+
[nodeId, onVote, voteEvent, eventBus]
|
|
32841
33030
|
);
|
|
32842
33031
|
const handleReply = useCallback(() => {
|
|
32843
|
-
onReply?.(
|
|
33032
|
+
onReply?.(nodeId);
|
|
32844
33033
|
setReplyOpen((open) => !open);
|
|
32845
|
-
}, [
|
|
33034
|
+
}, [nodeId, onReply]);
|
|
32846
33035
|
const handleSubmitReply = useCallback(() => {
|
|
32847
|
-
const
|
|
32848
|
-
if (!
|
|
32849
|
-
if (replyEvent) eventBus.emit(`UI:${replyEvent}`, { parentNodeId:
|
|
33036
|
+
const text = draft.trim();
|
|
33037
|
+
if (!text) return;
|
|
33038
|
+
if (replyEvent) eventBus.emit(`UI:${replyEvent}`, { parentNodeId: nodeId, content: text });
|
|
32850
33039
|
setDraft("");
|
|
32851
33040
|
setReplyOpen(false);
|
|
32852
|
-
}, [
|
|
33041
|
+
}, [nodeId, draft, replyEvent, eventBus]);
|
|
32853
33042
|
const handleCancelReply = useCallback(() => {
|
|
32854
33043
|
setDraft("");
|
|
32855
33044
|
setReplyOpen(false);
|
|
32856
33045
|
}, []);
|
|
32857
33046
|
const handleFlag = useCallback(() => {
|
|
32858
|
-
onFlag?.(
|
|
32859
|
-
if (flagEvent) eventBus.emit(`UI:${flagEvent}`, { nodeId
|
|
32860
|
-
}, [
|
|
33047
|
+
onFlag?.(nodeId);
|
|
33048
|
+
if (flagEvent) eventBus.emit(`UI:${flagEvent}`, { nodeId });
|
|
33049
|
+
}, [nodeId, onFlag, flagEvent, eventBus]);
|
|
32861
33050
|
const handleContinue = useCallback(() => {
|
|
32862
|
-
onContinueThread?.(
|
|
32863
|
-
if (continueThreadEvent) eventBus.emit(`UI:${continueThreadEvent}`, { nodeId
|
|
32864
|
-
}, [
|
|
33051
|
+
onContinueThread?.(nodeId);
|
|
33052
|
+
if (continueThreadEvent) eventBus.emit(`UI:${continueThreadEvent}`, { nodeId });
|
|
33053
|
+
}, [nodeId, onContinueThread, continueThreadEvent, eventBus]);
|
|
32865
33054
|
const handleToggle = useCallback(() => {
|
|
32866
|
-
toggleCollapse(
|
|
32867
|
-
}, [
|
|
33055
|
+
toggleCollapse(nodeId);
|
|
33056
|
+
}, [nodeId, toggleCollapse]);
|
|
32868
33057
|
return /* @__PURE__ */ jsxs(Box, { className: "flex flex-row gap-2 items-stretch min-w-0", children: [
|
|
32869
33058
|
/* @__PURE__ */ jsxs(Box, { className: "flex flex-col items-center flex-shrink-0 w-6", children: [
|
|
32870
33059
|
hasReplies ? /* @__PURE__ */ jsx(
|
|
@@ -32896,25 +33085,25 @@ var init_ReplyTree = __esm({
|
|
|
32896
33085
|
/* @__PURE__ */ jsx(
|
|
32897
33086
|
Avatar,
|
|
32898
33087
|
{
|
|
32899
|
-
src:
|
|
32900
|
-
name:
|
|
33088
|
+
src: authorAvatarUrl,
|
|
33089
|
+
name: authorName,
|
|
32901
33090
|
size: "sm"
|
|
32902
33091
|
}
|
|
32903
33092
|
),
|
|
32904
|
-
/* @__PURE__ */ jsx(Typography, { variant: "body", weight: "semibold", children:
|
|
32905
|
-
/* @__PURE__ */ jsx(Typography, { variant: "caption", color: "secondary", children:
|
|
33093
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body", weight: "semibold", children: authorName }),
|
|
33094
|
+
/* @__PURE__ */ jsx(Typography, { variant: "caption", color: "secondary", children: postedAt })
|
|
32906
33095
|
] }),
|
|
32907
|
-
/* @__PURE__ */ jsx(Typography, { variant: "body", className: "whitespace-pre-wrap break-words", children:
|
|
33096
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body", className: "whitespace-pre-wrap break-words", children: content }),
|
|
32908
33097
|
showActions && /* @__PURE__ */ jsxs(Box, { className: "flex flex-row gap-2 items-center", children: [
|
|
32909
33098
|
/* @__PURE__ */ jsx(
|
|
32910
33099
|
VoteStack,
|
|
32911
33100
|
{
|
|
32912
|
-
count:
|
|
32913
|
-
userVote:
|
|
33101
|
+
count: voteCount ?? 0,
|
|
33102
|
+
userVote: userVote ?? null,
|
|
32914
33103
|
onVote: handleVote,
|
|
32915
33104
|
size: "sm",
|
|
32916
33105
|
variant: "horizontal",
|
|
32917
|
-
label: t("replyTree.voteOnReplyBy", { author:
|
|
33106
|
+
label: t("replyTree.voteOnReplyBy", { author: authorName })
|
|
32918
33107
|
}
|
|
32919
33108
|
),
|
|
32920
33109
|
/* @__PURE__ */ jsx(
|
|
@@ -32924,7 +33113,7 @@ var init_ReplyTree = __esm({
|
|
|
32924
33113
|
size: "sm",
|
|
32925
33114
|
leftIcon: "message-square",
|
|
32926
33115
|
onClick: handleReply,
|
|
32927
|
-
"aria-label": t("replyTree.replyTo", { author:
|
|
33116
|
+
"aria-label": t("replyTree.replyTo", { author: authorName }),
|
|
32928
33117
|
children: t("replyTree.reply")
|
|
32929
33118
|
}
|
|
32930
33119
|
),
|
|
@@ -32935,7 +33124,7 @@ var init_ReplyTree = __esm({
|
|
|
32935
33124
|
size: "sm",
|
|
32936
33125
|
leftIcon: "flag",
|
|
32937
33126
|
onClick: handleFlag,
|
|
32938
|
-
"aria-label": t("replyTree.flagReplyBy", { author:
|
|
33127
|
+
"aria-label": t("replyTree.flagReplyBy", { author: authorName }),
|
|
32939
33128
|
children: t("replyTree.flag")
|
|
32940
33129
|
}
|
|
32941
33130
|
)
|
|
@@ -32947,9 +33136,9 @@ var init_ReplyTree = __esm({
|
|
|
32947
33136
|
inputType: "textarea",
|
|
32948
33137
|
rows: 2,
|
|
32949
33138
|
value: draft,
|
|
32950
|
-
placeholder: t("replyTree.replyToPlaceholder", { author:
|
|
33139
|
+
placeholder: t("replyTree.replyToPlaceholder", { author: authorName }),
|
|
32951
33140
|
onChange: (e) => setDraft(e.target.value),
|
|
32952
|
-
"aria-label": t("replyTree.replyTo", { author:
|
|
33141
|
+
"aria-label": t("replyTree.replyTo", { author: authorName })
|
|
32953
33142
|
}
|
|
32954
33143
|
),
|
|
32955
33144
|
/* @__PURE__ */ jsxs(Box, { className: "flex flex-row gap-2 items-center", children: [
|
|
@@ -32980,7 +33169,7 @@ var init_ReplyTree = __esm({
|
|
|
32980
33169
|
),
|
|
32981
33170
|
children: t("replyTree.continueThread")
|
|
32982
33171
|
}
|
|
32983
|
-
) : /* @__PURE__ */ jsx(Box, { className: "flex flex-col gap-2 mt-1", children:
|
|
33172
|
+
) : /* @__PURE__ */ jsx(Box, { className: "flex flex-col gap-2 mt-1", children: replies.map((child) => /* @__PURE__ */ jsx(
|
|
32984
33173
|
ReplyTreeNode,
|
|
32985
33174
|
{
|
|
32986
33175
|
node: child,
|
|
@@ -33442,7 +33631,7 @@ var init_DocBreadcrumb = __esm({
|
|
|
33442
33631
|
"aria-label": t("aria.breadcrumb"),
|
|
33443
33632
|
children: /* @__PURE__ */ jsx(HStack, { gap: "xs", align: "center", wrap: true, children: items.map((item, idx) => {
|
|
33444
33633
|
const isLast = idx === items.length - 1;
|
|
33445
|
-
return /* @__PURE__ */ jsxs(
|
|
33634
|
+
return /* @__PURE__ */ jsxs(React80__default.Fragment, { children: [
|
|
33446
33635
|
idx > 0 && /* @__PURE__ */ jsx(
|
|
33447
33636
|
Icon,
|
|
33448
33637
|
{
|
|
@@ -34406,7 +34595,7 @@ var init_MiniStateMachine = __esm({
|
|
|
34406
34595
|
const x = 2 + i * (NODE_W + GAP2 + ARROW_W + GAP2);
|
|
34407
34596
|
const tc = transitionCounts[s.name] ?? 0;
|
|
34408
34597
|
const role = getStateRole(s.name, s.isInitial, s.isTerminal, tc, maxTC);
|
|
34409
|
-
return /* @__PURE__ */ jsxs(
|
|
34598
|
+
return /* @__PURE__ */ jsxs(React80__default.Fragment, { children: [
|
|
34410
34599
|
/* @__PURE__ */ jsx(
|
|
34411
34600
|
AvlState,
|
|
34412
34601
|
{
|
|
@@ -34610,7 +34799,7 @@ var init_PageHeader = __esm({
|
|
|
34610
34799
|
info: "bg-info/10 text-info"
|
|
34611
34800
|
};
|
|
34612
34801
|
return /* @__PURE__ */ jsxs(Box, { className: cn("mb-6", className), children: [
|
|
34613
|
-
breadcrumbs && breadcrumbs.length > 0 && /* @__PURE__ */ jsx(Box, { as: "nav", className: "mb-4", children: /* @__PURE__ */ jsx(Box, { as: "ol", className: "flex items-center gap-2 text-sm", children: breadcrumbs.map((crumb, idx) => /* @__PURE__ */ jsxs(
|
|
34802
|
+
breadcrumbs && breadcrumbs.length > 0 && /* @__PURE__ */ jsx(Box, { as: "nav", className: "mb-4", children: /* @__PURE__ */ jsx(Box, { as: "ol", className: "flex items-center gap-2 text-sm", children: breadcrumbs.map((crumb, idx) => /* @__PURE__ */ jsxs(React80__default.Fragment, { children: [
|
|
34614
34803
|
idx > 0 && /* @__PURE__ */ jsx(Typography, { variant: "small", color: "muted", children: "/" }),
|
|
34615
34804
|
crumb.href ? /* @__PURE__ */ jsx(
|
|
34616
34805
|
"a",
|
|
@@ -34719,7 +34908,7 @@ var init_FormSection = __esm({
|
|
|
34719
34908
|
columns = 1,
|
|
34720
34909
|
className
|
|
34721
34910
|
}) => {
|
|
34722
|
-
const [collapsed, setCollapsed] =
|
|
34911
|
+
const [collapsed, setCollapsed] = React80__default.useState(defaultCollapsed);
|
|
34723
34912
|
const { t } = useTranslate();
|
|
34724
34913
|
const eventBus = useEventBus();
|
|
34725
34914
|
const gridClass = {
|
|
@@ -34727,7 +34916,7 @@ var init_FormSection = __esm({
|
|
|
34727
34916
|
2: "grid-cols-1 md:grid-cols-2",
|
|
34728
34917
|
3: "grid-cols-1 md:grid-cols-2 lg:grid-cols-3"
|
|
34729
34918
|
}[columns];
|
|
34730
|
-
|
|
34919
|
+
React80__default.useCallback(() => {
|
|
34731
34920
|
if (collapsible) {
|
|
34732
34921
|
setCollapsed((prev) => !prev);
|
|
34733
34922
|
eventBus.emit("UI:TOGGLE_COLLAPSE", { collapsed: !collapsed });
|
|
@@ -35427,8 +35616,8 @@ var init_WizardContainer = __esm({
|
|
|
35427
35616
|
return void 0;
|
|
35428
35617
|
if (typeof controlledStep === "number") return controlledStep;
|
|
35429
35618
|
if (typeof controlledStep === "string") return parseInt(controlledStep, 10);
|
|
35430
|
-
const
|
|
35431
|
-
return isNaN(
|
|
35619
|
+
const num2 = Number(controlledStep);
|
|
35620
|
+
return isNaN(num2) ? void 0 : num2;
|
|
35432
35621
|
})();
|
|
35433
35622
|
const currentStep = normalizedControlledStep !== void 0 ? normalizedControlledStep : internalStep;
|
|
35434
35623
|
const totalSteps = steps.length;
|
|
@@ -35474,7 +35663,7 @@ var init_WizardContainer = __esm({
|
|
|
35474
35663
|
const isCompleted = index < currentStep;
|
|
35475
35664
|
const stepKey = step.id ?? step.tabId ?? `step-${index}`;
|
|
35476
35665
|
const stepTitle = step.title ?? step.name ?? `Step ${index + 1}`;
|
|
35477
|
-
return /* @__PURE__ */ jsxs(
|
|
35666
|
+
return /* @__PURE__ */ jsxs(React80__default.Fragment, { children: [
|
|
35478
35667
|
/* @__PURE__ */ jsx(
|
|
35479
35668
|
Button,
|
|
35480
35669
|
{
|
|
@@ -37253,7 +37442,7 @@ function DebuggerBoard({
|
|
|
37253
37442
|
}) {
|
|
37254
37443
|
const { emit } = useEventBus();
|
|
37255
37444
|
const { t } = useTranslate();
|
|
37256
|
-
const resolved =
|
|
37445
|
+
const resolved = boardEntity(entity);
|
|
37257
37446
|
const [flaggedLines, setFlaggedLines] = useState(/* @__PURE__ */ new Set());
|
|
37258
37447
|
const [headerError, setHeaderError] = useState(false);
|
|
37259
37448
|
const [submitted, setSubmitted] = useState(false);
|
|
@@ -37271,7 +37460,7 @@ function DebuggerBoard({
|
|
|
37271
37460
|
return next;
|
|
37272
37461
|
});
|
|
37273
37462
|
};
|
|
37274
|
-
const lines = resolved?.lines
|
|
37463
|
+
const lines = Array.isArray(resolved?.lines) ? resolved.lines : [];
|
|
37275
37464
|
const bugLines = lines.filter((l) => l.isBug);
|
|
37276
37465
|
const correctFlags = lines.filter((l) => l.isBug && flaggedLines.has(l.id));
|
|
37277
37466
|
const falseFlags = lines.filter((l) => !l.isBug && flaggedLines.has(l.id));
|
|
@@ -37286,7 +37475,7 @@ function DebuggerBoard({
|
|
|
37286
37475
|
}, [correctFlags.length, bugLines.length, falseFlags.length, attempts, completeEvent, emit]);
|
|
37287
37476
|
const handleReset = () => {
|
|
37288
37477
|
setSubmitted(false);
|
|
37289
|
-
if (attempts >= 2 && resolved?.hint) {
|
|
37478
|
+
if (attempts >= 2 && str(resolved?.hint)) {
|
|
37290
37479
|
setShowHint(true);
|
|
37291
37480
|
}
|
|
37292
37481
|
};
|
|
@@ -37297,24 +37486,28 @@ function DebuggerBoard({
|
|
|
37297
37486
|
setShowHint(false);
|
|
37298
37487
|
};
|
|
37299
37488
|
if (!resolved) return null;
|
|
37489
|
+
const theme = resolved.theme ?? void 0;
|
|
37490
|
+
const themeBackground = theme?.background;
|
|
37491
|
+
const headerImage = str(resolved.headerImage);
|
|
37492
|
+
const hint = str(resolved.hint);
|
|
37300
37493
|
return /* @__PURE__ */ jsx(
|
|
37301
37494
|
Box,
|
|
37302
37495
|
{
|
|
37303
37496
|
className,
|
|
37304
37497
|
style: {
|
|
37305
|
-
backgroundImage:
|
|
37498
|
+
backgroundImage: themeBackground ? `url(${themeBackground})` : void 0,
|
|
37306
37499
|
backgroundSize: "cover",
|
|
37307
37500
|
backgroundPosition: "center"
|
|
37308
37501
|
},
|
|
37309
37502
|
children: /* @__PURE__ */ jsxs(VStack, { gap: "lg", className: "p-4", children: [
|
|
37310
|
-
|
|
37503
|
+
headerImage && !headerError ? /* @__PURE__ */ jsx(Box, { className: "w-full h-32 overflow-hidden rounded-container", children: /* @__PURE__ */ jsx("img", { src: headerImage, alt: "", onError: () => setHeaderError(true), className: "w-full h-full object-cover" }) }) : headerImage && headerError ? /* @__PURE__ */ jsx(Box, { className: "w-full h-32 rounded-container bg-gradient-to-br from-muted to-accent opacity-60" }) : null,
|
|
37311
37504
|
/* @__PURE__ */ jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxs(VStack, { gap: "sm", children: [
|
|
37312
37505
|
/* @__PURE__ */ jsxs(HStack, { gap: "xs", align: "center", children: [
|
|
37313
37506
|
/* @__PURE__ */ jsx(Icon, { icon: Bug, size: "sm" }),
|
|
37314
|
-
/* @__PURE__ */ jsx(Typography, { variant: "h4", weight: "bold", children: resolved.title })
|
|
37507
|
+
/* @__PURE__ */ jsx(Typography, { variant: "h4", weight: "bold", children: str(resolved.title) })
|
|
37315
37508
|
] }),
|
|
37316
|
-
/* @__PURE__ */ jsx(Typography, { variant: "body", children: resolved.description }),
|
|
37317
|
-
/* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-muted-foreground", children: t("debugger.findBugs", { count: String(resolved.bugCount) }) })
|
|
37509
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body", children: str(resolved.description) }),
|
|
37510
|
+
/* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-muted-foreground", children: t("debugger.findBugs", { count: String(num(resolved.bugCount)) }) })
|
|
37318
37511
|
] }) }),
|
|
37319
37512
|
/* @__PURE__ */ jsx(Card, { className: "p-0 overflow-hidden", children: /* @__PURE__ */ jsx(VStack, { gap: "none", children: lines.map((line, i) => {
|
|
37320
37513
|
const isFlagged = flaggedLines.has(line.id);
|
|
@@ -37346,7 +37539,7 @@ function DebuggerBoard({
|
|
|
37346
37539
|
);
|
|
37347
37540
|
}) }) }),
|
|
37348
37541
|
submitted && /* @__PURE__ */ jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxs(VStack, { gap: "sm", children: [
|
|
37349
|
-
/* @__PURE__ */ jsx(Typography, { variant: "body", weight: "bold", children: allCorrect ? resolved.successMessage
|
|
37542
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body", weight: "bold", children: allCorrect ? str(resolved.successMessage) || t("debugger.allFound") : `${correctFlags.length}/${bugLines.length} ${t("debugger.bugsFound")}` }),
|
|
37350
37543
|
bugLines.map((line) => /* @__PURE__ */ jsxs(HStack, { gap: "xs", align: "start", children: [
|
|
37351
37544
|
/* @__PURE__ */ jsx(
|
|
37352
37545
|
Icon,
|
|
@@ -37362,7 +37555,7 @@ function DebuggerBoard({
|
|
|
37362
37555
|
] })
|
|
37363
37556
|
] }, line.id))
|
|
37364
37557
|
] }) }),
|
|
37365
|
-
showHint &&
|
|
37558
|
+
showHint && hint && /* @__PURE__ */ jsx(Card, { className: "p-4 border-l-4 border-l-warning", children: /* @__PURE__ */ jsx(Typography, { variant: "body", children: hint }) }),
|
|
37366
37559
|
/* @__PURE__ */ jsxs(HStack, { gap: "sm", justify: "center", children: [
|
|
37367
37560
|
!submitted ? /* @__PURE__ */ jsxs(Button, { variant: "primary", onClick: handleSubmit, disabled: flaggedLines.size === 0, children: [
|
|
37368
37561
|
/* @__PURE__ */ jsx(Icon, { icon: Send, size: "sm" }),
|
|
@@ -37381,6 +37574,7 @@ var init_DebuggerBoard = __esm({
|
|
|
37381
37574
|
"components/game/organisms/puzzles/debugger/DebuggerBoard.tsx"() {
|
|
37382
37575
|
init_atoms2();
|
|
37383
37576
|
init_useEventBus();
|
|
37577
|
+
init_boardEntity();
|
|
37384
37578
|
DebuggerBoard.displayName = "DebuggerBoard";
|
|
37385
37579
|
}
|
|
37386
37580
|
});
|
|
@@ -37418,7 +37612,7 @@ function getBadgeVariant(fieldName, value) {
|
|
|
37418
37612
|
return "default";
|
|
37419
37613
|
}
|
|
37420
37614
|
function formatFieldLabel(fieldName) {
|
|
37421
|
-
return fieldName.replace(/([A-Z])/g, " $1").replace(/^./, (
|
|
37615
|
+
return fieldName.replace(/([A-Z])/g, " $1").replace(/^./, (str2) => str2.toUpperCase());
|
|
37422
37616
|
}
|
|
37423
37617
|
function formatFieldValue(value, fieldName) {
|
|
37424
37618
|
if (typeof value === "number") {
|
|
@@ -37437,26 +37631,26 @@ function formatFieldValue(value, fieldName) {
|
|
|
37437
37631
|
}
|
|
37438
37632
|
function renderRichFieldValue(value, fieldName, fieldType) {
|
|
37439
37633
|
if (value === void 0 || value === null) return "\u2014";
|
|
37440
|
-
const
|
|
37634
|
+
const str2 = String(value);
|
|
37441
37635
|
switch (fieldType) {
|
|
37442
37636
|
case "image":
|
|
37443
37637
|
case "url": {
|
|
37444
|
-
if (
|
|
37638
|
+
if (str2.match(/\.(png|jpe?g|gif|svg|webp|avif)(\?|$)/i) || str2.startsWith("data:image/")) {
|
|
37445
37639
|
return /* @__PURE__ */ jsx(Box, { className: "mt-1 max-w-full", children: /* @__PURE__ */ jsx(
|
|
37446
37640
|
"img",
|
|
37447
37641
|
{
|
|
37448
|
-
src:
|
|
37642
|
+
src: str2,
|
|
37449
37643
|
alt: formatFieldLabel(fieldName),
|
|
37450
37644
|
className: "max-w-full max-h-64 rounded-md object-contain",
|
|
37451
37645
|
loading: "lazy"
|
|
37452
37646
|
}
|
|
37453
37647
|
) });
|
|
37454
37648
|
}
|
|
37455
|
-
return
|
|
37649
|
+
return str2;
|
|
37456
37650
|
}
|
|
37457
37651
|
case "markdown":
|
|
37458
37652
|
case "richtext":
|
|
37459
|
-
return /* @__PURE__ */ jsx(Suspense, { fallback: /* @__PURE__ */ jsx(Typography, { variant: "body", className: "break-words", children:
|
|
37653
|
+
return /* @__PURE__ */ jsx(Suspense, { fallback: /* @__PURE__ */ jsx(Typography, { variant: "body", className: "break-words", children: str2 }), children: /* @__PURE__ */ jsx(
|
|
37460
37654
|
Box,
|
|
37461
37655
|
{
|
|
37462
37656
|
className: "prose prose-sm max-w-none",
|
|
@@ -37474,11 +37668,11 @@ function renderRichFieldValue(value, fieldName, fieldType) {
|
|
|
37474
37668
|
"--tw-prose-th-borders": "var(--color-border)",
|
|
37475
37669
|
"--tw-prose-td-borders": "var(--color-border)"
|
|
37476
37670
|
},
|
|
37477
|
-
children: /* @__PURE__ */ jsx(ReactMarkdown2, { children:
|
|
37671
|
+
children: /* @__PURE__ */ jsx(ReactMarkdown2, { children: str2 })
|
|
37478
37672
|
}
|
|
37479
37673
|
) });
|
|
37480
37674
|
case "code":
|
|
37481
|
-
return /* @__PURE__ */ jsx(Box, { className: "mt-1 rounded-md bg-muted p-3 overflow-x-auto", children: /* @__PURE__ */ jsx("pre", { className: "text-sm font-mono whitespace-pre-wrap break-words m-0", children: /* @__PURE__ */ jsx("code", { children:
|
|
37675
|
+
return /* @__PURE__ */ jsx(Box, { className: "mt-1 rounded-md bg-muted p-3 overflow-x-auto", children: /* @__PURE__ */ jsx("pre", { className: "text-sm font-mono whitespace-pre-wrap break-words m-0", children: /* @__PURE__ */ jsx("code", { children: str2 }) }) });
|
|
37482
37676
|
case "html":
|
|
37483
37677
|
return /* @__PURE__ */ jsx(
|
|
37484
37678
|
Box,
|
|
@@ -37498,12 +37692,12 @@ function renderRichFieldValue(value, fieldName, fieldType) {
|
|
|
37498
37692
|
"--tw-prose-th-borders": "var(--color-border)",
|
|
37499
37693
|
"--tw-prose-td-borders": "var(--color-border)"
|
|
37500
37694
|
},
|
|
37501
|
-
children: /* @__PURE__ */ jsx(Typography, { variant: "body", children:
|
|
37695
|
+
children: /* @__PURE__ */ jsx(Typography, { variant: "body", children: str2 })
|
|
37502
37696
|
}
|
|
37503
37697
|
);
|
|
37504
37698
|
case "date":
|
|
37505
37699
|
case "datetime": {
|
|
37506
|
-
const d = new Date(
|
|
37700
|
+
const d = new Date(str2);
|
|
37507
37701
|
if (!isNaN(d.getTime())) {
|
|
37508
37702
|
return d.toLocaleDateString(void 0, {
|
|
37509
37703
|
year: "numeric",
|
|
@@ -37512,7 +37706,7 @@ function renderRichFieldValue(value, fieldName, fieldType) {
|
|
|
37512
37706
|
...fieldType === "datetime" ? { hour: "2-digit", minute: "2-digit" } : {}
|
|
37513
37707
|
});
|
|
37514
37708
|
}
|
|
37515
|
-
return
|
|
37709
|
+
return str2;
|
|
37516
37710
|
}
|
|
37517
37711
|
default:
|
|
37518
37712
|
return formatFieldValue(value, fieldName);
|
|
@@ -37912,7 +38106,7 @@ var init_DialogueBubble = __esm({
|
|
|
37912
38106
|
}
|
|
37913
38107
|
});
|
|
37914
38108
|
function extractTitle(children) {
|
|
37915
|
-
if (!
|
|
38109
|
+
if (!React80__default.isValidElement(children)) return void 0;
|
|
37916
38110
|
const props = children.props;
|
|
37917
38111
|
if (typeof props.title === "string") {
|
|
37918
38112
|
return props.title;
|
|
@@ -38024,7 +38218,7 @@ function LinearView({
|
|
|
38024
38218
|
/* @__PURE__ */ jsx(HStack, { className: "flex-wrap items-center", gap: "xs", children: trait.states.map((state, i) => {
|
|
38025
38219
|
const isDone = i < currentIdx;
|
|
38026
38220
|
const isCurrent = i === currentIdx;
|
|
38027
|
-
return /* @__PURE__ */ jsxs(
|
|
38221
|
+
return /* @__PURE__ */ jsxs(React80__default.Fragment, { children: [
|
|
38028
38222
|
i > 0 && /* @__PURE__ */ jsx(
|
|
38029
38223
|
Typography,
|
|
38030
38224
|
{
|
|
@@ -38285,6 +38479,40 @@ var init_RuleEditor = __esm({
|
|
|
38285
38479
|
RuleEditor.displayName = "RuleEditor";
|
|
38286
38480
|
}
|
|
38287
38481
|
});
|
|
38482
|
+
|
|
38483
|
+
// components/game/organisms/puzzles/event-handler/puzzleObject.ts
|
|
38484
|
+
function objId(o) {
|
|
38485
|
+
return o.id == null ? "" : String(o.id);
|
|
38486
|
+
}
|
|
38487
|
+
function objName(o) {
|
|
38488
|
+
return o.name == null ? "" : String(o.name);
|
|
38489
|
+
}
|
|
38490
|
+
function objIcon(o) {
|
|
38491
|
+
return o.icon == null ? "" : String(o.icon);
|
|
38492
|
+
}
|
|
38493
|
+
function objStates(o) {
|
|
38494
|
+
return Array.isArray(o.states) ? o.states : [];
|
|
38495
|
+
}
|
|
38496
|
+
function objCurrentState(o) {
|
|
38497
|
+
return o.currentState == null ? "" : String(o.currentState);
|
|
38498
|
+
}
|
|
38499
|
+
function objAvailableEvents(o) {
|
|
38500
|
+
return Array.isArray(o.availableEvents) ? o.availableEvents : [];
|
|
38501
|
+
}
|
|
38502
|
+
function objAvailableActions(o) {
|
|
38503
|
+
return Array.isArray(o.availableActions) ? o.availableActions : [];
|
|
38504
|
+
}
|
|
38505
|
+
function objRules(o) {
|
|
38506
|
+
return Array.isArray(o.rules) ? o.rules : [];
|
|
38507
|
+
}
|
|
38508
|
+
function objMaxRules(o) {
|
|
38509
|
+
const n = Number(o.maxRules);
|
|
38510
|
+
return Number.isFinite(n) && n > 0 ? n : 3;
|
|
38511
|
+
}
|
|
38512
|
+
var init_puzzleObject = __esm({
|
|
38513
|
+
"components/game/organisms/puzzles/event-handler/puzzleObject.ts"() {
|
|
38514
|
+
}
|
|
38515
|
+
});
|
|
38288
38516
|
function ObjectRulePanel({
|
|
38289
38517
|
object,
|
|
38290
38518
|
onRulesChange,
|
|
@@ -38292,55 +38520,63 @@ function ObjectRulePanel({
|
|
|
38292
38520
|
className
|
|
38293
38521
|
}) {
|
|
38294
38522
|
const { t } = useTranslate();
|
|
38295
|
-
const
|
|
38296
|
-
const
|
|
38523
|
+
const id = objId(object);
|
|
38524
|
+
const name = objName(object);
|
|
38525
|
+
const icon = objIcon(object);
|
|
38526
|
+
const states = objStates(object);
|
|
38527
|
+
const currentState = objCurrentState(object);
|
|
38528
|
+
const availableEvents = objAvailableEvents(object);
|
|
38529
|
+
const availableActions = objAvailableActions(object);
|
|
38530
|
+
const rules = objRules(object);
|
|
38531
|
+
const maxRules = objMaxRules(object);
|
|
38532
|
+
const canAdd = rules.length < maxRules;
|
|
38297
38533
|
const handleRuleChange = useCallback((index, updatedRule) => {
|
|
38298
|
-
const newRules = [...
|
|
38534
|
+
const newRules = [...rules];
|
|
38299
38535
|
newRules[index] = updatedRule;
|
|
38300
|
-
onRulesChange(
|
|
38301
|
-
}, [
|
|
38536
|
+
onRulesChange(id, newRules);
|
|
38537
|
+
}, [id, rules, onRulesChange]);
|
|
38302
38538
|
const handleRuleRemove = useCallback((index) => {
|
|
38303
|
-
const newRules =
|
|
38304
|
-
onRulesChange(
|
|
38305
|
-
}, [
|
|
38539
|
+
const newRules = rules.filter((_, i) => i !== index);
|
|
38540
|
+
onRulesChange(id, newRules);
|
|
38541
|
+
}, [id, rules, onRulesChange]);
|
|
38306
38542
|
const handleAddRule = useCallback(() => {
|
|
38307
38543
|
if (!canAdd || disabled) return;
|
|
38308
|
-
const firstEvent =
|
|
38309
|
-
const firstAction =
|
|
38544
|
+
const firstEvent = availableEvents[0]?.value || "";
|
|
38545
|
+
const firstAction = availableActions[0]?.value || "";
|
|
38310
38546
|
const newRule = {
|
|
38311
38547
|
id: `rule-${nextRuleId++}`,
|
|
38312
38548
|
whenEvent: firstEvent,
|
|
38313
38549
|
thenAction: firstAction
|
|
38314
38550
|
};
|
|
38315
|
-
onRulesChange(
|
|
38316
|
-
}, [canAdd, disabled,
|
|
38551
|
+
onRulesChange(id, [...rules, newRule]);
|
|
38552
|
+
}, [canAdd, disabled, id, rules, availableEvents, availableActions, onRulesChange]);
|
|
38317
38553
|
const machine = {
|
|
38318
|
-
name
|
|
38319
|
-
states
|
|
38320
|
-
currentState
|
|
38321
|
-
transitions:
|
|
38322
|
-
from:
|
|
38323
|
-
to:
|
|
38554
|
+
name,
|
|
38555
|
+
states,
|
|
38556
|
+
currentState,
|
|
38557
|
+
transitions: rules.map((r) => ({
|
|
38558
|
+
from: currentState,
|
|
38559
|
+
to: states.find((s) => s !== currentState) || currentState,
|
|
38324
38560
|
event: r.whenEvent
|
|
38325
38561
|
}))
|
|
38326
38562
|
};
|
|
38327
38563
|
return /* @__PURE__ */ jsxs(VStack, { className: cn("p-4 rounded-lg bg-card border border-border", className), gap: "sm", children: [
|
|
38328
38564
|
/* @__PURE__ */ jsxs(HStack, { className: "items-center", gap: "sm", children: [
|
|
38329
|
-
/* @__PURE__ */ jsx(Typography, { variant: "h5", children:
|
|
38565
|
+
/* @__PURE__ */ jsx(Typography, { variant: "h5", children: icon }),
|
|
38330
38566
|
/* @__PURE__ */ jsxs(VStack, { gap: "none", children: [
|
|
38331
|
-
/* @__PURE__ */ jsx(Typography, { variant: "body1", className: "text-foreground font-bold", children:
|
|
38332
|
-
/* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-muted-foreground", children: t("eventHandler.state") + ": " +
|
|
38567
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body1", className: "text-foreground font-bold", children: name }),
|
|
38568
|
+
/* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-muted-foreground", children: t("eventHandler.state") + ": " + currentState })
|
|
38333
38569
|
] })
|
|
38334
38570
|
] }),
|
|
38335
38571
|
/* @__PURE__ */ jsx(TraitStateViewer, { trait: machine, variant: "compact", size: "sm" }),
|
|
38336
38572
|
/* @__PURE__ */ jsxs(VStack, { gap: "xs", children: [
|
|
38337
|
-
/* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-muted-foreground font-medium", children: t("eventHandler.rules", { count:
|
|
38338
|
-
|
|
38573
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-muted-foreground font-medium", children: t("eventHandler.rules", { count: rules.length, max: maxRules }) + ":" }),
|
|
38574
|
+
rules.map((rule, i) => /* @__PURE__ */ jsx(
|
|
38339
38575
|
RuleEditor,
|
|
38340
38576
|
{
|
|
38341
38577
|
rule,
|
|
38342
|
-
availableEvents
|
|
38343
|
-
availableActions
|
|
38578
|
+
availableEvents,
|
|
38579
|
+
availableActions,
|
|
38344
38580
|
onChange: (r) => handleRuleChange(i, r),
|
|
38345
38581
|
onRemove: () => handleRuleRemove(i),
|
|
38346
38582
|
disabled
|
|
@@ -38358,6 +38594,7 @@ var init_ObjectRulePanel = __esm({
|
|
|
38358
38594
|
init_cn();
|
|
38359
38595
|
init_TraitStateViewer();
|
|
38360
38596
|
init_RuleEditor();
|
|
38597
|
+
init_puzzleObject();
|
|
38361
38598
|
nextRuleId = 1;
|
|
38362
38599
|
ObjectRulePanel.displayName = "ObjectRulePanel";
|
|
38363
38600
|
}
|
|
@@ -38424,11 +38661,11 @@ function EventHandlerBoard({
|
|
|
38424
38661
|
}) {
|
|
38425
38662
|
const { emit } = useEventBus();
|
|
38426
38663
|
const { t } = useTranslate();
|
|
38427
|
-
const resolved =
|
|
38428
|
-
const entityObjects = resolved?.objects
|
|
38429
|
-
const [objects, setObjects] = useState(entityObjects);
|
|
38664
|
+
const resolved = boardEntity(entity);
|
|
38665
|
+
const entityObjects = rows(resolved?.objects);
|
|
38666
|
+
const [objects, setObjects] = useState(() => [...entityObjects]);
|
|
38430
38667
|
const [selectedObjectId, setSelectedObjectId] = useState(
|
|
38431
|
-
entityObjects[0]
|
|
38668
|
+
entityObjects[0] ? objId(entityObjects[0]) : null
|
|
38432
38669
|
);
|
|
38433
38670
|
const [headerError, setHeaderError] = useState(false);
|
|
38434
38671
|
const [playState, setPlayState] = useState("editing");
|
|
@@ -38439,10 +38676,10 @@ function EventHandlerBoard({
|
|
|
38439
38676
|
useEffect(() => () => {
|
|
38440
38677
|
if (timerRef.current) clearTimeout(timerRef.current);
|
|
38441
38678
|
}, []);
|
|
38442
|
-
const selectedObject = objects.find((o) => o
|
|
38679
|
+
const selectedObject = objects.find((o) => objId(o) === selectedObjectId) || null;
|
|
38443
38680
|
const handleRulesChange = useCallback((objectId, rules) => {
|
|
38444
38681
|
setObjects((prev) => prev.map(
|
|
38445
|
-
(o) => o
|
|
38682
|
+
(o) => objId(o) === objectId ? { ...o, rules } : o
|
|
38446
38683
|
));
|
|
38447
38684
|
}, []);
|
|
38448
38685
|
const addLogEntry = useCallback((icon, message, status = "done") => {
|
|
@@ -38456,11 +38693,12 @@ function EventHandlerBoard({
|
|
|
38456
38693
|
setEventLog([]);
|
|
38457
38694
|
const allRules = [];
|
|
38458
38695
|
objects.forEach((obj) => {
|
|
38459
|
-
obj.
|
|
38696
|
+
objRules(obj).forEach((rule) => {
|
|
38460
38697
|
allRules.push({ object: obj, rule });
|
|
38461
38698
|
});
|
|
38462
38699
|
});
|
|
38463
|
-
const triggers = resolved?.triggerEvents
|
|
38700
|
+
const triggers = Array.isArray(resolved?.triggerEvents) ? resolved.triggerEvents : [];
|
|
38701
|
+
const goalEvent = str(resolved?.goalEvent);
|
|
38464
38702
|
const eventQueue = [...triggers];
|
|
38465
38703
|
const firedEvents = /* @__PURE__ */ new Set();
|
|
38466
38704
|
let stepIdx = 0;
|
|
@@ -38489,14 +38727,14 @@ function EventHandlerBoard({
|
|
|
38489
38727
|
addLogEntry("\u26A1", t("eventHandler.noListeners", { event: currentEvent }), "done");
|
|
38490
38728
|
} else {
|
|
38491
38729
|
matching.forEach(({ object, rule }) => {
|
|
38492
|
-
addLogEntry(object
|
|
38730
|
+
addLogEntry(objIcon(object), t("eventHandler.heardEvent", { object: objName(object), event: currentEvent, action: rule.thenAction }), "done");
|
|
38493
38731
|
eventQueue.push(rule.thenAction);
|
|
38494
|
-
if (rule.thenAction ===
|
|
38732
|
+
if (rule.thenAction === goalEvent) {
|
|
38495
38733
|
goalReached = true;
|
|
38496
38734
|
}
|
|
38497
38735
|
});
|
|
38498
38736
|
}
|
|
38499
|
-
if (currentEvent ===
|
|
38737
|
+
if (currentEvent === goalEvent) {
|
|
38500
38738
|
goalReached = true;
|
|
38501
38739
|
}
|
|
38502
38740
|
stepIdx++;
|
|
@@ -38514,65 +38752,75 @@ function EventHandlerBoard({
|
|
|
38514
38752
|
}, []);
|
|
38515
38753
|
const handleReset = useCallback(() => {
|
|
38516
38754
|
if (timerRef.current) clearTimeout(timerRef.current);
|
|
38517
|
-
|
|
38755
|
+
const resetObjects = rows(resolved?.objects);
|
|
38756
|
+
setObjects([...resetObjects]);
|
|
38518
38757
|
setPlayState("editing");
|
|
38519
38758
|
setEventLog([]);
|
|
38520
|
-
setSelectedObjectId(
|
|
38759
|
+
setSelectedObjectId(resetObjects[0] ? objId(resetObjects[0]) : null);
|
|
38521
38760
|
setAttempts(0);
|
|
38522
38761
|
}, [resolved?.objects]);
|
|
38523
38762
|
if (!resolved) return null;
|
|
38524
38763
|
const objectViewers = objects.map((obj) => {
|
|
38764
|
+
const states = objStates(obj);
|
|
38765
|
+
const currentState = objCurrentState(obj);
|
|
38525
38766
|
const machine = {
|
|
38526
|
-
name: obj
|
|
38527
|
-
states
|
|
38528
|
-
currentState
|
|
38529
|
-
transitions: obj.
|
|
38530
|
-
from:
|
|
38531
|
-
to:
|
|
38767
|
+
name: objName(obj),
|
|
38768
|
+
states,
|
|
38769
|
+
currentState,
|
|
38770
|
+
transitions: objRules(obj).map((r) => ({
|
|
38771
|
+
from: currentState,
|
|
38772
|
+
to: states.find((s) => s !== currentState) || currentState,
|
|
38532
38773
|
event: r.whenEvent
|
|
38533
38774
|
}))
|
|
38534
38775
|
};
|
|
38535
38776
|
return { obj, machine };
|
|
38536
38777
|
});
|
|
38537
|
-
const
|
|
38778
|
+
const hint = str(resolved.hint);
|
|
38779
|
+
const showHint = attempts >= 3 && hint;
|
|
38780
|
+
const theme = resolved.theme ?? void 0;
|
|
38781
|
+
const themeBackground = theme?.background;
|
|
38782
|
+
const headerImage = str(resolved.headerImage);
|
|
38538
38783
|
const encourageKey = ENCOURAGEMENT_KEYS[Math.min(attempts - 1, ENCOURAGEMENT_KEYS.length - 1)] ?? ENCOURAGEMENT_KEYS[0];
|
|
38539
38784
|
return /* @__PURE__ */ jsxs(
|
|
38540
38785
|
VStack,
|
|
38541
38786
|
{
|
|
38542
38787
|
className: cn("p-4 gap-6", className),
|
|
38543
38788
|
style: {
|
|
38544
|
-
backgroundImage:
|
|
38789
|
+
backgroundImage: themeBackground ? `url(${themeBackground})` : void 0,
|
|
38545
38790
|
backgroundSize: "cover",
|
|
38546
38791
|
backgroundPosition: "center"
|
|
38547
38792
|
},
|
|
38548
38793
|
children: [
|
|
38549
|
-
|
|
38794
|
+
headerImage && !headerError ? /* @__PURE__ */ jsx(Box, { className: "w-full h-32 overflow-hidden rounded-container", children: /* @__PURE__ */ jsx("img", { src: headerImage, alt: "", onError: () => setHeaderError(true), className: "w-full h-full object-cover" }) }) : headerImage && headerError ? /* @__PURE__ */ jsx(Box, { className: "w-full h-32 rounded-container bg-gradient-to-br from-muted to-accent opacity-60" }) : null,
|
|
38550
38795
|
/* @__PURE__ */ jsxs(VStack, { gap: "xs", children: [
|
|
38551
|
-
/* @__PURE__ */ jsx(Typography, { variant: "h4", className: "text-foreground", children: resolved.title }),
|
|
38552
|
-
/* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-muted-foreground", children: resolved.description }),
|
|
38796
|
+
/* @__PURE__ */ jsx(Typography, { variant: "h4", className: "text-foreground", children: str(resolved.title) }),
|
|
38797
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-muted-foreground", children: str(resolved.description) }),
|
|
38553
38798
|
/* @__PURE__ */ jsxs(HStack, { className: "items-center p-2 rounded bg-primary/10 border border-primary/30", gap: "xs", children: [
|
|
38554
38799
|
/* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-primary font-bold", children: t("game.goal") + ":" }),
|
|
38555
|
-
/* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-foreground", children: resolved.goalCondition })
|
|
38800
|
+
/* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-foreground", children: str(resolved.goalCondition) })
|
|
38556
38801
|
] })
|
|
38557
38802
|
] }),
|
|
38558
38803
|
/* @__PURE__ */ jsxs(VStack, { gap: "sm", children: [
|
|
38559
38804
|
/* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-muted-foreground font-medium", children: t("eventHandler.clickObject") + ":" }),
|
|
38560
|
-
/* @__PURE__ */ jsx(HStack, { className: "flex-wrap", gap: "sm", children: objectViewers.map(({ obj, machine }) =>
|
|
38561
|
-
|
|
38562
|
-
|
|
38563
|
-
|
|
38564
|
-
|
|
38565
|
-
|
|
38566
|
-
|
|
38567
|
-
|
|
38568
|
-
|
|
38569
|
-
|
|
38570
|
-
/* @__PURE__ */
|
|
38571
|
-
|
|
38572
|
-
|
|
38573
|
-
|
|
38574
|
-
|
|
38575
|
-
|
|
38805
|
+
/* @__PURE__ */ jsx(HStack, { className: "flex-wrap", gap: "sm", children: objectViewers.map(({ obj, machine }) => {
|
|
38806
|
+
const oid = objId(obj);
|
|
38807
|
+
return /* @__PURE__ */ jsx(
|
|
38808
|
+
Box,
|
|
38809
|
+
{
|
|
38810
|
+
className: cn(
|
|
38811
|
+
"p-3 rounded-container border-2 cursor-pointer transition-all hover:scale-105",
|
|
38812
|
+
selectedObjectId === oid ? "border-primary bg-primary/10" : "border-border bg-card hover:border-muted-foreground"
|
|
38813
|
+
),
|
|
38814
|
+
onClick: () => setSelectedObjectId(oid),
|
|
38815
|
+
children: /* @__PURE__ */ jsxs(VStack, { gap: "xs", className: "items-center min-w-[120px]", children: [
|
|
38816
|
+
/* @__PURE__ */ jsx(Typography, { variant: "h5", children: objIcon(obj) }),
|
|
38817
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-foreground font-medium", children: objName(obj) }),
|
|
38818
|
+
/* @__PURE__ */ jsx(TraitStateViewer, { trait: machine, variant: "compact", size: "sm" })
|
|
38819
|
+
] })
|
|
38820
|
+
},
|
|
38821
|
+
oid
|
|
38822
|
+
);
|
|
38823
|
+
}) })
|
|
38576
38824
|
] }),
|
|
38577
38825
|
selectedObject && /* @__PURE__ */ jsx(
|
|
38578
38826
|
ObjectRulePanel,
|
|
@@ -38583,12 +38831,12 @@ function EventHandlerBoard({
|
|
|
38583
38831
|
}
|
|
38584
38832
|
),
|
|
38585
38833
|
eventLog.length > 0 && /* @__PURE__ */ jsx(EventLog, { entries: eventLog }),
|
|
38586
|
-
playState === "success" && /* @__PURE__ */ jsx(Box, { className: "p-4 rounded-container bg-success/20 border border-success text-center", children: /* @__PURE__ */ jsx(Typography, { variant: "h5", className: "text-success", children: resolved.successMessage || t("eventHandler.chainComplete") }) }),
|
|
38834
|
+
playState === "success" && /* @__PURE__ */ jsx(Box, { className: "p-4 rounded-container bg-success/20 border border-success text-center", children: /* @__PURE__ */ jsx(Typography, { variant: "h5", className: "text-success", children: str(resolved.successMessage) || t("eventHandler.chainComplete") }) }),
|
|
38587
38835
|
playState === "fail" && /* @__PURE__ */ jsxs(VStack, { gap: "sm", children: [
|
|
38588
38836
|
/* @__PURE__ */ jsx(Box, { className: "p-4 rounded-container bg-warning/10 border border-warning/30 text-center", children: /* @__PURE__ */ jsx(Typography, { variant: "body1", className: "text-foreground font-medium", children: t(encourageKey) }) }),
|
|
38589
38837
|
showHint && /* @__PURE__ */ jsx(Box, { className: "p-3 rounded-container bg-accent/10 border border-accent/30", children: /* @__PURE__ */ jsxs(HStack, { className: "items-start", gap: "xs", children: [
|
|
38590
38838
|
/* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-accent font-bold shrink-0", children: "\u{1F4A1} " + t("game.hint") + ":" }),
|
|
38591
|
-
/* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-foreground", children:
|
|
38839
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-foreground", children: hint })
|
|
38592
38840
|
] }) })
|
|
38593
38841
|
] }),
|
|
38594
38842
|
/* @__PURE__ */ jsxs(HStack, { gap: "sm", children: [
|
|
@@ -38616,6 +38864,8 @@ var init_EventHandlerBoard = __esm({
|
|
|
38616
38864
|
init_TraitStateViewer();
|
|
38617
38865
|
init_ObjectRulePanel();
|
|
38618
38866
|
init_EventLog();
|
|
38867
|
+
init_puzzleObject();
|
|
38868
|
+
init_boardEntity();
|
|
38619
38869
|
ENCOURAGEMENT_KEYS = [
|
|
38620
38870
|
"puzzle.tryAgain1",
|
|
38621
38871
|
"puzzle.tryAgain2",
|
|
@@ -38704,7 +38954,10 @@ var init_FeatureGridOrganism = __esm({
|
|
|
38704
38954
|
);
|
|
38705
38955
|
useCallback(
|
|
38706
38956
|
(feature) => {
|
|
38707
|
-
eventBus.emit("UI:FEATURE_CLICK", {
|
|
38957
|
+
eventBus.emit("UI:FEATURE_CLICK", {
|
|
38958
|
+
id: String(feature.id ?? ""),
|
|
38959
|
+
href: String(feature.href ?? "")
|
|
38960
|
+
});
|
|
38708
38961
|
},
|
|
38709
38962
|
[eventBus]
|
|
38710
38963
|
);
|
|
@@ -38714,14 +38967,17 @@ var init_FeatureGridOrganism = __esm({
|
|
|
38714
38967
|
if (error) {
|
|
38715
38968
|
return /* @__PURE__ */ jsx(ErrorState, { message: error.message, className });
|
|
38716
38969
|
}
|
|
38717
|
-
const featureCards = items.map((feature) =>
|
|
38718
|
-
|
|
38719
|
-
|
|
38720
|
-
|
|
38721
|
-
|
|
38722
|
-
|
|
38723
|
-
|
|
38724
|
-
|
|
38970
|
+
const featureCards = items.map((feature) => {
|
|
38971
|
+
const href = feature.href != null ? String(feature.href) : void 0;
|
|
38972
|
+
return {
|
|
38973
|
+
icon: feature.icon != null ? String(feature.icon) : void 0,
|
|
38974
|
+
title: String(feature.title ?? ""),
|
|
38975
|
+
description: String(feature.description ?? ""),
|
|
38976
|
+
href,
|
|
38977
|
+
linkLabel: feature.linkLabel != null ? String(feature.linkLabel) : void 0,
|
|
38978
|
+
variant: href ? "interactive" : "bordered"
|
|
38979
|
+
};
|
|
38980
|
+
});
|
|
38725
38981
|
return /* @__PURE__ */ jsxs(VStack, { gap: "lg", className: cn("w-full", className), children: [
|
|
38726
38982
|
(heading || subtitle) && /* @__PURE__ */ jsxs(VStack, { gap: "sm", align: "center", className: "w-full", children: [
|
|
38727
38983
|
heading && /* @__PURE__ */ jsx(Typography, { variant: "h2", align: "center", children: heading }),
|
|
@@ -38920,12 +39176,12 @@ var init_Form = __esm({
|
|
|
38920
39176
|
const isSchemaEntity = isOrbitalEntitySchema(entity);
|
|
38921
39177
|
const resolvedEntity = isSchemaEntity ? entity : void 0;
|
|
38922
39178
|
const entityName = typeof entity === "string" ? entity : resolvedEntity?.name;
|
|
38923
|
-
const normalizedInitialData =
|
|
39179
|
+
const normalizedInitialData = React80__default.useMemo(() => {
|
|
38924
39180
|
const entityRowAsInitial = isPlainEntityRow(entity) ? entity : void 0;
|
|
38925
39181
|
const callerInitial = initialData !== null && typeof initialData === "object" && !Array.isArray(initialData) ? initialData : {};
|
|
38926
39182
|
return entityRowAsInitial !== void 0 ? { ...entityRowAsInitial, ...callerInitial } : callerInitial;
|
|
38927
39183
|
}, [entity, initialData]);
|
|
38928
|
-
const entityDerivedFields =
|
|
39184
|
+
const entityDerivedFields = React80__default.useMemo(() => {
|
|
38929
39185
|
if (fields && fields.length > 0) return void 0;
|
|
38930
39186
|
if (!resolvedEntity) return void 0;
|
|
38931
39187
|
return resolvedEntity.fields.map(
|
|
@@ -38945,16 +39201,16 @@ var init_Form = __esm({
|
|
|
38945
39201
|
const conditionalFields = typeof conditionalFieldsRaw === "boolean" ? {} : conditionalFieldsRaw;
|
|
38946
39202
|
const hiddenCalculations = typeof hiddenCalculationsRaw === "boolean" ? [] : hiddenCalculationsRaw;
|
|
38947
39203
|
const violationTriggers = typeof violationTriggersRaw === "boolean" ? [] : violationTriggersRaw;
|
|
38948
|
-
const [formData, setFormData] =
|
|
39204
|
+
const [formData, setFormData] = React80__default.useState(
|
|
38949
39205
|
normalizedInitialData
|
|
38950
39206
|
);
|
|
38951
|
-
const [collapsedSections, setCollapsedSections] =
|
|
39207
|
+
const [collapsedSections, setCollapsedSections] = React80__default.useState(
|
|
38952
39208
|
/* @__PURE__ */ new Set()
|
|
38953
39209
|
);
|
|
38954
|
-
const [submitError, setSubmitError] =
|
|
38955
|
-
const formRef =
|
|
39210
|
+
const [submitError, setSubmitError] = React80__default.useState(null);
|
|
39211
|
+
const formRef = React80__default.useRef(null);
|
|
38956
39212
|
const formMode = props.mode;
|
|
38957
|
-
const mountedRef =
|
|
39213
|
+
const mountedRef = React80__default.useRef(false);
|
|
38958
39214
|
if (!mountedRef.current) {
|
|
38959
39215
|
mountedRef.current = true;
|
|
38960
39216
|
debug("forms", "mount", {
|
|
@@ -38967,7 +39223,7 @@ var init_Form = __esm({
|
|
|
38967
39223
|
});
|
|
38968
39224
|
}
|
|
38969
39225
|
const shouldShowCancel = showCancel ?? (fields && fields.length > 0);
|
|
38970
|
-
const evalContext =
|
|
39226
|
+
const evalContext = React80__default.useMemo(
|
|
38971
39227
|
() => ({
|
|
38972
39228
|
formValues: formData,
|
|
38973
39229
|
globalVariables: externalContext?.globalVariables ?? {},
|
|
@@ -38976,7 +39232,7 @@ var init_Form = __esm({
|
|
|
38976
39232
|
}),
|
|
38977
39233
|
[formData, externalContext]
|
|
38978
39234
|
);
|
|
38979
|
-
|
|
39235
|
+
React80__default.useEffect(() => {
|
|
38980
39236
|
debug("forms", "initialData-sync", {
|
|
38981
39237
|
mode: formMode,
|
|
38982
39238
|
normalizedInitialData,
|
|
@@ -38987,7 +39243,7 @@ var init_Form = __esm({
|
|
|
38987
39243
|
setFormData(normalizedInitialData);
|
|
38988
39244
|
}
|
|
38989
39245
|
}, [normalizedInitialData]);
|
|
38990
|
-
const processCalculations =
|
|
39246
|
+
const processCalculations = React80__default.useCallback(
|
|
38991
39247
|
(changedFieldId, newFormData) => {
|
|
38992
39248
|
if (!hiddenCalculations.length) return;
|
|
38993
39249
|
const context = {
|
|
@@ -39012,7 +39268,7 @@ var init_Form = __esm({
|
|
|
39012
39268
|
},
|
|
39013
39269
|
[hiddenCalculations, externalContext, eventBus]
|
|
39014
39270
|
);
|
|
39015
|
-
const checkViolations =
|
|
39271
|
+
const checkViolations = React80__default.useCallback(
|
|
39016
39272
|
(changedFieldId, newFormData) => {
|
|
39017
39273
|
if (!violationTriggers.length) return;
|
|
39018
39274
|
const context = {
|
|
@@ -39050,7 +39306,7 @@ var init_Form = __esm({
|
|
|
39050
39306
|
processCalculations(name, newFormData);
|
|
39051
39307
|
checkViolations(name, newFormData);
|
|
39052
39308
|
};
|
|
39053
|
-
const isFieldVisible =
|
|
39309
|
+
const isFieldVisible = React80__default.useCallback(
|
|
39054
39310
|
(fieldName) => {
|
|
39055
39311
|
const condition = conditionalFields[fieldName];
|
|
39056
39312
|
if (!condition) return true;
|
|
@@ -39058,7 +39314,7 @@ var init_Form = __esm({
|
|
|
39058
39314
|
},
|
|
39059
39315
|
[conditionalFields, evalContext]
|
|
39060
39316
|
);
|
|
39061
|
-
const isSectionVisible =
|
|
39317
|
+
const isSectionVisible = React80__default.useCallback(
|
|
39062
39318
|
(section) => {
|
|
39063
39319
|
if (!section.condition) return true;
|
|
39064
39320
|
return Boolean(evaluateFormExpression(section.condition, evalContext));
|
|
@@ -39134,7 +39390,7 @@ var init_Form = __esm({
|
|
|
39134
39390
|
eventBus.emit(`UI:${onCancel}`);
|
|
39135
39391
|
}
|
|
39136
39392
|
};
|
|
39137
|
-
const renderField =
|
|
39393
|
+
const renderField = React80__default.useCallback(
|
|
39138
39394
|
(field) => {
|
|
39139
39395
|
const fieldName = field.name || field.field;
|
|
39140
39396
|
if (!fieldName) return null;
|
|
@@ -39155,7 +39411,7 @@ var init_Form = __esm({
|
|
|
39155
39411
|
[formData, isFieldVisible, relationsData, relationsLoading, isLoading]
|
|
39156
39412
|
);
|
|
39157
39413
|
const effectiveFields = entityDerivedFields ?? fields;
|
|
39158
|
-
const normalizedFields =
|
|
39414
|
+
const normalizedFields = React80__default.useMemo(() => {
|
|
39159
39415
|
if (!effectiveFields || effectiveFields.length === 0) return [];
|
|
39160
39416
|
return effectiveFields.map((field) => {
|
|
39161
39417
|
if (typeof field === "string") {
|
|
@@ -39178,7 +39434,7 @@ var init_Form = __esm({
|
|
|
39178
39434
|
return field;
|
|
39179
39435
|
});
|
|
39180
39436
|
}, [effectiveFields, resolvedEntity]);
|
|
39181
|
-
const schemaFields =
|
|
39437
|
+
const schemaFields = React80__default.useMemo(() => {
|
|
39182
39438
|
if (normalizedFields.length === 0) return null;
|
|
39183
39439
|
if (isDebugEnabled()) {
|
|
39184
39440
|
debugGroup(`Form: ${entityName || "unknown"}`);
|
|
@@ -39188,7 +39444,7 @@ var init_Form = __esm({
|
|
|
39188
39444
|
}
|
|
39189
39445
|
return normalizedFields.map(renderField).filter(Boolean);
|
|
39190
39446
|
}, [normalizedFields, renderField, entityName, conditionalFields]);
|
|
39191
|
-
const sectionElements =
|
|
39447
|
+
const sectionElements = React80__default.useMemo(() => {
|
|
39192
39448
|
if (!sections || sections.length === 0) return null;
|
|
39193
39449
|
return sections.map((section) => {
|
|
39194
39450
|
if (!isSectionVisible(section)) {
|
|
@@ -40046,22 +40302,24 @@ var init_HeroOrganism = __esm({
|
|
|
40046
40302
|
() => Array.isArray(entity) ? entity[0] : entity && typeof entity === "object" ? entity : void 0,
|
|
40047
40303
|
[entity]
|
|
40048
40304
|
);
|
|
40305
|
+
const primaryAction = resolved?.primaryAction;
|
|
40306
|
+
const secondaryAction = resolved?.secondaryAction;
|
|
40049
40307
|
const handlePrimaryClick = useCallback(() => {
|
|
40050
|
-
if (
|
|
40308
|
+
if (primaryAction) {
|
|
40051
40309
|
eventBus.emit("UI:CTA_PRIMARY", {
|
|
40052
|
-
label:
|
|
40053
|
-
href:
|
|
40310
|
+
label: String(primaryAction.label ?? ""),
|
|
40311
|
+
href: String(primaryAction.href ?? "")
|
|
40054
40312
|
});
|
|
40055
40313
|
}
|
|
40056
|
-
}, [eventBus,
|
|
40314
|
+
}, [eventBus, primaryAction]);
|
|
40057
40315
|
const handleSecondaryClick = useCallback(() => {
|
|
40058
|
-
if (
|
|
40316
|
+
if (secondaryAction) {
|
|
40059
40317
|
eventBus.emit("UI:CTA_SECONDARY", {
|
|
40060
|
-
label:
|
|
40061
|
-
href:
|
|
40318
|
+
label: String(secondaryAction.label ?? ""),
|
|
40319
|
+
href: String(secondaryAction.href ?? "")
|
|
40062
40320
|
});
|
|
40063
40321
|
}
|
|
40064
|
-
}, [eventBus,
|
|
40322
|
+
}, [eventBus, secondaryAction]);
|
|
40065
40323
|
if (isLoading) {
|
|
40066
40324
|
return /* @__PURE__ */ jsx(LoadingState, { message: t("common.loading"), className });
|
|
40067
40325
|
}
|
|
@@ -40071,17 +40329,19 @@ var init_HeroOrganism = __esm({
|
|
|
40071
40329
|
if (!resolved) {
|
|
40072
40330
|
return null;
|
|
40073
40331
|
}
|
|
40332
|
+
const imageRaw = resolved.image;
|
|
40333
|
+
const image = imageRaw ? { src: String(imageRaw.src ?? ""), alt: String(imageRaw.alt ?? "") } : void 0;
|
|
40074
40334
|
return /* @__PURE__ */ jsxs(
|
|
40075
40335
|
HeroSection,
|
|
40076
40336
|
{
|
|
40077
|
-
tag: resolved.tag,
|
|
40078
|
-
title: resolved.title,
|
|
40079
|
-
titleAccent: resolved.titleAccent,
|
|
40080
|
-
subtitle: resolved.subtitle,
|
|
40081
|
-
primaryAction:
|
|
40082
|
-
secondaryAction:
|
|
40083
|
-
installCommand: resolved.installCommand,
|
|
40084
|
-
image
|
|
40337
|
+
tag: resolved.tag != null ? String(resolved.tag) : void 0,
|
|
40338
|
+
title: String(resolved.title ?? ""),
|
|
40339
|
+
titleAccent: resolved.titleAccent != null ? String(resolved.titleAccent) : void 0,
|
|
40340
|
+
subtitle: String(resolved.subtitle ?? ""),
|
|
40341
|
+
primaryAction: primaryAction ? { label: String(primaryAction.label ?? ""), href: String(primaryAction.href ?? "") } : void 0,
|
|
40342
|
+
secondaryAction: secondaryAction ? { label: String(secondaryAction.label ?? ""), href: String(secondaryAction.href ?? "") } : void 0,
|
|
40343
|
+
installCommand: resolved.installCommand != null ? String(resolved.installCommand) : void 0,
|
|
40344
|
+
image,
|
|
40085
40345
|
imagePosition: resolved.imagePosition,
|
|
40086
40346
|
background: resolved.background,
|
|
40087
40347
|
className: cn(className),
|
|
@@ -40090,8 +40350,8 @@ var init_HeroOrganism = __esm({
|
|
|
40090
40350
|
/* @__PURE__ */ jsx(
|
|
40091
40351
|
_HeroClickInterceptor,
|
|
40092
40352
|
{
|
|
40093
|
-
hasPrimary: !!
|
|
40094
|
-
hasSecondary: !!
|
|
40353
|
+
hasPrimary: !!primaryAction,
|
|
40354
|
+
hasSecondary: !!secondaryAction,
|
|
40095
40355
|
onPrimaryClick: handlePrimaryClick,
|
|
40096
40356
|
onSecondaryClick: handleSecondaryClick
|
|
40097
40357
|
}
|
|
@@ -40320,7 +40580,7 @@ function formatValue3(value, fieldName) {
|
|
|
40320
40580
|
return String(value);
|
|
40321
40581
|
}
|
|
40322
40582
|
function formatFieldLabel2(fieldName) {
|
|
40323
|
-
return fieldName.replace(/([A-Z])/g, " $1").replace(/^./, (
|
|
40583
|
+
return fieldName.replace(/([A-Z])/g, " $1").replace(/^./, (str2) => str2.toUpperCase()).replace(/Id$/, "").trim();
|
|
40324
40584
|
}
|
|
40325
40585
|
var STATUS_STYLES2, StatusBadge, ProgressIndicator, List3;
|
|
40326
40586
|
var init_List = __esm({
|
|
@@ -40466,7 +40726,7 @@ var init_List = __esm({
|
|
|
40466
40726
|
if (entity && typeof entity === "object" && "id" in entity) return [entity];
|
|
40467
40727
|
return [];
|
|
40468
40728
|
}, [entity]);
|
|
40469
|
-
const getItemActions =
|
|
40729
|
+
const getItemActions = React80__default.useCallback(
|
|
40470
40730
|
(item) => {
|
|
40471
40731
|
if (!itemActions) return [];
|
|
40472
40732
|
if (typeof itemActions === "function") {
|
|
@@ -40942,7 +41202,7 @@ var init_MediaGallery = __esm({
|
|
|
40942
41202
|
[selectable, selectedItems, selectionEvent, eventBus]
|
|
40943
41203
|
);
|
|
40944
41204
|
const entityData = Array.isArray(entity) ? entity : [];
|
|
40945
|
-
const items =
|
|
41205
|
+
const items = React80__default.useMemo(() => {
|
|
40946
41206
|
if (propItems) return propItems;
|
|
40947
41207
|
if (entityData.length === 0) return [];
|
|
40948
41208
|
return entityData.map((record, idx) => ({
|
|
@@ -41112,9 +41372,9 @@ function MiniMap({
|
|
|
41112
41372
|
viewportRect,
|
|
41113
41373
|
className
|
|
41114
41374
|
}) {
|
|
41115
|
-
const canvasRef =
|
|
41116
|
-
const frameRef =
|
|
41117
|
-
|
|
41375
|
+
const canvasRef = React80.useRef(null);
|
|
41376
|
+
const frameRef = React80.useRef(0);
|
|
41377
|
+
React80.useEffect(() => {
|
|
41118
41378
|
const canvas = canvasRef.current;
|
|
41119
41379
|
if (!canvas) return;
|
|
41120
41380
|
const ctx = canvas.getContext("2d");
|
|
@@ -41196,7 +41456,7 @@ var init_MiniMap = __esm({
|
|
|
41196
41456
|
}
|
|
41197
41457
|
});
|
|
41198
41458
|
function extractTitle2(children) {
|
|
41199
|
-
if (!
|
|
41459
|
+
if (!React80__default.isValidElement(children)) return void 0;
|
|
41200
41460
|
const props = children.props;
|
|
41201
41461
|
if (typeof props.title === "string") {
|
|
41202
41462
|
return props.title;
|
|
@@ -41260,20 +41520,22 @@ function NegotiatorBoard({
|
|
|
41260
41520
|
}) {
|
|
41261
41521
|
const { emit } = useEventBus();
|
|
41262
41522
|
const { t } = useTranslate();
|
|
41263
|
-
const resolved =
|
|
41523
|
+
const resolved = boardEntity(entity);
|
|
41264
41524
|
const [history, setHistory] = useState([]);
|
|
41265
41525
|
const [headerError, setHeaderError] = useState(false);
|
|
41266
41526
|
const [showHint, setShowHint] = useState(false);
|
|
41527
|
+
const totalRounds = num(resolved?.totalRounds);
|
|
41528
|
+
const targetScore = num(resolved?.targetScore);
|
|
41267
41529
|
const currentRound = history.length;
|
|
41268
|
-
const isComplete = currentRound >=
|
|
41530
|
+
const isComplete = currentRound >= totalRounds;
|
|
41269
41531
|
const playerTotal = history.reduce((s, r) => s + r.playerPayoff, 0);
|
|
41270
41532
|
const opponentTotal = history.reduce((s, r) => s + r.opponentPayoff, 0);
|
|
41271
|
-
const won = isComplete && playerTotal >=
|
|
41272
|
-
const actions = resolved?.actions
|
|
41273
|
-
const payoffMatrix = resolved?.payoffMatrix
|
|
41533
|
+
const won = isComplete && playerTotal >= targetScore;
|
|
41534
|
+
const actions = Array.isArray(resolved?.actions) ? resolved.actions : [];
|
|
41535
|
+
const payoffMatrix = Array.isArray(resolved?.payoffMatrix) ? resolved.payoffMatrix : [];
|
|
41274
41536
|
const handleAction = useCallback((actionId) => {
|
|
41275
41537
|
if (isComplete) return;
|
|
41276
|
-
const opponentAction = getOpponentAction(resolved?.opponentStrategy
|
|
41538
|
+
const opponentAction = getOpponentAction(str(resolved?.opponentStrategy) || "random", actions, history);
|
|
41277
41539
|
const payoff = payoffMatrix.find(
|
|
41278
41540
|
(p2) => p2.playerAction === actionId && p2.opponentAction === opponentAction
|
|
41279
41541
|
);
|
|
@@ -41286,42 +41548,46 @@ function NegotiatorBoard({
|
|
|
41286
41548
|
};
|
|
41287
41549
|
const newHistory = [...history, result];
|
|
41288
41550
|
setHistory(newHistory);
|
|
41289
|
-
if (newHistory.length >=
|
|
41551
|
+
if (newHistory.length >= totalRounds) {
|
|
41290
41552
|
const total = newHistory.reduce((s, r) => s + r.playerPayoff, 0);
|
|
41291
|
-
if (total >=
|
|
41553
|
+
if (total >= targetScore) {
|
|
41292
41554
|
emit(`UI:${completeEvent}`, { success: true, score: total });
|
|
41293
41555
|
}
|
|
41294
|
-
if (newHistory.length >= 3 && resolved?.hint) {
|
|
41556
|
+
if (newHistory.length >= 3 && str(resolved?.hint)) {
|
|
41295
41557
|
setShowHint(true);
|
|
41296
41558
|
}
|
|
41297
41559
|
}
|
|
41298
|
-
}, [isComplete, resolved, actions, payoffMatrix, history, currentRound, completeEvent, emit]);
|
|
41560
|
+
}, [isComplete, resolved, totalRounds, targetScore, actions, payoffMatrix, history, currentRound, completeEvent, emit]);
|
|
41299
41561
|
const handleReset = () => {
|
|
41300
41562
|
setHistory([]);
|
|
41301
41563
|
setShowHint(false);
|
|
41302
41564
|
};
|
|
41303
41565
|
const getActionLabel = (id) => actions.find((a) => a.id === id)?.label ?? id;
|
|
41304
41566
|
if (!resolved) return null;
|
|
41567
|
+
const theme = resolved.theme ?? void 0;
|
|
41568
|
+
const themeBackground = theme?.background;
|
|
41569
|
+
const headerImage = str(resolved.headerImage);
|
|
41570
|
+
const hint = str(resolved.hint);
|
|
41305
41571
|
return /* @__PURE__ */ jsx(
|
|
41306
41572
|
Box,
|
|
41307
41573
|
{
|
|
41308
41574
|
className,
|
|
41309
41575
|
style: {
|
|
41310
|
-
backgroundImage:
|
|
41576
|
+
backgroundImage: themeBackground ? `url(${themeBackground})` : void 0,
|
|
41311
41577
|
backgroundSize: "cover",
|
|
41312
41578
|
backgroundPosition: "center"
|
|
41313
41579
|
},
|
|
41314
41580
|
children: /* @__PURE__ */ jsxs(VStack, { gap: "lg", className: "p-4", children: [
|
|
41315
|
-
|
|
41581
|
+
headerImage && !headerError ? /* @__PURE__ */ jsx(Box, { className: "w-full h-32 overflow-hidden rounded-container", children: /* @__PURE__ */ jsx("img", { src: headerImage, alt: "", onError: () => setHeaderError(true), className: "w-full h-full object-cover" }) }) : headerImage && headerError ? /* @__PURE__ */ jsx(Box, { className: "w-full h-32 rounded-container bg-gradient-to-br from-muted to-accent opacity-60" }) : null,
|
|
41316
41582
|
/* @__PURE__ */ jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxs(VStack, { gap: "sm", children: [
|
|
41317
|
-
/* @__PURE__ */ jsx(Typography, { variant: "h4", weight: "bold", children: resolved.title }),
|
|
41318
|
-
/* @__PURE__ */ jsx(Typography, { variant: "body", children: resolved.description }),
|
|
41583
|
+
/* @__PURE__ */ jsx(Typography, { variant: "h4", weight: "bold", children: str(resolved.title) }),
|
|
41584
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body", children: str(resolved.description) }),
|
|
41319
41585
|
/* @__PURE__ */ jsxs(HStack, { gap: "md", children: [
|
|
41320
|
-
/* @__PURE__ */ jsx(Badge, { size: "sm", children: t("negotiator.round", { current: String(currentRound), total: String(
|
|
41586
|
+
/* @__PURE__ */ jsx(Badge, { size: "sm", children: t("negotiator.round", { current: String(currentRound), total: String(totalRounds) }) }),
|
|
41321
41587
|
/* @__PURE__ */ jsxs(Badge, { size: "sm", children: [
|
|
41322
41588
|
t("negotiator.target"),
|
|
41323
41589
|
": ",
|
|
41324
|
-
|
|
41590
|
+
targetScore
|
|
41325
41591
|
] })
|
|
41326
41592
|
] })
|
|
41327
41593
|
] }) }),
|
|
@@ -41370,16 +41636,16 @@ function NegotiatorBoard({
|
|
|
41370
41636
|
] }) }),
|
|
41371
41637
|
isComplete && /* @__PURE__ */ jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxs(VStack, { gap: "sm", align: "center", children: [
|
|
41372
41638
|
/* @__PURE__ */ jsx(Icon, { icon: CheckCircle, size: "lg", className: won ? "text-success" : "text-error" }),
|
|
41373
|
-
/* @__PURE__ */ jsx(Typography, { variant: "body", weight: "bold", children: won ? resolved.successMessage
|
|
41639
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body", weight: "bold", children: won ? str(resolved.successMessage) || t("negotiator.success") : str(resolved.failMessage) || t("negotiator.failed") }),
|
|
41374
41640
|
/* @__PURE__ */ jsxs(Typography, { variant: "caption", className: "text-muted-foreground", children: [
|
|
41375
41641
|
t("negotiator.finalScore"),
|
|
41376
41642
|
": ",
|
|
41377
41643
|
playerTotal,
|
|
41378
41644
|
"/",
|
|
41379
|
-
|
|
41645
|
+
targetScore
|
|
41380
41646
|
] })
|
|
41381
41647
|
] }) }),
|
|
41382
|
-
showHint &&
|
|
41648
|
+
showHint && hint && !won && /* @__PURE__ */ jsx(Card, { className: "p-4 border-l-4 border-l-warning", children: /* @__PURE__ */ jsx(Typography, { variant: "body", children: hint }) }),
|
|
41383
41649
|
isComplete && !won && /* @__PURE__ */ jsx(HStack, { justify: "center", children: /* @__PURE__ */ jsx(Button, { variant: "primary", onClick: handleReset, children: t("negotiator.playAgain") }) })
|
|
41384
41650
|
] })
|
|
41385
41651
|
}
|
|
@@ -41389,6 +41655,7 @@ var init_NegotiatorBoard = __esm({
|
|
|
41389
41655
|
"components/game/organisms/puzzles/negotiator/NegotiatorBoard.tsx"() {
|
|
41390
41656
|
init_atoms2();
|
|
41391
41657
|
init_useEventBus();
|
|
41658
|
+
init_boardEntity();
|
|
41392
41659
|
NegotiatorBoard.displayName = "NegotiatorBoard";
|
|
41393
41660
|
}
|
|
41394
41661
|
});
|
|
@@ -41424,13 +41691,13 @@ var init_PricingOrganism = __esm({
|
|
|
41424
41691
|
return /* @__PURE__ */ jsx(ErrorState, { message: error.message, className });
|
|
41425
41692
|
}
|
|
41426
41693
|
const plans = items.map((plan) => ({
|
|
41427
|
-
name: plan.name,
|
|
41428
|
-
price: plan.price,
|
|
41429
|
-
description: plan.description,
|
|
41430
|
-
features: plan.features,
|
|
41431
|
-
action: { label: plan.actionLabel, href: plan.actionHref },
|
|
41432
|
-
highlighted: plan.highlighted,
|
|
41433
|
-
badge: plan.badge
|
|
41694
|
+
name: String(plan.name ?? ""),
|
|
41695
|
+
price: String(plan.price ?? ""),
|
|
41696
|
+
description: plan.description != null ? String(plan.description) : void 0,
|
|
41697
|
+
features: (plan.features ?? []).map((f3) => String(f3)),
|
|
41698
|
+
action: { label: String(plan.actionLabel ?? ""), href: String(plan.actionHref ?? "") },
|
|
41699
|
+
highlighted: Boolean(plan.highlighted),
|
|
41700
|
+
badge: plan.badge != null ? String(plan.badge) : void 0
|
|
41434
41701
|
}));
|
|
41435
41702
|
return /* @__PURE__ */ jsxs(VStack, { gap: "lg", className: cn("w-full", className), children: [
|
|
41436
41703
|
(heading || subtitle) && /* @__PURE__ */ jsxs(VStack, { gap: "sm", align: "center", className: "w-full", children: [
|
|
@@ -41646,7 +41913,7 @@ var init_debugRegistry = __esm({
|
|
|
41646
41913
|
}
|
|
41647
41914
|
});
|
|
41648
41915
|
function useDebugData() {
|
|
41649
|
-
const [data, setData] =
|
|
41916
|
+
const [data, setData] = React80.useState(() => ({
|
|
41650
41917
|
traits: [],
|
|
41651
41918
|
ticks: [],
|
|
41652
41919
|
guards: [],
|
|
@@ -41660,7 +41927,7 @@ function useDebugData() {
|
|
|
41660
41927
|
},
|
|
41661
41928
|
lastUpdate: Date.now()
|
|
41662
41929
|
}));
|
|
41663
|
-
|
|
41930
|
+
React80.useEffect(() => {
|
|
41664
41931
|
const updateData = () => {
|
|
41665
41932
|
setData({
|
|
41666
41933
|
traits: getAllTraits(),
|
|
@@ -41769,12 +42036,12 @@ function layoutGraph(states, transitions, initialState, width, height) {
|
|
|
41769
42036
|
return positions;
|
|
41770
42037
|
}
|
|
41771
42038
|
function WalkMinimap() {
|
|
41772
|
-
const [walkStep, setWalkStep] =
|
|
41773
|
-
const [traits2, setTraits] =
|
|
41774
|
-
const [coveredEdges, setCoveredEdges] =
|
|
41775
|
-
const [completedTraits, setCompletedTraits] =
|
|
41776
|
-
const prevTraitRef =
|
|
41777
|
-
|
|
42039
|
+
const [walkStep, setWalkStep] = React80.useState(null);
|
|
42040
|
+
const [traits2, setTraits] = React80.useState([]);
|
|
42041
|
+
const [coveredEdges, setCoveredEdges] = React80.useState([]);
|
|
42042
|
+
const [completedTraits, setCompletedTraits] = React80.useState(/* @__PURE__ */ new Set());
|
|
42043
|
+
const prevTraitRef = React80.useRef(null);
|
|
42044
|
+
React80.useEffect(() => {
|
|
41778
42045
|
const interval = setInterval(() => {
|
|
41779
42046
|
const w = window;
|
|
41780
42047
|
const step = w.__orbitalWalkStep;
|
|
@@ -42210,15 +42477,15 @@ var init_EntitiesTab = __esm({
|
|
|
42210
42477
|
});
|
|
42211
42478
|
function EventFlowTab({ events: events2 }) {
|
|
42212
42479
|
const { t } = useTranslate();
|
|
42213
|
-
const [filter, setFilter] =
|
|
42214
|
-
const containerRef =
|
|
42215
|
-
const [autoScroll, setAutoScroll] =
|
|
42216
|
-
|
|
42480
|
+
const [filter, setFilter] = React80.useState("all");
|
|
42481
|
+
const containerRef = React80.useRef(null);
|
|
42482
|
+
const [autoScroll, setAutoScroll] = React80.useState(true);
|
|
42483
|
+
React80.useEffect(() => {
|
|
42217
42484
|
if (autoScroll && containerRef.current) {
|
|
42218
42485
|
containerRef.current.scrollTop = containerRef.current.scrollHeight;
|
|
42219
42486
|
}
|
|
42220
42487
|
}, [events2.length, autoScroll]);
|
|
42221
|
-
const filteredEvents =
|
|
42488
|
+
const filteredEvents = React80.useMemo(() => {
|
|
42222
42489
|
if (filter === "all") return events2;
|
|
42223
42490
|
return events2.filter((e) => e.type === filter);
|
|
42224
42491
|
}, [events2, filter]);
|
|
@@ -42334,7 +42601,7 @@ var init_EventFlowTab = __esm({
|
|
|
42334
42601
|
});
|
|
42335
42602
|
function GuardsPanel({ guards }) {
|
|
42336
42603
|
const { t } = useTranslate();
|
|
42337
|
-
const [filter, setFilter] =
|
|
42604
|
+
const [filter, setFilter] = React80.useState("all");
|
|
42338
42605
|
if (guards.length === 0) {
|
|
42339
42606
|
return /* @__PURE__ */ jsx(
|
|
42340
42607
|
EmptyState,
|
|
@@ -42347,7 +42614,7 @@ function GuardsPanel({ guards }) {
|
|
|
42347
42614
|
}
|
|
42348
42615
|
const passedCount = guards.filter((g) => g.result).length;
|
|
42349
42616
|
const failedCount = guards.length - passedCount;
|
|
42350
|
-
const filteredGuards =
|
|
42617
|
+
const filteredGuards = React80.useMemo(() => {
|
|
42351
42618
|
if (filter === "all") return guards;
|
|
42352
42619
|
if (filter === "passed") return guards.filter((g) => g.result);
|
|
42353
42620
|
return guards.filter((g) => !g.result);
|
|
@@ -42510,10 +42777,10 @@ function EffectBadge({ effect }) {
|
|
|
42510
42777
|
}
|
|
42511
42778
|
function TransitionTimeline({ transitions }) {
|
|
42512
42779
|
const { t } = useTranslate();
|
|
42513
|
-
const containerRef =
|
|
42514
|
-
const [autoScroll, setAutoScroll] =
|
|
42515
|
-
const [expandedId, setExpandedId] =
|
|
42516
|
-
|
|
42780
|
+
const containerRef = React80.useRef(null);
|
|
42781
|
+
const [autoScroll, setAutoScroll] = React80.useState(true);
|
|
42782
|
+
const [expandedId, setExpandedId] = React80.useState(null);
|
|
42783
|
+
React80.useEffect(() => {
|
|
42517
42784
|
if (autoScroll && containerRef.current) {
|
|
42518
42785
|
containerRef.current.scrollTop = containerRef.current.scrollHeight;
|
|
42519
42786
|
}
|
|
@@ -42793,9 +43060,9 @@ function getAllEvents(traits2) {
|
|
|
42793
43060
|
function EventDispatcherTab({ traits: traits2, schema }) {
|
|
42794
43061
|
const eventBus = useEventBus();
|
|
42795
43062
|
const { t } = useTranslate();
|
|
42796
|
-
const [log8, setLog] =
|
|
42797
|
-
const prevStatesRef =
|
|
42798
|
-
|
|
43063
|
+
const [log8, setLog] = React80.useState([]);
|
|
43064
|
+
const prevStatesRef = React80.useRef(/* @__PURE__ */ new Map());
|
|
43065
|
+
React80.useEffect(() => {
|
|
42799
43066
|
for (const trait of traits2) {
|
|
42800
43067
|
const prev = prevStatesRef.current.get(trait.id);
|
|
42801
43068
|
if (prev && prev !== trait.currentState) {
|
|
@@ -42964,10 +43231,10 @@ function VerifyModePanel({
|
|
|
42964
43231
|
localCount
|
|
42965
43232
|
}) {
|
|
42966
43233
|
const { t } = useTranslate();
|
|
42967
|
-
const [expanded, setExpanded] =
|
|
42968
|
-
const scrollRef =
|
|
42969
|
-
const prevCountRef =
|
|
42970
|
-
|
|
43234
|
+
const [expanded, setExpanded] = React80.useState(true);
|
|
43235
|
+
const scrollRef = React80.useRef(null);
|
|
43236
|
+
const prevCountRef = React80.useRef(0);
|
|
43237
|
+
React80.useEffect(() => {
|
|
42971
43238
|
if (expanded && transitions.length > prevCountRef.current && scrollRef.current) {
|
|
42972
43239
|
scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
|
|
42973
43240
|
}
|
|
@@ -43024,10 +43291,10 @@ function RuntimeDebugger({
|
|
|
43024
43291
|
schema
|
|
43025
43292
|
}) {
|
|
43026
43293
|
const { t } = useTranslate();
|
|
43027
|
-
const [isCollapsed, setIsCollapsed] =
|
|
43028
|
-
const [isVisible, setIsVisible] =
|
|
43294
|
+
const [isCollapsed, setIsCollapsed] = React80.useState(mode === "verify" ? true : defaultCollapsed);
|
|
43295
|
+
const [isVisible, setIsVisible] = React80.useState(mode === "inline" || mode === "verify" || isDebugEnabled2());
|
|
43029
43296
|
const debugData = useDebugData();
|
|
43030
|
-
|
|
43297
|
+
React80.useEffect(() => {
|
|
43031
43298
|
if (mode === "inline") return;
|
|
43032
43299
|
return onDebugToggle((enabled) => {
|
|
43033
43300
|
setIsVisible(enabled);
|
|
@@ -43036,7 +43303,7 @@ function RuntimeDebugger({
|
|
|
43036
43303
|
}
|
|
43037
43304
|
});
|
|
43038
43305
|
}, [mode]);
|
|
43039
|
-
|
|
43306
|
+
React80.useEffect(() => {
|
|
43040
43307
|
if (mode === "inline") return;
|
|
43041
43308
|
const handleKeyDown = (e) => {
|
|
43042
43309
|
if (e.key === "`" && isVisible) {
|
|
@@ -43485,7 +43752,7 @@ function SequenceBar({
|
|
|
43485
43752
|
onSlotRemove(index);
|
|
43486
43753
|
}, [onSlotRemove, playing]);
|
|
43487
43754
|
const paddedSlots = Array.from({ length: maxSlots }, (_, i) => slots[i]);
|
|
43488
|
-
return /* @__PURE__ */ jsx(HStack, { className: cn("items-center", className), gap: "sm", children: paddedSlots.map((slot, i) => /* @__PURE__ */ jsxs(
|
|
43755
|
+
return /* @__PURE__ */ jsx(HStack, { className: cn("items-center", className), gap: "sm", children: paddedSlots.map((slot, i) => /* @__PURE__ */ jsxs(React80__default.Fragment, { children: [
|
|
43489
43756
|
i > 0 && /* @__PURE__ */ jsx(
|
|
43490
43757
|
Typography,
|
|
43491
43758
|
{
|
|
@@ -43546,16 +43813,20 @@ function SequencerBoard({
|
|
|
43546
43813
|
}) {
|
|
43547
43814
|
const { emit } = useEventBus();
|
|
43548
43815
|
const { t } = useTranslate();
|
|
43549
|
-
const resolved =
|
|
43816
|
+
const resolved = boardEntity(entity);
|
|
43817
|
+
const maxSlots = num(resolved?.maxSlots);
|
|
43818
|
+
const solutions = Array.isArray(resolved?.solutions) ? resolved.solutions : [];
|
|
43819
|
+
const availableActions = Array.isArray(resolved?.availableActions) ? resolved.availableActions : [];
|
|
43820
|
+
const allowDuplicates = resolved?.allowDuplicates !== false;
|
|
43550
43821
|
const [headerError, setHeaderError] = useState(false);
|
|
43551
43822
|
const [slots, setSlots] = useState(
|
|
43552
|
-
() => Array.from({ length:
|
|
43823
|
+
() => Array.from({ length: maxSlots }, () => void 0)
|
|
43553
43824
|
);
|
|
43554
43825
|
const [playState, setPlayState] = useState("idle");
|
|
43555
43826
|
const [currentStep, setCurrentStep] = useState(-1);
|
|
43556
43827
|
const [attempts, setAttempts] = useState(0);
|
|
43557
43828
|
const [slotFeedback, setSlotFeedback] = useState(
|
|
43558
|
-
() => Array.from({ length:
|
|
43829
|
+
() => Array.from({ length: maxSlots }, () => null)
|
|
43559
43830
|
);
|
|
43560
43831
|
const timerRef = useRef(null);
|
|
43561
43832
|
useEffect(() => () => {
|
|
@@ -43589,17 +43860,17 @@ function SequencerBoard({
|
|
|
43589
43860
|
}, [emit]);
|
|
43590
43861
|
const handleReset = useCallback(() => {
|
|
43591
43862
|
if (timerRef.current) clearTimeout(timerRef.current);
|
|
43592
|
-
setSlots(Array.from({ length:
|
|
43863
|
+
setSlots(Array.from({ length: maxSlots }, () => void 0));
|
|
43593
43864
|
setPlayState("idle");
|
|
43594
43865
|
setCurrentStep(-1);
|
|
43595
43866
|
setAttempts(0);
|
|
43596
|
-
setSlotFeedback(Array.from({ length:
|
|
43597
|
-
}, [
|
|
43867
|
+
setSlotFeedback(Array.from({ length: maxSlots }, () => null));
|
|
43868
|
+
}, [maxSlots]);
|
|
43598
43869
|
const filledSlots = slots.filter((s) => !!s);
|
|
43599
43870
|
const canPlay = filledSlots.length > 0 && playState === "idle";
|
|
43600
43871
|
const handlePlay = useCallback(() => {
|
|
43601
43872
|
if (!canPlay) return;
|
|
43602
|
-
setSlotFeedback(Array.from({ length:
|
|
43873
|
+
setSlotFeedback(Array.from({ length: maxSlots }, () => null));
|
|
43603
43874
|
emit("UI:PLAY_SOUND", { key: "confirm" });
|
|
43604
43875
|
const sequence = slots.map((s) => s?.id || "");
|
|
43605
43876
|
if (playEvent) {
|
|
@@ -43610,10 +43881,10 @@ function SequencerBoard({
|
|
|
43610
43881
|
let step = 0;
|
|
43611
43882
|
const advance = () => {
|
|
43612
43883
|
step++;
|
|
43613
|
-
if (step >=
|
|
43884
|
+
if (step >= maxSlots) {
|
|
43614
43885
|
const playerSeq = slots.map((s) => s?.id);
|
|
43615
43886
|
const playerIds = slots.filter(Boolean).map((s) => s?.id || "");
|
|
43616
|
-
const success =
|
|
43887
|
+
const success = solutions.some(
|
|
43617
43888
|
(sol) => sol.length === playerIds.length && sol.every((id, i) => id === playerIds[i])
|
|
43618
43889
|
);
|
|
43619
43890
|
if (success) {
|
|
@@ -43625,7 +43896,7 @@ function SequencerBoard({
|
|
|
43625
43896
|
}
|
|
43626
43897
|
} else {
|
|
43627
43898
|
setAttempts((prev) => prev + 1);
|
|
43628
|
-
const feedback = computeSlotFeedback(playerSeq,
|
|
43899
|
+
const feedback = computeSlotFeedback(playerSeq, solutions);
|
|
43629
43900
|
setSlotFeedback(feedback);
|
|
43630
43901
|
setPlayState("idle");
|
|
43631
43902
|
setCurrentStep(-1);
|
|
@@ -43643,10 +43914,10 @@ function SequencerBoard({
|
|
|
43643
43914
|
}
|
|
43644
43915
|
};
|
|
43645
43916
|
timerRef.current = setTimeout(advance, stepDurationMs);
|
|
43646
|
-
}, [canPlay, slots,
|
|
43917
|
+
}, [canPlay, slots, maxSlots, solutions, stepDurationMs, playEvent, completeEvent, emit]);
|
|
43647
43918
|
const machine = {
|
|
43648
|
-
name: resolved?.title
|
|
43649
|
-
description: resolved?.description
|
|
43919
|
+
name: str(resolved?.title),
|
|
43920
|
+
description: str(resolved?.description),
|
|
43650
43921
|
states: slots.map((s, i) => stepLabel(s, i)),
|
|
43651
43922
|
currentState: currentStep >= 0 ? stepLabel(slots[currentStep], currentStep) : "__idle__",
|
|
43652
43923
|
transitions: slots.slice(0, -1).map((s, i) => ({
|
|
@@ -43655,37 +43926,41 @@ function SequencerBoard({
|
|
|
43655
43926
|
event: "NEXT"
|
|
43656
43927
|
}))
|
|
43657
43928
|
};
|
|
43658
|
-
const usedIds =
|
|
43659
|
-
const
|
|
43929
|
+
const usedIds = !allowDuplicates ? slots.filter(Boolean).map((s) => s?.id || "") : [];
|
|
43930
|
+
const hint = str(resolved?.hint);
|
|
43931
|
+
const showHint = attempts >= 3 && !!hint;
|
|
43660
43932
|
const hasFeedback = slotFeedback.some((f3) => f3 !== null);
|
|
43661
43933
|
const correctCount = slotFeedback.filter((f3) => f3 === "correct").length;
|
|
43662
43934
|
const encourageKey = ENCOURAGEMENT_KEYS2[Math.min(attempts - 1, ENCOURAGEMENT_KEYS2.length - 1)] ?? ENCOURAGEMENT_KEYS2[0];
|
|
43663
43935
|
if (!resolved) return null;
|
|
43936
|
+
const theme = resolved.theme ?? void 0;
|
|
43937
|
+
const themeBackground = theme?.background;
|
|
43938
|
+
const headerImage = str(resolved.headerImage);
|
|
43664
43939
|
return /* @__PURE__ */ jsxs(
|
|
43665
43940
|
VStack,
|
|
43666
43941
|
{
|
|
43667
43942
|
className: cn("p-4 gap-6", className),
|
|
43668
43943
|
style: {
|
|
43669
|
-
backgroundImage:
|
|
43944
|
+
backgroundImage: themeBackground ? `url(${themeBackground})` : void 0,
|
|
43670
43945
|
backgroundSize: "cover",
|
|
43671
43946
|
backgroundPosition: "center"
|
|
43672
43947
|
},
|
|
43673
43948
|
children: [
|
|
43674
|
-
|
|
43949
|
+
headerImage && !headerError ? /* @__PURE__ */ jsx(Box, { className: "w-full h-32 overflow-hidden rounded-container", children: /* @__PURE__ */ jsx("img", { src: headerImage, alt: "", onError: () => setHeaderError(true), className: "w-full h-full object-cover" }) }) : headerImage && headerError ? /* @__PURE__ */ jsx(Box, { className: "w-full h-32 rounded-container bg-gradient-to-br from-muted to-accent opacity-60" }) : null,
|
|
43675
43950
|
/* @__PURE__ */ jsxs(VStack, { gap: "xs", children: [
|
|
43676
|
-
/* @__PURE__ */ jsx(Typography, { variant: "h4", className: "text-foreground", children: resolved.title }),
|
|
43677
|
-
/* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-muted-foreground", children: resolved.description })
|
|
43951
|
+
/* @__PURE__ */ jsx(Typography, { variant: "h4", className: "text-foreground", children: str(resolved.title) }),
|
|
43952
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-muted-foreground", children: str(resolved.description) })
|
|
43678
43953
|
] }),
|
|
43679
43954
|
showHint && /* @__PURE__ */ jsx(Box, { className: "p-3 rounded-container bg-accent/10 border border-accent/30", children: /* @__PURE__ */ jsxs(HStack, { className: "items-start", gap: "xs", children: [
|
|
43680
43955
|
/* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-accent font-bold shrink-0", children: "\u{1F4A1} " + t("game.hint") + ":" }),
|
|
43681
|
-
/* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-foreground", children:
|
|
43956
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-foreground", children: hint })
|
|
43682
43957
|
] }) }),
|
|
43683
43958
|
filledSlots.length > 0 && /* @__PURE__ */ jsx(TraitStateViewer, { trait: machine, variant: "linear", size: "md" }),
|
|
43684
43959
|
/* @__PURE__ */ jsxs(VStack, { gap: "xs", children: [
|
|
43685
43960
|
/* @__PURE__ */ jsxs(HStack, { className: "items-center justify-between", children: [
|
|
43686
43961
|
/* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-muted-foreground font-medium", children: t("sequencer.yourSequence") + ":" }),
|
|
43687
43962
|
hasFeedback && playState === "idle" && /* @__PURE__ */ jsxs(Typography, { variant: "caption", className: "text-muted-foreground", children: [
|
|
43688
|
-
`${correctCount}/${
|
|
43963
|
+
`${correctCount}/${maxSlots} `,
|
|
43689
43964
|
"\u2705"
|
|
43690
43965
|
] })
|
|
43691
43966
|
] }),
|
|
@@ -43693,7 +43968,7 @@ function SequencerBoard({
|
|
|
43693
43968
|
SequenceBar,
|
|
43694
43969
|
{
|
|
43695
43970
|
slots,
|
|
43696
|
-
maxSlots
|
|
43971
|
+
maxSlots,
|
|
43697
43972
|
onSlotDrop: handleSlotDrop,
|
|
43698
43973
|
onSlotRemove: handleSlotRemove,
|
|
43699
43974
|
playing: playState === "playing",
|
|
@@ -43707,15 +43982,15 @@ function SequencerBoard({
|
|
|
43707
43982
|
playState !== "playing" && /* @__PURE__ */ jsx(
|
|
43708
43983
|
ActionPalette,
|
|
43709
43984
|
{
|
|
43710
|
-
actions:
|
|
43985
|
+
actions: availableActions,
|
|
43711
43986
|
usedActionIds: usedIds,
|
|
43712
|
-
allowDuplicates
|
|
43987
|
+
allowDuplicates,
|
|
43713
43988
|
categoryColors,
|
|
43714
43989
|
label: t("sequencer.dragActions")
|
|
43715
43990
|
}
|
|
43716
43991
|
),
|
|
43717
43992
|
hasFeedback && playState === "idle" && attempts > 0 && /* @__PURE__ */ jsx(Box, { className: "p-3 rounded-container bg-warning/10 border border-warning/30 text-center", children: /* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-foreground", children: t(encourageKey) }) }),
|
|
43718
|
-
playState === "success" && /* @__PURE__ */ jsx(Box, { className: "p-4 rounded-container bg-success/20 border border-success text-center", children: /* @__PURE__ */ jsx(Typography, { variant: "h5", className: "text-success", children: resolved.successMessage || t("sequencer.levelComplete") }) }),
|
|
43993
|
+
playState === "success" && /* @__PURE__ */ jsx(Box, { className: "p-4 rounded-container bg-success/20 border border-success text-center", children: /* @__PURE__ */ jsx(Typography, { variant: "h5", className: "text-success", children: str(resolved.successMessage) || t("sequencer.levelComplete") }) }),
|
|
43719
43994
|
/* @__PURE__ */ jsxs(HStack, { gap: "sm", children: [
|
|
43720
43995
|
/* @__PURE__ */ jsx(
|
|
43721
43996
|
Button,
|
|
@@ -43739,6 +44014,7 @@ var init_SequencerBoard = __esm({
|
|
|
43739
44014
|
init_cn();
|
|
43740
44015
|
init_useEventBus();
|
|
43741
44016
|
init_TraitStateViewer();
|
|
44017
|
+
init_boardEntity();
|
|
43742
44018
|
init_SequenceBar();
|
|
43743
44019
|
init_ActionPalette();
|
|
43744
44020
|
ENCOURAGEMENT_KEYS2 = [
|
|
@@ -43788,18 +44064,21 @@ var init_ShowcaseOrganism = __esm({
|
|
|
43788
44064
|
heading && /* @__PURE__ */ jsx(Typography, { variant: "h2", align: "center", children: heading }),
|
|
43789
44065
|
subtitle && /* @__PURE__ */ jsx(Typography, { variant: "body1", color: "muted", align: "center", className: "max-w-2xl", children: subtitle })
|
|
43790
44066
|
] }),
|
|
43791
|
-
/* @__PURE__ */ jsx(SimpleGrid, { cols: columns, gap: "lg", children: items.map((item) =>
|
|
43792
|
-
|
|
43793
|
-
|
|
43794
|
-
|
|
43795
|
-
|
|
43796
|
-
|
|
43797
|
-
|
|
43798
|
-
|
|
43799
|
-
|
|
43800
|
-
|
|
43801
|
-
|
|
43802
|
-
|
|
44067
|
+
/* @__PURE__ */ jsx(SimpleGrid, { cols: columns, gap: "lg", children: items.map((item) => {
|
|
44068
|
+
const imageRaw = item.image;
|
|
44069
|
+
return /* @__PURE__ */ jsx(
|
|
44070
|
+
ShowcaseCard,
|
|
44071
|
+
{
|
|
44072
|
+
title: String(item.title ?? ""),
|
|
44073
|
+
description: item.description != null ? String(item.description) : void 0,
|
|
44074
|
+
image: { src: String(imageRaw?.src ?? ""), alt: String(imageRaw?.alt ?? "") },
|
|
44075
|
+
href: item.href != null ? String(item.href) : void 0,
|
|
44076
|
+
badge: item.badge != null ? String(item.badge) : void 0,
|
|
44077
|
+
accentColor: item.accentColor != null ? String(item.accentColor) : void 0
|
|
44078
|
+
},
|
|
44079
|
+
String(item.id ?? "")
|
|
44080
|
+
);
|
|
44081
|
+
}) })
|
|
43803
44082
|
] });
|
|
43804
44083
|
};
|
|
43805
44084
|
ShowcaseOrganism.displayName = "ShowcaseOrganism";
|
|
@@ -44167,8 +44446,8 @@ function SimulatorBoard({
|
|
|
44167
44446
|
}) {
|
|
44168
44447
|
const { emit } = useEventBus();
|
|
44169
44448
|
const { t } = useTranslate();
|
|
44170
|
-
const resolved =
|
|
44171
|
-
const parameters = resolved?.parameters
|
|
44449
|
+
const resolved = boardEntity(entity);
|
|
44450
|
+
const parameters = Array.isArray(resolved?.parameters) ? resolved.parameters : [];
|
|
44172
44451
|
const [values, setValues] = useState(() => {
|
|
44173
44452
|
const init = {};
|
|
44174
44453
|
for (const p2 of parameters) {
|
|
@@ -44182,15 +44461,15 @@ function SimulatorBoard({
|
|
|
44182
44461
|
const [showHint, setShowHint] = useState(false);
|
|
44183
44462
|
const computeOutput = useCallback((params) => {
|
|
44184
44463
|
try {
|
|
44185
|
-
const fn = new Function("params", `return (${resolved?.computeExpression})`);
|
|
44464
|
+
const fn = new Function("params", `return (${str(resolved?.computeExpression)})`);
|
|
44186
44465
|
return fn(params);
|
|
44187
44466
|
} catch {
|
|
44188
44467
|
return 0;
|
|
44189
44468
|
}
|
|
44190
44469
|
}, [resolved?.computeExpression]);
|
|
44191
44470
|
const output = useMemo(() => computeOutput(values) ?? 0, [computeOutput, values]);
|
|
44192
|
-
const targetValue = resolved?.targetValue
|
|
44193
|
-
const targetTolerance = resolved?.targetTolerance
|
|
44471
|
+
const targetValue = num(resolved?.targetValue);
|
|
44472
|
+
const targetTolerance = num(resolved?.targetTolerance);
|
|
44194
44473
|
const isCorrect = Math.abs(output - targetValue) <= targetTolerance;
|
|
44195
44474
|
const handleParameterChange = (id, value) => {
|
|
44196
44475
|
if (submitted) return;
|
|
@@ -44205,7 +44484,7 @@ function SimulatorBoard({
|
|
|
44205
44484
|
};
|
|
44206
44485
|
const handleReset = () => {
|
|
44207
44486
|
setSubmitted(false);
|
|
44208
|
-
if (attempts >= 2 && resolved?.hint) {
|
|
44487
|
+
if (attempts >= 2 && str(resolved?.hint)) {
|
|
44209
44488
|
setShowHint(true);
|
|
44210
44489
|
}
|
|
44211
44490
|
};
|
|
@@ -44220,20 +44499,26 @@ function SimulatorBoard({
|
|
|
44220
44499
|
setShowHint(false);
|
|
44221
44500
|
};
|
|
44222
44501
|
if (!resolved) return null;
|
|
44502
|
+
const theme = resolved.theme ?? void 0;
|
|
44503
|
+
const themeBackground = theme?.background;
|
|
44504
|
+
const headerImage = str(resolved.headerImage);
|
|
44505
|
+
const hint = str(resolved.hint);
|
|
44506
|
+
const outputLabel = str(resolved.outputLabel);
|
|
44507
|
+
const outputUnit = str(resolved.outputUnit);
|
|
44223
44508
|
return /* @__PURE__ */ jsx(
|
|
44224
44509
|
Box,
|
|
44225
44510
|
{
|
|
44226
44511
|
className,
|
|
44227
44512
|
style: {
|
|
44228
|
-
backgroundImage:
|
|
44513
|
+
backgroundImage: themeBackground ? `url(${themeBackground})` : void 0,
|
|
44229
44514
|
backgroundSize: "cover",
|
|
44230
44515
|
backgroundPosition: "center"
|
|
44231
44516
|
},
|
|
44232
44517
|
children: /* @__PURE__ */ jsxs(VStack, { gap: "lg", className: "p-4", children: [
|
|
44233
|
-
|
|
44518
|
+
headerImage && !headerError ? /* @__PURE__ */ jsx(Box, { className: "w-full h-32 overflow-hidden rounded-container", children: /* @__PURE__ */ jsx("img", { src: headerImage, alt: "", onError: () => setHeaderError(true), className: "w-full h-full object-cover" }) }) : headerImage && headerError ? /* @__PURE__ */ jsx(Box, { className: "w-full h-32 rounded-container bg-gradient-to-br from-muted to-accent opacity-60" }) : null,
|
|
44234
44519
|
/* @__PURE__ */ jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxs(VStack, { gap: "sm", children: [
|
|
44235
|
-
/* @__PURE__ */ jsx(Typography, { variant: "h4", weight: "bold", children: resolved.title }),
|
|
44236
|
-
/* @__PURE__ */ jsx(Typography, { variant: "body", children: resolved.description })
|
|
44520
|
+
/* @__PURE__ */ jsx(Typography, { variant: "h4", weight: "bold", children: str(resolved.title) }),
|
|
44521
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body", children: str(resolved.description) })
|
|
44237
44522
|
] }) }),
|
|
44238
44523
|
/* @__PURE__ */ jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxs(VStack, { gap: "md", children: [
|
|
44239
44524
|
/* @__PURE__ */ jsx(Typography, { variant: "small", weight: "bold", className: "uppercase tracking-wider text-muted-foreground", children: t("simulator.parameters") }),
|
|
@@ -44274,28 +44559,28 @@ function SimulatorBoard({
|
|
|
44274
44559
|
] }, param.id))
|
|
44275
44560
|
] }) }),
|
|
44276
44561
|
/* @__PURE__ */ jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxs(VStack, { gap: "sm", align: "center", children: [
|
|
44277
|
-
/* @__PURE__ */ jsx(Typography, { variant: "small", weight: "bold", className: "uppercase tracking-wider text-muted-foreground", children:
|
|
44562
|
+
/* @__PURE__ */ jsx(Typography, { variant: "small", weight: "bold", className: "uppercase tracking-wider text-muted-foreground", children: outputLabel }),
|
|
44278
44563
|
/* @__PURE__ */ jsxs(Typography, { variant: "h3", weight: "bold", children: [
|
|
44279
44564
|
output.toFixed(2),
|
|
44280
44565
|
" ",
|
|
44281
|
-
|
|
44566
|
+
outputUnit
|
|
44282
44567
|
] }),
|
|
44283
44568
|
submitted && /* @__PURE__ */ jsxs(HStack, { gap: "xs", align: "center", children: [
|
|
44284
44569
|
/* @__PURE__ */ jsx(Icon, { icon: isCorrect ? CheckCircle : XCircle, size: "sm", className: isCorrect ? "text-success" : "text-error" }),
|
|
44285
|
-
/* @__PURE__ */ jsx(Typography, { variant: "body", className: isCorrect ? "text-success" : "text-error", children: isCorrect ? resolved.successMessage
|
|
44570
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body", className: isCorrect ? "text-success" : "text-error", children: isCorrect ? str(resolved.successMessage) || t("simulator.correct") : str(resolved.failMessage) || t("simulator.incorrect") })
|
|
44286
44571
|
] }),
|
|
44287
44572
|
/* @__PURE__ */ jsxs(Typography, { variant: "caption", className: "text-muted-foreground", children: [
|
|
44288
44573
|
t("simulator.target"),
|
|
44289
44574
|
": ",
|
|
44290
44575
|
targetValue,
|
|
44291
44576
|
" ",
|
|
44292
|
-
|
|
44577
|
+
outputUnit,
|
|
44293
44578
|
" (\xB1",
|
|
44294
44579
|
targetTolerance,
|
|
44295
44580
|
")"
|
|
44296
44581
|
] })
|
|
44297
44582
|
] }) }),
|
|
44298
|
-
showHint &&
|
|
44583
|
+
showHint && hint && /* @__PURE__ */ jsx(Card, { className: "p-4 border-l-4 border-l-warning", children: /* @__PURE__ */ jsx(Typography, { variant: "body", children: hint }) }),
|
|
44299
44584
|
/* @__PURE__ */ jsxs(HStack, { gap: "sm", justify: "center", children: [
|
|
44300
44585
|
!submitted ? /* @__PURE__ */ jsxs(Button, { variant: "primary", onClick: handleSubmit, children: [
|
|
44301
44586
|
/* @__PURE__ */ jsx(Icon, { icon: Play, size: "sm" }),
|
|
@@ -44314,6 +44599,7 @@ var init_SimulatorBoard = __esm({
|
|
|
44314
44599
|
"components/game/organisms/puzzles/simulator/SimulatorBoard.tsx"() {
|
|
44315
44600
|
init_atoms2();
|
|
44316
44601
|
init_useEventBus();
|
|
44602
|
+
init_boardEntity();
|
|
44317
44603
|
SimulatorBoard.displayName = "SimulatorBoard";
|
|
44318
44604
|
}
|
|
44319
44605
|
});
|
|
@@ -44556,7 +44842,7 @@ var init_StatCard = __esm({
|
|
|
44556
44842
|
const labelToUse = propLabel ?? propTitle;
|
|
44557
44843
|
const eventBus = useEventBus();
|
|
44558
44844
|
const { t } = useTranslate();
|
|
44559
|
-
const handleActionClick =
|
|
44845
|
+
const handleActionClick = React80__default.useCallback(() => {
|
|
44560
44846
|
if (action?.event) {
|
|
44561
44847
|
eventBus.emit(`UI:${action.event}`, {});
|
|
44562
44848
|
}
|
|
@@ -44567,7 +44853,7 @@ var init_StatCard = __esm({
|
|
|
44567
44853
|
const data = Array.isArray(entity) ? entity : entity ? [entity] : [];
|
|
44568
44854
|
const isLoading = externalLoading ?? false;
|
|
44569
44855
|
const error = externalError;
|
|
44570
|
-
const computeMetricValue =
|
|
44856
|
+
const computeMetricValue = React80__default.useCallback(
|
|
44571
44857
|
(metric, items) => {
|
|
44572
44858
|
if (metric.value !== void 0) {
|
|
44573
44859
|
return metric.value;
|
|
@@ -44606,7 +44892,7 @@ var init_StatCard = __esm({
|
|
|
44606
44892
|
},
|
|
44607
44893
|
[]
|
|
44608
44894
|
);
|
|
44609
|
-
const schemaStats =
|
|
44895
|
+
const schemaStats = React80__default.useMemo(() => {
|
|
44610
44896
|
if (!metrics || metrics.length === 0) return null;
|
|
44611
44897
|
return metrics.map((metric) => ({
|
|
44612
44898
|
label: metric.label,
|
|
@@ -44614,7 +44900,7 @@ var init_StatCard = __esm({
|
|
|
44614
44900
|
format: metric.format
|
|
44615
44901
|
}));
|
|
44616
44902
|
}, [metrics, data, computeMetricValue]);
|
|
44617
|
-
const calculatedTrend =
|
|
44903
|
+
const calculatedTrend = React80__default.useMemo(() => {
|
|
44618
44904
|
if (manualTrend !== void 0) return manualTrend;
|
|
44619
44905
|
if (previousValue === void 0 || currentValue === void 0)
|
|
44620
44906
|
return void 0;
|
|
@@ -44850,22 +45136,25 @@ function VariablePanel({
|
|
|
44850
45136
|
return /* @__PURE__ */ jsxs(VStack, { className: cn("p-3 rounded-lg bg-card border border-border", className), gap: "sm", children: [
|
|
44851
45137
|
/* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-muted-foreground font-medium", children: t("stateArchitect.variables", { name: entityName }) }),
|
|
44852
45138
|
variables.map((v) => {
|
|
44853
|
-
const
|
|
44854
|
-
const
|
|
44855
|
-
const
|
|
45139
|
+
const name = v.name == null ? "" : String(v.name);
|
|
45140
|
+
const value = numField(v.value);
|
|
45141
|
+
const max = numField(v.max, 100);
|
|
45142
|
+
const min = numField(v.min, 0);
|
|
45143
|
+
const unit = v.unit == null ? "" : String(v.unit);
|
|
45144
|
+
const pct = Math.round((value - min) / (max - min) * 100);
|
|
44856
45145
|
const isHigh = pct > 80;
|
|
44857
45146
|
const isLow = pct < 20;
|
|
44858
45147
|
return /* @__PURE__ */ jsxs(VStack, { gap: "none", children: [
|
|
44859
45148
|
/* @__PURE__ */ jsxs(HStack, { className: "items-center justify-between", children: [
|
|
44860
|
-
/* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-foreground font-medium", children:
|
|
45149
|
+
/* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-foreground font-medium", children: name }),
|
|
44861
45150
|
/* @__PURE__ */ jsxs(Typography, { variant: "caption", className: cn(
|
|
44862
45151
|
isHigh ? "text-error" : isLow ? "text-warning" : "text-foreground"
|
|
44863
45152
|
), children: [
|
|
44864
|
-
|
|
44865
|
-
|
|
45153
|
+
value,
|
|
45154
|
+
unit,
|
|
44866
45155
|
" / ",
|
|
44867
45156
|
max,
|
|
44868
|
-
|
|
45157
|
+
unit
|
|
44869
45158
|
] })
|
|
44870
45159
|
] }),
|
|
44871
45160
|
/* @__PURE__ */ jsx(
|
|
@@ -44876,14 +45165,19 @@ function VariablePanel({
|
|
|
44876
45165
|
size: "sm"
|
|
44877
45166
|
}
|
|
44878
45167
|
)
|
|
44879
|
-
] },
|
|
45168
|
+
] }, name);
|
|
44880
45169
|
})
|
|
44881
45170
|
] });
|
|
44882
45171
|
}
|
|
45172
|
+
var numField;
|
|
44883
45173
|
var init_VariablePanel = __esm({
|
|
44884
45174
|
"components/game/organisms/puzzles/state-architect/VariablePanel.tsx"() {
|
|
44885
45175
|
init_atoms2();
|
|
44886
45176
|
init_cn();
|
|
45177
|
+
numField = (v, fallback = 0) => {
|
|
45178
|
+
const n = Number(v);
|
|
45179
|
+
return Number.isFinite(n) ? n : fallback;
|
|
45180
|
+
};
|
|
44887
45181
|
VariablePanel.displayName = "VariablePanel";
|
|
44888
45182
|
}
|
|
44889
45183
|
});
|
|
@@ -44910,14 +45204,21 @@ function StateArchitectBoard({
|
|
|
44910
45204
|
}) {
|
|
44911
45205
|
const { emit } = useEventBus();
|
|
44912
45206
|
const { t } = useTranslate();
|
|
44913
|
-
const resolved =
|
|
44914
|
-
const
|
|
45207
|
+
const resolved = boardEntity(entity);
|
|
45208
|
+
const entityStates = Array.isArray(resolved?.states) ? resolved.states : [];
|
|
45209
|
+
const initialState = str(resolved?.initialState);
|
|
45210
|
+
const entityName = str(resolved?.entityName);
|
|
45211
|
+
const availableEvents = Array.isArray(resolved?.availableEvents) ? resolved.availableEvents : [];
|
|
45212
|
+
const testCases = Array.isArray(resolved?.testCases) ? resolved.testCases : [];
|
|
45213
|
+
const entityTransitions = Array.isArray(resolved?.transitions) ? resolved.transitions : [];
|
|
45214
|
+
const entityVariables = rows(resolved?.variables);
|
|
45215
|
+
const [transitions, setTransitions] = useState(entityTransitions);
|
|
44915
45216
|
const [headerError, setHeaderError] = useState(false);
|
|
44916
45217
|
const [playState, setPlayState] = useState("editing");
|
|
44917
|
-
const [currentState, setCurrentState] = useState(
|
|
45218
|
+
const [currentState, setCurrentState] = useState(initialState);
|
|
44918
45219
|
const [selectedState, setSelectedState] = useState(null);
|
|
44919
45220
|
const [testResults, setTestResults] = useState([]);
|
|
44920
|
-
const [variables, setVariables] = useState(
|
|
45221
|
+
const [variables, setVariables] = useState(() => [...entityVariables]);
|
|
44921
45222
|
const [attempts, setAttempts] = useState(0);
|
|
44922
45223
|
const timerRef = useRef(null);
|
|
44923
45224
|
const [addingFrom, setAddingFrom] = useState(null);
|
|
@@ -44926,12 +45227,12 @@ function StateArchitectBoard({
|
|
|
44926
45227
|
}, []);
|
|
44927
45228
|
const GRAPH_W = 500;
|
|
44928
45229
|
const GRAPH_H = 400;
|
|
44929
|
-
const positions = useMemo(() => layoutStates(
|
|
45230
|
+
const positions = useMemo(() => layoutStates(entityStates, GRAPH_W, GRAPH_H), [entityStates]);
|
|
44930
45231
|
const handleStateClick = useCallback((state) => {
|
|
44931
45232
|
if (playState !== "editing") return;
|
|
44932
45233
|
if (addingFrom) {
|
|
44933
45234
|
if (addingFrom !== state) {
|
|
44934
|
-
const event =
|
|
45235
|
+
const event = availableEvents[0] || "EVENT";
|
|
44935
45236
|
const newTrans = {
|
|
44936
45237
|
id: `t-${nextTransId++}`,
|
|
44937
45238
|
from: addingFrom,
|
|
@@ -44944,7 +45245,7 @@ function StateArchitectBoard({
|
|
|
44944
45245
|
} else {
|
|
44945
45246
|
setSelectedState(state);
|
|
44946
45247
|
}
|
|
44947
|
-
}, [playState, addingFrom,
|
|
45248
|
+
}, [playState, addingFrom, availableEvents]);
|
|
44948
45249
|
const handleStartAddTransition = useCallback(() => {
|
|
44949
45250
|
if (!selectedState) return;
|
|
44950
45251
|
setAddingFrom(selectedState);
|
|
@@ -44953,9 +45254,9 @@ function StateArchitectBoard({
|
|
|
44953
45254
|
setTransitions((prev) => prev.filter((t2) => t2.id !== transId));
|
|
44954
45255
|
}, []);
|
|
44955
45256
|
const machine = useMemo(() => ({
|
|
44956
|
-
name:
|
|
44957
|
-
description: resolved?.description
|
|
44958
|
-
states:
|
|
45257
|
+
name: entityName,
|
|
45258
|
+
description: str(resolved?.description),
|
|
45259
|
+
states: entityStates,
|
|
44959
45260
|
currentState,
|
|
44960
45261
|
transitions: transitions.map((t2) => ({
|
|
44961
45262
|
from: t2.from,
|
|
@@ -44963,7 +45264,7 @@ function StateArchitectBoard({
|
|
|
44963
45264
|
event: t2.event,
|
|
44964
45265
|
guardHint: t2.guardHint
|
|
44965
45266
|
}))
|
|
44966
|
-
}), [resolved, currentState, transitions]);
|
|
45267
|
+
}), [entityName, resolved, entityStates, currentState, transitions]);
|
|
44967
45268
|
const handleTest = useCallback(() => {
|
|
44968
45269
|
if (playState !== "editing") return;
|
|
44969
45270
|
if (testEvent) emit(`UI:${testEvent}`, {});
|
|
@@ -44972,7 +45273,7 @@ function StateArchitectBoard({
|
|
|
44972
45273
|
const results = [];
|
|
44973
45274
|
let testIdx = 0;
|
|
44974
45275
|
const runNextTest = () => {
|
|
44975
|
-
if (testIdx >=
|
|
45276
|
+
if (testIdx >= testCases.length) {
|
|
44976
45277
|
const allPassed = results.every((r) => r.passed);
|
|
44977
45278
|
setPlayState(allPassed ? "success" : "fail");
|
|
44978
45279
|
setTestResults(results);
|
|
@@ -44987,9 +45288,9 @@ function StateArchitectBoard({
|
|
|
44987
45288
|
}
|
|
44988
45289
|
return;
|
|
44989
45290
|
}
|
|
44990
|
-
const testCase =
|
|
45291
|
+
const testCase = testCases[testIdx];
|
|
44991
45292
|
if (!testCase) return;
|
|
44992
|
-
let state =
|
|
45293
|
+
let state = initialState;
|
|
44993
45294
|
for (const event of testCase.events) {
|
|
44994
45295
|
const trans = transitions.find((t2) => t2.from === state && t2.event === event);
|
|
44995
45296
|
if (trans) {
|
|
@@ -45007,53 +45308,57 @@ function StateArchitectBoard({
|
|
|
45007
45308
|
timerRef.current = setTimeout(runNextTest, stepDurationMs);
|
|
45008
45309
|
};
|
|
45009
45310
|
timerRef.current = setTimeout(runNextTest, stepDurationMs);
|
|
45010
|
-
}, [playState, transitions,
|
|
45311
|
+
}, [playState, transitions, testCases, initialState, stepDurationMs, testEvent, completeEvent, emit]);
|
|
45011
45312
|
const handleTryAgain = useCallback(() => {
|
|
45012
45313
|
if (timerRef.current) clearTimeout(timerRef.current);
|
|
45013
45314
|
setPlayState("editing");
|
|
45014
|
-
setCurrentState(
|
|
45315
|
+
setCurrentState(initialState);
|
|
45015
45316
|
setTestResults([]);
|
|
45016
|
-
}, [
|
|
45317
|
+
}, [initialState]);
|
|
45017
45318
|
const handleReset = useCallback(() => {
|
|
45018
45319
|
if (timerRef.current) clearTimeout(timerRef.current);
|
|
45019
|
-
setTransitions(
|
|
45320
|
+
setTransitions(entityTransitions);
|
|
45020
45321
|
setPlayState("editing");
|
|
45021
|
-
setCurrentState(
|
|
45322
|
+
setCurrentState(initialState);
|
|
45022
45323
|
setTestResults([]);
|
|
45023
|
-
setVariables(
|
|
45324
|
+
setVariables([...entityVariables]);
|
|
45024
45325
|
setSelectedState(null);
|
|
45025
45326
|
setAddingFrom(null);
|
|
45026
45327
|
setAttempts(0);
|
|
45027
|
-
}, [
|
|
45328
|
+
}, [entityTransitions, initialState, entityVariables]);
|
|
45028
45329
|
const codeData = useMemo(() => ({
|
|
45029
|
-
name:
|
|
45030
|
-
states:
|
|
45031
|
-
initialState
|
|
45330
|
+
name: entityName,
|
|
45331
|
+
states: entityStates,
|
|
45332
|
+
initialState,
|
|
45032
45333
|
transitions: transitions.map((t2) => ({
|
|
45033
45334
|
from: t2.from,
|
|
45034
45335
|
to: t2.to,
|
|
45035
45336
|
event: t2.event,
|
|
45036
45337
|
...t2.guardHint ? { guard: t2.guardHint } : {}
|
|
45037
45338
|
}))
|
|
45038
|
-
}), [
|
|
45339
|
+
}), [entityName, entityStates, initialState, transitions]);
|
|
45039
45340
|
if (!resolved) return null;
|
|
45341
|
+
const theme = resolved.theme ?? void 0;
|
|
45342
|
+
const themeBackground = theme?.background;
|
|
45343
|
+
const headerImage = str(resolved.headerImage);
|
|
45344
|
+
const hint = str(resolved.hint);
|
|
45040
45345
|
return /* @__PURE__ */ jsxs(
|
|
45041
45346
|
VStack,
|
|
45042
45347
|
{
|
|
45043
45348
|
className: cn("p-4 gap-6", className),
|
|
45044
45349
|
style: {
|
|
45045
|
-
backgroundImage:
|
|
45350
|
+
backgroundImage: themeBackground ? `url(${themeBackground})` : void 0,
|
|
45046
45351
|
backgroundSize: "cover",
|
|
45047
45352
|
backgroundPosition: "center"
|
|
45048
45353
|
},
|
|
45049
45354
|
children: [
|
|
45050
|
-
|
|
45355
|
+
headerImage && !headerError ? /* @__PURE__ */ jsx(Box, { className: "w-full h-32 overflow-hidden rounded-container", children: /* @__PURE__ */ jsx("img", { src: headerImage, alt: "", onError: () => setHeaderError(true), className: "w-full h-full object-cover" }) }) : headerImage && headerError ? /* @__PURE__ */ jsx(Box, { className: "w-full h-32 rounded-container bg-gradient-to-br from-muted to-accent opacity-60" }) : null,
|
|
45051
45356
|
/* @__PURE__ */ jsxs(VStack, { gap: "xs", children: [
|
|
45052
|
-
/* @__PURE__ */ jsx(Typography, { variant: "h4", className: "text-foreground", children: resolved.title }),
|
|
45053
|
-
/* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-muted-foreground", children: resolved.description }),
|
|
45357
|
+
/* @__PURE__ */ jsx(Typography, { variant: "h4", className: "text-foreground", children: str(resolved.title) }),
|
|
45358
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-muted-foreground", children: str(resolved.description) }),
|
|
45054
45359
|
/* @__PURE__ */ jsxs(HStack, { className: "items-center p-2 rounded bg-warning/10 border border-warning/30", gap: "xs", children: [
|
|
45055
45360
|
/* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-warning font-bold", children: t("game.hint") + ":" }),
|
|
45056
|
-
/* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-foreground", children:
|
|
45361
|
+
/* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-foreground", children: hint })
|
|
45057
45362
|
] })
|
|
45058
45363
|
] }),
|
|
45059
45364
|
/* @__PURE__ */ jsxs(HStack, { className: "flex-wrap items-start", gap: "lg", children: [
|
|
@@ -45101,14 +45406,14 @@ function StateArchitectBoard({
|
|
|
45101
45406
|
]
|
|
45102
45407
|
}
|
|
45103
45408
|
),
|
|
45104
|
-
|
|
45409
|
+
entityStates.map((state) => /* @__PURE__ */ jsx(
|
|
45105
45410
|
StateNode2,
|
|
45106
45411
|
{
|
|
45107
45412
|
name: state,
|
|
45108
45413
|
position: positions[state],
|
|
45109
45414
|
isCurrent: state === currentState,
|
|
45110
45415
|
isSelected: state === selectedState,
|
|
45111
|
-
isInitial: state ===
|
|
45416
|
+
isInitial: state === initialState,
|
|
45112
45417
|
onClick: () => handleStateClick(state)
|
|
45113
45418
|
},
|
|
45114
45419
|
state
|
|
@@ -45155,7 +45460,7 @@ function StateArchitectBoard({
|
|
|
45155
45460
|
/* @__PURE__ */ jsx(
|
|
45156
45461
|
VariablePanel,
|
|
45157
45462
|
{
|
|
45158
|
-
entityName
|
|
45463
|
+
entityName,
|
|
45159
45464
|
variables
|
|
45160
45465
|
}
|
|
45161
45466
|
),
|
|
@@ -45170,12 +45475,12 @@ function StateArchitectBoard({
|
|
|
45170
45475
|
resolved.showCodeView !== false && /* @__PURE__ */ jsx(CodeView, { data: codeData, label: "View Code" })
|
|
45171
45476
|
] })
|
|
45172
45477
|
] }),
|
|
45173
|
-
playState === "success" && /* @__PURE__ */ jsx(Box, { className: "p-4 rounded-container bg-success/20 border border-success text-center", children: /* @__PURE__ */ jsx(Typography, { variant: "h5", className: "text-success", children: resolved.successMessage || t("stateArchitect.allPassed") }) }),
|
|
45478
|
+
playState === "success" && /* @__PURE__ */ jsx(Box, { className: "p-4 rounded-container bg-success/20 border border-success text-center", children: /* @__PURE__ */ jsx(Typography, { variant: "h5", className: "text-success", children: str(resolved.successMessage) || t("stateArchitect.allPassed") }) }),
|
|
45174
45479
|
playState === "fail" && /* @__PURE__ */ jsxs(VStack, { gap: "sm", children: [
|
|
45175
45480
|
/* @__PURE__ */ jsx(Box, { className: "p-4 rounded-container bg-warning/10 border border-warning/30 text-center", children: /* @__PURE__ */ jsx(Typography, { variant: "body1", className: "text-foreground font-medium", children: t(ENCOURAGEMENT_KEYS3[Math.min(attempts - 1, ENCOURAGEMENT_KEYS3.length - 1)] ?? ENCOURAGEMENT_KEYS3[0]) }) }),
|
|
45176
|
-
attempts >= 3 &&
|
|
45481
|
+
attempts >= 3 && hint && /* @__PURE__ */ jsx(Box, { className: "p-3 rounded-container bg-accent/10 border border-accent/30", children: /* @__PURE__ */ jsxs(HStack, { className: "items-start", gap: "xs", children: [
|
|
45177
45482
|
/* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-accent font-bold shrink-0", children: "\u{1F4A1} " + t("game.hint") + ":" }),
|
|
45178
|
-
/* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-foreground", children:
|
|
45483
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-foreground", children: hint })
|
|
45179
45484
|
] }) })
|
|
45180
45485
|
] }),
|
|
45181
45486
|
/* @__PURE__ */ jsxs(HStack, { gap: "sm", children: [
|
|
@@ -45205,6 +45510,7 @@ var init_StateArchitectBoard = __esm({
|
|
|
45205
45510
|
init_TransitionArrow();
|
|
45206
45511
|
init_VariablePanel();
|
|
45207
45512
|
init_CodeView();
|
|
45513
|
+
init_boardEntity();
|
|
45208
45514
|
ENCOURAGEMENT_KEYS3 = [
|
|
45209
45515
|
"puzzle.tryAgain1",
|
|
45210
45516
|
"puzzle.tryAgain2",
|
|
@@ -45241,8 +45547,8 @@ var init_StatsOrganism = __esm({
|
|
|
45241
45547
|
return /* @__PURE__ */ jsx(ErrorState, { message: error.message, className });
|
|
45242
45548
|
}
|
|
45243
45549
|
const stats = items.map((item) => ({
|
|
45244
|
-
value: item.value,
|
|
45245
|
-
label: item.label
|
|
45550
|
+
value: String(item.value ?? ""),
|
|
45551
|
+
label: String(item.label ?? "")
|
|
45246
45552
|
}));
|
|
45247
45553
|
return /* @__PURE__ */ jsx(
|
|
45248
45554
|
StatsGrid,
|
|
@@ -45359,10 +45665,10 @@ var init_StepFlowOrganism = __esm({
|
|
|
45359
45665
|
return /* @__PURE__ */ jsx(ErrorState, { message: error.message, className });
|
|
45360
45666
|
}
|
|
45361
45667
|
const steps = items.map((item) => ({
|
|
45362
|
-
number: item.number,
|
|
45363
|
-
title: item.title,
|
|
45364
|
-
description: item.description,
|
|
45365
|
-
icon: item.icon
|
|
45668
|
+
number: item.number != null ? Number(item.number) : void 0,
|
|
45669
|
+
title: String(item.title ?? ""),
|
|
45670
|
+
description: String(item.description ?? ""),
|
|
45671
|
+
icon: item.icon != null ? String(item.icon) : void 0
|
|
45366
45672
|
}));
|
|
45367
45673
|
return /* @__PURE__ */ jsxs(VStack, { gap: "lg", className: cn("w-full", className), children: [
|
|
45368
45674
|
(heading || subtitle) && /* @__PURE__ */ jsxs(VStack, { gap: "sm", align: "center", className: "w-full", children: [
|
|
@@ -45535,13 +45841,13 @@ var init_TeamOrganism = __esm({
|
|
|
45535
45841
|
/* @__PURE__ */ jsx(SimpleGrid, { cols: cols > 0 ? cols : 1, gap: "lg", children: items.map((member) => /* @__PURE__ */ jsx(
|
|
45536
45842
|
TeamCard,
|
|
45537
45843
|
{
|
|
45538
|
-
name: member.name,
|
|
45539
|
-
nameAr: member.nameAr,
|
|
45540
|
-
role: member.role,
|
|
45541
|
-
bio: member.bio,
|
|
45542
|
-
avatar: member.avatar
|
|
45844
|
+
name: String(member.name ?? ""),
|
|
45845
|
+
nameAr: member.nameAr != null ? String(member.nameAr) : void 0,
|
|
45846
|
+
role: String(member.role ?? ""),
|
|
45847
|
+
bio: String(member.bio ?? ""),
|
|
45848
|
+
avatar: member.avatar != null ? String(member.avatar) : void 0
|
|
45543
45849
|
},
|
|
45544
|
-
member.id
|
|
45850
|
+
String(member.id ?? "")
|
|
45545
45851
|
)) })
|
|
45546
45852
|
] });
|
|
45547
45853
|
};
|
|
@@ -45599,7 +45905,7 @@ var init_Timeline = __esm({
|
|
|
45599
45905
|
}) => {
|
|
45600
45906
|
const { t } = useTranslate();
|
|
45601
45907
|
const entityData = Array.isArray(entity) ? entity : [];
|
|
45602
|
-
const items =
|
|
45908
|
+
const items = React80__default.useMemo(() => {
|
|
45603
45909
|
if (propItems) return propItems;
|
|
45604
45910
|
if (entityData.length === 0) return [];
|
|
45605
45911
|
return entityData.map((record, idx) => {
|
|
@@ -45756,7 +46062,7 @@ var init_TimerDisplay = __esm({
|
|
|
45756
46062
|
}
|
|
45757
46063
|
});
|
|
45758
46064
|
function extractToastProps(children) {
|
|
45759
|
-
if (!
|
|
46065
|
+
if (!React80__default.isValidElement(children)) {
|
|
45760
46066
|
if (typeof children === "string") {
|
|
45761
46067
|
return { message: children };
|
|
45762
46068
|
}
|
|
@@ -45794,7 +46100,7 @@ var init_ToastSlot = __esm({
|
|
|
45794
46100
|
eventBus.emit("UI:CLOSE");
|
|
45795
46101
|
};
|
|
45796
46102
|
if (!isVisible) return null;
|
|
45797
|
-
const isCustomContent =
|
|
46103
|
+
const isCustomContent = React80__default.isValidElement(children) && !message;
|
|
45798
46104
|
return /* @__PURE__ */ jsx(Box, { className: "fixed bottom-4 right-4 z-50", children: isCustomContent ? children : /* @__PURE__ */ jsx(
|
|
45799
46105
|
Toast,
|
|
45800
46106
|
{
|
|
@@ -45828,8 +46134,8 @@ function useBattleState(initialUnits, eventConfig = {}, callbacks = {}) {
|
|
|
45828
46134
|
const [turn, setTurn] = useState(1);
|
|
45829
46135
|
const [gameResult, setGameResult] = useState(null);
|
|
45830
46136
|
const checkGameEnd = useCallback((currentUnits) => {
|
|
45831
|
-
const pa = currentUnits.filter((u) => u
|
|
45832
|
-
const ea = currentUnits.filter((u) => u
|
|
46137
|
+
const pa = currentUnits.filter((u) => unitTeam(u) === "player" && unitHealth(u) > 0);
|
|
46138
|
+
const ea = currentUnits.filter((u) => unitTeam(u) === "enemy" && unitHealth(u) > 0);
|
|
45833
46139
|
if (pa.length === 0) {
|
|
45834
46140
|
setGameResult("defeat");
|
|
45835
46141
|
setPhase("game_over");
|
|
@@ -45847,34 +46153,36 @@ function useBattleState(initialUnits, eventConfig = {}, callbacks = {}) {
|
|
|
45847
46153
|
}
|
|
45848
46154
|
}, [onGameEnd, gameEndEvent, eventBus]);
|
|
45849
46155
|
const handleUnitClick = useCallback((unitId) => {
|
|
45850
|
-
const unit = units.find((u) => u.id === unitId);
|
|
46156
|
+
const unit = units.find((u) => str(u.id) === unitId);
|
|
45851
46157
|
if (!unit) return;
|
|
45852
46158
|
if (unitClickEvent) {
|
|
45853
46159
|
eventBus.emit(`UI:${unitClickEvent}`, { unitId });
|
|
45854
46160
|
}
|
|
45855
46161
|
if (phase === "observation" || phase === "selection") {
|
|
45856
|
-
if (unit
|
|
46162
|
+
if (unitTeam(unit) === "player") {
|
|
45857
46163
|
setSelectedUnitId(unitId);
|
|
45858
46164
|
setPhase("movement");
|
|
45859
46165
|
}
|
|
45860
46166
|
} else if (phase === "action") {
|
|
45861
|
-
const selectedUnit = units.find((u) => u.id === selectedUnitId);
|
|
46167
|
+
const selectedUnit = units.find((u) => str(u.id) === selectedUnitId);
|
|
45862
46168
|
if (!selectedUnit) return;
|
|
45863
|
-
if (unit
|
|
45864
|
-
const
|
|
45865
|
-
const
|
|
46169
|
+
if (unitTeam(unit) === "enemy") {
|
|
46170
|
+
const up = unitPosition(unit);
|
|
46171
|
+
const sp = unitPosition(selectedUnit);
|
|
46172
|
+
const dx = Math.abs(up.x - sp.x);
|
|
46173
|
+
const dy = Math.abs(up.y - sp.y);
|
|
45866
46174
|
if (dx <= 1 && dy <= 1 && dx + dy > 0) {
|
|
45867
|
-
const damage = calculateDamage2 ? calculateDamage2(selectedUnit, unit) : Math.max(1, selectedUnit.attack - unit.defense);
|
|
45868
|
-
const newHealth = Math.max(0, unit
|
|
46175
|
+
const damage = calculateDamage2 ? calculateDamage2(selectedUnit, unit) : Math.max(1, num(selectedUnit.attack) - num(unit.defense));
|
|
46176
|
+
const newHealth = Math.max(0, unitHealth(unit) - damage);
|
|
45869
46177
|
const updatedUnits = units.map(
|
|
45870
|
-
(u) => u.id === unit.id ? { ...u, health: newHealth } : u
|
|
46178
|
+
(u) => str(u.id) === str(unit.id) ? { ...u, health: newHealth } : u
|
|
45871
46179
|
);
|
|
45872
46180
|
setUnits(updatedUnits);
|
|
45873
46181
|
onAttack?.(selectedUnit, unit, damage);
|
|
45874
46182
|
if (attackEvent) {
|
|
45875
46183
|
eventBus.emit(`UI:${attackEvent}`, {
|
|
45876
|
-
attackerId: selectedUnit.id,
|
|
45877
|
-
targetId: unit.id,
|
|
46184
|
+
attackerId: str(selectedUnit.id),
|
|
46185
|
+
targetId: str(unit.id),
|
|
45878
46186
|
damage
|
|
45879
46187
|
});
|
|
45880
46188
|
}
|
|
@@ -45891,16 +46199,20 @@ function useBattleState(initialUnits, eventConfig = {}, callbacks = {}) {
|
|
|
45891
46199
|
eventBus.emit(`UI:${tileClickEvent}`, { x, y });
|
|
45892
46200
|
}
|
|
45893
46201
|
if (phase === "movement" && selectedUnitId) {
|
|
45894
|
-
const selectedUnit = units.find((u) => u.id === selectedUnitId);
|
|
46202
|
+
const selectedUnit = units.find((u) => str(u.id) === selectedUnitId);
|
|
45895
46203
|
if (!selectedUnit) return;
|
|
45896
|
-
const
|
|
45897
|
-
const
|
|
46204
|
+
const sp = unitPosition(selectedUnit);
|
|
46205
|
+
const dx = Math.abs(x - sp.x);
|
|
46206
|
+
const dy = Math.abs(y - sp.y);
|
|
45898
46207
|
const dist = dx + dy;
|
|
45899
|
-
if (dist > 0 && dist <= selectedUnit.movement) {
|
|
45900
|
-
if (!units.some((u) =>
|
|
46208
|
+
if (dist > 0 && dist <= num(selectedUnit.movement)) {
|
|
46209
|
+
if (!units.some((u) => {
|
|
46210
|
+
const p2 = unitPosition(u);
|
|
46211
|
+
return p2.x === x && p2.y === y && unitHealth(u) > 0;
|
|
46212
|
+
})) {
|
|
45901
46213
|
setUnits(
|
|
45902
46214
|
(prev) => prev.map(
|
|
45903
|
-
(u) => u.id === selectedUnitId ? { ...u, position: { x, y } } : u
|
|
46215
|
+
(u) => str(u.id) === selectedUnitId ? { ...u, position: { x, y } } : u
|
|
45904
46216
|
)
|
|
45905
46217
|
);
|
|
45906
46218
|
setPhase("action");
|
|
@@ -45943,12 +46255,13 @@ var init_useBattleState = __esm({
|
|
|
45943
46255
|
"components/game/organisms/hooks/useBattleState.ts"() {
|
|
45944
46256
|
"use client";
|
|
45945
46257
|
init_useEventBus();
|
|
46258
|
+
init_boardEntity();
|
|
45946
46259
|
}
|
|
45947
46260
|
});
|
|
45948
46261
|
function UncontrolledBattleBoard({ entity, ...rest }) {
|
|
45949
|
-
const resolved =
|
|
46262
|
+
const resolved = boardEntity(entity);
|
|
45950
46263
|
const battleState = useBattleState(
|
|
45951
|
-
resolved?.initialUnits
|
|
46264
|
+
rows(resolved?.initialUnits),
|
|
45952
46265
|
{
|
|
45953
46266
|
tileClickEvent: rest.tileClickEvent,
|
|
45954
46267
|
unitClickEvent: rest.unitClickEvent,
|
|
@@ -45984,10 +46297,23 @@ function UncontrolledBattleBoard({ entity, ...rest }) {
|
|
|
45984
46297
|
var init_UncontrolledBattleBoard = __esm({
|
|
45985
46298
|
"components/game/organisms/UncontrolledBattleBoard.tsx"() {
|
|
45986
46299
|
init_BattleBoard();
|
|
46300
|
+
init_boardEntity();
|
|
45987
46301
|
init_useBattleState();
|
|
45988
46302
|
UncontrolledBattleBoard.displayName = "UncontrolledBattleBoard";
|
|
45989
46303
|
}
|
|
45990
46304
|
});
|
|
46305
|
+
function heroPosition(h) {
|
|
46306
|
+
return vec2(h.position);
|
|
46307
|
+
}
|
|
46308
|
+
function heroOwner(h) {
|
|
46309
|
+
return str(h.owner);
|
|
46310
|
+
}
|
|
46311
|
+
function heroMovement(h) {
|
|
46312
|
+
return num(h.movement);
|
|
46313
|
+
}
|
|
46314
|
+
function hexPassable(h) {
|
|
46315
|
+
return h.passable !== false;
|
|
46316
|
+
}
|
|
45991
46317
|
function defaultIsInRange(from, to, range) {
|
|
45992
46318
|
return Math.abs(from.x - to.x) + Math.abs(from.y - to.y) <= range;
|
|
45993
46319
|
}
|
|
@@ -46018,36 +46344,36 @@ function WorldMapBoard({
|
|
|
46018
46344
|
className
|
|
46019
46345
|
}) {
|
|
46020
46346
|
const eventBus = useEventBus();
|
|
46021
|
-
const resolved =
|
|
46022
|
-
const hexes = resolved?.hexes
|
|
46023
|
-
const heroes = resolved?.heroes
|
|
46024
|
-
const features = resolved?.features
|
|
46025
|
-
const selectedHeroId = resolved?.selectedHeroId;
|
|
46347
|
+
const resolved = boardEntity(entity);
|
|
46348
|
+
const hexes = rows(resolved?.hexes);
|
|
46349
|
+
const heroes = rows(resolved?.heroes);
|
|
46350
|
+
const features = Array.isArray(resolved?.features) ? resolved.features : [];
|
|
46351
|
+
const selectedHeroId = resolved?.selectedHeroId ?? null;
|
|
46026
46352
|
const assetManifest = resolved?.assetManifest;
|
|
46027
46353
|
const backgroundImage = resolved?.backgroundImage;
|
|
46028
46354
|
const [hoveredTile, setHoveredTile] = useState(null);
|
|
46029
46355
|
const selectedHero = useMemo(
|
|
46030
|
-
() => heroes.find((h) => h.id === selectedHeroId) ?? null,
|
|
46356
|
+
() => heroes.find((h) => str(h.id) === selectedHeroId) ?? null,
|
|
46031
46357
|
[heroes, selectedHeroId]
|
|
46032
46358
|
);
|
|
46033
46359
|
const tiles = useMemo(
|
|
46034
46360
|
() => hexes.map((hex) => ({
|
|
46035
|
-
x: hex.x,
|
|
46036
|
-
y: hex.y,
|
|
46037
|
-
terrain: hex.terrain,
|
|
46038
|
-
terrainSprite: hex.terrainSprite
|
|
46361
|
+
x: num(hex.x),
|
|
46362
|
+
y: num(hex.y),
|
|
46363
|
+
terrain: str(hex.terrain),
|
|
46364
|
+
terrainSprite: hex.terrainSprite == null ? void 0 : str(hex.terrainSprite)
|
|
46039
46365
|
})),
|
|
46040
46366
|
[hexes]
|
|
46041
46367
|
);
|
|
46042
46368
|
const baseUnits = useMemo(
|
|
46043
46369
|
() => heroes.map((hero) => ({
|
|
46044
|
-
id: hero.id,
|
|
46045
|
-
position: hero
|
|
46046
|
-
name: hero.name,
|
|
46047
|
-
team: hero
|
|
46370
|
+
id: str(hero.id),
|
|
46371
|
+
position: heroPosition(hero),
|
|
46372
|
+
name: str(hero.name),
|
|
46373
|
+
team: heroOwner(hero) === "enemy" ? "enemy" : "player",
|
|
46048
46374
|
health: 100,
|
|
46049
46375
|
maxHealth: 100,
|
|
46050
|
-
sprite: hero.sprite
|
|
46376
|
+
sprite: hero.sprite == null ? void 0 : str(hero.sprite)
|
|
46051
46377
|
})),
|
|
46052
46378
|
[heroes]
|
|
46053
46379
|
);
|
|
@@ -46088,73 +46414,94 @@ function WorldMapBoard({
|
|
|
46088
46414
|
const isoUnits = useMemo(() => {
|
|
46089
46415
|
if (movingPositions.size === 0) return baseUnits;
|
|
46090
46416
|
return baseUnits.map((u) => {
|
|
46091
|
-
const pos = movingPositions.get(u.id);
|
|
46417
|
+
const pos = u.id == null ? void 0 : movingPositions.get(u.id);
|
|
46092
46418
|
return pos ? { ...u, position: pos } : u;
|
|
46093
46419
|
});
|
|
46094
46420
|
}, [baseUnits, movingPositions]);
|
|
46095
46421
|
const validMoves = useMemo(() => {
|
|
46096
|
-
if (!selectedHero || selectedHero
|
|
46422
|
+
if (!selectedHero || heroMovement(selectedHero) <= 0) return [];
|
|
46423
|
+
const sp = heroPosition(selectedHero);
|
|
46424
|
+
const sOwner = heroOwner(selectedHero);
|
|
46425
|
+
const range = heroMovement(selectedHero);
|
|
46097
46426
|
const moves = [];
|
|
46098
46427
|
hexes.forEach((hex) => {
|
|
46099
|
-
|
|
46100
|
-
|
|
46101
|
-
if (!
|
|
46102
|
-
if (
|
|
46103
|
-
|
|
46428
|
+
const hx = num(hex.x);
|
|
46429
|
+
const hy = num(hex.y);
|
|
46430
|
+
if (!hexPassable(hex)) return;
|
|
46431
|
+
if (hx === sp.x && hy === sp.y) return;
|
|
46432
|
+
if (!isInRange(sp, { x: hx, y: hy }, range)) return;
|
|
46433
|
+
if (heroes.some((h) => {
|
|
46434
|
+
const hp = heroPosition(h);
|
|
46435
|
+
return hp.x === hx && hp.y === hy && heroOwner(h) === sOwner;
|
|
46436
|
+
})) return;
|
|
46437
|
+
moves.push({ x: hx, y: hy });
|
|
46104
46438
|
});
|
|
46105
46439
|
return moves;
|
|
46106
46440
|
}, [selectedHero, hexes, heroes, isInRange]);
|
|
46107
46441
|
const attackTargets = useMemo(() => {
|
|
46108
|
-
if (!selectedHero || selectedHero
|
|
46109
|
-
|
|
46442
|
+
if (!selectedHero || heroMovement(selectedHero) <= 0) return [];
|
|
46443
|
+
const sp = heroPosition(selectedHero);
|
|
46444
|
+
const sOwner = heroOwner(selectedHero);
|
|
46445
|
+
const range = heroMovement(selectedHero);
|
|
46446
|
+
return heroes.filter((h) => heroOwner(h) !== sOwner).filter((h) => isInRange(sp, heroPosition(h), range)).map((h) => heroPosition(h));
|
|
46110
46447
|
}, [selectedHero, heroes, isInRange]);
|
|
46111
|
-
const maxY = Math.max(...hexes.map((h) => h.y), 0);
|
|
46448
|
+
const maxY = Math.max(...hexes.map((h) => num(h.y)), 0);
|
|
46112
46449
|
const baseOffsetX = (maxY + 1) * (TILE_WIDTH * scale / 2);
|
|
46113
46450
|
const tileToScreen = useCallback(
|
|
46114
46451
|
(tx, ty) => isoToScreen(tx, ty, scale, baseOffsetX),
|
|
46115
46452
|
[scale, baseOffsetX]
|
|
46116
46453
|
);
|
|
46117
46454
|
const hoveredHex = useMemo(
|
|
46118
|
-
() => hoveredTile ? hexes.find((h) => h.x === hoveredTile.x && h.y === hoveredTile.y) ?? null : null,
|
|
46455
|
+
() => hoveredTile ? hexes.find((h) => num(h.x) === hoveredTile.x && num(h.y) === hoveredTile.y) ?? null : null,
|
|
46119
46456
|
[hoveredTile, hexes]
|
|
46120
46457
|
);
|
|
46121
46458
|
const hoveredHero = useMemo(
|
|
46122
|
-
() => hoveredTile ? heroes.find((h) =>
|
|
46459
|
+
() => hoveredTile ? heroes.find((h) => {
|
|
46460
|
+
const hp = heroPosition(h);
|
|
46461
|
+
return hp.x === hoveredTile.x && hp.y === hoveredTile.y;
|
|
46462
|
+
}) ?? null : null,
|
|
46123
46463
|
[hoveredTile, heroes]
|
|
46124
46464
|
);
|
|
46125
46465
|
const handleTileClick = useCallback((x, y) => {
|
|
46126
46466
|
if (movementAnimRef.current) return;
|
|
46127
|
-
const hex = hexes.find((h) => h.x === x && h.y === y);
|
|
46467
|
+
const hex = hexes.find((h) => num(h.x) === x && num(h.y) === y);
|
|
46128
46468
|
if (!hex) return;
|
|
46129
46469
|
if (tileClickEvent) {
|
|
46130
46470
|
eventBus.emit(`UI:${tileClickEvent}`, { x, y });
|
|
46131
46471
|
}
|
|
46132
46472
|
if (selectedHero && validMoves.some((m) => m.x === x && m.y === y)) {
|
|
46133
|
-
|
|
46134
|
-
|
|
46473
|
+
const heroId = str(selectedHero.id);
|
|
46474
|
+
startMoveAnimation(heroId, { ...heroPosition(selectedHero) }, { x, y }, () => {
|
|
46475
|
+
onHeroMove?.(heroId, x, y);
|
|
46135
46476
|
if (heroMoveEvent) {
|
|
46136
|
-
eventBus.emit(`UI:${heroMoveEvent}`, { heroId
|
|
46477
|
+
eventBus.emit(`UI:${heroMoveEvent}`, { heroId, toX: x, toY: y });
|
|
46137
46478
|
}
|
|
46138
|
-
|
|
46139
|
-
|
|
46479
|
+
const feature = str(hex.feature);
|
|
46480
|
+
if (feature && feature !== "none") {
|
|
46481
|
+
onFeatureEnter?.(heroId, hex);
|
|
46140
46482
|
if (featureEnterEvent) {
|
|
46141
|
-
eventBus.emit(`UI:${featureEnterEvent}`, { heroId
|
|
46483
|
+
eventBus.emit(`UI:${featureEnterEvent}`, { heroId, feature, hex });
|
|
46142
46484
|
}
|
|
46143
46485
|
}
|
|
46144
46486
|
});
|
|
46145
46487
|
return;
|
|
46146
46488
|
}
|
|
46147
|
-
const enemy = heroes.find((h) =>
|
|
46489
|
+
const enemy = heroes.find((h) => {
|
|
46490
|
+
const hp = heroPosition(h);
|
|
46491
|
+
return hp.x === x && hp.y === y && heroOwner(h) === "enemy";
|
|
46492
|
+
});
|
|
46148
46493
|
if (selectedHero && enemy && attackTargets.some((t) => t.x === x && t.y === y)) {
|
|
46149
|
-
|
|
46494
|
+
const attackerId = str(selectedHero.id);
|
|
46495
|
+
const defenderId = str(enemy.id);
|
|
46496
|
+
onBattleEncounter?.(attackerId, defenderId);
|
|
46150
46497
|
if (battleEncounterEvent) {
|
|
46151
|
-
eventBus.emit(`UI:${battleEncounterEvent}`, { attackerId
|
|
46498
|
+
eventBus.emit(`UI:${battleEncounterEvent}`, { attackerId, defenderId });
|
|
46152
46499
|
}
|
|
46153
46500
|
}
|
|
46154
46501
|
}, [hexes, heroes, selectedHero, validMoves, attackTargets, startMoveAnimation, onHeroMove, onFeatureEnter, onBattleEncounter, eventBus, tileClickEvent, heroMoveEvent, featureEnterEvent, battleEncounterEvent]);
|
|
46155
46502
|
const handleUnitClick = useCallback((unitId) => {
|
|
46156
|
-
const hero = heroes.find((h) => h.id === unitId);
|
|
46157
|
-
if (hero && (hero
|
|
46503
|
+
const hero = heroes.find((h) => str(h.id) === unitId);
|
|
46504
|
+
if (hero && (heroOwner(hero) === "player" || allowMoveAllHeroes)) {
|
|
46158
46505
|
onHeroSelect?.(unitId);
|
|
46159
46506
|
if (heroSelectEvent) {
|
|
46160
46507
|
eventBus.emit(`UI:${heroSelectEvent}`, { heroId: unitId });
|
|
@@ -46227,6 +46574,7 @@ var init_WorldMapBoard = __esm({
|
|
|
46227
46574
|
init_Stack();
|
|
46228
46575
|
init_LoadingState();
|
|
46229
46576
|
init_IsometricCanvas2();
|
|
46577
|
+
init_boardEntity();
|
|
46230
46578
|
init_isometric();
|
|
46231
46579
|
WorldMapBoard.displayName = "WorldMapBoard";
|
|
46232
46580
|
}
|
|
@@ -46330,12 +46678,12 @@ var init_XPBar = __esm({
|
|
|
46330
46678
|
}
|
|
46331
46679
|
});
|
|
46332
46680
|
function lazyThree(name, loader) {
|
|
46333
|
-
const Lazy =
|
|
46681
|
+
const Lazy = React80__default.lazy(() => loader().then((m) => ({ default: m[name] })));
|
|
46334
46682
|
function ThreeWrapper(props) {
|
|
46335
|
-
return
|
|
46336
|
-
|
|
46683
|
+
return React80__default.createElement(
|
|
46684
|
+
React80__default.Suspense,
|
|
46337
46685
|
{ fallback: null },
|
|
46338
|
-
|
|
46686
|
+
React80__default.createElement(Lazy, props)
|
|
46339
46687
|
);
|
|
46340
46688
|
}
|
|
46341
46689
|
ThreeWrapper.displayName = `Lazy(${name})`;
|
|
@@ -46350,7 +46698,7 @@ var init_component_registry_generated = __esm({
|
|
|
46350
46698
|
init_ActionButtons();
|
|
46351
46699
|
init_ActionPalette();
|
|
46352
46700
|
init_ActionTile();
|
|
46353
|
-
|
|
46701
|
+
init_AnimatedCounter2();
|
|
46354
46702
|
init_AnimatedGraphic();
|
|
46355
46703
|
init_AnimatedReveal();
|
|
46356
46704
|
init_ArticleSection();
|
|
@@ -46621,7 +46969,7 @@ var init_component_registry_generated = __esm({
|
|
|
46621
46969
|
"ActionTile": ActionTile,
|
|
46622
46970
|
"Alert": AlertPattern,
|
|
46623
46971
|
"AlertPattern": AlertPattern,
|
|
46624
|
-
"AnimatedCounter":
|
|
46972
|
+
"AnimatedCounter": AnimatedCounter2,
|
|
46625
46973
|
"AnimatedGraphic": AnimatedGraphic,
|
|
46626
46974
|
"AnimatedReveal": AnimatedReveal,
|
|
46627
46975
|
"ArticleSection": ArticleSection,
|
|
@@ -46951,7 +47299,7 @@ function SuspenseConfigProvider({
|
|
|
46951
47299
|
config,
|
|
46952
47300
|
children
|
|
46953
47301
|
}) {
|
|
46954
|
-
return
|
|
47302
|
+
return React80__default.createElement(
|
|
46955
47303
|
SuspenseConfigContext.Provider,
|
|
46956
47304
|
{ value: config },
|
|
46957
47305
|
children
|
|
@@ -47436,7 +47784,7 @@ function renderPatternChildren(children, onDismiss, parentId = "root", parentPat
|
|
|
47436
47784
|
const key = `${parentId}-${index}-trait:${traitName}`;
|
|
47437
47785
|
return /* @__PURE__ */ jsx(TraitFrame, { traitName }, key);
|
|
47438
47786
|
}
|
|
47439
|
-
return /* @__PURE__ */ jsx(
|
|
47787
|
+
return /* @__PURE__ */ jsx(React80__default.Fragment, { children: child }, `${parentId}-${index}`);
|
|
47440
47788
|
}
|
|
47441
47789
|
if (!child || typeof child !== "object") return null;
|
|
47442
47790
|
const childId = `${parentId}-${index}`;
|
|
@@ -47476,14 +47824,14 @@ function isPatternConfig(value) {
|
|
|
47476
47824
|
if (value === null || value === void 0) return false;
|
|
47477
47825
|
if (typeof value !== "object") return false;
|
|
47478
47826
|
if (Array.isArray(value)) return false;
|
|
47479
|
-
if (
|
|
47827
|
+
if (React80__default.isValidElement(value)) return false;
|
|
47480
47828
|
if (value instanceof Date) return false;
|
|
47481
47829
|
if (typeof value === "function") return false;
|
|
47482
47830
|
const record = value;
|
|
47483
47831
|
return "type" in record && typeof record.type === "string";
|
|
47484
47832
|
}
|
|
47485
47833
|
function isPlainConfigObject(value) {
|
|
47486
|
-
if (
|
|
47834
|
+
if (React80__default.isValidElement(value)) return false;
|
|
47487
47835
|
if (value instanceof Date) return false;
|
|
47488
47836
|
const proto = Object.getPrototypeOf(value);
|
|
47489
47837
|
return proto === Object.prototype || proto === null;
|