@motion-core/motion-gpu 0.7.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +40 -34
- package/dist/motion-gpu.css +295 -0
- package/dist/vue/FragCanvas.js +8 -0
- package/dist/vue/FragCanvas.js.map +1 -0
- package/dist/vue/FragCanvas.vue.d.ts +49 -0
- package/dist/vue/FragCanvas.vue.d.ts.map +1 -0
- package/dist/vue/FragCanvas.vue_vue_type_script_setup_true_lang.js +228 -0
- package/dist/vue/FragCanvas.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/vue/MotionGPUErrorOverlay.js +8 -0
- package/dist/vue/MotionGPUErrorOverlay.js.map +1 -0
- package/dist/vue/MotionGPUErrorOverlay.vue.d.ts +8 -0
- package/dist/vue/MotionGPUErrorOverlay.vue.d.ts.map +1 -0
- package/dist/vue/MotionGPUErrorOverlay.vue_vue_type_script_setup_true_lang.js +166 -0
- package/dist/vue/MotionGPUErrorOverlay.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/vue/Portal.js +7 -0
- package/dist/vue/Portal.js.map +1 -0
- package/dist/vue/Portal.vue.d.ts +18 -0
- package/dist/vue/Portal.vue.d.ts.map +1 -0
- package/dist/vue/Portal.vue_vue_type_script_setup_true_lang.js +29 -0
- package/dist/vue/Portal.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/vue/advanced.d.ts +12 -0
- package/dist/vue/advanced.d.ts.map +1 -0
- package/dist/vue/advanced.js +15 -0
- package/dist/vue/frame-context.d.ts +22 -0
- package/dist/vue/frame-context.d.ts.map +1 -0
- package/dist/vue/frame-context.js +38 -0
- package/dist/vue/frame-context.js.map +1 -0
- package/dist/vue/index.d.ts +21 -0
- package/dist/vue/index.d.ts.map +1 -0
- package/dist/vue/index.js +14 -0
- package/dist/vue/motiongpu-context.d.ts +81 -0
- package/dist/vue/motiongpu-context.d.ts.map +1 -0
- package/dist/vue/motiongpu-context.js +29 -0
- package/dist/vue/motiongpu-context.js.map +1 -0
- package/dist/vue/shims-vue.d.js +0 -0
- package/dist/vue/use-motiongpu-user-context.d.ts +44 -0
- package/dist/vue/use-motiongpu-user-context.d.ts.map +1 -0
- package/dist/vue/use-motiongpu-user-context.js +76 -0
- package/dist/vue/use-motiongpu-user-context.js.map +1 -0
- package/dist/vue/use-pointer.d.ts +94 -0
- package/dist/vue/use-pointer.d.ts.map +1 -0
- package/dist/vue/use-pointer.js +298 -0
- package/dist/vue/use-pointer.js.map +1 -0
- package/dist/vue/use-texture.d.ts +45 -0
- package/dist/vue/use-texture.d.ts.map +1 -0
- package/dist/vue/use-texture.js +135 -0
- package/dist/vue/use-texture.js.map +1 -0
- package/package.json +25 -7
- package/src/lib/vue/FragCanvas.vue +294 -0
- package/src/lib/vue/MotionGPUErrorOverlay.vue +518 -0
- package/src/lib/vue/Portal.vue +46 -0
- package/src/lib/vue/advanced.ts +32 -0
- package/src/lib/vue/frame-context.ts +96 -0
- package/src/lib/vue/index.ts +78 -0
- package/src/lib/vue/motiongpu-context.ts +97 -0
- package/src/lib/vue/shims-vue.d.ts +6 -0
- package/src/lib/vue/use-motiongpu-user-context.ts +145 -0
- package/src/lib/vue/use-pointer.ts +514 -0
- package/src/lib/vue/use-texture.ts +232 -0
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
import { toMotionGPUErrorReport } from "../core/error-report.js";
|
|
2
|
+
import { createCurrentWritable } from "../core/current-value.js";
|
|
3
|
+
import { createFrameRegistry } from "../core/frame-registry.js";
|
|
4
|
+
import { createMotionGPURuntimeLoop } from "../core/runtime-loop.js";
|
|
5
|
+
import { provideFrameRegistry } from "./frame-context.js";
|
|
6
|
+
import { provideMotionGPUContext } from "./motiongpu-context.js";
|
|
7
|
+
import MotionGPUErrorOverlay_default from "./MotionGPUErrorOverlay.js";
|
|
8
|
+
import { computed, createCommentVNode, createElementBlock, createElementVNode, createVNode, defineComponent, normalizeClass, normalizeStyle, onBeforeUnmount, onMounted, openBlock, renderSlot, shallowRef, unref, useTemplateRef, watch } from "vue";
|
|
9
|
+
//#region src/lib/vue/FragCanvas.vue?vue&type=script&setup=true&lang.ts
|
|
10
|
+
var initialDpr = typeof window === "undefined" ? 1 : window.devicePixelRatio ?? 1;
|
|
11
|
+
var FragCanvas_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
|
|
12
|
+
__name: "FragCanvas",
|
|
13
|
+
props: {
|
|
14
|
+
material: {},
|
|
15
|
+
renderTargets: { default: () => ({}) },
|
|
16
|
+
passes: { default: () => [] },
|
|
17
|
+
clearColor: { default: () => [
|
|
18
|
+
0,
|
|
19
|
+
0,
|
|
20
|
+
0,
|
|
21
|
+
1
|
|
22
|
+
] },
|
|
23
|
+
outputColorSpace: { default: "srgb" },
|
|
24
|
+
renderMode: { default: "always" },
|
|
25
|
+
autoRender: {
|
|
26
|
+
type: Boolean,
|
|
27
|
+
default: true
|
|
28
|
+
},
|
|
29
|
+
maxDelta: { default: .1 },
|
|
30
|
+
adapterOptions: {},
|
|
31
|
+
deviceDescriptor: {},
|
|
32
|
+
dpr: { default: () => initialDpr },
|
|
33
|
+
showErrorOverlay: {
|
|
34
|
+
type: Boolean,
|
|
35
|
+
default: true
|
|
36
|
+
},
|
|
37
|
+
onError: {},
|
|
38
|
+
errorHistoryLimit: { default: 0 },
|
|
39
|
+
onErrorHistory: {},
|
|
40
|
+
canvasClass: { default: "" },
|
|
41
|
+
canvasStyle: {}
|
|
42
|
+
},
|
|
43
|
+
setup(__props) {
|
|
44
|
+
const props = __props;
|
|
45
|
+
const wrapperStyle = Object.freeze({
|
|
46
|
+
position: "relative",
|
|
47
|
+
width: "100%",
|
|
48
|
+
height: "100%",
|
|
49
|
+
minWidth: "0",
|
|
50
|
+
minHeight: "0",
|
|
51
|
+
overflow: "hidden"
|
|
52
|
+
});
|
|
53
|
+
const baseCanvasStyle = Object.freeze({
|
|
54
|
+
position: "absolute",
|
|
55
|
+
inset: "0",
|
|
56
|
+
display: "block",
|
|
57
|
+
width: "100%",
|
|
58
|
+
height: "100%"
|
|
59
|
+
});
|
|
60
|
+
const resolvedCanvasStyle = computed(() => [baseCanvasStyle, props.canvasStyle]);
|
|
61
|
+
const canvasRef = useTemplateRef("canvasEl");
|
|
62
|
+
const errorReport = shallowRef(null);
|
|
63
|
+
const errorHistory = shallowRef([]);
|
|
64
|
+
const registry = createFrameRegistry({ maxDelta: .1 });
|
|
65
|
+
provideFrameRegistry(registry);
|
|
66
|
+
let requestFrameSignal = null;
|
|
67
|
+
let runtimeLoopHandle = null;
|
|
68
|
+
const requestFrame = () => {
|
|
69
|
+
requestFrameSignal?.();
|
|
70
|
+
};
|
|
71
|
+
const invalidateFrame = () => {
|
|
72
|
+
registry.invalidate();
|
|
73
|
+
requestFrame();
|
|
74
|
+
};
|
|
75
|
+
const advanceFrame = () => {
|
|
76
|
+
registry.advance();
|
|
77
|
+
requestFrame();
|
|
78
|
+
};
|
|
79
|
+
const size = createCurrentWritable({
|
|
80
|
+
width: 0,
|
|
81
|
+
height: 0
|
|
82
|
+
});
|
|
83
|
+
const dprState = createCurrentWritable(initialDpr, requestFrame);
|
|
84
|
+
const maxDeltaState = createCurrentWritable(.1, (value) => {
|
|
85
|
+
registry.setMaxDelta(value);
|
|
86
|
+
requestFrame();
|
|
87
|
+
});
|
|
88
|
+
const renderModeState = createCurrentWritable("always", (value) => {
|
|
89
|
+
registry.setRenderMode(value);
|
|
90
|
+
requestFrame();
|
|
91
|
+
});
|
|
92
|
+
const autoRenderState = createCurrentWritable(true, (value) => {
|
|
93
|
+
registry.setAutoRender(value);
|
|
94
|
+
requestFrame();
|
|
95
|
+
});
|
|
96
|
+
provideMotionGPUContext({
|
|
97
|
+
get canvas() {
|
|
98
|
+
return canvasRef.value ?? void 0;
|
|
99
|
+
},
|
|
100
|
+
size,
|
|
101
|
+
dpr: dprState,
|
|
102
|
+
maxDelta: maxDeltaState,
|
|
103
|
+
renderMode: renderModeState,
|
|
104
|
+
autoRender: autoRenderState,
|
|
105
|
+
user: createCurrentWritable({}),
|
|
106
|
+
invalidate: invalidateFrame,
|
|
107
|
+
advance: advanceFrame,
|
|
108
|
+
scheduler: {
|
|
109
|
+
createStage: registry.createStage,
|
|
110
|
+
getStage: registry.getStage,
|
|
111
|
+
setDiagnosticsEnabled: registry.setDiagnosticsEnabled,
|
|
112
|
+
getDiagnosticsEnabled: registry.getDiagnosticsEnabled,
|
|
113
|
+
getLastRunTimings: registry.getLastRunTimings,
|
|
114
|
+
getSchedule: registry.getSchedule,
|
|
115
|
+
setProfilingEnabled: registry.setProfilingEnabled,
|
|
116
|
+
setProfilingWindow: registry.setProfilingWindow,
|
|
117
|
+
resetProfiling: registry.resetProfiling,
|
|
118
|
+
getProfilingEnabled: registry.getProfilingEnabled,
|
|
119
|
+
getProfilingWindow: registry.getProfilingWindow,
|
|
120
|
+
getProfilingSnapshot: registry.getProfilingSnapshot
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
/**
|
|
124
|
+
* Normalizes the user-supplied error history limit to a non-negative integer.
|
|
125
|
+
*/
|
|
126
|
+
function getNormalizedErrorHistoryLimit(value) {
|
|
127
|
+
if (!Number.isFinite(value) || value <= 0) return 0;
|
|
128
|
+
return Math.floor(value);
|
|
129
|
+
}
|
|
130
|
+
watch(() => props.renderMode, (value) => {
|
|
131
|
+
renderModeState.set(value);
|
|
132
|
+
});
|
|
133
|
+
watch(() => props.autoRender, (value) => {
|
|
134
|
+
autoRenderState.set(value);
|
|
135
|
+
});
|
|
136
|
+
watch(() => props.maxDelta, (value) => {
|
|
137
|
+
maxDeltaState.set(value);
|
|
138
|
+
});
|
|
139
|
+
watch(() => props.dpr, (value) => {
|
|
140
|
+
dprState.set(value);
|
|
141
|
+
});
|
|
142
|
+
watch([() => errorHistory.value, () => props.errorHistoryLimit], ([history, rawLimit]) => {
|
|
143
|
+
const limit = getNormalizedErrorHistoryLimit(rawLimit);
|
|
144
|
+
if (limit <= 0) {
|
|
145
|
+
if (history.length === 0) return;
|
|
146
|
+
errorHistory.value = [];
|
|
147
|
+
props.onErrorHistory?.([]);
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
if (history.length <= limit) return;
|
|
151
|
+
const trimmed = history.slice(history.length - limit);
|
|
152
|
+
errorHistory.value = trimmed;
|
|
153
|
+
props.onErrorHistory?.(trimmed);
|
|
154
|
+
});
|
|
155
|
+
onMounted(() => {
|
|
156
|
+
renderModeState.set(props.renderMode);
|
|
157
|
+
autoRenderState.set(props.autoRender);
|
|
158
|
+
maxDeltaState.set(props.maxDelta);
|
|
159
|
+
dprState.set(props.dpr);
|
|
160
|
+
requestFrame();
|
|
161
|
+
const canvas = canvasRef.value;
|
|
162
|
+
if (!canvas) {
|
|
163
|
+
const report = toMotionGPUErrorReport(/* @__PURE__ */ new Error("Canvas element is not available"), "initialization");
|
|
164
|
+
errorReport.value = report;
|
|
165
|
+
const historyLimit = getNormalizedErrorHistoryLimit(props.errorHistoryLimit);
|
|
166
|
+
if (historyLimit > 0) {
|
|
167
|
+
const nextHistory = [report].slice(-historyLimit);
|
|
168
|
+
errorHistory.value = nextHistory;
|
|
169
|
+
props.onErrorHistory?.(nextHistory);
|
|
170
|
+
}
|
|
171
|
+
props.onError?.(report);
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
const runtimeLoop = createMotionGPURuntimeLoop({
|
|
175
|
+
canvas,
|
|
176
|
+
registry,
|
|
177
|
+
size,
|
|
178
|
+
dpr: dprState,
|
|
179
|
+
maxDelta: maxDeltaState,
|
|
180
|
+
getMaterial: () => props.material,
|
|
181
|
+
getRenderTargets: () => props.renderTargets,
|
|
182
|
+
getPasses: () => props.passes,
|
|
183
|
+
getClearColor: () => props.clearColor,
|
|
184
|
+
getOutputColorSpace: () => props.outputColorSpace,
|
|
185
|
+
getAdapterOptions: () => props.adapterOptions,
|
|
186
|
+
getDeviceDescriptor: () => props.deviceDescriptor,
|
|
187
|
+
getOnError: () => props.onError,
|
|
188
|
+
getErrorHistoryLimit: () => props.errorHistoryLimit,
|
|
189
|
+
getOnErrorHistory: () => props.onErrorHistory,
|
|
190
|
+
reportErrorHistory: (history) => {
|
|
191
|
+
errorHistory.value = history;
|
|
192
|
+
},
|
|
193
|
+
reportError: (report) => {
|
|
194
|
+
errorReport.value = report;
|
|
195
|
+
}
|
|
196
|
+
});
|
|
197
|
+
runtimeLoopHandle = runtimeLoop;
|
|
198
|
+
requestFrameSignal = runtimeLoop.requestFrame;
|
|
199
|
+
});
|
|
200
|
+
onBeforeUnmount(() => {
|
|
201
|
+
requestFrameSignal = null;
|
|
202
|
+
runtimeLoopHandle?.destroy();
|
|
203
|
+
runtimeLoopHandle = null;
|
|
204
|
+
registry.clear();
|
|
205
|
+
});
|
|
206
|
+
return (_ctx, _cache) => {
|
|
207
|
+
return openBlock(), createElementBlock("div", {
|
|
208
|
+
class: "motiongpu-canvas-wrap",
|
|
209
|
+
style: normalizeStyle(unref(wrapperStyle))
|
|
210
|
+
}, [
|
|
211
|
+
createElementVNode("canvas", {
|
|
212
|
+
ref: "canvasEl",
|
|
213
|
+
class: normalizeClass(__props.canvasClass),
|
|
214
|
+
style: normalizeStyle(resolvedCanvasStyle.value)
|
|
215
|
+
}, null, 6),
|
|
216
|
+
__props.showErrorOverlay && errorReport.value ? renderSlot(_ctx.$slots, "errorRenderer", {
|
|
217
|
+
key: 0,
|
|
218
|
+
report: errorReport.value
|
|
219
|
+
}, () => [createVNode(MotionGPUErrorOverlay_default, { report: errorReport.value }, null, 8, ["report"])]) : createCommentVNode("", true),
|
|
220
|
+
renderSlot(_ctx.$slots, "default")
|
|
221
|
+
], 4);
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
});
|
|
225
|
+
//#endregion
|
|
226
|
+
export { FragCanvas_vue_vue_type_script_setup_true_lang_default as default };
|
|
227
|
+
|
|
228
|
+
//# sourceMappingURL=FragCanvas.vue_vue_type_script_setup_true_lang.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FragCanvas.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../src/lib/vue/FragCanvas.vue"],"sourcesContent":["<script lang=\"ts\">\nimport type { MotionGPUErrorReport } from '../core/error-report.js';\nimport type { FragMaterial } from '../core/material.js';\nimport type {\n\tAnyPass,\n\tOutputColorSpace,\n\tRenderMode,\n\tRenderTargetDefinitionMap\n} from '../core/types.js';\n\nexport interface FragCanvasProps {\n\tmaterial: FragMaterial;\n\trenderTargets?: RenderTargetDefinitionMap;\n\tpasses?: AnyPass[];\n\tclearColor?: [number, number, number, number];\n\toutputColorSpace?: OutputColorSpace;\n\trenderMode?: RenderMode;\n\tautoRender?: boolean;\n\tmaxDelta?: number;\n\tadapterOptions?: GPURequestAdapterOptions;\n\tdeviceDescriptor?: GPUDeviceDescriptor;\n\tdpr?: number;\n\tshowErrorOverlay?: boolean;\n\tonError?: (report: MotionGPUErrorReport) => void;\n\terrorHistoryLimit?: number;\n\tonErrorHistory?: (history: MotionGPUErrorReport[]) => void;\n\tcanvasClass?: string;\n\tcanvasStyle?: string | Record<string, string | number>;\n}\n\nconst initialDpr = typeof window === 'undefined' ? 1 : (window.devicePixelRatio ?? 1);\n</script>\n\n<script setup lang=\"ts\">\nimport { computed, onBeforeUnmount, onMounted, shallowRef, useTemplateRef, watch } from 'vue';\nimport { createCurrentWritable as currentWritable } from '../core/current-value.js';\nimport { toMotionGPUErrorReport } from '../core/error-report.js';\nimport { createFrameRegistry } from '../core/frame-registry.js';\nimport { createMotionGPURuntimeLoop } from '../core/runtime-loop.js';\nimport { provideFrameRegistry } from './frame-context.js';\nimport { provideMotionGPUContext } from './motiongpu-context.js';\nimport MotionGPUErrorOverlay from './MotionGPUErrorOverlay.vue';\n\nconst props = withDefaults(defineProps<FragCanvasProps>(), {\n\trenderTargets: () => ({}),\n\tpasses: () => [],\n\tclearColor: () => [0, 0, 0, 1] as [number, number, number, number],\n\toutputColorSpace: 'srgb',\n\trenderMode: 'always',\n\tautoRender: true,\n\tmaxDelta: 0.1,\n\tdpr: () => initialDpr,\n\tshowErrorOverlay: true,\n\terrorHistoryLimit: 0,\n\tcanvasClass: ''\n});\n\nconst wrapperStyle = Object.freeze({\n\tposition: 'relative',\n\twidth: '100%',\n\theight: '100%',\n\tminWidth: '0',\n\tminHeight: '0',\n\toverflow: 'hidden'\n});\n\nconst baseCanvasStyle = Object.freeze({\n\tposition: 'absolute',\n\tinset: '0',\n\tdisplay: 'block',\n\twidth: '100%',\n\theight: '100%'\n});\n\nconst resolvedCanvasStyle = computed(() => [baseCanvasStyle, props.canvasStyle]);\n\ndefineSlots<{\n\tdefault(): unknown;\n\terrorRenderer(props: { report: MotionGPUErrorReport }): unknown;\n}>();\n\nconst canvasRef = useTemplateRef<HTMLCanvasElement>('canvasEl');\nconst errorReport = shallowRef<MotionGPUErrorReport | null>(null);\nconst errorHistory = shallowRef<MotionGPUErrorReport[]>([]);\n\nconst registry = createFrameRegistry({ maxDelta: 0.1 });\nprovideFrameRegistry(registry);\n\nlet requestFrameSignal: (() => void) | null = null;\nlet runtimeLoopHandle: ReturnType<typeof createMotionGPURuntimeLoop> | null = null;\nconst requestFrame = (): void => {\n\trequestFrameSignal?.();\n};\nconst invalidateFrame = (): void => {\n\tregistry.invalidate();\n\trequestFrame();\n};\nconst advanceFrame = (): void => {\n\tregistry.advance();\n\trequestFrame();\n};\n\nconst size = currentWritable({ width: 0, height: 0 });\nconst dprState = currentWritable<number>(initialDpr, requestFrame);\nconst maxDeltaState = currentWritable<number>(0.1, (value) => {\n\tregistry.setMaxDelta(value);\n\trequestFrame();\n});\nconst renderModeState = currentWritable<RenderMode>('always', (value) => {\n\tregistry.setRenderMode(value);\n\trequestFrame();\n});\nconst autoRenderState = currentWritable<boolean>(true, (value) => {\n\tregistry.setAutoRender(value);\n\trequestFrame();\n});\nconst userState = currentWritable<Record<string | symbol, unknown>>({});\n\nprovideMotionGPUContext({\n\tget canvas() {\n\t\treturn canvasRef.value ?? undefined;\n\t},\n\tsize,\n\tdpr: dprState,\n\tmaxDelta: maxDeltaState,\n\trenderMode: renderModeState,\n\tautoRender: autoRenderState,\n\tuser: userState,\n\tinvalidate: invalidateFrame,\n\tadvance: advanceFrame,\n\tscheduler: {\n\t\tcreateStage: registry.createStage,\n\t\tgetStage: registry.getStage,\n\t\tsetDiagnosticsEnabled: registry.setDiagnosticsEnabled,\n\t\tgetDiagnosticsEnabled: registry.getDiagnosticsEnabled,\n\t\tgetLastRunTimings: registry.getLastRunTimings,\n\t\tgetSchedule: registry.getSchedule,\n\t\tsetProfilingEnabled: registry.setProfilingEnabled,\n\t\tsetProfilingWindow: registry.setProfilingWindow,\n\t\tresetProfiling: registry.resetProfiling,\n\t\tgetProfilingEnabled: registry.getProfilingEnabled,\n\t\tgetProfilingWindow: registry.getProfilingWindow,\n\t\tgetProfilingSnapshot: registry.getProfilingSnapshot\n\t}\n});\n\n/**\n * Normalizes the user-supplied error history limit to a non-negative integer.\n */\nfunction getNormalizedErrorHistoryLimit(value: number): number {\n\tif (!Number.isFinite(value) || value <= 0) {\n\t\treturn 0;\n\t}\n\n\treturn Math.floor(value);\n}\n\nwatch(\n\t() => props.renderMode,\n\t(value) => {\n\t\trenderModeState.set(value);\n\t}\n);\n\nwatch(\n\t() => props.autoRender,\n\t(value) => {\n\t\tautoRenderState.set(value);\n\t}\n);\n\nwatch(\n\t() => props.maxDelta,\n\t(value) => {\n\t\tmaxDeltaState.set(value);\n\t}\n);\n\nwatch(\n\t() => props.dpr,\n\t(value) => {\n\t\tdprState.set(value);\n\t}\n);\n\nwatch([() => errorHistory.value, () => props.errorHistoryLimit], ([history, rawLimit]) => {\n\tconst limit = getNormalizedErrorHistoryLimit(rawLimit);\n\tif (limit <= 0) {\n\t\tif (history.length === 0) {\n\t\t\treturn;\n\t\t}\n\t\terrorHistory.value = [];\n\t\tprops.onErrorHistory?.([]);\n\t\treturn;\n\t}\n\n\tif (history.length <= limit) {\n\t\treturn;\n\t}\n\n\tconst trimmed = history.slice(history.length - limit);\n\terrorHistory.value = trimmed;\n\tprops.onErrorHistory?.(trimmed);\n});\n\nonMounted(() => {\n\trenderModeState.set(props.renderMode);\n\tautoRenderState.set(props.autoRender);\n\tmaxDeltaState.set(props.maxDelta);\n\tdprState.set(props.dpr);\n\trequestFrame();\n\n\tconst canvas = canvasRef.value;\n\tif (!canvas) {\n\t\tconst report = toMotionGPUErrorReport(\n\t\t\tnew Error('Canvas element is not available'),\n\t\t\t'initialization'\n\t\t);\n\t\terrorReport.value = report;\n\t\tconst historyLimit = getNormalizedErrorHistoryLimit(props.errorHistoryLimit);\n\t\tif (historyLimit > 0) {\n\t\t\tconst nextHistory = [report].slice(-historyLimit);\n\t\t\terrorHistory.value = nextHistory;\n\t\t\tprops.onErrorHistory?.(nextHistory);\n\t\t}\n\t\tprops.onError?.(report);\n\t\treturn;\n\t}\n\n\tconst runtimeLoop = createMotionGPURuntimeLoop({\n\t\tcanvas,\n\t\tregistry,\n\t\tsize,\n\t\tdpr: dprState,\n\t\tmaxDelta: maxDeltaState,\n\t\tgetMaterial: () => props.material,\n\t\tgetRenderTargets: () => props.renderTargets,\n\t\tgetPasses: () => props.passes,\n\t\tgetClearColor: () => props.clearColor,\n\t\tgetOutputColorSpace: () => props.outputColorSpace,\n\t\tgetAdapterOptions: () => props.adapterOptions,\n\t\tgetDeviceDescriptor: () => props.deviceDescriptor,\n\t\tgetOnError: () => props.onError,\n\t\tgetErrorHistoryLimit: () => props.errorHistoryLimit,\n\t\tgetOnErrorHistory: () => props.onErrorHistory,\n\t\treportErrorHistory: (history) => {\n\t\t\terrorHistory.value = history;\n\t\t},\n\t\treportError: (report) => {\n\t\t\terrorReport.value = report;\n\t\t}\n\t});\n\truntimeLoopHandle = runtimeLoop;\n\trequestFrameSignal = runtimeLoop.requestFrame;\n});\n\nonBeforeUnmount(() => {\n\trequestFrameSignal = null;\n\truntimeLoopHandle?.destroy();\n\truntimeLoopHandle = null;\n\tregistry.clear();\n});\n</script>\n\n<template>\n\t<div class=\"motiongpu-canvas-wrap\" :style=\"wrapperStyle\">\n\t\t<canvas ref=\"canvasEl\" :class=\"canvasClass\" :style=\"resolvedCanvasStyle\"></canvas>\n\t\t<template v-if=\"showErrorOverlay && errorReport\">\n\t\t\t<slot name=\"errorRenderer\" :report=\"errorReport\">\n\t\t\t\t<MotionGPUErrorOverlay :report=\"errorReport\" />\n\t\t\t</slot>\n\t\t</template>\n\t\t<slot />\n\t</div>\n</template>\n\n<style>\n.motiongpu-canvas-wrap {\n\tposition: relative;\n\twidth: 100%;\n\theight: 100%;\n\tmin-width: 0;\n\tmin-height: 0;\n\toverflow: hidden;\n}\n\n.motiongpu-canvas-wrap > canvas {\n\tposition: absolute;\n\tinset: 0;\n\tdisplay: block;\n\twidth: 100%;\n\theight: 100%;\n}\n</style>\n"],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import MotionGPUErrorOverlay_vue_vue_type_script_setup_true_lang_default from "./MotionGPUErrorOverlay.vue_vue_type_script_setup_true_lang.js";
|
|
2
|
+
/* empty css */
|
|
3
|
+
//#region src/lib/vue/MotionGPUErrorOverlay.vue
|
|
4
|
+
var MotionGPUErrorOverlay_default = MotionGPUErrorOverlay_vue_vue_type_script_setup_true_lang_default;
|
|
5
|
+
//#endregion
|
|
6
|
+
export { MotionGPUErrorOverlay_default as default };
|
|
7
|
+
|
|
8
|
+
//# sourceMappingURL=MotionGPUErrorOverlay.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MotionGPUErrorOverlay.js","names":[],"sources":["../../src/lib/vue/MotionGPUErrorOverlay.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport type { MotionGPUErrorReport } from '../core/error-report.js';\nimport Portal from './Portal.vue';\n\ninterface Props {\n\treport: MotionGPUErrorReport;\n}\n\nconst props = defineProps<Props>();\n\n/**\n * Normalizes a string for case-insensitive comparison.\n */\nfunction normalizeErrorText(value: string): string {\n\treturn value\n\t\t.trim()\n\t\t.replace(/[.:!]+$/g, '')\n\t\t.toLowerCase();\n}\n\n/**\n * Resolves a non-redundant message to display, stripping a duplicated title prefix.\n */\nfunction resolveDisplayMessage(value: MotionGPUErrorReport): string {\n\tconst rawMessage = value.message.trim();\n\tif (rawMessage.length === 0) {\n\t\treturn '';\n\t}\n\n\tconst normalizedMessage = normalizeErrorText(rawMessage);\n\tconst normalizedTitle = normalizeErrorText(value.title);\n\tif (normalizedMessage === normalizedTitle) {\n\t\treturn '';\n\t}\n\n\tconst escapedTitle = value.title.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n\tconst prefixPattern = new RegExp(`^${escapedTitle}\\\\s*[:\\\\-|]\\\\s*`, 'i');\n\tconst stripped = rawMessage.replace(prefixPattern, '').trim();\n\treturn stripped.length > 0 ? stripped : rawMessage;\n}\n\n/**\n * Formats the runtime context payload as a human-readable YAML-ish block.\n */\nfunction formatRuntimeContext(context: MotionGPUErrorReport['context']): string {\n\tif (!context) {\n\t\treturn '';\n\t}\n\n\tconst indentBlock = (value: string, spaces = 2): string => {\n\t\tconst prefix = ' '.repeat(spaces);\n\t\treturn value\n\t\t\t.split('\\n')\n\t\t\t.map((line) => `${prefix}${line}`)\n\t\t\t.join('\\n');\n\t};\n\n\tconst formatMaterialSignature = (value: string): string => {\n\t\tconst trimmed = value.trim();\n\t\tif (trimmed.length === 0) {\n\t\t\treturn '<empty>';\n\t\t}\n\t\ttry {\n\t\t\treturn JSON.stringify(JSON.parse(trimmed), null, 2);\n\t\t} catch {\n\t\t\treturn trimmed;\n\t\t}\n\t};\n\n\tconst lines: string[] = [];\n\tif (context.materialSignature) {\n\t\tlines.push('materialSignature:');\n\t\tlines.push(indentBlock(formatMaterialSignature(context.materialSignature)));\n\t}\n\tif (context.passGraph) {\n\t\tlines.push('passGraph:');\n\t\tlines.push(` passCount: ${context.passGraph.passCount}`);\n\t\tlines.push(` enabledPassCount: ${context.passGraph.enabledPassCount}`);\n\t\tlines.push(' inputs:');\n\t\tif (context.passGraph.inputs.length === 0) {\n\t\t\tlines.push(' - <none>');\n\t\t} else {\n\t\t\tfor (const input of context.passGraph.inputs) {\n\t\t\t\tlines.push(` - ${input}`);\n\t\t\t}\n\t\t}\n\t\tlines.push(' outputs:');\n\t\tif (context.passGraph.outputs.length === 0) {\n\t\t\tlines.push(' - <none>');\n\t\t} else {\n\t\t\tfor (const output of context.passGraph.outputs) {\n\t\t\t\tlines.push(` - ${output}`);\n\t\t\t}\n\t\t}\n\t}\n\tlines.push('activeRenderTargets:');\n\tif (context.activeRenderTargets.length === 0) {\n\t\tlines.push(' - <none>');\n\t} else {\n\t\tfor (const target of context.activeRenderTargets) {\n\t\t\tlines.push(` - ${target}`);\n\t\t}\n\t}\n\treturn lines.join('\\n');\n}\n\nconst displayMessage = computed(() => resolveDisplayMessage(props.report));\nconst showDisplayMessage = computed(() => displayMessage.value.length > 0);\nconst detailsText = computed(() => props.report.details.join('\\n'));\nconst stackText = computed(() => props.report.stack.join('\\n'));\nconst runtimeContextText = computed(() => formatRuntimeContext(props.report.context));\nconst detailsSummary = computed(() =>\n\tprops.report.source ? 'Additional diagnostics' : 'Technical details'\n);\n</script>\n\n<template>\n\t<Portal>\n\t\t<div class=\"motiongpu-error-overlay\" role=\"presentation\">\n\t\t\t<section\n\t\t\t\tclass=\"motiongpu-error-dialog\"\n\t\t\t\trole=\"alertdialog\"\n\t\t\t\taria-live=\"assertive\"\n\t\t\t\taria-modal=\"true\"\n\t\t\t\tdata-testid=\"motiongpu-error\"\n\t\t\t>\n\t\t\t\t<header class=\"motiongpu-error-header\">\n\t\t\t\t\t<div class=\"motiongpu-error-header-top\">\n\t\t\t\t\t\t<div class=\"motiongpu-error-badges\">\n\t\t\t\t\t\t\t<div class=\"motiongpu-error-badge-wrap\">\n\t\t\t\t\t\t\t\t<p class=\"motiongpu-error-badge motiongpu-error-badge-phase\">\n\t\t\t\t\t\t\t\t\t{{ report.phase }}\n\t\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t<div class=\"motiongpu-error-badge-wrap\">\n\t\t\t\t\t\t\t\t<p class=\"motiongpu-error-badge motiongpu-error-badge-severity\">\n\t\t\t\t\t\t\t\t\t{{ report.severity }}\n\t\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t\t<h2 class=\"motiongpu-error-title\">{{ report.title }}</h2>\n\t\t\t\t\t<p class=\"motiongpu-error-recoverable\">\n\t\t\t\t\t\tRecoverable: <span>{{ report.recoverable ? 'yes' : 'no' }}</span>\n\t\t\t\t\t</p>\n\t\t\t\t</header>\n\t\t\t\t<div class=\"motiongpu-error-body\">\n\t\t\t\t\t<p v-if=\"showDisplayMessage\" class=\"motiongpu-error-message\">\n\t\t\t\t\t\t{{ displayMessage }}\n\t\t\t\t\t</p>\n\t\t\t\t\t<p class=\"motiongpu-error-hint\">{{ report.hint }}</p>\n\t\t\t\t</div>\n\n\t\t\t\t<section v-if=\"report.source\" class=\"motiongpu-error-source\" aria-label=\"Source\">\n\t\t\t\t\t<h3 class=\"motiongpu-error-source-title\">Source</h3>\n\t\t\t\t\t<div class=\"motiongpu-error-source-frame\" role=\"presentation\">\n\t\t\t\t\t\t<div class=\"motiongpu-error-source-tabs\" role=\"tablist\" aria-label=\"Source files\">\n\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\tclass=\"motiongpu-error-source-tab motiongpu-error-source-tab-active\"\n\t\t\t\t\t\t\t\trole=\"tab\"\n\t\t\t\t\t\t\t\taria-selected=\"true\"\n\t\t\t\t\t\t\t\t>{{ report.source.location\n\t\t\t\t\t\t\t\t}}<template v-if=\"report.source.column\"\n\t\t\t\t\t\t\t\t\t>, col {{ report.source.column }}</template\n\t\t\t\t\t\t\t\t></span\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<span class=\"motiongpu-error-source-tab-spacer\" aria-hidden=\"true\"></span>\n\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t<div class=\"motiongpu-error-source-snippet\">\n\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\tv-for=\"snippetLine in report.source.snippet\"\n\t\t\t\t\t\t\t\t:key=\"`snippet-${snippetLine.number}`\"\n\t\t\t\t\t\t\t\tclass=\"motiongpu-error-source-row\"\n\t\t\t\t\t\t\t\t:class=\"{\n\t\t\t\t\t\t\t\t\t'motiongpu-error-source-row-active': snippetLine.highlight\n\t\t\t\t\t\t\t\t}\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<span class=\"motiongpu-error-source-line\">{{ snippetLine.number }}</span>\n\t\t\t\t\t\t\t\t<span class=\"motiongpu-error-source-code\">{{ snippetLine.code || ' ' }}</span>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t</section>\n\n\t\t\t\t<div class=\"motiongpu-error-sections\">\n\t\t\t\t\t<details v-if=\"report.details.length > 0\" class=\"motiongpu-error-details\" open>\n\t\t\t\t\t\t<summary>{{ detailsSummary }}</summary>\n\t\t\t\t\t\t<pre>{{ detailsText }}</pre>\n\t\t\t\t\t</details>\n\t\t\t\t\t<details v-if=\"report.stack.length > 0\" class=\"motiongpu-error-details\">\n\t\t\t\t\t\t<summary>Stack trace</summary>\n\t\t\t\t\t\t<pre>{{ stackText }}</pre>\n\t\t\t\t\t</details>\n\t\t\t\t\t<details v-if=\"report.context\" class=\"motiongpu-error-details\">\n\t\t\t\t\t\t<summary>Runtime context</summary>\n\t\t\t\t\t\t<pre>{{ runtimeContextText }}</pre>\n\t\t\t\t\t</details>\n\t\t\t\t</div>\n\t\t\t</section>\n\t\t</div>\n\t</Portal>\n</template>\n\n<style>\n.motiongpu-error-overlay {\n\t--motiongpu-base-hue: var(--base-hue, 265);\n\t--motiongpu-color-background: oklch(0.2178 0.0056 var(--motiongpu-base-hue));\n\t--motiongpu-color-background-muted: oklch(0.261 0.007 var(--motiongpu-base-hue));\n\t--motiongpu-color-foreground: oklch(1 0 0);\n\t--motiongpu-color-foreground-muted: oklch(0.6699 0.0081 var(--motiongpu-base-hue));\n\t--motiongpu-color-card: var(--motiongpu-color-background);\n\t--motiongpu-color-accent: oklch(0.6996 0.181959 44.4414);\n\t--motiongpu-color-accent-secondary: oklch(0.5096 0.131959 44.4414);\n\t--motiongpu-color-border: oklch(0.928 0.013 var(--motiongpu-base-hue) / 0.05);\n\t--motiongpu-color-white-fixed: oklch(1 0 0);\n\t--motiongpu-shadow-card: var(\n\t\t--shadow-2xl,\n\t\t0px 1px 1px -0.5px rgba(0, 0, 0, 0.06),\n\t\t0px 3px 3px -1.5px rgba(0, 0, 0, 0.06),\n\t\t0px 6px 6px -3px rgba(0, 0, 0, 0.06),\n\t\t0px 12px 12px -6px rgba(0, 0, 0, 0.06),\n\t\t0px 24px 24px -12px rgba(0, 0, 0, 0.05),\n\t\t0px 48px 48px -24px rgba(0, 0, 0, 0.06)\n\t);\n\t--motiongpu-radius-md: var(--radius-md, 0.5rem);\n\t--motiongpu-radius-lg: var(--radius-lg, 0.75rem);\n\t--motiongpu-radius-xl: var(--radius-xl, 1rem);\n\t--motiongpu-font-sans: var(--font-sans, 'Inter', 'Segoe UI', 'Helvetica Neue', Arial, sans-serif);\n\t--motiongpu-font-mono: var(--font-mono, 'SFMono-Regular', 'Menlo', 'Consolas', monospace);\n\tposition: fixed;\n\tinset: 0;\n\tdisplay: grid;\n\tplace-items: center;\n\tpadding: clamp(0.75rem, 1.4vw, 1.5rem);\n\tbackground: rgba(0, 0, 0, 0.8);\n\tbackdrop-filter: blur(10px);\n\tz-index: 2147483647;\n\tfont-family: var(--motiongpu-font-sans);\n\tcolor-scheme: dark;\n}\n\n.motiongpu-error-dialog {\n\twidth: min(52rem, calc(100vw - 1.5rem));\n\tmax-height: min(84vh, 44rem);\n\toverflow: auto;\n\tmargin: 0;\n\tpadding: 1.1rem;\n\tborder: 1px solid var(--motiongpu-color-border);\n\tborder-radius: var(--motiongpu-radius-xl);\n\tmax-width: calc(100vw - 1.5rem);\n\tbox-sizing: border-box;\n\tfont-size: 0.875rem;\n\tfont-weight: 400;\n\tline-height: 1.45;\n\tbackground: var(--motiongpu-color-card);\n\tcolor: var(--motiongpu-color-foreground);\n\tbox-shadow: var(--motiongpu-shadow-card);\n}\n\n.motiongpu-error-header {\n\tdisplay: grid;\n\tgap: 0.55rem;\n\tpadding-bottom: 0.9rem;\n\tborder-bottom: 1px solid var(--motiongpu-color-border);\n}\n\n.motiongpu-error-header-top {\n\tdisplay: flex;\n\talign-items: flex-start;\n\tgap: 0.75rem;\n}\n\n.motiongpu-error-badges {\n\tdisplay: inline-flex;\n\talign-items: center;\n\tgap: 0.4rem;\n\tflex-wrap: wrap;\n}\n\n.motiongpu-error-badge-wrap {\n\tdisplay: inline-flex;\n\talign-items: center;\n\tgap: 0.4rem;\n\twidth: fit-content;\n\tpadding: 0.18rem;\n\tborder-radius: 999px;\n\tborder: 1px solid var(--motiongpu-color-border);\n\tbackground: var(--motiongpu-color-background-muted);\n}\n\n.motiongpu-error-badge {\n\tdisplay: inline-flex;\n\talign-items: center;\n\tmargin: 0;\n\tpadding: 0.22rem 0.56rem;\n\tborder-radius: 999px;\n\tfont-size: 0.66rem;\n\tletter-spacing: 0.08em;\n\tline-height: 1;\n\tfont-weight: 500;\n\ttext-transform: uppercase;\n\tcolor: var(--motiongpu-color-white-fixed);\n\tbackground: linear-gradient(\n\t\t180deg,\n\t\tvar(--motiongpu-color-accent) 0%,\n\t\tvar(--motiongpu-color-accent-secondary) 100%\n\t);\n\tbox-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.24);\n}\n\n.motiongpu-error-recoverable {\n\tmargin: 0;\n\tfont-size: 0.67rem;\n\tline-height: 1.2;\n\tletter-spacing: 0.06em;\n\ttext-transform: uppercase;\n\tcolor: var(--motiongpu-color-foreground-muted);\n}\n\n.motiongpu-error-recoverable span {\n\tfont-family: var(--motiongpu-font-mono);\n\tcolor: var(--motiongpu-color-foreground);\n}\n\n.motiongpu-error-title {\n\tmargin: 0;\n\tfont-size: clamp(1.02rem, 1vw + 0.72rem, 1.32rem);\n\tfont-weight: 500;\n\tline-height: 1.18;\n\tletter-spacing: -0.02em;\n\ttext-wrap: balance;\n\tcolor: var(--motiongpu-color-foreground);\n}\n\n.motiongpu-error-body {\n\tdisplay: grid;\n\tgap: 0.62rem;\n\tmargin-top: 0.92rem;\n}\n\n.motiongpu-error-message {\n\tmargin: 0;\n\tpadding: 0.72rem 0.78rem;\n\tborder: 1px solid color-mix(in oklch, var(--motiongpu-color-accent) 28%, transparent);\n\tborder-radius: var(--motiongpu-radius-md);\n\tbackground: color-mix(in oklch, var(--motiongpu-color-accent) 10%, transparent);\n\tfont-size: 0.82rem;\n\tline-height: 1.4;\n\tfont-weight: 400;\n\tcolor: var(--motiongpu-color-foreground);\n}\n\n.motiongpu-error-hint {\n\tmargin: 0;\n\tfont-size: 0.82rem;\n\tline-height: 1.45;\n\tfont-weight: 400;\n\tcolor: var(--motiongpu-color-foreground-muted);\n}\n\n.motiongpu-error-sections {\n\tdisplay: grid;\n\tgap: 0.62rem;\n\tmargin-top: 0.95rem;\n}\n\n.motiongpu-error-source {\n\tdisplay: grid;\n\tgap: 0.48rem;\n\tmargin-top: 0.96rem;\n}\n\n.motiongpu-error-source-title {\n\tmargin: 0;\n\tfont-size: 0.8rem;\n\tfont-weight: 500;\n\tline-height: 1.3;\n\tletter-spacing: 0.045em;\n\ttext-transform: uppercase;\n\tcolor: var(--motiongpu-color-foreground);\n}\n\n.motiongpu-error-source-frame {\n\tborder: 1px solid var(--motiongpu-color-border);\n\tborder-radius: var(--motiongpu-radius-lg);\n\toverflow: hidden;\n\tbackground: var(--motiongpu-color-background-muted);\n}\n\n.motiongpu-error-source-tabs {\n\tdisplay: flex;\n\talign-items: stretch;\n\tborder-bottom: 1px solid var(--motiongpu-color-border);\n\tbackground: var(--motiongpu-color-background);\n}\n\n.motiongpu-error-source-tab {\n\tdisplay: inline-flex;\n\talign-items: center;\n\tpadding: 0.5rem 0.68rem;\n\tfont-size: 0.76rem;\n\tfont-weight: 400;\n\tline-height: 1.2;\n\tcolor: var(--motiongpu-color-foreground-muted);\n\tborder-right: 1px solid var(--motiongpu-color-border);\n}\n\n.motiongpu-error-source-tab-active {\n\tcolor: var(--motiongpu-color-foreground);\n\tbackground: var(--motiongpu-color-background-muted);\n}\n\n.motiongpu-error-source-tab-spacer {\n\tflex: 1 1 auto;\n}\n\n.motiongpu-error-source-snippet {\n\tdisplay: grid;\n\tbackground: var(--motiongpu-color-background-muted);\n}\n\n.motiongpu-error-source-row {\n\tdisplay: grid;\n\tgrid-template-columns: 2rem minmax(0, 1fr);\n\talign-items: start;\n\tgap: 0.42rem;\n\tpadding: 0.2rem 0.68rem;\n}\n\n.motiongpu-error-source-row-active {\n\tbackground: color-mix(in oklch, var(--motiongpu-color-accent) 10%, transparent);\n}\n\n.motiongpu-error-source-line {\n\tfont-family: var(--motiongpu-font-mono);\n\tfont-size: 0.77rem;\n\tfont-weight: 400;\n\tline-height: 1.3;\n\tfont-variant-numeric: tabular-nums;\n\tfont-feature-settings: 'tnum' 1;\n\tborder-right: 1px solid var(--motiongpu-color-border);\n\tcolor: var(--motiongpu-color-foreground-muted);\n\ttext-align: left;\n}\n\n.motiongpu-error-source-code {\n\tfont-family: var(--motiongpu-font-mono);\n\tfont-size: 0.77rem;\n\tfont-weight: 400;\n\tline-height: 1.3;\n\tcolor: var(--motiongpu-color-foreground);\n\twhite-space: pre-wrap;\n\tword-break: break-word;\n}\n\n.motiongpu-error-details {\n\tborder: 1px solid var(--motiongpu-color-border);\n\tborder-radius: var(--motiongpu-radius-lg);\n\toverflow: hidden;\n\tbackground: var(--motiongpu-color-background);\n}\n\n.motiongpu-error-details summary {\n\tcursor: pointer;\n\tpadding: 0.56rem 0.68rem;\n\tfont-size: 0.7rem;\n\tletter-spacing: 0.07em;\n\tline-height: 1.2;\n\tfont-weight: 500;\n\ttext-transform: uppercase;\n\tcolor: var(--motiongpu-color-foreground);\n}\n\n.motiongpu-error-details[open] summary {\n\tborder-bottom: 1px solid var(--motiongpu-color-border);\n}\n\n.motiongpu-error-details pre {\n\tmargin: 0;\n\tpadding: 0.62rem 0.68rem;\n\twhite-space: pre-wrap;\n\tword-break: break-word;\n\toverflow: auto;\n\tbackground: var(--motiongpu-color-background-muted);\n\tfont-size: 0.74rem;\n\tline-height: 1.4;\n\tfont-weight: 400;\n\tcolor: var(--motiongpu-color-foreground);\n\tfont-family: var(--motiongpu-font-mono);\n}\n\n@media (max-width: 42rem) {\n\t.motiongpu-error-overlay {\n\t\tpadding: 0.62rem;\n\t}\n\n\t.motiongpu-error-dialog {\n\t\tpadding: 0.85rem;\n\t}\n\n\t.motiongpu-error-title {\n\t\tfont-size: 1.02rem;\n\t}\n\n\t.motiongpu-error-header-top {\n\t\tflex-direction: column;\n\t\talign-items: flex-start;\n\t}\n}\n\n@media (prefers-reduced-motion: reduce) {\n\t.motiongpu-error-overlay {\n\t\tbackdrop-filter: none;\n\t}\n}\n</style>\n"],"mappings":""}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { MotionGPUErrorReport } from '../core/error-report.js';
|
|
2
|
+
interface Props {
|
|
3
|
+
report: MotionGPUErrorReport;
|
|
4
|
+
}
|
|
5
|
+
declare const __VLS_export: import("vue").DefineComponent<Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
6
|
+
declare const _default: typeof __VLS_export;
|
|
7
|
+
export default _default;
|
|
8
|
+
//# sourceMappingURL=MotionGPUErrorOverlay.vue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MotionGPUErrorOverlay.vue.d.ts","sourceRoot":"","sources":["../../src/lib/vue/MotionGPUErrorOverlay.vue"],"names":[],"mappings":"AA0gBA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAGpE,UAAU,KAAK;IACd,MAAM,EAAE,oBAAoB,CAAC;CAC7B;AAqUD,QAAA,MAAM,YAAY,sRAEhB,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import Portal_default from "./Portal.js";
|
|
2
|
+
import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, defineComponent, normalizeClass, openBlock, renderList, toDisplayString, withCtx } from "vue";
|
|
3
|
+
//#region src/lib/vue/MotionGPUErrorOverlay.vue?vue&type=script&setup=true&lang.ts
|
|
4
|
+
var _hoisted_1 = {
|
|
5
|
+
class: "motiongpu-error-overlay",
|
|
6
|
+
role: "presentation"
|
|
7
|
+
};
|
|
8
|
+
var _hoisted_2 = {
|
|
9
|
+
class: "motiongpu-error-dialog",
|
|
10
|
+
role: "alertdialog",
|
|
11
|
+
"aria-live": "assertive",
|
|
12
|
+
"aria-modal": "true",
|
|
13
|
+
"data-testid": "motiongpu-error"
|
|
14
|
+
};
|
|
15
|
+
var _hoisted_3 = { class: "motiongpu-error-header" };
|
|
16
|
+
var _hoisted_4 = { class: "motiongpu-error-header-top" };
|
|
17
|
+
var _hoisted_5 = { class: "motiongpu-error-badges" };
|
|
18
|
+
var _hoisted_6 = { class: "motiongpu-error-badge-wrap" };
|
|
19
|
+
var _hoisted_7 = { class: "motiongpu-error-badge motiongpu-error-badge-phase" };
|
|
20
|
+
var _hoisted_8 = { class: "motiongpu-error-badge-wrap" };
|
|
21
|
+
var _hoisted_9 = { class: "motiongpu-error-badge motiongpu-error-badge-severity" };
|
|
22
|
+
var _hoisted_10 = { class: "motiongpu-error-title" };
|
|
23
|
+
var _hoisted_11 = { class: "motiongpu-error-recoverable" };
|
|
24
|
+
var _hoisted_12 = { class: "motiongpu-error-body" };
|
|
25
|
+
var _hoisted_13 = {
|
|
26
|
+
key: 0,
|
|
27
|
+
class: "motiongpu-error-message"
|
|
28
|
+
};
|
|
29
|
+
var _hoisted_14 = { class: "motiongpu-error-hint" };
|
|
30
|
+
var _hoisted_15 = {
|
|
31
|
+
key: 0,
|
|
32
|
+
class: "motiongpu-error-source",
|
|
33
|
+
"aria-label": "Source"
|
|
34
|
+
};
|
|
35
|
+
var _hoisted_16 = {
|
|
36
|
+
class: "motiongpu-error-source-frame",
|
|
37
|
+
role: "presentation"
|
|
38
|
+
};
|
|
39
|
+
var _hoisted_17 = {
|
|
40
|
+
class: "motiongpu-error-source-tabs",
|
|
41
|
+
role: "tablist",
|
|
42
|
+
"aria-label": "Source files"
|
|
43
|
+
};
|
|
44
|
+
var _hoisted_18 = {
|
|
45
|
+
class: "motiongpu-error-source-tab motiongpu-error-source-tab-active",
|
|
46
|
+
role: "tab",
|
|
47
|
+
"aria-selected": "true"
|
|
48
|
+
};
|
|
49
|
+
var _hoisted_19 = { class: "motiongpu-error-source-snippet" };
|
|
50
|
+
var _hoisted_20 = { class: "motiongpu-error-source-line" };
|
|
51
|
+
var _hoisted_21 = { class: "motiongpu-error-source-code" };
|
|
52
|
+
var _hoisted_22 = { class: "motiongpu-error-sections" };
|
|
53
|
+
var _hoisted_23 = {
|
|
54
|
+
key: 0,
|
|
55
|
+
class: "motiongpu-error-details",
|
|
56
|
+
open: ""
|
|
57
|
+
};
|
|
58
|
+
var _hoisted_24 = {
|
|
59
|
+
key: 1,
|
|
60
|
+
class: "motiongpu-error-details"
|
|
61
|
+
};
|
|
62
|
+
var _hoisted_25 = {
|
|
63
|
+
key: 2,
|
|
64
|
+
class: "motiongpu-error-details"
|
|
65
|
+
};
|
|
66
|
+
var MotionGPUErrorOverlay_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
|
|
67
|
+
__name: "MotionGPUErrorOverlay",
|
|
68
|
+
props: { report: {} },
|
|
69
|
+
setup(__props) {
|
|
70
|
+
const props = __props;
|
|
71
|
+
/**
|
|
72
|
+
* Normalizes a string for case-insensitive comparison.
|
|
73
|
+
*/
|
|
74
|
+
function normalizeErrorText(value) {
|
|
75
|
+
return value.trim().replace(/[.:!]+$/g, "").toLowerCase();
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Resolves a non-redundant message to display, stripping a duplicated title prefix.
|
|
79
|
+
*/
|
|
80
|
+
function resolveDisplayMessage(value) {
|
|
81
|
+
const rawMessage = value.message.trim();
|
|
82
|
+
if (rawMessage.length === 0) return "";
|
|
83
|
+
if (normalizeErrorText(rawMessage) === normalizeErrorText(value.title)) return "";
|
|
84
|
+
const escapedTitle = value.title.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
85
|
+
const prefixPattern = new RegExp(`^${escapedTitle}\\s*[:\\-|]\\s*`, "i");
|
|
86
|
+
const stripped = rawMessage.replace(prefixPattern, "").trim();
|
|
87
|
+
return stripped.length > 0 ? stripped : rawMessage;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Formats the runtime context payload as a human-readable YAML-ish block.
|
|
91
|
+
*/
|
|
92
|
+
function formatRuntimeContext(context) {
|
|
93
|
+
if (!context) return "";
|
|
94
|
+
const indentBlock = (value, spaces = 2) => {
|
|
95
|
+
const prefix = " ".repeat(spaces);
|
|
96
|
+
return value.split("\n").map((line) => `${prefix}${line}`).join("\n");
|
|
97
|
+
};
|
|
98
|
+
const formatMaterialSignature = (value) => {
|
|
99
|
+
const trimmed = value.trim();
|
|
100
|
+
if (trimmed.length === 0) return "<empty>";
|
|
101
|
+
try {
|
|
102
|
+
return JSON.stringify(JSON.parse(trimmed), null, 2);
|
|
103
|
+
} catch {
|
|
104
|
+
return trimmed;
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
const lines = [];
|
|
108
|
+
if (context.materialSignature) {
|
|
109
|
+
lines.push("materialSignature:");
|
|
110
|
+
lines.push(indentBlock(formatMaterialSignature(context.materialSignature)));
|
|
111
|
+
}
|
|
112
|
+
if (context.passGraph) {
|
|
113
|
+
lines.push("passGraph:");
|
|
114
|
+
lines.push(` passCount: ${context.passGraph.passCount}`);
|
|
115
|
+
lines.push(` enabledPassCount: ${context.passGraph.enabledPassCount}`);
|
|
116
|
+
lines.push(" inputs:");
|
|
117
|
+
if (context.passGraph.inputs.length === 0) lines.push(" - <none>");
|
|
118
|
+
else for (const input of context.passGraph.inputs) lines.push(` - ${input}`);
|
|
119
|
+
lines.push(" outputs:");
|
|
120
|
+
if (context.passGraph.outputs.length === 0) lines.push(" - <none>");
|
|
121
|
+
else for (const output of context.passGraph.outputs) lines.push(` - ${output}`);
|
|
122
|
+
}
|
|
123
|
+
lines.push("activeRenderTargets:");
|
|
124
|
+
if (context.activeRenderTargets.length === 0) lines.push(" - <none>");
|
|
125
|
+
else for (const target of context.activeRenderTargets) lines.push(` - ${target}`);
|
|
126
|
+
return lines.join("\n");
|
|
127
|
+
}
|
|
128
|
+
const displayMessage = computed(() => resolveDisplayMessage(props.report));
|
|
129
|
+
const showDisplayMessage = computed(() => displayMessage.value.length > 0);
|
|
130
|
+
const detailsText = computed(() => props.report.details.join("\n"));
|
|
131
|
+
const stackText = computed(() => props.report.stack.join("\n"));
|
|
132
|
+
const runtimeContextText = computed(() => formatRuntimeContext(props.report.context));
|
|
133
|
+
const detailsSummary = computed(() => props.report.source ? "Additional diagnostics" : "Technical details");
|
|
134
|
+
return (_ctx, _cache) => {
|
|
135
|
+
return openBlock(), createBlock(Portal_default, null, {
|
|
136
|
+
default: withCtx(() => [createElementVNode("div", _hoisted_1, [createElementVNode("section", _hoisted_2, [
|
|
137
|
+
createElementVNode("header", _hoisted_3, [
|
|
138
|
+
createElementVNode("div", _hoisted_4, [createElementVNode("div", _hoisted_5, [createElementVNode("div", _hoisted_6, [createElementVNode("p", _hoisted_7, toDisplayString(__props.report.phase), 1)]), createElementVNode("div", _hoisted_8, [createElementVNode("p", _hoisted_9, toDisplayString(__props.report.severity), 1)])])]),
|
|
139
|
+
createElementVNode("h2", _hoisted_10, toDisplayString(__props.report.title), 1),
|
|
140
|
+
createElementVNode("p", _hoisted_11, [_cache[0] || (_cache[0] = createTextVNode(" Recoverable: ", -1)), createElementVNode("span", null, toDisplayString(__props.report.recoverable ? "yes" : "no"), 1)])
|
|
141
|
+
]),
|
|
142
|
+
createElementVNode("div", _hoisted_12, [showDisplayMessage.value ? (openBlock(), createElementBlock("p", _hoisted_13, toDisplayString(displayMessage.value), 1)) : createCommentVNode("", true), createElementVNode("p", _hoisted_14, toDisplayString(__props.report.hint), 1)]),
|
|
143
|
+
__props.report.source ? (openBlock(), createElementBlock("section", _hoisted_15, [_cache[2] || (_cache[2] = createElementVNode("h3", { class: "motiongpu-error-source-title" }, "Source", -1)), createElementVNode("div", _hoisted_16, [createElementVNode("div", _hoisted_17, [createElementVNode("span", _hoisted_18, [createTextVNode(toDisplayString(__props.report.source.location), 1), __props.report.source.column ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [createTextVNode(", col " + toDisplayString(__props.report.source.column), 1)], 64)) : createCommentVNode("", true)]), _cache[1] || (_cache[1] = createElementVNode("span", {
|
|
144
|
+
class: "motiongpu-error-source-tab-spacer",
|
|
145
|
+
"aria-hidden": "true"
|
|
146
|
+
}, null, -1))]), createElementVNode("div", _hoisted_19, [(openBlock(true), createElementBlock(Fragment, null, renderList(__props.report.source.snippet, (snippetLine) => {
|
|
147
|
+
return openBlock(), createElementBlock("div", {
|
|
148
|
+
key: `snippet-${snippetLine.number}`,
|
|
149
|
+
class: normalizeClass(["motiongpu-error-source-row", { "motiongpu-error-source-row-active": snippetLine.highlight }])
|
|
150
|
+
}, [createElementVNode("span", _hoisted_20, toDisplayString(snippetLine.number), 1), createElementVNode("span", _hoisted_21, toDisplayString(snippetLine.code || " "), 1)], 2);
|
|
151
|
+
}), 128))])])])) : createCommentVNode("", true),
|
|
152
|
+
createElementVNode("div", _hoisted_22, [
|
|
153
|
+
__props.report.details.length > 0 ? (openBlock(), createElementBlock("details", _hoisted_23, [createElementVNode("summary", null, toDisplayString(detailsSummary.value), 1), createElementVNode("pre", null, toDisplayString(detailsText.value), 1)])) : createCommentVNode("", true),
|
|
154
|
+
__props.report.stack.length > 0 ? (openBlock(), createElementBlock("details", _hoisted_24, [_cache[3] || (_cache[3] = createElementVNode("summary", null, "Stack trace", -1)), createElementVNode("pre", null, toDisplayString(stackText.value), 1)])) : createCommentVNode("", true),
|
|
155
|
+
__props.report.context ? (openBlock(), createElementBlock("details", _hoisted_25, [_cache[4] || (_cache[4] = createElementVNode("summary", null, "Runtime context", -1)), createElementVNode("pre", null, toDisplayString(runtimeContextText.value), 1)])) : createCommentVNode("", true)
|
|
156
|
+
])
|
|
157
|
+
])])]),
|
|
158
|
+
_: 1
|
|
159
|
+
});
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
//#endregion
|
|
164
|
+
export { MotionGPUErrorOverlay_vue_vue_type_script_setup_true_lang_default as default };
|
|
165
|
+
|
|
166
|
+
//# sourceMappingURL=MotionGPUErrorOverlay.vue_vue_type_script_setup_true_lang.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MotionGPUErrorOverlay.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../src/lib/vue/MotionGPUErrorOverlay.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport type { MotionGPUErrorReport } from '../core/error-report.js';\nimport Portal from './Portal.vue';\n\ninterface Props {\n\treport: MotionGPUErrorReport;\n}\n\nconst props = defineProps<Props>();\n\n/**\n * Normalizes a string for case-insensitive comparison.\n */\nfunction normalizeErrorText(value: string): string {\n\treturn value\n\t\t.trim()\n\t\t.replace(/[.:!]+$/g, '')\n\t\t.toLowerCase();\n}\n\n/**\n * Resolves a non-redundant message to display, stripping a duplicated title prefix.\n */\nfunction resolveDisplayMessage(value: MotionGPUErrorReport): string {\n\tconst rawMessage = value.message.trim();\n\tif (rawMessage.length === 0) {\n\t\treturn '';\n\t}\n\n\tconst normalizedMessage = normalizeErrorText(rawMessage);\n\tconst normalizedTitle = normalizeErrorText(value.title);\n\tif (normalizedMessage === normalizedTitle) {\n\t\treturn '';\n\t}\n\n\tconst escapedTitle = value.title.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n\tconst prefixPattern = new RegExp(`^${escapedTitle}\\\\s*[:\\\\-|]\\\\s*`, 'i');\n\tconst stripped = rawMessage.replace(prefixPattern, '').trim();\n\treturn stripped.length > 0 ? stripped : rawMessage;\n}\n\n/**\n * Formats the runtime context payload as a human-readable YAML-ish block.\n */\nfunction formatRuntimeContext(context: MotionGPUErrorReport['context']): string {\n\tif (!context) {\n\t\treturn '';\n\t}\n\n\tconst indentBlock = (value: string, spaces = 2): string => {\n\t\tconst prefix = ' '.repeat(spaces);\n\t\treturn value\n\t\t\t.split('\\n')\n\t\t\t.map((line) => `${prefix}${line}`)\n\t\t\t.join('\\n');\n\t};\n\n\tconst formatMaterialSignature = (value: string): string => {\n\t\tconst trimmed = value.trim();\n\t\tif (trimmed.length === 0) {\n\t\t\treturn '<empty>';\n\t\t}\n\t\ttry {\n\t\t\treturn JSON.stringify(JSON.parse(trimmed), null, 2);\n\t\t} catch {\n\t\t\treturn trimmed;\n\t\t}\n\t};\n\n\tconst lines: string[] = [];\n\tif (context.materialSignature) {\n\t\tlines.push('materialSignature:');\n\t\tlines.push(indentBlock(formatMaterialSignature(context.materialSignature)));\n\t}\n\tif (context.passGraph) {\n\t\tlines.push('passGraph:');\n\t\tlines.push(` passCount: ${context.passGraph.passCount}`);\n\t\tlines.push(` enabledPassCount: ${context.passGraph.enabledPassCount}`);\n\t\tlines.push(' inputs:');\n\t\tif (context.passGraph.inputs.length === 0) {\n\t\t\tlines.push(' - <none>');\n\t\t} else {\n\t\t\tfor (const input of context.passGraph.inputs) {\n\t\t\t\tlines.push(` - ${input}`);\n\t\t\t}\n\t\t}\n\t\tlines.push(' outputs:');\n\t\tif (context.passGraph.outputs.length === 0) {\n\t\t\tlines.push(' - <none>');\n\t\t} else {\n\t\t\tfor (const output of context.passGraph.outputs) {\n\t\t\t\tlines.push(` - ${output}`);\n\t\t\t}\n\t\t}\n\t}\n\tlines.push('activeRenderTargets:');\n\tif (context.activeRenderTargets.length === 0) {\n\t\tlines.push(' - <none>');\n\t} else {\n\t\tfor (const target of context.activeRenderTargets) {\n\t\t\tlines.push(` - ${target}`);\n\t\t}\n\t}\n\treturn lines.join('\\n');\n}\n\nconst displayMessage = computed(() => resolveDisplayMessage(props.report));\nconst showDisplayMessage = computed(() => displayMessage.value.length > 0);\nconst detailsText = computed(() => props.report.details.join('\\n'));\nconst stackText = computed(() => props.report.stack.join('\\n'));\nconst runtimeContextText = computed(() => formatRuntimeContext(props.report.context));\nconst detailsSummary = computed(() =>\n\tprops.report.source ? 'Additional diagnostics' : 'Technical details'\n);\n</script>\n\n<template>\n\t<Portal>\n\t\t<div class=\"motiongpu-error-overlay\" role=\"presentation\">\n\t\t\t<section\n\t\t\t\tclass=\"motiongpu-error-dialog\"\n\t\t\t\trole=\"alertdialog\"\n\t\t\t\taria-live=\"assertive\"\n\t\t\t\taria-modal=\"true\"\n\t\t\t\tdata-testid=\"motiongpu-error\"\n\t\t\t>\n\t\t\t\t<header class=\"motiongpu-error-header\">\n\t\t\t\t\t<div class=\"motiongpu-error-header-top\">\n\t\t\t\t\t\t<div class=\"motiongpu-error-badges\">\n\t\t\t\t\t\t\t<div class=\"motiongpu-error-badge-wrap\">\n\t\t\t\t\t\t\t\t<p class=\"motiongpu-error-badge motiongpu-error-badge-phase\">\n\t\t\t\t\t\t\t\t\t{{ report.phase }}\n\t\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t<div class=\"motiongpu-error-badge-wrap\">\n\t\t\t\t\t\t\t\t<p class=\"motiongpu-error-badge motiongpu-error-badge-severity\">\n\t\t\t\t\t\t\t\t\t{{ report.severity }}\n\t\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t\t<h2 class=\"motiongpu-error-title\">{{ report.title }}</h2>\n\t\t\t\t\t<p class=\"motiongpu-error-recoverable\">\n\t\t\t\t\t\tRecoverable: <span>{{ report.recoverable ? 'yes' : 'no' }}</span>\n\t\t\t\t\t</p>\n\t\t\t\t</header>\n\t\t\t\t<div class=\"motiongpu-error-body\">\n\t\t\t\t\t<p v-if=\"showDisplayMessage\" class=\"motiongpu-error-message\">\n\t\t\t\t\t\t{{ displayMessage }}\n\t\t\t\t\t</p>\n\t\t\t\t\t<p class=\"motiongpu-error-hint\">{{ report.hint }}</p>\n\t\t\t\t</div>\n\n\t\t\t\t<section v-if=\"report.source\" class=\"motiongpu-error-source\" aria-label=\"Source\">\n\t\t\t\t\t<h3 class=\"motiongpu-error-source-title\">Source</h3>\n\t\t\t\t\t<div class=\"motiongpu-error-source-frame\" role=\"presentation\">\n\t\t\t\t\t\t<div class=\"motiongpu-error-source-tabs\" role=\"tablist\" aria-label=\"Source files\">\n\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\tclass=\"motiongpu-error-source-tab motiongpu-error-source-tab-active\"\n\t\t\t\t\t\t\t\trole=\"tab\"\n\t\t\t\t\t\t\t\taria-selected=\"true\"\n\t\t\t\t\t\t\t\t>{{ report.source.location\n\t\t\t\t\t\t\t\t}}<template v-if=\"report.source.column\"\n\t\t\t\t\t\t\t\t\t>, col {{ report.source.column }}</template\n\t\t\t\t\t\t\t\t></span\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<span class=\"motiongpu-error-source-tab-spacer\" aria-hidden=\"true\"></span>\n\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t<div class=\"motiongpu-error-source-snippet\">\n\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\tv-for=\"snippetLine in report.source.snippet\"\n\t\t\t\t\t\t\t\t:key=\"`snippet-${snippetLine.number}`\"\n\t\t\t\t\t\t\t\tclass=\"motiongpu-error-source-row\"\n\t\t\t\t\t\t\t\t:class=\"{\n\t\t\t\t\t\t\t\t\t'motiongpu-error-source-row-active': snippetLine.highlight\n\t\t\t\t\t\t\t\t}\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<span class=\"motiongpu-error-source-line\">{{ snippetLine.number }}</span>\n\t\t\t\t\t\t\t\t<span class=\"motiongpu-error-source-code\">{{ snippetLine.code || ' ' }}</span>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t</section>\n\n\t\t\t\t<div class=\"motiongpu-error-sections\">\n\t\t\t\t\t<details v-if=\"report.details.length > 0\" class=\"motiongpu-error-details\" open>\n\t\t\t\t\t\t<summary>{{ detailsSummary }}</summary>\n\t\t\t\t\t\t<pre>{{ detailsText }}</pre>\n\t\t\t\t\t</details>\n\t\t\t\t\t<details v-if=\"report.stack.length > 0\" class=\"motiongpu-error-details\">\n\t\t\t\t\t\t<summary>Stack trace</summary>\n\t\t\t\t\t\t<pre>{{ stackText }}</pre>\n\t\t\t\t\t</details>\n\t\t\t\t\t<details v-if=\"report.context\" class=\"motiongpu-error-details\">\n\t\t\t\t\t\t<summary>Runtime context</summary>\n\t\t\t\t\t\t<pre>{{ runtimeContextText }}</pre>\n\t\t\t\t\t</details>\n\t\t\t\t</div>\n\t\t\t</section>\n\t\t</div>\n\t</Portal>\n</template>\n\n<style>\n.motiongpu-error-overlay {\n\t--motiongpu-base-hue: var(--base-hue, 265);\n\t--motiongpu-color-background: oklch(0.2178 0.0056 var(--motiongpu-base-hue));\n\t--motiongpu-color-background-muted: oklch(0.261 0.007 var(--motiongpu-base-hue));\n\t--motiongpu-color-foreground: oklch(1 0 0);\n\t--motiongpu-color-foreground-muted: oklch(0.6699 0.0081 var(--motiongpu-base-hue));\n\t--motiongpu-color-card: var(--motiongpu-color-background);\n\t--motiongpu-color-accent: oklch(0.6996 0.181959 44.4414);\n\t--motiongpu-color-accent-secondary: oklch(0.5096 0.131959 44.4414);\n\t--motiongpu-color-border: oklch(0.928 0.013 var(--motiongpu-base-hue) / 0.05);\n\t--motiongpu-color-white-fixed: oklch(1 0 0);\n\t--motiongpu-shadow-card: var(\n\t\t--shadow-2xl,\n\t\t0px 1px 1px -0.5px rgba(0, 0, 0, 0.06),\n\t\t0px 3px 3px -1.5px rgba(0, 0, 0, 0.06),\n\t\t0px 6px 6px -3px rgba(0, 0, 0, 0.06),\n\t\t0px 12px 12px -6px rgba(0, 0, 0, 0.06),\n\t\t0px 24px 24px -12px rgba(0, 0, 0, 0.05),\n\t\t0px 48px 48px -24px rgba(0, 0, 0, 0.06)\n\t);\n\t--motiongpu-radius-md: var(--radius-md, 0.5rem);\n\t--motiongpu-radius-lg: var(--radius-lg, 0.75rem);\n\t--motiongpu-radius-xl: var(--radius-xl, 1rem);\n\t--motiongpu-font-sans: var(--font-sans, 'Inter', 'Segoe UI', 'Helvetica Neue', Arial, sans-serif);\n\t--motiongpu-font-mono: var(--font-mono, 'SFMono-Regular', 'Menlo', 'Consolas', monospace);\n\tposition: fixed;\n\tinset: 0;\n\tdisplay: grid;\n\tplace-items: center;\n\tpadding: clamp(0.75rem, 1.4vw, 1.5rem);\n\tbackground: rgba(0, 0, 0, 0.8);\n\tbackdrop-filter: blur(10px);\n\tz-index: 2147483647;\n\tfont-family: var(--motiongpu-font-sans);\n\tcolor-scheme: dark;\n}\n\n.motiongpu-error-dialog {\n\twidth: min(52rem, calc(100vw - 1.5rem));\n\tmax-height: min(84vh, 44rem);\n\toverflow: auto;\n\tmargin: 0;\n\tpadding: 1.1rem;\n\tborder: 1px solid var(--motiongpu-color-border);\n\tborder-radius: var(--motiongpu-radius-xl);\n\tmax-width: calc(100vw - 1.5rem);\n\tbox-sizing: border-box;\n\tfont-size: 0.875rem;\n\tfont-weight: 400;\n\tline-height: 1.45;\n\tbackground: var(--motiongpu-color-card);\n\tcolor: var(--motiongpu-color-foreground);\n\tbox-shadow: var(--motiongpu-shadow-card);\n}\n\n.motiongpu-error-header {\n\tdisplay: grid;\n\tgap: 0.55rem;\n\tpadding-bottom: 0.9rem;\n\tborder-bottom: 1px solid var(--motiongpu-color-border);\n}\n\n.motiongpu-error-header-top {\n\tdisplay: flex;\n\talign-items: flex-start;\n\tgap: 0.75rem;\n}\n\n.motiongpu-error-badges {\n\tdisplay: inline-flex;\n\talign-items: center;\n\tgap: 0.4rem;\n\tflex-wrap: wrap;\n}\n\n.motiongpu-error-badge-wrap {\n\tdisplay: inline-flex;\n\talign-items: center;\n\tgap: 0.4rem;\n\twidth: fit-content;\n\tpadding: 0.18rem;\n\tborder-radius: 999px;\n\tborder: 1px solid var(--motiongpu-color-border);\n\tbackground: var(--motiongpu-color-background-muted);\n}\n\n.motiongpu-error-badge {\n\tdisplay: inline-flex;\n\talign-items: center;\n\tmargin: 0;\n\tpadding: 0.22rem 0.56rem;\n\tborder-radius: 999px;\n\tfont-size: 0.66rem;\n\tletter-spacing: 0.08em;\n\tline-height: 1;\n\tfont-weight: 500;\n\ttext-transform: uppercase;\n\tcolor: var(--motiongpu-color-white-fixed);\n\tbackground: linear-gradient(\n\t\t180deg,\n\t\tvar(--motiongpu-color-accent) 0%,\n\t\tvar(--motiongpu-color-accent-secondary) 100%\n\t);\n\tbox-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.24);\n}\n\n.motiongpu-error-recoverable {\n\tmargin: 0;\n\tfont-size: 0.67rem;\n\tline-height: 1.2;\n\tletter-spacing: 0.06em;\n\ttext-transform: uppercase;\n\tcolor: var(--motiongpu-color-foreground-muted);\n}\n\n.motiongpu-error-recoverable span {\n\tfont-family: var(--motiongpu-font-mono);\n\tcolor: var(--motiongpu-color-foreground);\n}\n\n.motiongpu-error-title {\n\tmargin: 0;\n\tfont-size: clamp(1.02rem, 1vw + 0.72rem, 1.32rem);\n\tfont-weight: 500;\n\tline-height: 1.18;\n\tletter-spacing: -0.02em;\n\ttext-wrap: balance;\n\tcolor: var(--motiongpu-color-foreground);\n}\n\n.motiongpu-error-body {\n\tdisplay: grid;\n\tgap: 0.62rem;\n\tmargin-top: 0.92rem;\n}\n\n.motiongpu-error-message {\n\tmargin: 0;\n\tpadding: 0.72rem 0.78rem;\n\tborder: 1px solid color-mix(in oklch, var(--motiongpu-color-accent) 28%, transparent);\n\tborder-radius: var(--motiongpu-radius-md);\n\tbackground: color-mix(in oklch, var(--motiongpu-color-accent) 10%, transparent);\n\tfont-size: 0.82rem;\n\tline-height: 1.4;\n\tfont-weight: 400;\n\tcolor: var(--motiongpu-color-foreground);\n}\n\n.motiongpu-error-hint {\n\tmargin: 0;\n\tfont-size: 0.82rem;\n\tline-height: 1.45;\n\tfont-weight: 400;\n\tcolor: var(--motiongpu-color-foreground-muted);\n}\n\n.motiongpu-error-sections {\n\tdisplay: grid;\n\tgap: 0.62rem;\n\tmargin-top: 0.95rem;\n}\n\n.motiongpu-error-source {\n\tdisplay: grid;\n\tgap: 0.48rem;\n\tmargin-top: 0.96rem;\n}\n\n.motiongpu-error-source-title {\n\tmargin: 0;\n\tfont-size: 0.8rem;\n\tfont-weight: 500;\n\tline-height: 1.3;\n\tletter-spacing: 0.045em;\n\ttext-transform: uppercase;\n\tcolor: var(--motiongpu-color-foreground);\n}\n\n.motiongpu-error-source-frame {\n\tborder: 1px solid var(--motiongpu-color-border);\n\tborder-radius: var(--motiongpu-radius-lg);\n\toverflow: hidden;\n\tbackground: var(--motiongpu-color-background-muted);\n}\n\n.motiongpu-error-source-tabs {\n\tdisplay: flex;\n\talign-items: stretch;\n\tborder-bottom: 1px solid var(--motiongpu-color-border);\n\tbackground: var(--motiongpu-color-background);\n}\n\n.motiongpu-error-source-tab {\n\tdisplay: inline-flex;\n\talign-items: center;\n\tpadding: 0.5rem 0.68rem;\n\tfont-size: 0.76rem;\n\tfont-weight: 400;\n\tline-height: 1.2;\n\tcolor: var(--motiongpu-color-foreground-muted);\n\tborder-right: 1px solid var(--motiongpu-color-border);\n}\n\n.motiongpu-error-source-tab-active {\n\tcolor: var(--motiongpu-color-foreground);\n\tbackground: var(--motiongpu-color-background-muted);\n}\n\n.motiongpu-error-source-tab-spacer {\n\tflex: 1 1 auto;\n}\n\n.motiongpu-error-source-snippet {\n\tdisplay: grid;\n\tbackground: var(--motiongpu-color-background-muted);\n}\n\n.motiongpu-error-source-row {\n\tdisplay: grid;\n\tgrid-template-columns: 2rem minmax(0, 1fr);\n\talign-items: start;\n\tgap: 0.42rem;\n\tpadding: 0.2rem 0.68rem;\n}\n\n.motiongpu-error-source-row-active {\n\tbackground: color-mix(in oklch, var(--motiongpu-color-accent) 10%, transparent);\n}\n\n.motiongpu-error-source-line {\n\tfont-family: var(--motiongpu-font-mono);\n\tfont-size: 0.77rem;\n\tfont-weight: 400;\n\tline-height: 1.3;\n\tfont-variant-numeric: tabular-nums;\n\tfont-feature-settings: 'tnum' 1;\n\tborder-right: 1px solid var(--motiongpu-color-border);\n\tcolor: var(--motiongpu-color-foreground-muted);\n\ttext-align: left;\n}\n\n.motiongpu-error-source-code {\n\tfont-family: var(--motiongpu-font-mono);\n\tfont-size: 0.77rem;\n\tfont-weight: 400;\n\tline-height: 1.3;\n\tcolor: var(--motiongpu-color-foreground);\n\twhite-space: pre-wrap;\n\tword-break: break-word;\n}\n\n.motiongpu-error-details {\n\tborder: 1px solid var(--motiongpu-color-border);\n\tborder-radius: var(--motiongpu-radius-lg);\n\toverflow: hidden;\n\tbackground: var(--motiongpu-color-background);\n}\n\n.motiongpu-error-details summary {\n\tcursor: pointer;\n\tpadding: 0.56rem 0.68rem;\n\tfont-size: 0.7rem;\n\tletter-spacing: 0.07em;\n\tline-height: 1.2;\n\tfont-weight: 500;\n\ttext-transform: uppercase;\n\tcolor: var(--motiongpu-color-foreground);\n}\n\n.motiongpu-error-details[open] summary {\n\tborder-bottom: 1px solid var(--motiongpu-color-border);\n}\n\n.motiongpu-error-details pre {\n\tmargin: 0;\n\tpadding: 0.62rem 0.68rem;\n\twhite-space: pre-wrap;\n\tword-break: break-word;\n\toverflow: auto;\n\tbackground: var(--motiongpu-color-background-muted);\n\tfont-size: 0.74rem;\n\tline-height: 1.4;\n\tfont-weight: 400;\n\tcolor: var(--motiongpu-color-foreground);\n\tfont-family: var(--motiongpu-font-mono);\n}\n\n@media (max-width: 42rem) {\n\t.motiongpu-error-overlay {\n\t\tpadding: 0.62rem;\n\t}\n\n\t.motiongpu-error-dialog {\n\t\tpadding: 0.85rem;\n\t}\n\n\t.motiongpu-error-title {\n\t\tfont-size: 1.02rem;\n\t}\n\n\t.motiongpu-error-header-top {\n\t\tflex-direction: column;\n\t\talign-items: flex-start;\n\t}\n}\n\n@media (prefers-reduced-motion: reduce) {\n\t.motiongpu-error-overlay {\n\t\tbackdrop-filter: none;\n\t}\n}\n</style>\n"],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import Portal_vue_vue_type_script_setup_true_lang_default from "./Portal.vue_vue_type_script_setup_true_lang.js";
|
|
2
|
+
//#region src/lib/vue/Portal.vue
|
|
3
|
+
var Portal_default = Portal_vue_vue_type_script_setup_true_lang_default;
|
|
4
|
+
//#endregion
|
|
5
|
+
export { Portal_default as default };
|
|
6
|
+
|
|
7
|
+
//# sourceMappingURL=Portal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Portal.js","names":[],"sources":["../../src/lib/vue/Portal.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue';\n\ninterface Props {\n\ttarget?: string | HTMLElement | null;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n\ttarget: 'body'\n});\n\ndefineSlots<{\n\tdefault(): unknown;\n}>();\n\n/**\n * Resolves a teleport target to a concrete DOM element, falling back to body.\n */\nfunction resolveTargetElement(\n\tinput: string | HTMLElement | null | undefined\n): HTMLElement | string {\n\tif (typeof input === 'string') {\n\t\tif (typeof document === 'undefined') {\n\t\t\treturn input;\n\t\t}\n\n\t\treturn document.querySelector<HTMLElement>(input) ?? document.body;\n\t}\n\n\tif (input) {\n\t\treturn input;\n\t}\n\n\treturn typeof document === 'undefined' ? 'body' : document.body;\n}\n\nconst teleportTarget = computed(() => resolveTargetElement(props.target));\n</script>\n\n<template>\n\t<Teleport :to=\"teleportTarget\">\n\t\t<div class=\"motiongpu-portal-root\">\n\t\t\t<slot />\n\t\t</div>\n\t</Teleport>\n</template>\n"],"mappings":""}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
interface Props {
|
|
2
|
+
target?: string | HTMLElement | null;
|
|
3
|
+
}
|
|
4
|
+
type __VLS_Slots = {
|
|
5
|
+
default(): unknown;
|
|
6
|
+
};
|
|
7
|
+
declare const __VLS_base: import("vue").DefineComponent<Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<Props> & Readonly<{}>, {
|
|
8
|
+
target: string | HTMLElement | null;
|
|
9
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
10
|
+
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
11
|
+
declare const _default: typeof __VLS_export;
|
|
12
|
+
export default _default;
|
|
13
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
14
|
+
new (): {
|
|
15
|
+
$slots: S;
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
//# sourceMappingURL=Portal.vue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Portal.vue.d.ts","sourceRoot":"","sources":["../../src/lib/vue/Portal.vue"],"names":[],"mappings":"AAmDA,UAAU,KAAK;IACd,MAAM,CAAC,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CAAC;CACrC;AAOD,KAAK,WAAW,GAAG;IAClB,OAAO,IAAI,OAAO,CAAC;CACnB,CAAC;AAsEF,QAAA,MAAM,UAAU;YAhFN,MAAM,GAAG,WAAW,GAAG,IAAI;6EAmFnC,CAAC;AACH,QAAA,MAAM,YAAY,EAAS,eAAe,CAAC,OAAO,UAAU,EAAE,WAAW,CAAC,CAAC;wBACtD,OAAO,YAAY;AAAxC,wBAAyC;AAWzC,KAAK,eAAe,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG;IAChC,QAAO;QACN,MAAM,EAAE,CAAC,CAAC;KACV,CAAA;CACD,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { Teleport, computed, createBlock, createElementVNode, defineComponent, openBlock, renderSlot } from "vue";
|
|
2
|
+
//#region src/lib/vue/Portal.vue?vue&type=script&setup=true&lang.ts
|
|
3
|
+
var _hoisted_1 = { class: "motiongpu-portal-root" };
|
|
4
|
+
var Portal_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
|
|
5
|
+
__name: "Portal",
|
|
6
|
+
props: { target: { default: "body" } },
|
|
7
|
+
setup(__props) {
|
|
8
|
+
const props = __props;
|
|
9
|
+
/**
|
|
10
|
+
* Resolves a teleport target to a concrete DOM element, falling back to body.
|
|
11
|
+
*/
|
|
12
|
+
function resolveTargetElement(input) {
|
|
13
|
+
if (typeof input === "string") {
|
|
14
|
+
if (typeof document === "undefined") return input;
|
|
15
|
+
return document.querySelector(input) ?? document.body;
|
|
16
|
+
}
|
|
17
|
+
if (input) return input;
|
|
18
|
+
return typeof document === "undefined" ? "body" : document.body;
|
|
19
|
+
}
|
|
20
|
+
const teleportTarget = computed(() => resolveTargetElement(props.target));
|
|
21
|
+
return (_ctx, _cache) => {
|
|
22
|
+
return openBlock(), createBlock(Teleport, { to: teleportTarget.value }, [createElementVNode("div", _hoisted_1, [renderSlot(_ctx.$slots, "default")])], 8, ["to"]);
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
//#endregion
|
|
27
|
+
export { Portal_vue_vue_type_script_setup_true_lang_default as default };
|
|
28
|
+
|
|
29
|
+
//# sourceMappingURL=Portal.vue_vue_type_script_setup_true_lang.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Portal.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../src/lib/vue/Portal.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue';\n\ninterface Props {\n\ttarget?: string | HTMLElement | null;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n\ttarget: 'body'\n});\n\ndefineSlots<{\n\tdefault(): unknown;\n}>();\n\n/**\n * Resolves a teleport target to a concrete DOM element, falling back to body.\n */\nfunction resolveTargetElement(\n\tinput: string | HTMLElement | null | undefined\n): HTMLElement | string {\n\tif (typeof input === 'string') {\n\t\tif (typeof document === 'undefined') {\n\t\t\treturn input;\n\t\t}\n\n\t\treturn document.querySelector<HTMLElement>(input) ?? document.body;\n\t}\n\n\tif (input) {\n\t\treturn input;\n\t}\n\n\treturn typeof document === 'undefined' ? 'body' : document.body;\n}\n\nconst teleportTarget = computed(() => resolveTargetElement(props.target));\n</script>\n\n<template>\n\t<Teleport :to=\"teleportTarget\">\n\t\t<div class=\"motiongpu-portal-root\">\n\t\t\t<slot />\n\t\t</div>\n\t</Teleport>\n</template>\n"],"mappings":";;;;;;;EAOA,MAAM,QAAQ;;;;EAWd,SAAS,qBACR,OACuB;AACvB,OAAI,OAAO,UAAU,UAAU;AAC9B,QAAI,OAAO,aAAa,YACvB,QAAO;AAGR,WAAO,SAAS,cAA2B,MAAM,IAAI,SAAS;;AAG/D,OAAI,MACH,QAAO;AAGR,UAAO,OAAO,aAAa,cAAc,SAAS,SAAS;;EAG5D,MAAM,iBAAiB,eAAe,qBAAqB,MAAM,OAAO,CAAC;;uBAIxE,YAIW,UAAA,EAJA,IAAI,eAAA,OAAc,EAAA,CAC5B,mBAEM,OAFN,YAEM,CADL,WAAQ,KAAA,QAAA,UAAA,CAAA,CAAA,CAAA,EAAA,GAAA,CAAA,KAAA,CAAA"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vue adapter advanced entrypoint for MotionGPU.
|
|
3
|
+
*/
|
|
4
|
+
export * from './index.js';
|
|
5
|
+
export { applySchedulerPreset, captureSchedulerDebugSnapshot } from '../core/scheduler-helpers.js';
|
|
6
|
+
export { setMotionGPUUserContext, useMotionGPUUserContext } from './use-motiongpu-user-context.js';
|
|
7
|
+
export type { ApplySchedulerPresetOptions, SchedulerDebugSnapshot, SchedulerPreset, SchedulerPresetConfig } from '../core/scheduler-helpers.js';
|
|
8
|
+
export type { MotionGPUUserContext, MotionGPUUserNamespace } from './motiongpu-context.js';
|
|
9
|
+
export type { FrameProfilingSnapshot, FrameKey, FrameTaskInvalidation, FrameTaskInvalidationToken, FrameRunTimings, FrameScheduleSnapshot, FrameStage, FrameStageCallback, FrameTimingStats, FrameTask } from '../core/frame-registry.js';
|
|
10
|
+
export type { SetMotionGPUUserContextOptions } from './use-motiongpu-user-context.js';
|
|
11
|
+
export type { RenderPassContext, RenderTarget, UniformLayout, UniformLayoutEntry } from '../core/types.js';
|
|
12
|
+
//# sourceMappingURL=advanced.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"advanced.d.ts","sourceRoot":"","sources":["../../src/lib/vue/advanced.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,oBAAoB,EAAE,6BAA6B,EAAE,MAAM,8BAA8B,CAAC;AACnG,OAAO,EAAE,uBAAuB,EAAE,uBAAuB,EAAE,MAAM,iCAAiC,CAAC;AACnG,YAAY,EACX,2BAA2B,EAC3B,sBAAsB,EACtB,eAAe,EACf,qBAAqB,EACrB,MAAM,8BAA8B,CAAC;AACtC,YAAY,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAC3F,YAAY,EACX,sBAAsB,EACtB,QAAQ,EACR,qBAAqB,EACrB,0BAA0B,EAC1B,eAAe,EACf,qBAAqB,EACrB,UAAU,EACV,kBAAkB,EAClB,gBAAgB,EAChB,SAAS,EACT,MAAM,2BAA2B,CAAC;AACnC,YAAY,EAAE,8BAA8B,EAAE,MAAM,iCAAiC,CAAC;AACtF,YAAY,EACX,iBAAiB,EACjB,YAAY,EACZ,aAAa,EACb,kBAAkB,EAClB,MAAM,kBAAkB,CAAC"}
|