@wave3d/core 0.6.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/dist/config/model.d.ts +100 -8
- package/dist/config/model.js +47 -1
- package/dist/config/model.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/presets.d.ts +8 -2
- package/dist/presets.js +472 -1
- package/dist/presets.js.map +1 -1
- package/dist/renderer/WaveGeometry.d.ts +22 -3
- package/dist/renderer/WaveGeometry.js +22 -3
- package/dist/renderer/WaveGeometry.js.map +1 -1
- package/dist/renderer/WaveRenderer.d.ts +22 -0
- package/dist/renderer/WaveRenderer.js +107 -1
- package/dist/renderer/WaveRenderer.js.map +1 -1
- package/dist/renderer/palette.d.ts +1 -1
- package/dist/renderer/palette.js +7 -5
- package/dist/renderer/palette.js.map +1 -1
- package/dist/renderer/particleField.d.ts +81 -0
- package/dist/renderer/particleField.js +357 -0
- package/dist/renderer/particleField.js.map +1 -0
- package/dist/renderer/shaders.js +377 -127
- package/dist/renderer/shaders.js.map +1 -1
- package/dist/standalone/wave3d.standalone.js +2621 -1787
- package/dist/standalone.d.ts +2 -2
- package/dist/standalone.js +2 -2
- package/dist/studio/thumbnail.d.ts +2 -2
- package/dist/studio/thumbnail.js +16 -7
- package/dist/studio/thumbnail.js.map +1 -1
- package/package.json +6 -4
- package/skills/wave3d/SKILL.md +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"particleField.js","names":[],"sources":["../../src/renderer/particleField.ts"],"sourcesContent":["import * as THREE from \"three\";\nimport type { ParticlesConfig } from \"../config/model\";\nimport { RIPPLE_SLOTS } from \"./interaction\";\nimport { particleFragmentShader, particleVertexShader } from \"./shaders\";\n\n/**\n * A WAVE's additive particle / dust field: a single {@link THREE.Points} whose every particle is placed\n * and animated ENTIRELY in the vertex shader from `uTime` + baked per-particle attributes, so the field\n * is deterministic — the same `(count, seed, edgeBias, bias)` yields byte-identical buffers, and all\n * motion is a pure function of the scene time `t` (so timeOffset scrub / loopSeconds / paused reproduce).\n *\n * One field belongs to ONE wave (created/disposed alongside it, like {@link WavePalette}). Every particle\n * spawns on that wave's DEFORMED surface / edge (via the shared waveShape chunk, riding the exact deform\n * the ribbon uses) and drifts outward from the wave centre. Byte-identical when off: absent\n * `wave.particles` ⇒ the renderer never creates a field.\n */\nexport interface ParticleFrame {\n /** The owning wave's world-space centre — drift radiates from here. */\n center: THREE.Vector3;\n /** Screen-right / screen-up unit vectors (world space) for screen-relative motion. */\n right: THREE.Vector3;\n up: THREE.Vector3;\n}\n\n/** Deterministic PRNG (mulberry32): a pure function of the seed, so a `(count, seed)` layout\n * reproduces exactly. NEVER Math.random — that would desync timeOffset scrub / loop / paused. */\nfunction mulberry32(seed: number): () => number {\n let a = seed >>> 0;\n return () => {\n a |= 0;\n a = (a + 0x6d2b79f5) | 0;\n let t = Math.imul(a ^ (a >>> 15), 1 | a);\n t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t;\n return ((t ^ (t >>> 14)) >>> 0) / 4294967296;\n };\n}\n\n// sRGB hex → linear RGB. Replicates WaveRenderer.hexToLinearVec3 locally to avoid a circular import\n// (the renderer imports this module): three's ColorManagement linearizes on parse, so read .r/.g/.b\n// directly — a second convertSRGBToLinear() would double-linearize.\nconst HEX_SCRATCH = new THREE.Color();\nfunction setLinear(target: THREE.Vector3, hex: string): void {\n const c = HEX_SCRATCH.set(hex);\n target.set(c.r, c.g, c.b);\n}\n\nconst DEFAULT_COLOR = \"#ffcf8a\"; // warm gold\n\n/**\n * Edge of the square canvas a {@link ParticlesConfig.spriteUrl} is rasterized into. SVG has no\n * intrinsic pixel size, so something has to choose one — this is it.\n *\n * 256² RGBA is ~256 KB (~350 KB with mipmaps), which is LESS than the per-particle attribute\n * buffers a 20k field already uploads (~800 KB): one texture serves every particle in the field, so\n * sprite artwork is not what makes a dust field expensive. 256 also covers the largest sprite the\n * hardware will draw — gl.ALIASED_POINT_SIZE_RANGE tops out around 511 px, and `size` clamps to 200\n * before the pixel-ratio multiply.\n */\nconst SPRITE_PX = 256;\n\n/** Sprite-shape name → the int the fragment shader branches on (see particleFragmentShader). */\nconst SHAPE_INDEX: Record<string, number> = { glitter: 0, soft: 1, ring: 2, star: 3, streak: 4 };\n\n/** The owning wave's shape uniforms mirrored onto the particle material so the dust rides the same\n * deform as the ribbon. Names match the wave material's uniforms 1:1 (copied by value in configure). */\nconst SHAPE_UNIFORMS = [\n \"uDispFreqX\",\n \"uDispFreqZ\",\n \"uDispAmount\",\n \"uDetailFreq\",\n \"uDetailAmount\",\n \"uTwFreqX\",\n \"uTwFreqY\",\n \"uTwFreqZ\",\n \"uTwPowX\",\n \"uTwPowY\",\n \"uTwPowZ\",\n \"uHelixTurns\",\n \"uHelixRadius\",\n \"uHelixRoll\",\n \"uHelixPhase\",\n \"uRadialAmount\",\n \"uRadialArc\",\n \"uRadialSpread\",\n \"uRadialRadius\",\n \"uRadialCenter\",\n] as const;\n\n/** The owning wave's POINTER-FIELD uniforms, mirrored the same way so the dust reads the exact\n * cursor state the ribbon does (see pointerFieldChunk). Only uploaded under POINTER_FX — configure()\n * copies them regardless, which is a handful of scalars. The ripple entries are ARRAYS: those are\n * shared by reference (the wave owns them and applyPointerField mutates them in place), so a click\n * costs no per-frame copy. Mirroring rather than a second CPU write also keeps capture determinism\n * for free — applyInteractionRest zeroes the wave's uPointerActive / uRippleAmp, and the dust\n * inherits that rest state on the same frame (updateSceneFx runs after applyInteraction). */\nconst POINTER_UNIFORMS = [\n \"uPointer\",\n \"uPointerActive\",\n \"uPointerRadius\",\n \"uPointerAspect\",\n \"uPointerAgitate\",\n \"uPointerPush\",\n \"uPointerWake\",\n \"uPointerVel\",\n \"uShapeFlow\",\n \"uRippleOrigin\",\n \"uRippleAge\",\n \"uRippleAmp\",\n \"uPointerRipple\",\n] as const;\n\n/** Build the seeded per-particle attribute buffers. Pure function of `(count, seed, edgeBias, bias)` —\n * exported so a unit test can assert reproducibility without a GPU. */\nexport function buildParticleAttributes(\n count: number,\n seed: number,\n edgeBias = 1,\n bias = 0,\n): {\n position: Float32Array;\n aSeed: Float32Array;\n aRnd: Float32Array;\n aUv: Float32Array;\n} {\n const rand = mulberry32(seed >>> 0 || 1);\n const position = new Float32Array(count * 3); // dummy — the vertex shader computes real positions\n const aSeed = new Float32Array(count);\n const aRnd = new Float32Array(count * 4);\n const aUv = new Float32Array(count * 2);\n for (let i = 0; i < count; i++) {\n aSeed[i] = rand();\n aRnd[i * 4 + 0] = rand();\n aRnd[i * 4 + 1] = rand();\n aRnd[i * 4 + 2] = rand();\n aRnd[i * 4 + 3] = rand();\n }\n // aUv in a SEPARATE pass so adding/changing it never shifts the aSeed/aRnd RNG sequence above. aUv.x\n // = the flank position across the ribbon width; `bias` skews it toward one side (`u^p`, p<1 crowds\n // →1, p>1 crowds →0; p=1 / bias 0 leaves it untouched). aUv.y = WHERE ALONG the ribbon the particle\n // spawns, interpolated by `edgeBias`: 0 → uniform across the whole SURFACE, 1 → crowded to the outer\n // rim/EDGE (`1 − rand²·0.45`, the silk-dissolving-into-glitter look).\n const pexp = bias === 0 ? 1 : Math.exp(-bias * 2);\n const eb = Math.min(Math.max(edgeBias, 0), 1);\n for (let i = 0; i < count; i++) {\n const ux = rand();\n aUv[i * 2 + 0] = bias === 0 ? ux : Math.pow(ux, pexp);\n const e = rand();\n const rim = 1.0 - e * e * 0.45; // outer-rim biased\n aUv[i * 2 + 1] = e + (rim - e) * eb; // mix(surface, edge) by edgeBias\n }\n return { position, aSeed, aRnd, aUv };\n}\n\nexport class ParticleField {\n readonly points: THREE.Points;\n private readonly geometry = new THREE.BufferGeometry();\n private readonly material: THREE.ShaderMaterial;\n /** Layout signature — only these rebuild the seeded buffers; the rest are live uniforms. */\n private sig = \"\";\n /** Rasterized user artwork for shape \"sprite\", and the url it came from (so a repeat sync is a\n * no-op). `spriteFailedUrl` latches a broken image so a bad url is not retried every frame. */\n private sprite?: THREE.CanvasTexture;\n private spriteUrl = \"\";\n private spriteFailedUrl = \"\";\n private disposed = false;\n /** Defines this field owns (currently just PARTICLE_SPRITE), merged over the wave's in configure().\n * Set only once a texture is actually bound, so the sampler never compiles without one. */\n private ownDefines: Record<string, string> = {};\n /** Called when a sprite finishes rasterizing, so a paused/settled renderer redraws with it. */\n private readonly onReady?: () => void;\n\n constructor(onReady?: () => void) {\n this.onReady = onReady;\n this.material = new THREE.ShaderMaterial({\n uniforms: {\n uTime: { value: 0 },\n uLoopSeconds: { value: 0 },\n uLife: { value: 6 },\n uPartSpeed: { value: 1 },\n uSize: { value: 2 },\n uSizeJitter: { value: 0 },\n uTwinkle: { value: 0 },\n uPixelRatio: { value: 1 },\n uColor: { value: new THREE.Vector3(1, 0.81, 0.54) },\n uColor2: { value: new THREE.Vector3(1, 0.81, 0.54) },\n uCenter: { value: new THREE.Vector3() },\n uRight: { value: new THREE.Vector3(1, 0, 0) },\n uUp: { value: new THREE.Vector3(0, 1, 0) },\n uDrift: { value: 0 },\n uRise: { value: 0 },\n uSwirl: { value: 0 },\n uWander: { value: 0 },\n uShape: { value: 0 },\n // The owning wave's shape uniforms + world matrix, mirrored in configure() so the dust rides\n // the same deform as the ribbon. The nested HELIX/RADIAL uniforms are only declared (and\n // uploaded) when the matching #define is set — the byte-identity precedent from the wave material.\n uDispFreqX: { value: 0 },\n uDispFreqZ: { value: 0 },\n uDispAmount: { value: 0 },\n uDetailFreq: { value: 0 },\n uDetailAmount: { value: 0 },\n uTwFreqX: { value: 0 },\n uTwFreqY: { value: 0 },\n uTwFreqZ: { value: 0 },\n uTwPowX: { value: 0 },\n uTwPowY: { value: 0 },\n uTwPowZ: { value: 0 },\n uHelixTurns: { value: 0 },\n uHelixRadius: { value: 0 },\n uHelixRoll: { value: 0 },\n uHelixPhase: { value: 0 },\n uRadialAmount: { value: 0 },\n uRadialArc: { value: 0 },\n uRadialSpread: { value: 0 },\n uRadialRadius: { value: 0 },\n uRadialCenter: { value: 0 },\n uShedModel: { value: new THREE.Matrix4() },\n uShedSpeed: { value: 0 },\n uShedSeed: { value: 0 },\n // Pointer field, mirrored from the owning wave in configure() (read only under POINTER_FX).\n // The ripple arrays are sized to RIPPLE_SLOTS so the material is valid before the first\n // configure(); configure() then swaps in the wave's own arrays by reference.\n uPointer: { value: new THREE.Vector2() },\n uPointerActive: { value: 0 },\n uPointerRadius: { value: 0.6 },\n uPointerAspect: { value: 1 },\n uPointerAgitate: { value: 0 },\n uPointerPush: { value: 0 },\n uPointerWake: { value: 0 },\n uPointerVel: { value: new THREE.Vector2() },\n uShapeFlow: { value: 0 },\n uRippleOrigin: { value: Array.from({ length: RIPPLE_SLOTS }, () => new THREE.Vector2()) },\n uRippleAge: { value: Array.from({ length: RIPPLE_SLOTS }, () => 0) },\n uRippleAmp: { value: Array.from({ length: RIPPLE_SLOTS }, () => 0) },\n uPointerRipple: { value: 0 },\n uPartShove: { value: 1 },\n // User artwork (read only under PARTICLE_SPRITE, which is set only once this is non-null).\n uSprite: { value: null as THREE.Texture | null },\n },\n vertexShader: particleVertexShader,\n fragmentShader: particleFragmentShader,\n transparent: true,\n depthTest: false, // always composite OVER the waves...\n depthWrite: false, // ...and never occlude anything (additive glints)\n blending: THREE.AdditiveBlending,\n });\n this.points = new THREE.Points(this.geometry, this.material);\n this.points.frustumCulled = false; // positions are shader-computed; the base geometry is dummy\n this.points.renderOrder = 10; // after the waves (0..5)\n }\n\n /** Reconcile to `cfg`: rebuild the seeded buffers if the layout signature changed, then push the\n * frame-independent uniforms. `loopSeconds` is scene-level (passed in). Called from refresh(). */\n sync(cfg: ParticlesConfig, loopSeconds: number): void {\n const count = Math.max(0, Math.floor(cfg.count));\n const edgeBias = cfg.edgeBias ?? 1;\n const bias = cfg.bias ?? 0;\n const sig = `${count}|${cfg.seed}|${edgeBias}|${bias}`;\n if (sig !== this.sig) {\n this.sig = sig;\n const { position, aSeed, aRnd, aUv } = buildParticleAttributes(\n count,\n cfg.seed,\n edgeBias,\n bias,\n );\n this.geometry.setAttribute(\"position\", new THREE.BufferAttribute(position, 3));\n this.geometry.setAttribute(\"aSeed\", new THREE.BufferAttribute(aSeed, 1));\n this.geometry.setAttribute(\"aRnd\", new THREE.BufferAttribute(aRnd, 4));\n this.geometry.setAttribute(\"aUv\", new THREE.BufferAttribute(aUv, 2));\n this.geometry.setDrawRange(0, count);\n }\n const u = this.material.uniforms;\n u.uLoopSeconds.value = loopSeconds;\n u.uLife.value = cfg.life ?? 6;\n u.uPartSpeed.value = cfg.speed ?? 1;\n u.uSize.value = cfg.size;\n u.uSizeJitter.value = cfg.sizeJitter ?? 0;\n u.uTwinkle.value = cfg.twinkle ?? 0;\n u.uDrift.value = cfg.drift ?? 0;\n u.uRise.value = cfg.rise ?? 0;\n u.uSwirl.value = cfg.swirl ?? 0;\n u.uWander.value = cfg.wander ?? 0;\n u.uShape.value = SHAPE_INDEX[cfg.shape ?? \"glitter\"] ?? 0;\n u.uPartShove.value = cfg.pointerShove ?? 1;\n this.syncSprite(cfg.shape === \"sprite\" ? (cfg.spriteUrl ?? \"\") : \"\");\n setLinear(u.uColor.value as THREE.Vector3, cfg.color ?? DEFAULT_COLOR);\n setLinear(u.uColor2.value as THREE.Vector3, cfg.color2 ?? cfg.color ?? DEFAULT_COLOR);\n }\n\n /** Push the per-frame frame basis (the camera can move, so this runs every frame). */\n frame(f: ParticleFrame, pixelRatio: number): void {\n const u = this.material.uniforms;\n (u.uCenter.value as THREE.Vector3).copy(f.center);\n (u.uRight.value as THREE.Vector3).copy(f.right);\n (u.uUp.value as THREE.Vector3).copy(f.up);\n u.uPixelRatio.value = pixelRatio;\n }\n\n /** Bind the OWNING wave's shape AND cursor state: mirror its #defines + shape uniforms + pointer\n * uniforms + world matrix, so the dust rides the same deform as the ribbon and reacts to the same\n * pointer field. Recompiles the point program only when the define set changes — which is why the\n * defines must come from CONFIG only (shapeDefines), never from live input. Called from refresh()\n * each frame with the wave's live state. */\n configure(shape: {\n defines: Record<string, string>;\n uniforms: Record<string, THREE.IUniform>;\n matrixWorld: THREE.Matrix4;\n speed: number;\n seed: number;\n }): void {\n const want = { ...shape.defines, ...this.ownDefines };\n const cur = (this.material.defines ?? {}) as Record<string, string>;\n if (Object.keys(want).sort().join(\",\") !== Object.keys(cur).sort().join(\",\")) {\n this.material.defines = { ...want };\n this.material.needsUpdate = true; // define set changed → recompile the point program\n }\n const u = this.material.uniforms;\n for (const name of SHAPE_UNIFORMS) this.mirror(shape.uniforms, name);\n for (const name of POINTER_UNIFORMS) this.mirror(shape.uniforms, name);\n (u.uShedModel.value as THREE.Matrix4).copy(shape.matrixWorld);\n u.uShedSpeed.value = shape.speed;\n u.uShedSeed.value = shape.seed;\n }\n\n /** Reconcile the sprite texture to `url` (\"\" = none). Cheap and idempotent: a repeat call with the\n * same url does nothing, and a url that already failed is never retried. */\n private syncSprite(url: string): void {\n if (url === this.spriteUrl) return;\n this.spriteUrl = url;\n this.clearSprite();\n if (url && url !== this.spriteFailedUrl) this.loadSprite(url);\n }\n\n /** Drop the current sprite and fall back to the procedural shapes (which is what `uShape` still\n * holds, so a field mid-load or with a broken image draws \"glitter\" rather than nothing). */\n private clearSprite(): void {\n if (!this.sprite) return;\n this.sprite.dispose();\n this.sprite = undefined;\n this.material.uniforms.uSprite.value = null;\n if (this.ownDefines.PARTICLE_SPRITE !== undefined) {\n this.ownDefines = {};\n this.material.needsUpdate = true; // configure() will also notice, but a paused field may not tick\n }\n }\n\n /**\n * Rasterize `url` into a square {@link SPRITE_PX} texture and bind it.\n *\n * Deliberately the BACKGROUND-image pattern (load → apply → ask for a redraw) rather than\n * loadPaletteImage's fire-and-forget TextureLoader: a thumbnail or poster snapshotted while the\n * texture was still in flight would capture blank dust — the same class of bug that made\n * image-driven preset thumbnails render empty.\n */\n private loadSprite(url: string): void {\n const img = new Image();\n img.decoding = \"async\";\n // data:/blob: are same-origin already; anything else must be CORS-clean or the canvas taints\n // and readback (thumbnails, posters, captureImage) throws.\n if (!url.startsWith(\"data:\") && !url.startsWith(\"blob:\")) img.crossOrigin = \"anonymous\";\n img.addEventListener(\n \"load\",\n () => {\n // The config may have moved on (or the field been disposed) while this was decoding.\n if (this.disposed || this.spriteUrl !== url) return;\n const canvas = document.createElement(\"canvas\");\n canvas.width = SPRITE_PX;\n canvas.height = SPRITE_PX;\n const ctx = canvas.getContext(\"2d\");\n if (!ctx) return;\n // CONTAIN the artwork: a point sprite is always square (gl_PointCoord spans 0..1 on both\n // axes), so non-square art has to be letterboxed or it draws stretched. An SVG with no\n // intrinsic size reports 0 in some browsers — fall back to filling the square.\n const iw = img.naturalWidth || SPRITE_PX;\n const ih = img.naturalHeight || SPRITE_PX;\n const fit = Math.min(SPRITE_PX / iw, SPRITE_PX / ih);\n const w = iw * fit;\n const h = ih * fit;\n ctx.drawImage(img, (SPRITE_PX - w) / 2, (SPRITE_PX - h) / 2, w, h);\n const tex = new THREE.CanvasTexture(canvas);\n tex.colorSpace = THREE.SRGBColorSpace;\n // Mipmaps matter here in a way they do not for the palette: `sizeJitter` and the birth/death\n // fade draw the SAME texture at wildly different pixel sizes, and gl_PointCoord's\n // derivatives across a point sprite are well defined, so the GPU picks a sane level.\n tex.generateMipmaps = true;\n tex.minFilter = THREE.LinearMipmapLinearFilter;\n tex.magFilter = THREE.LinearFilter;\n tex.wrapS = THREE.ClampToEdgeWrapping;\n tex.wrapT = THREE.ClampToEdgeWrapping;\n this.sprite = tex;\n this.material.uniforms.uSprite.value = tex;\n this.ownDefines = { PARTICLE_SPRITE: \"\" };\n this.material.needsUpdate = true; // sampler appears → recompile the point program\n this.onReady?.(); // a paused / settled renderer would otherwise never draw it\n },\n { once: true },\n );\n // Latch the failure so a broken url is not re-requested on every sync.\n img.addEventListener(\n \"error\",\n () => {\n this.spriteFailedUrl = url;\n },\n { once: true },\n );\n img.src = url;\n }\n\n /** Copy one uniform across from the owning wave: numbers by value, vectors/matrices in place, and\n * arrays (the ripple slots) by reference — the wave owns those and mutates them in place. */\n private mirror(src: Record<string, THREE.IUniform>, name: string): void {\n const from = src[name];\n const to = this.material.uniforms[name];\n if (!from || !to) return;\n const dst = to.value;\n if (typeof from.value === \"number\" || Array.isArray(from.value)) to.value = from.value;\n else if (dst && typeof (dst as { copy?: unknown }).copy === \"function\") {\n (dst as THREE.Vector3).copy(from.value as THREE.Vector3);\n }\n }\n\n /** Advance the field to scene time `t` (= the same `t` the waves get). */\n setTime(t: number): void {\n this.material.uniforms.uTime.value = t;\n }\n\n dispose(): void {\n this.disposed = true;\n this.sprite?.dispose();\n this.geometry.dispose();\n this.material.dispose();\n }\n}\n"],"mappings":";;;;;AA0BA,SAAS,WAAW,MAA4B;CAC9C,IAAI,IAAI,SAAS;CACjB,aAAa;EACX,KAAK;EACL,IAAK,IAAI,aAAc;EACvB,IAAI,IAAI,KAAK,KAAK,IAAK,MAAM,IAAK,IAAI,CAAC;EACvC,IAAK,IAAI,KAAK,KAAK,IAAK,MAAM,GAAI,KAAK,CAAC,IAAK;EAC7C,SAAS,IAAK,MAAM,QAAS,KAAK;CACpC;AACF;AAKA,MAAM,cAAc,IAAI,MAAM,MAAM;AACpC,SAAS,UAAU,QAAuB,KAAmB;CAC3D,MAAM,IAAI,YAAY,IAAI,GAAG;CAC7B,OAAO,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;AAC1B;AAEA,MAAM,gBAAgB;;;;;;;;;;;AAYtB,MAAM,YAAY;;AAGlB,MAAM,cAAsC;CAAE,SAAS;CAAG,MAAM;CAAG,MAAM;CAAG,MAAM;CAAG,QAAQ;AAAE;;;AAI/F,MAAM,iBAAiB;CACrB;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;;;;;;;;AASA,MAAM,mBAAmB;CACvB;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;;;AAIA,SAAgB,wBACd,OACA,MACA,WAAW,GACX,OAAO,GAMP;CACA,MAAM,OAAO,WAAW,SAAS,KAAK,CAAC;CACvC,MAAM,WAAW,IAAI,aAAa,QAAQ,CAAC;CAC3C,MAAM,QAAQ,IAAI,aAAa,KAAK;CACpC,MAAM,OAAO,IAAI,aAAa,QAAQ,CAAC;CACvC,MAAM,MAAM,IAAI,aAAa,QAAQ,CAAC;CACtC,KAAK,IAAI,IAAI,GAAG,IAAI,OAAO,KAAK;EAC9B,MAAM,KAAK,KAAK;EAChB,KAAK,IAAI,IAAI,KAAK,KAAK;EACvB,KAAK,IAAI,IAAI,KAAK,KAAK;EACvB,KAAK,IAAI,IAAI,KAAK,KAAK;EACvB,KAAK,IAAI,IAAI,KAAK,KAAK;CACzB;CAMA,MAAM,OAAO,SAAS,IAAI,IAAI,KAAK,IAAI,CAAC,OAAO,CAAC;CAChD,MAAM,KAAK,KAAK,IAAI,KAAK,IAAI,UAAU,CAAC,GAAG,CAAC;CAC5C,KAAK,IAAI,IAAI,GAAG,IAAI,OAAO,KAAK;EAC9B,MAAM,KAAK,KAAK;EAChB,IAAI,IAAI,IAAI,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,IAAI,IAAI;EACpD,MAAM,IAAI,KAAK;EACf,MAAM,MAAM,IAAM,IAAI,IAAI;EAC1B,IAAI,IAAI,IAAI,KAAK,KAAK,MAAM,KAAK;CACnC;CACA,OAAO;EAAE;EAAU;EAAO;EAAM;CAAI;AACtC;AAEA,IAAa,gBAAb,MAA2B;CACzB;CACA,WAA4B,IAAI,MAAM,eAAe;CACrD;;CAEA,MAAc;;;CAGd;CACA,YAAoB;CACpB,kBAA0B;CAC1B,WAAmB;;;CAGnB,aAA6C,CAAC;;CAE9C;CAEA,YAAY,SAAsB;EAChC,KAAK,UAAU;EACf,KAAK,WAAW,IAAI,MAAM,eAAe;GACvC,UAAU;IACR,OAAO,EAAE,OAAO,EAAE;IAClB,cAAc,EAAE,OAAO,EAAE;IACzB,OAAO,EAAE,OAAO,EAAE;IAClB,YAAY,EAAE,OAAO,EAAE;IACvB,OAAO,EAAE,OAAO,EAAE;IAClB,aAAa,EAAE,OAAO,EAAE;IACxB,UAAU,EAAE,OAAO,EAAE;IACrB,aAAa,EAAE,OAAO,EAAE;IACxB,QAAQ,EAAE,OAAO,IAAI,MAAM,QAAQ,GAAG,KAAM,GAAI,EAAE;IAClD,SAAS,EAAE,OAAO,IAAI,MAAM,QAAQ,GAAG,KAAM,GAAI,EAAE;IACnD,SAAS,EAAE,OAAO,IAAI,MAAM,QAAQ,EAAE;IACtC,QAAQ,EAAE,OAAO,IAAI,MAAM,QAAQ,GAAG,GAAG,CAAC,EAAE;IAC5C,KAAK,EAAE,OAAO,IAAI,MAAM,QAAQ,GAAG,GAAG,CAAC,EAAE;IACzC,QAAQ,EAAE,OAAO,EAAE;IACnB,OAAO,EAAE,OAAO,EAAE;IAClB,QAAQ,EAAE,OAAO,EAAE;IACnB,SAAS,EAAE,OAAO,EAAE;IACpB,QAAQ,EAAE,OAAO,EAAE;IAInB,YAAY,EAAE,OAAO,EAAE;IACvB,YAAY,EAAE,OAAO,EAAE;IACvB,aAAa,EAAE,OAAO,EAAE;IACxB,aAAa,EAAE,OAAO,EAAE;IACxB,eAAe,EAAE,OAAO,EAAE;IAC1B,UAAU,EAAE,OAAO,EAAE;IACrB,UAAU,EAAE,OAAO,EAAE;IACrB,UAAU,EAAE,OAAO,EAAE;IACrB,SAAS,EAAE,OAAO,EAAE;IACpB,SAAS,EAAE,OAAO,EAAE;IACpB,SAAS,EAAE,OAAO,EAAE;IACpB,aAAa,EAAE,OAAO,EAAE;IACxB,cAAc,EAAE,OAAO,EAAE;IACzB,YAAY,EAAE,OAAO,EAAE;IACvB,aAAa,EAAE,OAAO,EAAE;IACxB,eAAe,EAAE,OAAO,EAAE;IAC1B,YAAY,EAAE,OAAO,EAAE;IACvB,eAAe,EAAE,OAAO,EAAE;IAC1B,eAAe,EAAE,OAAO,EAAE;IAC1B,eAAe,EAAE,OAAO,EAAE;IAC1B,YAAY,EAAE,OAAO,IAAI,MAAM,QAAQ,EAAE;IACzC,YAAY,EAAE,OAAO,EAAE;IACvB,WAAW,EAAE,OAAO,EAAE;IAItB,UAAU,EAAE,OAAO,IAAI,MAAM,QAAQ,EAAE;IACvC,gBAAgB,EAAE,OAAO,EAAE;IAC3B,gBAAgB,EAAE,OAAO,GAAI;IAC7B,gBAAgB,EAAE,OAAO,EAAE;IAC3B,iBAAiB,EAAE,OAAO,EAAE;IAC5B,cAAc,EAAE,OAAO,EAAE;IACzB,cAAc,EAAE,OAAO,EAAE;IACzB,aAAa,EAAE,OAAO,IAAI,MAAM,QAAQ,EAAE;IAC1C,YAAY,EAAE,OAAO,EAAE;IACvB,eAAe,EAAE,OAAO,MAAM,KAAK,EAAE,QAAA,EAAqB,SAAS,IAAI,MAAM,QAAQ,CAAC,EAAE;IACxF,YAAY,EAAE,OAAO,MAAM,KAAK,EAAE,QAAA,EAAqB,SAAS,CAAC,EAAE;IACnE,YAAY,EAAE,OAAO,MAAM,KAAK,EAAE,QAAA,EAAqB,SAAS,CAAC,EAAE;IACnE,gBAAgB,EAAE,OAAO,EAAE;IAC3B,YAAY,EAAE,OAAO,EAAE;IAEvB,SAAS,EAAE,OAAO,KAA6B;GACjD;GACA,cAAc;GACd,gBAAgB;GAChB,aAAa;GACb,WAAW;GACX,YAAY;GACZ,UAAU,MAAM;EAClB,CAAC;EACD,KAAK,SAAS,IAAI,MAAM,OAAO,KAAK,UAAU,KAAK,QAAQ;EAC3D,KAAK,OAAO,gBAAgB;EAC5B,KAAK,OAAO,cAAc;CAC5B;;;CAIA,KAAK,KAAsB,aAA2B;EACpD,MAAM,QAAQ,KAAK,IAAI,GAAG,KAAK,MAAM,IAAI,KAAK,CAAC;EAC/C,MAAM,WAAW,IAAI,YAAY;EACjC,MAAM,OAAO,IAAI,QAAQ;EACzB,MAAM,MAAM,GAAG,MAAM,GAAG,IAAI,KAAK,GAAG,SAAS,GAAG;EAChD,IAAI,QAAQ,KAAK,KAAK;GACpB,KAAK,MAAM;GACX,MAAM,EAAE,UAAU,OAAO,MAAM,QAAQ,wBACrC,OACA,IAAI,MACJ,UACA,IACF;GACA,KAAK,SAAS,aAAa,YAAY,IAAI,MAAM,gBAAgB,UAAU,CAAC,CAAC;GAC7E,KAAK,SAAS,aAAa,SAAS,IAAI,MAAM,gBAAgB,OAAO,CAAC,CAAC;GACvE,KAAK,SAAS,aAAa,QAAQ,IAAI,MAAM,gBAAgB,MAAM,CAAC,CAAC;GACrE,KAAK,SAAS,aAAa,OAAO,IAAI,MAAM,gBAAgB,KAAK,CAAC,CAAC;GACnE,KAAK,SAAS,aAAa,GAAG,KAAK;EACrC;EACA,MAAM,IAAI,KAAK,SAAS;EACxB,EAAE,aAAa,QAAQ;EACvB,EAAE,MAAM,QAAQ,IAAI,QAAQ;EAC5B,EAAE,WAAW,QAAQ,IAAI,SAAS;EAClC,EAAE,MAAM,QAAQ,IAAI;EACpB,EAAE,YAAY,QAAQ,IAAI,cAAc;EACxC,EAAE,SAAS,QAAQ,IAAI,WAAW;EAClC,EAAE,OAAO,QAAQ,IAAI,SAAS;EAC9B,EAAE,MAAM,QAAQ,IAAI,QAAQ;EAC5B,EAAE,OAAO,QAAQ,IAAI,SAAS;EAC9B,EAAE,QAAQ,QAAQ,IAAI,UAAU;EAChC,EAAE,OAAO,QAAQ,YAAY,IAAI,SAAS,cAAc;EACxD,EAAE,WAAW,QAAQ,IAAI,gBAAgB;EACzC,KAAK,WAAW,IAAI,UAAU,WAAY,IAAI,aAAa,KAAM,EAAE;EACnE,UAAU,EAAE,OAAO,OAAwB,IAAI,SAAS,aAAa;EACrE,UAAU,EAAE,QAAQ,OAAwB,IAAI,UAAU,IAAI,SAAS,aAAa;CACtF;;CAGA,MAAM,GAAkB,YAA0B;EAChD,MAAM,IAAI,KAAK,SAAS;EACxB,EAAG,QAAQ,MAAwB,KAAK,EAAE,MAAM;EAChD,EAAG,OAAO,MAAwB,KAAK,EAAE,KAAK;EAC9C,EAAG,IAAI,MAAwB,KAAK,EAAE,EAAE;EACxC,EAAE,YAAY,QAAQ;CACxB;;;;;;CAOA,UAAU,OAMD;EACP,MAAM,OAAO;GAAE,GAAG,MAAM;GAAS,GAAG,KAAK;EAAW;EACpD,MAAM,MAAO,KAAK,SAAS,WAAW,CAAC;EACvC,IAAI,OAAO,KAAK,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,GAAG,MAAM,OAAO,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,GAAG,GAAG;GAC5E,KAAK,SAAS,UAAU,EAAE,GAAG,KAAK;GAClC,KAAK,SAAS,cAAc;EAC9B;EACA,MAAM,IAAI,KAAK,SAAS;EACxB,KAAK,MAAM,QAAQ,gBAAgB,KAAK,OAAO,MAAM,UAAU,IAAI;EACnE,KAAK,MAAM,QAAQ,kBAAkB,KAAK,OAAO,MAAM,UAAU,IAAI;EACrE,EAAG,WAAW,MAAwB,KAAK,MAAM,WAAW;EAC5D,EAAE,WAAW,QAAQ,MAAM;EAC3B,EAAE,UAAU,QAAQ,MAAM;CAC5B;;;CAIA,WAAmB,KAAmB;EACpC,IAAI,QAAQ,KAAK,WAAW;EAC5B,KAAK,YAAY;EACjB,KAAK,YAAY;EACjB,IAAI,OAAO,QAAQ,KAAK,iBAAiB,KAAK,WAAW,GAAG;CAC9D;;;CAIA,cAA4B;EAC1B,IAAI,CAAC,KAAK,QAAQ;EAClB,KAAK,OAAO,QAAQ;EACpB,KAAK,SAAS,KAAA;EACd,KAAK,SAAS,SAAS,QAAQ,QAAQ;EACvC,IAAI,KAAK,WAAW,oBAAoB,KAAA,GAAW;GACjD,KAAK,aAAa,CAAC;GACnB,KAAK,SAAS,cAAc;EAC9B;CACF;;;;;;;;;CAUA,WAAmB,KAAmB;EACpC,MAAM,MAAM,IAAI,MAAM;EACtB,IAAI,WAAW;EAGf,IAAI,CAAC,IAAI,WAAW,OAAO,KAAK,CAAC,IAAI,WAAW,OAAO,GAAG,IAAI,cAAc;EAC5E,IAAI,iBACF,cACM;GAEJ,IAAI,KAAK,YAAY,KAAK,cAAc,KAAK;GAC7C,MAAM,SAAS,SAAS,cAAc,QAAQ;GAC9C,OAAO,QAAQ;GACf,OAAO,SAAS;GAChB,MAAM,MAAM,OAAO,WAAW,IAAI;GAClC,IAAI,CAAC,KAAK;GAIV,MAAM,KAAK,IAAI,gBAAgB;GAC/B,MAAM,KAAK,IAAI,iBAAiB;GAChC,MAAM,MAAM,KAAK,IAAI,YAAY,IAAI,YAAY,EAAE;GACnD,MAAM,IAAI,KAAK;GACf,MAAM,IAAI,KAAK;GACf,IAAI,UAAU,MAAM,YAAY,KAAK,IAAI,YAAY,KAAK,GAAG,GAAG,CAAC;GACjE,MAAM,MAAM,IAAI,MAAM,cAAc,MAAM;GAC1C,IAAI,aAAa,MAAM;GAIvB,IAAI,kBAAkB;GACtB,IAAI,YAAY,MAAM;GACtB,IAAI,YAAY,MAAM;GACtB,IAAI,QAAQ,MAAM;GAClB,IAAI,QAAQ,MAAM;GAClB,KAAK,SAAS;GACd,KAAK,SAAS,SAAS,QAAQ,QAAQ;GACvC,KAAK,aAAa,EAAE,iBAAiB,GAAG;GACxC,KAAK,SAAS,cAAc;GAC5B,KAAK,UAAU;EACjB,GACA,EAAE,MAAM,KAAK,CACf;EAEA,IAAI,iBACF,eACM;GACJ,KAAK,kBAAkB;EACzB,GACA,EAAE,MAAM,KAAK,CACf;EACA,IAAI,MAAM;CACZ;;;CAIA,OAAe,KAAqC,MAAoB;EACtE,MAAM,OAAO,IAAI;EACjB,MAAM,KAAK,KAAK,SAAS,SAAS;EAClC,IAAI,CAAC,QAAQ,CAAC,IAAI;EAClB,MAAM,MAAM,GAAG;EACf,IAAI,OAAO,KAAK,UAAU,YAAY,MAAM,QAAQ,KAAK,KAAK,GAAG,GAAG,QAAQ,KAAK;OAC5E,IAAI,OAAO,OAAQ,IAA2B,SAAS,YAC1D,IAAuB,KAAK,KAAK,KAAsB;CAE3D;;CAGA,QAAQ,GAAiB;EACvB,KAAK,SAAS,SAAS,MAAM,QAAQ;CACvC;CAEA,UAAgB;EACd,KAAK,WAAW;EAChB,KAAK,QAAQ,QAAQ;EACrB,KAAK,SAAS,QAAQ;EACtB,KAAK,SAAS,QAAQ;CACxB;AACF"}
|