Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
182 lines
8.9 KiB
HTML
182 lines
8.9 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
<!-- Served at /funpack/, physically at app/legacy/ -- every relative script
|
|
and stylesheet href below resolves against THIS, not the request URL. -->
|
|
<base href="/funpack/app/legacy/">
|
|
<title>FunPack · Cutting Room</title>
|
|
<!-- Before the stylesheet on purpose: data-theme has to be on <html> for the
|
|
first paint, or a light-theme user gets a dark flash on every load. -->
|
|
<script src="theme.js"></script>
|
|
<!-- Beside the theme for the same reason: both are browser preferences that decide
|
|
what the first paint looks like, so neither may load after the layout does. -->
|
|
<script src="timeline_peek.js"></script>
|
|
<script src="ui_mode.js"></script>
|
|
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
|
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Inter+Tight:wght@600;700;800&display=swap" rel="stylesheet" />
|
|
<link rel="stylesheet" href="styles.css" />
|
|
<script>
|
|
// Boot-time error surface: if any script fails, show it instead of a blank app.
|
|
(function () {
|
|
function show(msg) {
|
|
var b = document.getElementById("boot-error");
|
|
if (!b) {
|
|
b = document.createElement("div"); b.id = "boot-error";
|
|
b.style.cssText = "position:fixed;z-index:99999;left:0;right:0;top:0;padding:10px 34px 10px 14px;" +
|
|
"background:#3a1320;color:#ffb3c1;font:12px/1.5 var(--font-ui, system-ui, sans-serif);border-bottom:1px solid #e0566b;white-space:pre-wrap";
|
|
var x = document.createElement("button");
|
|
x.textContent = "✕"; x.title = "Dismiss";
|
|
x.style.cssText = "position:absolute;top:6px;right:8px;background:transparent;border:1px solid #e0566b;" +
|
|
"color:#ffb3c1;border-radius:6px;cursor:pointer;font:12px var(--font-ui, system-ui, sans-serif);padding:1px 7px;line-height:1.4";
|
|
x.onclick = function () { b.remove(); };
|
|
b.appendChild(x);
|
|
(document.body || document.documentElement).appendChild(b);
|
|
}
|
|
var t = b.querySelector(".boot-error-text");
|
|
if (!t) { t = document.createElement("span"); t.className = "boot-error-text"; b.insertBefore(t, b.firstChild); }
|
|
t.textContent = "Movie Editor error — " + msg + "\n(restart ComfyUI + hard-reload Cmd/Ctrl+Shift+R; if it persists, send me this text)";
|
|
}
|
|
window.addEventListener("error", function (e) {
|
|
// Ignore resource-load errors (e.g. a pooled <video>/<img> failing to fetch) —
|
|
// those fire an error event on the element with an empty message; only surface
|
|
// real script errors so a missing clip doesn't pop the scary boot overlay.
|
|
if (e && e.target && e.target !== window && e.target.nodeName) return;
|
|
show((e.message || "load error") + (e.filename ? " @ " + e.filename.split("/").pop() + ":" + e.lineno : ""));
|
|
}, true);
|
|
window.addEventListener("unhandledrejection", function (e) {
|
|
show("promise: " + ((e.reason && (e.reason.message || e.reason)) || "rejected"));
|
|
});
|
|
})();
|
|
</script>
|
|
</head>
|
|
<body>
|
|
<!-- ───────────────────────── MENU BAR ───────────────────────── -->
|
|
<nav class="menubar" id="menubar">
|
|
<span class="brand"><span class="brand-mark">◉</span> FunPack</span>
|
|
<div class="mode-switch" id="mode-switch" role="group" aria-label="Interface mode"></div>
|
|
<div class="menus" id="menus"><!-- populated by menubar.js --></div>
|
|
<div class="menubar-right">
|
|
<span class="save-chip" id="save-chip"></span>
|
|
<span class="health-chip" id="health-chip"></span>
|
|
</div>
|
|
</nav>
|
|
|
|
<!-- ───────── WORKSPACE — OpenCut-style NLE: Assets | Preview | Properties / Timeline ───────── -->
|
|
<div class="workspace" id="workspace">
|
|
<section class="main-row" id="main-row">
|
|
<aside class="zone media dock-panel" id="media-zone" data-dock="media">
|
|
<div class="zone-head"><span class="zone-title">Assets</span></div>
|
|
<div class="zone-body" id="media-body"></div>
|
|
</aside>
|
|
|
|
<div class="splitter splitter-v" id="split-left" title="Drag to resize"></div>
|
|
|
|
<section class="zone preview dock-panel" id="preview-zone" data-dock="preview">
|
|
<div class="zone-head">
|
|
<span class="zone-title">Preview</span>
|
|
<!-- Simple mode parks the transport here: its home is the timeline header, and
|
|
that whole zone is hidden. -->
|
|
<div class="mode-actions" id="simple-actions"></div>
|
|
<span class="zone-head-right" id="preview-status"></span>
|
|
</div>
|
|
<div class="zone-body program" id="preview-body"></div>
|
|
<!-- Simple mode only: the big prompt + the two panel buttons. -->
|
|
<div class="simple-bar" id="simple-bar" hidden></div>
|
|
</section>
|
|
|
|
<div class="splitter splitter-v" id="split-right" title="Drag to resize"></div>
|
|
|
|
<section class="zone inspector dock-panel" id="inspector-zone" data-dock="settings">
|
|
<div class="zone-head"><span class="zone-title" id="inspector-title">Properties</span></div>
|
|
<div class="zone-body" id="inspector-body"></div>
|
|
</section>
|
|
</section>
|
|
|
|
<div class="splitter splitter-h" id="split-bottom" title="Drag to resize"></div>
|
|
|
|
<!-- BOTTOM: timeline (single source of truth — recipe for a clip lives in Properties) -->
|
|
<section class="zone timeline" id="timeline-zone">
|
|
<div class="zone-head">
|
|
<span class="zone-title">Timeline</span>
|
|
<div class="transport-actions" id="transport-actions" aria-label="Generate and render"></div>
|
|
<div class="zone-head-right">
|
|
<span id="timeline-meta"></span>
|
|
<nav class="dock-tabs pinned-tabs" id="pinned-tabs" aria-label="Pinned shortcuts"></nav>
|
|
<nav class="dock-tabs" id="dock-tabs" aria-label="Workspace panels"></nav>
|
|
<button class="composer-btn" id="composer-btn" type="button" title="Open the Composer — global prompt, shortcuts, split markers">
|
|
<span class="composer-dot">◆</span> Composer
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<div class="zone-body" id="timeline-body"></div>
|
|
</section>
|
|
</div>
|
|
|
|
<div class="grain" aria-hidden="true"></div>
|
|
<div class="menu-veil" id="menu-veil" hidden></div>
|
|
|
|
<script src="modules.js"></script>
|
|
<script src="api.js"></script>
|
|
<script src="dom.js"></script>
|
|
<script src="actions.js"></script>
|
|
<script src="pipeline_state.js"></script>
|
|
<script src="settings_field.js"></script>
|
|
<!-- Module scripts always defer, so this runs after every classic script
|
|
above regardless of position -- placed here only for readability next
|
|
to the pipeline state it depends on (window.PipelineState). -->
|
|
<script type="module" src="generate_bridge.js"></script>
|
|
<script src="settings_window.js"></script>
|
|
<script src="appearance_settings.js"></script>
|
|
<script src="floating_window.js"></script>
|
|
<script src="restart_ui.js"></script>
|
|
<script src="git_actions.js"></script>
|
|
<script src="pipeline_caps.js"></script>
|
|
<script src="tour_mode.js"></script>
|
|
<script src="view_bus.js"></script>
|
|
<script src="history.js"></script>
|
|
<script src="media_picker.js"></script>
|
|
<script src="scene_align.js"></script>
|
|
<script src="references.js"></script>
|
|
<script src="store.js"></script>
|
|
<script src="models.js"></script>
|
|
<script src="workflow_import.js"></script>
|
|
<script src="menubar.js"></script>
|
|
<script src="actionbar.js"></script>
|
|
<script src="layout.js"></script>
|
|
<script src="pinned_buttons.js"></script>
|
|
<script src="mediabrowser.js"></script>
|
|
<script src="log.js"></script>
|
|
<script src="player.js"></script>
|
|
<script src="overlay_ui.js"></script>
|
|
<script src="montage_dialog.js"></script>
|
|
<script src="overlay_preview.js"></script>
|
|
<script src="sampler_panel.js"></script>
|
|
<script src="engine_settings.js"></script>
|
|
<script src="modules_control.js"></script>
|
|
<script src="sampler_quickbar.js"></script>
|
|
<script src="wheel.js"></script>
|
|
<script src="wheel_actions_seed.js"></script>
|
|
<script src="editor_settings.js"></script>
|
|
<script src="temp_browser.js"></script>
|
|
<script src="block_sweep.js"></script>
|
|
<script src="custom_nodes.js"></script>
|
|
<script src="autocomplete.js"></script>
|
|
<script src="suggestions.js"></script>
|
|
<script src="slot_picker.js"></script>
|
|
<script src="pipeline_setup.js"></script>
|
|
<script src="onboarding.js"></script>
|
|
<script src="inspector.js"></script>
|
|
<script src="rating_picker.js"></script>
|
|
<script src="waveform.js"></script>
|
|
<script src="timeline.js"></script>
|
|
<script src="enhancer_ui.js"></script>
|
|
<script src="composer.js"></script>
|
|
<script src="tour.js"></script>
|
|
<script src="simple_bar.js"></script>
|
|
<script src="app.js"></script>
|
|
</body>
|
|
</html>
|