hyperframes 0.6.14 → 0.6.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +135 -108
- package/dist/studio/assets/index-B2KncU-m.css +1 -0
- package/dist/studio/assets/index-BOdaPmiv.js +116 -0
- package/dist/studio/index.html +2 -2
- package/package.json +1 -1
- package/dist/studio/assets/index-4xujzzbu.js +0 -116
- package/dist/studio/assets/index-Ckqo37Co.css +0 -1
package/dist/cli.js
CHANGED
|
@@ -54,7 +54,7 @@ var VERSION;
|
|
|
54
54
|
var init_version = __esm({
|
|
55
55
|
"src/version.ts"() {
|
|
56
56
|
"use strict";
|
|
57
|
-
VERSION = true ? "0.6.
|
|
57
|
+
VERSION = true ? "0.6.16" : "0.0.0-dev";
|
|
58
58
|
}
|
|
59
59
|
});
|
|
60
60
|
|
|
@@ -33966,6 +33966,87 @@ var init_audioMixer = __esm({
|
|
|
33966
33966
|
}
|
|
33967
33967
|
});
|
|
33968
33968
|
|
|
33969
|
+
// ../engine/src/utils/assertSwiftShader.ts
|
|
33970
|
+
async function readWebGlVendorInfo(page) {
|
|
33971
|
+
await page.goto("chrome://gpu", { waitUntil: "domcontentloaded", timeout: 3e4 });
|
|
33972
|
+
const info = await page.evaluate(() => {
|
|
33973
|
+
const w3 = window;
|
|
33974
|
+
const rows = w3.browserBridge?.gpuInfo_?.graphics_info?.basic_info ?? [];
|
|
33975
|
+
let vendor = "";
|
|
33976
|
+
let renderer = "";
|
|
33977
|
+
for (const row of rows) {
|
|
33978
|
+
if (typeof row.description !== "string" || typeof row.value !== "string") continue;
|
|
33979
|
+
if (row.description === "GL_VENDOR") vendor = row.value;
|
|
33980
|
+
else if (row.description === "GL_RENDERER") renderer = row.value;
|
|
33981
|
+
}
|
|
33982
|
+
return { vendor, renderer };
|
|
33983
|
+
});
|
|
33984
|
+
return info;
|
|
33985
|
+
}
|
|
33986
|
+
async function assertSwiftShader(page, readInfo = readWebGlVendorInfo) {
|
|
33987
|
+
const { vendor, renderer } = await readInfo(page);
|
|
33988
|
+
const vendorMatches = vendor.trim() === SWIFTSHADER_VENDOR_SIGNATURE;
|
|
33989
|
+
const rendererMatches = renderer.toLowerCase().includes(SWIFTSHADER_RENDERER_TOKEN);
|
|
33990
|
+
if (vendorMatches && rendererMatches) return;
|
|
33991
|
+
throw new SwiftShaderAssertionError(
|
|
33992
|
+
`[assertSwiftShader] Chrome reported a non-SwiftShader WebGL backend. Distributed renders require pure-software GL for pixel-identical retries. Got vendor=${JSON.stringify(vendor)} renderer=${JSON.stringify(renderer)}; expected vendor=${JSON.stringify(SWIFTSHADER_VENDOR_SIGNATURE)} renderer to contain "SwiftShader". Ensure Chrome was launched with --use-gl=swiftshader --use-angle=swiftshader and that the SwiftShader libraries are present in the runtime image.`,
|
|
33993
|
+
vendor,
|
|
33994
|
+
renderer
|
|
33995
|
+
);
|
|
33996
|
+
}
|
|
33997
|
+
var BROWSER_GPU_NOT_SOFTWARE, SwiftShaderAssertionError, SWIFTSHADER_VENDOR_SIGNATURE, SWIFTSHADER_RENDERER_TOKEN;
|
|
33998
|
+
var init_assertSwiftShader = __esm({
|
|
33999
|
+
"../engine/src/utils/assertSwiftShader.ts"() {
|
|
34000
|
+
"use strict";
|
|
34001
|
+
BROWSER_GPU_NOT_SOFTWARE = "BROWSER_GPU_NOT_SOFTWARE";
|
|
34002
|
+
SwiftShaderAssertionError = class extends Error {
|
|
34003
|
+
code = BROWSER_GPU_NOT_SOFTWARE;
|
|
34004
|
+
vendor;
|
|
34005
|
+
renderer;
|
|
34006
|
+
constructor(message, vendor, renderer) {
|
|
34007
|
+
super(message);
|
|
34008
|
+
this.name = "SwiftShaderAssertionError";
|
|
34009
|
+
this.vendor = vendor;
|
|
34010
|
+
this.renderer = renderer;
|
|
34011
|
+
}
|
|
34012
|
+
};
|
|
34013
|
+
SWIFTSHADER_VENDOR_SIGNATURE = "Google Inc. (Google)";
|
|
34014
|
+
SWIFTSHADER_RENDERER_TOKEN = "swiftshader";
|
|
34015
|
+
}
|
|
34016
|
+
});
|
|
34017
|
+
|
|
34018
|
+
// ../engine/src/utils/readWebGlVendorInfoFromCanvas.ts
|
|
34019
|
+
async function readWebGlVendorInfoFromCanvas(page) {
|
|
34020
|
+
await page.goto("about:blank", { waitUntil: "domcontentloaded", timeout: 3e4 });
|
|
34021
|
+
return page.evaluate(() => {
|
|
34022
|
+
try {
|
|
34023
|
+
const canvas = document.createElement("canvas");
|
|
34024
|
+
const gl = canvas.getContext("webgl") ?? canvas.getContext("experimental-webgl");
|
|
34025
|
+
if (!gl) {
|
|
34026
|
+
return { vendor: "", renderer: "" };
|
|
34027
|
+
}
|
|
34028
|
+
const ext = gl.getExtension("WEBGL_debug_renderer_info");
|
|
34029
|
+
if (!ext) {
|
|
34030
|
+
return {
|
|
34031
|
+
vendor: String(gl.getParameter(gl.VENDOR) ?? ""),
|
|
34032
|
+
renderer: String(gl.getParameter(gl.RENDERER) ?? "")
|
|
34033
|
+
};
|
|
34034
|
+
}
|
|
34035
|
+
return {
|
|
34036
|
+
vendor: String(gl.getParameter(ext.UNMASKED_VENDOR_WEBGL) ?? ""),
|
|
34037
|
+
renderer: String(gl.getParameter(ext.UNMASKED_RENDERER_WEBGL) ?? "")
|
|
34038
|
+
};
|
|
34039
|
+
} catch {
|
|
34040
|
+
return { vendor: "", renderer: "" };
|
|
34041
|
+
}
|
|
34042
|
+
});
|
|
34043
|
+
}
|
|
34044
|
+
var init_readWebGlVendorInfoFromCanvas = __esm({
|
|
34045
|
+
"../engine/src/utils/readWebGlVendorInfoFromCanvas.ts"() {
|
|
34046
|
+
"use strict";
|
|
34047
|
+
}
|
|
34048
|
+
});
|
|
34049
|
+
|
|
33969
34050
|
// ../engine/src/services/parallelCoordinator.ts
|
|
33970
34051
|
import { cpus as cpus2, freemem, totalmem as totalmem2 } from "os";
|
|
33971
34052
|
import { existsSync as existsSync27, mkdirSync as mkdirSync17, readdirSync as readdirSync13 } from "fs";
|
|
@@ -34012,18 +34093,19 @@ function calculateOptimalWorkers(totalFrames, requested, config) {
|
|
|
34012
34093
|
}
|
|
34013
34094
|
return finalWorkers;
|
|
34014
34095
|
}
|
|
34015
|
-
function distributeFrames(totalFrames, workerCount, workDir) {
|
|
34096
|
+
function distributeFrames(totalFrames, workerCount, workDir, rangeStart = 0) {
|
|
34016
34097
|
const tasks = [];
|
|
34017
34098
|
const framesPerWorker = Math.ceil(totalFrames / workerCount);
|
|
34018
34099
|
for (let i2 = 0; i2 < workerCount; i2++) {
|
|
34019
|
-
const startFrame = i2 * framesPerWorker;
|
|
34020
|
-
const endFrame = Math.min((i2 + 1) * framesPerWorker, totalFrames);
|
|
34021
|
-
if (startFrame >= totalFrames) break;
|
|
34100
|
+
const startFrame = rangeStart + i2 * framesPerWorker;
|
|
34101
|
+
const endFrame = Math.min(rangeStart + (i2 + 1) * framesPerWorker, rangeStart + totalFrames);
|
|
34102
|
+
if (startFrame >= rangeStart + totalFrames) break;
|
|
34022
34103
|
tasks.push({
|
|
34023
34104
|
workerId: i2,
|
|
34024
34105
|
startFrame,
|
|
34025
34106
|
endFrame,
|
|
34026
|
-
outputDir: join30(workDir, `worker-${i2}`)
|
|
34107
|
+
outputDir: join30(workDir, `worker-${i2}`),
|
|
34108
|
+
outputFrameOffset: rangeStart
|
|
34027
34109
|
});
|
|
34028
34110
|
}
|
|
34029
34111
|
return tasks;
|
|
@@ -34042,17 +34124,22 @@ async function executeWorkerTask(task, serverUrl, captureOptions, createBeforeCa
|
|
|
34042
34124
|
createBeforeCaptureHook(),
|
|
34043
34125
|
config
|
|
34044
34126
|
);
|
|
34127
|
+
if (config?.browserGpuMode === "software") {
|
|
34128
|
+
await assertSwiftShader(session.page, readWebGlVendorInfoFromCanvas);
|
|
34129
|
+
}
|
|
34045
34130
|
await initializeSession(session);
|
|
34131
|
+
const outputOffset = task.outputFrameOffset ?? 0;
|
|
34046
34132
|
for (let i2 = task.startFrame; i2 < task.endFrame; i2++) {
|
|
34047
34133
|
if (signal?.aborted) {
|
|
34048
34134
|
throw new Error("Parallel worker cancelled");
|
|
34049
34135
|
}
|
|
34050
34136
|
const time = i2 * captureOptions.fps.den / captureOptions.fps.num;
|
|
34137
|
+
const fileFrameIdx = i2 - outputOffset;
|
|
34051
34138
|
if (onFrameBuffer) {
|
|
34052
|
-
const { buffer } = await captureFrameToBuffer(session,
|
|
34139
|
+
const { buffer } = await captureFrameToBuffer(session, fileFrameIdx, time);
|
|
34053
34140
|
await onFrameBuffer(i2, buffer);
|
|
34054
34141
|
} else {
|
|
34055
|
-
await captureFrame(session,
|
|
34142
|
+
await captureFrame(session, fileFrameIdx, time);
|
|
34056
34143
|
}
|
|
34057
34144
|
framesCaptured++;
|
|
34058
34145
|
if (onFrameCaptured) onFrameCaptured(task.workerId, i2);
|
|
@@ -34157,6 +34244,8 @@ var init_parallelCoordinator = __esm({
|
|
|
34157
34244
|
"use strict";
|
|
34158
34245
|
init_frameCapture();
|
|
34159
34246
|
init_config2();
|
|
34247
|
+
init_assertSwiftShader();
|
|
34248
|
+
init_readWebGlVendorInfoFromCanvas();
|
|
34160
34249
|
MEMORY_PER_WORKER_MB = 256;
|
|
34161
34250
|
MIN_WORKERS = 1;
|
|
34162
34251
|
ABSOLUTE_MAX_WORKERS = 24;
|
|
@@ -34241,55 +34330,6 @@ var init_fileServer = __esm({
|
|
|
34241
34330
|
}
|
|
34242
34331
|
});
|
|
34243
34332
|
|
|
34244
|
-
// ../engine/src/utils/assertSwiftShader.ts
|
|
34245
|
-
async function readWebGlVendorInfo(page) {
|
|
34246
|
-
await page.goto("chrome://gpu", { waitUntil: "domcontentloaded", timeout: 3e4 });
|
|
34247
|
-
const info = await page.evaluate(() => {
|
|
34248
|
-
const w3 = window;
|
|
34249
|
-
const rows = w3.browserBridge?.gpuInfo_?.graphics_info?.basic_info ?? [];
|
|
34250
|
-
let vendor = "";
|
|
34251
|
-
let renderer = "";
|
|
34252
|
-
for (const row of rows) {
|
|
34253
|
-
if (typeof row.description !== "string" || typeof row.value !== "string") continue;
|
|
34254
|
-
if (row.description === "GL_VENDOR") vendor = row.value;
|
|
34255
|
-
else if (row.description === "GL_RENDERER") renderer = row.value;
|
|
34256
|
-
}
|
|
34257
|
-
return { vendor, renderer };
|
|
34258
|
-
});
|
|
34259
|
-
return info;
|
|
34260
|
-
}
|
|
34261
|
-
async function assertSwiftShader(page, readInfo = readWebGlVendorInfo) {
|
|
34262
|
-
const { vendor, renderer } = await readInfo(page);
|
|
34263
|
-
const vendorMatches = vendor.trim() === SWIFTSHADER_VENDOR_SIGNATURE;
|
|
34264
|
-
const rendererMatches = renderer.toLowerCase().includes(SWIFTSHADER_RENDERER_TOKEN);
|
|
34265
|
-
if (vendorMatches && rendererMatches) return;
|
|
34266
|
-
throw new SwiftShaderAssertionError(
|
|
34267
|
-
`[assertSwiftShader] Chrome reported a non-SwiftShader WebGL backend. Distributed renders require pure-software GL for pixel-identical retries. Got vendor=${JSON.stringify(vendor)} renderer=${JSON.stringify(renderer)}; expected vendor=${JSON.stringify(SWIFTSHADER_VENDOR_SIGNATURE)} renderer to contain "SwiftShader". Ensure Chrome was launched with --use-gl=swiftshader --use-angle=swiftshader and that the SwiftShader libraries are present in the runtime image.`,
|
|
34268
|
-
vendor,
|
|
34269
|
-
renderer
|
|
34270
|
-
);
|
|
34271
|
-
}
|
|
34272
|
-
var BROWSER_GPU_NOT_SOFTWARE, SwiftShaderAssertionError, SWIFTSHADER_VENDOR_SIGNATURE, SWIFTSHADER_RENDERER_TOKEN;
|
|
34273
|
-
var init_assertSwiftShader = __esm({
|
|
34274
|
-
"../engine/src/utils/assertSwiftShader.ts"() {
|
|
34275
|
-
"use strict";
|
|
34276
|
-
BROWSER_GPU_NOT_SOFTWARE = "BROWSER_GPU_NOT_SOFTWARE";
|
|
34277
|
-
SwiftShaderAssertionError = class extends Error {
|
|
34278
|
-
code = BROWSER_GPU_NOT_SOFTWARE;
|
|
34279
|
-
vendor;
|
|
34280
|
-
renderer;
|
|
34281
|
-
constructor(message, vendor, renderer) {
|
|
34282
|
-
super(message);
|
|
34283
|
-
this.name = "SwiftShaderAssertionError";
|
|
34284
|
-
this.vendor = vendor;
|
|
34285
|
-
this.renderer = renderer;
|
|
34286
|
-
}
|
|
34287
|
-
};
|
|
34288
|
-
SWIFTSHADER_VENDOR_SIGNATURE = "Google Inc. (Google)";
|
|
34289
|
-
SWIFTSHADER_RENDERER_TOKEN = "swiftshader";
|
|
34290
|
-
}
|
|
34291
|
-
});
|
|
34292
|
-
|
|
34293
34333
|
// ../engine/src/utils/alphaBlit.ts
|
|
34294
34334
|
import { inflateSync } from "zlib";
|
|
34295
34335
|
function paeth(a, b2, c3) {
|
|
@@ -35845,6 +35885,7 @@ __export(src_exports2, {
|
|
|
35845
35885
|
queryElementStacking: () => queryElementStacking,
|
|
35846
35886
|
queryVideoElementBounds: () => queryVideoElementBounds,
|
|
35847
35887
|
readWebGlVendorInfo: () => readWebGlVendorInfo,
|
|
35888
|
+
readWebGlVendorInfoFromCanvas: () => readWebGlVendorInfoFromCanvas,
|
|
35848
35889
|
releaseBrowser: () => releaseBrowser,
|
|
35849
35890
|
removeDomLayerMask: () => removeDomLayerMask,
|
|
35850
35891
|
resampleRgb48leObjectFit: () => resampleRgb48leObjectFit,
|
|
@@ -35876,6 +35917,7 @@ var init_src2 = __esm({
|
|
|
35876
35917
|
init_fileServer();
|
|
35877
35918
|
init_src();
|
|
35878
35919
|
init_assertSwiftShader();
|
|
35920
|
+
init_readWebGlVendorInfoFromCanvas();
|
|
35879
35921
|
init_ffprobe();
|
|
35880
35922
|
init_urlDownloader();
|
|
35881
35923
|
init_runFfmpeg();
|
|
@@ -39073,17 +39115,18 @@ async function runCaptureStage(input) {
|
|
|
39073
39115
|
let { workerCount, probeSession } = input;
|
|
39074
39116
|
let lastBrowserConsole = [];
|
|
39075
39117
|
const captureCfg = cfg.forceScreenshot === forceScreenshot ? cfg : { ...cfg, forceScreenshot };
|
|
39076
|
-
if (frameRange !== void 0 && workerCount > 1) {
|
|
39077
|
-
throw new Error(
|
|
39078
|
-
`[captureStage] frameRange capture requires workerCount === 1 (received workerCount=${workerCount}). Distributed chunk workers fan out at the activity layer; reduce workerCount to 1 when passing frameRange.`
|
|
39079
|
-
);
|
|
39080
|
-
}
|
|
39081
39118
|
if (frameRange !== void 0) {
|
|
39082
39119
|
if (!Number.isFinite(frameRange.startFrame) || !Number.isFinite(frameRange.endFrame) || frameRange.startFrame < 0 || frameRange.endFrame <= frameRange.startFrame) {
|
|
39083
39120
|
throw new Error(
|
|
39084
39121
|
`[captureStage] invalid frameRange: ${JSON.stringify(frameRange)}. Expected non-negative startFrame strictly less than endFrame.`
|
|
39085
39122
|
);
|
|
39086
39123
|
}
|
|
39124
|
+
const rangeFrames = frameRange.endFrame - frameRange.startFrame;
|
|
39125
|
+
if (rangeFrames !== totalFrames) {
|
|
39126
|
+
throw new Error(
|
|
39127
|
+
`[captureStage] frameRange size (${rangeFrames}) must equal totalFrames (${totalFrames}). Received frameRange=${JSON.stringify(frameRange)}.`
|
|
39128
|
+
);
|
|
39129
|
+
}
|
|
39087
39130
|
}
|
|
39088
39131
|
if (workerCount > 1) {
|
|
39089
39132
|
const attempts = await executeDiskCaptureWithAdaptiveRetry({
|
|
@@ -39097,6 +39140,7 @@ async function runCaptureStage(input) {
|
|
|
39097
39140
|
captureOptions: buildCaptureOptions(),
|
|
39098
39141
|
createBeforeCaptureHook: createRenderVideoFrameInjector,
|
|
39099
39142
|
abortSignal,
|
|
39143
|
+
frameRangeStart: frameRange?.startFrame,
|
|
39100
39144
|
onProgress: (progress) => {
|
|
39101
39145
|
job.framesRendered = progress.capturedFrames;
|
|
39102
39146
|
const frameProgress = progress.capturedFrames / progress.totalFrames;
|
|
@@ -40986,16 +41030,17 @@ function findMissingFrameRanges(totalFrames, framesDir, frameExt) {
|
|
|
40986
41030
|
}
|
|
40987
41031
|
return ranges;
|
|
40988
41032
|
}
|
|
40989
|
-
function buildMissingFrameRetryBatches(ranges, maxWorkers, workDir, attempt) {
|
|
41033
|
+
function buildMissingFrameRetryBatches(ranges, maxWorkers, workDir, attempt, rangeStart = 0) {
|
|
40990
41034
|
const workersPerBatch = Math.max(1, Math.floor(maxWorkers));
|
|
40991
41035
|
const batches = [];
|
|
40992
41036
|
for (let i2 = 0; i2 < ranges.length; i2 += workersPerBatch) {
|
|
40993
41037
|
const batchIndex = batches.length;
|
|
40994
41038
|
const batch = ranges.slice(i2, i2 + workersPerBatch).map((range, workerId) => ({
|
|
40995
41039
|
workerId,
|
|
40996
|
-
startFrame: range.startFrame,
|
|
40997
|
-
endFrame: range.endFrame,
|
|
40998
|
-
outputDir: join49(workDir, `retry-${attempt}-batch-${batchIndex}-worker-${workerId}`)
|
|
41040
|
+
startFrame: rangeStart + range.startFrame,
|
|
41041
|
+
endFrame: rangeStart + range.endFrame,
|
|
41042
|
+
outputDir: join49(workDir, `retry-${attempt}-batch-${batchIndex}-worker-${workerId}`),
|
|
41043
|
+
outputFrameOffset: rangeStart
|
|
40999
41044
|
}));
|
|
41000
41045
|
batches.push(batch);
|
|
41001
41046
|
}
|
|
@@ -41026,6 +41071,7 @@ async function executeDiskCaptureWithAdaptiveRetry(options) {
|
|
|
41026
41071
|
let currentWorkers = options.initialWorkerCount;
|
|
41027
41072
|
let missingRanges = null;
|
|
41028
41073
|
let attempt = 0;
|
|
41074
|
+
const rangeStart = options.frameRangeStart ?? 0;
|
|
41029
41075
|
while (true) {
|
|
41030
41076
|
const frameCount = missingRanges ? countFrameRanges(missingRanges) : options.totalFrames;
|
|
41031
41077
|
attempts.push({
|
|
@@ -41035,7 +41081,13 @@ async function executeDiskCaptureWithAdaptiveRetry(options) {
|
|
|
41035
41081
|
reason: attempt === 0 ? "initial" : "retry"
|
|
41036
41082
|
});
|
|
41037
41083
|
const attemptWorkDir = join49(options.workDir, `capture-attempt-${attempt}`);
|
|
41038
|
-
const batches = missingRanges ? buildMissingFrameRetryBatches(
|
|
41084
|
+
const batches = missingRanges ? buildMissingFrameRetryBatches(
|
|
41085
|
+
missingRanges,
|
|
41086
|
+
currentWorkers,
|
|
41087
|
+
attemptWorkDir,
|
|
41088
|
+
attempt,
|
|
41089
|
+
rangeStart
|
|
41090
|
+
) : [distributeFrames(options.totalFrames, currentWorkers, attemptWorkDir, rangeStart)];
|
|
41039
41091
|
try {
|
|
41040
41092
|
for (const tasks of batches) {
|
|
41041
41093
|
const capturedBeforeBatch = countCapturedFrames(
|
|
@@ -43467,6 +43519,14 @@ async function plan(projectDir, config, planDir) {
|
|
|
43467
43519
|
height,
|
|
43468
43520
|
format: config.format
|
|
43469
43521
|
};
|
|
43522
|
+
try {
|
|
43523
|
+
rmSync11(workDir, { recursive: true, force: true });
|
|
43524
|
+
} catch (err) {
|
|
43525
|
+
log2.warn("[plan] failed to remove temp work dir", {
|
|
43526
|
+
workDir,
|
|
43527
|
+
error: err instanceof Error ? err.message : String(err)
|
|
43528
|
+
});
|
|
43529
|
+
}
|
|
43470
43530
|
const freezeResult = await freezePlan({
|
|
43471
43531
|
planDir,
|
|
43472
43532
|
composition: compositionJson,
|
|
@@ -43480,14 +43540,6 @@ async function plan(projectDir, config, planDir) {
|
|
|
43480
43540
|
hasAudio: audioResult.hasAudio
|
|
43481
43541
|
});
|
|
43482
43542
|
const planHash = freezeResult.planHash;
|
|
43483
|
-
try {
|
|
43484
|
-
rmSync11(workDir, { recursive: true, force: true });
|
|
43485
|
-
} catch (err) {
|
|
43486
|
-
log2.warn("[plan] failed to remove temp work dir", {
|
|
43487
|
-
workDir,
|
|
43488
|
-
error: err instanceof Error ? err.message : String(err)
|
|
43489
|
-
});
|
|
43490
|
-
}
|
|
43491
43543
|
const sizeLimitBytes = config.planDirSizeLimitBytes ?? PLAN_DIR_SIZE_LIMIT_BYTES;
|
|
43492
43544
|
const planDirBytes = measurePlanDirBytes(planDir);
|
|
43493
43545
|
if (planDirBytes > sizeLimitBytes) {
|
|
@@ -43605,31 +43657,6 @@ function rebuildExtractedFramesFromPlanDir(planDir, videos) {
|
|
|
43605
43657
|
}
|
|
43606
43658
|
return result;
|
|
43607
43659
|
}
|
|
43608
|
-
async function readWebGlVendorInfoFromCanvas(page) {
|
|
43609
|
-
await page.goto("about:blank", { waitUntil: "domcontentloaded", timeout: 3e4 });
|
|
43610
|
-
return page.evaluate(() => {
|
|
43611
|
-
try {
|
|
43612
|
-
const canvas = document.createElement("canvas");
|
|
43613
|
-
const gl = canvas.getContext("webgl") ?? canvas.getContext("experimental-webgl");
|
|
43614
|
-
if (!gl) {
|
|
43615
|
-
return { vendor: "", renderer: "" };
|
|
43616
|
-
}
|
|
43617
|
-
const ext = gl.getExtension("WEBGL_debug_renderer_info");
|
|
43618
|
-
if (!ext) {
|
|
43619
|
-
return {
|
|
43620
|
-
vendor: String(gl.getParameter(gl.VENDOR) ?? ""),
|
|
43621
|
-
renderer: String(gl.getParameter(gl.RENDERER) ?? "")
|
|
43622
|
-
};
|
|
43623
|
-
}
|
|
43624
|
-
return {
|
|
43625
|
-
vendor: String(gl.getParameter(ext.UNMASKED_VENDOR_WEBGL) ?? ""),
|
|
43626
|
-
renderer: String(gl.getParameter(ext.UNMASKED_RENDERER_WEBGL) ?? "")
|
|
43627
|
-
};
|
|
43628
|
-
} catch {
|
|
43629
|
-
return { vendor: "", renderer: "" };
|
|
43630
|
-
}
|
|
43631
|
-
});
|
|
43632
|
-
}
|
|
43633
43660
|
function hashChunkOutput(outputPath, kind) {
|
|
43634
43661
|
if (kind === "file") return sha256Hex(readFileSync30(outputPath));
|
|
43635
43662
|
const entries2 = readdirSync19(outputPath).filter((name) => /\.(png|jpg|jpeg)$/i.test(name)).sort();
|
|
@@ -43768,13 +43795,16 @@ async function renderChunk(planDir, chunkIndex, outputChunkPath) {
|
|
|
43768
43795
|
// `beginFrameTimeTicks` is host-independent. Only chunks ever set this.
|
|
43769
43796
|
lockWarmupTicks: true
|
|
43770
43797
|
};
|
|
43798
|
+
const chunkWorkerCount = calculateOptimalWorkers(framesInChunk, void 0, cfg);
|
|
43771
43799
|
let session = null;
|
|
43772
43800
|
let outputKind;
|
|
43773
43801
|
let framesEncoded = 0;
|
|
43774
43802
|
try {
|
|
43775
|
-
|
|
43776
|
-
|
|
43777
|
-
|
|
43803
|
+
if (chunkWorkerCount === 1) {
|
|
43804
|
+
session = await createCaptureSession(fileServer.url, framesDir, captureOptions, null, cfg);
|
|
43805
|
+
await assertSwiftShader(session.page, readWebGlVendorInfoFromCanvas);
|
|
43806
|
+
await initializeSession(session);
|
|
43807
|
+
}
|
|
43778
43808
|
await runCaptureStage({
|
|
43779
43809
|
fileServer,
|
|
43780
43810
|
workDir,
|
|
@@ -43784,11 +43814,7 @@ async function renderChunk(planDir, chunkIndex, outputChunkPath) {
|
|
|
43784
43814
|
cfg,
|
|
43785
43815
|
forceScreenshot: encoder.forceScreenshot,
|
|
43786
43816
|
log: log2,
|
|
43787
|
-
workerCount:
|
|
43788
|
-
// Pass the pre-warmed session through as `probeSession` so captureStage
|
|
43789
|
-
// reuses it via `prepareCaptureSessionForReuse` instead of spinning up
|
|
43790
|
-
// a fresh browser. The stage closes the session in its `finally`,
|
|
43791
|
-
// so we MUST clear our own reference here to avoid a double-close.
|
|
43817
|
+
workerCount: chunkWorkerCount,
|
|
43792
43818
|
probeSession: session,
|
|
43793
43819
|
needsAlpha: plan2.dimensions.format !== "mp4",
|
|
43794
43820
|
captureAttempts: [],
|
|
@@ -43909,6 +43935,7 @@ var init_renderChunk = __esm({
|
|
|
43909
43935
|
init_fileServer2();
|
|
43910
43936
|
init_shared2();
|
|
43911
43937
|
init_runtimeEnvSnapshot();
|
|
43938
|
+
init_src2();
|
|
43912
43939
|
FFMPEG_VERSION_MISMATCH = "FFMPEG_VERSION_MISMATCH";
|
|
43913
43940
|
PLAN_HASH_MISMATCH = "PLAN_HASH_MISMATCH";
|
|
43914
43941
|
MISSING_PLAN_ARTIFACT = "MISSING_PLAN_ARTIFACT";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
*,:before,:after{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }*,:before,:after{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}:before,:after{--tw-content: ""}html,:host{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji";font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}.\!container{width:100%!important}.container{width:100%}@media(min-width:640px){.\!container{max-width:640px!important}.container{max-width:640px}}@media(min-width:768px){.\!container{max-width:768px!important}.container{max-width:768px}}@media(min-width:1024px){.\!container{max-width:1024px!important}.container{max-width:1024px}}@media(min-width:1280px){.\!container{max-width:1280px!important}.container{max-width:1280px}}@media(min-width:1536px){.\!container{max-width:1536px!important}.container{max-width:1536px}}.pointer-events-none{pointer-events:none}.pointer-events-auto{pointer-events:auto}.\!visible{visibility:visible!important}.visible{visibility:visible}.collapse{visibility:collapse}.static{position:static}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.inset-0{top:0;right:0;bottom:0;left:0}.inset-2{top:.5rem;right:.5rem;bottom:.5rem;left:.5rem}.inset-x-0{left:0;right:0}.inset-y-0{top:0;bottom:0}.-bottom-1\.5{bottom:-.375rem}.-right-1\.5{right:-.375rem}.bottom-0{bottom:0}.bottom-1{bottom:.25rem}.bottom-2{bottom:.5rem}.bottom-6{bottom:1.5rem}.bottom-full{bottom:100%}.left-0{left:0}.left-1\/2{left:50%}.left-2{left:.5rem}.left-\[100px\]{left:100px}.left-\[176px\]{left:176px}.left-\[24px\]{left:24px}.left-\[31px\]{left:31px}.left-\[34px\]{left:34px}.left-\[52px\]{left:52px}.left-\[82px\]{left:82px}.right-0{right:0}.right-3{right:.75rem}.top-0{top:0}.top-1{top:.25rem}.top-1\/2{top:50%}.top-2{top:.5rem}.top-3{top:.75rem}.top-\[18px\]{top:18px}.top-\[21px\]{top:21px}.top-\[27px\]{top:27px}.top-\[3px\]{top:3px}.top-\[51px\]{top:51px}.top-\[calc\(100\%\+6px\)\]{top:calc(100% + 6px)}.top-full{top:100%}.z-10{z-index:10}.z-20{z-index:20}.z-30{z-index:30}.z-50{z-index:50}.z-\[100\]{z-index:100}.z-\[1\]{z-index:1}.z-\[200\]{z-index:200}.z-\[3\]{z-index:3}.z-\[4\]{z-index:4}.z-\[90\]{z-index:90}.z-\[91\]{z-index:91}.z-\[9999\]{z-index:9999}.mx-1{margin-left:.25rem;margin-right:.25rem}.my-0\.5{margin-top:.125rem;margin-bottom:.125rem}.my-1{margin-top:.25rem;margin-bottom:.25rem}.mb-0\.5{margin-bottom:.125rem}.mb-1\.5{margin-bottom:.375rem}.mb-2{margin-bottom:.5rem}.mb-3{margin-bottom:.75rem}.mb-4{margin-bottom:1rem}.ml-1{margin-left:.25rem}.ml-1\.5{margin-left:.375rem}.mt-0\.5{margin-top:.125rem}.mt-1{margin-top:.25rem}.mt-1\.5{margin-top:.375rem}.mt-2{margin-top:.5rem}.mt-3{margin-top:.75rem}.mt-4{margin-top:1rem}.mt-\[22px\]{margin-top:22px}.block{display:block}.inline-block{display:inline-block}.inline{display:inline}.flex{display:flex}.inline-flex{display:inline-flex}.grid{display:grid}.contents{display:contents}.hidden{display:none}.h-1{height:.25rem}.h-1\.5{height:.375rem}.h-10{height:2.5rem}.h-11{height:2.75rem}.h-2{height:.5rem}.h-24{height:6rem}.h-28{height:7rem}.h-3{height:.75rem}.h-3\.5{height:.875rem}.h-36{height:9rem}.h-4{height:1rem}.h-5{height:1.25rem}.h-6{height:1.5rem}.h-7{height:1.75rem}.h-8{height:2rem}.h-9{height:2.25rem}.h-\[18px\]{height:18px}.h-\[3px\]{height:3px}.h-\[45px\]{height:45px}.h-\[52px\]{height:52px}.h-\[5px\]{height:5px}.h-\[70px\]{height:70px}.h-full{height:100%}.h-px{height:1px}.max-h-24{max-height:6rem}.max-h-64{max-height:16rem}.max-h-\[70\%\]{max-height:70%}.max-h-\[80vh\]{max-height:80vh}.max-h-full{max-height:100%}.min-h-0{min-height:0px}.min-h-7{min-height:1.75rem}.min-h-8{min-height:2rem}.min-h-9{min-height:2.25rem}.w-0{width:0px}.w-1\.5{width:.375rem}.w-10{width:2.5rem}.w-14{width:3.5rem}.w-16{width:4rem}.w-2{width:.5rem}.w-20{width:5rem}.w-3{width:.75rem}.w-3\.5{width:.875rem}.w-4{width:1rem}.w-5{width:1.25rem}.w-52{width:13rem}.w-6{width:1.5rem}.w-7{width:1.75rem}.w-8{width:2rem}.w-80{width:20rem}.w-9{width:2.25rem}.w-\[110px\]{width:110px}.w-\[118px\]{width:118px}.w-\[160px\]{width:160px}.w-\[292px\]{width:292px}.w-\[320px\]{width:320px}.w-\[480px\]{width:480px}.w-\[56px\]{width:56px}.w-\[72px\]{width:72px}.w-full{width:100%}.w-px{width:1px}.min-w-0{min-width:0px}.min-w-7{min-width:1.75rem}.min-w-8{min-width:2rem}.min-w-9{min-width:2.25rem}.min-w-\[140px\]{min-width:140px}.min-w-\[160px\]{min-width:160px}.min-w-\[20px\]{min-width:20px}.min-w-\[220px\]{min-width:220px}.min-w-\[36px\]{min-width:36px}.min-w-\[52px\]{min-width:52px}.min-w-\[56px\]{min-width:56px}.min-w-\[58px\]{min-width:58px}.min-w-\[96px\]{min-width:96px}.max-w-\[260px\]{max-width:260px}.max-w-\[280px\]{max-width:280px}.max-w-\[calc\(100vw-2rem\)\]{max-width:calc(100vw - 2rem)}.max-w-full{max-width:100%}.max-w-xl{max-width:36rem}.flex-1{flex:1 1 0%}.flex-shrink{flex-shrink:1}.flex-shrink-0{flex-shrink:0}.shrink{flex-shrink:1}.shrink-0{flex-shrink:0}.flex-grow,.grow{flex-grow:1}.-translate-x-1\/2{--tw-translate-x: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.-translate-y-1\/2{--tw-translate-y: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.-rotate-90{--tw-rotate: -90deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.rotate-90{--tw-rotate: 90deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.\!transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))!important}.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}@keyframes pulse{50%{opacity:.5}}.animate-pulse{animation:pulse 2s cubic-bezier(.4,0,.6,1) infinite}@keyframes spin{to{transform:rotate(360deg)}}.animate-spin{animation:spin 1s linear infinite}.cursor-col-resize{cursor:col-resize}.cursor-crosshair{cursor:crosshair}.cursor-default{cursor:default}.cursor-ew-resize{cursor:ew-resize}.cursor-grab{cursor:grab}.cursor-help{cursor:help}.cursor-not-allowed{cursor:not-allowed}.cursor-pointer{cursor:pointer}.cursor-row-resize{cursor:row-resize}.touch-none{touch-action:none}.select-none{-webkit-user-select:none;-moz-user-select:none;user-select:none}.resize-none{resize:none}.\!resize{resize:both!important}.resize{resize:both}.appearance-none{-webkit-appearance:none;-moz-appearance:none;appearance:none}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.grid-cols-\[minmax\(0\,1fr\)_68px_28px\]{grid-template-columns:minmax(0,1fr) 68px 28px}.grid-cols-\[minmax\(0\,1fr\)_auto\]{grid-template-columns:minmax(0,1fr) auto}.grid-cols-\[minmax\(0\,1fr\)_auto_auto\]{grid-template-columns:minmax(0,1fr) auto auto}.grid-cols-\[repeat\(auto-fit\,minmax\(118px\,1fr\)\)\]{grid-template-columns:repeat(auto-fit,minmax(118px,1fr))}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-start{align-items:flex-start}.items-end{align-items:flex-end}.items-center{align-items:center}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-0\.5{gap:.125rem}.gap-1{gap:.25rem}.gap-1\.5{gap:.375rem}.gap-2{gap:.5rem}.gap-2\.5{gap:.625rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.gap-x-2{-moz-column-gap:.5rem;column-gap:.5rem}.gap-y-1{row-gap:.25rem}.gap-y-1\.5{row-gap:.375rem}.space-y-0\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.125rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.125rem * var(--tw-space-y-reverse))}.space-y-1>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.25rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.25rem * var(--tw-space-y-reverse))}.space-y-3>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.75rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.75rem * var(--tw-space-y-reverse))}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem * var(--tw-space-y-reverse))}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.overflow-x-hidden{overflow-x:hidden}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.rounded{border-radius:.25rem}.rounded-2xl{border-radius:1rem}.rounded-\[10px\]{border-radius:10px}.rounded-\[11px\]{border-radius:11px}.rounded-\[14px\]{border-radius:14px}.rounded-\[18px\]{border-radius:18px}.rounded-\[9px\]{border-radius:9px}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5rem}.rounded-md{border-radius:.375rem}.rounded-sm{border-radius:.125rem}.rounded-xl{border-radius:.75rem}.rounded-l{border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}.rounded-r{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.border{border-width:1px}.border-2{border-width:2px}.border-b{border-bottom-width:1px}.border-l{border-left-width:1px}.border-l-2{border-left-width:2px}.border-r{border-right-width:1px}.border-t{border-top-width:1px}.border-dashed{border-style:dashed}.border-none{border-style:none}.border-green-500\/30{border-color:#22c55e4d}.border-neutral-600{--tw-border-opacity: 1;border-color:rgb(82 82 82 / var(--tw-border-opacity, 1))}.border-neutral-700{--tw-border-opacity: 1;border-color:rgb(64 64 64 / var(--tw-border-opacity, 1))}.border-neutral-700\/40{border-color:#40404066}.border-neutral-700\/50{border-color:#40404080}.border-neutral-700\/60{border-color:#40404099}.border-neutral-800{--tw-border-opacity: 1;border-color:rgb(38 38 38 / var(--tw-border-opacity, 1))}.border-neutral-800\/30{border-color:#2626264d}.border-neutral-800\/40{border-color:#26262666}.border-neutral-800\/50{border-color:#26262680}.border-neutral-800\/60{border-color:#26262699}.border-neutral-800\/80{border-color:#262626cc}.border-neutral-900{--tw-border-opacity: 1;border-color:rgb(23 23 23 / var(--tw-border-opacity, 1))}.border-red-500{--tw-border-opacity: 1;border-color:rgb(239 68 68 / var(--tw-border-opacity, 1))}.border-red-700\/50{border-color:#b91c1c80}.border-studio-accent{--tw-border-opacity: 1;border-color:rgb(60 230 172 / var(--tw-border-opacity, 1))}.border-studio-accent\/25{border-color:#3ce6ac40}.border-studio-accent\/30{border-color:#3ce6ac4d}.border-studio-accent\/40{border-color:#3ce6ac66}.border-studio-accent\/50{border-color:#3ce6ac80}.border-studio-accent\/60{border-color:#3ce6ac99}.border-studio-accent\/70{border-color:#3ce6acb3}.border-studio-accent\/80{border-color:#3ce6accc}.border-transparent{border-color:transparent}.border-white{--tw-border-opacity: 1;border-color:rgb(255 255 255 / var(--tw-border-opacity, 1))}.border-white\/10{border-color:#ffffff1a}.border-white\/90{border-color:#ffffffe6}.border-yellow-400\/30{border-color:#facc154d}.border-t-neutral-500{--tw-border-opacity: 1;border-top-color:rgb(115 115 115 / var(--tw-border-opacity, 1))}.bg-\[\#0a0a0b\]{--tw-bg-opacity: 1;background-color:rgb(10 10 11 / var(--tw-bg-opacity, 1))}.bg-\[\#0d1117\]{--tw-bg-opacity: 1;background-color:rgb(13 17 23 / var(--tw-bg-opacity, 1))}.bg-\[\#0f141c\]{--tw-bg-opacity: 1;background-color:rgb(15 20 28 / var(--tw-bg-opacity, 1))}.bg-\[\#3CE6AC\]\/10{background-color:#3ce6ac1a}.bg-\[\#3CE6AC\]\/5{background-color:#3ce6ac0d}.bg-black{--tw-bg-opacity: 1;background-color:rgb(0 0 0 / var(--tw-bg-opacity, 1))}.bg-black\/20{background-color:#0003}.bg-black\/25{background-color:#00000040}.bg-black\/40{background-color:#0006}.bg-black\/50{background-color:#00000080}.bg-black\/60{background-color:#0009}.bg-blue-900\/40{background-color:#1e3a8a66}.bg-green-500\/20{background-color:#22c55e33}.bg-green-600{--tw-bg-opacity: 1;background-color:rgb(22 163 74 / var(--tw-bg-opacity, 1))}.bg-neutral-600{--tw-bg-opacity: 1;background-color:rgb(82 82 82 / var(--tw-bg-opacity, 1))}.bg-neutral-700{--tw-bg-opacity: 1;background-color:rgb(64 64 64 / var(--tw-bg-opacity, 1))}.bg-neutral-700\/40{background-color:#40404066}.bg-neutral-800{--tw-bg-opacity: 1;background-color:rgb(38 38 38 / var(--tw-bg-opacity, 1))}.bg-neutral-800\/60{background-color:#26262699}.bg-neutral-800\/70{background-color:#262626b3}.bg-neutral-900{--tw-bg-opacity: 1;background-color:rgb(23 23 23 / var(--tw-bg-opacity, 1))}.bg-neutral-900\/50{background-color:#17171780}.bg-neutral-900\/60{background-color:#17171799}.bg-neutral-900\/80{background-color:#171717cc}.bg-neutral-900\/95{background-color:#171717f2}.bg-neutral-950{--tw-bg-opacity: 1;background-color:rgb(10 10 10 / var(--tw-bg-opacity, 1))}.bg-neutral-950\/80{background-color:#0a0a0acc}.bg-red-400{--tw-bg-opacity: 1;background-color:rgb(248 113 113 / var(--tw-bg-opacity, 1))}.bg-red-500\/10{background-color:#ef44441a}.bg-red-600{--tw-bg-opacity: 1;background-color:rgb(220 38 38 / var(--tw-bg-opacity, 1))}.bg-red-900\/60{background-color:#7f1d1d99}.bg-red-900\/90{background-color:#7f1d1de6}.bg-red-950\/30{background-color:#450a0a4d}.bg-studio-accent{--tw-bg-opacity: 1;background-color:rgb(60 230 172 / var(--tw-bg-opacity, 1))}.bg-studio-accent\/10{background-color:#3ce6ac1a}.bg-studio-accent\/15{background-color:#3ce6ac26}.bg-studio-accent\/20{background-color:#3ce6ac33}.bg-studio-accent\/5{background-color:#3ce6ac0d}.bg-studio-accent\/60{background-color:#3ce6ac99}.bg-studio-accent\/90{background-color:#3ce6ace6}.bg-studio-accent\/\[0\.03\]{background-color:#3ce6ac08}.bg-studio-accent\/\[0\.05\]{background-color:#3ce6ac0d}.bg-studio-accent\/\[0\.06\]{background-color:#3ce6ac0f}.bg-transparent{background-color:transparent}.bg-white{--tw-bg-opacity: 1;background-color:rgb(255 255 255 / var(--tw-bg-opacity, 1))}.bg-white\/10{background-color:#ffffff1a}.bg-white\/5{background-color:#ffffff0d}.bg-white\/70{background-color:#ffffffb3}.bg-white\/\[0\.035\]{background-color:#ffffff09}.bg-white\/\[0\.04\]{background-color:#ffffff0a}.bg-white\/\[0\.07\]{background-color:#ffffff12}.bg-yellow-400\/10{background-color:#facc151a}.bg-gradient-to-r{background-image:linear-gradient(to right,var(--tw-gradient-stops))}.bg-gradient-to-t{background-image:linear-gradient(to top,var(--tw-gradient-stops))}.from-black{--tw-gradient-from: #000 var(--tw-gradient-from-position);--tw-gradient-to: rgb(0 0 0 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-white{--tw-gradient-from: #fff var(--tw-gradient-from-position);--tw-gradient-to: rgb(255 255 255 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.to-transparent{--tw-gradient-to: transparent var(--tw-gradient-to-position)}.fill-neutral-400{fill:#a3a3a3}.fill-neutral-500{fill:#737373}.object-contain{-o-object-fit:contain;object-fit:contain}.object-cover{-o-object-fit:cover;object-fit:cover}.p-0{padding:0}.p-0\.5{padding:.125rem}.p-1{padding:.25rem}.p-1\.5{padding:.375rem}.p-2{padding:.5rem}.p-2\.5{padding:.625rem}.p-3{padding:.75rem}.p-4{padding:1rem}.px-1{padding-left:.25rem;padding-right:.25rem}.px-1\.5{padding-left:.375rem;padding-right:.375rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-2\.5{padding-left:.625rem;padding-right:.625rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-3\.5{padding-left:.875rem;padding-right:.875rem}.px-4{padding-left:1rem;padding-right:1rem}.px-5{padding-left:1.25rem;padding-right:1.25rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.px-8{padding-left:2rem;padding-right:2rem}.py-0\.5{padding-top:.125rem;padding-bottom:.125rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-1\.5{padding-top:.375rem;padding-bottom:.375rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-2\.5{padding-top:.625rem;padding-bottom:.625rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-3\.5{padding-top:.875rem;padding-bottom:.875rem}.py-4{padding-top:1rem;padding-bottom:1rem}.py-5{padding-top:1.25rem;padding-bottom:1.25rem}.py-6{padding-top:1.5rem;padding-bottom:1.5rem}.py-8{padding-top:2rem;padding-bottom:2rem}.pb-0\.5{padding-bottom:.125rem}.pb-2{padding-bottom:.5rem}.pb-2\.5{padding-bottom:.625rem}.pb-3{padding-bottom:.75rem}.pb-4{padding-bottom:1rem}.pl-6{padding-left:1.5rem}.pr-1{padding-right:.25rem}.pr-9{padding-right:2.25rem}.pt-1{padding-top:.25rem}.pt-1\.5{padding-top:.375rem}.pt-2\.5{padding-top:.625rem}.pt-3{padding-top:.75rem}.text-left{text-align:left}.text-center{text-align:center}.text-right{text-align:right}.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.text-\[12px\]{font-size:12px}.text-\[13px\]{font-size:13px}.text-\[8px\]{font-size:8px}.text-\[9px\]{font-size:9px}.text-base{font-size:1rem;line-height:1.5rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-medium{font-weight:500}.font-semibold{font-weight:600}.uppercase{text-transform:uppercase}.lowercase{text-transform:lowercase}.capitalize{text-transform:capitalize}.italic{font-style:italic}.tabular-nums{--tw-numeric-spacing: tabular-nums;font-variant-numeric:var(--tw-ordinal) var(--tw-slashed-zero) var(--tw-numeric-figure) var(--tw-numeric-spacing) var(--tw-numeric-fraction)}.leading-4{line-height:1rem}.leading-5{line-height:1.25rem}.leading-none{line-height:1}.leading-relaxed{line-height:1.625}.leading-tight{line-height:1.25}.tracking-\[0\.08em\]{letter-spacing:.08em}.tracking-\[0\.12em\]{letter-spacing:.12em}.tracking-\[0\.14em\]{letter-spacing:.14em}.tracking-\[0\.16em\]{letter-spacing:.16em}.tracking-\[0\.18em\]{letter-spacing:.18em}.tracking-\[0\.22em\]{letter-spacing:.22em}.tracking-tight{letter-spacing:-.025em}.tracking-wider{letter-spacing:.05em}.text-\[\#09090B\]{--tw-text-opacity: 1;color:rgb(9 9 11 / var(--tw-text-opacity, 1))}.text-\[\#3ce6ac\]{--tw-text-opacity: 1;color:rgb(60 230 172 / var(--tw-text-opacity, 1))}.text-\[\#7f8796\]{--tw-text-opacity: 1;color:rgb(127 135 150 / var(--tw-text-opacity, 1))}.text-amber-400{--tw-text-opacity: 1;color:rgb(251 191 36 / var(--tw-text-opacity, 1))}.text-blue-400{--tw-text-opacity: 1;color:rgb(96 165 250 / var(--tw-text-opacity, 1))}.text-green-400{--tw-text-opacity: 1;color:rgb(74 222 128 / var(--tw-text-opacity, 1))}.text-neutral-100{--tw-text-opacity: 1;color:rgb(245 245 245 / var(--tw-text-opacity, 1))}.text-neutral-200{--tw-text-opacity: 1;color:rgb(229 229 229 / var(--tw-text-opacity, 1))}.text-neutral-300{--tw-text-opacity: 1;color:rgb(212 212 212 / var(--tw-text-opacity, 1))}.text-neutral-400{--tw-text-opacity: 1;color:rgb(163 163 163 / var(--tw-text-opacity, 1))}.text-neutral-50{--tw-text-opacity: 1;color:rgb(250 250 250 / var(--tw-text-opacity, 1))}.text-neutral-500{--tw-text-opacity: 1;color:rgb(115 115 115 / var(--tw-text-opacity, 1))}.text-neutral-600{--tw-text-opacity: 1;color:rgb(82 82 82 / var(--tw-text-opacity, 1))}.text-neutral-700{--tw-text-opacity: 1;color:rgb(64 64 64 / var(--tw-text-opacity, 1))}.text-neutral-950{--tw-text-opacity: 1;color:rgb(10 10 10 / var(--tw-text-opacity, 1))}.text-purple-400{--tw-text-opacity: 1;color:rgb(192 132 252 / var(--tw-text-opacity, 1))}.text-red-200{--tw-text-opacity: 1;color:rgb(254 202 202 / var(--tw-text-opacity, 1))}.text-red-300{--tw-text-opacity: 1;color:rgb(252 165 165 / var(--tw-text-opacity, 1))}.text-red-400{--tw-text-opacity: 1;color:rgb(248 113 113 / var(--tw-text-opacity, 1))}.text-studio-accent{--tw-text-opacity: 1;color:rgb(60 230 172 / var(--tw-text-opacity, 1))}.text-studio-accent\/50{color:#3ce6ac80}.text-studio-accent\/80{color:#3ce6accc}.text-white{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.text-white\/90{color:#ffffffe6}.text-yellow-300{--tw-text-opacity: 1;color:rgb(253 224 71 / var(--tw-text-opacity, 1))}.underline{text-decoration-line:underline}.line-through{text-decoration-line:line-through}.placeholder-neutral-600::-moz-placeholder{--tw-placeholder-opacity: 1;color:rgb(82 82 82 / var(--tw-placeholder-opacity, 1))}.placeholder-neutral-600::placeholder{--tw-placeholder-opacity: 1;color:rgb(82 82 82 / var(--tw-placeholder-opacity, 1))}.accent-\[\#3ce6ac\]{accent-color:#3ce6ac}.accent-studio-accent{accent-color:#3CE6AC}.opacity-25{opacity:.25}.opacity-50{opacity:.5}.opacity-60{opacity:.6}.opacity-70{opacity:.7}.opacity-75{opacity:.75}.mix-blend-difference{mix-blend-mode:difference}.shadow{--tw-shadow: 0 1px 3px 0 rgb(0 0 0 / .1), 0 1px 2px -1px rgb(0 0 0 / .1);--tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-2xl{--tw-shadow: 0 25px 50px -12px rgb(0 0 0 / .25);--tw-shadow-colored: 0 25px 50px -12px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-\[0_0_0_1px_rgba\(0\,0\,0\,0\.35\)\]{--tw-shadow: 0 0 0 1px rgba(0,0,0,.35);--tw-shadow-colored: 0 0 0 1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-\[0_0_0_1px_rgba\(0\,0\,0\,0\.45\)\]{--tw-shadow: 0 0 0 1px rgba(0,0,0,.45);--tw-shadow-colored: 0 0 0 1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-\[0_0_0_1px_rgba\(0\,0\,0\,0\.85\)\,0_6px_14px_rgba\(0\,0\,0\,0\.5\)\]{--tw-shadow: 0 0 0 1px rgba(0,0,0,.85),0 6px 14px rgba(0,0,0,.5);--tw-shadow-colored: 0 0 0 1px var(--tw-shadow-color), 0 6px 14px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-\[0_0_0_1px_rgba\(0\,0\,0\,0\.85\)\,0_8px_18px_rgba\(0\,0\,0\,0\.45\)\]{--tw-shadow: 0 0 0 1px rgba(0,0,0,.85),0 8px 18px rgba(0,0,0,.45);--tw-shadow-colored: 0 0 0 1px var(--tw-shadow-color), 0 8px 18px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-\[0_0_0_1px_rgba\(60\,230\,172\,0\.25\)\]{--tw-shadow: 0 0 0 1px rgba(60,230,172,.25);--tw-shadow-colored: 0 0 0 1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-\[0_0_0_1px_rgba\(60\,230\,172\,0\.3\)\]{--tw-shadow: 0 0 0 1px rgba(60,230,172,.3);--tw-shadow-colored: 0 0 0 1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-\[0_0_0_2px_rgba\(60\,230\,172\,0\.18\)\]{--tw-shadow: 0 0 0 2px rgba(60,230,172,.18);--tw-shadow-colored: 0 0 0 2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-\[0_18px_40px_rgba\(0\,0\,0\,0\.3\)\,0_4px_14px_rgba\(0\,0\,0\,0\.18\)\]{--tw-shadow: 0 18px 40px rgba(0,0,0,.3),0 4px 14px rgba(0,0,0,.18);--tw-shadow-colored: 0 18px 40px var(--tw-shadow-color), 0 4px 14px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-\[0_1px_2px_rgba\(0\,0\,0\,0\.2\)\]{--tw-shadow: 0 1px 2px rgba(0,0,0,.2);--tw-shadow-colored: 0 1px 2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-\[0_1px_3px_rgba\(0\,0\,0\,0\.28\)\]{--tw-shadow: 0 1px 3px rgba(0,0,0,.28);--tw-shadow-colored: 0 1px 3px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-\[inset_0_0_0_1px_rgba\(255\,255\,255\,0\.06\)\]{--tw-shadow: inset 0 0 0 1px rgba(255,255,255,.06);--tw-shadow-colored: inset 0 0 0 1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-\[inset_0_1px_0_rgba\(255\,255\,255\,0\.03\)\]{--tw-shadow: inset 0 1px 0 rgba(255,255,255,.03);--tw-shadow-colored: inset 0 1px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-\[inset_0_1px_0_rgba\(255\,255\,255\,0\.04\)\]{--tw-shadow: inset 0 1px 0 rgba(255,255,255,.04);--tw-shadow-colored: inset 0 1px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-\[inset_0_1px_0_rgba\(255\,255\,255\,0\.08\)\]{--tw-shadow: inset 0 1px 0 rgba(255,255,255,.08);--tw-shadow-colored: inset 0 1px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-\[inset_0_1px_2px_rgba\(0\,0\,0\,0\.55\)\]{--tw-shadow: inset 0 1px 2px rgba(0,0,0,.55);--tw-shadow-colored: inset 0 1px 2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-lg{--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / .1), 0 4px 6px -4px rgb(0 0 0 / .1);--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-sm{--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / .05);--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-xl{--tw-shadow: 0 20px 25px -5px rgb(0 0 0 / .1), 0 8px 10px -6px rgb(0 0 0 / .1);--tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-black\/40{--tw-shadow-color: rgb(0 0 0 / .4);--tw-shadow: var(--tw-shadow-colored)}.shadow-black\/50{--tw-shadow-color: rgb(0 0 0 / .5);--tw-shadow: var(--tw-shadow-colored)}.outline-none{outline:2px solid transparent;outline-offset:2px}.outline{outline-style:solid}.outline-1{outline-width:1px}.-outline-offset-1{outline-offset:-1px}.outline-\[\#3CE6AC\]\/30{outline-color:#3ce6ac4d}.outline-\[\#3CE6AC\]\/40{outline-color:#3ce6ac66}.ring{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.ring-1{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.ring-2{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.ring-inset{--tw-ring-inset: inset}.ring-studio-accent{--tw-ring-opacity: 1;--tw-ring-color: rgb(60 230 172 / var(--tw-ring-opacity, 1))}.ring-white\/50{--tw-ring-color: rgb(255 255 255 / .5)}.blur{--tw-blur: blur(8px);filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.drop-shadow{--tw-drop-shadow: drop-shadow(0 1px 2px rgb(0 0 0 / .1)) drop-shadow(0 1px 1px rgb(0 0 0 / .06));filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.invert{--tw-invert: invert(100%);filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.backdrop-blur-sm{--tw-backdrop-blur: blur(4px);-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.backdrop-blur-xl{--tw-backdrop-blur: blur(24px);-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.backdrop-filter{-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.transition{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-all{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-opacity{transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-transform{transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.duration-150{transition-duration:.15s}.duration-300{transition-duration:.3s}.ease-out{transition-timing-function:cubic-bezier(0,0,.2,1)}:root{color-scheme:dark}body{margin:0;padding:0;background:#0a0a0a;color:#e5e5e5;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif;overflow:hidden}#root{width:100vw;height:100vh;height:100dvh}.cm-editor{height:100%;font-size:13px}.cm-editor .cm-scroller{font-family:JetBrains Mono,Fira Code,SF Mono,monospace}.cm-editor.cm-focused{outline:none}.hf-loader{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:.75rem;width:min(34rem,100%);padding:1.5rem;box-sizing:border-box;text-align:center;cursor:default;-moz-user-select:none;user-select:none;-webkit-user-select:none;-webkit-user-drag:none}.hf-frame{display:grid;place-items:center;width:100%;height:100%;min-height:12rem;border:1px solid rgba(255,255,255,.08);background:#00000085}.hf-loader-mark-frame{display:grid;place-items:center;overflow:visible;transform-origin:50% 50%;-moz-user-select:none;user-select:none;-webkit-user-select:none;-webkit-user-drag:none}.hf-loader-mark{display:block;overflow:visible;filter:drop-shadow(0 0 7px rgba(79,219,94,.2));-moz-user-select:none;user-select:none;-webkit-user-select:none;-webkit-user-drag:none}.hf-loader-title{font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,sans-serif;font-size:1rem;font-weight:600;letter-spacing:0;color:var(--hf-heading, #f4f4f5);max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.hf-loader-detail{max-width:32rem;min-height:2.5rem;overflow:hidden;color:var(--hf-text-secondary, rgba(244, 244, 245, .68));font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,sans-serif;font-size:.82rem;line-height:1.6}.hf-loader-mono{width:min(36rem,100%);min-height:1.5rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--hf-text-tertiary, rgba(244, 244, 245, .46));font-family:IBM Plex Mono,SF Mono,Fira Code,monospace;font-size:.75rem;letter-spacing:0;font-variant-numeric:tabular-nums}.hf-loader-progress{width:min(18rem,72vw);height:.375rem;overflow:hidden;border-radius:999px;background:#ffffff1a}.hf-loader-progress__fill{width:100%;height:100%;transform:scaleX(0);transform-origin:left center;border-radius:inherit;background:linear-gradient(90deg,#06e3fa,#4fdb5e);transition:transform .16s ease}.placeholder\:text-neutral-600::-moz-placeholder{--tw-text-opacity: 1;color:rgb(82 82 82 / var(--tw-text-opacity, 1))}.placeholder\:text-neutral-600::placeholder{--tw-text-opacity: 1;color:rgb(82 82 82 / var(--tw-text-opacity, 1))}.last\:border-0:last-child{border-width:0px}.focus-within\:border-neutral-600:focus-within{--tw-border-opacity: 1;border-color:rgb(82 82 82 / var(--tw-border-opacity, 1))}.hover\:border-neutral-500:hover{--tw-border-opacity: 1;border-color:rgb(115 115 115 / var(--tw-border-opacity, 1))}.hover\:border-neutral-600:hover{--tw-border-opacity: 1;border-color:rgb(82 82 82 / var(--tw-border-opacity, 1))}.hover\:border-neutral-700:hover{--tw-border-opacity: 1;border-color:rgb(64 64 64 / var(--tw-border-opacity, 1))}.hover\:border-neutral-800:hover{--tw-border-opacity: 1;border-color:rgb(38 38 38 / var(--tw-border-opacity, 1))}.hover\:border-studio-accent\/40:hover{border-color:#3ce6ac66}.hover\:border-studio-accent\/50:hover{border-color:#3ce6ac80}.hover\:border-white\/20:hover{border-color:#fff3}.hover\:bg-neutral-200:hover{--tw-bg-opacity: 1;background-color:rgb(229 229 229 / var(--tw-bg-opacity, 1))}.hover\:bg-neutral-600:hover{--tw-bg-opacity: 1;background-color:rgb(82 82 82 / var(--tw-bg-opacity, 1))}.hover\:bg-neutral-800:hover{--tw-bg-opacity: 1;background-color:rgb(38 38 38 / var(--tw-bg-opacity, 1))}.hover\:bg-neutral-800\/30:hover{background-color:#2626264d}.hover\:bg-neutral-800\/50:hover{background-color:#26262680}.hover\:bg-neutral-800\/70:hover{background-color:#262626b3}.hover\:bg-neutral-900:hover{--tw-bg-opacity: 1;background-color:rgb(23 23 23 / var(--tw-bg-opacity, 1))}.hover\:bg-red-500:hover{--tw-bg-opacity: 1;background-color:rgb(239 68 68 / var(--tw-bg-opacity, 1))}.hover\:bg-red-600:hover{--tw-bg-opacity: 1;background-color:rgb(220 38 38 / var(--tw-bg-opacity, 1))}.hover\:bg-red-800\/60:hover{background-color:#991b1b99}.hover\:bg-red-900\/30:hover{background-color:#7f1d1d4d}.hover\:bg-studio-accent:hover{--tw-bg-opacity: 1;background-color:rgb(60 230 172 / var(--tw-bg-opacity, 1))}.hover\:bg-studio-accent\/25:hover{background-color:#3ce6ac40}.hover\:bg-studio-accent\/80:hover{background-color:#3ce6accc}.hover\:bg-white\/\[0\.04\]:hover{background-color:#ffffff0a}.hover\:bg-white\/\[0\.06\]:hover{background-color:#ffffff0f}.hover\:text-amber-300:hover{--tw-text-opacity: 1;color:rgb(252 211 77 / var(--tw-text-opacity, 1))}.hover\:text-green-400:hover{--tw-text-opacity: 1;color:rgb(74 222 128 / var(--tw-text-opacity, 1))}.hover\:text-neutral-100:hover{--tw-text-opacity: 1;color:rgb(245 245 245 / var(--tw-text-opacity, 1))}.hover\:text-neutral-200:hover{--tw-text-opacity: 1;color:rgb(229 229 229 / var(--tw-text-opacity, 1))}.hover\:text-neutral-300:hover{--tw-text-opacity: 1;color:rgb(212 212 212 / var(--tw-text-opacity, 1))}.hover\:text-neutral-400:hover{--tw-text-opacity: 1;color:rgb(163 163 163 / var(--tw-text-opacity, 1))}.hover\:text-red-400:hover{--tw-text-opacity: 1;color:rgb(248 113 113 / var(--tw-text-opacity, 1))}.hover\:text-studio-accent:hover{--tw-text-opacity: 1;color:rgb(60 230 172 / var(--tw-text-opacity, 1))}.hover\:text-white:hover{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.hover\:opacity-80:hover{opacity:.8}.hover\:ring-1:hover{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.hover\:ring-white\/30:hover{--tw-ring-color: rgb(255 255 255 / .3)}.hover\:brightness-110:hover{--tw-brightness: brightness(1.1);filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.focus\:border-\[\#3CE6AC\]:focus{--tw-border-opacity: 1;border-color:rgb(60 230 172 / var(--tw-border-opacity, 1))}.focus\:border-\[\#f5a400\]:focus{--tw-border-opacity: 1;border-color:rgb(245 164 0 / var(--tw-border-opacity, 1))}.focus\:border-neutral-600:focus{--tw-border-opacity: 1;border-color:rgb(82 82 82 / var(--tw-border-opacity, 1))}.focus\:border-studio-accent:focus{--tw-border-opacity: 1;border-color:rgb(60 230 172 / var(--tw-border-opacity, 1))}.focus\:border-studio-accent\/40:focus{border-color:#3ce6ac66}.focus\:border-studio-accent\/60:focus{border-color:#3ce6ac99}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus\:ring-1:focus{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus\:ring-2:focus{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus\:ring-\[\#3ce6ac\]:focus{--tw-ring-opacity: 1;--tw-ring-color: rgb(60 230 172 / var(--tw-ring-opacity, 1))}.focus\:ring-\[\#f5a400\]\/40:focus{--tw-ring-color: rgb(245 164 0 / .4)}.focus\:ring-studio-accent\/30:focus{--tw-ring-color: rgb(60 230 172 / .3)}.focus\:ring-studio-accent\/40:focus{--tw-ring-color: rgb(60 230 172 / .4)}.focus-visible\:outline-none:focus-visible{outline:2px solid transparent;outline-offset:2px}.focus-visible\:ring-2:focus-visible{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus-visible\:ring-studio-accent\/50:focus-visible{--tw-ring-color: rgb(60 230 172 / .5)}.active\:scale-\[0\.97\]:active{--tw-scale-x: .97;--tw-scale-y: .97;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.active\:scale-\[0\.98\]:active{--tw-scale-x: .98;--tw-scale-y: .98;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.active\:cursor-grabbing:active{cursor:grabbing}.disabled\:pointer-events-none:disabled{pointer-events:none}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:border-neutral-800:disabled{--tw-border-opacity: 1;border-color:rgb(38 38 38 / var(--tw-border-opacity, 1))}.disabled\:text-neutral-600:disabled{--tw-text-opacity: 1;color:rgb(82 82 82 / var(--tw-text-opacity, 1))}.disabled\:text-neutral-700:disabled{--tw-text-opacity: 1;color:rgb(64 64 64 / var(--tw-text-opacity, 1))}.disabled\:opacity-30:disabled{opacity:.3}.disabled\:opacity-40:disabled{opacity:.4}.disabled\:opacity-50:disabled{opacity:.5}.group:hover .group-hover\:scale-125{--tw-scale-x: 1.25;--tw-scale-y: 1.25;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.group:hover .group-hover\:text-neutral-300{--tw-text-opacity: 1;color:rgb(212 212 212 / var(--tw-text-opacity, 1))}@media(min-width:640px){.sm\:inline{display:inline}}
|