@bloopjs/web 0.0.90 → 0.0.91

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/App.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"App.d.ts","sourceRoot":"","sources":["../src/App.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"App.d.ts","sourceRoot":"","sources":["../src/App.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"BottomBar.d.ts","sourceRoot":"","sources":["../../../src/debugui/components/BottomBar.tsx"],"names":[],"mappings":"AAgFA,wBAAgB,SAAS,4CAoFxB"}
1
+ {"version":3,"file":"BottomBar.d.ts","sourceRoot":"","sources":["../../../src/debugui/components/BottomBar.tsx"],"names":[],"mappings":"AAiFA,wBAAgB,SAAS,4CA6FxB"}
@@ -0,0 +1,2 @@
1
+ export declare function LoadTapeDialog(): import("react/jsx-runtime").JSX.Element;
2
+ //# sourceMappingURL=LoadTapeDialog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LoadTapeDialog.d.ts","sourceRoot":"","sources":["../../../src/debugui/components/LoadTapeDialog.tsx"],"names":[],"mappings":"AAGA,wBAAgB,cAAc,4CA4G7B"}
@@ -39,6 +39,10 @@ export type DebugState = {
39
39
  onStepForward: Signal<(() => void) | null>;
40
40
  onJumpForward: Signal<(() => void) | null>;
41
41
  onSeek: Signal<((position: number) => void) | null>;
42
+ onLoadTape: Signal<((bytes: Uint8Array, fileName: string) => void) | null>;
43
+ onReplayLastTape: Signal<(() => void) | null>;
44
+ lastTapeName: Signal<string | null>;
45
+ isLoadDialogOpen: Signal<boolean>;
42
46
  };
43
47
  export declare const debugState: DebugState;
44
48
  /** Cycle through layout modes: off -> letterboxed -> full -> off */
@@ -57,4 +61,8 @@ export declare function resetState(): void;
57
61
  export declare function wirePlaybarHandlers(app: App): void;
58
62
  /** Set up drag-and-drop tape loading on a canvas element */
59
63
  export declare function wireTapeDragDrop(canvas: HTMLCanvasElement, app: App): void;
64
+ /** Check for saved tape and update lastTapeName signal */
65
+ export declare function checkForSavedTape(): Promise<void>;
66
+ /** Wire up tape loading handlers */
67
+ export declare function wireTapeLoadHandlers(app: App): void;
60
68
  //# sourceMappingURL=state.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../src/debugui/state.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../src/debugui/state.ts"],"names":[],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- export declare const styles = "\n/* Reset for shadow DOM */\n* {\n box-sizing: border-box;\n}\n\n/* Layout */\n.fullscreen {\n width: 100vw;\n height: 100vh;\n margin: 0;\n padding: 0;\n overflow: hidden;\n}\n\n.fullscreen .canvas-container {\n width: 100%;\n height: 100%;\n}\n\n.fullscreen canvas {\n width: 100%;\n height: 100%;\n display: block;\n}\n\n.layout {\n display: grid;\n grid-template-areas:\n \"game stats\"\n \"logs logs\";\n grid-template-columns: calc(50% - 0.5rem) calc(50% - 0.5rem);\n grid-template-rows: calc(50% - 0.5rem) calc(50% - 0.5rem);\n gap: 1rem;\n width: 100%;\n height: 100%;\n padding: 1rem;\n}\n\n/* Letterboxed layout - using equal vw/vh percentages keeps game at viewport aspect ratio */\n.layout-letterboxed {\n display: grid;\n grid-template-areas:\n \"top-bar top-bar top-bar\"\n \"left-bar game right-bar\"\n \"bottom-bar bottom-bar bottom-bar\";\n grid-template-columns: 2vw 1fr 2vw;\n grid-template-rows: 2vh 1fr 2vh;\n width: 100vw;\n height: 100vh;\n background: #1a1a1a;\n overflow: hidden;\n overscroll-behavior: none;\n}\n\n.top-bar {\n grid-area: top-bar;\n display: flex;\n align-items: center;\n justify-content: space-between;\n background: #111;\n color: #aaa;\n font-family: monospace;\n font-size: 12px;\n padding: 0;\n}\n\n.top-bar-side-label {\n width: 2vw;\n text-align: center;\n font-size: 9px;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: #666;\n}\n\n.top-bar-center {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 24px;\n flex: 1;\n}\n\n.top-bar-item {\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.top-bar-label {\n opacity: 0.6;\n}\n\n.top-bar-value {\n color: #fff;\n font-weight: 500;\n}\n\n.left-bar {\n grid-area: left-bar;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: flex-end;\n background: #111;\n padding: 4px 0;\n}\n\n.right-bar {\n grid-area: right-bar;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: flex-end;\n background: #111;\n padding: 4px 0;\n}\n\n.vertical-bar {\n width: 12px;\n flex: 1;\n background: #333;\n border-radius: 2px;\n position: relative;\n overflow: hidden;\n}\n\n.vertical-bar-fill {\n position: absolute;\n bottom: 0;\n left: 0;\n right: 0;\n background: #4a9eff;\n border-radius: 2px;\n transition: height 0.1s ease-out;\n}\n\n\n.bottom-bar {\n grid-area: bottom-bar;\n display: flex;\n align-items: center;\n background: #111;\n padding: 0 8px;\n gap: 8px;\n}\n\n.playbar-controls {\n display: flex;\n align-items: center;\n gap: 2px;\n flex-shrink: 0;\n}\n\n.playbar-btn {\n width: 1.5vh;\n height: 1.5vh;\n min-width: 18px;\n min-height: 18px;\n border: none;\n outline: none;\n background: transparent;\n color: #888;\n font-size: 10px;\n cursor: pointer;\n border-radius: 2px;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: background 0.15s, color 0.15s;\n position: relative;\n}\n\n.playbar-btn:hover {\n background: #333;\n color: #fff;\n}\n\n.playbar-btn:hover .tooltip {\n opacity: 1;\n visibility: visible;\n}\n\n.tooltip {\n position: absolute;\n bottom: calc(100% + 4px);\n left: 50%;\n transform: translateX(-50%);\n background: #222;\n color: #ccc;\n padding: 4px 8px;\n border-radius: 4px;\n font-size: 10px;\n white-space: nowrap;\n opacity: 0;\n visibility: hidden;\n transition: opacity 0.15s;\n pointer-events: none;\n z-index: 10;\n}\n\n.tooltip-left {\n left: 0;\n transform: none;\n}\n\n.tooltip kbd {\n background: #444;\n padding: 1px 4px;\n border-radius: 2px;\n margin-left: 4px;\n font-family: monospace;\n}\n\n.seek-bar {\n flex: 1;\n height: 16px;\n background: #222;\n border-radius: 4px;\n position: relative;\n cursor: pointer;\n overflow: hidden;\n}\n\n.seek-bar-fill {\n position: absolute;\n top: 0;\n left: 0;\n bottom: 0;\n background: linear-gradient(to right, #4a2070, #7b3fa0);\n border-radius: 4px;\n transition: width 0.1s ease-out;\n}\n\n.seek-bar-position {\n position: absolute;\n top: 0;\n bottom: 0;\n width: 2px;\n background: #fff;\n}\n\n.letterboxed-game {\n grid-area: game;\n overflow: hidden;\n}\n\n.letterboxed-game .canvas-container {\n width: 100%;\n height: 100%;\n}\n\n.letterboxed-game canvas {\n width: 100%;\n height: 100%;\n display: block;\n}\n\n.letterboxed-game {\n position: relative;\n}\n\n.letterboxed-game.hmr-flash::after {\n content: \"\";\n position: absolute;\n inset: 0;\n pointer-events: none;\n animation: hmr-pulse 0.3s ease-out forwards;\n}\n\n@keyframes hmr-pulse {\n 0% { box-shadow: inset 0 0 0 36px #7b3fa0; }\n 100% { box-shadow: inset 0 0 0 0 #7b3fa0; }\n}\n\n.game {\n grid-area: game;\n border-radius: 8px;\n overflow: hidden;\n}\n\n.stats {\n grid-area: stats;\n background-color: #f0f0f0;\n padding: 1rem;\n border-radius: 8px;\n overflow: hidden;\n}\n\n.logs {\n grid-area: logs;\n background-color: #f0f0f0;\n padding: 1rem;\n border-radius: 8px;\n overflow: hidden;\n}\n\n/* Canvas container */\n.canvas-container {\n width: 100%;\n height: 100%;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.canvas-container canvas {\n max-width: 100%;\n max-height: 100%;\n}\n\n/* Debug toggle button */\n.debug-toggle {\n position: fixed;\n bottom: 16px;\n right: 16px;\n width: 40px;\n height: 40px;\n border-radius: 50%;\n border: none;\n background-color: rgba(0, 0, 0, 0.5);\n color: white;\n font-size: 18px;\n cursor: pointer;\n z-index: 1000;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: background-color 0.2s;\n}\n\n.debug-toggle:hover {\n background-color: rgba(0, 0, 0, 0.7);\n}\n\n/* Stats panel */\n.stats-panel {\n background: rgba(0, 0, 0, 0.7);\n color: white;\n padding: 12px;\n border-radius: 8px;\n font-family: monospace;\n font-size: 14px;\n max-width: 100%;\n overflow: hidden;\n}\n\n.stats-panel h3 {\n margin: 0 0 8px 0;\n font-size: 14px;\n font-weight: 600;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.stats-panel table {\n width: 100%;\n border-collapse: collapse;\n table-layout: fixed;\n}\n\n.stats-panel tr {\n border-bottom: 1px solid rgba(255, 255, 255, 0.2);\n}\n\n.stats-panel tr:last-child {\n border-bottom: none;\n}\n\n.stats-panel td {\n padding: 4px 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.stats-panel td:first-child {\n opacity: 0.7;\n width: 60%;\n}\n\n.stats-panel td:last-child {\n text-align: right;\n font-weight: 600;\n width: 40%;\n}\n\n.stats-panel p {\n margin: 0;\n opacity: 0.7;\n}\n\n/* Logs panel */\n.logs-list {\n width: 100%;\n height: 100%;\n overflow: auto;\n margin: 0;\n padding: 0;\n}\n\n.logs-list li {\n margin: 0 0 24px 0;\n list-style: none;\n}\n\n.logs-list h3 {\n font-size: 16px;\n font-weight: 500;\n margin: 0;\n}\n\n.logs-list .ws {\n color: darkolivegreen;\n}\n\n.logs-list .webrtc {\n color: darkmagenta;\n}\n\n.logs-list .rollback {\n color: darkblue;\n}\n\n.logs-list .local {\n color: #333;\n}\n\n.logs-list .content {\n font-size: 16px;\n}\n\n.logs-list p {\n margin: 4px 0;\n}\n\n.logs-list pre {\n margin: 0;\n white-space: pre-wrap;\n word-break: break-word;\n background-color: oldlace;\n padding: 8px;\n border-radius: 4px;\n border: 1px inset lavender;\n}\n";
1
+ export declare const styles = "\n/* Reset for shadow DOM */\n* {\n box-sizing: border-box;\n}\n\n/* Layout */\n.fullscreen {\n width: 100vw;\n height: 100vh;\n margin: 0;\n padding: 0;\n overflow: hidden;\n}\n\n.fullscreen .canvas-container {\n width: 100%;\n height: 100%;\n}\n\n.fullscreen canvas {\n width: 100%;\n height: 100%;\n display: block;\n}\n\n.layout {\n display: grid;\n grid-template-areas:\n \"game stats\"\n \"logs logs\";\n grid-template-columns: calc(50% - 0.5rem) calc(50% - 0.5rem);\n grid-template-rows: calc(50% - 0.5rem) calc(50% - 0.5rem);\n gap: 1rem;\n width: 100%;\n height: 100%;\n padding: 1rem;\n}\n\n/* Letterboxed layout - using equal vw/vh percentages keeps game at viewport aspect ratio */\n.layout-letterboxed {\n display: grid;\n grid-template-areas:\n \"top-bar top-bar top-bar\"\n \"left-bar game right-bar\"\n \"bottom-bar bottom-bar bottom-bar\";\n grid-template-columns: 2vw 1fr 2vw;\n grid-template-rows: 2vh 1fr 2vh;\n width: 100vw;\n height: 100vh;\n background: #1a1a1a;\n overflow: hidden;\n overscroll-behavior: none;\n}\n\n.top-bar {\n grid-area: top-bar;\n display: flex;\n align-items: center;\n justify-content: space-between;\n background: #111;\n color: #aaa;\n font-family: monospace;\n font-size: 12px;\n padding: 0;\n}\n\n.top-bar-side-label {\n width: 2vw;\n text-align: center;\n font-size: 9px;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: #666;\n}\n\n.top-bar-center {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 24px;\n flex: 1;\n}\n\n.top-bar-item {\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.top-bar-label {\n opacity: 0.6;\n}\n\n.top-bar-value {\n color: #fff;\n font-weight: 500;\n}\n\n.left-bar {\n grid-area: left-bar;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: flex-end;\n background: #111;\n padding: 4px 0;\n}\n\n.right-bar {\n grid-area: right-bar;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: flex-end;\n background: #111;\n padding: 4px 0;\n}\n\n.vertical-bar {\n width: 12px;\n flex: 1;\n background: #333;\n border-radius: 2px;\n position: relative;\n overflow: hidden;\n}\n\n.vertical-bar-fill {\n position: absolute;\n bottom: 0;\n left: 0;\n right: 0;\n background: #4a9eff;\n border-radius: 2px;\n transition: height 0.1s ease-out;\n}\n\n\n.bottom-bar {\n grid-area: bottom-bar;\n display: flex;\n align-items: center;\n background: #111;\n padding: 0 8px;\n gap: 8px;\n}\n\n.playbar-controls {\n display: flex;\n align-items: center;\n gap: 2px;\n flex-shrink: 0;\n}\n\n.playbar-btn {\n width: 1.5vh;\n height: 1.5vh;\n min-width: 18px;\n min-height: 18px;\n border: none;\n outline: none;\n background: transparent;\n color: #888;\n font-size: 10px;\n cursor: pointer;\n border-radius: 2px;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: background 0.15s, color 0.15s;\n position: relative;\n}\n\n.playbar-btn:hover {\n background: #333;\n color: #fff;\n}\n\n.playbar-btn:hover .tooltip {\n opacity: 1;\n visibility: visible;\n}\n\n.tooltip {\n position: absolute;\n bottom: calc(100% + 4px);\n left: 50%;\n transform: translateX(-50%);\n background: #222;\n color: #ccc;\n padding: 4px 8px;\n border-radius: 4px;\n font-size: 10px;\n white-space: nowrap;\n opacity: 0;\n visibility: hidden;\n transition: opacity 0.15s;\n pointer-events: none;\n z-index: 10;\n}\n\n.tooltip-left {\n left: 0;\n transform: none;\n}\n\n.tooltip kbd {\n background: #444;\n padding: 1px 4px;\n border-radius: 2px;\n margin-left: 4px;\n font-family: monospace;\n}\n\n.seek-bar {\n flex: 1;\n height: 16px;\n background: #222;\n border-radius: 4px;\n position: relative;\n cursor: pointer;\n overflow: hidden;\n}\n\n.seek-bar-fill {\n position: absolute;\n top: 0;\n left: 0;\n bottom: 0;\n background: linear-gradient(to right, #4a2070, #7b3fa0);\n border-radius: 4px;\n transition: width 0.1s ease-out;\n}\n\n.seek-bar-position {\n position: absolute;\n top: 0;\n bottom: 0;\n width: 2px;\n background: #fff;\n}\n\n.letterboxed-game {\n grid-area: game;\n overflow: hidden;\n}\n\n.letterboxed-game .canvas-container {\n width: 100%;\n height: 100%;\n}\n\n.letterboxed-game canvas {\n width: 100%;\n height: 100%;\n display: block;\n}\n\n.letterboxed-game {\n position: relative;\n}\n\n.letterboxed-game.hmr-flash::after {\n content: \"\";\n position: absolute;\n inset: 0;\n pointer-events: none;\n animation: hmr-pulse 0.3s ease-out forwards;\n}\n\n@keyframes hmr-pulse {\n 0% { box-shadow: inset 0 0 0 36px #7b3fa0; }\n 100% { box-shadow: inset 0 0 0 0 #7b3fa0; }\n}\n\n.game {\n grid-area: game;\n border-radius: 8px;\n overflow: hidden;\n}\n\n.stats {\n grid-area: stats;\n background-color: #f0f0f0;\n padding: 1rem;\n border-radius: 8px;\n overflow: hidden;\n}\n\n.logs {\n grid-area: logs;\n background-color: #f0f0f0;\n padding: 1rem;\n border-radius: 8px;\n overflow: hidden;\n}\n\n/* Canvas container */\n.canvas-container {\n width: 100%;\n height: 100%;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.canvas-container canvas {\n max-width: 100%;\n max-height: 100%;\n}\n\n/* Debug toggle button */\n.debug-toggle {\n position: fixed;\n bottom: 16px;\n right: 16px;\n width: 40px;\n height: 40px;\n border-radius: 50%;\n border: none;\n background-color: rgba(0, 0, 0, 0.5);\n color: white;\n font-size: 18px;\n cursor: pointer;\n z-index: 1000;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: background-color 0.2s;\n}\n\n.debug-toggle:hover {\n background-color: rgba(0, 0, 0, 0.7);\n}\n\n/* Stats panel */\n.stats-panel {\n background: rgba(0, 0, 0, 0.7);\n color: white;\n padding: 12px;\n border-radius: 8px;\n font-family: monospace;\n font-size: 14px;\n max-width: 100%;\n overflow: hidden;\n}\n\n.stats-panel h3 {\n margin: 0 0 8px 0;\n font-size: 14px;\n font-weight: 600;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.stats-panel table {\n width: 100%;\n border-collapse: collapse;\n table-layout: fixed;\n}\n\n.stats-panel tr {\n border-bottom: 1px solid rgba(255, 255, 255, 0.2);\n}\n\n.stats-panel tr:last-child {\n border-bottom: none;\n}\n\n.stats-panel td {\n padding: 4px 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.stats-panel td:first-child {\n opacity: 0.7;\n width: 60%;\n}\n\n.stats-panel td:last-child {\n text-align: right;\n font-weight: 600;\n width: 40%;\n}\n\n.stats-panel p {\n margin: 0;\n opacity: 0.7;\n}\n\n/* Logs panel */\n.logs-list {\n width: 100%;\n height: 100%;\n overflow: auto;\n margin: 0;\n padding: 0;\n}\n\n.logs-list li {\n margin: 0 0 24px 0;\n list-style: none;\n}\n\n.logs-list h3 {\n font-size: 16px;\n font-weight: 500;\n margin: 0;\n}\n\n.logs-list .ws {\n color: darkolivegreen;\n}\n\n.logs-list .webrtc {\n color: darkmagenta;\n}\n\n.logs-list .rollback {\n color: darkblue;\n}\n\n.logs-list .local {\n color: #333;\n}\n\n.logs-list .content {\n font-size: 16px;\n}\n\n.logs-list p {\n margin: 4px 0;\n}\n\n.logs-list pre {\n margin: 0;\n white-space: pre-wrap;\n word-break: break-word;\n background-color: oldlace;\n padding: 8px;\n border-radius: 4px;\n border: 1px inset lavender;\n}\n\n/* Load Tape Dialog */\n.load-tape-dialog {\n background: #1a1a1a;\n border: 1px solid #333;\n border-radius: 8px;\n padding: 0;\n color: #ccc;\n font-family: monospace;\n max-width: 320px;\n width: 90vw;\n}\n\n.load-tape-dialog::backdrop {\n background: rgba(0, 0, 0, 0.7);\n}\n\n.load-tape-dialog-content {\n padding: 16px;\n}\n\n.load-tape-dialog h3 {\n margin: 0 0 16px 0;\n font-size: 14px;\n font-weight: 600;\n color: #fff;\n}\n\n.drop-zone {\n border: 2px dashed #444;\n border-radius: 8px;\n padding: 32px 16px;\n text-align: center;\n cursor: pointer;\n transition: border-color 0.15s, background 0.15s;\n}\n\n.drop-zone:hover {\n border-color: #666;\n background: #222;\n}\n\n.drop-zone.drag-over {\n border-color: #7b3fa0;\n background: rgba(123, 63, 160, 0.1);\n}\n\n.drop-zone-text {\n color: #888;\n font-size: 12px;\n line-height: 1.5;\n}\n\n.hidden-file-input {\n display: none;\n}\n\n.replay-last-btn {\n width: 100%;\n margin-top: 12px;\n padding: 8px 12px;\n background: #333;\n border: none;\n border-radius: 4px;\n color: #ccc;\n font-family: monospace;\n font-size: 12px;\n cursor: pointer;\n transition: background 0.15s;\n text-align: left;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.replay-last-btn:hover {\n background: #444;\n color: #fff;\n}\n\n.load-tape-btn {\n margin-left: 4px;\n}\n";
2
2
  //# sourceMappingURL=styles.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"styles.d.ts","sourceRoot":"","sources":["../../src/debugui/styles.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,MAAM,+yOA+blB,CAAC"}
1
+ {"version":3,"file":"styles.d.ts","sourceRoot":"","sources":["../../src/debugui/styles.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,MAAM,oqRAkhBlB,CAAC"}
package/dist/mod.js CHANGED
@@ -1432,7 +1432,7 @@ function readTapeHeader(tape) {
1432
1432
  eventCount: view.getUint16(14, true)
1433
1433
  };
1434
1434
  }
1435
- var DEFAULT_WASM_URL = new URL("https://unpkg.com/@bloopjs/engine@0.0.90/wasm/bloop.wasm");
1435
+ var DEFAULT_WASM_URL = new URL("https://unpkg.com/@bloopjs/engine@0.0.91/wasm/bloop.wasm");
1436
1436
  var MAX_ROLLBACK_FRAMES = 500;
1437
1437
  var TIME_CTX_OFFSET = 0;
1438
1438
  var INPUT_CTX_OFFSET = TIME_CTX_OFFSET + 4;
@@ -3273,7 +3273,7 @@ function readTapeHeader2(tape) {
3273
3273
  eventCount: view.getUint16(14, true)
3274
3274
  };
3275
3275
  }
3276
- var DEFAULT_WASM_URL2 = new URL("https://unpkg.com/@bloopjs/engine@0.0.90/wasm/bloop.wasm");
3276
+ var DEFAULT_WASM_URL2 = new URL("https://unpkg.com/@bloopjs/engine@0.0.91/wasm/bloop.wasm");
3277
3277
  var TIME_CTX_OFFSET2 = 0;
3278
3278
  var INPUT_CTX_OFFSET2 = TIME_CTX_OFFSET2 + 4;
3279
3279
  var EVENTS_OFFSET2 = INPUT_CTX_OFFSET2 + 4;
@@ -3283,6 +3283,7 @@ var SCREEN_CTX_OFFSET2 = NET_CTX_OFFSET2 + 4;
3283
3283
  // src/debugui/mod.ts
3284
3284
  var exports_mod = {};
3285
3285
  __export(exports_mod, {
3286
+ wireTapeLoadHandlers: () => wireTapeLoadHandlers,
3286
3287
  wireTapeDragDrop: () => wireTapeDragDrop,
3287
3288
  wirePlaybarHandlers: () => wirePlaybarHandlers,
3288
3289
  updatePeer: () => updatePeer,
@@ -3294,6 +3295,7 @@ __export(exports_mod, {
3294
3295
  debugState: () => debugState,
3295
3296
  cycleLayout: () => cycleLayout,
3296
3297
  clearLogs: () => clearLogs,
3298
+ checkForSavedTape: () => checkForSavedTape,
3297
3299
  addPeer: () => addPeer,
3298
3300
  addLog: () => addLog,
3299
3301
  DebugUi: () => DebugUi
@@ -3637,6 +3639,45 @@ function p2(n2, t3) {
3637
3639
  var u3 = r2.__H || (r2.__H = { __: [], __h: [] });
3638
3640
  return n2 >= u3.__.length && u3.__.push({}), u3.__[n2];
3639
3641
  }
3642
+ function d2(n2) {
3643
+ return o2 = 1, h2(D2, n2);
3644
+ }
3645
+ function h2(n2, u3, i3) {
3646
+ var o3 = p2(t2++, 2);
3647
+ if (o3.t = n2, !o3.__c && (o3.__ = [i3 ? i3(u3) : D2(undefined, u3), function(n3) {
3648
+ var t3 = o3.__N ? o3.__N[0] : o3.__[0], r3 = o3.t(t3, n3);
3649
+ t3 !== r3 && (o3.__N = [r3, o3.__[1]], o3.__c.setState({}));
3650
+ }], o3.__c = r2, !r2.__f)) {
3651
+ var f3 = function(n3, t3, r3) {
3652
+ if (!o3.__c.__H)
3653
+ return true;
3654
+ var u4 = o3.__c.__H.__.filter(function(n4) {
3655
+ return !!n4.__c;
3656
+ });
3657
+ if (u4.every(function(n4) {
3658
+ return !n4.__N;
3659
+ }))
3660
+ return !c3 || c3.call(this, n3, t3, r3);
3661
+ var i4 = o3.__c.props !== n3;
3662
+ return u4.forEach(function(n4) {
3663
+ if (n4.__N) {
3664
+ var t4 = n4.__[0];
3665
+ n4.__ = n4.__N, n4.__N = undefined, t4 !== n4.__[0] && (i4 = true);
3666
+ }
3667
+ }), c3 && c3.call(this, n3, t3, r3) || i4;
3668
+ };
3669
+ r2.__f = true;
3670
+ var { shouldComponentUpdate: c3, componentWillUpdate: e3 } = r2;
3671
+ r2.componentWillUpdate = function(n3, t3, r3) {
3672
+ if (this.__e) {
3673
+ var u4 = c3;
3674
+ c3 = undefined, f3(n3, t3, r3), c3 = u4;
3675
+ }
3676
+ e3 && e3.call(this, n3, t3, r3);
3677
+ }, r2.shouldComponentUpdate = f3;
3678
+ }
3679
+ return o3.__N || o3.__;
3680
+ }
3640
3681
  function y2(n2, u3) {
3641
3682
  var i3 = p2(t2++, 3);
3642
3683
  !c2.__s && C2(i3.__H, u3) && (i3.__ = n2, i3.u = u3, r2.__H.__h.push(i3));
@@ -3723,15 +3764,18 @@ function C2(n2, t3) {
3723
3764
  return t4 !== n2[r3];
3724
3765
  });
3725
3766
  }
3767
+ function D2(n2, t3) {
3768
+ return typeof t3 == "function" ? t3(n2) : t3;
3769
+ }
3726
3770
 
3727
3771
  // ../../node_modules/@preact/signals-core/dist/signals-core.module.js
3728
3772
  var i3 = Symbol.for("preact-signals");
3729
3773
  function t3() {
3730
3774
  if (!(s3 > 1)) {
3731
3775
  var i4, t4 = false;
3732
- while (h2 !== undefined) {
3733
- var r3 = h2;
3734
- h2 = undefined;
3776
+ while (h3 !== undefined) {
3777
+ var r3 = h3;
3778
+ h3 = undefined;
3735
3779
  f3++;
3736
3780
  while (r3 !== undefined) {
3737
3781
  var o3 = r3.o;
@@ -3766,7 +3810,7 @@ function n2(i4) {
3766
3810
  o3 = t4;
3767
3811
  }
3768
3812
  }
3769
- var h2 = undefined;
3813
+ var h3 = undefined;
3770
3814
  var s3 = 0;
3771
3815
  var f3 = 0;
3772
3816
  var v3 = 0;
@@ -3897,7 +3941,7 @@ Object.defineProperty(u3.prototype, "value", { get: function() {
3897
3941
  }
3898
3942
  }
3899
3943
  } });
3900
- function d2(i4, t4) {
3944
+ function d3(i4, t4) {
3901
3945
  return new u3(i4, t4);
3902
3946
  }
3903
3947
  function c3(i4) {
@@ -4097,8 +4141,8 @@ p3.prototype.S = function() {
4097
4141
  p3.prototype.N = function() {
4098
4142
  if (!(2 & this.f)) {
4099
4143
  this.f |= 2;
4100
- this.o = h2;
4101
- h2 = this;
4144
+ this.o = h3;
4145
+ h3 = this;
4102
4146
  }
4103
4147
  };
4104
4148
  p3.prototype.d = function() {
@@ -4128,12 +4172,12 @@ var s4;
4128
4172
  function l4(i4, n3) {
4129
4173
  l[i4] = n3.bind(null, l[i4] || function() {});
4130
4174
  }
4131
- function d3(i4) {
4175
+ function d4(i4) {
4132
4176
  if (s4)
4133
4177
  s4();
4134
4178
  s4 = i4 && i4.S();
4135
4179
  }
4136
- function h3(i4) {
4180
+ function h4(i4) {
4137
4181
  var r4 = this, f4 = i4.data, o4 = useSignal(f4);
4138
4182
  o4.value = f4;
4139
4183
  var e4 = T2(function() {
@@ -4159,8 +4203,8 @@ function h3(i4) {
4159
4203
  }, []);
4160
4204
  return e4.value;
4161
4205
  }
4162
- h3.displayName = "_st";
4163
- Object.defineProperties(u3.prototype, { constructor: { configurable: true, value: undefined }, type: { configurable: true, value: h3 }, props: { configurable: true, get: function() {
4206
+ h4.displayName = "_st";
4207
+ Object.defineProperties(u3.prototype, { constructor: { configurable: true, value: undefined }, type: { configurable: true, value: h4 }, props: { configurable: true, get: function() {
4164
4208
  return { data: this };
4165
4209
  } }, __b: { configurable: true, value: 1 } });
4166
4210
  l4("__b", function(i4, r4) {
@@ -4180,7 +4224,7 @@ l4("__b", function(i4, r4) {
4180
4224
  i4(r4);
4181
4225
  });
4182
4226
  l4("__r", function(i4, r4) {
4183
- d3();
4227
+ d4();
4184
4228
  var n3, t4 = r4.__c;
4185
4229
  if (t4) {
4186
4230
  t4.__$f &= -2;
@@ -4198,16 +4242,16 @@ l4("__r", function(i4, r4) {
4198
4242
  }();
4199
4243
  }
4200
4244
  v4 = t4;
4201
- d3(n3);
4245
+ d4(n3);
4202
4246
  i4(r4);
4203
4247
  });
4204
4248
  l4("__e", function(i4, r4, n3, t4) {
4205
- d3();
4249
+ d4();
4206
4250
  v4 = undefined;
4207
4251
  i4(r4, n3, t4);
4208
4252
  });
4209
4253
  l4("diffed", function(i4, r4) {
4210
- d3();
4254
+ d4();
4211
4255
  v4 = undefined;
4212
4256
  var n3;
4213
4257
  if (typeof r4.type == "string" && (n3 = r4.__e)) {
@@ -4237,7 +4281,7 @@ l4("diffed", function(i4, r4) {
4237
4281
  i4(r4);
4238
4282
  });
4239
4283
  function p4(i4, r4, n3, t4) {
4240
- var f4 = r4 in i4 && i4.ownerSVGElement === undefined, o4 = d2(n3);
4284
+ var f4 = r4 in i4 && i4.ownerSVGElement === undefined, o4 = d3(n3);
4241
4285
  return { o: function(i5, r5) {
4242
4286
  o4.value = i5;
4243
4287
  t4 = r5;
@@ -4310,7 +4354,7 @@ x.prototype.shouldComponentUpdate = function(i4, r4) {
4310
4354
  };
4311
4355
  function useSignal(i4) {
4312
4356
  return T2(function() {
4313
- return d2(i4);
4357
+ return d3(i4);
4314
4358
  }, []);
4315
4359
  }
4316
4360
  function useSignalEffect(i4) {
@@ -4324,30 +4368,34 @@ function useSignalEffect(i4) {
4324
4368
  }
4325
4369
 
4326
4370
  // src/debugui/state.ts
4327
- var layoutMode = d2("off");
4328
- var netStatus = d2({
4371
+ var layoutMode = d3("off");
4372
+ var netStatus = d3({
4329
4373
  ourId: null,
4330
4374
  remoteId: null,
4331
4375
  rtt: null,
4332
4376
  peers: []
4333
4377
  });
4334
- var logs = d2([]);
4335
- var fps = d2(0);
4336
- var frameTime = d2(0);
4337
- var snapshotSize = d2(0);
4338
- var frameNumber = d2(0);
4339
- var hmrFlash = d2(false);
4340
- var isPlaying = d2(true);
4341
- var tapeUtilization = d2(0);
4342
- var playheadPosition = d2(0);
4343
- var tapeStartFrame = d2(0);
4344
- var tapeFrameCount = d2(0);
4345
- var onJumpBack = d2(null);
4346
- var onStepBack = d2(null);
4347
- var onPlayPause = d2(null);
4348
- var onStepForward = d2(null);
4349
- var onJumpForward = d2(null);
4350
- var onSeek = d2(null);
4378
+ var logs = d3([]);
4379
+ var fps = d3(0);
4380
+ var frameTime = d3(0);
4381
+ var snapshotSize = d3(0);
4382
+ var frameNumber = d3(0);
4383
+ var hmrFlash = d3(false);
4384
+ var isPlaying = d3(true);
4385
+ var tapeUtilization = d3(0);
4386
+ var playheadPosition = d3(0);
4387
+ var tapeStartFrame = d3(0);
4388
+ var tapeFrameCount = d3(0);
4389
+ var onJumpBack = d3(null);
4390
+ var onStepBack = d3(null);
4391
+ var onPlayPause = d3(null);
4392
+ var onStepForward = d3(null);
4393
+ var onJumpForward = d3(null);
4394
+ var onSeek = d3(null);
4395
+ var onLoadTape = d3(null);
4396
+ var onReplayLastTape = d3(null);
4397
+ var lastTapeName = d3(null);
4398
+ var isLoadDialogOpen = d3(false);
4351
4399
  var debugState = {
4352
4400
  layoutMode,
4353
4401
  isVisible: w3(() => layoutMode.value !== "off"),
@@ -4373,7 +4421,11 @@ var debugState = {
4373
4421
  onPlayPause,
4374
4422
  onStepForward,
4375
4423
  onJumpForward,
4376
- onSeek
4424
+ onSeek,
4425
+ onLoadTape,
4426
+ onReplayLastTape,
4427
+ lastTapeName,
4428
+ isLoadDialogOpen
4377
4429
  };
4378
4430
  function cycleLayout() {
4379
4431
  const current = layoutMode.value;
@@ -4529,6 +4581,61 @@ function wireTapeDragDrop(canvas, app) {
4529
4581
  app.loadTape(bytes);
4530
4582
  });
4531
4583
  }
4584
+ var TAPE_DB_NAME = "bloop-debug";
4585
+ var TAPE_STORE_NAME = "tapes";
4586
+ var TAPE_KEY = "last";
4587
+ function openTapeDB() {
4588
+ return new Promise((resolve, reject) => {
4589
+ const request = indexedDB.open(TAPE_DB_NAME, 1);
4590
+ request.onerror = () => reject(request.error);
4591
+ request.onsuccess = () => resolve(request.result);
4592
+ request.onupgradeneeded = () => {
4593
+ request.result.createObjectStore(TAPE_STORE_NAME);
4594
+ };
4595
+ });
4596
+ }
4597
+ async function saveTapeToStorage(bytes, fileName) {
4598
+ const db = await openTapeDB();
4599
+ return new Promise((resolve, reject) => {
4600
+ const tx = db.transaction(TAPE_STORE_NAME, "readwrite");
4601
+ tx.objectStore(TAPE_STORE_NAME).put({ bytes, fileName }, TAPE_KEY);
4602
+ tx.oncomplete = () => resolve();
4603
+ tx.onerror = () => reject(tx.error);
4604
+ });
4605
+ }
4606
+ async function loadTapeFromStorage() {
4607
+ try {
4608
+ const db = await openTapeDB();
4609
+ return new Promise((resolve, reject) => {
4610
+ const tx = db.transaction(TAPE_STORE_NAME, "readonly");
4611
+ const request = tx.objectStore(TAPE_STORE_NAME).get(TAPE_KEY);
4612
+ request.onsuccess = () => resolve(request.result ?? null);
4613
+ request.onerror = () => reject(request.error);
4614
+ });
4615
+ } catch {
4616
+ return null;
4617
+ }
4618
+ }
4619
+ async function checkForSavedTape() {
4620
+ const saved = await loadTapeFromStorage();
4621
+ debugState.lastTapeName.value = saved?.fileName ?? null;
4622
+ }
4623
+ function wireTapeLoadHandlers(app) {
4624
+ debugState.onLoadTape.value = async (bytes, fileName) => {
4625
+ app.loadTape(bytes);
4626
+ await saveTapeToStorage(bytes, fileName);
4627
+ debugState.lastTapeName.value = fileName;
4628
+ debugState.isLoadDialogOpen.value = false;
4629
+ };
4630
+ debugState.onReplayLastTape.value = async () => {
4631
+ const saved = await loadTapeFromStorage();
4632
+ if (saved) {
4633
+ app.loadTape(saved.bytes);
4634
+ debugState.isLoadDialogOpen.value = false;
4635
+ }
4636
+ };
4637
+ checkForSavedTape();
4638
+ }
4532
4639
  // ../../node_modules/preact/jsx-runtime/dist/jsxRuntime.module.js
4533
4640
  var f4 = 0;
4534
4641
  function u4(e4, t4, n3, o4, i4, u5) {
@@ -4889,6 +4996,108 @@ function VerticalBar({
4889
4996
  }, undefined, false, undefined, this);
4890
4997
  }
4891
4998
 
4999
+ // src/debugui/components/LoadTapeDialog.tsx
5000
+ function LoadTapeDialog() {
5001
+ const dialogRef = A2(null);
5002
+ const fileInputRef = A2(null);
5003
+ const [isDragOver, setIsDragOver] = d2(false);
5004
+ const isOpen = debugState.isLoadDialogOpen.value;
5005
+ const lastTapeName2 = debugState.lastTapeName.value;
5006
+ y2(() => {
5007
+ const dialog = dialogRef.current;
5008
+ if (!dialog)
5009
+ return;
5010
+ if (isOpen && !dialog.open) {
5011
+ dialog.showModal();
5012
+ } else if (!isOpen && dialog.open) {
5013
+ dialog.close();
5014
+ }
5015
+ }, [isOpen]);
5016
+ const handleClose = q2(() => {
5017
+ debugState.isLoadDialogOpen.value = false;
5018
+ }, []);
5019
+ const handleFileSelect = q2(async (file) => {
5020
+ if (!file.name.endsWith(".bloop"))
5021
+ return;
5022
+ const bytes = new Uint8Array(await file.arrayBuffer());
5023
+ debugState.onLoadTape.value?.(bytes, file.name);
5024
+ }, []);
5025
+ const handleDropZoneClick = q2(() => {
5026
+ fileInputRef.current?.click();
5027
+ }, []);
5028
+ const handleFileInputChange = q2((e4) => {
5029
+ const input = e4.currentTarget;
5030
+ const file = input.files?.[0];
5031
+ if (file) {
5032
+ handleFileSelect(file);
5033
+ input.value = "";
5034
+ }
5035
+ }, [handleFileSelect]);
5036
+ const handleDragOver = q2((e4) => {
5037
+ e4.preventDefault();
5038
+ if (e4.dataTransfer)
5039
+ e4.dataTransfer.dropEffect = "copy";
5040
+ setIsDragOver(true);
5041
+ }, []);
5042
+ const handleDragLeave = q2(() => {
5043
+ setIsDragOver(false);
5044
+ }, []);
5045
+ const handleDrop = q2((e4) => {
5046
+ e4.preventDefault();
5047
+ setIsDragOver(false);
5048
+ const file = e4.dataTransfer?.files[0];
5049
+ if (file) {
5050
+ handleFileSelect(file);
5051
+ }
5052
+ }, [handleFileSelect]);
5053
+ const handleReplayLast = q2(() => {
5054
+ debugState.onReplayLastTape.value?.();
5055
+ }, []);
5056
+ return /* @__PURE__ */ u4("dialog", {
5057
+ ref: dialogRef,
5058
+ className: "load-tape-dialog",
5059
+ onClose: handleClose,
5060
+ children: /* @__PURE__ */ u4("div", {
5061
+ className: "load-tape-dialog-content",
5062
+ children: [
5063
+ /* @__PURE__ */ u4("h3", {
5064
+ children: "Load Tape"
5065
+ }, undefined, false, undefined, this),
5066
+ /* @__PURE__ */ u4("div", {
5067
+ className: `drop-zone ${isDragOver ? "drag-over" : ""}`,
5068
+ onClick: handleDropZoneClick,
5069
+ onDragOver: handleDragOver,
5070
+ onDragLeave: handleDragLeave,
5071
+ onDrop: handleDrop,
5072
+ children: /* @__PURE__ */ u4("span", {
5073
+ className: "drop-zone-text",
5074
+ children: [
5075
+ "Drop .bloop file here",
5076
+ /* @__PURE__ */ u4("br", {}, undefined, false, undefined, this),
5077
+ "or click to browse"
5078
+ ]
5079
+ }, undefined, true, undefined, this)
5080
+ }, undefined, false, undefined, this),
5081
+ /* @__PURE__ */ u4("input", {
5082
+ ref: fileInputRef,
5083
+ type: "file",
5084
+ accept: ".bloop",
5085
+ className: "hidden-file-input",
5086
+ onChange: handleFileInputChange
5087
+ }, undefined, false, undefined, this),
5088
+ lastTapeName2 && /* @__PURE__ */ u4("button", {
5089
+ className: "replay-last-btn",
5090
+ onClick: handleReplayLast,
5091
+ children: [
5092
+ "Replay last: ",
5093
+ lastTapeName2
5094
+ ]
5095
+ }, undefined, true, undefined, this)
5096
+ ]
5097
+ }, undefined, true, undefined, this)
5098
+ }, undefined, false, undefined, this);
5099
+ }
5100
+
4892
5101
  // src/debugui/components/BottomBar.tsx
4893
5102
  function useRepeatOnHold(action) {
4894
5103
  const rafId = A2(null);
@@ -4975,6 +5184,9 @@ function BottomBar() {
4975
5184
  debugState.onSeek.value?.(ratio);
4976
5185
  }, []);
4977
5186
  const seekDrag = useSeekDrag(handleSeek);
5187
+ const handleLoadTapeClick = q2(() => {
5188
+ debugState.isLoadDialogOpen.value = true;
5189
+ }, []);
4978
5190
  return /* @__PURE__ */ u4("div", {
4979
5191
  className: "bottom-bar",
4980
5192
  children: [
@@ -5061,6 +5273,17 @@ function BottomBar() {
5061
5273
  ]
5062
5274
  }, undefined, true, undefined, this)
5063
5275
  ]
5276
+ }, undefined, true, undefined, this),
5277
+ /* @__PURE__ */ u4("button", {
5278
+ className: "playbar-btn load-tape-btn",
5279
+ onClick: handleLoadTapeClick,
5280
+ children: [
5281
+ "Load",
5282
+ /* @__PURE__ */ u4("span", {
5283
+ className: "tooltip",
5284
+ children: "Load tape"
5285
+ }, undefined, false, undefined, this)
5286
+ ]
5064
5287
  }, undefined, true, undefined, this)
5065
5288
  ]
5066
5289
  }, undefined, true, undefined, this),
@@ -5077,7 +5300,8 @@ function BottomBar() {
5077
5300
  style: { left: `${playheadPosition2 * tapeUtilization2 * 100}%` }
5078
5301
  }, undefined, false, undefined, this)
5079
5302
  ]
5080
- }, undefined, true, undefined, this)
5303
+ }, undefined, true, undefined, this),
5304
+ /* @__PURE__ */ u4(LoadTapeDialog, {}, undefined, false, undefined, this)
5081
5305
  ]
5082
5306
  }, undefined, true, undefined, this);
5083
5307
  }
@@ -5644,6 +5868,89 @@ var styles = `
5644
5868
  border-radius: 4px;
5645
5869
  border: 1px inset lavender;
5646
5870
  }
5871
+
5872
+ /* Load Tape Dialog */
5873
+ .load-tape-dialog {
5874
+ background: #1a1a1a;
5875
+ border: 1px solid #333;
5876
+ border-radius: 8px;
5877
+ padding: 0;
5878
+ color: #ccc;
5879
+ font-family: monospace;
5880
+ max-width: 320px;
5881
+ width: 90vw;
5882
+ }
5883
+
5884
+ .load-tape-dialog::backdrop {
5885
+ background: rgba(0, 0, 0, 0.7);
5886
+ }
5887
+
5888
+ .load-tape-dialog-content {
5889
+ padding: 16px;
5890
+ }
5891
+
5892
+ .load-tape-dialog h3 {
5893
+ margin: 0 0 16px 0;
5894
+ font-size: 14px;
5895
+ font-weight: 600;
5896
+ color: #fff;
5897
+ }
5898
+
5899
+ .drop-zone {
5900
+ border: 2px dashed #444;
5901
+ border-radius: 8px;
5902
+ padding: 32px 16px;
5903
+ text-align: center;
5904
+ cursor: pointer;
5905
+ transition: border-color 0.15s, background 0.15s;
5906
+ }
5907
+
5908
+ .drop-zone:hover {
5909
+ border-color: #666;
5910
+ background: #222;
5911
+ }
5912
+
5913
+ .drop-zone.drag-over {
5914
+ border-color: #7b3fa0;
5915
+ background: rgba(123, 63, 160, 0.1);
5916
+ }
5917
+
5918
+ .drop-zone-text {
5919
+ color: #888;
5920
+ font-size: 12px;
5921
+ line-height: 1.5;
5922
+ }
5923
+
5924
+ .hidden-file-input {
5925
+ display: none;
5926
+ }
5927
+
5928
+ .replay-last-btn {
5929
+ width: 100%;
5930
+ margin-top: 12px;
5931
+ padding: 8px 12px;
5932
+ background: #333;
5933
+ border: none;
5934
+ border-radius: 4px;
5935
+ color: #ccc;
5936
+ font-family: monospace;
5937
+ font-size: 12px;
5938
+ cursor: pointer;
5939
+ transition: background 0.15s;
5940
+ text-align: left;
5941
+ overflow: hidden;
5942
+ text-overflow: ellipsis;
5943
+ white-space: nowrap;
5944
+ }
5945
+
5946
+ .replay-last-btn:hover {
5947
+ background: #444;
5948
+ color: #fff;
5949
+ }
5950
+
5951
+ .load-tape-btn {
5952
+ margin-left: 4px;
5953
+ }
5647
5954
  `;
5648
5955
 
5649
5956
  // src/debugui/DebugUi.ts
@@ -6671,6 +6978,7 @@ class App {
6671
6978
  this.#debugUi = new DebugUi(opts);
6672
6979
  wirePlaybarHandlers(this);
6673
6980
  wireTapeDragDrop(this.#debugUi.canvas, this);
6981
+ wireTapeLoadHandlers(this);
6674
6982
  return this.#debugUi;
6675
6983
  }
6676
6984
  get debugUi() {
@@ -6954,5 +7262,5 @@ export {
6954
7262
  App
6955
7263
  };
6956
7264
 
6957
- //# debugId=669ECA7E8ACBF62064756E2164756E21
7265
+ //# debugId=3429E07BC69AE66A64756E2164756E21
6958
7266
  //# sourceMappingURL=mod.js.map