@almadar/ui 5.134.0 → 5.136.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{TraitProvider-Ch79cUcb.d.cts → EntityBindingContext-CD9ZoXb4.d.cts} +30 -2
- package/dist/{TraitProvider-Ch79cUcb.d.ts → EntityBindingContext-CD9ZoXb4.d.ts} +30 -2
- package/dist/avl/index.cjs +819 -429
- package/dist/avl/index.js +820 -430
- package/dist/{cn-Dm0VrLRG.d.ts → cn-CCaph5o9.d.ts} +1 -1
- package/dist/{cn-D3H9UzCW.d.cts → cn-CL0kdshO.d.cts} +1 -1
- package/dist/components/index.cjs +1649 -1482
- package/dist/components/index.d.cts +105 -202
- package/dist/components/index.d.ts +105 -202
- package/dist/components/index.js +705 -533
- package/dist/lib/drawable/three/index.cjs +16 -0
- package/dist/lib/drawable/three/index.d.cts +1 -1
- package/dist/lib/drawable/three/index.d.ts +1 -1
- package/dist/lib/drawable/three/index.js +16 -0
- package/dist/lib/index.cjs +28 -0
- package/dist/lib/index.d.cts +21 -3
- package/dist/lib/index.d.ts +21 -3
- package/dist/lib/index.js +27 -1
- package/dist/marketing/index.cjs +1 -0
- package/dist/marketing/index.js +1 -0
- package/dist/{paintDispatch-BXJgISot.d.cts → paintDispatch-DXygiK7M.d.cts} +39 -10
- package/dist/{paintDispatch-BXJgISot.d.ts → paintDispatch-DXygiK7M.d.ts} +39 -10
- package/dist/providers/index.cjs +701 -323
- package/dist/providers/index.d.cts +3 -3
- package/dist/providers/index.d.ts +3 -3
- package/dist/providers/index.js +698 -322
- package/dist/runtime/index.cjs +819 -429
- package/dist/runtime/index.d.cts +5 -2
- package/dist/runtime/index.d.ts +5 -2
- package/dist/runtime/index.js +820 -430
- package/package.json +6 -5
package/dist/providers/index.js
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import * as React85 from 'react';
|
|
2
|
-
import React85__default, { createContext, useContext, useMemo, useRef, useEffect, useCallback, Suspense, useState, useLayoutEffect, lazy, useId
|
|
3
|
-
import { EventBusContext, useTraitScopeChain, useEntitySchemaOptional, TraitScopeProvider, useCurrentPagePath, useGameAudioContextOptional } from '@almadar/ui/providers';
|
|
2
|
+
import React85__default, { createContext, useContext, useMemo, useRef, useEffect, useCallback, Suspense, useState, useSyncExternalStore, useLayoutEffect, lazy, useId } from 'react';
|
|
3
|
+
import { EventBusContext, useTraitScopeChain, useEntitySchemaOptional, useEntityBindingSnapshot, useTraitScope, TraitScopeProvider, useCurrentPagePath, useGameAudioContextOptional } from '@almadar/ui/providers';
|
|
4
4
|
import { createLogger, isLogLevelEnabled } from '@almadar/logger';
|
|
5
|
+
import { createContextFromBindings, interpolateValue } from '@almadar/runtime';
|
|
6
|
+
import { ANONYMOUS_USER, isRenderBindingMarker, isInlineTrait } from '@almadar/core';
|
|
7
|
+
export { ANONYMOUS_USER } from '@almadar/core';
|
|
5
8
|
import { clsx } from 'clsx';
|
|
6
9
|
import { twMerge } from 'tailwind-merge';
|
|
7
10
|
import * as LucideIcons2 from 'lucide-react';
|
|
@@ -68,11 +71,10 @@ import ReactMarkdown from 'react-markdown';
|
|
|
68
71
|
import remarkGfm from 'remark-gfm';
|
|
69
72
|
import remarkMath from 'remark-math';
|
|
70
73
|
import rehypeKatex from 'rehype-katex';
|
|
71
|
-
import { ANONYMOUS_USER, isInlineTrait } from '@almadar/core';
|
|
72
|
-
export { ANONYMOUS_USER } from '@almadar/core';
|
|
73
74
|
import { DndContext, pointerWithin, rectIntersection, closestCorners, useSensors, useSensor, PointerSensor, KeyboardSensor, useDroppable } from '@dnd-kit/core';
|
|
74
75
|
import { useSortable, arrayMove, sortableKeyboardCoordinates, SortableContext, rectSortingStrategy, verticalListSortingStrategy } from '@dnd-kit/sortable';
|
|
75
76
|
import { CSS } from '@dnd-kit/utilities';
|
|
77
|
+
import { ordered, lib } from 'emojilib';
|
|
76
78
|
import { useNodeId, ReactFlowProvider, Handle, Position } from '@xyflow/react';
|
|
77
79
|
import { forceSimulation, forceLink, forceManyBody, forceCollide, forceX, forceY } from 'd3-force';
|
|
78
80
|
import { isDrawHostPattern, getPatternDefinition, getComponentForPattern as getComponentForPattern$1 } from '@almadar/core/patterns';
|
|
@@ -267,6 +269,75 @@ var init_useEventBus = __esm({
|
|
|
267
269
|
useEventBus_default = useEventBus;
|
|
268
270
|
}
|
|
269
271
|
});
|
|
272
|
+
function resolveMarkerExpression(expression, entity, config, state) {
|
|
273
|
+
const ctx = createContextFromBindings({
|
|
274
|
+
entity,
|
|
275
|
+
payload: {},
|
|
276
|
+
state,
|
|
277
|
+
...config !== void 0 ? { config } : {}
|
|
278
|
+
});
|
|
279
|
+
return interpolateValue(expression, ctx);
|
|
280
|
+
}
|
|
281
|
+
function isPlainObject(value) {
|
|
282
|
+
if (value === null || value === void 0 || typeof value !== "object") return false;
|
|
283
|
+
if (Array.isArray(value)) return false;
|
|
284
|
+
if (React85__default.isValidElement(value)) return false;
|
|
285
|
+
if (value instanceof Date) return false;
|
|
286
|
+
if (typeof value === "function") return false;
|
|
287
|
+
return true;
|
|
288
|
+
}
|
|
289
|
+
function walkValue(value, scopeTrait, entity, config, state) {
|
|
290
|
+
if (isRenderBindingMarker(value)) {
|
|
291
|
+
return { resolved: resolveMarkerExpression(value.expression, entity, config, state), changed: true };
|
|
292
|
+
}
|
|
293
|
+
if (Array.isArray(value)) {
|
|
294
|
+
const out = [];
|
|
295
|
+
let changed = false;
|
|
296
|
+
for (const item of value) {
|
|
297
|
+
const element = item;
|
|
298
|
+
const wasMarker = isRenderBindingMarker(element);
|
|
299
|
+
const { resolved, changed: itemChanged } = walkValue(element, scopeTrait, entity, config, state);
|
|
300
|
+
if (wasMarker && Array.isArray(resolved)) {
|
|
301
|
+
out.push(...resolved);
|
|
302
|
+
changed = true;
|
|
303
|
+
continue;
|
|
304
|
+
}
|
|
305
|
+
out.push(resolved);
|
|
306
|
+
if (itemChanged) changed = true;
|
|
307
|
+
}
|
|
308
|
+
return changed ? { resolved: out, changed: true } : { resolved: value, changed: false };
|
|
309
|
+
}
|
|
310
|
+
if (isPlainObject(value)) {
|
|
311
|
+
const sourceTrait = value._sourceTrait;
|
|
312
|
+
if (typeof sourceTrait === "string" && sourceTrait !== scopeTrait) {
|
|
313
|
+
return { resolved: value, changed: false };
|
|
314
|
+
}
|
|
315
|
+
const out = {};
|
|
316
|
+
let changed = false;
|
|
317
|
+
for (const [key, item] of Object.entries(value)) {
|
|
318
|
+
const { resolved, changed: itemChanged } = walkValue(item, scopeTrait, entity, config, state);
|
|
319
|
+
out[key] = resolved;
|
|
320
|
+
if (itemChanged) changed = true;
|
|
321
|
+
}
|
|
322
|
+
return changed ? { resolved: out, changed: true } : { resolved: value, changed: false };
|
|
323
|
+
}
|
|
324
|
+
return { resolved: value, changed: false };
|
|
325
|
+
}
|
|
326
|
+
function resolveRenderBindingMarkers(props, scopeTrait, entity, config, state) {
|
|
327
|
+
const out = {};
|
|
328
|
+
let changed = false;
|
|
329
|
+
for (const [key, value] of Object.entries(props)) {
|
|
330
|
+
const { resolved, changed: propChanged } = walkValue(value, scopeTrait, entity, config, state);
|
|
331
|
+
out[key] = resolved;
|
|
332
|
+
if (propChanged) changed = true;
|
|
333
|
+
}
|
|
334
|
+
return changed ? out : props;
|
|
335
|
+
}
|
|
336
|
+
var init_resolve_render_bindings = __esm({
|
|
337
|
+
"lib/resolve-render-bindings.ts"() {
|
|
338
|
+
"use client";
|
|
339
|
+
}
|
|
340
|
+
});
|
|
270
341
|
function cn(...inputs) {
|
|
271
342
|
return twMerge(clsx(inputs));
|
|
272
343
|
}
|
|
@@ -774,9 +845,13 @@ function getAtlas(url, onReady) {
|
|
|
774
845
|
onReady();
|
|
775
846
|
}).catch(() => {
|
|
776
847
|
atlasCache.set(url, null);
|
|
848
|
+
onReady();
|
|
777
849
|
});
|
|
778
850
|
return void 0;
|
|
779
851
|
}
|
|
852
|
+
function atlasFailed(url) {
|
|
853
|
+
return atlasCache.get(url) === null;
|
|
854
|
+
}
|
|
780
855
|
function subRectFor(atlas, sprite) {
|
|
781
856
|
if (isTilesheet(atlas)) {
|
|
782
857
|
let col;
|
|
@@ -1197,6 +1272,32 @@ function formatValue(value, format) {
|
|
|
1197
1272
|
return String(value);
|
|
1198
1273
|
}
|
|
1199
1274
|
}
|
|
1275
|
+
function compareCellValues(a, b) {
|
|
1276
|
+
const aEmpty = a === null || a === void 0 || a === "";
|
|
1277
|
+
const bEmpty = b === null || b === void 0 || b === "";
|
|
1278
|
+
if (aEmpty || bEmpty) return aEmpty && bEmpty ? 0 : aEmpty ? 1 : -1;
|
|
1279
|
+
if (typeof a === "number" && typeof b === "number") return a - b;
|
|
1280
|
+
if (typeof a === "boolean" && typeof b === "boolean") return Number(a) - Number(b);
|
|
1281
|
+
const aNum = Number(a);
|
|
1282
|
+
const bNum = Number(b);
|
|
1283
|
+
if (Number.isFinite(aNum) && Number.isFinite(bNum)) return aNum - bNum;
|
|
1284
|
+
const aTime = dateLikeTime(a);
|
|
1285
|
+
const bTime = dateLikeTime(b);
|
|
1286
|
+
if (aTime !== null && bTime !== null) return aTime - bTime;
|
|
1287
|
+
return String(a).localeCompare(String(b));
|
|
1288
|
+
}
|
|
1289
|
+
function dateLikeTime(value) {
|
|
1290
|
+
if (value instanceof Date) return value.getTime();
|
|
1291
|
+
const text = String(value);
|
|
1292
|
+
if (!/\d/.test(text) || !/[-/:T]/.test(text)) return null;
|
|
1293
|
+
const time = Date.parse(text);
|
|
1294
|
+
return Number.isNaN(time) ? null : time;
|
|
1295
|
+
}
|
|
1296
|
+
function sortRows(rows, field, direction = "asc") {
|
|
1297
|
+
if (!field) return rows;
|
|
1298
|
+
const dir = direction === "desc" ? -1 : 1;
|
|
1299
|
+
return [...rows].sort((a, b) => dir * compareCellValues(a?.[field], b?.[field]));
|
|
1300
|
+
}
|
|
1200
1301
|
var init_format = __esm({
|
|
1201
1302
|
"lib/format.ts"() {
|
|
1202
1303
|
}
|
|
@@ -3019,6 +3120,20 @@ var init_Input = __esm({
|
|
|
3019
3120
|
const { t } = useTranslate();
|
|
3020
3121
|
const eventBus = useEventBus();
|
|
3021
3122
|
const type = inputType || htmlType || "text";
|
|
3123
|
+
const isDeclarative = typeof onChange === "string";
|
|
3124
|
+
const [localValue, setLocalValue] = React85__default.useState(value);
|
|
3125
|
+
const pendingEchoRef = React85__default.useRef(/* @__PURE__ */ new Set());
|
|
3126
|
+
React85__default.useEffect(() => {
|
|
3127
|
+
if (!isDeclarative) return;
|
|
3128
|
+
const incoming = value == null ? "" : String(value);
|
|
3129
|
+
if (pendingEchoRef.current.has(incoming)) {
|
|
3130
|
+
pendingEchoRef.current.delete(incoming);
|
|
3131
|
+
return;
|
|
3132
|
+
}
|
|
3133
|
+
pendingEchoRef.current.clear();
|
|
3134
|
+
setLocalValue(value);
|
|
3135
|
+
}, [value, isDeclarative]);
|
|
3136
|
+
const displayValue = isDeclarative ? localValue : value;
|
|
3022
3137
|
const resolveIconNode = (i, cls) => {
|
|
3023
3138
|
if (!i) return null;
|
|
3024
3139
|
if (typeof i === "string") return /* @__PURE__ */ jsx(Icon, { name: i, className: cls });
|
|
@@ -3028,7 +3143,7 @@ var init_Input = __esm({
|
|
|
3028
3143
|
const iconCls = "h-icon-default w-icon-default";
|
|
3029
3144
|
const IconComponent = typeof iconProp === "string" ? resolveIcon(iconProp) : iconProp;
|
|
3030
3145
|
const resolvedLeftIcon = (leftIcon ? resolveIconNode(leftIcon, iconCls) : null) || IconComponent && /* @__PURE__ */ jsx(IconComponent, { className: iconCls });
|
|
3031
|
-
const showClearButton = clearable &&
|
|
3146
|
+
const showClearButton = clearable && displayValue && String(displayValue).length > 0;
|
|
3032
3147
|
const isMultiline = type === "textarea";
|
|
3033
3148
|
const baseClassName = cn(
|
|
3034
3149
|
"block w-full rounded-sm transition-all duration-fast",
|
|
@@ -3047,6 +3162,10 @@ var init_Input = __esm({
|
|
|
3047
3162
|
if (typeof onChange === "string") {
|
|
3048
3163
|
const target = e.target;
|
|
3049
3164
|
const payload = type === "checkbox" ? { checked: target.checked } : { value: target.value };
|
|
3165
|
+
if (type !== "checkbox") {
|
|
3166
|
+
pendingEchoRef.current.add(target.value);
|
|
3167
|
+
setLocalValue(target.value);
|
|
3168
|
+
}
|
|
3050
3169
|
eventBus.emit(`UI:${onChange}`, payload);
|
|
3051
3170
|
} else {
|
|
3052
3171
|
onChange?.(e);
|
|
@@ -3077,7 +3196,7 @@ var init_Input = __esm({
|
|
|
3077
3196
|
"select",
|
|
3078
3197
|
{
|
|
3079
3198
|
ref,
|
|
3080
|
-
value,
|
|
3199
|
+
value: displayValue,
|
|
3081
3200
|
onChange: handleChange,
|
|
3082
3201
|
className: cn(baseClassName, "appearance-none pr-10", className),
|
|
3083
3202
|
...props,
|
|
@@ -3097,7 +3216,7 @@ var init_Input = __esm({
|
|
|
3097
3216
|
"textarea",
|
|
3098
3217
|
{
|
|
3099
3218
|
ref,
|
|
3100
|
-
value,
|
|
3219
|
+
value: displayValue,
|
|
3101
3220
|
onChange: handleChange,
|
|
3102
3221
|
rows,
|
|
3103
3222
|
className: baseClassName,
|
|
@@ -3136,7 +3255,7 @@ var init_Input = __esm({
|
|
|
3136
3255
|
{
|
|
3137
3256
|
ref,
|
|
3138
3257
|
type,
|
|
3139
|
-
value,
|
|
3258
|
+
value: displayValue,
|
|
3140
3259
|
onChange: handleChange,
|
|
3141
3260
|
onKeyDown: handleKeyDown,
|
|
3142
3261
|
className: baseClassName,
|
|
@@ -7059,46 +7178,45 @@ var init_useImageCache = __esm({
|
|
|
7059
7178
|
});
|
|
7060
7179
|
|
|
7061
7180
|
// lib/isometric.ts
|
|
7062
|
-
function isoToScreen(tileX, tileY,
|
|
7063
|
-
const
|
|
7064
|
-
const
|
|
7181
|
+
function isoToScreen(tileX, tileY, cellWidth, baseOffsetX, layout = "isometric") {
|
|
7182
|
+
const w = cellWidth;
|
|
7183
|
+
const fh = cellWidth / 2;
|
|
7065
7184
|
if (layout === "hex") {
|
|
7066
|
-
const screenX2 = tileX *
|
|
7067
|
-
const screenY2 = tileY * (
|
|
7185
|
+
const screenX2 = tileX * w + (tileY & 1) * (w / 2) + baseOffsetX;
|
|
7186
|
+
const screenY2 = tileY * (fh * 0.75);
|
|
7068
7187
|
return { x: screenX2, y: screenY2 };
|
|
7069
7188
|
}
|
|
7070
7189
|
if (layout === "flat") {
|
|
7071
|
-
const screenX2 = tileX *
|
|
7072
|
-
const screenY2 = tileY *
|
|
7190
|
+
const screenX2 = tileX * w + baseOffsetX;
|
|
7191
|
+
const screenY2 = tileY * w;
|
|
7073
7192
|
return { x: screenX2, y: screenY2 };
|
|
7074
7193
|
}
|
|
7075
|
-
const screenX = (tileX - tileY) * (
|
|
7076
|
-
const screenY = (tileX + tileY) * (
|
|
7194
|
+
const screenX = (tileX - tileY) * (w / 2) + baseOffsetX;
|
|
7195
|
+
const screenY = (tileX + tileY) * (fh / 2);
|
|
7077
7196
|
return { x: screenX, y: screenY };
|
|
7078
7197
|
}
|
|
7079
|
-
function screenToIso(screenX, screenY,
|
|
7080
|
-
const
|
|
7081
|
-
const
|
|
7198
|
+
function screenToIso(screenX, screenY, cellWidth, baseOffsetX, layout = "isometric") {
|
|
7199
|
+
const w = cellWidth;
|
|
7200
|
+
const fh = cellWidth / 2;
|
|
7082
7201
|
if (layout === "hex") {
|
|
7083
|
-
const row = Math.round(screenY / (
|
|
7084
|
-
const col = Math.round((screenX - (row & 1) * (
|
|
7202
|
+
const row = Math.round(screenY / (fh * 0.75));
|
|
7203
|
+
const col = Math.round((screenX - (row & 1) * (w / 2) - baseOffsetX) / w);
|
|
7085
7204
|
return { x: col, y: row };
|
|
7086
7205
|
}
|
|
7087
7206
|
if (layout === "flat") {
|
|
7088
|
-
const col = Math.round((screenX - baseOffsetX) /
|
|
7089
|
-
const row = Math.round(screenY /
|
|
7207
|
+
const col = Math.round((screenX - baseOffsetX) / w);
|
|
7208
|
+
const row = Math.round(screenY / w);
|
|
7090
7209
|
return { x: col, y: row };
|
|
7091
7210
|
}
|
|
7092
7211
|
const adjustedX = screenX - baseOffsetX;
|
|
7093
|
-
const tileX = (adjustedX / (
|
|
7094
|
-
const tileY = (screenY / (
|
|
7212
|
+
const tileX = (adjustedX / (w / 2) + screenY / (fh / 2)) / 2;
|
|
7213
|
+
const tileY = (screenY / (fh / 2) - adjustedX / (w / 2)) / 2;
|
|
7095
7214
|
return { x: Math.round(tileX), y: Math.round(tileY) };
|
|
7096
7215
|
}
|
|
7097
|
-
var TILE_WIDTH,
|
|
7216
|
+
var TILE_WIDTH, DIAMOND_TOP_Y, BACKGROUND_FALLBACK_COLOR, MINIMAP_TERRAIN_COLORS;
|
|
7098
7217
|
var init_isometric = __esm({
|
|
7099
7218
|
"lib/isometric.ts"() {
|
|
7100
7219
|
TILE_WIDTH = 256;
|
|
7101
|
-
FLOOR_HEIGHT = 128;
|
|
7102
7220
|
DIAMOND_TOP_Y = 374;
|
|
7103
7221
|
BACKGROUND_FALLBACK_COLOR = "#1a1a2e";
|
|
7104
7222
|
MINIMAP_TERRAIN_COLORS = {
|
|
@@ -7583,210 +7701,6 @@ var init_ChoiceButton = __esm({
|
|
|
7583
7701
|
ChoiceButton.displayName = "ChoiceButton";
|
|
7584
7702
|
}
|
|
7585
7703
|
});
|
|
7586
|
-
function SvgStage({
|
|
7587
|
-
cols,
|
|
7588
|
-
rows,
|
|
7589
|
-
tileSize = 32,
|
|
7590
|
-
background = "var(--color-background)",
|
|
7591
|
-
tileClickEvent,
|
|
7592
|
-
tileHoverEvent,
|
|
7593
|
-
tileLeaveEvent,
|
|
7594
|
-
keyMap,
|
|
7595
|
-
keyUpMap,
|
|
7596
|
-
className,
|
|
7597
|
-
children
|
|
7598
|
-
}) {
|
|
7599
|
-
const eventBus = useEventBus();
|
|
7600
|
-
const svgRef = useRef(null);
|
|
7601
|
-
const pointerDownRef = useRef(null);
|
|
7602
|
-
const cellFromClient = useCallback((clientX, clientY) => {
|
|
7603
|
-
const svg = svgRef.current;
|
|
7604
|
-
if (!svg) return null;
|
|
7605
|
-
const rect = svg.getBoundingClientRect();
|
|
7606
|
-
if (rect.width === 0 || rect.height === 0) return null;
|
|
7607
|
-
const vbW = cols * tileSize;
|
|
7608
|
-
const vbH = rows * tileSize;
|
|
7609
|
-
const meet = Math.min(rect.width / vbW, rect.height / vbH);
|
|
7610
|
-
const offsetX = (rect.width - vbW * meet) / 2;
|
|
7611
|
-
const offsetY = (rect.height - vbH * meet) / 2;
|
|
7612
|
-
const svgX = (clientX - rect.left - offsetX) / meet;
|
|
7613
|
-
const svgY = (clientY - rect.top - offsetY) / meet;
|
|
7614
|
-
return {
|
|
7615
|
-
x: Math.min(Math.max(Math.floor(svgX / tileSize), 0), cols - 1),
|
|
7616
|
-
y: Math.min(Math.max(Math.floor(svgY / tileSize), 0), rows - 1)
|
|
7617
|
-
};
|
|
7618
|
-
}, [cols, rows, tileSize]);
|
|
7619
|
-
const handlePointerDown = useCallback((e) => {
|
|
7620
|
-
pointerDownRef.current = { clientX: e.clientX, clientY: e.clientY };
|
|
7621
|
-
}, []);
|
|
7622
|
-
const handlePointerUp = useCallback((e) => {
|
|
7623
|
-
const down = pointerDownRef.current;
|
|
7624
|
-
pointerDownRef.current = null;
|
|
7625
|
-
if (!tileClickEvent) return;
|
|
7626
|
-
if (down && Math.hypot(e.clientX - down.clientX, e.clientY - down.clientY) > 5) return;
|
|
7627
|
-
const cell = cellFromClient(e.clientX, e.clientY);
|
|
7628
|
-
if (cell) eventBus.emit(`UI:${tileClickEvent}`, cell);
|
|
7629
|
-
}, [cellFromClient, tileClickEvent, eventBus]);
|
|
7630
|
-
const handlePointerMove = useCallback((e) => {
|
|
7631
|
-
if (!tileHoverEvent) return;
|
|
7632
|
-
const cell = cellFromClient(e.clientX, e.clientY);
|
|
7633
|
-
if (cell) eventBus.emit(`UI:${tileHoverEvent}`, cell);
|
|
7634
|
-
}, [cellFromClient, tileHoverEvent, eventBus]);
|
|
7635
|
-
const handlePointerLeave = useCallback(() => {
|
|
7636
|
-
pointerDownRef.current = null;
|
|
7637
|
-
if (tileLeaveEvent) eventBus.emit(`UI:${tileLeaveEvent}`, {});
|
|
7638
|
-
}, [tileLeaveEvent, eventBus]);
|
|
7639
|
-
useEffect(() => {
|
|
7640
|
-
if (!keyMap && !keyUpMap) return;
|
|
7641
|
-
const onDown = (e) => {
|
|
7642
|
-
const ev = keyMap?.[e.code];
|
|
7643
|
-
if (ev) {
|
|
7644
|
-
eventBus.emit(`UI:${ev}`, {});
|
|
7645
|
-
e.preventDefault();
|
|
7646
|
-
}
|
|
7647
|
-
};
|
|
7648
|
-
const onUp = (e) => {
|
|
7649
|
-
const ev = keyUpMap?.[e.code];
|
|
7650
|
-
if (ev) eventBus.emit(`UI:${ev}`, {});
|
|
7651
|
-
};
|
|
7652
|
-
window.addEventListener("keydown", onDown);
|
|
7653
|
-
window.addEventListener("keyup", onUp);
|
|
7654
|
-
return () => {
|
|
7655
|
-
window.removeEventListener("keydown", onDown);
|
|
7656
|
-
window.removeEventListener("keyup", onUp);
|
|
7657
|
-
};
|
|
7658
|
-
}, [keyMap, keyUpMap, eventBus]);
|
|
7659
|
-
useEffect(() => {
|
|
7660
|
-
if (!keyMap && !keyUpMap) return;
|
|
7661
|
-
svgRef.current?.focus();
|
|
7662
|
-
}, [keyMap, keyUpMap]);
|
|
7663
|
-
const stageContext = useMemo(() => ({ tileSize }), [tileSize]);
|
|
7664
|
-
return /* @__PURE__ */ jsxs(
|
|
7665
|
-
"svg",
|
|
7666
|
-
{
|
|
7667
|
-
ref: svgRef,
|
|
7668
|
-
"data-testid": "svg-stage",
|
|
7669
|
-
viewBox: `0 0 ${cols * tileSize} ${rows * tileSize}`,
|
|
7670
|
-
preserveAspectRatio: "xMidYMid meet",
|
|
7671
|
-
className: cn("block h-full w-full", className),
|
|
7672
|
-
tabIndex: keyMap || keyUpMap ? 0 : void 0,
|
|
7673
|
-
onPointerDown: handlePointerDown,
|
|
7674
|
-
onPointerMove: handlePointerMove,
|
|
7675
|
-
onPointerUp: handlePointerUp,
|
|
7676
|
-
onPointerLeave: handlePointerLeave,
|
|
7677
|
-
children: [
|
|
7678
|
-
/* @__PURE__ */ jsx("rect", { width: cols * tileSize, height: rows * tileSize, fill: background }),
|
|
7679
|
-
/* @__PURE__ */ jsx(SvgStageContext.Provider, { value: stageContext, children })
|
|
7680
|
-
]
|
|
7681
|
-
}
|
|
7682
|
-
);
|
|
7683
|
-
}
|
|
7684
|
-
var SvgStageContext;
|
|
7685
|
-
var init_SvgStage = __esm({
|
|
7686
|
-
"components/game/molecules/SvgStage.tsx"() {
|
|
7687
|
-
"use client";
|
|
7688
|
-
init_cn();
|
|
7689
|
-
init_useEventBus();
|
|
7690
|
-
SvgStageContext = React85.createContext({ tileSize: 1 });
|
|
7691
|
-
SvgStage.displayName = "SvgStage";
|
|
7692
|
-
}
|
|
7693
|
-
});
|
|
7694
|
-
function SvgDrawShape({
|
|
7695
|
-
shape,
|
|
7696
|
-
x,
|
|
7697
|
-
y,
|
|
7698
|
-
width,
|
|
7699
|
-
height,
|
|
7700
|
-
radius,
|
|
7701
|
-
radiusY,
|
|
7702
|
-
points,
|
|
7703
|
-
d,
|
|
7704
|
-
x2,
|
|
7705
|
-
y2,
|
|
7706
|
-
fill,
|
|
7707
|
-
stroke,
|
|
7708
|
-
strokeWidth,
|
|
7709
|
-
opacity,
|
|
7710
|
-
className
|
|
7711
|
-
}) {
|
|
7712
|
-
const { tileSize } = useContext(SvgStageContext);
|
|
7713
|
-
const cell = (v) => v === void 0 ? void 0 : v * tileSize;
|
|
7714
|
-
const paint = {
|
|
7715
|
-
fill: fill ?? (stroke === void 0 ? "var(--color-primary)" : "none"),
|
|
7716
|
-
stroke,
|
|
7717
|
-
strokeWidth,
|
|
7718
|
-
opacity,
|
|
7719
|
-
className
|
|
7720
|
-
};
|
|
7721
|
-
return /* @__PURE__ */ jsxs("g", { transform: `translate(${x * tileSize} ${y * tileSize})`, children: [
|
|
7722
|
-
shape === "rect" && /* @__PURE__ */ jsx("rect", { width: cell(width), height: cell(height), ...paint }),
|
|
7723
|
-
shape === "circle" && /* @__PURE__ */ jsx("circle", { r: cell(radius), ...paint }),
|
|
7724
|
-
shape === "ellipse" && /* @__PURE__ */ jsx("ellipse", { rx: cell(radius), ry: cell(radiusY ?? radius), ...paint }),
|
|
7725
|
-
shape === "polygon" && /* @__PURE__ */ jsx("polygon", { points, ...paint }),
|
|
7726
|
-
shape === "polyline" && /* @__PURE__ */ jsx("polyline", { points, ...paint }),
|
|
7727
|
-
shape === "path" && /* @__PURE__ */ jsx("path", { d, ...paint }),
|
|
7728
|
-
shape === "line" && /* @__PURE__ */ jsx("line", { x2: cell(x2), y2: cell(y2), ...paint })
|
|
7729
|
-
] });
|
|
7730
|
-
}
|
|
7731
|
-
var init_SvgDrawShape = __esm({
|
|
7732
|
-
"components/game/atoms/SvgDrawShape.tsx"() {
|
|
7733
|
-
"use client";
|
|
7734
|
-
init_SvgStage();
|
|
7735
|
-
SvgDrawShape.displayName = "SvgDrawShape";
|
|
7736
|
-
}
|
|
7737
|
-
});
|
|
7738
|
-
function SvgDrawGroup({
|
|
7739
|
-
x = 0,
|
|
7740
|
-
y = 0,
|
|
7741
|
-
scale,
|
|
7742
|
-
rotate,
|
|
7743
|
-
opacity,
|
|
7744
|
-
className,
|
|
7745
|
-
children
|
|
7746
|
-
}) {
|
|
7747
|
-
const { tileSize } = useContext(SvgStageContext);
|
|
7748
|
-
const transforms = [`translate(${x * tileSize} ${y * tileSize})`];
|
|
7749
|
-
if (rotate !== void 0) transforms.push(`rotate(${rotate})`);
|
|
7750
|
-
if (scale !== void 0) transforms.push(`scale(${scale})`);
|
|
7751
|
-
return /* @__PURE__ */ jsx("g", { transform: transforms.join(" "), opacity, className, children });
|
|
7752
|
-
}
|
|
7753
|
-
var init_SvgDrawGroup = __esm({
|
|
7754
|
-
"components/game/atoms/SvgDrawGroup.tsx"() {
|
|
7755
|
-
"use client";
|
|
7756
|
-
init_SvgStage();
|
|
7757
|
-
SvgDrawGroup.displayName = "SvgDrawGroup";
|
|
7758
|
-
}
|
|
7759
|
-
});
|
|
7760
|
-
function SvgDrawText({
|
|
7761
|
-
x,
|
|
7762
|
-
y,
|
|
7763
|
-
text,
|
|
7764
|
-
size = 12,
|
|
7765
|
-
fill = "var(--color-foreground)",
|
|
7766
|
-
anchor = "middle",
|
|
7767
|
-
className
|
|
7768
|
-
}) {
|
|
7769
|
-
const { tileSize } = useContext(SvgStageContext);
|
|
7770
|
-
return /* @__PURE__ */ jsx(
|
|
7771
|
-
"text",
|
|
7772
|
-
{
|
|
7773
|
-
x: x * tileSize,
|
|
7774
|
-
y: y * tileSize,
|
|
7775
|
-
fontSize: size,
|
|
7776
|
-
fill,
|
|
7777
|
-
textAnchor: anchor,
|
|
7778
|
-
className,
|
|
7779
|
-
children: text
|
|
7780
|
-
}
|
|
7781
|
-
);
|
|
7782
|
-
}
|
|
7783
|
-
var init_SvgDrawText = __esm({
|
|
7784
|
-
"components/game/atoms/SvgDrawText.tsx"() {
|
|
7785
|
-
"use client";
|
|
7786
|
-
init_SvgStage();
|
|
7787
|
-
SvgDrawText.displayName = "SvgDrawText";
|
|
7788
|
-
}
|
|
7789
|
-
});
|
|
7790
7704
|
function ControlGrid({
|
|
7791
7705
|
kind,
|
|
7792
7706
|
buttons = DEFAULT_BUTTONS,
|
|
@@ -8490,6 +8404,7 @@ function MiniMap({
|
|
|
8490
8404
|
const cached = imgCacheRef.current.get(url);
|
|
8491
8405
|
if (cached) return cached.complete ? cached : null;
|
|
8492
8406
|
const img = new Image();
|
|
8407
|
+
img.crossOrigin = "anonymous";
|
|
8493
8408
|
img.src = url;
|
|
8494
8409
|
img.onload = () => {
|
|
8495
8410
|
const canvas = canvasRef.current;
|
|
@@ -8657,7 +8572,7 @@ function useCamera(initial) {
|
|
|
8657
8572
|
const handleWheel = useCallback((e, drawFn) => {
|
|
8658
8573
|
e.preventDefault();
|
|
8659
8574
|
const zoomDelta = e.deltaY > 0 ? 0.9 : 1.1;
|
|
8660
|
-
cameraRef.current.zoom = Math.max(
|
|
8575
|
+
cameraRef.current.zoom = Math.max(MIN_ZOOM, Math.min(MAX_ZOOM, cameraRef.current.zoom * zoomDelta));
|
|
8661
8576
|
drawFn?.();
|
|
8662
8577
|
}, []);
|
|
8663
8578
|
const handlePointerDown = useCallback((e) => {
|
|
@@ -8678,7 +8593,7 @@ function useCamera(initial) {
|
|
|
8678
8593
|
const zoomAtPoint = useCallback((factor, centerX, centerY, viewportSize, drawFn) => {
|
|
8679
8594
|
const cam = cameraRef.current;
|
|
8680
8595
|
const oldZoom = cam.zoom;
|
|
8681
|
-
const newZoom = Math.max(
|
|
8596
|
+
const newZoom = Math.max(MIN_ZOOM, Math.min(MAX_ZOOM, oldZoom * factor));
|
|
8682
8597
|
if (newZoom === oldZoom) {
|
|
8683
8598
|
drawFn?.();
|
|
8684
8599
|
return;
|
|
@@ -8730,9 +8645,12 @@ function useCamera(initial) {
|
|
|
8730
8645
|
lerpToTarget
|
|
8731
8646
|
};
|
|
8732
8647
|
}
|
|
8648
|
+
var MIN_ZOOM, MAX_ZOOM;
|
|
8733
8649
|
var init_useCamera = __esm({
|
|
8734
8650
|
"hooks/useCamera.ts"() {
|
|
8735
8651
|
"use client";
|
|
8652
|
+
MIN_ZOOM = 0.05;
|
|
8653
|
+
MAX_ZOOM = 10;
|
|
8736
8654
|
}
|
|
8737
8655
|
});
|
|
8738
8656
|
function localPoint(canvas, clientX, clientY) {
|
|
@@ -8853,6 +8771,7 @@ function getOrLoadImage(url, onReady) {
|
|
|
8853
8771
|
return null;
|
|
8854
8772
|
}
|
|
8855
8773
|
const img = new Image();
|
|
8774
|
+
img.crossOrigin = "anonymous";
|
|
8856
8775
|
const entry = { img, status: "pending", onReady };
|
|
8857
8776
|
cache.set(url, entry);
|
|
8858
8777
|
updateAssetStatus(url, "pending");
|
|
@@ -8864,10 +8783,14 @@ function getOrLoadImage(url, onReady) {
|
|
|
8864
8783
|
img.onerror = () => {
|
|
8865
8784
|
entry.status = "failed";
|
|
8866
8785
|
updateAssetStatus(url, "failed");
|
|
8786
|
+
entry.onReady?.();
|
|
8867
8787
|
};
|
|
8868
8788
|
img.src = url;
|
|
8869
8789
|
return null;
|
|
8870
8790
|
}
|
|
8791
|
+
function getImageStatus(url) {
|
|
8792
|
+
return cache.get(url)?.status;
|
|
8793
|
+
}
|
|
8871
8794
|
var cache;
|
|
8872
8795
|
var init_imageCache = __esm({
|
|
8873
8796
|
"lib/imageCache.ts"() {
|
|
@@ -8976,6 +8899,15 @@ function createWebPainter(ctx, onAssetLoad) {
|
|
|
8976
8899
|
ctx.lineWidth = lineWidth;
|
|
8977
8900
|
ctx.stroke();
|
|
8978
8901
|
},
|
|
8902
|
+
fillPath(d, color) {
|
|
8903
|
+
ctx.fillStyle = color;
|
|
8904
|
+
ctx.fill(new Path2D(d));
|
|
8905
|
+
},
|
|
8906
|
+
strokePath(d, color, lineWidth = 1) {
|
|
8907
|
+
ctx.strokeStyle = color;
|
|
8908
|
+
ctx.lineWidth = lineWidth;
|
|
8909
|
+
ctx.stroke(new Path2D(d));
|
|
8910
|
+
},
|
|
8979
8911
|
text(str, x, y, style) {
|
|
8980
8912
|
if (style.font) ctx.font = style.font;
|
|
8981
8913
|
ctx.fillStyle = style.color;
|
|
@@ -8997,12 +8929,13 @@ var init_webPainter2d = __esm({
|
|
|
8997
8929
|
|
|
8998
8930
|
// lib/drawable/projector.ts
|
|
8999
8931
|
function create2DProjector(opts) {
|
|
9000
|
-
const {
|
|
9001
|
-
const
|
|
9002
|
-
const
|
|
9003
|
-
const
|
|
8932
|
+
const { baseOffsetX, layout } = opts;
|
|
8933
|
+
const tw = opts.tileWidth ?? TILE_WIDTH;
|
|
8934
|
+
const tileWidth = layout === "free" ? 1 : tw;
|
|
8935
|
+
const floorHeight = layout === "free" ? 1 : tw / 2;
|
|
8936
|
+
const diamondTopY = layout === "free" ? 0 : opts.diamondTopY ?? tw * (DIAMOND_TOP_Y / TILE_WIDTH);
|
|
9004
8937
|
const squareGrid = layout === "flat" || layout === "free";
|
|
9005
|
-
const project = (pos) => layout === "free" ? { x: pos.x, y: pos.y } : isoToScreen(pos.x, pos.y,
|
|
8938
|
+
const project = (pos) => layout === "free" ? { x: pos.x, y: pos.y } : isoToScreen(pos.x, pos.y, tw, baseOffsetX, layout);
|
|
9006
8939
|
const anchorPoint = (pos, anchor) => {
|
|
9007
8940
|
const base = project(pos);
|
|
9008
8941
|
if (anchor === "top-left") return base;
|
|
@@ -9033,7 +8966,7 @@ function create2DProjector(opts) {
|
|
|
9033
8966
|
{ x: base.x, y: topY + floorHeight / 2 }
|
|
9034
8967
|
];
|
|
9035
8968
|
};
|
|
9036
|
-
return { project, anchorPoint, cellPath, tileWidth, floorHeight, diamondTopY,
|
|
8969
|
+
return { project, anchorPoint, cellPath, tileWidth, floorHeight, diamondTopY, squareGrid, worldPixelDirect: layout === "free" };
|
|
9037
8970
|
}
|
|
9038
8971
|
var init_projector = __esm({
|
|
9039
8972
|
"lib/drawable/projector.ts"() {
|
|
@@ -9049,32 +8982,67 @@ var init_contract = __esm({
|
|
|
9049
8982
|
"lib/drawable/contract.ts"() {
|
|
9050
8983
|
}
|
|
9051
8984
|
});
|
|
9052
|
-
|
|
9053
|
-
|
|
8985
|
+
function warnMissingOnce(reason, node) {
|
|
8986
|
+
const key = `${reason}:${node.asset.url}:${String(node.asset.atlas)}:${String(node.asset.sprite)}`;
|
|
8987
|
+
if (loggedMissing.has(key)) return;
|
|
8988
|
+
loggedMissing.add(key);
|
|
8989
|
+
spriteLog.warn("draw-sprite asset unresolvable \u2014 painting fallback square", { reason, url: node.asset.url, atlas: node.asset.atlas, sprite: node.asset.sprite });
|
|
8990
|
+
}
|
|
8991
|
+
function paintFallbackSquare(painter, node, dctx, reason) {
|
|
8992
|
+
warnMissingOnce(reason, node);
|
|
8993
|
+
const tw = dctx.projector.tileWidth;
|
|
8994
|
+
const natural = dctx.projector.worldPixelDirect ? FALLBACK_WORLD_PX : tw;
|
|
8995
|
+
const w = node.width !== void 0 ? node.width * tw : natural;
|
|
8996
|
+
const h = node.height !== void 0 ? node.height * tw : natural;
|
|
8997
|
+
const anchor = node.anchor ?? "top-left";
|
|
8998
|
+
const p = dctx.projector.anchorPoint(node.position, anchor);
|
|
8999
|
+
const dx = anchor === "top-left" ? p.x : p.x - w / 2;
|
|
9000
|
+
const dy = anchor === "ground" ? p.y - h : anchor === "center" ? p.y - h / 2 : p.y;
|
|
9001
|
+
painter.save();
|
|
9002
|
+
if (node.opacity !== void 0 && node.opacity !== 1) painter.setAlpha(node.opacity);
|
|
9003
|
+
painter.fillRect(dx, dy, w, h, "#9b8f7f");
|
|
9004
|
+
painter.strokeRect(dx, dy, w, h, "#5e564b", Math.max(1, tw / 32));
|
|
9005
|
+
painter.restore();
|
|
9006
|
+
}
|
|
9054
9007
|
function DrawSprite(_props) {
|
|
9055
9008
|
return null;
|
|
9056
9009
|
}
|
|
9057
|
-
var paintSprite;
|
|
9010
|
+
var spriteLog, loggedMissing, FALLBACK_WORLD_PX, paintSprite;
|
|
9058
9011
|
var init_DrawSprite = __esm({
|
|
9059
9012
|
"components/game/atoms/DrawSprite.tsx"() {
|
|
9060
9013
|
"use client";
|
|
9061
9014
|
init_atlasSlice();
|
|
9015
|
+
init_imageCache();
|
|
9062
9016
|
init_contract();
|
|
9017
|
+
spriteLog = createLogger("almadar:ui:draw-sprite");
|
|
9018
|
+
loggedMissing = /* @__PURE__ */ new Set();
|
|
9019
|
+
FALLBACK_WORLD_PX = 32;
|
|
9063
9020
|
paintSprite = (painter, node, dctx) => {
|
|
9064
9021
|
if (!node.asset?.url || !isValidScenePos(node.position)) return;
|
|
9065
9022
|
const tex = painter.resolveTexture(node.asset.url);
|
|
9066
|
-
if (!tex)
|
|
9023
|
+
if (!tex) {
|
|
9024
|
+
if (getImageStatus(node.asset.url) === "failed") paintFallbackSquare(painter, node, dctx, "texture-failed");
|
|
9025
|
+
return;
|
|
9026
|
+
}
|
|
9067
9027
|
let src = typeof node.frame === "object" ? node.frame : void 0;
|
|
9068
9028
|
if (!src && isAtlasAsset(node.asset)) {
|
|
9069
9029
|
const atlas = getAtlas(node.asset.atlas, dctx.invalidate);
|
|
9070
|
-
if (!atlas)
|
|
9030
|
+
if (!atlas) {
|
|
9031
|
+
if (atlasFailed(node.asset.atlas)) paintFallbackSquare(painter, node, dctx, "atlas-failed");
|
|
9032
|
+
return;
|
|
9033
|
+
}
|
|
9071
9034
|
const r = subRectFor(atlas, node.asset.sprite);
|
|
9072
|
-
if (!r)
|
|
9035
|
+
if (!r) {
|
|
9036
|
+
paintFallbackSquare(painter, node, dctx, "sprite-missing");
|
|
9037
|
+
return;
|
|
9038
|
+
}
|
|
9073
9039
|
src = { x: r.sx, y: r.sy, w: r.sw, h: r.sh };
|
|
9074
9040
|
}
|
|
9075
9041
|
const tw = dctx.projector.tileWidth;
|
|
9076
|
-
const
|
|
9077
|
-
const
|
|
9042
|
+
const fallbackW = dctx.projector.worldPixelDirect ? src ? src.w : tex.width : tw;
|
|
9043
|
+
const fallbackH = dctx.projector.worldPixelDirect ? src ? src.h : tex.height : tw;
|
|
9044
|
+
const w = node.width !== void 0 ? node.width * tw : fallbackW;
|
|
9045
|
+
const h = node.height !== void 0 ? node.height * tw : fallbackH;
|
|
9078
9046
|
const anchor = node.anchor ?? "top-left";
|
|
9079
9047
|
const p = dctx.projector.anchorPoint(node.position, anchor);
|
|
9080
9048
|
const dx = anchor === "top-left" ? p.x : p.x - w / 2;
|
|
@@ -9151,6 +9119,16 @@ var init_DrawShape = __esm({
|
|
|
9151
9119
|
if (node.stroke) painter.strokePoly(pts, node.stroke, node.strokeWidth ?? 1, true);
|
|
9152
9120
|
break;
|
|
9153
9121
|
}
|
|
9122
|
+
case "path": {
|
|
9123
|
+
if (!node.d) break;
|
|
9124
|
+
const base = dctx.projector.project(node.position);
|
|
9125
|
+
const tw = dctx.projector.tileWidth;
|
|
9126
|
+
painter.translate(base.x, base.y);
|
|
9127
|
+
painter.scale(tw, tw);
|
|
9128
|
+
if (node.fill) painter.fillPath(node.d, node.fill);
|
|
9129
|
+
if (node.stroke) painter.strokePath(node.d, node.stroke, (node.strokeWidth ?? 1) / tw);
|
|
9130
|
+
break;
|
|
9131
|
+
}
|
|
9154
9132
|
}
|
|
9155
9133
|
painter.restore();
|
|
9156
9134
|
};
|
|
@@ -9242,6 +9220,19 @@ function paintDrawable(painter, node, dctx) {
|
|
|
9242
9220
|
case "draw-text":
|
|
9243
9221
|
paintText(painter, node, dctx);
|
|
9244
9222
|
break;
|
|
9223
|
+
case "draw-group": {
|
|
9224
|
+
if (!isValidScenePos(node.position)) break;
|
|
9225
|
+
if (!Array.isArray(node.items)) break;
|
|
9226
|
+
const p = dctx.projector.project(node.position);
|
|
9227
|
+
painter.save();
|
|
9228
|
+
painter.translate(p.x, p.y);
|
|
9229
|
+
if (node.scale !== void 0) painter.scale(node.scale, node.scale);
|
|
9230
|
+
if (node.rotate !== void 0) painter.rotate(node.rotate);
|
|
9231
|
+
if (node.opacity !== void 0 && node.opacity !== 1) painter.setAlpha(node.opacity);
|
|
9232
|
+
for (const item of node.items) paintDrawable(painter, item, dctx);
|
|
9233
|
+
painter.restore();
|
|
9234
|
+
break;
|
|
9235
|
+
}
|
|
9245
9236
|
case "draw-sprite-layer":
|
|
9246
9237
|
paintSpriteLayer(painter, node, dctx);
|
|
9247
9238
|
break;
|
|
@@ -9255,6 +9246,7 @@ function paintDrawable(painter, node, dctx) {
|
|
|
9255
9246
|
}
|
|
9256
9247
|
var init_paintDispatch = __esm({
|
|
9257
9248
|
"lib/drawable/paintDispatch.ts"() {
|
|
9249
|
+
init_contract();
|
|
9258
9250
|
init_DrawSprite();
|
|
9259
9251
|
init_DrawShape();
|
|
9260
9252
|
init_DrawText();
|
|
@@ -9272,6 +9264,7 @@ function collectDrawnItems(nodes) {
|
|
|
9272
9264
|
case "draw-sprite":
|
|
9273
9265
|
case "draw-shape":
|
|
9274
9266
|
case "draw-text":
|
|
9267
|
+
case "draw-group":
|
|
9275
9268
|
if (isValidScenePos(n.position)) out.push({ pos: n.position, id: n.id });
|
|
9276
9269
|
break;
|
|
9277
9270
|
case "draw-sprite-layer":
|
|
@@ -9315,6 +9308,8 @@ function Canvas2D({
|
|
|
9315
9308
|
keyUpMap,
|
|
9316
9309
|
camera = "pan-zoom",
|
|
9317
9310
|
scale = 0.4,
|
|
9311
|
+
tileWidth,
|
|
9312
|
+
fit = false,
|
|
9318
9313
|
showMinimap = true,
|
|
9319
9314
|
followTarget,
|
|
9320
9315
|
cameraPos,
|
|
@@ -9357,9 +9352,32 @@ function Canvas2D({
|
|
|
9357
9352
|
observer2.observe(el);
|
|
9358
9353
|
return () => observer2.disconnect();
|
|
9359
9354
|
}, []);
|
|
9360
|
-
const
|
|
9361
|
-
const
|
|
9362
|
-
const
|
|
9355
|
+
const [atlasVersion, setAtlasVersion] = useState(0);
|
|
9356
|
+
const bumpAtlas = useCallback(() => setAtlasVersion((v) => v + 1), []);
|
|
9357
|
+
const detectedTileWidth = useMemo(() => {
|
|
9358
|
+
for (const n of drawables ?? []) {
|
|
9359
|
+
const refs = [];
|
|
9360
|
+
if (n.type === "draw-sprite") refs.push(n.asset);
|
|
9361
|
+
else if (n.type === "draw-sprite-layer") for (const it of n.items) refs.push(it.asset);
|
|
9362
|
+
for (const a of refs) {
|
|
9363
|
+
if (a && isAtlasAsset(a) && a.atlas) {
|
|
9364
|
+
const atlas = getAtlas(a.atlas, bumpAtlas);
|
|
9365
|
+
if (atlas) {
|
|
9366
|
+
if ("tileWidth" in atlas) return atlas.tileWidth;
|
|
9367
|
+
if ("subTextures" in atlas) {
|
|
9368
|
+
const first = Object.values(atlas.subTextures)[0];
|
|
9369
|
+
if (first && typeof first.width === "number") return first.width;
|
|
9370
|
+
}
|
|
9371
|
+
}
|
|
9372
|
+
}
|
|
9373
|
+
}
|
|
9374
|
+
}
|
|
9375
|
+
return void 0;
|
|
9376
|
+
}, [drawables, atlasVersion]);
|
|
9377
|
+
const nativeTileW = tileWidth ?? detectedTileWidth ?? TILE_WIDTH;
|
|
9378
|
+
const scaledTileWidth = nativeTileW;
|
|
9379
|
+
const scaledFloorHeight = nativeTileW / 2;
|
|
9380
|
+
const scaledDiamondTopY = nativeTileW * (DIAMOND_TOP_Y / TILE_WIDTH);
|
|
9363
9381
|
const drawnItems = useMemo(() => collectDrawnItems(drawables ?? []), [drawables]);
|
|
9364
9382
|
const scenePositions = useMemo(() => drawnItems.map((i) => i.pos), [drawnItems]);
|
|
9365
9383
|
const hitIndex = useMemo(() => buildHitIndex(drawnItems), [drawnItems]);
|
|
@@ -9377,14 +9395,36 @@ function Canvas2D({
|
|
|
9377
9395
|
if (isFree || projection === "flat" || projection === "side") return 0;
|
|
9378
9396
|
return (gridExtent.height - 1) * (scaledTileWidth / 2);
|
|
9379
9397
|
}, [isFree, projection, gridExtent.height, scaledTileWidth]);
|
|
9398
|
+
const effectiveZoom = useMemo(() => {
|
|
9399
|
+
if (isFree || projection === "side") return scale;
|
|
9400
|
+
if (!fit) {
|
|
9401
|
+
const z2 = TILE_WIDTH * scale * scale / nativeTileW;
|
|
9402
|
+
return Number.isFinite(z2) && z2 > 0 ? z2 : scale;
|
|
9403
|
+
}
|
|
9404
|
+
if (!viewportSize.width || gridExtent.width < 2 || gridExtent.height < 2) return scale;
|
|
9405
|
+
let boardW;
|
|
9406
|
+
let boardH;
|
|
9407
|
+
if (projection === "flat") {
|
|
9408
|
+
boardW = gridExtent.width * nativeTileW;
|
|
9409
|
+
boardH = gridExtent.height * nativeTileW;
|
|
9410
|
+
} else if (projection === "hex") {
|
|
9411
|
+
boardW = (gridExtent.width + 0.5) * nativeTileW;
|
|
9412
|
+
boardH = gridExtent.height * (nativeTileW / 2) * 0.75 + nativeTileW / 2;
|
|
9413
|
+
} else {
|
|
9414
|
+
boardW = (gridExtent.width + gridExtent.height) * (nativeTileW / 2);
|
|
9415
|
+
boardH = (gridExtent.width + gridExtent.height) * (nativeTileW / 4);
|
|
9416
|
+
}
|
|
9417
|
+
const z = Math.min(viewportSize.width * 0.85 / boardW, viewportSize.height * 0.85 / boardH);
|
|
9418
|
+
return Number.isFinite(z) && z > 0 ? z : scale;
|
|
9419
|
+
}, [isFree, projection, fit, viewportSize, gridExtent, nativeTileW, scale]);
|
|
9380
9420
|
const projector = useMemo(
|
|
9381
|
-
() => create2DProjector({
|
|
9382
|
-
[
|
|
9421
|
+
() => create2DProjector({ tileWidth: nativeTileW, baseOffsetX, layout }),
|
|
9422
|
+
[nativeTileW, baseOffsetX, layout]
|
|
9383
9423
|
);
|
|
9384
9424
|
const unproject = useCallback((screenX, screenY) => {
|
|
9385
9425
|
if (projection === "free" || projection === "side") return { x: Math.round(screenX), y: Math.round(screenY) };
|
|
9386
|
-
return screenToIso(screenX, screenY,
|
|
9387
|
-
}, [projection,
|
|
9426
|
+
return screenToIso(screenX, screenY, nativeTileW, baseOffsetX, projection);
|
|
9427
|
+
}, [projection, nativeTileW, baseOffsetX]);
|
|
9388
9428
|
const bgUrls = useMemo(() => backgroundImage ? [backgroundImage.url] : [], [backgroundImage]);
|
|
9389
9429
|
const { getImage, pendingCount: _imagePendingCount } = useImageCache(bgUrls);
|
|
9390
9430
|
useEffect(() => {
|
|
@@ -9411,9 +9451,7 @@ function Canvas2D({
|
|
|
9411
9451
|
zoomAtPoint,
|
|
9412
9452
|
screenToWorld,
|
|
9413
9453
|
lerpToTarget
|
|
9414
|
-
} = useCamera({ zoom:
|
|
9415
|
-
const [atlasVersion, setAtlasVersion] = useState(0);
|
|
9416
|
-
const bumpAtlas = useCallback(() => setAtlasVersion((v) => v + 1), []);
|
|
9454
|
+
} = useCamera({ zoom: effectiveZoom });
|
|
9417
9455
|
const miniMapTiles = useMemo(() => {
|
|
9418
9456
|
if (!showMinimap) return [];
|
|
9419
9457
|
const color = MINIMAP_TERRAIN_COLORS.default;
|
|
@@ -9488,6 +9526,13 @@ function Canvas2D({
|
|
|
9488
9526
|
useEffect(() => {
|
|
9489
9527
|
draw();
|
|
9490
9528
|
}, [_imagePendingCount, draw]);
|
|
9529
|
+
const userZoomedRef = useRef(false);
|
|
9530
|
+
useEffect(() => {
|
|
9531
|
+
if (userZoomedRef.current) return;
|
|
9532
|
+
if (cameraRef.current.zoom === effectiveZoom) return;
|
|
9533
|
+
cameraRef.current.zoom = effectiveZoom;
|
|
9534
|
+
draw();
|
|
9535
|
+
}, [effectiveZoom, cameraRef, draw]);
|
|
9491
9536
|
useEffect(() => {
|
|
9492
9537
|
draw();
|
|
9493
9538
|
}, [atlasVersion, draw]);
|
|
@@ -9544,7 +9589,9 @@ function Canvas2D({
|
|
|
9544
9589
|
if (tileLeaveEvent) eventBus.emit(`UI:${tileLeaveEvent}`, {});
|
|
9545
9590
|
}, [handleMouseLeave, tileLeaveEvent, eventBus]);
|
|
9546
9591
|
const applyZoom = useCallback((factor, centerX, centerY) => {
|
|
9547
|
-
if (enableCamera)
|
|
9592
|
+
if (!enableCamera) return;
|
|
9593
|
+
userZoomedRef.current = true;
|
|
9594
|
+
zoomAtPoint(factor, centerX, centerY, viewportSize, () => draw());
|
|
9548
9595
|
}, [enableCamera, zoomAtPoint, viewportSize, draw]);
|
|
9549
9596
|
const applyPanDelta = useCallback((dx, dy) => {
|
|
9550
9597
|
if (enableCamera) panBy(dx, dy, () => draw());
|
|
@@ -9729,6 +9776,8 @@ function Canvas({
|
|
|
9729
9776
|
isLoading,
|
|
9730
9777
|
unitScale,
|
|
9731
9778
|
showMinimap,
|
|
9779
|
+
fit,
|
|
9780
|
+
tileWidth,
|
|
9732
9781
|
backgroundImage,
|
|
9733
9782
|
backgroundColor,
|
|
9734
9783
|
worldWidth,
|
|
@@ -9786,6 +9835,8 @@ function Canvas({
|
|
|
9786
9835
|
projection,
|
|
9787
9836
|
camera: to2DCamera(camera?.mode),
|
|
9788
9837
|
...zoom !== void 0 ? { scale: zoom } : {},
|
|
9838
|
+
...fit !== void 0 ? { fit } : {},
|
|
9839
|
+
...tileWidth !== void 0 ? { tileWidth } : {},
|
|
9789
9840
|
...camera?.target !== void 0 ? { followTarget: camera.target } : {},
|
|
9790
9841
|
...camera?.pos !== void 0 ? { cameraPos: camera.pos } : {},
|
|
9791
9842
|
showMinimap,
|
|
@@ -9812,32 +9863,6 @@ var init_Canvas = __esm({
|
|
|
9812
9863
|
Canvas.displayName = "Canvas";
|
|
9813
9864
|
}
|
|
9814
9865
|
});
|
|
9815
|
-
function SvgDrawShapeLayer({
|
|
9816
|
-
items,
|
|
9817
|
-
fill,
|
|
9818
|
-
stroke,
|
|
9819
|
-
strokeWidth,
|
|
9820
|
-
opacity
|
|
9821
|
-
}) {
|
|
9822
|
-
return /* @__PURE__ */ jsx("g", { children: items.map(({ id, ...shape }) => /* @__PURE__ */ jsx(
|
|
9823
|
-
SvgDrawShape,
|
|
9824
|
-
{
|
|
9825
|
-
...shape,
|
|
9826
|
-
fill: shape.fill ?? fill,
|
|
9827
|
-
stroke: shape.stroke ?? stroke,
|
|
9828
|
-
strokeWidth: shape.strokeWidth ?? strokeWidth,
|
|
9829
|
-
opacity: shape.opacity ?? opacity
|
|
9830
|
-
},
|
|
9831
|
-
id
|
|
9832
|
-
)) });
|
|
9833
|
-
}
|
|
9834
|
-
var init_SvgDrawShapeLayer = __esm({
|
|
9835
|
-
"components/game/molecules/SvgDrawShapeLayer.tsx"() {
|
|
9836
|
-
"use client";
|
|
9837
|
-
init_SvgDrawShape();
|
|
9838
|
-
SvgDrawShapeLayer.displayName = "SvgDrawShapeLayer";
|
|
9839
|
-
}
|
|
9840
|
-
});
|
|
9841
9866
|
function GameAudioToggle({
|
|
9842
9867
|
size = "sm",
|
|
9843
9868
|
className,
|
|
@@ -23804,6 +23829,8 @@ function DataList({
|
|
|
23804
23829
|
hasMore,
|
|
23805
23830
|
children,
|
|
23806
23831
|
pageSize = 5,
|
|
23832
|
+
sortBy,
|
|
23833
|
+
sortDirection,
|
|
23807
23834
|
renderItem: schemaRenderItem,
|
|
23808
23835
|
dragGroup,
|
|
23809
23836
|
accepts,
|
|
@@ -23832,7 +23859,11 @@ function DataList({
|
|
|
23832
23859
|
dndItemIdField,
|
|
23833
23860
|
dndRoot
|
|
23834
23861
|
});
|
|
23835
|
-
const
|
|
23862
|
+
const orderedData = dnd.orderedItems;
|
|
23863
|
+
const allData = React85__default.useMemo(
|
|
23864
|
+
() => sortRows(orderedData, sortBy, sortDirection),
|
|
23865
|
+
[orderedData, sortBy, sortDirection]
|
|
23866
|
+
);
|
|
23836
23867
|
const data = pageSize > 0 ? allData.slice(0, visibleCount) : allData;
|
|
23837
23868
|
const hasMoreLocal = pageSize > 0 && visibleCount < allData.length;
|
|
23838
23869
|
const hasRenderProp = typeof children === "function";
|
|
@@ -23869,7 +23900,7 @@ function DataList({
|
|
|
23869
23900
|
};
|
|
23870
23901
|
eventBus.emit(`UI:${action.event}`, payload);
|
|
23871
23902
|
};
|
|
23872
|
-
const renderItemActions = (itemData) => {
|
|
23903
|
+
const renderItemActions = (itemData, onPrimary = false) => {
|
|
23873
23904
|
if (!itemActions || itemActions.length === 0) return null;
|
|
23874
23905
|
const inline = maxInlineActions != null ? itemActions.slice(0, maxInlineActions) : itemActions;
|
|
23875
23906
|
const overflow = maxInlineActions != null ? itemActions.slice(maxInlineActions) : [];
|
|
@@ -23882,7 +23913,12 @@ function DataList({
|
|
|
23882
23913
|
onClick: handleActionClick(action, itemData),
|
|
23883
23914
|
"data-testid": `action-${action.event}`,
|
|
23884
23915
|
"data-row-id": String(itemData.id),
|
|
23885
|
-
className: cn(
|
|
23916
|
+
className: cn(
|
|
23917
|
+
action.variant === "danger" && "text-error hover:bg-error/10",
|
|
23918
|
+
// Must sit on the Button itself: the variant's own text colour
|
|
23919
|
+
// beats an inherited one from the row wrapper.
|
|
23920
|
+
onPrimary && "!text-primary-foreground hover:bg-primary-foreground/15"
|
|
23921
|
+
),
|
|
23886
23922
|
children: [
|
|
23887
23923
|
action.icon && renderIconInput2(action.icon, { size: "xs", className: "mr-1" }),
|
|
23888
23924
|
action.label
|
|
@@ -23982,7 +24018,11 @@ function DataList({
|
|
|
23982
24018
|
metaFields.length > 0 && /* @__PURE__ */ jsx(HStack, { gap: "xs", className: "mt-1 flex-wrap", children: metaFields.map((f3) => {
|
|
23983
24019
|
const v = getNestedValue(itemData, f3.name);
|
|
23984
24020
|
if (v === void 0 || v === null || v === "") return null;
|
|
23985
|
-
return f3.variant === "badge" ?
|
|
24021
|
+
return f3.variant === "badge" ? (
|
|
24022
|
+
// `format` applies here too — a boolean field badged
|
|
24023
|
+
// without it renders the raw "false" instead of "No".
|
|
24024
|
+
/* @__PURE__ */ jsx(Badge, { variant: statusVariant3(String(v)), children: formatValue2(v, f3.format) }, f3.name)
|
|
24025
|
+
) : /* @__PURE__ */ jsx(
|
|
23986
24026
|
Typography,
|
|
23987
24027
|
{
|
|
23988
24028
|
variant: "caption",
|
|
@@ -24001,7 +24041,7 @@ function DataList({
|
|
|
24001
24041
|
children: formatDate(timestamp)
|
|
24002
24042
|
}
|
|
24003
24043
|
) : /* @__PURE__ */ jsx("span", {}),
|
|
24004
|
-
renderItemActions(itemData)
|
|
24044
|
+
renderItemActions(itemData, isSent)
|
|
24005
24045
|
] })
|
|
24006
24046
|
]
|
|
24007
24047
|
}
|
|
@@ -24094,7 +24134,7 @@ function DataList({
|
|
|
24094
24134
|
if (val === void 0 || val === null) return null;
|
|
24095
24135
|
return /* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "items-center flex-shrink-0", children: [
|
|
24096
24136
|
field.icon && renderIconInput2(field.icon, { size: "xs" }),
|
|
24097
|
-
/* @__PURE__ */ jsx(Badge, { variant: statusVariant3(String(val)), children:
|
|
24137
|
+
/* @__PURE__ */ jsx(Badge, { variant: statusVariant3(String(val)), children: formatValue2(val, field.format) })
|
|
24098
24138
|
] }, field.name);
|
|
24099
24139
|
})
|
|
24100
24140
|
] }),
|
|
@@ -24333,6 +24373,182 @@ var init_FormSection = __esm({
|
|
|
24333
24373
|
FormActions.displayName = "FormActions";
|
|
24334
24374
|
}
|
|
24335
24375
|
});
|
|
24376
|
+
var ALL_CATEGORY, MAX_RENDERED, GridPicker;
|
|
24377
|
+
var init_GridPicker = __esm({
|
|
24378
|
+
"components/core/molecules/GridPicker.tsx"() {
|
|
24379
|
+
"use client";
|
|
24380
|
+
init_cn();
|
|
24381
|
+
init_Input();
|
|
24382
|
+
init_Badge();
|
|
24383
|
+
init_Stack();
|
|
24384
|
+
ALL_CATEGORY = "__all__";
|
|
24385
|
+
MAX_RENDERED = 300;
|
|
24386
|
+
GridPicker = ({
|
|
24387
|
+
items,
|
|
24388
|
+
value,
|
|
24389
|
+
onChange,
|
|
24390
|
+
categories,
|
|
24391
|
+
searchPlaceholder,
|
|
24392
|
+
renderThumbnail,
|
|
24393
|
+
cellSize = 32,
|
|
24394
|
+
className
|
|
24395
|
+
}) => {
|
|
24396
|
+
const [search, setSearch] = useState("");
|
|
24397
|
+
const [activeCategory, setActiveCategory] = useState(ALL_CATEGORY);
|
|
24398
|
+
const gridRef = useRef(null);
|
|
24399
|
+
const categoryChips = useMemo(() => {
|
|
24400
|
+
if (categories !== void 0) return categories;
|
|
24401
|
+
const seen = [];
|
|
24402
|
+
for (const item of items) {
|
|
24403
|
+
if (!seen.includes(item.category)) seen.push(item.category);
|
|
24404
|
+
}
|
|
24405
|
+
return seen;
|
|
24406
|
+
}, [categories, items]);
|
|
24407
|
+
const filtered = useMemo(() => {
|
|
24408
|
+
const needle = search.trim().toLowerCase();
|
|
24409
|
+
return items.filter((item) => {
|
|
24410
|
+
const matchesCategory = activeCategory === ALL_CATEGORY || item.category === activeCategory;
|
|
24411
|
+
const matchesSearch = needle === "" || item.label.toLowerCase().includes(needle) || item.keywords !== void 0 && item.keywords.some((k) => k.toLowerCase().includes(needle));
|
|
24412
|
+
return matchesCategory && matchesSearch;
|
|
24413
|
+
});
|
|
24414
|
+
}, [items, search, activeCategory]);
|
|
24415
|
+
const visible = useMemo(() => filtered.slice(0, MAX_RENDERED), [filtered]);
|
|
24416
|
+
const truncated = filtered.length - visible.length;
|
|
24417
|
+
const select = useCallback(
|
|
24418
|
+
(item) => {
|
|
24419
|
+
onChange(item.id);
|
|
24420
|
+
},
|
|
24421
|
+
[onChange]
|
|
24422
|
+
);
|
|
24423
|
+
const handleKeyDown = useCallback(
|
|
24424
|
+
(e, index) => {
|
|
24425
|
+
const cells = gridRef.current?.querySelectorAll(
|
|
24426
|
+
"[data-gridpicker-cell]"
|
|
24427
|
+
);
|
|
24428
|
+
if (cells === void 0 || cells.length === 0) return;
|
|
24429
|
+
const columns = (() => {
|
|
24430
|
+
const grid = gridRef.current;
|
|
24431
|
+
if (grid === null) return 1;
|
|
24432
|
+
const style = window.getComputedStyle(grid);
|
|
24433
|
+
const cols = style.gridTemplateColumns.split(" ").filter(Boolean).length;
|
|
24434
|
+
return cols > 0 ? cols : 1;
|
|
24435
|
+
})();
|
|
24436
|
+
let next = -1;
|
|
24437
|
+
if (e.key === "ArrowRight") next = index + 1;
|
|
24438
|
+
else if (e.key === "ArrowLeft") next = index - 1;
|
|
24439
|
+
else if (e.key === "ArrowDown") next = index + columns;
|
|
24440
|
+
else if (e.key === "ArrowUp") next = index - columns;
|
|
24441
|
+
else if (e.key === "Enter" || e.key === " ") {
|
|
24442
|
+
e.preventDefault();
|
|
24443
|
+
select(filtered[index]);
|
|
24444
|
+
return;
|
|
24445
|
+
} else {
|
|
24446
|
+
return;
|
|
24447
|
+
}
|
|
24448
|
+
e.preventDefault();
|
|
24449
|
+
if (next >= 0 && next < cells.length) {
|
|
24450
|
+
cells[next].focus();
|
|
24451
|
+
}
|
|
24452
|
+
},
|
|
24453
|
+
[filtered, select]
|
|
24454
|
+
);
|
|
24455
|
+
return /* @__PURE__ */ jsxs(VStack, { gap: "sm", className: cn("w-full", className), children: [
|
|
24456
|
+
/* @__PURE__ */ jsx(
|
|
24457
|
+
Input,
|
|
24458
|
+
{
|
|
24459
|
+
type: "search",
|
|
24460
|
+
icon: "search",
|
|
24461
|
+
value: search,
|
|
24462
|
+
placeholder: searchPlaceholder,
|
|
24463
|
+
clearable: true,
|
|
24464
|
+
onClear: () => setSearch(""),
|
|
24465
|
+
onChange: (e) => setSearch(e.target.value)
|
|
24466
|
+
}
|
|
24467
|
+
),
|
|
24468
|
+
categoryChips.length > 0 && /* @__PURE__ */ jsxs(HStack, { gap: "xs", wrap: true, children: [
|
|
24469
|
+
/* @__PURE__ */ jsx(
|
|
24470
|
+
Badge,
|
|
24471
|
+
{
|
|
24472
|
+
variant: activeCategory === ALL_CATEGORY ? "primary" : "neutral",
|
|
24473
|
+
size: "sm",
|
|
24474
|
+
role: "button",
|
|
24475
|
+
tabIndex: 0,
|
|
24476
|
+
"aria-pressed": activeCategory === ALL_CATEGORY,
|
|
24477
|
+
className: "cursor-pointer",
|
|
24478
|
+
onClick: () => setActiveCategory(ALL_CATEGORY),
|
|
24479
|
+
onKeyDown: (e) => {
|
|
24480
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
24481
|
+
e.preventDefault();
|
|
24482
|
+
setActiveCategory(ALL_CATEGORY);
|
|
24483
|
+
}
|
|
24484
|
+
},
|
|
24485
|
+
children: "All"
|
|
24486
|
+
}
|
|
24487
|
+
),
|
|
24488
|
+
categoryChips.map((category) => /* @__PURE__ */ jsx(
|
|
24489
|
+
Badge,
|
|
24490
|
+
{
|
|
24491
|
+
variant: activeCategory === category ? "primary" : "neutral",
|
|
24492
|
+
size: "sm",
|
|
24493
|
+
role: "button",
|
|
24494
|
+
tabIndex: 0,
|
|
24495
|
+
"aria-pressed": activeCategory === category,
|
|
24496
|
+
className: "cursor-pointer",
|
|
24497
|
+
onClick: () => setActiveCategory(category),
|
|
24498
|
+
onKeyDown: (e) => {
|
|
24499
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
24500
|
+
e.preventDefault();
|
|
24501
|
+
setActiveCategory(category);
|
|
24502
|
+
}
|
|
24503
|
+
},
|
|
24504
|
+
children: category
|
|
24505
|
+
},
|
|
24506
|
+
category
|
|
24507
|
+
))
|
|
24508
|
+
] }),
|
|
24509
|
+
/* @__PURE__ */ jsx(
|
|
24510
|
+
"div",
|
|
24511
|
+
{
|
|
24512
|
+
ref: gridRef,
|
|
24513
|
+
role: "listbox",
|
|
24514
|
+
className: "grid gap-1 overflow-y-auto max-h-64 p-1",
|
|
24515
|
+
style: {
|
|
24516
|
+
gridTemplateColumns: `repeat(auto-fill, minmax(${cellSize}px, 1fr))`
|
|
24517
|
+
},
|
|
24518
|
+
children: visible.map((item, index) => {
|
|
24519
|
+
const selected = item.id === value;
|
|
24520
|
+
return /* @__PURE__ */ jsx(
|
|
24521
|
+
"button",
|
|
24522
|
+
{
|
|
24523
|
+
type: "button",
|
|
24524
|
+
role: "option",
|
|
24525
|
+
"aria-selected": selected,
|
|
24526
|
+
"aria-label": item.label,
|
|
24527
|
+
title: item.label,
|
|
24528
|
+
"data-gridpicker-cell": true,
|
|
24529
|
+
tabIndex: selected || value === void 0 && index === 0 ? 0 : -1,
|
|
24530
|
+
onClick: () => select(item),
|
|
24531
|
+
onKeyDown: (e) => handleKeyDown(e, index),
|
|
24532
|
+
className: cn(
|
|
24533
|
+
"flex items-center justify-center rounded-sm",
|
|
24534
|
+
"transition-colors hover:bg-muted",
|
|
24535
|
+
"focus:outline-none focus:ring-1 focus:ring-ring",
|
|
24536
|
+
selected && "bg-primary/10 ring-1 ring-primary"
|
|
24537
|
+
),
|
|
24538
|
+
style: { width: cellSize, height: cellSize },
|
|
24539
|
+
children: renderThumbnail(item)
|
|
24540
|
+
},
|
|
24541
|
+
item.id
|
|
24542
|
+
);
|
|
24543
|
+
})
|
|
24544
|
+
}
|
|
24545
|
+
),
|
|
24546
|
+
truncated > 0 && /* @__PURE__ */ jsx("div", { className: "px-1 text-xs text-muted-foreground", children: `+${truncated} more \u2014 refine your search` })
|
|
24547
|
+
] });
|
|
24548
|
+
};
|
|
24549
|
+
GridPicker.displayName = "GridPicker";
|
|
24550
|
+
}
|
|
24551
|
+
});
|
|
24336
24552
|
function fileIcon(name) {
|
|
24337
24553
|
const ext = name.split(".").pop()?.toLowerCase() ?? "";
|
|
24338
24554
|
switch (ext) {
|
|
@@ -25361,9 +25577,16 @@ var init_Popover = __esm({
|
|
|
25361
25577
|
position = "bottom",
|
|
25362
25578
|
trigger = "click",
|
|
25363
25579
|
showArrow = true,
|
|
25580
|
+
open,
|
|
25581
|
+
onOpenChange,
|
|
25364
25582
|
className
|
|
25365
25583
|
}) => {
|
|
25366
|
-
const [
|
|
25584
|
+
const [uncontrolledOpen, setUncontrolledOpen] = useState(false);
|
|
25585
|
+
const isOpen = open !== void 0 ? open : uncontrolledOpen;
|
|
25586
|
+
const setIsOpen = (next) => {
|
|
25587
|
+
if (open === void 0) setUncontrolledOpen(next);
|
|
25588
|
+
onOpenChange?.(next);
|
|
25589
|
+
};
|
|
25367
25590
|
const [triggerRect, setTriggerRect] = useState(null);
|
|
25368
25591
|
const [popoverWidth, setPopoverWidth] = useState(0);
|
|
25369
25592
|
const triggerRef = useRef(null);
|
|
@@ -25396,6 +25619,23 @@ var init_Popover = __esm({
|
|
|
25396
25619
|
updatePosition();
|
|
25397
25620
|
}
|
|
25398
25621
|
}, [isOpen]);
|
|
25622
|
+
useEffect(() => {
|
|
25623
|
+
if (!isOpen) return;
|
|
25624
|
+
let raf = 0;
|
|
25625
|
+
let lastTop = Number.NaN;
|
|
25626
|
+
let lastLeft = Number.NaN;
|
|
25627
|
+
const track = () => {
|
|
25628
|
+
const rect = triggerRef.current?.getBoundingClientRect();
|
|
25629
|
+
if (rect && (rect.top !== lastTop || rect.left !== lastLeft)) {
|
|
25630
|
+
lastTop = rect.top;
|
|
25631
|
+
lastLeft = rect.left;
|
|
25632
|
+
updatePosition();
|
|
25633
|
+
}
|
|
25634
|
+
raf = requestAnimationFrame(track);
|
|
25635
|
+
};
|
|
25636
|
+
raf = requestAnimationFrame(track);
|
|
25637
|
+
return () => cancelAnimationFrame(raf);
|
|
25638
|
+
}, [isOpen]);
|
|
25399
25639
|
useEffect(() => {
|
|
25400
25640
|
if (!mounted) setPopoverWidth(0);
|
|
25401
25641
|
}, [mounted]);
|
|
@@ -26744,6 +26984,80 @@ var init_FlipCard = __esm({
|
|
|
26744
26984
|
FlipCard.displayName = "FlipCard";
|
|
26745
26985
|
}
|
|
26746
26986
|
});
|
|
26987
|
+
var EMOJI_ITEMS, EmojiPicker;
|
|
26988
|
+
var init_EmojiPicker = __esm({
|
|
26989
|
+
"components/core/molecules/EmojiPicker.tsx"() {
|
|
26990
|
+
"use client";
|
|
26991
|
+
init_useEventBus();
|
|
26992
|
+
init_Button();
|
|
26993
|
+
init_GridPicker();
|
|
26994
|
+
init_Popover();
|
|
26995
|
+
EMOJI_ITEMS = (() => {
|
|
26996
|
+
const items = [];
|
|
26997
|
+
for (const name of ordered) {
|
|
26998
|
+
const entry = lib[name];
|
|
26999
|
+
if (entry === void 0 || entry.char === null || entry.char === "") continue;
|
|
27000
|
+
items.push({
|
|
27001
|
+
id: entry.char,
|
|
27002
|
+
label: name.replace(/_/g, " "),
|
|
27003
|
+
category: entry.category.replace(/_/g, " "),
|
|
27004
|
+
keywords: entry.keywords
|
|
27005
|
+
});
|
|
27006
|
+
}
|
|
27007
|
+
return items;
|
|
27008
|
+
})();
|
|
27009
|
+
EmojiPicker = ({
|
|
27010
|
+
pickEvent,
|
|
27011
|
+
position = "top",
|
|
27012
|
+
triggerIcon = "smile",
|
|
27013
|
+
triggerLabel = "Add emoji",
|
|
27014
|
+
className
|
|
27015
|
+
}) => {
|
|
27016
|
+
const eventBus = useEventBus();
|
|
27017
|
+
const [open, setOpen] = useState(false);
|
|
27018
|
+
const handlePick = (glyph) => {
|
|
27019
|
+
if (pickEvent !== void 0) {
|
|
27020
|
+
const payload = { emoji: glyph };
|
|
27021
|
+
eventBus.emit(`UI:${pickEvent}`, payload);
|
|
27022
|
+
}
|
|
27023
|
+
setOpen(false);
|
|
27024
|
+
};
|
|
27025
|
+
return /* @__PURE__ */ jsx(
|
|
27026
|
+
Popover,
|
|
27027
|
+
{
|
|
27028
|
+
position,
|
|
27029
|
+
trigger: "click",
|
|
27030
|
+
showArrow: false,
|
|
27031
|
+
open,
|
|
27032
|
+
onOpenChange: setOpen,
|
|
27033
|
+
content: /* @__PURE__ */ jsx(
|
|
27034
|
+
GridPicker,
|
|
27035
|
+
{
|
|
27036
|
+
items: EMOJI_ITEMS,
|
|
27037
|
+
onChange: handlePick,
|
|
27038
|
+
searchPlaceholder: "Search emoji\u2026",
|
|
27039
|
+
renderThumbnail: (item) => /* @__PURE__ */ jsx("span", { className: "text-xl leading-none", "aria-hidden": "true", children: item.id }),
|
|
27040
|
+
cellSize: 32,
|
|
27041
|
+
className: "w-80"
|
|
27042
|
+
}
|
|
27043
|
+
),
|
|
27044
|
+
children: /* @__PURE__ */ jsx(
|
|
27045
|
+
Button,
|
|
27046
|
+
{
|
|
27047
|
+
variant: "ghost",
|
|
27048
|
+
icon: triggerIcon,
|
|
27049
|
+
"aria-label": triggerLabel,
|
|
27050
|
+
title: triggerLabel,
|
|
27051
|
+
className,
|
|
27052
|
+
"data-testid": "emoji-picker-trigger"
|
|
27053
|
+
}
|
|
27054
|
+
)
|
|
27055
|
+
}
|
|
27056
|
+
);
|
|
27057
|
+
};
|
|
27058
|
+
EmojiPicker.displayName = "EmojiPicker";
|
|
27059
|
+
}
|
|
27060
|
+
});
|
|
26747
27061
|
function toISODate(d) {
|
|
26748
27062
|
return d.toISOString().slice(0, 10);
|
|
26749
27063
|
}
|
|
@@ -27696,13 +28010,13 @@ var init_MapView = __esm({
|
|
|
27696
28010
|
shadowSize: [41, 41]
|
|
27697
28011
|
});
|
|
27698
28012
|
L.Marker.prototype.options.icon = defaultIcon;
|
|
27699
|
-
const { useEffect:
|
|
28013
|
+
const { useEffect: useEffect62, useRef: useRef61, useCallback: useCallback95, useState: useState93 } = React85__default;
|
|
27700
28014
|
const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
|
|
27701
28015
|
const { useEventBus: useEventBus2 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
|
|
27702
28016
|
function MapUpdater({ centerLat, centerLng, zoom }) {
|
|
27703
28017
|
const map = useMap();
|
|
27704
28018
|
const prevRef = useRef61({ centerLat, centerLng, zoom });
|
|
27705
|
-
|
|
28019
|
+
useEffect62(() => {
|
|
27706
28020
|
const prev = prevRef.current;
|
|
27707
28021
|
if (prev.centerLat !== centerLat || prev.centerLng !== centerLng || prev.zoom !== zoom) {
|
|
27708
28022
|
map.setView([centerLat, centerLng], zoom);
|
|
@@ -27713,7 +28027,7 @@ var init_MapView = __esm({
|
|
|
27713
28027
|
}
|
|
27714
28028
|
function MapClickHandler({ onMapClick }) {
|
|
27715
28029
|
const map = useMap();
|
|
27716
|
-
|
|
28030
|
+
useEffect62(() => {
|
|
27717
28031
|
if (!onMapClick) return;
|
|
27718
28032
|
const handler = (e) => {
|
|
27719
28033
|
onMapClick(e.latlng.lat, e.latlng.lng);
|
|
@@ -27741,7 +28055,7 @@ var init_MapView = __esm({
|
|
|
27741
28055
|
showAttribution = true
|
|
27742
28056
|
}) {
|
|
27743
28057
|
const eventBus = useEventBus2();
|
|
27744
|
-
const [clickedPosition, setClickedPosition] =
|
|
28058
|
+
const [clickedPosition, setClickedPosition] = useState93(null);
|
|
27745
28059
|
const handleMapClick = useCallback95((lat, lng) => {
|
|
27746
28060
|
if (showClickedPin) {
|
|
27747
28061
|
setClickedPosition({ lat, lng });
|
|
@@ -28586,6 +28900,7 @@ function TableView({
|
|
|
28586
28900
|
fields,
|
|
28587
28901
|
itemActions,
|
|
28588
28902
|
maxInlineActions,
|
|
28903
|
+
itemClickEvent,
|
|
28589
28904
|
selectable = false,
|
|
28590
28905
|
selectEvent,
|
|
28591
28906
|
selectedIds,
|
|
@@ -28630,9 +28945,9 @@ function TableView({
|
|
|
28630
28945
|
dndItemIdField,
|
|
28631
28946
|
dndRoot
|
|
28632
28947
|
});
|
|
28633
|
-
const
|
|
28634
|
-
const data = pageSize > 0 ?
|
|
28635
|
-
const hasMore = pageSize > 0 && visibleCount <
|
|
28948
|
+
const ordered2 = dnd.orderedItems;
|
|
28949
|
+
const data = pageSize > 0 ? ordered2.slice(0, visibleCount) : ordered2;
|
|
28950
|
+
const hasMore = pageSize > 0 && visibleCount < ordered2.length;
|
|
28636
28951
|
const hasRenderProp = typeof children === "function";
|
|
28637
28952
|
const idField = dndItemIdField ?? "id";
|
|
28638
28953
|
const isCoarsePointer = useMediaQuery("(pointer: coarse)");
|
|
@@ -28685,6 +29000,14 @@ function TableView({
|
|
|
28685
29000
|
};
|
|
28686
29001
|
eventBus.emit(`UI:${action.event}`, payload);
|
|
28687
29002
|
};
|
|
29003
|
+
const handleRowClick = (row) => () => {
|
|
29004
|
+
if (!itemClickEvent) return;
|
|
29005
|
+
const payload = {
|
|
29006
|
+
id: row.id,
|
|
29007
|
+
row
|
|
29008
|
+
};
|
|
29009
|
+
eventBus.emit(`UI:${itemClickEvent}`, payload);
|
|
29010
|
+
};
|
|
28688
29011
|
const colFloors = React85__default.useMemo(
|
|
28689
29012
|
() => colDefs.map((col) => {
|
|
28690
29013
|
const longest = data.reduce((widest, row) => {
|
|
@@ -28761,10 +29084,12 @@ function TableView({
|
|
|
28761
29084
|
role: "row",
|
|
28762
29085
|
"data-entity-row": true,
|
|
28763
29086
|
"data-entity-id": id,
|
|
29087
|
+
onClick: itemClickEvent ? handleRowClick(row) : void 0,
|
|
28764
29088
|
style: !hasRenderProp ? { gridTemplateColumns } : void 0,
|
|
28765
29089
|
className: cn(
|
|
28766
29090
|
"group items-center gap-3 transition-colors duration-fast",
|
|
28767
29091
|
hasRenderProp ? "flex" : "grid",
|
|
29092
|
+
itemClickEvent && "cursor-pointer",
|
|
28768
29093
|
lk.rowPad,
|
|
28769
29094
|
lk.divider && "border-b border-[var(--color-border)]",
|
|
28770
29095
|
lk.striped && index % 2 === 1 && "bg-[var(--color-surface-subtle)]",
|
|
@@ -28772,7 +29097,7 @@ function TableView({
|
|
|
28772
29097
|
look === "bordered" && "[&>*]:border-r [&>*]:border-[var(--color-border)] [&>*:last-child]:border-r-0"
|
|
28773
29098
|
),
|
|
28774
29099
|
children: [
|
|
28775
|
-
selectable && /* @__PURE__ */ jsx(Box, { className: "flex items-center", children: /* @__PURE__ */ jsx(
|
|
29100
|
+
selectable && /* @__PURE__ */ jsx(Box, { className: "flex items-center", onClick: itemClickEvent ? (e) => e.stopPropagation() : void 0, children: /* @__PURE__ */ jsx(
|
|
28776
29101
|
Checkbox,
|
|
28777
29102
|
{
|
|
28778
29103
|
checked: selected.has(id),
|
|
@@ -28797,6 +29122,7 @@ function TableView({
|
|
|
28797
29122
|
HStack,
|
|
28798
29123
|
{
|
|
28799
29124
|
gap: "xs",
|
|
29125
|
+
onClick: itemClickEvent ? (e) => e.stopPropagation() : void 0,
|
|
28800
29126
|
className: cn(
|
|
28801
29127
|
// Pinned: the fixed column tracks routinely overflow the caller's
|
|
28802
29128
|
// scroll container, which used to leave the actions off-screen.
|
|
@@ -28866,7 +29192,7 @@ function TableView({
|
|
|
28866
29192
|
/* @__PURE__ */ jsx(Icon, { name: "chevron-down", size: "xs", className: "mr-1" }),
|
|
28867
29193
|
t("common.showMore"),
|
|
28868
29194
|
" (",
|
|
28869
|
-
t("common.remaining", { count:
|
|
29195
|
+
t("common.remaining", { count: ordered2.length - visibleCount }),
|
|
28870
29196
|
")"
|
|
28871
29197
|
] }) })
|
|
28872
29198
|
]
|
|
@@ -38305,6 +38631,16 @@ var init_DetailPanel = __esm({
|
|
|
38305
38631
|
DetailPanel.displayName = "DetailPanel";
|
|
38306
38632
|
}
|
|
38307
38633
|
});
|
|
38634
|
+
|
|
38635
|
+
// components/game/atoms/DrawGroup.tsx
|
|
38636
|
+
function DrawGroup(_props) {
|
|
38637
|
+
return null;
|
|
38638
|
+
}
|
|
38639
|
+
var init_DrawGroup = __esm({
|
|
38640
|
+
"components/game/atoms/DrawGroup.tsx"() {
|
|
38641
|
+
"use client";
|
|
38642
|
+
}
|
|
38643
|
+
});
|
|
38308
38644
|
function extractTitle(children) {
|
|
38309
38645
|
if (!React85__default.isValidElement(children)) return void 0;
|
|
38310
38646
|
const props = children.props;
|
|
@@ -44008,6 +44344,7 @@ var init_component_registry_generated = __esm({
|
|
|
44008
44344
|
init_DocSidebar();
|
|
44009
44345
|
init_DocTOC();
|
|
44010
44346
|
init_DocumentViewer();
|
|
44347
|
+
init_DrawGroup();
|
|
44011
44348
|
init_DrawShape();
|
|
44012
44349
|
init_DrawShapeLayer();
|
|
44013
44350
|
init_DrawSprite();
|
|
@@ -44017,6 +44354,7 @@ var init_component_registry_generated = __esm({
|
|
|
44017
44354
|
init_Drawer();
|
|
44018
44355
|
init_DrawerSlot();
|
|
44019
44356
|
init_EdgeDecoration();
|
|
44357
|
+
init_EmojiPicker();
|
|
44020
44358
|
init_EmptyState();
|
|
44021
44359
|
init_ErrorBoundary();
|
|
44022
44360
|
init_ErrorState();
|
|
@@ -44151,10 +44489,6 @@ var init_component_registry_generated = __esm({
|
|
|
44151
44489
|
init_SubagentTracePanel();
|
|
44152
44490
|
init_SvgBranch();
|
|
44153
44491
|
init_SvgConnection();
|
|
44154
|
-
init_SvgDrawGroup();
|
|
44155
|
-
init_SvgDrawShape();
|
|
44156
|
-
init_SvgDrawShapeLayer();
|
|
44157
|
-
init_SvgDrawText();
|
|
44158
44492
|
init_SvgFlow();
|
|
44159
44493
|
init_SvgGrid();
|
|
44160
44494
|
init_SvgLobe();
|
|
@@ -44165,7 +44499,6 @@ var init_component_registry_generated = __esm({
|
|
|
44165
44499
|
init_SvgRing();
|
|
44166
44500
|
init_SvgShield();
|
|
44167
44501
|
init_SvgStack();
|
|
44168
|
-
init_SvgStage();
|
|
44169
44502
|
init_SwipeableRow();
|
|
44170
44503
|
init_Switch();
|
|
44171
44504
|
init_TabbedContainer();
|
|
@@ -44279,6 +44612,7 @@ var init_component_registry_generated = __esm({
|
|
|
44279
44612
|
"DocSidebar": DocSidebar,
|
|
44280
44613
|
"DocTOC": DocTOC,
|
|
44281
44614
|
"DocumentViewer": DocumentViewer,
|
|
44615
|
+
"DrawGroup": DrawGroup,
|
|
44282
44616
|
"DrawShape": DrawShape,
|
|
44283
44617
|
"DrawShapeLayer": DrawShapeLayer,
|
|
44284
44618
|
"DrawSprite": DrawSprite,
|
|
@@ -44288,6 +44622,7 @@ var init_component_registry_generated = __esm({
|
|
|
44288
44622
|
"Drawer": Drawer,
|
|
44289
44623
|
"DrawerSlot": DrawerSlot,
|
|
44290
44624
|
"EdgeDecoration": EdgeDecoration,
|
|
44625
|
+
"EmojiPicker": EmojiPicker,
|
|
44291
44626
|
"EmptyState": EmptyState,
|
|
44292
44627
|
"ErrorBoundary": ErrorBoundary,
|
|
44293
44628
|
"ErrorState": ErrorState,
|
|
@@ -44427,10 +44762,6 @@ var init_component_registry_generated = __esm({
|
|
|
44427
44762
|
"SubagentTracePanel": SubagentTracePanel,
|
|
44428
44763
|
"SvgBranch": SvgBranch,
|
|
44429
44764
|
"SvgConnection": SvgConnection,
|
|
44430
|
-
"SvgDrawGroup": SvgDrawGroup,
|
|
44431
|
-
"SvgDrawShape": SvgDrawShape,
|
|
44432
|
-
"SvgDrawShapeLayer": SvgDrawShapeLayer,
|
|
44433
|
-
"SvgDrawText": SvgDrawText,
|
|
44434
44765
|
"SvgFlow": SvgFlow,
|
|
44435
44766
|
"SvgGrid": SvgGrid,
|
|
44436
44767
|
"SvgLobe": SvgLobe,
|
|
@@ -44441,7 +44772,6 @@ var init_component_registry_generated = __esm({
|
|
|
44441
44772
|
"SvgRing": SvgRing,
|
|
44442
44773
|
"SvgShield": SvgShield,
|
|
44443
44774
|
"SvgStack": SvgStack,
|
|
44444
|
-
"SvgStage": SvgStage,
|
|
44445
44775
|
"SwipeableRow": SwipeableRow,
|
|
44446
44776
|
"Switch": Switch,
|
|
44447
44777
|
"TabbedContainer": TabbedContainer,
|
|
@@ -44720,7 +45050,19 @@ function UISlotComponent({
|
|
|
44720
45050
|
const suspenseConfig = useContext(SuspenseConfigContext);
|
|
44721
45051
|
const contained = useContext(SlotContainedContext);
|
|
44722
45052
|
const schemaCtx = useEntitySchemaOptional();
|
|
44723
|
-
const
|
|
45053
|
+
const rawContent = slots[slot];
|
|
45054
|
+
const binding = useEntityBindingSnapshot(rawContent?.sourceTrait);
|
|
45055
|
+
const content = useMemo(() => {
|
|
45056
|
+
if (!rawContent) return rawContent;
|
|
45057
|
+
const resolvedProps = resolveRenderBindingMarkers(
|
|
45058
|
+
rawContent.props,
|
|
45059
|
+
rawContent.sourceTrait,
|
|
45060
|
+
binding.entity,
|
|
45061
|
+
binding.config,
|
|
45062
|
+
binding.state
|
|
45063
|
+
);
|
|
45064
|
+
return resolvedProps === rawContent.props ? rawContent : { ...rawContent, props: resolvedProps };
|
|
45065
|
+
}, [rawContent, binding.entity, binding.config, binding.state]);
|
|
44724
45066
|
if (children !== void 0) {
|
|
44725
45067
|
if (pattern === "clear") {
|
|
44726
45068
|
return null;
|
|
@@ -45064,6 +45406,7 @@ function isPlainConfigObject(value) {
|
|
|
45064
45406
|
return proto === Object.prototype || proto === null;
|
|
45065
45407
|
}
|
|
45066
45408
|
function substituteTraitRefsDeep(value, pathKey) {
|
|
45409
|
+
if (isRenderBindingMarker(value)) return value;
|
|
45067
45410
|
if (typeof value === "string") {
|
|
45068
45411
|
const match = TRAIT_BINDING_RE.exec(value);
|
|
45069
45412
|
if (match) {
|
|
@@ -45136,7 +45479,14 @@ function SlotContentRenderer({
|
|
|
45136
45479
|
onDismiss,
|
|
45137
45480
|
patternPath
|
|
45138
45481
|
}) {
|
|
45139
|
-
const
|
|
45482
|
+
const ambientScope = useTraitScope();
|
|
45483
|
+
const bindingTrait = content.sourceTrait ?? ambientScope?.trait;
|
|
45484
|
+
const binding = useEntityBindingSnapshot(bindingTrait);
|
|
45485
|
+
const liveProps = useMemo(
|
|
45486
|
+
() => resolveRenderBindingMarkers(content.props, bindingTrait, binding.entity, binding.config, binding.state),
|
|
45487
|
+
[content.props, bindingTrait, binding.entity, binding.config, binding.state]
|
|
45488
|
+
);
|
|
45489
|
+
const entityProp = liveProps.entity;
|
|
45140
45490
|
if (content.pattern === "form-section") {
|
|
45141
45491
|
slotLog.debug("SlotContentRenderer:form-section-render", {
|
|
45142
45492
|
contentId: content.id,
|
|
@@ -45167,7 +45517,7 @@ function SlotContentRenderer({
|
|
|
45167
45517
|
const orbitalName = schemaCtx && content.sourceTrait !== void 0 ? schemaCtx.orbitalsByTrait.get(content.sourceTrait) : void 0;
|
|
45168
45518
|
const PatternComponent = getComponentForPattern(content.pattern);
|
|
45169
45519
|
if (PatternComponent) {
|
|
45170
|
-
const childrenConfig =
|
|
45520
|
+
const childrenConfig = liveProps.children;
|
|
45171
45521
|
const isSingleChild = typeof childrenConfig === "string" || typeof childrenConfig === "object" && childrenConfig !== null && !Array.isArray(childrenConfig) && "type" in childrenConfig;
|
|
45172
45522
|
const hasChildren = PATTERNS_WITH_CHILDREN.has(content.pattern) || Array.isArray(childrenConfig) && childrenConfig.length > 0 || isSingleChild;
|
|
45173
45523
|
const isDrawHost = isDrawHostPattern(content.pattern);
|
|
@@ -45178,9 +45528,9 @@ function SlotContentRenderer({
|
|
|
45178
45528
|
fromState: content.fromState,
|
|
45179
45529
|
entity: content.entity
|
|
45180
45530
|
}) : void 0;
|
|
45181
|
-
const incomingChildren =
|
|
45531
|
+
const incomingChildren = liveProps.children;
|
|
45182
45532
|
const childrenIsRenderFn = typeof incomingChildren === "function";
|
|
45183
|
-
const { children: _childrenConfig, ...restPropsNoChildren } =
|
|
45533
|
+
const { children: _childrenConfig, ...restPropsNoChildren } = liveProps;
|
|
45184
45534
|
const restProps = childrenIsRenderFn ? { ...restPropsNoChildren, children: incomingChildren } : restPropsNoChildren;
|
|
45185
45535
|
const nodeSlotOverrides = {};
|
|
45186
45536
|
for (const slotKey of CONTENT_NODE_SLOTS) {
|
|
@@ -45289,7 +45639,7 @@ function SlotContentRenderer({
|
|
|
45289
45639
|
"data-orb-path": patternPath ?? "root",
|
|
45290
45640
|
"data-orb-pattern": content.pattern,
|
|
45291
45641
|
"data-orb-orbital": orbitalName,
|
|
45292
|
-
children:
|
|
45642
|
+
children: liveProps.children ?? /* @__PURE__ */ jsxs(Box, { className: "p-4 text-sm text-muted-foreground border border-dashed border-border rounded", children: [
|
|
45293
45643
|
"Unknown pattern: ",
|
|
45294
45644
|
content.pattern,
|
|
45295
45645
|
content.sourceTrait && /* @__PURE__ */ jsxs(Typography, { variant: "small", className: "ml-2", children: [
|
|
@@ -45361,6 +45711,7 @@ var scopeWrapLog, TRAIT_BINDING_RE, SuspenseConfigContext, SlotContainedContext,
|
|
|
45361
45711
|
var init_UISlotRenderer = __esm({
|
|
45362
45712
|
"components/core/organisms/UISlotRenderer.tsx"() {
|
|
45363
45713
|
"use client";
|
|
45714
|
+
init_resolve_render_bindings();
|
|
45364
45715
|
init_Modal();
|
|
45365
45716
|
init_Drawer();
|
|
45366
45717
|
init_Toast();
|
|
@@ -45755,9 +46106,10 @@ function VerificationProvider({
|
|
|
45755
46106
|
}));
|
|
45756
46107
|
const effectResults = Array.isArray(payload["effectResults"]) ? payload["effectResults"] : [];
|
|
45757
46108
|
for (const er of effectResults) {
|
|
46109
|
+
const target = er["entity"] ?? er["service"];
|
|
45758
46110
|
effects.push({
|
|
45759
46111
|
type: String(er["type"] ?? er["effect"] ?? "server-effect"),
|
|
45760
|
-
args:
|
|
46112
|
+
args: typeof target === "string" && target !== "" ? [target] : [],
|
|
45761
46113
|
status: er["error"] ? "failed" : "executed",
|
|
45762
46114
|
error: er["error"]
|
|
45763
46115
|
});
|
|
@@ -46546,7 +46898,7 @@ function reEmitServerEvent(eventBus, emitted, origin) {
|
|
|
46546
46898
|
sourceTrait: evTrait,
|
|
46547
46899
|
origin
|
|
46548
46900
|
});
|
|
46549
|
-
eventBus.emit(key, emitted.payload);
|
|
46901
|
+
eventBus.emit(key, emitted.payload, emitted.source);
|
|
46550
46902
|
}
|
|
46551
46903
|
function isBusPushEnvelope(value) {
|
|
46552
46904
|
return value.type === "bus" && typeof value.event === "string";
|
|
@@ -46714,7 +47066,12 @@ function ServerBridgeProvider({
|
|
|
46714
47066
|
}
|
|
46715
47067
|
if (result.emittedEvents) {
|
|
46716
47068
|
for (const emitted of result.emittedEvents) {
|
|
46717
|
-
|
|
47069
|
+
if (emitted.event === event) continue;
|
|
47070
|
+
reEmitServerEvent(
|
|
47071
|
+
eventBus,
|
|
47072
|
+
{ ...emitted, source: { ...emitted.source, dispatched: true } },
|
|
47073
|
+
orbitalName
|
|
47074
|
+
);
|
|
46718
47075
|
}
|
|
46719
47076
|
}
|
|
46720
47077
|
} else if (result.error) {
|
|
@@ -46852,10 +47209,29 @@ function useTraitScopeChain2() {
|
|
|
46852
47209
|
const chain = useContext(TraitScopeContext);
|
|
46853
47210
|
return chain ?? EMPTY_CHAIN;
|
|
46854
47211
|
}
|
|
46855
|
-
function
|
|
47212
|
+
function useTraitScope2() {
|
|
46856
47213
|
const chain = useContext(TraitScopeContext);
|
|
46857
47214
|
return chain && chain.length > 0 ? chain[0] : null;
|
|
46858
47215
|
}
|
|
47216
|
+
var EntityBindingContext = createContext(null);
|
|
47217
|
+
var EMPTY_ENTITY = {};
|
|
47218
|
+
var NOOP_SUBSCRIBE = () => () => void 0;
|
|
47219
|
+
function useEntityBindingSnapshot2(traitName) {
|
|
47220
|
+
const source = useContext(EntityBindingContext);
|
|
47221
|
+
const entity = useSyncExternalStore(
|
|
47222
|
+
source !== null && traitName !== void 0 ? (onStoreChange) => source.subscribe(traitName, onStoreChange) : NOOP_SUBSCRIBE,
|
|
47223
|
+
() => source !== null && traitName !== void 0 ? source.getEntitySnapshot(traitName) : EMPTY_ENTITY
|
|
47224
|
+
);
|
|
47225
|
+
const config = useMemo(
|
|
47226
|
+
() => source !== null && traitName !== void 0 ? source.getConfig(traitName) : void 0,
|
|
47227
|
+
[source, traitName]
|
|
47228
|
+
);
|
|
47229
|
+
return {
|
|
47230
|
+
entity,
|
|
47231
|
+
config,
|
|
47232
|
+
state: source !== null && traitName !== void 0 ? source.getState(traitName) : ""
|
|
47233
|
+
};
|
|
47234
|
+
}
|
|
46859
47235
|
|
|
46860
47236
|
// providers/OfflineModeProvider.tsx
|
|
46861
47237
|
init_offline_executor();
|
|
@@ -46948,4 +47324,4 @@ function GameAudioProvider2({
|
|
|
46948
47324
|
}
|
|
46949
47325
|
GameAudioProvider2.displayName = "GameAudioProvider";
|
|
46950
47326
|
|
|
46951
|
-
export { CurrentPagePathContext, CurrentPagePathProvider, EntitySchemaProvider, EventBusContext2 as EventBusContext, EventBusProvider, GameAudioContext2 as GameAudioContext, GameAudioProvider2 as GameAudioProvider, NavigationProvider2 as NavigationProvider, OfflineModeProvider, OrbitalProvider, OrbitalThemeProvider, SelectionContext, SelectionProvider, ServerBridgeProvider, TraitContext, TraitProvider, TraitScopeProvider3 as TraitScopeProvider, UserContext, UserProvider, VerificationProvider, comparePathSpecificity2 as comparePathSpecificity, extractRouteParams2 as extractRouteParams, findPageByName2 as findPageByName, findPageByPath2 as findPageByPath, getAllPages2 as getAllPages, getDefaultPage2 as getDefaultPage, matchPath2 as matchPath, matchPathAmong2 as matchPathAmong, pathMatches2 as pathMatches, useActivePage2 as useActivePage, useCurrentPagePath2 as useCurrentPagePath, useEntitySchema, useEntitySchemaOptional6 as useEntitySchemaOptional, useGameAudioContext2 as useGameAudioContext, useGameAudioContextOptional2 as useGameAudioContextOptional, useHasPermission, useHasRole, useInitPayload2 as useInitPayload, useNavigateTo2 as useNavigateTo, useNavigation2 as useNavigation, useNavigationId2 as useNavigationId, useNavigationState2 as useNavigationState, useOfflineMode, useOptionalOfflineMode, useSelection, useSelectionOptional, useServerBridge, useTrait, useTraitContext, useTraitScope, useTraitScopeChain2 as useTraitScopeChain, useUser, useUserForEvaluation };
|
|
47327
|
+
export { CurrentPagePathContext, CurrentPagePathProvider, EntityBindingContext, EntitySchemaProvider, EventBusContext2 as EventBusContext, EventBusProvider, GameAudioContext2 as GameAudioContext, GameAudioProvider2 as GameAudioProvider, NavigationProvider2 as NavigationProvider, OfflineModeProvider, OrbitalProvider, OrbitalThemeProvider, SelectionContext, SelectionProvider, ServerBridgeProvider, TraitContext, TraitProvider, TraitScopeProvider3 as TraitScopeProvider, UserContext, UserProvider, VerificationProvider, comparePathSpecificity2 as comparePathSpecificity, extractRouteParams2 as extractRouteParams, findPageByName2 as findPageByName, findPageByPath2 as findPageByPath, getAllPages2 as getAllPages, getDefaultPage2 as getDefaultPage, matchPath2 as matchPath, matchPathAmong2 as matchPathAmong, pathMatches2 as pathMatches, useActivePage2 as useActivePage, useCurrentPagePath2 as useCurrentPagePath, useEntityBindingSnapshot2 as useEntityBindingSnapshot, useEntitySchema, useEntitySchemaOptional6 as useEntitySchemaOptional, useGameAudioContext2 as useGameAudioContext, useGameAudioContextOptional2 as useGameAudioContextOptional, useHasPermission, useHasRole, useInitPayload2 as useInitPayload, useNavigateTo2 as useNavigateTo, useNavigation2 as useNavigation, useNavigationId2 as useNavigationId, useNavigationState2 as useNavigationState, useOfflineMode, useOptionalOfflineMode, useSelection, useSelectionOptional, useServerBridge, useTrait, useTraitContext, useTraitScope2 as useTraitScope, useTraitScopeChain2 as useTraitScopeChain, useUser, useUserForEvaluation };
|