cozyclay 3.1.6 → 3.2.1
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/CHANGELOG.md +145 -0
- package/INSTALL_FOR_AGENTS.md +4 -4
- package/README.md +4 -2
- package/bin/agent/agent-failure-codes.mjs +34 -8
- package/bin/agent/agent-routes.mjs +6 -6
- package/bin/agent/agent-runner.mjs +25 -17
- package/bin/agent/agent-stream.mjs +26 -3
- package/bin/agent/main-prompt.mjs +1 -1
- package/bin/agent/openai-compatible-provider.mjs +24 -1
- package/bin/agent/studio-prompt.mjs +2 -2
- package/bin/agent/supervisor-followup.mjs +34 -0
- package/bin/agent/supervisor.mjs +6 -6
- package/bin/cozyclay.mjs +23 -60
- package/bin/star-prompt.mjs +15 -14
- package/bin/studio-routes.mjs +6 -3
- package/bin/telemetry-state.mjs +5 -7
- package/bin/update-check.mjs +61 -7
- package/bin/update-install.mjs +16 -3
- package/bin/update-restart.mjs +95 -0
- package/bin/update-routes.mjs +25 -3
- package/dist/app/index.html +13 -7
- package/dist/assets/TaskBoard-tgO0MNKL.js +1 -0
- package/dist/assets/analytics-CaTUuLPM.js +1 -0
- package/dist/assets/{app-CEP7jzXB.css → app-CnDkB5WO.css} +1 -1
- package/dist/assets/app-DJt06Oyb.js +5144 -0
- package/dist/assets/compile-worker-D1pl6G7x.js +6 -0
- package/dist/assets/landing-2Fy7DU41.js +1 -0
- package/dist/assets/modulepreload-polyfill-P2Xu9kJm.js +1 -0
- package/dist/assets/motion3-compile-BxaM0Xwl.js +1 -0
- package/dist/assets/scene-asset-sync-CLGNbEBq.js +13 -0
- package/dist/assets/task-board-UVGTZLRF.js +15 -0
- package/dist/assets/workflow-CSiBlX1s.js +179 -0
- package/dist/cozyclay-package.json +1 -1
- package/dist/index.html +4 -1
- package/dist/privacy/index.html +9 -6
- package/dist/sitemap.xml +2 -2
- package/dist/workflow/index.html +5 -4
- package/mcp/README.md +1 -1
- package/mcp/live-hub.mjs +4 -4
- package/mcp/tool-handlers.mjs +14 -16
- package/package.json +3 -1
- package/src/App.jsx +42 -75
- package/src/analytics-controls.js +25 -3
- package/src/analytics-strict.js +16 -4
- package/src/analytics.js +32 -26
- package/src/app-version.js +13 -0
- package/src/asset-drop.js +39 -0
- package/src/asset-pane.css +34 -0
- package/src/asset-pane.jsx +4 -35
- package/src/bus-tasks.js +1 -1
- package/src/character-kind.js +8 -6
- package/src/click-friction.js +5 -4
- package/src/command-bus-telemetry.js +8 -7
- package/src/command-bus.js +2 -16
- package/src/commands/cast.js +2 -1
- package/src/commands/index.js +2 -1
- package/src/commands/motion3.js +3 -1
- package/src/commands/objects.js +2 -37
- package/src/commands/physics.js +21 -0
- package/src/commands/project.js +3 -3
- package/src/commands/sculpt-compare.js +53 -0
- package/src/content-tile.jsx +36 -0
- package/src/domains/cast.js +7 -6
- package/src/domains/motion.js +13 -14
- package/src/domains/scenes.js +41 -31
- package/src/execution-telemetry.js +7 -3
- package/src/export-menu-telemetry.js +26 -0
- package/src/finger-handles.jsx +128 -0
- package/src/friction-hint.js +82 -0
- package/src/live-control.js +2 -1
- package/src/locale-zh/panels.js +20 -0
- package/src/locale-zh/shell.js +4 -0
- package/src/locale-zh/workspace.js +6 -0
- package/src/motion/center-of-mass.js +5 -23
- package/src/motion/contact-project.js +143 -0
- package/src/motion/find-bone.js +13 -0
- package/src/motion/fingers.js +170 -0
- package/src/motion/fingertip-pick.js +21 -0
- package/src/motion/fix-collisions.js +1 -1
- package/src/motion/ik-drag.js +93 -1
- package/src/motion/ik-exposure.js +48 -0
- package/src/motion/ik.js +4 -11
- package/src/motion/timeline.css +12 -0
- package/src/motion/timeline.jsx +2 -2
- package/src/motion3/compile-job.js +3 -2
- package/src/motion3/compiler/compile.js +3 -3
- package/src/motion3/compiler/head-lead.js +4 -2
- package/src/motion3/compiler/spring.js +95 -0
- package/src/motion3/compiler/validate-objects.js +18 -2
- package/src/motion3/compiler/validate-parts.js +1 -0
- package/src/motion3/compiler/vocab.js +1 -1
- package/src/motion3/fix/index.js +8 -4
- package/src/motion3/fix/person.js +110 -0
- package/src/motion3/free-motion.js +49 -11
- package/src/motion3/hybrid-hint.js +19 -0
- package/src/motion3/load.js +19 -12
- package/src/motion3/object-pose.js +44 -2
- package/src/motion3/people.js +16 -1
- package/src/motion3/physics-frames.js +72 -0
- package/src/motion3/physics-trail.js +45 -0
- package/src/motion3/physics-view.js +79 -0
- package/src/motion3/pipeline.js +5 -1
- package/src/motion3/qa/ballistic.js +67 -0
- package/src/motion3/qa/com.js +140 -0
- package/src/motion3/qa/ground.js +10 -3
- package/src/motion3/qa/hints-contact.js +21 -7
- package/src/motion3/qa/hints-motion.js +38 -1
- package/src/motion3/qa/key-checks.js +5 -4
- package/src/motion3/qa/patch.js +32 -4
- package/src/motion3/qa/people-checks.js +1 -1
- package/src/motion3/qa/spring-pivot.js +23 -0
- package/src/motion3/qa/style.js +13 -30
- package/src/motion3/qa/verdict.js +7 -2
- package/src/motion3/repair.js +28 -8
- package/src/motion3/schema/fields.js +4 -2
- package/src/motion3/schema/topics.js +15 -11
- package/src/motion3/schema/types.js +13 -9
- package/src/motion3/skills/catch.js +2 -1
- package/src/panels/FingerPanel.jsx +38 -0
- package/src/panels/RigControlPanel.jsx +9 -1
- package/src/panels/SculptPanel.jsx +12 -12
- package/src/panels/SculptPartTree.jsx +46 -0
- package/src/panels/SubjectsPanel.jsx +1 -1
- package/src/panels/sculpt.css +11 -0
- package/src/physics-overlay-settings.js +41 -0
- package/src/physics-overlay.js +152 -0
- package/src/physics-overlay.jsx +54 -0
- package/src/physics-toggle.jsx +20 -0
- package/src/pose-fade.js +7 -3
- package/src/posestudio.jsx +15 -28
- package/src/project-browser.css +6 -0
- package/src/project-browser.jsx +9 -18
- package/src/project-start-choices.jsx +45 -0
- package/src/project.js +16 -12
- package/src/proxy-figure-shape.js +11 -0
- package/src/proxy-figure.jsx +25 -18
- package/src/scene-assets.js +17 -13
- package/src/scenes.js +22 -11
- package/src/sculpt-blueprint.js +56 -0
- package/src/sculpt-mode.js +5 -0
- package/src/sculpt-part-edit.js +115 -0
- package/src/sculpt-part-gizmo.jsx +159 -0
- package/src/sculpt-part-outline.jsx +72 -0
- package/src/sculpt-pick.js +53 -0
- package/src/sculpt-run-text.js +51 -0
- package/src/sculpt-run.js +10 -46
- package/src/sculpt-shelf-file.js +92 -0
- package/src/sculpt-shelf-tiles.jsx +69 -0
- package/src/sculpt-shelf.js +108 -0
- package/src/sculpt-stage.jsx +39 -2
- package/src/sculpt-thumb.js +72 -0
- package/src/sculpt-views.js +75 -0
- package/src/semantic-edit.js +0 -87
- package/src/settings-menu.jsx +2 -2
- package/src/shell/DetailsSlot.jsx +5 -6
- package/src/shell/LibrarySlot.jsx +8 -10
- package/src/shell/MenuBar.jsx +6 -6
- package/src/shell/PreferencesDialog.jsx +2 -3
- package/src/shell/ViewportToolbar.jsx +15 -18
- package/src/shell/add-character-entries.js +13 -0
- package/src/shell/pose-controls.js +32 -0
- package/src/shell/preference-pages.jsx +2 -11
- package/src/shell/storyboard-caption.js +21 -0
- package/src/shell/studio-shell-context.js +1 -0
- package/src/shortcut-friction.js +2 -1
- package/src/site/landing-analytics.js +28 -0
- package/src/studio-actions.js +3 -2
- package/src/studio-agent-protocol.js +4 -4
- package/src/studio-app-binding.js +4 -3
- package/src/update/UpdateChip.jsx +21 -2
- package/src/update/UpdateDialog.jsx +26 -6
- package/src/update/update-client.js +123 -17
- package/src/update/update-telemetry.js +15 -3
- package/src/use-sculpt-mode.js +62 -8
- package/src/workflow/agent-failure-codes.js +28 -9
- package/src/workflow/agent-turn-telemetry.js +1 -1
- package/src/workflow/task-board.js +2 -2
- package/tools/dev/page-shell.py +1 -1
- package/tools/dev/pages/greybox-to-video.html +21 -2
- package/tools/dev/pages/previs-software.html +3 -3
- package/tools/dev/pages/privacy.html +9 -6
- package/tools/dev/pages/seedance-camera-control.html +2 -2
- package/tools/loc-baseline.json +10 -10
- package/tools/run-tests.mjs +53 -84
- package/tools/select-tests.mjs +119 -0
- package/tools/test-durations.json +455 -0
- package/tools/test-graph.mjs +181 -0
- package/tools/test-shards.mjs +78 -0
- package/tools/tutorial/README.md +74 -0
- package/tools/tutorial/assemble.mjs +43 -0
- package/tools/tutorial/captions.mjs +43 -0
- package/tools/tutorial/cdp.mjs +55 -0
- package/tools/tutorial/cursor.mjs +159 -0
- package/tools/tutorial/episode.mjs +173 -0
- package/tools/tutorial/episodes/beginner-guide/00-install.mjs +42 -0
- package/tools/tutorial/episodes/beginner-guide/01-start.mjs +50 -0
- package/tools/tutorial/episodes/beginner-guide/02-layout.mjs +67 -0
- package/tools/tutorial/episodes/beginner-guide/03-stage.mjs +58 -0
- package/tools/tutorial/episodes/beginner-guide/04-motion.mjs +98 -0
- package/tools/tutorial/episodes/beginner-guide/05-camera.mjs +47 -0
- package/tools/tutorial/episodes/beginner-guide/06-export.mjs +59 -0
- package/tools/tutorial/episodes/beginner-guide/steps.mjs +32 -0
- package/tools/tutorial/episodes/beginner-guide.mjs +17 -0
- package/tools/tutorial/episodes/cast.mjs +12 -0
- package/tools/tutorial/episodes/first-video.mjs +121 -0
- package/tools/tutorial/episodes/stub-tour.mjs +97 -0
- package/tools/tutorial/launch.mjs +63 -0
- package/tools/tutorial/mux.mjs +61 -0
- package/tools/tutorial/overlay.mjs +142 -0
- package/tools/tutorial/record.mjs +156 -0
- package/tools/tutorial/scenes/terminal.html +63 -0
- package/tools/tutorial/steps.mjs +111 -0
- package/tools/tutorial/terminal.mjs +43 -0
- package/tools/tutorial/voice.mjs +49 -0
- package/tools/update-test-durations.mjs +42 -0
- package/tools/verify-package-tarball.mjs +18 -12
- package/dist/assets/TaskBoard-DwXhsJXz.js +0 -1
- package/dist/assets/app-BLS1Zaru.js +0 -5144
- package/dist/assets/compile-worker-or7djI2v.js +0 -6
- package/dist/assets/motion3-compile-Du7UXrWn.js +0 -1
- package/dist/assets/rolldown-runtime-hePW80VL.js +0 -1
- package/dist/assets/scene-asset-sync-t45pWCyq.js +0 -13
- package/dist/assets/task-board-CkLZGPkv.js +0 -15
- package/dist/assets/workflow-DJwOUzqJ.js +0 -179
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The supervised restart behind POST /__cozyclay/update/restart (#960).
|
|
3
|
+
*
|
|
4
|
+
* After a one-click install the running launcher still holds the old code.
|
|
5
|
+
* restart() closes the HTTP server (closeAllConnections first, so an open SSE
|
|
6
|
+
* stream cannot hold close() forever) and the live hub, then runs the new
|
|
7
|
+
* global bin/cozyclay.mjs as a child on the same port with the same argv and
|
|
8
|
+
* env and inherited stdio. This process stays the terminal's foreground job
|
|
9
|
+
* and exits with the child's exit code. A child that has not bound the port
|
|
10
|
+
* within 10 s gets the fallback line and exit 1.
|
|
11
|
+
*
|
|
12
|
+
* Everything with an effect is injected, so a test runs it without exiting.
|
|
13
|
+
*/
|
|
14
|
+
import { spawn as nodeSpawn } from "node:child_process";
|
|
15
|
+
import { connect } from "node:net";
|
|
16
|
+
import { globalLauncherPath } from "./update-install.mjs";
|
|
17
|
+
|
|
18
|
+
const BIND_TIMEOUT_MS = 10_000;
|
|
19
|
+
const HUB_CLOSE_MS = 3000;
|
|
20
|
+
const PROBE_MS = 150;
|
|
21
|
+
export const RESTART_FALLBACK = "cozyclay: the updated CozyClay did not start. Quit any CozyClay still running, then run `cclay` again.";
|
|
22
|
+
|
|
23
|
+
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
24
|
+
|
|
25
|
+
/** Stop accepting, drop every open connection (SSE included), resolve once the server has closed. */
|
|
26
|
+
export function closeServer(server) {
|
|
27
|
+
if (!server?.listening) return Promise.resolve();
|
|
28
|
+
server.closeAllConnections?.();
|
|
29
|
+
return new Promise((resolve) => server.close(() => resolve()));
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function portOpen(port) {
|
|
33
|
+
return new Promise((resolve) => {
|
|
34
|
+
const socket = connect({ port, host: "127.0.0.1" });
|
|
35
|
+
socket.once("connect", () => { socket.destroy(); resolve(true); });
|
|
36
|
+
socket.once("error", () => resolve(false));
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
async function waitForBind(port, timeoutMs, gone) {
|
|
41
|
+
const deadline = Date.now() + timeoutMs;
|
|
42
|
+
while (Date.now() < deadline && !gone()) {
|
|
43
|
+
if (await portOpen(port)) return true;
|
|
44
|
+
await sleep(PROBE_MS);
|
|
45
|
+
}
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* @param {object} options
|
|
51
|
+
* @param {number} options.port the launcher's port, which the child binds again
|
|
52
|
+
* @param {() => import("node:http").Server|null} options.getServer
|
|
53
|
+
* @param {() => Promise<void>} [options.closeHub] closes the live hub (the agent handler's close)
|
|
54
|
+
* @returns {{ target(): Promise<string|null>, restart(): Promise<void> }}
|
|
55
|
+
*/
|
|
56
|
+
export function createRestarter({
|
|
57
|
+
port, getServer, closeHub = async () => {}, launcherPath = globalLauncherPath, argv = process.argv.slice(2), env = process.env,
|
|
58
|
+
spawn = nodeSpawn, exit = (code) => process.exit(code), log = (line) => console.error(line), signals = process, bindTimeoutMs = BIND_TIMEOUT_MS,
|
|
59
|
+
}) {
|
|
60
|
+
let target = null;
|
|
61
|
+
let running = null;
|
|
62
|
+
const resolveTarget = () => (target ??= Promise.resolve().then(launcherPath).catch(() => null));
|
|
63
|
+
async function run() {
|
|
64
|
+
const bin = await resolveTarget();
|
|
65
|
+
if (!bin) { log(RESTART_FALLBACK); return; }
|
|
66
|
+
await closeServer(getServer());
|
|
67
|
+
await Promise.race([Promise.resolve().then(closeHub).catch(() => {}), sleep(HUB_CLOSE_MS)]);
|
|
68
|
+
// The Studio tab reloads itself; a second browser tab would be noise.
|
|
69
|
+
const args = argv.includes("--no-open") ? argv : [...argv, "--no-open"];
|
|
70
|
+
const child = spawn(process.execPath, [bin, ...args], { stdio: "inherit", env });
|
|
71
|
+
let exited = false, bound = false;
|
|
72
|
+
// The child owns Ctrl+C and the goodbye prompt now; this process only passes signals on.
|
|
73
|
+
for (const name of ["SIGINT", "SIGTERM"]) {
|
|
74
|
+
signals.removeAllListeners(name);
|
|
75
|
+
signals.on(name, () => { try { child.kill(name); } catch { /* already gone */ } });
|
|
76
|
+
}
|
|
77
|
+
child.once("error", () => { if (!exited) { exited = true; log(RESTART_FALLBACK); exit(1); } });
|
|
78
|
+
child.once("exit", (code) => {
|
|
79
|
+
if (exited) return;
|
|
80
|
+
exited = true;
|
|
81
|
+
if (!bound && code !== 0) log(RESTART_FALLBACK);
|
|
82
|
+
exit(code ?? 1);
|
|
83
|
+
});
|
|
84
|
+
bound = await waitForBind(port, bindTimeoutMs, () => exited);
|
|
85
|
+
if (bound || exited) return;
|
|
86
|
+
exited = true;
|
|
87
|
+
log(RESTART_FALLBACK);
|
|
88
|
+
try { child.kill("SIGTERM"); } catch { /* already gone */ }
|
|
89
|
+
exit(1);
|
|
90
|
+
}
|
|
91
|
+
return {
|
|
92
|
+
target: resolveTarget,
|
|
93
|
+
restart: () => (running ??= run()),
|
|
94
|
+
};
|
|
95
|
+
}
|
package/bin/update-routes.mjs
CHANGED
|
@@ -5,6 +5,10 @@
|
|
|
5
5
|
*
|
|
6
6
|
* POST reads no body. The version it installs is the registry's latest after
|
|
7
7
|
* an exact x.y.z test, never anything the request says.
|
|
8
|
+
*
|
|
9
|
+
* POST /__cozyclay/update/restart (#960) hands the launcher to the version a
|
|
10
|
+
* finished install put in place (bin/update-restart.mjs). Same Origin rule,
|
|
11
|
+
* no body, 409 unless the install state is restart_needed.
|
|
8
12
|
*/
|
|
9
13
|
const VERSION = /^\d+\.\d+\.\d+$/;
|
|
10
14
|
const NOTES_URL = "https://github.com/NomaDamas/CozyClay/releases/tag/v";
|
|
@@ -23,21 +27,22 @@ function sendJson(res, status, body, headers = {}) {
|
|
|
23
27
|
* @param {number} options.port the launcher's loopback port
|
|
24
28
|
* @param {() => Promise<boolean>} options.canSelfUpdate
|
|
25
29
|
* @param {{startInstall(version: string): boolean, getState(): object}} options.installer
|
|
30
|
+
* @param {{target(): Promise<string|null>, restart(): Promise<void>}} [options.restarter] absent: restart answers 409
|
|
26
31
|
*/
|
|
27
|
-
export function createUpdateRoutes({ currentVersion, checkLatest, kind, enabled, port, canSelfUpdate, installer }) {
|
|
32
|
+
export function createUpdateRoutes({ currentVersion, checkLatest, kind, enabled, port, canSelfUpdate, installer, restarter = null }) {
|
|
28
33
|
const command = kind === "npx" ? "npx cozyclay" : "npm install -g cozyclay@latest";
|
|
29
34
|
const hosts = new Set([`127.0.0.1:${port}`, `localhost:${port}`]);
|
|
30
35
|
// Spelled in two parts so the G014 loopback invariant does not read it as a client URL.
|
|
31
36
|
const origins = new Set([`http://127.0.0.1:${port}`, `http://${"local" + "host"}:${port}`]);
|
|
32
37
|
|
|
33
38
|
async function info() {
|
|
34
|
-
const base = { enabled, current: currentVersion, latest: null, status: "unknown", kind, canSelfUpdate: false, phase: "idle", errorClass: null, durationMs: null, notesUrl: null, command };
|
|
39
|
+
const base = { enabled, current: currentVersion, latest: null, status: "unknown", kind, canSelfUpdate: false, phase: "idle", errorClass: null, durationMs: null, installed: null, notesUrl: null, command };
|
|
35
40
|
if (!enabled) return base;
|
|
36
41
|
const [{ latest, status }, selfUpdate] = await Promise.all([
|
|
37
42
|
checkLatest().catch(() => ({ latest: null, status: "unknown" })),
|
|
38
43
|
kind === "global" ? canSelfUpdate().catch(() => false) : false,
|
|
39
44
|
]);
|
|
40
|
-
const { phase, errorClass, durationMs } = installer.getState();
|
|
45
|
+
const { phase, errorClass, durationMs, version: installing } = installer.getState();
|
|
41
46
|
const finished = phase === "restart_needed" || phase === "failed";
|
|
42
47
|
return {
|
|
43
48
|
...base,
|
|
@@ -47,6 +52,8 @@ export function createUpdateRoutes({ currentVersion, checkLatest, kind, enabled,
|
|
|
47
52
|
phase,
|
|
48
53
|
errorClass: phase === "failed" ? errorClass : null,
|
|
49
54
|
durationMs: finished ? durationMs : null,
|
|
55
|
+
// The version npm installs or installed: the restart target, even if the registry moves on meanwhile.
|
|
56
|
+
installed: phase === "updating" || phase === "restart_needed" ? installing : null,
|
|
50
57
|
notesUrl: latest ? `${NOTES_URL}${latest}` : null,
|
|
51
58
|
};
|
|
52
59
|
}
|
|
@@ -64,8 +71,23 @@ export function createUpdateRoutes({ currentVersion, checkLatest, kind, enabled,
|
|
|
64
71
|
return sendJson(res, 202, await info());
|
|
65
72
|
}
|
|
66
73
|
|
|
74
|
+
let restarting = false;
|
|
75
|
+
async function handleRestart(req, res) {
|
|
76
|
+
if (req.method !== "POST") return sendJson(res, 405, { error: "method not allowed" }, { allow: "POST" });
|
|
77
|
+
if (req.headers.origin !== `http://127.0.0.1:${port}`) return sendJson(res, 403, { error: "forbidden origin" });
|
|
78
|
+
if (restarting) return sendJson(res, 202, await info());
|
|
79
|
+
if (!enabled || installer.getState().phase !== "restart_needed" || !restarter || !(await restarter.target())) {
|
|
80
|
+
return sendJson(res, 409, { error: "restart unavailable" });
|
|
81
|
+
}
|
|
82
|
+
restarting = true;
|
|
83
|
+
// The answer has to leave before the server drops every connection.
|
|
84
|
+
res.once("finish", () => setTimeout(() => void restarter.restart(), 50));
|
|
85
|
+
return sendJson(res, 202, await info());
|
|
86
|
+
}
|
|
87
|
+
|
|
67
88
|
return async function handleUpdateRoute(req, res) {
|
|
68
89
|
try {
|
|
90
|
+
if (req.url?.split("?")[0] === "/__cozyclay/update/restart") return await handleRestart(req, res);
|
|
69
91
|
if (req.method === "GET") {
|
|
70
92
|
const origin = req.headers.origin;
|
|
71
93
|
if (!(origins.has(origin) || (origin === undefined && hosts.has(req.headers.host)))) return sendJson(res, 403, { error: "forbidden origin" });
|
package/dist/app/index.html
CHANGED
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
<!doctype html>
|
|
2
|
-
<html lang="en">
|
|
2
|
+
<html lang="en" translate="no">
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="UTF-8" />
|
|
5
|
+
<!-- The studio ships its own en / ko / zh UI. Browser page translation
|
|
6
|
+
swaps React-owned text nodes and crashes the tree with NotFoundError
|
|
7
|
+
(#972), so it is turned off here only; the landing and SEO pages stay
|
|
8
|
+
translatable. -->
|
|
9
|
+
<meta name="google" content="notranslate" />
|
|
5
10
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
|
|
6
11
|
<meta name="description" content="CozyClay studio: block a 3D scene, pose characters, author camera moves, and preview generated motion in your browser." />
|
|
7
12
|
<meta name="theme-color" content="#232323" />
|
|
@@ -34,14 +39,15 @@
|
|
|
34
39
|
<title>CozyClay Studio — 3D staging and previs in your browser</title>
|
|
35
40
|
|
|
36
41
|
<script defer src="https://static.cloudflareinsights.com/beacon.min.js" data-cf-beacon='{"token": "6a4384d1375d4ffc8a30a6346a8ad1a0"}'></script>
|
|
37
|
-
<script type="module" crossorigin src="/assets/app-
|
|
38
|
-
<link rel="modulepreload" crossorigin href="/assets/
|
|
39
|
-
<link rel="modulepreload" crossorigin href="/assets/task-board-
|
|
42
|
+
<script type="module" crossorigin src="/assets/app-DJt06Oyb.js"></script>
|
|
43
|
+
<link rel="modulepreload" crossorigin href="/assets/analytics-CaTUuLPM.js">
|
|
44
|
+
<link rel="modulepreload" crossorigin href="/assets/task-board-UVGTZLRF.js">
|
|
45
|
+
<link rel="modulepreload" crossorigin href="/assets/modulepreload-polyfill-P2Xu9kJm.js">
|
|
40
46
|
<link rel="modulepreload" crossorigin href="/assets/fflate.module-KbGj5-H6.js">
|
|
41
|
-
<link rel="modulepreload" crossorigin href="/assets/scene-asset-sync-
|
|
42
|
-
<link rel="modulepreload" crossorigin href="/assets/motion3-compile-
|
|
47
|
+
<link rel="modulepreload" crossorigin href="/assets/scene-asset-sync-CLGNbEBq.js">
|
|
48
|
+
<link rel="modulepreload" crossorigin href="/assets/motion3-compile-BxaM0Xwl.js">
|
|
43
49
|
<link rel="stylesheet" crossorigin href="/assets/scene-asset-sync-BEjjhNEo.css">
|
|
44
|
-
<link rel="stylesheet" crossorigin href="/assets/app-
|
|
50
|
+
<link rel="stylesheet" crossorigin href="/assets/app-CnDkB5WO.css">
|
|
45
51
|
</head>
|
|
46
52
|
<body>
|
|
47
53
|
<div id="root">
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{$r as e,c as t,d as n,f as r,l as i,la as a,m as o,o as s,oa as c,v as l}from"./task-board-UVGTZLRF.js";import{o as u,r as d,t as f}from"./motion3-compile-BxaM0Xwl.js";var p=a(c(),1),m=2e3,h=(e,t)=>new Promise(n=>{let r=setTimeout(n,e);t.addEventListener(`abort`,()=>{clearTimeout(r),n()},{once:!0})});function g(t,n){(0,p.useEffect)(()=>{let r=new Map;for(let[e,i]of Object.entries(t))for(let t of i)r.set(t,n[e]??e);let i=()=>{for(let t of document.querySelectorAll(`[data-node-id]`)){let n=r.get(t.getAttribute(`data-node-id`));n?(t.setAttribute(`data-task-scope`,n),t.setAttribute(`title`,e(`In task: ${n}`,`작업 중: ${n}`,`任务中:${n}`))):t.hasAttribute(`data-task-scope`)&&(t.removeAttribute(`data-task-scope`),t.removeAttribute(`title`))}};i();let a=new MutationObserver(i);return a.observe(document.body,{childList:!0,subtree:!0}),()=>{a.disconnect(),r.clear(),i()}},[t,n])}function _({sessionId:e,pulse:a,labelOf:c,onMainNote:_}){let v=(0,p.useMemo)(()=>s(),[]),y=u(),[b,x]=(0,p.useReducer)((e,r)=>r.seed?o(e,r.seed):r.reset?t():n(e,r.event),void 0,t),[S,C]=(0,p.useState)({}),[w,T]=(0,p.useState)(f),E=(0,p.useRef)(0),D=(0,p.useRef)(_);(0,p.useEffect)(()=>{E.current=b.after,D.current=_},[b.after,_]),(0,p.useEffect)(()=>{x({reset:!0}),E.current=0},[e]),(0,p.useEffect)(()=>d(T),[]),(0,p.useEffect)(()=>y.subscribe(e=>{typeof e?.type!=`string`||!e.type.startsWith(`task.`)||(C(t=>r(t,e)),(e.type===`task.userEdit`||e.type===`task.undone`)&&x({event:e}))}),[y]),(0,p.useEffect)(()=>{if(!e)return;let t=new AbortController;return(async()=>{for(;!t.signal.aborted;){try{let{tasks:n}=await v.board(e);x({seed:n}),await v.events(e,E.current,e=>{if(e.type===`main.turn`&&e.turnId){let n=``;v.frames(e.turnId,e=>{e.type===`text.delta`&&(n+=e.text??``),e.type===`tool.start`&&(n=``)},t.signal).then(()=>D.current?.(n),()=>{})}x({event:e})},t.signal)}catch{}await h(m,t.signal)}})(),()=>t.abort()},[v,e,a]);let O=b.order.filter(e=>b.tasks[e]?.status===`running`&&b.tasks[e]?.turnId),k=O.map(e=>`${e}:${b.tasks[e].turnId}`).join();return(0,p.useEffect)(()=>{let e=O.map(e=>{let t=new AbortController,{turnId:n}=b.tasks[e];return v.frames(n,t=>{let n=i(t,c);n&&x({event:{type:`task.progress`,taskId:e,status:`running`,progress:n}})},t.signal).catch(()=>{}),t});return()=>e.forEach(e=>e.abort())},[v,k,c]),g(S,(0,p.useMemo)(()=>Object.fromEntries(b.order.map(e=>[e,b.tasks[e].title])),[b])),(0,p.useEffect)(()=>{l.set({client:v,labelOf:c,undo:async e=>{let t=await y.run(`task.undo`,{taskId:e});if(t?.ok===!1)throw Error(t.message??t.code);x({event:{type:`task.undone`,taskId:e}})}})},[y,v,c]),(0,p.useEffect)(()=>{l.set({board:b,activity:w})},[b,w]),(0,p.useEffect)(()=>()=>l.set({board:t(),open:null}),[e]),null}export{_ as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var e={name:`cozyclay`,version:`3.2.1`,description:`Open source previs software in the browser: block a scene, pose characters, author camera moves and cuts, then take the same shots to an AI video model.`,scripts:{dev:`node tools/dev-full.mjs --host 127.0.0.1 --port 5180`,"dev:ui":`vite`,build:`vite build && node tools/sitemap.mjs`,lint:`node tools/check-knip.mjs && node tools/check-loc.mjs && node tools/check-eslint.mjs`,"lint:update":`node tools/check-knip.mjs --update && node tools/check-loc.mjs --update && node tools/check-eslint.mjs --update`,test:`npm run build && node tools/run-tests.mjs`,"test:manifest":`node tools/run-tests.mjs --list`,"test:analytics":`node test/verify-analytics.mjs`,"test:lifecycle":`npm run build && node test/process/verify-lifecycle.mjs`,"test:mcp-package":`node test/process/verify-mcp-package-isolation.mjs`,"test:hierarchy":`node test/verify-hierarchy.mjs`,"test:history":`node test/verify-history.mjs`,"test:scene-objects":`node test/verify-scene-objects.mjs`,"test:scene-assets":`node test/verify-scene-assets.mjs`,"test:scene-mesh":`node test/verify-scene-mesh.mjs`,"test:mesh-browser":`node tools/qa-browser.mjs -- node test/verify-mesh-browser.mjs`,"test:asset-shelf":`node test/verify-asset-shelf.mjs`,"test:matte":`node test/verify-matte.mjs`,"test:matte-editor":`node test/verify-matte-editor.mjs`,"test:scenes":`node test/verify-scenes.mjs`,"test:camera-move":`node test/verify-camera-move.mjs`,"test:cuts":`node test/verify-cuts.mjs`,"test:project-menu":`node tools/qa-browser.mjs -- node test/verify-project-menu-browser.mjs`,"test:first-success-guide":`QA_STARTUP_CHOOSER=1 node tools/qa-browser.mjs -- node test/verify-first-success-guide-browser.mjs`,"test:objects":`node tools/qa-browser.mjs -- node test/verify-object-gizmo.mjs`,"test:theme":`node test/verify-theme.mjs`,"test:appearance":`node test/verify-appearance.mjs`,"test:auto-color":`node test/verify-auto-color.mjs`,"test:shot-guides":`node test/verify-shot-guides.mjs`,"test:layout":`node test/verify-layout.mjs`,"test:timeline-camera":`node test/verify-timeline-camera.mjs`,"test:timeline-shots":`node test/verify-timeline-shots.mjs`,preview:`vite preview`,"test:ardy":`node tools/run-tests.mjs --scope ardy`,"test:ik-browser":`node tools/qa-browser.mjs -- node test/verify-ik-browser.mjs`,"demo:api":`npm --prefix workers/api run dev`,"demo:api:install":`npm --prefix workers/api ci`,"qa:browser":`node tools/qa-browser.mjs --`,"tutorial:record":`node tools/tutorial/launch.mjs`,"test:shot-authoring":`node test/verify-shot-authoring.mjs`,"test:camera-follow":`node test/verify-camera-follow.mjs`,"test:sample-at":`node test/verify-sample-at.mjs`,"test:offscreen-export":`node test/verify-offscreen-export.mjs`,"test:offscreen-export-browser":`node tools/qa-browser.mjs -- node test/verify-offscreen-export-browser.mjs`,"test:otio":`node test/verify-otio.mjs`,"test:usd-camera":`node test/verify-usd-camera.mjs`,"test:camera-rail-browser":`node tools/qa-browser.mjs -- node test/verify-camera-rail-browser.mjs`,"test:blocking-depth":`node test/verify-blocking-depth.mjs`,"test:pwa":`node test/verify-pwa.mjs`,"test:update-check":`node test/verify-update-check.mjs`,"test:korean-ui":`node test/verify-korean-ui.mjs`,prepack:`npm run build && node tools/prepare-package.mjs`,postpack:`node tools/prepare-package.mjs --clean`,prepublishOnly:`npm run build && node tools/prepare-package.mjs --check-key && node tools/prepare-package.mjs && node tools/verify-package-tarball.mjs`,"metrics:snapshot":`node tools/metrics-snapshot.mjs`},license:`AGPL-3.0-or-later`,type:`module`,dependencies:{"@anthropic-ai/claude-agent-sdk":`^0.3.306`,"@earendil-works/pi-agent-core":`1.4.0`,"@earendil-works/pi-ai":`1.4.0`,"@earendil-works/pi-codemode":`1.4.0`,zod:`^4.6.7`},devDependencies:{"@eslint/js":`^10.0.1`,"@react-three/drei":`^10.7.7`,"@react-three/fiber":`^9.7.0`,"@vitejs/plugin-react":`^6.0.5`,eslint:`^10.12.0`,"eslint-plugin-react-hooks":`^7.1.1`,globals:`^17.13.0`,"jpeg-js":`0.4.4`,knip:`^6.41.0`,mediabunny:`^1.55.2`,"posthog-js":`^1.418.12`,react:`^19.2.8`,"react-dom":`^19.2.8`,"react-hot-toast":`^2.6.0`,"react-icons":`^5.7.0`,reactflow:`^11.11.4`,three:`^0.185.1`,"three-bvh-csg":`^0.0.18`,"three-mesh-bvh":`^0.9.16`,vite:`^8.2.0`},bin:{cozyclay:`bin/cozyclay.mjs`,cclay:`bin/cozyclay.mjs`},files:[`bin`,`dist`,`!dist/media/*.mp4`,`src`,`tools`,`!tools/qa-*.mjs`,`mcp/server.mjs`,`mcp/tool-handlers.mjs`,`mcp/live-hub.mjs`,`mcp/mesh-file.mjs`,`mcp/image-file.mjs`,`mcp/project-camera.mjs`,`mcp/runtime`,`mcp/package.json`,`mcp/README.md`,`mcp/LIVE-PROTOCOL.md`,`README.md`,`INSTALL_FOR_AGENTS.md`,`CHANGELOG.md`,`LICENSE`,`LICENSES`,`LICENSING.md`,`THIRD_PARTY_NOTICES.md`],exports:{"./package.json":`./package.json`,"./src/*":`./src/*`,"./mcp/*":`./mcp/*`},peerDependencies:{three:`>=0.180`},peerDependenciesMeta:{three:{optional:!0}},engines:{node:`>=22.19.0`},keywords:[`3d`,`previs`,`animation`,`blocking`,`threejs`,`react-three-fiber`,`webgl`,`motion`,`ardy`,`storyboard`,`previz`],repository:{type:`git`,url:`git+https://github.com/NomaDamas/CozyClay.git`},homepage:`https://cozyclay.org/`,bugs:{url:`https://github.com/NomaDamas/CozyClay/issues`},publishConfig:{access:`public`}};function t(t=globalThis.window,n=e.version){try{let e=t?.__COZYCLAY_RUNTIME__?.appVersion;if(typeof e==`string`&&e.trim())return e.trim()}catch{}return n}var n=Object.freeze([`pose_edit`,`object_insert`,`cutout_insert`,`object_transform`,`shot_add`,`shot_edit`,`camera_key_record`,`rail_edit`,`prompt_block_add`,`prompt_block_edit`]);function r(e){let t=new Set,r=(r,i)=>![`craft`,`playground`].includes(r)||t.has(r)||!n.includes(i)?!1:(t.add(r),e(`${r}:first_edit`,{edit_kind:i,definition_version:2}),!0);return r.seen=e=>t.has(e),r}var i=new Set([`unsupported_codec`,`encode_failed`,`render_failed`,`aborted`,`unknown`]),a=new Set([`0`,`1-3`,`4-10`,`gte11`]),o=Object.freeze({export_kind:new Set([`video`,`depth_video`,`frame`,`keyframe_pack`,`workflow_send`,`animation_project`,`contact_sheet`,`panel_pack`,`animatic`,`storyboard`,`render_pass`,`otio`]),format:new Set([`mp4`,`png`,`zip`,`cclayproject`,`otio`]),surface:new Set([`studio`,`workflow`,`embed`]),duration_bucket:new Set([`lt1s`,`1-3s`,`3-10s`,`10-30s`,`gte30s`]),failure_code:i,objects:a,stage:new Set([`preparing`,`encoding`,`finalizing`,`handoff`]),progress:new Set([`0`,`1-25`,`26-50`,`51-75`,`76-99`]),method:new Set([`workspace`,`download`]),reason:new Set([`none`,`unsupported`,`no_workspace`,`permission`,`write_failed`])}),s=/^[a-f0-9]{32}$/;function c(e,t){return e===`attempt_id`||e===`retry_of`?typeof t==`string`&&s.test(t):e===`is_retry`?typeof t==`boolean`:o[e]?.has(t)??!1}var ee=new Set([`Error`,`TypeError`,`RangeError`,`ReferenceError`,`SyntaxError`,`EvalError`,`URIError`,`AggregateError`,`AbortError`,`TimeoutError`,`NotAllowedError`,`NotSupportedError`,`NotFoundError`,`NotReadableError`,`InvalidStateError`,`QuotaExceededError`,`SecurityError`,`NetworkError`,`DataCloneError`,`OperationError`,`EncodingError`,`UnknownError`,`DOMException`,`non_error`,`other`]),te=new Set([`lt1m`,`1-5m`,`5-15m`,`15-30m`,`gte30m`]),ne=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,re=20;function ie(e,t){return e===`duration_bucket`?te.has(t):e===`scenes_touched`?Number.isInteger(t)&&t>=0&&t<=re:e===`session_id`?typeof t==`string`&&ne.test(t):e.endsWith(`_bucket`)&&a.has(t)}var ae=Object.freeze([`refusals_ui`,`refusals_agent`,`undos`,`errors`,`rage_clicks`,`dead_clicks`,`shortcut_ignored`,`search_empty`,`nav_thrash`,`camera_thrash`,`long_tasks`,`compiles`]),oe=Object.freeze([`active_time`,...ae,`long_task_max`,`late_tick_ratio`]),se=new Set([`0`,`1`,`2`,`3`,`4-5`,`6-10`,`gte11`]),ce=new Set([`lt50`,`50-150`,`150-500`,`500-2000`,`gte2000`]),le=new Set([`0`,`lt5`,`5-20`,`20-50`,`gte50`]),l=new Map(ae.map(e=>[e,0])),u=new Map,d=0,ue=0,f=0,p=!1;function de(e){let t=Number.isFinite(e)?Math.max(0,Math.floor(e)):0;return t<=3?String(t):t<=5?`4-5`:t<=10?`6-10`:`gte11`}function fe(e){return e>=50?e<150?`50-150`:e<500?`150-500`:e<2e3?`500-2000`:`gte2000`:`lt50`}function pe(e,t){if(!(t>0)||!(e>0))return`0`;let n=e/t*100;return n<5?`lt5`:n<20?`5-20`:n<50?`20-50`:`gte50`}function m(e,t=1){return!l.has(e)||!Number.isFinite(t)||t<1?!1:(l.set(e,l.get(e)+Math.floor(t)),!0)}function me(e,t){let n=u.get(e)??0;return n<t&&(u.set(e,n+1),!0)}function he(e){!Number.isFinite(e)||e<0||(m(`long_tasks`),d=Math.max(d,e))}function ge(e,t){!Number.isInteger(e)||!Number.isInteger(t)||e<0||t<e||(ue+=e,f+=t)}function _e(e=globalThis.PerformanceObserver){if(p)return!0;try{return typeof e!=`function`||!e.supportedEntryTypes?.includes(`longtask`)?!1:(new e(e=>{for(let t of e.getEntries())he(t.duration)}).observe({type:`longtask`}),p=!0,!0)}catch{return!1}}function ve(){return{...Object.fromEntries([...l].map(([e,t])=>[e,de(t)])),long_task_max:fe(d),late_tick_ratio:pe(ue,f)}}function ye(e,t){return e===`active_time`?te.has(t):e===`long_task_max`?ce.has(t):e===`late_tick_ratio`?le.has(t):l.has(e)&&se.has(t)}var h=Object.freeze(`INVALID_ARGUMENT.INVALID_CONTEXT.INVALID_IDENTITY.INVALID_TURN_ID.INVALID_SESSION_ID.INVALID_RECEIPT.INVALID_RANGE.INVALID_REQUEST.UNKNOWN_TOOL.UNKNOWN_VARIANT.DUPLICATE_NAME.CONTEXT_LIMIT.CONTEXT_TOO_LARGE.AMBIGUOUS_TARGET.AMBIGUOUS_BASIS.TARGET_NOT_READY.TARGET_BUSY.STALE_TARGET.STALE_SCENE.STALE_ENVIRONMENT.STALE_CURSOR.CAPABILITY_MISSING.LIVE_HUB_UNAVAILABLE.AUTH_REQUIRED.GENERATION_LIMIT.RATE_LIMITED.BACKEND_UNAVAILABLE.VERIFICATION_FAILED.REPAIR_REGRESSED.CANCELLED.UNCERTAIN_APPLY.UNDO_CONFLICT.CONFIRMATION_REQUIRED.TIMEOUT.UNDO_EXPIRED.INTERNAL_ERROR.SCOPE_DENIED.SCOPE_BUSY`.split(`.`)),be=e=>e?.code??([`TypeError`,`ReferenceError`,`RangeError`,`SyntaxError`].includes(e?.name)?`INTERNAL_ERROR`:`INVALID_ARGUMENT`),g=Object.freeze(`dock_tab_board.dock_tab_animation.dock_tab_assets.mode_scene.mode_pose.mode_camera.mode_motion.mode_sculpt.tool_move.tool_rotate.tool_scale.tool_ik.tool_pin.tool_front.tool_side.tool_back.tl_play.shot_add.shot_delete.camera_key_add.export_animation_project.export_keyframe_pack.export_video.export_video_shot.export_render_passes.export_depth_video.export_storyboard.export_otio.menu_undo.menu_redo.agent_send.agent_stop.agent_steer.agent_retry.agent_connect.agent_panel.board_export.board_stylize`.split(`.`)),xe=[[`other_guide`,`.first-success-guide`],[`other_agent`,`.agent-panel`],[`other_menu`,`.menubar, [role='menu']`],[`other_sculpt`,`.sculpt-panel`],[`other_assets`,`.content-browser`],[`other_board`,`.dock-board`],[`other_timeline`,`.bottom-timeline, .studio-dock-slot`],[`other_inspector`,`.inspector-pane, .studio-right-column`],[`other_viewport`,`.studio-left-column`]],_=Object.freeze(xe.map(([e])=>e));function Se(e,t=null){if(g.includes(e))return e;for(let[e,n]of xe)if(t?.closest?.(n))return e;return`other`}var Ce=e=>e===`other`||_.includes(e),we=/^[a-f0-9]{32}$/,Te=new Set([`0`,`1`,`2`,`3`,`4-5`,`6-10`,`gte11`]),Ee=new Set([`lt10s`,`10-30s`,`30-60s`,`1-2m`,`2-5m`,`gte5m`]),v=new Set([`lt2s`,`2-10s`,`10-60s`,`gte60s`]),De=new Set([`lt50`,`50-150`,`150-500`,`500-2000`,`gte2000`]),Oe=new Set([...h,`other`]),y=Object.freeze([`openai-codex`,`anthropic`,`anthropic-subscription`,`openai`,`google`,`minimax`,`minimax-cn`,`openrouter`,`cliproxy`,`openai-compatible`]),ke=Object.freeze([`app`,`github`,`discord`,`npm`,`copy_npx`,`copy_clone`,`copy_mcp`,`copy_terminal`,`agent_install_doc`]),Ae=e=>h.includes(e)?e:`other`;function je(e){return!Number.isFinite(e)||e<1e4?`lt10s`:e<3e4?`10-30s`:e<6e4?`30-60s`:e<12e4?`1-2m`:e<3e5?`2-5m`:`gte5m`}function Me(e){return!Number.isFinite(e)||e<2e3?`lt2s`:e<1e4?`2-10s`:e<6e4?`10-60s`:`gte60s`}var b=(...e)=>t=>e.includes(t),x=e=>t=>e.has(t),S=e=>typeof e==`string`&&we.test(e),C=e=>typeof e==`boolean`,w=x(Te),T=x(Ee),Ne=Object.freeze({"studio:refused":{code:x(Oe),origin:b(`ui`,`agent`),phase:b(`admission`,`commit`),group:b(`object`,`shot`,`cast`,`scene`,`motion`,`edit`,`task`,`agent`,`other`),command:e=>typeof e==`string`&&e.length<=48&&/^[a-z][a-zA-Z0-9]*(?:\.[a-zA-Z0-9]+){1,3}$/.test(e)},"app:render_crash":{error_type:x(ee)},"app:gl_lost":{kind:b(`unavailable`,`context_lost`)},"studio:ready":{boot:b(`lt2s`,`2-5s`,`5-15s`,`gte15s`)},"playback:summary":{duration:T,late_ticks:b(`0`,`lt5`,`5-20`,`20-50`,`gte50`),max_catchup:b(`1`,`2`,`3-5`,`gte6`),fps:b(`12`,`24`,`30`,`60`,`other`),speed:b(`0.5`,`1`,`2`,`other`),measured_fps:b(`lt20`,`20-40`,`40-55`,`gte55`,`unknown`)},"guide:opened":{mode:b(`animation`,`storyboard`)},"guide:step":{mode:b(`animation`,`storyboard`),step:b(`1`,`2`,`3`,`4`),step_ms:T},"guide:dismissed":{mode:b(`animation`,`storyboard`),reached:b(`1`,`2`,`3`,`4`)},"guide:completed":{mode:b(`animation`,`storyboard`)},"agent:panel_toggled":{open:C,via:b(`key`,`button`)},"export:menu_opened":{surface:b(`studio`,`embed`),mode:b(`animation`,`storyboard`),webcodecs:C,shots:b(`0`,`1-3`,`4-10`,`gte11`)},"object:deleted_soon":{age:x(v)},"object:delete_undone":{age:x(v)},"edit:undone":{age:x(v),kind:b(`pose`,`camera`,`object`,`shot`,`prompt`,`agent_turn`,`ik_preview`,`other`),via:b(`key`,`menu`,`button`),result:b(`done`,`noop`,`refused`)},"agent:turn_summary":{turn_id:S,outcome:b(`succeeded`,`failed`,`cancelled`),wall:T,first_tool:T,tool_calls:w,tool_failed:w,refused:w,refusal_top:e=>e===`none`||Oe.has(e),stale_retry:w,authored:C,drafts:w,qa_first:b(`clean`,`problems`),qa_last:b(`clean`,`problems`),qa_trend:b(`improved`,`flat`,`worse`,`na`),stuck:C,cancel_phase:b(`before_tool`,`during_tool`,`after_tool`,`na`)},"motion:draft_compiled":{draft_index:w,qa_clean:C,qa_problems:w,qa_frames:b(`0`,`1-10`,`11-50`,`51-200`,`gte201`),compile:x(De),installed:C,stuck:C,repaired:C,searched:C,adjusted:C,frames:b(`lt30`,`30-120`,`121-480`,`gte481`)},"shortcut:ignored":{key_class:b(`undo`,`redo`,`mode`,`transform`,`frame`,`duplicate`,`delete`),reason:b(`no_selection`,`wrong_mode`,`workflow_mode`,`busy`,`empty_history`)},"shortcut:unbound":{combo:b(`copy`,`paste`,`cut`,`select_all`,`group`,`find`,`rename`,`help`)},"help:shortcuts_opened":{},"landing:cta_clicked":{target:b(...ke)},"search:no_results":{surface:b(`assets`,`outliner`),query_len:b(`1`,`2-3`,`4-8`,`gte9`)},"nav:thrash":{surface:b(`dock_tab`,`mode`,`agent_panel`),switches:b(`4-5`,`6-10`,`gte11`),window_s:b(10)},"camera:thrash":{gestures:b(`6-10`,`gte11`),kind_mix:b(`orbit`,`fly`,`pan`,`mixed`),window_s:b(20)},"agent:connect_opened":{entry:b(`first_run`,`failure_card`,`signed_out`,`menu`,`other`)},"agent:connect_started":{provider:b(...y,`other`),method:b(`oauth`,`api_key`,`chatgpt`)},"agent:connect_finished":{provider:b(...y,`other`),method:b(`oauth`,`api_key`,`chatgpt`),outcome:b(`ok`,`failed`,`cancelled`,`abandoned`),step:b(`list`,`prompt`,`waiting`,`done`),duration:T},"agent:model_changed":{provider:b(...y,`other`),after_failure:C},"agent:prompt_sent":{turn_id:S,provider:b(...y,`other`),via:b(`typed`,`retry_button`,`regenerate`,`chip`,`supervisor`),prompt_len:b(`1-20`,`21-80`,`81-240`,`gte241`),compose_ms:T,similarity:b(`first`,`same`,`near`,`different`),gap:e=>e===`first`||T(e),prev_outcome:b(`succeeded`,`failed`,`cancelled`,`none`),turn_index:w,attached:C,task_mode:C},"ui:rage_click":{control:b(...g,..._,`other`),clicks:b(`3`,`4-5`,`gte6`),changed:C},"ui:dead_click":{control:b(...g,..._,`other`),reason:b(`aria_disabled`,`refused`,`no_effect`)},"update:notice_shown":{kind:b(`global`,`npx`),behind:b(`patch`,`minor`,`major`)},"update:clicked":{action:b(`update_now`,`copy_command`,`later`,`dismiss`,`release_notes`,`restart`),kind:b(`global`,`npx`)},"update:restarted":{outcome:b(`ok`,`timeout`)},"update:finished":{outcome:b(`ok`,`failed`),error_class:b(`none`,`permission`,`network`,`node_version`,`npm_missing`,`other`),duration:T},"agent:post_turn_edit":{turn_id:S,edited:C,pose:w,camera:w,object:w,shot:w,prompt_block:w,first_delay:T}}),Pe=Object.freeze({"app:friction_summary":oe,...Object.fromEntries(Object.entries(Ne).map(([e,t])=>[e,Object.keys(t)]))});function Fe(e){if(e===`app:session_ended`)return ie;if(e===`app:friction_summary`)return ye;let t=Ne[e];return t?(e,n)=>Object.hasOwn(t,e)&&t[e](n):null}var Ie=`modulepreload`,Le=function(e){return`/`+e},Re={},ze=function(e,t,n){let r=Promise.resolve();if(t&&t.length>0){let e=document.getElementsByTagName(`link`),i=document.querySelector(`meta[property=csp-nonce]`),a=i?.nonce||i?.getAttribute(`nonce`);function o(e){return Promise.all(e.map(e=>Promise.resolve(e).then(e=>({status:`fulfilled`,value:e}),e=>({status:`rejected`,reason:e}))))}function s(e){return import.meta.resolve?import.meta.resolve(e):new URL(e,import.meta.url).href}r=o(t.map(t=>{if(t=Le(t,n),t=s(t),t in Re)return;Re[t]=!0;let r=t.endsWith(`.css`);for(let n=e.length-1;n>=0;n--){let i=e[n];if(i.href===t&&(!r||i.rel===`stylesheet`))return}let i=document.createElement(`link`);if(i.rel=r?`stylesheet`:Ie,r||(i.as=`script`),i.crossOrigin=``,i.href=t,a&&i.setAttribute(`nonce`,a),document.head.appendChild(i),r)return new Promise((e,n)=>{i.addEventListener(`load`,e),i.addEventListener(`error`,()=>n(Error(`Unable to preload CSS for ${t}`)))})}))}function i(e){let t=new Event(`vite:preloadError`,{cancelable:!0});if(t.payload=e,window.dispatchEvent(t),!t.defaultPrevented)throw e}return r.then(t=>{for(let e of t||[])e.status===`rejected`&&i(e.reason);return e().catch(i)})},Be=Object.freeze([`read`,`camera`,`scene_write`,`prompt_authoring`,`frame_capture`,`motion_generate`,`motion_apply`,`project_io`,`other`]),Ve=Object.freeze(`describe_scene.describe_shot.render_prompt.mark_camera_move.describe_camera_move.save_project.set_camera.frame_shot.add_character.place_character.remove_character.focus_character.place_object.import_mesh.sculpt_object.compare_sculpt.group_objects.update_object.remove_object.apply_batch.add_scene.switch_scene.open_project.capture_frame.studio_commands.studio_run.other`.split(`.`)),E=Object.freeze([`workflow_read`,`workflow_write`,`workflow_run`,`frame_capture`,`image_generate`,`scene_write`,`other`]),He=Object.freeze([`workflow:run_requested`,`workflow:run_succeeded`,`workflow:run_failed`,`workflow:run_cancelled`,`workflow:result_applied`,`agent:turn_requested`,`agent:tool_executed`,`agent:turn_succeeded`,`agent:turn_failed`,`agent:turn_cancelled`,`agent:result_applied`,`mcp:tool_requested`,`mcp:tool_executed`,`mcp:result_applied`]),Ue=Object.freeze({"workflow:run_requested":[`surface`,`run_id`,`node_count_bucket`],"workflow:run_succeeded":[`run_id`,`duration_bucket`],"workflow:run_failed":[`run_id`,`duration_bucket`,`failure_code`],"workflow:run_cancelled":[`run_id`,`duration_bucket`,`failure_code`],"workflow:result_applied":[`run_id`],"agent:turn_requested":[`surface`,`turn_id`],"agent:tool_executed":[`turn_id`,`tool_category`,`outcome`,`duration_bucket`],"agent:turn_succeeded":[`turn_id`,`duration_bucket`],"agent:turn_failed":[`turn_id`,`duration_bucket`,`failure_code`],"agent:turn_cancelled":[`turn_id`,`duration_bucket`,`failure_code`],"agent:result_applied":[`turn_id`],"mcp:tool_requested":[`tool_category`,`tool_name`,`request_id`],"mcp:tool_executed":[`tool_category`,`tool_name`,`outcome`,`duration_bucket`,`request_id`],"mcp:result_applied":[`request_id`]}),D=Object.freeze({surface:new Set([`studio`,`workflow`]),node_count_bucket:new Set([`0`,`1-3`,`4-10`,`gte11`]),duration_bucket:new Set([`lt1s`,`1-3s`,`3-10s`,`10-30s`,`gte30s`]),tool_category:new Set([...Be,...E]),tool_name:new Set(Ve),outcome:new Set([`succeeded`,`failed`,`uncertain`,`cancelled`])}),We=Object.freeze({source:new Set([`agent`,`manual`]),outcome:new Set([`ok`,`error`]),surface:new Set([`assets`,`agent`,`mcp`])}),Ge=`cozyclay.analyticsOptOut`,Ke=`cozyclay.internalQa`,qe=`cozyclay.analyticsActivation`,Je=`cozyclay.useCaseAsked`,O=Object.freeze({pose:Object.freeze([`pose_edit`]),camera:Object.freeze([`camera_key_record`,`rail_edit`]),object:Object.freeze([`object_insert`,`cutout_insert`,`object_transform`]),shot:Object.freeze([`shot_add`,`shot_edit`]),prompt:Object.freeze([`prompt_block_add`,`prompt_block_edit`])}),Ye=Object.freeze(Object.keys(O).map(e=>`${e}_edit_bucket`)),k=Object.freeze([`animation`,`film`,`game`,`ad_mv`,`personal`,`other`,`skip`]),A=Object.freeze([`team`,`solo`,`skip`]),Xe=new Set([`storyboard`,`animation`]),Ze=new Set([`rig`,`capsule`,`hybrid`]),Qe=Object.freeze([`latest`,`outdated`,`unknown`]),$e=Object.freeze([`https://cozyclay.org`,`https://www.cozyclay.org`]),j=[`attempt_id`,`export_kind`,`format`,`surface`,`is_retry`,`retry_of`,`objects`],M=Object.freeze({"install:first_launch":[`heard_from`],"app:session_started":[],"app:session_ended":[`duration_bucket`,`action_count_bucket`,`scenes_touched`,...Ye,`session_id`],...Pe,"app:error":[`error_kind`,`error_type`,`error_source`,`error_file`,`error_line`,`error_col`],"device:profile":[`gpu_vendor`,`gpu_class`,`webgl`,`cpu_bucket`,`memory_bucket`,`frame_rate_bucket`],"survey:use_case":[`use_case`,`team`],"feature:used":[`name`],"hosted:composer_viewed":[],"hosted:login_started":[],"hosted:ticket_created":[],"hosted:result_opened":[],"hosted:opened_in_studio":[],"scene:created":[`scene_source`,`previs_mode`,`cast_style`],"storyboard:panel_created":[`source`],"storyboard:panel_stylized":[`outcome`],"cast:proxy_added":[`surface`],"scene:loaded":[`scene_source`],"project:saved":[`object_count_bucket`,`shot_count_bucket`],"project:opened":[`age_bucket`],"craft:first_action":[`action_kind`],"craft:first_edit":[`edit_kind`,`definition_version`],"export:blocking_frame_succeeded":[`format`],"export:video_succeeded":[`format`],"export:keyframe_pack":[`entries`,`source`],"export:attempt_started":j,"export:attempt_succeeded":[...j,`duration_bucket`],"export:attempt_failed":[...j,`duration_bucket`,`failure_code`,`stage`,`progress`],"export:attempt_cancelled":[...j,`duration_bucket`,`failure_code`,`stage`,`progress`],"export:saved":[`method`,`reason`],"playground:opened":[],"playground:first_action":[`action_kind`],"playground:first_edit":[`edit_kind`,`definition_version`],"activation:completed":[`activation_path`],sculpt_run:[`outcome`,`rounds`,`final_iou`,`duration_ms`,`had_target`],...Ue}),N=new Set([`pose_edit`,`pose_save`,`camera_fly`,`orbit`,`dolly_rail`,`crane_graph`,`timeline_scrub`,`export_frame`,`export_video`,`export_depth_video`,`export_keyframe_pack`,`export_render_pass`,`export_storyboard`,`auto_color`]),et=Object.freeze([`x`,`hn`,`reddit`,`github`,`friend`,`other`,`site`,`playground`]),P=new Set(et),tt=new Set([`prompt`,`text`,`url`,`path`,`file`]),F=Object.freeze([`done`,`cancelled`,`failed`]),nt=10,rt=864e5,it=Object.freeze({workflow:new Set([`aborted`,`capture_failed`,`generation_failed`,`unknown`]),agent:new Set([`aborted`,`auth`,`rate_limited`,`tool_failed`,`upstream`,`network`,`unknown`,`key_refused`,`stale_scene`,`capability_missing`,`busy`,`invalid_request`])}),I=Object.freeze({error_kind:new Set([`error`,`unhandled_rejection`]),error_type:ee,error_source:new Set([`app`,`extension`,`external`,`unknown`])}),L=/^[A-Za-z0-9_.-]{1,80}\.(?:m?js|jsx|ts|tsx)$/,at=Object.freeze({gpu_vendor:new Set([`nvidia`,`amd`,`intel`,`apple`,`qualcomm`,`arm`,`software`,`other`,`unknown`]),gpu_class:new Set([`discrete`,`integrated`,`software`,`unknown`]),webgl:new Set([`webgl2`,`webgl1`,`none`]),cpu_bucket:new Set([`1-4`,`5-8`,`9-16`,`gte17`,`unknown`]),memory_bucket:new Set([`lt4`,`4-7`,`gte8`,`unknown`]),frame_rate_bucket:new Set([`lt20`,`20-40`,`40-55`,`gte55`,`unknown`])}),R=null,z=!1,B=!1,V=null,H=!1,ot=!1,U=0,st=0,ct=0,lt=!1,ut=!1,dt=new Set,ft=new Map(Object.entries(O).flatMap(([e,t])=>t.map(t=>[t,e]))),pt=1e3,mt=Object.fromEntries(Object.keys(O).map(e=>[e,0])),ht=null,gt=-1/0,_t=10,W=new Set,vt=!1,yt=!1,bt=new Set([`app:session_started`,`app:session_ended`,`install:first_launch`,...Object.keys(Pe),`app:error`,`device:profile`,`app:render_crash`,`app:gl_lost`]);function xt(){try{return globalThis.localStorage??null}catch{return null}}function G(e){try{return xt()?.getItem(e)??null}catch{return null}}function K(e,t){try{xt()?.setItem(e,t)}catch{}}function q(e){return typeof e==`string`?e.trim().toLowerCase().replace(/[/.]+$/g,``):``}function St(e){return e===void 0?[...$e]:e.split(`,`).map(q).filter(Boolean)}function Ct(e,t){let n=q(e);return Array.isArray(t)&&t.some(e=>n===q(e))}var wt=e=>typeof e==`boolean`?!0:typeof e==`number`?Number.isFinite(e):typeof e==`string`&&e.length<=32&&!/\s/.test(e);function J(e,t){let r=M[e]??[];if(!t||typeof t!=`object`||Array.isArray(t))return{};let i={},a=Fe(e);for(let o of r)if(!(tt.has(o)||!Object.hasOwn(t,o))&&!(e===`feature:used`&&(o!==`name`||!N.has(t[o])))&&!(e===`install:first_launch`&&(o!==`heard_from`||!P.has(t[o])))&&!((e.startsWith(`export:attempt_`)||e===`export:saved`)&&!c(o,t[o]))){if(a){a(o,t[o])&&(i[o]=t[o]);continue}if(!(e===`export:keyframe_pack`&&(o===`source`&&t[o]!==`workflow`||o===`entries`&&(!Number.isFinite(t[o])||t[o]<0)))&&!((e===`craft:first_edit`||e===`playground:first_edit`)&&(o===`edit_kind`&&!n.includes(t[o])||o===`definition_version`&&t[o]!==2))){if(e.startsWith(`workflow:`)||e.startsWith(`agent:`)||e.startsWith(`mcp:`)){if(o===`run_id`||o===`turn_id`||o===`request_id`){if(typeof t[o]!=`string`||!/^[a-f0-9]{32}$/.test(t[o]))continue}else if(o===`surface`){if(!D.surface.has(t[o])||e.startsWith(`workflow:`)&&t[o]!==`workflow`)continue}else if(o===`node_count_bucket`&&!D.node_count_bucket.has(t[o]))continue;else if(o===`duration_bucket`&&!D.duration_bucket.has(t[o]))continue;else if(o===`tool_category`){if(!(e.startsWith(`agent:`)?E:Be).includes(t[o]))continue}else if(o===`tool_name`){if(!e.startsWith(`mcp:`)||!D.tool_name.has(t[o]))continue}else if(o===`outcome`){if(!(e===`mcp:tool_executed`?[`succeeded`,`failed`,`uncertain`,`cancelled`]:[`succeeded`,`failed`,`cancelled`]).includes(t[o]))continue}else if(o===`failure_code`&&!it[e.startsWith(`agent:`)?`agent`:`workflow`].has(t[o]))continue}if(e===`app:error`){if(o===`error_file`){typeof t[o]==`string`&&L.test(t[o])&&(i[o]=t[o]);continue}if(o===`error_line`||o===`error_col`){Number.isInteger(t[o])&&t[o]>=0&&t[o]<=1e7&&(i[o]=t[o]);continue}if(!I[o]?.has(t[o]))continue}if(!(e===`device:profile`&&!at[o]?.has(t[o]))){if(e===`sculpt_run`){let e=t[o];o===`outcome`&&F.includes(e)||o===`rounds`&&Number.isInteger(e)&&e>=0&&e<=nt?i[o]=e:o===`final_iou`&&typeof e==`number`&&e>=0&&e<=1?i[o]=Math.round(e*100)/100:o===`duration_ms`&&typeof e==`number`&&e>=0&&e<=rt?i[o]=Math.round(e):o===`had_target`&&typeof e==`boolean`&&(i[o]=e);continue}o===`previs_mode`&&!Xe.has(t[o])||o===`cast_style`&&!Ze.has(t[o])||(e.startsWith(`storyboard:`)||e.startsWith(`cast:`))&&!We[o]?.has(t[o])||e===`survey:use_case`&&(o===`use_case`&&!k.includes(t[o])||o===`team`&&!A.includes(t[o]))||wt(t[o])&&(i[o]=t[o])}}}return i}Object.freeze([...N]);function Y(e){let t=Number.isFinite(e)?Math.max(0,Math.floor(e)):0;return t===0?`0`:t<=3?`1-3`:t<=10?`4-10`:`gte11`}function Tt(e){return!Number.isFinite(e)||e<6e4?`lt1m`:e<3e5?`1-5m`:e<9e5?`5-15m`:e<18e5?`15-30m`:`gte30m`}function Et(e){return!Number.isFinite(e)||e<0||e<36e5?`lt1h`:e<864e5?`1-24h`:e<6048e5?`1-7d`:e<2592e6?`7-30d`:`gte30d`}function Dt(){let e=String(globalThis.navigator?.userAgentData?.platform||globalThis.navigator?.platform||``).toLowerCase();return e.includes(`mac`)?`macos`:e.includes(`win`)?`windows`:e.includes(`linux`)?`linux`:e.includes(`android`)?`android`:e.includes(`iphone`)||e.includes(`ipad`)||e.includes(`ios`)?`ios`:`unknown`}function Ot(e){return!Number.isFinite(e)||e<1e3?`lt1s`:e<3e3?`1-3s`:e<1e4?`3-10s`:e<3e4?`10-30s`:`gte30s`}function kt(e){return!Number.isFinite(e)||e<=0?`unknown`:e<=4?`1-4`:e<=8?`5-8`:e<=16?`9-16`:`gte17`}function At(e){return!Number.isFinite(e)||e<=0?`unknown`:e<4?`lt4`:e<8?`4-7`:`gte8`}function jt(e){return!Number.isFinite(e)||e<=0?`unknown`:e<20?`lt20`:e<40?`20-40`:e<55?`40-55`:`gte55`}function Mt(e){let t=String(e??``).toLowerCase();return t.trim()?/swiftshader|llvmpipe|softpipe|software|basic render driver/.test(t)?{gpu_vendor:`software`,gpu_class:`software`}:/nvidia|geforce|quadro|\brtx\b|\bgtx\b|tesla/.test(t)?{gpu_vendor:`nvidia`,gpu_class:`discrete`}:/\bamd\b|radeon|\bati\b/.test(t)?{gpu_vendor:`amd`,gpu_class:/radeon\(tm\) graphics|radeon graphics|vega \d+ graphics|\b(?:610|660|680|740|760|780|880|890)m\b/.test(t)?`integrated`:`discrete`}:/intel|iris|uhd graphics|hd graphics/.test(t)?{gpu_vendor:`intel`,gpu_class:/arc(?:\(tm\))? [ab]\d{3}/.test(t)?`discrete`:`integrated`}:/apple|\bm[1-9](?: pro| max| ultra)?\b/.test(t)?{gpu_vendor:`apple`,gpu_class:`integrated`}:/adreno|qualcomm/.test(t)?{gpu_vendor:`qualcomm`,gpu_class:`integrated`}:/\bmali\b|\barm\b|powervr/.test(t)?{gpu_vendor:`arm`,gpu_class:`integrated`}:{gpu_vendor:`other`,gpu_class:`unknown`}:{gpu_vendor:`unknown`,gpu_class:`unknown`}}var Nt=/((?:https?|chrome-extension|moz-extension|safari-extension|safari-web-extension):\/\/[^\s()]+?):(\d+):(\d+)/g;function X(e,t){if(typeof e!=`string`||!e)return`unknown`;if(/^(?:chrome|moz|safari|safari-web)-extension:/.test(e))return`extension`;try{return t&&new URL(e).origin===t?`app`:`external`}catch{return`unknown`}}function Pt(e){try{let t=new URL(e).pathname.split(`/`).pop()??``;return L.test(t)?t:null}catch{return null}}function Ft(e){try{if(e===null||typeof e!=`object`&&typeof e!=`function`)return`non_error`;let t=typeof e.name==`string`?e.name:``;return t&&t!==`non_error`&&t!==`other`&&I.error_type.has(t)?t:typeof DOMException<`u`&&e instanceof DOMException?`DOMException`:e instanceof Error?`other`:`non_error`}catch{return`other`}}function It({error:e,filename:t,lineno:n,colno:r,kind:i=`error`}={},a=globalThis.location?.origin??``){let o={error_kind:i===`unhandled_rejection`?`unhandled_rejection`:`error`,error_type:Ft(e),error_source:`unknown`},s=typeof t==`string`&&t?{url:t,line:n,col:r}:null;if(!s||X(s.url,a)!==`app`){let t=``;try{t=typeof e?.stack==`string`?e.stack.slice(0,4e3):``}catch{t=``}let n=[...t.matchAll(Nt)].map(e=>({url:e[1],line:Number(e[2]),col:Number(e[3])}));s=n.find(e=>X(e.url,a)===`app`)??s??n[0]??null}if(!s||(o.error_source=X(s.url,a),o.error_source!==`app`))return o;let c=Pt(s.url);return c&&(o.error_file=c),Number.isInteger(s.line)&&s.line>=0&&(o.error_line=s.line),Number.isInteger(s.col)&&s.col>=0&&(o.error_col=s.col),o}function Lt(e,t=Date.now()){let n=ft.get(e);if(!n)return!1;let r=n===ht&&t-gt<pt;return ht=n,gt=t,r||(mt[n]+=1),e===`pose_edit`&&Qt(`pose_edit`),!r}function Rt(){return Object.fromEntries(Object.entries(mt).map(([e,t])=>[`${e}_edit_bucket`,Y(t)]))}function zt(e,t=`unknown`){try{if(e?.name===`AbortError`)return`aborted`;if(i.has(e?.exportFailureCode))return e.exportFailureCode}catch{}return i.has(t)?t:`unknown`}var Bt=[`$current_url`,`$initial_current_url`,`$referrer`,`$initial_referrer`],Vt=[`utm_source`,`utm_medium`,`utm_campaign`,`utm_content`,`utm_term`,`gad_source`,`mc_cid`,`gclid`,`gclsrc`,`dclid`,`gbraid`,`wbraid`,`fbclid`,`msclkid`,`twclid`,`li_fat_id`,`igshid`,`ttclid`,`rdt_cid`,`epik`,`qclid`,`sccid`,`irclid`,`_kx`,`ph_keyword`];function Ht(e){return typeof e==`string`?e.split(`#`)[0].split(`?`)[0]:e}function Ut(e){if(!e||typeof e!=`object`||!e.properties)return e;let t=[e.properties,e.properties.$set,e.properties.$set_once,e.$set,e.$set_once].filter(e=>e&&typeof e==`object`&&!Array.isArray(e));for(let e of t){for(let t of Bt)typeof e[t]==`string`&&(e[t]=Ht(e[t]));for(let t of Vt)delete e[t],delete e[`$initial_${t}`];for(let t of Object.keys(e))t.startsWith(`$session_entry_`)&&delete e[t]}return e}function Wt(e){return e?.activationTracked!==!0}function Z(){return Q()?.distribution===`npm`?Q()?.telemetryEnabled!==!0:G(Ge)===`1`}function Gt(){return{BASE_URL:`/`,DEV:!1,MODE:`production`,PROD:!0,SSR:!1,VITE_COZYCLAY_LIVE_PORT:`5184`}}function Q(){let e=globalThis.__COZYCLAY_RUNTIME__;return!e||typeof e!=`object`||Array.isArray(e)?null:e}function Kt(e){try{let t=new URL(e);return t.protocol===`http:`?[`127.0.0.1`,`localhost`].includes(t.hostname)?!0:/^(10\.|192\.168\.|172\.(?:1[6-9]|2\d|3[01])\.)/.test(t.hostname):!1}catch{return!1}}function qt({env:e=Gt(),origin:n=globalThis.location?.origin??``,runtime:r=Q()}={}){return e.PROD?r?.distribution===`npm`?r.telemetryEnabled===!0?Kt(n)?typeof r.apiKey!=`string`||r.apiKey.length===0?{kind:`disabled`,reason:`no key`}:typeof r.installationId!=`string`||!/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(r.installationId)?{kind:`disabled`,reason:`invalid anonymous identity`}:{kind:`enabled`,distribution:`npm`,apiKey:r.apiKey,apiHost:r.apiHost||`https://t.cozyclay.org`,appVersion:r.appVersion||null,installationId:r.installationId,firstLaunch:r.firstLaunch===!0,firstLaunchHeardFrom:P.has(r.firstLaunchHeardFrom)?r.firstLaunchHeardFrom:null,installKind:[`npx`,`global`,`clone`].includes(r.installKind)?r.installKind:`npx`,originKind:`local`,internalQa:r.internalQa===!0,updateStatus:Qe.includes(r.updateStatus)?r.updateStatus:`unknown`}:{kind:`disabled`,reason:`unapproved origin`}:{kind:`disabled`,reason:`opted out`}:e.VITE_POSTHOG_KEY?Ct(n,St(e.VITE_POSTHOG_ALLOWED_ORIGINS))?{kind:`enabled`,distribution:`hosted`,apiKey:e.VITE_POSTHOG_KEY,apiHost:e.VITE_POSTHOG_HOST||`https://us.i.posthog.com`,appVersion:e.VITE_APP_VERSION||t(),installationId:null,firstLaunch:!1,firstLaunchHeardFrom:null,installKind:null,originKind:`hosted`,internalQa:G(Ke)===`1`,updateStatus:null}:{kind:`disabled`,reason:`unapproved origin`}:{kind:`disabled`,reason:`no key`}:{kind:`disabled`,reason:`not production`}}function Jt(e){return{distribution:e.distribution,...e.appVersion?{app_version:e.appVersion}:{},origin_kind:e.originKind,os:Dt(),...e.installKind?{install_kind:e.installKind}:{},...e.updateStatus?{update_status:e.updateStatus}:{},internal_qa:e.internalQa}}function Yt(e){let t=qt({env:e});return t.kind===`disabled`?t.reason:Z()?`opted out`:null}async function Xt({lite:e=!1}={}){if(z||V)return V;if(Q()?.distribution!==`npm`){let e=new URLSearchParams(globalThis.location?.search??``).getAll(`internal_qa`);e.length===1&&(e[0]===`1`||e[0]===`0`)&&K(Ke,e[0])}let t=Gt(),n=Yt(t);if(n){ot||=(console.info(`[analytics] disabled: `+n),!0);return}V=(async()=>{try{let n=await ze(()=>import(`./module-MzlRiBjI.js`),[]);if(Z())return;let r=qt({env:t});if(r.kind===`disabled`)return;R=n.default??n,R.init(r.apiKey,{api_host:r.apiHost,defaults:`2025-05-24`,autocapture:!1,capture_pageview:!1,capture_pageleave:!1,person_profiles:`never`,persistence:r.distribution===`npm`?`memory`:`localStorage`,respect_dnt:!1,disable_session_recording:!0,capture_dead_clicks:!1,capture_performance:!1,disable_capture_url_hashes:!0,save_campaign_params:!1,save_referrer:!1,mask_personal_data_properties:!0,request_batching:!1,advanced_disable_feature_flags:!0,disable_external_dependency_loading:!0,disable_surveys:!0,ui_host:`https://us.posthog.com`,bootstrap:r.installationId?{distinctID:r.installationId,isIdentifiedID:!1}:void 0,before_send:Ut}),z=!0,B=!0;let i=Jt(r);if(R.register(i),globalThis.__cozyclayAnalytics={instance:R},R.capture(`$pageview`),U=Date.now(),e||(un(r,i),nn(),_e(),ln()),r.distribution===`npm`&&!e&&($(`app:session_started`),r.firstLaunch)){let e=r.firstLaunchHeardFrom;$(`install:first_launch`,e?{heard_from:e}:{})}}catch{console.info(`[analytics] initialization failed`)}})(),await V}function $(e,t={}){if(!(!z||!B||!R||!Object.hasOwn(M,e)))try{if(Z())return;let n=J(e,t);bt.has(e)||(st+=1,(e===`scene:created`||e===`scene:loaded`)&&(ct+=1)),R.capture(e,n)}catch{}}function Zt(e,{hadTarget:t=!1}={}){return F.includes(e?.stage)?{outcome:e.stage,rounds:e.round,...Number.isFinite(e.iou)?{final_iou:Math.round(e.iou*100)/100}:{},duration_ms:Math.round(e.elapsedMs),had_target:!!t}:null}function Qt(e){return!z||!B||!R||!N.has(e)||dt.has(e)?!1:(dt.add(e),$(`feature:used`,{name:e}),!0)}function $t(){try{return z&&B&&!!R&&!Z()}catch{return!1}}function en(){return $t()&&G(Je)!==`1`}function tn(e,t){K(Je,`1`),$(`survey:use_case`,{use_case:k.includes(e)?e:`skip`,team:A.includes(t)?t:`skip`})}function nn(){if(vt||typeof window>`u`||typeof window.addEventListener!=`function`)return;vt=!0;let e=e=>{try{let t=It(e);m(`errors`);let n=[t.error_kind,t.error_type,t.error_source,t.error_file,t.error_line,t.error_col].join(`|`);if(W.has(n)||W.size>=_t)return;W.add(n),$(`app:error`,t)}catch{}};window.addEventListener(`error`,t=>{try{if(typeof t?.message==`string`&&t.message.startsWith(`ResizeObserver loop`)||!t?.error&&!t?.filename)return;e({error:t?.error,filename:t?.filename,lineno:t?.lineno,colno:t?.colno,kind:`error`})}catch{}}),window.addEventListener(`unhandledrejection`,t=>{e({error:t?.reason,kind:`unhandled_rejection`})})}function rn(){try{let e=globalThis.document?.createElement?.(`canvas`);if(!e?.getContext)return{webgl:`none`,renderer:``};let t=e.getContext(`webgl2`),n=t?`webgl2`:`none`;if(t||(t=e.getContext(`webgl`),t&&(n=`webgl1`)),!t)return{webgl:n,renderer:``};let r=``;try{let e=t.getExtension(`WEBGL_debug_renderer_info`);r=String(t.getParameter(e?e.UNMASKED_RENDERER_WEBGL:t.RENDERER)??``)}catch{r=``}try{t.getExtension(`WEBGL_lose_context`)?.loseContext()}catch{}return{webgl:n,renderer:r}}catch{return{webgl:`none`,renderer:``}}}var an=8e3,on=3e3,sn=6e4;function cn(){return new Promise(e=>{let t=globalThis.requestAnimationFrame;if(typeof t!=`function`){e(null);return}let n=()=>globalThis.document?.visibilityState===`hidden`,r=Date.now(),i=()=>{if(Date.now()-r>sn){e(null);return}if(n()){setTimeout(i,2e3);return}let a=0,o=0,s=r=>{if(n()){setTimeout(i,2e3);return}if(o||=r,a+=1,r-o>=on){e((a-1)*1e3/(r-o));return}t(s)};t(s)};setTimeout(i,an)})}async function ln(){if(!(yt||globalThis.document===void 0||typeof globalThis.requestAnimationFrame!=`function`)){yt=!0;try{let{webgl:e,renderer:t}=rn(),n=Mt(t),r=await cn();$(`device:profile`,{...n,webgl:e,cpu_bucket:kt(globalThis.navigator?.hardwareConcurrency),memory_bucket:At(globalThis.navigator?.deviceMemory),frame_rate_bucket:jt(r)})}catch{}}}function un(e,t){if(ut||typeof window>`u`)return;ut=!0;let n=()=>{if(!(lt||!U)){lt=!0;try{if(!B||!R||Z()||R.has_opted_out_capturing())return;let n=`${e.apiHost.replace(/\/$/,``)}/e/`,r={...t,distinct_id:R.get_distinct_id()},i=(t,i)=>{let a=JSON.stringify({api_key:e.apiKey,event:t,properties:{...r,...J(t,i)}});typeof globalThis.navigator?.sendBeacon==`function`?globalThis.navigator.sendBeacon(n,new Blob([a],{type:`application/json`})):fetch(n,{method:`POST`,body:a,keepalive:!0,headers:{"content-type":`application/json`}})},a=Tt(Date.now()-U);i(`app:session_ended`,{session_id:R.get_session_id?.(),duration_bucket:a,action_count_bucket:Y(st),scenes_touched:Math.min(20,ct),...Rt()}),i(`app:friction_summary`,{active_time:a,...ve()})}catch{}}};window.addEventListener(`pagehide`,n,{once:!0}),window.addEventListener(`beforeunload`,n,{once:!0})}function dn(e){if(!(!z||!B||H)){if(!Wt({activationTracked:G(qe)===`1`})){H=!0;return}H=!0,K(qe,`1`),$(`activation:completed`,{activation_path:e})}}export{h as A,e as B,y as C,Ae as D,je as E,fe as F,m as I,ge as L,me as M,de as N,Se as O,pe as P,r as R,ze as S,Me as T,Zt as _,D as a,dn as b,jt as c,It as d,zt as f,J as g,tn as h,Ue as i,be as j,Ce as k,Ot as l,Lt as m,O as n,$t as o,Xt as p,He as r,Y as s,E as t,Et as u,en as v,ke as w,Qt as x,$ as y,t as z};
|