text-shaper 0.1.3 → 0.1.5

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.
@@ -1,442 +0,0 @@
1
- var __defProp = Object.defineProperty;
2
- var __export = (target, all) => {
3
- for (var name in all)
4
- __defProp(target, name, {
5
- get: all[name],
6
- enumerable: true,
7
- configurable: true,
8
- set: (newValue) => all[name] = () => newValue
9
- });
10
- };
11
- var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
12
-
13
- // tests/performance/utils/perf-utils.ts
14
- class PerformanceTimer {
15
- startTime = 0;
16
- endTime = 0;
17
- start() {
18
- this.startTime = performance.now();
19
- }
20
- end() {
21
- this.endTime = performance.now();
22
- return this.duration();
23
- }
24
- duration() {
25
- return this.endTime - this.startTime;
26
- }
27
- static now() {
28
- return performance.now();
29
- }
30
- }
31
- async function benchmark(name, fn, options = {}) {
32
- const {
33
- iterations = 100,
34
- warmupIterations = 10,
35
- gcBetweenRuns = false
36
- } = options;
37
- for (let i = 0;i < warmupIterations; i++) {
38
- await fn();
39
- }
40
- if (gcBetweenRuns && globalThis.gc) {
41
- globalThis.gc();
42
- }
43
- const samples = [];
44
- let totalTime = 0;
45
- let minTime = Infinity;
46
- let maxTime = -Infinity;
47
- for (let i = 0;i < iterations; i++) {
48
- const start = PerformanceTimer.now();
49
- await fn();
50
- const end = PerformanceTimer.now();
51
- const duration = end - start;
52
- samples.push(duration);
53
- totalTime += duration;
54
- minTime = Math.min(minTime, duration);
55
- maxTime = Math.max(maxTime, duration);
56
- if (i % 10 === 9) {
57
- await new Promise((resolve) => setTimeout(resolve, 1));
58
- }
59
- }
60
- return {
61
- name,
62
- iterations,
63
- totalTime,
64
- avgTime: totalTime / iterations,
65
- minTime,
66
- maxTime,
67
- samples
68
- };
69
- }
70
- async function comparePerformance(name, impl1, impl2, options = {}) {
71
- const result1 = await benchmark(`${name}-impl1`, impl1, options);
72
- const result2 = await benchmark(`${name}-impl2`, impl2, options);
73
- const speedup = result1.avgTime / result2.avgTime;
74
- const winner = result1.avgTime < result2.avgTime ? "impl1" : "impl2";
75
- return {
76
- impl1: result1,
77
- impl2: result2,
78
- speedup: Math.max(speedup, 1 / speedup),
79
- winner
80
- };
81
- }
82
-
83
- class MemoryTracker {
84
- initialUsage = 0;
85
- start() {
86
- if (globalThis.performance?.memory) {
87
- this.initialUsage = globalThis.performance.memory.usedJSHeapSize;
88
- }
89
- }
90
- getUsage() {
91
- if (globalThis.performance?.memory) {
92
- return globalThis.performance.memory.usedJSHeapSize - this.initialUsage;
93
- }
94
- return 0;
95
- }
96
- format(bytes) {
97
- return `${(bytes / 1024 / 1024).toFixed(2)} MB`;
98
- }
99
- }
100
- function createPerformanceReport(results) {
101
- const report = [];
102
- report.push("=== Performance Benchmark Report ===");
103
- report.push(`Generated: ${new Date().toISOString()}`);
104
- report.push("");
105
- results.forEach((result) => {
106
- report.push(`${result.name}:`);
107
- report.push(` Iterations: ${result.iterations}`);
108
- report.push(` Average: ${result.avgTime.toFixed(3)} ms`);
109
- report.push(` Min: ${result.minTime.toFixed(3)} ms`);
110
- report.push(` Max: ${result.maxTime.toFixed(3)} ms`);
111
- report.push(` Total: ${result.totalTime.toFixed(3)} ms`);
112
- report.push("");
113
- });
114
- return report.join(`
115
- `);
116
- }
117
- function isWebGPUSupported() {
118
- return !!(navigator.gpu && navigator.gpu.requestAdapter);
119
- }
120
- function isWebGLSupported() {
121
- try {
122
- const canvas = document.createElement("canvas");
123
- return !!(canvas.getContext("webgl") || canvas.getContext("webgl2"));
124
- } catch {
125
- return false;
126
- }
127
- }
128
- async function getGPUInfo() {
129
- const info = {
130
- vendor: "Unknown",
131
- renderer: "Unknown",
132
- webgpu: isWebGPUSupported(),
133
- webgl: isWebGLSupported()
134
- };
135
- if (info.webgpu) {
136
- try {
137
- const adapter = await navigator.gpu.requestAdapter();
138
- if (adapter) {
139
- info.vendor = adapter.info?.vendor || "Unknown";
140
- info.renderer = adapter.info?.architecture || "Unknown";
141
- }
142
- } catch {}
143
- }
144
- if (info.webgl && info.vendor === "Unknown") {
145
- try {
146
- const canvas = document.createElement("canvas");
147
- const gl = canvas.getContext("webgl2") || canvas.getContext("webgl");
148
- if (gl) {
149
- const debugInfo = gl.getExtension("WEBGL_debug_renderer_info");
150
- if (debugInfo) {
151
- info.vendor = gl.getParameter(debugInfo.UNMASKED_VENDOR_WEBGL);
152
- info.renderer = gl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL);
153
- }
154
- }
155
- } catch {}
156
- }
157
- return info;
158
- }
159
-
160
- // tests/performance/gpu/webgpu-perf.ts
161
- async function initWebGPU() {
162
- if (!navigator.gpu) {
163
- console.warn("WebGPU not supported");
164
- return null;
165
- }
166
- try {
167
- const adapter = await navigator.gpu.requestAdapter();
168
- if (!adapter) {
169
- console.warn("No WebGPU adapter found");
170
- return null;
171
- }
172
- const device = await adapter.requestDevice();
173
- return { adapter, device };
174
- } catch (error) {
175
- console.error("WebGPU initialization failed:", error);
176
- return null;
177
- }
178
- }
179
- async function benchmarkWebGPUSDF(context, options = {}) {
180
- const { device } = context;
181
- const size = 64;
182
- const shaderCode = `
183
- @group(0) @binding(0) var<storage, read_write> distances: array<f32>;
184
- @group(0) @binding(1) var<uniform> params: vec4<f32>;
185
- @group(0) @binding(2) var<storage, read> edges: array<vec4<f32>>;
186
-
187
- @compute @workgroup_size(8, 8)
188
- fn main(@builtin(global_invocation_id) id: vec3<u32>) {
189
- let x = id.x;
190
- let y = id.y;
191
- let width = u32(params.x);
192
- let height = u32(params.y);
193
-
194
- if (x >= width || y >= height) { return; }
195
-
196
- let px = f32(x) + 0.5;
197
- let py = f32(y) + 0.5;
198
- var minDist = 1000000.0;
199
-
200
- // Simple point-to-edge distance calculation
201
- for (var i = 0u; i < arrayLength(&edges); i = i + 1u) {
202
- let edge = edges[i];
203
- let dx = px - edge.x;
204
- let dy = py - edge.y;
205
- let dist = sqrt(dx * dx + dy * dy);
206
- minDist = min(minDist, dist);
207
- }
208
-
209
- distances[y * width + x] = minDist / params.z; // Normalize by spread
210
- }
211
- `;
212
- const shaderModule = device.createShaderModule({ code: shaderCode });
213
- const computePipeline = device.createComputePipeline({
214
- layout: "auto",
215
- compute: { module: shaderModule, entryPoint: "main" }
216
- });
217
- const distanceBuffer = device.createBuffer({
218
- size: size * size * 4,
219
- usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC
220
- });
221
- const uniformBuffer = device.createBuffer({
222
- size: 16,
223
- usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST
224
- });
225
- const edgeBuffer = device.createBuffer({
226
- size: 100 * 16,
227
- usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST
228
- });
229
- const bindGroup = device.createBindGroup({
230
- layout: computePipeline.getBindGroupLayout(0),
231
- entries: [
232
- { binding: 0, resource: { buffer: distanceBuffer } },
233
- { binding: 1, resource: { buffer: uniformBuffer } },
234
- { binding: 2, resource: { buffer: edgeBuffer } }
235
- ]
236
- });
237
- device.queue.writeBuffer(uniformBuffer, 0, new Float32Array([size, size, 8, 0]));
238
- return benchmark("WebGPU SDF Generation", async () => {
239
- const commandEncoder = device.createCommandEncoder();
240
- const computePass = commandEncoder.beginComputePass();
241
- computePass.setPipeline(computePipeline);
242
- computePass.setBindGroup(0, bindGroup);
243
- computePass.dispatchWorkgroups(Math.ceil(size / 8), Math.ceil(size / 8));
244
- computePass.end();
245
- device.queue.submit([commandEncoder.finish()]);
246
- }, options);
247
- }
248
- async function benchmarkWebGPUAtlasPacking(context, options = {}) {
249
- const { device } = context;
250
- const atlasSize = 512;
251
- const glyphCount = 256;
252
- const shaderCode = `
253
- struct Rect {
254
- x: f32,
255
- y: f32,
256
- width: f32,
257
- height: f32,
258
- placed: u32
259
- };
260
-
261
- @group(0) @binding(0) var<storage, read_write> rects: array<Rect>;
262
- @group(0) @binding(1) var<storage, read_write> atlas: array<u32>;
263
- @group(0) @binding(2) var<uniform> params: vec4<u32>;
264
-
265
- @compute @workgroup_size(16, 16)
266
- fn main(@builtin(global_invocation_id) id: vec3<u32>) {
267
- let rectIndex = id.x;
268
- let attempt = id.y;
269
-
270
- if (rectIndex >= params.x) { return; }
271
-
272
- let rect = &rects[rectIndex];
273
- if (rect.placed != 0u) { return; }
274
-
275
- // Simple packing algorithm - try different positions
276
- let x = (rectIndex * 7u + attempt * 13u) % (params.y - u32(rect.width));
277
- let y = (rectIndex * 11u + attempt * 17u) % (params.z - u32(rect.height));
278
-
279
- // Check if position is available (simplified)
280
- var canPlace = true;
281
- for (var dy = 0u; dy < u32(rect.height); dy = dy + 1u) {
282
- for (var dx = 0u; dx < u32(rect.width); dx = dx + 1u) {
283
- let atlasIdx = (y + dy) * params.y + (x + dx);
284
- if (atlas[atlasIdx] != 0u) {
285
- canPlace = false;
286
- break;
287
- }
288
- }
289
- if (!canPlace) { break; }
290
- }
291
-
292
- if (canPlace) {
293
- rect.x = f32(x);
294
- rect.y = f32(y);
295
- rect.placed = 1u;
296
-
297
- // Mark atlas positions as used
298
- for (var dy = 0u; dy < u32(rect.height); dy = dy + 1u) {
299
- for (var dx = 0u; dx < u32(rect.width); dx = dx + 1u) {
300
- let atlasIdx = (y + dy) * params.y + (x + dx);
301
- atlas[atlasIdx] = 1u;
302
- }
303
- }
304
- }
305
- }
306
- `;
307
- const shaderModule = device.createShaderModule({ code: shaderCode });
308
- const computePipeline = device.createComputePipeline({
309
- layout: "auto",
310
- compute: { module: shaderModule, entryPoint: "main" }
311
- });
312
- const rectBuffer = device.createBuffer({
313
- size: glyphCount * 20,
314
- usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST
315
- });
316
- const atlasBuffer = device.createBuffer({
317
- size: atlasSize * atlasSize * 4,
318
- usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST
319
- });
320
- const uniformBuffer = device.createBuffer({
321
- size: 16,
322
- usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST
323
- });
324
- const bindGroup = device.createBindGroup({
325
- layout: computePipeline.getBindGroupLayout(0),
326
- entries: [
327
- { binding: 0, resource: { buffer: rectBuffer } },
328
- { binding: 1, resource: { buffer: atlasBuffer } },
329
- { binding: 2, resource: { buffer: uniformBuffer } }
330
- ]
331
- });
332
- const rects = new ArrayBuffer(glyphCount * 20);
333
- const rectView = new DataView(rects);
334
- for (let i = 0;i < glyphCount; i++) {
335
- rectView.setFloat32(i * 20 + 0, 0, true);
336
- rectView.setFloat32(i * 20 + 4, 0, true);
337
- rectView.setFloat32(i * 20 + 8, 16 + i % 32, true);
338
- rectView.setFloat32(i * 20 + 12, 16 + i % 16, true);
339
- rectView.setUint32(i * 20 + 16, 0, true);
340
- }
341
- device.queue.writeBuffer(rectBuffer, 0, rects);
342
- device.queue.writeBuffer(uniformBuffer, 0, new Uint32Array([glyphCount, atlasSize, atlasSize, 0]));
343
- return benchmark("WebGPU Atlas Packing", async () => {
344
- const commandEncoder = device.createCommandEncoder();
345
- const computePass = commandEncoder.beginComputePass();
346
- computePass.setPipeline(computePipeline);
347
- computePass.setBindGroup(0, bindGroup);
348
- computePass.dispatchWorkgroups(Math.ceil(glyphCount / 16), 32);
349
- computePass.end();
350
- device.queue.submit([commandEncoder.finish()]);
351
- }, options);
352
- }
353
- async function benchmarkWebGPUGlyphRendering(context, options = {}) {
354
- const { device } = context;
355
- const glyphCount = 128;
356
- const glyphSize = 32;
357
- const shaderCode = `
358
- @group(0) @binding(0) var<storage, read> glyphData: array<vec4<f32>>;
359
- @group(0) @binding(1) var<storage, read_write> outputAtlas: array<vec4<f32>>;
360
- @group(0) @binding(2) var<uniform> params: vec4<u32>;
361
-
362
- fn drawPixel(x: u32, y: u32, glyphIndex: u32, color: vec4<f32>) {
363
- let atlasX = (glyphIndex % params.z) * params.x + x;
364
- let atlasY = (glyphIndex / params.z) * params.y + y;
365
- let atlasIndex = atlasY * (params.z * params.x) + atlasX;
366
-
367
- if (atlasIndex < arrayLength(&outputAtlas)) {
368
- outputAtlas[atlasIndex] = color;
369
- }
370
- }
371
-
372
- @compute @workgroup_size(8, 8)
373
- fn main(@builtin(global_invocation_id) id: vec3<u32>) {
374
- let x = id.x;
375
- let y = id.y;
376
- let glyphIndex = id.z;
377
-
378
- if (glyphIndex >= params.w) { return; }
379
- if (x >= params.x || y >= params.y) { return; }
380
-
381
- // Simple circle glyph simulation
382
- let center = vec2<f32>(f32(params.x) / 2.0, f32(params.y) / 2.0);
383
- let pos = vec2<f32>(f32(x), f32(y));
384
- let dist = distance(pos, center);
385
-
386
- if (dist < f32(params.x) / 2.0) {
387
- let alpha = 1.0 - (dist / (f32(params.x) / 2.0));
388
- drawPixel(x, y, glyphIndex, vec4<f32>(1.0, 1.0, 1.0, alpha));
389
- }
390
- }
391
- `;
392
- const shaderModule = device.createShaderModule({ code: shaderCode });
393
- const computePipeline = device.createComputePipeline({
394
- layout: "auto",
395
- compute: { module: shaderModule, entryPoint: "main" }
396
- });
397
- const glyphBuffer = device.createBuffer({
398
- size: glyphCount * 16,
399
- usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST
400
- });
401
- const atlasSize = Math.ceil(Math.sqrt(glyphCount)) * glyphSize;
402
- const outputBuffer = device.createBuffer({
403
- size: atlasSize * atlasSize * 16,
404
- usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC
405
- });
406
- const uniformBuffer = device.createBuffer({
407
- size: 16,
408
- usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST
409
- });
410
- const bindGroup = device.createBindGroup({
411
- layout: computePipeline.getBindGroupLayout(0),
412
- entries: [
413
- { binding: 0, resource: { buffer: glyphBuffer } },
414
- { binding: 1, resource: { buffer: outputBuffer } },
415
- { binding: 2, resource: { buffer: uniformBuffer } }
416
- ]
417
- });
418
- const glyphsPerRow = Math.ceil(Math.sqrt(glyphCount));
419
- device.queue.writeBuffer(uniformBuffer, 0, new Uint32Array([
420
- glyphSize,
421
- glyphSize,
422
- glyphsPerRow,
423
- glyphCount
424
- ]));
425
- return benchmark("WebGPU Parallel Glyph Rendering", async () => {
426
- const commandEncoder = device.createCommandEncoder();
427
- const computePass = commandEncoder.beginComputePass();
428
- computePass.setPipeline(computePipeline);
429
- computePass.setBindGroup(0, bindGroup);
430
- computePass.dispatchWorkgroups(Math.ceil(glyphSize / 8), Math.ceil(glyphSize / 8), glyphCount);
431
- computePass.end();
432
- device.queue.submit([commandEncoder.finish()]);
433
- }, options);
434
- }
435
- export {
436
- initWebGPU,
437
- benchmarkWebGPUSDF,
438
- benchmarkWebGPUGlyphRendering,
439
- benchmarkWebGPUAtlasPacking
440
- };
441
-
442
- //# debugId=4DC44201FDB035E564756E2164756E21
@@ -1,11 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../tests/performance/utils/perf-utils.ts", "../../tests/performance/gpu/webgpu-perf.ts"],
4
- "sourcesContent": [
5
- "/**\n * Performance testing utilities for browser-based benchmarks\n */\n\nexport interface PerformanceResult {\n name: string;\n iterations: number;\n totalTime: number;\n avgTime: number;\n minTime: number;\n maxTime: number;\n samples: number[];\n}\n\nexport interface BenchmarkOptions {\n iterations?: number;\n warmupIterations?: number;\n gcBetweenRuns?: boolean;\n}\n\n/**\n * High-precision timing utility\n */\nexport class PerformanceTimer {\n private startTime = 0;\n private endTime = 0;\n\n start(): void {\n this.startTime = performance.now();\n }\n\n end(): number {\n this.endTime = performance.now();\n return this.duration();\n }\n\n duration(): number {\n return this.endTime - this.startTime;\n }\n\n static now(): number {\n return performance.now();\n }\n}\n\n/**\n * Run a performance benchmark on a function\n */\nexport async function benchmark(\n name: string,\n fn: () => void | Promise<void>,\n options: BenchmarkOptions = {}\n): Promise<PerformanceResult> {\n const {\n iterations = 100,\n warmupIterations = 10,\n gcBetweenRuns = false\n } = options;\n\n // Warmup\n for (let i = 0; i < warmupIterations; i++) {\n await fn();\n }\n\n // Force GC if available and requested\n if (gcBetweenRuns && (globalThis as any).gc) {\n (globalThis as any).gc();\n }\n\n const samples: number[] = [];\n let totalTime = 0;\n let minTime = Infinity;\n let maxTime = -Infinity;\n\n // Run benchmark\n for (let i = 0; i < iterations; i++) {\n const start = PerformanceTimer.now();\n await fn();\n const end = PerformanceTimer.now();\n \n const duration = end - start;\n samples.push(duration);\n totalTime += duration;\n minTime = Math.min(minTime, duration);\n maxTime = Math.max(maxTime, duration);\n\n // Small delay between iterations to prevent overheating\n if (i % 10 === 9) {\n await new Promise(resolve => setTimeout(resolve, 1));\n }\n }\n\n return {\n name,\n iterations,\n totalTime,\n avgTime: totalTime / iterations,\n minTime,\n maxTime,\n samples\n };\n}\n\n/**\n * Compare performance between two implementations\n */\nexport async function comparePerformance(\n name: string,\n impl1: () => void | Promise<void>,\n impl2: () => void | Promise<void>,\n options: BenchmarkOptions = {}\n): Promise<{\n impl1: PerformanceResult;\n impl2: PerformanceResult;\n speedup: number;\n winner: string;\n}> {\n const result1 = await benchmark(`${name}-impl1`, impl1, options);\n const result2 = await benchmark(`${name}-impl2`, impl2, options);\n\n const speedup = result1.avgTime / result2.avgTime;\n const winner = result1.avgTime < result2.avgTime ? 'impl1' : 'impl2';\n\n return {\n impl1: result1,\n impl2: result2,\n speedup: Math.max(speedup, 1 / speedup),\n winner\n };\n}\n\n/**\n * Memory usage tracker\n */\nexport class MemoryTracker {\n private initialUsage: number = 0;\n\n start(): void {\n if ((globalThis as any).performance?.memory) {\n this.initialUsage = (globalThis as any).performance.memory.usedJSHeapSize;\n }\n }\n\n getUsage(): number {\n if ((globalThis as any).performance?.memory) {\n return (globalThis as any).performance.memory.usedJSHeapSize - this.initialUsage;\n }\n return 0;\n }\n\n format(bytes: number): string {\n return `${(bytes / 1024 / 1024).toFixed(2)} MB`;\n }\n}\n\n/**\n * Create a performance report\n */\nexport function createPerformanceReport(results: PerformanceResult[]): string {\n const report: string[] = [];\n \n report.push('=== Performance Benchmark Report ===');\n report.push(`Generated: ${new Date().toISOString()}`);\n report.push('');\n\n results.forEach(result => {\n report.push(`${result.name}:`);\n report.push(` Iterations: ${result.iterations}`);\n report.push(` Average: ${result.avgTime.toFixed(3)} ms`);\n report.push(` Min: ${result.minTime.toFixed(3)} ms`);\n report.push(` Max: ${result.maxTime.toFixed(3)} ms`);\n report.push(` Total: ${result.totalTime.toFixed(3)} ms`);\n report.push('');\n });\n\n return report.join('\\n');\n}\n\n/**\n * WebGPU support detection\n */\nexport function isWebGPUSupported(): boolean {\n return !!(navigator.gpu && navigator.gpu.requestAdapter);\n}\n\n/**\n * WebGL support detection\n */\nexport function isWebGLSupported(): boolean {\n try {\n const canvas = document.createElement('canvas');\n return !!(canvas.getContext('webgl') || canvas.getContext('webgl2'));\n } catch {\n return false;\n }\n}\n\n/**\n * Get GPU information\n */\nexport async function getGPUInfo(): Promise<{\n vendor: string;\n renderer: string;\n webgpu: boolean;\n webgl: boolean;\n}> {\n const info = {\n vendor: 'Unknown',\n renderer: 'Unknown',\n webgpu: isWebGPUSupported(),\n webgl: isWebGLSupported()\n };\n\n // Try WebGPU\n if (info.webgpu) {\n try {\n const adapter = await navigator.gpu.requestAdapter();\n if (adapter) {\n info.vendor = adapter.info?.vendor || 'Unknown';\n info.renderer = adapter.info?.architecture || 'Unknown';\n }\n } catch {\n // Ignore\n }\n }\n\n // Fallback to WebGL\n if (info.webgl && info.vendor === 'Unknown') {\n try {\n const canvas = document.createElement('canvas');\n const gl = canvas.getContext('webgl2') || canvas.getContext('webgl');\n if (gl) {\n const debugInfo = gl.getExtension('WEBGL_debug_renderer_info');\n if (debugInfo) {\n info.vendor = gl.getParameter(debugInfo.UNMASKED_VENDOR_WEBGL) as string;\n info.renderer = gl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL) as string;\n }\n }\n } catch {\n // Ignore\n }\n }\n\n return info;\n}",
6
- "/**\n * WebGPU Performance Tests\n */\n\nimport { benchmark, PerformanceResult, BenchmarkOptions } from '../utils/perf-utils.js';\n\nexport interface WebGPUTestContext {\n adapter: GPUAdapter;\n device: GPUDevice;\n commandEncoder?: GPUCommandEncoder;\n}\n\n/**\n * Initialize WebGPU context\n */\nexport async function initWebGPU(): Promise<WebGPUTestContext | null> {\n if (!navigator.gpu) {\n console.warn('WebGPU not supported');\n return null;\n }\n\n try {\n const adapter = await navigator.gpu.requestAdapter();\n if (!adapter) {\n console.warn('No WebGPU adapter found');\n return null;\n }\n\n const device = await adapter.requestDevice();\n return { adapter, device };\n } catch (error) {\n console.error('WebGPU initialization failed:', error);\n return null;\n }\n}\n\n/**\n * WebGPU SDF Generation Performance Test\n */\nexport async function benchmarkWebGPUSDF(\n context: WebGPUTestContext,\n options: BenchmarkOptions = {}\n): Promise<PerformanceResult> {\n const { device } = context;\n const size = 64;\n\n // Create compute shader for SDF generation\n const shaderCode = `\n @group(0) @binding(0) var<storage, read_write> distances: array<f32>;\n @group(0) @binding(1) var<uniform> params: vec4<f32>;\n @group(0) @binding(2) var<storage, read> edges: array<vec4<f32>>;\n\n @compute @workgroup_size(8, 8)\n fn main(@builtin(global_invocation_id) id: vec3<u32>) {\n let x = id.x;\n let y = id.y;\n let width = u32(params.x);\n let height = u32(params.y);\n\n if (x >= width || y >= height) { return; }\n\n let px = f32(x) + 0.5;\n let py = f32(y) + 0.5;\n var minDist = 1000000.0;\n\n // Simple point-to-edge distance calculation\n for (var i = 0u; i < arrayLength(&edges); i = i + 1u) {\n let edge = edges[i];\n let dx = px - edge.x;\n let dy = py - edge.y;\n let dist = sqrt(dx * dx + dy * dy);\n minDist = min(minDist, dist);\n }\n\n distances[y * width + x] = minDist / params.z; // Normalize by spread\n }\n `;\n\n const shaderModule = device.createShaderModule({ code: shaderCode });\n const computePipeline = device.createComputePipeline({\n layout: 'auto',\n compute: { module: shaderModule, entryPoint: 'main' }\n });\n\n // Create buffers\n const distanceBuffer = device.createBuffer({\n size: size * size * 4,\n usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC\n });\n\n const uniformBuffer = device.createBuffer({\n size: 16,\n usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST\n });\n\n // Sample edge data (simplified)\n const edgeBuffer = device.createBuffer({\n size: 100 * 16, // 100 edges * vec4<f32>\n usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST\n });\n\n const bindGroup = device.createBindGroup({\n layout: computePipeline.getBindGroupLayout(0),\n entries: [\n { binding: 0, resource: { buffer: distanceBuffer } },\n { binding: 1, resource: { buffer: uniformBuffer } },\n { binding: 2, resource: { buffer: edgeBuffer } }\n ]\n });\n\n // Upload uniform data\n device.queue.writeBuffer(uniformBuffer, 0, new Float32Array([size, size, 8.0, 0.0]));\n\n return benchmark('WebGPU SDF Generation', async () => {\n const commandEncoder = device.createCommandEncoder();\n const computePass = commandEncoder.beginComputePass();\n \n computePass.setPipeline(computePipeline);\n computePass.setBindGroup(0, bindGroup);\n computePass.dispatchWorkgroups(Math.ceil(size / 8), Math.ceil(size / 8));\n computePass.end();\n\n device.queue.submit([commandEncoder.finish()]);\n }, options);\n}\n\n/**\n * WebGPU Texture Atlas Packing Performance Test\n */\nexport async function benchmarkWebGPUAtlasPacking(\n context: WebGPUTestContext,\n options: BenchmarkOptions = {}\n): Promise<PerformanceResult> {\n const { device } = context;\n const atlasSize = 512;\n const glyphCount = 256;\n\n const shaderCode = `\n struct Rect {\n x: f32,\n y: f32,\n width: f32,\n height: f32,\n placed: u32\n };\n\n @group(0) @binding(0) var<storage, read_write> rects: array<Rect>;\n @group(0) @binding(1) var<storage, read_write> atlas: array<u32>;\n @group(0) @binding(2) var<uniform> params: vec4<u32>;\n\n @compute @workgroup_size(16, 16)\n fn main(@builtin(global_invocation_id) id: vec3<u32>) {\n let rectIndex = id.x;\n let attempt = id.y;\n \n if (rectIndex >= params.x) { return; }\n \n let rect = &rects[rectIndex];\n if (rect.placed != 0u) { return; }\n\n // Simple packing algorithm - try different positions\n let x = (rectIndex * 7u + attempt * 13u) % (params.y - u32(rect.width));\n let y = (rectIndex * 11u + attempt * 17u) % (params.z - u32(rect.height));\n\n // Check if position is available (simplified)\n var canPlace = true;\n for (var dy = 0u; dy < u32(rect.height); dy = dy + 1u) {\n for (var dx = 0u; dx < u32(rect.width); dx = dx + 1u) {\n let atlasIdx = (y + dy) * params.y + (x + dx);\n if (atlas[atlasIdx] != 0u) {\n canPlace = false;\n break;\n }\n }\n if (!canPlace) { break; }\n }\n\n if (canPlace) {\n rect.x = f32(x);\n rect.y = f32(y);\n rect.placed = 1u;\n \n // Mark atlas positions as used\n for (var dy = 0u; dy < u32(rect.height); dy = dy + 1u) {\n for (var dx = 0u; dx < u32(rect.width); dx = dx + 1u) {\n let atlasIdx = (y + dy) * params.y + (x + dx);\n atlas[atlasIdx] = 1u;\n }\n }\n }\n }\n `;\n\n const shaderModule = device.createShaderModule({ code: shaderCode });\n const computePipeline = device.createComputePipeline({\n layout: 'auto',\n compute: { module: shaderModule, entryPoint: 'main' }\n });\n\n // Create buffers\n const rectBuffer = device.createBuffer({\n size: glyphCount * 20, // sizeof(Rect)\n usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST\n });\n\n const atlasBuffer = device.createBuffer({\n size: atlasSize * atlasSize * 4,\n usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST\n });\n\n const uniformBuffer = device.createBuffer({\n size: 16,\n usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST\n });\n\n const bindGroup = device.createBindGroup({\n layout: computePipeline.getBindGroupLayout(0),\n entries: [\n { binding: 0, resource: { buffer: rectBuffer } },\n { binding: 1, resource: { buffer: atlasBuffer } },\n { binding: 2, resource: { buffer: uniformBuffer } }\n ]\n });\n\n // Initialize data\n const rects = new ArrayBuffer(glyphCount * 20);\n const rectView = new DataView(rects);\n for (let i = 0; i < glyphCount; i++) {\n rectView.setFloat32(i * 20 + 0, 0, true); // x\n rectView.setFloat32(i * 20 + 4, 0, true); // y\n rectView.setFloat32(i * 20 + 8, 16 + (i % 32), true); // width\n rectView.setFloat32(i * 20 + 12, 16 + (i % 16), true); // height\n rectView.setUint32(i * 20 + 16, 0, true); // placed\n }\n\n device.queue.writeBuffer(rectBuffer, 0, rects);\n device.queue.writeBuffer(uniformBuffer, 0, new Uint32Array([glyphCount, atlasSize, atlasSize, 0]));\n\n return benchmark('WebGPU Atlas Packing', async () => {\n const commandEncoder = device.createCommandEncoder();\n const computePass = commandEncoder.beginComputePass();\n \n computePass.setPipeline(computePipeline);\n computePass.setBindGroup(0, bindGroup);\n computePass.dispatchWorkgroups(Math.ceil(glyphCount / 16), 32);\n computePass.end();\n\n device.queue.submit([commandEncoder.finish()]);\n }, options);\n}\n\n/**\n * WebGPU Parallel Glyph Rendering Performance Test\n */\nexport async function benchmarkWebGPUGlyphRendering(\n context: WebGPUTestContext,\n options: BenchmarkOptions = {}\n): Promise<PerformanceResult> {\n const { device } = context;\n const glyphCount = 128;\n const glyphSize = 32;\n\n const shaderCode = `\n @group(0) @binding(0) var<storage, read> glyphData: array<vec4<f32>>;\n @group(0) @binding(1) var<storage, read_write> outputAtlas: array<vec4<f32>>;\n @group(0) @binding(2) var<uniform> params: vec4<u32>;\n\n fn drawPixel(x: u32, y: u32, glyphIndex: u32, color: vec4<f32>) {\n let atlasX = (glyphIndex % params.z) * params.x + x;\n let atlasY = (glyphIndex / params.z) * params.y + y;\n let atlasIndex = atlasY * (params.z * params.x) + atlasX;\n \n if (atlasIndex < arrayLength(&outputAtlas)) {\n outputAtlas[atlasIndex] = color;\n }\n }\n\n @compute @workgroup_size(8, 8)\n fn main(@builtin(global_invocation_id) id: vec3<u32>) {\n let x = id.x;\n let y = id.y;\n let glyphIndex = id.z;\n \n if (glyphIndex >= params.w) { return; }\n if (x >= params.x || y >= params.y) { return; }\n\n // Simple circle glyph simulation\n let center = vec2<f32>(f32(params.x) / 2.0, f32(params.y) / 2.0);\n let pos = vec2<f32>(f32(x), f32(y));\n let dist = distance(pos, center);\n \n if (dist < f32(params.x) / 2.0) {\n let alpha = 1.0 - (dist / (f32(params.x) / 2.0));\n drawPixel(x, y, glyphIndex, vec4<f32>(1.0, 1.0, 1.0, alpha));\n }\n }\n `;\n\n const shaderModule = device.createShaderModule({ code: shaderCode });\n const computePipeline = device.createComputePipeline({\n layout: 'auto',\n compute: { module: shaderModule, entryPoint: 'main' }\n });\n\n // Create buffers\n const glyphBuffer = device.createBuffer({\n size: glyphCount * 16,\n usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST\n });\n\n const atlasSize = Math.ceil(Math.sqrt(glyphCount)) * glyphSize;\n const outputBuffer = device.createBuffer({\n size: atlasSize * atlasSize * 16, // vec4<f32>\n usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC\n });\n\n const uniformBuffer = device.createBuffer({\n size: 16,\n usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST\n });\n\n const bindGroup = device.createBindGroup({\n layout: computePipeline.getBindGroupLayout(0),\n entries: [\n { binding: 0, resource: { buffer: glyphBuffer } },\n { binding: 1, resource: { buffer: outputBuffer } },\n { binding: 2, resource: { buffer: uniformBuffer } }\n ]\n });\n\n // Initialize uniform data\n const glyphsPerRow = Math.ceil(Math.sqrt(glyphCount));\n device.queue.writeBuffer(uniformBuffer, 0, new Uint32Array([\n glyphSize, glyphSize, glyphsPerRow, glyphCount\n ]));\n\n return benchmark('WebGPU Parallel Glyph Rendering', async () => {\n const commandEncoder = device.createCommandEncoder();\n const computePass = commandEncoder.beginComputePass();\n \n computePass.setPipeline(computePipeline);\n computePass.setBindGroup(0, bindGroup);\n computePass.dispatchWorkgroups(\n Math.ceil(glyphSize / 8),\n Math.ceil(glyphSize / 8),\n glyphCount\n );\n computePass.end();\n\n device.queue.submit([commandEncoder.finish()]);\n }, options);\n}"
7
- ],
8
- "mappings": ";;;;;;;;;;;;;AAuBO,MAAM,iBAAiB;AAAA,EACpB,YAAY;AAAA,EACZ,UAAU;AAAA,EAElB,KAAK,GAAS;AAAA,IACZ,KAAK,YAAY,YAAY,IAAI;AAAA;AAAA,EAGnC,GAAG,GAAW;AAAA,IACZ,KAAK,UAAU,YAAY,IAAI;AAAA,IAC/B,OAAO,KAAK,SAAS;AAAA;AAAA,EAGvB,QAAQ,GAAW;AAAA,IACjB,OAAO,KAAK,UAAU,KAAK;AAAA;AAAA,SAGtB,GAAG,GAAW;AAAA,IACnB,OAAO,YAAY,IAAI;AAAA;AAE3B;AAKA,eAAsB,SAAS,CAC7B,MACA,IACA,UAA4B,CAAC,GACD;AAAA,EAC5B;AAAA,IACE,aAAa;AAAA,IACb,mBAAmB;AAAA,IACnB,gBAAgB;AAAA,MACd;AAAA,EAGJ,SAAS,IAAI,EAAG,IAAI,kBAAkB,KAAK;AAAA,IACzC,MAAM,GAAG;AAAA,EACX;AAAA,EAGA,IAAI,iBAAkB,WAAmB,IAAI;AAAA,IAC1C,WAAmB,GAAG;AAAA,EACzB;AAAA,EAEA,MAAM,UAAoB,CAAC;AAAA,EAC3B,IAAI,YAAY;AAAA,EAChB,IAAI,UAAU;AAAA,EACd,IAAI,UAAU;AAAA,EAGd,SAAS,IAAI,EAAG,IAAI,YAAY,KAAK;AAAA,IACnC,MAAM,QAAQ,iBAAiB,IAAI;AAAA,IACnC,MAAM,GAAG;AAAA,IACT,MAAM,MAAM,iBAAiB,IAAI;AAAA,IAEjC,MAAM,WAAW,MAAM;AAAA,IACvB,QAAQ,KAAK,QAAQ;AAAA,IACrB,aAAa;AAAA,IACb,UAAU,KAAK,IAAI,SAAS,QAAQ;AAAA,IACpC,UAAU,KAAK,IAAI,SAAS,QAAQ;AAAA,IAGpC,IAAI,IAAI,OAAO,GAAG;AAAA,MAChB,MAAM,IAAI,QAAQ,aAAW,WAAW,SAAS,CAAC,CAAC;AAAA,IACrD;AAAA,EACF;AAAA,EAEA,OAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,SAAS,YAAY;AAAA,IACrB;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA;AAMF,eAAsB,kBAAkB,CACtC,MACA,OACA,OACA,UAA4B,CAAC,GAM5B;AAAA,EACD,MAAM,UAAU,MAAM,UAAU,GAAG,cAAc,OAAO,OAAO;AAAA,EAC/D,MAAM,UAAU,MAAM,UAAU,GAAG,cAAc,OAAO,OAAO;AAAA,EAE/D,MAAM,UAAU,QAAQ,UAAU,QAAQ;AAAA,EAC1C,MAAM,SAAS,QAAQ,UAAU,QAAQ,UAAU,UAAU;AAAA,EAE7D,OAAO;AAAA,IACL,OAAO;AAAA,IACP,OAAO;AAAA,IACP,SAAS,KAAK,IAAI,SAAS,IAAI,OAAO;AAAA,IACtC;AAAA,EACF;AAAA;AAAA;AAMK,MAAM,cAAc;AAAA,EACjB,eAAuB;AAAA,EAE/B,KAAK,GAAS;AAAA,IACZ,IAAK,WAAmB,aAAa,QAAQ;AAAA,MAC3C,KAAK,eAAgB,WAAmB,YAAY,OAAO;AAAA,IAC7D;AAAA;AAAA,EAGF,QAAQ,GAAW;AAAA,IACjB,IAAK,WAAmB,aAAa,QAAQ;AAAA,MAC3C,OAAQ,WAAmB,YAAY,OAAO,iBAAiB,KAAK;AAAA,IACtE;AAAA,IACA,OAAO;AAAA;AAAA,EAGT,MAAM,CAAC,OAAuB;AAAA,IAC5B,OAAO,IAAI,QAAQ,OAAO,MAAM,QAAQ,CAAC;AAAA;AAE7C;AAKO,SAAS,uBAAuB,CAAC,SAAsC;AAAA,EAC5E,MAAM,SAAmB,CAAC;AAAA,EAE1B,OAAO,KAAK,sCAAsC;AAAA,EAClD,OAAO,KAAK,cAAc,IAAI,KAAK,EAAE,YAAY,GAAG;AAAA,EACpD,OAAO,KAAK,EAAE;AAAA,EAEd,QAAQ,QAAQ,YAAU;AAAA,IACxB,OAAO,KAAK,GAAG,OAAO,OAAO;AAAA,IAC7B,OAAO,KAAK,iBAAiB,OAAO,YAAY;AAAA,IAChD,OAAO,KAAK,cAAc,OAAO,QAAQ,QAAQ,CAAC,MAAM;AAAA,IACxD,OAAO,KAAK,UAAU,OAAO,QAAQ,QAAQ,CAAC,MAAM;AAAA,IACpD,OAAO,KAAK,UAAU,OAAO,QAAQ,QAAQ,CAAC,MAAM;AAAA,IACpD,OAAO,KAAK,YAAY,OAAO,UAAU,QAAQ,CAAC,MAAM;AAAA,IACxD,OAAO,KAAK,EAAE;AAAA,GACf;AAAA,EAED,OAAO,OAAO,KAAK;AAAA,CAAI;AAAA;AAMlB,SAAS,iBAAiB,GAAY;AAAA,EAC3C,OAAO,CAAC,EAAE,UAAU,OAAO,UAAU,IAAI;AAAA;AAMpC,SAAS,gBAAgB,GAAY;AAAA,EAC1C,IAAI;AAAA,IACF,MAAM,SAAS,SAAS,cAAc,QAAQ;AAAA,IAC9C,OAAO,CAAC,EAAE,OAAO,WAAW,OAAO,KAAK,OAAO,WAAW,QAAQ;AAAA,IAClE,MAAM;AAAA,IACN,OAAO;AAAA;AAAA;AAOX,eAAsB,UAAU,GAK7B;AAAA,EACD,MAAM,OAAO;AAAA,IACX,QAAQ;AAAA,IACR,UAAU;AAAA,IACV,QAAQ,kBAAkB;AAAA,IAC1B,OAAO,iBAAiB;AAAA,EAC1B;AAAA,EAGA,IAAI,KAAK,QAAQ;AAAA,IACf,IAAI;AAAA,MACF,MAAM,UAAU,MAAM,UAAU,IAAI,eAAe;AAAA,MACnD,IAAI,SAAS;AAAA,QACX,KAAK,SAAS,QAAQ,MAAM,UAAU;AAAA,QACtC,KAAK,WAAW,QAAQ,MAAM,gBAAgB;AAAA,MAChD;AAAA,MACA,MAAM;AAAA,EAGV;AAAA,EAGA,IAAI,KAAK,SAAS,KAAK,WAAW,WAAW;AAAA,IAC3C,IAAI;AAAA,MACF,MAAM,SAAS,SAAS,cAAc,QAAQ;AAAA,MAC9C,MAAM,KAAK,OAAO,WAAW,QAAQ,KAAK,OAAO,WAAW,OAAO;AAAA,MACnE,IAAI,IAAI;AAAA,QACN,MAAM,YAAY,GAAG,aAAa,2BAA2B;AAAA,QAC7D,IAAI,WAAW;AAAA,UACb,KAAK,SAAS,GAAG,aAAa,UAAU,qBAAqB;AAAA,UAC7D,KAAK,WAAW,GAAG,aAAa,UAAU,uBAAuB;AAAA,QACnE;AAAA,MACF;AAAA,MACA,MAAM;AAAA,EAGV;AAAA,EAEA,OAAO;AAAA;;;ACpOT,eAAsB,UAAU,GAAsC;AAAA,EACpE,IAAI,CAAC,UAAU,KAAK;AAAA,IAClB,QAAQ,KAAK,sBAAsB;AAAA,IACnC,OAAO;AAAA,EACT;AAAA,EAEA,IAAI;AAAA,IACF,MAAM,UAAU,MAAM,UAAU,IAAI,eAAe;AAAA,IACnD,IAAI,CAAC,SAAS;AAAA,MACZ,QAAQ,KAAK,yBAAyB;AAAA,MACtC,OAAO;AAAA,IACT;AAAA,IAEA,MAAM,SAAS,MAAM,QAAQ,cAAc;AAAA,IAC3C,OAAO,EAAE,SAAS,OAAO;AAAA,IACzB,OAAO,OAAO;AAAA,IACd,QAAQ,MAAM,iCAAiC,KAAK;AAAA,IACpD,OAAO;AAAA;AAAA;AAOX,eAAsB,kBAAkB,CACtC,SACA,UAA4B,CAAC,GACD;AAAA,EAC5B,QAAQ,WAAW;AAAA,EACnB,MAAM,OAAO;AAAA,EAGb,MAAM,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA+BnB,MAAM,eAAe,OAAO,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAAA,EACnE,MAAM,kBAAkB,OAAO,sBAAsB;AAAA,IACnD,QAAQ;AAAA,IACR,SAAS,EAAE,QAAQ,cAAc,YAAY,OAAO;AAAA,EACtD,CAAC;AAAA,EAGD,MAAM,iBAAiB,OAAO,aAAa;AAAA,IACzC,MAAM,OAAO,OAAO;AAAA,IACpB,OAAO,eAAe,UAAU,eAAe;AAAA,EACjD,CAAC;AAAA,EAED,MAAM,gBAAgB,OAAO,aAAa;AAAA,IACxC,MAAM;AAAA,IACN,OAAO,eAAe,UAAU,eAAe;AAAA,EACjD,CAAC;AAAA,EAGD,MAAM,aAAa,OAAO,aAAa;AAAA,IACrC,MAAM,MAAM;AAAA,IACZ,OAAO,eAAe,UAAU,eAAe;AAAA,EACjD,CAAC;AAAA,EAED,MAAM,YAAY,OAAO,gBAAgB;AAAA,IACvC,QAAQ,gBAAgB,mBAAmB,CAAC;AAAA,IAC5C,SAAS;AAAA,MACP,EAAE,SAAS,GAAG,UAAU,EAAE,QAAQ,eAAe,EAAE;AAAA,MACnD,EAAE,SAAS,GAAG,UAAU,EAAE,QAAQ,cAAc,EAAE;AAAA,MAClD,EAAE,SAAS,GAAG,UAAU,EAAE,QAAQ,WAAW,EAAE;AAAA,IACjD;AAAA,EACF,CAAC;AAAA,EAGD,OAAO,MAAM,YAAY,eAAe,GAAG,IAAI,aAAa,CAAC,MAAM,MAAM,GAAK,CAAG,CAAC,CAAC;AAAA,EAEnF,OAAO,UAAU,yBAAyB,YAAY;AAAA,IACpD,MAAM,iBAAiB,OAAO,qBAAqB;AAAA,IACnD,MAAM,cAAc,eAAe,iBAAiB;AAAA,IAEpD,YAAY,YAAY,eAAe;AAAA,IACvC,YAAY,aAAa,GAAG,SAAS;AAAA,IACrC,YAAY,mBAAmB,KAAK,KAAK,OAAO,CAAC,GAAG,KAAK,KAAK,OAAO,CAAC,CAAC;AAAA,IACvE,YAAY,IAAI;AAAA,IAEhB,OAAO,MAAM,OAAO,CAAC,eAAe,OAAO,CAAC,CAAC;AAAA,KAC5C,OAAO;AAAA;AAMZ,eAAsB,2BAA2B,CAC/C,SACA,UAA4B,CAAC,GACD;AAAA,EAC5B,QAAQ,WAAW;AAAA,EACnB,MAAM,YAAY;AAAA,EAClB,MAAM,aAAa;AAAA,EAEnB,MAAM,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAwDnB,MAAM,eAAe,OAAO,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAAA,EACnE,MAAM,kBAAkB,OAAO,sBAAsB;AAAA,IACnD,QAAQ;AAAA,IACR,SAAS,EAAE,QAAQ,cAAc,YAAY,OAAO;AAAA,EACtD,CAAC;AAAA,EAGD,MAAM,aAAa,OAAO,aAAa;AAAA,IACrC,MAAM,aAAa;AAAA,IACnB,OAAO,eAAe,UAAU,eAAe;AAAA,EACjD,CAAC;AAAA,EAED,MAAM,cAAc,OAAO,aAAa;AAAA,IACtC,MAAM,YAAY,YAAY;AAAA,IAC9B,OAAO,eAAe,UAAU,eAAe;AAAA,EACjD,CAAC;AAAA,EAED,MAAM,gBAAgB,OAAO,aAAa;AAAA,IACxC,MAAM;AAAA,IACN,OAAO,eAAe,UAAU,eAAe;AAAA,EACjD,CAAC;AAAA,EAED,MAAM,YAAY,OAAO,gBAAgB;AAAA,IACvC,QAAQ,gBAAgB,mBAAmB,CAAC;AAAA,IAC5C,SAAS;AAAA,MACP,EAAE,SAAS,GAAG,UAAU,EAAE,QAAQ,WAAW,EAAE;AAAA,MAC/C,EAAE,SAAS,GAAG,UAAU,EAAE,QAAQ,YAAY,EAAE;AAAA,MAChD,EAAE,SAAS,GAAG,UAAU,EAAE,QAAQ,cAAc,EAAE;AAAA,IACpD;AAAA,EACF,CAAC;AAAA,EAGD,MAAM,QAAQ,IAAI,YAAY,aAAa,EAAE;AAAA,EAC7C,MAAM,WAAW,IAAI,SAAS,KAAK;AAAA,EACnC,SAAS,IAAI,EAAG,IAAI,YAAY,KAAK;AAAA,IACnC,SAAS,WAAW,IAAI,KAAK,GAAG,GAAG,IAAI;AAAA,IACvC,SAAS,WAAW,IAAI,KAAK,GAAG,GAAG,IAAI;AAAA,IACvC,SAAS,WAAW,IAAI,KAAK,GAAG,KAAM,IAAI,IAAK,IAAI;AAAA,IACnD,SAAS,WAAW,IAAI,KAAK,IAAI,KAAM,IAAI,IAAK,IAAI;AAAA,IACpD,SAAS,UAAU,IAAI,KAAK,IAAI,GAAG,IAAI;AAAA,EACzC;AAAA,EAEA,OAAO,MAAM,YAAY,YAAY,GAAG,KAAK;AAAA,EAC7C,OAAO,MAAM,YAAY,eAAe,GAAG,IAAI,YAAY,CAAC,YAAY,WAAW,WAAW,CAAC,CAAC,CAAC;AAAA,EAEjG,OAAO,UAAU,wBAAwB,YAAY;AAAA,IACnD,MAAM,iBAAiB,OAAO,qBAAqB;AAAA,IACnD,MAAM,cAAc,eAAe,iBAAiB;AAAA,IAEpD,YAAY,YAAY,eAAe;AAAA,IACvC,YAAY,aAAa,GAAG,SAAS;AAAA,IACrC,YAAY,mBAAmB,KAAK,KAAK,aAAa,EAAE,GAAG,EAAE;AAAA,IAC7D,YAAY,IAAI;AAAA,IAEhB,OAAO,MAAM,OAAO,CAAC,eAAe,OAAO,CAAC,CAAC;AAAA,KAC5C,OAAO;AAAA;AAMZ,eAAsB,6BAA6B,CACjD,SACA,UAA4B,CAAC,GACD;AAAA,EAC5B,QAAQ,WAAW;AAAA,EACnB,MAAM,aAAa;AAAA,EACnB,MAAM,YAAY;AAAA,EAElB,MAAM,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAoCnB,MAAM,eAAe,OAAO,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAAA,EACnE,MAAM,kBAAkB,OAAO,sBAAsB;AAAA,IACnD,QAAQ;AAAA,IACR,SAAS,EAAE,QAAQ,cAAc,YAAY,OAAO;AAAA,EACtD,CAAC;AAAA,EAGD,MAAM,cAAc,OAAO,aAAa;AAAA,IACtC,MAAM,aAAa;AAAA,IACnB,OAAO,eAAe,UAAU,eAAe;AAAA,EACjD,CAAC;AAAA,EAED,MAAM,YAAY,KAAK,KAAK,KAAK,KAAK,UAAU,CAAC,IAAI;AAAA,EACrD,MAAM,eAAe,OAAO,aAAa;AAAA,IACvC,MAAM,YAAY,YAAY;AAAA,IAC9B,OAAO,eAAe,UAAU,eAAe;AAAA,EACjD,CAAC;AAAA,EAED,MAAM,gBAAgB,OAAO,aAAa;AAAA,IACxC,MAAM;AAAA,IACN,OAAO,eAAe,UAAU,eAAe;AAAA,EACjD,CAAC;AAAA,EAED,MAAM,YAAY,OAAO,gBAAgB;AAAA,IACvC,QAAQ,gBAAgB,mBAAmB,CAAC;AAAA,IAC5C,SAAS;AAAA,MACP,EAAE,SAAS,GAAG,UAAU,EAAE,QAAQ,YAAY,EAAE;AAAA,MAChD,EAAE,SAAS,GAAG,UAAU,EAAE,QAAQ,aAAa,EAAE;AAAA,MACjD,EAAE,SAAS,GAAG,UAAU,EAAE,QAAQ,cAAc,EAAE;AAAA,IACpD;AAAA,EACF,CAAC;AAAA,EAGD,MAAM,eAAe,KAAK,KAAK,KAAK,KAAK,UAAU,CAAC;AAAA,EACpD,OAAO,MAAM,YAAY,eAAe,GAAG,IAAI,YAAY;AAAA,IACzD;AAAA,IAAW;AAAA,IAAW;AAAA,IAAc;AAAA,EACtC,CAAC,CAAC;AAAA,EAEF,OAAO,UAAU,mCAAmC,YAAY;AAAA,IAC9D,MAAM,iBAAiB,OAAO,qBAAqB;AAAA,IACnD,MAAM,cAAc,eAAe,iBAAiB;AAAA,IAEpD,YAAY,YAAY,eAAe;AAAA,IACvC,YAAY,aAAa,GAAG,SAAS;AAAA,IACrC,YAAY,mBACV,KAAK,KAAK,YAAY,CAAC,GACvB,KAAK,KAAK,YAAY,CAAC,GACvB,UACF;AAAA,IACA,YAAY,IAAI;AAAA,IAEhB,OAAO,MAAM,OAAO,CAAC,eAAe,OAAO,CAAC,CAAC;AAAA,KAC5C,OAAO;AAAA;",
9
- "debugId": "4DC44201FDB035E564756E2164756E21",
10
- "names": []
11
- }