@fjandin/react-shader 0.0.20 → 0.0.30
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 +21 -213
- package/dist/example/frontend.d.ts.map +1 -1
- package/dist/hooks/useWebGPU.d.ts.map +1 -1
- package/dist/index.cjs +24 -1007
- package/dist/index.d.ts +1 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +24 -1007
- package/dist/types.d.ts +0 -28
- package/dist/types.d.ts.map +1 -1
- package/package.json +4 -4
- package/dist/ReactShader.d.ts +0 -3
- package/dist/ReactShader.d.ts.map +0 -1
- package/dist/example/examples/webgl.d.ts +0 -2
- package/dist/example/examples/webgl.d.ts.map +0 -1
- package/dist/hooks/useWebGL.d.ts +0 -20
- package/dist/hooks/useWebGL.d.ts.map +0 -1
- package/dist/shaders/color-palette.d.ts +0 -2
- package/dist/shaders/color-palette.d.ts.map +0 -1
- package/dist/shaders/distortion-ripple.d.ts +0 -16
- package/dist/shaders/distortion-ripple.d.ts.map +0 -1
- package/dist/shaders/scene-circles.d.ts +0 -21
- package/dist/shaders/scene-circles.d.ts.map +0 -1
- package/dist/shaders/simplex-noise.d.ts +0 -2
- package/dist/shaders/simplex-noise.d.ts.map +0 -1
- package/dist/shaders/utils.d.ts +0 -2
- package/dist/shaders/utils.d.ts.map +0 -1
- package/dist/utils/shader.d.ts +0 -6
- package/dist/utils/shader.d.ts.map +0 -1
- package/dist/utils/textures.d.ts +0 -23
- package/dist/utils/textures.d.ts.map +0 -1
- package/dist/utils/uniforms.d.ts +0 -12
- package/dist/utils/uniforms.d.ts.map +0 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @fjandin/react-shader
|
|
2
2
|
|
|
3
|
-
A React component library for rendering
|
|
3
|
+
A React component library for rendering WebGPU shaders. Provides `<ReactGpuShader>` for WGSL with automatic uniform handling, storage buffers, and audio reactivity.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
@@ -12,42 +12,7 @@ yarn add @fjandin/react-shader
|
|
|
12
12
|
bun add @fjandin/react-shader
|
|
13
13
|
```
|
|
14
14
|
|
|
15
|
-
##
|
|
16
|
-
|
|
17
|
-
### `<ReactShader>` (WebGL)
|
|
18
|
-
|
|
19
|
-
Renders GLSL fragment shaders. Uses WebGL2 with WebGL1 fallback.
|
|
20
|
-
|
|
21
|
-
```tsx
|
|
22
|
-
import { ReactShader } from "@fjandin/react-shader"
|
|
23
|
-
|
|
24
|
-
const fragment = `#version 300 es
|
|
25
|
-
precision highp float;
|
|
26
|
-
|
|
27
|
-
uniform float iTime;
|
|
28
|
-
uniform vec2 iResolution;
|
|
29
|
-
|
|
30
|
-
out vec4 fragColor;
|
|
31
|
-
|
|
32
|
-
void main() {
|
|
33
|
-
vec2 uv = gl_FragCoord.xy / iResolution;
|
|
34
|
-
vec3 color = 0.5 + 0.5 * cos(iTime + uv.xyx + vec3(0, 2, 4));
|
|
35
|
-
fragColor = vec4(color, 1.0);
|
|
36
|
-
}
|
|
37
|
-
`
|
|
38
|
-
|
|
39
|
-
function App() {
|
|
40
|
-
return (
|
|
41
|
-
<div style={{ width: "800px", height: "600px" }}>
|
|
42
|
-
<ReactShader fragment={fragment} />
|
|
43
|
-
</div>
|
|
44
|
-
)
|
|
45
|
-
}
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
### `<ReactGpuShader>` (WebGPU)
|
|
49
|
-
|
|
50
|
-
Renders WGSL fragment shaders using WebGPU. Supports storage buffers for large array data.
|
|
15
|
+
## Quick Start
|
|
51
16
|
|
|
52
17
|
```tsx
|
|
53
18
|
import { ReactGpuShader } from "@fjandin/react-shader"
|
|
@@ -68,29 +33,10 @@ function App() {
|
|
|
68
33
|
}
|
|
69
34
|
```
|
|
70
35
|
|
|
71
|
-
|
|
36
|
+
Shaders define a `mainImage(uv: vec2f) -> vec4f` function. Built-in uniforms are accessed via `uniforms.iTime`, `uniforms.iResolution`, etc. The component automatically generates the uniform struct and wrapping `@fragment` entry point.
|
|
72
37
|
|
|
73
38
|
## Props
|
|
74
39
|
|
|
75
|
-
### ReactShader
|
|
76
|
-
|
|
77
|
-
| Prop | Type | Required | Default | Description |
|
|
78
|
-
|------|------|----------|---------|-------------|
|
|
79
|
-
| `fragment` | `string` | Yes | - | GLSL fragment shader source code |
|
|
80
|
-
| `vertex` | `string` | No | Default quad shader | GLSL vertex shader source code |
|
|
81
|
-
| `uniforms` | `Record<string, UniformValue>` | No | `{}` | Custom uniform values |
|
|
82
|
-
| `className` | `string` | No | - | CSS class name for the canvas |
|
|
83
|
-
| `fullscreen` | `boolean` | No | `false` | Render as fixed fullscreen overlay |
|
|
84
|
-
| `timeScale` | `number` | No | `1` | Scale factor for elapsed time |
|
|
85
|
-
| `onFrame` | `(info: FrameInfo) => void` | No | - | Callback invoked on each frame |
|
|
86
|
-
| `onClick` | `(info: FrameInfo) => void` | No | - | Callback invoked on canvas click |
|
|
87
|
-
| `onMouseMove` | `(info: FrameInfo) => void` | No | - | Callback invoked on mouse move |
|
|
88
|
-
| `onMouseDown` | `(info: FrameInfo) => void` | No | - | Callback invoked on mouse button press |
|
|
89
|
-
| `onMouseUp` | `(info: FrameInfo) => void` | No | - | Callback invoked on mouse button release |
|
|
90
|
-
| `onMouseWheel` | `(info: FrameInfo, wheelDelta: number) => void` | No | - | Callback invoked on mouse wheel scroll |
|
|
91
|
-
|
|
92
|
-
### ReactGpuShader
|
|
93
|
-
|
|
94
40
|
| Prop | Type | Required | Default | Description |
|
|
95
41
|
|------|------|----------|---------|-------------|
|
|
96
42
|
| `fragment` | `string` | Yes | - | WGSL fragment shader source code |
|
|
@@ -110,50 +56,16 @@ WebGPU shaders define a `mainImage(uv: vec2f) -> vec4f` function. Built-in unifo
|
|
|
110
56
|
|
|
111
57
|
These uniforms are automatically provided to your shader every frame:
|
|
112
58
|
|
|
113
|
-
| Uniform |
|
|
114
|
-
|
|
115
|
-
| `iTime` | `
|
|
116
|
-
| `iMouse` | `
|
|
117
|
-
| `iMouseNormalized` | `
|
|
118
|
-
| `iMouseLeftDown` | `
|
|
119
|
-
| `iResolution` | `
|
|
59
|
+
| Uniform | WGSL Type | Description |
|
|
60
|
+
|---------|-----------|-------------|
|
|
61
|
+
| `iTime` | `f32` | Elapsed time in seconds (scaled by `timeScale`) |
|
|
62
|
+
| `iMouse` | `vec2f` | Mouse position in pixels (Y=0 at bottom) |
|
|
63
|
+
| `iMouseNormalized` | `vec2f` | Mouse position normalized with aspect correction (shorter axis -0.5 to 0.5, center is 0,0) |
|
|
64
|
+
| `iMouseLeftDown` | `f32` | `1.0` when left mouse button is pressed, `0.0` otherwise |
|
|
65
|
+
| `iResolution` | `vec2f` | Canvas resolution in pixels (includes high-DPI scaling) |
|
|
120
66
|
|
|
121
67
|
## Custom Uniforms
|
|
122
68
|
|
|
123
|
-
### WebGL (ReactShader)
|
|
124
|
-
|
|
125
|
-
Pass custom uniform values via the `uniforms` prop. Supports scalars, vectors, arrays, and textures:
|
|
126
|
-
|
|
127
|
-
```tsx
|
|
128
|
-
<ReactShader
|
|
129
|
-
fragment={fragment}
|
|
130
|
-
uniforms={{
|
|
131
|
-
scale: 2.0, // float
|
|
132
|
-
offset: [0.5, 0.5], // vec2
|
|
133
|
-
color: [1.0, 0.5, 0.2], // vec3
|
|
134
|
-
transform: [1, 0, 0, 1], // vec4
|
|
135
|
-
weights: [0.1, 0.2, 0.3, 0.25, 0.15], // float array
|
|
136
|
-
points: [[0, 0], [1, 0], [0.5, 1]], // vec2 array
|
|
137
|
-
colors: [[1, 0, 0], [0, 1, 0]], // vec3 array
|
|
138
|
-
ripples: [[0, 0, 0.5, 0.1]], // vec4 array
|
|
139
|
-
}}
|
|
140
|
-
/>
|
|
141
|
-
```
|
|
142
|
-
|
|
143
|
-
Supported types:
|
|
144
|
-
- `number` → `float`
|
|
145
|
-
- `[number, number]` → `vec2`
|
|
146
|
-
- `[number, number, number]` → `vec3`
|
|
147
|
-
- `[number, number, number, number]` → `vec4`
|
|
148
|
-
- `number[]` (length > 4) → `float[N]`
|
|
149
|
-
- `[number, number][]` → `vec2[N]`
|
|
150
|
-
- `[number, number, number][]` → `vec3[N]`
|
|
151
|
-
- `[number, number, number, number][]` → `vec4[N]`
|
|
152
|
-
- `HTMLImageElement | HTMLCanvasElement | HTMLVideoElement | ImageBitmap | ImageData | OffscreenCanvas` → `sampler2D` (texture)
|
|
153
|
-
- `TextureOptions` object → `sampler2D` with wrap/filter configuration
|
|
154
|
-
|
|
155
|
-
### WebGPU (ReactGpuShader)
|
|
156
|
-
|
|
157
69
|
Custom uniforms support scalar and vector types:
|
|
158
70
|
|
|
159
71
|
```tsx
|
|
@@ -170,25 +82,9 @@ Custom uniforms support scalar and vector types:
|
|
|
170
82
|
|
|
171
83
|
Custom uniforms are accessed via `uniforms.scale`, `uniforms.color`, etc. in your WGSL code.
|
|
172
84
|
|
|
173
|
-
##
|
|
85
|
+
## Storage Buffers
|
|
174
86
|
|
|
175
|
-
For array
|
|
176
|
-
|
|
177
|
-
```tsx
|
|
178
|
-
uniforms={{ points: [[0, 0], [1, 0], [0.5, 1]] }}
|
|
179
|
-
```
|
|
180
|
-
|
|
181
|
-
This generates both `uniform vec2 points[3]` and `uniform int points_count` (set to `3`), allowing you to loop over arrays in your shader:
|
|
182
|
-
|
|
183
|
-
```glsl
|
|
184
|
-
for (int i = 0; i < points_count; i++) {
|
|
185
|
-
// Use points[i]...
|
|
186
|
-
}
|
|
187
|
-
```
|
|
188
|
-
|
|
189
|
-
## Storage Buffers (WebGPU)
|
|
190
|
-
|
|
191
|
-
For large dynamic array data, `ReactGpuShader` supports storage buffers. These are more efficient than uniforms for large datasets and support dynamic resizing:
|
|
87
|
+
For large dynamic array data, storage buffers are more efficient than uniforms and support dynamic resizing:
|
|
192
88
|
|
|
193
89
|
```tsx
|
|
194
90
|
const [particles, setParticles] = useState<Vec4Array>([
|
|
@@ -216,61 +112,12 @@ fn mainImage(uv: vec2f) -> vec4f {
|
|
|
216
112
|
|
|
217
113
|
Storage buffers use over-allocation (1.5x growth) to minimize GPU buffer rebuilds when array sizes change frequently.
|
|
218
114
|
|
|
219
|
-
## Texture Uniforms (WebGL)
|
|
220
|
-
|
|
221
|
-
Pass images, canvases, or video elements as texture uniforms:
|
|
222
|
-
|
|
223
|
-
```tsx
|
|
224
|
-
<ReactShader
|
|
225
|
-
fragment={fragment}
|
|
226
|
-
uniforms={{
|
|
227
|
-
myTexture: imageElement,
|
|
228
|
-
// or with options:
|
|
229
|
-
myTexture: {
|
|
230
|
-
source: imageElement,
|
|
231
|
-
wrapS: "repeat", // "repeat" | "clamp" | "mirror"
|
|
232
|
-
wrapT: "repeat",
|
|
233
|
-
minFilter: "linear", // "nearest" | "linear" | "mipmap"
|
|
234
|
-
magFilter: "linear", // "nearest" | "linear"
|
|
235
|
-
flipY: true,
|
|
236
|
-
},
|
|
237
|
-
}}
|
|
238
|
-
/>
|
|
239
|
-
```
|
|
240
|
-
|
|
241
|
-
## Automatic Uniform Injection (WebGL)
|
|
242
|
-
|
|
243
|
-
Instead of manually declaring uniforms in your shader, you can use the `// @UNIFORM_VALUES` marker to automatically inject all uniform declarations:
|
|
244
|
-
|
|
245
|
-
```tsx
|
|
246
|
-
const fragment = `#version 300 es
|
|
247
|
-
precision highp float;
|
|
248
|
-
|
|
249
|
-
// @UNIFORM_VALUES
|
|
250
|
-
|
|
251
|
-
out vec4 fragColor;
|
|
252
|
-
|
|
253
|
-
void main() {
|
|
254
|
-
vec2 uv = gl_FragCoord.xy / iResolution;
|
|
255
|
-
vec3 col = baseColor * (sin(iTime) * 0.5 + 0.5);
|
|
256
|
-
fragColor = vec4(col, 1.0);
|
|
257
|
-
}
|
|
258
|
-
`
|
|
259
|
-
|
|
260
|
-
<ReactShader
|
|
261
|
-
fragment={fragment}
|
|
262
|
-
uniforms={{ baseColor: [1.0, 0.5, 0.2] }}
|
|
263
|
-
/>
|
|
264
|
-
```
|
|
265
|
-
|
|
266
|
-
The marker gets replaced with declarations for both built-in uniforms (`iTime`, `iMouse`, `iMouseNormalized`, `iMouseLeftDown`, `iResolution`) and your custom uniforms.
|
|
267
|
-
|
|
268
115
|
## Audio Reactivity
|
|
269
116
|
|
|
270
117
|
The `useAudio` hook provides real-time audio analysis for audio-reactive shaders:
|
|
271
118
|
|
|
272
119
|
```tsx
|
|
273
|
-
import {
|
|
120
|
+
import { ReactGpuShader, useAudio } from "@fjandin/react-shader"
|
|
274
121
|
|
|
275
122
|
function AudioVisualizer() {
|
|
276
123
|
const audio = useAudio({
|
|
@@ -283,7 +130,7 @@ function AudioVisualizer() {
|
|
|
283
130
|
<button onClick={() => audio.isRunning ? audio.stop() : audio.start()}>
|
|
284
131
|
{audio.isRunning ? "Stop" : "Start"}
|
|
285
132
|
</button>
|
|
286
|
-
<
|
|
133
|
+
<ReactGpuShader
|
|
287
134
|
fragment={fragment}
|
|
288
135
|
uniforms={{
|
|
289
136
|
audioLow: audio.levels.low,
|
|
@@ -320,17 +167,10 @@ function AudioVisualizer() {
|
|
|
320
167
|
|
|
321
168
|
## Shader Helper Functions
|
|
322
169
|
|
|
323
|
-
Pre-built shader functions are available
|
|
170
|
+
Pre-built WGSL shader functions are available:
|
|
324
171
|
|
|
325
172
|
```tsx
|
|
326
173
|
import {
|
|
327
|
-
// GLSL (WebGL)
|
|
328
|
-
generateSimplexNoiseFunction,
|
|
329
|
-
generateColorPaletteFunction,
|
|
330
|
-
generateDistortionRippleFunction,
|
|
331
|
-
generateSceneCirclesFunction,
|
|
332
|
-
generateUtilsFunction,
|
|
333
|
-
// WGSL (WebGPU)
|
|
334
174
|
generateSimplexNoiseFunctionGpu,
|
|
335
175
|
generateColorPaletteFunctionGpu,
|
|
336
176
|
generateDistortionRippleFunctionGpu,
|
|
@@ -341,14 +181,6 @@ import {
|
|
|
341
181
|
Inject them into your shader source:
|
|
342
182
|
|
|
343
183
|
```tsx
|
|
344
|
-
// GLSL
|
|
345
|
-
const fragment = `#version 300 es
|
|
346
|
-
precision highp float;
|
|
347
|
-
${generateSimplexNoiseFunction()}
|
|
348
|
-
// Use SimplexNoise3D(vec3 v) in your shader...
|
|
349
|
-
`
|
|
350
|
-
|
|
351
|
-
// WGSL
|
|
352
184
|
const fragment = /*wgsl*/ `
|
|
353
185
|
${generateSimplexNoiseFunctionGpu()}
|
|
354
186
|
fn mainImage(uv: vec2f) -> vec4f {
|
|
@@ -367,7 +199,7 @@ function App() {
|
|
|
367
199
|
const [customTime, setCustomTime] = useState(0)
|
|
368
200
|
|
|
369
201
|
return (
|
|
370
|
-
<
|
|
202
|
+
<ReactGpuShader
|
|
371
203
|
fragment={fragment}
|
|
372
204
|
uniforms={{ customTime }}
|
|
373
205
|
onFrame={(info) => {
|
|
@@ -395,21 +227,14 @@ import type {
|
|
|
395
227
|
Vec2,
|
|
396
228
|
Vec3,
|
|
397
229
|
Vec4,
|
|
398
|
-
FloatArray,
|
|
399
230
|
Vec2Array,
|
|
400
231
|
Vec3Array,
|
|
401
232
|
Vec4Array,
|
|
402
|
-
|
|
233
|
+
GpuUniformValue,
|
|
403
234
|
GpuStorageBuffers,
|
|
404
235
|
DefaultUniforms,
|
|
405
236
|
FrameInfo,
|
|
406
|
-
ReactShaderProps,
|
|
407
237
|
ReactGpuShaderProps,
|
|
408
|
-
TextureSource,
|
|
409
|
-
TextureOptions,
|
|
410
|
-
TextureWrap,
|
|
411
|
-
TextureMinFilter,
|
|
412
|
-
TextureMagFilter,
|
|
413
238
|
AudioLevels,
|
|
414
239
|
AudioConnectionState,
|
|
415
240
|
AudioSourceType,
|
|
@@ -418,39 +243,22 @@ import type {
|
|
|
418
243
|
} from "@fjandin/react-shader"
|
|
419
244
|
```
|
|
420
245
|
|
|
421
|
-
A utility function for generating uniform declarations is also exported:
|
|
422
|
-
|
|
423
|
-
```tsx
|
|
424
|
-
import { generateUniformDeclarations } from "@fjandin/react-shader"
|
|
425
|
-
|
|
426
|
-
const declarations = generateUniformDeclarations({
|
|
427
|
-
scale: 1.0,
|
|
428
|
-
points: [[0, 0], [1, 1]],
|
|
429
|
-
})
|
|
430
|
-
// Returns:
|
|
431
|
-
// uniform float scale;
|
|
432
|
-
// uniform vec2 points[2];
|
|
433
|
-
// uniform int points_count;
|
|
434
|
-
```
|
|
435
|
-
|
|
436
246
|
## Features
|
|
437
247
|
|
|
438
|
-
-
|
|
439
|
-
-
|
|
440
|
-
- Storage buffers for large dynamic arrays (WebGPU)
|
|
441
|
-
- Texture uniforms with configurable wrap/filter modes (WebGL)
|
|
248
|
+
- WebGPU rendering with WGSL shaders
|
|
249
|
+
- Storage buffers for large dynamic arrays
|
|
442
250
|
- Audio reactivity via `useAudio` hook
|
|
443
251
|
- Pre-built shader functions (simplex noise, color palettes, distortion ripples, circles)
|
|
444
252
|
- High-DPI display support with automatic DPR change detection
|
|
445
253
|
- Automatic canvas resizing
|
|
446
254
|
- Shader compilation error display
|
|
447
|
-
-
|
|
448
|
-
- Mouse tracking with WebGL/WebGPU coordinate convention
|
|
255
|
+
- Mouse tracking with WebGPU coordinate convention
|
|
449
256
|
- Optimized render loop with minimal per-frame allocations
|
|
450
257
|
|
|
451
258
|
## Requirements
|
|
452
259
|
|
|
453
260
|
- React >= 17.0.0
|
|
261
|
+
- A browser with WebGPU support
|
|
454
262
|
|
|
455
263
|
## License
|
|
456
264
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"frontend.d.ts","sourceRoot":"","sources":["../../src/example/frontend.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"frontend.d.ts","sourceRoot":"","sources":["../../src/example/frontend.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,aAAa,CAAA;AAyBpB,wBAAgB,GAAG,4CAiClB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useWebGPU.d.ts","sourceRoot":"","sources":["../../src/hooks/useWebGPU.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,eAAe,EAAoB,SAAS,EAAE,MAAM,UAAU,CAAA;AAEvF,UAAU,gBAAgB;IACxB,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAA;IAC1C,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;IAC1C,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAA;IAChC,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAA;IACnC,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAA;IACnC,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAA;IACvC,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAA;IACvC,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAA;IACrC,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,KAAK,IAAI,CAAA;CAC7D;
|
|
1
|
+
{"version":3,"file":"useWebGPU.d.ts","sourceRoot":"","sources":["../../src/hooks/useWebGPU.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,eAAe,EAAoB,SAAS,EAAE,MAAM,UAAU,CAAA;AAEvF,UAAU,gBAAgB;IACxB,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAA;IAC1C,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;IAC1C,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAA;IAChC,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAA;IACnC,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAA;IACnC,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAA;IACvC,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAA;IACvC,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAA;IACrC,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,KAAK,IAAI,CAAA;CAC7D;AAkXD,wBAAgB,SAAS,CAAC,OAAO,EAAE,gBAAgB;;;EAiTlD"}
|