@almadar/shell-web 1.0.0 → 1.2.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 (109) hide show
  1. package/LICENSE +72 -0
  2. package/dist/AvlGlyph-KZMJDBEB.js +5 -0
  3. package/dist/AvlStateMachine-KVZMFHFU.js +8 -0
  4. package/dist/AvlTransitionDetail-7DVGV27I.js +10 -0
  5. package/dist/AvlTransitionExplainer-RMJ5LQLK.js +11 -0
  6. package/dist/BehaviorView-EYRPME67.js +10 -0
  7. package/dist/{FileTree-BCFnBEuQ.d.ts → FileTree-B3GDAjaQ.d.ts} +131 -4
  8. package/dist/FlowCanvas-J54627TC.js +23 -0
  9. package/dist/{FlowCanvas-3JRMNJLV.css → FlowCanvas-R4LL3KRI.css} +190 -192
  10. package/dist/{GameAudioProvider-ceM_n0ey.d.ts → GameAudioProvider-BgWOOYT3.d.ts} +15 -20
  11. package/dist/{KernelEngineContext-CcxGYtlr.d.ts → KernelEngineContext-BPx-q0iw.d.ts} +15 -2
  12. package/dist/{LayersPanel-M2LHWUFF.js → LayersPanel-PSXI4EHG.js} +4 -4
  13. package/dist/ModuleCard-TNRLL45H.js +6 -0
  14. package/dist/{OrbInspector-MHLJ6OEE.css → OrbInspector-2EGVZLOJ.css} +190 -192
  15. package/dist/OrbInspector-UBEQWWZ2.js +23 -0
  16. package/dist/{parseLessonSegments-GpCeMrb2.d.ts → SegmentRenderer-BAQ6Jwf6.d.ts} +4 -20
  17. package/dist/{Select-B-iDdnvE.d.ts → Select-BJ8Fgc8A.d.ts} +1 -1
  18. package/dist/{UISlotContext-Dl_ewwCI.d.ts → UISlotContext-7r0SQdTL.d.ts} +1 -1
  19. package/dist/UISlotRenderer-5OURMAP2.js +23 -0
  20. package/dist/{UISlotRenderer-KVFO6J7R.css → UISlotRenderer-SJBSQGBQ.css} +190 -192
  21. package/dist/auth/react/index.js +7 -6
  22. package/dist/avl/index.css +190 -192
  23. package/dist/avl/index.d.ts +19 -7
  24. package/dist/avl/index.js +170 -39
  25. package/dist/{chunk-AE7VCQB6.js → chunk-2LNXLMK3.js} +2 -2
  26. package/dist/{chunk-REXYVBUO.js → chunk-3DA36FOA.js} +1 -1
  27. package/dist/{chunk-UXLE3IPR.js → chunk-3UQNFRYV.js} +207 -9
  28. package/dist/{chunk-AGXD77SL.js → chunk-3YUMGEEW.js} +1 -1
  29. package/dist/{chunk-K4MOPSEL.js → chunk-6RXP5ZXE.js} +7 -8
  30. package/dist/{chunk-E6KA4J6N.js → chunk-7UCL26QB.js} +4 -5
  31. package/dist/{chunk-57DC34LY.js → chunk-AL2XXMYR.js} +2 -2
  32. package/dist/{chunk-YHMRX6YA.js → chunk-ANTJUQRD.js} +53 -13
  33. package/dist/{chunk-P4ZFUQFF.js → chunk-AZ74UPG6.js} +4 -1
  34. package/dist/{chunk-ROICKAU7.js → chunk-B23EZH2P.js} +3 -3
  35. package/dist/{chunk-CPLN6NBQ.js → chunk-CCO2ZH7F.js} +3 -4
  36. package/dist/{chunk-4YXBKHHM.js → chunk-D5FJU4XC.js} +87 -16
  37. package/dist/{chunk-HH5KSMH5.js → chunk-DPDKBY6Z.js} +1 -1
  38. package/dist/{chunk-A2LR6VQQ.js → chunk-ECC3WQIB.js} +9 -93
  39. package/dist/{chunk-VO2TTLS5.js → chunk-GHAF7QUD.js} +1 -1
  40. package/dist/{chunk-TXAUOLWZ.js → chunk-HA2BYO5E.js} +1 -1
  41. package/dist/{chunk-ILQXJ2AR.js → chunk-JEN4EIUF.js} +1 -1
  42. package/dist/{chunk-UTDC2NEA.js → chunk-KTYOYEVA.js} +1 -1
  43. package/dist/{chunk-X3DMMX27.js → chunk-LINJRTNB.js} +2 -2
  44. package/dist/{chunk-TUPZWTRE.js → chunk-LKL5RULQ.js} +467 -141
  45. package/dist/{chunk-UU57VNS2.js → chunk-PWXZN5G5.js} +2 -2
  46. package/dist/{chunk-SP5CDJ6K.js → chunk-RDPELAFQ.js} +4 -4
  47. package/dist/{chunk-PRXQGGCO.js → chunk-S3LS3B7N.js} +1 -1
  48. package/dist/{chunk-LHP2TK7O.js → chunk-TAEOMNDK.js} +3611 -4737
  49. package/dist/{chunk-3S54FWRC.js → chunk-UFQLHCFJ.js} +1 -1
  50. package/dist/{chunk-AB3X7QTE.js → chunk-V5SVGUYN.js} +2 -3
  51. package/dist/{chunk-3VZ36ZKO.js → chunk-ZDRDJKYB.js} +5 -2
  52. package/dist/components/index.css +190 -192
  53. package/dist/components/index.d.ts +568 -190
  54. package/dist/components/index.js +27 -30
  55. package/dist/context/index.d.ts +2 -2
  56. package/dist/context/index.js +5 -5
  57. package/dist/core.d.ts +21 -4
  58. package/dist/core.js +1 -1
  59. package/dist/{fx-CmQjnHmT.d.ts → fx-Bx5RqplG.d.ts} +10 -7
  60. package/dist/hooks/index.d.ts +8 -8
  61. package/dist/hooks/index.js +6 -6
  62. package/dist/index.d.ts +4 -0
  63. package/dist/index.js +2 -2
  64. package/dist/{katexPlugin-FA7NX4PE.css → katexPlugin-BUHVNRBJ.css} +1 -1
  65. package/dist/{kernel-client-TZKGHJRY.js → kernel-client-NMZ56JVU.js} +60 -6
  66. package/dist/{kernel-wire-wNdAPfhJ.d.ts → kernel-wire-CRsHtLsf.d.ts} +8 -1
  67. package/dist/lib/index.d.ts +3 -4
  68. package/dist/lib/index.js +435 -4
  69. package/dist/providers/index.css +190 -192
  70. package/dist/providers/index.d.ts +6 -8
  71. package/dist/providers/index.js +21 -25
  72. package/dist/renderer/index.d.ts +3 -79
  73. package/dist/renderer/index.js +2 -2
  74. package/dist/runtime/index.css +190 -192
  75. package/dist/runtime/index.d.ts +9 -2
  76. package/dist/runtime/index.js +20 -23
  77. package/dist/ssr/index.cjs +105 -28
  78. package/dist/ssr/index.js +106 -29
  79. package/dist/test-support.js +2 -2
  80. package/dist/{useUISlots-CiobNFGb.d.ts → useUISlots-BLcGd__D.d.ts} +2 -0
  81. package/dist/{paintDispatch-CuJLsr9Y.d.ts → verificationRegistry-BLuQU1JV.d.ts} +127 -15
  82. package/package.json +10 -38
  83. package/src/core/locales/ar.json +10 -1
  84. package/src/core/locales/en.json +10 -1
  85. package/src/core/locales/sl.json +10 -1
  86. package/tailwind-preset.cjs +8 -4
  87. package/dist/AvlGlyph-EPJKFEO3.js +0 -6
  88. package/dist/AvlStateMachine-RKZIKNGC.js +0 -9
  89. package/dist/AvlTransitionDetail-63SD6GZF.js +0 -11
  90. package/dist/AvlTransitionExplainer-ZBTLOM3T.js +0 -12
  91. package/dist/BehaviorView-YS5G4GNB.js +0 -11
  92. package/dist/Canvas3DHost-BkZQB5l2.d.ts +0 -552
  93. package/dist/FlowCanvas-AUMTWMNG.js +0 -26
  94. package/dist/ModuleCard-QHDGK5XK.js +0 -7
  95. package/dist/OrbInspector-QCPEPUPH.js +0 -26
  96. package/dist/UISlotRenderer-C7WWOK43.js +0 -26
  97. package/dist/avl-3d-context-BycmO6tG.d.ts +0 -201
  98. package/dist/avl-schema-parser-CtJxJ9KU.d.ts +0 -132
  99. package/dist/avl-zoom-state-CKMVuBFg.d.ts +0 -17
  100. package/dist/chunk-4T3P43NS.js +0 -1133
  101. package/dist/chunk-DZBQA2OW.js +0 -176
  102. package/dist/chunk-EOWMARUB.js +0 -16
  103. package/dist/chunk-GFXCPUMX.js +0 -1334
  104. package/dist/chunk-ILZ7ORX7.js +0 -432
  105. package/dist/three/index.css +0 -503
  106. package/dist/three/index.d.ts +0 -1185
  107. package/dist/three/index.js +0 -3908
  108. package/dist/verificationRegistry-CVrcxG1s.d.ts +0 -122
  109. /package/dist/{katexPlugin-NCDKOOQY.js → katexPlugin-WGJ4JFZU.js} +0 -0
@@ -1,6 +1,6 @@
1
1
  import { resolveThemeForRuntime, themeTokensToCssVars } from './chunk-3BBUBJFF.js';
2
- import { useUISlotManager } from './chunk-YHMRX6YA.js';
3
- import { useThemeScope, useTheme, keyInViewerMode, ThemeScopeContext, Box, cn } from './chunk-4YXBKHHM.js';
2
+ import { useUISlotManager } from './chunk-ANTJUQRD.js';
3
+ import { useThemeScope, useTheme, keyInViewerMode, ThemeScopeContext, Box, cn } from './chunk-D5FJU4XC.js';
4
4
  import { createContext, useMemo, useContext, useCallback, useEffect } from 'react';
5
5
  import { jsx, Fragment } from 'react/jsx-runtime';
6
6
  import { ANONYMOUS_USER, isThemeRegistryKey, toPayloadValue } from '@almadar/core';
@@ -1,5 +1,5 @@
1
1
  import { traitLevelFromDescription } from './chunk-PCR37T3U.js';
2
- import { useContentSurface, useEventBus, Typography, Icon, cn, domPassthrough } from './chunk-4YXBKHHM.js';
2
+ import { useContentSurface, useEventBus, Typography, Icon, cn, domPassthrough } from './chunk-D5FJU4XC.js';
3
3
  import { useState } from 'react';
4
4
  import { jsx, jsxs } from 'react/jsx-runtime';
5
5
 
@@ -1,4 +1,5 @@
1
1
  import { createLogger } from '@almadar/logger';
2
+ import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
2
3
 
3
4
  var log = createLogger("almadar:ui:theme-color");
4
5
  var THEME_SERIES = [
@@ -198,6 +199,7 @@ var EFFECT_OPERATOR_CATEGORY = {
198
199
  "program/os-grants": "system",
199
200
  "program/compose": "system",
200
201
  "program/step": "system",
202
+ "program/navigate": "system",
201
203
  "program/resolve-rows": "system",
202
204
  "program/self": "system",
203
205
  "program/tick": "system",
@@ -234,7 +236,18 @@ var EFFECT_OPERATOR_CATEGORY = {
234
236
  "mem/atomic-cas": "system",
235
237
  "kernel/queue-front": "communication",
236
238
  "kernel/queue-back": "communication",
237
- "ffi/call": "system"
239
+ "ffi/call": "system",
240
+ "gpu/device-open": "system",
241
+ "gpu/device-close": "system",
242
+ "gpu/buffer-create": "system",
243
+ "gpu/texture-create": "system",
244
+ "gpu/sampler-create": "system",
245
+ "gpu/query-create": "system",
246
+ "gpu/shader-create": "system",
247
+ "gpu/pipeline-create": "system",
248
+ "gpu/bind-group-create": "system",
249
+ "gpu/submit": "system",
250
+ "gpu/release": "system"
238
251
  };
239
252
  var EFFECT_FAMILY_CATEGORY = {
240
253
  agent: "system",
@@ -294,6 +307,7 @@ var EFFECT_OPERATOR_ZONE = {
294
307
  "program/os-grants": "system",
295
308
  "program/compose": "system",
296
309
  "program/step": "system",
310
+ "program/navigate": "system",
297
311
  "program/resolve-rows": "system",
298
312
  "program/self": "system",
299
313
  "program/tick": "system",
@@ -330,7 +344,18 @@ var EFFECT_OPERATOR_ZONE = {
330
344
  "mem/atomic-cas": "system",
331
345
  "kernel/queue-front": "bus",
332
346
  "kernel/queue-back": "bus",
333
- "ffi/call": "system"
347
+ "ffi/call": "system",
348
+ "gpu/device-open": "system",
349
+ "gpu/device-close": "system",
350
+ "gpu/buffer-create": "system",
351
+ "gpu/texture-create": "system",
352
+ "gpu/sampler-create": "system",
353
+ "gpu/query-create": "system",
354
+ "gpu/shader-create": "system",
355
+ "gpu/pipeline-create": "system",
356
+ "gpu/bind-group-create": "system",
357
+ "gpu/submit": "system",
358
+ "gpu/release": "system"
334
359
  };
335
360
  var EFFECT_FAMILY_ZONE = {
336
361
  agent: "system",
@@ -365,12 +390,9 @@ function effectCategoryOf(head) {
365
390
  function asEffectOperator(head) {
366
391
  return isEffectOperator(head) ? head : null;
367
392
  }
368
- var PENDING_STD_CATEGORY_COLORS = {
369
- "std-behavior-value": avlBlend("var(--color-accent)", 40, "var(--color-success)"),
370
- "std-program": avlBlend("var(--color-accent)", 60, "var(--color-info)")
371
- };
372
393
  var OPERATOR_CATEGORY_COLORS = {
373
- ...PENDING_STD_CATEGORY_COLORS,
394
+ "std-behavior-value": avlBlend("var(--color-accent)", 40, "var(--color-success)"),
395
+ "std-program": avlBlend("var(--color-accent)", 60, "var(--color-info)"),
374
396
  "arithmetic": "var(--color-primary)",
375
397
  "comparison": "var(--color-warning)",
376
398
  "logic": "var(--color-accent)",
@@ -406,7 +428,13 @@ var OPERATOR_CATEGORY_COLORS = {
406
428
  "std-audio": avlBlend("var(--color-accent)", 50, "var(--color-warning)"),
407
429
  "std-auth": avlBlend("var(--color-warning)", 60, "var(--color-primary)"),
408
430
  "std-trace": "var(--color-muted-foreground)",
409
- "std-behavior": avlBlend("var(--color-accent)", 60, "var(--color-success)")
431
+ "std-behavior": avlBlend("var(--color-accent)", 60, "var(--color-success)"),
432
+ "std-mem": avlBlend("var(--color-muted-foreground)", 70, "var(--color-error)"),
433
+ "std-mem-read": avlBlend("var(--color-muted-foreground)", 70, "var(--color-info)"),
434
+ "std-kernel": avlBlend("var(--color-muted-foreground)", 70, "var(--color-accent)"),
435
+ "std-kernel-read": avlBlend("var(--color-muted-foreground)", 70, "var(--color-success)"),
436
+ "std-ffi": avlBlend("var(--color-muted-foreground)", 70, "var(--color-warning)"),
437
+ "std-gpu": avlBlend("var(--color-muted-foreground)", 60, "var(--color-accent)")
410
438
  };
411
439
  function effectZoneOf(head) {
412
440
  if (isEffectOperator(head)) return EFFECT_OPERATOR_ZONE[head];
@@ -417,5 +445,175 @@ function effectZoneOf(head) {
417
445
  }
418
446
  return null;
419
447
  }
448
+ var log2 = createLogger("almadar:ui:avl:effect");
449
+ function headIcon(type, x, y, s, color) {
450
+ switch (type) {
451
+ case "render-ui":
452
+ return /* @__PURE__ */ jsxs("g", { children: [
453
+ /* @__PURE__ */ jsx("rect", { x: x - s, y: y - s, width: s * 2, height: s * 2, fill: "none", stroke: color, strokeWidth: 1.5, rx: 1 }),
454
+ /* @__PURE__ */ jsx("line", { x1: x, y1: y - s, x2: x, y2: y + s, stroke: color, strokeWidth: 1 }),
455
+ /* @__PURE__ */ jsx("line", { x1: x - s, y1: y, x2: x + s, y2: y, stroke: color, strokeWidth: 1 })
456
+ ] });
457
+ case "set":
458
+ return /* @__PURE__ */ jsx(
459
+ "path",
460
+ {
461
+ d: `M${x - s * 0.6},${y + s} L${x - s},${y + s * 0.4} L${x + s * 0.4},${y - s} L${x + s},${y - s * 0.4} Z`,
462
+ fill: "none",
463
+ stroke: color,
464
+ strokeWidth: 1.5,
465
+ strokeLinejoin: "round"
466
+ }
467
+ );
468
+ case "persist":
469
+ return /* @__PURE__ */ jsxs("g", { children: [
470
+ /* @__PURE__ */ jsx("ellipse", { cx: x, cy: y - s * 0.6, rx: s, ry: s * 0.4, fill: "none", stroke: color, strokeWidth: 1.5 }),
471
+ /* @__PURE__ */ jsx("line", { x1: x - s, y1: y - s * 0.6, x2: x - s, y2: y + s * 0.4, stroke: color, strokeWidth: 1.5 }),
472
+ /* @__PURE__ */ jsx("line", { x1: x + s, y1: y - s * 0.6, x2: x + s, y2: y + s * 0.4, stroke: color, strokeWidth: 1.5 }),
473
+ /* @__PURE__ */ jsx("ellipse", { cx: x, cy: y + s * 0.4, rx: s, ry: s * 0.4, fill: "none", stroke: color, strokeWidth: 1.5 })
474
+ ] });
475
+ case "fetch":
476
+ return /* @__PURE__ */ jsxs("g", { children: [
477
+ /* @__PURE__ */ jsx("line", { x1: x, y1: y - s, x2: x, y2: y + s * 0.6, stroke: color, strokeWidth: 1.5 }),
478
+ /* @__PURE__ */ jsx("polyline", { points: `${x - s * 0.5},${y + s * 0.1} ${x},${y + s} ${x + s * 0.5},${y + s * 0.1}`, fill: "none", stroke: color, strokeWidth: 1.5, strokeLinejoin: "round" })
479
+ ] });
480
+ case "emit":
481
+ return /* @__PURE__ */ jsxs("g", { children: [
482
+ /* @__PURE__ */ jsx("circle", { cx: x, cy: y, r: s * 0.3, fill: color }),
483
+ /* @__PURE__ */ jsx("path", { d: `M${x - s * 0.7},${y - s * 0.7} A${s},${s} 0 0,1 ${x + s * 0.7},${y - s * 0.7}`, fill: "none", stroke: color, strokeWidth: 1.5 }),
484
+ /* @__PURE__ */ jsx("path", { d: `M${x - s},${y - s} A${s * 1.4},${s * 1.4} 0 0,1 ${x + s},${y - s}`, fill: "none", stroke: color, strokeWidth: 1, opacity: 0.6 })
485
+ ] });
486
+ case "navigate":
487
+ return /* @__PURE__ */ jsxs("g", { children: [
488
+ /* @__PURE__ */ jsx("line", { x1: x - s, y1: y, x2: x + s * 0.6, y2: y, stroke: color, strokeWidth: 1.5 }),
489
+ /* @__PURE__ */ jsx("polyline", { points: `${x + s * 0.1},${y - s * 0.5} ${x + s},${y} ${x + s * 0.1},${y + s * 0.5}`, fill: "none", stroke: color, strokeWidth: 1.5, strokeLinejoin: "round" })
490
+ ] });
491
+ case "call-service":
492
+ return /* @__PURE__ */ jsxs("g", { children: [
493
+ /* @__PURE__ */ jsx("line", { x1: x - s, y1: y - s * 0.3, x2: x + s, y2: y - s * 0.3, stroke: color, strokeWidth: 1.5 }),
494
+ /* @__PURE__ */ jsx("polyline", { points: `${x + s * 0.5},${y - s * 0.7} ${x + s},${y - s * 0.3} ${x + s * 0.5},${y + s * 0.1}`, fill: "none", stroke: color, strokeWidth: 1.5, strokeLinejoin: "round" }),
495
+ /* @__PURE__ */ jsx("line", { x1: x + s, y1: y + s * 0.3, x2: x - s, y2: y + s * 0.3, stroke: color, strokeWidth: 1.5 }),
496
+ /* @__PURE__ */ jsx("polyline", { points: `${x - s * 0.5},${y - s * 0.1} ${x - s},${y + s * 0.3} ${x - s * 0.5},${y + s * 0.7}`, fill: "none", stroke: color, strokeWidth: 1.5, strokeLinejoin: "round" })
497
+ ] });
498
+ case "spawn":
499
+ return /* @__PURE__ */ jsxs("g", { children: [
500
+ /* @__PURE__ */ jsx("circle", { cx: x, cy: y, r: s, fill: "none", stroke: color, strokeWidth: 1.5 }),
501
+ /* @__PURE__ */ jsx("line", { x1: x - s * 0.5, y1: y, x2: x + s * 0.5, y2: y, stroke: color, strokeWidth: 1.5 }),
502
+ /* @__PURE__ */ jsx("line", { x1: x, y1: y - s * 0.5, x2: x, y2: y + s * 0.5, stroke: color, strokeWidth: 1.5 })
503
+ ] });
504
+ case "despawn":
505
+ return /* @__PURE__ */ jsxs("g", { children: [
506
+ /* @__PURE__ */ jsx("circle", { cx: x, cy: y, r: s, fill: "none", stroke: color, strokeWidth: 1.5 }),
507
+ /* @__PURE__ */ jsx("line", { x1: x - s * 0.5, y1: y, x2: x + s * 0.5, y2: y, stroke: color, strokeWidth: 1.5 })
508
+ ] });
509
+ case "do":
510
+ return /* @__PURE__ */ jsxs("g", { children: [
511
+ /* @__PURE__ */ jsx("circle", { cx: x, cy: y, r: s, fill: "none", stroke: color, strokeWidth: 1.5 }),
512
+ /* @__PURE__ */ jsx("polygon", { points: `${x - s * 0.3},${y - s * 0.5} ${x + s * 0.5},${y} ${x - s * 0.3},${y + s * 0.5}`, fill: color })
513
+ ] });
514
+ case "if":
515
+ return /* @__PURE__ */ jsx(
516
+ "polygon",
517
+ {
518
+ points: `${x},${y - s} ${x + s * 0.7},${y} ${x},${y + s} ${x - s * 0.7},${y}`,
519
+ fill: "none",
520
+ stroke: color,
521
+ strokeWidth: 1.5,
522
+ strokeLinejoin: "round"
523
+ }
524
+ );
525
+ case "log":
526
+ return /* @__PURE__ */ jsx(
527
+ "text",
528
+ {
529
+ x,
530
+ y,
531
+ textAnchor: "middle",
532
+ dominantBaseline: "central",
533
+ fill: color,
534
+ fontSize: s * 2.2,
535
+ fontFamily: "serif",
536
+ children: "\xB6"
537
+ }
538
+ );
539
+ default:
540
+ return null;
541
+ }
542
+ }
543
+ var clock = (x, y, s, color) => /* @__PURE__ */ jsxs("g", { children: [
544
+ /* @__PURE__ */ jsx("circle", { cx: x, cy: y, r: s, fill: "none", stroke: color, strokeWidth: 1.5 }),
545
+ /* @__PURE__ */ jsx("polyline", { points: `${x},${y - s * 0.6} ${x},${y} ${x + s * 0.5},${y + s * 0.3}`, fill: "none", stroke: color, strokeWidth: 1.5, strokeLinejoin: "round" })
546
+ ] });
547
+ var neuron = (x, y, s, color) => /* @__PURE__ */ jsxs("g", { children: [
548
+ /* @__PURE__ */ jsx("line", { x1: x - s, y1: y - s * 0.6, x2: x + s * 0.8, y2: y, stroke: color, strokeWidth: 1 }),
549
+ /* @__PURE__ */ jsx("line", { x1: x - s, y1: y + s * 0.6, x2: x + s * 0.8, y2: y, stroke: color, strokeWidth: 1 }),
550
+ /* @__PURE__ */ jsx("circle", { cx: x - s, cy: y - s * 0.6, r: s * 0.3, fill: color }),
551
+ /* @__PURE__ */ jsx("circle", { cx: x - s, cy: y + s * 0.6, r: s * 0.3, fill: color }),
552
+ /* @__PURE__ */ jsx("circle", { cx: x + s * 0.8, cy: y, r: s * 0.35, fill: color })
553
+ ] });
554
+ var gear = (x, y, s, color) => /* @__PURE__ */ jsxs("g", { children: [
555
+ /* @__PURE__ */ jsx("circle", { cx: x, cy: y, r: s * 0.75, fill: "none", stroke: color, strokeWidth: 1.5, strokeDasharray: `${s * 0.5} ${s * 0.3}` }),
556
+ /* @__PURE__ */ jsx("circle", { cx: x, cy: y, r: s * 0.3, fill: color })
557
+ ] });
558
+ var unknown = (x, y, s, color) => /* @__PURE__ */ jsxs("g", { children: [
559
+ /* @__PURE__ */ jsx("circle", { cx: x, cy: y, r: s, fill: "none", stroke: color, strokeWidth: 1.2, strokeDasharray: "2 2" }),
560
+ /* @__PURE__ */ jsx("text", { x, y, textAnchor: "middle", dominantBaseline: "central", fill: color, fontSize: s * 1.4, children: "?" })
561
+ ] });
562
+ var CATEGORY_GLYPH = {
563
+ ui: (x, y, s, c) => headIcon("render-ui", x, y, s, c),
564
+ data: (x, y, s, c) => headIcon("set", x, y, s, c),
565
+ communication: (x, y, s, c) => headIcon("emit", x, y, s, c),
566
+ lifecycle: (x, y, s, c) => headIcon("spawn", x, y, s, c),
567
+ control: (x, y, s, c) => headIcon("if", x, y, s, c),
568
+ async: clock,
569
+ compute: neuron,
570
+ system: gear
571
+ };
572
+ function effectIcon(type, x, y, s, color) {
573
+ const op = asEffectOperator(type);
574
+ const own = op ? headIcon(op, x, y, s, color) : null;
575
+ if (own) return own;
576
+ const category = effectCategoryOf(type);
577
+ if (category) return CATEGORY_GLYPH[category](x, y, s, color);
578
+ log2.error("unknown-effect-operator", { effectType: type });
579
+ return unknown(x, y, s, color);
580
+ }
581
+ var AvlEffect = ({
582
+ x = 0,
583
+ y = 0,
584
+ effectType,
585
+ size = 8,
586
+ label,
587
+ color = "var(--color-primary)",
588
+ opacity = 1,
589
+ className,
590
+ showBackground = false
591
+ }) => {
592
+ const category = effectCategoryOf(effectType);
593
+ const catColors = category ? EFFECT_CATEGORY_COLORS[category] : null;
594
+ const iconColor = showBackground && catColors ? catColors.color : color;
595
+ return /* @__PURE__ */ jsxs("g", { className, opacity, children: [
596
+ showBackground && catColors && /* @__PURE__ */ jsxs(Fragment, { children: [
597
+ /* @__PURE__ */ jsx("circle", { cx: x, cy: y, r: size * 1.2, fill: catColors.bg }),
598
+ /* @__PURE__ */ jsx("circle", { cx: x, cy: y, r: size * 1.2, fill: "none", stroke: catColors.color, strokeWidth: 0.5, opacity: 0.3 })
599
+ ] }),
600
+ effectIcon(effectType, x, y, size, iconColor),
601
+ label && /* @__PURE__ */ jsx(
602
+ "text",
603
+ {
604
+ x,
605
+ y: y + size + 10,
606
+ textAnchor: "middle",
607
+ fill: iconColor,
608
+ fontSize: 11,
609
+ fontWeight: 500,
610
+ fontFamily: "inherit",
611
+ opacity: 0.7,
612
+ children: label
613
+ }
614
+ )
615
+ ] });
616
+ };
617
+ AvlEffect.displayName = "AvlEffect";
420
618
 
421
- export { AVL_FONT, AVL_INK, AVL_STROKE, CONNECTION_COLORS, EFFECT_CATEGORY_COLORS, OPERATOR_CATEGORY_COLORS, STATE_COLORS, THEME_SERIES, asEffectOperator, avlBlend, avlSeries, avlTint, effectCategoryOf, effectZoneOf, getStateRole, parseComputedColor, resolveThemeColor };
619
+ export { AVL_FONT, AVL_INK, AVL_STROKE, AvlEffect, CONNECTION_COLORS, EFFECT_CATEGORY_COLORS, OPERATOR_CATEGORY_COLORS, STATE_COLORS, THEME_SERIES, avlBlend, avlSeries, avlTint, effectCategoryOf, effectZoneOf, getStateRole, parseComputedColor, resolveThemeColor };
@@ -1,4 +1,4 @@
1
- import { useEventBus, useTranslate, Box, VStack, Icon, cn, Typography, Button, domPassthrough } from './chunk-4YXBKHHM.js';
1
+ import { useEventBus, useTranslate, Box, VStack, Icon, cn, Typography, Button, domPassthrough } from './chunk-D5FJU4XC.js';
2
2
  import { EMPTY_STATE_MARKER } from '@almadar/core';
3
3
  import { jsx, jsxs } from 'react/jsx-runtime';
4
4
 
@@ -1,12 +1,11 @@
1
- import { JsonTreeEditor } from './chunk-ILQXJ2AR.js';
2
- import { transitionPlayback, Accordion } from './chunk-REXYVBUO.js';
3
- import { EmptyState } from './chunk-AGXD77SL.js';
4
- import { useContainerWidth, roundedEdgePath } from './chunk-TXAUOLWZ.js';
5
- import { AvlExplain, AvlEffectChip } from './chunk-AB3X7QTE.js';
6
- import { AvlEffect } from './chunk-DZBQA2OW.js';
1
+ import { JsonTreeEditor } from './chunk-JEN4EIUF.js';
2
+ import { transitionPlayback, Accordion } from './chunk-3DA36FOA.js';
3
+ import { EmptyState } from './chunk-3YUMGEEW.js';
4
+ import { useContainerWidth, roundedEdgePath } from './chunk-HA2BYO5E.js';
7
5
  import { parseTraitLevel } from './chunk-PCR37T3U.js';
8
- import { AVL_INK, AVL_FONT, effectZoneOf, avlTint, OPERATOR_CATEGORY_COLORS, avlBlend } from './chunk-UXLE3IPR.js';
9
- import { useTranslate, useMediaQuery, Box, Typography, Card, VStack, HStack, Badge, Button } from './chunk-4YXBKHHM.js';
6
+ import { AvlExplain, AvlEffectChip } from './chunk-V5SVGUYN.js';
7
+ import { AVL_INK, AVL_FONT, effectZoneOf, avlTint, AvlEffect, OPERATOR_CATEGORY_COLORS, avlBlend } from './chunk-3UQNFRYV.js';
8
+ import { useTranslate, useMediaQuery, Box, Typography, Card, VStack, HStack, Badge, Button } from './chunk-D5FJU4XC.js';
10
9
  import { useRef, useMemo, useState } from 'react';
11
10
  import { formatSExpr, JsonValueSchema, isJsonObject, isBinding } from '@almadar/core';
12
11
  import { operatorVisualForm, getStdOperatorMeta } from '@almadar/std/registry';
@@ -1,8 +1,7 @@
1
- import { AvlState, AvlEntity, AvlFieldType, AvlPage } from './chunk-HH5KSMH5.js';
2
- import { AvlExplain, useEffectLines } from './chunk-AB3X7QTE.js';
3
- import { AvlEffect } from './chunk-DZBQA2OW.js';
4
- import { getStateRole, CONNECTION_COLORS } from './chunk-UXLE3IPR.js';
5
- import { useTranslate, Box, cn, domPassthrough } from './chunk-4YXBKHHM.js';
1
+ import { AvlState, AvlEntity, AvlFieldType, AvlPage } from './chunk-DPDKBY6Z.js';
2
+ import { AvlExplain, useEffectLines } from './chunk-V5SVGUYN.js';
3
+ import { getStateRole, AvlEffect, CONNECTION_COLORS } from './chunk-3UQNFRYV.js';
4
+ import { useTranslate, Box, cn, domPassthrough } from './chunk-D5FJU4XC.js';
6
5
  import { useNodeId, ReactFlowProvider, Handle, Position } from '@xyflow/react';
7
6
  import React from 'react';
8
7
  import { jsxs, jsx } from 'react/jsx-runtime';
@@ -1,5 +1,5 @@
1
- import { useDraggable, useDropZone } from './chunk-VO2TTLS5.js';
2
- import { Box, domPassthrough, useTranslate, Icon, pressableProps, Typography } from './chunk-4YXBKHHM.js';
1
+ import { useDraggable, useDropZone } from './chunk-GHAF7QUD.js';
2
+ import { Box, domPassthrough, useTranslate, Icon, pressableProps, Typography } from './chunk-D5FJU4XC.js';
3
3
  import React, { createContext, useState, useCallback, useRef, useEffect, useContext } from 'react';
4
4
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
5
5
 
@@ -1,5 +1,5 @@
1
- import { isNotificationSlot } from './chunk-P4ZFUQFF.js';
2
- import React, { useState, useRef, useMemo, useEffect, useCallback } from 'react';
1
+ import { isNotificationSlot } from './chunk-AZ74UPG6.js';
2
+ import React, { useState, useRef, useCallback, useMemo, useEffect } from 'react';
3
3
  import { RENDERED_SLOTS, isRenderBindingMarker } from '@almadar/core';
4
4
  import { createLogger } from '@almadar/logger';
5
5
 
@@ -35,6 +35,10 @@ function isPlainSlotObject(value) {
35
35
  if (isRenderBindingMarker(value)) return false;
36
36
  return true;
37
37
  }
38
+ function elementRef(element) {
39
+ const props = element.props;
40
+ return props?.ref ?? element.ref;
41
+ }
38
42
  function shareValue(prev, next) {
39
43
  if (Object.is(prev, next)) return { value: prev, equal: true };
40
44
  const prevMarker = isRenderBindingMarker(prev) ? prev : void 0;
@@ -49,6 +53,11 @@ function shareValue(prev, next) {
49
53
  return prev instanceof Date && next instanceof Date && prev.getTime() === next.getTime() ? { value: prev, equal: true } : { value: next, equal: false };
50
54
  }
51
55
  if (typeof prev === "function" || typeof next === "function") return { value: next, equal: false };
56
+ if (React.isValidElement(prev) && React.isValidElement(next)) {
57
+ if (prev.type !== next.type || prev.key !== next.key || elementRef(prev) !== elementRef(next)) return { value: next, equal: false };
58
+ const props = shareValue(prev.props, next.props);
59
+ return props.equal ? { value: prev, equal: true } : { value: next, equal: false };
60
+ }
52
61
  if (React.isValidElement(prev) || React.isValidElement(next)) return { value: next, equal: false };
53
62
  if (Array.isArray(prev) && Array.isArray(next)) {
54
63
  let equal = prev.length === next.length;
@@ -98,6 +107,7 @@ var DEFAULT_SLOTS = ALL_SLOTS.reduce(
98
107
  },
99
108
  {}
100
109
  );
110
+ var NO_DECLARED_ORDER = /* @__PURE__ */ new Map();
101
111
  var DEFAULT_SOURCES = ALL_SLOTS.reduce(
102
112
  (acc, slot) => {
103
113
  acc[slot] = {};
@@ -105,9 +115,11 @@ var DEFAULT_SOURCES = ALL_SLOTS.reduce(
105
115
  },
106
116
  {}
107
117
  );
108
- function aggregateSlot(sources) {
118
+ function aggregateSlot(sources, declaredOrder) {
109
119
  if (!sources) return null;
110
- const entries = Object.entries(sources);
120
+ const entries = Object.entries(sources).sort(
121
+ ([a], [b]) => (declaredOrder.get(a) ?? Infinity) - (declaredOrder.get(b) ?? Infinity) || 0
122
+ );
111
123
  if (entries.length === 0) return null;
112
124
  if (entries.length === 1) return entries[0][1];
113
125
  const children = entries.map(
@@ -144,14 +156,24 @@ function useUISlotManager() {
144
156
  const subscribersRef = useRef(/* @__PURE__ */ new Set());
145
157
  const timersRef = useRef(/* @__PURE__ */ new Map());
146
158
  const traitIndexRef = useRef(/* @__PURE__ */ new Map());
159
+ const lastWriteRef = useRef(/* @__PURE__ */ new Map());
160
+ const [declaredOrder, setDeclaredOrder] = useState(NO_DECLARED_ORDER);
161
+ const declaredOrderRef = useRef(NO_DECLARED_ORDER);
162
+ const setDeclaredTraitOrder = useCallback((traits) => {
163
+ const next = new Map(traits.map((trait, index) => [trait, index]));
164
+ const held = declaredOrderRef.current;
165
+ if (held.size === next.size && [...next].every(([trait, index]) => held.get(trait) === index)) return;
166
+ declaredOrderRef.current = next;
167
+ setDeclaredOrder(next);
168
+ }, []);
147
169
  const traitSubscribersRef = useRef(/* @__PURE__ */ new Map());
148
170
  const slots = useMemo(() => {
149
171
  const out = { ...DEFAULT_SLOTS };
150
172
  for (const slot of ALL_SLOTS) {
151
- out[slot] = aggregateSlot(sources[slot]);
173
+ out[slot] = aggregateSlot(sources[slot], declaredOrder);
152
174
  }
153
175
  return out;
154
- }, [sources]);
176
+ }, [sources, declaredOrder]);
155
177
  useEffect(() => {
156
178
  return () => {
157
179
  timersRef.current.forEach((timer) => clearTimeout(timer));
@@ -206,6 +228,13 @@ function useUISlotManager() {
206
228
  fromState: config.fromState,
207
229
  entity: config.entity
208
230
  };
231
+ const writeKey = `${config.target}\0${sourceKey}`;
232
+ const last = lastWriteRef.current.get(writeKey);
233
+ if (last && !(config.autoDismissMs && config.autoDismissMs > 0) && last.autoDismissAt === void 0 && last.priority === content.priority && last.pattern === content.pattern && last.transitionEvent === content.transitionEvent && last.fromState === content.fromState && last.entity === content.entity && last.nodeId === content.nodeId && last.onDismiss === void 0 === (content.onDismiss === void 0) && reconcileSlotProps(last.props, content.props).equal) {
234
+ log.debug("slot:write-unchanged", { slot: config.target, sourceKey, pattern: content.pattern });
235
+ return id;
236
+ }
237
+ lastWriteRef.current.set(writeKey, content);
209
238
  if (config.autoDismissMs && config.autoDismissMs > 0) {
210
239
  content.autoDismissAt = Date.now() + config.autoDismissMs;
211
240
  const prevTimer = timersRef.current.get(id);
@@ -218,7 +247,7 @@ function useUISlotManager() {
218
247
  const next = { ...slotSources };
219
248
  delete next[sourceKey];
220
249
  const updated = { ...prev, [config.target]: next };
221
- notifySubscribers(config.target, aggregateSlot(next));
250
+ notifySubscribers(config.target, aggregateSlot(next, declaredOrderRef.current));
222
251
  return updated;
223
252
  }
224
253
  return prev;
@@ -271,7 +300,7 @@ function useUISlotManager() {
271
300
  patternType: content.pattern,
272
301
  priority: content.priority
273
302
  });
274
- notifySubscribers(config.target, aggregateSlot(nextSources));
303
+ notifySubscribers(config.target, aggregateSlot(nextSources, declaredOrderRef.current));
275
304
  return nextAll;
276
305
  });
277
306
  return id;
@@ -280,6 +309,7 @@ function useUISlotManager() {
280
309
  );
281
310
  const clear = useCallback(
282
311
  (slot) => {
312
+ for (const key of [...lastWriteRef.current.keys()]) if (key.startsWith(`${slot}\0`)) lastWriteRef.current.delete(key);
283
313
  setSources((prev) => {
284
314
  const slotSources = prev[slot];
285
315
  if (!slotSources || Object.keys(slotSources).length === 0) {
@@ -306,6 +336,7 @@ function useUISlotManager() {
306
336
  const clearBySource = useCallback(
307
337
  (slot, sourceTrait) => {
308
338
  const sourceKey = sourceTrait;
339
+ lastWriteRef.current.delete(`${slot}\0${sourceKey}`);
309
340
  setSources((prev) => {
310
341
  const slotSources = prev[slot];
311
342
  if (!slotSources || !(sourceKey in slotSources)) {
@@ -333,7 +364,7 @@ function useUISlotManager() {
333
364
  const nextSources = { ...slotSources };
334
365
  delete nextSources[sourceKey];
335
366
  log.info("slot:cleared", { slot, sourceTrait, lastPatternType: content.pattern });
336
- notifySubscribers(slot, aggregateSlot(nextSources));
367
+ notifySubscribers(slot, aggregateSlot(nextSources, declaredOrderRef.current));
337
368
  return { ...prev, [slot]: nextSources };
338
369
  });
339
370
  },
@@ -341,6 +372,7 @@ function useUISlotManager() {
341
372
  );
342
373
  const clearById = useCallback(
343
374
  (id) => {
375
+ for (const [key, written] of [...lastWriteRef.current]) if (written.id === id) lastWriteRef.current.delete(key);
344
376
  setSources((prev) => {
345
377
  for (const slot of ALL_SLOTS) {
346
378
  const slotSources = prev[slot];
@@ -362,7 +394,7 @@ function useUISlotManager() {
362
394
  }
363
395
  const nextSources = { ...slotSources };
364
396
  delete nextSources[matchKey];
365
- notifySubscribers(slot, aggregateSlot(nextSources));
397
+ notifySubscribers(slot, aggregateSlot(nextSources, declaredOrderRef.current));
366
398
  return { ...prev, [slot]: nextSources };
367
399
  }
368
400
  return prev;
@@ -371,6 +403,7 @@ function useUISlotManager() {
371
403
  [notifySubscribers, notifyTraitSubscribers, unindexTrait]
372
404
  );
373
405
  const clearAll = useCallback(() => {
406
+ lastWriteRef.current.clear();
374
407
  timersRef.current.forEach((timer) => clearTimeout(timer));
375
408
  timersRef.current.clear();
376
409
  setSources((prev) => {
@@ -430,13 +463,19 @@ function useUISlotManager() {
430
463
  (traitName, content) => {
431
464
  const id = `slot-content-trait-${traitName}`;
432
465
  const fullContent = { ...content, id, sourceTrait: traitName };
466
+ const existing = traitIndexRef.current.get(traitName);
467
+ if (existing && existing.slot === fullContent.slot && existing.priority === fullContent.priority && existing.pattern === fullContent.pattern && existing.transitionEvent === fullContent.transitionEvent && existing.fromState === fullContent.fromState && existing.entity === fullContent.entity && existing.nodeId === fullContent.nodeId) {
468
+ const reconciled = reconcileSlotProps(existing.props, fullContent.props);
469
+ if (reconciled.equal) return id;
470
+ fullContent.props = reconciled.value;
471
+ }
433
472
  indexTraitRender(traitName, fullContent);
434
473
  notifyTraitSubscribers(traitName, fullContent);
435
474
  return id;
436
475
  },
437
476
  [indexTraitRender, notifyTraitSubscribers]
438
477
  );
439
- return {
478
+ return useMemo(() => ({
440
479
  slots,
441
480
  render,
442
481
  clear,
@@ -448,8 +487,9 @@ function useUISlotManager() {
448
487
  getContent,
449
488
  getTraitContent,
450
489
  subscribeTrait,
451
- updateTraitContent
452
- };
490
+ updateTraitContent,
491
+ setDeclaredTraitOrder
492
+ }), [slots, render, clear, clearBySource, clearById, clearAll, subscribe, hasContent, getContent, getTraitContent, subscribeTrait, updateTraitContent, setDeclaredTraitOrder]);
453
493
  }
454
494
 
455
495
  export { ALL_SLOTS, DEFAULT_SLOTS, useUISlotManager };
@@ -82,6 +82,9 @@ function isPortalSlot(slot) {
82
82
  function isNotificationSlot(slot) {
83
83
  return SLOT_DEFINITIONS[slot]?.notification === true;
84
84
  }
85
+ function paintsInTraitFrame(traitEmbedded, slot) {
86
+ return traitEmbedded && !isNotificationSlot(slot);
87
+ }
85
88
  function getSlotsByType(type) {
86
89
  return Object.entries(SLOT_DEFINITIONS).filter(([, def]) => def?.type === type).map(([name]) => name);
87
90
  }
@@ -90,4 +93,4 @@ function getInlineSlots() {
90
93
  }
91
94
  var ALL_SLOTS = Object.keys(SLOT_DEFINITIONS);
92
95
 
93
- export { ALL_SLOTS, SLOT_DEFINITIONS, getInlineSlots, getSlotDefinition, isNotificationSlot, isPortalSlot };
96
+ export { ALL_SLOTS, SLOT_DEFINITIONS, getInlineSlots, getSlotDefinition, isNotificationSlot, isPortalSlot, paintsInTraitFrame };
@@ -1,6 +1,6 @@
1
- import { AvlStateMachine } from './chunk-SP5CDJ6K.js';
2
- import { EmptyState } from './chunk-AGXD77SL.js';
3
- import { useTranslate, Box, domPassthrough } from './chunk-4YXBKHHM.js';
1
+ import { AvlStateMachine } from './chunk-RDPELAFQ.js';
2
+ import { EmptyState } from './chunk-3YUMGEEW.js';
3
+ import { useTranslate, Box, domPassthrough } from './chunk-D5FJU4XC.js';
4
4
  import { jsx } from 'react/jsx-runtime';
5
5
 
6
6
  var BehaviorView = ({ data, ...rest }) => {
@@ -1,7 +1,6 @@
1
- import { AvlFieldType, AvlState, AvlPage, AvlEntity } from './chunk-HH5KSMH5.js';
2
- import { AvlEffect } from './chunk-DZBQA2OW.js';
3
- import { OPERATOR_CATEGORY_COLORS } from './chunk-UXLE3IPR.js';
4
- import { useTranslate, Box, Typography, domPassthrough } from './chunk-4YXBKHHM.js';
1
+ import { AvlFieldType, AvlState, AvlPage, AvlEntity } from './chunk-DPDKBY6Z.js';
2
+ import { OPERATOR_CATEGORY_COLORS, AvlEffect } from './chunk-3UQNFRYV.js';
3
+ import { useTranslate, Box, Typography, domPassthrough } from './chunk-D5FJU4XC.js';
5
4
  import React, { useRef, useState, useLayoutEffect } from 'react';
6
5
  import { jsxs, jsx } from 'react/jsx-runtime';
7
6