@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.cjs
CHANGED
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
var React85 = require('react');
|
|
4
4
|
var providers = require('@almadar/ui/providers');
|
|
5
5
|
var logger = require('@almadar/logger');
|
|
6
|
+
var runtime = require('@almadar/runtime');
|
|
7
|
+
var core = require('@almadar/core');
|
|
6
8
|
var clsx = require('clsx');
|
|
7
9
|
var tailwindMerge = require('tailwind-merge');
|
|
8
10
|
var LucideIcons2 = require('lucide-react');
|
|
@@ -67,10 +69,10 @@ var ReactMarkdown = require('react-markdown');
|
|
|
67
69
|
var remarkGfm = require('remark-gfm');
|
|
68
70
|
var remarkMath = require('remark-math');
|
|
69
71
|
var rehypeKatex = require('rehype-katex');
|
|
70
|
-
var core = require('@almadar/core');
|
|
71
72
|
var core$1 = require('@dnd-kit/core');
|
|
72
73
|
var sortable = require('@dnd-kit/sortable');
|
|
73
74
|
var utilities = require('@dnd-kit/utilities');
|
|
75
|
+
var emojilib = require('emojilib');
|
|
74
76
|
var react = require('@xyflow/react');
|
|
75
77
|
var d3Force = require('d3-force');
|
|
76
78
|
var patterns = require('@almadar/core/patterns');
|
|
@@ -341,6 +343,75 @@ var init_useEventBus = __esm({
|
|
|
341
343
|
useEventBus_default = useEventBus;
|
|
342
344
|
}
|
|
343
345
|
});
|
|
346
|
+
function resolveMarkerExpression(expression, entity, config, state) {
|
|
347
|
+
const ctx = runtime.createContextFromBindings({
|
|
348
|
+
entity,
|
|
349
|
+
payload: {},
|
|
350
|
+
state,
|
|
351
|
+
...config !== void 0 ? { config } : {}
|
|
352
|
+
});
|
|
353
|
+
return runtime.interpolateValue(expression, ctx);
|
|
354
|
+
}
|
|
355
|
+
function isPlainObject(value) {
|
|
356
|
+
if (value === null || value === void 0 || typeof value !== "object") return false;
|
|
357
|
+
if (Array.isArray(value)) return false;
|
|
358
|
+
if (React85__namespace.default.isValidElement(value)) return false;
|
|
359
|
+
if (value instanceof Date) return false;
|
|
360
|
+
if (typeof value === "function") return false;
|
|
361
|
+
return true;
|
|
362
|
+
}
|
|
363
|
+
function walkValue(value, scopeTrait, entity, config, state) {
|
|
364
|
+
if (core.isRenderBindingMarker(value)) {
|
|
365
|
+
return { resolved: resolveMarkerExpression(value.expression, entity, config, state), changed: true };
|
|
366
|
+
}
|
|
367
|
+
if (Array.isArray(value)) {
|
|
368
|
+
const out = [];
|
|
369
|
+
let changed = false;
|
|
370
|
+
for (const item of value) {
|
|
371
|
+
const element = item;
|
|
372
|
+
const wasMarker = core.isRenderBindingMarker(element);
|
|
373
|
+
const { resolved, changed: itemChanged } = walkValue(element, scopeTrait, entity, config, state);
|
|
374
|
+
if (wasMarker && Array.isArray(resolved)) {
|
|
375
|
+
out.push(...resolved);
|
|
376
|
+
changed = true;
|
|
377
|
+
continue;
|
|
378
|
+
}
|
|
379
|
+
out.push(resolved);
|
|
380
|
+
if (itemChanged) changed = true;
|
|
381
|
+
}
|
|
382
|
+
return changed ? { resolved: out, changed: true } : { resolved: value, changed: false };
|
|
383
|
+
}
|
|
384
|
+
if (isPlainObject(value)) {
|
|
385
|
+
const sourceTrait = value._sourceTrait;
|
|
386
|
+
if (typeof sourceTrait === "string" && sourceTrait !== scopeTrait) {
|
|
387
|
+
return { resolved: value, changed: false };
|
|
388
|
+
}
|
|
389
|
+
const out = {};
|
|
390
|
+
let changed = false;
|
|
391
|
+
for (const [key, item] of Object.entries(value)) {
|
|
392
|
+
const { resolved, changed: itemChanged } = walkValue(item, scopeTrait, entity, config, state);
|
|
393
|
+
out[key] = resolved;
|
|
394
|
+
if (itemChanged) changed = true;
|
|
395
|
+
}
|
|
396
|
+
return changed ? { resolved: out, changed: true } : { resolved: value, changed: false };
|
|
397
|
+
}
|
|
398
|
+
return { resolved: value, changed: false };
|
|
399
|
+
}
|
|
400
|
+
function resolveRenderBindingMarkers(props, scopeTrait, entity, config, state) {
|
|
401
|
+
const out = {};
|
|
402
|
+
let changed = false;
|
|
403
|
+
for (const [key, value] of Object.entries(props)) {
|
|
404
|
+
const { resolved, changed: propChanged } = walkValue(value, scopeTrait, entity, config, state);
|
|
405
|
+
out[key] = resolved;
|
|
406
|
+
if (propChanged) changed = true;
|
|
407
|
+
}
|
|
408
|
+
return changed ? out : props;
|
|
409
|
+
}
|
|
410
|
+
var init_resolve_render_bindings = __esm({
|
|
411
|
+
"lib/resolve-render-bindings.ts"() {
|
|
412
|
+
"use client";
|
|
413
|
+
}
|
|
414
|
+
});
|
|
344
415
|
function cn(...inputs) {
|
|
345
416
|
return tailwindMerge.twMerge(clsx.clsx(inputs));
|
|
346
417
|
}
|
|
@@ -848,9 +919,13 @@ function getAtlas(url, onReady) {
|
|
|
848
919
|
onReady();
|
|
849
920
|
}).catch(() => {
|
|
850
921
|
atlasCache.set(url, null);
|
|
922
|
+
onReady();
|
|
851
923
|
});
|
|
852
924
|
return void 0;
|
|
853
925
|
}
|
|
926
|
+
function atlasFailed(url) {
|
|
927
|
+
return atlasCache.get(url) === null;
|
|
928
|
+
}
|
|
854
929
|
function subRectFor(atlas, sprite) {
|
|
855
930
|
if (isTilesheet(atlas)) {
|
|
856
931
|
let col;
|
|
@@ -1271,6 +1346,32 @@ function formatValue(value, format) {
|
|
|
1271
1346
|
return String(value);
|
|
1272
1347
|
}
|
|
1273
1348
|
}
|
|
1349
|
+
function compareCellValues(a, b) {
|
|
1350
|
+
const aEmpty = a === null || a === void 0 || a === "";
|
|
1351
|
+
const bEmpty = b === null || b === void 0 || b === "";
|
|
1352
|
+
if (aEmpty || bEmpty) return aEmpty && bEmpty ? 0 : aEmpty ? 1 : -1;
|
|
1353
|
+
if (typeof a === "number" && typeof b === "number") return a - b;
|
|
1354
|
+
if (typeof a === "boolean" && typeof b === "boolean") return Number(a) - Number(b);
|
|
1355
|
+
const aNum = Number(a);
|
|
1356
|
+
const bNum = Number(b);
|
|
1357
|
+
if (Number.isFinite(aNum) && Number.isFinite(bNum)) return aNum - bNum;
|
|
1358
|
+
const aTime = dateLikeTime(a);
|
|
1359
|
+
const bTime = dateLikeTime(b);
|
|
1360
|
+
if (aTime !== null && bTime !== null) return aTime - bTime;
|
|
1361
|
+
return String(a).localeCompare(String(b));
|
|
1362
|
+
}
|
|
1363
|
+
function dateLikeTime(value) {
|
|
1364
|
+
if (value instanceof Date) return value.getTime();
|
|
1365
|
+
const text = String(value);
|
|
1366
|
+
if (!/\d/.test(text) || !/[-/:T]/.test(text)) return null;
|
|
1367
|
+
const time = Date.parse(text);
|
|
1368
|
+
return Number.isNaN(time) ? null : time;
|
|
1369
|
+
}
|
|
1370
|
+
function sortRows(rows, field, direction = "asc") {
|
|
1371
|
+
if (!field) return rows;
|
|
1372
|
+
const dir = direction === "desc" ? -1 : 1;
|
|
1373
|
+
return [...rows].sort((a, b) => dir * compareCellValues(a?.[field], b?.[field]));
|
|
1374
|
+
}
|
|
1274
1375
|
var init_format = __esm({
|
|
1275
1376
|
"lib/format.ts"() {
|
|
1276
1377
|
}
|
|
@@ -3093,6 +3194,20 @@ var init_Input = __esm({
|
|
|
3093
3194
|
const { t } = hooks.useTranslate();
|
|
3094
3195
|
const eventBus = useEventBus();
|
|
3095
3196
|
const type = inputType || htmlType || "text";
|
|
3197
|
+
const isDeclarative = typeof onChange === "string";
|
|
3198
|
+
const [localValue, setLocalValue] = React85__namespace.default.useState(value);
|
|
3199
|
+
const pendingEchoRef = React85__namespace.default.useRef(/* @__PURE__ */ new Set());
|
|
3200
|
+
React85__namespace.default.useEffect(() => {
|
|
3201
|
+
if (!isDeclarative) return;
|
|
3202
|
+
const incoming = value == null ? "" : String(value);
|
|
3203
|
+
if (pendingEchoRef.current.has(incoming)) {
|
|
3204
|
+
pendingEchoRef.current.delete(incoming);
|
|
3205
|
+
return;
|
|
3206
|
+
}
|
|
3207
|
+
pendingEchoRef.current.clear();
|
|
3208
|
+
setLocalValue(value);
|
|
3209
|
+
}, [value, isDeclarative]);
|
|
3210
|
+
const displayValue = isDeclarative ? localValue : value;
|
|
3096
3211
|
const resolveIconNode = (i, cls) => {
|
|
3097
3212
|
if (!i) return null;
|
|
3098
3213
|
if (typeof i === "string") return /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: i, className: cls });
|
|
@@ -3102,7 +3217,7 @@ var init_Input = __esm({
|
|
|
3102
3217
|
const iconCls = "h-icon-default w-icon-default";
|
|
3103
3218
|
const IconComponent = typeof iconProp === "string" ? resolveIcon(iconProp) : iconProp;
|
|
3104
3219
|
const resolvedLeftIcon = (leftIcon ? resolveIconNode(leftIcon, iconCls) : null) || IconComponent && /* @__PURE__ */ jsxRuntime.jsx(IconComponent, { className: iconCls });
|
|
3105
|
-
const showClearButton = clearable &&
|
|
3220
|
+
const showClearButton = clearable && displayValue && String(displayValue).length > 0;
|
|
3106
3221
|
const isMultiline = type === "textarea";
|
|
3107
3222
|
const baseClassName = cn(
|
|
3108
3223
|
"block w-full rounded-sm transition-all duration-fast",
|
|
@@ -3121,6 +3236,10 @@ var init_Input = __esm({
|
|
|
3121
3236
|
if (typeof onChange === "string") {
|
|
3122
3237
|
const target = e.target;
|
|
3123
3238
|
const payload = type === "checkbox" ? { checked: target.checked } : { value: target.value };
|
|
3239
|
+
if (type !== "checkbox") {
|
|
3240
|
+
pendingEchoRef.current.add(target.value);
|
|
3241
|
+
setLocalValue(target.value);
|
|
3242
|
+
}
|
|
3124
3243
|
eventBus.emit(`UI:${onChange}`, payload);
|
|
3125
3244
|
} else {
|
|
3126
3245
|
onChange?.(e);
|
|
@@ -3151,7 +3270,7 @@ var init_Input = __esm({
|
|
|
3151
3270
|
"select",
|
|
3152
3271
|
{
|
|
3153
3272
|
ref,
|
|
3154
|
-
value,
|
|
3273
|
+
value: displayValue,
|
|
3155
3274
|
onChange: handleChange,
|
|
3156
3275
|
className: cn(baseClassName, "appearance-none pr-10", className),
|
|
3157
3276
|
...props,
|
|
@@ -3171,7 +3290,7 @@ var init_Input = __esm({
|
|
|
3171
3290
|
"textarea",
|
|
3172
3291
|
{
|
|
3173
3292
|
ref,
|
|
3174
|
-
value,
|
|
3293
|
+
value: displayValue,
|
|
3175
3294
|
onChange: handleChange,
|
|
3176
3295
|
rows,
|
|
3177
3296
|
className: baseClassName,
|
|
@@ -3210,7 +3329,7 @@ var init_Input = __esm({
|
|
|
3210
3329
|
{
|
|
3211
3330
|
ref,
|
|
3212
3331
|
type,
|
|
3213
|
-
value,
|
|
3332
|
+
value: displayValue,
|
|
3214
3333
|
onChange: handleChange,
|
|
3215
3334
|
onKeyDown: handleKeyDown,
|
|
3216
3335
|
className: baseClassName,
|
|
@@ -7133,46 +7252,45 @@ var init_useImageCache = __esm({
|
|
|
7133
7252
|
});
|
|
7134
7253
|
|
|
7135
7254
|
// lib/isometric.ts
|
|
7136
|
-
function isoToScreen(tileX, tileY,
|
|
7137
|
-
const
|
|
7138
|
-
const
|
|
7255
|
+
function isoToScreen(tileX, tileY, cellWidth, baseOffsetX, layout = "isometric") {
|
|
7256
|
+
const w = cellWidth;
|
|
7257
|
+
const fh = cellWidth / 2;
|
|
7139
7258
|
if (layout === "hex") {
|
|
7140
|
-
const screenX2 = tileX *
|
|
7141
|
-
const screenY2 = tileY * (
|
|
7259
|
+
const screenX2 = tileX * w + (tileY & 1) * (w / 2) + baseOffsetX;
|
|
7260
|
+
const screenY2 = tileY * (fh * 0.75);
|
|
7142
7261
|
return { x: screenX2, y: screenY2 };
|
|
7143
7262
|
}
|
|
7144
7263
|
if (layout === "flat") {
|
|
7145
|
-
const screenX2 = tileX *
|
|
7146
|
-
const screenY2 = tileY *
|
|
7264
|
+
const screenX2 = tileX * w + baseOffsetX;
|
|
7265
|
+
const screenY2 = tileY * w;
|
|
7147
7266
|
return { x: screenX2, y: screenY2 };
|
|
7148
7267
|
}
|
|
7149
|
-
const screenX = (tileX - tileY) * (
|
|
7150
|
-
const screenY = (tileX + tileY) * (
|
|
7268
|
+
const screenX = (tileX - tileY) * (w / 2) + baseOffsetX;
|
|
7269
|
+
const screenY = (tileX + tileY) * (fh / 2);
|
|
7151
7270
|
return { x: screenX, y: screenY };
|
|
7152
7271
|
}
|
|
7153
|
-
function screenToIso(screenX, screenY,
|
|
7154
|
-
const
|
|
7155
|
-
const
|
|
7272
|
+
function screenToIso(screenX, screenY, cellWidth, baseOffsetX, layout = "isometric") {
|
|
7273
|
+
const w = cellWidth;
|
|
7274
|
+
const fh = cellWidth / 2;
|
|
7156
7275
|
if (layout === "hex") {
|
|
7157
|
-
const row = Math.round(screenY / (
|
|
7158
|
-
const col = Math.round((screenX - (row & 1) * (
|
|
7276
|
+
const row = Math.round(screenY / (fh * 0.75));
|
|
7277
|
+
const col = Math.round((screenX - (row & 1) * (w / 2) - baseOffsetX) / w);
|
|
7159
7278
|
return { x: col, y: row };
|
|
7160
7279
|
}
|
|
7161
7280
|
if (layout === "flat") {
|
|
7162
|
-
const col = Math.round((screenX - baseOffsetX) /
|
|
7163
|
-
const row = Math.round(screenY /
|
|
7281
|
+
const col = Math.round((screenX - baseOffsetX) / w);
|
|
7282
|
+
const row = Math.round(screenY / w);
|
|
7164
7283
|
return { x: col, y: row };
|
|
7165
7284
|
}
|
|
7166
7285
|
const adjustedX = screenX - baseOffsetX;
|
|
7167
|
-
const tileX = (adjustedX / (
|
|
7168
|
-
const tileY = (screenY / (
|
|
7286
|
+
const tileX = (adjustedX / (w / 2) + screenY / (fh / 2)) / 2;
|
|
7287
|
+
const tileY = (screenY / (fh / 2) - adjustedX / (w / 2)) / 2;
|
|
7169
7288
|
return { x: Math.round(tileX), y: Math.round(tileY) };
|
|
7170
7289
|
}
|
|
7171
|
-
var TILE_WIDTH,
|
|
7290
|
+
var TILE_WIDTH, DIAMOND_TOP_Y, BACKGROUND_FALLBACK_COLOR, MINIMAP_TERRAIN_COLORS;
|
|
7172
7291
|
var init_isometric = __esm({
|
|
7173
7292
|
"lib/isometric.ts"() {
|
|
7174
7293
|
TILE_WIDTH = 256;
|
|
7175
|
-
FLOOR_HEIGHT = 128;
|
|
7176
7294
|
DIAMOND_TOP_Y = 374;
|
|
7177
7295
|
BACKGROUND_FALLBACK_COLOR = "#1a1a2e";
|
|
7178
7296
|
MINIMAP_TERRAIN_COLORS = {
|
|
@@ -7657,210 +7775,6 @@ var init_ChoiceButton = __esm({
|
|
|
7657
7775
|
ChoiceButton.displayName = "ChoiceButton";
|
|
7658
7776
|
}
|
|
7659
7777
|
});
|
|
7660
|
-
function SvgStage({
|
|
7661
|
-
cols,
|
|
7662
|
-
rows,
|
|
7663
|
-
tileSize = 32,
|
|
7664
|
-
background = "var(--color-background)",
|
|
7665
|
-
tileClickEvent,
|
|
7666
|
-
tileHoverEvent,
|
|
7667
|
-
tileLeaveEvent,
|
|
7668
|
-
keyMap,
|
|
7669
|
-
keyUpMap,
|
|
7670
|
-
className,
|
|
7671
|
-
children
|
|
7672
|
-
}) {
|
|
7673
|
-
const eventBus = useEventBus();
|
|
7674
|
-
const svgRef = React85.useRef(null);
|
|
7675
|
-
const pointerDownRef = React85.useRef(null);
|
|
7676
|
-
const cellFromClient = React85.useCallback((clientX, clientY) => {
|
|
7677
|
-
const svg = svgRef.current;
|
|
7678
|
-
if (!svg) return null;
|
|
7679
|
-
const rect = svg.getBoundingClientRect();
|
|
7680
|
-
if (rect.width === 0 || rect.height === 0) return null;
|
|
7681
|
-
const vbW = cols * tileSize;
|
|
7682
|
-
const vbH = rows * tileSize;
|
|
7683
|
-
const meet = Math.min(rect.width / vbW, rect.height / vbH);
|
|
7684
|
-
const offsetX = (rect.width - vbW * meet) / 2;
|
|
7685
|
-
const offsetY = (rect.height - vbH * meet) / 2;
|
|
7686
|
-
const svgX = (clientX - rect.left - offsetX) / meet;
|
|
7687
|
-
const svgY = (clientY - rect.top - offsetY) / meet;
|
|
7688
|
-
return {
|
|
7689
|
-
x: Math.min(Math.max(Math.floor(svgX / tileSize), 0), cols - 1),
|
|
7690
|
-
y: Math.min(Math.max(Math.floor(svgY / tileSize), 0), rows - 1)
|
|
7691
|
-
};
|
|
7692
|
-
}, [cols, rows, tileSize]);
|
|
7693
|
-
const handlePointerDown = React85.useCallback((e) => {
|
|
7694
|
-
pointerDownRef.current = { clientX: e.clientX, clientY: e.clientY };
|
|
7695
|
-
}, []);
|
|
7696
|
-
const handlePointerUp = React85.useCallback((e) => {
|
|
7697
|
-
const down = pointerDownRef.current;
|
|
7698
|
-
pointerDownRef.current = null;
|
|
7699
|
-
if (!tileClickEvent) return;
|
|
7700
|
-
if (down && Math.hypot(e.clientX - down.clientX, e.clientY - down.clientY) > 5) return;
|
|
7701
|
-
const cell = cellFromClient(e.clientX, e.clientY);
|
|
7702
|
-
if (cell) eventBus.emit(`UI:${tileClickEvent}`, cell);
|
|
7703
|
-
}, [cellFromClient, tileClickEvent, eventBus]);
|
|
7704
|
-
const handlePointerMove = React85.useCallback((e) => {
|
|
7705
|
-
if (!tileHoverEvent) return;
|
|
7706
|
-
const cell = cellFromClient(e.clientX, e.clientY);
|
|
7707
|
-
if (cell) eventBus.emit(`UI:${tileHoverEvent}`, cell);
|
|
7708
|
-
}, [cellFromClient, tileHoverEvent, eventBus]);
|
|
7709
|
-
const handlePointerLeave = React85.useCallback(() => {
|
|
7710
|
-
pointerDownRef.current = null;
|
|
7711
|
-
if (tileLeaveEvent) eventBus.emit(`UI:${tileLeaveEvent}`, {});
|
|
7712
|
-
}, [tileLeaveEvent, eventBus]);
|
|
7713
|
-
React85.useEffect(() => {
|
|
7714
|
-
if (!keyMap && !keyUpMap) return;
|
|
7715
|
-
const onDown = (e) => {
|
|
7716
|
-
const ev = keyMap?.[e.code];
|
|
7717
|
-
if (ev) {
|
|
7718
|
-
eventBus.emit(`UI:${ev}`, {});
|
|
7719
|
-
e.preventDefault();
|
|
7720
|
-
}
|
|
7721
|
-
};
|
|
7722
|
-
const onUp = (e) => {
|
|
7723
|
-
const ev = keyUpMap?.[e.code];
|
|
7724
|
-
if (ev) eventBus.emit(`UI:${ev}`, {});
|
|
7725
|
-
};
|
|
7726
|
-
window.addEventListener("keydown", onDown);
|
|
7727
|
-
window.addEventListener("keyup", onUp);
|
|
7728
|
-
return () => {
|
|
7729
|
-
window.removeEventListener("keydown", onDown);
|
|
7730
|
-
window.removeEventListener("keyup", onUp);
|
|
7731
|
-
};
|
|
7732
|
-
}, [keyMap, keyUpMap, eventBus]);
|
|
7733
|
-
React85.useEffect(() => {
|
|
7734
|
-
if (!keyMap && !keyUpMap) return;
|
|
7735
|
-
svgRef.current?.focus();
|
|
7736
|
-
}, [keyMap, keyUpMap]);
|
|
7737
|
-
const stageContext = React85.useMemo(() => ({ tileSize }), [tileSize]);
|
|
7738
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
7739
|
-
"svg",
|
|
7740
|
-
{
|
|
7741
|
-
ref: svgRef,
|
|
7742
|
-
"data-testid": "svg-stage",
|
|
7743
|
-
viewBox: `0 0 ${cols * tileSize} ${rows * tileSize}`,
|
|
7744
|
-
preserveAspectRatio: "xMidYMid meet",
|
|
7745
|
-
className: cn("block h-full w-full", className),
|
|
7746
|
-
tabIndex: keyMap || keyUpMap ? 0 : void 0,
|
|
7747
|
-
onPointerDown: handlePointerDown,
|
|
7748
|
-
onPointerMove: handlePointerMove,
|
|
7749
|
-
onPointerUp: handlePointerUp,
|
|
7750
|
-
onPointerLeave: handlePointerLeave,
|
|
7751
|
-
children: [
|
|
7752
|
-
/* @__PURE__ */ jsxRuntime.jsx("rect", { width: cols * tileSize, height: rows * tileSize, fill: background }),
|
|
7753
|
-
/* @__PURE__ */ jsxRuntime.jsx(SvgStageContext.Provider, { value: stageContext, children })
|
|
7754
|
-
]
|
|
7755
|
-
}
|
|
7756
|
-
);
|
|
7757
|
-
}
|
|
7758
|
-
var SvgStageContext;
|
|
7759
|
-
var init_SvgStage = __esm({
|
|
7760
|
-
"components/game/molecules/SvgStage.tsx"() {
|
|
7761
|
-
"use client";
|
|
7762
|
-
init_cn();
|
|
7763
|
-
init_useEventBus();
|
|
7764
|
-
SvgStageContext = React85__namespace.createContext({ tileSize: 1 });
|
|
7765
|
-
SvgStage.displayName = "SvgStage";
|
|
7766
|
-
}
|
|
7767
|
-
});
|
|
7768
|
-
function SvgDrawShape({
|
|
7769
|
-
shape,
|
|
7770
|
-
x,
|
|
7771
|
-
y,
|
|
7772
|
-
width,
|
|
7773
|
-
height,
|
|
7774
|
-
radius,
|
|
7775
|
-
radiusY,
|
|
7776
|
-
points,
|
|
7777
|
-
d,
|
|
7778
|
-
x2,
|
|
7779
|
-
y2,
|
|
7780
|
-
fill,
|
|
7781
|
-
stroke,
|
|
7782
|
-
strokeWidth,
|
|
7783
|
-
opacity,
|
|
7784
|
-
className
|
|
7785
|
-
}) {
|
|
7786
|
-
const { tileSize } = React85.useContext(SvgStageContext);
|
|
7787
|
-
const cell = (v) => v === void 0 ? void 0 : v * tileSize;
|
|
7788
|
-
const paint = {
|
|
7789
|
-
fill: fill ?? (stroke === void 0 ? "var(--color-primary)" : "none"),
|
|
7790
|
-
stroke,
|
|
7791
|
-
strokeWidth,
|
|
7792
|
-
opacity,
|
|
7793
|
-
className
|
|
7794
|
-
};
|
|
7795
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("g", { transform: `translate(${x * tileSize} ${y * tileSize})`, children: [
|
|
7796
|
-
shape === "rect" && /* @__PURE__ */ jsxRuntime.jsx("rect", { width: cell(width), height: cell(height), ...paint }),
|
|
7797
|
-
shape === "circle" && /* @__PURE__ */ jsxRuntime.jsx("circle", { r: cell(radius), ...paint }),
|
|
7798
|
-
shape === "ellipse" && /* @__PURE__ */ jsxRuntime.jsx("ellipse", { rx: cell(radius), ry: cell(radiusY ?? radius), ...paint }),
|
|
7799
|
-
shape === "polygon" && /* @__PURE__ */ jsxRuntime.jsx("polygon", { points, ...paint }),
|
|
7800
|
-
shape === "polyline" && /* @__PURE__ */ jsxRuntime.jsx("polyline", { points, ...paint }),
|
|
7801
|
-
shape === "path" && /* @__PURE__ */ jsxRuntime.jsx("path", { d, ...paint }),
|
|
7802
|
-
shape === "line" && /* @__PURE__ */ jsxRuntime.jsx("line", { x2: cell(x2), y2: cell(y2), ...paint })
|
|
7803
|
-
] });
|
|
7804
|
-
}
|
|
7805
|
-
var init_SvgDrawShape = __esm({
|
|
7806
|
-
"components/game/atoms/SvgDrawShape.tsx"() {
|
|
7807
|
-
"use client";
|
|
7808
|
-
init_SvgStage();
|
|
7809
|
-
SvgDrawShape.displayName = "SvgDrawShape";
|
|
7810
|
-
}
|
|
7811
|
-
});
|
|
7812
|
-
function SvgDrawGroup({
|
|
7813
|
-
x = 0,
|
|
7814
|
-
y = 0,
|
|
7815
|
-
scale,
|
|
7816
|
-
rotate,
|
|
7817
|
-
opacity,
|
|
7818
|
-
className,
|
|
7819
|
-
children
|
|
7820
|
-
}) {
|
|
7821
|
-
const { tileSize } = React85.useContext(SvgStageContext);
|
|
7822
|
-
const transforms = [`translate(${x * tileSize} ${y * tileSize})`];
|
|
7823
|
-
if (rotate !== void 0) transforms.push(`rotate(${rotate})`);
|
|
7824
|
-
if (scale !== void 0) transforms.push(`scale(${scale})`);
|
|
7825
|
-
return /* @__PURE__ */ jsxRuntime.jsx("g", { transform: transforms.join(" "), opacity, className, children });
|
|
7826
|
-
}
|
|
7827
|
-
var init_SvgDrawGroup = __esm({
|
|
7828
|
-
"components/game/atoms/SvgDrawGroup.tsx"() {
|
|
7829
|
-
"use client";
|
|
7830
|
-
init_SvgStage();
|
|
7831
|
-
SvgDrawGroup.displayName = "SvgDrawGroup";
|
|
7832
|
-
}
|
|
7833
|
-
});
|
|
7834
|
-
function SvgDrawText({
|
|
7835
|
-
x,
|
|
7836
|
-
y,
|
|
7837
|
-
text,
|
|
7838
|
-
size = 12,
|
|
7839
|
-
fill = "var(--color-foreground)",
|
|
7840
|
-
anchor = "middle",
|
|
7841
|
-
className
|
|
7842
|
-
}) {
|
|
7843
|
-
const { tileSize } = React85.useContext(SvgStageContext);
|
|
7844
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
7845
|
-
"text",
|
|
7846
|
-
{
|
|
7847
|
-
x: x * tileSize,
|
|
7848
|
-
y: y * tileSize,
|
|
7849
|
-
fontSize: size,
|
|
7850
|
-
fill,
|
|
7851
|
-
textAnchor: anchor,
|
|
7852
|
-
className,
|
|
7853
|
-
children: text
|
|
7854
|
-
}
|
|
7855
|
-
);
|
|
7856
|
-
}
|
|
7857
|
-
var init_SvgDrawText = __esm({
|
|
7858
|
-
"components/game/atoms/SvgDrawText.tsx"() {
|
|
7859
|
-
"use client";
|
|
7860
|
-
init_SvgStage();
|
|
7861
|
-
SvgDrawText.displayName = "SvgDrawText";
|
|
7862
|
-
}
|
|
7863
|
-
});
|
|
7864
7778
|
function ControlGrid({
|
|
7865
7779
|
kind,
|
|
7866
7780
|
buttons = DEFAULT_BUTTONS,
|
|
@@ -8564,6 +8478,7 @@ function MiniMap({
|
|
|
8564
8478
|
const cached = imgCacheRef.current.get(url);
|
|
8565
8479
|
if (cached) return cached.complete ? cached : null;
|
|
8566
8480
|
const img = new Image();
|
|
8481
|
+
img.crossOrigin = "anonymous";
|
|
8567
8482
|
img.src = url;
|
|
8568
8483
|
img.onload = () => {
|
|
8569
8484
|
const canvas = canvasRef.current;
|
|
@@ -8731,7 +8646,7 @@ function useCamera(initial) {
|
|
|
8731
8646
|
const handleWheel = React85.useCallback((e, drawFn) => {
|
|
8732
8647
|
e.preventDefault();
|
|
8733
8648
|
const zoomDelta = e.deltaY > 0 ? 0.9 : 1.1;
|
|
8734
|
-
cameraRef.current.zoom = Math.max(
|
|
8649
|
+
cameraRef.current.zoom = Math.max(MIN_ZOOM, Math.min(MAX_ZOOM, cameraRef.current.zoom * zoomDelta));
|
|
8735
8650
|
drawFn?.();
|
|
8736
8651
|
}, []);
|
|
8737
8652
|
const handlePointerDown = React85.useCallback((e) => {
|
|
@@ -8752,7 +8667,7 @@ function useCamera(initial) {
|
|
|
8752
8667
|
const zoomAtPoint = React85.useCallback((factor, centerX, centerY, viewportSize, drawFn) => {
|
|
8753
8668
|
const cam = cameraRef.current;
|
|
8754
8669
|
const oldZoom = cam.zoom;
|
|
8755
|
-
const newZoom = Math.max(
|
|
8670
|
+
const newZoom = Math.max(MIN_ZOOM, Math.min(MAX_ZOOM, oldZoom * factor));
|
|
8756
8671
|
if (newZoom === oldZoom) {
|
|
8757
8672
|
drawFn?.();
|
|
8758
8673
|
return;
|
|
@@ -8804,9 +8719,12 @@ function useCamera(initial) {
|
|
|
8804
8719
|
lerpToTarget
|
|
8805
8720
|
};
|
|
8806
8721
|
}
|
|
8722
|
+
var MIN_ZOOM, MAX_ZOOM;
|
|
8807
8723
|
var init_useCamera = __esm({
|
|
8808
8724
|
"hooks/useCamera.ts"() {
|
|
8809
8725
|
"use client";
|
|
8726
|
+
MIN_ZOOM = 0.05;
|
|
8727
|
+
MAX_ZOOM = 10;
|
|
8810
8728
|
}
|
|
8811
8729
|
});
|
|
8812
8730
|
function localPoint(canvas, clientX, clientY) {
|
|
@@ -8927,6 +8845,7 @@ function getOrLoadImage(url, onReady) {
|
|
|
8927
8845
|
return null;
|
|
8928
8846
|
}
|
|
8929
8847
|
const img = new Image();
|
|
8848
|
+
img.crossOrigin = "anonymous";
|
|
8930
8849
|
const entry = { img, status: "pending", onReady };
|
|
8931
8850
|
cache.set(url, entry);
|
|
8932
8851
|
updateAssetStatus(url, "pending");
|
|
@@ -8938,10 +8857,14 @@ function getOrLoadImage(url, onReady) {
|
|
|
8938
8857
|
img.onerror = () => {
|
|
8939
8858
|
entry.status = "failed";
|
|
8940
8859
|
updateAssetStatus(url, "failed");
|
|
8860
|
+
entry.onReady?.();
|
|
8941
8861
|
};
|
|
8942
8862
|
img.src = url;
|
|
8943
8863
|
return null;
|
|
8944
8864
|
}
|
|
8865
|
+
function getImageStatus(url) {
|
|
8866
|
+
return cache.get(url)?.status;
|
|
8867
|
+
}
|
|
8945
8868
|
var cache;
|
|
8946
8869
|
var init_imageCache = __esm({
|
|
8947
8870
|
"lib/imageCache.ts"() {
|
|
@@ -9050,6 +8973,15 @@ function createWebPainter(ctx, onAssetLoad) {
|
|
|
9050
8973
|
ctx.lineWidth = lineWidth;
|
|
9051
8974
|
ctx.stroke();
|
|
9052
8975
|
},
|
|
8976
|
+
fillPath(d, color) {
|
|
8977
|
+
ctx.fillStyle = color;
|
|
8978
|
+
ctx.fill(new Path2D(d));
|
|
8979
|
+
},
|
|
8980
|
+
strokePath(d, color, lineWidth = 1) {
|
|
8981
|
+
ctx.strokeStyle = color;
|
|
8982
|
+
ctx.lineWidth = lineWidth;
|
|
8983
|
+
ctx.stroke(new Path2D(d));
|
|
8984
|
+
},
|
|
9053
8985
|
text(str, x, y, style) {
|
|
9054
8986
|
if (style.font) ctx.font = style.font;
|
|
9055
8987
|
ctx.fillStyle = style.color;
|
|
@@ -9071,12 +9003,13 @@ var init_webPainter2d = __esm({
|
|
|
9071
9003
|
|
|
9072
9004
|
// lib/drawable/projector.ts
|
|
9073
9005
|
function create2DProjector(opts) {
|
|
9074
|
-
const {
|
|
9075
|
-
const
|
|
9076
|
-
const
|
|
9077
|
-
const
|
|
9006
|
+
const { baseOffsetX, layout } = opts;
|
|
9007
|
+
const tw = opts.tileWidth ?? TILE_WIDTH;
|
|
9008
|
+
const tileWidth = layout === "free" ? 1 : tw;
|
|
9009
|
+
const floorHeight = layout === "free" ? 1 : tw / 2;
|
|
9010
|
+
const diamondTopY = layout === "free" ? 0 : opts.diamondTopY ?? tw * (DIAMOND_TOP_Y / TILE_WIDTH);
|
|
9078
9011
|
const squareGrid = layout === "flat" || layout === "free";
|
|
9079
|
-
const project = (pos) => layout === "free" ? { x: pos.x, y: pos.y } : isoToScreen(pos.x, pos.y,
|
|
9012
|
+
const project = (pos) => layout === "free" ? { x: pos.x, y: pos.y } : isoToScreen(pos.x, pos.y, tw, baseOffsetX, layout);
|
|
9080
9013
|
const anchorPoint = (pos, anchor) => {
|
|
9081
9014
|
const base = project(pos);
|
|
9082
9015
|
if (anchor === "top-left") return base;
|
|
@@ -9107,7 +9040,7 @@ function create2DProjector(opts) {
|
|
|
9107
9040
|
{ x: base.x, y: topY + floorHeight / 2 }
|
|
9108
9041
|
];
|
|
9109
9042
|
};
|
|
9110
|
-
return { project, anchorPoint, cellPath, tileWidth, floorHeight, diamondTopY,
|
|
9043
|
+
return { project, anchorPoint, cellPath, tileWidth, floorHeight, diamondTopY, squareGrid, worldPixelDirect: layout === "free" };
|
|
9111
9044
|
}
|
|
9112
9045
|
var init_projector = __esm({
|
|
9113
9046
|
"lib/drawable/projector.ts"() {
|
|
@@ -9123,32 +9056,67 @@ var init_contract = __esm({
|
|
|
9123
9056
|
"lib/drawable/contract.ts"() {
|
|
9124
9057
|
}
|
|
9125
9058
|
});
|
|
9126
|
-
|
|
9127
|
-
|
|
9059
|
+
function warnMissingOnce(reason, node) {
|
|
9060
|
+
const key = `${reason}:${node.asset.url}:${String(node.asset.atlas)}:${String(node.asset.sprite)}`;
|
|
9061
|
+
if (loggedMissing.has(key)) return;
|
|
9062
|
+
loggedMissing.add(key);
|
|
9063
|
+
spriteLog.warn("draw-sprite asset unresolvable \u2014 painting fallback square", { reason, url: node.asset.url, atlas: node.asset.atlas, sprite: node.asset.sprite });
|
|
9064
|
+
}
|
|
9065
|
+
function paintFallbackSquare(painter, node, dctx, reason) {
|
|
9066
|
+
warnMissingOnce(reason, node);
|
|
9067
|
+
const tw = dctx.projector.tileWidth;
|
|
9068
|
+
const natural = dctx.projector.worldPixelDirect ? FALLBACK_WORLD_PX : tw;
|
|
9069
|
+
const w = node.width !== void 0 ? node.width * tw : natural;
|
|
9070
|
+
const h = node.height !== void 0 ? node.height * tw : natural;
|
|
9071
|
+
const anchor = node.anchor ?? "top-left";
|
|
9072
|
+
const p = dctx.projector.anchorPoint(node.position, anchor);
|
|
9073
|
+
const dx = anchor === "top-left" ? p.x : p.x - w / 2;
|
|
9074
|
+
const dy = anchor === "ground" ? p.y - h : anchor === "center" ? p.y - h / 2 : p.y;
|
|
9075
|
+
painter.save();
|
|
9076
|
+
if (node.opacity !== void 0 && node.opacity !== 1) painter.setAlpha(node.opacity);
|
|
9077
|
+
painter.fillRect(dx, dy, w, h, "#9b8f7f");
|
|
9078
|
+
painter.strokeRect(dx, dy, w, h, "#5e564b", Math.max(1, tw / 32));
|
|
9079
|
+
painter.restore();
|
|
9080
|
+
}
|
|
9128
9081
|
function DrawSprite(_props) {
|
|
9129
9082
|
return null;
|
|
9130
9083
|
}
|
|
9131
|
-
var paintSprite;
|
|
9084
|
+
var spriteLog, loggedMissing, FALLBACK_WORLD_PX, paintSprite;
|
|
9132
9085
|
var init_DrawSprite = __esm({
|
|
9133
9086
|
"components/game/atoms/DrawSprite.tsx"() {
|
|
9134
9087
|
"use client";
|
|
9135
9088
|
init_atlasSlice();
|
|
9089
|
+
init_imageCache();
|
|
9136
9090
|
init_contract();
|
|
9091
|
+
spriteLog = logger.createLogger("almadar:ui:draw-sprite");
|
|
9092
|
+
loggedMissing = /* @__PURE__ */ new Set();
|
|
9093
|
+
FALLBACK_WORLD_PX = 32;
|
|
9137
9094
|
paintSprite = (painter, node, dctx) => {
|
|
9138
9095
|
if (!node.asset?.url || !isValidScenePos(node.position)) return;
|
|
9139
9096
|
const tex = painter.resolveTexture(node.asset.url);
|
|
9140
|
-
if (!tex)
|
|
9097
|
+
if (!tex) {
|
|
9098
|
+
if (getImageStatus(node.asset.url) === "failed") paintFallbackSquare(painter, node, dctx, "texture-failed");
|
|
9099
|
+
return;
|
|
9100
|
+
}
|
|
9141
9101
|
let src = typeof node.frame === "object" ? node.frame : void 0;
|
|
9142
9102
|
if (!src && isAtlasAsset(node.asset)) {
|
|
9143
9103
|
const atlas = getAtlas(node.asset.atlas, dctx.invalidate);
|
|
9144
|
-
if (!atlas)
|
|
9104
|
+
if (!atlas) {
|
|
9105
|
+
if (atlasFailed(node.asset.atlas)) paintFallbackSquare(painter, node, dctx, "atlas-failed");
|
|
9106
|
+
return;
|
|
9107
|
+
}
|
|
9145
9108
|
const r = subRectFor(atlas, node.asset.sprite);
|
|
9146
|
-
if (!r)
|
|
9109
|
+
if (!r) {
|
|
9110
|
+
paintFallbackSquare(painter, node, dctx, "sprite-missing");
|
|
9111
|
+
return;
|
|
9112
|
+
}
|
|
9147
9113
|
src = { x: r.sx, y: r.sy, w: r.sw, h: r.sh };
|
|
9148
9114
|
}
|
|
9149
9115
|
const tw = dctx.projector.tileWidth;
|
|
9150
|
-
const
|
|
9151
|
-
const
|
|
9116
|
+
const fallbackW = dctx.projector.worldPixelDirect ? src ? src.w : tex.width : tw;
|
|
9117
|
+
const fallbackH = dctx.projector.worldPixelDirect ? src ? src.h : tex.height : tw;
|
|
9118
|
+
const w = node.width !== void 0 ? node.width * tw : fallbackW;
|
|
9119
|
+
const h = node.height !== void 0 ? node.height * tw : fallbackH;
|
|
9152
9120
|
const anchor = node.anchor ?? "top-left";
|
|
9153
9121
|
const p = dctx.projector.anchorPoint(node.position, anchor);
|
|
9154
9122
|
const dx = anchor === "top-left" ? p.x : p.x - w / 2;
|
|
@@ -9225,6 +9193,16 @@ var init_DrawShape = __esm({
|
|
|
9225
9193
|
if (node.stroke) painter.strokePoly(pts, node.stroke, node.strokeWidth ?? 1, true);
|
|
9226
9194
|
break;
|
|
9227
9195
|
}
|
|
9196
|
+
case "path": {
|
|
9197
|
+
if (!node.d) break;
|
|
9198
|
+
const base = dctx.projector.project(node.position);
|
|
9199
|
+
const tw = dctx.projector.tileWidth;
|
|
9200
|
+
painter.translate(base.x, base.y);
|
|
9201
|
+
painter.scale(tw, tw);
|
|
9202
|
+
if (node.fill) painter.fillPath(node.d, node.fill);
|
|
9203
|
+
if (node.stroke) painter.strokePath(node.d, node.stroke, (node.strokeWidth ?? 1) / tw);
|
|
9204
|
+
break;
|
|
9205
|
+
}
|
|
9228
9206
|
}
|
|
9229
9207
|
painter.restore();
|
|
9230
9208
|
};
|
|
@@ -9316,6 +9294,19 @@ function paintDrawable(painter, node, dctx) {
|
|
|
9316
9294
|
case "draw-text":
|
|
9317
9295
|
paintText(painter, node, dctx);
|
|
9318
9296
|
break;
|
|
9297
|
+
case "draw-group": {
|
|
9298
|
+
if (!isValidScenePos(node.position)) break;
|
|
9299
|
+
if (!Array.isArray(node.items)) break;
|
|
9300
|
+
const p = dctx.projector.project(node.position);
|
|
9301
|
+
painter.save();
|
|
9302
|
+
painter.translate(p.x, p.y);
|
|
9303
|
+
if (node.scale !== void 0) painter.scale(node.scale, node.scale);
|
|
9304
|
+
if (node.rotate !== void 0) painter.rotate(node.rotate);
|
|
9305
|
+
if (node.opacity !== void 0 && node.opacity !== 1) painter.setAlpha(node.opacity);
|
|
9306
|
+
for (const item of node.items) paintDrawable(painter, item, dctx);
|
|
9307
|
+
painter.restore();
|
|
9308
|
+
break;
|
|
9309
|
+
}
|
|
9319
9310
|
case "draw-sprite-layer":
|
|
9320
9311
|
paintSpriteLayer(painter, node, dctx);
|
|
9321
9312
|
break;
|
|
@@ -9329,6 +9320,7 @@ function paintDrawable(painter, node, dctx) {
|
|
|
9329
9320
|
}
|
|
9330
9321
|
var init_paintDispatch = __esm({
|
|
9331
9322
|
"lib/drawable/paintDispatch.ts"() {
|
|
9323
|
+
init_contract();
|
|
9332
9324
|
init_DrawSprite();
|
|
9333
9325
|
init_DrawShape();
|
|
9334
9326
|
init_DrawText();
|
|
@@ -9346,6 +9338,7 @@ function collectDrawnItems(nodes) {
|
|
|
9346
9338
|
case "draw-sprite":
|
|
9347
9339
|
case "draw-shape":
|
|
9348
9340
|
case "draw-text":
|
|
9341
|
+
case "draw-group":
|
|
9349
9342
|
if (isValidScenePos(n.position)) out.push({ pos: n.position, id: n.id });
|
|
9350
9343
|
break;
|
|
9351
9344
|
case "draw-sprite-layer":
|
|
@@ -9389,6 +9382,8 @@ function Canvas2D({
|
|
|
9389
9382
|
keyUpMap,
|
|
9390
9383
|
camera = "pan-zoom",
|
|
9391
9384
|
scale = 0.4,
|
|
9385
|
+
tileWidth,
|
|
9386
|
+
fit = false,
|
|
9392
9387
|
showMinimap = true,
|
|
9393
9388
|
followTarget,
|
|
9394
9389
|
cameraPos,
|
|
@@ -9431,9 +9426,32 @@ function Canvas2D({
|
|
|
9431
9426
|
observer2.observe(el);
|
|
9432
9427
|
return () => observer2.disconnect();
|
|
9433
9428
|
}, []);
|
|
9434
|
-
const
|
|
9435
|
-
const
|
|
9436
|
-
const
|
|
9429
|
+
const [atlasVersion, setAtlasVersion] = React85.useState(0);
|
|
9430
|
+
const bumpAtlas = React85.useCallback(() => setAtlasVersion((v) => v + 1), []);
|
|
9431
|
+
const detectedTileWidth = React85.useMemo(() => {
|
|
9432
|
+
for (const n of drawables ?? []) {
|
|
9433
|
+
const refs = [];
|
|
9434
|
+
if (n.type === "draw-sprite") refs.push(n.asset);
|
|
9435
|
+
else if (n.type === "draw-sprite-layer") for (const it of n.items) refs.push(it.asset);
|
|
9436
|
+
for (const a of refs) {
|
|
9437
|
+
if (a && isAtlasAsset(a) && a.atlas) {
|
|
9438
|
+
const atlas = getAtlas(a.atlas, bumpAtlas);
|
|
9439
|
+
if (atlas) {
|
|
9440
|
+
if ("tileWidth" in atlas) return atlas.tileWidth;
|
|
9441
|
+
if ("subTextures" in atlas) {
|
|
9442
|
+
const first = Object.values(atlas.subTextures)[0];
|
|
9443
|
+
if (first && typeof first.width === "number") return first.width;
|
|
9444
|
+
}
|
|
9445
|
+
}
|
|
9446
|
+
}
|
|
9447
|
+
}
|
|
9448
|
+
}
|
|
9449
|
+
return void 0;
|
|
9450
|
+
}, [drawables, atlasVersion]);
|
|
9451
|
+
const nativeTileW = tileWidth ?? detectedTileWidth ?? TILE_WIDTH;
|
|
9452
|
+
const scaledTileWidth = nativeTileW;
|
|
9453
|
+
const scaledFloorHeight = nativeTileW / 2;
|
|
9454
|
+
const scaledDiamondTopY = nativeTileW * (DIAMOND_TOP_Y / TILE_WIDTH);
|
|
9437
9455
|
const drawnItems = React85.useMemo(() => collectDrawnItems(drawables ?? []), [drawables]);
|
|
9438
9456
|
const scenePositions = React85.useMemo(() => drawnItems.map((i) => i.pos), [drawnItems]);
|
|
9439
9457
|
const hitIndex = React85.useMemo(() => buildHitIndex(drawnItems), [drawnItems]);
|
|
@@ -9451,14 +9469,36 @@ function Canvas2D({
|
|
|
9451
9469
|
if (isFree || projection === "flat" || projection === "side") return 0;
|
|
9452
9470
|
return (gridExtent.height - 1) * (scaledTileWidth / 2);
|
|
9453
9471
|
}, [isFree, projection, gridExtent.height, scaledTileWidth]);
|
|
9472
|
+
const effectiveZoom = React85.useMemo(() => {
|
|
9473
|
+
if (isFree || projection === "side") return scale;
|
|
9474
|
+
if (!fit) {
|
|
9475
|
+
const z2 = TILE_WIDTH * scale * scale / nativeTileW;
|
|
9476
|
+
return Number.isFinite(z2) && z2 > 0 ? z2 : scale;
|
|
9477
|
+
}
|
|
9478
|
+
if (!viewportSize.width || gridExtent.width < 2 || gridExtent.height < 2) return scale;
|
|
9479
|
+
let boardW;
|
|
9480
|
+
let boardH;
|
|
9481
|
+
if (projection === "flat") {
|
|
9482
|
+
boardW = gridExtent.width * nativeTileW;
|
|
9483
|
+
boardH = gridExtent.height * nativeTileW;
|
|
9484
|
+
} else if (projection === "hex") {
|
|
9485
|
+
boardW = (gridExtent.width + 0.5) * nativeTileW;
|
|
9486
|
+
boardH = gridExtent.height * (nativeTileW / 2) * 0.75 + nativeTileW / 2;
|
|
9487
|
+
} else {
|
|
9488
|
+
boardW = (gridExtent.width + gridExtent.height) * (nativeTileW / 2);
|
|
9489
|
+
boardH = (gridExtent.width + gridExtent.height) * (nativeTileW / 4);
|
|
9490
|
+
}
|
|
9491
|
+
const z = Math.min(viewportSize.width * 0.85 / boardW, viewportSize.height * 0.85 / boardH);
|
|
9492
|
+
return Number.isFinite(z) && z > 0 ? z : scale;
|
|
9493
|
+
}, [isFree, projection, fit, viewportSize, gridExtent, nativeTileW, scale]);
|
|
9454
9494
|
const projector = React85.useMemo(
|
|
9455
|
-
() => create2DProjector({
|
|
9456
|
-
[
|
|
9495
|
+
() => create2DProjector({ tileWidth: nativeTileW, baseOffsetX, layout }),
|
|
9496
|
+
[nativeTileW, baseOffsetX, layout]
|
|
9457
9497
|
);
|
|
9458
9498
|
const unproject = React85.useCallback((screenX, screenY) => {
|
|
9459
9499
|
if (projection === "free" || projection === "side") return { x: Math.round(screenX), y: Math.round(screenY) };
|
|
9460
|
-
return screenToIso(screenX, screenY,
|
|
9461
|
-
}, [projection,
|
|
9500
|
+
return screenToIso(screenX, screenY, nativeTileW, baseOffsetX, projection);
|
|
9501
|
+
}, [projection, nativeTileW, baseOffsetX]);
|
|
9462
9502
|
const bgUrls = React85.useMemo(() => backgroundImage ? [backgroundImage.url] : [], [backgroundImage]);
|
|
9463
9503
|
const { getImage, pendingCount: _imagePendingCount } = useImageCache(bgUrls);
|
|
9464
9504
|
React85.useEffect(() => {
|
|
@@ -9485,9 +9525,7 @@ function Canvas2D({
|
|
|
9485
9525
|
zoomAtPoint,
|
|
9486
9526
|
screenToWorld,
|
|
9487
9527
|
lerpToTarget
|
|
9488
|
-
} = useCamera({ zoom:
|
|
9489
|
-
const [atlasVersion, setAtlasVersion] = React85.useState(0);
|
|
9490
|
-
const bumpAtlas = React85.useCallback(() => setAtlasVersion((v) => v + 1), []);
|
|
9528
|
+
} = useCamera({ zoom: effectiveZoom });
|
|
9491
9529
|
const miniMapTiles = React85.useMemo(() => {
|
|
9492
9530
|
if (!showMinimap) return [];
|
|
9493
9531
|
const color = MINIMAP_TERRAIN_COLORS.default;
|
|
@@ -9562,6 +9600,13 @@ function Canvas2D({
|
|
|
9562
9600
|
React85.useEffect(() => {
|
|
9563
9601
|
draw();
|
|
9564
9602
|
}, [_imagePendingCount, draw]);
|
|
9603
|
+
const userZoomedRef = React85.useRef(false);
|
|
9604
|
+
React85.useEffect(() => {
|
|
9605
|
+
if (userZoomedRef.current) return;
|
|
9606
|
+
if (cameraRef.current.zoom === effectiveZoom) return;
|
|
9607
|
+
cameraRef.current.zoom = effectiveZoom;
|
|
9608
|
+
draw();
|
|
9609
|
+
}, [effectiveZoom, cameraRef, draw]);
|
|
9565
9610
|
React85.useEffect(() => {
|
|
9566
9611
|
draw();
|
|
9567
9612
|
}, [atlasVersion, draw]);
|
|
@@ -9618,7 +9663,9 @@ function Canvas2D({
|
|
|
9618
9663
|
if (tileLeaveEvent) eventBus.emit(`UI:${tileLeaveEvent}`, {});
|
|
9619
9664
|
}, [handleMouseLeave, tileLeaveEvent, eventBus]);
|
|
9620
9665
|
const applyZoom = React85.useCallback((factor, centerX, centerY) => {
|
|
9621
|
-
if (enableCamera)
|
|
9666
|
+
if (!enableCamera) return;
|
|
9667
|
+
userZoomedRef.current = true;
|
|
9668
|
+
zoomAtPoint(factor, centerX, centerY, viewportSize, () => draw());
|
|
9622
9669
|
}, [enableCamera, zoomAtPoint, viewportSize, draw]);
|
|
9623
9670
|
const applyPanDelta = React85.useCallback((dx, dy) => {
|
|
9624
9671
|
if (enableCamera) panBy(dx, dy, () => draw());
|
|
@@ -9803,6 +9850,8 @@ function Canvas({
|
|
|
9803
9850
|
isLoading,
|
|
9804
9851
|
unitScale,
|
|
9805
9852
|
showMinimap,
|
|
9853
|
+
fit,
|
|
9854
|
+
tileWidth,
|
|
9806
9855
|
backgroundImage,
|
|
9807
9856
|
backgroundColor,
|
|
9808
9857
|
worldWidth,
|
|
@@ -9860,6 +9909,8 @@ function Canvas({
|
|
|
9860
9909
|
projection,
|
|
9861
9910
|
camera: to2DCamera(camera?.mode),
|
|
9862
9911
|
...zoom !== void 0 ? { scale: zoom } : {},
|
|
9912
|
+
...fit !== void 0 ? { fit } : {},
|
|
9913
|
+
...tileWidth !== void 0 ? { tileWidth } : {},
|
|
9863
9914
|
...camera?.target !== void 0 ? { followTarget: camera.target } : {},
|
|
9864
9915
|
...camera?.pos !== void 0 ? { cameraPos: camera.pos } : {},
|
|
9865
9916
|
showMinimap,
|
|
@@ -9886,32 +9937,6 @@ var init_Canvas = __esm({
|
|
|
9886
9937
|
Canvas.displayName = "Canvas";
|
|
9887
9938
|
}
|
|
9888
9939
|
});
|
|
9889
|
-
function SvgDrawShapeLayer({
|
|
9890
|
-
items,
|
|
9891
|
-
fill,
|
|
9892
|
-
stroke,
|
|
9893
|
-
strokeWidth,
|
|
9894
|
-
opacity
|
|
9895
|
-
}) {
|
|
9896
|
-
return /* @__PURE__ */ jsxRuntime.jsx("g", { children: items.map(({ id, ...shape }) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
9897
|
-
SvgDrawShape,
|
|
9898
|
-
{
|
|
9899
|
-
...shape,
|
|
9900
|
-
fill: shape.fill ?? fill,
|
|
9901
|
-
stroke: shape.stroke ?? stroke,
|
|
9902
|
-
strokeWidth: shape.strokeWidth ?? strokeWidth,
|
|
9903
|
-
opacity: shape.opacity ?? opacity
|
|
9904
|
-
},
|
|
9905
|
-
id
|
|
9906
|
-
)) });
|
|
9907
|
-
}
|
|
9908
|
-
var init_SvgDrawShapeLayer = __esm({
|
|
9909
|
-
"components/game/molecules/SvgDrawShapeLayer.tsx"() {
|
|
9910
|
-
"use client";
|
|
9911
|
-
init_SvgDrawShape();
|
|
9912
|
-
SvgDrawShapeLayer.displayName = "SvgDrawShapeLayer";
|
|
9913
|
-
}
|
|
9914
|
-
});
|
|
9915
9940
|
function GameAudioToggle({
|
|
9916
9941
|
size = "sm",
|
|
9917
9942
|
className,
|
|
@@ -23878,6 +23903,8 @@ function DataList({
|
|
|
23878
23903
|
hasMore,
|
|
23879
23904
|
children,
|
|
23880
23905
|
pageSize = 5,
|
|
23906
|
+
sortBy,
|
|
23907
|
+
sortDirection,
|
|
23881
23908
|
renderItem: schemaRenderItem,
|
|
23882
23909
|
dragGroup,
|
|
23883
23910
|
accepts,
|
|
@@ -23906,7 +23933,11 @@ function DataList({
|
|
|
23906
23933
|
dndItemIdField,
|
|
23907
23934
|
dndRoot
|
|
23908
23935
|
});
|
|
23909
|
-
const
|
|
23936
|
+
const orderedData = dnd.orderedItems;
|
|
23937
|
+
const allData = React85__namespace.default.useMemo(
|
|
23938
|
+
() => sortRows(orderedData, sortBy, sortDirection),
|
|
23939
|
+
[orderedData, sortBy, sortDirection]
|
|
23940
|
+
);
|
|
23910
23941
|
const data = pageSize > 0 ? allData.slice(0, visibleCount) : allData;
|
|
23911
23942
|
const hasMoreLocal = pageSize > 0 && visibleCount < allData.length;
|
|
23912
23943
|
const hasRenderProp = typeof children === "function";
|
|
@@ -23943,7 +23974,7 @@ function DataList({
|
|
|
23943
23974
|
};
|
|
23944
23975
|
eventBus.emit(`UI:${action.event}`, payload);
|
|
23945
23976
|
};
|
|
23946
|
-
const renderItemActions = (itemData) => {
|
|
23977
|
+
const renderItemActions = (itemData, onPrimary = false) => {
|
|
23947
23978
|
if (!itemActions || itemActions.length === 0) return null;
|
|
23948
23979
|
const inline = maxInlineActions != null ? itemActions.slice(0, maxInlineActions) : itemActions;
|
|
23949
23980
|
const overflow = maxInlineActions != null ? itemActions.slice(maxInlineActions) : [];
|
|
@@ -23956,7 +23987,12 @@ function DataList({
|
|
|
23956
23987
|
onClick: handleActionClick(action, itemData),
|
|
23957
23988
|
"data-testid": `action-${action.event}`,
|
|
23958
23989
|
"data-row-id": String(itemData.id),
|
|
23959
|
-
className: cn(
|
|
23990
|
+
className: cn(
|
|
23991
|
+
action.variant === "danger" && "text-error hover:bg-error/10",
|
|
23992
|
+
// Must sit on the Button itself: the variant's own text colour
|
|
23993
|
+
// beats an inherited one from the row wrapper.
|
|
23994
|
+
onPrimary && "!text-primary-foreground hover:bg-primary-foreground/15"
|
|
23995
|
+
),
|
|
23960
23996
|
children: [
|
|
23961
23997
|
action.icon && renderIconInput2(action.icon, { size: "xs", className: "mr-1" }),
|
|
23962
23998
|
action.label
|
|
@@ -24056,7 +24092,11 @@ function DataList({
|
|
|
24056
24092
|
metaFields.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(HStack, { gap: "xs", className: "mt-1 flex-wrap", children: metaFields.map((f3) => {
|
|
24057
24093
|
const v = getNestedValue(itemData, f3.name);
|
|
24058
24094
|
if (v === void 0 || v === null || v === "") return null;
|
|
24059
|
-
return f3.variant === "badge" ?
|
|
24095
|
+
return f3.variant === "badge" ? (
|
|
24096
|
+
// `format` applies here too — a boolean field badged
|
|
24097
|
+
// without it renders the raw "false" instead of "No".
|
|
24098
|
+
/* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: statusVariant3(String(v)), children: formatValue2(v, f3.format) }, f3.name)
|
|
24099
|
+
) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
24060
24100
|
Typography,
|
|
24061
24101
|
{
|
|
24062
24102
|
variant: "caption",
|
|
@@ -24075,7 +24115,7 @@ function DataList({
|
|
|
24075
24115
|
children: formatDate(timestamp)
|
|
24076
24116
|
}
|
|
24077
24117
|
) : /* @__PURE__ */ jsxRuntime.jsx("span", {}),
|
|
24078
|
-
renderItemActions(itemData)
|
|
24118
|
+
renderItemActions(itemData, isSent)
|
|
24079
24119
|
] })
|
|
24080
24120
|
]
|
|
24081
24121
|
}
|
|
@@ -24168,7 +24208,7 @@ function DataList({
|
|
|
24168
24208
|
if (val === void 0 || val === null) return null;
|
|
24169
24209
|
return /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "xs", className: "items-center flex-shrink-0", children: [
|
|
24170
24210
|
field.icon && renderIconInput2(field.icon, { size: "xs" }),
|
|
24171
|
-
/* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: statusVariant3(String(val)), children:
|
|
24211
|
+
/* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: statusVariant3(String(val)), children: formatValue2(val, field.format) })
|
|
24172
24212
|
] }, field.name);
|
|
24173
24213
|
})
|
|
24174
24214
|
] }),
|
|
@@ -24407,6 +24447,182 @@ var init_FormSection = __esm({
|
|
|
24407
24447
|
FormActions.displayName = "FormActions";
|
|
24408
24448
|
}
|
|
24409
24449
|
});
|
|
24450
|
+
var ALL_CATEGORY, MAX_RENDERED, GridPicker;
|
|
24451
|
+
var init_GridPicker = __esm({
|
|
24452
|
+
"components/core/molecules/GridPicker.tsx"() {
|
|
24453
|
+
"use client";
|
|
24454
|
+
init_cn();
|
|
24455
|
+
init_Input();
|
|
24456
|
+
init_Badge();
|
|
24457
|
+
init_Stack();
|
|
24458
|
+
ALL_CATEGORY = "__all__";
|
|
24459
|
+
MAX_RENDERED = 300;
|
|
24460
|
+
GridPicker = ({
|
|
24461
|
+
items,
|
|
24462
|
+
value,
|
|
24463
|
+
onChange,
|
|
24464
|
+
categories,
|
|
24465
|
+
searchPlaceholder,
|
|
24466
|
+
renderThumbnail,
|
|
24467
|
+
cellSize = 32,
|
|
24468
|
+
className
|
|
24469
|
+
}) => {
|
|
24470
|
+
const [search, setSearch] = React85.useState("");
|
|
24471
|
+
const [activeCategory, setActiveCategory] = React85.useState(ALL_CATEGORY);
|
|
24472
|
+
const gridRef = React85.useRef(null);
|
|
24473
|
+
const categoryChips = React85.useMemo(() => {
|
|
24474
|
+
if (categories !== void 0) return categories;
|
|
24475
|
+
const seen = [];
|
|
24476
|
+
for (const item of items) {
|
|
24477
|
+
if (!seen.includes(item.category)) seen.push(item.category);
|
|
24478
|
+
}
|
|
24479
|
+
return seen;
|
|
24480
|
+
}, [categories, items]);
|
|
24481
|
+
const filtered = React85.useMemo(() => {
|
|
24482
|
+
const needle = search.trim().toLowerCase();
|
|
24483
|
+
return items.filter((item) => {
|
|
24484
|
+
const matchesCategory = activeCategory === ALL_CATEGORY || item.category === activeCategory;
|
|
24485
|
+
const matchesSearch = needle === "" || item.label.toLowerCase().includes(needle) || item.keywords !== void 0 && item.keywords.some((k) => k.toLowerCase().includes(needle));
|
|
24486
|
+
return matchesCategory && matchesSearch;
|
|
24487
|
+
});
|
|
24488
|
+
}, [items, search, activeCategory]);
|
|
24489
|
+
const visible = React85.useMemo(() => filtered.slice(0, MAX_RENDERED), [filtered]);
|
|
24490
|
+
const truncated = filtered.length - visible.length;
|
|
24491
|
+
const select = React85.useCallback(
|
|
24492
|
+
(item) => {
|
|
24493
|
+
onChange(item.id);
|
|
24494
|
+
},
|
|
24495
|
+
[onChange]
|
|
24496
|
+
);
|
|
24497
|
+
const handleKeyDown = React85.useCallback(
|
|
24498
|
+
(e, index) => {
|
|
24499
|
+
const cells = gridRef.current?.querySelectorAll(
|
|
24500
|
+
"[data-gridpicker-cell]"
|
|
24501
|
+
);
|
|
24502
|
+
if (cells === void 0 || cells.length === 0) return;
|
|
24503
|
+
const columns = (() => {
|
|
24504
|
+
const grid = gridRef.current;
|
|
24505
|
+
if (grid === null) return 1;
|
|
24506
|
+
const style = window.getComputedStyle(grid);
|
|
24507
|
+
const cols = style.gridTemplateColumns.split(" ").filter(Boolean).length;
|
|
24508
|
+
return cols > 0 ? cols : 1;
|
|
24509
|
+
})();
|
|
24510
|
+
let next = -1;
|
|
24511
|
+
if (e.key === "ArrowRight") next = index + 1;
|
|
24512
|
+
else if (e.key === "ArrowLeft") next = index - 1;
|
|
24513
|
+
else if (e.key === "ArrowDown") next = index + columns;
|
|
24514
|
+
else if (e.key === "ArrowUp") next = index - columns;
|
|
24515
|
+
else if (e.key === "Enter" || e.key === " ") {
|
|
24516
|
+
e.preventDefault();
|
|
24517
|
+
select(filtered[index]);
|
|
24518
|
+
return;
|
|
24519
|
+
} else {
|
|
24520
|
+
return;
|
|
24521
|
+
}
|
|
24522
|
+
e.preventDefault();
|
|
24523
|
+
if (next >= 0 && next < cells.length) {
|
|
24524
|
+
cells[next].focus();
|
|
24525
|
+
}
|
|
24526
|
+
},
|
|
24527
|
+
[filtered, select]
|
|
24528
|
+
);
|
|
24529
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "sm", className: cn("w-full", className), children: [
|
|
24530
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
24531
|
+
Input,
|
|
24532
|
+
{
|
|
24533
|
+
type: "search",
|
|
24534
|
+
icon: "search",
|
|
24535
|
+
value: search,
|
|
24536
|
+
placeholder: searchPlaceholder,
|
|
24537
|
+
clearable: true,
|
|
24538
|
+
onClear: () => setSearch(""),
|
|
24539
|
+
onChange: (e) => setSearch(e.target.value)
|
|
24540
|
+
}
|
|
24541
|
+
),
|
|
24542
|
+
categoryChips.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "xs", wrap: true, children: [
|
|
24543
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
24544
|
+
Badge,
|
|
24545
|
+
{
|
|
24546
|
+
variant: activeCategory === ALL_CATEGORY ? "primary" : "neutral",
|
|
24547
|
+
size: "sm",
|
|
24548
|
+
role: "button",
|
|
24549
|
+
tabIndex: 0,
|
|
24550
|
+
"aria-pressed": activeCategory === ALL_CATEGORY,
|
|
24551
|
+
className: "cursor-pointer",
|
|
24552
|
+
onClick: () => setActiveCategory(ALL_CATEGORY),
|
|
24553
|
+
onKeyDown: (e) => {
|
|
24554
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
24555
|
+
e.preventDefault();
|
|
24556
|
+
setActiveCategory(ALL_CATEGORY);
|
|
24557
|
+
}
|
|
24558
|
+
},
|
|
24559
|
+
children: "All"
|
|
24560
|
+
}
|
|
24561
|
+
),
|
|
24562
|
+
categoryChips.map((category) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
24563
|
+
Badge,
|
|
24564
|
+
{
|
|
24565
|
+
variant: activeCategory === category ? "primary" : "neutral",
|
|
24566
|
+
size: "sm",
|
|
24567
|
+
role: "button",
|
|
24568
|
+
tabIndex: 0,
|
|
24569
|
+
"aria-pressed": activeCategory === category,
|
|
24570
|
+
className: "cursor-pointer",
|
|
24571
|
+
onClick: () => setActiveCategory(category),
|
|
24572
|
+
onKeyDown: (e) => {
|
|
24573
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
24574
|
+
e.preventDefault();
|
|
24575
|
+
setActiveCategory(category);
|
|
24576
|
+
}
|
|
24577
|
+
},
|
|
24578
|
+
children: category
|
|
24579
|
+
},
|
|
24580
|
+
category
|
|
24581
|
+
))
|
|
24582
|
+
] }),
|
|
24583
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
24584
|
+
"div",
|
|
24585
|
+
{
|
|
24586
|
+
ref: gridRef,
|
|
24587
|
+
role: "listbox",
|
|
24588
|
+
className: "grid gap-1 overflow-y-auto max-h-64 p-1",
|
|
24589
|
+
style: {
|
|
24590
|
+
gridTemplateColumns: `repeat(auto-fill, minmax(${cellSize}px, 1fr))`
|
|
24591
|
+
},
|
|
24592
|
+
children: visible.map((item, index) => {
|
|
24593
|
+
const selected = item.id === value;
|
|
24594
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
24595
|
+
"button",
|
|
24596
|
+
{
|
|
24597
|
+
type: "button",
|
|
24598
|
+
role: "option",
|
|
24599
|
+
"aria-selected": selected,
|
|
24600
|
+
"aria-label": item.label,
|
|
24601
|
+
title: item.label,
|
|
24602
|
+
"data-gridpicker-cell": true,
|
|
24603
|
+
tabIndex: selected || value === void 0 && index === 0 ? 0 : -1,
|
|
24604
|
+
onClick: () => select(item),
|
|
24605
|
+
onKeyDown: (e) => handleKeyDown(e, index),
|
|
24606
|
+
className: cn(
|
|
24607
|
+
"flex items-center justify-center rounded-sm",
|
|
24608
|
+
"transition-colors hover:bg-muted",
|
|
24609
|
+
"focus:outline-none focus:ring-1 focus:ring-ring",
|
|
24610
|
+
selected && "bg-primary/10 ring-1 ring-primary"
|
|
24611
|
+
),
|
|
24612
|
+
style: { width: cellSize, height: cellSize },
|
|
24613
|
+
children: renderThumbnail(item)
|
|
24614
|
+
},
|
|
24615
|
+
item.id
|
|
24616
|
+
);
|
|
24617
|
+
})
|
|
24618
|
+
}
|
|
24619
|
+
),
|
|
24620
|
+
truncated > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-1 text-xs text-muted-foreground", children: `+${truncated} more \u2014 refine your search` })
|
|
24621
|
+
] });
|
|
24622
|
+
};
|
|
24623
|
+
GridPicker.displayName = "GridPicker";
|
|
24624
|
+
}
|
|
24625
|
+
});
|
|
24410
24626
|
function fileIcon(name) {
|
|
24411
24627
|
const ext = name.split(".").pop()?.toLowerCase() ?? "";
|
|
24412
24628
|
switch (ext) {
|
|
@@ -25435,9 +25651,16 @@ var init_Popover = __esm({
|
|
|
25435
25651
|
position = "bottom",
|
|
25436
25652
|
trigger = "click",
|
|
25437
25653
|
showArrow = true,
|
|
25654
|
+
open,
|
|
25655
|
+
onOpenChange,
|
|
25438
25656
|
className
|
|
25439
25657
|
}) => {
|
|
25440
|
-
const [
|
|
25658
|
+
const [uncontrolledOpen, setUncontrolledOpen] = React85.useState(false);
|
|
25659
|
+
const isOpen = open !== void 0 ? open : uncontrolledOpen;
|
|
25660
|
+
const setIsOpen = (next) => {
|
|
25661
|
+
if (open === void 0) setUncontrolledOpen(next);
|
|
25662
|
+
onOpenChange?.(next);
|
|
25663
|
+
};
|
|
25441
25664
|
const [triggerRect, setTriggerRect] = React85.useState(null);
|
|
25442
25665
|
const [popoverWidth, setPopoverWidth] = React85.useState(0);
|
|
25443
25666
|
const triggerRef = React85.useRef(null);
|
|
@@ -25470,6 +25693,23 @@ var init_Popover = __esm({
|
|
|
25470
25693
|
updatePosition();
|
|
25471
25694
|
}
|
|
25472
25695
|
}, [isOpen]);
|
|
25696
|
+
React85.useEffect(() => {
|
|
25697
|
+
if (!isOpen) return;
|
|
25698
|
+
let raf = 0;
|
|
25699
|
+
let lastTop = Number.NaN;
|
|
25700
|
+
let lastLeft = Number.NaN;
|
|
25701
|
+
const track = () => {
|
|
25702
|
+
const rect = triggerRef.current?.getBoundingClientRect();
|
|
25703
|
+
if (rect && (rect.top !== lastTop || rect.left !== lastLeft)) {
|
|
25704
|
+
lastTop = rect.top;
|
|
25705
|
+
lastLeft = rect.left;
|
|
25706
|
+
updatePosition();
|
|
25707
|
+
}
|
|
25708
|
+
raf = requestAnimationFrame(track);
|
|
25709
|
+
};
|
|
25710
|
+
raf = requestAnimationFrame(track);
|
|
25711
|
+
return () => cancelAnimationFrame(raf);
|
|
25712
|
+
}, [isOpen]);
|
|
25473
25713
|
React85.useEffect(() => {
|
|
25474
25714
|
if (!mounted) setPopoverWidth(0);
|
|
25475
25715
|
}, [mounted]);
|
|
@@ -26818,6 +27058,80 @@ var init_FlipCard = __esm({
|
|
|
26818
27058
|
FlipCard.displayName = "FlipCard";
|
|
26819
27059
|
}
|
|
26820
27060
|
});
|
|
27061
|
+
var EMOJI_ITEMS, EmojiPicker;
|
|
27062
|
+
var init_EmojiPicker = __esm({
|
|
27063
|
+
"components/core/molecules/EmojiPicker.tsx"() {
|
|
27064
|
+
"use client";
|
|
27065
|
+
init_useEventBus();
|
|
27066
|
+
init_Button();
|
|
27067
|
+
init_GridPicker();
|
|
27068
|
+
init_Popover();
|
|
27069
|
+
EMOJI_ITEMS = (() => {
|
|
27070
|
+
const items = [];
|
|
27071
|
+
for (const name of emojilib.ordered) {
|
|
27072
|
+
const entry = emojilib.lib[name];
|
|
27073
|
+
if (entry === void 0 || entry.char === null || entry.char === "") continue;
|
|
27074
|
+
items.push({
|
|
27075
|
+
id: entry.char,
|
|
27076
|
+
label: name.replace(/_/g, " "),
|
|
27077
|
+
category: entry.category.replace(/_/g, " "),
|
|
27078
|
+
keywords: entry.keywords
|
|
27079
|
+
});
|
|
27080
|
+
}
|
|
27081
|
+
return items;
|
|
27082
|
+
})();
|
|
27083
|
+
EmojiPicker = ({
|
|
27084
|
+
pickEvent,
|
|
27085
|
+
position = "top",
|
|
27086
|
+
triggerIcon = "smile",
|
|
27087
|
+
triggerLabel = "Add emoji",
|
|
27088
|
+
className
|
|
27089
|
+
}) => {
|
|
27090
|
+
const eventBus = useEventBus();
|
|
27091
|
+
const [open, setOpen] = React85.useState(false);
|
|
27092
|
+
const handlePick = (glyph) => {
|
|
27093
|
+
if (pickEvent !== void 0) {
|
|
27094
|
+
const payload = { emoji: glyph };
|
|
27095
|
+
eventBus.emit(`UI:${pickEvent}`, payload);
|
|
27096
|
+
}
|
|
27097
|
+
setOpen(false);
|
|
27098
|
+
};
|
|
27099
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
27100
|
+
Popover,
|
|
27101
|
+
{
|
|
27102
|
+
position,
|
|
27103
|
+
trigger: "click",
|
|
27104
|
+
showArrow: false,
|
|
27105
|
+
open,
|
|
27106
|
+
onOpenChange: setOpen,
|
|
27107
|
+
content: /* @__PURE__ */ jsxRuntime.jsx(
|
|
27108
|
+
GridPicker,
|
|
27109
|
+
{
|
|
27110
|
+
items: EMOJI_ITEMS,
|
|
27111
|
+
onChange: handlePick,
|
|
27112
|
+
searchPlaceholder: "Search emoji\u2026",
|
|
27113
|
+
renderThumbnail: (item) => /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xl leading-none", "aria-hidden": "true", children: item.id }),
|
|
27114
|
+
cellSize: 32,
|
|
27115
|
+
className: "w-80"
|
|
27116
|
+
}
|
|
27117
|
+
),
|
|
27118
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
27119
|
+
Button,
|
|
27120
|
+
{
|
|
27121
|
+
variant: "ghost",
|
|
27122
|
+
icon: triggerIcon,
|
|
27123
|
+
"aria-label": triggerLabel,
|
|
27124
|
+
title: triggerLabel,
|
|
27125
|
+
className,
|
|
27126
|
+
"data-testid": "emoji-picker-trigger"
|
|
27127
|
+
}
|
|
27128
|
+
)
|
|
27129
|
+
}
|
|
27130
|
+
);
|
|
27131
|
+
};
|
|
27132
|
+
EmojiPicker.displayName = "EmojiPicker";
|
|
27133
|
+
}
|
|
27134
|
+
});
|
|
26821
27135
|
function toISODate(d) {
|
|
26822
27136
|
return d.toISOString().slice(0, 10);
|
|
26823
27137
|
}
|
|
@@ -27770,13 +28084,13 @@ var init_MapView = __esm({
|
|
|
27770
28084
|
shadowSize: [41, 41]
|
|
27771
28085
|
});
|
|
27772
28086
|
L.Marker.prototype.options.icon = defaultIcon;
|
|
27773
|
-
const { useEffect:
|
|
28087
|
+
const { useEffect: useEffect62, useRef: useRef61, useCallback: useCallback95, useState: useState93 } = React85__namespace.default;
|
|
27774
28088
|
const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
|
|
27775
28089
|
const { useEventBus: useEventBus2 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
|
|
27776
28090
|
function MapUpdater({ centerLat, centerLng, zoom }) {
|
|
27777
28091
|
const map = useMap();
|
|
27778
28092
|
const prevRef = useRef61({ centerLat, centerLng, zoom });
|
|
27779
|
-
|
|
28093
|
+
useEffect62(() => {
|
|
27780
28094
|
const prev = prevRef.current;
|
|
27781
28095
|
if (prev.centerLat !== centerLat || prev.centerLng !== centerLng || prev.zoom !== zoom) {
|
|
27782
28096
|
map.setView([centerLat, centerLng], zoom);
|
|
@@ -27787,7 +28101,7 @@ var init_MapView = __esm({
|
|
|
27787
28101
|
}
|
|
27788
28102
|
function MapClickHandler({ onMapClick }) {
|
|
27789
28103
|
const map = useMap();
|
|
27790
|
-
|
|
28104
|
+
useEffect62(() => {
|
|
27791
28105
|
if (!onMapClick) return;
|
|
27792
28106
|
const handler = (e) => {
|
|
27793
28107
|
onMapClick(e.latlng.lat, e.latlng.lng);
|
|
@@ -27815,7 +28129,7 @@ var init_MapView = __esm({
|
|
|
27815
28129
|
showAttribution = true
|
|
27816
28130
|
}) {
|
|
27817
28131
|
const eventBus = useEventBus2();
|
|
27818
|
-
const [clickedPosition, setClickedPosition] =
|
|
28132
|
+
const [clickedPosition, setClickedPosition] = useState93(null);
|
|
27819
28133
|
const handleMapClick = useCallback95((lat, lng) => {
|
|
27820
28134
|
if (showClickedPin) {
|
|
27821
28135
|
setClickedPosition({ lat, lng });
|
|
@@ -28660,6 +28974,7 @@ function TableView({
|
|
|
28660
28974
|
fields,
|
|
28661
28975
|
itemActions,
|
|
28662
28976
|
maxInlineActions,
|
|
28977
|
+
itemClickEvent,
|
|
28663
28978
|
selectable = false,
|
|
28664
28979
|
selectEvent,
|
|
28665
28980
|
selectedIds,
|
|
@@ -28704,9 +29019,9 @@ function TableView({
|
|
|
28704
29019
|
dndItemIdField,
|
|
28705
29020
|
dndRoot
|
|
28706
29021
|
});
|
|
28707
|
-
const
|
|
28708
|
-
const data = pageSize > 0 ?
|
|
28709
|
-
const hasMore = pageSize > 0 && visibleCount <
|
|
29022
|
+
const ordered2 = dnd.orderedItems;
|
|
29023
|
+
const data = pageSize > 0 ? ordered2.slice(0, visibleCount) : ordered2;
|
|
29024
|
+
const hasMore = pageSize > 0 && visibleCount < ordered2.length;
|
|
28710
29025
|
const hasRenderProp = typeof children === "function";
|
|
28711
29026
|
const idField = dndItemIdField ?? "id";
|
|
28712
29027
|
const isCoarsePointer = useMediaQuery("(pointer: coarse)");
|
|
@@ -28759,6 +29074,14 @@ function TableView({
|
|
|
28759
29074
|
};
|
|
28760
29075
|
eventBus.emit(`UI:${action.event}`, payload);
|
|
28761
29076
|
};
|
|
29077
|
+
const handleRowClick = (row) => () => {
|
|
29078
|
+
if (!itemClickEvent) return;
|
|
29079
|
+
const payload = {
|
|
29080
|
+
id: row.id,
|
|
29081
|
+
row
|
|
29082
|
+
};
|
|
29083
|
+
eventBus.emit(`UI:${itemClickEvent}`, payload);
|
|
29084
|
+
};
|
|
28762
29085
|
const colFloors = React85__namespace.default.useMemo(
|
|
28763
29086
|
() => colDefs.map((col) => {
|
|
28764
29087
|
const longest = data.reduce((widest, row) => {
|
|
@@ -28835,10 +29158,12 @@ function TableView({
|
|
|
28835
29158
|
role: "row",
|
|
28836
29159
|
"data-entity-row": true,
|
|
28837
29160
|
"data-entity-id": id,
|
|
29161
|
+
onClick: itemClickEvent ? handleRowClick(row) : void 0,
|
|
28838
29162
|
style: !hasRenderProp ? { gridTemplateColumns } : void 0,
|
|
28839
29163
|
className: cn(
|
|
28840
29164
|
"group items-center gap-3 transition-colors duration-fast",
|
|
28841
29165
|
hasRenderProp ? "flex" : "grid",
|
|
29166
|
+
itemClickEvent && "cursor-pointer",
|
|
28842
29167
|
lk.rowPad,
|
|
28843
29168
|
lk.divider && "border-b border-[var(--color-border)]",
|
|
28844
29169
|
lk.striped && index % 2 === 1 && "bg-[var(--color-surface-subtle)]",
|
|
@@ -28846,7 +29171,7 @@ function TableView({
|
|
|
28846
29171
|
look === "bordered" && "[&>*]:border-r [&>*]:border-[var(--color-border)] [&>*:last-child]:border-r-0"
|
|
28847
29172
|
),
|
|
28848
29173
|
children: [
|
|
28849
|
-
selectable && /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "flex items-center", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
29174
|
+
selectable && /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "flex items-center", onClick: itemClickEvent ? (e) => e.stopPropagation() : void 0, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
28850
29175
|
Checkbox,
|
|
28851
29176
|
{
|
|
28852
29177
|
checked: selected.has(id),
|
|
@@ -28871,6 +29196,7 @@ function TableView({
|
|
|
28871
29196
|
HStack,
|
|
28872
29197
|
{
|
|
28873
29198
|
gap: "xs",
|
|
29199
|
+
onClick: itemClickEvent ? (e) => e.stopPropagation() : void 0,
|
|
28874
29200
|
className: cn(
|
|
28875
29201
|
// Pinned: the fixed column tracks routinely overflow the caller's
|
|
28876
29202
|
// scroll container, which used to leave the actions off-screen.
|
|
@@ -28940,7 +29266,7 @@ function TableView({
|
|
|
28940
29266
|
/* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "chevron-down", size: "xs", className: "mr-1" }),
|
|
28941
29267
|
t("common.showMore"),
|
|
28942
29268
|
" (",
|
|
28943
|
-
t("common.remaining", { count:
|
|
29269
|
+
t("common.remaining", { count: ordered2.length - visibleCount }),
|
|
28944
29270
|
")"
|
|
28945
29271
|
] }) })
|
|
28946
29272
|
]
|
|
@@ -38379,6 +38705,16 @@ var init_DetailPanel = __esm({
|
|
|
38379
38705
|
DetailPanel.displayName = "DetailPanel";
|
|
38380
38706
|
}
|
|
38381
38707
|
});
|
|
38708
|
+
|
|
38709
|
+
// components/game/atoms/DrawGroup.tsx
|
|
38710
|
+
function DrawGroup(_props) {
|
|
38711
|
+
return null;
|
|
38712
|
+
}
|
|
38713
|
+
var init_DrawGroup = __esm({
|
|
38714
|
+
"components/game/atoms/DrawGroup.tsx"() {
|
|
38715
|
+
"use client";
|
|
38716
|
+
}
|
|
38717
|
+
});
|
|
38382
38718
|
function extractTitle(children) {
|
|
38383
38719
|
if (!React85__namespace.default.isValidElement(children)) return void 0;
|
|
38384
38720
|
const props = children.props;
|
|
@@ -44082,6 +44418,7 @@ var init_component_registry_generated = __esm({
|
|
|
44082
44418
|
init_DocSidebar();
|
|
44083
44419
|
init_DocTOC();
|
|
44084
44420
|
init_DocumentViewer();
|
|
44421
|
+
init_DrawGroup();
|
|
44085
44422
|
init_DrawShape();
|
|
44086
44423
|
init_DrawShapeLayer();
|
|
44087
44424
|
init_DrawSprite();
|
|
@@ -44091,6 +44428,7 @@ var init_component_registry_generated = __esm({
|
|
|
44091
44428
|
init_Drawer();
|
|
44092
44429
|
init_DrawerSlot();
|
|
44093
44430
|
init_EdgeDecoration();
|
|
44431
|
+
init_EmojiPicker();
|
|
44094
44432
|
init_EmptyState();
|
|
44095
44433
|
init_ErrorBoundary();
|
|
44096
44434
|
init_ErrorState();
|
|
@@ -44225,10 +44563,6 @@ var init_component_registry_generated = __esm({
|
|
|
44225
44563
|
init_SubagentTracePanel();
|
|
44226
44564
|
init_SvgBranch();
|
|
44227
44565
|
init_SvgConnection();
|
|
44228
|
-
init_SvgDrawGroup();
|
|
44229
|
-
init_SvgDrawShape();
|
|
44230
|
-
init_SvgDrawShapeLayer();
|
|
44231
|
-
init_SvgDrawText();
|
|
44232
44566
|
init_SvgFlow();
|
|
44233
44567
|
init_SvgGrid();
|
|
44234
44568
|
init_SvgLobe();
|
|
@@ -44239,7 +44573,6 @@ var init_component_registry_generated = __esm({
|
|
|
44239
44573
|
init_SvgRing();
|
|
44240
44574
|
init_SvgShield();
|
|
44241
44575
|
init_SvgStack();
|
|
44242
|
-
init_SvgStage();
|
|
44243
44576
|
init_SwipeableRow();
|
|
44244
44577
|
init_Switch();
|
|
44245
44578
|
init_TabbedContainer();
|
|
@@ -44353,6 +44686,7 @@ var init_component_registry_generated = __esm({
|
|
|
44353
44686
|
"DocSidebar": DocSidebar,
|
|
44354
44687
|
"DocTOC": DocTOC,
|
|
44355
44688
|
"DocumentViewer": DocumentViewer,
|
|
44689
|
+
"DrawGroup": DrawGroup,
|
|
44356
44690
|
"DrawShape": DrawShape,
|
|
44357
44691
|
"DrawShapeLayer": DrawShapeLayer,
|
|
44358
44692
|
"DrawSprite": DrawSprite,
|
|
@@ -44362,6 +44696,7 @@ var init_component_registry_generated = __esm({
|
|
|
44362
44696
|
"Drawer": Drawer,
|
|
44363
44697
|
"DrawerSlot": DrawerSlot,
|
|
44364
44698
|
"EdgeDecoration": EdgeDecoration,
|
|
44699
|
+
"EmojiPicker": EmojiPicker,
|
|
44365
44700
|
"EmptyState": EmptyState,
|
|
44366
44701
|
"ErrorBoundary": ErrorBoundary,
|
|
44367
44702
|
"ErrorState": ErrorState,
|
|
@@ -44501,10 +44836,6 @@ var init_component_registry_generated = __esm({
|
|
|
44501
44836
|
"SubagentTracePanel": SubagentTracePanel,
|
|
44502
44837
|
"SvgBranch": SvgBranch,
|
|
44503
44838
|
"SvgConnection": SvgConnection,
|
|
44504
|
-
"SvgDrawGroup": SvgDrawGroup,
|
|
44505
|
-
"SvgDrawShape": SvgDrawShape,
|
|
44506
|
-
"SvgDrawShapeLayer": SvgDrawShapeLayer,
|
|
44507
|
-
"SvgDrawText": SvgDrawText,
|
|
44508
44839
|
"SvgFlow": SvgFlow,
|
|
44509
44840
|
"SvgGrid": SvgGrid,
|
|
44510
44841
|
"SvgLobe": SvgLobe,
|
|
@@ -44515,7 +44846,6 @@ var init_component_registry_generated = __esm({
|
|
|
44515
44846
|
"SvgRing": SvgRing,
|
|
44516
44847
|
"SvgShield": SvgShield,
|
|
44517
44848
|
"SvgStack": SvgStack,
|
|
44518
|
-
"SvgStage": SvgStage,
|
|
44519
44849
|
"SwipeableRow": SwipeableRow,
|
|
44520
44850
|
"Switch": Switch,
|
|
44521
44851
|
"TabbedContainer": TabbedContainer,
|
|
@@ -44794,7 +45124,19 @@ function UISlotComponent({
|
|
|
44794
45124
|
const suspenseConfig = React85.useContext(SuspenseConfigContext);
|
|
44795
45125
|
const contained = React85.useContext(SlotContainedContext);
|
|
44796
45126
|
const schemaCtx = providers.useEntitySchemaOptional();
|
|
44797
|
-
const
|
|
45127
|
+
const rawContent = slots[slot];
|
|
45128
|
+
const binding = providers.useEntityBindingSnapshot(rawContent?.sourceTrait);
|
|
45129
|
+
const content = React85.useMemo(() => {
|
|
45130
|
+
if (!rawContent) return rawContent;
|
|
45131
|
+
const resolvedProps = resolveRenderBindingMarkers(
|
|
45132
|
+
rawContent.props,
|
|
45133
|
+
rawContent.sourceTrait,
|
|
45134
|
+
binding.entity,
|
|
45135
|
+
binding.config,
|
|
45136
|
+
binding.state
|
|
45137
|
+
);
|
|
45138
|
+
return resolvedProps === rawContent.props ? rawContent : { ...rawContent, props: resolvedProps };
|
|
45139
|
+
}, [rawContent, binding.entity, binding.config, binding.state]);
|
|
44798
45140
|
if (children !== void 0) {
|
|
44799
45141
|
if (pattern === "clear") {
|
|
44800
45142
|
return null;
|
|
@@ -45138,6 +45480,7 @@ function isPlainConfigObject(value) {
|
|
|
45138
45480
|
return proto === Object.prototype || proto === null;
|
|
45139
45481
|
}
|
|
45140
45482
|
function substituteTraitRefsDeep(value, pathKey) {
|
|
45483
|
+
if (core.isRenderBindingMarker(value)) return value;
|
|
45141
45484
|
if (typeof value === "string") {
|
|
45142
45485
|
const match = TRAIT_BINDING_RE.exec(value);
|
|
45143
45486
|
if (match) {
|
|
@@ -45210,7 +45553,14 @@ function SlotContentRenderer({
|
|
|
45210
45553
|
onDismiss,
|
|
45211
45554
|
patternPath
|
|
45212
45555
|
}) {
|
|
45213
|
-
const
|
|
45556
|
+
const ambientScope = providers.useTraitScope();
|
|
45557
|
+
const bindingTrait = content.sourceTrait ?? ambientScope?.trait;
|
|
45558
|
+
const binding = providers.useEntityBindingSnapshot(bindingTrait);
|
|
45559
|
+
const liveProps = React85.useMemo(
|
|
45560
|
+
() => resolveRenderBindingMarkers(content.props, bindingTrait, binding.entity, binding.config, binding.state),
|
|
45561
|
+
[content.props, bindingTrait, binding.entity, binding.config, binding.state]
|
|
45562
|
+
);
|
|
45563
|
+
const entityProp = liveProps.entity;
|
|
45214
45564
|
if (content.pattern === "form-section") {
|
|
45215
45565
|
slotLog.debug("SlotContentRenderer:form-section-render", {
|
|
45216
45566
|
contentId: content.id,
|
|
@@ -45241,7 +45591,7 @@ function SlotContentRenderer({
|
|
|
45241
45591
|
const orbitalName = schemaCtx && content.sourceTrait !== void 0 ? schemaCtx.orbitalsByTrait.get(content.sourceTrait) : void 0;
|
|
45242
45592
|
const PatternComponent = getComponentForPattern(content.pattern);
|
|
45243
45593
|
if (PatternComponent) {
|
|
45244
|
-
const childrenConfig =
|
|
45594
|
+
const childrenConfig = liveProps.children;
|
|
45245
45595
|
const isSingleChild = typeof childrenConfig === "string" || typeof childrenConfig === "object" && childrenConfig !== null && !Array.isArray(childrenConfig) && "type" in childrenConfig;
|
|
45246
45596
|
const hasChildren = PATTERNS_WITH_CHILDREN.has(content.pattern) || Array.isArray(childrenConfig) && childrenConfig.length > 0 || isSingleChild;
|
|
45247
45597
|
const isDrawHost = patterns.isDrawHostPattern(content.pattern);
|
|
@@ -45252,9 +45602,9 @@ function SlotContentRenderer({
|
|
|
45252
45602
|
fromState: content.fromState,
|
|
45253
45603
|
entity: content.entity
|
|
45254
45604
|
}) : void 0;
|
|
45255
|
-
const incomingChildren =
|
|
45605
|
+
const incomingChildren = liveProps.children;
|
|
45256
45606
|
const childrenIsRenderFn = typeof incomingChildren === "function";
|
|
45257
|
-
const { children: _childrenConfig, ...restPropsNoChildren } =
|
|
45607
|
+
const { children: _childrenConfig, ...restPropsNoChildren } = liveProps;
|
|
45258
45608
|
const restProps = childrenIsRenderFn ? { ...restPropsNoChildren, children: incomingChildren } : restPropsNoChildren;
|
|
45259
45609
|
const nodeSlotOverrides = {};
|
|
45260
45610
|
for (const slotKey of CONTENT_NODE_SLOTS) {
|
|
@@ -45363,7 +45713,7 @@ function SlotContentRenderer({
|
|
|
45363
45713
|
"data-orb-path": patternPath ?? "root",
|
|
45364
45714
|
"data-orb-pattern": content.pattern,
|
|
45365
45715
|
"data-orb-orbital": orbitalName,
|
|
45366
|
-
children:
|
|
45716
|
+
children: liveProps.children ?? /* @__PURE__ */ jsxRuntime.jsxs(Box, { className: "p-4 text-sm text-muted-foreground border border-dashed border-border rounded", children: [
|
|
45367
45717
|
"Unknown pattern: ",
|
|
45368
45718
|
content.pattern,
|
|
45369
45719
|
content.sourceTrait && /* @__PURE__ */ jsxRuntime.jsxs(Typography, { variant: "small", className: "ml-2", children: [
|
|
@@ -45435,6 +45785,7 @@ var scopeWrapLog, TRAIT_BINDING_RE, SuspenseConfigContext, SlotContainedContext,
|
|
|
45435
45785
|
var init_UISlotRenderer = __esm({
|
|
45436
45786
|
"components/core/organisms/UISlotRenderer.tsx"() {
|
|
45437
45787
|
"use client";
|
|
45788
|
+
init_resolve_render_bindings();
|
|
45438
45789
|
init_Modal();
|
|
45439
45790
|
init_Drawer();
|
|
45440
45791
|
init_Toast();
|
|
@@ -45829,9 +46180,10 @@ function VerificationProvider({
|
|
|
45829
46180
|
}));
|
|
45830
46181
|
const effectResults = Array.isArray(payload["effectResults"]) ? payload["effectResults"] : [];
|
|
45831
46182
|
for (const er of effectResults) {
|
|
46183
|
+
const target = er["entity"] ?? er["service"];
|
|
45832
46184
|
effects.push({
|
|
45833
46185
|
type: String(er["type"] ?? er["effect"] ?? "server-effect"),
|
|
45834
|
-
args:
|
|
46186
|
+
args: typeof target === "string" && target !== "" ? [target] : [],
|
|
45835
46187
|
status: er["error"] ? "failed" : "executed",
|
|
45836
46188
|
error: er["error"]
|
|
45837
46189
|
});
|
|
@@ -46620,7 +46972,7 @@ function reEmitServerEvent(eventBus, emitted, origin) {
|
|
|
46620
46972
|
sourceTrait: evTrait,
|
|
46621
46973
|
origin
|
|
46622
46974
|
});
|
|
46623
|
-
eventBus.emit(key, emitted.payload);
|
|
46975
|
+
eventBus.emit(key, emitted.payload, emitted.source);
|
|
46624
46976
|
}
|
|
46625
46977
|
function isBusPushEnvelope(value) {
|
|
46626
46978
|
return value.type === "bus" && typeof value.event === "string";
|
|
@@ -46788,7 +47140,12 @@ function ServerBridgeProvider({
|
|
|
46788
47140
|
}
|
|
46789
47141
|
if (result.emittedEvents) {
|
|
46790
47142
|
for (const emitted of result.emittedEvents) {
|
|
46791
|
-
|
|
47143
|
+
if (emitted.event === event) continue;
|
|
47144
|
+
reEmitServerEvent(
|
|
47145
|
+
eventBus,
|
|
47146
|
+
{ ...emitted, source: { ...emitted.source, dispatched: true } },
|
|
47147
|
+
orbitalName
|
|
47148
|
+
);
|
|
46792
47149
|
}
|
|
46793
47150
|
}
|
|
46794
47151
|
} else if (result.error) {
|
|
@@ -46926,10 +47283,29 @@ function useTraitScopeChain2() {
|
|
|
46926
47283
|
const chain = React85.useContext(TraitScopeContext);
|
|
46927
47284
|
return chain ?? EMPTY_CHAIN;
|
|
46928
47285
|
}
|
|
46929
|
-
function
|
|
47286
|
+
function useTraitScope2() {
|
|
46930
47287
|
const chain = React85.useContext(TraitScopeContext);
|
|
46931
47288
|
return chain && chain.length > 0 ? chain[0] : null;
|
|
46932
47289
|
}
|
|
47290
|
+
var EntityBindingContext = React85.createContext(null);
|
|
47291
|
+
var EMPTY_ENTITY = {};
|
|
47292
|
+
var NOOP_SUBSCRIBE = () => () => void 0;
|
|
47293
|
+
function useEntityBindingSnapshot2(traitName) {
|
|
47294
|
+
const source = React85.useContext(EntityBindingContext);
|
|
47295
|
+
const entity = React85.useSyncExternalStore(
|
|
47296
|
+
source !== null && traitName !== void 0 ? (onStoreChange) => source.subscribe(traitName, onStoreChange) : NOOP_SUBSCRIBE,
|
|
47297
|
+
() => source !== null && traitName !== void 0 ? source.getEntitySnapshot(traitName) : EMPTY_ENTITY
|
|
47298
|
+
);
|
|
47299
|
+
const config = React85.useMemo(
|
|
47300
|
+
() => source !== null && traitName !== void 0 ? source.getConfig(traitName) : void 0,
|
|
47301
|
+
[source, traitName]
|
|
47302
|
+
);
|
|
47303
|
+
return {
|
|
47304
|
+
entity,
|
|
47305
|
+
config,
|
|
47306
|
+
state: source !== null && traitName !== void 0 ? source.getState(traitName) : ""
|
|
47307
|
+
};
|
|
47308
|
+
}
|
|
46933
47309
|
|
|
46934
47310
|
// providers/OfflineModeProvider.tsx
|
|
46935
47311
|
init_offline_executor();
|
|
@@ -47022,6 +47398,10 @@ function GameAudioProvider2({
|
|
|
47022
47398
|
}
|
|
47023
47399
|
GameAudioProvider2.displayName = "GameAudioProvider";
|
|
47024
47400
|
|
|
47401
|
+
Object.defineProperty(exports, "ANONYMOUS_USER", {
|
|
47402
|
+
enumerable: true,
|
|
47403
|
+
get: function () { return core.ANONYMOUS_USER; }
|
|
47404
|
+
});
|
|
47025
47405
|
Object.defineProperty(exports, "DesignThemeProvider", {
|
|
47026
47406
|
enumerable: true,
|
|
47027
47407
|
get: function () { return context.DesignThemeProvider; }
|
|
@@ -47030,12 +47410,9 @@ Object.defineProperty(exports, "useDesignTheme", {
|
|
|
47030
47410
|
enumerable: true,
|
|
47031
47411
|
get: function () { return context.useDesignTheme; }
|
|
47032
47412
|
});
|
|
47033
|
-
Object.defineProperty(exports, "ANONYMOUS_USER", {
|
|
47034
|
-
enumerable: true,
|
|
47035
|
-
get: function () { return core.ANONYMOUS_USER; }
|
|
47036
|
-
});
|
|
47037
47413
|
exports.CurrentPagePathContext = CurrentPagePathContext;
|
|
47038
47414
|
exports.CurrentPagePathProvider = CurrentPagePathProvider;
|
|
47415
|
+
exports.EntityBindingContext = EntityBindingContext;
|
|
47039
47416
|
exports.EntitySchemaProvider = EntitySchemaProvider;
|
|
47040
47417
|
exports.EventBusContext = EventBusContext2;
|
|
47041
47418
|
exports.EventBusProvider = EventBusProvider;
|
|
@@ -47065,6 +47442,7 @@ exports.matchPathAmong = matchPathAmong2;
|
|
|
47065
47442
|
exports.pathMatches = pathMatches2;
|
|
47066
47443
|
exports.useActivePage = useActivePage2;
|
|
47067
47444
|
exports.useCurrentPagePath = useCurrentPagePath2;
|
|
47445
|
+
exports.useEntityBindingSnapshot = useEntityBindingSnapshot2;
|
|
47068
47446
|
exports.useEntitySchema = useEntitySchema;
|
|
47069
47447
|
exports.useEntitySchemaOptional = useEntitySchemaOptional6;
|
|
47070
47448
|
exports.useGameAudioContext = useGameAudioContext2;
|
|
@@ -47083,7 +47461,7 @@ exports.useSelectionOptional = useSelectionOptional;
|
|
|
47083
47461
|
exports.useServerBridge = useServerBridge;
|
|
47084
47462
|
exports.useTrait = useTrait;
|
|
47085
47463
|
exports.useTraitContext = useTraitContext;
|
|
47086
|
-
exports.useTraitScope =
|
|
47464
|
+
exports.useTraitScope = useTraitScope2;
|
|
47087
47465
|
exports.useTraitScopeChain = useTraitScopeChain2;
|
|
47088
47466
|
exports.useUser = useUser;
|
|
47089
47467
|
exports.useUserForEvaluation = useUserForEvaluation;
|