schematex 0.1.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 (181) hide show
  1. package/LICENSE +661 -0
  2. package/README.md +379 -0
  3. package/dist/chunk-2MQWZ2XY.cjs +453 -0
  4. package/dist/chunk-2MQWZ2XY.cjs.map +1 -0
  5. package/dist/chunk-2UKC6ZCY.cjs +1803 -0
  6. package/dist/chunk-2UKC6ZCY.cjs.map +1 -0
  7. package/dist/chunk-34X3ZJ6E.cjs +783 -0
  8. package/dist/chunk-34X3ZJ6E.cjs.map +1 -0
  9. package/dist/chunk-3FTUWAXK.cjs +1220 -0
  10. package/dist/chunk-3FTUWAXK.cjs.map +1 -0
  11. package/dist/chunk-3J7TFUOC.js +745 -0
  12. package/dist/chunk-3J7TFUOC.js.map +1 -0
  13. package/dist/chunk-47ZC6EMJ.js +1009 -0
  14. package/dist/chunk-47ZC6EMJ.js.map +1 -0
  15. package/dist/chunk-4DBRNOPA.cjs +750 -0
  16. package/dist/chunk-4DBRNOPA.cjs.map +1 -0
  17. package/dist/chunk-4G7ZIBHN.js +778 -0
  18. package/dist/chunk-4G7ZIBHN.js.map +1 -0
  19. package/dist/chunk-5C7DPDHQ.js +1321 -0
  20. package/dist/chunk-5C7DPDHQ.js.map +1 -0
  21. package/dist/chunk-ADOXGKAK.js +1251 -0
  22. package/dist/chunk-ADOXGKAK.js.map +1 -0
  23. package/dist/chunk-BE5HNDA5.cjs +874 -0
  24. package/dist/chunk-BE5HNDA5.cjs.map +1 -0
  25. package/dist/chunk-CZRM7LT7.js +889 -0
  26. package/dist/chunk-CZRM7LT7.js.map +1 -0
  27. package/dist/chunk-D4JTSPOL.js +1795 -0
  28. package/dist/chunk-D4JTSPOL.js.map +1 -0
  29. package/dist/chunk-DS47NTWZ.cjs +1034 -0
  30. package/dist/chunk-DS47NTWZ.cjs.map +1 -0
  31. package/dist/chunk-FDLZEKEB.js +449 -0
  32. package/dist/chunk-FDLZEKEB.js.map +1 -0
  33. package/dist/chunk-FGPTCDUT.cjs +1851 -0
  34. package/dist/chunk-FGPTCDUT.cjs.map +1 -0
  35. package/dist/chunk-HDKDQAEQ.cjs +86 -0
  36. package/dist/chunk-HDKDQAEQ.cjs.map +1 -0
  37. package/dist/chunk-IX554O5K.js +346 -0
  38. package/dist/chunk-IX554O5K.js.map +1 -0
  39. package/dist/chunk-KLJEK547.js +71 -0
  40. package/dist/chunk-KLJEK547.js.map +1 -0
  41. package/dist/chunk-LMFSHK45.js +1028 -0
  42. package/dist/chunk-LMFSHK45.js.map +1 -0
  43. package/dist/chunk-MDICUK6F.cjs +1258 -0
  44. package/dist/chunk-MDICUK6F.cjs.map +1 -0
  45. package/dist/chunk-N7KOXOMX.cjs +363 -0
  46. package/dist/chunk-N7KOXOMX.cjs.map +1 -0
  47. package/dist/chunk-NYCIK4SU.cjs +775 -0
  48. package/dist/chunk-NYCIK4SU.cjs.map +1 -0
  49. package/dist/chunk-PDPHRZZT.js +770 -0
  50. package/dist/chunk-PDPHRZZT.js.map +1 -0
  51. package/dist/chunk-ROFLJ74T.js +1212 -0
  52. package/dist/chunk-ROFLJ74T.js.map +1 -0
  53. package/dist/chunk-S6BK5DB6.cjs +845 -0
  54. package/dist/chunk-S6BK5DB6.cjs.map +1 -0
  55. package/dist/chunk-U4I37IBN.js +874 -0
  56. package/dist/chunk-U4I37IBN.js.map +1 -0
  57. package/dist/chunk-U5GGE6PJ.js +839 -0
  58. package/dist/chunk-U5GGE6PJ.js.map +1 -0
  59. package/dist/chunk-UHLYS3W5.cjs +1015 -0
  60. package/dist/chunk-UHLYS3W5.cjs.map +1 -0
  61. package/dist/chunk-URSKIHSY.cjs +881 -0
  62. package/dist/chunk-URSKIHSY.cjs.map +1 -0
  63. package/dist/chunk-V6WO7RK7.cjs +1056 -0
  64. package/dist/chunk-V6WO7RK7.cjs.map +1 -0
  65. package/dist/chunk-VFQCTXOX.js +869 -0
  66. package/dist/chunk-VFQCTXOX.js.map +1 -0
  67. package/dist/chunk-XQ52ICHU.cjs +895 -0
  68. package/dist/chunk-XQ52ICHU.cjs.map +1 -0
  69. package/dist/chunk-XX4BKS7Y.js +1051 -0
  70. package/dist/chunk-XX4BKS7Y.js.map +1 -0
  71. package/dist/chunk-XXU36667.js +1844 -0
  72. package/dist/chunk-XXU36667.js.map +1 -0
  73. package/dist/chunk-ZX7QKZK2.cjs +1326 -0
  74. package/dist/chunk-ZX7QKZK2.cjs.map +1 -0
  75. package/dist/diagrams/blockdiagram/index.cjs +25 -0
  76. package/dist/diagrams/blockdiagram/index.cjs.map +1 -0
  77. package/dist/diagrams/blockdiagram/index.d.cts +67 -0
  78. package/dist/diagrams/blockdiagram/index.d.ts +67 -0
  79. package/dist/diagrams/blockdiagram/index.js +4 -0
  80. package/dist/diagrams/blockdiagram/index.js.map +1 -0
  81. package/dist/diagrams/circuit/index.cjs +34 -0
  82. package/dist/diagrams/circuit/index.cjs.map +1 -0
  83. package/dist/diagrams/circuit/index.d.cts +138 -0
  84. package/dist/diagrams/circuit/index.d.ts +138 -0
  85. package/dist/diagrams/circuit/index.js +5 -0
  86. package/dist/diagrams/circuit/index.js.map +1 -0
  87. package/dist/diagrams/ecomap/index.cjs +30 -0
  88. package/dist/diagrams/ecomap/index.cjs.map +1 -0
  89. package/dist/diagrams/ecomap/index.d.cts +15 -0
  90. package/dist/diagrams/ecomap/index.d.ts +15 -0
  91. package/dist/diagrams/ecomap/index.js +5 -0
  92. package/dist/diagrams/ecomap/index.js.map +1 -0
  93. package/dist/diagrams/entity/index.cjs +26 -0
  94. package/dist/diagrams/entity/index.cjs.map +1 -0
  95. package/dist/diagrams/entity/index.d.cts +54 -0
  96. package/dist/diagrams/entity/index.d.ts +54 -0
  97. package/dist/diagrams/entity/index.js +5 -0
  98. package/dist/diagrams/entity/index.js.map +1 -0
  99. package/dist/diagrams/fishbone/index.cjs +34 -0
  100. package/dist/diagrams/fishbone/index.cjs.map +1 -0
  101. package/dist/diagrams/fishbone/index.d.cts +185 -0
  102. package/dist/diagrams/fishbone/index.d.ts +185 -0
  103. package/dist/diagrams/fishbone/index.js +5 -0
  104. package/dist/diagrams/fishbone/index.js.map +1 -0
  105. package/dist/diagrams/flowchart/index.cjs +34 -0
  106. package/dist/diagrams/flowchart/index.cjs.map +1 -0
  107. package/dist/diagrams/flowchart/index.d.cts +2 -0
  108. package/dist/diagrams/flowchart/index.d.ts +2 -0
  109. package/dist/diagrams/flowchart/index.js +5 -0
  110. package/dist/diagrams/flowchart/index.js.map +1 -0
  111. package/dist/diagrams/genogram/index.cjs +38 -0
  112. package/dist/diagrams/genogram/index.cjs.map +1 -0
  113. package/dist/diagrams/genogram/index.d.cts +20 -0
  114. package/dist/diagrams/genogram/index.d.ts +20 -0
  115. package/dist/diagrams/genogram/index.js +5 -0
  116. package/dist/diagrams/genogram/index.js.map +1 -0
  117. package/dist/diagrams/ladder/index.cjs +26 -0
  118. package/dist/diagrams/ladder/index.cjs.map +1 -0
  119. package/dist/diagrams/ladder/index.d.cts +49 -0
  120. package/dist/diagrams/ladder/index.d.ts +49 -0
  121. package/dist/diagrams/ladder/index.js +5 -0
  122. package/dist/diagrams/ladder/index.js.map +1 -0
  123. package/dist/diagrams/logic/index.cjs +26 -0
  124. package/dist/diagrams/logic/index.cjs.map +1 -0
  125. package/dist/diagrams/logic/index.d.cts +73 -0
  126. package/dist/diagrams/logic/index.d.ts +73 -0
  127. package/dist/diagrams/logic/index.js +5 -0
  128. package/dist/diagrams/logic/index.js.map +1 -0
  129. package/dist/diagrams/orgchart/index.cjs +30 -0
  130. package/dist/diagrams/orgchart/index.cjs.map +1 -0
  131. package/dist/diagrams/orgchart/index.d.cts +100 -0
  132. package/dist/diagrams/orgchart/index.d.ts +100 -0
  133. package/dist/diagrams/orgchart/index.js +5 -0
  134. package/dist/diagrams/orgchart/index.js.map +1 -0
  135. package/dist/diagrams/pedigree/index.cjs +30 -0
  136. package/dist/diagrams/pedigree/index.cjs.map +1 -0
  137. package/dist/diagrams/pedigree/index.d.cts +15 -0
  138. package/dist/diagrams/pedigree/index.d.ts +15 -0
  139. package/dist/diagrams/pedigree/index.js +5 -0
  140. package/dist/diagrams/pedigree/index.js.map +1 -0
  141. package/dist/diagrams/phylo/index.cjs +30 -0
  142. package/dist/diagrams/phylo/index.cjs.map +1 -0
  143. package/dist/diagrams/phylo/index.d.cts +32 -0
  144. package/dist/diagrams/phylo/index.d.ts +32 -0
  145. package/dist/diagrams/phylo/index.js +5 -0
  146. package/dist/diagrams/phylo/index.js.map +1 -0
  147. package/dist/diagrams/sld/index.cjs +26 -0
  148. package/dist/diagrams/sld/index.cjs.map +1 -0
  149. package/dist/diagrams/sld/index.d.cts +58 -0
  150. package/dist/diagrams/sld/index.d.ts +58 -0
  151. package/dist/diagrams/sld/index.js +5 -0
  152. package/dist/diagrams/sld/index.js.map +1 -0
  153. package/dist/diagrams/sociogram/index.cjs +26 -0
  154. package/dist/diagrams/sociogram/index.cjs.map +1 -0
  155. package/dist/diagrams/sociogram/index.d.cts +76 -0
  156. package/dist/diagrams/sociogram/index.d.ts +76 -0
  157. package/dist/diagrams/sociogram/index.js +5 -0
  158. package/dist/diagrams/sociogram/index.js.map +1 -0
  159. package/dist/diagrams/timing/index.cjs +21 -0
  160. package/dist/diagrams/timing/index.cjs.map +1 -0
  161. package/dist/diagrams/timing/index.d.cts +9 -0
  162. package/dist/diagrams/timing/index.d.ts +9 -0
  163. package/dist/diagrams/timing/index.js +4 -0
  164. package/dist/diagrams/timing/index.js.map +1 -0
  165. package/dist/diagrams/venn/index.cjs +38 -0
  166. package/dist/diagrams/venn/index.cjs.map +1 -0
  167. package/dist/diagrams/venn/index.d.cts +69 -0
  168. package/dist/diagrams/venn/index.d.ts +69 -0
  169. package/dist/diagrams/venn/index.js +5 -0
  170. package/dist/diagrams/venn/index.js.map +1 -0
  171. package/dist/index-BSlza1YY.d.ts +150 -0
  172. package/dist/index-BXefHVce.d.cts +150 -0
  173. package/dist/index.cjs +2033 -0
  174. package/dist/index.cjs.map +1 -0
  175. package/dist/index.d.cts +29 -0
  176. package/dist/index.d.ts +29 -0
  177. package/dist/index.js +1944 -0
  178. package/dist/index.js.map +1 -0
  179. package/dist/types-DqfcYkcY.d.cts +741 -0
  180. package/dist/types-DqfcYkcY.d.ts +741 -0
  181. package/package.json +163 -0
@@ -0,0 +1,1015 @@
1
+ 'use strict';
2
+
3
+ var chunkN7KOXOMX_cjs = require('./chunk-N7KOXOMX.cjs');
4
+ var chunkHDKDQAEQ_cjs = require('./chunk-HDKDQAEQ.cjs');
5
+
6
+ // src/diagrams/orgchart/parser.ts
7
+ var OrgchartParseError = class extends Error {
8
+ constructor(message) {
9
+ super(message);
10
+ this.name = "OrgchartParseError";
11
+ }
12
+ };
13
+ var ROLE_ICONS = {
14
+ ceo: "CEO",
15
+ cto: "CTO",
16
+ cfo: "CFO",
17
+ coo: "COO",
18
+ cmo: "CMO",
19
+ cpo: "CPO",
20
+ vp: "VP",
21
+ engineer: "Engineer",
22
+ engineering: "Engineer",
23
+ designer: "Designer",
24
+ design: "Designer",
25
+ sales: "Sales",
26
+ hr: "HR",
27
+ legal: "Legal",
28
+ ops: "Ops",
29
+ operations: "Ops",
30
+ marketing: "Marketing",
31
+ product: "Product",
32
+ data: "Data",
33
+ advisor: "Advisor",
34
+ intern: "Intern",
35
+ vacant: "Vacant"
36
+ };
37
+ var NODE_KIND_KEYWORDS = /* @__PURE__ */ new Set([
38
+ "person",
39
+ "role",
40
+ "open",
41
+ "draft",
42
+ "tbh",
43
+ "advisor",
44
+ "external"
45
+ ]);
46
+ function stripComment(line) {
47
+ let out = "";
48
+ let inQuote = false;
49
+ for (const ch of line) {
50
+ if (ch === '"') inQuote = !inQuote;
51
+ if ((ch === "#" || ch === "/" && out.endsWith("/")) && !inQuote) {
52
+ if (ch === "/") return out.slice(0, -1);
53
+ return out;
54
+ }
55
+ out += ch;
56
+ }
57
+ return out;
58
+ }
59
+ function stripQuotes(v) {
60
+ const t = v.trim();
61
+ if (t.length >= 2 && t.startsWith('"') && t.endsWith('"')) return t.slice(1, -1);
62
+ return t;
63
+ }
64
+ function splitTopLevelCommas(inside) {
65
+ const parts = [];
66
+ let cur = "";
67
+ let inQuote = false;
68
+ for (const ch of inside) {
69
+ if (ch === '"') inQuote = !inQuote;
70
+ if (ch === "," && !inQuote) {
71
+ parts.push(cur);
72
+ cur = "";
73
+ } else {
74
+ cur += ch;
75
+ }
76
+ }
77
+ if (cur.trim()) parts.push(cur);
78
+ return parts;
79
+ }
80
+ function parseProps(inside) {
81
+ const out = {};
82
+ for (const p of splitTopLevelCommas(inside)) {
83
+ const s = p.trim();
84
+ if (!s) continue;
85
+ const colon = s.indexOf(":");
86
+ if (colon < 0) {
87
+ out[s.toLowerCase()] = "true";
88
+ continue;
89
+ }
90
+ const k = s.slice(0, colon).trim().toLowerCase();
91
+ const v = s.slice(colon + 1).trim();
92
+ out[k] = stripQuotes(v);
93
+ }
94
+ return out;
95
+ }
96
+ function tokenizeLines(text2) {
97
+ const result = [];
98
+ for (const raw of text2.split("\n")) {
99
+ const stripped = stripComment(raw.replace(/\r$/, ""));
100
+ if (!stripped.trim()) continue;
101
+ const match = stripped.match(/^(\s*)(.*)$/);
102
+ if (!match) continue;
103
+ const indent = match[1].replace(/\t/g, " ").length;
104
+ result.push({ indent, text: match[2].trim() });
105
+ }
106
+ return result;
107
+ }
108
+ function parseNodeLine(line) {
109
+ let kind = "person";
110
+ let rest = line;
111
+ const firstSp = line.indexOf(" ");
112
+ if (firstSp > 0) {
113
+ const first = line.slice(0, firstSp).toLowerCase();
114
+ if (NODE_KIND_KEYWORDS.has(first)) {
115
+ if (first === "role" || first === "open") kind = "role";
116
+ else if (first === "draft" || first === "tbh") kind = "draft";
117
+ else if (first === "advisor" || first === "external") kind = "advisor";
118
+ else kind = "person";
119
+ rest = line.slice(firstSp + 1).trim();
120
+ }
121
+ }
122
+ const colonIdx = rest.indexOf(":");
123
+ if (colonIdx < 0) return null;
124
+ const id = rest.slice(0, colonIdx).trim();
125
+ if (!/^[A-Za-z][A-Za-z0-9_-]*$/.test(id)) return null;
126
+ let tail = rest.slice(colonIdx + 1).trim();
127
+ let props = {};
128
+ const propsMatch = tail.match(/\[([^\]]*)\]\s*$/);
129
+ if (propsMatch) {
130
+ props = parseProps(propsMatch[1]);
131
+ tail = tail.slice(0, tail.length - propsMatch[0].length).trim();
132
+ }
133
+ const fields = [];
134
+ let cur = "";
135
+ let inQuote = false;
136
+ for (const ch of tail) {
137
+ if (ch === '"') inQuote = !inQuote;
138
+ if (ch === "|" && !inQuote) {
139
+ fields.push(cur.trim());
140
+ cur = "";
141
+ } else {
142
+ cur += ch;
143
+ }
144
+ }
145
+ if (cur.trim()) fields.push(cur.trim());
146
+ if (fields.length > 0) fields[0] = stripQuotes(fields[0]);
147
+ return { kind, id, fields, props };
148
+ }
149
+ function resolveRole(raw) {
150
+ if (!raw) return void 0;
151
+ const key = raw.trim().toLowerCase();
152
+ return ROLE_ICONS[key];
153
+ }
154
+ var EDGE_OPS = [
155
+ { token: "-.->", kind: "matrix" },
156
+ { token: "->", kind: "report" }
157
+ ];
158
+ function findEdgeToken(line, token) {
159
+ let inQuote = false;
160
+ for (let i = 0; i < line.length; i++) {
161
+ const ch = line[i];
162
+ if (ch === '"') inQuote = !inQuote;
163
+ if (!inQuote && line.startsWith(token, i)) return i;
164
+ }
165
+ return -1;
166
+ }
167
+ function parseOrgchart(text2) {
168
+ const rawLines = tokenizeLines(text2);
169
+ let title2;
170
+ let direction = "TD";
171
+ let layout = "tree";
172
+ const nodes = [];
173
+ const nodeMap = /* @__PURE__ */ new Map();
174
+ const edges = [];
175
+ const indentStack = [];
176
+ for (const rl of rawLines) {
177
+ const line = rl.text;
178
+ if (/^orgchart\b/i.test(line)) {
179
+ const m = line.match(/"([^"]*)"/);
180
+ if (m) title2 = m[1];
181
+ continue;
182
+ }
183
+ if (/^config\b/i.test(line)) {
184
+ const m = line.match(/^config\s*:\s*(\w+)\s*=\s*"?([^"\n]+?)"?\s*$/i);
185
+ if (m) {
186
+ const key = m[1].toLowerCase();
187
+ const val = m[2].trim();
188
+ if (key === "direction") {
189
+ direction = val.toUpperCase() === "LR" ? "LR" : "TD";
190
+ } else if (key === "layout") {
191
+ const v = val.toLowerCase();
192
+ if (v === "list" || v === "directory" || v === "compact") layout = "list";
193
+ else layout = "tree";
194
+ }
195
+ }
196
+ continue;
197
+ }
198
+ let edgeHandled = false;
199
+ for (const { token, kind } of EDGE_OPS) {
200
+ const idx = findEdgeToken(line, token);
201
+ if (idx < 0) continue;
202
+ const left = line.slice(0, idx).trim();
203
+ let rest = line.slice(idx + token.length).trim();
204
+ if (!/^[A-Za-z][A-Za-z0-9_-]*$/.test(left)) break;
205
+ let props = {};
206
+ const propsMatch = rest.match(/\[([^\]]*)\]\s*$/);
207
+ if (propsMatch) {
208
+ props = parseProps(propsMatch[1]);
209
+ rest = rest.slice(0, rest.length - propsMatch[0].length).trim();
210
+ }
211
+ const to = rest.split(/\s+/)[0];
212
+ if (!/^[A-Za-z][A-Za-z0-9_-]*$/.test(to)) break;
213
+ const edge = { from: left, to, kind };
214
+ if (props.label) edge.label = props.label;
215
+ edges.push(edge);
216
+ edgeHandled = true;
217
+ break;
218
+ }
219
+ if (edgeHandled) continue;
220
+ const parsed = parseNodeLine(line);
221
+ if (!parsed) {
222
+ throw new OrgchartParseError(`Cannot parse line: ${line}`);
223
+ }
224
+ if (nodeMap.has(parsed.id)) {
225
+ throw new OrgchartParseError(`Duplicate node id "${parsed.id}"`);
226
+ }
227
+ const node = {
228
+ id: parsed.id,
229
+ name: parsed.fields[0] ?? parsed.id,
230
+ title: parsed.fields[1] || void 0,
231
+ department: parsed.fields[2] || void 0,
232
+ info: parsed.fields[3] || void 0,
233
+ kind: parsed.kind,
234
+ matrix: []
235
+ };
236
+ const p = parsed.props;
237
+ if (p.role) node.role = resolveRole(p.role);
238
+ if (p.icon) node.role = resolveRole(p.icon) ?? node.role;
239
+ if (p.open === "true") {
240
+ node.open = true;
241
+ node.kind = "role";
242
+ }
243
+ if (p.draft === "true" || p.tbh === "true") {
244
+ node.draft = true;
245
+ node.kind = "draft";
246
+ }
247
+ if (p.external === "true") {
248
+ node.external = true;
249
+ if (node.kind === "person") node.kind = "advisor";
250
+ }
251
+ if (p["assistant-of"]) node.assistantOf = p["assistant-of"];
252
+ if (p.reports) node.parent = p.reports;
253
+ if (p.matrix) {
254
+ node.matrix = p.matrix.split(/[\s,]+/).filter(Boolean);
255
+ }
256
+ if (p.department) node.department = p.department;
257
+ if (p["avatar-color"] || p.avatarcolor) {
258
+ node.avatarColor = p["avatar-color"] ?? p.avatarcolor;
259
+ }
260
+ if (p.gender) {
261
+ const g = p.gender.toLowerCase();
262
+ if (g === "male" || g === "m") node.gender = "male";
263
+ else if (g === "female" || g === "f") node.gender = "female";
264
+ }
265
+ if (!node.info) {
266
+ node.info = p.note ?? p.email ?? p.phone ?? p.location ?? void 0;
267
+ }
268
+ if (p.status) {
269
+ const s = p.status.toLowerCase();
270
+ if (s === "new" || s === "leaving" || s === "on-leave") node.status = s;
271
+ }
272
+ if (node.kind === "role" && node.open === void 0 && !p.draft) node.open = true;
273
+ if (node.kind === "role" && !node.role) node.role = "Vacant";
274
+ while (indentStack.length > 0 && indentStack[indentStack.length - 1].indent >= rl.indent) {
275
+ indentStack.pop();
276
+ }
277
+ if (!node.parent && indentStack.length > 0) {
278
+ node.parent = indentStack[indentStack.length - 1].id;
279
+ }
280
+ indentStack.push({ indent: rl.indent, id: node.id });
281
+ for (const m of node.matrix) {
282
+ edges.push({ from: m, to: node.id, kind: "matrix" });
283
+ }
284
+ nodes.push(node);
285
+ nodeMap.set(node.id, node);
286
+ }
287
+ for (const n of nodes) {
288
+ if (n.parent && !n.assistantOf) {
289
+ const exists = edges.some(
290
+ (e) => e.kind === "report" && e.from === n.parent && e.to === n.id
291
+ );
292
+ if (!exists) edges.push({ from: n.parent, to: n.id, kind: "report" });
293
+ }
294
+ }
295
+ for (const e of edges) {
296
+ if (!nodeMap.has(e.from)) {
297
+ throw new OrgchartParseError(`Edge references unknown node "${e.from}"`);
298
+ }
299
+ if (!nodeMap.has(e.to)) {
300
+ throw new OrgchartParseError(`Edge references unknown node "${e.to}"`);
301
+ }
302
+ }
303
+ if (nodes.length === 0) {
304
+ throw new OrgchartParseError("Orgchart has no nodes");
305
+ }
306
+ return {
307
+ type: "orgchart",
308
+ title: title2,
309
+ direction,
310
+ layout,
311
+ nodes,
312
+ edges
313
+ };
314
+ }
315
+
316
+ // src/diagrams/orgchart/layout.ts
317
+ var CARD_W = 240;
318
+ var CARD_H = 76;
319
+ var TIER_GAP = 44;
320
+ var SIB_GAP = 20;
321
+ var PADDING = 30;
322
+ var ASSISTANT_GAP = 32;
323
+ function hashString(s) {
324
+ let h = 0;
325
+ for (let i = 0; i < s.length; i++) {
326
+ h = h * 31 + s.charCodeAt(i) | 0;
327
+ }
328
+ return Math.abs(h);
329
+ }
330
+ function hexToRgb(hex) {
331
+ const h = hex.replace("#", "").padEnd(6, "0");
332
+ return {
333
+ r: parseInt(h.slice(0, 2), 16),
334
+ g: parseInt(h.slice(2, 4), 16),
335
+ b: parseInt(h.slice(4, 6), 16)
336
+ };
337
+ }
338
+ function rgbToHex(r, g, b) {
339
+ const c = (v) => Math.max(0, Math.min(255, Math.round(v))).toString(16).padStart(2, "0");
340
+ return `#${c(r)}${c(g)}${c(b)}`;
341
+ }
342
+ function tint(hex, weight) {
343
+ const { r, g, b } = hexToRgb(hex);
344
+ return rgbToHex(255 + (r - 255) * weight, 255 + (g - 255) * weight, 255 + (b - 255) * weight);
345
+ }
346
+ function shade(hex, weight) {
347
+ const { r, g, b } = hexToRgb(hex);
348
+ return rgbToHex(r * (1 - weight), g * (1 - weight), b * (1 - weight));
349
+ }
350
+ function computeInitials(name) {
351
+ const trimmed = name.trim();
352
+ if (!trimmed) return "?";
353
+ if (/[^\x00-\x7F]/.test(trimmed[0])) {
354
+ return Array.from(trimmed)[0];
355
+ }
356
+ const parts = trimmed.split(/\s+/);
357
+ if (parts.length === 1) return parts[0].slice(0, 2).toUpperCase();
358
+ return (parts[0][0] + parts[parts.length - 1][0]).toUpperCase();
359
+ }
360
+ function layoutOrgchart(ast, palette) {
361
+ const hasInfo = ast.nodes.some((n) => !!n.info);
362
+ const cW = CARD_W;
363
+ const cH = hasInfo ? 92 : CARD_H;
364
+ const tierGap = TIER_GAP;
365
+ const sibGap = SIB_GAP;
366
+ const nodeById = /* @__PURE__ */ new Map();
367
+ for (const n of ast.nodes) nodeById.set(n.id, n);
368
+ const childrenMap = /* @__PURE__ */ new Map();
369
+ const parentMap = /* @__PURE__ */ new Map();
370
+ for (const n of ast.nodes) childrenMap.set(n.id, []);
371
+ for (const e of ast.edges) {
372
+ if (e.kind !== "report") continue;
373
+ childrenMap.get(e.from)?.push(e.to);
374
+ parentMap.set(e.to, e.from);
375
+ }
376
+ const roots = [];
377
+ for (const n of ast.nodes) {
378
+ if (!parentMap.has(n.id) && !n.assistantOf) roots.push(n);
379
+ }
380
+ const treeById = /* @__PURE__ */ new Map();
381
+ for (const n of ast.nodes) {
382
+ treeById.set(n.id, {
383
+ id: n.id,
384
+ node: n,
385
+ children: [],
386
+ assistants: [],
387
+ subtreeWidth: 0,
388
+ x: 0,
389
+ y: 0
390
+ });
391
+ }
392
+ for (const n of ast.nodes) {
393
+ const t = treeById.get(n.id);
394
+ for (const cid of childrenMap.get(n.id) ?? []) {
395
+ const c = nodeById.get(cid);
396
+ if (c.assistantOf === n.id) continue;
397
+ t.children.push(treeById.get(cid));
398
+ }
399
+ }
400
+ for (const n of ast.nodes) {
401
+ if (n.assistantOf) {
402
+ const parent = treeById.get(n.assistantOf);
403
+ if (parent) parent.assistants.push(treeById.get(n.id));
404
+ }
405
+ }
406
+ function computeWidth(t) {
407
+ if (t.children.length === 0) {
408
+ t.subtreeWidth = cW;
409
+ return t.subtreeWidth;
410
+ }
411
+ let sum = 0;
412
+ for (let i = 0; i < t.children.length; i++) {
413
+ sum += computeWidth(t.children[i]);
414
+ if (i < t.children.length - 1) sum += sibGap;
415
+ }
416
+ t.subtreeWidth = Math.max(cW, sum);
417
+ return t.subtreeWidth;
418
+ }
419
+ function assign(t, leftX, depth) {
420
+ const cx = leftX + t.subtreeWidth / 2;
421
+ t.x = cx;
422
+ t.y = PADDING + depth * (cH + tierGap);
423
+ if (t.children.length > 0) {
424
+ const childBlock = t.children.reduce(
425
+ (s, c, i) => s + c.subtreeWidth + (i > 0 ? sibGap : 0),
426
+ 0
427
+ );
428
+ let childLeft = cx - childBlock / 2;
429
+ for (const c of t.children) {
430
+ assign(c, childLeft, depth + 1);
431
+ childLeft += c.subtreeWidth + sibGap;
432
+ }
433
+ }
434
+ }
435
+ let curLeft = PADDING;
436
+ for (const r of roots) {
437
+ const rt = treeById.get(r.id);
438
+ computeWidth(rt);
439
+ assign(rt, curLeft, 0);
440
+ curLeft += rt.subtreeWidth + sibGap * 2;
441
+ }
442
+ for (const [, t] of treeById) {
443
+ for (let i = 0; i < t.assistants.length; i++) {
444
+ const a = t.assistants[i];
445
+ a.x = t.x + cW + ASSISTANT_GAP + i * (cW + sibGap);
446
+ a.y = t.y + cH * 0.3;
447
+ }
448
+ }
449
+ const deptIndex = /* @__PURE__ */ new Map();
450
+ for (const n of ast.nodes) {
451
+ if (n.department && !deptIndex.has(n.department)) {
452
+ deptIndex.set(n.department, deptIndex.size);
453
+ }
454
+ }
455
+ const nodes = [];
456
+ for (const n of ast.nodes) {
457
+ const t = treeById.get(n.id);
458
+ const deptColor = n.department ? palette[(deptIndex.get(n.department) ?? 0) % palette.length] : void 0;
459
+ const base = n.avatarColor ?? deptColor ?? palette[hashString(n.name) % palette.length];
460
+ const avatarBg = tint(base, 0.14);
461
+ const avatarFg = shade(base, 0.4);
462
+ nodes.push({
463
+ node: n,
464
+ x: t.x,
465
+ y: t.y,
466
+ width: cW,
467
+ height: cH,
468
+ deptColor,
469
+ avatarBg,
470
+ avatarFg,
471
+ initials: computeInitials(n.name)
472
+ });
473
+ }
474
+ let minX = Infinity;
475
+ for (const n of nodes) minX = Math.min(minX, n.x - n.width / 2);
476
+ const shift = PADDING - minX;
477
+ if (Math.abs(shift) > 0.5) {
478
+ for (const n of nodes) n.x += shift;
479
+ }
480
+ const nodeLayoutById = /* @__PURE__ */ new Map();
481
+ for (const n of nodes) nodeLayoutById.set(n.node.id, n);
482
+ const layoutEdges = [];
483
+ for (const e of ast.edges) {
484
+ const from = nodeLayoutById.get(e.from);
485
+ const to = nodeLayoutById.get(e.to);
486
+ if (!from || !to) continue;
487
+ if (e.kind === "report") {
488
+ if (to.node.assistantOf === from.node.id) {
489
+ const sx2 = from.x + from.width / 2;
490
+ const sy2 = from.y + from.height / 2;
491
+ const ex2 = to.x - to.width / 2;
492
+ const ey2 = to.y + to.height / 2;
493
+ layoutEdges.push({ edge: e, path: `M ${sx2} ${sy2} L ${ex2} ${ey2}` });
494
+ continue;
495
+ }
496
+ const sx = from.x;
497
+ const sy = from.y + from.height;
498
+ const ex = to.x;
499
+ const ey = to.y;
500
+ const midY = (sy + ey) / 2;
501
+ const path2 = Math.abs(sx - ex) < 0.5 ? `M ${sx} ${sy} L ${ex} ${ey}` : `M ${sx} ${sy} L ${sx} ${midY} L ${ex} ${midY} L ${ex} ${ey}`;
502
+ layoutEdges.push({ edge: e, path: path2 });
503
+ } else {
504
+ const sx = from.x;
505
+ const sy = from.y + from.height / 2;
506
+ const ex = to.x;
507
+ const ey = to.y + to.height / 2;
508
+ const midY = (sy + ey) / 2;
509
+ const path2 = `M ${sx} ${sy} C ${sx} ${midY}, ${ex} ${midY}, ${ex} ${ey}`;
510
+ const entry = { edge: e, path: path2 };
511
+ if (e.label) {
512
+ entry.labelX = (sx + ex) / 2;
513
+ entry.labelY = midY;
514
+ }
515
+ layoutEdges.push(entry);
516
+ }
517
+ }
518
+ let maxX = 0;
519
+ let maxY = 0;
520
+ for (const n of nodes) {
521
+ maxX = Math.max(maxX, n.x + n.width / 2);
522
+ maxY = Math.max(maxY, n.y + n.height);
523
+ }
524
+ const width = Math.max(400, maxX + PADDING);
525
+ const height = Math.max(200, maxY + PADDING);
526
+ return {
527
+ width,
528
+ height,
529
+ nodes,
530
+ edges: layoutEdges,
531
+ title: ast.title,
532
+ mode: "tree"
533
+ };
534
+ }
535
+ var LIST_ROW_H = 32;
536
+ var LIST_INDENT = 22;
537
+ var LIST_PAD = 20;
538
+ var LIST_PANEL_W = 820;
539
+ var LIST_GUIDE_X0 = 32;
540
+ function layoutOrgchartList(ast, palette) {
541
+ const nodeById = /* @__PURE__ */ new Map();
542
+ for (const n of ast.nodes) nodeById.set(n.id, n);
543
+ const childrenMap = /* @__PURE__ */ new Map();
544
+ const parentMap = /* @__PURE__ */ new Map();
545
+ for (const n of ast.nodes) childrenMap.set(n.id, []);
546
+ for (const e of ast.edges) {
547
+ if (e.kind !== "report") continue;
548
+ childrenMap.get(e.from)?.push(e.to);
549
+ parentMap.set(e.to, e.from);
550
+ }
551
+ const roots = [];
552
+ for (const n of ast.nodes) {
553
+ if (!parentMap.has(n.id) && !n.assistantOf) roots.push(n);
554
+ }
555
+ const subtreeSize = /* @__PURE__ */ new Map();
556
+ function computeSize(id) {
557
+ const cached = subtreeSize.get(id);
558
+ if (cached !== void 0) return cached;
559
+ const kids = childrenMap.get(id) ?? [];
560
+ let s = kids.length;
561
+ for (const k of kids) s += computeSize(k);
562
+ subtreeSize.set(id, s);
563
+ return s;
564
+ }
565
+ for (const n of ast.nodes) computeSize(n.id);
566
+ const deptIndex = /* @__PURE__ */ new Map();
567
+ for (const n of ast.nodes) {
568
+ if (n.department && !deptIndex.has(n.department)) {
569
+ deptIndex.set(n.department, deptIndex.size);
570
+ }
571
+ }
572
+ const nodes = [];
573
+ const guides = [];
574
+ let rowIdx = 0;
575
+ function visit(id, depth) {
576
+ const n = nodeById.get(id);
577
+ if (!n) return;
578
+ const y = LIST_PAD + rowIdx * LIST_ROW_H;
579
+ const x = LIST_GUIDE_X0 + depth * LIST_INDENT;
580
+ const deptColor = n.department ? palette[(deptIndex.get(n.department) ?? 0) % palette.length] : void 0;
581
+ const base = n.avatarColor ?? deptColor ?? palette[hashString(n.name) % palette.length];
582
+ const kids = childrenMap.get(id) ?? [];
583
+ const hasKids = kids.length > 0;
584
+ nodes.push({
585
+ node: n,
586
+ x,
587
+ y,
588
+ width: LIST_PANEL_W - x - LIST_PAD,
589
+ height: LIST_ROW_H,
590
+ deptColor,
591
+ avatarBg: tint(base, 0.14),
592
+ avatarFg: shade(base, 0.4),
593
+ initials: computeInitials(n.name),
594
+ depth,
595
+ subtreeSize: subtreeSize.get(id) ?? 0,
596
+ hasChildren: hasKids
597
+ });
598
+ rowIdx++;
599
+ for (const c of kids) visit(c, depth + 1);
600
+ }
601
+ for (const r of roots) visit(r.id, 0);
602
+ for (let i = 0; i < nodes.length; i++) {
603
+ const p = nodes[i];
604
+ if (!p.hasChildren) continue;
605
+ const pxLine = p.x + 10;
606
+ const pyStart = p.y + LIST_ROW_H / 2 + 6;
607
+ const directChildren = [];
608
+ for (let j = i + 1; j < nodes.length; j++) {
609
+ const q = nodes[j];
610
+ if ((q.depth ?? 0) <= (p.depth ?? 0)) break;
611
+ if ((q.depth ?? 0) === (p.depth ?? 0) + 1) directChildren.push(q);
612
+ }
613
+ if (directChildren.length === 0) continue;
614
+ const lastChild = directChildren[directChildren.length - 1];
615
+ const pyEnd = lastChild.y + LIST_ROW_H / 2;
616
+ guides.push(`M ${pxLine} ${pyStart} L ${pxLine} ${pyEnd}`);
617
+ for (const c of directChildren) {
618
+ const tickY = c.y + LIST_ROW_H / 2;
619
+ guides.push(`M ${pxLine} ${tickY} L ${c.x - 2} ${tickY}`);
620
+ }
621
+ }
622
+ const height = LIST_PAD * 2 + rowIdx * LIST_ROW_H;
623
+ return {
624
+ width: LIST_PANEL_W,
625
+ height,
626
+ nodes,
627
+ edges: [],
628
+ title: ast.title,
629
+ mode: "list",
630
+ guides
631
+ };
632
+ }
633
+
634
+ // src/diagrams/orgchart/renderer.ts
635
+ function buildCss(t) {
636
+ return `
637
+ .lt-org { background: ${t.bg}; font-family: system-ui, -apple-system, sans-serif; }
638
+ .lt-org-title { font: 500 16px sans-serif; fill: ${t.text}; }
639
+ .lt-org-card { fill: ${t.bg}; stroke: ${t.neutral}; stroke-width: 1; }
640
+ .lt-org-card-vacant { fill: ${t.bg}; stroke: ${t.warn}; stroke-width: 1; stroke-dasharray: 4,3; }
641
+ .lt-org-card-draft { fill: ${t.bg}; stroke: ${t.neutral}; stroke-width: 1; stroke-dasharray: 4,3; opacity: 0.7; }
642
+ .lt-org-card-external { fill: ${t.bg}; stroke: ${t.neutral}; stroke-width: 1; stroke-dasharray: 4,3; }
643
+ .lt-org-name { font: 500 14px sans-serif; fill: ${t.text}; }
644
+ .lt-org-title-text { font: 400 12px sans-serif; fill: ${t.textMuted}; }
645
+ .lt-org-info { font: 400 11px sans-serif; fill: ${t.textMuted}; }
646
+ .lt-org-dept { font: 500 10px sans-serif; }
647
+ .lt-org-avatar-text { font: 600 13px sans-serif; text-anchor: middle; }
648
+ .lt-org-edge { stroke: ${t.stroke}; stroke-width: 1.4; fill: none; }
649
+ .lt-org-edge-matrix { stroke: ${t.neutral}; stroke-width: 1.2; stroke-dasharray: 4,3; fill: none; }
650
+ .lt-org-edge-label-bg { fill: ${t.bg}; stroke: ${t.neutral}; stroke-width: 1; }
651
+ .lt-org-edge-label { font: 500 10px sans-serif; fill: ${t.textMuted}; text-anchor: middle; }
652
+ .lt-org-pill-bg { fill: ${t.bg}; stroke-width: 1; }
653
+ .lt-org-pill { font: 600 9px sans-serif; text-anchor: middle; letter-spacing: 0.4px; }
654
+ .lt-org-panel { fill: ${t.bg}; stroke: ${t.neutral}; stroke-width: 1; }
655
+ .lt-org-guide { stroke: ${t.neutral}; stroke-width: 1; fill: none; }
656
+ .lt-org-caret { font: 400 9px sans-serif; fill: ${t.textMuted}; }
657
+ .lt-org-row-name { font: 500 13px sans-serif; fill: ${t.text}; }
658
+ .lt-org-row-title { font: 400 12px sans-serif; fill: ${t.textMuted}; }
659
+ .lt-org-row-avatar-text { font: 600 10px sans-serif; text-anchor: middle; }
660
+ .lt-org-row-count { font: 400 11px sans-serif; fill: ${t.textMuted}; text-anchor: end; }
661
+ .lt-org-row-dept { font: 500 10px sans-serif; text-anchor: middle; }
662
+ `.trim();
663
+ }
664
+ function renderGenderGlyph(gender, fg) {
665
+ const f = `fill="${fg}"`;
666
+ if (gender === "male") {
667
+ return `<circle cx="0" cy="-7" r="5.5" ${f}/><path d="M -9 11 C -9 2 -5 0 0 0 C 5 0 9 2 9 11 Z" ${f}/>`;
668
+ }
669
+ return `<circle cx="0" cy="-7" r="5.5" ${f}/><path d="M -5 0 C -10 5 -11 10 -10 11 L 10 11 C 11 10 10 5 5 0 Z" ${f}/>`;
670
+ }
671
+ function renderRoleGlyph(role, fg) {
672
+ const stroke = `stroke="${fg}" stroke-width="1.6" fill="none" stroke-linecap="round" stroke-linejoin="round"`;
673
+ const fillWhite = `fill="${fg}"`;
674
+ switch (role) {
675
+ case "CEO":
676
+ case "VP":
677
+ return `<path d="M -10 4 L -10 -6 L -4 0 L 0 -8 L 4 0 L 10 -6 L 10 4 Z" ${fillWhite} stroke="none"/>`;
678
+ case "CTO":
679
+ case "Engineer":
680
+ return `<circle r="6" ${stroke}/><circle r="2" ${fillWhite} stroke="none"/><g ${stroke}><line x1="0" y1="-9" x2="0" y2="-7"/><line x1="0" y1="9" x2="0" y2="7"/><line x1="-9" y1="0" x2="-7" y2="0"/><line x1="9" y1="0" x2="7" y2="0"/><line x1="-6.4" y1="-6.4" x2="-5" y2="-5"/><line x1="6.4" y1="-6.4" x2="5" y2="-5"/><line x1="-6.4" y1="6.4" x2="-5" y2="5"/><line x1="6.4" y1="6.4" x2="5" y2="5"/></g>`;
681
+ case "CFO":
682
+ return `<text x="0" y="6" text-anchor="middle" font-size="18" font-weight="700" fill="${fg}">$</text>`;
683
+ case "COO":
684
+ case "Ops":
685
+ return `<g ${fillWhite}><circle cx="-6" cy="0" r="3" stroke="none"/><circle cx="6" cy="0" r="3" stroke="none"/><circle cx="0" cy="-5" r="3" stroke="none"/></g>`;
686
+ case "CMO":
687
+ case "Marketing":
688
+ return `<path d="M -8 -4 L 2 -7 L 2 7 L -8 4 Z" ${fillWhite} stroke="none"/><path d="M 2 -4 L 8 -6 L 8 6 L 2 4 Z" ${fillWhite} stroke="none"/>`;
689
+ case "CPO":
690
+ case "Product":
691
+ return `<path d="M 0 -8 C 5 -8 7 -4 7 0 C 7 3 4 4 4 6 L -4 6 C -4 4 -7 3 -7 0 C -7 -4 -5 -8 0 -8 Z" ${fillWhite} stroke="none"/><line x1="-3" y1="9" x2="3" y2="9" stroke="${fg}" stroke-width="1.5"/>`;
692
+ case "Designer":
693
+ return `<path d="M -7 7 L 7 -7 L 9 -5 L -5 9 Z" ${fillWhite} stroke="none"/>`;
694
+ case "Sales":
695
+ return `<rect x="-8" y="-4" width="16" height="10" rx="1" ${fillWhite} stroke="none"/><rect x="-4" y="-7" width="8" height="4" ${stroke}/>`;
696
+ case "HR":
697
+ return `<circle cx="-3" cy="-4" r="3" ${fillWhite} stroke="none"/><circle cx="4" cy="-3" r="2.5" ${fillWhite} stroke="none"/><path d="M -8 7 C -8 2 -2 2 -2 2 C -2 2 2 2 2 7 Z" ${fillWhite} stroke="none"/><path d="M 0 7 C 0 4 4 4 4 4 C 4 4 9 4 9 7 Z" ${fillWhite} stroke="none"/>`;
698
+ case "Legal":
699
+ return `<line x1="0" y1="-8" x2="0" y2="8" stroke="${fg}" stroke-width="1.6"/><line x1="-7" y1="-6" x2="7" y2="-6" stroke="${fg}" stroke-width="1.6"/><path d="M -9 0 L -5 -6 L -1 0 Z" ${fillWhite} stroke="none"/><path d="M 1 0 L 5 -6 L 9 0 Z" ${fillWhite} stroke="none"/>`;
700
+ case "Data":
701
+ return `<g ${fillWhite}><rect x="-8" y="0" width="4" height="7" stroke="none"/><rect x="-2" y="-4" width="4" height="11" stroke="none"/><rect x="4" y="-7" width="4" height="14" stroke="none"/></g>`;
702
+ case "Advisor":
703
+ return `<path d="M 0 -9 L 2.6 -2.7 L 9 -2 L 4 2.3 L 5.3 8.5 L 0 5 L -5.3 8.5 L -4 2.3 L -9 -2 L -2.6 -2.7 Z" ${fillWhite} stroke="none"/>`;
704
+ case "Intern":
705
+ return `<path d="M -10 -2 L 0 -7 L 10 -2 L 0 3 Z" ${fillWhite} stroke="none"/><path d="M -5 0 L -5 5 C -5 7 5 7 5 5 L 5 0" ${stroke}/>`;
706
+ case "Vacant":
707
+ return `<circle r="7" stroke="${fg}" stroke-width="1.4" fill="none" stroke-dasharray="3,2"/><text x="0" y="4" text-anchor="middle" font-size="12" font-weight="700" fill="${fg}">?</text>`;
708
+ default:
709
+ return "";
710
+ }
711
+ }
712
+ function renderAvatar(ln) {
713
+ const role = ln.node.role;
714
+ const cx = -ln.width / 2 + 14 + 18;
715
+ const cy = 0;
716
+ const r = 18;
717
+ const parts = [
718
+ chunkHDKDQAEQ_cjs.circle({ cx, cy, r, fill: ln.avatarBg, stroke: "none" })
719
+ ];
720
+ if (role && role !== "Vacant") {
721
+ parts.push(
722
+ chunkHDKDQAEQ_cjs.group({ transform: `translate(${cx}, ${cy})` }, [
723
+ renderRoleGlyph(role, ln.avatarFg)
724
+ ])
725
+ );
726
+ } else if (ln.node.open) {
727
+ parts.push(
728
+ chunkHDKDQAEQ_cjs.group({ transform: `translate(${cx}, ${cy})` }, [
729
+ renderRoleGlyph("Vacant", ln.avatarFg)
730
+ ])
731
+ );
732
+ } else if (ln.node.gender) {
733
+ parts.push(
734
+ chunkHDKDQAEQ_cjs.group({ transform: `translate(${cx}, ${cy})` }, [
735
+ renderGenderGlyph(ln.node.gender, ln.avatarFg)
736
+ ])
737
+ );
738
+ } else {
739
+ parts.push(
740
+ chunkHDKDQAEQ_cjs.text(
741
+ { x: cx, y: cy + 5, class: "lt-org-avatar-text", fill: ln.avatarFg },
742
+ ln.initials
743
+ )
744
+ );
745
+ }
746
+ return chunkHDKDQAEQ_cjs.group({}, parts);
747
+ }
748
+ function renderCardBody(ln, t) {
749
+ const n = ln.node;
750
+ const x = -ln.width / 2;
751
+ const y = -ln.height / 2;
752
+ let cardClass = "lt-org-card";
753
+ if (n.open) cardClass = "lt-org-card-vacant";
754
+ else if (n.draft) cardClass = "lt-org-card-draft";
755
+ else if (n.external) cardClass = "lt-org-card-external";
756
+ const parts = [];
757
+ parts.push(
758
+ chunkHDKDQAEQ_cjs.rect({
759
+ x,
760
+ y,
761
+ width: ln.width,
762
+ height: ln.height,
763
+ rx: 10,
764
+ ry: 10,
765
+ class: cardClass
766
+ })
767
+ );
768
+ parts.push(renderAvatar(ln));
769
+ const textX = x + 14 + 36 + 12;
770
+ const hasTitle = !!n.title;
771
+ const hasInfo = !!n.info;
772
+ const displayName = n.open && !n.name ? "Open Role" : n.name;
773
+ const lineCount = 1 + (hasTitle ? 1 : 0) + (hasInfo ? 1 : 0);
774
+ const lineH = 16;
775
+ let nameY = -(lineCount - 1) * lineH / 2;
776
+ parts.push(chunkHDKDQAEQ_cjs.text({ x: textX, y: nameY, class: "lt-org-name" }, displayName));
777
+ if (hasTitle) {
778
+ parts.push(chunkHDKDQAEQ_cjs.text({ x: textX, y: nameY + lineH, class: "lt-org-title-text" }, n.title));
779
+ }
780
+ if (hasInfo) {
781
+ parts.push(
782
+ chunkHDKDQAEQ_cjs.text(
783
+ { x: textX, y: nameY + lineH * (hasTitle ? 2 : 1), class: "lt-org-info" },
784
+ n.info
785
+ )
786
+ );
787
+ }
788
+ const pillLabel = n.open ? "HIRING" : n.status === "new" ? "NEW" : n.status === "leaving" ? "LEAVING" : n.status === "on-leave" ? "ON LEAVE" : void 0;
789
+ if (pillLabel) {
790
+ const pw = pillLabel.length * 5.8 + 10;
791
+ const ph = 14;
792
+ const px = ln.width / 2 - pw - 8;
793
+ const py = y + 8;
794
+ const pillFg = pillLabel === "HIRING" ? "#8a6d00" : pillLabel === "NEW" ? "#2b6a3a" : pillLabel === "LEAVING" ? "#8a3b1a" : t.textMuted;
795
+ const pillBg = pillLabel === "HIRING" ? "#fef3c7" : pillLabel === "NEW" ? "#dcfce7" : pillLabel === "LEAVING" ? "#fee4d8" : "#eeeeea";
796
+ parts.push(
797
+ chunkHDKDQAEQ_cjs.rect({ x: px, y: py, width: pw, height: ph, rx: 3, fill: pillBg, stroke: "none" })
798
+ );
799
+ parts.push(
800
+ chunkHDKDQAEQ_cjs.text(
801
+ { x: px + pw / 2, y: py + ph - 4, class: "lt-org-pill", fill: pillFg },
802
+ pillLabel
803
+ )
804
+ );
805
+ }
806
+ return chunkHDKDQAEQ_cjs.group(
807
+ {
808
+ transform: `translate(${ln.x}, ${ln.y + ln.height / 2})`,
809
+ "data-person-id": n.id,
810
+ "data-department": n.department ?? "",
811
+ "data-role": n.role ?? ""
812
+ },
813
+ parts
814
+ );
815
+ }
816
+ function renderListRow(ln) {
817
+ const n = ln.node;
818
+ const rowCenterY = ln.y + ln.height / 2;
819
+ const caretX = ln.x;
820
+ const avatarCx = ln.x + 20;
821
+ const avatarR = 11;
822
+ const parts = [];
823
+ const caret = ln.hasChildren ? "\u25BC" : "\xB7";
824
+ parts.push(
825
+ chunkHDKDQAEQ_cjs.text(
826
+ { x: caretX, y: rowCenterY + 3, class: "lt-org-caret" },
827
+ caret
828
+ )
829
+ );
830
+ parts.push(chunkHDKDQAEQ_cjs.circle({ cx: avatarCx, cy: rowCenterY, r: avatarR, fill: ln.avatarBg, stroke: "none" }));
831
+ if (n.role && n.role !== "Vacant") {
832
+ parts.push(
833
+ chunkHDKDQAEQ_cjs.group({ transform: `translate(${avatarCx}, ${rowCenterY}) scale(0.58)` }, [
834
+ renderRoleGlyph(n.role, ln.avatarFg)
835
+ ])
836
+ );
837
+ } else if (n.open) {
838
+ parts.push(
839
+ chunkHDKDQAEQ_cjs.group({ transform: `translate(${avatarCx}, ${rowCenterY}) scale(0.58)` }, [
840
+ renderRoleGlyph("Vacant", ln.avatarFg)
841
+ ])
842
+ );
843
+ } else if (n.gender) {
844
+ parts.push(
845
+ chunkHDKDQAEQ_cjs.group({ transform: `translate(${avatarCx}, ${rowCenterY}) scale(0.56)` }, [
846
+ renderGenderGlyph(n.gender, ln.avatarFg)
847
+ ])
848
+ );
849
+ } else {
850
+ parts.push(
851
+ chunkHDKDQAEQ_cjs.text(
852
+ {
853
+ x: avatarCx,
854
+ y: rowCenterY + 3,
855
+ class: "lt-org-row-avatar-text",
856
+ fill: ln.avatarFg
857
+ },
858
+ ln.initials
859
+ )
860
+ );
861
+ }
862
+ const textY = rowCenterY + 4;
863
+ const nameX = avatarCx + avatarR + 10;
864
+ const displayName = n.open && !n.name ? "Open Role" : n.name;
865
+ parts.push(chunkHDKDQAEQ_cjs.text({ x: nameX, y: textY, class: "lt-org-row-name" }, displayName));
866
+ if (n.title) {
867
+ const titleX = nameX + Math.max(80, displayName.length * 8 + 10);
868
+ parts.push(chunkHDKDQAEQ_cjs.text({ x: titleX, y: textY, class: "lt-org-row-title" }, n.title));
869
+ }
870
+ const rightEdge = ln.x + ln.width;
871
+ let cursor = rightEdge;
872
+ if (ln.subtreeSize && ln.subtreeSize > 0) {
873
+ const countLabel = ln.depth === 0 ? `${ln.subtreeSize} reports` : `${ln.subtreeSize}`;
874
+ parts.push(
875
+ chunkHDKDQAEQ_cjs.text(
876
+ { x: cursor, y: textY, class: "lt-org-row-count" },
877
+ countLabel
878
+ )
879
+ );
880
+ cursor -= Math.max(30, countLabel.length * 6.5) + 12;
881
+ }
882
+ if (n.department) {
883
+ const pw = n.department.length * 5.6 + 14;
884
+ const ph = 16;
885
+ const px = cursor - pw;
886
+ const py = rowCenterY - ph / 2;
887
+ parts.push(
888
+ chunkHDKDQAEQ_cjs.rect({ x: px, y: py, width: pw, height: ph, rx: 3, fill: ln.avatarBg, stroke: "none" })
889
+ );
890
+ parts.push(
891
+ chunkHDKDQAEQ_cjs.text(
892
+ {
893
+ x: px + pw / 2,
894
+ y: textY,
895
+ class: "lt-org-row-dept",
896
+ fill: ln.avatarFg
897
+ },
898
+ n.department
899
+ )
900
+ );
901
+ }
902
+ return chunkHDKDQAEQ_cjs.group({ "data-person-id": n.id }, parts);
903
+ }
904
+ function renderOrgchartList(ast, layout, t) {
905
+ const titleOffset = ast.title ? 42 : 16;
906
+ const width = Math.ceil(layout.width);
907
+ const height = Math.ceil(layout.height + titleOffset);
908
+ const children = [];
909
+ children.push(chunkHDKDQAEQ_cjs.title(ast.title ?? "Organizational Directory"));
910
+ children.push(
911
+ chunkHDKDQAEQ_cjs.desc(
912
+ `Organizational directory with ${ast.nodes.length} people and ${ast.edges.length} reporting relationships`
913
+ )
914
+ );
915
+ children.push(chunkHDKDQAEQ_cjs.el("style", {}, buildCss(t)));
916
+ if (ast.title) {
917
+ children.push(chunkHDKDQAEQ_cjs.text({ x: 20, y: 24, class: "lt-org-title" }, ast.title));
918
+ }
919
+ const inner = [];
920
+ for (const g of layout.guides ?? []) {
921
+ inner.push(chunkHDKDQAEQ_cjs.path({ d: g, class: "lt-org-guide" }));
922
+ }
923
+ for (const ln of layout.nodes) {
924
+ inner.push(renderListRow(ln));
925
+ }
926
+ children.push(chunkHDKDQAEQ_cjs.group({ transform: `translate(0, ${titleOffset})` }, inner));
927
+ return chunkHDKDQAEQ_cjs.svgRoot(
928
+ {
929
+ class: "lt-org",
930
+ role: "img",
931
+ "aria-label": chunkHDKDQAEQ_cjs.escapeXml(ast.title ?? "Organizational directory"),
932
+ width,
933
+ height,
934
+ viewBox: `0 0 ${width} ${height}`
935
+ },
936
+ children
937
+ );
938
+ }
939
+ function renderOrgchart(ast, config) {
940
+ const t = chunkN7KOXOMX_cjs.resolveBaseTheme(config?.theme ?? "default");
941
+ if (ast.layout === "list") {
942
+ return renderOrgchartList(ast, layoutOrgchartList(ast, t.palette), t);
943
+ }
944
+ const layout = layoutOrgchart(ast, t.palette);
945
+ const titleOffset = ast.title ? 36 : 10;
946
+ const width = Math.ceil(layout.width);
947
+ const height = Math.ceil(layout.height + titleOffset);
948
+ const children = [];
949
+ children.push(chunkHDKDQAEQ_cjs.title(ast.title ?? "Organizational Chart"));
950
+ children.push(
951
+ chunkHDKDQAEQ_cjs.desc(
952
+ `Organizational chart with ${ast.nodes.length} people and ${ast.edges.length} relationships`
953
+ )
954
+ );
955
+ children.push(chunkHDKDQAEQ_cjs.el("style", {}, buildCss(t)));
956
+ if (ast.title) {
957
+ children.push(chunkHDKDQAEQ_cjs.text({ x: 20, y: 24, class: "lt-org-title" }, ast.title));
958
+ }
959
+ const inner = [];
960
+ for (const le of layout.edges) {
961
+ const cls = le.edge.kind === "matrix" ? "lt-org-edge-matrix" : "lt-org-edge";
962
+ inner.push(chunkHDKDQAEQ_cjs.path({ d: le.path, class: cls }));
963
+ }
964
+ for (const le of layout.edges) {
965
+ if (le.edge.kind !== "matrix" || !le.edge.label || le.labelX === void 0) continue;
966
+ const w = le.edge.label.length * 6 + 12;
967
+ const h = 16;
968
+ const x = (le.labelX ?? 0) - w / 2;
969
+ const y = (le.labelY ?? 0) - h / 2;
970
+ inner.push(
971
+ chunkHDKDQAEQ_cjs.rect({ x, y, width: w, height: h, rx: 3, class: "lt-org-edge-label-bg" })
972
+ );
973
+ inner.push(
974
+ chunkHDKDQAEQ_cjs.text(
975
+ { x: le.labelX, y: (le.labelY ?? 0) + 4, class: "lt-org-edge-label" },
976
+ le.edge.label
977
+ )
978
+ );
979
+ }
980
+ for (const ln of layout.nodes) {
981
+ inner.push(renderCardBody(ln, t));
982
+ }
983
+ children.push(chunkHDKDQAEQ_cjs.group({ transform: `translate(0, ${titleOffset})` }, inner));
984
+ return chunkHDKDQAEQ_cjs.svgRoot(
985
+ {
986
+ class: "lt-org",
987
+ role: "img",
988
+ "aria-label": chunkHDKDQAEQ_cjs.escapeXml(ast.title ?? "Organizational chart"),
989
+ width,
990
+ height,
991
+ viewBox: `0 0 ${width} ${height}`
992
+ },
993
+ children
994
+ );
995
+ }
996
+
997
+ // src/diagrams/orgchart/index.ts
998
+ var orgchart = {
999
+ type: "orgchart",
1000
+ detect(text2) {
1001
+ return /^\s*orgchart\b/i.test(text2);
1002
+ },
1003
+ render(text2, config) {
1004
+ const ast = parseOrgchart(text2);
1005
+ return renderOrgchart(ast, config);
1006
+ }
1007
+ };
1008
+
1009
+ exports.OrgchartParseError = OrgchartParseError;
1010
+ exports.layoutOrgchart = layoutOrgchart;
1011
+ exports.orgchart = orgchart;
1012
+ exports.parseOrgchart = parseOrgchart;
1013
+ exports.renderOrgchart = renderOrgchart;
1014
+ //# sourceMappingURL=chunk-UHLYS3W5.cjs.map
1015
+ //# sourceMappingURL=chunk-UHLYS3W5.cjs.map