@almadar/ui 5.146.2 → 5.147.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/avl/index.cjs +285 -35
- package/dist/avl/index.d.cts +18 -0
- package/dist/avl/index.d.ts +18 -0
- package/dist/avl/index.js +285 -35
- package/dist/{cn-BdGFhYe3.d.cts → cn-BAn68sNO.d.cts} +92 -2
- package/dist/{cn-DNkqAWZK.d.ts → cn-CWxxLkri.d.ts} +92 -2
- package/dist/components/index.cjs +267 -34
- package/dist/components/index.d.cts +93 -175
- package/dist/components/index.d.ts +93 -175
- package/dist/components/index.js +267 -34
- package/dist/lib/index.cjs +104 -0
- package/dist/lib/index.d.cts +2 -1
- package/dist/lib/index.d.ts +2 -1
- package/dist/lib/index.js +104 -1
- package/dist/providers/index.cjs +266 -33
- package/dist/providers/index.js +266 -33
- package/dist/runtime/index.cjs +266 -33
- package/dist/runtime/index.js +266 -33
- package/package.json +6 -6
- package/themes/bloomberg-dense.css +266 -229
- package/themes/retro.css +30 -30
package/dist/avl/index.js
CHANGED
|
@@ -29887,7 +29887,12 @@ function daysAgo(n) {
|
|
|
29887
29887
|
d.setDate(d.getDate() - n);
|
|
29888
29888
|
return d;
|
|
29889
29889
|
}
|
|
29890
|
-
|
|
29890
|
+
function resolvePresetRange(preset) {
|
|
29891
|
+
if (typeof preset.range === "function") return preset.range();
|
|
29892
|
+
if (preset.range) return preset.range;
|
|
29893
|
+
return TOKEN_RANGES[preset.value]?.() ?? null;
|
|
29894
|
+
}
|
|
29895
|
+
var TOKEN_RANGES, DEFAULT_PRESETS, DateRangePicker;
|
|
29891
29896
|
var init_DateRangePicker = __esm({
|
|
29892
29897
|
"components/core/molecules/DateRangePicker.tsx"() {
|
|
29893
29898
|
"use client";
|
|
@@ -29897,32 +29902,19 @@ var init_DateRangePicker = __esm({
|
|
|
29897
29902
|
init_Stack();
|
|
29898
29903
|
init_Typography();
|
|
29899
29904
|
init_useEventBus();
|
|
29905
|
+
TOKEN_RANGES = {
|
|
29906
|
+
"7d": () => ({ from: toISODate(daysAgo(7)), to: toISODate(/* @__PURE__ */ new Date()) }),
|
|
29907
|
+
"30d": () => ({ from: toISODate(daysAgo(30)), to: toISODate(/* @__PURE__ */ new Date()) }),
|
|
29908
|
+
month: () => ({ from: toISODate(startOfMonth(/* @__PURE__ */ new Date())), to: toISODate(/* @__PURE__ */ new Date()) }),
|
|
29909
|
+
quarter: () => ({ from: toISODate(startOfQuarter(/* @__PURE__ */ new Date())), to: toISODate(/* @__PURE__ */ new Date()) }),
|
|
29910
|
+
ytd: () => ({ from: toISODate(startOfYear(/* @__PURE__ */ new Date())), to: toISODate(/* @__PURE__ */ new Date()) })
|
|
29911
|
+
};
|
|
29900
29912
|
DEFAULT_PRESETS = [
|
|
29901
|
-
{
|
|
29902
|
-
|
|
29903
|
-
|
|
29904
|
-
|
|
29905
|
-
}
|
|
29906
|
-
{
|
|
29907
|
-
label: "Last 30 days",
|
|
29908
|
-
value: "30d",
|
|
29909
|
-
range: () => ({ from: toISODate(daysAgo(30)), to: toISODate(/* @__PURE__ */ new Date()) })
|
|
29910
|
-
},
|
|
29911
|
-
{
|
|
29912
|
-
label: "This Month",
|
|
29913
|
-
value: "month",
|
|
29914
|
-
range: () => ({ from: toISODate(startOfMonth(/* @__PURE__ */ new Date())), to: toISODate(/* @__PURE__ */ new Date()) })
|
|
29915
|
-
},
|
|
29916
|
-
{
|
|
29917
|
-
label: "This Quarter",
|
|
29918
|
-
value: "quarter",
|
|
29919
|
-
range: () => ({ from: toISODate(startOfQuarter(/* @__PURE__ */ new Date())), to: toISODate(/* @__PURE__ */ new Date()) })
|
|
29920
|
-
},
|
|
29921
|
-
{
|
|
29922
|
-
label: "YTD",
|
|
29923
|
-
value: "ytd",
|
|
29924
|
-
range: () => ({ from: toISODate(startOfYear(/* @__PURE__ */ new Date())), to: toISODate(/* @__PURE__ */ new Date()) })
|
|
29925
|
-
}
|
|
29913
|
+
{ label: "Last 7 days", value: "7d" },
|
|
29914
|
+
{ label: "Last 30 days", value: "30d" },
|
|
29915
|
+
{ label: "This Month", value: "month" },
|
|
29916
|
+
{ label: "This Quarter", value: "quarter" },
|
|
29917
|
+
{ label: "YTD", value: "ytd" }
|
|
29926
29918
|
];
|
|
29927
29919
|
DateRangePicker = ({
|
|
29928
29920
|
from: fromProp,
|
|
@@ -29963,7 +29955,8 @@ var init_DateRangePicker = __esm({
|
|
|
29963
29955
|
);
|
|
29964
29956
|
const handlePreset = useCallback(
|
|
29965
29957
|
(preset) => {
|
|
29966
|
-
const range = preset
|
|
29958
|
+
const range = resolvePresetRange(preset);
|
|
29959
|
+
if (range === null) return;
|
|
29967
29960
|
setFrom(range.from);
|
|
29968
29961
|
setTo(range.to);
|
|
29969
29962
|
setActivePreset(preset.value);
|
|
@@ -29971,8 +29964,12 @@ var init_DateRangePicker = __esm({
|
|
|
29971
29964
|
},
|
|
29972
29965
|
[emit]
|
|
29973
29966
|
);
|
|
29967
|
+
const renderablePresets = useMemo(
|
|
29968
|
+
() => presets.filter((p) => p.range !== void 0 || TOKEN_RANGES[p.value] !== void 0),
|
|
29969
|
+
[presets]
|
|
29970
|
+
);
|
|
29974
29971
|
const presetButtons = useMemo(
|
|
29975
|
-
() =>
|
|
29972
|
+
() => renderablePresets.map((preset) => /* @__PURE__ */ jsx(
|
|
29976
29973
|
Button,
|
|
29977
29974
|
{
|
|
29978
29975
|
variant: activePreset === preset.value ? "primary" : "ghost",
|
|
@@ -29982,7 +29979,7 @@ var init_DateRangePicker = __esm({
|
|
|
29982
29979
|
},
|
|
29983
29980
|
preset.value
|
|
29984
29981
|
)),
|
|
29985
|
-
[
|
|
29982
|
+
[renderablePresets, activePreset, handlePreset]
|
|
29986
29983
|
);
|
|
29987
29984
|
return /* @__PURE__ */ jsxs(VStack, { gap: "sm", className: cn(className), children: [
|
|
29988
29985
|
/* @__PURE__ */ jsxs(HStack, { gap: "md", align: "end", children: [
|
|
@@ -30009,7 +30006,7 @@ var init_DateRangePicker = __esm({
|
|
|
30009
30006
|
)
|
|
30010
30007
|
] })
|
|
30011
30008
|
] }),
|
|
30012
|
-
|
|
30009
|
+
renderablePresets.length > 0 && /* @__PURE__ */ jsx(HStack, { gap: "xs", wrap: true, children: presetButtons })
|
|
30013
30010
|
] });
|
|
30014
30011
|
};
|
|
30015
30012
|
DateRangePicker.displayName = "DateRangePicker";
|
|
@@ -30451,6 +30448,208 @@ var init_PhysicsCanvas = __esm({
|
|
|
30451
30448
|
};
|
|
30452
30449
|
}
|
|
30453
30450
|
});
|
|
30451
|
+
|
|
30452
|
+
// lib/graphViewLayouts.ts
|
|
30453
|
+
function buildAdjacency(nodeIds, edges) {
|
|
30454
|
+
const known = new Set(nodeIds);
|
|
30455
|
+
const out = /* @__PURE__ */ new Map();
|
|
30456
|
+
const inMap = /* @__PURE__ */ new Map();
|
|
30457
|
+
for (const id of nodeIds) {
|
|
30458
|
+
out.set(id, []);
|
|
30459
|
+
inMap.set(id, []);
|
|
30460
|
+
}
|
|
30461
|
+
for (const edge of edges) {
|
|
30462
|
+
if (!known.has(edge.source) || !known.has(edge.target)) continue;
|
|
30463
|
+
out.get(edge.source)?.push(edge.target);
|
|
30464
|
+
inMap.get(edge.target)?.push(edge.source);
|
|
30465
|
+
}
|
|
30466
|
+
return { out, in: inMap };
|
|
30467
|
+
}
|
|
30468
|
+
function findRoots(nodeIds, adjacency) {
|
|
30469
|
+
return nodeIds.filter((id) => (adjacency.in.get(id)?.length ?? 0) === 0);
|
|
30470
|
+
}
|
|
30471
|
+
function assignLayers(nodeIds, adjacency, roots) {
|
|
30472
|
+
const layer = new Map(nodeIds.map((id) => [id, 0]));
|
|
30473
|
+
const onStack = /* @__PURE__ */ new Set();
|
|
30474
|
+
const visit = (id) => {
|
|
30475
|
+
onStack.add(id);
|
|
30476
|
+
const currentLayer = layer.get(id) ?? 0;
|
|
30477
|
+
for (const next of adjacency.out.get(id) ?? []) {
|
|
30478
|
+
if (onStack.has(next)) continue;
|
|
30479
|
+
const candidate = currentLayer + 1;
|
|
30480
|
+
if (candidate > (layer.get(next) ?? 0)) {
|
|
30481
|
+
layer.set(next, candidate);
|
|
30482
|
+
}
|
|
30483
|
+
visit(next);
|
|
30484
|
+
}
|
|
30485
|
+
onStack.delete(id);
|
|
30486
|
+
};
|
|
30487
|
+
for (const root of roots) visit(root);
|
|
30488
|
+
return layer;
|
|
30489
|
+
}
|
|
30490
|
+
function computeVisitOrder(nodeIds, adjacency, roots) {
|
|
30491
|
+
const order = /* @__PURE__ */ new Map();
|
|
30492
|
+
const visited = /* @__PURE__ */ new Set();
|
|
30493
|
+
let counter = 0;
|
|
30494
|
+
const visit = (id) => {
|
|
30495
|
+
if (visited.has(id)) return;
|
|
30496
|
+
visited.add(id);
|
|
30497
|
+
order.set(id, counter++);
|
|
30498
|
+
for (const next of adjacency.out.get(id) ?? []) visit(next);
|
|
30499
|
+
};
|
|
30500
|
+
for (const root of roots) visit(root);
|
|
30501
|
+
for (const id of nodeIds) {
|
|
30502
|
+
if (!visited.has(id)) order.set(id, counter++);
|
|
30503
|
+
}
|
|
30504
|
+
return order;
|
|
30505
|
+
}
|
|
30506
|
+
function bfsDepthAndOrder(nodeIds, adjacency, roots) {
|
|
30507
|
+
const depth = new Map(nodeIds.map((id) => [id, 0]));
|
|
30508
|
+
const visitOrder = /* @__PURE__ */ new Map();
|
|
30509
|
+
const visited = /* @__PURE__ */ new Set();
|
|
30510
|
+
const queue = [];
|
|
30511
|
+
let counter = 0;
|
|
30512
|
+
for (const root of roots) {
|
|
30513
|
+
if (visited.has(root)) continue;
|
|
30514
|
+
visited.add(root);
|
|
30515
|
+
depth.set(root, 0);
|
|
30516
|
+
visitOrder.set(root, counter++);
|
|
30517
|
+
queue.push(root);
|
|
30518
|
+
}
|
|
30519
|
+
let head = 0;
|
|
30520
|
+
while (head < queue.length) {
|
|
30521
|
+
const id = queue[head++];
|
|
30522
|
+
const d = depth.get(id) ?? 0;
|
|
30523
|
+
for (const next of adjacency.out.get(id) ?? []) {
|
|
30524
|
+
if (visited.has(next)) continue;
|
|
30525
|
+
visited.add(next);
|
|
30526
|
+
depth.set(next, d + 1);
|
|
30527
|
+
visitOrder.set(next, counter++);
|
|
30528
|
+
queue.push(next);
|
|
30529
|
+
}
|
|
30530
|
+
}
|
|
30531
|
+
for (const id of nodeIds) {
|
|
30532
|
+
if (!visited.has(id)) visitOrder.set(id, counter++);
|
|
30533
|
+
}
|
|
30534
|
+
return { depth, visitOrder };
|
|
30535
|
+
}
|
|
30536
|
+
function edgeWalkOrder(nodeIds, adjacency) {
|
|
30537
|
+
const visited = /* @__PURE__ */ new Set();
|
|
30538
|
+
const result = [];
|
|
30539
|
+
for (const start of nodeIds) {
|
|
30540
|
+
if (visited.has(start)) continue;
|
|
30541
|
+
let current = start;
|
|
30542
|
+
while (current !== void 0 && !visited.has(current)) {
|
|
30543
|
+
visited.add(current);
|
|
30544
|
+
result.push(current);
|
|
30545
|
+
const outs = adjacency.out.get(current) ?? [];
|
|
30546
|
+
current = outs.find((next) => !visited.has(next));
|
|
30547
|
+
}
|
|
30548
|
+
}
|
|
30549
|
+
return result;
|
|
30550
|
+
}
|
|
30551
|
+
function groupByTier(nodeIds, tierOf, maxTier) {
|
|
30552
|
+
const groups = Array.from({ length: maxTier + 1 }, () => []);
|
|
30553
|
+
for (const id of nodeIds) {
|
|
30554
|
+
groups[tierOf.get(id) ?? 0].push(id);
|
|
30555
|
+
}
|
|
30556
|
+
return groups;
|
|
30557
|
+
}
|
|
30558
|
+
function distributeAxis(count, start, end) {
|
|
30559
|
+
if (count <= 0) return [];
|
|
30560
|
+
const slot = (end - start) / count;
|
|
30561
|
+
return Array.from({ length: count }, (_, i) => start + slot * (i + 0.5));
|
|
30562
|
+
}
|
|
30563
|
+
function orderByParentPositionThenInput(group, adjacency, positioned, inputIndex) {
|
|
30564
|
+
const withKey = group.map((id) => {
|
|
30565
|
+
const parentValues = (adjacency.in.get(id) ?? []).map((p) => positioned.get(p)).filter((v) => v !== void 0);
|
|
30566
|
+
const avg = parentValues.length > 0 ? parentValues.reduce((a, b) => a + b, 0) / parentValues.length : Number.POSITIVE_INFINITY;
|
|
30567
|
+
return { id, avg, idx: inputIndex.get(id) ?? 0 };
|
|
30568
|
+
});
|
|
30569
|
+
withKey.sort((a, b) => a.avg !== b.avg ? a.avg - b.avg : a.idx - b.idx);
|
|
30570
|
+
return withKey.map((k) => k.id);
|
|
30571
|
+
}
|
|
30572
|
+
function layoutFlow(nodeIds, adjacency, roots, width, height, margin) {
|
|
30573
|
+
const inputIndex = new Map(nodeIds.map((id, i) => [id, i]));
|
|
30574
|
+
const layers = assignLayers(nodeIds, adjacency, roots);
|
|
30575
|
+
const maxLayer = Math.max(...Array.from(layers.values()));
|
|
30576
|
+
const layerGroups = groupByTier(nodeIds, layers, maxLayer);
|
|
30577
|
+
const positions = /* @__PURE__ */ new Map();
|
|
30578
|
+
const yById = /* @__PURE__ */ new Map();
|
|
30579
|
+
for (let l = 0; l <= maxLayer; l++) {
|
|
30580
|
+
const x = margin + l * (width - 2 * margin) / Math.max(1, maxLayer);
|
|
30581
|
+
const ordered2 = orderByParentPositionThenInput(layerGroups[l], adjacency, yById, inputIndex);
|
|
30582
|
+
const ys = distributeAxis(ordered2.length, margin, height - margin);
|
|
30583
|
+
ordered2.forEach((id, i) => {
|
|
30584
|
+
positions.set(id, { id, x, y: ys[i] });
|
|
30585
|
+
yById.set(id, ys[i]);
|
|
30586
|
+
});
|
|
30587
|
+
}
|
|
30588
|
+
return nodeIds.map((id) => positions.get(id));
|
|
30589
|
+
}
|
|
30590
|
+
function layoutTree2(nodeIds, adjacency, roots, width, height, margin) {
|
|
30591
|
+
const effectiveRoots = roots.length > 0 ? roots : [nodeIds[0]];
|
|
30592
|
+
const layers = assignLayers(nodeIds, adjacency, effectiveRoots);
|
|
30593
|
+
const maxLayer = Math.max(...Array.from(layers.values()));
|
|
30594
|
+
const visitOrder = computeVisitOrder(nodeIds, adjacency, effectiveRoots);
|
|
30595
|
+
const layerGroups = groupByTier(nodeIds, layers, maxLayer);
|
|
30596
|
+
const positions = /* @__PURE__ */ new Map();
|
|
30597
|
+
for (let l = 0; l <= maxLayer; l++) {
|
|
30598
|
+
const ordered2 = [...layerGroups[l]].sort(
|
|
30599
|
+
(a, b) => (visitOrder.get(a) ?? 0) - (visitOrder.get(b) ?? 0)
|
|
30600
|
+
);
|
|
30601
|
+
const y = margin + l * (height - 2 * margin) / Math.max(1, maxLayer);
|
|
30602
|
+
const xs = distributeAxis(ordered2.length, margin, width - margin);
|
|
30603
|
+
ordered2.forEach((id, i) => positions.set(id, { id, x: xs[i], y }));
|
|
30604
|
+
}
|
|
30605
|
+
return nodeIds.map((id) => positions.get(id));
|
|
30606
|
+
}
|
|
30607
|
+
function layoutRadial(nodeIds, adjacency, roots, width, height, margin) {
|
|
30608
|
+
const cx = width / 2;
|
|
30609
|
+
const cy = height / 2;
|
|
30610
|
+
const maxRadius = Math.min(width, height) / 2 - margin;
|
|
30611
|
+
if (roots.length === 0) {
|
|
30612
|
+
const order = edgeWalkOrder(nodeIds, adjacency);
|
|
30613
|
+
const k = order.length;
|
|
30614
|
+
const positions2 = /* @__PURE__ */ new Map();
|
|
30615
|
+
order.forEach((id, i) => {
|
|
30616
|
+
const angle = i / k * 2 * Math.PI;
|
|
30617
|
+
positions2.set(id, { id, x: cx + maxRadius * Math.cos(angle), y: cy + maxRadius * Math.sin(angle) });
|
|
30618
|
+
});
|
|
30619
|
+
return nodeIds.map((id) => positions2.get(id));
|
|
30620
|
+
}
|
|
30621
|
+
const { depth, visitOrder } = bfsDepthAndOrder(nodeIds, adjacency, roots);
|
|
30622
|
+
const maxDepth = Math.max(...Array.from(depth.values()));
|
|
30623
|
+
const ringGroups = groupByTier(nodeIds, depth, maxDepth);
|
|
30624
|
+
const positions = /* @__PURE__ */ new Map();
|
|
30625
|
+
for (let d = 0; d <= maxDepth; d++) {
|
|
30626
|
+
const ordered2 = [...ringGroups[d]].sort(
|
|
30627
|
+
(a, b) => (visitOrder.get(a) ?? 0) - (visitOrder.get(b) ?? 0)
|
|
30628
|
+
);
|
|
30629
|
+
const radius = d * maxRadius / Math.max(1, maxDepth);
|
|
30630
|
+
const k = ordered2.length;
|
|
30631
|
+
ordered2.forEach((id, i) => {
|
|
30632
|
+
const angle = i / k * 2 * Math.PI;
|
|
30633
|
+
positions.set(id, { id, x: cx + radius * Math.cos(angle), y: cy + radius * Math.sin(angle) });
|
|
30634
|
+
});
|
|
30635
|
+
}
|
|
30636
|
+
return nodeIds.map((id) => positions.get(id));
|
|
30637
|
+
}
|
|
30638
|
+
function computeStaticLayout(mode, input) {
|
|
30639
|
+
const { nodeIds, edges, width, height } = input;
|
|
30640
|
+
const margin = input.margin ?? 40;
|
|
30641
|
+
if (nodeIds.length === 0) return [];
|
|
30642
|
+
if (nodeIds.length === 1) return [{ id: nodeIds[0], x: width / 2, y: height / 2 }];
|
|
30643
|
+
const adjacency = buildAdjacency(nodeIds, edges);
|
|
30644
|
+
const roots = findRoots(nodeIds, adjacency);
|
|
30645
|
+
if (mode === "flow") return layoutFlow(nodeIds, adjacency, roots, width, height, margin);
|
|
30646
|
+
if (mode === "tree") return layoutTree2(nodeIds, adjacency, roots, width, height, margin);
|
|
30647
|
+
return layoutRadial(nodeIds, adjacency, roots, width, height, margin);
|
|
30648
|
+
}
|
|
30649
|
+
var init_graphViewLayouts = __esm({
|
|
30650
|
+
"lib/graphViewLayouts.ts"() {
|
|
30651
|
+
}
|
|
30652
|
+
});
|
|
30454
30653
|
function resolveNodeColor(node, groups) {
|
|
30455
30654
|
if (node.color) return node.color;
|
|
30456
30655
|
if (node.group) {
|
|
@@ -30465,6 +30664,7 @@ var init_GraphView = __esm({
|
|
|
30465
30664
|
"use client";
|
|
30466
30665
|
init_cn();
|
|
30467
30666
|
init_atoms();
|
|
30667
|
+
init_graphViewLayouts();
|
|
30468
30668
|
GROUP_COLORS = [
|
|
30469
30669
|
"#3b82f6",
|
|
30470
30670
|
// blue-500
|
|
@@ -30495,11 +30695,13 @@ var init_GraphView = __esm({
|
|
|
30495
30695
|
height: propHeight,
|
|
30496
30696
|
className,
|
|
30497
30697
|
showLabels = true,
|
|
30498
|
-
zoomToFit = true
|
|
30698
|
+
zoomToFit = true,
|
|
30699
|
+
layout = "force"
|
|
30499
30700
|
}) => {
|
|
30500
30701
|
const { t } = useTranslate();
|
|
30501
30702
|
const containerRef = useRef(null);
|
|
30502
30703
|
const animRef = useRef(0);
|
|
30704
|
+
const arrowMarkerId = useId();
|
|
30503
30705
|
const [simNodes, setSimNodes] = useState([]);
|
|
30504
30706
|
const [settled, setSettled] = useState(false);
|
|
30505
30707
|
const [hoveredId, setHoveredId] = useState(null);
|
|
@@ -30556,6 +30758,22 @@ var init_GraphView = __esm({
|
|
|
30556
30758
|
fy: 0
|
|
30557
30759
|
};
|
|
30558
30760
|
});
|
|
30761
|
+
if (layout !== "force") {
|
|
30762
|
+
const points = computeStaticLayout(layout, {
|
|
30763
|
+
nodeIds: nodes.map((n) => n.id),
|
|
30764
|
+
edges,
|
|
30765
|
+
width: w,
|
|
30766
|
+
height: h
|
|
30767
|
+
});
|
|
30768
|
+
const pointById = new Map(points.map((p) => [p.id, p]));
|
|
30769
|
+
const laidOut = initialNodes.map((node) => {
|
|
30770
|
+
const point = pointById.get(node.id);
|
|
30771
|
+
return point ? { ...node, x: point.x, y: point.y } : node;
|
|
30772
|
+
});
|
|
30773
|
+
setSimNodes(laidOut);
|
|
30774
|
+
setSettled(true);
|
|
30775
|
+
return;
|
|
30776
|
+
}
|
|
30559
30777
|
let iterations = 0;
|
|
30560
30778
|
const maxIterations = 120;
|
|
30561
30779
|
let currentNodes = initialNodes;
|
|
@@ -30624,7 +30842,7 @@ var init_GraphView = __esm({
|
|
|
30624
30842
|
return () => {
|
|
30625
30843
|
cancelAnimationFrame(animRef.current);
|
|
30626
30844
|
};
|
|
30627
|
-
}, [nodes, edges, w, h, groups]);
|
|
30845
|
+
}, [nodes, edges, w, h, groups, layout]);
|
|
30628
30846
|
const viewBox = useMemo(() => {
|
|
30629
30847
|
if (!zoomToFit || !settled || simNodes.length === 0) {
|
|
30630
30848
|
return `0 0 ${w} ${h}`;
|
|
@@ -30699,6 +30917,19 @@ var init_GraphView = __esm({
|
|
|
30699
30917
|
viewBox,
|
|
30700
30918
|
preserveAspectRatio: "xMidYMid meet",
|
|
30701
30919
|
children: [
|
|
30920
|
+
layout !== "force" && /* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsx(
|
|
30921
|
+
"marker",
|
|
30922
|
+
{
|
|
30923
|
+
id: arrowMarkerId,
|
|
30924
|
+
viewBox: "0 0 10 10",
|
|
30925
|
+
refX: "9",
|
|
30926
|
+
refY: "5",
|
|
30927
|
+
markerWidth: "6",
|
|
30928
|
+
markerHeight: "6",
|
|
30929
|
+
orient: "auto-start-reverse",
|
|
30930
|
+
children: /* @__PURE__ */ jsx("path", { d: "M0,0 L10,5 L0,10 z", fill: "currentColor" })
|
|
30931
|
+
}
|
|
30932
|
+
) }),
|
|
30702
30933
|
edges.map((edge, idx) => {
|
|
30703
30934
|
const source = nodeMap.get(edge.source);
|
|
30704
30935
|
const target = nodeMap.get(edge.target);
|
|
@@ -30713,8 +30944,10 @@ var init_GraphView = __esm({
|
|
|
30713
30944
|
x2: target.x,
|
|
30714
30945
|
y2: target.y,
|
|
30715
30946
|
stroke: edge.color ?? DEFAULT_EDGE_COLOR,
|
|
30947
|
+
color: edge.color ?? DEFAULT_EDGE_COLOR,
|
|
30716
30948
|
strokeWidth: 1.5,
|
|
30717
|
-
opacity: isHighlighted ? 0.8 : 0.15
|
|
30949
|
+
opacity: isHighlighted ? 0.8 : 0.15,
|
|
30950
|
+
markerEnd: layout !== "force" ? `url(#${arrowMarkerId})` : void 0
|
|
30718
30951
|
}
|
|
30719
30952
|
),
|
|
30720
30953
|
showLabels && edge.label && /* @__PURE__ */ jsx(
|
|
@@ -55787,7 +56020,9 @@ function FlowCanvasInner({
|
|
|
55787
56020
|
behaviorEntries,
|
|
55788
56021
|
behaviorWires,
|
|
55789
56022
|
userType = "builder",
|
|
55790
|
-
themeManifest
|
|
56023
|
+
themeManifest,
|
|
56024
|
+
nodePositions,
|
|
56025
|
+
onPositionsChange
|
|
55791
56026
|
}) {
|
|
55792
56027
|
const { t } = useTranslate();
|
|
55793
56028
|
const NODE_TYPES2 = useMemo(() => ({
|
|
@@ -55874,9 +56109,15 @@ function FlowCanvasInner({
|
|
|
55874
56109
|
const [nodes, setNodes, onNodesChange] = useNodesState(activeNodes);
|
|
55875
56110
|
const [edges, setEdges, onEdgesChange] = useEdgesState(activeEdges);
|
|
55876
56111
|
const reactFlow = useReactFlow();
|
|
56112
|
+
const savedPositionsRef = React94__default.useRef(nodePositions);
|
|
56113
|
+
savedPositionsRef.current = nodePositions;
|
|
56114
|
+
const nodesRef = React94__default.useRef(nodes);
|
|
56115
|
+
nodesRef.current = nodes;
|
|
55877
56116
|
useEffect(() => {
|
|
55878
56117
|
setEdges([]);
|
|
55879
|
-
|
|
56118
|
+
const saved = savedPositionsRef.current;
|
|
56119
|
+
const merged = saved ? activeNodes.map((n) => saved[n.id] ? { ...n, position: saved[n.id] } : n) : activeNodes;
|
|
56120
|
+
setNodes(merged);
|
|
55880
56121
|
setEdges(activeEdges);
|
|
55881
56122
|
requestAnimationFrame(() => {
|
|
55882
56123
|
reactFlow.fitView({ duration: 300, padding: 0.25 });
|
|
@@ -56026,6 +56267,14 @@ function FlowCanvasInner({
|
|
|
56026
56267
|
targetTraitName: tgtData.traitName
|
|
56027
56268
|
});
|
|
56028
56269
|
}, [nodes, onEventWire, eventBus]);
|
|
56270
|
+
const handleNodeDragStop = useCallback(() => {
|
|
56271
|
+
if (!onPositionsChange) return;
|
|
56272
|
+
const positions = {};
|
|
56273
|
+
for (const n of nodesRef.current) {
|
|
56274
|
+
positions[n.id] = { x: n.position.x, y: n.position.y };
|
|
56275
|
+
}
|
|
56276
|
+
onPositionsChange(positions);
|
|
56277
|
+
}, [onPositionsChange]);
|
|
56029
56278
|
const screenSizeKeys = ["mobile", "tablet", "laptop", "wide"];
|
|
56030
56279
|
const traitCardSelectionValue = useMemo(() => ({
|
|
56031
56280
|
selectTransition: (sel) => {
|
|
@@ -56057,6 +56306,7 @@ function FlowCanvasInner({
|
|
|
56057
56306
|
onNodeDoubleClick: handleNodeDoubleClick,
|
|
56058
56307
|
onNodeClick: handleNodeClick,
|
|
56059
56308
|
onConnect: handleConnect,
|
|
56309
|
+
onNodeDragStop: handleNodeDragStop,
|
|
56060
56310
|
minZoom: 0.1,
|
|
56061
56311
|
maxZoom: 2,
|
|
56062
56312
|
fitView: true,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { OrbitalSchema, SExpr, Effect, OrbitalVerificationAPI, TraitStateSnapshot, EventPayload, BusEvent, VerificationCheck, BridgeHealth, VerificationSnapshot, VerificationSummary, TransitionTrace, ServerResponseTrace, CheckStatus, AssetLoadStatus } from '@almadar/core';
|
|
2
|
+
import React__default from 'react';
|
|
2
3
|
import { D as DrawableNode } from './paintDispatch-Cb_hQj4Y.cjs';
|
|
3
4
|
import { ClassValue } from 'clsx';
|
|
4
5
|
|
|
@@ -34,7 +35,7 @@ type ContentSegment = {
|
|
|
34
35
|
* Splits markdown into segments of plain markdown and fenced code blocks.
|
|
35
36
|
* JSON/orb code blocks containing orbital schemas are tagged as 'orbital'.
|
|
36
37
|
*/
|
|
37
|
-
declare function parseMarkdownWithCodeBlocks(content: string | undefined | null): ContentSegment[];
|
|
38
|
+
declare function parseMarkdownWithCodeBlocks$1(content: string | undefined | null): ContentSegment[];
|
|
38
39
|
/**
|
|
39
40
|
* Parse content to extract all segments including quiz tags and code blocks.
|
|
40
41
|
*
|
|
@@ -45,6 +46,95 @@ declare function parseMarkdownWithCodeBlocks(content: string | undefined | null)
|
|
|
45
46
|
*/
|
|
46
47
|
declare function parseContentSegments(content: string | undefined | null): ContentSegment[];
|
|
47
48
|
|
|
49
|
+
/**
|
|
50
|
+
* BloomQuizBlock Molecule Component
|
|
51
|
+
*
|
|
52
|
+
* Practice Q&A with Bloom's Taxonomy level badge. Emits `UI:ANSWER_BLOOM { index, level }`.
|
|
53
|
+
*
|
|
54
|
+
* Event Contract:
|
|
55
|
+
* - Emits: UI:ANSWER_BLOOM { index, level }
|
|
56
|
+
* - entityAware: false
|
|
57
|
+
*/
|
|
58
|
+
|
|
59
|
+
type BloomLevel = 'remember' | 'understand' | 'apply' | 'analyze' | 'evaluate' | 'create';
|
|
60
|
+
interface BloomQuizBlockProps {
|
|
61
|
+
level: BloomLevel;
|
|
62
|
+
question: string;
|
|
63
|
+
answer: string;
|
|
64
|
+
/** Zero-based index (used in the emitted event payload) */
|
|
65
|
+
index?: number;
|
|
66
|
+
/** Whether the learner has already answered */
|
|
67
|
+
isAnswered?: boolean;
|
|
68
|
+
/** Event name emitted on first reveal (as `UI:<answerEvent>`). Defaults to 'ANSWER_BLOOM'. */
|
|
69
|
+
answerEvent?: string;
|
|
70
|
+
/** Additional CSS classes */
|
|
71
|
+
className?: string;
|
|
72
|
+
}
|
|
73
|
+
declare const BloomQuizBlock: React__default.FC<BloomQuizBlockProps>;
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Utility for lesson-segment parsing: splits a markdown string into alternating
|
|
77
|
+
* markdown and fenced-code-block segments. Exported so SegmentRenderer and
|
|
78
|
+
* BloomQuizBlock can reuse without circular imports.
|
|
79
|
+
*/
|
|
80
|
+
type MarkdownSegment = {
|
|
81
|
+
type: 'markdown';
|
|
82
|
+
content: string;
|
|
83
|
+
};
|
|
84
|
+
type CodeSegment = {
|
|
85
|
+
type: 'code';
|
|
86
|
+
language: string;
|
|
87
|
+
content: string;
|
|
88
|
+
runnable?: boolean;
|
|
89
|
+
};
|
|
90
|
+
type MixedSegment = MarkdownSegment | CodeSegment;
|
|
91
|
+
/** Splits markdown content into markdown and fenced-code-block segments. */
|
|
92
|
+
declare function parseMarkdownWithCodeBlocks(content: string): MixedSegment[];
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* parseLessonSegments — parses lesson markdown with embedded learning-science
|
|
96
|
+
* XML-style tags into a typed Segment array.
|
|
97
|
+
*
|
|
98
|
+
* Supported tags: <activate>, <connect>, <reflect>, <bloom level="...">,
|
|
99
|
+
* <question>/<answer>, <visualize type="..." description="..." />.
|
|
100
|
+
*
|
|
101
|
+
* Tags may be open (unclosed) — the parser falls back to consuming content
|
|
102
|
+
* until the next recognised tag, a section heading (`\n\n#`), or end-of-input.
|
|
103
|
+
*/
|
|
104
|
+
|
|
105
|
+
type InteractiveOrbitalType = 'algorithms' | 'math' | 'physics' | 'biology' | 'chemistry' | 'probability';
|
|
106
|
+
type LessonSegment = MixedSegment | {
|
|
107
|
+
type: 'quiz';
|
|
108
|
+
question: string;
|
|
109
|
+
answer: string;
|
|
110
|
+
} | {
|
|
111
|
+
type: 'activate';
|
|
112
|
+
question: string;
|
|
113
|
+
} | {
|
|
114
|
+
type: 'connect';
|
|
115
|
+
content: string;
|
|
116
|
+
} | {
|
|
117
|
+
type: 'reflect';
|
|
118
|
+
prompt: string;
|
|
119
|
+
} | {
|
|
120
|
+
type: 'bloom';
|
|
121
|
+
level: BloomLevel;
|
|
122
|
+
question: string;
|
|
123
|
+
answer: string;
|
|
124
|
+
} | {
|
|
125
|
+
type: 'visualization';
|
|
126
|
+
visualizationType: InteractiveOrbitalType;
|
|
127
|
+
description: string;
|
|
128
|
+
};
|
|
129
|
+
/** User progress state passed into SegmentRenderer. */
|
|
130
|
+
interface LessonUserProgress {
|
|
131
|
+
activationResponse?: string;
|
|
132
|
+
reflectionNotes?: string[];
|
|
133
|
+
bloomAnswered?: Record<number, boolean>;
|
|
134
|
+
}
|
|
135
|
+
/** Parse a lesson string into typed segments. Returns `[]` when input is empty. */
|
|
136
|
+
declare function parseLessonSegments(lesson: string | undefined): LessonSegment[];
|
|
137
|
+
|
|
48
138
|
/**
|
|
49
139
|
* Orbital State Machine Visualizer
|
|
50
140
|
*
|
|
@@ -292,4 +382,4 @@ declare function clearVerification(): void;
|
|
|
292
382
|
*/
|
|
293
383
|
declare function cn(...inputs: ClassValue[]): string;
|
|
294
384
|
|
|
295
|
-
export { parseMarkdownWithCodeBlocks as A,
|
|
385
|
+
export { parseMarkdownWithCodeBlocks as $, parseLessonSegments as A, parseMarkdownWithCodeBlocks$1 as B, type ContentSegment as C, DEFAULT_CONFIG as D, type EntityDefinition as E, recordServerResponse as F, recordTransition as G, registerCheck as H, registerTraitSnapshot as I, renderStateMachineToDomData as J, renderStateMachineToSvg as K, type LessonSegment as L, subscribeToVerification as M, updateAssetStatus as N, updateBridgeHealth as O, updateCheck as P, waitForTransition as Q, type RenderOptions as R, type StateDefinition as S, type TraitSnapshotGetter as T, type LessonUserProgress as U, type VisualizerConfig as V, type InteractiveOrbitalType as W, type BloomLevel as X, BloomQuizBlock as Y, type BloomQuizBlockProps as Z, type MixedSegment as _, type DomEntityBox as a, type DomLayoutData as b, type DomOutputsBox as c, type DomStateNode as d, type DomTransitionLabel as e, type DomTransitionPath as f, type StateMachineDefinition as g, type TransitionDefinition as h, bindCanvasCapture as i, bindEventBus as j, bindLastDrawables as k, bindTraitStateGetter as l, clearVerification as m, cn as n, extractOutputsFromTransitions as o, extractStateMachine as p, formatGuard as q, getAllChecks as r, getBridgeHealth as s, getEffectSummary as t, getSnapshot as u, getSummary as v, getTraitSnapshots as w, getTransitions as x, getTransitionsForTrait as y, parseContentSegments as z };
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { OrbitalSchema, SExpr, Effect, OrbitalVerificationAPI, TraitStateSnapshot, EventPayload, BusEvent, VerificationCheck, BridgeHealth, VerificationSnapshot, VerificationSummary, TransitionTrace, ServerResponseTrace, CheckStatus, AssetLoadStatus } from '@almadar/core';
|
|
2
|
+
import React__default from 'react';
|
|
2
3
|
import { D as DrawableNode } from './paintDispatch-Cb_hQj4Y.js';
|
|
3
4
|
import { ClassValue } from 'clsx';
|
|
4
5
|
|
|
@@ -34,7 +35,7 @@ type ContentSegment = {
|
|
|
34
35
|
* Splits markdown into segments of plain markdown and fenced code blocks.
|
|
35
36
|
* JSON/orb code blocks containing orbital schemas are tagged as 'orbital'.
|
|
36
37
|
*/
|
|
37
|
-
declare function parseMarkdownWithCodeBlocks(content: string | undefined | null): ContentSegment[];
|
|
38
|
+
declare function parseMarkdownWithCodeBlocks$1(content: string | undefined | null): ContentSegment[];
|
|
38
39
|
/**
|
|
39
40
|
* Parse content to extract all segments including quiz tags and code blocks.
|
|
40
41
|
*
|
|
@@ -45,6 +46,95 @@ declare function parseMarkdownWithCodeBlocks(content: string | undefined | null)
|
|
|
45
46
|
*/
|
|
46
47
|
declare function parseContentSegments(content: string | undefined | null): ContentSegment[];
|
|
47
48
|
|
|
49
|
+
/**
|
|
50
|
+
* BloomQuizBlock Molecule Component
|
|
51
|
+
*
|
|
52
|
+
* Practice Q&A with Bloom's Taxonomy level badge. Emits `UI:ANSWER_BLOOM { index, level }`.
|
|
53
|
+
*
|
|
54
|
+
* Event Contract:
|
|
55
|
+
* - Emits: UI:ANSWER_BLOOM { index, level }
|
|
56
|
+
* - entityAware: false
|
|
57
|
+
*/
|
|
58
|
+
|
|
59
|
+
type BloomLevel = 'remember' | 'understand' | 'apply' | 'analyze' | 'evaluate' | 'create';
|
|
60
|
+
interface BloomQuizBlockProps {
|
|
61
|
+
level: BloomLevel;
|
|
62
|
+
question: string;
|
|
63
|
+
answer: string;
|
|
64
|
+
/** Zero-based index (used in the emitted event payload) */
|
|
65
|
+
index?: number;
|
|
66
|
+
/** Whether the learner has already answered */
|
|
67
|
+
isAnswered?: boolean;
|
|
68
|
+
/** Event name emitted on first reveal (as `UI:<answerEvent>`). Defaults to 'ANSWER_BLOOM'. */
|
|
69
|
+
answerEvent?: string;
|
|
70
|
+
/** Additional CSS classes */
|
|
71
|
+
className?: string;
|
|
72
|
+
}
|
|
73
|
+
declare const BloomQuizBlock: React__default.FC<BloomQuizBlockProps>;
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Utility for lesson-segment parsing: splits a markdown string into alternating
|
|
77
|
+
* markdown and fenced-code-block segments. Exported so SegmentRenderer and
|
|
78
|
+
* BloomQuizBlock can reuse without circular imports.
|
|
79
|
+
*/
|
|
80
|
+
type MarkdownSegment = {
|
|
81
|
+
type: 'markdown';
|
|
82
|
+
content: string;
|
|
83
|
+
};
|
|
84
|
+
type CodeSegment = {
|
|
85
|
+
type: 'code';
|
|
86
|
+
language: string;
|
|
87
|
+
content: string;
|
|
88
|
+
runnable?: boolean;
|
|
89
|
+
};
|
|
90
|
+
type MixedSegment = MarkdownSegment | CodeSegment;
|
|
91
|
+
/** Splits markdown content into markdown and fenced-code-block segments. */
|
|
92
|
+
declare function parseMarkdownWithCodeBlocks(content: string): MixedSegment[];
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* parseLessonSegments — parses lesson markdown with embedded learning-science
|
|
96
|
+
* XML-style tags into a typed Segment array.
|
|
97
|
+
*
|
|
98
|
+
* Supported tags: <activate>, <connect>, <reflect>, <bloom level="...">,
|
|
99
|
+
* <question>/<answer>, <visualize type="..." description="..." />.
|
|
100
|
+
*
|
|
101
|
+
* Tags may be open (unclosed) — the parser falls back to consuming content
|
|
102
|
+
* until the next recognised tag, a section heading (`\n\n#`), or end-of-input.
|
|
103
|
+
*/
|
|
104
|
+
|
|
105
|
+
type InteractiveOrbitalType = 'algorithms' | 'math' | 'physics' | 'biology' | 'chemistry' | 'probability';
|
|
106
|
+
type LessonSegment = MixedSegment | {
|
|
107
|
+
type: 'quiz';
|
|
108
|
+
question: string;
|
|
109
|
+
answer: string;
|
|
110
|
+
} | {
|
|
111
|
+
type: 'activate';
|
|
112
|
+
question: string;
|
|
113
|
+
} | {
|
|
114
|
+
type: 'connect';
|
|
115
|
+
content: string;
|
|
116
|
+
} | {
|
|
117
|
+
type: 'reflect';
|
|
118
|
+
prompt: string;
|
|
119
|
+
} | {
|
|
120
|
+
type: 'bloom';
|
|
121
|
+
level: BloomLevel;
|
|
122
|
+
question: string;
|
|
123
|
+
answer: string;
|
|
124
|
+
} | {
|
|
125
|
+
type: 'visualization';
|
|
126
|
+
visualizationType: InteractiveOrbitalType;
|
|
127
|
+
description: string;
|
|
128
|
+
};
|
|
129
|
+
/** User progress state passed into SegmentRenderer. */
|
|
130
|
+
interface LessonUserProgress {
|
|
131
|
+
activationResponse?: string;
|
|
132
|
+
reflectionNotes?: string[];
|
|
133
|
+
bloomAnswered?: Record<number, boolean>;
|
|
134
|
+
}
|
|
135
|
+
/** Parse a lesson string into typed segments. Returns `[]` when input is empty. */
|
|
136
|
+
declare function parseLessonSegments(lesson: string | undefined): LessonSegment[];
|
|
137
|
+
|
|
48
138
|
/**
|
|
49
139
|
* Orbital State Machine Visualizer
|
|
50
140
|
*
|
|
@@ -292,4 +382,4 @@ declare function clearVerification(): void;
|
|
|
292
382
|
*/
|
|
293
383
|
declare function cn(...inputs: ClassValue[]): string;
|
|
294
384
|
|
|
295
|
-
export { parseMarkdownWithCodeBlocks as A,
|
|
385
|
+
export { parseMarkdownWithCodeBlocks as $, parseLessonSegments as A, parseMarkdownWithCodeBlocks$1 as B, type ContentSegment as C, DEFAULT_CONFIG as D, type EntityDefinition as E, recordServerResponse as F, recordTransition as G, registerCheck as H, registerTraitSnapshot as I, renderStateMachineToDomData as J, renderStateMachineToSvg as K, type LessonSegment as L, subscribeToVerification as M, updateAssetStatus as N, updateBridgeHealth as O, updateCheck as P, waitForTransition as Q, type RenderOptions as R, type StateDefinition as S, type TraitSnapshotGetter as T, type LessonUserProgress as U, type VisualizerConfig as V, type InteractiveOrbitalType as W, type BloomLevel as X, BloomQuizBlock as Y, type BloomQuizBlockProps as Z, type MixedSegment as _, type DomEntityBox as a, type DomLayoutData as b, type DomOutputsBox as c, type DomStateNode as d, type DomTransitionLabel as e, type DomTransitionPath as f, type StateMachineDefinition as g, type TransitionDefinition as h, bindCanvasCapture as i, bindEventBus as j, bindLastDrawables as k, bindTraitStateGetter as l, clearVerification as m, cn as n, extractOutputsFromTransitions as o, extractStateMachine as p, formatGuard as q, getAllChecks as r, getBridgeHealth as s, getEffectSummary as t, getSnapshot as u, getSummary as v, getTraitSnapshots as w, getTransitions as x, getTransitionsForTrait as y, parseContentSegments as z };
|