@theoremjs/studio 0.3.4-next.460.g4444a29 → 0.3.4-next.464.g5fc5eed

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 (28) hide show
  1. package/compile.js +1 -1
  2. package/package.json +4 -4
  3. package/page/assets/{Banner-BXLdz4y2.js → Banner-fUKWqHmI.js} +2 -2
  4. package/page/assets/{ConsoleFrame-DJ2vIGy8.js → ConsoleFrame-B3cd6mje.js} +1 -1
  5. package/page/assets/{ContextMenu-DnU_R5on.js → ContextMenu-C1HQbsdS.js} +2 -2
  6. package/page/assets/{ToolResultCharts-BFLDoF4L.js → ToolResultCharts-CngV4ccU.js} +1 -1
  7. package/page/assets/{TraceInspector-CLL7OG3M.js → TraceInspector-BJS_1iXX.js} +1 -1
  8. package/page/assets/{TraceOverview-BUqgljgU.js → TraceOverview-6hlA2pmX.js} +1 -1
  9. package/page/assets/{browser-engine-zievI8f-.js → browser-engine-BReGdZx4.js} +1 -1
  10. package/page/assets/browser-transport-Bsz-KNbB.js +47 -0
  11. package/page/assets/{export-agent-Dz3Y7tO7.js → export-agent-DDZ8cq19.js} +1 -1
  12. package/page/assets/{guardrail-tester-D-hsX8gK.js → guardrail-tester-C_T6-YOZ.js} +1 -1
  13. package/page/assets/{index-DGzlieAM.js → index-Cw3Spve0.js} +6 -6
  14. package/page/assets/{studio-code-pane-BNwB_may.js → studio-code-pane-xsBtdlWI.js} +1 -1
  15. package/page/assets/{studio-console-gYuEwLzY.js → studio-console-C3uStRGc.js} +1 -1
  16. package/page/assets/{studio-decision-BenlP-cQ.js → studio-decision-MvC7eEPm.js} +1 -1
  17. package/page/assets/{studio-embedding-ChUIvwWb.js → studio-embedding-mvARkljv.js} +1 -1
  18. package/page/assets/{studio-host-console-Dg6LezAO.js → studio-host-console-CzHR2V7s.js} +2 -2
  19. package/page/assets/{studio-labels-YnrLEnjn.js → studio-labels-DsQLZ9_e.js} +1 -1
  20. package/page/assets/{studio-live-CaYSM1iE.js → studio-live-DXV_PScy.js} +1 -1
  21. package/page/assets/{studio-map-BYqiUV_l.js → studio-map-DBLOQt2Q.js} +1 -1
  22. package/page/assets/{studio-trace-replay-DDcuo5Zv.js → studio-trace-replay-DHJTvGZO.js} +1 -1
  23. package/page/assets/{use-one-call-DLdyrBVf.js → use-one-call-B3x4YoMP.js} +1 -1
  24. package/page/index.html +5 -5
  25. package/ui/tree-map.css +0 -82
  26. package/ui/tree-map.d.ts +7 -5
  27. package/ui/tree-map.js +181 -55
  28. package/page/assets/browser-transport-ArRkOmu8.js +0 -47
package/ui/tree-map.css CHANGED
@@ -13,85 +13,3 @@
13
13
  .studio-tree-map-lines .map-line {
14
14
  stroke: color-mix(in srgb, var(--color-border-emphasized) 60%, var(--color-background-surface));
15
15
  }
16
-
17
- /*
18
- * Detail adds nodes. What is drawn moves to make room first, then each added node draws in after
19
- * the one before, as the loader's map draws (read-map.css): its line, then its token. Without
20
- * detail, the added ones leave in the reverse order, then the rest moves back.
21
- * invariant: Transitions, not keyframes, so both ways ease, and a turn mid-way goes back from
22
- * where it is. An added node only ever jumps to its place while it is not drawn.
23
- */
24
- .studio-tree-map {
25
- --added-step: 40ms;
26
- --added-draw: var(--duration-medium, 240ms);
27
- --map-move: var(--duration-slow, 400ms);
28
- /* How long the added nodes take to leave, before the rest moves back. */
29
- --map-leave: calc(var(--added-n) * var(--added-step) + 2 * var(--added-draw));
30
- --map-ease: var(--ease-standard, ease-out);
31
- }
32
-
33
- .studio-tree-map > [data-added] {
34
- opacity: 0;
35
- }
36
-
37
- .studio-tree-map-lines [data-added] {
38
- stroke-dasharray: 1;
39
- stroke-dashoffset: var(--added-from);
40
- }
41
-
42
- .studio-tree-map[data-detail] > [data-added] {
43
- opacity: 1;
44
- }
45
-
46
- .studio-tree-map[data-detail] .studio-tree-map-lines [data-added] {
47
- stroke-dashoffset: 0;
48
- }
49
-
50
- /* invariant: With reduced motion, nothing moves: each node is at once where it ends. */
51
- @media (prefers-reduced-motion: no-preference) {
52
- .studio-tree-map > .map-token,
53
- .studio-tree-map-lines .map-line {
54
- transition:
55
- top var(--map-move) var(--map-ease) var(--map-leave),
56
- left var(--map-move) var(--map-ease) var(--map-leave),
57
- d var(--map-move) var(--map-ease) var(--map-leave);
58
- }
59
-
60
- .studio-tree-map > [data-added] {
61
- transition:
62
- opacity var(--added-draw) var(--map-ease)
63
- calc((var(--added-n) - var(--added-i)) * var(--added-step)),
64
- top 0s var(--map-leave),
65
- left 0s var(--map-leave);
66
- }
67
-
68
- .studio-tree-map-lines [data-added] {
69
- transition:
70
- stroke-dashoffset var(--added-draw) var(--map-ease)
71
- calc((var(--added-n) - var(--added-i)) * var(--added-step) + var(--added-draw)),
72
- d 0s var(--map-leave);
73
- }
74
-
75
- .studio-tree-map[data-detail] > .map-token {
76
- transition-delay: 0s;
77
- }
78
-
79
- .studio-tree-map[data-detail] > [data-added] {
80
- transition:
81
- opacity var(--added-draw) var(--map-ease)
82
- calc(var(--map-move) + var(--added-i) * var(--added-step) + var(--added-draw)),
83
- top 0s,
84
- left 0s;
85
- }
86
-
87
- .studio-tree-map[data-detail] .studio-tree-map-lines .map-line {
88
- transition-delay: 0s;
89
- }
90
-
91
- .studio-tree-map[data-detail] .studio-tree-map-lines [data-added] {
92
- transition:
93
- stroke-dashoffset var(--added-draw) var(--map-ease)
94
- calc(var(--map-move) + var(--added-i) * var(--added-step)),
95
- d 0s;
96
- }
97
- }
package/ui/tree-map.d.ts CHANGED
@@ -4,10 +4,12 @@ export interface StudioTreeMapProps {
4
4
  /** The keys of the agents to draw, in the workspace's order; every agent when unset. */
5
5
  agents?: readonly string[] | undefined;
6
6
  /**
7
- * Every tool in the registry, not a few, and each turn runner opened into the steps of a turn. Turned on, what is drawn moves to make room, then each
8
- * node it adds draws in after the one before, its line first, as the loader's map draws; turned
9
- * off, they leave in the reverse order and the rest moves back.
7
+ * How far the tree has grown, from 0 to 1. As it grows each section drifts to its own zone: the
8
+ * providers to a band along the top, each agent's tree apart from the next with its runner level
9
+ * with it, and the tool registry to a field of its own. What growing adds draws in on the way,
10
+ * each over its own stretch, its line and then its token: the steps of a turn under each turn
11
+ * runner, and every tool in the registry. Shrinking takes it all back the same way.
10
12
  */
11
- detail?: boolean | undefined;
13
+ grow?: number | undefined;
12
14
  }
13
- export declare function StudioTreeMap({ workspace, agents, detail }: StudioTreeMapProps): import("react").JSX.Element;
15
+ export declare function StudioTreeMap({ workspace, agents, grow }: StudioTreeMapProps): import("react").JSX.Element;
package/ui/tree-map.js CHANGED
@@ -34,7 +34,7 @@ function rowsOf(workspace, only) {
34
34
  agent,
35
35
  x: PAD + depth * INDENT,
36
36
  y: PAD + HALF + rows.length * ROW,
37
- ...(parent ? { parent: { x: parent.x, y: parent.y } } : {}),
37
+ ...(parent ? { parent: rowId(parent) } : {}),
38
38
  };
39
39
  rows.push(row);
40
40
  for (const child of node.children)
@@ -170,79 +170,205 @@ function linePath(from, to) {
170
170
  const x = from.x + TRUNK;
171
171
  return `M ${x} ${from.y + HALF} V ${to.y - TURN} Q ${x} ${to.y} ${x + TURN} ${to.y} H ${to.x - LINE_GAP}`;
172
172
  }
173
- /** The order an added node draws in, and which end its line starts from: 1 the path's start, -1 its end. */
174
- const addedStyle = (index, from = 1) => ({ '--added-i': index, '--added-from': from });
175
173
  /**
176
- * A line's path as a style too, so a line that moves eases to its new shape where the browser
177
- * eases `d`; the attribute draws it where it does not.
174
+ * From under the parent's icon to a child in any column of the rows under it: across just under
175
+ * the parent to the child's own trunk, a level in from the child, then down it and across. A child
176
+ * one level in has its trunk under the parent's icon, so it is the tree's line.
178
177
  */
179
- const pathStyle = (d, style) => ({ ...style, d: `path("${d}")` });
180
- export function StudioTreeMap({ workspace, agents, detail = false }) {
178
+ function underPath(from, to) {
179
+ const trunk = to.x - INDENT + TRUNK;
180
+ const across = from.y + HALF + LINE_GAP;
181
+ return (`M ${from.x + TRUNK} ${from.y + HALF} V ${across} H ${trunk} V ${to.y - TURN}` +
182
+ ` Q ${trunk} ${to.y} ${trunk + TURN} ${to.y} H ${to.x - LINE_GAP}`);
183
+ }
184
+ /** Grown, a row's height and the room between two agents' trees. */
185
+ const GROWN_ROW = 28;
186
+ const AGENT_GAP = 16;
187
+ /** Grown, the providers' band and the room under it. */
188
+ const BAND = GROWN_ROW + AGENT_GAP;
189
+ /** Grown, a turn's steps in rows under its runner, so many to a row. */
190
+ const STEPS_ACROSS = 3;
191
+ const STEP_SLOT = 160;
192
+ /** Grown, the registry's field: right of the turn's steps, its tools in columns this tall. */
193
+ const REGISTRY_IN = 186;
194
+ const TOOLS_DOWN = 16;
195
+ const TOOL_SLOT = 210;
196
+ /** Over what stretch of growing the added nodes draw, and how long each takes of it. */
197
+ const DRAW_FROM = 0.2;
198
+ const DRAW_TO = 0.95;
199
+ const DRAW_SPAN = 0.1;
200
+ const clamp = (value) => Math.min(Math.max(value, 0), 1);
201
+ const between = (from, to, at) => from + (to - from) * at;
202
+ /** Every other one from each list, while both last: the turn's steps and the tools draw by turns. */
203
+ function byTurns(first, second) {
204
+ return Array.from({ length: Math.max(first.length, second.length) }, (_, index) => [first[index], second[index]].filter((each) => each !== undefined)).flat();
205
+ }
206
+ /** The rows grown: restacked, each agent apart from the next, under the providers' band. */
207
+ function grownRows(rows) {
208
+ const places = new Map();
209
+ let agents = -1;
210
+ rows.forEach((row, index) => {
211
+ if (index === 0 || rows[index - 1]?.agent !== row.agent)
212
+ agents += 1;
213
+ places.set(rowId(row), {
214
+ x: row.x,
215
+ y: PAD + HALF + BAND + index * GROWN_ROW + agents * AGENT_GAP,
216
+ });
217
+ });
218
+ return places;
219
+ }
220
+ /** The next place under a holder, counting it. */
221
+ function nextUnder(growing, holder) {
222
+ const index = growing.under.get(holder) ?? 0;
223
+ growing.under.set(holder, index + 1);
224
+ return index;
225
+ }
226
+ /** A provider's place in the band, by name: an agent that has one too shares it. */
227
+ function bandPlace(growing, feed) {
228
+ const held = growing.band.get(feed.label);
229
+ if (held)
230
+ return held;
231
+ const place = { x: growing.bandX, y: PAD + HALF };
232
+ growing.band.set(feed.label, place);
233
+ growing.bandX += growing.width(feed.id) + AGENT_GAP;
234
+ return place;
235
+ }
236
+ /** Under the registry: its tools in columns, then the tool runner below them. */
237
+ function registryPlace(growing, feed, above) {
238
+ if (feed.depth === 0) {
239
+ const tools = Math.min(growing.under.get(REGISTRY) ?? 0, TOOLS_DOWN);
240
+ return { x: above.x, y: above.y + (tools + 1) * GROWN_ROW };
241
+ }
242
+ const index = nextUnder(growing, REGISTRY);
243
+ return {
244
+ x: above.x + INDENT + Math.floor(index / TOOLS_DOWN) * TOOL_SLOT,
245
+ y: above.y + ((index % TOOLS_DOWN) + 1) * GROWN_ROW,
246
+ };
247
+ }
248
+ /** A step under its runner, in rows so many across. */
249
+ function stepPlace(growing, holder, above) {
250
+ const index = nextUnder(growing, holder);
251
+ const y = above.y + (Math.floor(index / STEPS_ACROSS) + 1) * GROWN_ROW;
252
+ growing.stepsEnd = Math.max(growing.stepsEnd, y);
253
+ return { x: above.x + INDENT + (index % STEPS_ACROSS) * STEP_SLOT, y };
254
+ }
255
+ function feedPlace(growing, feed) {
256
+ if (feed.id.includes('/provider:'))
257
+ return bandPlace(growing, feed);
258
+ if (feed.id === REGISTRY) {
259
+ return { x: growing.feedX + REGISTRY_IN, y: growing.stepsEnd + GROWN_ROW * 1.5 };
260
+ }
261
+ const above = feed.under === undefined ? undefined : growing.places.get(feed.under);
262
+ if (feed.under === REGISTRY && above)
263
+ return registryPlace(growing, feed, above);
264
+ if (feed.under !== undefined && above)
265
+ return stepPlace(growing, feed.under, above);
266
+ const into = growing.places.get(feed.into[0] ?? '');
267
+ return { x: growing.feedX, y: into?.y ?? feed.y };
268
+ }
269
+ /** Each node's place grown: by its token id, rows and feeds alike. */
270
+ function grownPlaces(rows, feeds, feedX, width) {
271
+ const growing = {
272
+ places: grownRows(rows),
273
+ band: new Map(),
274
+ bandX: feedX,
275
+ under: new Map(),
276
+ stepsEnd: PAD + HALF + BAND,
277
+ feedX,
278
+ width,
279
+ };
280
+ for (const feed of feeds)
281
+ growing.places.set(feed.id, feedPlace(growing, feed));
282
+ return growing.places;
283
+ }
284
+ export function StudioTreeMap({ workspace, agents, grow = 0 }) {
181
285
  const root = useRef(null);
182
286
  const rows = rowsOf(workspace, agents);
183
287
  const few = feedsOf(workspace, rows, false);
184
288
  const full = feedsOf(workspace, rows, true);
185
- const fewIds = new Set(few.map((feed) => feed.id));
186
- const addedIndex = new Map(full.filter((feed) => !fewIds.has(feed.id)).map((feed, index) => [feed.id, index]));
187
- /** The feeds laid out; without detail, an added one waits on the feed it comes under. */
188
- const feeds = detail ? full : few;
189
289
  const widths = useTokenWidths(root, workspace);
290
+ const width = (id) => widths[id] ?? GUESS;
190
291
  const drafts = new Map(workspace.agents.map((agent) => [
191
292
  agent.key,
192
293
  libraryDraft(workspace, agent.key) ?? createBlankDraft(),
193
294
  ]));
194
- const right = (row) => row.x + (widths[rowId(row)] ?? GUESS);
195
- const feedX = Math.max(0, ...rows.map(right)) + GAP;
196
- const byId = new Map(rows.map((row) => [rowId(row), row]));
197
- const feedById = new Map(feeds.map((feed) => [feed.id, feed]));
198
- const placed = (feed) => feedById.get(feed.id) ?? { ...feed, y: feedById.get(feed.under ?? '')?.y ?? feed.y };
199
- const height = PAD * 2 + Math.max(rows.length * ROW, ...feeds.map((feed) => feed.y + HALF - PAD));
200
- const feedLeft = (feed) => feedX + feed.depth * INDENT;
201
- const feedRight = (feed) => feedLeft(feed) + (widths[feed.id] ?? GUESS);
202
- /** Right of every feed from `above` down to `feed`. */
203
- const railFor = (feed, above) => Math.max(...feeds.filter((each) => each.y >= above.y && each.y <= feed.y).map(feedRight)) +
204
- RAIL;
205
- const rails = feeds.flatMap((feed) => {
295
+ const feedX = Math.max(0, ...rows.map((row) => row.x + width(rowId(row)))) + GAP;
296
+ // The tree as it stands: the rows, and the few feeds beside them.
297
+ const closed = new Map(rows.map((row) => [rowId(row), row]));
298
+ for (const feed of few)
299
+ closed.set(feed.id, { x: feedX + feed.depth * INDENT, y: feed.y });
300
+ const grown = grownPlaces(rows, full, feedX, width);
301
+ const feedById = new Map(full.map((feed) => [feed.id, feed]));
302
+ /**
303
+ * Where a node is, this far grown. One growing adds keeps its place in its zone and rides with
304
+ * the feed it comes under, so a zone drifts whole.
305
+ */
306
+ const at = (id) => {
307
+ const to = grown.get(id) ?? closed.get(id) ?? { x: 0, y: 0 };
308
+ const from = closed.get(id);
309
+ if (from)
310
+ return { x: between(from.x, to.x, grow), y: between(from.y, to.y, grow) };
311
+ const under = feedById.get(id)?.under;
312
+ const holder = under === undefined ? undefined : grown.get(under);
313
+ if (under === undefined || holder === undefined)
314
+ return to;
315
+ const now = at(under);
316
+ return { x: to.x + now.x - holder.x, y: to.y + now.y - holder.y };
317
+ };
318
+ // What growing adds draws in order, the turn's steps and the tools by turns.
319
+ const fewIds = new Set(few.map((feed) => feed.id));
320
+ const added = full.filter((feed) => !fewIds.has(feed.id));
321
+ const order = byTurns(added.filter((feed) => feed.under !== REGISTRY), added.filter((feed) => feed.under === REGISTRY));
322
+ /** How far an added node has drawn, 0 to 1: its line in the first half, its token in the second. */
323
+ const drawn = new Map(order.map((feed, index) => {
324
+ const start = DRAW_FROM + ((DRAW_TO - DRAW_SPAN - DRAW_FROM) * index) / Math.max(order.length - 1, 1);
325
+ return [feed.id, clamp((grow - start) / DRAW_SPAN)];
326
+ }));
327
+ const lineDrawn = (id) => {
328
+ const part = drawn.get(id);
329
+ return part === undefined
330
+ ? {}
331
+ : { pathLength: 1, style: { strokeDasharray: 1, strokeDashoffset: 1 - clamp(part * 2) } };
332
+ };
333
+ const shown = full.filter((feed) => (drawn.get(feed.id) ?? 1) > 0);
334
+ const right = (id) => at(id).x + width(id);
335
+ /** Right of every feed from `above` down to `feed`, where each stands now. */
336
+ const railFor = (feed, above) => {
337
+ const [top, bottom] = [at(above.id).y, at(feed.id).y].sort((a, b) => a - b);
338
+ const lying = shown.filter((each) => {
339
+ const { y } = at(each.id);
340
+ return y >= (top ?? 0) && y <= (bottom ?? 0) && each.id !== feed.id;
341
+ });
342
+ return Math.max(right(feed.id), ...lying.map((each) => right(each.id))) + RAIL;
343
+ };
344
+ const places = [...rows.map(rowId), ...shown.map((feed) => feed.id)];
345
+ const rails = shown.flatMap((feed) => {
206
346
  const above = feed.under === undefined ? undefined : feedById.get(feed.under);
207
347
  return above && feed.depth <= above.depth ? [railFor(feed, above)] : [];
208
348
  });
209
- const width = Math.max(GUESS, ...feeds.map(feedRight), ...rails) + PAD;
210
- /** What marks a node or line detail adds: its turn to draw, and the end its line draws from. */
211
- const addedProps = (id, from = 1) => {
212
- const index = addedIndex.get(id);
213
- return index === undefined ? {} : { 'data-added': '', style: addedStyle(index, from) };
214
- };
215
- return (_jsxs("div", { ref: root, className: "studio-tree-map", "data-detail": detail ? '' : undefined, style: { width, height, '--added-n': addedIndex.size }, children: [_jsxs("svg", { className: "studio-tree-map-lines", width: width, height: height, "aria-hidden": "true", children: [rows.map((row) => row.parent && (_jsx("path", { className: "map-line", d: linePath(row.parent, row), style: pathStyle(linePath(row.parent, row)) }, rowId(row)))), full.flatMap((each) => {
216
- const feed = placed(each);
217
- return feed.into.map((id) => {
218
- const row = byId.get(id);
219
- if (!row)
220
- return null;
221
- const { d } = mapCurve({ x: feedX - LINE_GAP, y: feed.y }, { x: right(row) + LINE_GAP, y: row.y });
222
- // The line runs from the feed to the row; it draws from the row.
223
- const { style, ...added } = addedProps(feed.id, -1);
224
- return (_jsx("path", { className: "map-line", d: d, pathLength: 1, style: pathStyle(d, style), ...added }, `${feed.id}>${id}`));
225
- });
226
- }), full.map((each) => {
227
- const feed = placed(each);
349
+ const mapWidth = Math.max(GUESS, ...places.map(right), ...rails) + PAD;
350
+ const height = Math.max(...places.map((id) => at(id).y)) + HALF + PAD;
351
+ return (_jsxs("div", { ref: root, className: "studio-tree-map", style: { width: mapWidth, height }, children: [_jsxs("svg", { className: "studio-tree-map-lines", width: mapWidth, height: height, "aria-hidden": "true", children: [rows.map((row) => row.parent && (_jsx("path", { className: "map-line", d: linePath(at(row.parent), at(rowId(row))) }, rowId(row)))), shown.flatMap((feed) => feed.into.map((id) => {
352
+ const from = at(feed.id);
353
+ const { d } = mapCurve({ x: from.x - LINE_GAP, y: from.y }, { x: right(id) + LINE_GAP, y: at(id).y });
354
+ return _jsx("path", { className: "map-line", d: d }, `${feed.id}>${id}`);
355
+ })), shown.map((feed) => {
228
356
  const above = feed.under === undefined ? undefined : feedById.get(feed.under);
229
357
  if (above === undefined)
230
358
  return null;
231
- const from = { x: feedLeft(above), y: above.y };
232
- // One of its own turns in from the trunk, as a tree row does; one level with it comes round
359
+ // One of its own comes down from it, as a tree row does; one level with it comes round
233
360
  // the right of what lies between, so it reads as joining the feed, not as one of its own.
234
- const isOwn = feed.depth > above.depth;
235
- const d = isOwn
236
- ? linePath(from, { x: feedLeft(feed), y: feed.y })
237
- : sidePath({ x: feedRight(feed) + LINE_GAP, y: feed.y }, { x: feedRight(above) + LINE_GAP, y: above.y }, railFor(feed, above));
238
- // A turn in runs from the feed above; a line round the side runs from this one.
239
- const { style, ...added } = addedProps(feed.id, isOwn ? 1 : -1);
240
- return (_jsx("path", { className: "map-line", d: d, pathLength: 1, style: pathStyle(d, style), ...added }, `${feed.id}^`));
361
+ const d = feed.depth > above.depth
362
+ ? underPath(at(above.id), at(feed.id))
363
+ : sidePath({ x: right(feed.id) + LINE_GAP, y: at(feed.id).y }, { x: right(above.id) + LINE_GAP, y: at(above.id).y }, railFor(feed, above));
364
+ return _jsx("path", { className: "map-line", d: d, ...lineDrawn(feed.id) }, `${feed.id}^`);
241
365
  })] }), rows.map((row) => {
242
366
  const draft = drafts.get(row.agent) ?? createBlankDraft();
243
- return (_jsx(MapToken, { id: rowId(row), label: row.node.label, icon: nodeIcon(draft, row.node.ref), x: row.x, y: row.y }, rowId(row)));
244
- }), full.map((each) => {
245
- const feed = placed(each);
246
- return (_jsx(MapToken, { id: feed.id, label: feed.label, icon: feed.icon, x: feedLeft(feed), y: feed.y, ...addedProps(feed.id) }, feed.id));
367
+ const { x, y } = at(rowId(row));
368
+ return (_jsx(MapToken, { id: rowId(row), label: row.node.label, icon: nodeIcon(draft, row.node.ref), x: x, y: y }, rowId(row)));
369
+ }), shown.map((feed) => {
370
+ const { x, y } = at(feed.id);
371
+ const part = drawn.get(feed.id);
372
+ return (_jsx(MapToken, { id: feed.id, label: feed.label, icon: feed.icon, x: x, y: y, ...(part === undefined ? {} : { style: { opacity: clamp(part * 2 - 1) } }) }, feed.id));
247
373
  })] }));
248
374
  }