@edv4h/usketch-gpu3d-renderer 0.0.0-stage → 0.1.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 EdV4H
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,63 @@
1
- # Temporary Holding Version
1
+ # @edv4h/usketch-gpu3d-renderer
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ ボードの 3D 表示(コアの `View3dState`)を WebGL2 の 1 枚のキャンバスで描くレンダラー(**実験中**)。CSS 3D レンダラーの代わりに使う。地面・地形・その上に立つものを深度バッファ付きの 1 枚に描くので、前後の重なりが正しくなる。
4
+
5
+ 今のバージョンで描くのは、**地面(グリッド)・GPU で描くプラグイン(標高の地形)・ボードの Shape(平らに置いたもの)** まで。描いている間、3D で見せる層(`view3d` が `tilt` / `depth` / `ground` の層)は隠れ、その中身をキャンバスに描く。キャラや選択枠などはまだ見えない(次の段階で描く)。CSS 3D レンダラーと見比べるためのもので、既定には使わない。
6
+
7
+ ### Shape の描き方
8
+
9
+ Shape は、DOM レンダラーが(隠れたまま)描いた Shape の DOM を画像にして、地面に貼る。画像は Shape が変わったときと、ズームで解像度が足りなくなったときにだけ作り直す。1 フレームで作る量には上限があり、カメラに近いものから作る。できるまでは薄い四角で代わりに描く。
10
+
11
+ - 置く高さは、CSS 3D レンダラーと同じく Shape の中心の地面の高さ。地形の上に重ねて描く(丘の陰でも隠れない)
12
+ - 2D の GPU レンダラーが描く Shape(DOM が無いもの)は、`gpuPrimitive` から描く
13
+ - 画像にするときの制限(SVG の `foreignObject` を画像として読むため): Web フォントは端末のフォントになり、外部 URL の画像は入らない。ブラウザによっては画像を GPU に載せられず、代わりの四角のままになる
14
+ - 3D の見た目を持つ Shape(立てる・箱・浮かせる)も、今は平らに描く
15
+
16
+ ## Install
17
+
18
+ ```bash
19
+ pnpm add @edv4h/usketch-gpu3d-renderer @edv4h/usketch-shared react
20
+ ```
21
+
22
+ ## 使い方
23
+
24
+ CSS 3D レンダラーの **代わりに**、3D ビュー(Mode 7)より前に追加する。ボードにもう 3D レンダラーがあれば何もしない。
25
+
26
+ ```ts
27
+ import { createGpu3dRendererPlugin } from "@edv4h/usketch-gpu3d-renderer";
28
+ import { createMode7Plugin } from "@edv4h/usketch-plugin-mode7";
29
+
30
+ createApp({
31
+ plugins: [
32
+ createDomRendererPlugin(),
33
+ createGpu3dRendererPlugin(),
34
+ createMode7Plugin(),
35
+ ],
36
+ });
37
+ ```
38
+
39
+ レンダラーは `view3dRendererService`(`@edv4h/usketch-shared`)で、どの 3D レンダラーでも同じ形で取れる(傾ける層・奥行きを持たせる層の変更、描いているかどうか)。
40
+
41
+ ## プラグインから GPU に描く
42
+
43
+ 自前の GL で描くプラグインは、ボードの描画フック `view3dGl(ctx.services)` に描画を登録する。GPU レンダラーがあればそのキャンバスに毎フレーム描かれ、無ければ呼ばれない(そのときは自分のキャンバスで描く)。
44
+
45
+ ```ts
46
+ import { VIEW3D_DEPTH_GLSL, view3dGl } from "@edv4h/usketch-shared";
47
+
48
+ const gpu = view3dGl(ctx.services);
49
+ const off = gpu.register({
50
+ id: "my-plugin:mesh",
51
+ draw(frame) {
52
+ // frame.gl / frame.matrix(viewMatrix)/ frame.view / frame.pixelRatio
53
+ // 頂点シェーダーでは gl_Position = view3dPosition(uView * pos) で深度を揃える
54
+ },
55
+ release(gl) {
56
+ // GL オブジェクトを解放
57
+ },
58
+ });
59
+ gpu.isDrawing(); // GPU レンダラーが描いている間 true(自分のキャンバスは止める)
60
+ gpu.requestFrame(); // 見た目が変わったら次のフレームを頼む
61
+ ```
62
+
63
+ 深度は全員が `VIEW3D_DEPTH_GLSL` の `view3dPosition` で同じように入れる。地面は深度を書かない背景として最初に描かれる。
@@ -0,0 +1,42 @@
1
+ import { type Point, type View3dGlFrame, type Viewport } from "@edv4h/usketch-shared";
2
+ /** World units between grid lines (the bg-grid plugin's). */
3
+ export declare const GROUND_GRID_SIZE = 20;
4
+ /** A rectangle of the flat stage, px. */
5
+ export interface StageRect {
6
+ left: number;
7
+ top: number;
8
+ right: number;
9
+ bottom: number;
10
+ }
11
+ /**
12
+ * The part of the flat stage (px, before the tilt) the ground covers: the stage box, cut
13
+ * to the near band or grown past the box by the draw distance — as the CSS 3D renderer
14
+ * clips its tilted layers (`drawDistanceClip`). Pure.
15
+ */
16
+ export declare function groundRegionPx(drawDistance: number, zoom: number, width: number, height: number, amount?: number): StageRect;
17
+ /** The world corners of a flat-stage rectangle (clockwise from top-left). Pure. */
18
+ export declare function stageRectWorld(r: StageRect, viewport: Viewport): Point[];
19
+ /** A CSS colour as premultiplied RGBA 0…1 (`null` when it can't be read). Pure. */
20
+ export declare function parseCssColor(css: string): [number, number, number, number] | null;
21
+ /** Builds a program from the two sources (throws with the log on failure). */
22
+ export declare function linkProgram(gl: WebGL2RenderingContext, vertex: string, fragment: string): WebGLProgram;
23
+ export interface GroundLook {
24
+ /** Premultiplied RGBA 0…1. */
25
+ background: [number, number, number, number];
26
+ line: [number, number, number, number];
27
+ grid: boolean;
28
+ /** Grid line width, world units (the flat grid's 1 px at the view's zoom). */
29
+ lineWidth: number;
30
+ }
31
+ /** Draws the ground in one GL context. */
32
+ export declare class GroundPainter {
33
+ private readonly gl;
34
+ private readonly program;
35
+ private readonly vao;
36
+ private readonly buffer;
37
+ private readonly u;
38
+ constructor(gl: WebGL2RenderingContext);
39
+ draw(frame: View3dGlFrame, look: GroundLook): void;
40
+ release(): void;
41
+ }
42
+ //# sourceMappingURL=gpu3d-ground.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gpu3d-ground.d.ts","sourceRoot":"","sources":["../src/gpu3d-ground.ts"],"names":[],"mappings":"AAIA,OAAO,EACN,KAAK,KAAK,EAGV,KAAK,aAAa,EAClB,KAAK,QAAQ,EAEb,MAAM,uBAAuB,CAAC;AAE/B,6DAA6D;AAC7D,eAAO,MAAM,gBAAgB,KAAK,CAAC;AAEnC,yCAAyC;AACzC,MAAM,WAAW,SAAS;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CACf;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAC7B,YAAY,EAAE,MAAM,EACpB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,MAAM,SAAI,GACR,SAAS,CAUX;AAED,mFAAmF;AACnF,wBAAgB,cAAc,CAAC,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,GAAG,KAAK,EAAE,CAOxE;AAED,mFAAmF;AACnF,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAkBlF;AAmDD,8EAA8E;AAC9E,wBAAgB,WAAW,CAC1B,EAAE,EAAE,sBAAsB,EAC1B,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,GACd,YAAY,CAcd;AAED,MAAM,WAAW,UAAU;IAC1B,8BAA8B;IAC9B,UAAU,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7C,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IACvC,IAAI,EAAE,OAAO,CAAC;IACd,8EAA8E;IAC9E,SAAS,EAAE,MAAM,CAAC;CAClB;AAED,0CAA0C;AAC1C,qBAAa,aAAa;IAMb,OAAO,CAAC,QAAQ,CAAC,EAAE;IAL/B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAe;IACvC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAyB;IAC7C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAc;IACrC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAmD;IAErE,YAA6B,EAAE,EAAE,sBAAsB,EAetD;IAED,IAAI,CAAC,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE,UAAU,GAAG,IAAI,CAwCjD;IAED,OAAO,IAAI,IAAI,CAKd;CACD"}
@@ -0,0 +1,187 @@
1
+ // The ground of the GPU 3D view: the board's background (and its grid, when the board
2
+ // shows one) on the plane at height 0, as far as the draw distance shows it. It is drawn
3
+ // first and without writing depth, as a backdrop: the terrain and what stands on the
4
+ // ground draw over it.
5
+ import { screenToWorld, VIEW3D_DEPTH_GLSL, viewMatrix, } from "@edv4h/usketch-shared";
6
+ /** World units between grid lines (the bg-grid plugin's). */
7
+ export const GROUND_GRID_SIZE = 20;
8
+ /**
9
+ * The part of the flat stage (px, before the tilt) the ground covers: the stage box, cut
10
+ * to the near band or grown past the box by the draw distance — as the CSS 3D renderer
11
+ * clips its tilted layers (`drawDistanceClip`). Pure.
12
+ */
13
+ export function groundRegionPx(drawDistance, zoom, width, height, amount = 1) {
14
+ const box = { left: 0, top: 0, right: width, bottom: height };
15
+ if (!(drawDistance > 0) || !(zoom > 0) || !(height > 0))
16
+ return box;
17
+ const band = drawDistance * zoom;
18
+ if (band <= height) {
19
+ const s = Math.min(1, Math.max(0, amount));
20
+ return { ...box, top: (height - band) * s };
21
+ }
22
+ const over = band - height;
23
+ return { left: -over, top: -over, right: width + over, bottom: height + over };
24
+ }
25
+ /** The world corners of a flat-stage rectangle (clockwise from top-left). Pure. */
26
+ export function stageRectWorld(r, viewport) {
27
+ return [
28
+ screenToWorld(r.left, r.top, viewport),
29
+ screenToWorld(r.right, r.top, viewport),
30
+ screenToWorld(r.right, r.bottom, viewport),
31
+ screenToWorld(r.left, r.bottom, viewport),
32
+ ];
33
+ }
34
+ /** A CSS colour as premultiplied RGBA 0…1 (`null` when it can't be read). Pure. */
35
+ export function parseCssColor(css) {
36
+ const m = css.trim().match(/^rgba?\(([^)]+)\)$/i);
37
+ if (m) {
38
+ const parts = m[1]
39
+ .split(/[\s,/]+/)
40
+ .filter(Boolean)
41
+ .map(Number);
42
+ if (parts.length < 3 || parts.slice(0, 3).some((n) => !Number.isFinite(n)))
43
+ return null;
44
+ const a = parts.length > 3 && Number.isFinite(parts[3]) ? parts[3] : 1;
45
+ return [(parts[0] / 255) * a, (parts[1] / 255) * a, (parts[2] / 255) * a, a];
46
+ }
47
+ const hex = css.trim().match(/^#([0-9a-f]{3}|[0-9a-f]{6})$/i);
48
+ if (hex) {
49
+ const h = hex[1].length === 3 ? [...hex[1]].map((c) => c + c).join("") : hex[1];
50
+ const n = Number.parseInt(h, 16);
51
+ return [((n >> 16) & 255) / 255, ((n >> 8) & 255) / 255, (n & 255) / 255, 1];
52
+ }
53
+ return null;
54
+ }
55
+ const VERTEX = `#version 300 es
56
+ layout(location = 0) in vec2 aWorld;
57
+ uniform mat4 uView;
58
+ out vec2 vWorld;
59
+ ${VIEW3D_DEPTH_GLSL}
60
+ void main() {
61
+ vWorld = aWorld;
62
+ gl_Position = view3dPosition(uView * vec4(aWorld, 0.0, 1.0));
63
+ }`;
64
+ const FRAGMENT = `#version 300 es
65
+ precision highp float;
66
+ in vec2 vWorld;
67
+ uniform vec4 uBackground;
68
+ uniform vec4 uLine;
69
+ uniform float uGrid;
70
+ uniform float uGridSize;
71
+ uniform float uLineWidth;
72
+ out vec4 outColor;
73
+ void main() {
74
+ vec4 color = uBackground;
75
+ if (uGrid > 0.5) {
76
+ vec2 c = vWorld / uGridSize;
77
+ vec2 fw = max(fwidth(c), vec2(1e-6));
78
+ // Distance to the nearest line and the line's half width, in cells.
79
+ vec2 d = abs(fract(c - 0.5) - 0.5);
80
+ float hw = 0.5 * uLineWidth / uGridSize;
81
+ // At least a device px wide; thinner lines get fainter instead.
82
+ vec2 w = max(vec2(2.0 * hw), fw);
83
+ vec2 cover = clamp((0.5 * w + 0.5 * fw - d) / fw, 0.0, 1.0) * (2.0 * hw / w);
84
+ float on = 1.0 - (1.0 - cover.x) * (1.0 - cover.y);
85
+ // Where cells get a few px small, fade to the lines' average cover (no moire).
86
+ float cellPx = 1.0 / max(fw.x, fw.y);
87
+ float avg = 1.0 - (1.0 - 2.0 * hw) * (1.0 - 2.0 * hw);
88
+ on = mix(avg, on, clamp((cellPx - 3.0) / 6.0, 0.0, 1.0));
89
+ color = uLine * on + color * (1.0 - uLine.a * on);
90
+ }
91
+ outColor = color;
92
+ }`;
93
+ function compile(gl, type, src) {
94
+ const s = gl.createShader(type);
95
+ if (!s)
96
+ throw new Error("shader");
97
+ gl.shaderSource(s, src);
98
+ gl.compileShader(s);
99
+ if (!gl.getShaderParameter(s, gl.COMPILE_STATUS))
100
+ throw new Error(gl.getShaderInfoLog(s) ?? "");
101
+ return s;
102
+ }
103
+ /** Builds a program from the two sources (throws with the log on failure). */
104
+ export function linkProgram(gl, vertex, fragment) {
105
+ const program = gl.createProgram();
106
+ if (!program)
107
+ throw new Error("program");
108
+ const vs = compile(gl, gl.VERTEX_SHADER, vertex);
109
+ const fs = compile(gl, gl.FRAGMENT_SHADER, fragment);
110
+ gl.attachShader(program, vs);
111
+ gl.attachShader(program, fs);
112
+ gl.linkProgram(program);
113
+ gl.deleteShader(vs);
114
+ gl.deleteShader(fs);
115
+ if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
116
+ throw new Error(gl.getProgramInfoLog(program) ?? "");
117
+ }
118
+ return program;
119
+ }
120
+ /** Draws the ground in one GL context. */
121
+ export class GroundPainter {
122
+ gl;
123
+ program;
124
+ vao;
125
+ buffer;
126
+ u = {};
127
+ constructor(gl) {
128
+ this.gl = gl;
129
+ this.program = linkProgram(gl, VERTEX, FRAGMENT);
130
+ for (const name of ["uView", "uBackground", "uLine", "uGrid", "uGridSize", "uLineWidth"]) {
131
+ this.u[name] = gl.getUniformLocation(this.program, name);
132
+ }
133
+ const vao = gl.createVertexArray();
134
+ const buffer = gl.createBuffer();
135
+ if (!vao || !buffer)
136
+ throw new Error("gl objects");
137
+ this.vao = vao;
138
+ this.buffer = buffer;
139
+ gl.bindVertexArray(vao);
140
+ gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
141
+ gl.enableVertexAttribArray(0);
142
+ gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 8, 0);
143
+ gl.bindVertexArray(null);
144
+ }
145
+ draw(frame, look) {
146
+ const { gl, u } = this;
147
+ const { viewport, stage } = frame.view;
148
+ const region = groundRegionPx(frame.drawDistance, viewport.zoom, stage.width, stage.height, frame.amount);
149
+ const corners = stageRectWorld(region, viewport);
150
+ // Vertices relative to a grid-aligned origin near them: float32 keeps the precision,
151
+ // and the grid lines stay on the world's.
152
+ const cx = (corners[0].x + corners[2].x) / 2;
153
+ const cy = (corners[0].y + corners[2].y) / 2;
154
+ const origin = {
155
+ x: Math.round(cx / GROUND_GRID_SIZE) * GROUND_GRID_SIZE,
156
+ y: Math.round(cy / GROUND_GRID_SIZE) * GROUND_GRID_SIZE,
157
+ };
158
+ const v = new Float32Array(12);
159
+ const order = [0, 1, 2, 0, 2, 3];
160
+ order.forEach((k, i) => {
161
+ v[i * 2] = corners[k].x - origin.x;
162
+ v[i * 2 + 1] = corners[k].y - origin.y;
163
+ });
164
+ // biome-ignore lint/correctness/useHookAtTopLevel: WebGL's useProgram, not a React hook
165
+ gl.useProgram(this.program);
166
+ gl.bindVertexArray(this.vao);
167
+ gl.bindBuffer(gl.ARRAY_BUFFER, this.buffer);
168
+ gl.bufferData(gl.ARRAY_BUFFER, v, gl.DYNAMIC_DRAW);
169
+ gl.uniformMatrix4fv(u.uView, false, viewMatrix(frame.view, origin));
170
+ gl.uniform4fv(u.uBackground, look.background);
171
+ gl.uniform4fv(u.uLine, look.line);
172
+ gl.uniform1f(u.uGrid, look.grid ? 1 : 0);
173
+ gl.uniform1f(u.uGridSize, GROUND_GRID_SIZE);
174
+ gl.uniform1f(u.uLineWidth, look.lineWidth);
175
+ gl.depthMask(false);
176
+ gl.drawArrays(gl.TRIANGLES, 0, 6);
177
+ gl.depthMask(true);
178
+ gl.bindVertexArray(null);
179
+ }
180
+ release() {
181
+ const { gl } = this;
182
+ gl.deleteBuffer(this.buffer);
183
+ gl.deleteVertexArray(this.vao);
184
+ gl.deleteProgram(this.program);
185
+ }
186
+ }
187
+ //# sourceMappingURL=gpu3d-ground.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gpu3d-ground.js","sourceRoot":"","sources":["../src/gpu3d-ground.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ import { type PluginContext, type ProjectionCamera, type UsketchPlugin, type View3dCell, type View3dRendererApi, type View3dState } from "@edv4h/usketch-shared";
2
+ /** The canvas layer's id. */
3
+ export declare const GPU3D_LAYER_ID = "gpu3d:view";
4
+ /** Attribute on the main canvas container while the GPU renderer draws. */
5
+ export declare const GPU_STAGE_ATTR = "data-view3d-gpu";
6
+ export type Gpu3dRendererApi = View3dRendererApi;
7
+ /** The GPU 3D renderer on `ctx.services` (one per board). */
8
+ export declare const gpu3dRendererService: import("@edv4h/usketch-shared").ServiceHandle<View3dRendererApi>;
9
+ export interface Gpu3dRendererOptions {
10
+ /** Layers drawn in 3D instead of the declared ones. */
11
+ tiltLayerIds?: readonly string[];
12
+ /** Layers with depth instead of the declared ones. */
13
+ depthLayerIds?: readonly string[];
14
+ /** Where the 3D view state lives. Default: the board store's. */
15
+ view3d?: View3dCell;
16
+ /** Draw the board's shapes (default `true`). */
17
+ shapes?: boolean;
18
+ }
19
+ /** The camera a 3D view state draws with, as the projection functions take it. Pure. */
20
+ export declare function drawnCamera(state: View3dState, zoom: number): ProjectionCamera;
21
+ /** The CSS that hides the layers the canvas draws instead. Pure. */
22
+ export declare function hiddenLayerRules(ids: readonly string[]): string;
23
+ /**
24
+ * Set the renderer up on `ctx` (the plugin does it). Returns its API and teardown, or
25
+ * `null` when the board has no 3D view state.
26
+ */
27
+ export declare function setupGpu3dRenderer(ctx: PluginContext, options?: Gpu3dRendererOptions): {
28
+ api: Gpu3dRendererApi;
29
+ dispose: () => void;
30
+ } | null;
31
+ /**
32
+ * The GPU 3D renderer plugin (experimental). Add it INSTEAD of the CSS 3D renderer, before
33
+ * the 3D view (Mode 7). If a 3D renderer is already on the board, this one does nothing.
34
+ */
35
+ export declare function createGpu3dRendererPlugin(options?: Gpu3dRendererOptions): UsketchPlugin;
36
+ //# sourceMappingURL=gpu3d-renderer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gpu3d-renderer.d.ts","sourceRoot":"","sources":["../src/gpu3d-renderer.tsx"],"names":[],"mappings":"AAUA,OAAO,EAMN,KAAK,aAAa,EAClB,KAAK,gBAAgB,EACrB,KAAK,aAAa,EAClB,KAAK,UAAU,EAGf,KAAK,iBAAiB,EACtB,KAAK,WAAW,EAKhB,MAAM,uBAAuB,CAAC;AAK/B,6BAA6B;AAC7B,eAAO,MAAM,cAAc,eAAe,CAAC;AAC3C,2EAA2E;AAC3E,eAAO,MAAM,cAAc,oBAAoB,CAAC;AAMhD,MAAM,MAAM,gBAAgB,GAAG,iBAAiB,CAAC;AAEjD,6DAA6D;AAC7D,eAAO,MAAM,oBAAoB,kEAA4D,CAAC;AAE9F,MAAM,WAAW,oBAAoB;IACpC,uDAAuD;IACvD,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,sDAAsD;IACtD,aAAa,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,iEAAiE;IACjE,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,gDAAgD;IAChD,MAAM,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,wFAAwF;AACxF,wBAAgB,WAAW,CAAC,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,GAAG,gBAAgB,CAK9E;AAED,oEAAoE;AACpE,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAO/D;AA4GD;;;GAGG;AACH,wBAAgB,kBAAkB,CACjC,GAAG,EAAE,aAAa,EAClB,OAAO,GAAE,oBAAyB,GAChC;IAAE,GAAG,EAAE,gBAAgB,CAAC;IAAC,OAAO,EAAE,MAAM,IAAI,CAAA;CAAE,GAAG,IAAI,CAsLvD;AAuBD;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,GAAE,oBAAyB,GAAG,aAAa,CAiB3F"}