@almadar/ui 5.146.3 → 5.148.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 +363 -35
- package/dist/avl/index.js +363 -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 +364 -36
- package/dist/components/index.d.cts +99 -175
- package/dist/components/index.d.ts +99 -175
- package/dist/components/index.js +364 -36
- 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 +363 -35
- package/dist/providers/index.js +363 -35
- package/dist/runtime/index.cjs +363 -35
- package/dist/runtime/index.js +363 -35
- package/package.json +6 -6
- package/themes/bloomberg-dense.css +266 -229
- package/themes/retro.css +30 -30
package/dist/avl/index.js
CHANGED
|
@@ -15252,7 +15252,10 @@ var init_LearningCanvas = __esm({
|
|
|
15252
15252
|
ctx.fillRect(0, 0, width, height);
|
|
15253
15253
|
}
|
|
15254
15254
|
for (const shape of shapes) {
|
|
15255
|
-
drawShape(ctx, shape, width, height);
|
|
15255
|
+
if (shape.type !== "text") drawShape(ctx, shape, width, height);
|
|
15256
|
+
}
|
|
15257
|
+
for (const shape of shapes) {
|
|
15258
|
+
if (shape.type === "text") drawShape(ctx, shape, width, height);
|
|
15256
15259
|
}
|
|
15257
15260
|
}, [width, height, backgroundColor, shapes]);
|
|
15258
15261
|
useEffect(() => {
|
|
@@ -16815,7 +16818,7 @@ var init_AlgorithmCanvas = __esm({
|
|
|
16815
16818
|
DEFAULT_CELL_COLOR = "#e5e7eb";
|
|
16816
16819
|
DEFAULT_POINTER_COLOR = "#dc2626";
|
|
16817
16820
|
POINTER_BAND = 34;
|
|
16818
|
-
TOP_PAD =
|
|
16821
|
+
TOP_PAD = 26;
|
|
16819
16822
|
AlgorithmCanvas = ({
|
|
16820
16823
|
className,
|
|
16821
16824
|
width = 600,
|
|
@@ -27594,6 +27597,7 @@ var init_FilterGroup = __esm({
|
|
|
27594
27597
|
init_Badge();
|
|
27595
27598
|
init_Stack();
|
|
27596
27599
|
init_Icon();
|
|
27600
|
+
init_RangeSlider();
|
|
27597
27601
|
init_useEventBus();
|
|
27598
27602
|
init_useQuerySingleton();
|
|
27599
27603
|
resolveFilterType = (filter) => filter.filterType ?? filter.type;
|
|
@@ -27788,6 +27792,35 @@ var init_FilterGroup = __esm({
|
|
|
27788
27792
|
onClear: () => handleFilterSelect(`${filter.field}_to`, null)
|
|
27789
27793
|
}
|
|
27790
27794
|
)
|
|
27795
|
+
] }) : resolveFilterType(filter) === "numberrange" || resolveFilterType(filter) === "number-range" ? /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
|
|
27796
|
+
/* @__PURE__ */ jsx(
|
|
27797
|
+
RangeSlider,
|
|
27798
|
+
{
|
|
27799
|
+
min: filter.min ?? 0,
|
|
27800
|
+
max: filter.max ?? 100,
|
|
27801
|
+
step: filter.step ?? 1,
|
|
27802
|
+
value: Number(
|
|
27803
|
+
selectedValues[`${filter.field}_min`] ?? filter.min ?? 0
|
|
27804
|
+
),
|
|
27805
|
+
onChange: (v) => handleFilterSelect(`${filter.field}_min`, String(v)),
|
|
27806
|
+
showTooltip: true,
|
|
27807
|
+
"aria-label": t("filterGroup.from")
|
|
27808
|
+
}
|
|
27809
|
+
),
|
|
27810
|
+
/* @__PURE__ */ jsx(
|
|
27811
|
+
RangeSlider,
|
|
27812
|
+
{
|
|
27813
|
+
min: filter.min ?? 0,
|
|
27814
|
+
max: filter.max ?? 100,
|
|
27815
|
+
step: filter.step ?? 1,
|
|
27816
|
+
value: Number(
|
|
27817
|
+
selectedValues[`${filter.field}_max`] ?? filter.max ?? 100
|
|
27818
|
+
),
|
|
27819
|
+
onChange: (v) => handleFilterSelect(`${filter.field}_max`, String(v)),
|
|
27820
|
+
showTooltip: true,
|
|
27821
|
+
"aria-label": t("filterGroup.to")
|
|
27822
|
+
}
|
|
27823
|
+
)
|
|
27791
27824
|
] }) : resolveFilterType(filter) === "text" ? /* @__PURE__ */ jsx(
|
|
27792
27825
|
Input,
|
|
27793
27826
|
{
|
|
@@ -27870,6 +27903,36 @@ var init_FilterGroup = __esm({
|
|
|
27870
27903
|
className: "text-sm min-w-[100px]"
|
|
27871
27904
|
}
|
|
27872
27905
|
)
|
|
27906
|
+
] }) : resolveFilterType(filter) === "numberrange" || resolveFilterType(filter) === "number-range" ? /* @__PURE__ */ jsxs(HStack, { gap: "xs", align: "center", children: [
|
|
27907
|
+
/* @__PURE__ */ jsx(
|
|
27908
|
+
RangeSlider,
|
|
27909
|
+
{
|
|
27910
|
+
min: filter.min ?? 0,
|
|
27911
|
+
max: filter.max ?? 100,
|
|
27912
|
+
step: filter.step ?? 1,
|
|
27913
|
+
value: Number(
|
|
27914
|
+
selectedValues[`${filter.field}_min`] ?? filter.min ?? 0
|
|
27915
|
+
),
|
|
27916
|
+
onChange: (v) => handleFilterSelect(`${filter.field}_min`, String(v)),
|
|
27917
|
+
className: "min-w-[100px]",
|
|
27918
|
+
"aria-label": t("filterGroup.from")
|
|
27919
|
+
}
|
|
27920
|
+
),
|
|
27921
|
+
/* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "-" }),
|
|
27922
|
+
/* @__PURE__ */ jsx(
|
|
27923
|
+
RangeSlider,
|
|
27924
|
+
{
|
|
27925
|
+
min: filter.min ?? 0,
|
|
27926
|
+
max: filter.max ?? 100,
|
|
27927
|
+
step: filter.step ?? 1,
|
|
27928
|
+
value: Number(
|
|
27929
|
+
selectedValues[`${filter.field}_max`] ?? filter.max ?? 100
|
|
27930
|
+
),
|
|
27931
|
+
onChange: (v) => handleFilterSelect(`${filter.field}_max`, String(v)),
|
|
27932
|
+
className: "min-w-[100px]",
|
|
27933
|
+
"aria-label": t("filterGroup.to")
|
|
27934
|
+
}
|
|
27935
|
+
)
|
|
27873
27936
|
] }) : resolveFilterType(filter) === "text" ? /* @__PURE__ */ jsx(
|
|
27874
27937
|
Input,
|
|
27875
27938
|
{
|
|
@@ -27988,6 +28051,38 @@ var init_FilterGroup = __esm({
|
|
|
27988
28051
|
className: "min-w-[130px]"
|
|
27989
28052
|
}
|
|
27990
28053
|
)
|
|
28054
|
+
] }) : resolveFilterType(filter) === "numberrange" || resolveFilterType(filter) === "number-range" ? /* @__PURE__ */ jsxs(HStack, { gap: "xs", align: "center", children: [
|
|
28055
|
+
/* @__PURE__ */ jsx(
|
|
28056
|
+
RangeSlider,
|
|
28057
|
+
{
|
|
28058
|
+
min: filter.min ?? 0,
|
|
28059
|
+
max: filter.max ?? 100,
|
|
28060
|
+
step: filter.step ?? 1,
|
|
28061
|
+
value: Number(
|
|
28062
|
+
selectedValues[`${filter.field}_min`] ?? filter.min ?? 0
|
|
28063
|
+
),
|
|
28064
|
+
onChange: (v) => handleFilterSelect(`${filter.field}_min`, String(v)),
|
|
28065
|
+
showTooltip: true,
|
|
28066
|
+
className: "min-w-[130px]",
|
|
28067
|
+
"aria-label": t("filterGroup.from")
|
|
28068
|
+
}
|
|
28069
|
+
),
|
|
28070
|
+
/* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "-" }),
|
|
28071
|
+
/* @__PURE__ */ jsx(
|
|
28072
|
+
RangeSlider,
|
|
28073
|
+
{
|
|
28074
|
+
min: filter.min ?? 0,
|
|
28075
|
+
max: filter.max ?? 100,
|
|
28076
|
+
step: filter.step ?? 1,
|
|
28077
|
+
value: Number(
|
|
28078
|
+
selectedValues[`${filter.field}_max`] ?? filter.max ?? 100
|
|
28079
|
+
),
|
|
28080
|
+
onChange: (v) => handleFilterSelect(`${filter.field}_max`, String(v)),
|
|
28081
|
+
showTooltip: true,
|
|
28082
|
+
className: "min-w-[130px]",
|
|
28083
|
+
"aria-label": t("filterGroup.to")
|
|
28084
|
+
}
|
|
28085
|
+
)
|
|
27991
28086
|
] }) : resolveFilterType(filter) === "text" ? /* @__PURE__ */ jsx(
|
|
27992
28087
|
Input,
|
|
27993
28088
|
{
|
|
@@ -29887,7 +29982,12 @@ function daysAgo(n) {
|
|
|
29887
29982
|
d.setDate(d.getDate() - n);
|
|
29888
29983
|
return d;
|
|
29889
29984
|
}
|
|
29890
|
-
|
|
29985
|
+
function resolvePresetRange(preset) {
|
|
29986
|
+
if (typeof preset.range === "function") return preset.range();
|
|
29987
|
+
if (preset.range) return preset.range;
|
|
29988
|
+
return TOKEN_RANGES[preset.value]?.() ?? null;
|
|
29989
|
+
}
|
|
29990
|
+
var TOKEN_RANGES, DEFAULT_PRESETS, DateRangePicker;
|
|
29891
29991
|
var init_DateRangePicker = __esm({
|
|
29892
29992
|
"components/core/molecules/DateRangePicker.tsx"() {
|
|
29893
29993
|
"use client";
|
|
@@ -29897,32 +29997,19 @@ var init_DateRangePicker = __esm({
|
|
|
29897
29997
|
init_Stack();
|
|
29898
29998
|
init_Typography();
|
|
29899
29999
|
init_useEventBus();
|
|
30000
|
+
TOKEN_RANGES = {
|
|
30001
|
+
"7d": () => ({ from: toISODate(daysAgo(7)), to: toISODate(/* @__PURE__ */ new Date()) }),
|
|
30002
|
+
"30d": () => ({ from: toISODate(daysAgo(30)), to: toISODate(/* @__PURE__ */ new Date()) }),
|
|
30003
|
+
month: () => ({ from: toISODate(startOfMonth(/* @__PURE__ */ new Date())), to: toISODate(/* @__PURE__ */ new Date()) }),
|
|
30004
|
+
quarter: () => ({ from: toISODate(startOfQuarter(/* @__PURE__ */ new Date())), to: toISODate(/* @__PURE__ */ new Date()) }),
|
|
30005
|
+
ytd: () => ({ from: toISODate(startOfYear(/* @__PURE__ */ new Date())), to: toISODate(/* @__PURE__ */ new Date()) })
|
|
30006
|
+
};
|
|
29900
30007
|
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
|
-
}
|
|
30008
|
+
{ label: "Last 7 days", value: "7d" },
|
|
30009
|
+
{ label: "Last 30 days", value: "30d" },
|
|
30010
|
+
{ label: "This Month", value: "month" },
|
|
30011
|
+
{ label: "This Quarter", value: "quarter" },
|
|
30012
|
+
{ label: "YTD", value: "ytd" }
|
|
29926
30013
|
];
|
|
29927
30014
|
DateRangePicker = ({
|
|
29928
30015
|
from: fromProp,
|
|
@@ -29963,7 +30050,8 @@ var init_DateRangePicker = __esm({
|
|
|
29963
30050
|
);
|
|
29964
30051
|
const handlePreset = useCallback(
|
|
29965
30052
|
(preset) => {
|
|
29966
|
-
const range = preset
|
|
30053
|
+
const range = resolvePresetRange(preset);
|
|
30054
|
+
if (range === null) return;
|
|
29967
30055
|
setFrom(range.from);
|
|
29968
30056
|
setTo(range.to);
|
|
29969
30057
|
setActivePreset(preset.value);
|
|
@@ -29971,8 +30059,12 @@ var init_DateRangePicker = __esm({
|
|
|
29971
30059
|
},
|
|
29972
30060
|
[emit]
|
|
29973
30061
|
);
|
|
30062
|
+
const renderablePresets = useMemo(
|
|
30063
|
+
() => presets.filter((p) => p.range !== void 0 || TOKEN_RANGES[p.value] !== void 0),
|
|
30064
|
+
[presets]
|
|
30065
|
+
);
|
|
29974
30066
|
const presetButtons = useMemo(
|
|
29975
|
-
() =>
|
|
30067
|
+
() => renderablePresets.map((preset) => /* @__PURE__ */ jsx(
|
|
29976
30068
|
Button,
|
|
29977
30069
|
{
|
|
29978
30070
|
variant: activePreset === preset.value ? "primary" : "ghost",
|
|
@@ -29982,7 +30074,7 @@ var init_DateRangePicker = __esm({
|
|
|
29982
30074
|
},
|
|
29983
30075
|
preset.value
|
|
29984
30076
|
)),
|
|
29985
|
-
[
|
|
30077
|
+
[renderablePresets, activePreset, handlePreset]
|
|
29986
30078
|
);
|
|
29987
30079
|
return /* @__PURE__ */ jsxs(VStack, { gap: "sm", className: cn(className), children: [
|
|
29988
30080
|
/* @__PURE__ */ jsxs(HStack, { gap: "md", align: "end", children: [
|
|
@@ -30009,7 +30101,7 @@ var init_DateRangePicker = __esm({
|
|
|
30009
30101
|
)
|
|
30010
30102
|
] })
|
|
30011
30103
|
] }),
|
|
30012
|
-
|
|
30104
|
+
renderablePresets.length > 0 && /* @__PURE__ */ jsx(HStack, { gap: "xs", wrap: true, children: presetButtons })
|
|
30013
30105
|
] });
|
|
30014
30106
|
};
|
|
30015
30107
|
DateRangePicker.displayName = "DateRangePicker";
|
|
@@ -30451,6 +30543,208 @@ var init_PhysicsCanvas = __esm({
|
|
|
30451
30543
|
};
|
|
30452
30544
|
}
|
|
30453
30545
|
});
|
|
30546
|
+
|
|
30547
|
+
// lib/graphViewLayouts.ts
|
|
30548
|
+
function buildAdjacency(nodeIds, edges) {
|
|
30549
|
+
const known = new Set(nodeIds);
|
|
30550
|
+
const out = /* @__PURE__ */ new Map();
|
|
30551
|
+
const inMap = /* @__PURE__ */ new Map();
|
|
30552
|
+
for (const id of nodeIds) {
|
|
30553
|
+
out.set(id, []);
|
|
30554
|
+
inMap.set(id, []);
|
|
30555
|
+
}
|
|
30556
|
+
for (const edge of edges) {
|
|
30557
|
+
if (!known.has(edge.source) || !known.has(edge.target)) continue;
|
|
30558
|
+
out.get(edge.source)?.push(edge.target);
|
|
30559
|
+
inMap.get(edge.target)?.push(edge.source);
|
|
30560
|
+
}
|
|
30561
|
+
return { out, in: inMap };
|
|
30562
|
+
}
|
|
30563
|
+
function findRoots(nodeIds, adjacency) {
|
|
30564
|
+
return nodeIds.filter((id) => (adjacency.in.get(id)?.length ?? 0) === 0);
|
|
30565
|
+
}
|
|
30566
|
+
function assignLayers(nodeIds, adjacency, roots) {
|
|
30567
|
+
const layer = new Map(nodeIds.map((id) => [id, 0]));
|
|
30568
|
+
const onStack = /* @__PURE__ */ new Set();
|
|
30569
|
+
const visit = (id) => {
|
|
30570
|
+
onStack.add(id);
|
|
30571
|
+
const currentLayer = layer.get(id) ?? 0;
|
|
30572
|
+
for (const next of adjacency.out.get(id) ?? []) {
|
|
30573
|
+
if (onStack.has(next)) continue;
|
|
30574
|
+
const candidate = currentLayer + 1;
|
|
30575
|
+
if (candidate > (layer.get(next) ?? 0)) {
|
|
30576
|
+
layer.set(next, candidate);
|
|
30577
|
+
}
|
|
30578
|
+
visit(next);
|
|
30579
|
+
}
|
|
30580
|
+
onStack.delete(id);
|
|
30581
|
+
};
|
|
30582
|
+
for (const root of roots) visit(root);
|
|
30583
|
+
return layer;
|
|
30584
|
+
}
|
|
30585
|
+
function computeVisitOrder(nodeIds, adjacency, roots) {
|
|
30586
|
+
const order = /* @__PURE__ */ new Map();
|
|
30587
|
+
const visited = /* @__PURE__ */ new Set();
|
|
30588
|
+
let counter = 0;
|
|
30589
|
+
const visit = (id) => {
|
|
30590
|
+
if (visited.has(id)) return;
|
|
30591
|
+
visited.add(id);
|
|
30592
|
+
order.set(id, counter++);
|
|
30593
|
+
for (const next of adjacency.out.get(id) ?? []) visit(next);
|
|
30594
|
+
};
|
|
30595
|
+
for (const root of roots) visit(root);
|
|
30596
|
+
for (const id of nodeIds) {
|
|
30597
|
+
if (!visited.has(id)) order.set(id, counter++);
|
|
30598
|
+
}
|
|
30599
|
+
return order;
|
|
30600
|
+
}
|
|
30601
|
+
function bfsDepthAndOrder(nodeIds, adjacency, roots) {
|
|
30602
|
+
const depth = new Map(nodeIds.map((id) => [id, 0]));
|
|
30603
|
+
const visitOrder = /* @__PURE__ */ new Map();
|
|
30604
|
+
const visited = /* @__PURE__ */ new Set();
|
|
30605
|
+
const queue = [];
|
|
30606
|
+
let counter = 0;
|
|
30607
|
+
for (const root of roots) {
|
|
30608
|
+
if (visited.has(root)) continue;
|
|
30609
|
+
visited.add(root);
|
|
30610
|
+
depth.set(root, 0);
|
|
30611
|
+
visitOrder.set(root, counter++);
|
|
30612
|
+
queue.push(root);
|
|
30613
|
+
}
|
|
30614
|
+
let head = 0;
|
|
30615
|
+
while (head < queue.length) {
|
|
30616
|
+
const id = queue[head++];
|
|
30617
|
+
const d = depth.get(id) ?? 0;
|
|
30618
|
+
for (const next of adjacency.out.get(id) ?? []) {
|
|
30619
|
+
if (visited.has(next)) continue;
|
|
30620
|
+
visited.add(next);
|
|
30621
|
+
depth.set(next, d + 1);
|
|
30622
|
+
visitOrder.set(next, counter++);
|
|
30623
|
+
queue.push(next);
|
|
30624
|
+
}
|
|
30625
|
+
}
|
|
30626
|
+
for (const id of nodeIds) {
|
|
30627
|
+
if (!visited.has(id)) visitOrder.set(id, counter++);
|
|
30628
|
+
}
|
|
30629
|
+
return { depth, visitOrder };
|
|
30630
|
+
}
|
|
30631
|
+
function edgeWalkOrder(nodeIds, adjacency) {
|
|
30632
|
+
const visited = /* @__PURE__ */ new Set();
|
|
30633
|
+
const result = [];
|
|
30634
|
+
for (const start of nodeIds) {
|
|
30635
|
+
if (visited.has(start)) continue;
|
|
30636
|
+
let current = start;
|
|
30637
|
+
while (current !== void 0 && !visited.has(current)) {
|
|
30638
|
+
visited.add(current);
|
|
30639
|
+
result.push(current);
|
|
30640
|
+
const outs = adjacency.out.get(current) ?? [];
|
|
30641
|
+
current = outs.find((next) => !visited.has(next));
|
|
30642
|
+
}
|
|
30643
|
+
}
|
|
30644
|
+
return result;
|
|
30645
|
+
}
|
|
30646
|
+
function groupByTier(nodeIds, tierOf, maxTier) {
|
|
30647
|
+
const groups = Array.from({ length: maxTier + 1 }, () => []);
|
|
30648
|
+
for (const id of nodeIds) {
|
|
30649
|
+
groups[tierOf.get(id) ?? 0].push(id);
|
|
30650
|
+
}
|
|
30651
|
+
return groups;
|
|
30652
|
+
}
|
|
30653
|
+
function distributeAxis(count, start, end) {
|
|
30654
|
+
if (count <= 0) return [];
|
|
30655
|
+
const slot = (end - start) / count;
|
|
30656
|
+
return Array.from({ length: count }, (_, i) => start + slot * (i + 0.5));
|
|
30657
|
+
}
|
|
30658
|
+
function orderByParentPositionThenInput(group, adjacency, positioned, inputIndex) {
|
|
30659
|
+
const withKey = group.map((id) => {
|
|
30660
|
+
const parentValues = (adjacency.in.get(id) ?? []).map((p) => positioned.get(p)).filter((v) => v !== void 0);
|
|
30661
|
+
const avg = parentValues.length > 0 ? parentValues.reduce((a, b) => a + b, 0) / parentValues.length : Number.POSITIVE_INFINITY;
|
|
30662
|
+
return { id, avg, idx: inputIndex.get(id) ?? 0 };
|
|
30663
|
+
});
|
|
30664
|
+
withKey.sort((a, b) => a.avg !== b.avg ? a.avg - b.avg : a.idx - b.idx);
|
|
30665
|
+
return withKey.map((k) => k.id);
|
|
30666
|
+
}
|
|
30667
|
+
function layoutFlow(nodeIds, adjacency, roots, width, height, margin) {
|
|
30668
|
+
const inputIndex = new Map(nodeIds.map((id, i) => [id, i]));
|
|
30669
|
+
const layers = assignLayers(nodeIds, adjacency, roots);
|
|
30670
|
+
const maxLayer = Math.max(...Array.from(layers.values()));
|
|
30671
|
+
const layerGroups = groupByTier(nodeIds, layers, maxLayer);
|
|
30672
|
+
const positions = /* @__PURE__ */ new Map();
|
|
30673
|
+
const yById = /* @__PURE__ */ new Map();
|
|
30674
|
+
for (let l = 0; l <= maxLayer; l++) {
|
|
30675
|
+
const x = margin + l * (width - 2 * margin) / Math.max(1, maxLayer);
|
|
30676
|
+
const ordered2 = orderByParentPositionThenInput(layerGroups[l], adjacency, yById, inputIndex);
|
|
30677
|
+
const ys = distributeAxis(ordered2.length, margin, height - margin);
|
|
30678
|
+
ordered2.forEach((id, i) => {
|
|
30679
|
+
positions.set(id, { id, x, y: ys[i] });
|
|
30680
|
+
yById.set(id, ys[i]);
|
|
30681
|
+
});
|
|
30682
|
+
}
|
|
30683
|
+
return nodeIds.map((id) => positions.get(id));
|
|
30684
|
+
}
|
|
30685
|
+
function layoutTree2(nodeIds, adjacency, roots, width, height, margin) {
|
|
30686
|
+
const effectiveRoots = roots.length > 0 ? roots : [nodeIds[0]];
|
|
30687
|
+
const layers = assignLayers(nodeIds, adjacency, effectiveRoots);
|
|
30688
|
+
const maxLayer = Math.max(...Array.from(layers.values()));
|
|
30689
|
+
const visitOrder = computeVisitOrder(nodeIds, adjacency, effectiveRoots);
|
|
30690
|
+
const layerGroups = groupByTier(nodeIds, layers, maxLayer);
|
|
30691
|
+
const positions = /* @__PURE__ */ new Map();
|
|
30692
|
+
for (let l = 0; l <= maxLayer; l++) {
|
|
30693
|
+
const ordered2 = [...layerGroups[l]].sort(
|
|
30694
|
+
(a, b) => (visitOrder.get(a) ?? 0) - (visitOrder.get(b) ?? 0)
|
|
30695
|
+
);
|
|
30696
|
+
const y = margin + l * (height - 2 * margin) / Math.max(1, maxLayer);
|
|
30697
|
+
const xs = distributeAxis(ordered2.length, margin, width - margin);
|
|
30698
|
+
ordered2.forEach((id, i) => positions.set(id, { id, x: xs[i], y }));
|
|
30699
|
+
}
|
|
30700
|
+
return nodeIds.map((id) => positions.get(id));
|
|
30701
|
+
}
|
|
30702
|
+
function layoutRadial(nodeIds, adjacency, roots, width, height, margin) {
|
|
30703
|
+
const cx = width / 2;
|
|
30704
|
+
const cy = height / 2;
|
|
30705
|
+
const maxRadius = Math.min(width, height) / 2 - margin;
|
|
30706
|
+
if (roots.length === 0) {
|
|
30707
|
+
const order = edgeWalkOrder(nodeIds, adjacency);
|
|
30708
|
+
const k = order.length;
|
|
30709
|
+
const positions2 = /* @__PURE__ */ new Map();
|
|
30710
|
+
order.forEach((id, i) => {
|
|
30711
|
+
const angle = i / k * 2 * Math.PI;
|
|
30712
|
+
positions2.set(id, { id, x: cx + maxRadius * Math.cos(angle), y: cy + maxRadius * Math.sin(angle) });
|
|
30713
|
+
});
|
|
30714
|
+
return nodeIds.map((id) => positions2.get(id));
|
|
30715
|
+
}
|
|
30716
|
+
const { depth, visitOrder } = bfsDepthAndOrder(nodeIds, adjacency, roots);
|
|
30717
|
+
const maxDepth = Math.max(...Array.from(depth.values()));
|
|
30718
|
+
const ringGroups = groupByTier(nodeIds, depth, maxDepth);
|
|
30719
|
+
const positions = /* @__PURE__ */ new Map();
|
|
30720
|
+
for (let d = 0; d <= maxDepth; d++) {
|
|
30721
|
+
const ordered2 = [...ringGroups[d]].sort(
|
|
30722
|
+
(a, b) => (visitOrder.get(a) ?? 0) - (visitOrder.get(b) ?? 0)
|
|
30723
|
+
);
|
|
30724
|
+
const radius = d * maxRadius / Math.max(1, maxDepth);
|
|
30725
|
+
const k = ordered2.length;
|
|
30726
|
+
ordered2.forEach((id, i) => {
|
|
30727
|
+
const angle = i / k * 2 * Math.PI;
|
|
30728
|
+
positions.set(id, { id, x: cx + radius * Math.cos(angle), y: cy + radius * Math.sin(angle) });
|
|
30729
|
+
});
|
|
30730
|
+
}
|
|
30731
|
+
return nodeIds.map((id) => positions.get(id));
|
|
30732
|
+
}
|
|
30733
|
+
function computeStaticLayout(mode, input) {
|
|
30734
|
+
const { nodeIds, edges, width, height } = input;
|
|
30735
|
+
const margin = input.margin ?? 40;
|
|
30736
|
+
if (nodeIds.length === 0) return [];
|
|
30737
|
+
if (nodeIds.length === 1) return [{ id: nodeIds[0], x: width / 2, y: height / 2 }];
|
|
30738
|
+
const adjacency = buildAdjacency(nodeIds, edges);
|
|
30739
|
+
const roots = findRoots(nodeIds, adjacency);
|
|
30740
|
+
if (mode === "flow") return layoutFlow(nodeIds, adjacency, roots, width, height, margin);
|
|
30741
|
+
if (mode === "tree") return layoutTree2(nodeIds, adjacency, roots, width, height, margin);
|
|
30742
|
+
return layoutRadial(nodeIds, adjacency, roots, width, height, margin);
|
|
30743
|
+
}
|
|
30744
|
+
var init_graphViewLayouts = __esm({
|
|
30745
|
+
"lib/graphViewLayouts.ts"() {
|
|
30746
|
+
}
|
|
30747
|
+
});
|
|
30454
30748
|
function resolveNodeColor(node, groups) {
|
|
30455
30749
|
if (node.color) return node.color;
|
|
30456
30750
|
if (node.group) {
|
|
@@ -30465,6 +30759,7 @@ var init_GraphView = __esm({
|
|
|
30465
30759
|
"use client";
|
|
30466
30760
|
init_cn();
|
|
30467
30761
|
init_atoms();
|
|
30762
|
+
init_graphViewLayouts();
|
|
30468
30763
|
GROUP_COLORS = [
|
|
30469
30764
|
"#3b82f6",
|
|
30470
30765
|
// blue-500
|
|
@@ -30495,11 +30790,13 @@ var init_GraphView = __esm({
|
|
|
30495
30790
|
height: propHeight,
|
|
30496
30791
|
className,
|
|
30497
30792
|
showLabels = true,
|
|
30498
|
-
zoomToFit = true
|
|
30793
|
+
zoomToFit = true,
|
|
30794
|
+
layout = "force"
|
|
30499
30795
|
}) => {
|
|
30500
30796
|
const { t } = useTranslate();
|
|
30501
30797
|
const containerRef = useRef(null);
|
|
30502
30798
|
const animRef = useRef(0);
|
|
30799
|
+
const arrowMarkerId = useId();
|
|
30503
30800
|
const [simNodes, setSimNodes] = useState([]);
|
|
30504
30801
|
const [settled, setSettled] = useState(false);
|
|
30505
30802
|
const [hoveredId, setHoveredId] = useState(null);
|
|
@@ -30556,6 +30853,22 @@ var init_GraphView = __esm({
|
|
|
30556
30853
|
fy: 0
|
|
30557
30854
|
};
|
|
30558
30855
|
});
|
|
30856
|
+
if (layout !== "force") {
|
|
30857
|
+
const points = computeStaticLayout(layout, {
|
|
30858
|
+
nodeIds: nodes.map((n) => n.id),
|
|
30859
|
+
edges,
|
|
30860
|
+
width: w,
|
|
30861
|
+
height: h
|
|
30862
|
+
});
|
|
30863
|
+
const pointById = new Map(points.map((p) => [p.id, p]));
|
|
30864
|
+
const laidOut = initialNodes.map((node) => {
|
|
30865
|
+
const point = pointById.get(node.id);
|
|
30866
|
+
return point ? { ...node, x: point.x, y: point.y } : node;
|
|
30867
|
+
});
|
|
30868
|
+
setSimNodes(laidOut);
|
|
30869
|
+
setSettled(true);
|
|
30870
|
+
return;
|
|
30871
|
+
}
|
|
30559
30872
|
let iterations = 0;
|
|
30560
30873
|
const maxIterations = 120;
|
|
30561
30874
|
let currentNodes = initialNodes;
|
|
@@ -30624,7 +30937,7 @@ var init_GraphView = __esm({
|
|
|
30624
30937
|
return () => {
|
|
30625
30938
|
cancelAnimationFrame(animRef.current);
|
|
30626
30939
|
};
|
|
30627
|
-
}, [nodes, edges, w, h, groups]);
|
|
30940
|
+
}, [nodes, edges, w, h, groups, layout]);
|
|
30628
30941
|
const viewBox = useMemo(() => {
|
|
30629
30942
|
if (!zoomToFit || !settled || simNodes.length === 0) {
|
|
30630
30943
|
return `0 0 ${w} ${h}`;
|
|
@@ -30699,6 +31012,19 @@ var init_GraphView = __esm({
|
|
|
30699
31012
|
viewBox,
|
|
30700
31013
|
preserveAspectRatio: "xMidYMid meet",
|
|
30701
31014
|
children: [
|
|
31015
|
+
layout !== "force" && /* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsx(
|
|
31016
|
+
"marker",
|
|
31017
|
+
{
|
|
31018
|
+
id: arrowMarkerId,
|
|
31019
|
+
viewBox: "0 0 10 10",
|
|
31020
|
+
refX: "9",
|
|
31021
|
+
refY: "5",
|
|
31022
|
+
markerWidth: "6",
|
|
31023
|
+
markerHeight: "6",
|
|
31024
|
+
orient: "auto-start-reverse",
|
|
31025
|
+
children: /* @__PURE__ */ jsx("path", { d: "M0,0 L10,5 L0,10 z", fill: "currentColor" })
|
|
31026
|
+
}
|
|
31027
|
+
) }),
|
|
30702
31028
|
edges.map((edge, idx) => {
|
|
30703
31029
|
const source = nodeMap.get(edge.source);
|
|
30704
31030
|
const target = nodeMap.get(edge.target);
|
|
@@ -30713,8 +31039,10 @@ var init_GraphView = __esm({
|
|
|
30713
31039
|
x2: target.x,
|
|
30714
31040
|
y2: target.y,
|
|
30715
31041
|
stroke: edge.color ?? DEFAULT_EDGE_COLOR,
|
|
31042
|
+
color: edge.color ?? DEFAULT_EDGE_COLOR,
|
|
30716
31043
|
strokeWidth: 1.5,
|
|
30717
|
-
opacity: isHighlighted ? 0.8 : 0.15
|
|
31044
|
+
opacity: isHighlighted ? 0.8 : 0.15,
|
|
31045
|
+
markerEnd: layout !== "force" ? `url(#${arrowMarkerId})` : void 0
|
|
30718
31046
|
}
|
|
30719
31047
|
),
|
|
30720
31048
|
showLabels && edge.label && /* @__PURE__ */ jsx(
|
|
@@ -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 };
|