@neta-art/cohub-cli 10.0.0 → 10.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +24 -2
- package/dist/auth.d.ts +2 -1
- package/dist/auth.js +39 -28
- package/dist/board-kernel.js +1908 -1267
- package/dist/command-input.d.ts +4 -0
- package/dist/command-input.js +16 -0
- package/dist/commands/app-commerce.js +1 -3
- package/dist/commands/decision.d.ts +4 -0
- package/dist/commands/decision.js +113 -0
- package/dist/commands/run.js +14 -2
- package/dist/commands/spaces.js +4 -15
- package/dist/endpoint-options.d.ts +4 -0
- package/dist/endpoint-options.js +26 -0
- package/dist/help-path.js +2 -2
- package/dist/index.js +7 -2
- package/dist/runtime/supervisor.js +3 -3
- package/dist/space.d.ts +1 -0
- package/dist/space.js +26 -18
- package/dist/web.js +2 -4
- package/package.json +3 -3
package/dist/board-kernel.js
CHANGED
|
@@ -5953,8 +5953,16 @@ const fileProps$1 = {
|
|
|
5953
5953
|
coverUrl: string().optional()
|
|
5954
5954
|
}).strict().optional()
|
|
5955
5955
|
};
|
|
5956
|
-
const
|
|
5956
|
+
const BoardMediaOriginSchema$1 = object({
|
|
5957
|
+
taskRunId: string().min(1).max(160),
|
|
5958
|
+
artifactId: string().min(1).max(240)
|
|
5959
|
+
}).strict();
|
|
5960
|
+
const mediaProps$1 = {
|
|
5957
5961
|
...fileProps$1,
|
|
5962
|
+
origin: BoardMediaOriginSchema$1.optional()
|
|
5963
|
+
};
|
|
5964
|
+
const timedFileProps$1 = {
|
|
5965
|
+
...mediaProps$1,
|
|
5958
5966
|
time: nonNegative$1.optional()
|
|
5959
5967
|
};
|
|
5960
5968
|
const BoardCropSchema$1 = object({
|
|
@@ -5967,7 +5975,7 @@ const BoardImageItemSchema$1 = object({
|
|
|
5967
5975
|
...boxed$1(640, 360),
|
|
5968
5976
|
type: literal("image"),
|
|
5969
5977
|
props: object({
|
|
5970
|
-
...
|
|
5978
|
+
...mediaProps$1,
|
|
5971
5979
|
crop: BoardCropSchema$1.optional()
|
|
5972
5980
|
}).strict()
|
|
5973
5981
|
}).strict();
|
|
@@ -6032,8 +6040,10 @@ const BoardTaskSnapshotSchema$1 = object({
|
|
|
6032
6040
|
title: string().min(1).max(240),
|
|
6033
6041
|
model: string().max(160).optional(),
|
|
6034
6042
|
promptExcerpt: string().max(480).optional(),
|
|
6043
|
+
errorExcerpt: string().max(240).optional(),
|
|
6035
6044
|
artifactCount: number$1().int().nonnegative(),
|
|
6036
6045
|
artifacts: array(BoardTaskArtifactSchema$1).max(6).default([]),
|
|
6046
|
+
startedAt: string().max(64).optional(),
|
|
6037
6047
|
updatedAt: string().optional()
|
|
6038
6048
|
}).strict();
|
|
6039
6049
|
const BoardTaskItemSchema$1 = object({
|
|
@@ -6041,7 +6051,7 @@ const BoardTaskItemSchema$1 = object({
|
|
|
6041
6051
|
type: literal("task"),
|
|
6042
6052
|
props: object({
|
|
6043
6053
|
taskRunId: string().min(1).max(160),
|
|
6044
|
-
snapshot: BoardTaskSnapshotSchema$1
|
|
6054
|
+
snapshot: BoardTaskSnapshotSchema$1.describe("Maintained by the server for tasks in the Board's Space; writers may omit it.")
|
|
6045
6055
|
}).strict()
|
|
6046
6056
|
}).strict();
|
|
6047
6057
|
const BOARD_EFFECT_KINDS$1 = [
|
|
@@ -7328,6 +7338,42 @@ function parseBoardDocument(input) {
|
|
|
7328
7338
|
} : result;
|
|
7329
7339
|
}
|
|
7330
7340
|
//#endregion
|
|
7341
|
+
//#region ../protocol/src/board-task.ts
|
|
7342
|
+
function artifactScore(artifact) {
|
|
7343
|
+
const kind = {
|
|
7344
|
+
text: 1,
|
|
7345
|
+
image: 2,
|
|
7346
|
+
audio: 3,
|
|
7347
|
+
video: 4
|
|
7348
|
+
}[artifact.type];
|
|
7349
|
+
if (artifact.type === "text") return [kind, artifact.textExcerpt.length];
|
|
7350
|
+
if (artifact.type === "image") return [kind, (artifact.naturalWidth ?? 0) * (artifact.naturalHeight ?? 0)];
|
|
7351
|
+
return [
|
|
7352
|
+
kind,
|
|
7353
|
+
artifact.previewUrl ? 1 : 0,
|
|
7354
|
+
artifact.durationMs ? 1 : 0,
|
|
7355
|
+
artifact.durationMs ?? 0
|
|
7356
|
+
];
|
|
7357
|
+
}
|
|
7358
|
+
function compareArtifacts(a, b) {
|
|
7359
|
+
const left = artifactScore(a);
|
|
7360
|
+
const right = artifactScore(b);
|
|
7361
|
+
for (let index = 0; index < Math.max(left.length, right.length); index += 1) {
|
|
7362
|
+
const difference = (right[index] ?? 0) - (left[index] ?? 0);
|
|
7363
|
+
if (difference !== 0) return difference;
|
|
7364
|
+
}
|
|
7365
|
+
return 0;
|
|
7366
|
+
}
|
|
7367
|
+
function featuredTaskArtifact(artifacts) {
|
|
7368
|
+
let featured;
|
|
7369
|
+
for (const artifact of artifacts) if (!featured || compareArtifacts(artifact, featured) < 0) featured = artifact;
|
|
7370
|
+
return featured;
|
|
7371
|
+
}
|
|
7372
|
+
function taskArtifactPreviewUrl(artifact) {
|
|
7373
|
+
if (artifact?.type === "image") return artifact.url;
|
|
7374
|
+
if (artifact?.type === "video" || artifact?.type === "audio") return artifact.previewUrl;
|
|
7375
|
+
}
|
|
7376
|
+
//#endregion
|
|
7331
7377
|
//#region ../sdk/src/board/model/script-index.ts
|
|
7332
7378
|
const scriptsByItems = /* @__PURE__ */ new WeakMap();
|
|
7333
7379
|
function boardScriptItems(document) {
|
|
@@ -7490,6 +7536,10 @@ function validateBoardScriptOutput(output, scope) {
|
|
|
7490
7536
|
if (!output || typeof output !== "object" || !output.patches || !output.items || !output.hits || !Array.isArray(output.listens)) throw new Error("Invalid script output.");
|
|
7491
7537
|
if (JSON.stringify(output).length > 1e6) throw new Error("Script output exceeds the 1 MB limit.");
|
|
7492
7538
|
if (output.space !== void 0 && output.space !== "world" && output.space !== "screen") throw new Error("Invalid script scene space.");
|
|
7539
|
+
if (output.anchor) {
|
|
7540
|
+
const { item, point } = output.anchor;
|
|
7541
|
+
if (output.space !== "screen" || typeof item !== "string" || !item || point && ![point.x, point.y].every((n) => Number.isFinite(n) && n >= 0 && n <= 1)) throw new Error("Invalid screen scene anchor.");
|
|
7542
|
+
}
|
|
7493
7543
|
if (output.parameters) {
|
|
7494
7544
|
if (Object.keys(output.parameters).length > 64) throw new Error("A script may declare at most 64 parameters.");
|
|
7495
7545
|
for (const spec of Object.values(output.parameters)) {
|
|
@@ -7513,6 +7563,7 @@ function validateBoardScriptOutput(output, scope) {
|
|
|
7513
7563
|
if (!patch || typeof patch !== "object" || Object.keys(patch).some((key) => !DISPLAY_FIELDS.has(key))) throw new Error("Scripts may only present display properties.");
|
|
7514
7564
|
}
|
|
7515
7565
|
for (const hit of Object.values(output.hits)) {
|
|
7566
|
+
if (!hit || typeof hit !== "object") throw new Error("Invalid script hit region.");
|
|
7516
7567
|
if (hit.cursor && ![
|
|
7517
7568
|
"default",
|
|
7518
7569
|
"pointer",
|
|
@@ -7525,7 +7576,11 @@ function validateBoardScriptOutput(output, scope) {
|
|
|
7525
7576
|
"ns-resize",
|
|
7526
7577
|
"not-allowed"
|
|
7527
7578
|
].includes(hit.cursor)) throw new Error("Invalid script cursor.");
|
|
7528
|
-
if (
|
|
7579
|
+
if ("target" in hit) {
|
|
7580
|
+
if (hit.target !== "self" || "item" in hit || "x" in hit) throw new Error("Invalid script hit target.");
|
|
7581
|
+
} else if ("item" in hit) {
|
|
7582
|
+
if (typeof hit.item !== "string" || !Object.hasOwn(output.items, hit.item) || "x" in hit) throw new Error("Hit items must belong to the temporary scene.");
|
|
7583
|
+
} else if (![
|
|
7529
7584
|
hit.x,
|
|
7530
7585
|
hit.y,
|
|
7531
7586
|
hit.width,
|
|
@@ -7540,6 +7595,15 @@ function scriptTemporaryPrefix(owner) {
|
|
|
7540
7595
|
}
|
|
7541
7596
|
const preparedOutputs = /* @__PURE__ */ new WeakMap();
|
|
7542
7597
|
const preparedScopes = /* @__PURE__ */ new WeakMap();
|
|
7598
|
+
const itemOrders = /* @__PURE__ */ new WeakMap();
|
|
7599
|
+
function orderedScriptOwners(document, outputs) {
|
|
7600
|
+
let order = itemOrders.get(document.items);
|
|
7601
|
+
if (!order) {
|
|
7602
|
+
order = new Map(Object.keys(document.items).map((id, index) => [id, index]));
|
|
7603
|
+
itemOrders.set(document.items, order);
|
|
7604
|
+
}
|
|
7605
|
+
return [...outputs.keys()].filter((id) => order.has(id)).sort((a, b) => (order.get(a) ?? 0) - (order.get(b) ?? 0));
|
|
7606
|
+
}
|
|
7543
7607
|
function prepareBoardScriptOutput(document, owner, output) {
|
|
7544
7608
|
const previous = preparedOutputs.get(output);
|
|
7545
7609
|
if (previous?.document === document && previous.owner === owner) return previous;
|
|
@@ -7553,6 +7617,7 @@ function prepareBoardScriptOutput(document, owner, output) {
|
|
|
7553
7617
|
scope = boardScriptScope(document, owner);
|
|
7554
7618
|
scopes.set(owner, scope);
|
|
7555
7619
|
}
|
|
7620
|
+
if (output.anchor && document.items[output.anchor.item] && !scope.has(output.anchor.item)) throw new Error("Scene anchor is outside the script scope.");
|
|
7556
7621
|
validateBoardScriptOutput(output, scope);
|
|
7557
7622
|
const presented = /* @__PURE__ */ new Map();
|
|
7558
7623
|
for (const [id, patch] of Object.entries(output.patches)) {
|
|
@@ -7617,11 +7682,11 @@ function prepareBoardScriptOutput(document, owner, output) {
|
|
|
7617
7682
|
preparedOutputs.set(output, prepared);
|
|
7618
7683
|
return prepared;
|
|
7619
7684
|
}
|
|
7620
|
-
function composeBoardScriptItems(document, scene, outputs, incoming = /* @__PURE__ */ new Map(), screen, onError) {
|
|
7685
|
+
function composeBoardScriptItems(document, scene, outputs, incoming = /* @__PURE__ */ new Map(), screen, onError, gestureLayout) {
|
|
7621
7686
|
const result = new Map(incoming);
|
|
7622
7687
|
const screenAnchors = /* @__PURE__ */ new Map();
|
|
7623
7688
|
if (outputs.size === 0) return result;
|
|
7624
|
-
for (const owner of
|
|
7689
|
+
for (const owner of orderedScriptOwners(document, outputs)) {
|
|
7625
7690
|
const output = outputs.get(owner);
|
|
7626
7691
|
if (!output) continue;
|
|
7627
7692
|
try {
|
|
@@ -7689,15 +7754,23 @@ function composeBoardScriptItems(document, scene, outputs, incoming = /* @__PURE
|
|
|
7689
7754
|
}
|
|
7690
7755
|
}
|
|
7691
7756
|
if (screenAnchors.size) {
|
|
7692
|
-
const layout = createBoardLayout((id) => result.get(id) ?? document.items[id]);
|
|
7757
|
+
const layout = gestureLayout ?? createBoardLayout((id) => result.get(id) ?? document.items[id]);
|
|
7693
7758
|
for (const [owner, rootId] of screenAnchors) {
|
|
7694
7759
|
const root = result.get(rootId);
|
|
7760
|
+
const anchor = outputs.get(owner)?.anchor;
|
|
7761
|
+
const target = anchor?.item ?? owner;
|
|
7762
|
+
const exists = Boolean(document.items[target]);
|
|
7763
|
+
const box = exists ? layout.box(target) : {
|
|
7764
|
+
width: 0,
|
|
7765
|
+
height: 0
|
|
7766
|
+
};
|
|
7695
7767
|
if (root) result.set(rootId, {
|
|
7696
7768
|
...root,
|
|
7697
|
-
|
|
7698
|
-
|
|
7699
|
-
|
|
7700
|
-
|
|
7769
|
+
opacity: exists ? root.opacity : 0,
|
|
7770
|
+
position: exists ? applyMatrix$1(layout.matrix(target), {
|
|
7771
|
+
x: (anchor?.point?.x ?? 0) * box.width,
|
|
7772
|
+
y: (anchor?.point?.y ?? 0) * box.height
|
|
7773
|
+
}) : root.position
|
|
7701
7774
|
});
|
|
7702
7775
|
}
|
|
7703
7776
|
}
|
|
@@ -9268,13 +9341,47 @@ function filePreviewKind(snapshot) {
|
|
|
9268
9341
|
if (snapshot.excerpt) return "text";
|
|
9269
9342
|
return "blank";
|
|
9270
9343
|
}
|
|
9271
|
-
/** Short uppercase type label for a file card (`MD`, `JSON`, `FILE`). */
|
|
9272
9344
|
function fileTypeLabel(path) {
|
|
9345
|
+
if (isWebPageUrl(path)) return "LINK";
|
|
9273
9346
|
const name = fileBaseName(path);
|
|
9274
9347
|
const dot = name.lastIndexOf(".");
|
|
9275
9348
|
if (dot <= 0) return (name.replace(/^\./, "") || "file").toUpperCase();
|
|
9276
9349
|
return name.slice(dot + 1).toUpperCase();
|
|
9277
9350
|
}
|
|
9351
|
+
function isWebPageUrl(path) {
|
|
9352
|
+
if (!/^https?:\/\//i.test(path)) return false;
|
|
9353
|
+
try {
|
|
9354
|
+
const last = new URL(path).pathname.split("/").filter(Boolean).pop() ?? "";
|
|
9355
|
+
return !/\.[a-z\d]{1,8}$/i.test(last);
|
|
9356
|
+
} catch {
|
|
9357
|
+
return false;
|
|
9358
|
+
}
|
|
9359
|
+
}
|
|
9360
|
+
/** Human-readable byte size. Kept as a public helper for custom card renderers. */
|
|
9361
|
+
function formatFileSize(bytes) {
|
|
9362
|
+
if (bytes === void 0 || !Number.isFinite(bytes) || bytes < 0) return "";
|
|
9363
|
+
if (bytes < 1024) return `${bytes} B`;
|
|
9364
|
+
const units = [
|
|
9365
|
+
"KB",
|
|
9366
|
+
"MB",
|
|
9367
|
+
"GB",
|
|
9368
|
+
"TB"
|
|
9369
|
+
];
|
|
9370
|
+
let value = bytes / 1024;
|
|
9371
|
+
let unit = 0;
|
|
9372
|
+
while (value >= 1024 && unit < units.length - 1) {
|
|
9373
|
+
value /= 1024;
|
|
9374
|
+
unit += 1;
|
|
9375
|
+
}
|
|
9376
|
+
return `${value < 10 ? value.toFixed(1) : Math.round(value)} ${units[unit]}`;
|
|
9377
|
+
}
|
|
9378
|
+
/** `MD · 12 KB` — empty when neither fact is available. */
|
|
9379
|
+
function fileMetaLine(path, size) {
|
|
9380
|
+
const type = fileTypeLabel(path);
|
|
9381
|
+
const formatted = formatFileSize(size);
|
|
9382
|
+
if (type && formatted) return `${type} · ${formatted}`;
|
|
9383
|
+
return formatted || type;
|
|
9384
|
+
}
|
|
9278
9385
|
/** Map a file category onto an existing palette token. */
|
|
9279
9386
|
function fileCategoryAccent(category, palette) {
|
|
9280
9387
|
switch (category) {
|
|
@@ -9449,42 +9556,6 @@ function boardFontFamily(font, stacks) {
|
|
|
9449
9556
|
return `"${font.replaceAll("\"", "")}", ${stacks.sans}`;
|
|
9450
9557
|
}
|
|
9451
9558
|
//#endregion
|
|
9452
|
-
//#region ../sdk/src/board/model/task.ts
|
|
9453
|
-
function artifactScore(artifact) {
|
|
9454
|
-
const kind = {
|
|
9455
|
-
text: 1,
|
|
9456
|
-
image: 2,
|
|
9457
|
-
audio: 3,
|
|
9458
|
-
video: 4
|
|
9459
|
-
}[artifact.type];
|
|
9460
|
-
if (artifact.type === "text") return [kind, artifact.textExcerpt.length];
|
|
9461
|
-
if (artifact.type === "image") return [kind, (artifact.naturalWidth ?? 0) * (artifact.naturalHeight ?? 0)];
|
|
9462
|
-
return [
|
|
9463
|
-
kind,
|
|
9464
|
-
artifact.previewUrl ? 1 : 0,
|
|
9465
|
-
artifact.durationMs ? 1 : 0,
|
|
9466
|
-
artifact.durationMs ?? 0
|
|
9467
|
-
];
|
|
9468
|
-
}
|
|
9469
|
-
function compareArtifacts(a, b) {
|
|
9470
|
-
const left = artifactScore(a);
|
|
9471
|
-
const right = artifactScore(b);
|
|
9472
|
-
for (let index = 0; index < Math.max(left.length, right.length); index += 1) {
|
|
9473
|
-
const difference = (right[index] ?? 0) - (left[index] ?? 0);
|
|
9474
|
-
if (difference !== 0) return difference;
|
|
9475
|
-
}
|
|
9476
|
-
return 0;
|
|
9477
|
-
}
|
|
9478
|
-
function featuredTaskArtifact(artifacts) {
|
|
9479
|
-
let featured;
|
|
9480
|
-
for (const artifact of artifacts) if (!featured || compareArtifacts(artifact, featured) < 0) featured = artifact;
|
|
9481
|
-
return featured;
|
|
9482
|
-
}
|
|
9483
|
-
function taskArtifactPreviewUrl(artifact) {
|
|
9484
|
-
if (artifact?.type === "image") return artifact.url;
|
|
9485
|
-
if (artifact?.type === "video" || artifact?.type === "audio") return artifact.previewUrl;
|
|
9486
|
-
}
|
|
9487
|
-
//#endregion
|
|
9488
9559
|
//#region ../sdk/src/board/model/image-key.ts
|
|
9489
9560
|
function imageAssetKey(item) {
|
|
9490
9561
|
if (item.type === "image") {
|
|
@@ -26974,8 +27045,8 @@ const DARK = {
|
|
|
26974
27045
|
legendary: 16096779
|
|
26975
27046
|
};
|
|
26976
27047
|
const LIGHT = {
|
|
26977
|
-
bg:
|
|
26978
|
-
surface:
|
|
27048
|
+
bg: 16251129,
|
|
27049
|
+
surface: 16777215,
|
|
26979
27050
|
hover: 15329772,
|
|
26980
27051
|
border: 14079706,
|
|
26981
27052
|
brand: 15222030,
|
|
@@ -27158,6 +27229,298 @@ function inspectBoardScene(scene, limit = 100) {
|
|
|
27158
27229
|
return diagnostics;
|
|
27159
27230
|
}
|
|
27160
27231
|
//#endregion
|
|
27232
|
+
//#region ../sdk/src/board/render/text-fit.ts
|
|
27233
|
+
function fitLineWithEllipsis(line, wrapWidth, measureWidth) {
|
|
27234
|
+
const trimmed = line.replace(/\s+$/u, "");
|
|
27235
|
+
if (!trimmed) return "…";
|
|
27236
|
+
const full = `${trimmed}…`;
|
|
27237
|
+
if (measureWidth(full) <= wrapWidth) return full;
|
|
27238
|
+
let lo = 0;
|
|
27239
|
+
let hi = trimmed.length;
|
|
27240
|
+
let best = "…";
|
|
27241
|
+
while (lo <= hi) {
|
|
27242
|
+
const mid = lo + hi >> 1;
|
|
27243
|
+
const candidate = mid > 0 ? `${trimmed.slice(0, mid)}…` : "…";
|
|
27244
|
+
if (measureWidth(candidate) <= wrapWidth) {
|
|
27245
|
+
best = candidate;
|
|
27246
|
+
lo = mid + 1;
|
|
27247
|
+
} else hi = mid - 1;
|
|
27248
|
+
}
|
|
27249
|
+
return best;
|
|
27250
|
+
}
|
|
27251
|
+
function fitTextToLines(text, value, maxLines, wrapWidth) {
|
|
27252
|
+
const width = Math.max(1, wrapWidth);
|
|
27253
|
+
text.style.wordWrapWidth = width;
|
|
27254
|
+
if (!value || maxLines <= 0) {
|
|
27255
|
+
if (text.text !== "") text.text = "";
|
|
27256
|
+
return;
|
|
27257
|
+
}
|
|
27258
|
+
const charCap = Math.max(maxLines * Math.ceil(width), maxLines * 4);
|
|
27259
|
+
const sample = value.length > charCap ? value.slice(0, charCap) : value;
|
|
27260
|
+
const metrics = CanvasTextMetrics.measureText(sample, text.style);
|
|
27261
|
+
if (!(metrics.lines.length > maxLines || sample !== value)) {
|
|
27262
|
+
if (text.text !== value) text.text = value;
|
|
27263
|
+
return;
|
|
27264
|
+
}
|
|
27265
|
+
const keptCount = Math.min(maxLines, metrics.lines.length);
|
|
27266
|
+
const kept = metrics.lines.slice(0, keptCount);
|
|
27267
|
+
const lastIndex = kept.length - 1;
|
|
27268
|
+
const probe = text.style.clone();
|
|
27269
|
+
probe.wordWrap = false;
|
|
27270
|
+
kept[lastIndex] = fitLineWithEllipsis(kept[lastIndex] ?? "", width, (candidate) => CanvasTextMetrics.measureText(candidate, probe).width);
|
|
27271
|
+
const fitted = kept.join("\n");
|
|
27272
|
+
if (text.text !== fitted) text.text = fitted;
|
|
27273
|
+
}
|
|
27274
|
+
function fitTextToWidth(text, value, width) {
|
|
27275
|
+
text.style.wordWrap = false;
|
|
27276
|
+
const measure = (candidate) => CanvasTextMetrics.measureText(candidate, text.style).width;
|
|
27277
|
+
const fitted = !value || measure(value) <= width ? value : fitLineWithEllipsis(value, width, measure);
|
|
27278
|
+
if (text.text !== fitted) text.text = fitted;
|
|
27279
|
+
}
|
|
27280
|
+
//#endregion
|
|
27281
|
+
//#region ../sdk/src/board/render/text-resolution.ts
|
|
27282
|
+
const MAX_BOARD_RESOLUTION = 2;
|
|
27283
|
+
function getBoardResolution() {
|
|
27284
|
+
return Math.min(globalThis.devicePixelRatio || 1, MAX_BOARD_RESOLUTION);
|
|
27285
|
+
}
|
|
27286
|
+
/**
|
|
27287
|
+
* Zoom buckets for text re-rasterisation. Pixi Text is a bitmap: at high zoom it
|
|
27288
|
+
* looks soft unless we raise its resolution. We quantise zoom into a few
|
|
27289
|
+
* buckets so small zoom changes don't thrash texture regeneration.
|
|
27290
|
+
*/
|
|
27291
|
+
const TEXT_ZOOM_BUCKETS = [
|
|
27292
|
+
.5,
|
|
27293
|
+
1,
|
|
27294
|
+
1.5,
|
|
27295
|
+
2,
|
|
27296
|
+
3,
|
|
27297
|
+
4
|
|
27298
|
+
];
|
|
27299
|
+
function textZoomBucket(zoom) {
|
|
27300
|
+
const clamped = Math.max(.1, Math.min(4, zoom));
|
|
27301
|
+
for (const bucket of TEXT_ZOOM_BUCKETS) if (clamped <= bucket) return bucket;
|
|
27302
|
+
return TEXT_ZOOM_BUCKETS[TEXT_ZOOM_BUCKETS.length - 1] ?? 4;
|
|
27303
|
+
}
|
|
27304
|
+
function boardCardDetailed(zoom) {
|
|
27305
|
+
return textZoomBucket(zoom) >= 1;
|
|
27306
|
+
}
|
|
27307
|
+
/** Effective text resolution for a given camera zoom. */
|
|
27308
|
+
function textResolutionForZoom(zoom) {
|
|
27309
|
+
const bucket = textZoomBucket(zoom);
|
|
27310
|
+
return Math.min(getBoardResolution() * Math.max(1, bucket), 6);
|
|
27311
|
+
}
|
|
27312
|
+
/** Update a Pixi text texture only when zoom crosses a resolution bucket. */
|
|
27313
|
+
function syncTextResolution(text, state, zoom) {
|
|
27314
|
+
const resolution = textResolutionForZoom(zoom);
|
|
27315
|
+
if (resolution === state.resolution) return;
|
|
27316
|
+
text.resolution = resolution;
|
|
27317
|
+
state.resolution = resolution;
|
|
27318
|
+
}
|
|
27319
|
+
/** Defer expensive Pixi word-wrap rasterisation during a live resize. */
|
|
27320
|
+
function syncTextWrapWidth(text, state, width, defer) {
|
|
27321
|
+
if (defer || width === state.wrapWidth) return;
|
|
27322
|
+
text.style.wordWrapWidth = width;
|
|
27323
|
+
state.wrapWidth = width;
|
|
27324
|
+
}
|
|
27325
|
+
const ICON = 12;
|
|
27326
|
+
const GAP$2 = 5;
|
|
27327
|
+
const MAX_GROWTH = 1.25;
|
|
27328
|
+
const MIN_READABLE = 7;
|
|
27329
|
+
const SECOND$1 = 1e3;
|
|
27330
|
+
function formatBoardDuration(ms) {
|
|
27331
|
+
const total = Math.max(0, Math.floor(ms / SECOND$1));
|
|
27332
|
+
const hours = Math.floor(total / 3600);
|
|
27333
|
+
const minutes = Math.floor(total % 3600 / 60);
|
|
27334
|
+
const seconds = String(total % 60).padStart(2, "0");
|
|
27335
|
+
return hours > 0 ? `${hours}:${String(minutes).padStart(2, "0")}:${seconds}` : `${minutes}:${seconds}`;
|
|
27336
|
+
}
|
|
27337
|
+
const PIXEL_GLYPHS = {
|
|
27338
|
+
image: [
|
|
27339
|
+
"######",
|
|
27340
|
+
"#....#",
|
|
27341
|
+
"#.#..#",
|
|
27342
|
+
"#.##.#",
|
|
27343
|
+
"######",
|
|
27344
|
+
"......"
|
|
27345
|
+
],
|
|
27346
|
+
video: [
|
|
27347
|
+
"######",
|
|
27348
|
+
"#.#..#",
|
|
27349
|
+
"#.##.#",
|
|
27350
|
+
"#.#..#",
|
|
27351
|
+
"######",
|
|
27352
|
+
"......"
|
|
27353
|
+
],
|
|
27354
|
+
audio: [
|
|
27355
|
+
"...#..",
|
|
27356
|
+
"...##.",
|
|
27357
|
+
"...#.#",
|
|
27358
|
+
"...#..",
|
|
27359
|
+
".###..",
|
|
27360
|
+
".###.."
|
|
27361
|
+
],
|
|
27362
|
+
file: [
|
|
27363
|
+
"####..",
|
|
27364
|
+
"#..##.",
|
|
27365
|
+
"#...##",
|
|
27366
|
+
"#....#",
|
|
27367
|
+
"#....#",
|
|
27368
|
+
"######"
|
|
27369
|
+
],
|
|
27370
|
+
task: [
|
|
27371
|
+
"..#...",
|
|
27372
|
+
".###..",
|
|
27373
|
+
"#####.",
|
|
27374
|
+
".###..",
|
|
27375
|
+
"..#...",
|
|
27376
|
+
"......"
|
|
27377
|
+
]
|
|
27378
|
+
};
|
|
27379
|
+
function drawLineGlyph(graphics, glyph, color) {
|
|
27380
|
+
const line = {
|
|
27381
|
+
color,
|
|
27382
|
+
width: 1.25,
|
|
27383
|
+
alpha: 1,
|
|
27384
|
+
cap: "round",
|
|
27385
|
+
join: "round"
|
|
27386
|
+
};
|
|
27387
|
+
switch (glyph) {
|
|
27388
|
+
case "image":
|
|
27389
|
+
graphics.roundRect(1, 2, 10, 8, 1.5).stroke(line);
|
|
27390
|
+
graphics.moveTo(2.5, 9).lineTo(5, 6).lineTo(7, 8).lineTo(8.5, 6.5).lineTo(10, 8).stroke(line);
|
|
27391
|
+
return;
|
|
27392
|
+
case "video":
|
|
27393
|
+
graphics.roundRect(1, 2.5, 10, 7, 1.5).stroke(line);
|
|
27394
|
+
graphics.poly([
|
|
27395
|
+
5,
|
|
27396
|
+
4.5,
|
|
27397
|
+
5,
|
|
27398
|
+
7.5,
|
|
27399
|
+
7.5,
|
|
27400
|
+
6
|
|
27401
|
+
]).fill({ color });
|
|
27402
|
+
return;
|
|
27403
|
+
case "audio":
|
|
27404
|
+
for (const [x, height] of [
|
|
27405
|
+
[2.5, 3],
|
|
27406
|
+
[5, 7],
|
|
27407
|
+
[7.5, 9],
|
|
27408
|
+
[10, 5]
|
|
27409
|
+
]) graphics.moveTo(x, 6 - height / 2).lineTo(x, 6 + height / 2);
|
|
27410
|
+
graphics.stroke(line);
|
|
27411
|
+
return;
|
|
27412
|
+
case "file":
|
|
27413
|
+
graphics.poly([
|
|
27414
|
+
2.5,
|
|
27415
|
+
1,
|
|
27416
|
+
7.5,
|
|
27417
|
+
1,
|
|
27418
|
+
9.5,
|
|
27419
|
+
3,
|
|
27420
|
+
9.5,
|
|
27421
|
+
11,
|
|
27422
|
+
2.5,
|
|
27423
|
+
11
|
|
27424
|
+
]).stroke(line);
|
|
27425
|
+
graphics.moveTo(7.5, 1).lineTo(7.5, 3).lineTo(9.5, 3).stroke(line);
|
|
27426
|
+
return;
|
|
27427
|
+
case "task":
|
|
27428
|
+
graphics.poly([
|
|
27429
|
+
6,
|
|
27430
|
+
1,
|
|
27431
|
+
7.3,
|
|
27432
|
+
4.7,
|
|
27433
|
+
11,
|
|
27434
|
+
6,
|
|
27435
|
+
7.3,
|
|
27436
|
+
7.3,
|
|
27437
|
+
6,
|
|
27438
|
+
11,
|
|
27439
|
+
4.7,
|
|
27440
|
+
7.3,
|
|
27441
|
+
1,
|
|
27442
|
+
6,
|
|
27443
|
+
4.7,
|
|
27444
|
+
4.7
|
|
27445
|
+
]).fill({ color });
|
|
27446
|
+
return;
|
|
27447
|
+
}
|
|
27448
|
+
}
|
|
27449
|
+
function drawCardGlyph(graphics, glyph, color, pixel) {
|
|
27450
|
+
if (!pixel) {
|
|
27451
|
+
drawLineGlyph(graphics, glyph, color);
|
|
27452
|
+
return;
|
|
27453
|
+
}
|
|
27454
|
+
PIXEL_GLYPHS[glyph].forEach((row, y) => {
|
|
27455
|
+
for (let x = 0; x < row.length; x += 1) if (row[x] === "#") graphics.rect(x * 2, y * 2, 2, 2);
|
|
27456
|
+
});
|
|
27457
|
+
graphics.fill({ color });
|
|
27458
|
+
}
|
|
27459
|
+
function createCardTag() {
|
|
27460
|
+
const root = new Container({ label: "card-tag" });
|
|
27461
|
+
const icon = new Graphics();
|
|
27462
|
+
root.addChild(icon);
|
|
27463
|
+
root.visible = false;
|
|
27464
|
+
return {
|
|
27465
|
+
root,
|
|
27466
|
+
icon,
|
|
27467
|
+
text: null,
|
|
27468
|
+
sig: "",
|
|
27469
|
+
resolution: 0,
|
|
27470
|
+
width: 0
|
|
27471
|
+
};
|
|
27472
|
+
}
|
|
27473
|
+
function zoomCardTag(tag, zoom) {
|
|
27474
|
+
if (!tag.text || !tag.sig) return;
|
|
27475
|
+
const scale = Math.min(MAX_GROWTH, Math.max(1, 1 / Math.max(zoom, .01)));
|
|
27476
|
+
const span = 17 + tag.text.width;
|
|
27477
|
+
tag.root.scale.set(scale);
|
|
27478
|
+
tag.root.position.set(0, -18 * scale);
|
|
27479
|
+
tag.root.visible = 11 * scale * zoom >= MIN_READABLE && span * scale <= tag.width + .5;
|
|
27480
|
+
}
|
|
27481
|
+
function syncCardTag(tag, input, context) {
|
|
27482
|
+
tag.width = input.width;
|
|
27483
|
+
if (!input.text || input.width <= 24) {
|
|
27484
|
+
tag.sig = "";
|
|
27485
|
+
tag.root.visible = false;
|
|
27486
|
+
return;
|
|
27487
|
+
}
|
|
27488
|
+
if (!tag.text) {
|
|
27489
|
+
tag.resolution = textResolutionForZoom(context.zoom);
|
|
27490
|
+
tag.text = new Text({
|
|
27491
|
+
text: "",
|
|
27492
|
+
style: {
|
|
27493
|
+
fontFamily: context.style.font,
|
|
27494
|
+
fontSize: 11,
|
|
27495
|
+
fontWeight: "500"
|
|
27496
|
+
},
|
|
27497
|
+
resolution: tag.resolution,
|
|
27498
|
+
roundPixels: true
|
|
27499
|
+
});
|
|
27500
|
+
tag.root.addChild(tag.text);
|
|
27501
|
+
}
|
|
27502
|
+
syncTextResolution(tag.text, tag, context.zoom);
|
|
27503
|
+
const sig = [
|
|
27504
|
+
input.glyph,
|
|
27505
|
+
input.text,
|
|
27506
|
+
input.width,
|
|
27507
|
+
context.themeKey
|
|
27508
|
+
].join("|");
|
|
27509
|
+
if (sig === tag.sig) {
|
|
27510
|
+
zoomCardTag(tag, context.zoom);
|
|
27511
|
+
return;
|
|
27512
|
+
}
|
|
27513
|
+
tag.sig = sig;
|
|
27514
|
+
const color = context.palette.muted;
|
|
27515
|
+
const pixel = context.style.icons === "pixel";
|
|
27516
|
+
drawCardGlyph(tag.icon.clear(), input.glyph, color, pixel);
|
|
27517
|
+
tag.text.style.fill = color;
|
|
27518
|
+
tag.text.style.fontFamily = context.style.font;
|
|
27519
|
+
fitTextToWidth(tag.text, input.text, Math.max(1, input.width - ICON - GAP$2));
|
|
27520
|
+
tag.text.position.set(17, (ICON - tag.text.height) / 2);
|
|
27521
|
+
zoomCardTag(tag, context.zoom);
|
|
27522
|
+
}
|
|
27523
|
+
//#endregion
|
|
27161
27524
|
//#region ../sdk/src/board/render/clip.ts
|
|
27162
27525
|
function isClippingFrame(item) {
|
|
27163
27526
|
return item.type === "frame" && item.props.clip !== false;
|
|
@@ -27221,7 +27584,7 @@ function audioWaveformBars(seed, count) {
|
|
|
27221
27584
|
}
|
|
27222
27585
|
return bars;
|
|
27223
27586
|
}
|
|
27224
|
-
function drawAudioWaveform(graphics, seed, rect, color, alpha = .72) {
|
|
27587
|
+
function drawAudioWaveform(graphics, seed, rect, color, alpha = .72, square = false) {
|
|
27225
27588
|
const count = Math.max(8, Math.min(DEFAULT_BARS, Math.floor(rect.width / 4)));
|
|
27226
27589
|
const step = rect.width / count;
|
|
27227
27590
|
const barWidth = Math.max(1.5, step - BAR_GAP);
|
|
@@ -27230,53 +27593,225 @@ function drawAudioWaveform(graphics, seed, rect, color, alpha = .72) {
|
|
|
27230
27593
|
const bars = audioWaveformBars(seed, count);
|
|
27231
27594
|
for (let index = 0; index < count; index += 1) {
|
|
27232
27595
|
const height = Math.max(2, (bars[index] ?? .4) * maxHeight);
|
|
27233
|
-
|
|
27234
|
-
|
|
27235
|
-
|
|
27236
|
-
});
|
|
27596
|
+
const x = rect.x + index * step;
|
|
27597
|
+
if (square) graphics.rect(x, centerY - height / 2, barWidth, height);
|
|
27598
|
+
else graphics.roundRect(x, centerY - height / 2, barWidth, height, barWidth / 2);
|
|
27237
27599
|
}
|
|
27600
|
+
graphics.fill({
|
|
27601
|
+
color,
|
|
27602
|
+
alpha
|
|
27603
|
+
});
|
|
27238
27604
|
}
|
|
27239
27605
|
//#endregion
|
|
27240
|
-
//#region ../sdk/src/board/render/
|
|
27241
|
-
const
|
|
27242
|
-
function
|
|
27243
|
-
return Math.
|
|
27244
|
-
|
|
27245
|
-
|
|
27246
|
-
* Zoom buckets for text re-rasterisation. Pixi Text is a bitmap: at high zoom it
|
|
27247
|
-
* looks soft unless we raise its resolution. We quantise zoom into a few
|
|
27248
|
-
* buckets so small zoom changes don't thrash texture regeneration.
|
|
27249
|
-
*/
|
|
27250
|
-
const TEXT_ZOOM_BUCKETS = [
|
|
27251
|
-
.5,
|
|
27252
|
-
1,
|
|
27253
|
-
1.5,
|
|
27254
|
-
2,
|
|
27255
|
-
3,
|
|
27256
|
-
4
|
|
27257
|
-
];
|
|
27258
|
-
function textZoomBucket(zoom) {
|
|
27259
|
-
const clamped = Math.max(.1, Math.min(4, zoom));
|
|
27260
|
-
for (const bucket of TEXT_ZOOM_BUCKETS) if (clamped <= bucket) return bucket;
|
|
27261
|
-
return TEXT_ZOOM_BUCKETS[TEXT_ZOOM_BUCKETS.length - 1] ?? 4;
|
|
27606
|
+
//#region ../sdk/src/board/render/stroke.ts
|
|
27607
|
+
const HEAD_SPREAD = Math.PI / 6;
|
|
27608
|
+
function dashPattern(dash, width) {
|
|
27609
|
+
if (dash === "dashed") return [Math.max(6, width * 4), Math.max(4, width * 3)];
|
|
27610
|
+
if (dash === "dotted") return [Math.max(.5, width * .01), Math.max(3, width * 2)];
|
|
27611
|
+
return null;
|
|
27262
27612
|
}
|
|
27263
|
-
|
|
27264
|
-
|
|
27265
|
-
|
|
27266
|
-
|
|
27613
|
+
function trimPolyline(path, trim) {
|
|
27614
|
+
if (trim === void 0 || trim >= 1 || path.length < 2) return path;
|
|
27615
|
+
if (trim <= 0) return [];
|
|
27616
|
+
let total = 0;
|
|
27617
|
+
for (let index = 1; index < path.length; index += 1) {
|
|
27618
|
+
const a = path[index - 1];
|
|
27619
|
+
const b = path[index];
|
|
27620
|
+
total += Math.hypot(b.x - a.x, b.y - a.y);
|
|
27621
|
+
}
|
|
27622
|
+
let remaining = total * trim;
|
|
27623
|
+
const out = [path[0]];
|
|
27624
|
+
for (let index = 1; index < path.length; index += 1) {
|
|
27625
|
+
const a = path[index - 1];
|
|
27626
|
+
const b = path[index];
|
|
27627
|
+
const length = Math.hypot(b.x - a.x, b.y - a.y);
|
|
27628
|
+
if (length >= remaining) {
|
|
27629
|
+
const t = length > 0 ? remaining / length : 0;
|
|
27630
|
+
out.push(worldPoint(a.x + (b.x - a.x) * t, a.y + (b.y - a.y) * t));
|
|
27631
|
+
return out;
|
|
27632
|
+
}
|
|
27633
|
+
out.push(b);
|
|
27634
|
+
remaining -= length;
|
|
27635
|
+
}
|
|
27636
|
+
return out;
|
|
27267
27637
|
}
|
|
27268
|
-
|
|
27269
|
-
|
|
27270
|
-
|
|
27271
|
-
if (
|
|
27272
|
-
|
|
27273
|
-
|
|
27638
|
+
function tracePolyline(graphics, path, pattern, closed = false, offset = 0) {
|
|
27639
|
+
const points = closed && path.length > 2 ? [...path, path[0]] : path;
|
|
27640
|
+
if (points.length < 2) return;
|
|
27641
|
+
if (!pattern) {
|
|
27642
|
+
const first = points[0];
|
|
27643
|
+
graphics.moveTo(first.x, first.y);
|
|
27644
|
+
for (let index = 1; index < points.length; index += 1) {
|
|
27645
|
+
const point = points[index];
|
|
27646
|
+
graphics.lineTo(point.x, point.y);
|
|
27647
|
+
}
|
|
27648
|
+
if (closed) graphics.closePath();
|
|
27649
|
+
return;
|
|
27650
|
+
}
|
|
27651
|
+
const [dash, gap] = pattern;
|
|
27652
|
+
const phase = Math.max(0, offset) % (dash + gap);
|
|
27653
|
+
let penDown = phase < dash;
|
|
27654
|
+
let fresh = penDown;
|
|
27655
|
+
let remaining = penDown ? dash - phase : dash + gap - phase;
|
|
27656
|
+
for (let index = 1; index < points.length; index += 1) {
|
|
27657
|
+
const a = points[index - 1];
|
|
27658
|
+
const b = points[index];
|
|
27659
|
+
const dx = b.x - a.x;
|
|
27660
|
+
const dy = b.y - a.y;
|
|
27661
|
+
const length = Math.hypot(dx, dy);
|
|
27662
|
+
let travelled = 0;
|
|
27663
|
+
while (length - travelled > 1e-4) {
|
|
27664
|
+
const step = Math.min(length - travelled, remaining);
|
|
27665
|
+
if (penDown) {
|
|
27666
|
+
const t0 = travelled / length;
|
|
27667
|
+
const t1 = (travelled + step) / length;
|
|
27668
|
+
if (fresh) graphics.moveTo(a.x + dx * t0, a.y + dy * t0);
|
|
27669
|
+
fresh = false;
|
|
27670
|
+
graphics.lineTo(a.x + dx * t1, a.y + dy * t1);
|
|
27671
|
+
}
|
|
27672
|
+
travelled += step;
|
|
27673
|
+
remaining -= step;
|
|
27674
|
+
if (remaining <= 1e-4) {
|
|
27675
|
+
penDown = !penDown;
|
|
27676
|
+
fresh = penDown;
|
|
27677
|
+
remaining = penDown ? dash : gap;
|
|
27678
|
+
}
|
|
27679
|
+
}
|
|
27680
|
+
}
|
|
27274
27681
|
}
|
|
27275
|
-
|
|
27276
|
-
|
|
27277
|
-
|
|
27278
|
-
|
|
27279
|
-
|
|
27682
|
+
function traceArrowhead(graphics, tip, angle, size) {
|
|
27683
|
+
graphics.moveTo(tip.x - size * Math.cos(angle - HEAD_SPREAD), tip.y - size * Math.sin(angle - HEAD_SPREAD)).lineTo(tip.x, tip.y).lineTo(tip.x - size * Math.cos(angle + HEAD_SPREAD), tip.y - size * Math.sin(angle + HEAD_SPREAD));
|
|
27684
|
+
}
|
|
27685
|
+
function endAngle(path, atStart) {
|
|
27686
|
+
if (path.length < 2) return null;
|
|
27687
|
+
const tip = atStart ? path[0] : path[path.length - 1];
|
|
27688
|
+
for (let offset = 1; offset < path.length; offset += 1) {
|
|
27689
|
+
const other = atStart ? path[offset] : path[path.length - 1 - offset];
|
|
27690
|
+
if (Math.hypot(tip.x - other.x, tip.y - other.y) > .001) return Math.atan2(tip.y - other.y, tip.x - other.x);
|
|
27691
|
+
}
|
|
27692
|
+
return null;
|
|
27693
|
+
}
|
|
27694
|
+
function roundRectPoints(width, height, radius) {
|
|
27695
|
+
const r = Math.min(radius, width / 2, height / 2);
|
|
27696
|
+
if (r <= 0) return [
|
|
27697
|
+
worldPoint(0, 0),
|
|
27698
|
+
worldPoint(width, 0),
|
|
27699
|
+
worldPoint(width, height),
|
|
27700
|
+
worldPoint(0, height),
|
|
27701
|
+
worldPoint(0, 0)
|
|
27702
|
+
];
|
|
27703
|
+
const corner = (cx, cy, from) => Array.from({ length: 9 }, (_, index) => {
|
|
27704
|
+
const angle = from + index / 8 * (Math.PI / 2);
|
|
27705
|
+
return worldPoint(cx + Math.cos(angle) * r, cy + Math.sin(angle) * r);
|
|
27706
|
+
});
|
|
27707
|
+
return [
|
|
27708
|
+
...corner(width - r, r, -Math.PI / 2),
|
|
27709
|
+
...corner(width - r, height - r, 0),
|
|
27710
|
+
...corner(r, height - r, Math.PI / 2),
|
|
27711
|
+
...corner(r, r, Math.PI),
|
|
27712
|
+
worldPoint(width - r, 0)
|
|
27713
|
+
];
|
|
27714
|
+
}
|
|
27715
|
+
const SHADOW_LAYERS = 5;
|
|
27716
|
+
function traceCardOutline(graphics, rect, style, grow = 0) {
|
|
27717
|
+
const x = rect.x - grow;
|
|
27718
|
+
const y = rect.y - grow;
|
|
27719
|
+
const width = Math.max(0, rect.width + grow * 2);
|
|
27720
|
+
const height = Math.max(0, rect.height + grow * 2);
|
|
27721
|
+
if (style.corner === "pixel") return tracePixelRect(graphics, x, y, width, height, 2);
|
|
27722
|
+
const radius = Math.min(Math.max(0, style.radius + grow), width / 2, height / 2);
|
|
27723
|
+
return radius > 0 ? graphics.roundRect(x, y, width, height, radius) : graphics.rect(x, y, width, height);
|
|
27724
|
+
}
|
|
27725
|
+
function tracePixelRect(graphics, x, y, width, height, step) {
|
|
27726
|
+
const s = Math.min(step, width / 4, height / 4);
|
|
27727
|
+
if (s <= 0) return graphics.rect(x, y, width, height);
|
|
27728
|
+
return graphics.poly(pixelRectPoints(x, y, width, height, s).flatMap((point) => [point.x, point.y]));
|
|
27729
|
+
}
|
|
27730
|
+
function pixelRectPoints(x, y, width, height, s) {
|
|
27731
|
+
const r = x + width;
|
|
27732
|
+
const b = y + height;
|
|
27733
|
+
const p = worldPoint;
|
|
27734
|
+
return [
|
|
27735
|
+
p(x, y + s * 2),
|
|
27736
|
+
p(x + s, y + s * 2),
|
|
27737
|
+
p(x + s, y + s),
|
|
27738
|
+
p(x + s * 2, y + s),
|
|
27739
|
+
p(x + s * 2, y),
|
|
27740
|
+
p(r - s * 2, y),
|
|
27741
|
+
p(r - s * 2, y + s),
|
|
27742
|
+
p(r - s, y + s),
|
|
27743
|
+
p(r - s, y + s * 2),
|
|
27744
|
+
p(r, y + s * 2),
|
|
27745
|
+
p(r, b - s * 2),
|
|
27746
|
+
p(r - s, b - s * 2),
|
|
27747
|
+
p(r - s, b - s),
|
|
27748
|
+
p(r - s * 2, b - s),
|
|
27749
|
+
p(r - s * 2, b),
|
|
27750
|
+
p(x + s * 2, b),
|
|
27751
|
+
p(x + s * 2, b - s),
|
|
27752
|
+
p(x + s, b - s),
|
|
27753
|
+
p(x + s, b - s * 2),
|
|
27754
|
+
p(x, b - s * 2)
|
|
27755
|
+
];
|
|
27756
|
+
}
|
|
27757
|
+
function drawCardShadow(graphics, rect, style, shadow) {
|
|
27758
|
+
if (!shadow || shadow.alpha <= 0 || shadow.blur <= 0) return;
|
|
27759
|
+
const offset = {
|
|
27760
|
+
...rect,
|
|
27761
|
+
y: rect.y + shadow.y
|
|
27762
|
+
};
|
|
27763
|
+
const reach = (index) => (1 - index / SHADOW_LAYERS) ** 2;
|
|
27764
|
+
for (let index = SHADOW_LAYERS; index >= 1; index -= 1) {
|
|
27765
|
+
const alpha = shadow.alpha * (reach(index - 1) - reach(index));
|
|
27766
|
+
traceCardOutline(graphics, offset, style, shadow.blur * index / SHADOW_LAYERS).fill({
|
|
27767
|
+
color: shadow.color,
|
|
27768
|
+
alpha
|
|
27769
|
+
});
|
|
27770
|
+
traceCardOutline(graphics, rect, style).cut();
|
|
27771
|
+
}
|
|
27772
|
+
}
|
|
27773
|
+
function cardShadow(style, elevation) {
|
|
27774
|
+
const shadow = style.shadow;
|
|
27775
|
+
if (!shadow || elevation === 0) return null;
|
|
27776
|
+
if (elevation === 1) return shadow;
|
|
27777
|
+
return {
|
|
27778
|
+
...shadow,
|
|
27779
|
+
alpha: Math.min(1, shadow.alpha * 1.6),
|
|
27780
|
+
blur: shadow.blur * 1.6,
|
|
27781
|
+
y: shadow.y * 2 + 4
|
|
27782
|
+
};
|
|
27783
|
+
}
|
|
27784
|
+
function drawCardSurface(graphics, rect, style, surface) {
|
|
27785
|
+
drawCardShadow(graphics, rect, style, cardShadow(style, surface.elevation ?? 0));
|
|
27786
|
+
traceCardOutline(graphics, rect, style).fill({
|
|
27787
|
+
color: surface.fill,
|
|
27788
|
+
alpha: surface.fillAlpha ?? 1
|
|
27789
|
+
});
|
|
27790
|
+
if (surface.border != null) traceCardOutline(graphics, rect, style).stroke({
|
|
27791
|
+
color: surface.border,
|
|
27792
|
+
width: 1,
|
|
27793
|
+
alpha: surface.borderAlpha ?? 1,
|
|
27794
|
+
alignment: 1
|
|
27795
|
+
});
|
|
27796
|
+
return graphics;
|
|
27797
|
+
}
|
|
27798
|
+
function containRect(width, height, imageWidth, imageHeight) {
|
|
27799
|
+
if (width <= 0 || height <= 0 || imageWidth <= 0 || imageHeight <= 0) return {
|
|
27800
|
+
x: 0,
|
|
27801
|
+
y: 0,
|
|
27802
|
+
width: 0,
|
|
27803
|
+
height: 0
|
|
27804
|
+
};
|
|
27805
|
+
const scale = Math.min(width / imageWidth, height / imageHeight);
|
|
27806
|
+
return {
|
|
27807
|
+
x: (width - imageWidth * scale) / 2,
|
|
27808
|
+
y: (height - imageHeight * scale) / 2,
|
|
27809
|
+
width: imageWidth * scale,
|
|
27810
|
+
height: imageHeight * scale
|
|
27811
|
+
};
|
|
27812
|
+
}
|
|
27813
|
+
function cardElevation(context, id) {
|
|
27814
|
+
return context.liftedIds.has(id) ? 2 : 1;
|
|
27280
27815
|
}
|
|
27281
27816
|
//#endregion
|
|
27282
27817
|
//#region ../sdk/src/board/render/renderers/base-card-renderer.ts
|
|
@@ -27288,7 +27823,10 @@ function createLabel(text, style) {
|
|
|
27288
27823
|
return new Text({
|
|
27289
27824
|
...TEXT_OPTIONS,
|
|
27290
27825
|
text,
|
|
27291
|
-
style
|
|
27826
|
+
style: {
|
|
27827
|
+
fontFamily: BOARD_FONT_STACK,
|
|
27828
|
+
...style
|
|
27829
|
+
}
|
|
27292
27830
|
});
|
|
27293
27831
|
}
|
|
27294
27832
|
function positionShell(root, item) {
|
|
@@ -27370,796 +27908,162 @@ function drawFarStroke(graphics, points, style) {
|
|
|
27370
27908
|
});
|
|
27371
27909
|
}
|
|
27372
27910
|
//#endregion
|
|
27373
|
-
//#region ../sdk/src/board/render/renderers/
|
|
27374
|
-
const
|
|
27375
|
-
const
|
|
27376
|
-
|
|
27377
|
-
const
|
|
27378
|
-
const
|
|
27379
|
-
|
|
27380
|
-
const
|
|
27381
|
-
|
|
27382
|
-
|
|
27383
|
-
|
|
27384
|
-
|
|
27385
|
-
const
|
|
27386
|
-
const
|
|
27387
|
-
const
|
|
27388
|
-
|
|
27389
|
-
|
|
27390
|
-
const partsByContainer$12 = /* @__PURE__ */ new WeakMap();
|
|
27391
|
-
function detailFor(zoom) {
|
|
27392
|
-
if (zoom < LOD_TITLE_ZOOM) return "plate";
|
|
27393
|
-
if (zoom < LOD_BODY_ZOOM) return "title";
|
|
27394
|
-
return "full";
|
|
27395
|
-
}
|
|
27396
|
-
function coverHeight(item, height) {
|
|
27397
|
-
if (filePreviewKind(item.props.snapshot) !== "cover") return 0;
|
|
27398
|
-
const ideal = Math.round(height * COVER_RATIO);
|
|
27399
|
-
return Math.max(0, Math.min(ideal, height - MIN_BODY_FOR_COVER));
|
|
27400
|
-
}
|
|
27401
|
-
function fitLineWithEllipsis(line, wrapWidth, measureWidth) {
|
|
27402
|
-
const trimmed = line.replace(/\s+$/u, "");
|
|
27403
|
-
if (!trimmed) return "…";
|
|
27404
|
-
const full = `${trimmed}…`;
|
|
27405
|
-
if (measureWidth(full) <= wrapWidth) return full;
|
|
27406
|
-
let lo = 0;
|
|
27407
|
-
let hi = trimmed.length;
|
|
27408
|
-
let best = "…";
|
|
27409
|
-
while (lo <= hi) {
|
|
27410
|
-
const mid = lo + hi >> 1;
|
|
27411
|
-
const candidate = mid > 0 ? `${trimmed.slice(0, mid)}…` : "…";
|
|
27412
|
-
if (measureWidth(candidate) <= wrapWidth) {
|
|
27413
|
-
best = candidate;
|
|
27414
|
-
lo = mid + 1;
|
|
27415
|
-
} else hi = mid - 1;
|
|
27416
|
-
}
|
|
27417
|
-
return best;
|
|
27418
|
-
}
|
|
27419
|
-
function fitTextToLines(text, value, maxLines, wrapWidth) {
|
|
27420
|
-
const width = Math.max(1, wrapWidth);
|
|
27421
|
-
text.style.wordWrapWidth = width;
|
|
27422
|
-
if (!value || maxLines <= 0) {
|
|
27423
|
-
if (text.text !== "") text.text = "";
|
|
27424
|
-
return;
|
|
27425
|
-
}
|
|
27426
|
-
const charCap = Math.max(maxLines * Math.ceil(width), maxLines * 4);
|
|
27427
|
-
const sample = value.length > charCap ? value.slice(0, charCap) : value;
|
|
27428
|
-
const metrics = CanvasTextMetrics.measureText(sample, text.style);
|
|
27429
|
-
if (!(metrics.lines.length > maxLines || sample !== value)) {
|
|
27430
|
-
if (text.text !== value) text.text = value;
|
|
27911
|
+
//#region ../sdk/src/board/render/renderers/media-key.ts
|
|
27912
|
+
const MEDIA_SCRIM = 0;
|
|
27913
|
+
const MEDIA_INK = 16777215;
|
|
27914
|
+
function drawMediaPlayKey(graphics, cx, cy, radius, context, solid = false) {
|
|
27915
|
+
const face = solid ? context.palette.text : MEDIA_SCRIM;
|
|
27916
|
+
const ink = solid ? context.palette.surface : MEDIA_INK;
|
|
27917
|
+
if (context.style.corner === "pixel") {
|
|
27918
|
+
const size = Math.round(radius * 1.6);
|
|
27919
|
+
tracePixelRect(graphics, Math.round(cx - size / 2), Math.round(cy - size / 2), size, size, 2).fill({
|
|
27920
|
+
color: face,
|
|
27921
|
+
alpha: solid ? 1 : .62
|
|
27922
|
+
});
|
|
27923
|
+
const cell = Math.max(1, Math.round(size / 14));
|
|
27924
|
+
const x = Math.round(cx - cell * 1.5);
|
|
27925
|
+
const y = Math.round(cy - cell * 3.5);
|
|
27926
|
+
for (let row = 0; row < 7; row += 1) graphics.rect(x, y + row * cell, (4 - Math.abs(row - 3)) * cell, cell);
|
|
27927
|
+
graphics.fill({ color: ink });
|
|
27431
27928
|
return;
|
|
27432
27929
|
}
|
|
27433
|
-
|
|
27434
|
-
|
|
27435
|
-
|
|
27436
|
-
|
|
27437
|
-
|
|
27438
|
-
|
|
27439
|
-
|
|
27440
|
-
|
|
27441
|
-
|
|
27442
|
-
|
|
27443
|
-
|
|
27444
|
-
|
|
27930
|
+
graphics.circle(cx, cy, radius).fill({
|
|
27931
|
+
color: face,
|
|
27932
|
+
alpha: solid ? 1 : .45
|
|
27933
|
+
});
|
|
27934
|
+
const size = radius * .5;
|
|
27935
|
+
graphics.poly([
|
|
27936
|
+
cx - size * .45,
|
|
27937
|
+
cy - size * .75,
|
|
27938
|
+
cx + size * .8,
|
|
27939
|
+
cy,
|
|
27940
|
+
cx - size * .45,
|
|
27941
|
+
cy + size * .75
|
|
27942
|
+
]).fill({
|
|
27943
|
+
color: ink,
|
|
27944
|
+
alpha: .96
|
|
27945
|
+
});
|
|
27445
27946
|
}
|
|
27446
|
-
|
|
27447
|
-
|
|
27448
|
-
|
|
27449
|
-
|
|
27450
|
-
|
|
27451
|
-
height: 0
|
|
27452
|
-
};
|
|
27453
|
-
const scale = Math.min(width / imageWidth, height / imageHeight);
|
|
27454
|
-
const renderedWidth = imageWidth * scale;
|
|
27455
|
-
const renderedHeight = imageHeight * scale;
|
|
27947
|
+
const GAP$1 = 12;
|
|
27948
|
+
const WAVE_HEIGHT = 16;
|
|
27949
|
+
const partsByContainer$12 = /* @__PURE__ */ new WeakMap();
|
|
27950
|
+
function audioKeyCenter(width, height) {
|
|
27951
|
+
const radius = Math.min(16, Math.max(8, height / 2 - 8), width / 4);
|
|
27456
27952
|
return {
|
|
27457
|
-
x:
|
|
27458
|
-
y:
|
|
27459
|
-
|
|
27460
|
-
height: renderedHeight
|
|
27953
|
+
x: 14 + radius,
|
|
27954
|
+
y: height / 2,
|
|
27955
|
+
radius
|
|
27461
27956
|
};
|
|
27462
27957
|
}
|
|
27463
|
-
function layoutCover(sprite, width, height, texture) {
|
|
27464
|
-
const rect = containCoverRect(width, height, texture.width, texture.height);
|
|
27465
|
-
sprite.position.set(rect.x, rect.y);
|
|
27466
|
-
sprite.width = rect.width;
|
|
27467
|
-
sprite.height = rect.height;
|
|
27468
|
-
}
|
|
27469
|
-
function syncClip(parts, width, height) {
|
|
27470
|
-
parts.clip.clear().roundRect(0, 0, Math.max(1, width), Math.max(1, height), RADIUS$5).fill({ color: 16777215 });
|
|
27471
|
-
}
|
|
27472
27958
|
function sync$12(container, item, context) {
|
|
27473
27959
|
const parts = partsByContainer$12.get(container);
|
|
27474
27960
|
if (!parts) return;
|
|
27475
27961
|
positionShell(parts.root, item);
|
|
27476
27962
|
const { width, height } = item.frame;
|
|
27477
|
-
const
|
|
27478
|
-
const
|
|
27479
|
-
const
|
|
27480
|
-
|
|
27481
|
-
const
|
|
27482
|
-
const
|
|
27483
|
-
const fileState = context.fileState(item.props.src);
|
|
27484
|
-
const band = coverHeight(item, height);
|
|
27485
|
-
const kind = filePreviewKind(item.props.snapshot);
|
|
27486
|
-
const category = fileCategory(item.props.src, item.props.snapshot?.mimeType);
|
|
27487
|
-
const accent = fileCategoryAccent(category, context.palette);
|
|
27488
|
-
syncTextResolution(parts.title, parts.titleRes, context.zoom);
|
|
27489
|
-
syncTextResolution(parts.excerpt, parts.excerptRes, context.zoom);
|
|
27490
|
-
syncTextResolution(parts.typeMark, parts.typeMarkRes, context.zoom);
|
|
27491
|
-
const visualSig = [
|
|
27492
|
-
key ?? "",
|
|
27963
|
+
const title = item.props.snapshot?.title ?? getMediaResourceTitle(item.props.src);
|
|
27964
|
+
const durationMs = item.props.snapshot?.durationMs;
|
|
27965
|
+
const detailed = boardCardDetailed(context.zoom);
|
|
27966
|
+
syncTextResolution(parts.title, parts, context.zoom);
|
|
27967
|
+
const elevation = cardElevation(context, item.id);
|
|
27968
|
+
const sig = [
|
|
27493
27969
|
width,
|
|
27494
27970
|
height,
|
|
27495
|
-
|
|
27496
|
-
|
|
27497
|
-
|
|
27498
|
-
|
|
27499
|
-
|
|
27500
|
-
|
|
27501
|
-
|
|
27502
|
-
category,
|
|
27503
|
-
context.colorScheme,
|
|
27504
|
-
context.palette.surface,
|
|
27505
|
-
context.palette.hover,
|
|
27506
|
-
accent
|
|
27971
|
+
title,
|
|
27972
|
+
durationMs ?? "",
|
|
27973
|
+
detailed,
|
|
27974
|
+
elevation,
|
|
27975
|
+
item.props.src,
|
|
27976
|
+
item.props.snapshot?.mtimeMs ?? "",
|
|
27977
|
+
context.themeKey
|
|
27507
27978
|
].join("|");
|
|
27508
|
-
if (
|
|
27509
|
-
|
|
27510
|
-
|
|
27511
|
-
parts.plate.clear();
|
|
27512
|
-
parts.plate.roundRect(0, 0, width, height, RADIUS$5).fill({
|
|
27513
|
-
color: context.palette.surface,
|
|
27514
|
-
alpha: .98
|
|
27515
|
-
}).roundRect(0, 0, width, height, RADIUS$5).stroke({
|
|
27516
|
-
color: selected ? context.palette.brand : hovered ? context.palette.muted : context.palette.border,
|
|
27517
|
-
width: selected ? 2 : 1,
|
|
27518
|
-
alpha: selected ? .95 : .85
|
|
27519
|
-
});
|
|
27520
|
-
if (fileState !== "ok") {
|
|
27521
|
-
const dash = Math.max(6, width / MAX_DASHES / 2);
|
|
27522
|
-
for (let x = 0; x < width; x += dash * 2) parts.plate.moveTo(x, .5).lineTo(Math.min(x + dash, width), .5);
|
|
27523
|
-
parts.plate.stroke({
|
|
27524
|
-
color: context.palette.muted,
|
|
27525
|
-
width: 2,
|
|
27526
|
-
alpha: fileState === "missing" ? .9 : .5
|
|
27527
|
-
});
|
|
27528
|
-
}
|
|
27529
|
-
const showCover = band > 0 && Boolean(texture);
|
|
27530
|
-
if (band > 0) parts.plate.rect(1, 1, width - 2, band - 1).fill({
|
|
27531
|
-
color: context.palette.hover,
|
|
27532
|
-
alpha: coverFailed ? .35 : .6
|
|
27533
|
-
});
|
|
27534
|
-
if (showCover && texture) {
|
|
27535
|
-
if (parts.cover.texture !== texture) parts.cover.texture = texture;
|
|
27536
|
-
layoutCover(parts.cover, width, band, texture);
|
|
27537
|
-
parts.coverMask.clear().roundRect(0, 0, width, band, RADIUS$5).fill({ color: 16777215 });
|
|
27538
|
-
parts.coverMask.rect(0, band - RADIUS$5, width, RADIUS$5).fill({ color: 16777215 });
|
|
27539
|
-
}
|
|
27540
|
-
parts.cover.visible = showCover;
|
|
27541
|
-
parts.coverMask.visible = showCover;
|
|
27542
|
-
if (!band) parts.plate.rect(1, 1, STRIPE, height - 2).fill({
|
|
27543
|
-
color: accent,
|
|
27544
|
-
alpha: .55
|
|
27545
|
-
});
|
|
27546
|
-
parts.title.visible = detail !== "plate";
|
|
27547
|
-
parts.excerpt.visible = detail === "full";
|
|
27548
|
-
parts.typeMark.visible = kind === "blank" && detail !== "plate";
|
|
27549
|
-
}
|
|
27550
|
-
if (detail === "plate") {
|
|
27551
|
-
parts.typeMark.visible = false;
|
|
27552
|
-
return;
|
|
27553
|
-
}
|
|
27554
|
-
const title = item.props.snapshot?.title || fileStem(item.props.src);
|
|
27555
|
-
const excerpt = item.props.snapshot?.excerpt ?? "";
|
|
27556
|
-
const mark = fileTypeLabel(item.props.src);
|
|
27557
|
-
const innerWidth = Math.max(1, width - 20);
|
|
27558
|
-
const showTypeMark = kind === "blank";
|
|
27559
|
-
const textSig = [
|
|
27560
|
-
title,
|
|
27561
|
-
excerpt,
|
|
27562
|
-
mark,
|
|
27563
|
-
detail,
|
|
27564
|
-
innerWidth,
|
|
27565
|
-
band,
|
|
27566
|
-
height,
|
|
27567
|
-
kind,
|
|
27568
|
-
context.palette.text,
|
|
27569
|
-
context.palette.muted,
|
|
27570
|
-
accent
|
|
27571
|
-
].join("|");
|
|
27572
|
-
if (textSig === parts.textSig) return;
|
|
27573
|
-
parts.textSig = textSig;
|
|
27574
|
-
const top = band > 0 ? band + PADDING$1 * .8 : PADDING$1;
|
|
27575
|
-
const contentBottom = height - PADDING$1;
|
|
27576
|
-
let cursor = top;
|
|
27577
|
-
if (showTypeMark) {
|
|
27578
|
-
const markSize = Math.max(18, Math.min(TYPE_MARK_SIZE, Math.round(height * .22)));
|
|
27579
|
-
parts.typeMark.style.fill = accent;
|
|
27580
|
-
parts.typeMark.style.fontSize = markSize;
|
|
27581
|
-
parts.typeMark.style.lineHeight = markSize * 1.1;
|
|
27582
|
-
if (parts.typeMark.text !== mark) parts.typeMark.text = mark;
|
|
27583
|
-
parts.typeMark.position.set(PADDING$1, cursor);
|
|
27584
|
-
parts.typeMark.visible = true;
|
|
27585
|
-
cursor += parts.typeMark.height + GAP;
|
|
27586
|
-
} else parts.typeMark.visible = false;
|
|
27587
|
-
const titleLines = linesInRoom(Math.max(0, contentBottom - cursor), TITLE_LINE, TITLE_MAX_LINES);
|
|
27588
|
-
parts.title.style.fill = context.palette.text;
|
|
27589
|
-
fitTextToLines(parts.title, title, titleLines, innerWidth);
|
|
27590
|
-
parts.title.position.set(PADDING$1, cursor);
|
|
27591
|
-
parts.title.visible = titleLines > 0;
|
|
27592
|
-
if (detail !== "full") {
|
|
27593
|
-
parts.excerpt.visible = false;
|
|
27594
|
-
return;
|
|
27595
|
-
}
|
|
27596
|
-
const excerptTop = cursor + (titleLines > 0 ? parts.title.height + GAP : 0);
|
|
27597
|
-
const excerptLines = linesInRoom(contentBottom - excerptTop, EXCERPT_LINE, EXCERPT_MAX_LINES);
|
|
27598
|
-
const showExcerpt = Boolean(excerpt) && excerptLines > 0;
|
|
27599
|
-
if (showExcerpt) {
|
|
27600
|
-
parts.excerpt.style.fill = context.palette.muted;
|
|
27601
|
-
fitTextToLines(parts.excerpt, excerpt, excerptLines, innerWidth);
|
|
27602
|
-
parts.excerpt.position.set(PADDING$1, excerptTop);
|
|
27603
|
-
}
|
|
27604
|
-
parts.excerpt.visible = showExcerpt;
|
|
27605
|
-
}
|
|
27606
|
-
const fileCardRenderer = {
|
|
27607
|
-
id: "file-card",
|
|
27608
|
-
canRender: (item) => item.type === "file",
|
|
27609
|
-
create: (item, context) => {
|
|
27610
|
-
const root = new Container();
|
|
27611
|
-
const plate = new Graphics();
|
|
27612
|
-
const body = new Container();
|
|
27613
|
-
const clip = new Graphics();
|
|
27614
|
-
const cover = new Sprite(Texture.EMPTY);
|
|
27615
|
-
const coverMask = new Graphics();
|
|
27616
|
-
cover.mask = coverMask;
|
|
27617
|
-
const resolution = 1;
|
|
27618
|
-
const title = new Text({
|
|
27619
|
-
text: "",
|
|
27620
|
-
style: {
|
|
27621
|
-
fill: context.palette.text,
|
|
27622
|
-
fontFamily: BOARD_FONT_STACK,
|
|
27623
|
-
fontSize: TITLE_SIZE,
|
|
27624
|
-
fontWeight: "600",
|
|
27625
|
-
wordWrap: true,
|
|
27626
|
-
breakWords: true,
|
|
27627
|
-
lineHeight: TITLE_LINE
|
|
27628
|
-
},
|
|
27629
|
-
resolution,
|
|
27630
|
-
roundPixels: true
|
|
27631
|
-
});
|
|
27632
|
-
const excerpt = new Text({
|
|
27633
|
-
text: "",
|
|
27634
|
-
style: {
|
|
27635
|
-
fill: context.palette.muted,
|
|
27636
|
-
fontFamily: BOARD_FONT_STACK,
|
|
27637
|
-
fontSize: EXCERPT_SIZE,
|
|
27638
|
-
fontWeight: "400",
|
|
27639
|
-
wordWrap: true,
|
|
27640
|
-
breakWords: true,
|
|
27641
|
-
lineHeight: EXCERPT_LINE
|
|
27642
|
-
},
|
|
27643
|
-
resolution,
|
|
27644
|
-
roundPixels: true
|
|
27645
|
-
});
|
|
27646
|
-
const typeMark = new Text({
|
|
27647
|
-
text: "",
|
|
27648
|
-
style: {
|
|
27649
|
-
fill: context.palette.muted,
|
|
27650
|
-
fontFamily: BOARD_MONO_FONT_STACK,
|
|
27651
|
-
fontSize: TYPE_MARK_SIZE,
|
|
27652
|
-
fontWeight: "700",
|
|
27653
|
-
lineHeight: TYPE_MARK_SIZE * 1.1
|
|
27654
|
-
},
|
|
27655
|
-
resolution,
|
|
27656
|
-
roundPixels: true
|
|
27657
|
-
});
|
|
27658
|
-
body.mask = clip;
|
|
27659
|
-
body.addChild(cover, coverMask, typeMark, title, excerpt);
|
|
27660
|
-
root.addChild(plate, body, clip);
|
|
27661
|
-
partsByContainer$12.set(root, {
|
|
27662
|
-
root,
|
|
27663
|
-
plate,
|
|
27664
|
-
body,
|
|
27665
|
-
clip,
|
|
27666
|
-
cover,
|
|
27667
|
-
coverMask,
|
|
27668
|
-
typeMark,
|
|
27669
|
-
title,
|
|
27670
|
-
excerpt,
|
|
27671
|
-
visualSig: "",
|
|
27672
|
-
textSig: "",
|
|
27673
|
-
titleRes: { resolution },
|
|
27674
|
-
excerptRes: { resolution },
|
|
27675
|
-
typeMarkRes: { resolution }
|
|
27676
|
-
});
|
|
27677
|
-
if (item.type === "file") sync$12(root, item, context);
|
|
27678
|
-
return root;
|
|
27679
|
-
},
|
|
27680
|
-
update: (container, item, context) => {
|
|
27681
|
-
if (item.type === "file") sync$12(container, item, context);
|
|
27682
|
-
},
|
|
27683
|
-
renderFar: (graphics, item, context) => {
|
|
27684
|
-
const category = fileCategory(item.type === "file" ? item.props.src : "", item.type === "file" ? item.props.snapshot?.mimeType : void 0);
|
|
27685
|
-
drawFarPlate(graphics, item.frame, {
|
|
27686
|
-
fill: context.palette.surface,
|
|
27687
|
-
fillAlpha: .96,
|
|
27688
|
-
accent: fileCategoryAccent(category, context.palette),
|
|
27689
|
-
accentAlpha: .45
|
|
27690
|
-
});
|
|
27691
|
-
},
|
|
27692
|
-
destroy: (container) => {
|
|
27693
|
-
partsByContainer$12.get(container)?.root.destroy({ children: true });
|
|
27694
|
-
partsByContainer$12.delete(container);
|
|
27695
|
-
}
|
|
27696
|
-
};
|
|
27697
|
-
//#endregion
|
|
27698
|
-
//#region ../sdk/src/board/render/renderers/task-card-renderer.ts
|
|
27699
|
-
const RADIUS$4 = 4;
|
|
27700
|
-
const PADDING = 12;
|
|
27701
|
-
const META_HEIGHT = 28;
|
|
27702
|
-
const TASK_CARD_FULL_DETAIL_ZOOM = .55;
|
|
27703
|
-
const PLAY_BADGE_RADIUS = 15;
|
|
27704
|
-
const partsByContainer$11 = /* @__PURE__ */ new WeakMap();
|
|
27705
|
-
function previewKindFor(artifact) {
|
|
27706
|
-
if (!artifact) return "empty";
|
|
27707
|
-
if (artifact.type === "image" || artifact.type === "video") return "texture";
|
|
27708
|
-
if (artifact.type === "audio") return artifact.previewUrl ? "texture" : "waveform";
|
|
27709
|
-
return artifact.textExcerpt ? "text" : "empty";
|
|
27710
|
-
}
|
|
27711
|
-
function stateSurfaceFor(item, kind, hasTexture, previewFailed) {
|
|
27712
|
-
if (kind === "texture" && !hasTexture) {
|
|
27713
|
-
if (item.props.snapshot.status === "failed") return "failed";
|
|
27714
|
-
return previewFailed ? "unavailable" : "media-loading";
|
|
27715
|
-
}
|
|
27716
|
-
if (kind !== "empty") return null;
|
|
27717
|
-
if (item.props.snapshot.status === "failed") return "failed";
|
|
27718
|
-
if (item.props.snapshot.status === "running") return "generating";
|
|
27719
|
-
if (item.props.snapshot.status === "pending") return "queued";
|
|
27720
|
-
return "empty";
|
|
27721
|
-
}
|
|
27722
|
-
function stateLabel(surface) {
|
|
27723
|
-
switch (surface) {
|
|
27724
|
-
case "generating": return "Generating";
|
|
27725
|
-
case "queued": return "Queued";
|
|
27726
|
-
case "failed": return "Failed";
|
|
27727
|
-
case "unavailable": return "Preview unavailable";
|
|
27728
|
-
case "empty": return "No preview";
|
|
27729
|
-
default: return "";
|
|
27730
|
-
}
|
|
27731
|
-
}
|
|
27732
|
-
function statusColor(item, context) {
|
|
27733
|
-
if (item.props.snapshot.status === "failed") return context.colors.rose.stroke;
|
|
27734
|
-
if (item.props.snapshot.status === "running") return context.colors.brand.stroke;
|
|
27735
|
-
return context.colors.neutral.stroke;
|
|
27736
|
-
}
|
|
27737
|
-
function metadata(item) {
|
|
27738
|
-
const { artifactCount, artifacts } = item.props.snapshot;
|
|
27739
|
-
const extra = artifactCount > artifacts.length ? `${artifacts.length}/${artifactCount}` : artifactCount > 1 ? `+${artifactCount - 1}` : null;
|
|
27740
|
-
return [item.props.snapshot.model, extra].filter(Boolean).join(" · ");
|
|
27741
|
-
}
|
|
27742
|
-
function containTaskPreviewRect(width, height, imageWidth, imageHeight) {
|
|
27743
|
-
if (width <= 0 || height <= 0 || imageWidth <= 0 || imageHeight <= 0) return {
|
|
27979
|
+
if (sig === parts.sig) return;
|
|
27980
|
+
parts.sig = sig;
|
|
27981
|
+
drawCardSurface(parts.plate.clear(), {
|
|
27744
27982
|
x: 0,
|
|
27745
27983
|
y: 0,
|
|
27746
|
-
width: 0,
|
|
27747
|
-
height: 0
|
|
27748
|
-
};
|
|
27749
|
-
const scale = Math.min(width / imageWidth, height / imageHeight);
|
|
27750
|
-
const renderedWidth = imageWidth * scale;
|
|
27751
|
-
const renderedHeight = imageHeight * scale;
|
|
27752
|
-
return {
|
|
27753
|
-
x: (width - renderedWidth) / 2,
|
|
27754
|
-
y: (height - renderedHeight) / 2,
|
|
27755
|
-
width: renderedWidth,
|
|
27756
|
-
height: renderedHeight
|
|
27757
|
-
};
|
|
27758
|
-
}
|
|
27759
|
-
function drawPlayBadge(graphics, rect, context) {
|
|
27760
|
-
const radius = Math.min(PLAY_BADGE_RADIUS, Math.max(8, Math.min(rect.width, rect.height) * .16));
|
|
27761
|
-
const cx = rect.x + rect.width / 2;
|
|
27762
|
-
const cy = rect.y + rect.height / 2;
|
|
27763
|
-
graphics.circle(cx, cy, radius).fill({
|
|
27764
|
-
color: context.palette.bg,
|
|
27765
|
-
alpha: .64
|
|
27766
|
-
});
|
|
27767
|
-
const size = radius * .72;
|
|
27768
|
-
graphics.moveTo(cx - size * .34, cy - size * .56).lineTo(cx + size * .62, cy).lineTo(cx - size * .34, cy + size * .56).closePath().fill({
|
|
27769
|
-
color: context.palette.text,
|
|
27770
|
-
alpha: .94
|
|
27771
|
-
});
|
|
27772
|
-
}
|
|
27773
|
-
function drawStateMark(graphics, surface, cx, cy, color) {
|
|
27774
|
-
if (surface === "generating" || surface === "media-loading") {
|
|
27775
|
-
graphics.circle(cx, cy, 4).fill({
|
|
27776
|
-
color,
|
|
27777
|
-
alpha: .9
|
|
27778
|
-
});
|
|
27779
|
-
graphics.circle(cx - 12, cy + 7, 2.5).fill({
|
|
27780
|
-
color,
|
|
27781
|
-
alpha: .48
|
|
27782
|
-
});
|
|
27783
|
-
graphics.circle(cx + 11, cy + 6, 3).fill({
|
|
27784
|
-
color,
|
|
27785
|
-
alpha: .68
|
|
27786
|
-
});
|
|
27787
|
-
graphics.circle(cx + 3, cy - 12, 2).fill({
|
|
27788
|
-
color,
|
|
27789
|
-
alpha: .36
|
|
27790
|
-
});
|
|
27791
|
-
return;
|
|
27792
|
-
}
|
|
27793
|
-
if (surface === "queued") {
|
|
27794
|
-
graphics.circle(cx, cy, 10).stroke({
|
|
27795
|
-
color,
|
|
27796
|
-
width: 1.5,
|
|
27797
|
-
alpha: .62
|
|
27798
|
-
}).circle(cx, cy, 3).fill({
|
|
27799
|
-
color,
|
|
27800
|
-
alpha: .78
|
|
27801
|
-
});
|
|
27802
|
-
return;
|
|
27803
|
-
}
|
|
27804
|
-
if (surface === "failed") {
|
|
27805
|
-
graphics.circle(cx, cy, 11).stroke({
|
|
27806
|
-
color,
|
|
27807
|
-
width: 1.5,
|
|
27808
|
-
alpha: .86
|
|
27809
|
-
});
|
|
27810
|
-
graphics.moveTo(cx - 4, cy - 4).lineTo(cx + 4, cy + 4).moveTo(cx + 4, cy - 4).lineTo(cx - 4, cy + 4).stroke({
|
|
27811
|
-
color,
|
|
27812
|
-
width: 1.5,
|
|
27813
|
-
alpha: .94,
|
|
27814
|
-
cap: "round"
|
|
27815
|
-
});
|
|
27816
|
-
return;
|
|
27817
|
-
}
|
|
27818
|
-
if (surface === "unavailable") graphics.roundRect(cx - 12, cy - 9, 24, 18, 3).stroke({
|
|
27819
|
-
color,
|
|
27820
|
-
width: 1.25,
|
|
27821
|
-
alpha: .62
|
|
27822
|
-
}).moveTo(cx - 8, cy + 5).lineTo(cx + 8, cy - 5).stroke({
|
|
27823
|
-
color,
|
|
27824
|
-
width: 1.25,
|
|
27825
|
-
alpha: .72,
|
|
27826
|
-
cap: "round"
|
|
27827
|
-
});
|
|
27828
|
-
}
|
|
27829
|
-
function drawFailedBadge(graphics, width, color, context) {
|
|
27830
|
-
const cx = Math.max(12, width - 12);
|
|
27831
|
-
graphics.circle(cx, 12, 8).fill({
|
|
27832
|
-
color: context.palette.bg,
|
|
27833
|
-
alpha: .72
|
|
27834
|
-
});
|
|
27835
|
-
graphics.moveTo(cx - 2.5, 9.5).lineTo(cx + 2.5, 14.5).moveTo(cx + 2.5, 9.5).lineTo(cx - 2.5, 14.5).stroke({
|
|
27836
|
-
color,
|
|
27837
|
-
width: 1.5,
|
|
27838
|
-
alpha: .96,
|
|
27839
|
-
cap: "round"
|
|
27840
|
-
});
|
|
27841
|
-
}
|
|
27842
|
-
function sync$11(container, item, context) {
|
|
27843
|
-
const parts = partsByContainer$11.get(container);
|
|
27844
|
-
if (!parts) return;
|
|
27845
|
-
positionShell(parts.root, item);
|
|
27846
|
-
const { width, height } = item.frame;
|
|
27847
|
-
const selected = context.selectedIds.has(item.id);
|
|
27848
|
-
const hovered = context.hoveredId === item.id;
|
|
27849
|
-
const full = context.zoom >= TASK_CARD_FULL_DETAIL_ZOOM;
|
|
27850
|
-
const color = statusColor(item, context);
|
|
27851
|
-
const key = context.assetKey(item);
|
|
27852
|
-
if (key !== parts.assetKey) {
|
|
27853
|
-
if (parts.assetKey) context.releaseTexture(parts.assetKey);
|
|
27854
|
-
parts.assetKey = key;
|
|
27855
|
-
if (key) context.acquireTexture(key);
|
|
27856
|
-
}
|
|
27857
|
-
const texture = key ? context.getTexture(key) : null;
|
|
27858
|
-
const previewFailed = Boolean(key && !texture && context.hasError(key));
|
|
27859
|
-
const artifact = featuredTaskArtifact(item.props.snapshot.artifacts);
|
|
27860
|
-
const kind = previewKindFor(artifact);
|
|
27861
|
-
const surface = stateSurfaceFor(item, kind, Boolean(texture), previewFailed);
|
|
27862
|
-
const frame = {
|
|
27863
|
-
x: 1,
|
|
27864
|
-
y: 1,
|
|
27865
|
-
width: Math.max(1, width - 2),
|
|
27866
|
-
height: Math.max(1, height - 2)
|
|
27867
|
-
};
|
|
27868
|
-
const metaText = artifact ? metadata(item) : "";
|
|
27869
|
-
const showMeta = full && Boolean(metaText);
|
|
27870
|
-
const failedWithOutput = item.props.snapshot.status === "failed" && kind !== "empty";
|
|
27871
|
-
syncTextResolution(parts.body, parts, context.zoom);
|
|
27872
|
-
syncTextResolution(parts.meta, parts, context.zoom);
|
|
27873
|
-
const visualSig = [
|
|
27874
27984
|
width,
|
|
27875
|
-
height
|
|
27876
|
-
|
|
27877
|
-
|
|
27878
|
-
|
|
27879
|
-
|
|
27880
|
-
|
|
27881
|
-
|
|
27882
|
-
|
|
27883
|
-
|
|
27884
|
-
|
|
27885
|
-
|
|
27886
|
-
|
|
27887
|
-
|
|
27888
|
-
|
|
27889
|
-
|
|
27890
|
-
|
|
27891
|
-
|
|
27892
|
-
|
|
27893
|
-
|
|
27894
|
-
|
|
27895
|
-
|
|
27896
|
-
|
|
27897
|
-
|
|
27898
|
-
|
|
27899
|
-
|
|
27900
|
-
|
|
27901
|
-
alpha: selected ? .96 : .82
|
|
27902
|
-
});
|
|
27903
|
-
parts.clip.clear().roundRect(1, 1, frame.width, frame.height, 3).fill({ color: 16777215 });
|
|
27904
|
-
parts.previewBg.clear().rect(frame.x, frame.y, frame.width, frame.height).fill({
|
|
27905
|
-
color: context.palette.hover,
|
|
27906
|
-
alpha: .5
|
|
27907
|
-
});
|
|
27908
|
-
parts.previewMask.clear().rect(frame.x, frame.y, frame.width, frame.height).fill({ color: 16777215 });
|
|
27909
|
-
parts.previewArt.clear();
|
|
27910
|
-
if (kind === "waveform") {
|
|
27911
|
-
const bottomInset = showMeta ? META_HEIGHT : 0;
|
|
27912
|
-
drawAudioWaveform(parts.previewArt, item.props.taskRunId, {
|
|
27913
|
-
x: frame.x + PADDING,
|
|
27914
|
-
y: frame.y + PADDING,
|
|
27915
|
-
width: Math.max(1, frame.width - 24),
|
|
27916
|
-
height: Math.max(1, frame.height - 24 - bottomInset)
|
|
27917
|
-
}, context.colors.brand.stroke);
|
|
27918
|
-
}
|
|
27919
|
-
if (full && (artifact?.type === "audio" || artifact?.type === "video" && texture)) drawPlayBadge(parts.previewArt, frame, context);
|
|
27920
|
-
if (surface) {
|
|
27921
|
-
const markY = frame.y + frame.height / 2 - (full && stateLabel(surface) ? 10 : 0);
|
|
27922
|
-
drawStateMark(parts.previewArt, surface, frame.x + frame.width / 2, markY, surface === "failed" ? color : context.colors.neutral.stroke);
|
|
27923
|
-
}
|
|
27924
|
-
if (showMeta) parts.previewArt.rect(frame.x, frame.y + frame.height - META_HEIGHT, frame.width, META_HEIGHT).fill({
|
|
27925
|
-
color: context.palette.bg,
|
|
27926
|
-
alpha: .68
|
|
27927
|
-
});
|
|
27928
|
-
if (failedWithOutput) drawFailedBadge(parts.previewArt, width, color, context);
|
|
27929
|
-
}
|
|
27930
|
-
parts.preview.visible = kind === "texture" && Boolean(texture);
|
|
27931
|
-
if (parts.preview.visible && texture) {
|
|
27932
|
-
if (parts.preview.texture !== texture) parts.preview.texture = texture;
|
|
27933
|
-
const fitted = containTaskPreviewRect(frame.width, frame.height, texture.width, texture.height);
|
|
27934
|
-
parts.preview.position.set(frame.x + fitted.x, frame.y + fitted.y);
|
|
27935
|
-
parts.preview.width = fitted.width;
|
|
27936
|
-
parts.preview.height = fitted.height;
|
|
27937
|
-
}
|
|
27938
|
-
const bodyText = kind === "text" && artifact?.type === "text" ? artifact.textExcerpt : stateLabel(surface);
|
|
27939
|
-
const textSig = [
|
|
27940
|
-
bodyText,
|
|
27941
|
-
metaText,
|
|
27942
|
-
kind,
|
|
27943
|
-
surface,
|
|
27944
|
-
full,
|
|
27945
|
-
width,
|
|
27946
|
-
height,
|
|
27947
|
-
context.palette.text,
|
|
27948
|
-
context.palette.muted
|
|
27949
|
-
].join("|");
|
|
27950
|
-
if (textSig !== parts.textSig) {
|
|
27951
|
-
parts.textSig = textSig;
|
|
27952
|
-
parts.body.style.fill = surface === "failed" ? color : context.palette.text;
|
|
27953
|
-
fitTextToLines(parts.body, bodyText, kind === "text" ? Math.max(1, Math.floor((height - 24 - (showMeta ? META_HEIGHT : 0)) / 16)) : 1, Math.max(24, width - 24));
|
|
27954
|
-
parts.meta.style.fill = context.palette.text;
|
|
27955
|
-
fitTextToLines(parts.meta, metaText, 1, Math.max(24, width - 24));
|
|
27956
|
-
}
|
|
27957
|
-
parts.body.visible = full && Boolean(bodyText);
|
|
27958
|
-
parts.meta.visible = showMeta;
|
|
27959
|
-
if (kind === "text") parts.body.position.set(PADDING, PADDING);
|
|
27960
|
-
else parts.body.position.set(Math.max(PADDING, (width - parts.body.width) / 2), height / 2 + 10);
|
|
27961
|
-
parts.meta.position.set(PADDING, height - META_HEIGHT + 7);
|
|
27985
|
+
height
|
|
27986
|
+
}, context.style, {
|
|
27987
|
+
fill: context.palette.surface,
|
|
27988
|
+
border: context.palette.border,
|
|
27989
|
+
borderAlpha: .85,
|
|
27990
|
+
elevation
|
|
27991
|
+
});
|
|
27992
|
+
const key = audioKeyCenter(width, height);
|
|
27993
|
+
drawMediaPlayKey(parts.plate, key.x, key.y, key.radius, context, true);
|
|
27994
|
+
const left = key.x + key.radius + GAP$1;
|
|
27995
|
+
const room = width - 14 - left;
|
|
27996
|
+
parts.title.visible = detailed && room > 24;
|
|
27997
|
+
parts.wave.clear();
|
|
27998
|
+
if (!parts.title.visible) return;
|
|
27999
|
+
parts.title.style.fontFamily = context.style.font;
|
|
28000
|
+
parts.title.style.fill = context.palette.text;
|
|
28001
|
+
fitTextToWidth(parts.title, durationMs ? `${title} · ${formatBoardDuration(durationMs)}` : title, room);
|
|
28002
|
+
const withWave = height >= 56;
|
|
28003
|
+
const top = (height - (parts.title.height + (withWave ? 22 : 0))) / 2;
|
|
28004
|
+
parts.title.position.set(left, top);
|
|
28005
|
+
if (withWave) drawAudioWaveform(parts.wave, `${item.props.src}:${item.props.snapshot?.mtimeMs ?? "unknown"}`, {
|
|
28006
|
+
x: left,
|
|
28007
|
+
y: top + parts.title.height + 6,
|
|
28008
|
+
width: room,
|
|
28009
|
+
height: WAVE_HEIGHT
|
|
28010
|
+
}, context.palette.muted, .45, context.style.corner === "pixel");
|
|
27962
28011
|
}
|
|
27963
|
-
const
|
|
27964
|
-
id: "
|
|
27965
|
-
canRender: (item) => item.type === "
|
|
28012
|
+
const audioCardRenderer = {
|
|
28013
|
+
id: "audio-card",
|
|
28014
|
+
canRender: (item) => item.type === "audio",
|
|
27966
28015
|
create: (item, context) => {
|
|
27967
28016
|
const root = new Container();
|
|
27968
28017
|
const plate = new Graphics();
|
|
27969
|
-
const
|
|
27970
|
-
const previewBg = new Graphics();
|
|
27971
|
-
const preview = new Sprite();
|
|
27972
|
-
const previewMask = new Graphics();
|
|
27973
|
-
const previewArt = new Graphics();
|
|
28018
|
+
const wave = new Graphics();
|
|
27974
28019
|
const resolution = textResolutionForZoom(context.zoom);
|
|
27975
|
-
const
|
|
27976
|
-
text: "",
|
|
27977
|
-
style: {
|
|
27978
|
-
fontFamily: BOARD_FONT_STACK,
|
|
27979
|
-
fontSize: 11.5,
|
|
27980
|
-
fontWeight: "500",
|
|
27981
|
-
wordWrap: true,
|
|
27982
|
-
breakWords: true
|
|
27983
|
-
},
|
|
27984
|
-
resolution,
|
|
27985
|
-
roundPixels: true
|
|
27986
|
-
});
|
|
27987
|
-
const meta = new Text({
|
|
28020
|
+
const title = new Text({
|
|
27988
28021
|
text: "",
|
|
27989
28022
|
style: {
|
|
27990
|
-
|
|
27991
|
-
|
|
27992
|
-
fontWeight: "500",
|
|
27993
|
-
wordWrap: true,
|
|
27994
|
-
breakWords: true
|
|
28023
|
+
fontSize: 13,
|
|
28024
|
+
fontWeight: "600"
|
|
27995
28025
|
},
|
|
27996
28026
|
resolution,
|
|
27997
28027
|
roundPixels: true
|
|
27998
28028
|
});
|
|
27999
|
-
|
|
28000
|
-
root
|
|
28001
|
-
root.addChild(plate, clip, previewBg, preview, previewMask, previewArt, body, meta);
|
|
28002
|
-
partsByContainer$11.set(root, {
|
|
28029
|
+
root.addChild(plate, wave, title);
|
|
28030
|
+
partsByContainer$12.set(root, {
|
|
28003
28031
|
root,
|
|
28004
28032
|
plate,
|
|
28005
|
-
|
|
28006
|
-
|
|
28007
|
-
|
|
28008
|
-
previewMask,
|
|
28009
|
-
previewArt,
|
|
28010
|
-
body,
|
|
28011
|
-
meta,
|
|
28012
|
-
assetKey: null,
|
|
28013
|
-
visualSig: "",
|
|
28014
|
-
textSig: "",
|
|
28033
|
+
wave,
|
|
28034
|
+
title,
|
|
28035
|
+
sig: "",
|
|
28015
28036
|
resolution
|
|
28016
28037
|
});
|
|
28017
|
-
if (item.type === "
|
|
28038
|
+
if (item.type === "audio") sync$12(root, item, context);
|
|
28018
28039
|
return root;
|
|
28019
28040
|
},
|
|
28020
28041
|
update: (container, item, context) => {
|
|
28021
|
-
if (item.type === "
|
|
28042
|
+
if (item.type === "audio") sync$12(container, item, context);
|
|
28022
28043
|
},
|
|
28023
28044
|
renderFar: (graphics, item, context) => {
|
|
28024
|
-
if (item.type !== "task") return;
|
|
28025
|
-
const active = item.props.snapshot.status === "failed" || item.props.snapshot.status === "running" || item.props.snapshot.status === "pending";
|
|
28026
28045
|
drawFarPlate(graphics, item.frame, {
|
|
28027
28046
|
fill: context.palette.surface,
|
|
28028
|
-
fillAlpha: .
|
|
28029
|
-
|
|
28030
|
-
|
|
28031
|
-
accentAlpha: .9
|
|
28032
|
-
} : {}
|
|
28047
|
+
fillAlpha: .96,
|
|
28048
|
+
accent: context.palette.brand,
|
|
28049
|
+
accentAlpha: .72
|
|
28033
28050
|
});
|
|
28034
28051
|
},
|
|
28035
|
-
destroy: (container
|
|
28036
|
-
|
|
28037
|
-
|
|
28038
|
-
parts?.root.destroy({ children: true });
|
|
28039
|
-
partsByContainer$11.delete(container);
|
|
28052
|
+
destroy: (container) => {
|
|
28053
|
+
partsByContainer$12.get(container)?.root.destroy({ children: true });
|
|
28054
|
+
partsByContainer$12.delete(container);
|
|
28040
28055
|
}
|
|
28041
28056
|
};
|
|
28042
28057
|
//#endregion
|
|
28043
|
-
//#region ../sdk/src/board/render/stroke.ts
|
|
28044
|
-
const HEAD_SPREAD = Math.PI / 6;
|
|
28045
|
-
function dashPattern(dash, width) {
|
|
28046
|
-
if (dash === "dashed") return [Math.max(6, width * 4), Math.max(4, width * 3)];
|
|
28047
|
-
if (dash === "dotted") return [Math.max(.5, width * .01), Math.max(3, width * 2)];
|
|
28048
|
-
return null;
|
|
28049
|
-
}
|
|
28050
|
-
function trimPolyline(path, trim) {
|
|
28051
|
-
if (trim === void 0 || trim >= 1 || path.length < 2) return path;
|
|
28052
|
-
if (trim <= 0) return [];
|
|
28053
|
-
let total = 0;
|
|
28054
|
-
for (let index = 1; index < path.length; index += 1) {
|
|
28055
|
-
const a = path[index - 1];
|
|
28056
|
-
const b = path[index];
|
|
28057
|
-
total += Math.hypot(b.x - a.x, b.y - a.y);
|
|
28058
|
-
}
|
|
28059
|
-
let remaining = total * trim;
|
|
28060
|
-
const out = [path[0]];
|
|
28061
|
-
for (let index = 1; index < path.length; index += 1) {
|
|
28062
|
-
const a = path[index - 1];
|
|
28063
|
-
const b = path[index];
|
|
28064
|
-
const length = Math.hypot(b.x - a.x, b.y - a.y);
|
|
28065
|
-
if (length >= remaining) {
|
|
28066
|
-
const t = length > 0 ? remaining / length : 0;
|
|
28067
|
-
out.push(worldPoint(a.x + (b.x - a.x) * t, a.y + (b.y - a.y) * t));
|
|
28068
|
-
return out;
|
|
28069
|
-
}
|
|
28070
|
-
out.push(b);
|
|
28071
|
-
remaining -= length;
|
|
28072
|
-
}
|
|
28073
|
-
return out;
|
|
28074
|
-
}
|
|
28075
|
-
function tracePolyline(graphics, path, pattern, closed = false) {
|
|
28076
|
-
const points = closed && path.length > 2 ? [...path, path[0]] : path;
|
|
28077
|
-
if (points.length < 2) return;
|
|
28078
|
-
if (!pattern) {
|
|
28079
|
-
const first = points[0];
|
|
28080
|
-
graphics.moveTo(first.x, first.y);
|
|
28081
|
-
for (let index = 1; index < points.length; index += 1) {
|
|
28082
|
-
const point = points[index];
|
|
28083
|
-
graphics.lineTo(point.x, point.y);
|
|
28084
|
-
}
|
|
28085
|
-
if (closed) graphics.closePath();
|
|
28086
|
-
return;
|
|
28087
|
-
}
|
|
28088
|
-
const [dash, gap] = pattern;
|
|
28089
|
-
let penDown = true;
|
|
28090
|
-
let fresh = true;
|
|
28091
|
-
let remaining = dash;
|
|
28092
|
-
for (let index = 1; index < points.length; index += 1) {
|
|
28093
|
-
const a = points[index - 1];
|
|
28094
|
-
const b = points[index];
|
|
28095
|
-
const dx = b.x - a.x;
|
|
28096
|
-
const dy = b.y - a.y;
|
|
28097
|
-
const length = Math.hypot(dx, dy);
|
|
28098
|
-
let travelled = 0;
|
|
28099
|
-
while (length - travelled > 1e-4) {
|
|
28100
|
-
const step = Math.min(length - travelled, remaining);
|
|
28101
|
-
if (penDown) {
|
|
28102
|
-
const t0 = travelled / length;
|
|
28103
|
-
const t1 = (travelled + step) / length;
|
|
28104
|
-
if (fresh) graphics.moveTo(a.x + dx * t0, a.y + dy * t0);
|
|
28105
|
-
fresh = false;
|
|
28106
|
-
graphics.lineTo(a.x + dx * t1, a.y + dy * t1);
|
|
28107
|
-
}
|
|
28108
|
-
travelled += step;
|
|
28109
|
-
remaining -= step;
|
|
28110
|
-
if (remaining <= 1e-4) {
|
|
28111
|
-
penDown = !penDown;
|
|
28112
|
-
fresh = penDown;
|
|
28113
|
-
remaining = penDown ? dash : gap;
|
|
28114
|
-
}
|
|
28115
|
-
}
|
|
28116
|
-
}
|
|
28117
|
-
}
|
|
28118
|
-
function traceArrowhead(graphics, tip, angle, size) {
|
|
28119
|
-
graphics.moveTo(tip.x - size * Math.cos(angle - HEAD_SPREAD), tip.y - size * Math.sin(angle - HEAD_SPREAD)).lineTo(tip.x, tip.y).lineTo(tip.x - size * Math.cos(angle + HEAD_SPREAD), tip.y - size * Math.sin(angle + HEAD_SPREAD));
|
|
28120
|
-
}
|
|
28121
|
-
function endAngle(path, atStart) {
|
|
28122
|
-
if (path.length < 2) return null;
|
|
28123
|
-
const tip = atStart ? path[0] : path[path.length - 1];
|
|
28124
|
-
for (let offset = 1; offset < path.length; offset += 1) {
|
|
28125
|
-
const other = atStart ? path[offset] : path[path.length - 1 - offset];
|
|
28126
|
-
if (Math.hypot(tip.x - other.x, tip.y - other.y) > .001) return Math.atan2(tip.y - other.y, tip.x - other.x);
|
|
28127
|
-
}
|
|
28128
|
-
return null;
|
|
28129
|
-
}
|
|
28130
|
-
function roundRectPoints(width, height, radius) {
|
|
28131
|
-
const r = Math.min(radius, width / 2, height / 2);
|
|
28132
|
-
if (r <= 0) return [
|
|
28133
|
-
worldPoint(0, 0),
|
|
28134
|
-
worldPoint(width, 0),
|
|
28135
|
-
worldPoint(width, height),
|
|
28136
|
-
worldPoint(0, height),
|
|
28137
|
-
worldPoint(0, 0)
|
|
28138
|
-
];
|
|
28139
|
-
const corner = (cx, cy, from) => Array.from({ length: 9 }, (_, index) => {
|
|
28140
|
-
const angle = from + index / 8 * (Math.PI / 2);
|
|
28141
|
-
return worldPoint(cx + Math.cos(angle) * r, cy + Math.sin(angle) * r);
|
|
28142
|
-
});
|
|
28143
|
-
return [
|
|
28144
|
-
...corner(width - r, r, -Math.PI / 2),
|
|
28145
|
-
...corner(width - r, height - r, 0),
|
|
28146
|
-
...corner(r, height - r, Math.PI / 2),
|
|
28147
|
-
...corner(r, r, Math.PI),
|
|
28148
|
-
worldPoint(width - r, 0)
|
|
28149
|
-
];
|
|
28150
|
-
}
|
|
28151
|
-
//#endregion
|
|
28152
28058
|
//#region ../sdk/src/board/render/renderers/arrow-card-renderer.ts
|
|
28153
|
-
const partsByContainer$
|
|
28154
|
-
function sync$
|
|
28155
|
-
const parts = partsByContainer$
|
|
28059
|
+
const partsByContainer$11 = /* @__PURE__ */ new WeakMap();
|
|
28060
|
+
function sync$11(container, item, context) {
|
|
28061
|
+
const parts = partsByContainer$11.get(container);
|
|
28156
28062
|
if (!parts) return;
|
|
28157
28063
|
parts.root.position.set(0, 0);
|
|
28158
28064
|
parts.root.rotation = 0;
|
|
28159
28065
|
parts.root.scale.set(1);
|
|
28160
28066
|
const { props, style } = item;
|
|
28161
|
-
const selected = context.selectedIds.has(item.id);
|
|
28162
|
-
const hovered = context.hoveredId === item.id;
|
|
28163
28067
|
parts.line.alpha = itemAlpha(context, style.stroke);
|
|
28164
28068
|
const color = itemColor(context, style.stroke, "brand");
|
|
28165
28069
|
const size = style.strokeWidth ?? 2.5;
|
|
@@ -28168,8 +28072,6 @@ function sync$10(container, item, context) {
|
|
|
28168
28072
|
const path = trimPolyline(resolved.path, style.trim);
|
|
28169
28073
|
const lineSig = [
|
|
28170
28074
|
path.map((point) => `${point.x},${point.y}`).join(";"),
|
|
28171
|
-
selected,
|
|
28172
|
-
hovered,
|
|
28173
28075
|
color,
|
|
28174
28076
|
size,
|
|
28175
28077
|
style.dash,
|
|
@@ -28179,11 +28081,11 @@ function sync$10(container, item, context) {
|
|
|
28179
28081
|
if (lineSig !== parts.lineSig) {
|
|
28180
28082
|
parts.lineSig = lineSig;
|
|
28181
28083
|
parts.line.clear();
|
|
28182
|
-
const width =
|
|
28084
|
+
const width = size;
|
|
28183
28085
|
const stroke = {
|
|
28184
28086
|
color,
|
|
28185
28087
|
width,
|
|
28186
|
-
alpha:
|
|
28088
|
+
alpha: .92,
|
|
28187
28089
|
cap: "round",
|
|
28188
28090
|
join: "round"
|
|
28189
28091
|
};
|
|
@@ -28207,22 +28109,29 @@ function sync$10(container, item, context) {
|
|
|
28207
28109
|
}
|
|
28208
28110
|
const labelSig = [
|
|
28209
28111
|
props.label,
|
|
28210
|
-
|
|
28211
|
-
context.
|
|
28212
|
-
props.fontSize
|
|
28112
|
+
props.fontSize,
|
|
28113
|
+
context.themeKey
|
|
28213
28114
|
].join("|");
|
|
28214
28115
|
if (labelSig !== parts.labelSig) {
|
|
28215
28116
|
parts.labelSig = labelSig;
|
|
28216
28117
|
parts.label.text = props.label;
|
|
28217
28118
|
parts.label.style.fill = context.palette.text;
|
|
28218
28119
|
parts.label.style.fontSize = props.fontSize;
|
|
28219
|
-
const padX = props.fontSize * .
|
|
28220
|
-
const padY = props.fontSize * .
|
|
28120
|
+
const padX = props.fontSize * .5;
|
|
28121
|
+
const padY = props.fontSize * .25;
|
|
28221
28122
|
const { width, height } = parts.label;
|
|
28222
|
-
|
|
28223
|
-
|
|
28224
|
-
|
|
28225
|
-
|
|
28123
|
+
const plate = {
|
|
28124
|
+
x: -width / 2 - padX,
|
|
28125
|
+
y: -height / 2 - padY,
|
|
28126
|
+
width: width + padX * 2,
|
|
28127
|
+
height: height + padY * 2
|
|
28128
|
+
};
|
|
28129
|
+
drawCardSurface(parts.backdrop.clear(), plate, {
|
|
28130
|
+
...context.style,
|
|
28131
|
+
radius: Math.min(context.style.radius, plate.height / 2)
|
|
28132
|
+
}, {
|
|
28133
|
+
fill: context.palette.surface,
|
|
28134
|
+
border: context.palette.border
|
|
28226
28135
|
});
|
|
28227
28136
|
}
|
|
28228
28137
|
const visible = props.label.length > 0 && (style.trim === void 0 || style.trim >= .5);
|
|
@@ -28253,7 +28162,7 @@ const arrowCardRenderer = {
|
|
|
28253
28162
|
label.anchor.set(.5);
|
|
28254
28163
|
const backdrop = new Graphics();
|
|
28255
28164
|
root.addChild(line, backdrop, label);
|
|
28256
|
-
partsByContainer$
|
|
28165
|
+
partsByContainer$11.set(root, {
|
|
28257
28166
|
root,
|
|
28258
28167
|
line,
|
|
28259
28168
|
backdrop,
|
|
@@ -28262,11 +28171,11 @@ const arrowCardRenderer = {
|
|
|
28262
28171
|
labelSig: "",
|
|
28263
28172
|
resolution
|
|
28264
28173
|
});
|
|
28265
|
-
if (item.type === "arrow") sync$
|
|
28174
|
+
if (item.type === "arrow") sync$11(root, item, context);
|
|
28266
28175
|
return root;
|
|
28267
28176
|
},
|
|
28268
28177
|
update: (container, item, context) => {
|
|
28269
|
-
if (item.type === "arrow") sync$
|
|
28178
|
+
if (item.type === "arrow") sync$11(container, item, context);
|
|
28270
28179
|
},
|
|
28271
28180
|
renderFar: (graphics, item, context) => {
|
|
28272
28181
|
if (item.type !== "arrow") return;
|
|
@@ -28278,126 +28187,13 @@ const arrowCardRenderer = {
|
|
|
28278
28187
|
});
|
|
28279
28188
|
},
|
|
28280
28189
|
destroy: (container) => {
|
|
28281
|
-
partsByContainer$
|
|
28282
|
-
partsByContainer$
|
|
28283
|
-
}
|
|
28284
|
-
};
|
|
28285
|
-
//#endregion
|
|
28286
|
-
//#region ../sdk/src/board/render/renderers/audio-card-renderer.ts
|
|
28287
|
-
const RADIUS$3 = 4;
|
|
28288
|
-
const PLAY_RADIUS = 18;
|
|
28289
|
-
const partsByContainer$9 = /* @__PURE__ */ new WeakMap();
|
|
28290
|
-
function sync$9(container, item, context) {
|
|
28291
|
-
const parts = partsByContainer$9.get(container);
|
|
28292
|
-
if (!parts) return;
|
|
28293
|
-
positionShell(parts.root, item);
|
|
28294
|
-
const { width, height } = item.frame;
|
|
28295
|
-
const selected = context.selectedIds.has(item.id);
|
|
28296
|
-
const hovered = context.hoveredId === item.id;
|
|
28297
|
-
const title = item.props.snapshot?.title ?? getMediaResourceTitle(item.props.src);
|
|
28298
|
-
syncTextResolution(parts.label, parts, context.zoom);
|
|
28299
|
-
if (parts.label.text !== title) parts.label.text = title;
|
|
28300
|
-
syncTextWrapWidth(parts.label, parts, Math.max(1, width - 24), false);
|
|
28301
|
-
parts.label.position.set(12, Math.max(8, height - parts.label.height - 8));
|
|
28302
|
-
const sig = [
|
|
28303
|
-
width,
|
|
28304
|
-
height,
|
|
28305
|
-
selected,
|
|
28306
|
-
hovered,
|
|
28307
|
-
title,
|
|
28308
|
-
parts.label.height,
|
|
28309
|
-
context.palette.surface,
|
|
28310
|
-
context.palette.brand,
|
|
28311
|
-
context.palette.border,
|
|
28312
|
-
context.palette.muted,
|
|
28313
|
-
context.palette.text
|
|
28314
|
-
].join("|");
|
|
28315
|
-
if (sig === parts.sig) return;
|
|
28316
|
-
parts.sig = sig;
|
|
28317
|
-
parts.plate.clear().roundRect(0, 0, width, height, RADIUS$3).fill({
|
|
28318
|
-
color: context.palette.surface,
|
|
28319
|
-
alpha: .98
|
|
28320
|
-
}).roundRect(0, 0, width, height, RADIUS$3).stroke({
|
|
28321
|
-
color: selected ? context.palette.brand : hovered ? context.palette.muted : context.palette.border,
|
|
28322
|
-
width: selected ? 2 : 1,
|
|
28323
|
-
alpha: selected ? .96 : .84
|
|
28324
|
-
});
|
|
28325
|
-
const labelBand = Math.min(height * .38, parts.label.height + 16);
|
|
28326
|
-
const waveformInset = Math.min(24, width * .08);
|
|
28327
|
-
parts.waveform.clear();
|
|
28328
|
-
drawAudioWaveform(parts.waveform, `${item.props.src}:${item.props.snapshot?.mtimeMs ?? "unknown"}`, {
|
|
28329
|
-
x: waveformInset,
|
|
28330
|
-
y: 10,
|
|
28331
|
-
width: Math.max(1, width - waveformInset * 2),
|
|
28332
|
-
height: Math.max(8, height - labelBand - 16)
|
|
28333
|
-
}, context.palette.brand);
|
|
28334
|
-
const cx = width / 2;
|
|
28335
|
-
const cy = Math.max(24, (height - labelBand) / 2);
|
|
28336
|
-
parts.chrome.clear().circle(cx, cy, PLAY_RADIUS).fill({
|
|
28337
|
-
color: selected ? context.palette.brand : context.palette.surface,
|
|
28338
|
-
alpha: .92
|
|
28339
|
-
});
|
|
28340
|
-
const triangle = PLAY_RADIUS * .58;
|
|
28341
|
-
parts.chrome.moveTo(cx - triangle * .35, cy - triangle * .62).lineTo(cx - triangle * .35, cy + triangle * .62).lineTo(cx + triangle * .72, cy).closePath().fill({
|
|
28342
|
-
color: context.palette.text,
|
|
28343
|
-
alpha: .96
|
|
28344
|
-
});
|
|
28345
|
-
parts.label.style.fill = context.palette.text;
|
|
28346
|
-
}
|
|
28347
|
-
const audioCardRenderer = {
|
|
28348
|
-
id: "audio-card",
|
|
28349
|
-
canRender: (item) => item.type === "audio",
|
|
28350
|
-
create: (item, context) => {
|
|
28351
|
-
const root = new Container();
|
|
28352
|
-
const plate = new Graphics();
|
|
28353
|
-
const waveform = new Graphics();
|
|
28354
|
-
const chrome = new Graphics();
|
|
28355
|
-
const resolution = textResolutionForZoom(context.zoom);
|
|
28356
|
-
const label = new Text({
|
|
28357
|
-
text: "",
|
|
28358
|
-
style: {
|
|
28359
|
-
fill: context.palette.text,
|
|
28360
|
-
fontFamily: BOARD_FONT_STACK,
|
|
28361
|
-
fontSize: 12,
|
|
28362
|
-
fontWeight: "500",
|
|
28363
|
-
wordWrap: true
|
|
28364
|
-
},
|
|
28365
|
-
resolution,
|
|
28366
|
-
roundPixels: true
|
|
28367
|
-
});
|
|
28368
|
-
root.addChild(plate, waveform, chrome, label);
|
|
28369
|
-
partsByContainer$9.set(root, {
|
|
28370
|
-
root,
|
|
28371
|
-
plate,
|
|
28372
|
-
waveform,
|
|
28373
|
-
chrome,
|
|
28374
|
-
label,
|
|
28375
|
-
sig: "",
|
|
28376
|
-
wrapWidth: 0,
|
|
28377
|
-
resolution
|
|
28378
|
-
});
|
|
28379
|
-
if (item.type === "audio") sync$9(root, item, context);
|
|
28380
|
-
return root;
|
|
28381
|
-
},
|
|
28382
|
-
update: (container, item, context) => {
|
|
28383
|
-
if (item.type === "audio") sync$9(container, item, context);
|
|
28384
|
-
},
|
|
28385
|
-
renderFar: (graphics, item, context) => {
|
|
28386
|
-
drawFarPlate(graphics, item.frame, {
|
|
28387
|
-
fill: context.palette.surface,
|
|
28388
|
-
fillAlpha: .96,
|
|
28389
|
-
accent: context.palette.brand,
|
|
28390
|
-
accentAlpha: .72
|
|
28391
|
-
});
|
|
28392
|
-
},
|
|
28393
|
-
destroy: (container) => {
|
|
28394
|
-
partsByContainer$9.get(container)?.root.destroy({ children: true });
|
|
28395
|
-
partsByContainer$9.delete(container);
|
|
28190
|
+
partsByContainer$11.get(container)?.root.destroy({ children: true });
|
|
28191
|
+
partsByContainer$11.delete(container);
|
|
28396
28192
|
}
|
|
28397
28193
|
};
|
|
28398
28194
|
//#endregion
|
|
28399
28195
|
//#region ../sdk/src/board/render/renderers/draw-card-renderer.ts
|
|
28400
|
-
const partsByContainer$
|
|
28196
|
+
const partsByContainer$10 = /* @__PURE__ */ new WeakMap();
|
|
28401
28197
|
function fillRibbon(graphics, ribbon, color) {
|
|
28402
28198
|
const { positions, indices } = ribbon;
|
|
28403
28199
|
for (let offset = 0; offset < indices.length; offset += 3) {
|
|
@@ -28448,8 +28244,8 @@ function tessellate(parts, points, size, paint) {
|
|
|
28448
28244
|
texture: Texture.WHITE
|
|
28449
28245
|
}));
|
|
28450
28246
|
}
|
|
28451
|
-
function sync$
|
|
28452
|
-
const parts = partsByContainer$
|
|
28247
|
+
function sync$10(container, item, context) {
|
|
28248
|
+
const parts = partsByContainer$10.get(container);
|
|
28453
28249
|
if (!parts) return;
|
|
28454
28250
|
positionShell(parts.root, item);
|
|
28455
28251
|
const { points } = item.props;
|
|
@@ -28482,7 +28278,7 @@ const drawCardRenderer = {
|
|
|
28482
28278
|
canRender: (item) => item.type === "draw",
|
|
28483
28279
|
create: (item, context) => {
|
|
28484
28280
|
const root = new Container();
|
|
28485
|
-
partsByContainer$
|
|
28281
|
+
partsByContainer$10.set(root, {
|
|
28486
28282
|
root,
|
|
28487
28283
|
stroke: null,
|
|
28488
28284
|
ribbon: null,
|
|
@@ -28499,11 +28295,11 @@ const drawCardRenderer = {
|
|
|
28499
28295
|
height: 1
|
|
28500
28296
|
}
|
|
28501
28297
|
});
|
|
28502
|
-
if (item.type === "draw") sync$
|
|
28298
|
+
if (item.type === "draw") sync$10(root, item, context);
|
|
28503
28299
|
return root;
|
|
28504
28300
|
},
|
|
28505
28301
|
update: (container, item, context) => {
|
|
28506
|
-
if (item.type === "draw") sync$
|
|
28302
|
+
if (item.type === "draw") sync$10(container, item, context);
|
|
28507
28303
|
},
|
|
28508
28304
|
renderFar: (graphics, item, context) => {
|
|
28509
28305
|
if (item.type !== "draw") return;
|
|
@@ -28516,15 +28312,15 @@ const drawCardRenderer = {
|
|
|
28516
28312
|
});
|
|
28517
28313
|
},
|
|
28518
28314
|
destroy: (container) => {
|
|
28519
|
-
partsByContainer$
|
|
28520
|
-
partsByContainer$
|
|
28315
|
+
partsByContainer$10.get(container)?.root.destroy({ children: true });
|
|
28316
|
+
partsByContainer$10.delete(container);
|
|
28521
28317
|
}
|
|
28522
28318
|
};
|
|
28523
28319
|
//#endregion
|
|
28524
28320
|
//#region ../sdk/src/board/render/renderers/effect-card-renderer.ts
|
|
28525
28321
|
const BOARD_EFFECT_MAX_PARTICLES = 4e3;
|
|
28526
28322
|
const TRAIL_SAMPLES = 64;
|
|
28527
|
-
const partsByContainer$
|
|
28323
|
+
const partsByContainer$9 = /* @__PURE__ */ new WeakMap();
|
|
28528
28324
|
function hashString(value) {
|
|
28529
28325
|
let hash = 2166136261;
|
|
28530
28326
|
for (let index = 0; index < value.length; index += 1) {
|
|
@@ -28665,8 +28461,8 @@ function drawTrail(graphics, parts, item, context, color) {
|
|
|
28665
28461
|
});
|
|
28666
28462
|
}
|
|
28667
28463
|
}
|
|
28668
|
-
function sync$
|
|
28669
|
-
const parts = partsByContainer$
|
|
28464
|
+
function sync$9(container, item, context) {
|
|
28465
|
+
const parts = partsByContainer$9.get(container);
|
|
28670
28466
|
if (!parts) return;
|
|
28671
28467
|
positionShell(parts.root, item);
|
|
28672
28468
|
const { width, height } = item.frame;
|
|
@@ -28692,11 +28488,6 @@ function sync$7(container, item, context) {
|
|
|
28692
28488
|
break;
|
|
28693
28489
|
case "trail": drawTrail(graphics, parts, item, context, color);
|
|
28694
28490
|
}
|
|
28695
|
-
if (context.selectedIds.has(item.id) || context.hoveredId === item.id) graphics.rect(0, 0, width, height).stroke({
|
|
28696
|
-
color: context.palette.muted,
|
|
28697
|
-
width: 1,
|
|
28698
|
-
alpha: .6
|
|
28699
|
-
});
|
|
28700
28491
|
}
|
|
28701
28492
|
const effectCardRenderer = {
|
|
28702
28493
|
id: "effect-card",
|
|
@@ -28706,16 +28497,16 @@ const effectCardRenderer = {
|
|
|
28706
28497
|
const root = new Container();
|
|
28707
28498
|
const graphics = new Graphics();
|
|
28708
28499
|
root.addChild(graphics);
|
|
28709
|
-
partsByContainer$
|
|
28500
|
+
partsByContainer$9.set(root, {
|
|
28710
28501
|
root,
|
|
28711
28502
|
graphics,
|
|
28712
28503
|
trail: []
|
|
28713
28504
|
});
|
|
28714
|
-
if (item.type === "effect") sync$
|
|
28505
|
+
if (item.type === "effect") sync$9(root, item, context);
|
|
28715
28506
|
return root;
|
|
28716
28507
|
},
|
|
28717
28508
|
update: (container, item, context) => {
|
|
28718
|
-
if (item.type === "effect") sync$
|
|
28509
|
+
if (item.type === "effect") sync$9(container, item, context);
|
|
28719
28510
|
},
|
|
28720
28511
|
renderFar: (graphics, item, context) => {
|
|
28721
28512
|
if (item.type !== "effect") return;
|
|
@@ -28725,27 +28516,293 @@ const effectCardRenderer = {
|
|
|
28725
28516
|
});
|
|
28726
28517
|
},
|
|
28727
28518
|
destroy: (container) => {
|
|
28728
|
-
partsByContainer$
|
|
28729
|
-
partsByContainer$
|
|
28519
|
+
partsByContainer$9.get(container)?.root.destroy({ children: true });
|
|
28520
|
+
partsByContainer$9.delete(container);
|
|
28521
|
+
}
|
|
28522
|
+
};
|
|
28523
|
+
//#endregion
|
|
28524
|
+
//#region ../sdk/src/board/render/renderers/file-card-renderer.ts
|
|
28525
|
+
const PADDING$1 = 10;
|
|
28526
|
+
const COVER_RATIO = .56;
|
|
28527
|
+
const MIN_BODY_FOR_COVER = 38;
|
|
28528
|
+
const TITLE_SIZE = 13;
|
|
28529
|
+
const TITLE_LINE = TITLE_SIZE * 1.35;
|
|
28530
|
+
const TITLE_MAX_LINES = 2;
|
|
28531
|
+
const EXCERPT_SIZE = 11;
|
|
28532
|
+
const EXCERPT_LINE = EXCERPT_SIZE * 1.45;
|
|
28533
|
+
const EXCERPT_MAX_LINES = 3;
|
|
28534
|
+
const TYPE_MARK_SIZE = 28;
|
|
28535
|
+
const GAP = 4;
|
|
28536
|
+
const STRIPE = 2;
|
|
28537
|
+
const MAX_DASHES = 40;
|
|
28538
|
+
const partsByContainer$8 = /* @__PURE__ */ new WeakMap();
|
|
28539
|
+
function detailFor(zoom) {
|
|
28540
|
+
return boardCardDetailed(zoom) ? "full" : "title";
|
|
28541
|
+
}
|
|
28542
|
+
function coverHeight(item, height) {
|
|
28543
|
+
if (filePreviewKind(item.props.snapshot) !== "cover") return 0;
|
|
28544
|
+
const ideal = Math.round(height * COVER_RATIO);
|
|
28545
|
+
return Math.max(0, Math.min(ideal, height - MIN_BODY_FOR_COVER));
|
|
28546
|
+
}
|
|
28547
|
+
function linesInRoom(room, lineHeight, max) {
|
|
28548
|
+
if (room < lineHeight * .85) return 0;
|
|
28549
|
+
return Math.max(0, Math.min(max, Math.floor((room + .5) / lineHeight)));
|
|
28550
|
+
}
|
|
28551
|
+
function layoutCover(sprite, width, height, texture) {
|
|
28552
|
+
const rect = containRect(width, height, texture.width, texture.height);
|
|
28553
|
+
sprite.position.set(rect.x, rect.y);
|
|
28554
|
+
sprite.width = rect.width;
|
|
28555
|
+
sprite.height = rect.height;
|
|
28556
|
+
}
|
|
28557
|
+
function syncClip(parts, rect, style) {
|
|
28558
|
+
traceCardOutline(parts.clip.clear(), rect, style).fill({ color: 16777215 });
|
|
28559
|
+
}
|
|
28560
|
+
function sync$8(container, item, context) {
|
|
28561
|
+
const parts = partsByContainer$8.get(container);
|
|
28562
|
+
if (!parts) return;
|
|
28563
|
+
positionShell(parts.root, item);
|
|
28564
|
+
const { width, height } = item.frame;
|
|
28565
|
+
const detail = detailFor(context.zoom);
|
|
28566
|
+
const elevation = cardElevation(context, item.id);
|
|
28567
|
+
syncCardTag(parts.tag, {
|
|
28568
|
+
glyph: "file",
|
|
28569
|
+
text: fileMetaLine(item.props.src, item.props.snapshot?.size),
|
|
28570
|
+
width
|
|
28571
|
+
}, context);
|
|
28572
|
+
const key = context.assetKey(item);
|
|
28573
|
+
const texture = key ? context.getTexture(key) : null;
|
|
28574
|
+
const coverFailed = Boolean(key && !texture && context.hasError(key));
|
|
28575
|
+
const fileState = context.fileState(item.props.src);
|
|
28576
|
+
const band = coverHeight(item, height);
|
|
28577
|
+
const kind = filePreviewKind(item.props.snapshot);
|
|
28578
|
+
const category = fileCategory(item.props.src, item.props.snapshot?.mimeType);
|
|
28579
|
+
const accent = fileCategoryAccent(category, context.palette);
|
|
28580
|
+
syncTextResolution(parts.title, parts.titleRes, context.zoom);
|
|
28581
|
+
syncTextResolution(parts.excerpt, parts.excerptRes, context.zoom);
|
|
28582
|
+
syncTextResolution(parts.typeMark, parts.typeMarkRes, context.zoom);
|
|
28583
|
+
const visualSig = [
|
|
28584
|
+
key ?? "",
|
|
28585
|
+
width,
|
|
28586
|
+
height,
|
|
28587
|
+
detail,
|
|
28588
|
+
elevation,
|
|
28589
|
+
texture ? `${texture.width}x${texture.height}` : "none",
|
|
28590
|
+
coverFailed,
|
|
28591
|
+
fileState,
|
|
28592
|
+
kind,
|
|
28593
|
+
category,
|
|
28594
|
+
context.themeKey,
|
|
28595
|
+
accent
|
|
28596
|
+
].join("|");
|
|
28597
|
+
if (visualSig !== parts.visualSig) {
|
|
28598
|
+
parts.visualSig = visualSig;
|
|
28599
|
+
const rect = {
|
|
28600
|
+
x: 0,
|
|
28601
|
+
y: 0,
|
|
28602
|
+
width,
|
|
28603
|
+
height
|
|
28604
|
+
};
|
|
28605
|
+
syncClip(parts, rect, context.style);
|
|
28606
|
+
drawCardSurface(parts.plate.clear(), rect, context.style, {
|
|
28607
|
+
fill: context.palette.surface,
|
|
28608
|
+
border: context.palette.border,
|
|
28609
|
+
borderAlpha: .85,
|
|
28610
|
+
elevation
|
|
28611
|
+
});
|
|
28612
|
+
if (fileState !== "ok") {
|
|
28613
|
+
const dash = Math.max(6, width / MAX_DASHES / 2);
|
|
28614
|
+
for (let x = 0; x < width; x += dash * 2) parts.plate.moveTo(x, .5).lineTo(Math.min(x + dash, width), .5);
|
|
28615
|
+
parts.plate.stroke({
|
|
28616
|
+
color: context.palette.muted,
|
|
28617
|
+
width: 2,
|
|
28618
|
+
alpha: fileState === "missing" ? .9 : .5
|
|
28619
|
+
});
|
|
28620
|
+
}
|
|
28621
|
+
const showCover = band > 0 && Boolean(texture);
|
|
28622
|
+
if (band > 0) parts.plate.rect(1, 1, width - 2, band - 1).fill({
|
|
28623
|
+
color: context.palette.hover,
|
|
28624
|
+
alpha: coverFailed ? .35 : .6
|
|
28625
|
+
});
|
|
28626
|
+
if (showCover && texture) {
|
|
28627
|
+
if (parts.cover.texture !== texture) parts.cover.texture = texture;
|
|
28628
|
+
layoutCover(parts.cover, width, band, texture);
|
|
28629
|
+
parts.coverMask.clear().rect(0, 0, width, band).fill({ color: 16777215 });
|
|
28630
|
+
}
|
|
28631
|
+
parts.cover.visible = showCover;
|
|
28632
|
+
parts.coverMask.visible = showCover;
|
|
28633
|
+
if (!band) parts.plate.rect(1, 1, STRIPE, height - 2).fill({
|
|
28634
|
+
color: accent,
|
|
28635
|
+
alpha: .55
|
|
28636
|
+
});
|
|
28637
|
+
parts.excerpt.visible = detail === "full";
|
|
28638
|
+
parts.typeMark.visible = kind === "blank";
|
|
28639
|
+
}
|
|
28640
|
+
const title = item.props.snapshot?.title || fileStem(item.props.src);
|
|
28641
|
+
const excerpt = item.props.snapshot?.excerpt ?? "";
|
|
28642
|
+
const mark = fileTypeLabel(item.props.src);
|
|
28643
|
+
const innerWidth = Math.max(1, width - 20);
|
|
28644
|
+
const showTypeMark = kind === "blank";
|
|
28645
|
+
const textSig = [
|
|
28646
|
+
title,
|
|
28647
|
+
excerpt,
|
|
28648
|
+
mark,
|
|
28649
|
+
detail,
|
|
28650
|
+
innerWidth,
|
|
28651
|
+
band,
|
|
28652
|
+
height,
|
|
28653
|
+
kind,
|
|
28654
|
+
context.palette.text,
|
|
28655
|
+
context.palette.muted,
|
|
28656
|
+
context.style.font,
|
|
28657
|
+
accent
|
|
28658
|
+
].join("|");
|
|
28659
|
+
if (textSig === parts.textSig) return;
|
|
28660
|
+
parts.textSig = textSig;
|
|
28661
|
+
parts.title.style.fontFamily = context.style.font;
|
|
28662
|
+
parts.excerpt.style.fontFamily = context.style.font;
|
|
28663
|
+
const top = band > 0 ? band + PADDING$1 * .8 : PADDING$1;
|
|
28664
|
+
const contentBottom = height - PADDING$1;
|
|
28665
|
+
let cursor = top;
|
|
28666
|
+
if (showTypeMark) {
|
|
28667
|
+
const markSize = Math.max(18, Math.min(TYPE_MARK_SIZE, Math.round(height * .22)));
|
|
28668
|
+
parts.typeMark.style.fill = accent;
|
|
28669
|
+
parts.typeMark.style.fontSize = markSize;
|
|
28670
|
+
parts.typeMark.style.lineHeight = markSize * 1.1;
|
|
28671
|
+
if (parts.typeMark.text !== mark) parts.typeMark.text = mark;
|
|
28672
|
+
parts.typeMark.position.set(PADDING$1, cursor);
|
|
28673
|
+
parts.typeMark.visible = true;
|
|
28674
|
+
cursor += parts.typeMark.height + GAP;
|
|
28675
|
+
} else parts.typeMark.visible = false;
|
|
28676
|
+
const titleLines = linesInRoom(Math.max(0, contentBottom - cursor), TITLE_LINE, TITLE_MAX_LINES);
|
|
28677
|
+
parts.title.style.fill = context.palette.text;
|
|
28678
|
+
fitTextToLines(parts.title, title, titleLines, innerWidth);
|
|
28679
|
+
parts.title.position.set(PADDING$1, cursor);
|
|
28680
|
+
parts.title.visible = titleLines > 0;
|
|
28681
|
+
if (detail !== "full") {
|
|
28682
|
+
parts.excerpt.visible = false;
|
|
28683
|
+
return;
|
|
28684
|
+
}
|
|
28685
|
+
const excerptTop = cursor + (titleLines > 0 ? parts.title.height + GAP : 0);
|
|
28686
|
+
const excerptLines = linesInRoom(contentBottom - excerptTop, EXCERPT_LINE, EXCERPT_MAX_LINES);
|
|
28687
|
+
const showExcerpt = Boolean(excerpt) && excerptLines > 0;
|
|
28688
|
+
if (showExcerpt) {
|
|
28689
|
+
parts.excerpt.style.fill = context.palette.muted;
|
|
28690
|
+
fitTextToLines(parts.excerpt, excerpt, excerptLines, innerWidth);
|
|
28691
|
+
parts.excerpt.position.set(PADDING$1, excerptTop);
|
|
28692
|
+
}
|
|
28693
|
+
parts.excerpt.visible = showExcerpt;
|
|
28694
|
+
}
|
|
28695
|
+
const fileCardRenderer = {
|
|
28696
|
+
id: "file-card",
|
|
28697
|
+
canRender: (item) => item.type === "file",
|
|
28698
|
+
create: (item, context) => {
|
|
28699
|
+
const root = new Container();
|
|
28700
|
+
const plate = new Graphics();
|
|
28701
|
+
const body = new Container();
|
|
28702
|
+
const clip = new Graphics();
|
|
28703
|
+
const cover = new Sprite(Texture.EMPTY);
|
|
28704
|
+
const coverMask = new Graphics();
|
|
28705
|
+
cover.mask = coverMask;
|
|
28706
|
+
const resolution = 1;
|
|
28707
|
+
const title = new Text({
|
|
28708
|
+
text: "",
|
|
28709
|
+
style: {
|
|
28710
|
+
fill: context.palette.text,
|
|
28711
|
+
fontFamily: BOARD_FONT_STACK,
|
|
28712
|
+
fontSize: TITLE_SIZE,
|
|
28713
|
+
fontWeight: "600",
|
|
28714
|
+
wordWrap: true,
|
|
28715
|
+
breakWords: true,
|
|
28716
|
+
lineHeight: TITLE_LINE
|
|
28717
|
+
},
|
|
28718
|
+
resolution,
|
|
28719
|
+
roundPixels: true
|
|
28720
|
+
});
|
|
28721
|
+
const excerpt = new Text({
|
|
28722
|
+
text: "",
|
|
28723
|
+
style: {
|
|
28724
|
+
fill: context.palette.muted,
|
|
28725
|
+
fontFamily: BOARD_FONT_STACK,
|
|
28726
|
+
fontSize: EXCERPT_SIZE,
|
|
28727
|
+
fontWeight: "400",
|
|
28728
|
+
wordWrap: true,
|
|
28729
|
+
breakWords: true,
|
|
28730
|
+
lineHeight: EXCERPT_LINE
|
|
28731
|
+
},
|
|
28732
|
+
resolution,
|
|
28733
|
+
roundPixels: true
|
|
28734
|
+
});
|
|
28735
|
+
const typeMark = new Text({
|
|
28736
|
+
text: "",
|
|
28737
|
+
style: {
|
|
28738
|
+
fill: context.palette.muted,
|
|
28739
|
+
fontFamily: BOARD_MONO_FONT_STACK,
|
|
28740
|
+
fontSize: TYPE_MARK_SIZE,
|
|
28741
|
+
fontWeight: "700",
|
|
28742
|
+
lineHeight: TYPE_MARK_SIZE * 1.1
|
|
28743
|
+
},
|
|
28744
|
+
resolution,
|
|
28745
|
+
roundPixels: true
|
|
28746
|
+
});
|
|
28747
|
+
body.mask = clip;
|
|
28748
|
+
body.addChild(cover, coverMask, typeMark, title, excerpt);
|
|
28749
|
+
const tag = createCardTag();
|
|
28750
|
+
root.addChild(plate, body, clip, tag.root);
|
|
28751
|
+
partsByContainer$8.set(root, {
|
|
28752
|
+
tag,
|
|
28753
|
+
root,
|
|
28754
|
+
plate,
|
|
28755
|
+
body,
|
|
28756
|
+
clip,
|
|
28757
|
+
cover,
|
|
28758
|
+
coverMask,
|
|
28759
|
+
typeMark,
|
|
28760
|
+
title,
|
|
28761
|
+
excerpt,
|
|
28762
|
+
visualSig: "",
|
|
28763
|
+
textSig: "",
|
|
28764
|
+
titleRes: { resolution },
|
|
28765
|
+
excerptRes: { resolution },
|
|
28766
|
+
typeMarkRes: { resolution }
|
|
28767
|
+
});
|
|
28768
|
+
if (item.type === "file") sync$8(root, item, context);
|
|
28769
|
+
return root;
|
|
28770
|
+
},
|
|
28771
|
+
update: (container, item, context) => {
|
|
28772
|
+
if (item.type === "file") sync$8(container, item, context);
|
|
28773
|
+
},
|
|
28774
|
+
zoom: (container, zoom) => {
|
|
28775
|
+
const tag = partsByContainer$8.get(container)?.tag;
|
|
28776
|
+
if (tag) zoomCardTag(tag, zoom);
|
|
28777
|
+
},
|
|
28778
|
+
renderFar: (graphics, item, context) => {
|
|
28779
|
+
const category = fileCategory(item.type === "file" ? item.props.src : "", item.type === "file" ? item.props.snapshot?.mimeType : void 0);
|
|
28780
|
+
drawFarPlate(graphics, item.frame, {
|
|
28781
|
+
fill: context.palette.surface,
|
|
28782
|
+
fillAlpha: .96,
|
|
28783
|
+
accent: fileCategoryAccent(category, context.palette),
|
|
28784
|
+
accentAlpha: .45
|
|
28785
|
+
});
|
|
28786
|
+
},
|
|
28787
|
+
destroy: (container) => {
|
|
28788
|
+
partsByContainer$8.get(container)?.root.destroy({ children: true });
|
|
28789
|
+
partsByContainer$8.delete(container);
|
|
28730
28790
|
}
|
|
28731
28791
|
};
|
|
28732
28792
|
//#endregion
|
|
28733
28793
|
//#region ../sdk/src/board/render/renderers/frame-card-renderer.ts
|
|
28734
|
-
const partsByContainer$
|
|
28794
|
+
const partsByContainer$7 = /* @__PURE__ */ new WeakMap();
|
|
28735
28795
|
const DEFAULT_WASH = .04;
|
|
28736
|
-
function sync$
|
|
28737
|
-
const parts = partsByContainer$
|
|
28796
|
+
function sync$7(container, item, context) {
|
|
28797
|
+
const parts = partsByContainer$7.get(container);
|
|
28738
28798
|
if (!parts) return;
|
|
28739
28799
|
const { frame, style, props, locked } = item;
|
|
28740
28800
|
positionShell(parts.root, item);
|
|
28741
28801
|
syncTextResolution(parts.label, parts, context.zoom);
|
|
28742
|
-
const selected = context.selectedIds.has(item.id);
|
|
28743
|
-
const hovered = context.hoveredId === item.id;
|
|
28744
28802
|
const fill = itemColor(context, style.fill ?? style.stroke, "neutral", "fill");
|
|
28745
28803
|
const fillAlpha = (style.fillOpacity ?? (style.fill ? 1 : DEFAULT_WASH)) * itemAlpha(context, style.fill ?? style.stroke);
|
|
28746
28804
|
const baseStroke = itemColor(context, style.stroke, "neutral");
|
|
28747
|
-
const
|
|
28748
|
-
const alpha = (selected || style.stroke ? 1 : hovered ? .85 : .55) * itemAlpha(context, style.stroke);
|
|
28805
|
+
const alpha = (style.stroke ? 1 : .55) * itemAlpha(context, style.stroke);
|
|
28749
28806
|
const radius = style.radius ?? 4;
|
|
28750
28807
|
const strokeWidth = style.strokeWidth ?? 1.5;
|
|
28751
28808
|
const decorated = props.decoration !== "none";
|
|
@@ -28753,11 +28810,9 @@ function sync$6(container, item, context) {
|
|
|
28753
28810
|
props.decoration,
|
|
28754
28811
|
frame.width,
|
|
28755
28812
|
frame.height,
|
|
28756
|
-
selected,
|
|
28757
|
-
hovered,
|
|
28758
28813
|
fill,
|
|
28759
28814
|
fillAlpha,
|
|
28760
|
-
|
|
28815
|
+
baseStroke,
|
|
28761
28816
|
alpha,
|
|
28762
28817
|
radius,
|
|
28763
28818
|
strokeWidth,
|
|
@@ -28771,15 +28826,14 @@ function sync$6(container, item, context) {
|
|
|
28771
28826
|
color: fill,
|
|
28772
28827
|
alpha: fillAlpha
|
|
28773
28828
|
});
|
|
28774
|
-
const
|
|
28775
|
-
const
|
|
28776
|
-
|
|
28777
|
-
if ((decorated && strokeWidth > 0 || selected || hovered) && trim > 0) {
|
|
28829
|
+
const pattern = dashPattern(style.dash, strokeWidth);
|
|
28830
|
+
const trim = style.trim ?? 1;
|
|
28831
|
+
if (decorated && strokeWidth > 0 && trim > 0) {
|
|
28778
28832
|
if (pattern || trim < 1) tracePolyline(parts.box, trimPolyline(roundRectPoints(frame.width, frame.height, radius), trim), pattern);
|
|
28779
28833
|
else parts.box.roundRect(0, 0, frame.width, frame.height, radius);
|
|
28780
28834
|
parts.box.stroke({
|
|
28781
|
-
color:
|
|
28782
|
-
width,
|
|
28835
|
+
color: baseStroke,
|
|
28836
|
+
width: strokeWidth,
|
|
28783
28837
|
alpha,
|
|
28784
28838
|
cap: pattern || trim < 1 ? "round" : "butt",
|
|
28785
28839
|
join: "round"
|
|
@@ -28789,11 +28843,16 @@ function sync$6(container, item, context) {
|
|
|
28789
28843
|
parts.label.visible = decorated;
|
|
28790
28844
|
const title = locked ? `🔒 ${props.label}`.trim() : props.label;
|
|
28791
28845
|
const labelColor = style.stroke ? baseStroke : context.palette.muted;
|
|
28792
|
-
const textSig = [
|
|
28846
|
+
const textSig = [
|
|
28847
|
+
title,
|
|
28848
|
+
labelColor,
|
|
28849
|
+
context.style.font
|
|
28850
|
+
].join("|");
|
|
28793
28851
|
if (textSig !== parts.textSig) {
|
|
28794
28852
|
parts.textSig = textSig;
|
|
28795
28853
|
parts.label.text = title;
|
|
28796
28854
|
parts.label.style.fill = labelColor;
|
|
28855
|
+
parts.label.style.fontFamily = context.style.font;
|
|
28797
28856
|
}
|
|
28798
28857
|
parts.label.position.set(4, -18);
|
|
28799
28858
|
}
|
|
@@ -28810,7 +28869,7 @@ const frameCardRenderer = {
|
|
|
28810
28869
|
fontWeight: "600"
|
|
28811
28870
|
});
|
|
28812
28871
|
root.addChild(box, label);
|
|
28813
|
-
partsByContainer$
|
|
28872
|
+
partsByContainer$7.set(root, {
|
|
28814
28873
|
root,
|
|
28815
28874
|
box,
|
|
28816
28875
|
label,
|
|
@@ -28818,11 +28877,11 @@ const frameCardRenderer = {
|
|
|
28818
28877
|
textSig: "",
|
|
28819
28878
|
resolution: label.resolution
|
|
28820
28879
|
});
|
|
28821
|
-
if (item.type === "frame") sync$
|
|
28880
|
+
if (item.type === "frame") sync$7(root, item, context);
|
|
28822
28881
|
return root;
|
|
28823
28882
|
},
|
|
28824
28883
|
update: (container, item, context) => {
|
|
28825
|
-
if (item.type === "frame") sync$
|
|
28884
|
+
if (item.type === "frame") sync$7(container, item, context);
|
|
28826
28885
|
},
|
|
28827
28886
|
renderFar: (graphics, item, context) => {
|
|
28828
28887
|
if (item.type !== "frame" || item.props.decoration === "none") return;
|
|
@@ -28832,14 +28891,14 @@ const frameCardRenderer = {
|
|
|
28832
28891
|
});
|
|
28833
28892
|
},
|
|
28834
28893
|
destroy: (container) => {
|
|
28835
|
-
partsByContainer$
|
|
28894
|
+
partsByContainer$7.delete(container);
|
|
28836
28895
|
container.destroy({ children: true });
|
|
28837
28896
|
}
|
|
28838
28897
|
};
|
|
28839
28898
|
//#endregion
|
|
28840
28899
|
//#region ../sdk/src/board/render/renderers/shape-card-renderer.ts
|
|
28841
28900
|
const DEFAULT_ROUNDED_RADIUS = 8;
|
|
28842
|
-
const partsByContainer$
|
|
28901
|
+
const partsByContainer$6 = /* @__PURE__ */ new WeakMap();
|
|
28843
28902
|
const pathCache = /* @__PURE__ */ new Map();
|
|
28844
28903
|
function parsedPath(d) {
|
|
28845
28904
|
if (pathCache.has(d)) return pathCache.get(d) ?? null;
|
|
@@ -28920,14 +28979,12 @@ function outlinePoints(geometry, width, height, radius) {
|
|
|
28920
28979
|
default: return roundRectPoints(width, height, radius);
|
|
28921
28980
|
}
|
|
28922
28981
|
}
|
|
28923
|
-
function sync$
|
|
28924
|
-
const parts = partsByContainer$
|
|
28982
|
+
function sync$6(container, item, context) {
|
|
28983
|
+
const parts = partsByContainer$6.get(container);
|
|
28925
28984
|
if (!parts) return;
|
|
28926
28985
|
positionShell(parts.root, item);
|
|
28927
28986
|
const { width, height } = item.frame;
|
|
28928
28987
|
const { props, style } = item;
|
|
28929
|
-
const selected = context.selectedIds.has(item.id);
|
|
28930
|
-
const hovered = context.hoveredId === item.id;
|
|
28931
28988
|
const stroke = itemColor(context, style.stroke ?? style.fill, "brand");
|
|
28932
28989
|
const fill = itemColor(context, style.fill ?? style.stroke, "brand", "fill");
|
|
28933
28990
|
const fillOpacity = (style.fillOpacity ?? (style.fill ? 1 : 0)) * itemAlpha(context, style.fill ?? style.stroke);
|
|
@@ -28937,8 +28994,6 @@ function sync$5(container, item, context) {
|
|
|
28937
28994
|
const visualSig = [
|
|
28938
28995
|
width,
|
|
28939
28996
|
height,
|
|
28940
|
-
selected,
|
|
28941
|
-
hovered,
|
|
28942
28997
|
props.geometry,
|
|
28943
28998
|
props.path,
|
|
28944
28999
|
fill,
|
|
@@ -28948,8 +29003,7 @@ function sync$5(container, item, context) {
|
|
|
28948
29003
|
strokeWidth,
|
|
28949
29004
|
style.dash,
|
|
28950
29005
|
style.radius,
|
|
28951
|
-
style.trim
|
|
28952
|
-
context.palette.muted
|
|
29006
|
+
style.trim
|
|
28953
29007
|
].join("|");
|
|
28954
29008
|
if (visualSig !== parts.visualSig) {
|
|
28955
29009
|
parts.visualSig = visualSig;
|
|
@@ -28961,8 +29015,7 @@ function sync$5(container, item, context) {
|
|
|
28961
29015
|
alpha: fillOpacity
|
|
28962
29016
|
});
|
|
28963
29017
|
}
|
|
28964
|
-
const
|
|
28965
|
-
const pattern = dashPattern(style.dash, lineWidth);
|
|
29018
|
+
const pattern = dashPattern(style.dash, strokeWidth);
|
|
28966
29019
|
const partial = style.trim !== void 0 && style.trim < 1;
|
|
28967
29020
|
if (strokeWidth > 0 && (!partial || style.trim)) {
|
|
28968
29021
|
if ((pattern || partial) && props.geometry !== "path") {
|
|
@@ -28970,9 +29023,9 @@ function sync$5(container, item, context) {
|
|
|
28970
29023
|
tracePolyline(parts.shape, trimPolyline(outlinePoints(props.geometry, width, height, radius), style.trim), pattern);
|
|
28971
29024
|
} else traceShapeOutline(parts.shape, props, width, height, style.radius);
|
|
28972
29025
|
parts.shape.stroke({
|
|
28973
|
-
color:
|
|
28974
|
-
width:
|
|
28975
|
-
alpha:
|
|
29026
|
+
color: stroke,
|
|
29027
|
+
width: strokeWidth,
|
|
29028
|
+
alpha: .85 * strokeAlpha,
|
|
28976
29029
|
cap: partial || pattern ? "round" : "butt",
|
|
28977
29030
|
join: "round"
|
|
28978
29031
|
});
|
|
@@ -29021,7 +29074,7 @@ const shapeCardRenderer = {
|
|
|
29021
29074
|
});
|
|
29022
29075
|
label.anchor.set(.5);
|
|
29023
29076
|
root.addChild(shape, label);
|
|
29024
|
-
partsByContainer$
|
|
29077
|
+
partsByContainer$6.set(root, {
|
|
29025
29078
|
root,
|
|
29026
29079
|
shape,
|
|
29027
29080
|
label,
|
|
@@ -29030,11 +29083,11 @@ const shapeCardRenderer = {
|
|
|
29030
29083
|
wrapWidth: 0,
|
|
29031
29084
|
resolution
|
|
29032
29085
|
});
|
|
29033
|
-
if (item.type === "shape") sync$
|
|
29086
|
+
if (item.type === "shape") sync$6(root, item, context);
|
|
29034
29087
|
return root;
|
|
29035
29088
|
},
|
|
29036
29089
|
update: (container, item, context) => {
|
|
29037
|
-
if (item.type === "shape") sync$
|
|
29090
|
+
if (item.type === "shape") sync$6(container, item, context);
|
|
29038
29091
|
},
|
|
29039
29092
|
renderFar: (graphics, item, context) => {
|
|
29040
29093
|
if (item.type !== "shape") return;
|
|
@@ -29046,15 +29099,15 @@ const shapeCardRenderer = {
|
|
|
29046
29099
|
});
|
|
29047
29100
|
},
|
|
29048
29101
|
destroy: (container) => {
|
|
29049
|
-
partsByContainer$
|
|
29050
|
-
partsByContainer$
|
|
29102
|
+
partsByContainer$6.get(container)?.root.destroy({ children: true });
|
|
29103
|
+
partsByContainer$6.delete(container);
|
|
29051
29104
|
}
|
|
29052
29105
|
};
|
|
29053
29106
|
//#endregion
|
|
29054
29107
|
//#region ../sdk/src/board/render/renderers/custom-card-renderer.ts
|
|
29055
|
-
const partsByContainer$
|
|
29056
|
-
function sync$
|
|
29057
|
-
const parts = partsByContainer$
|
|
29108
|
+
const partsByContainer$5 = /* @__PURE__ */ new WeakMap();
|
|
29109
|
+
function sync$5(container, item, context) {
|
|
29110
|
+
const parts = partsByContainer$5.get(container);
|
|
29058
29111
|
if (!parts) return;
|
|
29059
29112
|
if (parts.id !== item.id) {
|
|
29060
29113
|
context.scripts?.release(parts.id);
|
|
@@ -29066,27 +29119,25 @@ function sync$4(container, item, context) {
|
|
|
29066
29119
|
const texture = context.scripts?.frame(item, context.time, resolution) ?? null;
|
|
29067
29120
|
const error = context.scripts?.error(item.id) ?? null;
|
|
29068
29121
|
parts.sprite.visible = Boolean(texture);
|
|
29069
|
-
|
|
29122
|
+
const display = texture ?? Texture.EMPTY;
|
|
29123
|
+
if (parts.sprite.texture !== display) parts.sprite.texture = display;
|
|
29070
29124
|
parts.sprite.width = width;
|
|
29071
29125
|
parts.sprite.height = height;
|
|
29072
|
-
const selected = context.selectedIds.has(item.id);
|
|
29073
29126
|
const ready = Boolean(texture) || context.scripts?.ready?.(item.id) === true;
|
|
29074
29127
|
const message = error ? `${item.script.src}\n${error}` : ready ? "" : item.script.src;
|
|
29075
29128
|
const sig = [
|
|
29076
29129
|
width,
|
|
29077
29130
|
height,
|
|
29078
|
-
selected,
|
|
29079
29131
|
Boolean(texture),
|
|
29080
29132
|
message,
|
|
29081
|
-
context.
|
|
29082
|
-
context.palette.muted
|
|
29133
|
+
context.themeKey
|
|
29083
29134
|
].join("|");
|
|
29084
29135
|
if (sig === parts.sig) return;
|
|
29085
29136
|
parts.sig = sig;
|
|
29086
29137
|
parts.placeholder.clear();
|
|
29087
|
-
if (!ready ||
|
|
29088
|
-
color:
|
|
29089
|
-
width:
|
|
29138
|
+
if (!ready || error) parts.placeholder.rect(0, 0, width, height).stroke({
|
|
29139
|
+
color: context.palette.border,
|
|
29140
|
+
width: 1,
|
|
29090
29141
|
alpha: .8
|
|
29091
29142
|
});
|
|
29092
29143
|
parts.label.visible = !ready || Boolean(error);
|
|
@@ -29116,7 +29167,7 @@ const customCardRenderer = {
|
|
|
29116
29167
|
});
|
|
29117
29168
|
label.anchor.set(.5);
|
|
29118
29169
|
root.addChild(sprite, placeholder, label);
|
|
29119
|
-
partsByContainer$
|
|
29170
|
+
partsByContainer$5.set(root, {
|
|
29120
29171
|
id: item.id,
|
|
29121
29172
|
root,
|
|
29122
29173
|
sprite,
|
|
@@ -29124,11 +29175,11 @@ const customCardRenderer = {
|
|
|
29124
29175
|
label,
|
|
29125
29176
|
sig: ""
|
|
29126
29177
|
});
|
|
29127
|
-
if (item.type === "custom") sync$
|
|
29178
|
+
if (item.type === "custom") sync$5(root, item, context);
|
|
29128
29179
|
return root;
|
|
29129
29180
|
},
|
|
29130
29181
|
update: (container, item, context) => {
|
|
29131
|
-
if (item.type === "custom") sync$
|
|
29182
|
+
if (item.type === "custom") sync$5(container, item, context);
|
|
29132
29183
|
},
|
|
29133
29184
|
renderFar: (graphics, item, context) => {
|
|
29134
29185
|
drawFarPlate(graphics, item.frame, {
|
|
@@ -29137,27 +29188,15 @@ const customCardRenderer = {
|
|
|
29137
29188
|
});
|
|
29138
29189
|
},
|
|
29139
29190
|
destroy: (container, context) => {
|
|
29140
|
-
const parts = partsByContainer$
|
|
29191
|
+
const parts = partsByContainer$5.get(container);
|
|
29141
29192
|
if (parts) context.scripts?.release(parts.id);
|
|
29142
29193
|
parts?.root.destroy({ children: true });
|
|
29143
|
-
partsByContainer$
|
|
29194
|
+
partsByContainer$5.delete(container);
|
|
29144
29195
|
}
|
|
29145
29196
|
};
|
|
29146
29197
|
//#endregion
|
|
29147
29198
|
//#region ../sdk/src/board/render/renderers/image-card-renderer.ts
|
|
29148
|
-
const partsByContainer$
|
|
29149
|
-
const RADIUS$2 = 2;
|
|
29150
|
-
function layoutContain$1(sprite, width, height) {
|
|
29151
|
-
const texture = sprite.texture;
|
|
29152
|
-
const tw = texture.width;
|
|
29153
|
-
const th = texture.height;
|
|
29154
|
-
if (!tw || !th) return;
|
|
29155
|
-
const scale = Math.min(width / tw, height / th);
|
|
29156
|
-
sprite.width = tw * scale;
|
|
29157
|
-
sprite.height = th * scale;
|
|
29158
|
-
sprite.x = (width - sprite.width) / 2;
|
|
29159
|
-
sprite.y = (height - sprite.height) / 2;
|
|
29160
|
-
}
|
|
29199
|
+
const partsByContainer$4 = /* @__PURE__ */ new WeakMap();
|
|
29161
29200
|
function cropRect(crop) {
|
|
29162
29201
|
if (!crop) return null;
|
|
29163
29202
|
const w = Math.min(crop.w, 1 - crop.x);
|
|
@@ -29191,116 +29230,640 @@ function showTexture(parts, texture, crop) {
|
|
|
29191
29230
|
if (parts.sprite.texture !== display) parts.sprite.texture = display;
|
|
29192
29231
|
if (previous && previous !== parts.cropped) previous.destroy(false);
|
|
29193
29232
|
}
|
|
29233
|
+
const PRINT_MARGIN = 6;
|
|
29234
|
+
function sync$4(container, item, context) {
|
|
29235
|
+
const parts = partsByContainer$4.get(container);
|
|
29236
|
+
if (!parts) return;
|
|
29237
|
+
positionShell(parts.root, item);
|
|
29238
|
+
const { width, height } = item.frame;
|
|
29239
|
+
const key = context.assetKey(item);
|
|
29240
|
+
const texture = key ? context.getTexture(key) : null;
|
|
29241
|
+
const failed = Boolean(key && !texture && context.hasError(key));
|
|
29242
|
+
const elevation = cardElevation(context, item.id);
|
|
29243
|
+
const sig = [
|
|
29244
|
+
key ?? "",
|
|
29245
|
+
width,
|
|
29246
|
+
height,
|
|
29247
|
+
texture ? `${texture.width}x${texture.height}` : "none",
|
|
29248
|
+
JSON.stringify(item.props.crop ?? null),
|
|
29249
|
+
failed,
|
|
29250
|
+
elevation,
|
|
29251
|
+
context.themeKey
|
|
29252
|
+
].join("|");
|
|
29253
|
+
if (sig === parts.sig) return;
|
|
29254
|
+
parts.sig = sig;
|
|
29255
|
+
showTexture(parts, texture, item.props.crop);
|
|
29256
|
+
const display = parts.sprite.texture;
|
|
29257
|
+
const framed = context.style.media === "framed";
|
|
29258
|
+
const margin = framed ? Math.min(PRINT_MARGIN, width / 8, height / 8) : 0;
|
|
29259
|
+
const area = {
|
|
29260
|
+
x: margin,
|
|
29261
|
+
y: margin,
|
|
29262
|
+
width: width - margin * 2,
|
|
29263
|
+
height: height - margin * 2
|
|
29264
|
+
};
|
|
29265
|
+
const fitted = texture ? containRect(area.width, area.height, display.width, display.height) : {
|
|
29266
|
+
...area,
|
|
29267
|
+
x: 0,
|
|
29268
|
+
y: 0
|
|
29269
|
+
};
|
|
29270
|
+
const picture = {
|
|
29271
|
+
x: area.x + fitted.x,
|
|
29272
|
+
y: area.y + fitted.y,
|
|
29273
|
+
width: fitted.width,
|
|
29274
|
+
height: fitted.height
|
|
29275
|
+
};
|
|
29276
|
+
const card = framed ? {
|
|
29277
|
+
x: picture.x - margin,
|
|
29278
|
+
y: picture.y - margin,
|
|
29279
|
+
width: picture.width + margin * 2,
|
|
29280
|
+
height: picture.height + margin * 2
|
|
29281
|
+
} : picture;
|
|
29282
|
+
parts.sprite.visible = Boolean(texture);
|
|
29283
|
+
if (texture) {
|
|
29284
|
+
parts.sprite.position.set(picture.x, picture.y);
|
|
29285
|
+
parts.sprite.width = picture.width;
|
|
29286
|
+
parts.sprite.height = picture.height;
|
|
29287
|
+
}
|
|
29288
|
+
traceCardOutline(parts.mask.clear(), picture, framed ? {
|
|
29289
|
+
corner: "round",
|
|
29290
|
+
radius: 0
|
|
29291
|
+
} : context.style).fill({ color: 16777215 });
|
|
29292
|
+
parts.placeholder.clear();
|
|
29293
|
+
if (texture && !framed) return;
|
|
29294
|
+
drawCardSurface(parts.placeholder, card, context.style, {
|
|
29295
|
+
fill: context.palette.surface,
|
|
29296
|
+
border: texture ? null : failed ? context.palette.border : context.palette.hover,
|
|
29297
|
+
elevation
|
|
29298
|
+
});
|
|
29299
|
+
if (texture) return;
|
|
29300
|
+
const cx = width / 2;
|
|
29301
|
+
const cy = height / 2;
|
|
29302
|
+
if (failed) parts.placeholder.moveTo(cx - 10, cy - 10).lineTo(cx + 10, cy + 10).moveTo(cx + 10, cy - 10).lineTo(cx - 10, cy + 10).stroke({
|
|
29303
|
+
color: context.palette.muted,
|
|
29304
|
+
width: 1.5,
|
|
29305
|
+
alpha: .8
|
|
29306
|
+
});
|
|
29307
|
+
else parts.placeholder.circle(cx, cy, 6).stroke({
|
|
29308
|
+
color: context.palette.muted,
|
|
29309
|
+
width: 1.25,
|
|
29310
|
+
alpha: .55
|
|
29311
|
+
});
|
|
29312
|
+
}
|
|
29313
|
+
const imageCardRenderer = {
|
|
29314
|
+
id: "image-card",
|
|
29315
|
+
canRender: (item) => item.type === "image",
|
|
29316
|
+
create: (item, context) => {
|
|
29317
|
+
const root = new Container();
|
|
29318
|
+
const sprite = new Sprite(Texture.EMPTY);
|
|
29319
|
+
const placeholder = new Graphics();
|
|
29320
|
+
const mask = new Graphics();
|
|
29321
|
+
root.addChild(placeholder, sprite, mask);
|
|
29322
|
+
sprite.mask = mask;
|
|
29323
|
+
partsByContainer$4.set(root, {
|
|
29324
|
+
root,
|
|
29325
|
+
sprite,
|
|
29326
|
+
placeholder,
|
|
29327
|
+
mask,
|
|
29328
|
+
sig: "",
|
|
29329
|
+
cropped: null,
|
|
29330
|
+
cropSource: null,
|
|
29331
|
+
cropKey: ""
|
|
29332
|
+
});
|
|
29333
|
+
if (item.type === "image") sync$4(root, item, context);
|
|
29334
|
+
return root;
|
|
29335
|
+
},
|
|
29336
|
+
update: (container, item, context) => {
|
|
29337
|
+
if (item.type === "image") sync$4(container, item, context);
|
|
29338
|
+
},
|
|
29339
|
+
renderFar: (graphics, item, context) => {
|
|
29340
|
+
drawFarPlate(graphics, item.frame, {
|
|
29341
|
+
fill: context.palette.hover,
|
|
29342
|
+
fillAlpha: .9
|
|
29343
|
+
});
|
|
29344
|
+
},
|
|
29345
|
+
destroy: (container) => {
|
|
29346
|
+
const parts = partsByContainer$4.get(container);
|
|
29347
|
+
parts?.root.destroy({ children: true });
|
|
29348
|
+
parts?.cropped?.destroy(false);
|
|
29349
|
+
partsByContainer$4.delete(container);
|
|
29350
|
+
}
|
|
29351
|
+
};
|
|
29352
|
+
//#endregion
|
|
29353
|
+
//#region ../sdk/src/board/render/renderers/task-card-renderer.ts
|
|
29354
|
+
const PADDING = 12;
|
|
29355
|
+
const META_HEIGHT = 28;
|
|
29356
|
+
const PLAY_BADGE_RADIUS = 15;
|
|
29357
|
+
const SHIMMER_PERIOD_MS = 1600;
|
|
29358
|
+
const SHIMMER_FRAME_MS = 33;
|
|
29359
|
+
const REVEAL_MS = 180;
|
|
29360
|
+
const SECOND = 1e3;
|
|
29361
|
+
const partsByContainer$3 = /* @__PURE__ */ new WeakMap();
|
|
29362
|
+
function previewKindFor(artifact) {
|
|
29363
|
+
if (!artifact) return "empty";
|
|
29364
|
+
if (artifact.type === "image" || artifact.type === "video") return "texture";
|
|
29365
|
+
if (artifact.type === "audio") return artifact.previewUrl ? "texture" : "waveform";
|
|
29366
|
+
return artifact.textExcerpt ? "text" : "empty";
|
|
29367
|
+
}
|
|
29368
|
+
function liveStatus(item, context) {
|
|
29369
|
+
const { snapshot } = item.props;
|
|
29370
|
+
const live = snapshot.status === "completed" ? null : context.taskRun(item.props.taskRunId);
|
|
29371
|
+
const liveStart = Date.parse(live?.startedAt ?? "");
|
|
29372
|
+
const working = live?.status === "pending" || live?.status === "running";
|
|
29373
|
+
const adopt = snapshot.status === "failed" ? working && liveStart > Date.parse(snapshot.updatedAt ?? "") : live?.status === "running" || live?.status === "pending" && snapshot.status === "pending";
|
|
29374
|
+
const status = adopt && live ? live.status : snapshot.status;
|
|
29375
|
+
const started = adopt ? liveStart : Date.parse(snapshot.startedAt ?? "");
|
|
29376
|
+
return {
|
|
29377
|
+
status,
|
|
29378
|
+
startedAt: Number.isFinite(started) ? started : null
|
|
29379
|
+
};
|
|
29380
|
+
}
|
|
29381
|
+
function stateSurfaceFor(status, kind, hasTexture, previewFailed) {
|
|
29382
|
+
if (kind === "texture" && !hasTexture) {
|
|
29383
|
+
if (status === "failed") return "failed";
|
|
29384
|
+
return previewFailed ? "unavailable" : "media-loading";
|
|
29385
|
+
}
|
|
29386
|
+
if (kind !== "empty") return null;
|
|
29387
|
+
if (status === "failed") return "failed";
|
|
29388
|
+
if (status === "running") return "generating";
|
|
29389
|
+
if (status === "pending") return "queued";
|
|
29390
|
+
return "empty";
|
|
29391
|
+
}
|
|
29392
|
+
function stateLabel(surface, context) {
|
|
29393
|
+
switch (surface) {
|
|
29394
|
+
case "generating": return context.labels.generating;
|
|
29395
|
+
case "queued": return context.labels.queued;
|
|
29396
|
+
case "failed": return context.labels.failed;
|
|
29397
|
+
case "unavailable": return context.labels.previewUnavailable;
|
|
29398
|
+
case "empty": return context.labels.noPreview;
|
|
29399
|
+
default: return "";
|
|
29400
|
+
}
|
|
29401
|
+
}
|
|
29402
|
+
function statusColor(status, context) {
|
|
29403
|
+
if (status === "failed") return context.colors.rose.stroke;
|
|
29404
|
+
if (status === "running") return context.colors.brand.stroke;
|
|
29405
|
+
return context.colors.neutral.stroke;
|
|
29406
|
+
}
|
|
29407
|
+
function drawPlayBadge(graphics, rect, context) {
|
|
29408
|
+
const radius = Math.min(PLAY_BADGE_RADIUS, Math.max(8, Math.min(rect.width, rect.height) * .16));
|
|
29409
|
+
const cx = rect.x + rect.width / 2;
|
|
29410
|
+
const cy = rect.y + rect.height / 2;
|
|
29411
|
+
graphics.circle(cx, cy, radius).fill({
|
|
29412
|
+
color: context.palette.bg,
|
|
29413
|
+
alpha: .64
|
|
29414
|
+
});
|
|
29415
|
+
const size = radius * .72;
|
|
29416
|
+
graphics.moveTo(cx - size * .34, cy - size * .56).lineTo(cx + size * .62, cy).lineTo(cx - size * .34, cy + size * .56).closePath().fill({
|
|
29417
|
+
color: context.palette.text,
|
|
29418
|
+
alpha: .94
|
|
29419
|
+
});
|
|
29420
|
+
}
|
|
29421
|
+
function drawStateMark(graphics, surface, cx, cy, color) {
|
|
29422
|
+
if (surface === "generating" || surface === "media-loading") {
|
|
29423
|
+
graphics.circle(cx, cy, 4).fill({
|
|
29424
|
+
color,
|
|
29425
|
+
alpha: .9
|
|
29426
|
+
});
|
|
29427
|
+
graphics.circle(cx - 12, cy + 7, 2.5).fill({
|
|
29428
|
+
color,
|
|
29429
|
+
alpha: .48
|
|
29430
|
+
});
|
|
29431
|
+
graphics.circle(cx + 11, cy + 6, 3).fill({
|
|
29432
|
+
color,
|
|
29433
|
+
alpha: .68
|
|
29434
|
+
});
|
|
29435
|
+
graphics.circle(cx + 3, cy - 12, 2).fill({
|
|
29436
|
+
color,
|
|
29437
|
+
alpha: .36
|
|
29438
|
+
});
|
|
29439
|
+
return;
|
|
29440
|
+
}
|
|
29441
|
+
if (surface === "queued") {
|
|
29442
|
+
graphics.circle(cx, cy, 10).stroke({
|
|
29443
|
+
color,
|
|
29444
|
+
width: 1.5,
|
|
29445
|
+
alpha: .62
|
|
29446
|
+
}).circle(cx, cy, 3).fill({
|
|
29447
|
+
color,
|
|
29448
|
+
alpha: .78
|
|
29449
|
+
});
|
|
29450
|
+
return;
|
|
29451
|
+
}
|
|
29452
|
+
if (surface === "failed") {
|
|
29453
|
+
graphics.circle(cx, cy, 11).stroke({
|
|
29454
|
+
color,
|
|
29455
|
+
width: 1.5,
|
|
29456
|
+
alpha: .86
|
|
29457
|
+
});
|
|
29458
|
+
graphics.moveTo(cx - 4, cy - 4).lineTo(cx + 4, cy + 4).moveTo(cx + 4, cy - 4).lineTo(cx - 4, cy + 4).stroke({
|
|
29459
|
+
color,
|
|
29460
|
+
width: 1.5,
|
|
29461
|
+
alpha: .94,
|
|
29462
|
+
cap: "round"
|
|
29463
|
+
});
|
|
29464
|
+
return;
|
|
29465
|
+
}
|
|
29466
|
+
if (surface === "unavailable") graphics.roundRect(cx - 12, cy - 9, 24, 18, 3).stroke({
|
|
29467
|
+
color,
|
|
29468
|
+
width: 1.25,
|
|
29469
|
+
alpha: .62
|
|
29470
|
+
}).moveTo(cx - 8, cy + 5).lineTo(cx + 8, cy - 5).stroke({
|
|
29471
|
+
color,
|
|
29472
|
+
width: 1.25,
|
|
29473
|
+
alpha: .72,
|
|
29474
|
+
cap: "round"
|
|
29475
|
+
});
|
|
29476
|
+
}
|
|
29477
|
+
function drawFailedBadge(graphics, width, color, context) {
|
|
29478
|
+
const cx = Math.max(12, width - 12);
|
|
29479
|
+
graphics.circle(cx, 12, 8).fill({
|
|
29480
|
+
color: context.palette.bg,
|
|
29481
|
+
alpha: .72
|
|
29482
|
+
});
|
|
29483
|
+
graphics.moveTo(cx - 2.5, 9.5).lineTo(cx + 2.5, 14.5).moveTo(cx + 2.5, 9.5).lineTo(cx - 2.5, 14.5).stroke({
|
|
29484
|
+
color,
|
|
29485
|
+
width: 1.5,
|
|
29486
|
+
alpha: .96,
|
|
29487
|
+
cap: "round"
|
|
29488
|
+
});
|
|
29489
|
+
}
|
|
29490
|
+
const shimmerGradients = /* @__PURE__ */ new Map();
|
|
29491
|
+
function shimmerGradient(color) {
|
|
29492
|
+
let gradient = shimmerGradients.get(color);
|
|
29493
|
+
if (!gradient) {
|
|
29494
|
+
const rgb = `${color >> 16 & 255}, ${color >> 8 & 255}, ${color & 255}`;
|
|
29495
|
+
gradient = new FillGradient({
|
|
29496
|
+
type: "linear",
|
|
29497
|
+
start: {
|
|
29498
|
+
x: 0,
|
|
29499
|
+
y: 0
|
|
29500
|
+
},
|
|
29501
|
+
end: {
|
|
29502
|
+
x: 1,
|
|
29503
|
+
y: 0
|
|
29504
|
+
},
|
|
29505
|
+
textureSpace: "local",
|
|
29506
|
+
colorStops: [
|
|
29507
|
+
{
|
|
29508
|
+
offset: 0,
|
|
29509
|
+
color: `rgba(${rgb}, 0)`
|
|
29510
|
+
},
|
|
29511
|
+
{
|
|
29512
|
+
offset: .5,
|
|
29513
|
+
color: `rgba(${rgb}, 0.07)`
|
|
29514
|
+
},
|
|
29515
|
+
{
|
|
29516
|
+
offset: 1,
|
|
29517
|
+
color: `rgba(${rgb}, 0)`
|
|
29518
|
+
}
|
|
29519
|
+
]
|
|
29520
|
+
});
|
|
29521
|
+
shimmerGradients.set(color, gradient);
|
|
29522
|
+
}
|
|
29523
|
+
return gradient;
|
|
29524
|
+
}
|
|
29525
|
+
function drawShimmerBand(graphics, width, height, color) {
|
|
29526
|
+
const band = Math.max(48, width * .45);
|
|
29527
|
+
graphics.clear().rect(-band, 0, band, height).fill(shimmerGradient(color));
|
|
29528
|
+
}
|
|
29529
|
+
const MOSAIC_FRAME_MS = 160;
|
|
29530
|
+
const MOSAIC_CELL = 8;
|
|
29531
|
+
function drawMosaic(graphics, width, height, color, frame) {
|
|
29532
|
+
const columns = Math.max(1, Math.floor(width / MOSAIC_CELL));
|
|
29533
|
+
const rows = Math.max(1, Math.floor(height / MOSAIC_CELL));
|
|
29534
|
+
const left = (width - columns * MOSAIC_CELL) / 2;
|
|
29535
|
+
const top = (height - rows * MOSAIC_CELL) / 2;
|
|
29536
|
+
graphics.clear();
|
|
29537
|
+
for (const [threshold, alpha] of [[.08, .16], [.02, .3]]) {
|
|
29538
|
+
for (let row = 0; row < rows; row += 1) for (let column = 0; column < columns; column += 1) {
|
|
29539
|
+
let hash = Math.imul(column + 1, 2654435761) ^ Math.imul(row + 1, 2246822507) ^ Math.imul(frame + 1, 3266489909);
|
|
29540
|
+
hash ^= hash >>> 15;
|
|
29541
|
+
hash = Math.imul(hash, 739982445);
|
|
29542
|
+
hash ^= hash >>> 12;
|
|
29543
|
+
if ((hash >>> 0) / 4294967295 < threshold) graphics.rect(left + column * MOSAIC_CELL + 1, top + row * MOSAIC_CELL + 1, 6, 6);
|
|
29544
|
+
}
|
|
29545
|
+
graphics.fill({
|
|
29546
|
+
color,
|
|
29547
|
+
alpha
|
|
29548
|
+
});
|
|
29549
|
+
}
|
|
29550
|
+
}
|
|
29551
|
+
function advance(parts, clock) {
|
|
29552
|
+
const { motion } = parts;
|
|
29553
|
+
let next = null;
|
|
29554
|
+
if (motion.mosaic) {
|
|
29555
|
+
const frame = Math.floor(clock / MOSAIC_FRAME_MS);
|
|
29556
|
+
if (frame !== motion.mosaic.step) {
|
|
29557
|
+
motion.mosaic.step = frame;
|
|
29558
|
+
drawMosaic(parts.shimmer, motion.width, motion.mosaic.height, motion.mosaic.color, frame);
|
|
29559
|
+
}
|
|
29560
|
+
next = MOSAIC_FRAME_MS - clock % MOSAIC_FRAME_MS;
|
|
29561
|
+
} else if (motion.shimmer) {
|
|
29562
|
+
const travel = motion.width + parts.shimmer.width;
|
|
29563
|
+
parts.shimmer.x = clock % SHIMMER_PERIOD_MS / SHIMMER_PERIOD_MS * travel;
|
|
29564
|
+
next = SHIMMER_FRAME_MS;
|
|
29565
|
+
}
|
|
29566
|
+
if (motion.startedAt !== null) {
|
|
29567
|
+
const elapsedMs = Date.now() - motion.startedAt;
|
|
29568
|
+
const elapsed = formatBoardDuration(elapsedMs);
|
|
29569
|
+
if (elapsed !== motion.elapsed) {
|
|
29570
|
+
motion.elapsed = elapsed;
|
|
29571
|
+
parts.body.text = `${motion.label} · ${elapsed}`;
|
|
29572
|
+
}
|
|
29573
|
+
const untilNextSecond = SECOND - Math.max(0, elapsedMs) % SECOND;
|
|
29574
|
+
next = next === null ? untilNextSecond : Math.min(next, untilNextSecond);
|
|
29575
|
+
}
|
|
29576
|
+
if (motion.revealFrom !== null) {
|
|
29577
|
+
const progress = Math.min(1, (clock - motion.revealFrom) / REVEAL_MS);
|
|
29578
|
+
parts.preview.alpha = progress * (2 - progress);
|
|
29579
|
+
if (progress >= 1) motion.revealFrom = null;
|
|
29580
|
+
else next = 0;
|
|
29581
|
+
}
|
|
29582
|
+
return next;
|
|
29583
|
+
}
|
|
29194
29584
|
function sync$3(container, item, context) {
|
|
29195
29585
|
const parts = partsByContainer$3.get(container);
|
|
29196
29586
|
if (!parts) return;
|
|
29197
29587
|
positionShell(parts.root, item);
|
|
29198
29588
|
const { width, height } = item.frame;
|
|
29199
|
-
const
|
|
29200
|
-
const
|
|
29589
|
+
const { snapshot } = item.props;
|
|
29590
|
+
const { status, startedAt } = liveStatus(item, context);
|
|
29591
|
+
const full = boardCardDetailed(context.zoom);
|
|
29592
|
+
const elevation = cardElevation(context, item.id);
|
|
29593
|
+
syncCardTag(parts.tag, {
|
|
29594
|
+
glyph: "task",
|
|
29595
|
+
text: snapshot.title,
|
|
29596
|
+
width
|
|
29597
|
+
}, context);
|
|
29598
|
+
const working = status === "pending" || status === "running";
|
|
29599
|
+
const color = statusColor(status, context);
|
|
29201
29600
|
const key = context.assetKey(item);
|
|
29601
|
+
if (key !== parts.assetKey) {
|
|
29602
|
+
if (parts.assetKey) context.releaseTexture(parts.assetKey);
|
|
29603
|
+
parts.assetKey = key;
|
|
29604
|
+
if (key) context.acquireTexture(key);
|
|
29605
|
+
}
|
|
29202
29606
|
const texture = key ? context.getTexture(key) : null;
|
|
29203
|
-
const
|
|
29204
|
-
const
|
|
29205
|
-
const
|
|
29206
|
-
|
|
29607
|
+
const previewFailed = Boolean(key && !texture && context.hasError(key));
|
|
29608
|
+
const artifact = featuredTaskArtifact(snapshot.artifacts);
|
|
29609
|
+
const kind = previewKindFor(artifact);
|
|
29610
|
+
const surface = stateSurfaceFor(status, kind, Boolean(texture), previewFailed);
|
|
29611
|
+
const frame = {
|
|
29612
|
+
x: 1,
|
|
29613
|
+
y: 1,
|
|
29614
|
+
width: Math.max(1, width - 2),
|
|
29615
|
+
height: Math.max(1, height - 2)
|
|
29616
|
+
};
|
|
29617
|
+
const metaText = artifact || working ? snapshot.model ?? "" : "";
|
|
29618
|
+
const showMeta = full && Boolean(metaText);
|
|
29619
|
+
const failedWithOutput = status === "failed" && kind !== "empty";
|
|
29620
|
+
const count = artifact && snapshot.artifactCount > 1 ? String(snapshot.artifactCount) : "";
|
|
29621
|
+
const showBadge = full && Boolean(count);
|
|
29622
|
+
const label = stateLabel(surface, context);
|
|
29623
|
+
const counting = full && working && startedAt !== null && surface !== null;
|
|
29624
|
+
const elapsed = counting ? formatBoardDuration(Date.now() - startedAt) : "";
|
|
29625
|
+
const detailText = !full || !surface ? "" : status === "failed" ? snapshot.errorExcerpt ?? "" : working ? snapshot.promptExcerpt ?? "" : "";
|
|
29626
|
+
const textArtifact = kind === "text" && artifact?.type === "text";
|
|
29627
|
+
const bodyText = textArtifact ? artifact.textExcerpt : counting ? `${label} · ${elapsed}` : label;
|
|
29628
|
+
syncTextResolution(parts.body, parts, context.zoom);
|
|
29629
|
+
syncTextResolution(parts.detail, parts, context.zoom);
|
|
29630
|
+
syncTextResolution(parts.meta, parts, context.zoom);
|
|
29631
|
+
syncTextResolution(parts.badge, parts, context.zoom);
|
|
29632
|
+
const textSig = [
|
|
29633
|
+
counting ? label : bodyText,
|
|
29634
|
+
detailText,
|
|
29635
|
+
metaText,
|
|
29636
|
+
count,
|
|
29637
|
+
kind,
|
|
29638
|
+
surface,
|
|
29639
|
+
full,
|
|
29207
29640
|
width,
|
|
29208
29641
|
height,
|
|
29209
|
-
|
|
29210
|
-
|
|
29211
|
-
|
|
29212
|
-
|
|
29213
|
-
failed,
|
|
29214
|
-
context.colorScheme
|
|
29642
|
+
color,
|
|
29643
|
+
context.palette.text,
|
|
29644
|
+
context.palette.muted,
|
|
29645
|
+
context.style.font
|
|
29215
29646
|
].join("|");
|
|
29216
|
-
if (
|
|
29217
|
-
|
|
29218
|
-
|
|
29219
|
-
|
|
29220
|
-
|
|
29221
|
-
|
|
29222
|
-
|
|
29223
|
-
parts.
|
|
29224
|
-
|
|
29225
|
-
|
|
29226
|
-
|
|
29227
|
-
|
|
29228
|
-
|
|
29229
|
-
|
|
29647
|
+
if (textSig !== parts.textSig) {
|
|
29648
|
+
parts.textSig = textSig;
|
|
29649
|
+
parts.body.style.fontFamily = context.style.font;
|
|
29650
|
+
parts.detail.style.fontFamily = context.style.font;
|
|
29651
|
+
const wrap = Math.max(24, width - 24);
|
|
29652
|
+
parts.body.style.fill = surface === "failed" ? color : context.palette.text;
|
|
29653
|
+
parts.body.anchor.set(textArtifact ? 0 : .5, 0);
|
|
29654
|
+
fitTextToLines(parts.body, bodyText, textArtifact ? Math.max(1, Math.floor((height - 24 - (showMeta ? META_HEIGHT : 0)) / 16)) : 1, wrap);
|
|
29655
|
+
parts.detail.style.fill = context.palette.muted;
|
|
29656
|
+
fitTextToLines(parts.detail, detailText, height - 24 > 120 ? 2 : 1, Math.min(wrap, 360));
|
|
29657
|
+
parts.meta.style.fill = context.palette.text;
|
|
29658
|
+
fitTextToLines(parts.meta, metaText, 1, wrap);
|
|
29659
|
+
parts.badge.style.fill = context.palette.text;
|
|
29660
|
+
if (parts.badge.text !== count) parts.badge.text = count;
|
|
29661
|
+
}
|
|
29662
|
+
const badgeWidth = Math.max(22, parts.badge.width + 12);
|
|
29663
|
+
const visualSig = [
|
|
29664
|
+
width,
|
|
29665
|
+
height,
|
|
29666
|
+
full,
|
|
29667
|
+
elevation,
|
|
29668
|
+
color,
|
|
29669
|
+
kind,
|
|
29670
|
+
surface,
|
|
29671
|
+
showMeta,
|
|
29672
|
+
showBadge && badgeWidth,
|
|
29673
|
+
failedWithOutput,
|
|
29674
|
+
artifact?.type ?? "none",
|
|
29675
|
+
artifact?.id ?? "none",
|
|
29676
|
+
item.props.taskRunId,
|
|
29677
|
+
texture ? `${texture.width}x${texture.height}` : "none",
|
|
29678
|
+
context.themeKey
|
|
29679
|
+
].join("|");
|
|
29680
|
+
if (visualSig !== parts.visualSig) {
|
|
29681
|
+
parts.visualSig = visualSig;
|
|
29682
|
+
const rect = {
|
|
29683
|
+
x: 0,
|
|
29684
|
+
y: 0,
|
|
29685
|
+
width,
|
|
29686
|
+
height
|
|
29687
|
+
};
|
|
29688
|
+
drawCardSurface(parts.plate.clear(), rect, context.style, {
|
|
29689
|
+
fill: context.palette.surface,
|
|
29690
|
+
border: context.palette.border,
|
|
29691
|
+
borderAlpha: .82,
|
|
29692
|
+
elevation
|
|
29230
29693
|
});
|
|
29231
|
-
|
|
29232
|
-
|
|
29233
|
-
|
|
29234
|
-
|
|
29235
|
-
width: 1.5,
|
|
29236
|
-
alpha: .8
|
|
29694
|
+
traceCardOutline(parts.clip.clear(), rect, context.style, -1).fill({ color: 16777215 });
|
|
29695
|
+
parts.previewBg.clear().rect(frame.x, frame.y, frame.width, frame.height).fill({
|
|
29696
|
+
color: context.palette.hover,
|
|
29697
|
+
alpha: .5
|
|
29237
29698
|
});
|
|
29238
|
-
|
|
29239
|
-
|
|
29240
|
-
|
|
29241
|
-
|
|
29699
|
+
parts.previewMask.clear().rect(frame.x, frame.y, frame.width, frame.height).fill({ color: 16777215 });
|
|
29700
|
+
if (context.style.progress === "shimmer") drawShimmerBand(parts.shimmer, frame.width, frame.height, context.palette.text);
|
|
29701
|
+
parts.shimmer.position.set(context.style.progress === "shimmer" ? 0 : frame.x, frame.y);
|
|
29702
|
+
parts.previewArt.clear();
|
|
29703
|
+
if (kind === "waveform") {
|
|
29704
|
+
const bottomInset = showMeta ? META_HEIGHT : 0;
|
|
29705
|
+
drawAudioWaveform(parts.previewArt, item.props.taskRunId, {
|
|
29706
|
+
x: frame.x + PADDING,
|
|
29707
|
+
y: frame.y + PADDING,
|
|
29708
|
+
width: Math.max(1, frame.width - 24),
|
|
29709
|
+
height: Math.max(1, frame.height - 24 - bottomInset)
|
|
29710
|
+
}, context.colors.brand.stroke);
|
|
29711
|
+
}
|
|
29712
|
+
if (full && (artifact?.type === "audio" || artifact?.type === "video" && texture)) drawPlayBadge(parts.previewArt, frame, context);
|
|
29713
|
+
if (surface) {
|
|
29714
|
+
const markY = frame.y + frame.height / 2 - (full && label ? 18 : 0);
|
|
29715
|
+
drawStateMark(parts.previewArt, surface, frame.x + frame.width / 2, markY, surface === "failed" ? color : context.colors.neutral.stroke);
|
|
29716
|
+
}
|
|
29717
|
+
if (showMeta) parts.previewArt.rect(frame.x, frame.y + frame.height - META_HEIGHT, frame.width, META_HEIGHT).fill({
|
|
29718
|
+
color: context.palette.bg,
|
|
29719
|
+
alpha: .68
|
|
29242
29720
|
});
|
|
29243
|
-
|
|
29244
|
-
|
|
29245
|
-
|
|
29246
|
-
const hasPixels = Boolean(texture) && parts.sprite.width > 0;
|
|
29247
|
-
const ox = hasPixels ? parts.sprite.x : 0;
|
|
29248
|
-
const oy = hasPixels ? parts.sprite.y : 0;
|
|
29249
|
-
const ow = hasPixels ? parts.sprite.width : width;
|
|
29250
|
-
const oh = hasPixels ? parts.sprite.height : height;
|
|
29251
|
-
parts.placeholder.visible = true;
|
|
29252
|
-
parts.placeholder.roundRect(ox, oy, ow, oh, RADIUS$2).stroke({
|
|
29253
|
-
color: selected ? context.palette.brand : context.palette.muted,
|
|
29254
|
-
width: selected ? 2 : 1,
|
|
29255
|
-
alpha: selected ? .95 : .7
|
|
29721
|
+
if (showBadge) parts.previewArt.roundRect(width - badgeWidth - 8, 8, badgeWidth, 20, 10).fill({
|
|
29722
|
+
color: context.palette.bg,
|
|
29723
|
+
alpha: .72
|
|
29256
29724
|
});
|
|
29725
|
+
if (failedWithOutput) drawFailedBadge(parts.previewArt, width, color, context);
|
|
29726
|
+
}
|
|
29727
|
+
const showPreview = kind === "texture" && Boolean(texture);
|
|
29728
|
+
const revealKey = showPreview ? `${artifact?.id}:${texture?.uid}` : null;
|
|
29729
|
+
const sameCard = parts.motion.itemId === item.id;
|
|
29730
|
+
parts.motion.itemId = item.id;
|
|
29731
|
+
if (revealKey !== parts.motion.revealKey || !sameCard) {
|
|
29732
|
+
const appearing = sameCard && parts.motion.revealKey === null && revealKey !== null;
|
|
29733
|
+
parts.motion.revealKey = revealKey;
|
|
29734
|
+
parts.motion.revealFrom = appearing && !context.reducedMotion ? performance.now() : null;
|
|
29735
|
+
parts.preview.alpha = parts.motion.revealFrom === null ? 1 : 0;
|
|
29736
|
+
}
|
|
29737
|
+
parts.preview.visible = showPreview;
|
|
29738
|
+
if (showPreview && texture) {
|
|
29739
|
+
if (parts.preview.texture !== texture) parts.preview.texture = texture;
|
|
29740
|
+
const fitted = containRect(frame.width, frame.height, texture.width, texture.height);
|
|
29741
|
+
parts.preview.position.set(frame.x + fitted.x, frame.y + fitted.y);
|
|
29742
|
+
parts.preview.width = fitted.width;
|
|
29743
|
+
parts.preview.height = fitted.height;
|
|
29257
29744
|
}
|
|
29745
|
+
parts.body.visible = full && Boolean(bodyText);
|
|
29746
|
+
parts.detail.visible = full && Boolean(detailText);
|
|
29747
|
+
parts.meta.visible = showMeta;
|
|
29748
|
+
parts.badge.visible = showBadge;
|
|
29749
|
+
if (textArtifact) parts.body.position.set(PADDING, PADDING);
|
|
29750
|
+
else parts.body.position.set(width / 2, height / 2 + 2);
|
|
29751
|
+
parts.detail.position.set(width / 2, height / 2 + 2 + parts.body.height + 4);
|
|
29752
|
+
parts.meta.position.set(PADDING, height - META_HEIGHT + 7);
|
|
29753
|
+
parts.badge.position.set(width - 8 - badgeWidth / 2, 18);
|
|
29754
|
+
parts.motion.width = frame.width;
|
|
29755
|
+
parts.motion.shimmer = full && working && kind !== "texture" && !context.reducedMotion;
|
|
29756
|
+
const mosaic = parts.motion.shimmer && context.style.progress === "mosaic";
|
|
29757
|
+
parts.motion.mosaic = mosaic ? {
|
|
29758
|
+
color: context.palette.brand,
|
|
29759
|
+
height: frame.height,
|
|
29760
|
+
step: -1
|
|
29761
|
+
} : null;
|
|
29762
|
+
parts.shimmer.visible = parts.motion.shimmer;
|
|
29763
|
+
parts.motion.startedAt = counting ? startedAt : null;
|
|
29764
|
+
parts.motion.label = label;
|
|
29765
|
+
parts.motion.elapsed = elapsed;
|
|
29258
29766
|
}
|
|
29259
|
-
const
|
|
29260
|
-
id: "
|
|
29261
|
-
canRender: (item) => item.type === "
|
|
29767
|
+
const taskCardRenderer = {
|
|
29768
|
+
id: "task-card",
|
|
29769
|
+
canRender: (item) => item.type === "task",
|
|
29262
29770
|
create: (item, context) => {
|
|
29263
29771
|
const root = new Container();
|
|
29264
|
-
const
|
|
29265
|
-
const
|
|
29266
|
-
const
|
|
29267
|
-
const
|
|
29268
|
-
|
|
29269
|
-
|
|
29270
|
-
|
|
29271
|
-
|
|
29272
|
-
|
|
29273
|
-
|
|
29772
|
+
const plate = new Graphics();
|
|
29773
|
+
const clip = new Graphics();
|
|
29774
|
+
const previewBg = new Graphics();
|
|
29775
|
+
const preview = new Sprite();
|
|
29776
|
+
const previewMask = new Graphics();
|
|
29777
|
+
const shimmer = new Graphics();
|
|
29778
|
+
const previewArt = new Graphics();
|
|
29779
|
+
const resolution = textResolutionForZoom(context.zoom);
|
|
29780
|
+
const text = (fontFamily, fontSize, fontWeight) => new Text({
|
|
29781
|
+
text: "",
|
|
29782
|
+
style: {
|
|
29783
|
+
fontFamily,
|
|
29784
|
+
fontSize,
|
|
29785
|
+
fontWeight,
|
|
29786
|
+
wordWrap: true,
|
|
29787
|
+
breakWords: true
|
|
29788
|
+
},
|
|
29789
|
+
resolution,
|
|
29790
|
+
roundPixels: true
|
|
29791
|
+
});
|
|
29792
|
+
const body = text(BOARD_FONT_STACK, 11.5, "500");
|
|
29793
|
+
const detail = text(BOARD_FONT_STACK, 10.5, "400");
|
|
29794
|
+
const meta = text(BOARD_MONO_FONT_STACK, 10, "500");
|
|
29795
|
+
const badge = text(BOARD_MONO_FONT_STACK, 10, "500");
|
|
29796
|
+
badge.style.wordWrap = false;
|
|
29797
|
+
badge.anchor.set(.5);
|
|
29798
|
+
detail.anchor.set(.5, 0);
|
|
29799
|
+
detail.style.align = "center";
|
|
29800
|
+
preview.mask = previewMask;
|
|
29801
|
+
const content = new Container();
|
|
29802
|
+
content.mask = clip;
|
|
29803
|
+
content.addChild(previewBg, shimmer, preview, previewMask, previewArt, body, detail, meta, badge);
|
|
29804
|
+
const tag = createCardTag();
|
|
29805
|
+
root.addChild(plate, content, clip, tag.root);
|
|
29274
29806
|
partsByContainer$3.set(root, {
|
|
29275
29807
|
root,
|
|
29276
|
-
|
|
29277
|
-
|
|
29278
|
-
|
|
29279
|
-
|
|
29280
|
-
|
|
29281
|
-
|
|
29808
|
+
tag,
|
|
29809
|
+
plate,
|
|
29810
|
+
clip,
|
|
29811
|
+
previewBg,
|
|
29812
|
+
preview,
|
|
29813
|
+
previewMask,
|
|
29814
|
+
shimmer,
|
|
29815
|
+
previewArt,
|
|
29816
|
+
badge,
|
|
29817
|
+
body,
|
|
29818
|
+
detail,
|
|
29819
|
+
meta,
|
|
29820
|
+
assetKey: null,
|
|
29821
|
+
visualSig: "",
|
|
29822
|
+
textSig: "",
|
|
29823
|
+
resolution,
|
|
29824
|
+
motion: {
|
|
29825
|
+
itemId: "",
|
|
29826
|
+
width: 0,
|
|
29827
|
+
shimmer: false,
|
|
29828
|
+
mosaic: null,
|
|
29829
|
+
startedAt: null,
|
|
29830
|
+
label: "",
|
|
29831
|
+
elapsed: "",
|
|
29832
|
+
revealFrom: null,
|
|
29833
|
+
revealKey: null
|
|
29834
|
+
}
|
|
29282
29835
|
});
|
|
29283
|
-
if (item.type === "
|
|
29836
|
+
if (item.type === "task") sync$3(root, item, context);
|
|
29284
29837
|
return root;
|
|
29285
29838
|
},
|
|
29286
29839
|
update: (container, item, context) => {
|
|
29287
|
-
if (item.type
|
|
29840
|
+
if (item.type === "task") sync$3(container, item, context);
|
|
29841
|
+
},
|
|
29842
|
+
tick: (container, clock) => {
|
|
29288
29843
|
const parts = partsByContainer$3.get(container);
|
|
29289
|
-
|
|
29290
|
-
|
|
29291
|
-
|
|
29292
|
-
|
|
29844
|
+
return parts ? advance(parts, clock) : null;
|
|
29845
|
+
},
|
|
29846
|
+
zoom: (container, zoom) => {
|
|
29847
|
+
const tag = partsByContainer$3.get(container)?.tag;
|
|
29848
|
+
if (tag) zoomCardTag(tag, zoom);
|
|
29293
29849
|
},
|
|
29294
29850
|
renderFar: (graphics, item, context) => {
|
|
29851
|
+
if (item.type !== "task") return;
|
|
29852
|
+
const { status } = liveStatus(item, context);
|
|
29853
|
+
const active = status === "failed" || status === "running" || status === "pending";
|
|
29295
29854
|
drawFarPlate(graphics, item.frame, {
|
|
29296
|
-
fill: context.palette.
|
|
29297
|
-
fillAlpha: .
|
|
29855
|
+
fill: context.palette.surface,
|
|
29856
|
+
fillAlpha: .82,
|
|
29857
|
+
...active ? {
|
|
29858
|
+
accent: statusColor(status, context),
|
|
29859
|
+
accentAlpha: .9
|
|
29860
|
+
} : {}
|
|
29298
29861
|
});
|
|
29299
29862
|
},
|
|
29300
|
-
destroy: (container) => {
|
|
29863
|
+
destroy: (container, context) => {
|
|
29301
29864
|
const parts = partsByContainer$3.get(container);
|
|
29865
|
+
if (parts?.assetKey) context.releaseTexture(parts.assetKey);
|
|
29302
29866
|
parts?.root.destroy({ children: true });
|
|
29303
|
-
parts?.cropped?.destroy(false);
|
|
29304
29867
|
partsByContainer$3.delete(container);
|
|
29305
29868
|
}
|
|
29306
29869
|
};
|
|
@@ -29404,37 +29967,37 @@ const textCardRenderer = {
|
|
|
29404
29967
|
};
|
|
29405
29968
|
//#endregion
|
|
29406
29969
|
//#region ../sdk/src/board/render/renderers/unknown-card-renderer.ts
|
|
29407
|
-
const RADIUS$1 = 10;
|
|
29408
29970
|
const partsByContainer$1 = /* @__PURE__ */ new WeakMap();
|
|
29409
29971
|
function sync$1(container, item, context) {
|
|
29410
29972
|
const parts = partsByContainer$1.get(container);
|
|
29411
29973
|
if (!parts) return;
|
|
29412
29974
|
positionShell(parts.root, item);
|
|
29413
29975
|
const { width, height } = item.frame;
|
|
29414
|
-
const selected = context.selectedIds.has(item.id);
|
|
29415
29976
|
const realType = item.type;
|
|
29416
29977
|
syncTextResolution(parts.label, parts, context.zoom);
|
|
29978
|
+
const elevation = cardElevation(context, item.id);
|
|
29417
29979
|
const visualSig = [
|
|
29418
29980
|
width,
|
|
29419
29981
|
height,
|
|
29420
|
-
|
|
29421
|
-
context.
|
|
29422
|
-
context.palette.brand,
|
|
29423
|
-
context.palette.border,
|
|
29424
|
-
context.palette.muted
|
|
29982
|
+
elevation,
|
|
29983
|
+
context.themeKey
|
|
29425
29984
|
].join("|");
|
|
29426
29985
|
if (visualSig !== parts.visualSig) {
|
|
29427
29986
|
parts.visualSig = visualSig;
|
|
29428
|
-
|
|
29429
|
-
|
|
29430
|
-
|
|
29431
|
-
|
|
29432
|
-
|
|
29433
|
-
|
|
29434
|
-
|
|
29435
|
-
|
|
29987
|
+
const rect = {
|
|
29988
|
+
x: 0,
|
|
29989
|
+
y: 0,
|
|
29990
|
+
width,
|
|
29991
|
+
height
|
|
29992
|
+
};
|
|
29993
|
+
drawCardSurface(parts.box.clear(), rect, context.style, {
|
|
29994
|
+
fill: context.palette.surface,
|
|
29995
|
+
fillAlpha: .7,
|
|
29996
|
+
border: context.palette.border,
|
|
29997
|
+
borderAlpha: .8,
|
|
29998
|
+
elevation
|
|
29436
29999
|
});
|
|
29437
|
-
parts.box
|
|
30000
|
+
traceCardOutline(parts.box, rect, context.style, -6).stroke({
|
|
29438
30001
|
color: context.palette.muted,
|
|
29439
30002
|
width: 1,
|
|
29440
30003
|
alpha: .4
|
|
@@ -29496,146 +30059,145 @@ const unknownCardRenderer = {
|
|
|
29496
30059
|
//#endregion
|
|
29497
30060
|
//#region ../sdk/src/board/render/renderers/video-card-renderer.ts
|
|
29498
30061
|
const partsByContainer = /* @__PURE__ */ new WeakMap();
|
|
29499
|
-
const
|
|
29500
|
-
|
|
29501
|
-
|
|
29502
|
-
|
|
29503
|
-
const scale = Math.min(width / texture.width, height / texture.height);
|
|
29504
|
-
sprite.width = texture.width * scale;
|
|
29505
|
-
sprite.height = texture.height * scale;
|
|
29506
|
-
sprite.x = (width - sprite.width) / 2;
|
|
29507
|
-
sprite.y = (height - sprite.height) / 2;
|
|
30062
|
+
const FILM_RAIL = 10;
|
|
30063
|
+
const FILM_HOLE = 4;
|
|
30064
|
+
function videoTitle(item) {
|
|
30065
|
+
return item.props.snapshot?.title ?? getMediaResourceTitle(item.props.src);
|
|
29508
30066
|
}
|
|
29509
30067
|
function sync(container, item, context) {
|
|
29510
30068
|
const parts = partsByContainer.get(container);
|
|
29511
30069
|
if (!parts) return;
|
|
29512
30070
|
positionShell(parts.root, item);
|
|
29513
30071
|
const { width, height } = item.frame;
|
|
29514
|
-
const
|
|
29515
|
-
const
|
|
29516
|
-
const
|
|
29517
|
-
|
|
30072
|
+
const title = videoTitle(item);
|
|
30073
|
+
const durationMs = item.props.snapshot?.durationMs;
|
|
30074
|
+
const duration = durationMs ? formatBoardDuration(durationMs) : "";
|
|
30075
|
+
syncCardTag(parts.tag, {
|
|
30076
|
+
glyph: "video",
|
|
30077
|
+
text: duration ? `${title} · ${duration}` : title,
|
|
30078
|
+
width
|
|
30079
|
+
}, context);
|
|
29518
30080
|
const key = context.assetKey(item);
|
|
29519
30081
|
const texture = key ? context.getTexture(key) : null;
|
|
29520
|
-
const
|
|
29521
|
-
syncTextResolution(parts.label, parts, context.zoom);
|
|
29522
|
-
if (parts.label.text !== title) parts.label.text = title;
|
|
29523
|
-
syncTextWrapWidth(parts.label, parts, Math.max(1, width - 16), resizing);
|
|
29524
|
-
parts.label.position.set(8, Math.max(8, height - parts.label.height - 8));
|
|
30082
|
+
const elevation = cardElevation(context, item.id);
|
|
29525
30083
|
const sig = [
|
|
29526
30084
|
key ?? "",
|
|
29527
30085
|
texture ? `${texture.width}x${texture.height}` : "none",
|
|
29528
30086
|
width,
|
|
29529
30087
|
height,
|
|
29530
|
-
|
|
29531
|
-
|
|
29532
|
-
|
|
29533
|
-
title,
|
|
29534
|
-
item.props.time ?? 0,
|
|
29535
|
-
parts.label.height,
|
|
29536
|
-
context.palette.surface,
|
|
29537
|
-
context.palette.brand,
|
|
29538
|
-
context.palette.muted,
|
|
29539
|
-
context.palette.border,
|
|
29540
|
-
context.palette.hover,
|
|
29541
|
-
context.palette.text
|
|
30088
|
+
elevation,
|
|
30089
|
+
boardCardDetailed(context.zoom),
|
|
30090
|
+
context.themeKey
|
|
29542
30091
|
].join("|");
|
|
29543
30092
|
if (sig === parts.sig) return;
|
|
29544
30093
|
parts.sig = sig;
|
|
30094
|
+
const framed = context.style.media === "framed";
|
|
30095
|
+
const rect = {
|
|
30096
|
+
x: 0,
|
|
30097
|
+
y: 0,
|
|
30098
|
+
width,
|
|
30099
|
+
height
|
|
30100
|
+
};
|
|
30101
|
+
const rail = framed ? Math.min(FILM_RAIL, height / 6) : 0;
|
|
30102
|
+
const screen = {
|
|
30103
|
+
x: framed ? rail * .6 : 0,
|
|
30104
|
+
y: rail,
|
|
30105
|
+
width: width - (framed ? rail * 1.2 : 0),
|
|
30106
|
+
height: height - rail * 2
|
|
30107
|
+
};
|
|
30108
|
+
drawCardSurface(parts.plate.clear(), rect, context.style, {
|
|
30109
|
+
fill: framed ? context.palette.text : context.palette.surface,
|
|
30110
|
+
border: framed ? null : context.palette.border,
|
|
30111
|
+
borderAlpha: .85,
|
|
30112
|
+
elevation
|
|
30113
|
+
});
|
|
30114
|
+
if (framed) drawFilmRails(parts.plate, width, height, rail, context.palette.bg);
|
|
30115
|
+
traceCardOutline(parts.mask.clear(), framed ? screen : rect, framed ? {
|
|
30116
|
+
corner: "round",
|
|
30117
|
+
radius: 1
|
|
30118
|
+
} : context.style).fill({ color: 16777215 });
|
|
29545
30119
|
if (texture && parts.sprite.texture !== texture) parts.sprite.texture = texture;
|
|
29546
30120
|
parts.sprite.visible = Boolean(texture);
|
|
29547
|
-
if (texture) layoutContain(parts.sprite, width, height);
|
|
29548
|
-
parts.mask.clear().roundRect(0, 0, width, height, RADIUS).fill({ color: 16777215 });
|
|
29549
|
-
parts.plate.clear().roundRect(0, 0, width, height, RADIUS).fill({
|
|
29550
|
-
color: context.palette.surface,
|
|
29551
|
-
alpha: .96
|
|
29552
|
-
});
|
|
29553
|
-
parts.chrome.clear();
|
|
29554
30121
|
if (texture) {
|
|
29555
|
-
const
|
|
29556
|
-
parts.
|
|
29557
|
-
|
|
29558
|
-
|
|
29559
|
-
});
|
|
30122
|
+
const fitted = containRect(screen.width, screen.height, texture.width, texture.height);
|
|
30123
|
+
parts.sprite.position.set(screen.x + fitted.x, screen.y + fitted.y);
|
|
30124
|
+
parts.sprite.width = fitted.width;
|
|
30125
|
+
parts.sprite.height = fitted.height;
|
|
29560
30126
|
}
|
|
29561
|
-
|
|
29562
|
-
|
|
29563
|
-
|
|
29564
|
-
|
|
29565
|
-
|
|
29566
|
-
|
|
29567
|
-
|
|
29568
|
-
const
|
|
29569
|
-
|
|
29570
|
-
|
|
29571
|
-
|
|
29572
|
-
}
|
|
29573
|
-
|
|
29574
|
-
color:
|
|
29575
|
-
|
|
29576
|
-
alpha: selected ? .95 : .85
|
|
30127
|
+
parts.chrome.clear();
|
|
30128
|
+
if (boardCardDetailed(context.zoom)) drawMediaPlayKey(parts.chrome, screen.x + screen.width / 2, screen.y + screen.height / 2, Math.min(18, Math.min(screen.width, screen.height) * .16), context);
|
|
30129
|
+
}
|
|
30130
|
+
function drawFilmRails(graphics, width, height, rail, hole) {
|
|
30131
|
+
const size = Math.min(FILM_HOLE, rail * .45);
|
|
30132
|
+
const step = size * 2.5;
|
|
30133
|
+
const count = Math.max(1, Math.floor((width - step) / step));
|
|
30134
|
+
const start = (width - (count - 1) * step - size) / 2;
|
|
30135
|
+
for (let index = 0; index < count; index += 1) {
|
|
30136
|
+
const x = start + index * step;
|
|
30137
|
+
graphics.rect(x, (rail - size) / 2, size, size).rect(x, height - rail + (rail - size) / 2, size, size);
|
|
30138
|
+
}
|
|
30139
|
+
graphics.fill({
|
|
30140
|
+
color: hole,
|
|
30141
|
+
alpha: .9
|
|
29577
30142
|
});
|
|
29578
|
-
parts.label.style.fill = texture ? context.palette.text : context.palette.muted;
|
|
29579
30143
|
}
|
|
30144
|
+
const videoCardRenderer = {
|
|
30145
|
+
id: "video-card",
|
|
30146
|
+
canRender: (item) => item.type === "video",
|
|
30147
|
+
create: (item, context) => {
|
|
30148
|
+
const root = new Container();
|
|
30149
|
+
const plate = new Graphics();
|
|
30150
|
+
const sprite = new Sprite(Texture.EMPTY);
|
|
30151
|
+
const mask = new Graphics();
|
|
30152
|
+
const chrome = new Graphics();
|
|
30153
|
+
const tag = createCardTag();
|
|
30154
|
+
root.addChild(plate, sprite, mask, chrome, tag.root);
|
|
30155
|
+
sprite.mask = mask;
|
|
30156
|
+
partsByContainer.set(root, {
|
|
30157
|
+
root,
|
|
30158
|
+
plate,
|
|
30159
|
+
sprite,
|
|
30160
|
+
mask,
|
|
30161
|
+
chrome,
|
|
30162
|
+
tag,
|
|
30163
|
+
sig: ""
|
|
30164
|
+
});
|
|
30165
|
+
if (item.type === "video") sync(root, item, context);
|
|
30166
|
+
return root;
|
|
30167
|
+
},
|
|
30168
|
+
update: (container, item, context) => {
|
|
30169
|
+
if (item.type === "video") sync(container, item, context);
|
|
30170
|
+
},
|
|
30171
|
+
zoom: (container, zoom) => {
|
|
30172
|
+
const tag = partsByContainer.get(container)?.tag;
|
|
30173
|
+
if (tag) zoomCardTag(tag, zoom);
|
|
30174
|
+
},
|
|
30175
|
+
renderFar: (graphics, item, context) => {
|
|
30176
|
+
drawFarPlate(graphics, item.frame, {
|
|
30177
|
+
fill: context.palette.surface,
|
|
30178
|
+
fillAlpha: .96,
|
|
30179
|
+
accent: context.palette.brand,
|
|
30180
|
+
accentAlpha: .75
|
|
30181
|
+
});
|
|
30182
|
+
},
|
|
30183
|
+
destroy: (container) => {
|
|
30184
|
+
partsByContainer.get(container)?.root.destroy({ children: true });
|
|
30185
|
+
partsByContainer.delete(container);
|
|
30186
|
+
}
|
|
30187
|
+
};
|
|
29580
30188
|
//#endregion
|
|
29581
30189
|
//#region ../sdk/src/board/render/renderers/board-renderer-registry.ts
|
|
30190
|
+
const DEFAULT_BOARD_RENDER_LABELS = {
|
|
30191
|
+
queued: "Queued",
|
|
30192
|
+
generating: "Generating",
|
|
30193
|
+
failed: "Failed",
|
|
30194
|
+
previewUnavailable: "Preview unavailable",
|
|
30195
|
+
noPreview: "No preview"
|
|
30196
|
+
};
|
|
29582
30197
|
const builtinCardRenderers = [
|
|
29583
30198
|
textCardRenderer,
|
|
29584
30199
|
imageCardRenderer,
|
|
29585
|
-
|
|
29586
|
-
id: "video-card",
|
|
29587
|
-
canRender: (item) => item.type === "video",
|
|
29588
|
-
create: (item, context) => {
|
|
29589
|
-
const root = new Container();
|
|
29590
|
-
const plate = new Graphics();
|
|
29591
|
-
const sprite = new Sprite(Texture.EMPTY);
|
|
29592
|
-
const mask = new Graphics();
|
|
29593
|
-
const chrome = new Graphics();
|
|
29594
|
-
const resolution = textResolutionForZoom(context.zoom);
|
|
29595
|
-
const label = new Text({
|
|
29596
|
-
text: "",
|
|
29597
|
-
style: {
|
|
29598
|
-
fill: context.palette.muted,
|
|
29599
|
-
fontFamily: BOARD_FONT_STACK,
|
|
29600
|
-
fontSize: 12,
|
|
29601
|
-
fontWeight: "500",
|
|
29602
|
-
wordWrap: true
|
|
29603
|
-
},
|
|
29604
|
-
resolution,
|
|
29605
|
-
roundPixels: true
|
|
29606
|
-
});
|
|
29607
|
-
root.addChild(plate, sprite, mask, chrome, label);
|
|
29608
|
-
sprite.mask = mask;
|
|
29609
|
-
partsByContainer.set(root, {
|
|
29610
|
-
root,
|
|
29611
|
-
plate,
|
|
29612
|
-
sprite,
|
|
29613
|
-
mask,
|
|
29614
|
-
chrome,
|
|
29615
|
-
label,
|
|
29616
|
-
sig: "",
|
|
29617
|
-
wrapWidth: 0,
|
|
29618
|
-
resolution
|
|
29619
|
-
});
|
|
29620
|
-
if (item.type === "video") sync(root, item, context);
|
|
29621
|
-
return root;
|
|
29622
|
-
},
|
|
29623
|
-
update: (container, item, context) => {
|
|
29624
|
-
if (item.type === "video") sync(container, item, context);
|
|
29625
|
-
},
|
|
29626
|
-
renderFar: (graphics, item, context) => {
|
|
29627
|
-
drawFarPlate(graphics, item.frame, {
|
|
29628
|
-
fill: context.palette.surface,
|
|
29629
|
-
fillAlpha: .96,
|
|
29630
|
-
accent: context.palette.brand,
|
|
29631
|
-
accentAlpha: .75
|
|
29632
|
-
});
|
|
29633
|
-
},
|
|
29634
|
-
destroy: (container) => {
|
|
29635
|
-
partsByContainer.get(container)?.root.destroy({ children: true });
|
|
29636
|
-
partsByContainer.delete(container);
|
|
29637
|
-
}
|
|
29638
|
-
},
|
|
30200
|
+
videoCardRenderer,
|
|
29639
30201
|
audioCardRenderer,
|
|
29640
30202
|
fileCardRenderer,
|
|
29641
30203
|
taskCardRenderer,
|
|
@@ -29960,8 +30522,16 @@ const fileProps = {
|
|
|
29960
30522
|
coverUrl: string().optional()
|
|
29961
30523
|
}).strict().optional()
|
|
29962
30524
|
};
|
|
29963
|
-
const
|
|
30525
|
+
const BoardMediaOriginSchema = object({
|
|
30526
|
+
taskRunId: string().min(1).max(160),
|
|
30527
|
+
artifactId: string().min(1).max(240)
|
|
30528
|
+
}).strict();
|
|
30529
|
+
const mediaProps = {
|
|
29964
30530
|
...fileProps,
|
|
30531
|
+
origin: BoardMediaOriginSchema.optional()
|
|
30532
|
+
};
|
|
30533
|
+
const timedFileProps = {
|
|
30534
|
+
...mediaProps,
|
|
29965
30535
|
time: nonNegative.optional()
|
|
29966
30536
|
};
|
|
29967
30537
|
const BoardCropSchema = object({
|
|
@@ -29974,7 +30544,7 @@ object({
|
|
|
29974
30544
|
...boxed(640, 360),
|
|
29975
30545
|
type: literal("image"),
|
|
29976
30546
|
props: object({
|
|
29977
|
-
...
|
|
30547
|
+
...mediaProps,
|
|
29978
30548
|
crop: BoardCropSchema.optional()
|
|
29979
30549
|
}).strict()
|
|
29980
30550
|
}).strict();
|
|
@@ -30039,8 +30609,10 @@ const BoardTaskSnapshotSchema = object({
|
|
|
30039
30609
|
title: string().min(1).max(240),
|
|
30040
30610
|
model: string().max(160).optional(),
|
|
30041
30611
|
promptExcerpt: string().max(480).optional(),
|
|
30612
|
+
errorExcerpt: string().max(240).optional(),
|
|
30042
30613
|
artifactCount: number$1().int().nonnegative(),
|
|
30043
30614
|
artifacts: array(BoardTaskArtifactSchema).max(6).default([]),
|
|
30615
|
+
startedAt: string().max(64).optional(),
|
|
30044
30616
|
updatedAt: string().optional()
|
|
30045
30617
|
}).strict();
|
|
30046
30618
|
object({
|
|
@@ -30048,7 +30620,7 @@ object({
|
|
|
30048
30620
|
type: literal("task"),
|
|
30049
30621
|
props: object({
|
|
30050
30622
|
taskRunId: string().min(1).max(160),
|
|
30051
|
-
snapshot: BoardTaskSnapshotSchema
|
|
30623
|
+
snapshot: BoardTaskSnapshotSchema.describe("Maintained by the server for tasks in the Board's Space; writers may omit it.")
|
|
30052
30624
|
}).strict()
|
|
30053
30625
|
}).strict();
|
|
30054
30626
|
const BOARD_EFFECT_KINDS = [
|
|
@@ -30337,6 +30909,8 @@ function createScriptRuntime(module, initial, host) {
|
|
|
30337
30909
|
let patches = effects?.patches ?? {};
|
|
30338
30910
|
let items = effects?.items ?? {};
|
|
30339
30911
|
let space = effects?.space ?? "world";
|
|
30912
|
+
let anchor = effects?.anchor;
|
|
30913
|
+
let view = null;
|
|
30340
30914
|
let hits = effects?.hits ?? {};
|
|
30341
30915
|
const invalidate = () => {
|
|
30342
30916
|
if (disposed) return;
|
|
@@ -30373,6 +30947,9 @@ function createScriptRuntime(module, initial, host) {
|
|
|
30373
30947
|
get frame() {
|
|
30374
30948
|
return frame;
|
|
30375
30949
|
},
|
|
30950
|
+
get view() {
|
|
30951
|
+
return view;
|
|
30952
|
+
},
|
|
30376
30953
|
random() {
|
|
30377
30954
|
randomState = Math.imul(randomState, 1664525) + 1013904223 >>> 0;
|
|
30378
30955
|
return randomState / 4294967296;
|
|
@@ -30383,10 +30960,11 @@ function createScriptRuntime(module, initial, host) {
|
|
|
30383
30960
|
listeners = /* @__PURE__ */ new Set();
|
|
30384
30961
|
handlers.set(type, listeners);
|
|
30385
30962
|
}
|
|
30386
|
-
|
|
30963
|
+
const listener = (event) => handler(event);
|
|
30964
|
+
listeners.add(listener);
|
|
30387
30965
|
invalidate();
|
|
30388
30966
|
return () => {
|
|
30389
|
-
listeners.delete(
|
|
30967
|
+
listeners.delete(listener);
|
|
30390
30968
|
invalidate();
|
|
30391
30969
|
};
|
|
30392
30970
|
},
|
|
@@ -30405,6 +30983,7 @@ function createScriptRuntime(module, initial, host) {
|
|
|
30405
30983
|
scene(next, options) {
|
|
30406
30984
|
items = structuredClone(next);
|
|
30407
30985
|
space = options?.space ?? "world";
|
|
30986
|
+
anchor = options?.anchor ? structuredClone(options.anchor) : void 0;
|
|
30408
30987
|
invalidate();
|
|
30409
30988
|
},
|
|
30410
30989
|
hitRegions(next) {
|
|
@@ -30466,6 +31045,7 @@ function createScriptRuntime(module, initial, host) {
|
|
|
30466
31045
|
},
|
|
30467
31046
|
event(event) {
|
|
30468
31047
|
if (disposed) return;
|
|
31048
|
+
if (event.type === "viewchange") view = event.data;
|
|
30469
31049
|
const listeners = handlers.get(event.type);
|
|
30470
31050
|
if (!listeners?.size) return;
|
|
30471
31051
|
for (const handler of listeners) handler(event);
|
|
@@ -30479,6 +31059,7 @@ function createScriptRuntime(module, initial, host) {
|
|
|
30479
31059
|
return {
|
|
30480
31060
|
parameters: module.parameters,
|
|
30481
31061
|
space,
|
|
31062
|
+
anchor,
|
|
30482
31063
|
patches,
|
|
30483
31064
|
items,
|
|
30484
31065
|
hits,
|
|
@@ -30497,7 +31078,8 @@ function createScriptRuntime(module, initial, host) {
|
|
|
30497
31078
|
patches,
|
|
30498
31079
|
items,
|
|
30499
31080
|
hits,
|
|
30500
|
-
space
|
|
31081
|
+
space,
|
|
31082
|
+
anchor
|
|
30501
31083
|
} : void 0
|
|
30502
31084
|
};
|
|
30503
31085
|
return clone ? structuredClone(snapshot) : snapshot;
|
|
@@ -30514,6 +31096,58 @@ function createScriptRuntime(module, initial, host) {
|
|
|
30514
31096
|
};
|
|
30515
31097
|
}
|
|
30516
31098
|
//#endregion
|
|
31099
|
+
//#region ../sdk/src/board/render/style.ts
|
|
31100
|
+
const BASE = {
|
|
31101
|
+
corner: "round",
|
|
31102
|
+
radius: 6,
|
|
31103
|
+
selection: {
|
|
31104
|
+
width: 1.5,
|
|
31105
|
+
outset: 3,
|
|
31106
|
+
dash: 0,
|
|
31107
|
+
handle: "square",
|
|
31108
|
+
handleSize: 8
|
|
31109
|
+
},
|
|
31110
|
+
media: "plain",
|
|
31111
|
+
progress: "shimmer",
|
|
31112
|
+
icons: "line",
|
|
31113
|
+
motion: "smooth",
|
|
31114
|
+
font: BOARD_FONT_STACK
|
|
31115
|
+
};
|
|
31116
|
+
const SHADOW = {
|
|
31117
|
+
light: {
|
|
31118
|
+
color: 1447704,
|
|
31119
|
+
alpha: .06,
|
|
31120
|
+
blur: 12,
|
|
31121
|
+
y: 2
|
|
31122
|
+
},
|
|
31123
|
+
dark: {
|
|
31124
|
+
color: 0,
|
|
31125
|
+
alpha: .24,
|
|
31126
|
+
blur: 12,
|
|
31127
|
+
y: 2
|
|
31128
|
+
}
|
|
31129
|
+
};
|
|
31130
|
+
function defaultBoardRenderStyle(mode) {
|
|
31131
|
+
return {
|
|
31132
|
+
...BASE,
|
|
31133
|
+
selection: { ...BASE.selection },
|
|
31134
|
+
shadow: { ...SHADOW[mode] }
|
|
31135
|
+
};
|
|
31136
|
+
}
|
|
31137
|
+
function resolveBoardRenderStyle(mode, style) {
|
|
31138
|
+
const base = defaultBoardRenderStyle(mode);
|
|
31139
|
+
if (!style) return base;
|
|
31140
|
+
return {
|
|
31141
|
+
...base,
|
|
31142
|
+
...style,
|
|
31143
|
+
selection: {
|
|
31144
|
+
...base.selection,
|
|
31145
|
+
...style.selection
|
|
31146
|
+
},
|
|
31147
|
+
shadow: style.shadow === void 0 ? base.shadow : style.shadow
|
|
31148
|
+
};
|
|
31149
|
+
}
|
|
31150
|
+
//#endregion
|
|
30517
31151
|
//#region ../sdk/src/board/export/scene.ts
|
|
30518
31152
|
function buildContext(input) {
|
|
30519
31153
|
const missing = /* @__PURE__ */ new Set();
|
|
@@ -30527,14 +31161,20 @@ function buildContext(input) {
|
|
|
30527
31161
|
selectedIds: /* @__PURE__ */ new Set(),
|
|
30528
31162
|
hoveredId: null,
|
|
30529
31163
|
resizingIds: /* @__PURE__ */ new Set(),
|
|
31164
|
+
liftedIds: /* @__PURE__ */ new Set(),
|
|
30530
31165
|
palette: {
|
|
30531
31166
|
...defaultBoardPalette(input.colorScheme),
|
|
30532
31167
|
...input.palette
|
|
30533
31168
|
},
|
|
30534
31169
|
colors: input.colors ?? buildFallbackShapeColors(input.colorScheme),
|
|
30535
31170
|
colorScheme: input.colorScheme,
|
|
31171
|
+
style: resolveBoardRenderStyle(input.colorScheme, input.style),
|
|
31172
|
+
themeKey: "export",
|
|
30536
31173
|
rendererType: "canvas",
|
|
30537
31174
|
zoom: input.scale,
|
|
31175
|
+
reducedMotion: true,
|
|
31176
|
+
labels: DEFAULT_BOARD_RENDER_LABELS,
|
|
31177
|
+
taskRun: () => null,
|
|
30538
31178
|
scripts: input.scripts,
|
|
30539
31179
|
assetKey: input.assetKey ?? imageAssetKey,
|
|
30540
31180
|
getTexture: (key) => textures.get(key) ?? null,
|
|
@@ -30689,6 +31329,7 @@ function renderBoardExport(renderer, input, options = {}) {
|
|
|
30689
31329
|
colorScheme,
|
|
30690
31330
|
palette,
|
|
30691
31331
|
colors: options.colors,
|
|
31332
|
+
style: options.style,
|
|
30692
31333
|
textures: options.textures,
|
|
30693
31334
|
scripts: options.scripts,
|
|
30694
31335
|
assetKey: options.assetKey,
|