@almadar/ui 5.113.0 → 5.115.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.js CHANGED
@@ -11,6 +11,7 @@ import { Loader2, X, Code, FileText, WrapText, Check, Copy, Lightbulb, CheckCirc
11
11
  import { createPortal } from 'react-dom';
12
12
  import { UISlotProvider, useUISlots, useTheme } from '@almadar/ui/context';
13
13
  import { evaluateGuard, evaluate, createMinimalContext, executeEffects } from '@almadar/evaluator';
14
+ import { prepareSchemaForPreview, collectTraitRefsFromResolvedTrait, buildOrbitalsByTrait, collectEmbeddedTraits, wrapCallbackForEvent, pushPerfEntry, perfStart, perfEnd } from '@almadar/runtime/ui';
14
15
  import { Link, Outlet, useLocation } from 'react-router-dom';
15
16
  import SyntaxHighlighter from 'react-syntax-highlighter/dist/esm/prism-light.js';
16
17
  import dark from 'react-syntax-highlighter/dist/esm/styles/prism/vsc-dark-plus.js';
@@ -35,13 +36,14 @@ import ReactMarkdown from 'react-markdown';
35
36
  import remarkGfm from 'remark-gfm';
36
37
  import remarkMath from 'remark-math';
37
38
  import rehypeKatex from 'rehype-katex';
38
- import { FieldTypeSchema, isInlineTrait, isPageReference, isEntityCall, schemaToIR, getPage, isCircuitEvent, walkSExpr, mergeEntityFrame } from '@almadar/core';
39
+ import { FieldTypeSchema, isInlineTrait, isPageReference, buildResolvedTraitConfigs, schemaToIR, getPage, isCircuitEvent, walkSExpr, mergeEntityFrame, isSExpr, isEventPayloadValue } from '@almadar/core';
39
40
  import { useDroppable, useDraggable, DndContext, DragOverlay, useSensors, useSensor, PointerSensor, KeyboardSensor, pointerWithin, rectIntersection, closestCorners } from '@dnd-kit/core';
40
41
  import { sortableKeyboardCoordinates, useSortable, arrayMove, SortableContext, rectSortingStrategy, verticalListSortingStrategy } from '@dnd-kit/sortable';
41
42
  import { CSS } from '@dnd-kit/utilities';
42
43
  import { isDrawHostPattern, getPatternDefinition, getComponentForPattern as getComponentForPattern$1, isEntityAwarePattern } from '@almadar/core/patterns';
43
44
  import { OrbitalServerRuntime } from '@almadar/runtime/OrbitalServerRuntime';
44
- import { InMemoryPersistence, StateMachineManager, collectDeclaredConfigDefaults, createServerEffectHandlers, EffectExecutor, createContextFromBindings, createTickScheduler, isValidCronExpression, parseDurationString, normalizeCallSiteConfigToValues } from '@almadar/runtime';
45
+ import { isKnownStdOperator } from '@almadar/std/registry';
46
+ import { InMemoryPersistence, StateMachineManager, collectDeclaredConfigDefaults, resolveCallSitePayloadCaptures, createServerEffectHandlers, EffectExecutor, createContextFromBindings, createTickScheduler, isValidCronExpression, parseDurationString, normalizeCallSiteConfigToValues } from '@almadar/runtime';
45
47
 
46
48
  var __defProp = Object.defineProperty;
47
49
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
@@ -4485,41 +4487,6 @@ function kebabToPascal(name) {
4485
4487
  return part.charAt(0).toUpperCase() + part.slice(1);
4486
4488
  }).join("");
4487
4489
  }
4488
- function loadLib(key, importer) {
4489
- let p = libPromises.get(key);
4490
- if (!p) {
4491
- p = importer();
4492
- libPromises.set(key, p);
4493
- }
4494
- return p;
4495
- }
4496
- function lazyFamilyIcon(libKey, importer, pick, fallbackName, family) {
4497
- const Lazy = React90__default.lazy(async () => {
4498
- const lib = await loadLib(libKey, importer);
4499
- const Comp = pick(lib);
4500
- if (!Comp) {
4501
- warnFallback(fallbackName, family);
4502
- return { default: makeLucideAdapter(fallbackName, true) };
4503
- }
4504
- return { default: Comp };
4505
- });
4506
- const Wrapped = (props) => /* @__PURE__ */ jsx(
4507
- React90__default.Suspense,
4508
- {
4509
- fallback: /* @__PURE__ */ jsx(
4510
- "span",
4511
- {
4512
- "aria-hidden": true,
4513
- className: props.className,
4514
- style: { display: "inline-block", ...props.style }
4515
- }
4516
- ),
4517
- children: /* @__PURE__ */ jsx(Lazy, { ...props })
4518
- }
4519
- );
4520
- Wrapped.displayName = `Lazy.${libKey}.${fallbackName}`;
4521
- return Wrapped;
4522
- }
4523
4490
  function isComponentLike(v) {
4524
4491
  return v != null && (typeof v === "function" || typeof v === "object");
4525
4492
  }
@@ -4533,146 +4500,32 @@ function resolveLucide(name) {
4533
4500
  if (isComponentLike(asIs)) return asIs;
4534
4501
  return LucideIcons2.HelpCircle;
4535
4502
  }
4536
- function resolvePhosphor(name, weight, family) {
4537
- const target = phosphorAliases[name] ?? kebabToPascal(name);
4538
- return lazyFamilyIcon(
4539
- "phosphor",
4540
- () => import('@phosphor-icons/react'),
4541
- (lib) => {
4542
- const PhosphorComp = lib[target];
4543
- if (!PhosphorComp) return null;
4544
- const Component = PhosphorComp;
4545
- const Adapter = (props) => /* @__PURE__ */ jsx(
4546
- Component,
4547
- {
4548
- weight,
4549
- className: props.className,
4550
- style: props.style,
4551
- size: props.size ?? "1em"
4552
- }
4553
- );
4554
- Adapter.displayName = `Phosphor.${target}.${weight}`;
4555
- return Adapter;
4556
- },
4557
- name,
4558
- family
4559
- );
4560
- }
4561
- function resolveTabler(name, family) {
4562
- const suffix = tablerAliases[name] ?? kebabToPascal(name);
4563
- const target = `Icon${suffix}`;
4564
- return lazyFamilyIcon(
4565
- "tabler",
4566
- () => import('@tabler/icons-react'),
4567
- (lib) => {
4568
- const TablerComp = lib[target];
4569
- if (!TablerComp) return null;
4570
- const Component = TablerComp;
4571
- const Adapter = (props) => /* @__PURE__ */ jsx(
4572
- Component,
4573
- {
4574
- stroke: props.strokeWidth ?? 1.5,
4575
- className: props.className,
4576
- style: props.style,
4577
- size: props.size ?? 24
4578
- }
4579
- );
4580
- Adapter.displayName = `Tabler.${target}`;
4581
- return Adapter;
4582
- },
4583
- name,
4584
- family
4585
- );
4586
- }
4587
- function resolveFa(name, family) {
4588
- const suffix = faAliases[name] ?? kebabToPascal(name);
4589
- const target = `Fa${suffix}`;
4590
- return lazyFamilyIcon(
4591
- "fa",
4592
- () => import('react-icons/fa'),
4593
- (lib) => {
4594
- const FaComp = lib[target];
4595
- if (!FaComp) return null;
4596
- const Component = FaComp;
4597
- const Adapter = (props) => /* @__PURE__ */ jsx(
4598
- Component,
4599
- {
4600
- className: props.className,
4601
- style: props.style,
4602
- size: props.size ?? "1em"
4603
- }
4604
- );
4605
- Adapter.displayName = `Fa.${target}`;
4606
- return Adapter;
4607
- },
4608
- name,
4609
- family
4610
- );
4611
- }
4612
- function warnFallback(name, family) {
4613
- const key = `${family}::${name}`;
4614
- if (warned.has(key)) return;
4615
- warned.add(key);
4616
- if (typeof console !== "undefined") {
4617
- console.warn(
4618
- `[iconFamily] No '${name}' mapping in family '${family}'; falling back to lucide. Add an alias in lib/iconFamily.ts.`
4619
- );
4620
- }
4621
- }
4622
- function makeLucideAdapter(name, isFallback = false) {
4503
+ function makeLucideAdapter(name) {
4623
4504
  const LucideComp = resolveLucide(name);
4624
- const Adapter = (props) => {
4625
- const stroke = props.strokeWidth ?? (isFallback ? 2 : void 0);
4626
- const style = isFallback ? { ...props.style ?? {}, strokeWidth: stroke ?? 2 } : props.style;
4627
- return /* @__PURE__ */ jsx(
4628
- LucideComp,
4629
- {
4630
- className: props.className,
4631
- strokeWidth: stroke,
4632
- style,
4633
- size: props.size
4634
- }
4635
- );
4636
- };
4637
- Adapter.displayName = `Lucide.${name}${isFallback ? ".fallback" : ""}`;
4505
+ const Adapter = (props) => /* @__PURE__ */ jsx(
4506
+ LucideComp,
4507
+ {
4508
+ className: props.className,
4509
+ strokeWidth: props.strokeWidth,
4510
+ style: props.style,
4511
+ size: props.size
4512
+ }
4513
+ );
4514
+ Adapter.displayName = `Lucide.${name}`;
4638
4515
  return Adapter;
4639
4516
  }
4640
- function resolveIconForFamily(name, family) {
4641
- switch (family) {
4642
- case "lucide":
4643
- return makeLucideAdapter(name, false);
4644
- // Non-lucide families resolve to a lazy, Suspense-wrapped component that
4645
- // dynamic-imports the library on first render and falls back to lucide
4646
- // internally when the family lacks the icon (see lazyFamilyIcon).
4647
- case "phosphor-outline":
4648
- return resolvePhosphor(name, "regular", family);
4649
- case "phosphor-fill":
4650
- return resolvePhosphor(name, "fill", family);
4651
- case "phosphor-duotone":
4652
- return resolvePhosphor(name, "duotone", family);
4653
- case "tabler":
4654
- return resolveTabler(name, family);
4655
- case "fa-solid":
4656
- return resolveFa(name, family);
4657
- }
4658
- }
4659
- var DEFAULT_FAMILY, VALID_FAMILIES, cachedFamily, listeners, observer, libPromises, lucideAliases, phosphorAliases, tablerAliases, faAliases, warned;
4517
+ function resolveIconForFamily(name, _family) {
4518
+ return makeLucideAdapter(name);
4519
+ }
4520
+ var DEFAULT_FAMILY, VALID_FAMILIES, cachedFamily, listeners, observer, lucideAliases;
4660
4521
  var init_iconFamily = __esm({
4661
4522
  "lib/iconFamily.tsx"() {
4662
4523
  "use client";
4663
4524
  DEFAULT_FAMILY = "lucide";
4664
- VALID_FAMILIES = [
4665
- "lucide",
4666
- "phosphor-outline",
4667
- "phosphor-fill",
4668
- "phosphor-duotone",
4669
- "tabler",
4670
- "fa-solid"
4671
- ];
4525
+ VALID_FAMILIES = [DEFAULT_FAMILY];
4672
4526
  cachedFamily = null;
4673
4527
  listeners = /* @__PURE__ */ new Set();
4674
4528
  observer = null;
4675
- libPromises = /* @__PURE__ */ new Map();
4676
4529
  lucideAliases = {
4677
4530
  close: LucideIcons2.X,
4678
4531
  trash: LucideIcons2.Trash2,
@@ -4685,478 +4538,6 @@ var init_iconFamily = __esm({
4685
4538
  "sort-asc": LucideIcons2.ArrowUpNarrowWide,
4686
4539
  "sort-desc": LucideIcons2.ArrowDownNarrowWide
4687
4540
  };
4688
- phosphorAliases = {
4689
- // lucide name → phosphor PascalCase name
4690
- // Actions
4691
- plus: "Plus",
4692
- minus: "Minus",
4693
- x: "X",
4694
- check: "Check",
4695
- close: "X",
4696
- edit: "PencilSimple",
4697
- pencil: "PencilSimple",
4698
- trash: "Trash",
4699
- save: "FloppyDisk",
4700
- copy: "Copy",
4701
- share: "Share",
4702
- send: "PaperPlaneRight",
4703
- download: "DownloadSimple",
4704
- upload: "UploadSimple",
4705
- archive: "Archive",
4706
- refresh: "ArrowsClockwise",
4707
- loader: "CircleNotch",
4708
- link: "Link",
4709
- paperclip: "Paperclip",
4710
- // Navigation
4711
- "chevron-down": "CaretDown",
4712
- "chevron-up": "CaretUp",
4713
- "chevron-left": "CaretLeft",
4714
- "chevron-right": "CaretRight",
4715
- "arrow-up": "ArrowUp",
4716
- "arrow-down": "ArrowDown",
4717
- "arrow-left": "ArrowLeft",
4718
- "arrow-right": "ArrowRight",
4719
- menu: "List",
4720
- more: "DotsThree",
4721
- "more-vertical": "DotsThreeVertical",
4722
- "more-horizontal": "DotsThree",
4723
- external: "ArrowSquareOut",
4724
- "external-link": "ArrowSquareOut",
4725
- // Files
4726
- file: "File",
4727
- "file-text": "FileText",
4728
- "file-plus": "FilePlus",
4729
- "file-minus": "FileMinus",
4730
- folder: "Folder",
4731
- "folder-open": "FolderOpen",
4732
- document: "FileText",
4733
- // Charts
4734
- "bar-chart": "ChartBar",
4735
- "bar-chart-2": "ChartBar",
4736
- "bar-chart-3": "ChartBar",
4737
- "line-chart": "ChartLine",
4738
- "pie-chart": "ChartPie",
4739
- activity: "Pulse",
4740
- "trending-up": "TrendUp",
4741
- "trending-down": "TrendDown",
4742
- // Messages
4743
- message: "ChatCircle",
4744
- "message-circle": "ChatCircle",
4745
- "message-square": "ChatText",
4746
- "messages-square": "ChatsCircle",
4747
- comment: "ChatCircle",
4748
- comments: "ChatsCircle",
4749
- inbox: "Tray",
4750
- mail: "Envelope",
4751
- envelope: "Envelope",
4752
- // Status
4753
- "alert-circle": "WarningCircle",
4754
- "alert-triangle": "Warning",
4755
- "check-circle": "CheckCircle",
4756
- "x-circle": "XCircle",
4757
- info: "Info",
4758
- "help-circle": "Question",
4759
- "life-buoy": "Lifebuoy",
4760
- lifebuoy: "Lifebuoy",
4761
- warning: "Warning",
4762
- error: "WarningCircle",
4763
- // Media
4764
- image: "Image",
4765
- video: "VideoCamera",
4766
- film: "FilmStrip",
4767
- camera: "Camera",
4768
- music: "MusicNote",
4769
- play: "Play",
4770
- pause: "Pause",
4771
- stop: "Stop",
4772
- "skip-forward": "SkipForward",
4773
- "skip-back": "SkipBack",
4774
- volume: "SpeakerHigh",
4775
- "volume-2": "SpeakerHigh",
4776
- "volume-x": "SpeakerX",
4777
- mic: "Microphone",
4778
- "mic-off": "MicrophoneSlash",
4779
- // People
4780
- user: "User",
4781
- users: "Users",
4782
- "user-plus": "UserPlus",
4783
- "user-check": "UserCheck",
4784
- // Time
4785
- calendar: "Calendar",
4786
- clock: "Clock",
4787
- timer: "Timer",
4788
- // Location
4789
- map: "MapTrifold",
4790
- "map-pin": "MapPin",
4791
- navigation: "NavigationArrow",
4792
- compass: "Compass",
4793
- globe: "Globe",
4794
- target: "Target",
4795
- // Project / layout
4796
- kanban: "Kanban",
4797
- list: "List",
4798
- table: "Table",
4799
- grid: "GridFour",
4800
- layout: "Layout",
4801
- columns: "Columns",
4802
- rows: "Rows",
4803
- // Misc
4804
- bell: "Bell",
4805
- bookmark: "Bookmark",
4806
- briefcase: "Briefcase",
4807
- flag: "Flag",
4808
- tag: "Tag",
4809
- tags: "Tag",
4810
- star: "Star",
4811
- heart: "Heart",
4812
- home: "House",
4813
- settings: "Gear",
4814
- eye: "Eye",
4815
- "eye-off": "EyeSlash",
4816
- lock: "Lock",
4817
- unlock: "LockOpen",
4818
- key: "Key",
4819
- shield: "Shield",
4820
- search: "MagnifyingGlass",
4821
- filter: "Funnel",
4822
- "sort-asc": "SortAscending",
4823
- "sort-desc": "SortDescending",
4824
- zap: "Lightning",
4825
- sparkles: "Sparkle",
4826
- // Code
4827
- code: "Code",
4828
- terminal: "Terminal",
4829
- database: "Database",
4830
- server: "HardDrives",
4831
- cloud: "Cloud",
4832
- wifi: "WifiHigh",
4833
- package: "Package",
4834
- box: "Package",
4835
- // Theme
4836
- sun: "Sun",
4837
- moon: "Moon",
4838
- // Phone
4839
- phone: "Phone",
4840
- printer: "Printer",
4841
- // Hierarchy
4842
- tree: "Tree",
4843
- network: "Network"
4844
- };
4845
- tablerAliases = {
4846
- // lucide name → tabler suffix (after the `Icon` prefix)
4847
- // Actions
4848
- plus: "Plus",
4849
- minus: "Minus",
4850
- x: "X",
4851
- check: "Check",
4852
- close: "X",
4853
- edit: "Pencil",
4854
- pencil: "Pencil",
4855
- trash: "Trash",
4856
- save: "DeviceFloppy",
4857
- copy: "Copy",
4858
- share: "Share",
4859
- send: "Send",
4860
- download: "Download",
4861
- upload: "Upload",
4862
- archive: "Archive",
4863
- refresh: "Refresh",
4864
- loader: "Loader2",
4865
- link: "Link",
4866
- paperclip: "Paperclip",
4867
- external: "ExternalLink",
4868
- "external-link": "ExternalLink",
4869
- // Navigation
4870
- "chevron-down": "ChevronDown",
4871
- "chevron-up": "ChevronUp",
4872
- "chevron-left": "ChevronLeft",
4873
- "chevron-right": "ChevronRight",
4874
- "arrow-down": "ArrowDown",
4875
- "arrow-up": "ArrowUp",
4876
- "arrow-left": "ArrowLeft",
4877
- "arrow-right": "ArrowRight",
4878
- menu: "Menu2",
4879
- more: "Dots",
4880
- "more-vertical": "DotsVertical",
4881
- // Files
4882
- file: "File",
4883
- "file-text": "FileText",
4884
- "file-plus": "FilePlus",
4885
- "file-check": "FileCheck",
4886
- "file-minus": "FileMinus",
4887
- folder: "Folder",
4888
- "folder-open": "FolderOpen",
4889
- document: "FileText",
4890
- // Charts
4891
- "bar-chart": "ChartBar",
4892
- "bar-chart-2": "ChartBar",
4893
- "bar-chart-3": "ChartBar",
4894
- "line-chart": "ChartLine",
4895
- "pie-chart": "ChartPie",
4896
- activity: "Activity",
4897
- "trending-up": "TrendingUp",
4898
- "trending-down": "TrendingDown",
4899
- // Messages
4900
- message: "Message",
4901
- "message-circle": "MessageCircle",
4902
- "message-square": "Message2",
4903
- "messages-square": "Messages",
4904
- comment: "Message",
4905
- comments: "Messages",
4906
- inbox: "Inbox",
4907
- mail: "Mail",
4908
- envelope: "Mail",
4909
- // Status
4910
- "alert-circle": "AlertCircle",
4911
- "alert-triangle": "AlertTriangle",
4912
- "check-circle": "CircleCheck",
4913
- "x-circle": "CircleX",
4914
- info: "InfoCircle",
4915
- "help-circle": "HelpCircle",
4916
- "life-buoy": "Lifebuoy",
4917
- warning: "AlertTriangle",
4918
- error: "AlertOctagon",
4919
- // Media
4920
- image: "Photo",
4921
- video: "Video",
4922
- camera: "Camera",
4923
- music: "Music",
4924
- play: "PlayerPlay",
4925
- pause: "PlayerPause",
4926
- stop: "PlayerStop",
4927
- "skip-forward": "PlayerSkipForward",
4928
- "skip-back": "PlayerSkipBack",
4929
- volume: "Volume",
4930
- "volume-2": "Volume",
4931
- "volume-x": "VolumeOff",
4932
- mic: "Microphone",
4933
- "mic-off": "MicrophoneOff",
4934
- // People
4935
- user: "User",
4936
- users: "Users",
4937
- "user-plus": "UserPlus",
4938
- "user-check": "UserCheck",
4939
- // Time
4940
- calendar: "Calendar",
4941
- clock: "Clock",
4942
- timer: "Hourglass",
4943
- // Location
4944
- map: "Map",
4945
- "map-pin": "MapPin",
4946
- navigation: "Navigation",
4947
- compass: "Compass",
4948
- globe: "World",
4949
- target: "Target",
4950
- // Project / layout
4951
- kanban: "LayoutKanban",
4952
- list: "List",
4953
- table: "Table",
4954
- grid: "LayoutGrid",
4955
- layout: "Layout",
4956
- columns: "LayoutColumns",
4957
- rows: "LayoutRows",
4958
- // Misc
4959
- bell: "Bell",
4960
- bookmark: "Bookmark",
4961
- briefcase: "Briefcase",
4962
- flag: "Flag",
4963
- tag: "Tag",
4964
- tags: "Tags",
4965
- star: "Star",
4966
- heart: "Heart",
4967
- home: "Home",
4968
- settings: "Settings",
4969
- eye: "Eye",
4970
- "eye-off": "EyeOff",
4971
- lock: "Lock",
4972
- unlock: "LockOpen",
4973
- key: "Key",
4974
- shield: "Shield",
4975
- search: "Search",
4976
- filter: "Filter",
4977
- "sort-asc": "SortAscending",
4978
- "sort-desc": "SortDescending",
4979
- zap: "Bolt",
4980
- sparkles: "Sparkles",
4981
- // Code / data
4982
- code: "Code",
4983
- terminal: "Terminal",
4984
- database: "Database",
4985
- server: "Server",
4986
- cloud: "Cloud",
4987
- wifi: "Wifi",
4988
- package: "Package",
4989
- box: "Box",
4990
- // Theme
4991
- sun: "Sun",
4992
- moon: "Moon",
4993
- // Phone
4994
- phone: "Phone",
4995
- printer: "Printer",
4996
- // Hierarchy
4997
- tree: "Hierarchy",
4998
- network: "Network"
4999
- };
5000
- faAliases = {
5001
- // lucide name → fa-solid suffix (after the `Fa` prefix).
5002
- // react-icons/fa ships FontAwesome 5 — names like `FaFileText` don't exist
5003
- // (FA renamed to `FaFileAlt`). When you see a console.warn from
5004
- // [iconFamily] about an unmapped lucide name in this family, add the
5005
- // closest FA5 sibling here so the fallback stays in-family.
5006
- search: "Search",
5007
- close: "Times",
5008
- x: "Times",
5009
- loader: "Spinner",
5010
- refresh: "Sync",
5011
- "sort-asc": "SortAmountUp",
5012
- "sort-desc": "SortAmountDown",
5013
- "chevron-down": "ChevronDown",
5014
- "chevron-up": "ChevronUp",
5015
- "chevron-left": "ChevronLeft",
5016
- "chevron-right": "ChevronRight",
5017
- "help-circle": "QuestionCircle",
5018
- "alert-triangle": "ExclamationTriangle",
5019
- "alert-circle": "ExclamationCircle",
5020
- "check-circle": "CheckCircle",
5021
- "x-circle": "TimesCircle",
5022
- edit: "Edit",
5023
- pencil: "PencilAlt",
5024
- trash: "Trash",
5025
- send: "PaperPlane",
5026
- share: "ShareAlt",
5027
- external: "ExternalLinkAlt",
5028
- plus: "Plus",
5029
- minus: "Minus",
5030
- check: "Check",
5031
- star: "Star",
5032
- heart: "Heart",
5033
- home: "Home",
5034
- user: "User",
5035
- users: "Users",
5036
- "user-plus": "UserPlus",
5037
- "user-check": "UserCheck",
5038
- settings: "Cog",
5039
- menu: "Bars",
5040
- "arrow-up": "ArrowUp",
5041
- "arrow-down": "ArrowDown",
5042
- "arrow-left": "ArrowLeft",
5043
- "arrow-right": "ArrowRight",
5044
- copy: "Copy",
5045
- download: "Download",
5046
- upload: "Upload",
5047
- filter: "Filter",
5048
- calendar: "Calendar",
5049
- clock: "Clock",
5050
- bell: "Bell",
5051
- mail: "Envelope",
5052
- envelope: "Envelope",
5053
- lock: "Lock",
5054
- unlock: "LockOpen",
5055
- eye: "Eye",
5056
- "eye-off": "EyeSlash",
5057
- more: "EllipsisH",
5058
- "more-vertical": "EllipsisV",
5059
- info: "InfoCircle",
5060
- warning: "ExclamationTriangle",
5061
- error: "ExclamationCircle",
5062
- // Time
5063
- timer: "Hourglass",
5064
- // Files (FA renamed FileText → FileAlt)
5065
- file: "File",
5066
- "file-text": "FileAlt",
5067
- "file-plus": "FileMedical",
5068
- "file-minus": "FileExcel",
5069
- "file-check": "FileSignature",
5070
- document: "FileAlt",
5071
- // Charts (lucide BarChart2 / BarChart3 → FA ChartBar)
5072
- "bar-chart": "ChartBar",
5073
- "bar-chart-2": "ChartBar",
5074
- "bar-chart-3": "ChartBar",
5075
- "line-chart": "ChartLine",
5076
- "pie-chart": "ChartPie",
5077
- activity: "ChartLine",
5078
- "trending-up": "ChartLine",
5079
- "trending-down": "ChartLine",
5080
- // Messages (lucide MessageCircle/MessageSquare → FA CommentDots/CommentAlt)
5081
- message: "Comment",
5082
- "message-circle": "CommentDots",
5083
- "message-square": "CommentAlt",
5084
- "messages-square": "Comments",
5085
- comment: "Comment",
5086
- comments: "Comments",
5087
- inbox: "Inbox",
5088
- // Support / help
5089
- "life-buoy": "LifeRing",
5090
- lifebuoy: "LifeRing",
5091
- // Project / kanban (FA has no kanban; closest semantic is Tasks/Columns)
5092
- kanban: "Tasks",
5093
- columns: "Columns",
5094
- rows: "Bars",
5095
- layout: "ThLarge",
5096
- grid: "Th",
5097
- list: "List",
5098
- table: "Table",
5099
- // Storage / folders
5100
- folder: "Folder",
5101
- "folder-open": "FolderOpen",
5102
- archive: "Archive",
5103
- bookmark: "Bookmark",
5104
- briefcase: "Briefcase",
5105
- package: "Box",
5106
- box: "Box",
5107
- // Map / location
5108
- map: "Map",
5109
- "map-pin": "MapMarkerAlt",
5110
- navigation: "LocationArrow",
5111
- compass: "Compass",
5112
- globe: "Globe",
5113
- target: "Bullseye",
5114
- // Media
5115
- image: "Image",
5116
- video: "Video",
5117
- film: "Film",
5118
- camera: "Camera",
5119
- music: "Music",
5120
- play: "Play",
5121
- pause: "Pause",
5122
- stop: "Stop",
5123
- "skip-forward": "Forward",
5124
- "skip-back": "Backward",
5125
- volume: "VolumeUp",
5126
- "volume-2": "VolumeUp",
5127
- "volume-x": "VolumeMute",
5128
- mic: "Microphone",
5129
- "mic-off": "MicrophoneSlash",
5130
- phone: "Phone",
5131
- // Code / data
5132
- code: "Code",
5133
- terminal: "Terminal",
5134
- database: "Database",
5135
- server: "Server",
5136
- cloud: "Cloud",
5137
- wifi: "Wifi",
5138
- // Security
5139
- shield: "ShieldAlt",
5140
- key: "Key",
5141
- // Misc actions
5142
- printer: "Print",
5143
- save: "Save",
5144
- link: "Link",
5145
- unlink: "Unlink",
5146
- paperclip: "Paperclip",
5147
- flag: "Flag",
5148
- tag: "Tag",
5149
- tags: "Tags",
5150
- zap: "Bolt",
5151
- sparkles: "Magic",
5152
- // Theme
5153
- sun: "Sun",
5154
- moon: "Moon",
5155
- // Hierarchy (FA has no Tree icon for hierarchies; Sitemap is the org-chart icon)
5156
- tree: "Sitemap",
5157
- network: "NetworkWired"
5158
- };
5159
- warned = /* @__PURE__ */ new Set();
5160
4541
  }
5161
4542
  });
5162
4543
  function kebabToPascal2(name) {
@@ -5237,7 +4618,7 @@ var init_Icon = __esm({
5237
4618
  const family = useIconFamily();
5238
4619
  const RenderedComponent = React90__default.useMemo(() => {
5239
4620
  if (directIcon) return null;
5240
- return effectiveName ? resolveIconForFamily(effectiveName, family) : null;
4621
+ return effectiveName ? resolveIconForFamily(effectiveName) : null;
5241
4622
  }, [directIcon, effectiveName, family]);
5242
4623
  const effectiveStrokeWidth = strokeWidth ?? void 0;
5243
4624
  const inlineStyle = {
@@ -5616,7 +4997,7 @@ var init_Button = __esm({
5616
4997
  ref,
5617
4998
  disabled: disabled || isLoading,
5618
4999
  className: cn(
5619
- "inline-flex items-center justify-center gap-2",
5000
+ "relative inline-flex items-center justify-center gap-2",
5620
5001
  "font-medium",
5621
5002
  "rounded-sm",
5622
5003
  "cursor-pointer",
@@ -7266,6 +6647,7 @@ var init_Input = __esm({
7266
6647
  icon: iconProp,
7267
6648
  clearable,
7268
6649
  onClear,
6650
+ action,
7269
6651
  value,
7270
6652
  options,
7271
6653
  rows = 3,
@@ -7315,6 +6697,11 @@ var init_Input = __esm({
7315
6697
  onClear?.();
7316
6698
  }
7317
6699
  };
6700
+ const handleKeyDown = (e) => {
6701
+ if (action && e.key === "Enter") {
6702
+ eventBus.emit(`UI:${action}`, { value: e.currentTarget.value });
6703
+ }
6704
+ };
7318
6705
  const wrapField = (field) => /* @__PURE__ */ jsxs("div", { className: "w-full", children: [
7319
6706
  label && /* @__PURE__ */ jsx("label", { className: "block text-sm font-medium text-foreground mb-1", children: label }),
7320
6707
  field,
@@ -7388,6 +6775,7 @@ var init_Input = __esm({
7388
6775
  type,
7389
6776
  value,
7390
6777
  onChange: handleChange,
6778
+ onKeyDown: handleKeyDown,
7391
6779
  className: baseClassName,
7392
6780
  ...props
7393
6781
  }
@@ -7920,7 +7308,7 @@ var init_Card = __esm({
7920
7308
  });
7921
7309
  function GameIcon({ assetUrl, icon, size = "md", alt, className }) {
7922
7310
  const px = typeof size === "number" ? size : sizeMap[size];
7923
- const family = useIconFamily();
7311
+ useIconFamily();
7924
7312
  if (assetUrl?.url) {
7925
7313
  return /* @__PURE__ */ jsx(
7926
7314
  AtlasImage,
@@ -7932,7 +7320,7 @@ function GameIcon({ assetUrl, icon, size = "md", alt, className }) {
7932
7320
  }
7933
7321
  );
7934
7322
  }
7935
- const I = typeof icon === "string" ? resolveIconForFamily(icon, family) : icon;
7323
+ const I = typeof icon === "string" ? resolveIconForFamily(icon) : icon;
7936
7324
  return /* @__PURE__ */ jsx(I, { width: px, height: px, className: cn("flex-shrink-0", className) });
7937
7325
  }
7938
7326
  var sizeMap;
@@ -10279,8 +9667,8 @@ function Seigaiha({ size, color, strokeWidth }) {
10279
9667
  [s, s * 0.1]
10280
9668
  ];
10281
9669
  for (const [cx, cy] of centers) {
10282
- for (let ring2 = 1; ring2 <= 3; ring2++) {
10283
- const cr = r2 * (ring2 / 3);
9670
+ for (let ring = 1; ring <= 3; ring++) {
9671
+ const cr = r2 * (ring / 3);
10284
9672
  paths.push(
10285
9673
  `M ${f(cx - cr)},${f(cy)} A ${f(cr)} ${f(cr)} 0 0 1 ${f(cx + cr)},${f(cy)}`
10286
9674
  );
@@ -10377,8 +9765,8 @@ function Arch({ size, color, strokeWidth }) {
10377
9765
  const h = size * 1.5;
10378
9766
  const cx = w / 2;
10379
9767
  const paths = [];
10380
- for (let ring2 = 0; ring2 < 4; ring2++) {
10381
- const scale = 1 - ring2 * 0.2;
9768
+ for (let ring = 0; ring < 4; ring++) {
9769
+ const scale = 1 - ring * 0.2;
10382
9770
  const archW = w * 0.48 * scale;
10383
9771
  const archH = h * 0.7 * scale;
10384
9772
  const baseY = h * 0.85;
@@ -10393,7 +9781,7 @@ function Arch({ size, color, strokeWidth }) {
10393
9781
  paths.push(
10394
9782
  `M ${f(lx)},${f(baseY)} A ${f(radius)} ${f(radius)} 0 0 1 ${f(cx)},${f(tipY)} A ${f(radius)} ${f(radius)} 0 0 1 ${f(rx)},${f(baseY)}`
10395
9783
  );
10396
- if (ring2 === 0) {
9784
+ if (ring === 0) {
10397
9785
  paths.push(`M ${f(lx)},${f(baseY)} L ${f(rx)},${f(baseY)}`);
10398
9786
  }
10399
9787
  }
@@ -12908,9 +12296,9 @@ var init_webPainter2d = __esm({
12908
12296
  // lib/drawable/projector.ts
12909
12297
  function create2DProjector(opts) {
12910
12298
  const { scale, baseOffsetX, layout } = opts;
12911
- const tileWidth = TILE_WIDTH * scale;
12912
- const floorHeight = FLOOR_HEIGHT * scale;
12913
- const diamondTopY = (opts.diamondTopY ?? DIAMOND_TOP_Y) * scale;
12299
+ const tileWidth = layout === "free" ? 1 : TILE_WIDTH * scale;
12300
+ const floorHeight = layout === "free" ? 1 : FLOOR_HEIGHT * scale;
12301
+ const diamondTopY = layout === "free" ? 0 : (opts.diamondTopY ?? DIAMOND_TOP_Y) * scale;
12914
12302
  const squareGrid = layout === "flat" || layout === "free";
12915
12303
  const project = (pos) => layout === "free" ? { x: pos.x, y: pos.y } : isoToScreen(pos.x, pos.y, scale, baseOffsetX, layout);
12916
12304
  const anchorPoint = (pos, anchor) => {
@@ -12951,6 +12339,15 @@ var init_projector = __esm({
12951
12339
  }
12952
12340
  });
12953
12341
 
12342
+ // lib/drawable/contract.ts
12343
+ function isValidScenePos(pos) {
12344
+ return Number.isFinite(pos?.x) && Number.isFinite(pos?.y);
12345
+ }
12346
+ var init_contract = __esm({
12347
+ "lib/drawable/contract.ts"() {
12348
+ }
12349
+ });
12350
+
12954
12351
  // components/game/atoms/DrawSprite.tsx
12955
12352
  function DrawSprite(_props) {
12956
12353
  return null;
@@ -12960,10 +12357,12 @@ var init_DrawSprite = __esm({
12960
12357
  "components/game/atoms/DrawSprite.tsx"() {
12961
12358
  "use client";
12962
12359
  init_atlasSlice();
12360
+ init_contract();
12963
12361
  paintSprite = (painter, node, dctx) => {
12362
+ if (!node.asset?.url || !isValidScenePos(node.position)) return;
12964
12363
  const tex = painter.resolveTexture(node.asset.url);
12965
12364
  if (!tex) return;
12966
- let src = node.frame;
12365
+ let src = typeof node.frame === "object" ? node.frame : void 0;
12967
12366
  if (!src && isAtlasAsset(node.asset)) {
12968
12367
  const atlas = getAtlas(node.asset.atlas, dctx.invalidate);
12969
12368
  if (!atlas) return;
@@ -13008,7 +12407,9 @@ var paintShape;
13008
12407
  var init_DrawShape = __esm({
13009
12408
  "components/game/atoms/DrawShape.tsx"() {
13010
12409
  "use client";
12410
+ init_contract();
13011
12411
  paintShape = (painter, node, dctx) => {
12412
+ if (!isValidScenePos(node.position)) return;
13012
12413
  painter.save();
13013
12414
  if (node.opacity !== void 0 && node.opacity !== 1) painter.setAlpha(node.opacity);
13014
12415
  switch (node.shape) {
@@ -13062,7 +12463,9 @@ var paintText;
13062
12463
  var init_DrawText = __esm({
13063
12464
  "components/game/atoms/DrawText.tsx"() {
13064
12465
  "use client";
12466
+ init_contract();
13065
12467
  paintText = (painter, node, dctx) => {
12468
+ if (!isValidScenePos(node.position)) return;
13066
12469
  const p = dctx.projector.anchorPoint(node.position, node.anchor ?? "center");
13067
12470
  const x = p.x + (node.offsetX ?? 0);
13068
12471
  const y = p.y + (node.offsetY ?? 0);
@@ -13167,12 +12570,14 @@ function collectDrawnItems(nodes) {
13167
12570
  case "draw-sprite":
13168
12571
  case "draw-shape":
13169
12572
  case "draw-text":
13170
- out.push({ pos: n.position, id: n.id });
12573
+ if (isValidScenePos(n.position)) out.push({ pos: n.position, id: n.id });
13171
12574
  break;
13172
12575
  case "draw-sprite-layer":
13173
12576
  case "draw-shape-layer":
13174
12577
  case "draw-text-layer":
13175
- for (const it of n.items) out.push({ pos: it.position, id: it.id });
12578
+ for (const it of n.items) {
12579
+ if (isValidScenePos(it.position)) out.push({ pos: it.position, id: it.id });
12580
+ }
13176
12581
  break;
13177
12582
  }
13178
12583
  }
@@ -13187,6 +12592,7 @@ function buildHitIndex(items) {
13187
12592
  }
13188
12593
  var init_hitTest = __esm({
13189
12594
  "lib/drawable/hitTest.ts"() {
12595
+ init_contract();
13190
12596
  }
13191
12597
  });
13192
12598
  function normalizeBackdrop(bg) {
@@ -15226,21 +14632,6 @@ var init_renderer = __esm({
15226
14632
  init_slot_definitions();
15227
14633
  }
15228
14634
  });
15229
-
15230
- // lib/wrapCallbackForEvent.ts
15231
- function wrapCallbackForEvent(qualifiedEvent, callbackArgs, emit) {
15232
- const argNames = (callbackArgs ?? []).map((a) => a.name);
15233
- if (argNames.length === 0) {
15234
- return () => emit(qualifiedEvent);
15235
- }
15236
- return (...args) => {
15237
- const payload = {};
15238
- for (let i = 0; i < argNames.length; i += 1) {
15239
- payload[argNames[i]] = args[i];
15240
- }
15241
- emit(qualifiedEvent, payload);
15242
- };
15243
- }
15244
14635
  var init_wrapCallbackForEvent = __esm({
15245
14636
  "lib/wrapCallbackForEvent.ts"() {
15246
14637
  }
@@ -25435,7 +24826,8 @@ function DataGrid({
25435
24826
  const { t } = useTranslate();
25436
24827
  const [selectedIds, setSelectedIds] = useState(/* @__PURE__ */ new Set());
25437
24828
  const [visibleCount, setVisibleCount] = useState(pageSize || Infinity);
25438
- const fieldDefs = fields ?? columns ?? [];
24829
+ const fieldDefs = (Array.isArray(fields) ? fields : void 0) ?? (Array.isArray(columns) ? columns : void 0) ?? [];
24830
+ const actionDefs = Array.isArray(itemActions) ? itemActions : [];
25439
24831
  const allDataRaw = Array.isArray(entity) ? entity : entity ? [entity] : [];
25440
24832
  const dnd = useDataDnd({
25441
24833
  items: allDataRaw,
@@ -25479,8 +24871,8 @@ function DataGrid({
25479
24871
  const titleField = fieldDefs.find((f3) => f3.variant === "h3" || f3.variant === "h4") ?? fieldDefs[0];
25480
24872
  const badgeFields = fieldDefs.filter((f3) => f3.variant === "badge" && f3 !== titleField);
25481
24873
  const bodyFields = fieldDefs.filter((f3) => f3 !== titleField && !badgeFields.includes(f3));
25482
- const primaryActions = itemActions?.filter((a) => a.variant !== "danger") ?? [];
25483
- const dangerActions = itemActions?.filter((a) => a.variant === "danger") ?? [];
24874
+ const primaryActions = actionDefs.filter((a) => a.variant !== "danger");
24875
+ const dangerActions = actionDefs.filter((a) => a.variant === "danger");
25484
24876
  const handleActionClick = (action, itemData) => (e) => {
25485
24877
  e.stopPropagation();
25486
24878
  const payload = {
@@ -37803,7 +37195,7 @@ function measureLabelWidth(text) {
37803
37195
  if (typeof document === "undefined") return text.length * 6;
37804
37196
  if (!labelMeasureCtx) labelMeasureCtx = document.createElement("canvas").getContext("2d");
37805
37197
  if (!labelMeasureCtx) return text.length * 6;
37806
- labelMeasureCtx.font = "10px system-ui";
37198
+ labelMeasureCtx.font = "12px system-ui";
37807
37199
  return labelMeasureCtx.measureText(text).width;
37808
37200
  }
37809
37201
  function getGroupColor(group, groups) {
@@ -37849,6 +37241,7 @@ var init_GraphCanvas = __esm({
37849
37241
  actions,
37850
37242
  onNodeClick,
37851
37243
  onNodeDoubleClick,
37244
+ onBadgeClick,
37852
37245
  nodeClickEvent,
37853
37246
  selectedNodeId,
37854
37247
  repulsion = 800,
@@ -37966,7 +37359,7 @@ var init_GraphCanvas = __esm({
37966
37359
  nodesRef.current = simNodes;
37967
37360
  if (layout === "force") {
37968
37361
  let iterations = 0;
37969
- const maxIterations = 100;
37362
+ const maxIterations = 300;
37970
37363
  const tick = () => {
37971
37364
  const nodes = nodesRef.current;
37972
37365
  const centerX = w / 2;
@@ -37996,7 +37389,9 @@ var init_GraphCanvas = __esm({
37996
37389
  const dx = target.x - source.x;
37997
37390
  const dy = target.y - source.y;
37998
37391
  const dist = Math.sqrt(dx * dx + dy * dy) || 1;
37999
- const force = (dist - linkDistance) * 0.05;
37392
+ const w2 = Math.min(1, Math.max(0, edge.weight ?? 1));
37393
+ const linkTarget = linkDistance * (0.5 + (1 - w2) * 1.5);
37394
+ const force = (dist - linkTarget) * (0.04 + 0.1 * w2);
38000
37395
  const fx = dx / dist * force;
38001
37396
  const fy = dy / dist * force;
38002
37397
  source.fx += fx;
@@ -38004,9 +37399,27 @@ var init_GraphCanvas = __esm({
38004
37399
  target.fx -= fx;
38005
37400
  target.fy -= fy;
38006
37401
  }
37402
+ const centroids = /* @__PURE__ */ new Map();
37403
+ for (const node of nodes) {
37404
+ const g = node.group ?? "__none__";
37405
+ let c = centroids.get(g);
37406
+ if (!c) {
37407
+ c = { x: 0, y: 0, n: 0 };
37408
+ centroids.set(g, c);
37409
+ }
37410
+ c.x += node.x;
37411
+ c.y += node.y;
37412
+ c.n += 1;
37413
+ }
38007
37414
  for (const node of nodes) {
38008
- node.fx += (centerX - node.x) * 0.01;
38009
- node.fy += (centerY - node.y) * 0.01;
37415
+ const c = centroids.get(node.group ?? "__none__");
37416
+ if (c && c.n > 1) {
37417
+ node.fx += (c.x / c.n - node.x) * 0.04;
37418
+ node.fy += (c.y / c.n - node.y) * 0.04;
37419
+ } else {
37420
+ node.fx += (centerX - node.x) * 0.01;
37421
+ node.fy += (centerY - node.y) * 0.01;
37422
+ }
38010
37423
  }
38011
37424
  const damping = 0.9;
38012
37425
  for (const node of nodes) {
@@ -38018,7 +37431,7 @@ var init_GraphCanvas = __esm({
38018
37431
  node.y = Math.max(30, Math.min(h - 30, node.y));
38019
37432
  }
38020
37433
  const LABEL_GAP = 12;
38021
- const LABEL_H = 12;
37434
+ const LABEL_H = 16;
38022
37435
  const pad = nodeSpacing / 2;
38023
37436
  for (let i = 0; i < nodes.length; i++) {
38024
37437
  for (let j = i + 1; j < nodes.length; j++) {
@@ -38039,13 +37452,13 @@ var init_GraphCanvas = __esm({
38039
37452
  const overlapY = Math.min(aBot, bBot) - Math.max(aTop, bTop);
38040
37453
  if (overlapX > 0 && overlapY > 0) {
38041
37454
  if (overlapX <= overlapY) {
38042
- const push2 = overlapX / 2 * (b.x >= a.x ? 1 : -1);
38043
- a.x = Math.max(30, Math.min(w - 30, a.x - push2));
38044
- b.x = Math.max(30, Math.min(w - 30, b.x + push2));
37455
+ const push = overlapX / 2 * (b.x >= a.x ? 1 : -1);
37456
+ a.x = Math.max(30, Math.min(w - 30, a.x - push));
37457
+ b.x = Math.max(30, Math.min(w - 30, b.x + push));
38045
37458
  } else {
38046
- const push2 = overlapY / 2 * (bTop + bBot >= aTop + aBot ? 1 : -1);
38047
- a.y = Math.max(30, Math.min(h - 30, a.y - push2));
38048
- b.y = Math.max(30, Math.min(h - 30, b.y + push2));
37459
+ const push = overlapY / 2 * (bTop + bBot >= aTop + aBot ? 1 : -1);
37460
+ a.y = Math.max(30, Math.min(h - 30, a.y - push));
37461
+ b.y = Math.max(30, Math.min(h - 30, b.y + push));
38049
37462
  }
38050
37463
  }
38051
37464
  }
@@ -38073,6 +37486,11 @@ var init_GraphCanvas = __esm({
38073
37486
  const h = height;
38074
37487
  const nodes = nodesRef.current;
38075
37488
  const accentColor = resolveColor3("var(--color-accent)", canvas);
37489
+ const fontFamily = resolveColor3("var(--font-family)", canvas) || "system-ui";
37490
+ const fgColor = resolveColor3("var(--color-foreground)", canvas);
37491
+ const mutedColor = resolveColor3("var(--color-muted-foreground)", canvas) || fgColor;
37492
+ const bgColor = resolveColor3("var(--color-background)", canvas) || "#ffffff";
37493
+ const accentFg = resolveColor3("var(--color-accent-foreground)", canvas) || "#ffffff";
38076
37494
  const dpr = typeof window !== "undefined" && window.devicePixelRatio || 1;
38077
37495
  ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
38078
37496
  ctx.clearRect(0, 0, w, h);
@@ -38092,19 +37510,21 @@ var init_GraphCanvas = __esm({
38092
37510
  const target = nodes.find((n) => n.id === edge.target);
38093
37511
  if (!source || !target) continue;
38094
37512
  const incident = !!hoveredNode && (edge.source === hoveredNode || edge.target === hoveredNode);
38095
- ctx.globalAlpha = hoveredNode ? incident ? 1 : 0.05 : linkOpacity;
37513
+ const w2 = edge.weight ?? 1;
37514
+ ctx.globalAlpha = hoveredNode ? incident ? 1 : 0.05 : linkOpacity * w2;
38096
37515
  ctx.beginPath();
38097
37516
  ctx.moveTo(source.x, source.y);
38098
37517
  ctx.lineTo(target.x, target.y);
38099
37518
  ctx.strokeStyle = incident ? accentColor : edge.color || "#888888";
38100
- ctx.lineWidth = incident ? 2 : edge.weight ? Math.max(1, edge.weight) : 1;
37519
+ ctx.lineWidth = incident ? 2 : Math.max(0.75, w2);
38101
37520
  ctx.stroke();
38102
37521
  if (edge.label && showLabels) {
38103
37522
  const mx = (source.x + target.x) / 2;
38104
37523
  const my = (source.y + target.y) / 2;
38105
- ctx.fillStyle = "#888888";
38106
- ctx.font = "9px system-ui";
37524
+ ctx.fillStyle = mutedColor;
37525
+ ctx.font = `9px ${fontFamily}`;
38107
37526
  ctx.textAlign = "center";
37527
+ ctx.textBaseline = "alphabetic";
38108
37528
  ctx.fillText(edge.label, mx, my - 4);
38109
37529
  }
38110
37530
  }
@@ -38129,10 +37549,33 @@ var init_GraphCanvas = __esm({
38129
37549
  }
38130
37550
  ctx.stroke();
38131
37551
  if (showLabels && node.label) {
38132
- ctx.fillStyle = "#666666";
38133
- ctx.font = `${isSelected || isHovered ? "bold " : ""}10px system-ui`;
37552
+ ctx.font = `${isSelected || isHovered ? "600" : "500"} 12px ${fontFamily}`;
37553
+ ctx.textAlign = "center";
37554
+ ctx.textBaseline = "middle";
37555
+ const ly = node.y + radius + 14;
37556
+ ctx.lineWidth = 3;
37557
+ ctx.lineJoin = "round";
37558
+ ctx.strokeStyle = bgColor;
37559
+ ctx.strokeText(node.label, node.x, ly);
37560
+ ctx.fillStyle = isSelected || isHovered ? fgColor : mutedColor;
37561
+ ctx.fillText(node.label, node.x, ly);
37562
+ }
37563
+ if (node.badge && node.badge > 1) {
37564
+ const bx = node.x + radius * 0.7;
37565
+ const by = node.y - radius * 0.7;
37566
+ const br = Math.max(7, Math.min(11, radius * 0.45));
37567
+ ctx.beginPath();
37568
+ ctx.arc(bx, by, br, 0, Math.PI * 2);
37569
+ ctx.fillStyle = accentColor;
37570
+ ctx.fill();
37571
+ ctx.strokeStyle = bgColor;
37572
+ ctx.lineWidth = 2;
37573
+ ctx.stroke();
37574
+ ctx.fillStyle = accentFg;
37575
+ ctx.font = `600 9px ${fontFamily}`;
38134
37576
  ctx.textAlign = "center";
38135
- ctx.fillText(node.label, node.x, node.y + radius + 12);
37577
+ ctx.textBaseline = "middle";
37578
+ ctx.fillText(String(node.badge), bx, by + 0.5);
38136
37579
  }
38137
37580
  }
38138
37581
  ctx.restore();
@@ -38225,11 +37668,21 @@ var init_GraphCanvas = __esm({
38225
37668
  if (!coords) return;
38226
37669
  const node = nodeAt(coords.graphX, coords.graphY);
38227
37670
  if (node) {
37671
+ if (node.badge && node.badge > 1 && onBadgeClick) {
37672
+ const r2 = (node.size || 8) + (selectedNodeId === node.id ? 4 : 0);
37673
+ const bx = node.x + r2 * 0.7;
37674
+ const by = node.y - r2 * 0.7;
37675
+ const br = Math.max(7, Math.min(11, r2 * 0.45)) + 3;
37676
+ if (Math.hypot(coords.graphX - bx, coords.graphY - by) <= br) {
37677
+ onBadgeClick(node);
37678
+ return;
37679
+ }
37680
+ }
38228
37681
  handleNodeClick(node);
38229
37682
  }
38230
37683
  }
38231
37684
  },
38232
- [toCoords, nodeAt, handleNodeClick]
37685
+ [toCoords, nodeAt, handleNodeClick, onBadgeClick, selectedNodeId]
38233
37686
  );
38234
37687
  const handlePointerLeave = useCallback(() => {
38235
37688
  setHoveredNode(null);
@@ -42750,7 +42203,7 @@ function getAllEvents(traits2) {
42750
42203
  function EventDispatcherTab({ traits: traits2, schema }) {
42751
42204
  const eventBus = useEventBus();
42752
42205
  const { t } = useTranslate();
42753
- const [log12, setLog] = React90.useState([]);
42206
+ const [log11, setLog] = React90.useState([]);
42754
42207
  const prevStatesRef = React90.useRef(/* @__PURE__ */ new Map());
42755
42208
  React90.useEffect(() => {
42756
42209
  for (const trait of traits2) {
@@ -42814,9 +42267,9 @@ function EventDispatcherTab({ traits: traits2, schema }) {
42814
42267
  /* @__PURE__ */ jsx(Typography, { variant: "small", weight: "medium", className: "text-gray-500 mb-1", children: t("debug.otherEvents") }),
42815
42268
  /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-1", children: unavailableEvents.map((event) => /* @__PURE__ */ jsx(Badge, { variant: "default", size: "sm", className: "opacity-50", children: event }, event)) })
42816
42269
  ] }),
42817
- log12.length > 0 && /* @__PURE__ */ jsxs("div", { children: [
42270
+ log11.length > 0 && /* @__PURE__ */ jsxs("div", { children: [
42818
42271
  /* @__PURE__ */ jsx(Typography, { variant: "small", weight: "medium", className: "text-gray-500 mb-1", children: t("debug.recentTransitions") }),
42819
- /* @__PURE__ */ jsx(Stack, { gap: "xs", children: log12.map((entry, i) => /* @__PURE__ */ jsxs(Typography, { variant: "small", className: "font-mono text-xs", children: [
42272
+ /* @__PURE__ */ jsx(Stack, { gap: "xs", children: log11.map((entry, i) => /* @__PURE__ */ jsxs(Typography, { variant: "small", className: "font-mono text-xs", children: [
42820
42273
  /* @__PURE__ */ jsx("span", { className: "text-purple-400", children: entry.traitName }),
42821
42274
  " ",
42822
42275
  /* @__PURE__ */ jsx("span", { className: "text-gray-500", children: entry.from }),
@@ -49820,85 +49273,12 @@ function useResolvedSchema(schema, pageName) {
49820
49273
  }, [ir, pageName, loading, error, schema]);
49821
49274
  return result;
49822
49275
  }
49823
-
49824
- // lib/embedded-traits.ts
49825
- var TRAIT_BINDING_PREFIX = "@trait.";
49826
- function collectTraitRefsFromValue(value, into) {
49827
- if (value === null || value === void 0) return;
49828
- if (typeof value === "string") {
49829
- if (value.startsWith(TRAIT_BINDING_PREFIX)) {
49830
- const rest = value.slice(TRAIT_BINDING_PREFIX.length);
49831
- const dot = rest.indexOf(".");
49832
- const traitName = dot === -1 ? rest : rest.slice(0, dot);
49833
- if (traitName.length > 0) into.add(traitName);
49834
- }
49835
- return;
49836
- }
49837
- if (Array.isArray(value)) {
49838
- for (const item of value) collectTraitRefsFromValue(item, into);
49839
- return;
49840
- }
49841
- if (typeof value === "object") {
49842
- for (const v of Object.values(value)) {
49843
- collectTraitRefsFromValue(v, into);
49844
- }
49845
- }
49846
- }
49847
- function collectTraitRefsFromEffects(effects, into) {
49848
- if (!effects) return;
49849
- for (const effect of effects) {
49850
- if (!Array.isArray(effect)) continue;
49851
- if (effect[0] === "render-ui" && effect.length >= 3) {
49852
- collectTraitRefsFromValue(effect[2], into);
49853
- continue;
49854
- }
49855
- for (let i = 1; i < effect.length; i++) {
49856
- const arg = effect[i];
49857
- if (Array.isArray(arg)) collectTraitRefsFromEffects([arg], into);
49858
- else collectTraitRefsFromValue(arg, into);
49859
- }
49860
- }
49861
- }
49862
- function collectTraitRefsFromResolvedTrait(trait) {
49863
- const out = /* @__PURE__ */ new Set();
49864
- for (const transition of trait.transitions ?? []) {
49865
- collectTraitRefsFromEffects(transition.effects, out);
49866
- }
49867
- for (const tick of trait.ticks ?? []) {
49868
- collectTraitRefsFromEffects(tick.effects, out);
49869
- }
49870
- return out;
49871
- }
49872
- function collectEmbeddedTraits(schema) {
49873
- const out = /* @__PURE__ */ new Set();
49874
- if (!schema?.orbitals) return out;
49875
- for (const orbital of schema.orbitals) {
49876
- const traits2 = orbital.traits;
49877
- if (!Array.isArray(traits2)) continue;
49878
- for (const traitRef of traits2) {
49879
- if (!traitRef || typeof traitRef !== "object") continue;
49880
- const resolved = traitRef._resolved;
49881
- const target = resolved && typeof resolved === "object" ? resolved : traitRef;
49882
- if (target.config) {
49883
- collectTraitRefsFromValue(target.config, out);
49884
- }
49885
- const transitions = target.stateMachine?.transitions;
49886
- if (!Array.isArray(transitions)) continue;
49887
- for (const t of transitions) {
49888
- collectTraitRefsFromEffects(t.effects, out);
49889
- }
49890
- collectTraitRefsFromEffects(target.initialEffects, out);
49891
- const ticks2 = target.ticks;
49892
- if (Array.isArray(ticks2)) {
49893
- for (const tick of ticks2) {
49894
- collectTraitRefsFromEffects(tick.effects, out);
49895
- }
49896
- }
49897
- }
49898
- }
49899
- return out;
49900
- }
49901
49276
  var lambdaLog = createLogger("almadar:ui:fn-form-lambda");
49277
+ function isOperatorCall(value) {
49278
+ const first = value[0];
49279
+ if (typeof first !== "string") return false;
49280
+ return isKnownStdOperator(first) || first.includes("/") || first === "lambda" || first === "let";
49281
+ }
49902
49282
  function isFnFormLambda(value) {
49903
49283
  if (!Array.isArray(value)) return false;
49904
49284
  const arr = value;
@@ -49938,7 +49318,14 @@ function resolveLambdaBindings(body, params, item, index) {
49938
49318
  return body;
49939
49319
  }
49940
49320
  if (Array.isArray(body)) {
49941
- return body.map((b) => recur(b));
49321
+ if (isFnFormLambda(body)) return body;
49322
+ const arr = body;
49323
+ const substituted = arr.map((b) => recur(b));
49324
+ if (isOperatorCall(substituted) && isSExpr(substituted)) {
49325
+ const evaluated = evaluate(substituted, createMinimalContext());
49326
+ return isEventPayloadValue(evaluated) ? evaluated : String(evaluated);
49327
+ }
49328
+ return substituted;
49942
49329
  }
49943
49330
  if (body !== null && typeof body === "object" && !React90__default.isValidElement(body) && !(body instanceof Date) && typeof body !== "function") {
49944
49331
  const out = {};
@@ -50031,27 +49418,27 @@ var log7 = createLogger("almadar:ui:shared-entity-store");
50031
49418
  var EMPTY_ENTITY_STATE = {};
50032
49419
  function createSharedEntityStore() {
50033
49420
  const states = /* @__PURE__ */ new Map();
50034
- const subscribers2 = /* @__PURE__ */ new Map();
49421
+ const subscribers = /* @__PURE__ */ new Map();
50035
49422
  const getSnapshot2 = (entityId) => states.get(entityId) ?? EMPTY_ENTITY_STATE;
50036
49423
  const subscribe = (entityId, callback) => {
50037
- let set = subscribers2.get(entityId);
49424
+ let set = subscribers.get(entityId);
50038
49425
  if (!set) {
50039
49426
  set = /* @__PURE__ */ new Set();
50040
- subscribers2.set(entityId, set);
49427
+ subscribers.set(entityId, set);
50041
49428
  }
50042
49429
  set.add(callback);
50043
49430
  return () => {
50044
- const current = subscribers2.get(entityId);
49431
+ const current = subscribers.get(entityId);
50045
49432
  if (!current) return;
50046
49433
  current.delete(callback);
50047
49434
  if (current.size === 0) {
50048
- subscribers2.delete(entityId);
49435
+ subscribers.delete(entityId);
50049
49436
  }
50050
49437
  };
50051
49438
  };
50052
49439
  const commit = (entityId, nextState) => {
50053
49440
  states.set(entityId, nextState);
50054
- const set = subscribers2.get(entityId);
49441
+ const set = subscribers.get(entityId);
50055
49442
  if (!set) return;
50056
49443
  set.forEach((callback) => {
50057
49444
  try {
@@ -50255,8 +49642,8 @@ function getBindingConfig(binding) {
50255
49642
  function evalFieldDefault(value) {
50256
49643
  if (!Array.isArray(value) || value.length === 0) return value;
50257
49644
  const head = value[0];
50258
- const isSExpr = typeof head === "string" && (head.includes("/") || head === "let" || head === "if" || head === "lambda");
50259
- if (!isSExpr) return value;
49645
+ const isSExpr2 = typeof head === "string" && (head.includes("/") || head === "let" || head === "if" || head === "lambda");
49646
+ if (!isSExpr2) return value;
50260
49647
  try {
50261
49648
  return evaluate(value, createMinimalContext({}, {}, ""));
50262
49649
  } catch {
@@ -50330,7 +49717,9 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
50330
49717
  const traitDefs = traitBindings.map(toTraitDefinition);
50331
49718
  const m = new StateMachineManager(traitDefs);
50332
49719
  for (const binding of traitBindings) {
50333
- const cfg = getBindingConfig(binding) ?? traitConfigsByName?.[binding.trait.name];
49720
+ const rawCfg = getBindingConfig(binding);
49721
+ const resolvedCfg = traitConfigsByName?.[binding.trait.name];
49722
+ const cfg = rawCfg || resolvedCfg ? { ...rawCfg ?? {}, ...resolvedCfg ?? {} } : void 0;
50334
49723
  if (cfg !== void 0) {
50335
49724
  m.setTraitConfig(binding.trait.name, cfg);
50336
49725
  }
@@ -50508,7 +49897,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
50508
49897
  };
50509
49898
  }, [traitBindings]);
50510
49899
  const executeTransitionEffects = useCallback(async (params) => {
50511
- const { binding, previousState, newState, payload, flushEvent, syncOnly, log: log12 } = params;
49900
+ const { binding, previousState, newState, payload, flushEvent, syncOnly, log: log11 } = params;
50512
49901
  const traitName = binding.trait.name;
50513
49902
  const linkedEntity = binding.linkedEntity || "";
50514
49903
  const entityId = payload?.entityId;
@@ -50582,10 +49971,20 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
50582
49971
  state: previousState
50583
49972
  };
50584
49973
  const sharedDeclared = collectDeclaredConfigDefaults(binding.trait);
50585
- const sharedCallSite = getBindingConfig(binding);
50586
- if (sharedDeclared || sharedCallSite) {
49974
+ const sharedResolved = traitConfigsByName?.[traitName];
49975
+ const sharedCallSiteRaw = getBindingConfig(binding);
49976
+ const sharedCallSite = sharedCallSiteRaw ? resolveCallSitePayloadCaptures(
49977
+ Object.fromEntries(
49978
+ Object.entries(sharedCallSiteRaw).filter(
49979
+ ([, v]) => !(typeof v === "string" && v.startsWith("@config."))
49980
+ )
49981
+ ),
49982
+ payload || {}
49983
+ ) : void 0;
49984
+ if (sharedDeclared || sharedResolved || sharedCallSite) {
50587
49985
  sharedBindings.config = {
50588
49986
  ...sharedDeclared ?? {},
49987
+ ...sharedResolved ?? {},
50589
49988
  ...sharedCallSite ?? {}
50590
49989
  };
50591
49990
  }
@@ -50619,7 +50018,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
50619
50018
  ...handlers,
50620
50019
  set: async (targetId, field, value) => {
50621
50020
  if (baseSet) await baseSet(targetId, field, value);
50622
- log12.debug("set:write", {
50021
+ log11.debug("set:write", {
50623
50022
  traitName,
50624
50023
  field,
50625
50024
  value: JSON.stringify(value),
@@ -50633,11 +50032,21 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
50633
50032
  state: previousState
50634
50033
  };
50635
50034
  const declaredDefaults = collectDeclaredConfigDefaults(binding.trait);
50035
+ const resolvedDefaults = traitConfigsByName?.[traitName];
50636
50036
  const callSiteConfig = getBindingConfig(binding);
50637
- if (declaredDefaults || callSiteConfig) {
50037
+ const callSiteOverrides = callSiteConfig ? resolveCallSitePayloadCaptures(
50038
+ Object.fromEntries(
50039
+ Object.entries(callSiteConfig).filter(
50040
+ ([, v]) => !(typeof v === "string" && v.startsWith("@config."))
50041
+ )
50042
+ ),
50043
+ payload || {}
50044
+ ) : void 0;
50045
+ if (declaredDefaults || resolvedDefaults || callSiteOverrides) {
50638
50046
  bindingCtx.config = {
50639
50047
  ...declaredDefaults ?? {},
50640
- ...callSiteConfig ?? {}
50048
+ ...resolvedDefaults ?? {},
50049
+ ...callSiteOverrides ?? {}
50641
50050
  };
50642
50051
  }
50643
50052
  if (traitName === "Authority" || traitName === "Hero") {
@@ -50686,7 +50095,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
50686
50095
  if (sharedKey !== void 0) {
50687
50096
  sharedEntityStore.commit(sharedKey, liveEntity);
50688
50097
  }
50689
- log12.debug("effects:executed", () => ({
50098
+ log11.debug("effects:executed", () => ({
50690
50099
  traitName,
50691
50100
  transition: `${previousState}->${newState}`,
50692
50101
  event: flushEvent,
@@ -50696,7 +50105,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
50696
50105
  slotsTouched: Array.from(pendingSlots.keys()).join(",")
50697
50106
  }));
50698
50107
  for (const [slot, patterns] of pendingSlots) {
50699
- log12.debug("flush:slot", {
50108
+ log11.debug("flush:slot", {
50700
50109
  traitName,
50701
50110
  slot,
50702
50111
  patternCount: patterns.length,
@@ -50711,7 +50120,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
50711
50120
  });
50712
50121
  }
50713
50122
  } catch (error) {
50714
- log12.error("effects:error", {
50123
+ log11.error("effects:error", {
50715
50124
  traitName,
50716
50125
  transition: `${previousState}->${newState}`,
50717
50126
  event: flushEvent,
@@ -50733,7 +50142,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
50733
50142
  payload: {},
50734
50143
  state: currentState
50735
50144
  };
50736
- const bindingCfg = getBindingConfig(binding);
50145
+ const bindingCfg = getBindingConfig(binding) ?? traitConfigsByName?.[traitName];
50737
50146
  if (bindingCfg) {
50738
50147
  guardCtx.config = bindingCfg;
50739
50148
  }
@@ -51096,17 +50505,19 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
51096
50505
  }, [traitBindings, eventBus, enqueueAndDrain]);
51097
50506
  useEffect(() => {
51098
50507
  const mgr = managerRef.current;
51099
- const inited = initedTraitsRef.current;
50508
+ const eventsToFire = /* @__PURE__ */ new Set();
51100
50509
  for (const binding of traitBindings) {
51101
50510
  const traitName = binding.trait.name;
51102
- if (inited.has(traitName)) continue;
51103
50511
  const lifecycleEvent = LIFECYCLE_EVENTS.find(
51104
50512
  (evt) => mgr.canHandleEvent(traitName, evt)
51105
50513
  );
51106
- if (lifecycleEvent === void 0) continue;
51107
- inited.add(traitName);
51108
- stateLog.debug("mount:fire-lifecycle", { traitName, event: lifecycleEvent });
51109
- enqueueAndDrain(lifecycleEvent, {});
50514
+ if (lifecycleEvent !== void 0) {
50515
+ eventsToFire.add(lifecycleEvent);
50516
+ }
50517
+ }
50518
+ for (const event of eventsToFire) {
50519
+ stateLog.debug("mount:fire-lifecycle", { event, traitCount: traitBindings.length });
50520
+ enqueueAndDrain(event, {});
51110
50521
  }
51111
50522
  return () => {
51112
50523
  initedTraitsRef.current = /* @__PURE__ */ new Set();
@@ -51120,228 +50531,8 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
51120
50531
  };
51121
50532
  }
51122
50533
 
51123
- // lib/orbitalsByTrait.ts
51124
- function buildOrbitalsByTrait(schema, resolvedPages = []) {
51125
- const map = {};
51126
- if (!schema?.orbitals) return map;
51127
- const pagePathToOrbital = {};
51128
- for (const orb of schema.orbitals) {
51129
- for (const traitRef of orb.traits ?? []) {
51130
- let traitName;
51131
- if (typeof traitRef === "string") {
51132
- const parts = traitRef.split(".");
51133
- traitName = parts[parts.length - 1];
51134
- } else if (typeof traitRef.ref === "string") {
51135
- const parts = traitRef.ref.split(".");
51136
- traitName = traitRef.name ?? parts[parts.length - 1];
51137
- } else if (typeof traitRef.name === "string") {
51138
- traitName = traitRef.name;
51139
- }
51140
- if (traitName) map[traitName] = orb.name;
51141
- }
51142
- for (const pg of orb.pages ?? []) {
51143
- const path = typeof pg === "string" ? pg : pg?.path;
51144
- if (path) pagePathToOrbital[path] = orb.name;
51145
- }
51146
- }
51147
- for (const page of resolvedPages) {
51148
- const orbital = page.path ? pagePathToOrbital[page.path] : void 0;
51149
- if (!orbital) continue;
51150
- for (const traitName of page.traitNames) {
51151
- if (traitName && !(traitName in map)) map[traitName] = orbital;
51152
- }
51153
- }
51154
- return map;
51155
- }
51156
-
51157
50534
  // runtime/OrbPreview.tsx
51158
50535
  init_verificationRegistry();
51159
- var PERF_NAMESPACE = "almadar:perf:canvas";
51160
- var log9 = createLogger(PERF_NAMESPACE);
51161
- var RING_SIZE = 50;
51162
- var ring = [];
51163
- var writeIdx = 0;
51164
- var subscribers = /* @__PURE__ */ new Set();
51165
- var notifyScheduled = false;
51166
- function scheduleNotify() {
51167
- if (notifyScheduled) return;
51168
- notifyScheduled = true;
51169
- queueMicrotask(() => {
51170
- notifyScheduled = false;
51171
- for (const fn of subscribers) fn();
51172
- });
51173
- }
51174
- function push(entry) {
51175
- if (ring.length < RING_SIZE) {
51176
- ring.push(entry);
51177
- } else {
51178
- ring[writeIdx] = entry;
51179
- }
51180
- writeIdx = (writeIdx + 1) % RING_SIZE;
51181
- scheduleNotify();
51182
- }
51183
- function isEnabled() {
51184
- return isLogLevelEnabled("DEBUG", PERF_NAMESPACE);
51185
- }
51186
- function now() {
51187
- return typeof performance !== "undefined" && typeof performance.now === "function" ? performance.now() : Date.now();
51188
- }
51189
- function perfStart(name) {
51190
- if (!isEnabled()) return -1;
51191
- if (typeof performance !== "undefined" && typeof performance.mark === "function") {
51192
- try {
51193
- performance.mark(`${name}-start`);
51194
- } catch {
51195
- }
51196
- }
51197
- return now();
51198
- }
51199
- function perfEnd(name, startToken, detail) {
51200
- if (startToken < 0 || !isEnabled()) return;
51201
- const endTs = now();
51202
- const durationMs = endTs - startToken;
51203
- if (typeof performance !== "undefined" && typeof performance.measure === "function") {
51204
- try {
51205
- performance.mark(`${name}-end`);
51206
- performance.measure(name, `${name}-start`, `${name}-end`);
51207
- } catch {
51208
- }
51209
- }
51210
- push({ name, durationMs, ts: endTs, detail });
51211
- log9.debug(name, () => ({ durationMs, ...detail ?? {} }));
51212
- }
51213
- var profilerOnRender = (id, phase, actualDuration, baseDuration, _startTime, commitTime) => {
51214
- if (!isEnabled()) return;
51215
- push({
51216
- name: `profiler:${id}:${phase}`,
51217
- durationMs: actualDuration,
51218
- ts: commitTime,
51219
- detail: { baseDuration }
51220
- });
51221
- log9.debug(`profiler:${id}:${phase}`, () => ({ actualDuration, baseDuration }));
51222
- };
51223
-
51224
- // lib/prepareSchemaForPreview.ts
51225
- function generateEntityRow(entity, idx) {
51226
- const row = { id: String(idx) };
51227
- for (const f3 of entity.fields) {
51228
- if (f3.name === void 0 || f3.name === "id") continue;
51229
- row[f3.name] = generateFieldValue(entity.name, f3, idx);
51230
- }
51231
- return row;
51232
- }
51233
- function generateFieldValue(entityName, field, idx) {
51234
- if ("values" in field && field.values && field.values.length > 0) {
51235
- return field.values[(idx - 1) % field.values.length];
51236
- }
51237
- const fieldName = field.name ?? "";
51238
- switch (field.type) {
51239
- case "string":
51240
- return `${entityName} ${fieldName.charAt(0).toUpperCase() + fieldName.slice(1)} ${idx}`;
51241
- case "number":
51242
- return idx * 10;
51243
- case "boolean":
51244
- return idx % 2 === 0;
51245
- default:
51246
- return field.default ?? null;
51247
- }
51248
- }
51249
- function buildMockData(schema) {
51250
- const t = perfStart("build-mock-data");
51251
- const result = {};
51252
- for (const orbital of schema.orbitals) {
51253
- const entity = orbital.entity;
51254
- if (!entity || typeof entity === "string") continue;
51255
- if (isEntityCall(entity)) continue;
51256
- const entityName = entity.name;
51257
- if (!entityName) continue;
51258
- if (entity.instances && entity.instances.length > 0) {
51259
- result[entityName] = entity.instances;
51260
- continue;
51261
- }
51262
- const rows = Array.from(
51263
- { length: 10 },
51264
- (_, i) => generateEntityRow(entity, i + 1)
51265
- );
51266
- result[entityName] = rows;
51267
- }
51268
- for (const orbital of schema.orbitals) {
51269
- for (const traitRef of orbital.traits ?? []) {
51270
- if (!isInlineTrait3(traitRef)) continue;
51271
- const trait = traitRef;
51272
- const sourceEntity = trait.sourceEntityDefinition;
51273
- if (!sourceEntity || isEntityCall(sourceEntity)) continue;
51274
- const sourceName = sourceEntity.name;
51275
- if (!sourceName) continue;
51276
- if (!result[sourceName]) {
51277
- result[sourceName] = sourceEntity.instances && sourceEntity.instances.length > 0 ? sourceEntity.instances : Array.from(
51278
- { length: 10 },
51279
- (_, i) => generateEntityRow(sourceEntity, i + 1)
51280
- );
51281
- }
51282
- const reboundName = trait.linkedEntity;
51283
- if (!reboundName || reboundName === sourceName) continue;
51284
- const reboundRows = result[reboundName];
51285
- if (!reboundRows || reboundRows.length === 0) continue;
51286
- reboundRows.forEach((row, i) => {
51287
- for (const f3 of sourceEntity.fields) {
51288
- if (f3.name === void 0 || f3.name === "id") continue;
51289
- if (row[f3.name] !== void 0) continue;
51290
- row[f3.name] = generateFieldValue(sourceName, f3, i + 1);
51291
- }
51292
- });
51293
- }
51294
- }
51295
- perfEnd("build-mock-data", t, { orbitalCount: schema.orbitals.length, entityCount: Object.keys(result).length });
51296
- return result;
51297
- }
51298
- function isInlineTrait3(traitRef) {
51299
- return typeof traitRef === "object" && traitRef !== null && "stateMachine" in traitRef;
51300
- }
51301
- function findDataState(sm, initialStateName) {
51302
- return sm.states.find((s) => {
51303
- if (s.name === initialStateName) return false;
51304
- return sm.transitions.some(
51305
- (t) => t.event === "INIT" && (t.from === s.name || Array.isArray(t.from) && t.from.includes(s.name))
51306
- );
51307
- });
51308
- }
51309
- function rewriteTraitInitialState(trait, mockData) {
51310
- const sm = trait.stateMachine;
51311
- if (!sm) return trait;
51312
- const linkedEntity = trait.linkedEntity;
51313
- if (!linkedEntity || !mockData[linkedEntity]?.length) return trait;
51314
- const initialStateName = sm.states.find((s) => s.isInitial)?.name ?? sm.states[0]?.name;
51315
- if (!initialStateName) return trait;
51316
- const dataState = findDataState(sm, initialStateName);
51317
- if (!dataState) return trait;
51318
- const updatedStates = sm.states.map((s) => {
51319
- if (s.name === initialStateName) return { ...s, isInitial: false };
51320
- if (s.name === dataState.name) return { ...s, isInitial: true };
51321
- return s;
51322
- });
51323
- return { ...trait, stateMachine: { ...sm, states: updatedStates } };
51324
- }
51325
- function adjustSchemaForMockData(schema, mockData) {
51326
- let changed = false;
51327
- const updatedOrbitals = schema.orbitals.map((orbital) => {
51328
- const traits2 = orbital.traits ?? [];
51329
- const updatedTraits = traits2.map((traitRef) => {
51330
- if (!isInlineTrait3(traitRef)) return traitRef;
51331
- const updated = rewriteTraitInitialState(traitRef, mockData);
51332
- if (updated !== traitRef) changed = true;
51333
- return updated;
51334
- });
51335
- return changed ? { ...orbital, traits: updatedTraits } : orbital;
51336
- });
51337
- return changed ? { ...schema, orbitals: updatedOrbitals } : schema;
51338
- }
51339
- function prepareSchemaForPreview(input) {
51340
- const parsed = typeof input === "string" ? JSON.parse(input) : input;
51341
- const mockData = buildMockData(parsed);
51342
- const schema = adjustSchemaForMockData(parsed, mockData);
51343
- return { schema, mockData };
51344
- }
51345
50536
  var xOrbitalLog = createLogger("almadar:runtime:cross-orbital");
51346
50537
  var navLog = createLogger("almadar:runtime:navigation");
51347
50538
  function normalizeChild(child) {
@@ -51575,24 +50766,10 @@ function SchemaRunner({ schema, serverUrl, transport, mockData, pageName, onNavi
51575
50766
  pageOrbitalNames: pageOrbitalNames.join(",")
51576
50767
  });
51577
50768
  }, [pageName, allPageTraits, orbitalsByTrait, pageOrbitalNames]);
51578
- const traitConfigsByName = useMemo(() => {
51579
- const map = {};
51580
- const orbitals = schema?.orbitals;
51581
- if (!orbitals) return map;
51582
- for (const orb of orbitals) {
51583
- const traitRefs = orb.traits;
51584
- if (!traitRefs) continue;
51585
- for (const t of traitRefs) {
51586
- if (typeof t === "string") continue;
51587
- const name = t.name ?? t.ref;
51588
- const config = t.config;
51589
- if (typeof name === "string" && config !== void 0) {
51590
- map[name] = config;
51591
- }
51592
- }
51593
- }
51594
- return map;
51595
- }, [schema]);
50769
+ const traitConfigsByName = useMemo(
50770
+ () => buildResolvedTraitConfigs(schema),
50771
+ [schema]
50772
+ );
51596
50773
  const embeddedTraits = useMemo(() => {
51597
50774
  const set = collectEmbeddedTraits(schema);
51598
50775
  xOrbitalLog.info("SchemaRunner:embeddedTraits", {
@@ -51861,7 +51038,7 @@ init_useEventBus();
51861
51038
  // components/avl/hooks/useCanvasDnd.tsx
51862
51039
  init_useEventBus();
51863
51040
  init_useAlmadarDndCollision();
51864
- var log10 = createLogger("almadar:ui:canvas-dnd");
51041
+ var log9 = createLogger("almadar:ui:canvas-dnd");
51865
51042
  function useCanvasDraggable({
51866
51043
  id,
51867
51044
  payload,
@@ -51900,7 +51077,7 @@ function defaultEmit(eventBus, drop) {
51900
51077
  if (payload.kind === "pattern") {
51901
51078
  const patternType = payload.data["type"];
51902
51079
  if (typeof patternType !== "string") {
51903
- log10.warn("default-emit:pattern:missing-type");
51080
+ log9.warn("default-emit:pattern:missing-type");
51904
51081
  return;
51905
51082
  }
51906
51083
  const out = { patternType, containerNode: target.containerNode };
@@ -51909,23 +51086,23 @@ function defaultEmit(eventBus, drop) {
51909
51086
  out.index = resolved.index;
51910
51087
  }
51911
51088
  eventBus.emit("UI:PATTERN_DROP", out);
51912
- log10.info("default-emit:pattern", { patternType, level: target.level });
51089
+ log9.info("default-emit:pattern", { patternType, level: target.level });
51913
51090
  return;
51914
51091
  }
51915
51092
  if (payload.kind === "behavior") {
51916
51093
  const behaviorName = payload.data["name"];
51917
51094
  if (typeof behaviorName !== "string") {
51918
- log10.warn("default-emit:behavior:missing-name");
51095
+ log9.warn("default-emit:behavior:missing-name");
51919
51096
  return;
51920
51097
  }
51921
51098
  eventBus.emit("UI:BEHAVIOR_DROP", {
51922
51099
  behaviorName,
51923
51100
  containerNode: target.containerNode
51924
51101
  });
51925
- log10.info("default-emit:behavior", { behaviorName, level: target.level });
51102
+ log9.info("default-emit:behavior", { behaviorName, level: target.level });
51926
51103
  return;
51927
51104
  }
51928
- log10.debug("default-emit:unhandled-kind", { kind: payload.kind });
51105
+ log9.debug("default-emit:unhandled-kind", { kind: payload.kind });
51929
51106
  }
51930
51107
  function CanvasDndProvider({
51931
51108
  children,
@@ -51941,9 +51118,9 @@ function CanvasDndProvider({
51941
51118
  if (payload) {
51942
51119
  setActivePayload(payload);
51943
51120
  eventBus.emit("UI:DRAG_START", { kind: payload.kind, data: payload.data });
51944
- log10.info("dragStart", { id: e.active.id, kind: payload.kind });
51121
+ log9.info("dragStart", { id: e.active.id, kind: payload.kind });
51945
51122
  } else {
51946
- log10.warn("dragStart:missing-payload", { id: e.active.id });
51123
+ log9.warn("dragStart:missing-payload", { id: e.active.id });
51947
51124
  }
51948
51125
  }, [eventBus]);
51949
51126
  const handleDragEnd = React90__default.useCallback((e) => {
@@ -51953,7 +51130,7 @@ function CanvasDndProvider({
51953
51130
  const overData = e.over?.data.current;
51954
51131
  const target = overData?.target;
51955
51132
  const accepts = overData?.accepts;
51956
- log10.info("dragEnd", {
51133
+ log9.info("dragEnd", {
51957
51134
  activeId: e.active.id,
51958
51135
  overId: e.over?.id,
51959
51136
  hasPayload: !!payload,
@@ -51965,7 +51142,7 @@ function CanvasDndProvider({
51965
51142
  }
51966
51143
  if (!payload || !target) return;
51967
51144
  if (accepts && !accepts.includes(payload.kind)) {
51968
- log10.debug("dragEnd:rejected:kind", { kind: payload.kind, accepts: [...accepts] });
51145
+ log9.debug("dragEnd:rejected:kind", { kind: payload.kind, accepts: [...accepts] });
51969
51146
  return;
51970
51147
  }
51971
51148
  const activator = e.activatorEvent;
@@ -51977,7 +51154,7 @@ function CanvasDndProvider({
51977
51154
  }, [eventBus, onDrop]);
51978
51155
  const handleDragCancel = React90__default.useCallback(() => {
51979
51156
  setActivePayload(null);
51980
- log10.info("dragCancel");
51157
+ log9.info("dragCancel");
51981
51158
  }, []);
51982
51159
  return /* @__PURE__ */ jsxs(
51983
51160
  DndContext,
@@ -53810,7 +52987,7 @@ init_AvlTransitionLane();
53810
52987
  init_AvlSwimLane();
53811
52988
  init_avl_atom_types();
53812
52989
  init_avl_elk_layout();
53813
- var log11 = createLogger("almadar:ui:avl:trait-scene");
52990
+ var log10 = createLogger("almadar:ui:avl:trait-scene");
53814
52991
  var SWIM_GUTTER2 = 120;
53815
52992
  var CENTER_W2 = 360;
53816
52993
  var AvlTraitScene = ({
@@ -53823,7 +53000,7 @@ var AvlTraitScene = ({
53823
53000
  const dataKey = useMemo(() => JSON.stringify(data), [data]);
53824
53001
  useEffect(() => {
53825
53002
  computeTraitLayout(data).then(setLayout).catch((error) => {
53826
- log11.error("computeTraitLayout failed", { error: error instanceof Error ? error : String(error) });
53003
+ log10.error("computeTraitLayout failed", { error: error instanceof Error ? error : String(error) });
53827
53004
  });
53828
53005
  }, [dataKey]);
53829
53006
  if (!layout) {
@@ -54016,6 +53193,14 @@ TraitCardNode.displayName = "TraitCardNode";
54016
53193
 
54017
53194
  // components/avl/organisms/FlowCanvas.tsx
54018
53195
  init_useEventBus();
53196
+ var profilerOnRender = (id, phase, actualDuration, baseDuration, _startTime, commitTime) => {
53197
+ pushPerfEntry({
53198
+ name: `profiler:${id}:${phase}`,
53199
+ durationMs: actualDuration,
53200
+ ts: commitTime,
53201
+ detail: { baseDuration }
53202
+ });
53203
+ };
54019
53204
  var flowCanvasLog = createLogger("almadar:ui:flow-canvas");
54020
53205
  var NODE_TYPES = {
54021
53206
  preview: OrbPreviewNode,