@morlay/dsh-client-ui-primitives 0.0.6 → 0.0.7

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.
@@ -0,0 +1,4576 @@
1
+ import { n as __exportAll, t as __commonJSMin } from "./rolldown-runtime-EAsCxrDo.mjs";
2
+ import { a as parseReference, i as isLocalReference, n as formatReference, o as parseReferenceToken, r as formatReferenceMention, t as findReferences } from "./reference-Cjcn21uW.mjs";
3
+ import { createSnapshotStore } from "@deepseek-ai/dsh-client-store";
4
+ import { Service } from "@deepseek-ai/cordis";
5
+ import { cloneElement, createElement, forwardRef, useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
6
+ import { IconCheckOutlineRegular, IconChevronDownOutlineRegular, IconChevronRightOutlineRegular, IconCloseOutlineRegular, IconCopyOutlineRegular, IconRefreshOutlineRegular, IconTrashOutlineRegular, Input, MarkdownText, Menu, SettingsForm as SettingsForm$1, Tooltip } from "@deepseek-ai/dsh-client-ui-primitives";
7
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
8
+ function emptyMeta() {
9
+ return {
10
+ description: void 0,
11
+ comment: void 0,
12
+ link: void 0,
13
+ role: void 0,
14
+ secret: false,
15
+ required: false,
16
+ disabled: false,
17
+ collapse: false,
18
+ badges: [],
19
+ pattern: void 0,
20
+ min: void 0,
21
+ max: void 0,
22
+ step: void 0,
23
+ hasDefault: false,
24
+ defaultValue: void 0,
25
+ extra: void 0
26
+ };
27
+ }
28
+ function badgesOf(meta) {
29
+ return (meta.badges ?? []).map((badge) => badge.text);
30
+ }
31
+ function metaOf(schema) {
32
+ const meta = schema.meta ?? {};
33
+ return {
34
+ description: meta.description,
35
+ comment: meta.comment,
36
+ link: meta.link,
37
+ role: meta.role,
38
+ secret: meta.role === "secret",
39
+ required: meta.required === true,
40
+ disabled: meta.disabled === true,
41
+ collapse: meta.collapse === true,
42
+ badges: badgesOf(meta),
43
+ pattern: typeof meta.pattern === "string" ? meta.pattern : meta.pattern?.source ?? void 0,
44
+ min: meta.min,
45
+ max: meta.max,
46
+ step: meta.step,
47
+ hasDefault: meta.default !== void 0,
48
+ defaultValue: meta.default,
49
+ extra: meta.extra
50
+ };
51
+ }
52
+ function mergeMeta(inner, outer) {
53
+ const merged = { ...inner };
54
+ for (const [key, value] of Object.entries(outer)) if (value !== void 0) merged[key] = value;
55
+ return merged;
56
+ }
57
+ function keyOf(path) {
58
+ return path[path.length - 1] ?? "";
59
+ }
60
+ function stringLeaf(path, meta) {
61
+ return {
62
+ key: keyOf(path),
63
+ path,
64
+ label: void 0,
65
+ meta,
66
+ readOnly: null,
67
+ type: "string"
68
+ };
69
+ }
70
+ function leafTypeOf(type) {
71
+ switch (type) {
72
+ case "string": return "string";
73
+ case "number": return "number";
74
+ case "boolean": return "boolean";
75
+ case "function": return "function";
76
+ case "never": return "never";
77
+ default: return "any";
78
+ }
79
+ }
80
+ function projectNode(schema, path = []) {
81
+ return project(schema, path, []);
82
+ }
83
+ function project(schema, path, ancestors) {
84
+ const base = {
85
+ key: keyOf(path),
86
+ path,
87
+ label: void 0,
88
+ meta: metaOf(schema),
89
+ readOnly: null
90
+ };
91
+ if (ancestors.includes(schema)) return {
92
+ ...base,
93
+ type: "recursive",
94
+ origin: schema.type
95
+ };
96
+ const chain = [...ancestors, schema];
97
+ switch (schema.type) {
98
+ case "object": {
99
+ const fields = Object.entries(schema.dict ?? {}).filter(([, child]) => child.meta?.hidden !== true).map(([key, child]) => project(child, [...path, key], chain));
100
+ return {
101
+ ...base,
102
+ type: "object",
103
+ fields
104
+ };
105
+ }
106
+ case "dict": {
107
+ const segment = [...path, "*"];
108
+ const keyNode = schema.sKey === void 0 ? stringLeaf(segment, emptyMeta()) : project(schema.sKey, segment, chain);
109
+ return {
110
+ ...base,
111
+ type: "dict",
112
+ keyNode,
113
+ valueNode: project(schema.inner ?? schema, segment, chain)
114
+ };
115
+ }
116
+ case "array": {
117
+ const item = project(schema.inner ?? schema, [...path, "*"], chain);
118
+ return {
119
+ ...base,
120
+ type: "array",
121
+ item,
122
+ mergeKey: mergeKeyOf(schema, item)
123
+ };
124
+ }
125
+ case "tuple": {
126
+ const items = (schema.list ?? []).map((child, index) => project(child, [...path, String(index)], chain));
127
+ return {
128
+ ...base,
129
+ type: "tuple",
130
+ items
131
+ };
132
+ }
133
+ case "union": {
134
+ const members = schema.list ?? [];
135
+ const variants = members.map((child) => project(child, path, chain));
136
+ const literals = members.every((child) => child.type === "const") ? members.map((child) => child.value) : void 0;
137
+ return {
138
+ ...base,
139
+ type: "union",
140
+ choices: literals,
141
+ variants,
142
+ tagKey: tagKeyOf(schema, variants)
143
+ };
144
+ }
145
+ case "intersect": return {
146
+ ...base,
147
+ type: "intersect",
148
+ members: (schema.list ?? []).map((child) => project(child, path, chain))
149
+ };
150
+ case "bitset": {
151
+ const bits = Object.entries(schema.bits ?? {}).map(([name, bit]) => ({
152
+ name,
153
+ bit
154
+ }));
155
+ return {
156
+ ...base,
157
+ type: "bitset",
158
+ bits
159
+ };
160
+ }
161
+ case "const": return {
162
+ ...base,
163
+ type: "const",
164
+ value: schema.value
165
+ };
166
+ case "transform": {
167
+ const projected = project(schema.inner ?? schema, path, chain);
168
+ return {
169
+ ...projected,
170
+ meta: mergeMeta(projected.meta, base.meta),
171
+ readOnly: "transform"
172
+ };
173
+ }
174
+ case "lazy": {
175
+ const inner = schema.inner;
176
+ return inner === void 0 ? {
177
+ ...base,
178
+ type: "any"
179
+ } : {
180
+ ...base,
181
+ type: "lazy",
182
+ inner: project(inner, path, chain)
183
+ };
184
+ }
185
+ case "is": return {
186
+ ...base,
187
+ type: "any",
188
+ readOnly: "constructor"
189
+ };
190
+ default: return {
191
+ ...base,
192
+ type: leafTypeOf(schema.type),
193
+ readOnly: schema.type === "function" ? "function" : null
194
+ };
195
+ }
196
+ }
197
+ function unwrapLazy(node) {
198
+ let current = node;
199
+ while (current?.type === "lazy") current = current.inner;
200
+ return current;
201
+ }
202
+ function fieldsOf(node) {
203
+ const current = unwrapLazy(node);
204
+ switch (current?.type) {
205
+ case "object": return current.fields;
206
+ case "union": return current.variants.flatMap((variant) => fieldsOf(variant));
207
+ case "intersect": return current.members.flatMap((member) => fieldsOf(member));
208
+ default: return [];
209
+ }
210
+ }
211
+ function seekNode(root, path) {
212
+ let current = root;
213
+ for (const segment of path) {
214
+ const node = unwrapLazy(current);
215
+ if (node === void 0) return void 0;
216
+ switch (node.type) {
217
+ case "object":
218
+ case "union":
219
+ case "intersect":
220
+ current = fieldsOf(node).find((field) => field.key === segment);
221
+ break;
222
+ case "dict":
223
+ current = node.valueNode;
224
+ break;
225
+ case "array":
226
+ current = node.item;
227
+ break;
228
+ case "tuple":
229
+ current = node.items[Number(segment)];
230
+ break;
231
+ default: return;
232
+ }
233
+ }
234
+ return unwrapLazy(current);
235
+ }
236
+ function walkFields(root, value) {
237
+ const out = [];
238
+ visit(root, root.path, value, out, true, void 0, /* @__PURE__ */ new Set(), void 0);
239
+ return out;
240
+ }
241
+ function visit(node, path, value, out, emit, label, emitted, member) {
242
+ const current = unwrapLazy(node);
243
+ if (current === void 0) return;
244
+ const positioned = {
245
+ ...current,
246
+ path,
247
+ ...member === void 0 ? {} : { key: member.key },
248
+ ...label === void 0 ? {} : { label }
249
+ };
250
+ const key = JSON.stringify(path);
251
+ if (emit && !emitted.has(key)) {
252
+ emitted.add(key);
253
+ out.push({
254
+ path,
255
+ node: positioned,
256
+ ...member === void 0 ? {} : { member }
257
+ });
258
+ }
259
+ switch (positioned.type) {
260
+ case "object":
261
+ for (const field of positioned.fields) {
262
+ const child = memberOf(value, field.key);
263
+ if (child === void 0 && field.meta.required !== true) continue;
264
+ visit(field, [...path, field.key], child, out, true, void 0, emitted, void 0);
265
+ }
266
+ return;
267
+ case "dict":
268
+ for (const [key, child] of entriesOf(value)) visit(positioned.valueNode, [...path, key], child, out, true, void 0, emitted, {
269
+ parent: path,
270
+ key,
271
+ index: void 0
272
+ });
273
+ return;
274
+ case "array":
275
+ for (const [key, child] of entriesOf(value)) {
276
+ const label = positioned.mergeKey === void 0 ? void 0 : memberLabel(child, positioned.mergeKey);
277
+ visit(positioned.item, [...path, key], child, out, true, label, emitted, {
278
+ parent: path,
279
+ key,
280
+ index: Number(key)
281
+ });
282
+ }
283
+ return;
284
+ case "tuple":
285
+ positioned.items.forEach((item, index) => {
286
+ visit(item, [...path, String(index)], memberOf(value, index), out, true, void 0, emitted, void 0);
287
+ });
288
+ return;
289
+ case "union": {
290
+ if (positioned.choices !== void 0) return;
291
+ const variant = pickVariant(positioned, value);
292
+ if (variant !== void 0) visit(variant, path, value, out, false, void 0, emitted, member);
293
+ return;
294
+ }
295
+ case "intersect":
296
+ for (const part of positioned.members) visit(part, path, value, out, false, void 0, emitted, member);
297
+ return;
298
+ default: return;
299
+ }
300
+ }
301
+ function mergeKeyOf(schema, item) {
302
+ const declared = declaredExtra(schema, "mergeKey");
303
+ if (declared !== void 0) return declared;
304
+ const current = unwrapLazy(item);
305
+ return current?.type === "object" && current.fields.some((field) => field.key === "id") ? "id" : void 0;
306
+ }
307
+ function tagKeyOf(schema, variants) {
308
+ const declared = declaredExtra(schema, "tag");
309
+ if (declared !== void 0) return declared;
310
+ const members = variants.map((variant) => unwrapLazy(variant));
311
+ if (members.length === 0 || members.some((member) => member?.type !== "object")) return void 0;
312
+ const objects = members;
313
+ const candidates = (objects[0]?.fields ?? []).map((field) => unwrapLazy(field)).filter((field) => field?.type === "const").map((field) => field.key).filter((key) => objects.every((object) => unwrapLazy(object.fields.find((field) => field.key === key))?.type === "const"));
314
+ return candidates.length === 1 ? candidates[0] : void 0;
315
+ }
316
+ function declaredExtra(schema, name) {
317
+ const extra = schema.meta?.extra;
318
+ if (typeof extra !== "object" || extra === null) return void 0;
319
+ const value = Reflect.get(extra, name);
320
+ return typeof value === "string" && value.length > 0 ? value : void 0;
321
+ }
322
+ function memberLabel(value, mergeKey) {
323
+ if (typeof value !== "object" || value === null || Array.isArray(value)) return void 0;
324
+ const member = Reflect.get(value, mergeKey);
325
+ if (typeof member === "string") return member;
326
+ if (typeof member === "number" && Number.isFinite(member)) return String(member);
327
+ }
328
+ function mergeKeyConflict(root, value) {
329
+ return scanConflict(root, root.path, value);
330
+ }
331
+ function scanConflict(node, path, value) {
332
+ const current = unwrapLazy(node);
333
+ if (current === void 0) return void 0;
334
+ switch (current.type) {
335
+ case "object":
336
+ for (const field of current.fields) {
337
+ const conflict = scanConflict(field, [...path, field.key], memberOf(value, field.key));
338
+ if (conflict !== void 0) return conflict;
339
+ }
340
+ return;
341
+ case "dict":
342
+ for (const [key, child] of entriesOf(value)) {
343
+ const conflict = scanConflict(current.valueNode, [...path, key], child);
344
+ if (conflict !== void 0) return conflict;
345
+ }
346
+ return;
347
+ case "array": {
348
+ const names = /* @__PURE__ */ new Set();
349
+ for (const [key, child] of entriesOf(value)) {
350
+ const itemPath = [...path, key];
351
+ if (current.mergeKey !== void 0) {
352
+ const label = memberLabel(child, current.mergeKey);
353
+ if (label === void 0 || label.trim() === "") return {
354
+ kind: "missing",
355
+ path: itemPath,
356
+ mergeKey: current.mergeKey,
357
+ value: ""
358
+ };
359
+ if (names.has(label)) return {
360
+ kind: "duplicate",
361
+ path: itemPath,
362
+ mergeKey: current.mergeKey,
363
+ value: label
364
+ };
365
+ names.add(label);
366
+ }
367
+ const conflict = scanConflict(current.item, itemPath, child);
368
+ if (conflict !== void 0) return conflict;
369
+ }
370
+ return;
371
+ }
372
+ case "tuple":
373
+ for (const [index, item] of current.items.entries()) {
374
+ const conflict = scanConflict(item, [...path, String(index)], memberOf(value, index));
375
+ if (conflict !== void 0) return conflict;
376
+ }
377
+ return;
378
+ case "union": {
379
+ if (current.choices !== void 0) return void 0;
380
+ const variant = pickVariant(current, value);
381
+ return variant === void 0 ? void 0 : scanConflict(variant, path, value);
382
+ }
383
+ case "intersect":
384
+ for (const member of current.members) {
385
+ const conflict = scanConflict(member, path, value);
386
+ if (conflict !== void 0) return conflict;
387
+ }
388
+ return;
389
+ default: return;
390
+ }
391
+ }
392
+ function entriesOf(value) {
393
+ if (Array.isArray(value)) return value.map((item, index) => [String(index), item]);
394
+ if (typeof value === "object" && value !== null) return Object.entries(value);
395
+ return [];
396
+ }
397
+ function memberOf(value, key) {
398
+ if (Array.isArray(value)) return value[Number(key)];
399
+ if (typeof value === "object" && value !== null) return value[String(key)];
400
+ }
401
+ function unionOf(node) {
402
+ const current = unwrapLazy(node);
403
+ return current?.type === "union" ? current : void 0;
404
+ }
405
+ function variantOf(node, value) {
406
+ const union = unionOf(node);
407
+ if (union === void 0) return unwrapLazy(node) ?? node;
408
+ return pickVariant(union, value) ?? union;
409
+ }
410
+ function tagValueOf(variant, tagKey) {
411
+ const current = unwrapLazy(variant);
412
+ if (current?.type !== "object" && current?.type !== "intersect") return {
413
+ found: false,
414
+ value: void 0
415
+ };
416
+ for (const field of fieldsOf(current)) {
417
+ if (field.key !== tagKey) continue;
418
+ const candidate = unwrapLazy(field);
419
+ if (candidate?.type === "const") return {
420
+ found: true,
421
+ value: candidate.value
422
+ };
423
+ }
424
+ return {
425
+ found: false,
426
+ value: void 0
427
+ };
428
+ }
429
+ function variantLabel(variant, tag) {
430
+ if (tag.found) return JSON.stringify(tag.value);
431
+ switch (unwrapLazy(variant)?.type) {
432
+ case "string": return "\"\"";
433
+ case "number": return "0";
434
+ case "boolean": return "true";
435
+ case "array":
436
+ case "tuple": return "[ ]";
437
+ case "object":
438
+ case "dict":
439
+ case "intersect": return "{ }";
440
+ default: return unwrapLazy(variant)?.type ?? "any";
441
+ }
442
+ }
443
+ function variantChoices(union) {
444
+ return union.variants.map((variant) => {
445
+ const tag = union.tagKey === void 0 ? {
446
+ found: false,
447
+ value: void 0
448
+ } : tagValueOf(variant, union.tagKey);
449
+ return {
450
+ label: variantLabel(variant, tag),
451
+ value: tag.found ? tag.value : emptyValueOf(variant)
452
+ };
453
+ });
454
+ }
455
+ function readPath(root, path) {
456
+ return path.reduce((node, segment) => {
457
+ if (Array.isArray(node)) return node[Number(segment)];
458
+ if (typeof node !== "object" || node === null) return void 0;
459
+ return node[segment];
460
+ }, root);
461
+ }
462
+ function isBlankDefault(node) {
463
+ const value = node.meta.defaultValue;
464
+ if (value === null) return true;
465
+ if (node.type !== "object" && node.type !== "intersect") return false;
466
+ return typeof value === "object" && !Array.isArray(value) && Object.keys(value).length === 0;
467
+ }
468
+ function emptyValueOf(node) {
469
+ if (node.meta.hasDefault && !isBlankDefault(node)) return structuredClone(node.meta.defaultValue);
470
+ switch (node.type) {
471
+ case "array": return [];
472
+ case "tuple": return node.items.map((item) => emptyValueOf(item));
473
+ case "dict": return {};
474
+ case "object":
475
+ case "intersect": return Object.fromEntries(fieldsOf(node).map((field) => [field.key, emptyValueOf(field)]));
476
+ case "const": return node.value;
477
+ case "bitset": return 0;
478
+ case "lazy": return emptyValueOf(node.inner);
479
+ default: return null;
480
+ }
481
+ }
482
+ function pickVariant(node, value) {
483
+ if (node.tagKey !== void 0 && typeof value === "object" && value !== null && !Array.isArray(value)) {
484
+ const tagValue = Reflect.get(value, node.tagKey);
485
+ for (const variant of node.variants) {
486
+ const current = unwrapLazy(variant);
487
+ if (current?.type !== "object") continue;
488
+ const field = unwrapLazy(current.fields.find((candidate) => candidate.key === node.tagKey));
489
+ if (field?.type === "const" && field.value === tagValue) return variant;
490
+ }
491
+ }
492
+ for (const variant of node.variants) {
493
+ const current = unwrapLazy(variant);
494
+ if (current?.type === "string" && typeof value === "string") return variant;
495
+ if (current?.type === "number" && typeof value === "number") return variant;
496
+ if (current?.type === "boolean" && typeof value === "boolean") return variant;
497
+ if (current?.type === "array" && Array.isArray(value)) return variant;
498
+ }
499
+ return node.variants[0];
500
+ }
501
+ //#endregion
502
+ //#region src/client/schema-form/draft.ts
503
+ function failureOf(error) {
504
+ const raw = error instanceof Error ? error.message : String(error);
505
+ const path = (error.options?.path ?? []).filter((segment) => typeof segment === "string" || typeof segment === "number").map(String);
506
+ const message = raw.replace(/^\$\S*\s/, "").trim();
507
+ return {
508
+ message: message === "" ? raw : message,
509
+ path
510
+ };
511
+ }
512
+ var SchemaDraftModel = class {
513
+ #scope;
514
+ #root;
515
+ #validate;
516
+ #staged = /* @__PURE__ */ new Map();
517
+ #listeners = /* @__PURE__ */ new Set();
518
+ #unsubscribe;
519
+ #baseline;
520
+ #saving = false;
521
+ #failed = false;
522
+ #violation;
523
+ constructor(options) {
524
+ this.#scope = options.scope;
525
+ this.#root = options.root;
526
+ this.#validate = options.validate;
527
+ this.#unsubscribe = this.#scope.subscribe(() => {
528
+ this.#publish();
529
+ });
530
+ }
531
+ setRoot(root) {
532
+ this.#root = root;
533
+ }
534
+ subscribe(listener) {
535
+ this.#listeners.add(listener);
536
+ return () => {
537
+ this.#listeners.delete(listener);
538
+ };
539
+ }
540
+ bind(project) {
541
+ const store = createSnapshotStore(project());
542
+ this.subscribe(() => {
543
+ store.set(project());
544
+ });
545
+ return store;
546
+ }
547
+ shell() {
548
+ const { writes, blocked } = this.#plan();
549
+ return {
550
+ available: this.#scope.getSnapshot().status === "ready",
551
+ writable: this.#scope.getSnapshot().writable,
552
+ dirty: writes.some((item) => item.op !== void 0) || blocked,
553
+ invalid: blocked || this.#violation !== void 0,
554
+ saving: this.#saving,
555
+ failed: this.#failed
556
+ };
557
+ }
558
+ violation() {
559
+ return this.#violation;
560
+ }
561
+ field(path, preview) {
562
+ const snapshot = this.#scope.getSnapshot();
563
+ const staged = this.#staged.get(pathKey(path));
564
+ const stored = hasPath(snapshot.user, path);
565
+ if (staged === void 0) return {
566
+ value: readPath(preview ?? snapshot.value, path),
567
+ text: void 0,
568
+ invalid: void 0,
569
+ overridden: stored,
570
+ staged: false
571
+ };
572
+ switch (staged.edit.kind) {
573
+ case "value": return {
574
+ value: staged.edit.value,
575
+ text: void 0,
576
+ invalid: void 0,
577
+ overridden: true,
578
+ staged: true
579
+ };
580
+ case "text": {
581
+ const parsed = staged.edit.parse(staged.edit.text);
582
+ return {
583
+ value: parsed.kind === "value" ? parsed.value : readPath(snapshot.value, path),
584
+ text: staged.edit.text,
585
+ invalid: parsed.kind === "invalid" ? parsed.message : void 0,
586
+ overridden: true,
587
+ staged: true
588
+ };
589
+ }
590
+ case "clear": return {
591
+ value: readPath(snapshot.base, path),
592
+ text: void 0,
593
+ invalid: void 0,
594
+ overridden: false,
595
+ staged: true
596
+ };
597
+ case "drop": return {
598
+ value: void 0,
599
+ text: void 0,
600
+ invalid: void 0,
601
+ overridden: false,
602
+ staged: true
603
+ };
604
+ }
605
+ }
606
+ set(path, value) {
607
+ this.#stage(path, {
608
+ kind: "value",
609
+ value
610
+ });
611
+ }
612
+ setText(path, text, parse) {
613
+ this.#stage(path, {
614
+ kind: "text",
615
+ text,
616
+ parse
617
+ });
618
+ }
619
+ clear(path) {
620
+ this.#stage(path, { kind: "clear" });
621
+ }
622
+ appendItem(path) {
623
+ const node = seekNode(this.#root, path);
624
+ if (node?.type !== "array") return;
625
+ const current = readPath(this.preview(), path);
626
+ const index = Array.isArray(current) ? current.length : 0;
627
+ this.set([...path, String(index)], emptyValueOf(node.item));
628
+ }
629
+ removeItem(path, index) {
630
+ this.#stage([...path, String(index)], { kind: "drop" });
631
+ }
632
+ addKey(path, key) {
633
+ const node = seekNode(this.#root, path);
634
+ if (node === void 0) return;
635
+ if (node.type === "dict") {
636
+ this.set([...path, key], emptyValueOf(node.valueNode));
637
+ return;
638
+ }
639
+ const field = fieldsOf(node).find((candidate) => candidate.key === key);
640
+ if (field === void 0) return;
641
+ this.set([...path, key], emptyValueOf(field));
642
+ }
643
+ removeKey(path, key) {
644
+ this.#stage([...path, key], { kind: "drop" });
645
+ }
646
+ revert(path) {
647
+ if (!this.#staged.delete(pathKey(path))) return;
648
+ this.#failed = false;
649
+ this.#violation = void 0;
650
+ this.#publish();
651
+ }
652
+ discard() {
653
+ if (this.#staged.size === 0 && !this.#failed && this.#violation === void 0) return;
654
+ this.#staged.clear();
655
+ this.#baseline = void 0;
656
+ this.#failed = false;
657
+ this.#violation = void 0;
658
+ this.#publish();
659
+ }
660
+ async save() {
661
+ const snapshot = this.#scope.getSnapshot();
662
+ if (this.#saving || !snapshot.writable) return;
663
+ const { writes, blocked } = this.#plan();
664
+ if (blocked) return;
665
+ const ops = writes.flatMap((item) => item.op === void 0 ? [] : [item.op]);
666
+ if (ops.length === 0) {
667
+ this.#violation = void 0;
668
+ this.#publish();
669
+ return;
670
+ }
671
+ const failure = this.#validate(applyOps(snapshot.value ?? {}, ops));
672
+ if (failure !== void 0) {
673
+ this.#violation = failure;
674
+ this.#publish();
675
+ return;
676
+ }
677
+ this.#violation = void 0;
678
+ this.#saving = true;
679
+ this.#failed = false;
680
+ this.#publish();
681
+ try {
682
+ const landed = await this.#scope.mutate(ops, this.#baseline?.revision);
683
+ if (landed) {
684
+ this.#staged.clear();
685
+ this.#baseline = void 0;
686
+ }
687
+ this.#failed = !landed;
688
+ } catch {
689
+ this.#failed = true;
690
+ } finally {
691
+ this.#saving = false;
692
+ this.#publish();
693
+ }
694
+ }
695
+ dispose() {
696
+ this.#unsubscribe();
697
+ this.#listeners.clear();
698
+ }
699
+ #plan() {
700
+ const snapshot = this.#scope.getSnapshot();
701
+ const writes = [];
702
+ let blocked = false;
703
+ for (const { path, edit } of this.#staged.values()) {
704
+ if (edit.kind === "drop") {
705
+ writes.push({ op: {
706
+ op: "unset",
707
+ path: [...path]
708
+ } });
709
+ continue;
710
+ }
711
+ if (edit.kind === "clear") {
712
+ if (hasPath(snapshot.user, path)) writes.push({ op: {
713
+ op: "unset",
714
+ path: [...path]
715
+ } });
716
+ continue;
717
+ }
718
+ const parsed = edit.kind === "value" ? {
719
+ kind: "value",
720
+ value: edit.value
721
+ } : edit.parse(edit.text);
722
+ if (parsed.kind === "invalid") {
723
+ blocked = true;
724
+ continue;
725
+ }
726
+ if (parsed.kind === "skip") continue;
727
+ if (sameValue$1(readPath(snapshot.value, path), parsed.value)) continue;
728
+ writes.push({ op: {
729
+ op: "set",
730
+ path: [...path],
731
+ value: parsed.value
732
+ } });
733
+ }
734
+ return {
735
+ writes,
736
+ blocked
737
+ };
738
+ }
739
+ preview() {
740
+ const ops = this.#plan().writes.flatMap((item) => item.op === void 0 ? [] : [item.op]);
741
+ return applyOps(this.#scope.getSnapshot().value ?? {}, ops);
742
+ }
743
+ #stage(path, edit) {
744
+ this.#baseline ??= this.#scope.getSnapshot();
745
+ this.#staged.set(pathKey(path), {
746
+ path: [...path],
747
+ edit
748
+ });
749
+ this.#failed = false;
750
+ this.#violation = void 0;
751
+ this.#publish();
752
+ }
753
+ #publish() {
754
+ for (const listener of this.#listeners) listener();
755
+ }
756
+ };
757
+ function sameValue$1(left, right) {
758
+ if (Object.is(left, right)) return true;
759
+ if (typeof left !== "object" || typeof right !== "object" || left === null || right === null) return false;
760
+ return JSON.stringify(left) === JSON.stringify(right);
761
+ }
762
+ function pathKey(path) {
763
+ return JSON.stringify(path);
764
+ }
765
+ function hasPath(root, path) {
766
+ if (path.length === 0) return root !== void 0;
767
+ const parent = readPath(root, path.slice(0, -1));
768
+ const leaf = path[path.length - 1] ?? "";
769
+ if (Array.isArray(parent)) return Number(leaf) < parent.length;
770
+ if (typeof parent !== "object" || parent === null) return false;
771
+ return leaf in parent;
772
+ }
773
+ function applyOps(section, ops) {
774
+ const next = structuredClone(section);
775
+ for (const op of ops) {
776
+ const parent = readPath(next, op.path.slice(0, -1));
777
+ const leaf = op.path[op.path.length - 1] ?? "";
778
+ if (Array.isArray(parent)) {
779
+ if (op.op === "set") parent[Number(leaf)] = op.value;
780
+ else parent.splice(Number(leaf), 1);
781
+ continue;
782
+ }
783
+ if (typeof parent !== "object" || parent === null) continue;
784
+ if (op.op === "set") parent[leaf] = op.value;
785
+ else Reflect.deleteProperty(parent, leaf);
786
+ }
787
+ return next;
788
+ }
789
+ //#endregion
790
+ //#region src/client/schema-form/controller.ts
791
+ function declaredSource(node) {
792
+ const extra = node?.meta.extra;
793
+ if (typeof extra !== "object" || extra === null) return void 0;
794
+ const name = Reflect.get(extra, "source");
795
+ return typeof name === "string" && name.length > 0 ? name : void 0;
796
+ }
797
+ function fieldKey(path) {
798
+ return JSON.stringify(path);
799
+ }
800
+ function projectRoot(serialized, rehydrate) {
801
+ try {
802
+ const schema = rehydrate(serialized);
803
+ const root = projectNode(schema);
804
+ if (root.type === "object" || root.type === "intersect") return {
805
+ schema,
806
+ root
807
+ };
808
+ if (root.type === "union" && root.tagKey !== void 0 && root.choices === void 0) return {
809
+ schema,
810
+ root
811
+ };
812
+ return;
813
+ } catch {
814
+ return;
815
+ }
816
+ }
817
+ function canRender(view, rehydrate) {
818
+ return view !== void 0 && projectRoot(view.schema, rehydrate) !== void 0;
819
+ }
820
+ const NO_FIELDS = {
821
+ key: "",
822
+ path: [],
823
+ label: void 0,
824
+ meta: emptyMeta(),
825
+ readOnly: null,
826
+ type: "object",
827
+ fields: []
828
+ };
829
+ function keysOf(value) {
830
+ if (Array.isArray(value)) return value.map((_item, index) => String(index));
831
+ if (typeof value === "object" && value !== null) return Object.keys(value);
832
+ return [];
833
+ }
834
+ function addableAt(node, path, value, hints) {
835
+ const current = variantOf(node, value);
836
+ if (current.type === "dict") {
837
+ const present = new Set(keysOf(value));
838
+ return (hints?.keysFor(path) ?? []).flatMap((key) => present.has(key) ? [] : [{
839
+ key,
840
+ description: void 0
841
+ }]);
842
+ }
843
+ if (current.type !== "object" && current.type !== "intersect") return [];
844
+ return fieldsOf(current).flatMap((field) => field.meta.required !== true && readPath(value, [field.key]) === void 0 ? [{
845
+ key: field.key,
846
+ description: field.meta.description ?? field.meta.comment
847
+ }] : []);
848
+ }
849
+ function optionsFor(node, path, value, hints) {
850
+ const current = unwrapLazy(node);
851
+ if (current?.type === "union" && current.choices !== void 0) return current.choices.map((choice) => ({ value: choice }));
852
+ const source = declaredSource(current);
853
+ const spec = source === void 0 ? hints?.selectFor?.(path) : hints?.sourceFor?.(source);
854
+ if (spec === void 0) return void 0;
855
+ const parent = path.slice(0, -1);
856
+ const options = spec.options((relative) => readPath(value, [...parent, ...relative]));
857
+ return options.length === 0 ? void 0 : options;
858
+ }
859
+ var SchemaFormController = class {
860
+ #ns;
861
+ #deps;
862
+ #model;
863
+ #store;
864
+ #disposers = [];
865
+ #view;
866
+ #schema;
867
+ #root;
868
+ constructor(ns, deps) {
869
+ this.#ns = ns;
870
+ this.#deps = deps;
871
+ this.#model = new SchemaDraftModel({
872
+ scope: deps.form,
873
+ root: NO_FIELDS,
874
+ validate: (value) => this.#validate(deps, value)
875
+ });
876
+ this.#store = createSnapshotStore(this.#project());
877
+ this.#disposers.push(this.#model.subscribe(() => {
878
+ this.#store.set(this.#project());
879
+ }));
880
+ this.#disposers.push(deps.describe.subscribe(() => {
881
+ this.#sync();
882
+ }));
883
+ deps.describe.ensure();
884
+ this.#sync();
885
+ }
886
+ face() {
887
+ return {
888
+ hooks: { schemaForm: this.#store },
889
+ set: (path, value) => {
890
+ this.#model.set(path, value);
891
+ },
892
+ setText: (path, text, parse) => {
893
+ this.#model.setText(path, text, parse);
894
+ },
895
+ clear: (path) => {
896
+ this.#model.clear(path);
897
+ },
898
+ appendItem: (path) => {
899
+ this.#model.appendItem(path);
900
+ },
901
+ removeItem: (path, index) => {
902
+ this.#model.removeItem(path, index);
903
+ },
904
+ addKey: (path, key) => {
905
+ this.#model.addKey(path, key);
906
+ },
907
+ removeKey: (path, key) => {
908
+ this.#model.removeKey(path, key);
909
+ },
910
+ save: () => {
911
+ this.#model.save();
912
+ },
913
+ revert: (path) => {
914
+ this.#model.revert(path);
915
+ },
916
+ discard: () => {
917
+ this.#model.discard();
918
+ }
919
+ };
920
+ }
921
+ namespace() {
922
+ return this.#ns;
923
+ }
924
+ refresh() {
925
+ this.#store.set(this.#project());
926
+ }
927
+ dispose() {
928
+ for (const dispose of this.#disposers.splice(0)) dispose();
929
+ this.#model.dispose();
930
+ }
931
+ #sync() {
932
+ const view = this.#deps.describe.getSnapshot().view?.namespaces.find((row) => row.ns === this.#ns);
933
+ this.#view = view;
934
+ const projected = view === void 0 ? void 0 : projectRoot(view.schema, this.#deps.rehydrate);
935
+ this.#schema = projected?.schema;
936
+ this.#root = projected?.root;
937
+ this.#model.setRoot(projected?.root ?? NO_FIELDS);
938
+ this.#store.set(this.#project());
939
+ }
940
+ #validate(deps, value) {
941
+ if (this.#schema !== void 0) {
942
+ const failure = deps.validate(this.#schema, value);
943
+ if (failure !== void 0) return failure;
944
+ }
945
+ if (this.#root === void 0) return void 0;
946
+ const conflict = mergeKeyConflict(this.#root, value);
947
+ if (conflict === void 0) return void 0;
948
+ return {
949
+ message: conflict.kind === "duplicate" ? deps.t("duplicateItem", {
950
+ key: conflict.mergeKey,
951
+ value: conflict.value
952
+ }) : deps.t("missingItem", { key: conflict.mergeKey }),
953
+ path: conflict.path
954
+ };
955
+ }
956
+ #project() {
957
+ const fields = /* @__PURE__ */ new Map();
958
+ const root = this.#root;
959
+ const preview = this.#model.preview();
960
+ const walked = root === void 0 ? [] : walkFields(root, preview);
961
+ for (const item of walked) fields.set(fieldKey(item.path), this.#model.field(item.path, preview));
962
+ const secrets = /* @__PURE__ */ new Map();
963
+ for (const secret of this.#view?.secrets ?? []) secrets.set(fieldKey(secret.path), secret.set);
964
+ const texts = /* @__PURE__ */ new Map();
965
+ const options = /* @__PURE__ */ new Map();
966
+ const addable = /* @__PURE__ */ new Map();
967
+ for (const item of walked) {
968
+ const text = this.#deps.hints?.textFor(item.path);
969
+ if (text !== void 0) texts.set(fieldKey(item.path), text);
970
+ const candidates = optionsFor(item.node, item.path, preview, this.#deps.hints);
971
+ if (candidates !== void 0) options.set(fieldKey(item.path), candidates);
972
+ const addableHere = addableAt(item.node, item.path, readPath(preview, item.path), this.#deps.hints);
973
+ if (addableHere.length > 0) addable.set(fieldKey(item.path), addableHere);
974
+ }
975
+ const violation = this.#model.violation();
976
+ const invalidAt = /* @__PURE__ */ new Map();
977
+ if (violation !== void 0 && violation.path.length > 0) invalidAt.set(fieldKey(violation.path), violation.message);
978
+ return {
979
+ ...this.#model.shell(),
980
+ configured: root !== void 0,
981
+ root: root ?? NO_FIELDS,
982
+ walked,
983
+ fields,
984
+ secrets,
985
+ texts,
986
+ options,
987
+ addable,
988
+ violation,
989
+ invalidAt
990
+ };
991
+ }
992
+ };
993
+ //#endregion
994
+ //#region src/client/schema-form/hints.ts
995
+ var SchemaFormHints = class extends Service {
996
+ #readers = /* @__PURE__ */ new Map();
997
+ #texts = /* @__PURE__ */ new Map();
998
+ #selects = /* @__PURE__ */ new Map();
999
+ #sources = /* @__PURE__ */ new Map();
1000
+ #listeners = /* @__PURE__ */ new Set();
1001
+ constructor(ctx) {
1002
+ super(ctx, "schemaFormHints");
1003
+ }
1004
+ keysFor(ns, path) {
1005
+ return lookup(this.#readers, ns, path)?.() ?? [];
1006
+ }
1007
+ textFor(ns, path) {
1008
+ return lookup(this.#texts, ns, path)?.() ?? {};
1009
+ }
1010
+ select(ns, path, spec) {
1011
+ const key = locationKey(ns, path);
1012
+ this.#selects.set(key, spec);
1013
+ this.#publish();
1014
+ return () => {
1015
+ if (this.#selects.get(key) !== spec) return;
1016
+ this.#selects.delete(key);
1017
+ this.#publish();
1018
+ };
1019
+ }
1020
+ selectFor(ns, path) {
1021
+ return lookup(this.#selects, ns, path);
1022
+ }
1023
+ source(name, spec) {
1024
+ this.#sources.set(name, spec);
1025
+ this.#publish();
1026
+ return () => {
1027
+ if (this.#sources.get(name) !== spec) return;
1028
+ this.#sources.delete(name);
1029
+ this.#publish();
1030
+ };
1031
+ }
1032
+ sourceFor(name) {
1033
+ return this.#sources.get(name);
1034
+ }
1035
+ describe(ns, path, read) {
1036
+ const key = locationKey(ns, path);
1037
+ this.#texts.set(key, read);
1038
+ this.#publish();
1039
+ return () => {
1040
+ if (this.#texts.get(key) !== read) return;
1041
+ this.#texts.delete(key);
1042
+ this.#publish();
1043
+ };
1044
+ }
1045
+ suggestKeys(ns, path, read) {
1046
+ const key = locationKey(ns, path);
1047
+ this.#readers.set(key, read);
1048
+ this.#publish();
1049
+ return () => {
1050
+ if (this.#readers.get(key) !== read) return;
1051
+ this.#readers.delete(key);
1052
+ this.#publish();
1053
+ };
1054
+ }
1055
+ subscribe(listener) {
1056
+ this.#listeners.add(listener);
1057
+ return () => {
1058
+ this.#listeners.delete(listener);
1059
+ };
1060
+ }
1061
+ refresh() {
1062
+ this.#publish();
1063
+ }
1064
+ #publish() {
1065
+ for (const listener of this.#listeners) listener();
1066
+ }
1067
+ };
1068
+ function locationKey(ns, path) {
1069
+ return `${ns}\u0000${path.join("\0")}`;
1070
+ }
1071
+ function lookup(map, ns, path) {
1072
+ const exact = map.get(locationKey(ns, path));
1073
+ if (exact !== void 0) return exact;
1074
+ for (const masked of templates(path)) {
1075
+ const hit = map.get(locationKey(ns, masked));
1076
+ if (hit !== void 0) return hit;
1077
+ }
1078
+ }
1079
+ function* templates(path) {
1080
+ const wildcardable = Math.max(0, path.length - 1);
1081
+ for (let bits = (1 << wildcardable) - 1; bits > 0; bits--) yield path.map((segment, index) => index > 0 && (bits & 1 << index - 1) !== 0 ? "*" : segment);
1082
+ }
1083
+ //#endregion
1084
+ //#region src/client/schema-form/locales.ts
1085
+ const zh = {
1086
+ unavailable: "该插件当前未加载,暂时无法配置。",
1087
+ readOnly: "本部署的设置为只读。",
1088
+ save: "保存",
1089
+ confirmEdit: "确认",
1090
+ cancelEdit: "取消",
1091
+ saving: "保存中…",
1092
+ saveFailed: "本部署没有接受这些值,已保留供你修改。",
1093
+ notSaved: "没有保存:{message}",
1094
+ noSchema: "这一行没有可自动生成的配置项。",
1095
+ reset: "恢复默认",
1096
+ revert: "撤回",
1097
+ invalid: "这个值不被接受。",
1098
+ invalidNumber: "需要一个数字。",
1099
+ invalidInteger: "需要一个整数。",
1100
+ invalidJson: "需要一段合法的 JSON。",
1101
+ invalidBoolean: "需要 true 或 false。",
1102
+ invalidConst: "这个字段只接受固定值。",
1103
+ invalidPattern: "要匹配 {pattern}。",
1104
+ invalidRange: "要在 {min} 与 {max} 之间。",
1105
+ invalidMin: "不能小于 {min}。",
1106
+ invalidMax: "不能大于 {max}。",
1107
+ invalidChoice: "只能是 {choices} 之一。",
1108
+ unknownProperty: "这一层没有这个字段:从上面的候选里选,或换个键名。",
1109
+ empty: "(空)",
1110
+ toggleGroup: "展开 / 收起这一层",
1111
+ switchVariant: "切换这一层的形状或分支",
1112
+ copyValue: "复制值",
1113
+ copied: "已复制",
1114
+ addProperty: "添加属性",
1115
+ addItemPaste: "添加数组项(可粘贴 JSON 字符串)",
1116
+ addItem: "添加一项",
1117
+ removeItem: "移除",
1118
+ addKey: "添加键(可粘贴 JSON 字符串)",
1119
+ keyName: "键名",
1120
+ noKeys: "还没有键。",
1121
+ noItems: "还没有项。",
1122
+ deprecated: "已废弃",
1123
+ experimental: "试验中",
1124
+ secretSet: "已配置",
1125
+ secretUnset: "未配置",
1126
+ secretHint: "留空即保留已存的值。",
1127
+ constValue: "固定值",
1128
+ notEditable: "这一项由插件在运行时提供,不能在页面上编辑。",
1129
+ recursive: "递归结构:展开到这一层为止。",
1130
+ fixedLength: "固定长度",
1131
+ bitsetHint: "可多选。",
1132
+ unconfigured: "未配置",
1133
+ readOnlyField: "只读",
1134
+ noDescription: "(无说明)",
1135
+ required: "必填",
1136
+ duplicateItem: "重复的 {key}:{value}",
1137
+ missingItem: "每一项都需要一个 {key}"
1138
+ };
1139
+ const en = {
1140
+ unavailable: "This plugin is not loaded, so it cannot be configured right now.",
1141
+ readOnly: "This deployment stores settings read-only.",
1142
+ save: "Save",
1143
+ confirmEdit: "Confirm",
1144
+ cancelEdit: "Cancel",
1145
+ saving: "Saving…",
1146
+ saveFailed: "This deployment did not accept these values; they are kept for you to fix.",
1147
+ notSaved: "Not saved: {message}",
1148
+ noSchema: "This row has no configuration to generate.",
1149
+ reset: "Reset",
1150
+ revert: "Revert",
1151
+ invalid: "This value is not accepted.",
1152
+ invalidNumber: "Enter a number.",
1153
+ invalidInteger: "Enter a whole number.",
1154
+ invalidJson: "Enter valid JSON.",
1155
+ invalidBoolean: "Enter true or false.",
1156
+ invalidConst: "This field only accepts its fixed value.",
1157
+ invalidPattern: "Must match {pattern}.",
1158
+ invalidRange: "Must be between {min} and {max}.",
1159
+ invalidMin: "Must not be less than {min}.",
1160
+ invalidMax: "Must not be greater than {max}.",
1161
+ invalidChoice: "Must be one of {choices}.",
1162
+ unknownProperty: "No such field at this level: pick one of the candidates above.",
1163
+ empty: "(empty)",
1164
+ toggleGroup: "Expand or collapse this level",
1165
+ switchVariant: "Switch this level's shape or branch",
1166
+ copyValue: "Copy value",
1167
+ copied: "Copied",
1168
+ addProperty: "Add property",
1169
+ addItemPaste: "Add item (a JSON string can be pasted)",
1170
+ addItem: "Add item",
1171
+ removeItem: "Remove",
1172
+ addKey: "Add key (a JSON string can be pasted)",
1173
+ keyName: "Key",
1174
+ noKeys: "No keys yet.",
1175
+ noItems: "No items yet.",
1176
+ deprecated: "deprecated",
1177
+ experimental: "experimental",
1178
+ secretSet: "configured",
1179
+ secretUnset: "not set",
1180
+ secretHint: "Leave blank to keep the stored value.",
1181
+ constValue: "fixed",
1182
+ notEditable: "This entry is provided by the plugin at runtime and cannot be edited here.",
1183
+ recursive: "Recursive structure: expanded down to this level.",
1184
+ fixedLength: "fixed length",
1185
+ bitsetHint: "Multiple choices.",
1186
+ unconfigured: "not configured",
1187
+ readOnlyField: "read-only",
1188
+ noDescription: "(no description)",
1189
+ required: "required",
1190
+ duplicateItem: "Duplicate {key}: {value}",
1191
+ missingItem: "Every item needs a {key}"
1192
+ };
1193
+ //#endregion
1194
+ //#region src/client/schema-form/rows.ts
1195
+ function rowRegistrations(namespaces, bundles) {
1196
+ const owners = /* @__PURE__ */ new Map();
1197
+ for (const bundle of bundles) for (const row of bundle.rows) owners.set(row.rowId, bundle.name);
1198
+ const plans = [];
1199
+ for (const view of namespaces) {
1200
+ if (view.autoGenerate !== true) continue;
1201
+ const owner = owners.get(view.ns);
1202
+ if (owner === void 0) continue;
1203
+ plans.push({
1204
+ key: `${owner}#${view.ns}`,
1205
+ ns: view.ns
1206
+ });
1207
+ }
1208
+ return plans;
1209
+ }
1210
+ const FALLBACK_PRIORITY = 100;
1211
+ var RowRegistration = class {
1212
+ #deps;
1213
+ #live = /* @__PURE__ */ new Map();
1214
+ #pending;
1215
+ #disposed = false;
1216
+ constructor(deps) {
1217
+ this.#deps = deps;
1218
+ }
1219
+ sync() {
1220
+ if (this.#disposed) return Promise.resolve();
1221
+ this.#pending ??= this.#run().finally(() => {
1222
+ this.#pending = void 0;
1223
+ });
1224
+ return this.#pending;
1225
+ }
1226
+ dispose() {
1227
+ this.#disposed = true;
1228
+ this.#release();
1229
+ }
1230
+ async #run() {
1231
+ const bundles = await this.#deps.bundles();
1232
+ if (this.#disposed) return;
1233
+ const namespaces = this.#deps.describe.getSnapshot().view?.namespaces ?? [];
1234
+ const wanted = /* @__PURE__ */ new Map();
1235
+ for (const plan of rowRegistrations(namespaces, bundles)) {
1236
+ if (this.#deps.entryFor(plan.ns) === void 0) continue;
1237
+ wanted.set(plan.ns, plan);
1238
+ }
1239
+ for (const [ns, dispose] of this.#live) {
1240
+ if (wanted.has(ns)) continue;
1241
+ dispose();
1242
+ this.#live.delete(ns);
1243
+ this.#deps.release(ns);
1244
+ }
1245
+ for (const [ns, plan] of wanted) {
1246
+ if (this.#live.has(ns)) continue;
1247
+ const entry = this.#deps.entryFor(ns);
1248
+ if (entry === void 0) continue;
1249
+ const dispose = this.#deps.slots.register({
1250
+ name: "plugins.row.config",
1251
+ key: plan.key,
1252
+ priority: FALLBACK_PRIORITY,
1253
+ locale: this.#deps.locale
1254
+ }, entry.component);
1255
+ this.#live.set(ns, dispose);
1256
+ }
1257
+ }
1258
+ #release() {
1259
+ for (const [ns, dispose] of this.#live) {
1260
+ dispose();
1261
+ this.#live.delete(ns);
1262
+ this.#deps.release(ns);
1263
+ }
1264
+ }
1265
+ };
1266
+ //#endregion
1267
+ //#region src/client/schema-form/labels.ts
1268
+ function fieldHint(node, resolveText) {
1269
+ const parts = [];
1270
+ if (node.meta.description !== void 0) parts.push(resolveText(node.meta.description));
1271
+ if (node.meta.comment !== void 0) parts.push(node.meta.comment);
1272
+ return parts.length === 0 ? void 0 : parts.join(" ");
1273
+ }
1274
+ //#endregion
1275
+ //#region src/client/schema-form/lines.ts
1276
+ function containerShape(node, value) {
1277
+ switch (variantOf(node, value).type) {
1278
+ case "object":
1279
+ case "dict":
1280
+ case "intersect": return "object";
1281
+ case "array":
1282
+ case "tuple": return "array";
1283
+ default: return;
1284
+ }
1285
+ }
1286
+ function visibleFields(state, fold) {
1287
+ const containers = new Set(state.walked.filter((item) => containerShape(item.node, valueAt(state, item.path)) !== void 0).map((item) => fieldKey(item.path)));
1288
+ return state.walked.filter((item) => {
1289
+ for (let depth = 1; depth < item.path.length; depth++) {
1290
+ const ancestor = item.path.slice(0, depth);
1291
+ if (containers.has(fieldKey(ancestor)) && fold.collapsed(ancestor)) return false;
1292
+ }
1293
+ return true;
1294
+ });
1295
+ }
1296
+ function valueAt(state, path) {
1297
+ return state.fields.get(fieldKey(path))?.value;
1298
+ }
1299
+ function addOf(node, shape, options) {
1300
+ if (shape === "array") return { kind: "item" };
1301
+ if (unwrapLazy(node)?.type === "dict") return {
1302
+ kind: "key",
1303
+ options
1304
+ };
1305
+ return options.length === 0 ? void 0 : {
1306
+ kind: "prop",
1307
+ options
1308
+ };
1309
+ }
1310
+ function variantsOf(node, value) {
1311
+ const union = unionOf(node);
1312
+ if (union === void 0 || union.choices !== void 0 || union.variants.length < 2) return void 0;
1313
+ return {
1314
+ choices: variantChoices(union),
1315
+ selected: union.variants.indexOf(variantOf(union, value))
1316
+ };
1317
+ }
1318
+ function editorLines(state, fold, resolveText, t) {
1319
+ const lines = [];
1320
+ const open = [];
1321
+ const closeOpenUntil = (path) => {
1322
+ while (open.length > 0) {
1323
+ const top = open[open.length - 1];
1324
+ if (isPrefix(top.path, path)) return;
1325
+ open.pop();
1326
+ lines.push({
1327
+ kind: "close",
1328
+ path: top.path,
1329
+ node: top.node,
1330
+ shape: top.shape,
1331
+ depth: top.depth,
1332
+ add: top.add,
1333
+ member: top.member
1334
+ });
1335
+ }
1336
+ };
1337
+ for (const item of visibleFields(state, fold)) {
1338
+ closeOpenUntil(item.path);
1339
+ const node = unwrapLazy(item.node) ?? item.node;
1340
+ const value = valueAt(state, item.path);
1341
+ const depth = item.path.length;
1342
+ const comment = commentFor(state, item, resolveText, t);
1343
+ if (comment !== void 0) lines.push({
1344
+ kind: "comment",
1345
+ path: item.path,
1346
+ depth,
1347
+ text: comment.text,
1348
+ invalid: comment.invalid
1349
+ });
1350
+ const variants = variantsOf(node, value);
1351
+ const shape = containerShape(node, value);
1352
+ if (shape !== void 0) {
1353
+ const collapsed = fold.collapsed(item.path);
1354
+ const add = addOf(node, shape, state.addable.get(fieldKey(item.path)) ?? []);
1355
+ lines.push({
1356
+ kind: "open",
1357
+ path: item.path,
1358
+ node,
1359
+ shape,
1360
+ depth,
1361
+ collapsed,
1362
+ member: item.member,
1363
+ variants
1364
+ });
1365
+ if (!collapsed) open.push({
1366
+ path: item.path,
1367
+ node,
1368
+ shape,
1369
+ depth,
1370
+ add,
1371
+ member: item.member
1372
+ });
1373
+ continue;
1374
+ }
1375
+ lines.push({
1376
+ kind: "field",
1377
+ path: item.path,
1378
+ node,
1379
+ depth,
1380
+ field: state.fields.get(fieldKey(item.path)) ?? {
1381
+ value: void 0,
1382
+ text: void 0,
1383
+ invalid: void 0,
1384
+ overridden: false,
1385
+ staged: false
1386
+ },
1387
+ member: item.member,
1388
+ variants,
1389
+ variantsStandIn: false
1390
+ });
1391
+ }
1392
+ while (open.length > 0) {
1393
+ const top = open.pop();
1394
+ lines.push({
1395
+ kind: "close",
1396
+ path: top.path,
1397
+ node: top.node,
1398
+ shape: top.shape,
1399
+ depth: top.depth,
1400
+ add: top.add,
1401
+ member: top.member
1402
+ });
1403
+ }
1404
+ return moveVariantControlToTag(lines);
1405
+ }
1406
+ function moveVariantControlToTag(lines) {
1407
+ for (const line of lines) {
1408
+ if (line.kind === "comment" || line.kind === "close") continue;
1409
+ if (line.variants === void 0) continue;
1410
+ const tagKey = unionOf(line.node)?.tagKey;
1411
+ if (tagKey === void 0) continue;
1412
+ const tagPath = [...line.path, tagKey];
1413
+ const tagLine = lines.find((candidate) => candidate.kind === "field" && candidate.path.length === tagPath.length && candidate.path.every((segment, index) => segment === tagPath[index]));
1414
+ if (tagLine === void 0 || tagLine.kind !== "field") continue;
1415
+ tagLine.variants = line.variants;
1416
+ tagLine.variantsStandIn = true;
1417
+ line.variants = void 0;
1418
+ }
1419
+ return lines;
1420
+ }
1421
+ function commentFor(state, item, resolveText, t) {
1422
+ const key = fieldKey(item.path);
1423
+ const failure = state.fields.get(key)?.invalid ?? state.invalidAt.get(key);
1424
+ if (failure !== void 0) return {
1425
+ text: failure,
1426
+ invalid: true
1427
+ };
1428
+ const node = unwrapLazy(item.node) ?? item.node;
1429
+ const parts = [];
1430
+ const text = state.texts.get(fieldKey(item.path));
1431
+ const hint = [text?.label, text?.hint].filter((part) => part !== void 0 && part !== "").join(":") || fieldHint(node, resolveText);
1432
+ if (hint !== void 0 && hint !== "") parts.push(hint);
1433
+ if (node.meta.disabled) parts.push(t("readOnlyField"));
1434
+ if (node.meta.badges.length > 0) parts.push(node.meta.badges.join(" / "));
1435
+ return parts.length === 0 ? void 0 : {
1436
+ text: parts.join(" · "),
1437
+ invalid: false
1438
+ };
1439
+ }
1440
+ function isPrefix(prefix, path) {
1441
+ if (prefix.length > path.length) return false;
1442
+ return prefix.every((segment, index) => path[index] === segment);
1443
+ }
1444
+ //#endregion
1445
+ //#region src/client/styling/toolkit.ts
1446
+ function isUndefined(value) {
1447
+ return value === void 0;
1448
+ }
1449
+ function isNull(value) {
1450
+ return value === null;
1451
+ }
1452
+ function isString(value) {
1453
+ return typeof value === "string";
1454
+ }
1455
+ function isFunction(value) {
1456
+ return typeof value === "function";
1457
+ }
1458
+ function isPlainObject(value) {
1459
+ return typeof value === "object" && value !== null && !Array.isArray(value);
1460
+ }
1461
+ function toMerged(target, source) {
1462
+ if (!isPlainObject(target) || !isPlainObject(source)) return source;
1463
+ const result = { ...target };
1464
+ for (const [key, value] of Object.entries(source)) result[key] = key in result ? toMerged(result[key], value) : value;
1465
+ return result;
1466
+ }
1467
+ function mapKeys(source, map) {
1468
+ const result = {};
1469
+ for (const [key, value] of Object.entries(source)) result[map(key, value)] = value;
1470
+ return result;
1471
+ }
1472
+ //#endregion
1473
+ //#region src/client/styling/token.ts
1474
+ const cssVarSymbol = Symbol("cssVar");
1475
+ const tokensSymbol = Symbol("tokens");
1476
+ const tokenInstSymbol = Symbol("tokenInst");
1477
+ const SELF = "$";
1478
+ function tokenVars(token, tokens, path) {
1479
+ const reserved = /* @__PURE__ */ new Set([
1480
+ "constructor",
1481
+ "toJSON",
1482
+ "__proto__"
1483
+ ]);
1484
+ return new Proxy(() => {}, {
1485
+ apply() {
1486
+ return Token.fallbackVar(token.cssVar(path));
1487
+ },
1488
+ get(_target, property) {
1489
+ if (property === Symbol.toPrimitive || property === Symbol.toStringTag || property === "toString") return () => `var(${token.cssVar(path)})`;
1490
+ if (property === "valueOf") return () => Token.fallbackVar(token.cssVar(path));
1491
+ if (property === tokenInstSymbol) return token;
1492
+ if (property === tokensSymbol) return tokens;
1493
+ if (property === cssVarSymbol) return token.cssVar(path);
1494
+ if (!isString(property) || reserved.has(property)) return void 0;
1495
+ const next = tokens[property];
1496
+ if (isUndefined(next)) return void 0;
1497
+ return tokenVars(token, next, [...path, property]);
1498
+ }
1499
+ });
1500
+ }
1501
+ var Token = class Token {
1502
+ prefix;
1503
+ static vars(tokens, options = {}) {
1504
+ return tokenVars(new Token(options.prefix ?? ""), tokens, []);
1505
+ }
1506
+ static extendsVars(vars, extra) {
1507
+ const tokens = vars[tokensSymbol] ?? {};
1508
+ return Token.vars(toMerged(tokens, extra));
1509
+ }
1510
+ static assignVars(vars, overwrites) {
1511
+ const tokens = overwrites ?? vars[tokensSymbol] ?? {};
1512
+ const token = vars[tokenInstSymbol] ?? new Token("");
1513
+ const result = {};
1514
+ for (const [name, value] of flattenTokens(token, tokens, [])) result[name] = token.normalize(value);
1515
+ return result;
1516
+ }
1517
+ static variants(variants) {
1518
+ return mapKeys(variants, (key) => `&[data-variant="${key}"]`);
1519
+ }
1520
+ static val(strings, ...values) {
1521
+ return function* () {
1522
+ for (let index = 0; index < strings.length; index += 1) {
1523
+ const literal = strings[index];
1524
+ if (literal) yield literal;
1525
+ if (index >= values.length) continue;
1526
+ const value = values[index];
1527
+ yield* isFunction(value) ? value() : [value];
1528
+ }
1529
+ };
1530
+ }
1531
+ static calc(strings, ...values) {
1532
+ return combinator("calc(", ")", strings, values);
1533
+ }
1534
+ static min(strings, ...values) {
1535
+ return combinator("min(", ")", strings, values);
1536
+ }
1537
+ static max(strings, ...values) {
1538
+ return combinator("max(", ")", strings, values);
1539
+ }
1540
+ static url(strings, ...values) {
1541
+ return combinator("url(", ")", strings, values);
1542
+ }
1543
+ static colorMix(strings, ...values) {
1544
+ return combinator("color-mix(", ")", strings, values);
1545
+ }
1546
+ static colorScale(color, options = {}) {
1547
+ const channel = (name, amount, max) => Token.calc`${name} + (${String(max)} - ${name}) * max(${amount}, 0) + ${name} * min(${amount}, 0)`;
1548
+ const mix = (from, to, amount) => Token.colorMix`in srgb, ${from}, ${to} ${Token.calc`${amount} * 100%`}`;
1549
+ let result = color;
1550
+ if (!isUndefined(options.alpha) || !isUndefined(options.lightness) || !isUndefined(options.saturation)) result = Token.val`hsl(from ${result} h ${isUndefined(options.saturation) ? "s" : channel("s", options.saturation, 100)} ${isUndefined(options.lightness) ? "l" : channel("l", options.lightness, 100)} / ${isUndefined(options.alpha) ? "alpha" : channel("alpha", options.alpha, 1)})`;
1551
+ if (!isUndefined(options.whiteness)) result = mix(result, "white", options.whiteness);
1552
+ if (!isUndefined(options.blackness)) result = mix(result, "black", options.blackness);
1553
+ return result;
1554
+ }
1555
+ static fallbackVar(value, ...fallbacks) {
1556
+ return Object.assign(function* () {
1557
+ yield "var(";
1558
+ for (const [index, item] of [value, ...fallbacks].entries()) {
1559
+ if (index > 0) yield ", ";
1560
+ yield* asIterable(item);
1561
+ }
1562
+ yield ")";
1563
+ }, { [cssVarSymbol]: value });
1564
+ }
1565
+ static collect(value) {
1566
+ const iterable = isFunction(value) ? value() : value;
1567
+ let result = "";
1568
+ for (const item of iterable) result += `${item}`;
1569
+ return result;
1570
+ }
1571
+ constructor(prefix = "") {
1572
+ this.prefix = prefix;
1573
+ }
1574
+ prop = (key) => key.startsWith("--") ? key : kebabCase(key);
1575
+ normalize = (input) => {
1576
+ const value = isFunction(input) ? input() : input;
1577
+ if (typeof value === "number") return `${value}`;
1578
+ if (typeof value === "string") return value;
1579
+ if (isUndefined(value) || isNull(value)) return "";
1580
+ if (isFunction(value)) return Token.collect(value);
1581
+ if (isPlainObject(value) && Symbol.iterator in value) return Token.collect(value);
1582
+ return "";
1583
+ };
1584
+ cssVar = (paths) => `--${[this.prefix, ...paths].filter(Boolean).join("-")}`;
1585
+ };
1586
+ function combinator(open, close, strings, values) {
1587
+ return function* () {
1588
+ yield open;
1589
+ yield* Token.val(strings, ...values)();
1590
+ yield close;
1591
+ };
1592
+ }
1593
+ function* asIterable(value) {
1594
+ const resolved = isFunction(value) ? value() : value;
1595
+ const variable = resolved?.[cssVarSymbol];
1596
+ if (!isUndefined(variable)) {
1597
+ yield variable;
1598
+ return;
1599
+ }
1600
+ if (typeof resolved === "object" && resolved !== null && Symbol.iterator in resolved) {
1601
+ yield* resolved;
1602
+ return;
1603
+ }
1604
+ yield resolved;
1605
+ }
1606
+ function* flattenTokens(token, value, parents) {
1607
+ for (const [property, child] of Object.entries(value)) {
1608
+ if (property === SELF) continue;
1609
+ if (isPlainObject(child)) {
1610
+ yield* flattenTokens(token, child, [...parents, property]);
1611
+ continue;
1612
+ }
1613
+ yield [token.cssVar([...parents, property]), child];
1614
+ }
1615
+ }
1616
+ function kebabCase(value) {
1617
+ return value.replace(/([A-Z])/g, "-$1").toLowerCase();
1618
+ }
1619
+ //#endregion
1620
+ //#region src/client/styling/styling.ts
1621
+ var Styling = class Styling {
1622
+ static create() {
1623
+ return new Styling();
1624
+ }
1625
+ static toRule(sheet) {
1626
+ return sheet.selector === void 0 ? sheet.contents.join("") : `${sheet.selector} {${sheet.contents.join("")} }`;
1627
+ }
1628
+ #token = new Token();
1629
+ #sheets = /* @__PURE__ */ new Map();
1630
+ #injected = /* @__PURE__ */ new Set();
1631
+ props = (...styles) => {
1632
+ const merged = mergeStyles(styles);
1633
+ if (Object.keys(merged).length === 0) return {};
1634
+ const sheet = this.#sheet(2, this.#rules(merged));
1635
+ return sheet === void 0 ? {} : { [`data-css-${sheet.id}`]: "" };
1636
+ };
1637
+ keyframes = (frames = {}) => {
1638
+ return this.#sheet(1, this.#rules(frames))?.id ?? "anim-none";
1639
+ };
1640
+ injectGlobals = (styles = {}) => {
1641
+ for (const [name, style] of Object.entries(styles)) this.#sheet(0, this.#rules(style), name);
1642
+ };
1643
+ className = (...styles) => {
1644
+ const merged = mergeStyles(styles);
1645
+ if (Object.keys(merged).length === 0) return "";
1646
+ const sheet = this.#sheet(3, this.#rules(merged));
1647
+ return sheet === void 0 ? "" : `cls-${sheet.id}`;
1648
+ };
1649
+ sheets = () => [...this.#sheets.values()].map((sheet) => Styling.toRule(sheet));
1650
+ #sheet(type, rules, selector) {
1651
+ let hash = 0;
1652
+ const contents = [];
1653
+ for (const rule of rules) {
1654
+ contents.push(rule);
1655
+ hash = incrementalHash(rule, hash);
1656
+ }
1657
+ if (selector !== void 0) hash = incrementalHash(selector, hash);
1658
+ if (hash === 0) return void 0;
1659
+ let id = selector ?? "";
1660
+ if (type === 2) id = `s${hash.toString(36)}`;
1661
+ if (type === 3) id = `c${hash.toString(36)}`;
1662
+ if (type === 0) id = `g${hash.toString(36)}`;
1663
+ if (type === 1) id = `a${hash.toString(36)}`;
1664
+ let resolvedSelector = selector;
1665
+ if (resolvedSelector === void 0) {
1666
+ if (type === 1) resolvedSelector = `@keyframes ${id}`;
1667
+ if (type === 2) resolvedSelector = `[data-css-${id}]`;
1668
+ if (type === 3) resolvedSelector = `.cls-${id}`;
1669
+ }
1670
+ const sheet = {
1671
+ id,
1672
+ contents,
1673
+ selector: resolvedSelector
1674
+ };
1675
+ const existing = this.#sheets.get(id);
1676
+ if (existing !== void 0 && existing.contents.join("") === contents.join("")) return existing;
1677
+ this.#sheets.set(id, sheet);
1678
+ this.#inject(sheet);
1679
+ return sheet;
1680
+ }
1681
+ #inject(sheet) {
1682
+ if (this.#injected.has(sheet.id)) return;
1683
+ this.#injected.add(sheet.id);
1684
+ if (typeof document === "undefined") return;
1685
+ const element = document.createElement("style");
1686
+ element.setAttribute("data-css", sheet.id);
1687
+ element.textContent = Styling.toRule(sheet);
1688
+ document.head.appendChild(element);
1689
+ }
1690
+ *#rules(styles) {
1691
+ const nested = /* @__PURE__ */ new Map();
1692
+ for (const [key, value] of Object.entries(styles)) {
1693
+ if (isNull(value) || isUndefined(value)) continue;
1694
+ if (isPlainObject(value)) {
1695
+ nested.set(key, value);
1696
+ continue;
1697
+ }
1698
+ yield ` ${this.#token.prop(key)}: ${this.#token.normalize(value)};`;
1699
+ }
1700
+ for (const [key, value] of nested.entries()) {
1701
+ yield ` ${key} {`;
1702
+ yield* this.#rules(value);
1703
+ yield " }";
1704
+ }
1705
+ }
1706
+ };
1707
+ function mergeStyles(styles) {
1708
+ return styles.reduce((accumulated, style) => style ? toMerged(accumulated, style) : accumulated, {});
1709
+ }
1710
+ function incrementalHash(value, previous = 0) {
1711
+ let hash = previous;
1712
+ for (let index = 0; index < value.length; index += 1) {
1713
+ hash = (hash << 5) - hash + value.charCodeAt(index);
1714
+ hash &= 2147483647;
1715
+ }
1716
+ return hash;
1717
+ }
1718
+ const STYLING_SINGLETON = Symbol.for("@morlay/dsh-client-ui-primitives/styling");
1719
+ const globalScope = globalThis;
1720
+ const styling = globalScope[STYLING_SINGLETON] ??= Styling.create();
1721
+ //#endregion
1722
+ //#region src/client/styling/styled.tsx
1723
+ const sxSymbol = Symbol("styled.sx");
1724
+ function styled(Component, defaultProps = {}) {
1725
+ return (...styles) => {
1726
+ const sx = styles.reduce((merged, style) => toMerged(merged, style), {});
1727
+ const Styled = forwardRef((props, ref) => {
1728
+ const styleProps = useMemo(() => styling.props(sx), []);
1729
+ return createElement(Component, {
1730
+ ...defaultProps,
1731
+ ...props,
1732
+ ...styleProps,
1733
+ ref
1734
+ });
1735
+ });
1736
+ Styled.displayName = `styled(${typeof Component === "string" ? Component : Component.displayName ?? Component.name ?? "Component"})`;
1737
+ return Object.assign(Styled, { [sxSymbol]: sx });
1738
+ };
1739
+ }
1740
+ function styleOf(component) {
1741
+ return component[sxSymbol];
1742
+ }
1743
+ //#endregion
1744
+ //#region src/client/theme.generated.ts
1745
+ const designTokens = {
1746
+ alias: {
1747
+ bg: {
1748
+ base: "var(--dsw-static-neutral-bluish-00)",
1749
+ document: {
1750
+ preview: "var(--dsw-static-neutral-bluish-100)",
1751
+ selection: "color-mix(in srgb, var(--dsw-static-blue-500) 40%, transparent)"
1752
+ },
1753
+ layer: {
1754
+ "1": "var(--dsw-static-neutral-bluish-00)",
1755
+ "2": "var(--dsw-static-neutral-bluish-00)",
1756
+ "3": "var(--dsw-static-neutral-bluish-00)"
1757
+ },
1758
+ mask: {
1759
+ "1": "rgba(0, 0, 0, 0.24)",
1760
+ "2": "rgba(0, 0, 0, 0.12)",
1761
+ "3": "rgba(0, 0, 0, 0.48)",
1762
+ drop: "rgba(255, 255, 255, 0.7)",
1763
+ photo: "rgba(0, 0, 0, 0.88)"
1764
+ },
1765
+ module: { platform: "var(--dsw-static-neutral-bluish-60)" },
1766
+ multi: { select: "var(--dsw-static-neutral-bluish-60)" },
1767
+ overlay: "var(--dsw-static-neutral-bluish-150)",
1768
+ skeleton: "rgba(0, 0, 0, 0.04)"
1769
+ },
1770
+ border: {
1771
+ inverted: "rgba(0, 0, 0, 0)",
1772
+ inverted2: "rgba(0, 0, 0, 0)",
1773
+ l1: "rgba(0, 0, 0, 0.04)",
1774
+ l2: {
1775
+ $: "rgba(0, 0, 0, 0.1)",
1776
+ darkmode: { thin: "rgba(0, 0, 0, 0.1)" }
1777
+ },
1778
+ l3: "rgba(0, 0, 0, 0.12)",
1779
+ l4: "rgba(0, 0, 0, 0.16)"
1780
+ },
1781
+ brand: {
1782
+ primary: {
1783
+ $: "var(--dsw-static-neutral-bluish-1000)",
1784
+ invert: "var(--dsw-static-neutral-bluish-1000)",
1785
+ new: { colorprimary: { new: { color: "rgb(65, 118, 230)" } } }
1786
+ },
1787
+ text: "var(--dsw-static-neutral-bluish-1000)"
1788
+ },
1789
+ button: {
1790
+ contrast: { fill: "var(--dsw-static-neutral-bluish-700)" },
1791
+ elevated: { fill: "var(--dsw-static-neutral-bluish-00)" },
1792
+ floating: {
1793
+ fill: "var(--dsw-static-neutral-bluish-00)",
1794
+ hover: "var(--dsw-static-neutral-bluish-75)"
1795
+ },
1796
+ ghost: { active: {
1797
+ border: "var(--dsw-static-neutral-bluish-500)",
1798
+ fill: "var(--dsw-static-neutral-bluish-100)",
1799
+ hover: "var(--dsw-static-neutral-bluish-150)"
1800
+ } },
1801
+ info: {
1802
+ fill: "var(--dsw-static-deepseek-500)",
1803
+ hover: "var(--dsw-static-deepseek-400)"
1804
+ },
1805
+ primary: {
1806
+ dimmed: "var(--dsw-static-neutral-bluish-100)",
1807
+ fill: "var(--dsw-alias-brand-primary)",
1808
+ hover: "var(--dsw-static-neutral-bluish-750)"
1809
+ },
1810
+ tool: { bar: {
1811
+ fill: {
1812
+ $: "rgba(84, 85, 87, 0.5)",
1813
+ invisible: "rgba(31, 31, 31, 0.36)"
1814
+ },
1815
+ hover: "rgba(84, 85, 87, 0.6)"
1816
+ } }
1817
+ },
1818
+ code: { diff: {
1819
+ added: "var(--dsw-static-green-500-a08)",
1820
+ deleted: "var(--dsw-static-red-600-a08)"
1821
+ } },
1822
+ file: { diff: {
1823
+ added: {
1824
+ bg: "rgb(230, 244, 231)",
1825
+ gutter: "rgb(237, 247, 237)",
1826
+ marker: "rgb(1, 162, 65)"
1827
+ },
1828
+ deleted: {
1829
+ bg: "rgb(252, 230, 226)",
1830
+ gutter: "rgb(253, 236, 233)",
1831
+ marker: "rgb(186, 39, 35)"
1832
+ }
1833
+ } },
1834
+ interactive: { bg: {
1835
+ active: "rgba(38, 49, 72, 0.1)",
1836
+ hover: {
1837
+ $: "rgba(38, 49, 72, 0.06)",
1838
+ accent: "rgba(38, 49, 72, 0.14)",
1839
+ danger: "rgba(236, 19, 19, 0.05)",
1840
+ solid: "var(--dsw-static-neutral-bluish-75)"
1841
+ }
1842
+ } },
1843
+ label: {
1844
+ caption: "var(--dsw-static-neutral-bluish-400)",
1845
+ deep: { diving: {
1846
+ $: "color-mix(in srgb, var(--dsw-static-deepseek-500) 70%, var(--dsw-static-blue-950))",
1847
+ shimmer: "color-mix(in srgb, var(--dsw-static-deepseek-500) 30%, var(--dsw-static-blue-950))"
1848
+ } },
1849
+ dimmed: "var(--dsw-static-neutral-bluish-200)",
1850
+ document: { preview: "var(--dsw-static-neutral-bluish-700)" },
1851
+ primary: {
1852
+ $: "var(--dsw-static-neutral-bluish-1000)",
1853
+ bluish: "var(--dsw-static-blue-900)",
1854
+ dimmed: "var(--dsw-static-neutral-bluish-950)",
1855
+ foreground: "var(--dsw-static-neutral-bluish-00)",
1856
+ inverted: "var(--dsw-static-neutral-bluish-00)"
1857
+ },
1858
+ secondary: "var(--dsw-static-neutral-bluish-700)",
1859
+ shimmer: "color-mix(in srgb, var(--dsw-static-neutral-1000) 30%, transparent)",
1860
+ tertiary: "var(--dsw-static-neutral-bluish-600)"
1861
+ },
1862
+ link: "var(--dsw-static-deepseek-500)",
1863
+ markdown: {
1864
+ citation: "var(--dsw-static-neutral-bluish-100)",
1865
+ code: {
1866
+ block: {
1867
+ $: "var(--dsw-static-neutral-bluish-50)",
1868
+ banner: "var(--dsw-static-neutral-bluish-50)"
1869
+ },
1870
+ segment: {
1871
+ selected: "var(--dsw-static-neutral-bluish-00)",
1872
+ unselected: "var(--dsw-static-neutral-bluish-75)"
1873
+ }
1874
+ },
1875
+ inline: { code: "var(--dsw-static-neutral-50)" },
1876
+ placeholder: "var(--dsw-static-neutral-bluish-60)",
1877
+ tag: "var(--dsw-static-neutral-bluish-75)"
1878
+ },
1879
+ menu: {
1880
+ group: { header: { fill: "rgba(248, 249, 250, 0.94)" } },
1881
+ icon: "var(--dsw-static-neutral-bluish-800)"
1882
+ },
1883
+ onboarding: {
1884
+ accent: "rgb(57, 100, 254)",
1885
+ card: { fill: "color-mix(in srgb, var(--dsw-static-neutral-bluish-00) 80%, transparent)" },
1886
+ checkbox: { border: "color-mix(in srgb, var(--dsw-static-neutral-bluish-1000) 20%, transparent)" },
1887
+ secondary: { fill: "var(--dsw-static-neutral-bluish-00)" }
1888
+ },
1889
+ scrollbar: {
1890
+ bg: {
1891
+ l1: "var(--dsw-static-neutral-200)",
1892
+ l2: "var(--dsw-static-neutral-200)"
1893
+ },
1894
+ hover: {
1895
+ l1: "var(--dsw-static-neutral-300)",
1896
+ l2: "var(--dsw-static-neutral-300)"
1897
+ }
1898
+ },
1899
+ settings: { card: {
1900
+ fill: "var(--dsw-alias-bg-layer-2)",
1901
+ stroke: "var(--dsw-alias-border-l4)"
1902
+ } },
1903
+ state: {
1904
+ business: {
1905
+ primary: "var(--dsw-static-deepseek-500)",
1906
+ tertiary: "var(--dsw-static-deepseek-100)"
1907
+ },
1908
+ error: {
1909
+ primary: "var(--dsw-static-red-600)",
1910
+ secondary: "var(--dsw-static-red-400)"
1911
+ },
1912
+ idle: { primary: "var(--dsw-static-neutral-300)" },
1913
+ success: {
1914
+ primary: "var(--dsw-static-green-500)",
1915
+ secondary: "var(--dsw-static-green-400)",
1916
+ tertiary: "var(--dsw-static-green-100)"
1917
+ },
1918
+ warn: {
1919
+ label: "var(--dsw-static-amber-600)",
1920
+ primary: "var(--dsw-static-amber-500)",
1921
+ secondary: "var(--dsw-static-amber-400)",
1922
+ tertiary: "var(--dsw-static-amber-100)"
1923
+ }
1924
+ },
1925
+ switch: { thumb: "var(--dsw-static-neutral-bluish-00)" },
1926
+ toast: {
1927
+ bg: "var(--dsw-static-neutral-bluish-800)",
1928
+ label: "var(--dsw-static-neutral-bluish-00)"
1929
+ },
1930
+ tooltip: {
1931
+ bg: "var(--dsw-static-neutral-bluish-850)",
1932
+ key: { bg: "color-mix(in srgb, var(--dsw-alias-tooltip-bg), white 18%)" }
1933
+ },
1934
+ turn: { trigger: { bg: {
1935
+ $: "var(--dsw-alias-markdown-code-block)",
1936
+ hover: "var(--dsw-alias-interactive-bg-hover)"
1937
+ } } }
1938
+ },
1939
+ corner: { shape: "superellipse(1.5)" },
1940
+ elevation: {
1941
+ panel: "var(--dsw-elevation-stroke), 0 3px 8px 0 rgba(0, 0, 0, 0.03), 0 0 16px 0 rgba(0, 0, 0, 0.02)",
1942
+ prominent: "var(--dsw-elevation-stroke), 0 3px 8px 0 rgba(0, 0, 0, 0.04), 0 0 20px 0 rgba(0, 0, 0, 0.05)",
1943
+ soft: "var(--dsw-elevation-stroke), 0 4px 16px 0 rgba(0, 0, 0, 0.03), 0 0 24px 0 rgba(0, 0, 0, 0.03)",
1944
+ stroke: {
1945
+ $: "0 0 0 0.5px var(--dsw-elevation-stroke-color)",
1946
+ color: "var(--dsw-alias-border-l4)"
1947
+ }
1948
+ },
1949
+ focus: { ring: {
1950
+ color: "transparent",
1951
+ width: "2px"
1952
+ } },
1953
+ font: {
1954
+ base: {
1955
+ "16": {
1956
+ $: "16px/24px var(--dsw-font-family)",
1957
+ font: {
1958
+ family: "var(--dsw-font-family)",
1959
+ size: "16px",
1960
+ style: "normal",
1961
+ weight: "400"
1962
+ },
1963
+ line: { height: "24px" }
1964
+ },
1965
+ strong: { "16": {
1966
+ $: "500 16px/24px var(--dsw-font-family)",
1967
+ font: {
1968
+ family: "var(--dsw-font-family)",
1969
+ size: "16px",
1970
+ style: "normal",
1971
+ weight: "500"
1972
+ },
1973
+ line: { height: "24px" }
1974
+ } }
1975
+ },
1976
+ family: {
1977
+ $: "-apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC',\n 'Hiragino Sans GB', 'Microsoft YaHei', 'Helvetica Neue', Helvetica, Arial, sans-serif",
1978
+ brand: "'Montserrat', var(--dsw-font-family)"
1979
+ },
1980
+ l: { "20": {
1981
+ $: "500 20px/28px var(--dsw-font-family)",
1982
+ font: {
1983
+ family: "var(--dsw-font-family)",
1984
+ size: "20px",
1985
+ style: "normal",
1986
+ weight: "500"
1987
+ },
1988
+ line: { height: "28px" }
1989
+ } },
1990
+ m: { "18": {
1991
+ $: "500 16px/28px var(--dsw-font-family)",
1992
+ font: {
1993
+ family: "var(--dsw-font-family)",
1994
+ size: "16px",
1995
+ style: "normal",
1996
+ weight: "500"
1997
+ },
1998
+ line: { height: "28px" }
1999
+ } },
2000
+ markdown: {
2001
+ base: {
2002
+ $: "var(--dsh-content-font-size, 14px) / calc(24px + var(--dsh-content-font-delta)) var(--dsw-font-family)",
2003
+ font: {
2004
+ family: "var(--dsw-font-family)",
2005
+ size: "var(--dsh-content-font-size, 14px)",
2006
+ style: "normal",
2007
+ weight: "400"
2008
+ },
2009
+ italic: {
2010
+ $: "italic var(--dsh-content-font-size, 14px) / calc(24px + var(--dsh-content-font-delta)) var(--dsw-font-family)",
2011
+ font: {
2012
+ family: "var(--dsw-font-family)",
2013
+ size: "var(--dsh-content-font-size, 14px)",
2014
+ style: "italic",
2015
+ weight: "400"
2016
+ },
2017
+ line: { height: "calc(24px + var(--dsh-content-font-delta))" }
2018
+ },
2019
+ line: { height: "calc(24px + var(--dsh-content-font-delta))" },
2020
+ strong: {
2021
+ $: "600 var(--dsh-content-font-size, 14px) / calc(24px + var(--dsh-content-font-delta)) var(--dsw-font-family)",
2022
+ font: {
2023
+ family: "var(--dsw-font-family)",
2024
+ size: "var(--dsh-content-font-size, 14px)",
2025
+ style: "normal",
2026
+ weight: "600"
2027
+ },
2028
+ italic: {
2029
+ $: "italic 600 var(--dsh-content-font-size, 14px) / calc(24px + var(--dsh-content-font-delta)) var(--dsw-font-family)",
2030
+ font: {
2031
+ family: "var(--dsw-font-family)",
2032
+ size: "var(--dsh-content-font-size, 14px)",
2033
+ style: "italic",
2034
+ weight: "600"
2035
+ },
2036
+ line: { height: "calc(24px + var(--dsh-content-font-delta))" }
2037
+ },
2038
+ line: { height: "calc(24px + var(--dsh-content-font-delta))" }
2039
+ }
2040
+ },
2041
+ code: {
2042
+ $: "12px/19px var(--ds-font-family-code)",
2043
+ block: {
2044
+ $: "11px/19px var(--ds-font-family-code)",
2045
+ font: {
2046
+ family: "var(--ds-font-family-code)",
2047
+ size: "11px",
2048
+ style: "normal",
2049
+ weight: "400"
2050
+ },
2051
+ line: { height: "19px" },
2052
+ small: {
2053
+ $: "11px/16px var(--ds-font-family-code)",
2054
+ font: {
2055
+ family: "var(--ds-font-family-code)",
2056
+ size: "11px",
2057
+ style: "normal",
2058
+ weight: "400"
2059
+ },
2060
+ line: { height: "16px" }
2061
+ }
2062
+ },
2063
+ font: {
2064
+ family: "var(--ds-font-family-code)",
2065
+ size: "12px",
2066
+ style: "normal",
2067
+ weight: "400"
2068
+ },
2069
+ line: { height: "19px" }
2070
+ },
2071
+ h1: {
2072
+ $: "700 calc(21px + var(--dsh-content-font-delta)) / calc(30px + var(--dsh-content-font-delta)) var(--dsw-font-family)",
2073
+ font: {
2074
+ family: "var(--dsw-font-family)",
2075
+ size: "calc(21px + var(--dsh-content-font-delta))",
2076
+ style: "normal",
2077
+ weight: "700"
2078
+ },
2079
+ line: { height: "calc(30px + var(--dsh-content-font-delta))" }
2080
+ },
2081
+ h2: {
2082
+ $: "700 calc(19px + var(--dsh-content-font-delta)) / calc(28px + var(--dsh-content-font-delta)) var(--dsw-font-family)",
2083
+ font: {
2084
+ family: "var(--dsw-font-family)",
2085
+ size: "calc(19px + var(--dsh-content-font-delta))",
2086
+ style: "normal",
2087
+ weight: "700"
2088
+ },
2089
+ line: { height: "calc(28px + var(--dsh-content-font-delta))" }
2090
+ },
2091
+ h3: {
2092
+ $: "700 calc(18px + var(--dsh-content-font-delta)) / calc(26px + var(--dsh-content-font-delta)) var(--dsw-font-family)",
2093
+ font: {
2094
+ family: "var(--dsw-font-family)",
2095
+ size: "calc(18px + var(--dsh-content-font-delta))",
2096
+ style: "normal",
2097
+ weight: "700"
2098
+ },
2099
+ line: { height: "calc(26px + var(--dsh-content-font-delta))" }
2100
+ },
2101
+ h4: {
2102
+ $: "600 var(--dsh-content-font-size, 14px) / calc(24px + var(--dsh-content-font-delta)) var(--dsw-font-family)",
2103
+ font: {
2104
+ family: "var(--dsw-font-family)",
2105
+ size: "var(--dsh-content-font-size, 14px)",
2106
+ style: "normal",
2107
+ weight: "600"
2108
+ },
2109
+ line: { height: "calc(24px + var(--dsh-content-font-delta))" }
2110
+ },
2111
+ small: {
2112
+ $: "12px/20px var(--dsw-font-family)",
2113
+ font: {
2114
+ family: "var(--dsw-font-family)",
2115
+ size: "12px",
2116
+ style: "normal",
2117
+ weight: "400"
2118
+ },
2119
+ italic: {
2120
+ $: "italic 12px/20px var(--dsw-font-family)",
2121
+ font: {
2122
+ family: "var(--dsw-font-family)",
2123
+ size: "12px",
2124
+ style: "italic",
2125
+ weight: "400"
2126
+ },
2127
+ line: { height: "20px" }
2128
+ },
2129
+ line: { height: "20px" },
2130
+ strong: {
2131
+ $: "600 12px/20px var(--dsw-font-family)",
2132
+ font: {
2133
+ family: "var(--dsw-font-family)",
2134
+ size: "12px",
2135
+ style: "normal",
2136
+ weight: "600"
2137
+ },
2138
+ italic: {
2139
+ $: "italic 600 12px/20px var(--dsw-font-family)",
2140
+ font: {
2141
+ family: "var(--dsw-font-family)",
2142
+ size: "12px",
2143
+ style: "italic",
2144
+ weight: "600"
2145
+ },
2146
+ line: { height: "20px" }
2147
+ },
2148
+ line: { height: "20px" }
2149
+ }
2150
+ },
2151
+ table: {
2152
+ $: "var(--dsh-content-font-size-secondary, 13px)/calc(22px + var(--dsh-content-font-delta-secondary, 0px)) var(--dsw-font-family)",
2153
+ font: {
2154
+ family: "var(--dsw-font-family)",
2155
+ size: "var(--dsh-content-font-size-secondary, 13px)",
2156
+ style: "normal",
2157
+ weight: "400"
2158
+ },
2159
+ head: {
2160
+ $: "500 var(--dsh-content-font-size-secondary, 13px)/calc(22px + var(--dsh-content-font-delta-secondary, 0px)) var(--dsw-font-family)",
2161
+ font: {
2162
+ family: "var(--dsw-font-family)",
2163
+ size: "var(--dsh-content-font-size-secondary, 13px)",
2164
+ style: "normal",
2165
+ weight: "500"
2166
+ },
2167
+ line: { height: "calc(22px + var(--dsh-content-font-delta-secondary, 0px))" }
2168
+ },
2169
+ line: { height: "calc(22px + var(--dsh-content-font-delta-secondary, 0px))" }
2170
+ }
2171
+ },
2172
+ s: {
2173
+ "14": {
2174
+ $: "14px/22px var(--dsw-font-family)",
2175
+ font: {
2176
+ family: "var(--dsw-font-family)",
2177
+ size: "14px",
2178
+ style: "normal",
2179
+ weight: "400"
2180
+ },
2181
+ line: { height: "22px" }
2182
+ },
2183
+ strong: { "14": {
2184
+ $: "500 14px/22px var(--dsw-font-family)",
2185
+ font: {
2186
+ family: "var(--dsw-font-family)",
2187
+ size: "14px",
2188
+ style: "normal",
2189
+ weight: "500"
2190
+ },
2191
+ line: { height: "22px" }
2192
+ } }
2193
+ },
2194
+ xl: { "24": {
2195
+ $: "600 24px/32px var(--dsw-font-family)",
2196
+ font: {
2197
+ family: "var(--dsw-font-family)",
2198
+ size: "24px",
2199
+ style: "normal",
2200
+ weight: "600"
2201
+ },
2202
+ line: { height: "32px" }
2203
+ } },
2204
+ xs: {
2205
+ "13": {
2206
+ $: "13px/20px var(--dsw-font-family)",
2207
+ font: {
2208
+ family: "var(--dsw-font-family)",
2209
+ size: "13px",
2210
+ style: "normal",
2211
+ weight: "400"
2212
+ },
2213
+ line: { height: "20px" }
2214
+ },
2215
+ strong: { "13": {
2216
+ $: "500 13px/20px var(--dsw-font-family)",
2217
+ font: {
2218
+ family: "var(--dsw-font-family)",
2219
+ size: "13px",
2220
+ style: "normal",
2221
+ weight: "500"
2222
+ },
2223
+ line: { height: "20px" }
2224
+ } }
2225
+ },
2226
+ xxs: {
2227
+ "12": {
2228
+ $: "12px/18px var(--dsw-font-family)",
2229
+ font: {
2230
+ family: "var(--dsw-font-family)",
2231
+ size: "12px",
2232
+ style: "normal",
2233
+ weight: "400"
2234
+ },
2235
+ line: { height: "18px" }
2236
+ },
2237
+ strong: { "12": {
2238
+ $: "500 12px/18px var(--dsw-font-family)",
2239
+ font: {
2240
+ family: "var(--dsw-font-family)",
2241
+ size: "12px",
2242
+ style: "normal",
2243
+ weight: "500"
2244
+ },
2245
+ line: { height: "18px" }
2246
+ } }
2247
+ },
2248
+ xxxs: {
2249
+ "11": {
2250
+ $: "11px/14px var(--dsw-font-family)",
2251
+ font: {
2252
+ family: "var(--dsw-font-family)",
2253
+ size: "11px",
2254
+ style: "normal",
2255
+ weight: "400"
2256
+ },
2257
+ line: { height: "14px" }
2258
+ },
2259
+ strong: { "11": {
2260
+ $: "500 11px/14px var(--dsw-font-family)",
2261
+ font: {
2262
+ family: "var(--dsw-font-family)",
2263
+ size: "11px",
2264
+ style: "normal",
2265
+ weight: "500"
2266
+ },
2267
+ line: { height: "14px" }
2268
+ } }
2269
+ }
2270
+ },
2271
+ gradient: { onboarding: {
2272
+ blue: { stops: "#3964fe 18.75%, #398efe 51.78%, #6dccff 86.252%, #3964fe" },
2273
+ cyan: { stops: "#0293b4 21.154%, #2dc8eb 50.954%, #aff0ff 85.326%, #0293b4" },
2274
+ violet: { stops: "#2a2fb6 33.102%, #8b76f6 50.954%, #c5c0ff 85.326%, #2a2fb6" }
2275
+ } },
2276
+ linear: {
2277
+ gradient: { think: "linear-gradient(180deg, #fff 20.19%, rgba(255, 255, 255, 0) 100%)" },
2278
+ think: { select: "linear-gradient(180deg, #f5f6f7 20.19%, rgba(245, 246, 247, 0) 100%)" }
2279
+ },
2280
+ mask: { blur: "none" },
2281
+ menu: {
2282
+ backdrop: { filter: "blur(40px) saturate(150%)" },
2283
+ surface: { fill: "rgba(248, 249, 250, 0.58)" }
2284
+ },
2285
+ radius: {
2286
+ lg: "16px",
2287
+ md: "12px",
2288
+ panel: "28px",
2289
+ sm: "8px",
2290
+ xl: "20px",
2291
+ xs: "4px"
2292
+ },
2293
+ shadow: {
2294
+ lv1: {
2295
+ $: "0 2px 4px 0 rgba(0, 0, 0, 0.05)",
2296
+ blur: "0 4px 12px 0 rgba(0, 0, 0, 0.02)"
2297
+ },
2298
+ lv2: "0 4px 12px 0 rgba(0, 0, 0, 0.02), 0 2px 8px 0 rgba(0, 0, 0, 0.04)",
2299
+ lv3: "0 0 1px 0 rgba(0, 0, 0, 0.2), 0 0 4px 0 rgba(0, 0, 0, 0.02), 0 12px 32px 0 rgba(0, 0, 0, 0.08)"
2300
+ },
2301
+ specific: {
2302
+ bubble: {
2303
+ $: "var(--dsw-static-deepseek-50)",
2304
+ highlight: "var(--dsw-static-deepseek-200)"
2305
+ },
2306
+ input: { major: "var(--dsw-static-neutral-bluish-00)" },
2307
+ login: { input: "var(--dsw-static-neutral-bluish-50)" },
2308
+ menu: "var(--dsw-menu-surface-fill)",
2309
+ selector: "var(--dsw-static-neutral-bluish-60)",
2310
+ sidebar: {
2311
+ fill: "var(--dsw-static-neutral-bluish-50)",
2312
+ nav: { item: {
2313
+ active: {
2314
+ $: "var(--dsw-static-neutral-bluish-100)",
2315
+ accent: "var(--dsw-static-deepseek-100)"
2316
+ },
2317
+ hover: "var(--dsw-static-neutral-bluish-75)"
2318
+ } }
2319
+ },
2320
+ tip: "var(--dsw-static-neutral-bluish-60)"
2321
+ },
2322
+ static: {
2323
+ amber: {
2324
+ "100": "rgb(254, 245, 231)",
2325
+ "400": "rgb(247, 173, 49)",
2326
+ "500": "rgb(245, 158, 11)",
2327
+ "600": "rgb(221, 134, 41)",
2328
+ "900": "rgb(39, 36, 31)"
2329
+ },
2330
+ blue: {
2331
+ "50": "rgb(239, 246, 255)",
2332
+ "75": "rgb(229, 240, 255)",
2333
+ "100": "rgb(219, 234, 254)",
2334
+ "300": "rgb(147, 197, 253)",
2335
+ "400": "rgb(96, 165, 250)",
2336
+ "450": "rgb(77, 147, 248)",
2337
+ "500": "rgb(59, 130, 246)",
2338
+ "600": "rgb(37, 99, 235)",
2339
+ "800": "rgb(30, 64, 175)",
2340
+ "900": "rgb(14, 48, 116)",
2341
+ "950": "rgb(23, 37, 84)",
2342
+ "50p": "rgb(234, 243, 255)"
2343
+ },
2344
+ deepseek: {
2345
+ "50": "rgb(237, 243, 254)",
2346
+ "100": "rgb(228, 237, 253)",
2347
+ "200": "rgb(211, 226, 255)",
2348
+ "300": "rgb(183, 200, 254)",
2349
+ "400": "rgb(122, 170, 255)",
2350
+ "450": "rgb(86, 134, 254)",
2351
+ "500": "rgb(65, 118, 230)",
2352
+ "600": "rgb(72, 104, 178)",
2353
+ "700": { delete: "rgb(47, 76, 143)" },
2354
+ "800": "rgb(52, 65, 91)",
2355
+ "900": "rgb(40, 49, 66)"
2356
+ },
2357
+ green: {
2358
+ "100": "rgb(230, 250, 237)",
2359
+ "400": "rgb(78, 209, 126)",
2360
+ "500": {
2361
+ $: "rgb(34, 197, 94)",
2362
+ a08: "rgb(34 197 94 / 8%)",
2363
+ a12: "rgb(34 197 94 / 12%)"
2364
+ },
2365
+ "900": "rgb(35, 60, 44)"
2366
+ },
2367
+ neutral: {
2368
+ "50": "rgb(250, 250, 250)",
2369
+ "100": "rgb(245, 245, 245)",
2370
+ "150": "rgb(237, 237, 237)",
2371
+ "200": "rgb(229, 229, 229)",
2372
+ "250": "rgb(220, 220, 220)",
2373
+ "300": "rgb(212, 212, 212)",
2374
+ "400": "rgb(162, 164, 166)",
2375
+ "500": "rgb(127, 130, 135)",
2376
+ "550": "rgb(101, 103, 107)",
2377
+ "600": "rgb(84, 85, 87)",
2378
+ "700": "rgb(60, 60, 61)",
2379
+ "800": "rgb(41, 41, 41)",
2380
+ "850": "rgb(33, 33, 35)",
2381
+ "900": "rgb(15, 15, 15)",
2382
+ "1000": "rgb(0, 0, 0)",
2383
+ "00": "rgb(255, 255, 255)",
2384
+ bluish: {
2385
+ "50": "rgb(249, 250, 251)",
2386
+ "60": "rgb(245, 246, 247)",
2387
+ "75": "rgb(241, 243, 245)",
2388
+ "100": "rgb(235, 238, 242)",
2389
+ "150": "rgb(233, 236, 242)",
2390
+ "200": "rgb(225, 229, 238)",
2391
+ "300": "rgb(207, 211, 214)",
2392
+ "400": "rgb(173, 178, 184)",
2393
+ "500": "rgb(151, 157, 166)",
2394
+ "600": "rgb(129, 133, 140)",
2395
+ "700": "rgb(97, 102, 107)",
2396
+ "750": "rgb(67, 69, 74)",
2397
+ "800": "rgb(53, 54, 56)",
2398
+ "850": "rgb(44, 44, 46)",
2399
+ "875": "rgb(35, 35, 36)",
2400
+ "900": "rgb(27, 27, 28)",
2401
+ "950": "rgb(21, 21, 23)",
2402
+ "1000": "rgb(15, 17, 21)",
2403
+ "00": "rgb(255, 255, 255)"
2404
+ }
2405
+ },
2406
+ red: {
2407
+ "50": "rgb(254, 242, 242)",
2408
+ "100": "rgb(254, 226, 226)",
2409
+ "400": {
2410
+ $: "rgb(242, 90, 90)",
2411
+ a12: "rgb(242 90 90 / 12%)"
2412
+ },
2413
+ "500": "rgb(239, 68, 68)",
2414
+ "600": {
2415
+ $: "rgb(236, 19, 19)",
2416
+ a08: "rgb(236 19 19 / 8%)"
2417
+ },
2418
+ "900": "rgb(87, 12, 12)"
2419
+ }
2420
+ }
2421
+ };
2422
+ //#endregion
2423
+ //#region src/client/theme.ts
2424
+ const dsw = Token.vars(designTokens, { prefix: "dsw" });
2425
+ //#endregion
2426
+ //#region src/client/schema-form/styles.ts
2427
+ const MONO = "ui-monospace, SFMono-Regular, \"SF Mono\", Menlo, Consolas, monospace";
2428
+ const ROW = "22px";
2429
+ const GAP = "6px";
2430
+ const ACTION = "20px";
2431
+ const ACTION_GAP = "4px";
2432
+ const FOLD = "14px";
2433
+ const NUMBER = "32px";
2434
+ const PAD = "8px";
2435
+ const HAIRLINE = dsw.elevation.stroke;
2436
+ const LINE = dsw.elevation.stroke.color;
2437
+ const EDGE = "2px";
2438
+ const ERROR_WASH = `color-mix(in srgb, ${String(dsw.alias.state.error.secondary)} 12%, transparent)`;
2439
+ const EditorRoot = styled("div")({
2440
+ display: "flex",
2441
+ flexDirection: "column",
2442
+ width: "100%",
2443
+ fontFamily: MONO,
2444
+ fontSize: "14px",
2445
+ lineHeight: ROW,
2446
+ color: dsw.alias.label.primary
2447
+ });
2448
+ const LineRow = styled("div")({
2449
+ display: "flex",
2450
+ alignItems: "flex-start",
2451
+ gap: GAP,
2452
+ minHeight: ROW,
2453
+ paddingRight: PAD,
2454
+ whiteSpace: "nowrap",
2455
+ "&:hover": { background: dsw.alias.bg.layer["2"] },
2456
+ "&[data-selected='true']": { background: dsw.alias.bg.layer["3"] },
2457
+ "&[data-dirty='true']": { boxShadow: `inset ${EDGE} 0 0 ${String(dsw.alias.brand.primary)}` },
2458
+ "&[data-overridden='true']": { boxShadow: `inset ${EDGE} 0 0 ${String(LINE)}` },
2459
+ "&[data-dirty='true'] [data-role='key']": { color: dsw.alias.brand.primary },
2460
+ "&[data-overridden='true'] [data-role='key']": { color: dsw.alias.brand.primary },
2461
+ "&[data-invalid='true']": {
2462
+ background: ERROR_WASH,
2463
+ boxShadow: `inset ${EDGE} 0 0 ${String(dsw.alias.state.error.primary)}`
2464
+ },
2465
+ "&[data-invalid='true'] [data-role='key']": { color: dsw.alias.state.error.primary },
2466
+ "&:hover [data-role='actions']": { opacity: 1 }
2467
+ });
2468
+ const LineBody = styled("div")({
2469
+ display: "flex",
2470
+ alignItems: "center",
2471
+ gap: GAP,
2472
+ flex: 1,
2473
+ minWidth: 0,
2474
+ minHeight: ROW
2475
+ });
2476
+ const LineNumber = styled("span")({
2477
+ flex: "none",
2478
+ width: NUMBER,
2479
+ lineHeight: ROW,
2480
+ textAlign: "right",
2481
+ color: dsw.alias.label.caption,
2482
+ userSelect: "none",
2483
+ cursor: "pointer"
2484
+ });
2485
+ const LineFold = styled("button")({
2486
+ display: "inline-flex",
2487
+ alignItems: "center",
2488
+ justifyContent: "center",
2489
+ flex: "none",
2490
+ width: FOLD,
2491
+ height: ROW,
2492
+ padding: 0,
2493
+ border: 0,
2494
+ background: "none",
2495
+ color: dsw.alias.label.caption,
2496
+ cursor: "pointer",
2497
+ "&:hover": { color: dsw.alias.label.secondary }
2498
+ });
2499
+ const LineFoldSpacer = styled("span")({
2500
+ flex: "none",
2501
+ width: FOLD
2502
+ });
2503
+ const LineKey = styled("span")({
2504
+ flex: "none",
2505
+ color: dsw.alias.label.primary,
2506
+ "&[data-index='true']": { color: dsw.alias.label.caption }
2507
+ });
2508
+ const LineToken = styled("span")({
2509
+ flex: "none",
2510
+ color: dsw.alias.label.caption
2511
+ });
2512
+ const LineValue = styled("span")({
2513
+ display: "block",
2514
+ minWidth: 0,
2515
+ overflow: "hidden",
2516
+ textOverflow: "ellipsis",
2517
+ cursor: "text",
2518
+ color: dsw.alias.state.business.primary,
2519
+ "&[data-tone='number']": { color: dsw.alias.state.warn.primary },
2520
+ "&[data-tone='boolean']": { color: dsw.alias.state.success.primary },
2521
+ "&[data-tone='empty']": { color: dsw.alias.label.caption }
2522
+ });
2523
+ const ValueSlot = styled("span")({
2524
+ display: "block",
2525
+ flex: "0 1 auto",
2526
+ minWidth: 0,
2527
+ overflow: "hidden"
2528
+ });
2529
+ const ValueTrigger = styled("button")({
2530
+ display: "inline-flex",
2531
+ alignItems: "center",
2532
+ gap: "2px",
2533
+ minWidth: 0,
2534
+ padding: 0,
2535
+ border: 0,
2536
+ background: "none",
2537
+ font: "inherit",
2538
+ textAlign: "left",
2539
+ cursor: "pointer",
2540
+ color: dsw.alias.label.caption,
2541
+ "&:disabled": { cursor: "default" },
2542
+ "&:focus-visible": { outline: "none" }
2543
+ });
2544
+ const CompactInput = styled("span")({
2545
+ display: "inline-flex",
2546
+ flex: "1 1 auto",
2547
+ minWidth: 0,
2548
+ "& > span": {
2549
+ width: "100%",
2550
+ height: ROW,
2551
+ padding: "0 6px",
2552
+ borderRadius: "4px"
2553
+ },
2554
+ "& input": {
2555
+ fontSize: "14px",
2556
+ lineHeight: ROW
2557
+ }
2558
+ });
2559
+ const CompactTextField = styled("span")({
2560
+ display: "inline-flex",
2561
+ flex: "1 1 auto",
2562
+ minWidth: 0,
2563
+ padding: "0 6px",
2564
+ borderRadius: "4px",
2565
+ background: dsw.alias.bg.layer["1"],
2566
+ border: 0,
2567
+ boxShadow: HAIRLINE,
2568
+ "&:focus-within": { "--dsw-elevation-stroke-color": dsw.alias.brand.primary },
2569
+ "& > textarea": {
2570
+ flex: 1,
2571
+ width: "100%",
2572
+ minHeight: ACTION,
2573
+ maxHeight: "240px",
2574
+ padding: 0,
2575
+ border: 0,
2576
+ outline: "none",
2577
+ background: "transparent",
2578
+ resize: "none",
2579
+ fieldSizing: "content",
2580
+ fontFamily: "inherit",
2581
+ fontSize: "14px",
2582
+ lineHeight: ROW,
2583
+ color: dsw.alias.label.primary
2584
+ }
2585
+ });
2586
+ const LineComment = styled("span")({
2587
+ flex: "1 1 auto",
2588
+ minWidth: 0,
2589
+ overflow: "hidden",
2590
+ textOverflow: "ellipsis",
2591
+ color: dsw.alias.label.tertiary,
2592
+ fontFamily: "inherit",
2593
+ fontSize: "12px"
2594
+ });
2595
+ const LineInvalid = styled("span")({
2596
+ flex: "0 1 auto",
2597
+ minWidth: 0,
2598
+ overflow: "hidden",
2599
+ textOverflow: "ellipsis",
2600
+ color: dsw.alias.state.error.primary,
2601
+ fontFamily: "inherit",
2602
+ fontSize: "12px"
2603
+ });
2604
+ const HoverActions = styled(styled("span")({
2605
+ display: "inline-flex",
2606
+ alignItems: "center",
2607
+ gap: ACTION_GAP,
2608
+ flex: "none",
2609
+ opacity: 0,
2610
+ "& > button": {
2611
+ display: "inline-flex",
2612
+ alignItems: "center",
2613
+ justifyContent: "center",
2614
+ width: ACTION,
2615
+ height: ACTION,
2616
+ padding: 0,
2617
+ border: 0,
2618
+ borderRadius: "4px",
2619
+ background: "none",
2620
+ color: dsw.alias.label.secondary,
2621
+ cursor: "pointer",
2622
+ "&:hover": {
2623
+ background: dsw.alias.bg.layer["3"],
2624
+ color: dsw.alias.label.primary
2625
+ },
2626
+ "&:disabled": {
2627
+ cursor: "not-allowed",
2628
+ color: dsw.alias.label.dimmed
2629
+ }
2630
+ }
2631
+ }))({ "&[data-editing='true']": {
2632
+ opacity: 1,
2633
+ gap: GAP,
2634
+ "& > button": {
2635
+ boxShadow: HAIRLINE,
2636
+ background: dsw.alias.bg.layer["1"],
2637
+ color: dsw.alias.label.primary,
2638
+ "&:first-of-type": { color: dsw.alias.state.success.primary }
2639
+ }
2640
+ } });
2641
+ const AddWrap = styled("span")({
2642
+ position: "relative",
2643
+ display: "inline-flex",
2644
+ alignItems: "center",
2645
+ gap: GAP,
2646
+ flex: "1 1 auto",
2647
+ minWidth: 0,
2648
+ marginLeft: GAP,
2649
+ "&[data-invalid='true'] input": { borderColor: dsw.alias.state.error.primary }
2650
+ });
2651
+ const Hint$1 = styled("p")({
2652
+ margin: 0,
2653
+ fontSize: "12px",
2654
+ lineHeight: 1.5,
2655
+ color: dsw.alias.label.tertiary
2656
+ });
2657
+ //#endregion
2658
+ //#region src/client/schema-form/TruncatedTooltip.tsx
2659
+ function TruncatedTooltip({ label, children }) {
2660
+ const node = useRef(null);
2661
+ const watch = useRef(null);
2662
+ const [truncated, setTruncated] = useState(false);
2663
+ const measure = useCallback(() => {
2664
+ const el = node.current;
2665
+ if (el === null) return;
2666
+ setTruncated(el.scrollWidth > el.clientWidth);
2667
+ }, []);
2668
+ const anchor = useCallback((el) => {
2669
+ watch.current?.disconnect();
2670
+ watch.current = null;
2671
+ node.current = el;
2672
+ if (el === null) return;
2673
+ const observer = new ResizeObserver(measure);
2674
+ observer.observe(el);
2675
+ watch.current = observer;
2676
+ }, [measure]);
2677
+ useLayoutEffect(measure);
2678
+ return /* @__PURE__ */ jsx(Tooltip, {
2679
+ label,
2680
+ side: "bottom",
2681
+ portal: true,
2682
+ disabled: !truncated,
2683
+ children: cloneElement(children, { ref: anchor })
2684
+ });
2685
+ }
2686
+ //#endregion
2687
+ //#region src/client/schema-form/value.tsx
2688
+ function valueText(value) {
2689
+ if (value === void 0 || value === null) return "";
2690
+ if (typeof value === "string") return value;
2691
+ if (typeof value === "number" || typeof value === "boolean") return String(value);
2692
+ return JSON.stringify(value);
2693
+ }
2694
+ function isMultiline(value) {
2695
+ return typeof value === "string" && /[\r\n]/.test(value);
2696
+ }
2697
+ function tokenText(value) {
2698
+ if (value === void 0 || value === null) return "null";
2699
+ if (typeof value === "string") return JSON.stringify(value);
2700
+ if (typeof value === "number" || typeof value === "boolean") return String(value);
2701
+ return JSON.stringify(value);
2702
+ }
2703
+ function tokenTone(value) {
2704
+ if (value === void 0 || value === null) return "empty";
2705
+ if (typeof value === "number") return "number";
2706
+ if (typeof value === "boolean") return "boolean";
2707
+ return "string";
2708
+ }
2709
+ function InlineValue({ owner }) {
2710
+ if (owner.options !== void 0) return /* @__PURE__ */ jsx(OptionSelect, {
2711
+ owner,
2712
+ options: owner.options
2713
+ });
2714
+ if (owner.node.meta.secret) return /* @__PURE__ */ jsx(LineValue, {
2715
+ "data-tone": "empty",
2716
+ title: owner.hint,
2717
+ children: owner.secretConfigured ? "••••••" : ""
2718
+ });
2719
+ const text = tokenText(owner.value);
2720
+ return /* @__PURE__ */ jsx(TruncatedTooltip, {
2721
+ label: text,
2722
+ children: /* @__PURE__ */ jsx(LineValue, {
2723
+ "data-tone": owner.node.readOnly === null ? tokenTone(owner.value) : "empty",
2724
+ children: text
2725
+ })
2726
+ });
2727
+ }
2728
+ function OptionSelect({ owner, options }) {
2729
+ const [open, setOpen] = useState(false);
2730
+ const selected = options.findIndex((option) => sameValue(option.value, owner.value));
2731
+ const current = selected < 0 ? void 0 : options[selected];
2732
+ const label = current?.label ?? (owner.value === void 0 ? owner.t("unconfigured") : tokenText(current?.value ?? owner.value));
2733
+ return /* @__PURE__ */ jsx(Menu, {
2734
+ open,
2735
+ dense: true,
2736
+ compact: true,
2737
+ portal: true,
2738
+ align: "start",
2739
+ items: options.map((option, index) => ({
2740
+ id: String(index),
2741
+ label: option.label ?? tokenText(option.value)
2742
+ })),
2743
+ selectedId: selected < 0 ? void 0 : String(selected),
2744
+ onSelect: (id) => {
2745
+ setOpen(false);
2746
+ const option = options[Number(id)];
2747
+ if (option !== void 0) owner.onChange(option.value);
2748
+ },
2749
+ onClose: () => {
2750
+ setOpen(false);
2751
+ },
2752
+ anchor: /* @__PURE__ */ jsxs(ValueTrigger, {
2753
+ type: "button",
2754
+ disabled: owner.disabled,
2755
+ "aria-label": owner.label,
2756
+ onClick: () => {
2757
+ setOpen(true);
2758
+ },
2759
+ children: [/* @__PURE__ */ jsx(LineValue, {
2760
+ "data-tone": current === void 0 ? tokenTone(owner.value) : tokenTone(current.value),
2761
+ children: label
2762
+ }), /* @__PURE__ */ jsx(IconChevronDownOutlineRegular, { size: 14 })]
2763
+ })
2764
+ });
2765
+ }
2766
+ function sameValue(left, right) {
2767
+ if (Object.is(left, right)) return true;
2768
+ if (typeof left !== "object" || typeof right !== "object" || left === null || right === null) return false;
2769
+ return JSON.stringify(left) === JSON.stringify(right);
2770
+ }
2771
+ function SchemaFieldDefault({ owner }) {
2772
+ return /* @__PURE__ */ jsx(InlineValue, { owner });
2773
+ }
2774
+ //#endregion
2775
+ //#region src/client/schema-form/fields.tsx
2776
+ function parseFor(node, t) {
2777
+ switch (node.type) {
2778
+ case "number": return (text) => {
2779
+ const trimmed = text.trim();
2780
+ const value = Number(trimmed);
2781
+ if (trimmed === "" || !Number.isFinite(value)) return {
2782
+ kind: "invalid",
2783
+ message: t("invalidNumber")
2784
+ };
2785
+ if (node.meta.step === 1 && !Number.isInteger(value)) return {
2786
+ kind: "invalid",
2787
+ message: t("invalidInteger")
2788
+ };
2789
+ const { min, max } = node.meta;
2790
+ if (min !== void 0 && max !== void 0 && (value < min || value > max)) return {
2791
+ kind: "invalid",
2792
+ message: t("invalidRange", {
2793
+ min,
2794
+ max
2795
+ })
2796
+ };
2797
+ if (min !== void 0 && value < min) return {
2798
+ kind: "invalid",
2799
+ message: t("invalidMin", { min })
2800
+ };
2801
+ if (max !== void 0 && value > max) return {
2802
+ kind: "invalid",
2803
+ message: t("invalidMax", { max })
2804
+ };
2805
+ return {
2806
+ kind: "value",
2807
+ value
2808
+ };
2809
+ };
2810
+ case "string": {
2811
+ const pattern = node.meta.pattern;
2812
+ if (pattern === void 0) return (text) => ({
2813
+ kind: "value",
2814
+ value: text
2815
+ });
2816
+ return (text) => new RegExp(pattern).test(text) ? {
2817
+ kind: "value",
2818
+ value: text
2819
+ } : {
2820
+ kind: "invalid",
2821
+ message: t("invalidPattern", { pattern })
2822
+ };
2823
+ }
2824
+ case "boolean": return (text) => {
2825
+ const trimmed = text.trim();
2826
+ if (trimmed === "true") return {
2827
+ kind: "value",
2828
+ value: true
2829
+ };
2830
+ if (trimmed === "false") return {
2831
+ kind: "value",
2832
+ value: false
2833
+ };
2834
+ return {
2835
+ kind: "invalid",
2836
+ message: t("invalidBoolean")
2837
+ };
2838
+ };
2839
+ case "const": return (text) => text === String(node.type === "const" ? node.value : "") || text.trim() === JSON.stringify(node.value) ? {
2840
+ kind: "value",
2841
+ value: node.value
2842
+ } : {
2843
+ kind: "invalid",
2844
+ message: t("invalidConst")
2845
+ };
2846
+ case "bitset": return (text) => {
2847
+ const value = Number(text.trim());
2848
+ return Number.isFinite(value) ? {
2849
+ kind: "value",
2850
+ value
2851
+ } : {
2852
+ kind: "invalid",
2853
+ message: t("invalidNumber")
2854
+ };
2855
+ };
2856
+ case "any": return (text) => {
2857
+ try {
2858
+ return {
2859
+ kind: "value",
2860
+ value: JSON.parse(text)
2861
+ };
2862
+ } catch {
2863
+ return {
2864
+ kind: "invalid",
2865
+ message: t("invalidJson")
2866
+ };
2867
+ }
2868
+ };
2869
+ default:
2870
+ if (node.type === "union" && node.choices !== void 0) {
2871
+ const choices = node.choices;
2872
+ const options = choices.map((choice) => String(choice)).join(" / ");
2873
+ return (text) => choices.some((choice) => String(choice) === text) ? {
2874
+ kind: "value",
2875
+ value: text
2876
+ } : {
2877
+ kind: "invalid",
2878
+ message: t("invalidChoice", { choices: options })
2879
+ };
2880
+ }
2881
+ return (text) => ({
2882
+ kind: "value",
2883
+ value: text
2884
+ });
2885
+ }
2886
+ }
2887
+ //#endregion
2888
+ //#region src/client/schema-form/Editor.tsx
2889
+ function Editor(props) {
2890
+ const { ns, state, face, t, resolveText, renderField } = props;
2891
+ const [toggled, setToggled] = useState(() => /* @__PURE__ */ new Set());
2892
+ const [editing, setEditing] = useState(void 0);
2893
+ const [selected, setSelected] = useState(void 0);
2894
+ const [dismissed, setDismissed] = useState(() => /* @__PURE__ */ new Set());
2895
+ const fold = useFold(state, toggled, setToggled);
2896
+ const lines = useMemo(() => editorLines(state, fold, resolveText, t), [
2897
+ state,
2898
+ fold,
2899
+ resolveText,
2900
+ t
2901
+ ]);
2902
+ const disabled = !state.writable || !state.available;
2903
+ return /* @__PURE__ */ jsx(EditorRoot, {
2904
+ "data-editor": "schema-form",
2905
+ children: lines.map((line, index) => /* @__PURE__ */ jsx(Row, {
2906
+ line,
2907
+ n: index + 1,
2908
+ ns,
2909
+ state,
2910
+ face,
2911
+ fold,
2912
+ t,
2913
+ resolveText,
2914
+ disabled,
2915
+ editing,
2916
+ selected,
2917
+ onEdit: (key) => {
2918
+ setEditing(key);
2919
+ if (key !== void 0) setDismissed((previous) => {
2920
+ const next = new Set(previous);
2921
+ next.delete(key);
2922
+ return next;
2923
+ });
2924
+ },
2925
+ onAdded: (path) => {
2926
+ setEditing(fieldKey(path));
2927
+ },
2928
+ dismissed,
2929
+ onDismiss: (key) => {
2930
+ setDismissed((previous) => new Set(previous).add(key));
2931
+ },
2932
+ onSelect: (path) => {
2933
+ setSelected(fieldKey(path));
2934
+ },
2935
+ renderField
2936
+ }, `${line.kind}:${fieldKey(line.path)}:${String(index)}`))
2937
+ });
2938
+ }
2939
+ function useFold(state, toggled, setToggled) {
2940
+ const defaults = useMemo(() => {
2941
+ const collapsed = /* @__PURE__ */ new Set();
2942
+ for (const item of state.walked) {
2943
+ const value = state.fields.get(fieldKey(item.path))?.value;
2944
+ if (item.node.meta.collapse && containerShape(item.node, value) !== void 0) collapsed.add(fieldKey(item.path));
2945
+ }
2946
+ return collapsed;
2947
+ }, [state.walked, state.fields]);
2948
+ return useMemo(() => ({
2949
+ collapsed: (path) => {
2950
+ const key = fieldKey(path);
2951
+ return toggled.has(key) !== defaults.has(key);
2952
+ },
2953
+ toggle: (path) => {
2954
+ const key = fieldKey(path);
2955
+ const next = new Set(toggled);
2956
+ if (next.has(key)) next.delete(key);
2957
+ else next.add(key);
2958
+ setToggled(next);
2959
+ }
2960
+ }), [
2961
+ defaults,
2962
+ setToggled,
2963
+ toggled
2964
+ ]);
2965
+ }
2966
+ function Row({ line, n, ns, state, face, fold, t, resolveText, disabled, editing, selected, dismissed, onEdit, onAdded, onDismiss, onSelect, renderField }) {
2967
+ const key = fieldKey(line.path);
2968
+ const indent = { paddingLeft: `${String(line.depth * 14)}px` };
2969
+ const body = line.kind === "comment" ? /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(LineFoldSpacer, { "data-role": "fold" }), /* @__PURE__ */ jsx(TruncatedTooltip, {
2970
+ label: line.text,
2971
+ children: line.invalid ? /* @__PURE__ */ jsx(LineInvalid, {
2972
+ "data-role": "comment",
2973
+ children: `// ${line.text}`
2974
+ }) : /* @__PURE__ */ jsx(LineComment, {
2975
+ "data-role": "comment",
2976
+ children: `// ${line.text}`
2977
+ })
2978
+ })] }) : line.kind === "open" ? /* @__PURE__ */ jsxs(Fragment, { children: [
2979
+ /* @__PURE__ */ jsx(LineFold, {
2980
+ "data-role": "fold",
2981
+ type: "button",
2982
+ "aria-expanded": !line.collapsed,
2983
+ "aria-label": t("toggleGroup"),
2984
+ onClick: () => {
2985
+ fold.toggle(line.path);
2986
+ },
2987
+ children: line.collapsed ? /* @__PURE__ */ jsx(IconChevronRightOutlineRegular, { size: 14 }) : /* @__PURE__ */ jsx(IconChevronDownOutlineRegular, { size: 14 })
2988
+ }),
2989
+ /* @__PURE__ */ jsx(LinePrefix, {
2990
+ line,
2991
+ face,
2992
+ t,
2993
+ disabled
2994
+ }),
2995
+ /* @__PURE__ */ jsx(LineToken, { children: line.shape === "object" ? line.collapsed ? "{…}" : "{" : line.collapsed ? "[…]" : "[" }),
2996
+ /* @__PURE__ */ jsx(VariantSelect, {
2997
+ control: line.variants,
2998
+ path: line.path,
2999
+ face,
3000
+ disabled,
3001
+ t
3002
+ })
3003
+ ] }) : line.kind === "close" ? /* @__PURE__ */ jsxs(Fragment, { children: [
3004
+ /* @__PURE__ */ jsx(LineFoldSpacer, { "data-role": "fold" }),
3005
+ /* @__PURE__ */ jsx(LineToken, { children: line.shape === "object" ? "}" : "]" }),
3006
+ /* @__PURE__ */ jsx(AddLine, {
3007
+ line,
3008
+ state,
3009
+ face,
3010
+ t,
3011
+ resolveText,
3012
+ disabled,
3013
+ onAdded
3014
+ })
3015
+ ] }) : /* @__PURE__ */ jsx(FieldLine, {
3016
+ line,
3017
+ ns,
3018
+ state,
3019
+ face,
3020
+ t,
3021
+ disabled,
3022
+ editing,
3023
+ dismissed,
3024
+ onEdit,
3025
+ onDismiss,
3026
+ renderField
3027
+ });
3028
+ return /* @__PURE__ */ jsxs(LineRow, {
3029
+ "data-line": line.kind,
3030
+ "data-field-path": line.path.join("."),
3031
+ "data-selected": selected === key ? "true" : void 0,
3032
+ "data-dirty": line.kind === "field" && line.field.staged ? "true" : void 0,
3033
+ "data-overridden": line.kind === "field" && line.field.overridden && !line.field.staged ? "true" : void 0,
3034
+ "data-invalid": line.kind === "field" && (line.field.invalid !== void 0 || state.invalidAt.has(key)) ? "true" : void 0,
3035
+ children: [/* @__PURE__ */ jsx(LineNumber, {
3036
+ "data-role": "number",
3037
+ onClick: () => {
3038
+ onSelect(line.path);
3039
+ },
3040
+ children: n
3041
+ }), /* @__PURE__ */ jsx(LineBody, {
3042
+ "data-role": "body",
3043
+ style: indent,
3044
+ children: body
3045
+ })]
3046
+ });
3047
+ }
3048
+ function FieldLine({ line, ns, state, face, t, disabled, editing, dismissed, onEdit, onDismiss, renderField }) {
3049
+ const key = fieldKey(line.path);
3050
+ const member = line.member;
3051
+ const owner = {
3052
+ ns,
3053
+ path: line.path,
3054
+ node: line.node,
3055
+ label: line.node.label ?? member?.key ?? line.node.key,
3056
+ hint: void 0,
3057
+ value: line.field.value,
3058
+ options: state.options.get(key),
3059
+ text: line.field.text,
3060
+ secretConfigured: state.secrets.get(key) === true,
3061
+ depth: line.depth,
3062
+ overridden: line.field.overridden,
3063
+ invalid: line.field.invalid,
3064
+ disabled,
3065
+ t,
3066
+ actions: face,
3067
+ group: void 0,
3068
+ member,
3069
+ onChange: (value) => {
3070
+ face.set(line.path, value);
3071
+ },
3072
+ onEditText: (text, parse) => {
3073
+ face.setText(line.path, text, parse ?? parseFor(line.node, t));
3074
+ },
3075
+ onReset: () => {
3076
+ face.clear(line.path);
3077
+ }
3078
+ };
3079
+ const readOnly = line.node.meta.disabled || line.node.readOnly !== null;
3080
+ const editable = !disabled && !readOnly && line.node.type !== "const" && owner.options === void 0 && !line.variantsStandIn;
3081
+ const missing = line.field.value === null || line.field.value === void 0;
3082
+ const isEditing = editable && (editing === key || missing && !dismissed.has(key));
3083
+ const text = line.field.text ?? valueText(line.field.value);
3084
+ const multiline = isMultiline(line.field.value) || /[\r\n]/.test(text);
3085
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
3086
+ /* @__PURE__ */ jsx(LineFoldSpacer, { "data-role": "fold" }),
3087
+ /* @__PURE__ */ jsx(LineKey, {
3088
+ "data-role": "key",
3089
+ "data-index": member?.index === void 0 ? void 0 : "true",
3090
+ title: member?.key ?? line.node.key,
3091
+ children: member?.key ?? line.node.key
3092
+ }),
3093
+ /* @__PURE__ */ jsx(LineToken, { children: member?.index === void 0 ? ": " : " " }),
3094
+ isEditing ? multiline ? /* @__PURE__ */ jsx(CompactTextField, { children: /* @__PURE__ */ jsx("textarea", {
3095
+ autoFocus: !missing,
3096
+ rows: 1,
3097
+ "aria-label": owner.label,
3098
+ value: text,
3099
+ onChange: (event) => {
3100
+ owner.onEditText(event.target.value);
3101
+ },
3102
+ onKeyDown: (event) => {
3103
+ if (event.key === "Escape") {
3104
+ face.revert(line.path);
3105
+ onEdit(void 0);
3106
+ }
3107
+ }
3108
+ }) }) : /* @__PURE__ */ jsx(CompactInput, { children: /* @__PURE__ */ jsx(Input, {
3109
+ autoFocus: !missing,
3110
+ type: "text",
3111
+ "aria-label": owner.label,
3112
+ placeholder: missing ? t("empty") : "",
3113
+ value: text,
3114
+ onBlur: () => {
3115
+ if (!missing) onEdit(void 0);
3116
+ },
3117
+ onChange: (event) => {
3118
+ owner.onEditText(event.target.value);
3119
+ },
3120
+ onKeyDown: (event) => {
3121
+ if (event.key === "Enter" && !missing) onEdit(void 0);
3122
+ if (event.key === "Escape") {
3123
+ face.revert(line.path);
3124
+ onEdit(void 0);
3125
+ }
3126
+ }
3127
+ }) }) : null,
3128
+ isEditing || line.variantsStandIn ? null : /* @__PURE__ */ jsx(ValueSlot, {
3129
+ "data-role": "value",
3130
+ onClick: () => {
3131
+ if (editable) onEdit(key);
3132
+ },
3133
+ children: renderField(owner)
3134
+ }),
3135
+ /* @__PURE__ */ jsx(VariantSelect, {
3136
+ control: line.variants,
3137
+ path: line.path,
3138
+ face,
3139
+ disabled,
3140
+ t
3141
+ }),
3142
+ isEditing ? /* @__PURE__ */ jsxs(HoverActions, {
3143
+ "data-role": "actions",
3144
+ "data-editing": "true",
3145
+ children: [/* @__PURE__ */ jsx("button", {
3146
+ type: "button",
3147
+ "aria-label": t("confirmEdit"),
3148
+ title: t("confirmEdit"),
3149
+ onClick: () => {
3150
+ onEdit(void 0);
3151
+ },
3152
+ children: /* @__PURE__ */ jsx(IconCheckOutlineRegular, { size: 14 })
3153
+ }), /* @__PURE__ */ jsx("button", {
3154
+ type: "button",
3155
+ "aria-label": t("cancelEdit"),
3156
+ title: t("cancelEdit"),
3157
+ onClick: () => {
3158
+ face.revert(line.path);
3159
+ onEdit(void 0);
3160
+ onDismiss(key);
3161
+ },
3162
+ children: /* @__PURE__ */ jsx(IconCloseOutlineRegular, { size: 14 })
3163
+ })]
3164
+ }) : null,
3165
+ /* @__PURE__ */ jsxs(HoverActions, {
3166
+ "data-role": "actions",
3167
+ children: [
3168
+ line.field.staged && !disabled ? /* @__PURE__ */ jsx("button", {
3169
+ type: "button",
3170
+ "aria-label": t("revert"),
3171
+ title: t("revert"),
3172
+ onClick: () => {
3173
+ face.revert(line.path);
3174
+ },
3175
+ children: /* @__PURE__ */ jsx(IconRefreshOutlineRegular, { size: 14 })
3176
+ }) : null,
3177
+ line.field.overridden && !line.field.staged && !disabled ? /* @__PURE__ */ jsx("button", {
3178
+ type: "button",
3179
+ "aria-label": t("reset"),
3180
+ title: t("reset"),
3181
+ onClick: () => {
3182
+ face.clear(line.path);
3183
+ },
3184
+ children: /* @__PURE__ */ jsx(IconRefreshOutlineRegular, { size: 14 })
3185
+ }) : null,
3186
+ /* @__PURE__ */ jsx("button", {
3187
+ type: "button",
3188
+ "aria-label": t("copyValue"),
3189
+ title: t("copyValue"),
3190
+ onClick: () => {
3191
+ navigator.clipboard?.writeText(line.field.text ?? tokenFor(line.field.value)).catch(() => {});
3192
+ },
3193
+ children: /* @__PURE__ */ jsx(IconCopyOutlineRegular, { size: 14 })
3194
+ }),
3195
+ member === void 0 ? null : /* @__PURE__ */ jsx(RemoveLineButton, {
3196
+ member,
3197
+ face,
3198
+ t,
3199
+ disabled
3200
+ })
3201
+ ]
3202
+ })
3203
+ ] });
3204
+ }
3205
+ function tokenFor(value) {
3206
+ return typeof value === "string" ? JSON.stringify(value) : JSON.stringify(value ?? null);
3207
+ }
3208
+ function VariantSelect({ control, path, face, disabled, t }) {
3209
+ const [open, setOpen] = useState(false);
3210
+ if (control === void 0) return null;
3211
+ const current = control.choices[control.selected];
3212
+ return /* @__PURE__ */ jsx(Menu, {
3213
+ open,
3214
+ dense: true,
3215
+ compact: true,
3216
+ portal: true,
3217
+ align: "start",
3218
+ items: control.choices.map((choice, index) => ({
3219
+ id: String(index),
3220
+ label: choice.label
3221
+ })),
3222
+ selectedId: String(control.selected),
3223
+ onSelect: (id) => {
3224
+ setOpen(false);
3225
+ const choice = control.choices[Number(id)];
3226
+ if (choice !== void 0) face.set(path, choice.value);
3227
+ },
3228
+ onClose: () => {
3229
+ setOpen(false);
3230
+ },
3231
+ anchor: /* @__PURE__ */ jsxs(ValueTrigger, {
3232
+ type: "button",
3233
+ "data-role": "variant",
3234
+ disabled,
3235
+ "aria-label": t("switchVariant"),
3236
+ onClick: () => {
3237
+ setOpen(true);
3238
+ },
3239
+ children: [/* @__PURE__ */ jsx(LineValue, {
3240
+ "data-tone": "empty",
3241
+ children: current?.label ?? ""
3242
+ }), /* @__PURE__ */ jsx(IconChevronDownOutlineRegular, { size: 14 })]
3243
+ })
3244
+ });
3245
+ }
3246
+ function LinePrefix({ line, face, t, disabled }) {
3247
+ const member = line.member;
3248
+ const key = member?.key ?? line.node.key;
3249
+ if (key === "") return null;
3250
+ const indexed = member !== void 0 && member.index !== void 0;
3251
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
3252
+ /* @__PURE__ */ jsx(LineKey, {
3253
+ "data-role": "key",
3254
+ "data-index": indexed ? "true" : void 0,
3255
+ title: key,
3256
+ children: key
3257
+ }),
3258
+ /* @__PURE__ */ jsx(LineToken, { children: indexed ? " " : ": " }),
3259
+ member === void 0 ? null : /* @__PURE__ */ jsx(HoverActions, {
3260
+ "data-role": "actions",
3261
+ children: /* @__PURE__ */ jsx(RemoveLineButton, {
3262
+ member,
3263
+ face,
3264
+ t,
3265
+ disabled
3266
+ })
3267
+ })
3268
+ ] });
3269
+ }
3270
+ function RemoveLineButton({ member, face, t, disabled }) {
3271
+ return /* @__PURE__ */ jsx("button", {
3272
+ type: "button",
3273
+ "aria-label": t("removeItem"),
3274
+ title: t("removeItem"),
3275
+ disabled,
3276
+ onClick: () => {
3277
+ if (member.index === void 0) face.removeKey(member.parent, member.key);
3278
+ else face.removeItem(member.parent, member.index);
3279
+ },
3280
+ children: /* @__PURE__ */ jsx(IconTrashOutlineRegular, { size: 14 })
3281
+ });
3282
+ }
3283
+ function AddLine({ line, state, face, t, resolveText, disabled, onAdded }) {
3284
+ const spec = line.add;
3285
+ const [text, setText] = useState("");
3286
+ const [open, setOpen] = useState(false);
3287
+ const [invalid, setInvalid] = useState(false);
3288
+ if (spec === void 0 || disabled) return null;
3289
+ const options = spec.kind === "item" ? [] : spec.options;
3290
+ const query = text.trim().toLowerCase();
3291
+ const matched = options.filter((option) => query === "" || option.key.toLowerCase().includes(query));
3292
+ const label = spec.kind === "item" ? t("addItemPaste") : spec.kind === "key" ? t("addKey") : t("addProperty");
3293
+ const commit = (picked) => {
3294
+ const raw = (picked ?? text).trim();
3295
+ if (raw === "") return;
3296
+ setInvalid(false);
3297
+ if (raw.startsWith("{") || raw.startsWith("[")) try {
3298
+ face.set(line.path, JSON.parse(raw));
3299
+ setText("");
3300
+ setOpen(false);
3301
+ return;
3302
+ } catch {}
3303
+ if (spec.kind === "key") {
3304
+ face.addKey(line.path, raw);
3305
+ onAdded([...line.path, raw]);
3306
+ } else if (spec.kind === "item") {
3307
+ const current = state.fields.get(fieldKey(line.path))?.value;
3308
+ const index = Array.isArray(current) ? current.length : 0;
3309
+ face.appendItem(line.path);
3310
+ onAdded([...line.path, String(index)]);
3311
+ } else {
3312
+ if (!spec.options.some((option) => option.key === raw)) {
3313
+ setInvalid(true);
3314
+ return;
3315
+ }
3316
+ face.addKey(line.path, raw);
3317
+ onAdded([...line.path, raw]);
3318
+ }
3319
+ setText("");
3320
+ setOpen(false);
3321
+ };
3322
+ return /* @__PURE__ */ jsxs(AddWrap, {
3323
+ "data-add": spec.kind,
3324
+ "data-invalid": invalid ? "true" : void 0,
3325
+ children: [
3326
+ /* @__PURE__ */ jsx(Menu, {
3327
+ open: open && spec.kind !== "item" && matched.length > 0,
3328
+ dense: true,
3329
+ compact: true,
3330
+ portal: true,
3331
+ align: "start",
3332
+ items: matched.map((option) => ({
3333
+ id: option.key,
3334
+ label: option.key
3335
+ })),
3336
+ onSelect: (key) => {
3337
+ commit(key);
3338
+ },
3339
+ onClose: () => {
3340
+ setOpen(false);
3341
+ },
3342
+ anchor: /* @__PURE__ */ jsx(CompactInput, { children: /* @__PURE__ */ jsx(Input, {
3343
+ value: text,
3344
+ placeholder: label,
3345
+ "aria-label": label,
3346
+ disabled,
3347
+ onFocus: () => {
3348
+ setOpen(true);
3349
+ },
3350
+ onChange: (event) => {
3351
+ setText(event.target.value);
3352
+ setInvalid(false);
3353
+ setOpen(true);
3354
+ },
3355
+ onKeyDown: (event) => {
3356
+ if (event.key === "Enter") {
3357
+ event.preventDefault();
3358
+ commit(matched.length === 1 && spec.kind === "prop" ? matched[0]?.key : void 0);
3359
+ }
3360
+ if (event.key === "Escape") {
3361
+ setText("");
3362
+ setOpen(false);
3363
+ }
3364
+ }
3365
+ }) })
3366
+ }),
3367
+ invalid ? /* @__PURE__ */ jsx(LineInvalid, { children: t("unknownProperty") }) : null,
3368
+ !invalid && matched.length === 1 && matched[0]?.description !== void 0 ? /* @__PURE__ */ jsx(TruncatedTooltip, {
3369
+ label: resolveText(matched[0].description),
3370
+ children: /* @__PURE__ */ jsx(LineComment, { children: resolveText(matched[0].description) })
3371
+ }) : null
3372
+ ]
3373
+ });
3374
+ }
3375
+ //#endregion
3376
+ //#region src/client/schema-form/SchemaForm.tsx
3377
+ function SchemaForm(props) {
3378
+ const { ns, face, t, resolveText, renderSlotChain } = props;
3379
+ const store = face.hooks.schemaForm;
3380
+ const state = useSyncExternalStore((listener) => store.subscribe(listener), () => store.getSnapshot());
3381
+ const labels = {
3382
+ unavailable: t("unavailable"),
3383
+ readOnly: t("readOnly"),
3384
+ saveFailed: t("saveFailed"),
3385
+ save: t("save"),
3386
+ saving: t("saving")
3387
+ };
3388
+ if (!state.configured) return /* @__PURE__ */ jsx(Hint$1, {
3389
+ role: "status",
3390
+ children: t("noSchema")
3391
+ });
3392
+ return /* @__PURE__ */ jsxs(SettingsForm$1, {
3393
+ labels,
3394
+ state,
3395
+ onSave: () => {
3396
+ face.save();
3397
+ },
3398
+ onDiscard: () => {
3399
+ face.discard();
3400
+ },
3401
+ children: [/* @__PURE__ */ jsx(Editor, {
3402
+ ns,
3403
+ state,
3404
+ face,
3405
+ t,
3406
+ resolveText,
3407
+ renderField: (owner) => renderSlotChain("settings.schema-form.field", owner, { fallback: /* @__PURE__ */ jsx(SchemaFieldDefault, { owner: {
3408
+ ...owner,
3409
+ onEditText: withParse(owner, t)
3410
+ } }) })
3411
+ }), state.violation === void 0 ? null : /* @__PURE__ */ jsx(Hint$1, {
3412
+ role: "alert",
3413
+ "data-violation": "true",
3414
+ children: t("notSaved", { message: state.violation.message })
3415
+ })]
3416
+ });
3417
+ }
3418
+ function withParse(owner, t) {
3419
+ return (text, parse) => {
3420
+ owner.onEditText(text, parse ?? parseFor(owner.node, t));
3421
+ };
3422
+ }
3423
+ //#endregion
3424
+ //#region src/client/schema-form/index.ts
3425
+ var schema_form_exports = /* @__PURE__ */ __exportAll({
3426
+ InlineValue: () => InlineValue,
3427
+ NS: () => NS,
3428
+ SchemaFieldDefault: () => SchemaFieldDefault,
3429
+ SchemaFormController: () => SchemaFormController,
3430
+ SchemaFormHints: () => SchemaFormHints,
3431
+ apply: () => apply$1,
3432
+ canRender: () => canRender,
3433
+ containerShape: () => containerShape,
3434
+ editorLines: () => editorLines,
3435
+ failureOf: () => failureOf,
3436
+ inject: () => inject$1,
3437
+ optionsFor: () => optionsFor,
3438
+ parseFor: () => parseFor,
3439
+ projectNode: () => projectNode,
3440
+ projectRoot: () => projectRoot,
3441
+ rowRegistrations: () => rowRegistrations,
3442
+ tokenText: () => tokenText,
3443
+ tokenTone: () => tokenTone,
3444
+ valueText: () => valueText,
3445
+ visibleFields: () => visibleFields,
3446
+ walkFields: () => walkFields
3447
+ });
3448
+ const NS = "settings.schema-form";
3449
+ const inject$1 = [
3450
+ "slots",
3451
+ "locale",
3452
+ "configForms",
3453
+ "settingsSchema",
3454
+ "remote",
3455
+ "remote.pluginManager"
3456
+ ];
3457
+ function apply$1(ctx) {
3458
+ ctx.inject([...inject$1], (scope) => {
3459
+ if (scope.get("schemaFormHints") !== void 0) return;
3460
+ install(scope);
3461
+ });
3462
+ }
3463
+ function install(ctx) {
3464
+ ctx.effect(() => ctx.locale.register(NS, {
3465
+ zh,
3466
+ en
3467
+ }), "ui-schema-form: dictionaries");
3468
+ const hints = new SchemaFormHints(ctx);
3469
+ ctx.effect(() => ctx.slots.registerFactory({
3470
+ name: "settings.schema-form.form",
3471
+ scope: "root",
3472
+ children: { "settings.schema-form.field": {
3473
+ kind: "chain",
3474
+ scope: "root"
3475
+ } },
3476
+ locale: NS
3477
+ }, SchemaForm), "ui-schema-form: form factory");
3478
+ const rehydrate = (serialized) => ctx.settingsSchema.rehydrate(serialized);
3479
+ const validate = (schema, value) => {
3480
+ try {
3481
+ schema(value);
3482
+ return;
3483
+ } catch (error) {
3484
+ return failureOf(error);
3485
+ }
3486
+ };
3487
+ const resolveText = (text) => typeof text === "string" ? text : ctx.locale.resolveText(text);
3488
+ const entries = /* @__PURE__ */ new Map();
3489
+ const entryFor = (ns) => {
3490
+ const describe = ctx.configForms.describe();
3491
+ const view = describe.getSnapshot().view?.namespaces.find((row) => row.ns === ns);
3492
+ if (!canRender(view, rehydrate)) return void 0;
3493
+ const existing = entries.get(ns);
3494
+ if (existing !== void 0) return existing;
3495
+ const controller = new SchemaFormController(ns, {
3496
+ form: ctx.configForms.get(ns),
3497
+ describe,
3498
+ rehydrate,
3499
+ validate,
3500
+ t: ctx.locale.bind(NS),
3501
+ hints: {
3502
+ keysFor: (path) => hints.keysFor(ns, path),
3503
+ textFor: (path) => hints.textFor(ns, path),
3504
+ selectFor: (path) => hints.selectFor(ns, path),
3505
+ sourceFor: (name) => hints.sourceFor(name)
3506
+ }
3507
+ });
3508
+ const face = controller.face();
3509
+ const props = {
3510
+ ns,
3511
+ face,
3512
+ resolveText
3513
+ };
3514
+ const component = (entryProps) => entryProps.view === "page" ? entryProps.renderFactorySlot("settings.schema-form.form", props) : null;
3515
+ const entry = {
3516
+ controller,
3517
+ face,
3518
+ component
3519
+ };
3520
+ entries.set(ns, entry);
3521
+ return entry;
3522
+ };
3523
+ const registration = new RowRegistration({
3524
+ slots: ctx.slots,
3525
+ describe: ctx.configForms.describe(),
3526
+ bundles: async () => {
3527
+ const response = await ctx.remote.pluginManager.listBundles();
3528
+ return response.ok ? response.value : [];
3529
+ },
3530
+ subscribeBundles: (listener) => ctx.remote.$on("plugin-manager/changed", listener),
3531
+ entryFor,
3532
+ locale: NS,
3533
+ release: (ns) => {
3534
+ const entry = entries.get(ns);
3535
+ entries.delete(ns);
3536
+ entry?.controller.dispose();
3537
+ }
3538
+ });
3539
+ ctx.effect(() => {
3540
+ const offDescribe = ctx.configForms.describe().subscribe(() => {
3541
+ registration.sync();
3542
+ });
3543
+ const offHints = hints.subscribe(() => {
3544
+ for (const entry of entries.values()) entry.controller.refresh();
3545
+ });
3546
+ registration.sync();
3547
+ return () => {
3548
+ offDescribe();
3549
+ offHints();
3550
+ registration.dispose();
3551
+ for (const [ns, entry] of entries) {
3552
+ entries.delete(ns);
3553
+ entry.controller.dispose();
3554
+ }
3555
+ };
3556
+ }, "ui-schema-form: row registrations");
3557
+ }
3558
+ //#endregion
3559
+ //#region src/client/markdown-labels.ts
3560
+ function markdownLabels(t) {
3561
+ return {
3562
+ code: {
3563
+ copyLabel: t("copy"),
3564
+ copiedLabel: t("copied")
3565
+ },
3566
+ footnotes: t("markdown.footnotes")
3567
+ };
3568
+ }
3569
+ //#endregion
3570
+ //#region src/client/settings-form/form-model.ts
3571
+ function settingsNumberField(field) {
3572
+ return {
3573
+ field,
3574
+ format: (value) => typeof value === "number" ? String(value) : "",
3575
+ parse: (text) => {
3576
+ const trimmed = text.trim();
3577
+ if (trimmed === "") return { kind: "clear" };
3578
+ const parsed = Number(trimmed);
3579
+ return Number.isFinite(parsed) ? {
3580
+ kind: "set",
3581
+ value: parsed
3582
+ } : void 0;
3583
+ }
3584
+ };
3585
+ }
3586
+ function settingsTextField(field) {
3587
+ return {
3588
+ field,
3589
+ format: (value) => typeof value === "string" ? value : "",
3590
+ parse: (text) => {
3591
+ const trimmed = text.trim();
3592
+ return trimmed === "" ? { kind: "clear" } : {
3593
+ kind: "set",
3594
+ value: trimmed
3595
+ };
3596
+ }
3597
+ };
3598
+ }
3599
+ var SettingsFormModel = class {
3600
+ scope;
3601
+ specs;
3602
+ secretSpecs;
3603
+ staged = /* @__PURE__ */ new Map();
3604
+ listeners = /* @__PURE__ */ new Set();
3605
+ baseline;
3606
+ unsubscribe;
3607
+ saving = false;
3608
+ failed = false;
3609
+ constructor(scope, specs, secrets = []) {
3610
+ this.scope = scope;
3611
+ this.specs = new Map(specs.map((spec) => [spec.field, spec]));
3612
+ this.secretSpecs = new Map(secrets.map((spec) => [spec.field, spec]));
3613
+ this.unsubscribe = scope.subscribe(() => {
3614
+ this.publish();
3615
+ });
3616
+ }
3617
+ bind(project) {
3618
+ const store = createSnapshotStore(project());
3619
+ this.listeners.add(() => {
3620
+ store.set(project());
3621
+ });
3622
+ return store;
3623
+ }
3624
+ shell() {
3625
+ const snapshot = this.scope.getSnapshot();
3626
+ const plan = this.plan();
3627
+ return {
3628
+ available: snapshot.status === "ready",
3629
+ writable: snapshot.writable,
3630
+ dirty: plan.length > 0,
3631
+ invalid: plan.some((item) => item.run === void 0 && item.op === void 0),
3632
+ saving: this.saving,
3633
+ failed: this.failed
3634
+ };
3635
+ }
3636
+ field(field) {
3637
+ const staged = this.staged.get(field);
3638
+ if (this.secretSpecs.has(field)) return {
3639
+ text: staged?.text ?? "",
3640
+ overridden: false,
3641
+ invalid: false
3642
+ };
3643
+ const spec = this.spec(field);
3644
+ if (staged === void 0) return {
3645
+ text: spec.format(this.sectionValue(field)),
3646
+ overridden: this.stored(field),
3647
+ invalid: false
3648
+ };
3649
+ const write = staged.clear ? { kind: "clear" } : spec.parse(staged.text);
3650
+ return {
3651
+ text: staged.text,
3652
+ overridden: write?.kind === "set",
3653
+ invalid: write === void 0
3654
+ };
3655
+ }
3656
+ actions() {
3657
+ return {
3658
+ edit: (field, text) => {
3659
+ this.stage(field, {
3660
+ text,
3661
+ clear: false
3662
+ });
3663
+ },
3664
+ resetField: (field) => {
3665
+ this.stage(field, {
3666
+ text: this.spec(field).format(this.baseValue(field)),
3667
+ clear: true
3668
+ });
3669
+ },
3670
+ save: () => {
3671
+ this.save();
3672
+ },
3673
+ discard: () => {
3674
+ if (this.staged.size === 0 && !this.failed) return;
3675
+ this.staged.clear();
3676
+ this.baseline = void 0;
3677
+ this.failed = false;
3678
+ this.publish();
3679
+ }
3680
+ };
3681
+ }
3682
+ async save() {
3683
+ const plan = this.plan();
3684
+ if (!plan.length || this.saving || !this.scope.getSnapshot().writable || plan.some((item) => item.run === void 0 && item.op === void 0)) return;
3685
+ this.saving = true;
3686
+ this.failed = false;
3687
+ this.publish();
3688
+ try {
3689
+ const ops = plan.flatMap((item) => item.op === void 0 ? [] : [item.op]);
3690
+ let landed = !ops.length || await this.scope.mutate(ops, this.baseline?.revision);
3691
+ if (!landed) {
3692
+ this.failed = true;
3693
+ return;
3694
+ }
3695
+ for (const item of plan) if (item.run) landed = await item.run() && landed;
3696
+ if (landed) {
3697
+ this.staged.clear();
3698
+ this.baseline = void 0;
3699
+ }
3700
+ this.failed = !landed;
3701
+ } catch {
3702
+ this.failed = true;
3703
+ } finally {
3704
+ this.saving = false;
3705
+ this.publish();
3706
+ }
3707
+ }
3708
+ dispose() {
3709
+ this.unsubscribe();
3710
+ this.listeners.clear();
3711
+ }
3712
+ plan() {
3713
+ const plan = [];
3714
+ for (const [field, staged] of this.staged) {
3715
+ const secret = this.secretSpecs.get(field);
3716
+ if (secret !== void 0) {
3717
+ const value = staged.text.trim();
3718
+ if (value !== "") plan.push({
3719
+ field,
3720
+ run: () => secret.write(value)
3721
+ });
3722
+ continue;
3723
+ }
3724
+ const spec = this.spec(field);
3725
+ if (staged.clear) {
3726
+ if (this.stored(field)) plan.push({
3727
+ field,
3728
+ op: {
3729
+ op: "unset",
3730
+ path: [field]
3731
+ }
3732
+ });
3733
+ continue;
3734
+ }
3735
+ if (staged.text === spec.format(this.sectionValue(field))) continue;
3736
+ const write = spec.parse(staged.text);
3737
+ if (write === void 0) plan.push({ field });
3738
+ else if (write.kind === "clear") plan.push({
3739
+ field,
3740
+ op: {
3741
+ op: "unset",
3742
+ path: [field]
3743
+ }
3744
+ });
3745
+ else plan.push({
3746
+ field,
3747
+ op: {
3748
+ op: "set",
3749
+ path: [field],
3750
+ value: write.value
3751
+ }
3752
+ });
3753
+ }
3754
+ return plan;
3755
+ }
3756
+ stage(field, edit) {
3757
+ this.baseline ??= this.scope.getSnapshot();
3758
+ this.staged.set(field, edit);
3759
+ this.failed = false;
3760
+ this.publish();
3761
+ }
3762
+ spec(field) {
3763
+ const spec = this.specs.get(field);
3764
+ if (spec === void 0) throw new Error(`plugin card has no field ${field}`);
3765
+ return spec;
3766
+ }
3767
+ snapshotOf() {
3768
+ return this.scope.getSnapshot();
3769
+ }
3770
+ sectionValue(field) {
3771
+ return this.snapshotOf().value?.[field];
3772
+ }
3773
+ baseValue(field) {
3774
+ return this.snapshotOf().base?.[field];
3775
+ }
3776
+ userLayer() {
3777
+ return this.snapshotOf().user;
3778
+ }
3779
+ stored(field) {
3780
+ const user = this.userLayer();
3781
+ return user !== void 0 && Object.hasOwn(user, field);
3782
+ }
3783
+ publish() {
3784
+ for (const listener of this.listeners) listener();
3785
+ }
3786
+ };
3787
+ //#endregion
3788
+ //#region src/client/styling/focus.ts
3789
+ const focusRing = `${String(dsw.focus.ring.width)} solid ${Token.collect(Token.fallbackVar(dsw.focus.ring.color, String(dsw.alias.state.business.primary)))}`;
3790
+ //#endregion
3791
+ //#region src/client/settings-form/fields.styles.ts
3792
+ const helpButtonHoverBackground = "var(--dsw-alias-bg-layer-4)";
3793
+ const styles$1 = {
3794
+ field: {
3795
+ display: "flex",
3796
+ flexDirection: "column",
3797
+ gap: "6px",
3798
+ padding: "12px 0",
3799
+ "& + &": { borderTop: `0.5px solid ${String(dsw.alias.border.l2)}` }
3800
+ },
3801
+ head: {
3802
+ display: "flex",
3803
+ alignItems: "center",
3804
+ gap: "8px"
3805
+ },
3806
+ label: {
3807
+ flex: 1,
3808
+ minWidth: 0,
3809
+ fontSize: "13px",
3810
+ fontWeight: 500,
3811
+ lineHeight: 1.5,
3812
+ color: dsw.alias.label.primary
3813
+ },
3814
+ groupLabel: { flex: "0 1 auto" },
3815
+ labelGroup: {
3816
+ display: "flex",
3817
+ alignItems: "center",
3818
+ gap: "4px",
3819
+ flex: 1,
3820
+ minWidth: 0
3821
+ },
3822
+ helpButton: {
3823
+ display: "inline-flex",
3824
+ alignItems: "center",
3825
+ justifyContent: "center",
3826
+ flex: "none",
3827
+ width: "24px",
3828
+ height: "24px",
3829
+ padding: 0,
3830
+ border: 0,
3831
+ borderRadius: "6px",
3832
+ background: "none",
3833
+ color: dsw.alias.label.tertiary,
3834
+ cursor: "pointer",
3835
+ "&:hover": {
3836
+ background: helpButtonHoverBackground,
3837
+ color: dsw.alias.label.secondary
3838
+ },
3839
+ "&[aria-expanded='true']": {
3840
+ background: helpButtonHoverBackground,
3841
+ color: dsw.alias.label.secondary
3842
+ },
3843
+ "&:focus-visible": {
3844
+ outline: focusRing,
3845
+ outlineOffset: "1px"
3846
+ }
3847
+ },
3848
+ help: {
3849
+ padding: "10px 0 0",
3850
+ fontSize: "12px",
3851
+ lineHeight: 1.6,
3852
+ color: dsw.alias.label.secondary,
3853
+ "& > p": { margin: 0 },
3854
+ "& > p + p": { marginTop: "8px" }
3855
+ },
3856
+ badges: {
3857
+ display: "inline-flex",
3858
+ alignItems: "center",
3859
+ gap: "8px"
3860
+ },
3861
+ badge: {
3862
+ display: "inline-flex",
3863
+ alignItems: "center",
3864
+ borderRadius: "999px",
3865
+ cornerShape: "round",
3866
+ padding: "1px 8px",
3867
+ fontSize: "11px",
3868
+ lineHeight: "17px",
3869
+ fontWeight: 500,
3870
+ whiteSpace: "nowrap"
3871
+ },
3872
+ badgeNeutral: {
3873
+ background: dsw.alias.bg.module.platform,
3874
+ color: dsw.alias.label.secondary
3875
+ },
3876
+ badgeQuiet: { color: dsw.alias.label.tertiary },
3877
+ reset: {
3878
+ border: "none",
3879
+ background: "none",
3880
+ padding: 0,
3881
+ font: "inherit",
3882
+ fontSize: "12px",
3883
+ lineHeight: 1.5,
3884
+ color: dsw.alias.label.secondary,
3885
+ cursor: "pointer",
3886
+ "&:hover:not(:disabled)": { color: dsw.alias.label.primary },
3887
+ "&:disabled": { cursor: "default" }
3888
+ },
3889
+ input: {
3890
+ height: "34px",
3891
+ padding: "0 12px",
3892
+ border: `0.5px solid ${String(dsw.alias.border.l4)}`,
3893
+ borderRadius: "8px",
3894
+ background: dsw.alias.bg.layer["3"],
3895
+ font: "inherit",
3896
+ fontSize: "13px",
3897
+ lineHeight: 1.5,
3898
+ color: dsw.alias.label.primary,
3899
+ "&:focus-visible": {
3900
+ outline: "none",
3901
+ borderColor: dsw.alias.state.business.primary
3902
+ },
3903
+ "&:disabled": {
3904
+ color: dsw.alias.label.tertiary,
3905
+ cursor: "default"
3906
+ },
3907
+ "&[aria-invalid='true']": { borderColor: dsw.alias.state.error.primary }
3908
+ },
3909
+ invalid: {
3910
+ margin: 0,
3911
+ fontSize: "12px",
3912
+ lineHeight: 1.5,
3913
+ color: dsw.alias.state.error.primary
3914
+ },
3915
+ hint: {
3916
+ margin: 0,
3917
+ fontSize: "12px",
3918
+ lineHeight: 1.5,
3919
+ color: dsw.alias.label.tertiary
3920
+ }
3921
+ };
3922
+ //#endregion
3923
+ //#region src/client/settings-form/fields.tsx
3924
+ const Field = styled("div")(styles$1.field);
3925
+ const Head = styled("div")(styles$1.head);
3926
+ const LabelGroup = styled("div")(styles$1.labelGroup);
3927
+ const GroupLabel = styled("label")(styles$1.label, styles$1.groupLabel);
3928
+ const HeadLabel = styled("label")(styles$1.label);
3929
+ const HelpButton = styled("button")(styles$1.helpButton);
3930
+ const Help = styled("div")(styles$1.help);
3931
+ const Badges = styled("span")(styles$1.badges);
3932
+ const NeutralBadge = styled("span")(styles$1.badge, styles$1.badgeNeutral);
3933
+ const QuietBadge = styled("span")(styles$1.badge, styles$1.badgeQuiet);
3934
+ const Reset = styled("button")(styles$1.reset);
3935
+ const Input$1 = styled("input")(styles$1.input);
3936
+ const Invalid = styled("p")(styles$1.invalid);
3937
+ const Hint = styled("p")(styles$1.hint);
3938
+ function InfoGlyph({ size }) {
3939
+ return /* @__PURE__ */ jsxs("svg", {
3940
+ width: size,
3941
+ height: size,
3942
+ viewBox: "0 0 14 14",
3943
+ fill: "none",
3944
+ xmlns: "http://www.w3.org/2000/svg",
3945
+ "aria-hidden": "true",
3946
+ children: [
3947
+ /* @__PURE__ */ jsx("path", {
3948
+ d: "M12.5757 7.00012C12.5757 3.92085 10.0794 1.42463 7.00012 1.42456C3.9208 1.42456 1.42456 3.9208 1.42456 7.00012C1.42463 10.0794 3.92085 12.5757 7.00012 12.5757C10.0793 12.5756 12.5756 10.0793 12.5757 7.00012ZM13.8002 7.00012C13.8001 10.7559 10.7559 13.8001 7.00012 13.8002C3.2443 13.8002 0.199291 10.7559 0.199219 7.00012C0.199219 3.24426 3.24426 0.199219 7.00012 0.199219C10.7559 0.199291 13.8002 3.2443 13.8002 7.00012Z",
3949
+ fill: "currentColor"
3950
+ }),
3951
+ /* @__PURE__ */ jsx("path", {
3952
+ d: "M7.6127 3.18921V4.55986H6.38735V3.18921H7.6127Z",
3953
+ fill: "currentColor"
3954
+ }),
3955
+ /* @__PURE__ */ jsx("path", {
3956
+ d: "M7.6127 5.68921V10.8109H6.38735V5.68921H7.6127Z",
3957
+ fill: "currentColor"
3958
+ })
3959
+ ]
3960
+ });
3961
+ }
3962
+ function SettingsValueField(props) {
3963
+ const [helpOpen, setHelpOpen] = useState(false);
3964
+ const helpId = `${props.id}-help`;
3965
+ const messageId = `${props.id}-message`;
3966
+ const hasMessage = props.invalid || Boolean(props.hint);
3967
+ const description = [hasMessage ? messageId : "", helpOpen ? helpId : ""].filter(Boolean).join(" ");
3968
+ return /* @__PURE__ */ jsxs(Field, { children: [
3969
+ /* @__PURE__ */ jsxs(Head, { children: [/* @__PURE__ */ jsxs(LabelGroup, { children: [/* @__PURE__ */ jsx(GroupLabel, {
3970
+ htmlFor: props.id,
3971
+ children: props.label
3972
+ }), props.help !== void 0 ? /* @__PURE__ */ jsx(HelpButton, {
3973
+ type: "button",
3974
+ "aria-label": props.help.label,
3975
+ "aria-expanded": helpOpen,
3976
+ "aria-controls": helpId,
3977
+ onClick: () => {
3978
+ setHelpOpen(!helpOpen);
3979
+ },
3980
+ children: /* @__PURE__ */ jsx(InfoGlyph, { size: 12 })
3981
+ }) : null] }), props.overridden ? /* @__PURE__ */ jsxs(Badges, { children: [/* @__PURE__ */ jsx(NeutralBadge, { children: props.overriddenLabel }), /* @__PURE__ */ jsx(Reset, {
3982
+ type: "button",
3983
+ disabled: props.disabled,
3984
+ onClick: props.onReset,
3985
+ children: props.resetLabel
3986
+ })] }) : null] }),
3987
+ /* @__PURE__ */ jsx(Input$1, {
3988
+ id: props.id,
3989
+ type: "text",
3990
+ ...props.numeric === true ? { inputMode: "numeric" } : {},
3991
+ ...props.invalid ? { "aria-invalid": true } : {},
3992
+ "aria-describedby": description || void 0,
3993
+ value: props.text,
3994
+ placeholder: props.placeholder ?? "",
3995
+ disabled: props.disabled,
3996
+ onChange: (event) => {
3997
+ props.onEdit(event.target.value);
3998
+ }
3999
+ }),
4000
+ hasMessage ? props.invalid ? /* @__PURE__ */ jsx(Invalid, {
4001
+ id: messageId,
4002
+ children: props.invalidLabel
4003
+ }) : /* @__PURE__ */ jsx(Hint, {
4004
+ id: messageId,
4005
+ children: props.hint
4006
+ }) : null,
4007
+ props.help !== void 0 && helpOpen ? /* @__PURE__ */ jsx(Help, {
4008
+ id: helpId,
4009
+ role: "region",
4010
+ "aria-label": props.help.label,
4011
+ children: props.help.content
4012
+ }) : null
4013
+ ] });
4014
+ }
4015
+ function SettingsSecretField(props) {
4016
+ const Badge = props.configured ? NeutralBadge : QuietBadge;
4017
+ return /* @__PURE__ */ jsxs(Field, { children: [
4018
+ /* @__PURE__ */ jsxs(Head, { children: [/* @__PURE__ */ jsx(HeadLabel, {
4019
+ htmlFor: props.id,
4020
+ children: props.label
4021
+ }), /* @__PURE__ */ jsx(Badges, { children: /* @__PURE__ */ jsx(Badge, { children: props.stateLabel }) })] }),
4022
+ /* @__PURE__ */ jsx(Input$1, {
4023
+ id: props.id,
4024
+ type: "password",
4025
+ autoComplete: "new-password",
4026
+ value: props.text,
4027
+ disabled: props.disabled,
4028
+ onChange: (event) => {
4029
+ props.onEdit(event.target.value);
4030
+ }
4031
+ }),
4032
+ /* @__PURE__ */ jsx(Hint, { children: props.hint })
4033
+ ] });
4034
+ }
4035
+ const styles = {
4036
+ form: {
4037
+ display: "flex",
4038
+ flexDirection: "column"
4039
+ },
4040
+ notice: {
4041
+ margin: "0 0 12px",
4042
+ fontSize: "12px",
4043
+ lineHeight: 1.5,
4044
+ color: dsw.alias.label.tertiary
4045
+ },
4046
+ footer: {
4047
+ display: "flex",
4048
+ alignItems: "center",
4049
+ gap: "8px",
4050
+ paddingTop: "16px"
4051
+ },
4052
+ failed: {
4053
+ flex: 1,
4054
+ minWidth: 0,
4055
+ margin: 0,
4056
+ fontSize: "12px",
4057
+ lineHeight: 1.5,
4058
+ color: "var(--dsw-alias-label-error)"
4059
+ },
4060
+ save: {
4061
+ appearance: "none",
4062
+ border: "1px solid transparent",
4063
+ borderRadius: "8px",
4064
+ padding: "5px 14px",
4065
+ font: "inherit",
4066
+ fontSize: "13px",
4067
+ lineHeight: 1.5,
4068
+ cursor: "pointer",
4069
+ background: dsw.alias.label.primary,
4070
+ color: dsw.alias.bg.layer["3"],
4071
+ "&:disabled": {
4072
+ opacity: .4,
4073
+ cursor: "default"
4074
+ },
4075
+ "&:focus-visible": {
4076
+ outline: focusRing,
4077
+ outlineOffset: "1px"
4078
+ }
4079
+ }
4080
+ };
4081
+ //#endregion
4082
+ //#region src/client/settings-form/SettingsForm.tsx
4083
+ const Form = styled("div")(styles.form);
4084
+ const Notice = styled("p")(styles.notice);
4085
+ const Footer = styled("div")(styles.footer);
4086
+ const Failed = styled("p")(styles.failed);
4087
+ const Save = styled("button")(styles.save);
4088
+ function SettingsForm(props) {
4089
+ const { state, labels } = props;
4090
+ const discard = useRef(props.onDiscard);
4091
+ discard.current = props.onDiscard;
4092
+ useEffect(() => () => {
4093
+ discard.current();
4094
+ }, []);
4095
+ if (!state.available) return /* @__PURE__ */ jsx(Notice, {
4096
+ role: "status",
4097
+ children: labels.unavailable
4098
+ });
4099
+ const blocked = !state.dirty || state.invalid || state.saving;
4100
+ return /* @__PURE__ */ jsxs(Form, { children: [
4101
+ !state.writable ? /* @__PURE__ */ jsx(Notice, {
4102
+ role: "status",
4103
+ children: labels.readOnly
4104
+ }) : null,
4105
+ props.children,
4106
+ /* @__PURE__ */ jsxs(Footer, { children: [state.failed ? /* @__PURE__ */ jsx(Failed, {
4107
+ role: "status",
4108
+ children: labels.saveFailed
4109
+ }) : null, /* @__PURE__ */ jsx(Save, {
4110
+ type: "button",
4111
+ disabled: blocked,
4112
+ onClick: props.onSave,
4113
+ children: state.saving ? labels.saving : labels.save
4114
+ })] })
4115
+ ] });
4116
+ }
4117
+ //#endregion
4118
+ //#region ../../../node_modules/.pnpm/react@18.3.1/node_modules/react/cjs/react.production.min.js
4119
+ /**
4120
+ * @license React
4121
+ * react.production.min.js
4122
+ *
4123
+ * Copyright (c) Facebook, Inc. and its affiliates.
4124
+ *
4125
+ * This source code is licensed under the MIT license found in the
4126
+ * LICENSE file in the root directory of this source tree.
4127
+ */
4128
+ var require_react_production_min = /* @__PURE__ */ __commonJSMin(((exports) => {
4129
+ var l = Symbol.for("react.element");
4130
+ var n = Symbol.for("react.portal");
4131
+ var p = Symbol.for("react.fragment");
4132
+ var q = Symbol.for("react.strict_mode");
4133
+ var r = Symbol.for("react.profiler");
4134
+ var t = Symbol.for("react.provider");
4135
+ var u = Symbol.for("react.context");
4136
+ var v = Symbol.for("react.forward_ref");
4137
+ var w = Symbol.for("react.suspense");
4138
+ var x = Symbol.for("react.memo");
4139
+ var y = Symbol.for("react.lazy");
4140
+ var z = Symbol.iterator;
4141
+ function A(a) {
4142
+ if (null === a || "object" !== typeof a) return null;
4143
+ a = z && a[z] || a["@@iterator"];
4144
+ return "function" === typeof a ? a : null;
4145
+ }
4146
+ var B = {
4147
+ isMounted: function() {
4148
+ return !1;
4149
+ },
4150
+ enqueueForceUpdate: function() {},
4151
+ enqueueReplaceState: function() {},
4152
+ enqueueSetState: function() {}
4153
+ };
4154
+ var C = Object.assign;
4155
+ var D = {};
4156
+ function E(a, b, e) {
4157
+ this.props = a;
4158
+ this.context = b;
4159
+ this.refs = D;
4160
+ this.updater = e || B;
4161
+ }
4162
+ E.prototype.isReactComponent = {};
4163
+ E.prototype.setState = function(a, b) {
4164
+ if ("object" !== typeof a && "function" !== typeof a && null != a) throw Error("setState(...): takes an object of state variables to update or a function which returns an object of state variables.");
4165
+ this.updater.enqueueSetState(this, a, b, "setState");
4166
+ };
4167
+ E.prototype.forceUpdate = function(a) {
4168
+ this.updater.enqueueForceUpdate(this, a, "forceUpdate");
4169
+ };
4170
+ function F() {}
4171
+ F.prototype = E.prototype;
4172
+ function G(a, b, e) {
4173
+ this.props = a;
4174
+ this.context = b;
4175
+ this.refs = D;
4176
+ this.updater = e || B;
4177
+ }
4178
+ var H = G.prototype = new F();
4179
+ H.constructor = G;
4180
+ C(H, E.prototype);
4181
+ H.isPureReactComponent = !0;
4182
+ var I = Array.isArray;
4183
+ var J = Object.prototype.hasOwnProperty;
4184
+ var K = { current: null };
4185
+ var L = {
4186
+ key: !0,
4187
+ ref: !0,
4188
+ __self: !0,
4189
+ __source: !0
4190
+ };
4191
+ function M(a, b, e) {
4192
+ var d, c = {}, k = null, h = null;
4193
+ if (null != b) for (d in void 0 !== b.ref && (h = b.ref), void 0 !== b.key && (k = "" + b.key), b) J.call(b, d) && !L.hasOwnProperty(d) && (c[d] = b[d]);
4194
+ var g = arguments.length - 2;
4195
+ if (1 === g) c.children = e;
4196
+ else if (1 < g) {
4197
+ for (var f = Array(g), m = 0; m < g; m++) f[m] = arguments[m + 2];
4198
+ c.children = f;
4199
+ }
4200
+ if (a && a.defaultProps) for (d in g = a.defaultProps, g) void 0 === c[d] && (c[d] = g[d]);
4201
+ return {
4202
+ $$typeof: l,
4203
+ type: a,
4204
+ key: k,
4205
+ ref: h,
4206
+ props: c,
4207
+ _owner: K.current
4208
+ };
4209
+ }
4210
+ function N(a, b) {
4211
+ return {
4212
+ $$typeof: l,
4213
+ type: a.type,
4214
+ key: b,
4215
+ ref: a.ref,
4216
+ props: a.props,
4217
+ _owner: a._owner
4218
+ };
4219
+ }
4220
+ function O(a) {
4221
+ return "object" === typeof a && null !== a && a.$$typeof === l;
4222
+ }
4223
+ function escape(a) {
4224
+ var b = {
4225
+ "=": "=0",
4226
+ ":": "=2"
4227
+ };
4228
+ return "$" + a.replace(/[=:]/g, function(a) {
4229
+ return b[a];
4230
+ });
4231
+ }
4232
+ var P = /\/+/g;
4233
+ function Q(a, b) {
4234
+ return "object" === typeof a && null !== a && null != a.key ? escape("" + a.key) : b.toString(36);
4235
+ }
4236
+ function R(a, b, e, d, c) {
4237
+ var k = typeof a;
4238
+ if ("undefined" === k || "boolean" === k) a = null;
4239
+ var h = !1;
4240
+ if (null === a) h = !0;
4241
+ else switch (k) {
4242
+ case "string":
4243
+ case "number":
4244
+ h = !0;
4245
+ break;
4246
+ case "object": switch (a.$$typeof) {
4247
+ case l:
4248
+ case n: h = !0;
4249
+ }
4250
+ }
4251
+ if (h) return h = a, c = c(h), a = "" === d ? "." + Q(h, 0) : d, I(c) ? (e = "", null != a && (e = a.replace(P, "$&/") + "/"), R(c, b, e, "", function(a) {
4252
+ return a;
4253
+ })) : null != c && (O(c) && (c = N(c, e + (!c.key || h && h.key === c.key ? "" : ("" + c.key).replace(P, "$&/") + "/") + a)), b.push(c)), 1;
4254
+ h = 0;
4255
+ d = "" === d ? "." : d + ":";
4256
+ if (I(a)) for (var g = 0; g < a.length; g++) {
4257
+ k = a[g];
4258
+ var f = d + Q(k, g);
4259
+ h += R(k, b, e, f, c);
4260
+ }
4261
+ else if (f = A(a), "function" === typeof f) for (a = f.call(a), g = 0; !(k = a.next()).done;) k = k.value, f = d + Q(k, g++), h += R(k, b, e, f, c);
4262
+ else if ("object" === k) throw b = String(a), Error("Objects are not valid as a React child (found: " + ("[object Object]" === b ? "object with keys {" + Object.keys(a).join(", ") + "}" : b) + "). If you meant to render a collection of children, use an array instead.");
4263
+ return h;
4264
+ }
4265
+ function S(a, b, e) {
4266
+ if (null == a) return a;
4267
+ var d = [], c = 0;
4268
+ R(a, d, "", "", function(a) {
4269
+ return b.call(e, a, c++);
4270
+ });
4271
+ return d;
4272
+ }
4273
+ function T(a) {
4274
+ if (-1 === a._status) {
4275
+ var b = a._result;
4276
+ b = b();
4277
+ b.then(function(b) {
4278
+ if (0 === a._status || -1 === a._status) a._status = 1, a._result = b;
4279
+ }, function(b) {
4280
+ if (0 === a._status || -1 === a._status) a._status = 2, a._result = b;
4281
+ });
4282
+ -1 === a._status && (a._status = 0, a._result = b);
4283
+ }
4284
+ if (1 === a._status) return a._result.default;
4285
+ throw a._result;
4286
+ }
4287
+ var U = { current: null };
4288
+ var V = { transition: null };
4289
+ var W = {
4290
+ ReactCurrentDispatcher: U,
4291
+ ReactCurrentBatchConfig: V,
4292
+ ReactCurrentOwner: K
4293
+ };
4294
+ function X() {
4295
+ throw Error("act(...) is not supported in production builds of React.");
4296
+ }
4297
+ exports.Children = {
4298
+ map: S,
4299
+ forEach: function(a, b, e) {
4300
+ S(a, function() {
4301
+ b.apply(this, arguments);
4302
+ }, e);
4303
+ },
4304
+ count: function(a) {
4305
+ var b = 0;
4306
+ S(a, function() {
4307
+ b++;
4308
+ });
4309
+ return b;
4310
+ },
4311
+ toArray: function(a) {
4312
+ return S(a, function(a) {
4313
+ return a;
4314
+ }) || [];
4315
+ },
4316
+ only: function(a) {
4317
+ if (!O(a)) throw Error("React.Children.only expected to receive a single React element child.");
4318
+ return a;
4319
+ }
4320
+ };
4321
+ exports.Component = E;
4322
+ exports.Fragment = p;
4323
+ exports.Profiler = r;
4324
+ exports.PureComponent = G;
4325
+ exports.StrictMode = q;
4326
+ exports.Suspense = w;
4327
+ exports.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = W;
4328
+ exports.act = X;
4329
+ exports.cloneElement = function(a, b, e) {
4330
+ if (null === a || void 0 === a) throw Error("React.cloneElement(...): The argument must be a React element, but you passed " + a + ".");
4331
+ var d = C({}, a.props), c = a.key, k = a.ref, h = a._owner;
4332
+ if (null != b) {
4333
+ void 0 !== b.ref && (k = b.ref, h = K.current);
4334
+ void 0 !== b.key && (c = "" + b.key);
4335
+ if (a.type && a.type.defaultProps) var g = a.type.defaultProps;
4336
+ for (f in b) J.call(b, f) && !L.hasOwnProperty(f) && (d[f] = void 0 === b[f] && void 0 !== g ? g[f] : b[f]);
4337
+ }
4338
+ var f = arguments.length - 2;
4339
+ if (1 === f) d.children = e;
4340
+ else if (1 < f) {
4341
+ g = Array(f);
4342
+ for (var m = 0; m < f; m++) g[m] = arguments[m + 2];
4343
+ d.children = g;
4344
+ }
4345
+ return {
4346
+ $$typeof: l,
4347
+ type: a.type,
4348
+ key: c,
4349
+ ref: k,
4350
+ props: d,
4351
+ _owner: h
4352
+ };
4353
+ };
4354
+ exports.createContext = function(a) {
4355
+ a = {
4356
+ $$typeof: u,
4357
+ _currentValue: a,
4358
+ _currentValue2: a,
4359
+ _threadCount: 0,
4360
+ Provider: null,
4361
+ Consumer: null,
4362
+ _defaultValue: null,
4363
+ _globalName: null
4364
+ };
4365
+ a.Provider = {
4366
+ $$typeof: t,
4367
+ _context: a
4368
+ };
4369
+ return a.Consumer = a;
4370
+ };
4371
+ exports.createElement = M;
4372
+ exports.createFactory = function(a) {
4373
+ var b = M.bind(null, a);
4374
+ b.type = a;
4375
+ return b;
4376
+ };
4377
+ exports.createRef = function() {
4378
+ return { current: null };
4379
+ };
4380
+ exports.forwardRef = function(a) {
4381
+ return {
4382
+ $$typeof: v,
4383
+ render: a
4384
+ };
4385
+ };
4386
+ exports.isValidElement = O;
4387
+ exports.lazy = function(a) {
4388
+ return {
4389
+ $$typeof: y,
4390
+ _payload: {
4391
+ _status: -1,
4392
+ _result: a
4393
+ },
4394
+ _init: T
4395
+ };
4396
+ };
4397
+ exports.memo = function(a, b) {
4398
+ return {
4399
+ $$typeof: x,
4400
+ type: a,
4401
+ compare: void 0 === b ? null : b
4402
+ };
4403
+ };
4404
+ exports.startTransition = function(a) {
4405
+ var b = V.transition;
4406
+ V.transition = {};
4407
+ try {
4408
+ a();
4409
+ } finally {
4410
+ V.transition = b;
4411
+ }
4412
+ };
4413
+ exports.unstable_act = X;
4414
+ exports.useCallback = function(a, b) {
4415
+ return U.current.useCallback(a, b);
4416
+ };
4417
+ exports.useContext = function(a) {
4418
+ return U.current.useContext(a);
4419
+ };
4420
+ exports.useDebugValue = function() {};
4421
+ exports.useDeferredValue = function(a) {
4422
+ return U.current.useDeferredValue(a);
4423
+ };
4424
+ exports.useEffect = function(a, b) {
4425
+ return U.current.useEffect(a, b);
4426
+ };
4427
+ exports.useId = function() {
4428
+ return U.current.useId();
4429
+ };
4430
+ exports.useImperativeHandle = function(a, b, e) {
4431
+ return U.current.useImperativeHandle(a, b, e);
4432
+ };
4433
+ exports.useInsertionEffect = function(a, b) {
4434
+ return U.current.useInsertionEffect(a, b);
4435
+ };
4436
+ exports.useLayoutEffect = function(a, b) {
4437
+ return U.current.useLayoutEffect(a, b);
4438
+ };
4439
+ exports.useMemo = function(a, b) {
4440
+ return U.current.useMemo(a, b);
4441
+ };
4442
+ exports.useReducer = function(a, b, e) {
4443
+ return U.current.useReducer(a, b, e);
4444
+ };
4445
+ exports.useRef = function(a) {
4446
+ return U.current.useRef(a);
4447
+ };
4448
+ exports.useState = function(a) {
4449
+ return U.current.useState(a);
4450
+ };
4451
+ exports.useSyncExternalStore = function(a, b, e) {
4452
+ return U.current.useSyncExternalStore(a, b, e);
4453
+ };
4454
+ exports.useTransition = function() {
4455
+ return U.current.useTransition();
4456
+ };
4457
+ exports.version = "18.3.1";
4458
+ }));
4459
+ //#endregion
4460
+ //#region ../../../node_modules/.pnpm/react@18.3.1/node_modules/react/index.js
4461
+ var require_react = /* @__PURE__ */ __commonJSMin(((exports, module) => {
4462
+ module.exports = require_react_production_min();
4463
+ }));
4464
+ //#endregion
4465
+ //#region src/client/markdown-text.ts
4466
+ var import_react = require_react();
4467
+ //#endregion
4468
+ //#region ../../../node_modules/.pnpm/react@18.3.1/node_modules/react/cjs/react-jsx-runtime.production.min.js
4469
+ /**
4470
+ * @license React
4471
+ * react-jsx-runtime.production.min.js
4472
+ *
4473
+ * Copyright (c) Facebook, Inc. and its affiliates.
4474
+ *
4475
+ * This source code is licensed under the MIT license found in the
4476
+ * LICENSE file in the root directory of this source tree.
4477
+ */
4478
+ var require_react_jsx_runtime_production_min = /* @__PURE__ */ __commonJSMin(((exports) => {
4479
+ var f = require_react();
4480
+ var k = Symbol.for("react.element");
4481
+ var m = Object.prototype.hasOwnProperty;
4482
+ var n = f.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner;
4483
+ var p = {
4484
+ key: !0,
4485
+ ref: !0,
4486
+ __self: !0,
4487
+ __source: !0
4488
+ };
4489
+ function q(c, a, g) {
4490
+ var b, d = {}, e = null, h = null;
4491
+ void 0 !== g && (e = "" + g);
4492
+ void 0 !== a.key && (e = "" + a.key);
4493
+ void 0 !== a.ref && (h = a.ref);
4494
+ for (b in a) m.call(a, b) && !p.hasOwnProperty(b) && (d[b] = a[b]);
4495
+ if (c && c.defaultProps) for (b in a = c.defaultProps, a) void 0 === d[b] && (d[b] = a[b]);
4496
+ return {
4497
+ $$typeof: k,
4498
+ type: c,
4499
+ key: e,
4500
+ ref: h,
4501
+ props: d,
4502
+ _owner: n.current
4503
+ };
4504
+ }
4505
+ exports.jsx = q;
4506
+ }));
4507
+ //#endregion
4508
+ //#region src/reference-markdown.tsx
4509
+ var import_jsx_runtime = (/* @__PURE__ */ __commonJSMin(((exports, module) => {
4510
+ module.exports = require_react_jsx_runtime_production_min();
4511
+ })))();
4512
+ function referenceMentions(actions, tokens) {
4513
+ return { resolve: (value) => {
4514
+ const reference = tokens?.get(value) ?? parseReferenceToken(value);
4515
+ if (reference === void 0) return void 0;
4516
+ return {
4517
+ label: value,
4518
+ title: formatReference(reference),
4519
+ open: () => {
4520
+ openReference(reference, actions);
4521
+ }
4522
+ };
4523
+ } };
4524
+ }
4525
+ const ReferenceMarkdown = (0, import_react.memo)(function ReferenceMarkdown({ text, labels, actions, streaming = false, pathImages }) {
4526
+ const { source, tokens } = (0, import_react.useMemo)(() => tokenizeReferences(text), [text]);
4527
+ const mentions = (0, import_react.useMemo)(() => referenceMentions(actions, tokens), [actions, tokens]);
4528
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MarkdownText, {
4529
+ text: source,
4530
+ streaming,
4531
+ labels,
4532
+ fileMentions: mentions,
4533
+ pathImages
4534
+ });
4535
+ });
4536
+ function displayTextOf(reference) {
4537
+ return (reference.title ?? `${reference.path ?? ""}${rangeOf(reference)}`).replaceAll("`", "'");
4538
+ }
4539
+ function rangeOf(reference) {
4540
+ if (reference.lineStart === void 0) return "";
4541
+ const column = reference.column === void 0 ? "" : `C${String(reference.column)}`;
4542
+ return reference.lineEnd === void 0 ? `#L${String(reference.lineStart)}${column}` : `#L${String(reference.lineStart)}${column}-L${String(reference.lineEnd)}`;
4543
+ }
4544
+ function tokenizeReferences(text) {
4545
+ const tokens = /* @__PURE__ */ new Map();
4546
+ let out = "";
4547
+ let cursor = 0;
4548
+ for (const span of findReferences(text)) {
4549
+ if (!isLocalReference(span.reference) || span.start < cursor) continue;
4550
+ const display = displayTextOf(span.reference);
4551
+ tokens.set(display, span.reference);
4552
+ out += `${text.slice(cursor, span.start)}\`${display}\``;
4553
+ cursor = span.end;
4554
+ }
4555
+ return {
4556
+ source: cursor === 0 ? text : out + text.slice(cursor),
4557
+ tokens
4558
+ };
4559
+ }
4560
+ function openReference(reference, actions) {
4561
+ const path = reference.path;
4562
+ if (actions === void 0 || path === void 0) return;
4563
+ if (reference.protocol === "skill") {
4564
+ actions.openSkill(path);
4565
+ return;
4566
+ }
4567
+ if (reference.protocol === "file") actions.openFile(path);
4568
+ }
4569
+ //#endregion
4570
+ //#region src/client/index.ts
4571
+ const inject = [...inject$1];
4572
+ function apply(ctx) {
4573
+ apply$1(ctx);
4574
+ }
4575
+ //#endregion
4576
+ export { ReferenceMarkdown, NS as SCHEMA_FORM_NS, SchemaFormController, SchemaFormHints, SettingsForm, SettingsFormModel, SettingsSecretField, SettingsValueField, Styling, Token, apply, designTokens, dsw, failureOf, findReferences, formatReference, formatReferenceMention, inject, isLocalReference, markdownLabels, parseReference, parseReferenceToken, projectRoot, referenceMentions, rowRegistrations, schema_form_exports as schemaForm, settingsNumberField, settingsTextField, styleOf, styled, styling, walkFields };