@almadar/ui 5.77.0 → 5.79.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.
Files changed (71) hide show
  1. package/dist/avl/index.cjs +863 -98
  2. package/dist/avl/index.css +3 -3
  3. package/dist/avl/index.js +863 -98
  4. package/dist/components/core/atoms/FlipContainer.d.ts +1 -1
  5. package/dist/components/core/atoms/index.d.ts +2 -1
  6. package/dist/components/core/molecules/Card.d.ts +1 -1
  7. package/dist/components/core/molecules/DataGrid.d.ts +1 -1
  8. package/dist/components/core/molecules/DataList.d.ts +1 -1
  9. package/dist/components/core/molecules/DocPagination.d.ts +8 -1
  10. package/dist/components/core/molecules/DocSearch.d.ts +8 -1
  11. package/dist/components/core/molecules/FlipCard.d.ts +1 -1
  12. package/dist/components/core/molecules/MapView.d.ts +18 -1
  13. package/dist/components/core/molecules/PropertyInspector.d.ts +2 -0
  14. package/dist/components/core/molecules/SortableList.d.ts +1 -1
  15. package/dist/components/core/molecules/TableView.d.ts +1 -1
  16. package/dist/components/core/molecules/index.d.ts +4 -0
  17. package/dist/components/core/organisms/DataTable.d.ts +1 -1
  18. package/dist/components/core/organisms/debug/RuntimeDebugger.d.ts +10 -1
  19. package/dist/components/core/organisms/debug/tabs/EntitiesTab.d.ts +2 -1
  20. package/dist/components/core/organisms/debug/tabs/EventDispatcherTab.d.ts +2 -1
  21. package/dist/components/core/organisms/debug/tabs/EventFlowTab.d.ts +6 -1
  22. package/dist/components/core/organisms/debug/tabs/GuardsPanel.d.ts +6 -1
  23. package/dist/components/core/organisms/debug/tabs/ServerBridgeTab.d.ts +12 -1
  24. package/dist/components/core/organisms/debug/tabs/TicksTab.d.ts +2 -1
  25. package/dist/components/core/organisms/debug/tabs/TraitsTab.d.ts +2 -1
  26. package/dist/components/core/organisms/debug/tabs/TransitionTimeline.d.ts +11 -1
  27. package/dist/components/core/organisms/debug/tabs/VerificationTab.d.ts +8 -1
  28. package/dist/components/game/2d/atoms/ActionButton.d.ts +2 -1
  29. package/dist/components/game/2d/atoms/ChoiceButton.d.ts +2 -1
  30. package/dist/components/game/2d/atoms/ComboCounter.d.ts +2 -1
  31. package/dist/components/game/2d/atoms/ControlButton.d.ts +2 -1
  32. package/dist/components/game/2d/atoms/DamageNumber.d.ts +2 -1
  33. package/dist/components/game/2d/atoms/DialogueBubble.d.ts +2 -1
  34. package/dist/components/game/2d/atoms/GameIcon.d.ts +2 -1
  35. package/dist/components/game/2d/atoms/HealthBar.d.ts +2 -1
  36. package/dist/components/game/2d/atoms/ItemSlot.d.ts +2 -1
  37. package/dist/components/game/2d/atoms/MiniMap.d.ts +2 -1
  38. package/dist/components/game/2d/atoms/ResourceCounter.d.ts +2 -1
  39. package/dist/components/game/2d/atoms/ScoreDisplay.d.ts +2 -1
  40. package/dist/components/game/2d/atoms/StatusEffect.d.ts +2 -1
  41. package/dist/components/game/2d/atoms/TimerDisplay.d.ts +2 -1
  42. package/dist/components/game/2d/atoms/TurnIndicator.d.ts +2 -1
  43. package/dist/components/game/2d/atoms/WaypointMarker.d.ts +2 -1
  44. package/dist/components/game/2d/molecules/GameHud.d.ts +2 -1
  45. package/dist/components/game/2d/molecules/GameMenu.d.ts +2 -1
  46. package/dist/components/game/2d/molecules/InventoryGrid.d.ts +2 -1
  47. package/dist/components/game/2d/molecules/ResourceBar.d.ts +2 -1
  48. package/dist/components/game/2d/molecules/StatBadge.d.ts +2 -1
  49. package/dist/components/game/shared/lib/editorUtils.d.ts +8 -8
  50. package/dist/components/index.cjs +2212 -1525
  51. package/dist/components/index.css +3 -3
  52. package/dist/components/index.js +1002 -315
  53. package/dist/components/learning/atoms/LearningCanvas.d.ts +80 -0
  54. package/dist/components/learning/molecules/BiologyCanvas.d.ts +47 -0
  55. package/dist/components/learning/molecules/ChemistryCanvas.d.ts +55 -0
  56. package/dist/components/learning/molecules/MathCanvas.d.ts +61 -0
  57. package/dist/components/learning/molecules/PhysicsCanvas.d.ts +54 -0
  58. package/dist/components/marketing/atoms/MarketingStatCard.d.ts +2 -2
  59. package/dist/hooks/useGitHub.d.ts +7 -7
  60. package/dist/marketing/index.cjs +2 -2
  61. package/dist/marketing/index.js +2 -2
  62. package/dist/providers/EventBusProvider.d.ts +1 -1
  63. package/dist/providers/SelectionProvider.d.ts +1 -1
  64. package/dist/providers/ServerBridge.d.ts +1 -1
  65. package/dist/providers/index.cjs +859 -94
  66. package/dist/providers/index.css +3 -3
  67. package/dist/providers/index.js +859 -94
  68. package/dist/runtime/index.cjs +859 -94
  69. package/dist/runtime/index.css +3 -3
  70. package/dist/runtime/index.js +859 -94
  71. package/package.json +1 -1
@@ -6225,6 +6225,66 @@ var init_RangeSlider = __esm({
6225
6225
  RangeSlider.displayName = "RangeSlider";
6226
6226
  }
6227
6227
  });
6228
+ function easeOut(t) {
6229
+ return t * (2 - t);
6230
+ }
6231
+ var AnimatedCounter;
6232
+ var init_AnimatedCounter = __esm({
6233
+ "components/marketing/atoms/AnimatedCounter.tsx"() {
6234
+ "use client";
6235
+ init_cn();
6236
+ init_Typography();
6237
+ AnimatedCounter = ({
6238
+ value: rawValue,
6239
+ duration = 600,
6240
+ prefix,
6241
+ suffix,
6242
+ className
6243
+ }) => {
6244
+ const numericRaw = typeof rawValue === "number" ? rawValue : Number.parseFloat(String(rawValue ?? ""));
6245
+ const value = !Number.isNaN(numericRaw) ? numericRaw : 0;
6246
+ const [displayValue, setDisplayValue] = React105.useState(value);
6247
+ const previousValueRef = React105.useRef(value);
6248
+ const animationFrameRef = React105.useRef(null);
6249
+ React105.useEffect(() => {
6250
+ const from = previousValueRef.current;
6251
+ const to = value;
6252
+ previousValueRef.current = value;
6253
+ if (from === to) {
6254
+ setDisplayValue(to);
6255
+ return;
6256
+ }
6257
+ const startTime = performance.now();
6258
+ const diff = to - from;
6259
+ function animate(currentTime) {
6260
+ const elapsed = currentTime - startTime;
6261
+ const progress = Math.min(elapsed / duration, 1);
6262
+ const easedProgress = easeOut(progress);
6263
+ setDisplayValue(from + diff * easedProgress);
6264
+ if (progress < 1) {
6265
+ animationFrameRef.current = requestAnimationFrame(animate);
6266
+ } else {
6267
+ setDisplayValue(to);
6268
+ }
6269
+ }
6270
+ animationFrameRef.current = requestAnimationFrame(animate);
6271
+ return () => {
6272
+ if (animationFrameRef.current !== null) {
6273
+ cancelAnimationFrame(animationFrameRef.current);
6274
+ }
6275
+ };
6276
+ }, [value, duration]);
6277
+ const decimalPlaces = Number.isInteger(value) ? 0 : String(value).split(".")[1]?.length ?? 0;
6278
+ const formattedValue = displayValue.toFixed(decimalPlaces);
6279
+ return /* @__PURE__ */ jsxRuntime.jsxs(Typography, { variant: "h3", className: cn("tabular-nums", className), children: [
6280
+ prefix,
6281
+ formattedValue,
6282
+ suffix
6283
+ ] });
6284
+ };
6285
+ AnimatedCounter.displayName = "AnimatedCounter";
6286
+ }
6287
+ });
6228
6288
  var InfiniteScrollSentinel;
6229
6289
  var init_InfiniteScrollSentinel = __esm({
6230
6290
  "components/core/atoms/InfiniteScrollSentinel.tsx"() {
@@ -6486,6 +6546,34 @@ var init_SectionHeader = __esm({
6486
6546
  SectionHeader.displayName = "SectionHeader";
6487
6547
  }
6488
6548
  });
6549
+ var sizeClasses6, MarketingStatCard;
6550
+ var init_MarketingStatCard = __esm({
6551
+ "components/marketing/atoms/MarketingStatCard.tsx"() {
6552
+ init_cn();
6553
+ init_Stack();
6554
+ init_Typography();
6555
+ sizeClasses6 = {
6556
+ sm: "text-2xl",
6557
+ md: "text-4xl",
6558
+ lg: "text-5xl"
6559
+ };
6560
+ MarketingStatCard = ({ value, label, size = "md", className }) => {
6561
+ return /* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "xs", align: "center", className: cn(className), children: [
6562
+ /* @__PURE__ */ jsxRuntime.jsx(
6563
+ Typography,
6564
+ {
6565
+ weight: "bold",
6566
+ color: "primary",
6567
+ className: cn(sizeClasses6[size]),
6568
+ children: value
6569
+ }
6570
+ ),
6571
+ /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "caption", color: "muted", children: label })
6572
+ ] });
6573
+ };
6574
+ MarketingStatCard.displayName = "MarketingStatCard";
6575
+ }
6576
+ });
6489
6577
  var backgroundClasses, paddingClasses, ContentSection;
6490
6578
  var init_ContentSection = __esm({
6491
6579
  "components/marketing/atoms/ContentSection.tsx"() {
@@ -20151,6 +20239,315 @@ var init_molecules = __esm({
20151
20239
  init_puzzleObject();
20152
20240
  }
20153
20241
  });
20242
+ function resolveColor2(color, ctx, fallback) {
20243
+ if (!color) return fallback;
20244
+ if (color.startsWith("var(")) {
20245
+ ctx.canvas.style;
20246
+ const m = /^var\((--[^,)]+)(?:,\s*([^)]+))?\)$/.exec(color);
20247
+ if (m) {
20248
+ const computed = getComputedStyle(ctx.canvas).getPropertyValue(m[1]).trim();
20249
+ return computed || m[2]?.trim() || fallback;
20250
+ }
20251
+ }
20252
+ return color;
20253
+ }
20254
+ function shapeBounds(shape) {
20255
+ switch (shape.type) {
20256
+ case "line":
20257
+ case "arrow":
20258
+ if (shape.x1 == null || shape.y1 == null || shape.x2 == null || shape.y2 == null) return null;
20259
+ return {
20260
+ x: Math.min(shape.x1, shape.x2) - 6,
20261
+ y: Math.min(shape.y1, shape.y2) - 6,
20262
+ w: Math.abs(shape.x2 - shape.x1) + 12,
20263
+ h: Math.abs(shape.y2 - shape.y1) + 12
20264
+ };
20265
+ case "circle":
20266
+ if (shape.x == null || shape.y == null || shape.radius == null) return null;
20267
+ return {
20268
+ x: shape.x - shape.radius - 4,
20269
+ y: shape.y - shape.radius - 4,
20270
+ w: shape.radius * 2 + 8,
20271
+ h: shape.radius * 2 + 8
20272
+ };
20273
+ case "rect":
20274
+ if (shape.x == null || shape.y == null || shape.width == null || shape.height == null) return null;
20275
+ return { x: shape.x - 4, y: shape.y - 4, w: shape.width + 8, h: shape.height + 8 };
20276
+ case "polygon":
20277
+ if (!shape.points || shape.points.length === 0) return null;
20278
+ {
20279
+ const xs = shape.points.map((p2) => p2.x);
20280
+ const ys = shape.points.map((p2) => p2.y);
20281
+ const minX = Math.min(...xs);
20282
+ const minY = Math.min(...ys);
20283
+ return {
20284
+ x: minX - 4,
20285
+ y: minY - 4,
20286
+ w: Math.max(...xs) - minX + 8,
20287
+ h: Math.max(...ys) - minY + 8
20288
+ };
20289
+ }
20290
+ case "text":
20291
+ if (shape.x == null || shape.y == null) return null;
20292
+ return { x: shape.x - 4, y: shape.y - (shape.fontSize ?? 14) - 4, w: 120, h: (shape.fontSize ?? 14) + 8 };
20293
+ default:
20294
+ return null;
20295
+ }
20296
+ }
20297
+ function drawArrowHead(ctx, x1, y1, x2, y2, size) {
20298
+ const angle = Math.atan2(y2 - y1, x2 - x1);
20299
+ ctx.beginPath();
20300
+ ctx.moveTo(x2, y2);
20301
+ ctx.lineTo(x2 - size * Math.cos(angle - Math.PI / 6), y2 - size * Math.sin(angle - Math.PI / 6));
20302
+ ctx.lineTo(x2 - size * Math.cos(angle + Math.PI / 6), y2 - size * Math.sin(angle + Math.PI / 6));
20303
+ ctx.closePath();
20304
+ ctx.fill();
20305
+ }
20306
+ function drawShape(ctx, shape, width, height) {
20307
+ ctx.save();
20308
+ const opacity = shape.opacity ?? 1;
20309
+ ctx.globalAlpha = opacity;
20310
+ const stroke = resolveColor2(shape.color, ctx, "#333333");
20311
+ const fill = shape.fill ? resolveColor2(shape.fill, ctx, "#cccccc") : void 0;
20312
+ ctx.lineWidth = shape.lineWidth ?? 2;
20313
+ switch (shape.type) {
20314
+ case "grid": {
20315
+ const step = shape.step ?? 40;
20316
+ ctx.strokeStyle = stroke;
20317
+ ctx.globalAlpha = opacity * 0.25;
20318
+ ctx.lineWidth = 1;
20319
+ ctx.beginPath();
20320
+ for (let x = 0; x <= width; x += step) {
20321
+ ctx.moveTo(x, 0);
20322
+ ctx.lineTo(x, height);
20323
+ }
20324
+ for (let y = 0; y <= height; y += step) {
20325
+ ctx.moveTo(0, y);
20326
+ ctx.lineTo(width, y);
20327
+ }
20328
+ ctx.stroke();
20329
+ break;
20330
+ }
20331
+ case "axis": {
20332
+ const axis = shape.axis ?? "x";
20333
+ ctx.strokeStyle = stroke;
20334
+ ctx.lineWidth = shape.lineWidth ?? 2;
20335
+ ctx.beginPath();
20336
+ if (axis === "x") {
20337
+ ctx.moveTo(0, height / 2);
20338
+ ctx.lineTo(width, height / 2);
20339
+ } else {
20340
+ ctx.moveTo(width / 2, 0);
20341
+ ctx.lineTo(width / 2, height);
20342
+ }
20343
+ ctx.stroke();
20344
+ break;
20345
+ }
20346
+ case "line": {
20347
+ if (shape.x1 == null || shape.y1 == null || shape.x2 == null || shape.y2 == null) break;
20348
+ ctx.strokeStyle = stroke;
20349
+ ctx.beginPath();
20350
+ ctx.moveTo(shape.x1, shape.y1);
20351
+ ctx.lineTo(shape.x2, shape.y2);
20352
+ ctx.stroke();
20353
+ break;
20354
+ }
20355
+ case "arrow": {
20356
+ if (shape.x1 == null || shape.y1 == null || shape.x2 == null || shape.y2 == null) break;
20357
+ ctx.strokeStyle = stroke;
20358
+ ctx.fillStyle = stroke;
20359
+ ctx.beginPath();
20360
+ ctx.moveTo(shape.x1, shape.y1);
20361
+ ctx.lineTo(shape.x2, shape.y2);
20362
+ ctx.stroke();
20363
+ drawArrowHead(ctx, shape.x1, shape.y1, shape.x2, shape.y2, 10);
20364
+ break;
20365
+ }
20366
+ case "circle": {
20367
+ if (shape.x == null || shape.y == null || shape.radius == null) break;
20368
+ ctx.beginPath();
20369
+ ctx.arc(shape.x, shape.y, shape.radius, 0, Math.PI * 2);
20370
+ if (fill) {
20371
+ ctx.fillStyle = fill;
20372
+ ctx.fill();
20373
+ }
20374
+ ctx.strokeStyle = stroke;
20375
+ ctx.stroke();
20376
+ break;
20377
+ }
20378
+ case "rect": {
20379
+ if (shape.x == null || shape.y == null || shape.width == null || shape.height == null) break;
20380
+ if (fill) {
20381
+ ctx.fillStyle = fill;
20382
+ ctx.fillRect(shape.x, shape.y, shape.width, shape.height);
20383
+ }
20384
+ ctx.strokeStyle = stroke;
20385
+ ctx.strokeRect(shape.x, shape.y, shape.width, shape.height);
20386
+ break;
20387
+ }
20388
+ case "polygon": {
20389
+ if (!shape.points || shape.points.length < 2) break;
20390
+ ctx.beginPath();
20391
+ ctx.moveTo(shape.points[0].x, shape.points[0].y);
20392
+ for (let i = 1; i < shape.points.length; i++) {
20393
+ ctx.lineTo(shape.points[i].x, shape.points[i].y);
20394
+ }
20395
+ ctx.closePath();
20396
+ if (fill) {
20397
+ ctx.fillStyle = fill;
20398
+ ctx.fill();
20399
+ }
20400
+ ctx.strokeStyle = stroke;
20401
+ ctx.stroke();
20402
+ break;
20403
+ }
20404
+ case "path": {
20405
+ if (!shape.path) break;
20406
+ const p2 = new Path2D(shape.path);
20407
+ if (fill) {
20408
+ ctx.fillStyle = fill;
20409
+ ctx.fill(p2);
20410
+ }
20411
+ ctx.strokeStyle = stroke;
20412
+ ctx.stroke(p2);
20413
+ break;
20414
+ }
20415
+ case "text": {
20416
+ if (shape.x == null || shape.y == null || !shape.text) break;
20417
+ ctx.fillStyle = stroke;
20418
+ ctx.font = `${shape.fontSize ?? 14}px system-ui, sans-serif`;
20419
+ ctx.textAlign = shape.align ?? "left";
20420
+ ctx.textBaseline = "middle";
20421
+ ctx.fillText(shape.text, shape.x, shape.y);
20422
+ break;
20423
+ }
20424
+ }
20425
+ ctx.restore();
20426
+ }
20427
+ var LearningCanvas;
20428
+ var init_LearningCanvas = __esm({
20429
+ "components/learning/atoms/LearningCanvas.tsx"() {
20430
+ "use client";
20431
+ init_cn();
20432
+ init_useEventBus();
20433
+ LearningCanvas = ({
20434
+ className,
20435
+ width = 600,
20436
+ height = 400,
20437
+ backgroundColor,
20438
+ shapes = [],
20439
+ interactive = false,
20440
+ animate = false,
20441
+ onShapeClick,
20442
+ onShapeHover,
20443
+ isLoading,
20444
+ error
20445
+ }) => {
20446
+ const canvasRef = React105.useRef(null);
20447
+ const eventBus = useEventBus();
20448
+ const animRef = React105.useRef(0);
20449
+ const hoverIndexRef = React105.useRef(-1);
20450
+ const findShapeAt = React105.useCallback((clientX, clientY) => {
20451
+ const canvas = canvasRef.current;
20452
+ if (!canvas) return -1;
20453
+ const rect = canvas.getBoundingClientRect();
20454
+ const x = clientX - rect.left;
20455
+ const y = clientY - rect.top;
20456
+ for (let i = shapes.length - 1; i >= 0; i--) {
20457
+ const b = shapeBounds(shapes[i]);
20458
+ if (b && x >= b.x && x <= b.x + b.w && y >= b.y && y <= b.y + b.h) {
20459
+ return i;
20460
+ }
20461
+ }
20462
+ return -1;
20463
+ }, [shapes]);
20464
+ const draw = React105.useCallback(() => {
20465
+ const canvas = canvasRef.current;
20466
+ if (!canvas) return;
20467
+ const ctx = canvas.getContext("2d");
20468
+ if (!ctx) return;
20469
+ const dpr = typeof window !== "undefined" ? window.devicePixelRatio || 1 : 1;
20470
+ canvas.width = Math.max(1, Math.floor(width * dpr));
20471
+ canvas.height = Math.max(1, Math.floor(height * dpr));
20472
+ canvas.style.width = `${width}px`;
20473
+ canvas.style.height = `${height}px`;
20474
+ ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
20475
+ ctx.clearRect(0, 0, width, height);
20476
+ if (backgroundColor) {
20477
+ ctx.fillStyle = backgroundColor;
20478
+ ctx.fillRect(0, 0, width, height);
20479
+ }
20480
+ for (const shape of shapes) {
20481
+ drawShape(ctx, shape, width, height);
20482
+ }
20483
+ }, [width, height, backgroundColor, shapes]);
20484
+ React105.useEffect(() => {
20485
+ draw();
20486
+ }, [draw]);
20487
+ React105.useEffect(() => {
20488
+ if (!animate) return;
20489
+ const loop = () => {
20490
+ draw();
20491
+ animRef.current = requestAnimationFrame(loop);
20492
+ };
20493
+ animRef.current = requestAnimationFrame(loop);
20494
+ return () => cancelAnimationFrame(animRef.current);
20495
+ }, [animate, draw]);
20496
+ const handlePointerMove = React105.useCallback(
20497
+ (e) => {
20498
+ if (!interactive) return;
20499
+ const idx = findShapeAt(e.clientX, e.clientY);
20500
+ if (idx !== hoverIndexRef.current) {
20501
+ hoverIndexRef.current = idx;
20502
+ if (idx >= 0) {
20503
+ const shape = shapes[idx];
20504
+ const payload = { id: shape.id, type: shape.type, index: idx };
20505
+ if (onShapeHover) onShapeHover(payload);
20506
+ else if (eventBus) eventBus.emit(`UI:SHAPE_HOVER`, payload);
20507
+ }
20508
+ }
20509
+ },
20510
+ [interactive, onShapeHover, eventBus, findShapeAt, shapes]
20511
+ );
20512
+ const handleClick = React105.useCallback(
20513
+ (e) => {
20514
+ if (!interactive) return;
20515
+ const idx = findShapeAt(e.clientX, e.clientY);
20516
+ if (idx >= 0) {
20517
+ const shape = shapes[idx];
20518
+ const payload = { id: shape.id, type: shape.type, index: idx };
20519
+ if (onShapeClick) onShapeClick(payload);
20520
+ else if (eventBus) eventBus.emit(`UI:SHAPE_CLICK`, payload);
20521
+ }
20522
+ },
20523
+ [interactive, onShapeClick, eventBus, findShapeAt, shapes]
20524
+ );
20525
+ if (isLoading || error) {
20526
+ return /* @__PURE__ */ jsxRuntime.jsx(
20527
+ "div",
20528
+ {
20529
+ className: cn(
20530
+ "flex items-center justify-center rounded border border-border bg-surface",
20531
+ className
20532
+ ),
20533
+ style: { width, height },
20534
+ children: error ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-destructive", children: error.message }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-muted-foreground", children: "Loading canvas\u2026" })
20535
+ }
20536
+ );
20537
+ }
20538
+ return /* @__PURE__ */ jsxRuntime.jsx(
20539
+ "canvas",
20540
+ {
20541
+ ref: canvasRef,
20542
+ className: cn("block touch-none rounded border border-border", className),
20543
+ style: { width, height },
20544
+ onClick: handleClick,
20545
+ onPointerMove: handlePointerMove
20546
+ }
20547
+ );
20548
+ };
20549
+ }
20550
+ });
20154
20551
 
20155
20552
  // components/core/atoms/index.ts
20156
20553
  var init_atoms = __esm({
@@ -21636,91 +22033,6 @@ var init_ComponentPatterns = __esm({
21636
22033
  AlertPattern.displayName = "AlertPattern";
21637
22034
  }
21638
22035
  });
21639
- function parseValue(value) {
21640
- if (value === "" || value == null) return { num: 0, prefix: "", suffix: "", decimals: 0 };
21641
- const match = String(value).match(/^([^0-9]*)([0-9]+(?:\.[0-9]+)?)(.*)$/);
21642
- if (!match) {
21643
- return { num: 0, prefix: "", suffix: String(value), decimals: 0 };
21644
- }
21645
- const numStr = match[2];
21646
- const decimalIdx = numStr.indexOf(".");
21647
- const decimals = decimalIdx >= 0 ? numStr.length - decimalIdx - 1 : 0;
21648
- return {
21649
- prefix: match[1],
21650
- num: parseFloat(numStr),
21651
- suffix: match[3],
21652
- decimals
21653
- };
21654
- }
21655
- var AnimatedCounter;
21656
- var init_AnimatedCounter = __esm({
21657
- "components/core/molecules/AnimatedCounter.tsx"() {
21658
- "use client";
21659
- init_cn();
21660
- init_Box();
21661
- init_Typography();
21662
- AnimatedCounter = ({
21663
- value,
21664
- label,
21665
- duration = 1500,
21666
- className
21667
- }) => {
21668
- const ref = React105.useRef(null);
21669
- const [displayValue, setDisplayValue] = React105.useState("0");
21670
- const [hasAnimated, setHasAnimated] = React105.useState(false);
21671
- const animate = React105.useCallback(() => {
21672
- const { num: num2, prefix, suffix, decimals } = parseValue(value);
21673
- if (num2 === 0) {
21674
- setDisplayValue(String(value));
21675
- return;
21676
- }
21677
- const startTime = performance.now();
21678
- const tick = (now2) => {
21679
- const elapsed = now2 - startTime;
21680
- const progress = Math.min(elapsed / duration, 1);
21681
- const eased = 1 - Math.pow(1 - progress, 3);
21682
- const current = eased * num2;
21683
- setDisplayValue(`${prefix}${current.toFixed(decimals)}${suffix}`);
21684
- if (progress < 1) {
21685
- requestAnimationFrame(tick);
21686
- } else {
21687
- setDisplayValue(String(value));
21688
- }
21689
- };
21690
- requestAnimationFrame(tick);
21691
- }, [value, duration]);
21692
- React105.useEffect(() => {
21693
- if (hasAnimated) return;
21694
- const el = ref.current;
21695
- if (!el) return;
21696
- const observer2 = new IntersectionObserver(
21697
- (entries) => {
21698
- if (entries[0].isIntersecting) {
21699
- setHasAnimated(true);
21700
- animate();
21701
- observer2.disconnect();
21702
- }
21703
- },
21704
- { threshold: 0.3 }
21705
- );
21706
- observer2.observe(el);
21707
- return () => observer2.disconnect();
21708
- }, [hasAnimated, animate]);
21709
- return /* @__PURE__ */ jsxRuntime.jsxs(Box, { ref, className: cn("flex flex-col items-center gap-1 p-4", className), children: [
21710
- /* @__PURE__ */ jsxRuntime.jsx(
21711
- Typography,
21712
- {
21713
- variant: "h2",
21714
- className: "text-primary font-bold tabular-nums",
21715
- children: hasAnimated ? displayValue : "0"
21716
- }
21717
- ),
21718
- /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body2", color: "muted", className: "text-center", children: label })
21719
- ] });
21720
- };
21721
- AnimatedCounter.displayName = "AnimatedCounter";
21722
- }
21723
- });
21724
22036
  var AuthLayout;
21725
22037
  var init_AuthLayout = __esm({
21726
22038
  "components/marketing/templates/AuthLayout.tsx"() {
@@ -22689,10 +23001,107 @@ var init_BehaviorView = __esm({
22689
23001
  BehaviorView.displayName = "BehaviorView";
22690
23002
  }
22691
23003
  });
23004
+ var BiologyCanvas;
23005
+ var init_BiologyCanvas = __esm({
23006
+ "components/learning/molecules/BiologyCanvas.tsx"() {
23007
+ "use client";
23008
+ init_atoms();
23009
+ init_Stack();
23010
+ init_LearningCanvas();
23011
+ BiologyCanvas = ({
23012
+ className,
23013
+ width = 600,
23014
+ height = 400,
23015
+ title,
23016
+ backgroundColor,
23017
+ nodes = [],
23018
+ edges = [],
23019
+ shapes = [],
23020
+ interactive = false,
23021
+ animate = false,
23022
+ onShapeClick,
23023
+ isLoading,
23024
+ error
23025
+ }) => {
23026
+ const derivedShapes = React105.useMemo(() => {
23027
+ const out = [];
23028
+ const nodeById = /* @__PURE__ */ new Map();
23029
+ for (const n of nodes) {
23030
+ if (n.id) nodeById.set(n.id, n);
23031
+ }
23032
+ for (const e of edges) {
23033
+ const a = nodeById.get(e.from);
23034
+ const b = nodeById.get(e.to);
23035
+ if (!a || !b) continue;
23036
+ out.push({
23037
+ type: "line",
23038
+ x1: a.x,
23039
+ y1: a.y,
23040
+ x2: b.x,
23041
+ y2: b.y,
23042
+ color: e.color ?? "#9ca3af",
23043
+ lineWidth: 2
23044
+ });
23045
+ if (e.label) {
23046
+ out.push({
23047
+ type: "text",
23048
+ x: (a.x + b.x) / 2 + 4,
23049
+ y: (a.y + b.y) / 2 - 4,
23050
+ text: e.label,
23051
+ color: "#374151",
23052
+ fontSize: 11
23053
+ });
23054
+ }
23055
+ }
23056
+ for (const n of nodes) {
23057
+ out.push({
23058
+ type: "circle",
23059
+ x: n.x,
23060
+ y: n.y,
23061
+ radius: n.radius ?? 16,
23062
+ color: n.color ?? "#16a34a",
23063
+ fill: `${n.color ?? "#16a34a"}33`,
23064
+ id: n.id
23065
+ });
23066
+ if (n.label) {
23067
+ out.push({
23068
+ type: "text",
23069
+ x: n.x,
23070
+ y: n.y + (n.radius ?? 16) + 14,
23071
+ text: n.label,
23072
+ color: "#111827",
23073
+ fontSize: 12,
23074
+ align: "center"
23075
+ });
23076
+ }
23077
+ }
23078
+ out.push(...shapes);
23079
+ return out;
23080
+ }, [nodes, edges, shapes]);
23081
+ return /* @__PURE__ */ jsxRuntime.jsx(Card, { className, children: /* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "sm", children: [
23082
+ title ? /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "h4", children: title }) : null,
23083
+ /* @__PURE__ */ jsxRuntime.jsx(
23084
+ LearningCanvas,
23085
+ {
23086
+ width,
23087
+ height,
23088
+ backgroundColor,
23089
+ shapes: derivedShapes,
23090
+ interactive,
23091
+ animate,
23092
+ onShapeClick,
23093
+ isLoading,
23094
+ error
23095
+ }
23096
+ )
23097
+ ] }) });
23098
+ };
23099
+ }
23100
+ });
22692
23101
 
22693
- // node_modules/katex/dist/katex.min.css
23102
+ // node_modules/.pnpm/katex@0.16.47/node_modules/katex/dist/katex.min.css
22694
23103
  var init_katex_min = __esm({
22695
- "node_modules/katex/dist/katex.min.css"() {
23104
+ "node_modules/.pnpm/katex@0.16.47/node_modules/katex/dist/katex.min.css"() {
22696
23105
  }
22697
23106
  });
22698
23107
  var Tabs;
@@ -29061,6 +29470,122 @@ var init_ChatBar = __esm({
29061
29470
  ChatBar.displayName = "ChatBar";
29062
29471
  }
29063
29472
  });
29473
+ var ChemistryCanvas;
29474
+ var init_ChemistryCanvas = __esm({
29475
+ "components/learning/molecules/ChemistryCanvas.tsx"() {
29476
+ "use client";
29477
+ init_atoms();
29478
+ init_Stack();
29479
+ init_LearningCanvas();
29480
+ ChemistryCanvas = ({
29481
+ className,
29482
+ width = 600,
29483
+ height = 400,
29484
+ title,
29485
+ backgroundColor,
29486
+ atoms = [],
29487
+ bonds = [],
29488
+ arrows = [],
29489
+ shapes = [],
29490
+ interactive = false,
29491
+ animate = false,
29492
+ onShapeClick,
29493
+ isLoading,
29494
+ error
29495
+ }) => {
29496
+ const derivedShapes = React105.useMemo(() => {
29497
+ const out = [];
29498
+ const atomById = /* @__PURE__ */ new Map();
29499
+ for (const a of atoms) {
29500
+ if (a.id) atomById.set(a.id, a);
29501
+ }
29502
+ for (const b of bonds) {
29503
+ const a = atomById.get(b.from);
29504
+ const c = atomById.get(b.to);
29505
+ if (!a || !c) continue;
29506
+ const color = b.color ?? "#6b7280";
29507
+ const strokeWidth = b.type === "double" ? 4 : b.type === "triple" ? 6 : 2;
29508
+ out.push({
29509
+ type: "line",
29510
+ x1: a.x,
29511
+ y1: a.y,
29512
+ x2: c.x,
29513
+ y2: c.y,
29514
+ color,
29515
+ lineWidth: strokeWidth
29516
+ });
29517
+ }
29518
+ for (const a of arrows) {
29519
+ const angle = (a.angle ?? 0) * (Math.PI / 180);
29520
+ const len = a.length ?? 60;
29521
+ const x2 = a.x + Math.cos(angle) * len;
29522
+ const y2 = a.y + Math.sin(angle) * len;
29523
+ out.push({
29524
+ type: "arrow",
29525
+ x1: a.x,
29526
+ y1: a.y,
29527
+ x2,
29528
+ y2,
29529
+ color: a.color ?? "#dc2626",
29530
+ lineWidth: 2
29531
+ });
29532
+ if (a.label) {
29533
+ out.push({
29534
+ type: "text",
29535
+ x: (a.x + x2) / 2,
29536
+ y: (a.y + y2) / 2 - 10,
29537
+ text: a.label,
29538
+ color: "#111827",
29539
+ fontSize: 12,
29540
+ align: "center"
29541
+ });
29542
+ }
29543
+ }
29544
+ for (const a of atoms) {
29545
+ out.push({
29546
+ type: "circle",
29547
+ x: a.x,
29548
+ y: a.y,
29549
+ radius: a.radius ?? 14,
29550
+ color: a.color ?? "#2563eb",
29551
+ fill: a.color ?? "#2563eb",
29552
+ id: a.id
29553
+ });
29554
+ if (a.element) {
29555
+ out.push({
29556
+ type: "text",
29557
+ x: a.x,
29558
+ y: a.y,
29559
+ text: a.element,
29560
+ color: "#ffffff",
29561
+ fontSize: 12,
29562
+ align: "center"
29563
+ });
29564
+ }
29565
+ }
29566
+ out.push(...shapes);
29567
+ return out;
29568
+ }, [atoms, bonds, arrows, shapes]);
29569
+ return /* @__PURE__ */ jsxRuntime.jsx(Card, { className, children: /* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "sm", children: [
29570
+ title ? /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "h4", children: title }) : null,
29571
+ /* @__PURE__ */ jsxRuntime.jsx(
29572
+ LearningCanvas,
29573
+ {
29574
+ width,
29575
+ height,
29576
+ backgroundColor,
29577
+ shapes: derivedShapes,
29578
+ interactive,
29579
+ animate,
29580
+ onShapeClick,
29581
+ isLoading,
29582
+ error
29583
+ }
29584
+ )
29585
+ ] }) });
29586
+ };
29587
+ }
29588
+ });
29064
29589
  var CodeRunnerPanel;
29065
29590
  var init_CodeRunnerPanel = __esm({
29066
29591
  "components/core/organisms/CodeRunnerPanel.tsx"() {
@@ -34680,6 +35205,234 @@ var init_ProgressDots = __esm({
34680
35205
  ProgressDots.displayName = "ProgressDots";
34681
35206
  }
34682
35207
  });
35208
+ var MathCanvas;
35209
+ var init_MathCanvas = __esm({
35210
+ "components/learning/molecules/MathCanvas.tsx"() {
35211
+ "use client";
35212
+ init_atoms();
35213
+ init_Stack();
35214
+ init_LearningCanvas();
35215
+ MathCanvas = ({
35216
+ className,
35217
+ width = 600,
35218
+ height = 400,
35219
+ title,
35220
+ xMin = -10,
35221
+ xMax = 10,
35222
+ yMin = -10,
35223
+ yMax = 10,
35224
+ showAxes = true,
35225
+ showGrid = true,
35226
+ gridStep = 1,
35227
+ curves = [],
35228
+ points = [],
35229
+ vectors = [],
35230
+ shapes = [],
35231
+ interactive = false,
35232
+ animate = false,
35233
+ onShapeClick,
35234
+ isLoading,
35235
+ error
35236
+ }) => {
35237
+ const derivedShapes = React105.useMemo(() => {
35238
+ const out = [];
35239
+ const margin = 24;
35240
+ const plotW = width - margin * 2;
35241
+ const plotH = height - margin * 2;
35242
+ const mapX = (x) => margin + (x - xMin) / (xMax - xMin) * plotW;
35243
+ const mapY = (y) => height - (margin + (y - yMin) / (yMax - yMin) * plotH);
35244
+ if (showGrid) {
35245
+ for (let x = Math.ceil(xMin / gridStep) * gridStep; x <= xMax; x += gridStep) {
35246
+ const px = mapX(x);
35247
+ out.push({ type: "line", x1: px, y1: margin, x2: px, y2: height - margin, color: "#e5e7eb", lineWidth: 1 });
35248
+ }
35249
+ for (let y = Math.ceil(yMin / gridStep) * gridStep; y <= yMax; y += gridStep) {
35250
+ const py = mapY(y);
35251
+ out.push({ type: "line", x1: margin, y1: py, x2: width - margin, y2: py, color: "#e5e7eb", lineWidth: 1 });
35252
+ }
35253
+ }
35254
+ if (showAxes) {
35255
+ const xAxisY = Math.max(margin, Math.min(height - margin, mapY(0)));
35256
+ const yAxisX = Math.max(margin, Math.min(width - margin, mapX(0)));
35257
+ out.push({ type: "line", x1: margin, y1: xAxisY, x2: width - margin, y2: xAxisY, color: "#374151", lineWidth: 2 });
35258
+ out.push({ type: "line", x1: yAxisX, y1: margin, x2: yAxisX, y2: height - margin, color: "#374151", lineWidth: 2 });
35259
+ }
35260
+ for (const curve of curves) {
35261
+ if (!curve.samples || curve.samples.length < 2) continue;
35262
+ for (let i = 1; i < curve.samples.length; i++) {
35263
+ const a = curve.samples[i - 1];
35264
+ const b = curve.samples[i];
35265
+ if (a.x < xMin || a.x > xMax || b.x < xMin || b.x > xMax) continue;
35266
+ out.push({
35267
+ type: "line",
35268
+ x1: mapX(a.x),
35269
+ y1: mapY(a.y),
35270
+ x2: mapX(b.x),
35271
+ y2: mapY(b.y),
35272
+ color: curve.color ?? "#2563eb",
35273
+ lineWidth: 2
35274
+ });
35275
+ }
35276
+ }
35277
+ for (const p2 of points) {
35278
+ if (p2.x < xMin || p2.x > xMax || p2.y < yMin || p2.y > yMax) continue;
35279
+ out.push({
35280
+ type: "circle",
35281
+ x: mapX(p2.x),
35282
+ y: mapY(p2.y),
35283
+ radius: p2.radius ?? 4,
35284
+ color: p2.color ?? "#dc2626",
35285
+ fill: p2.color ?? "#dc2626"
35286
+ });
35287
+ if (p2.label) {
35288
+ out.push({ type: "text", x: mapX(p2.x) + 8, y: mapY(p2.y) - 8, text: p2.label, color: "#111827", fontSize: 12 });
35289
+ }
35290
+ }
35291
+ for (const v of vectors) {
35292
+ if (v.x < xMin || v.x > xMax || v.y < yMin || v.y > yMax) continue;
35293
+ const x1 = mapX(v.x);
35294
+ const y1 = mapY(v.y);
35295
+ const x2 = mapX(v.x + v.vx);
35296
+ const y2 = mapY(v.y + v.vy);
35297
+ out.push({ type: "arrow", x1, y1, x2, y2, color: v.color ?? "#7c3aed", lineWidth: 2 });
35298
+ if (v.label) {
35299
+ out.push({ type: "text", x: x2 + 6, y: y2 - 6, text: v.label, color: "#111827", fontSize: 12 });
35300
+ }
35301
+ }
35302
+ out.push(...shapes);
35303
+ return out;
35304
+ }, [width, height, xMin, xMax, yMin, yMax, showAxes, showGrid, gridStep, curves, points, vectors, shapes]);
35305
+ return /* @__PURE__ */ jsxRuntime.jsx(Card, { className, children: /* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "sm", children: [
35306
+ title ? /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "h4", children: title }) : null,
35307
+ /* @__PURE__ */ jsxRuntime.jsx(
35308
+ LearningCanvas,
35309
+ {
35310
+ width,
35311
+ height,
35312
+ shapes: derivedShapes,
35313
+ interactive,
35314
+ animate,
35315
+ onShapeClick,
35316
+ isLoading,
35317
+ error
35318
+ }
35319
+ )
35320
+ ] }) });
35321
+ };
35322
+ }
35323
+ });
35324
+ var PhysicsCanvas;
35325
+ var init_PhysicsCanvas = __esm({
35326
+ "components/learning/molecules/PhysicsCanvas.tsx"() {
35327
+ "use client";
35328
+ init_atoms();
35329
+ init_Stack();
35330
+ init_LearningCanvas();
35331
+ PhysicsCanvas = ({
35332
+ className,
35333
+ width = 600,
35334
+ height = 400,
35335
+ title,
35336
+ backgroundColor,
35337
+ bodies = [],
35338
+ constraints = [],
35339
+ showVelocity = true,
35340
+ showForces = false,
35341
+ velocityScale = 20,
35342
+ forceScale = 20,
35343
+ shapes = [],
35344
+ interactive = false,
35345
+ animate = false,
35346
+ onShapeClick,
35347
+ isLoading,
35348
+ error
35349
+ }) => {
35350
+ const derivedShapes = React105.useMemo(() => {
35351
+ const out = [];
35352
+ const bodyById = /* @__PURE__ */ new Map();
35353
+ for (const b of bodies) {
35354
+ if (b.id) bodyById.set(b.id, b);
35355
+ }
35356
+ for (const c of constraints) {
35357
+ const a = bodyById.get(c.from);
35358
+ const b = bodyById.get(c.to);
35359
+ if (!a || !b) continue;
35360
+ out.push({
35361
+ type: "line",
35362
+ x1: a.x,
35363
+ y1: a.y,
35364
+ x2: b.x,
35365
+ y2: b.y,
35366
+ color: c.color ?? "#9ca3af",
35367
+ lineWidth: 2
35368
+ });
35369
+ }
35370
+ for (const b of bodies) {
35371
+ out.push({
35372
+ type: "circle",
35373
+ x: b.x,
35374
+ y: b.y,
35375
+ radius: b.radius ?? 12,
35376
+ color: b.color ?? "#2563eb",
35377
+ fill: b.color ?? "#2563eb",
35378
+ id: b.id
35379
+ });
35380
+ if (b.label) {
35381
+ out.push({
35382
+ type: "text",
35383
+ x: b.x + (b.radius ?? 12) + 6,
35384
+ y: b.y - (b.radius ?? 12) - 6,
35385
+ text: b.label,
35386
+ color: "#111827",
35387
+ fontSize: 12
35388
+ });
35389
+ }
35390
+ if (showVelocity && b.vx != null && b.vy != null && (b.vx !== 0 || b.vy !== 0)) {
35391
+ out.push({
35392
+ type: "arrow",
35393
+ x1: b.x,
35394
+ y1: b.y,
35395
+ x2: b.x + b.vx * velocityScale,
35396
+ y2: b.y + b.vy * velocityScale,
35397
+ color: "#16a34a",
35398
+ lineWidth: 2
35399
+ });
35400
+ }
35401
+ if (showForces && b.fx != null && b.fy != null && (b.fx !== 0 || b.fy !== 0)) {
35402
+ out.push({
35403
+ type: "arrow",
35404
+ x1: b.x,
35405
+ y1: b.y,
35406
+ x2: b.x + b.fx * forceScale,
35407
+ y2: b.y + b.fy * forceScale,
35408
+ color: "#dc2626",
35409
+ lineWidth: 2
35410
+ });
35411
+ }
35412
+ }
35413
+ out.push(...shapes);
35414
+ return out;
35415
+ }, [bodies, constraints, showVelocity, showForces, velocityScale, forceScale, shapes]);
35416
+ return /* @__PURE__ */ jsxRuntime.jsx(Card, { className, children: /* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "sm", children: [
35417
+ title ? /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "h4", children: title }) : null,
35418
+ /* @__PURE__ */ jsxRuntime.jsx(
35419
+ LearningCanvas,
35420
+ {
35421
+ width,
35422
+ height,
35423
+ backgroundColor,
35424
+ shapes: derivedShapes,
35425
+ interactive,
35426
+ animate,
35427
+ onShapeClick,
35428
+ isLoading,
35429
+ error
35430
+ }
35431
+ )
35432
+ ] }) });
35433
+ };
35434
+ }
35435
+ });
34683
35436
  function resolveNodeColor(node, groups) {
34684
35437
  if (node.color) return node.color;
34685
35438
  if (node.group) {
@@ -35051,13 +35804,13 @@ var init_MapView = __esm({
35051
35804
  shadowSize: [41, 41]
35052
35805
  });
35053
35806
  L.Marker.prototype.options.icon = defaultIcon;
35054
- const { useEffect: useEffect74, useRef: useRef76, useCallback: useCallback112, useState: useState107 } = React105__namespace.default;
35807
+ const { useEffect: useEffect75, useRef: useRef77, useCallback: useCallback112, useState: useState107 } = React105__namespace.default;
35055
35808
  const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
35056
35809
  const { useEventBus: useEventBus2 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
35057
35810
  function MapUpdater({ centerLat, centerLng, zoom }) {
35058
35811
  const map = useMap();
35059
- const prevRef = useRef76({ centerLat, centerLng, zoom });
35060
- useEffect74(() => {
35812
+ const prevRef = useRef77({ centerLat, centerLng, zoom });
35813
+ useEffect75(() => {
35061
35814
  const prev = prevRef.current;
35062
35815
  if (prev.centerLat !== centerLat || prev.centerLng !== centerLng || prev.zoom !== zoom) {
35063
35816
  map.setView([centerLat, centerLng], zoom);
@@ -35068,7 +35821,7 @@ var init_MapView = __esm({
35068
35821
  }
35069
35822
  function MapClickHandler({ onMapClick }) {
35070
35823
  const map = useMap();
35071
- useEffect74(() => {
35824
+ useEffect75(() => {
35072
35825
  if (!onMapClick) return;
35073
35826
  const handler = (e) => {
35074
35827
  onMapClick(e.latlng.lat, e.latlng.lng);
@@ -43371,7 +44124,7 @@ function getGroupColor(group, groups) {
43371
44124
  const idx = groups.indexOf(group);
43372
44125
  return GROUP_COLORS2[idx % GROUP_COLORS2.length];
43373
44126
  }
43374
- function resolveColor2(color, el) {
44127
+ function resolveColor3(color, el) {
43375
44128
  const m = /^var\((--[^,)]+)(?:,\s*([^)]+))?\)$/.exec(color.trim());
43376
44129
  if (!m) return color;
43377
44130
  const resolved = getComputedStyle(el).getPropertyValue(m[1]).trim();
@@ -43632,7 +44385,7 @@ var init_GraphCanvas = __esm({
43632
44385
  const w = logicalW;
43633
44386
  const h = height;
43634
44387
  const nodes = nodesRef.current;
43635
- const accentColor = resolveColor2("var(--color-accent)", canvas);
44388
+ const accentColor = resolveColor3("var(--color-accent)", canvas);
43636
44389
  const dpr = typeof window !== "undefined" && window.devicePixelRatio || 1;
43637
44390
  ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
43638
44391
  ctx.clearRect(0, 0, w, h);
@@ -43671,7 +44424,7 @@ var init_GraphCanvas = __esm({
43671
44424
  ctx.globalAlpha = 1;
43672
44425
  for (const node of nodes) {
43673
44426
  const size = node.size || 8;
43674
- const color = resolveColor2(node.color || getGroupColor(node.group, groups), canvas);
44427
+ const color = resolveColor3(node.color || getGroupColor(node.group, groups), canvas);
43675
44428
  const isHovered = hoveredNode === node.id;
43676
44429
  const isSelected = selectedNodeId !== void 0 && node.id === selectedNodeId;
43677
44430
  ctx.globalAlpha = hoveredNode && !neighbors.has(node.id) ? 0.2 : 1;
@@ -50569,6 +51322,7 @@ var init_component_registry_generated = __esm({
50569
51322
  init_BattleBoard();
50570
51323
  init_BattleTemplate();
50571
51324
  init_BehaviorView();
51325
+ init_BiologyCanvas();
50572
51326
  init_BloomQuizBlock();
50573
51327
  init_BoardgameBoard();
50574
51328
  init_BookChapterView();
@@ -50598,6 +51352,7 @@ var init_component_registry_generated = __esm({
50598
51352
  init_ChartLegend();
50599
51353
  init_ChatBar();
50600
51354
  init_Checkbox();
51355
+ init_ChemistryCanvas();
50601
51356
  init_ChoiceButton();
50602
51357
  init_CityBuilderBoard();
50603
51358
  init_CityBuilderTemplate();
@@ -50689,6 +51444,7 @@ var init_component_registry_generated = __esm({
50689
51444
  init_JazariStateMachine();
50690
51445
  init_LandingPageTemplate();
50691
51446
  init_LawReferenceTooltip();
51447
+ init_LearningCanvas();
50692
51448
  init_Lightbox();
50693
51449
  init_LikertScale();
50694
51450
  init_LineChart();
@@ -50697,9 +51453,11 @@ var init_component_registry_generated = __esm({
50697
51453
  init_MapView();
50698
51454
  init_MarkdownContent();
50699
51455
  init_MarketingFooter();
51456
+ init_MarketingStatCard();
50700
51457
  init_MasterDetail();
50701
51458
  init_MasterDetailLayout();
50702
51459
  init_MatchPuzzleBoard();
51460
+ init_MathCanvas();
50703
51461
  init_MatrixQuestion();
50704
51462
  init_MediaGallery();
50705
51463
  init_Menu();
@@ -50718,6 +51476,7 @@ var init_component_registry_generated = __esm({
50718
51476
  init_PageHeader();
50719
51477
  init_Pagination();
50720
51478
  init_PatternTile();
51479
+ init_PhysicsCanvas();
50721
51480
  init_PinballBoard();
50722
51481
  init_PirateBoard();
50723
51482
  init_PlatformerBoard();
@@ -50894,6 +51653,7 @@ var init_component_registry_generated = __esm({
50894
51653
  "BattleBoard": BattleBoard,
50895
51654
  "BattleTemplate": BattleTemplate,
50896
51655
  "BehaviorView": BehaviorView,
51656
+ "BiologyCanvas": BiologyCanvas,
50897
51657
  "BloomQuizBlock": BloomQuizBlock,
50898
51658
  "BoardgameBoard": BoardgameBoard,
50899
51659
  "BookChapterView": BookChapterView,
@@ -50926,6 +51686,7 @@ var init_component_registry_generated = __esm({
50926
51686
  "ChartLegend": ChartLegend,
50927
51687
  "ChatBar": ChatBar,
50928
51688
  "Checkbox": Checkbox,
51689
+ "ChemistryCanvas": ChemistryCanvas,
50929
51690
  "ChoiceButton": ChoiceButton,
50930
51691
  "CityBuilderBoard": CityBuilderBoard,
50931
51692
  "CityBuilderTemplate": CityBuilderTemplate,
@@ -51027,6 +51788,7 @@ var init_component_registry_generated = __esm({
51027
51788
  "LabelPattern": LabelPattern,
51028
51789
  "LandingPageTemplate": LandingPageTemplate,
51029
51790
  "LawReferenceTooltip": LawReferenceTooltip,
51791
+ "LearningCanvas": LearningCanvas,
51030
51792
  "Lightbox": Lightbox,
51031
51793
  "LikertScale": LikertScale,
51032
51794
  "LineChart": LineChart2,
@@ -51035,9 +51797,11 @@ var init_component_registry_generated = __esm({
51035
51797
  "MapView": MapView,
51036
51798
  "MarkdownContent": MarkdownContent,
51037
51799
  "MarketingFooter": MarketingFooter,
51800
+ "MarketingStatCard": MarketingStatCard,
51038
51801
  "MasterDetail": MasterDetail,
51039
51802
  "MasterDetailLayout": MasterDetailLayout,
51040
51803
  "MatchPuzzleBoard": MatchPuzzleBoard,
51804
+ "MathCanvas": MathCanvas,
51041
51805
  "MatrixQuestion": MatrixQuestion,
51042
51806
  "MediaGallery": MediaGallery,
51043
51807
  "Menu": Menu,
@@ -51056,6 +51820,7 @@ var init_component_registry_generated = __esm({
51056
51820
  "PageHeader": PageHeader,
51057
51821
  "Pagination": Pagination,
51058
51822
  "PatternTile": PatternTile,
51823
+ "PhysicsCanvas": PhysicsCanvas,
51059
51824
  "PinballBoard": PinballBoard,
51060
51825
  "PirateBoard": PirateBoard,
51061
51826
  "PlatformerBoard": PlatformerBoard,